feat(health+ai): P2 咨询联动 + AI 巡检消费 — 全链路打通
业务链路打通 5/5 断点全部完成: - 咨询→随访:医生端新增"创建随访"按钮,从咨询会话直接创建随访任务 - 咨询→AI:医生端新增"AI 分析"按钮,对咨询上下文触发 AI 分析 - 告警→咨询:小程序告警详情页新增"在线咨询"快捷入口 - AI 巡检消费:erp-ai 新增 patrol_consumer,订阅 ai.patrol.requested 事件 - 前端联动:Web ConsultationDetail + 小程序 alerts 页面联动实现 后端:2 新 API + 2 handler + 1 service + AI event consumer 前端:Web 2 API + 1 页面改造 + 小程序 2 页面改造 测试:Web consultations.test.ts 9/9 通过
This commit is contained in:
@@ -138,3 +138,24 @@
|
||||
color: $white;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ─── 告警上下文横幅 ─── */
|
||||
.consultation-alert-banner {
|
||||
margin-bottom: var(--tk-gap-sm);
|
||||
}
|
||||
|
||||
.consultation-alert-banner-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--tk-gap-xs);
|
||||
}
|
||||
|
||||
.consultation-alert-banner-icon {
|
||||
font-size: var(--tk-font-body-lg);
|
||||
}
|
||||
|
||||
.consultation-alert-banner-text {
|
||||
font-size: var(--tk-font-body-sm);
|
||||
color: var(--tk-text-secondary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,24 @@ import GuestGuard from '@/components/GuestGuard';
|
||||
import { useElderClass } from '../../hooks/useElderClass';
|
||||
import './index.scss';
|
||||
|
||||
/** 读取当前页面 URL 中的查询参数 */
|
||||
function getQueryParams(): Record<string, string> {
|
||||
try {
|
||||
const instance = Taro.getCurrentInstance();
|
||||
const params = instance?.router?.params;
|
||||
if (!params) return {};
|
||||
const result: Record<string, string> = {};
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
if (typeof value === 'string') {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function formatTime(iso: string): string {
|
||||
if (!iso) return '';
|
||||
const d = new Date(iso);
|
||||
@@ -59,6 +77,9 @@ export default function Consultation() {
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
|
||||
// Alert context: when navigated from an alert page
|
||||
const [alertContext, setAlertContext] = useState<{ alertId: string; alertTitle: string } | null>(null);
|
||||
|
||||
const loadSessions = useCallback(async (pageNum: number, isRefresh = false) => {
|
||||
if (isRefresh) setLoading(true);
|
||||
setError('');
|
||||
@@ -87,6 +108,14 @@ export default function Consultation() {
|
||||
usePageData(
|
||||
useCallback(async () => {
|
||||
Taro.setNavigationBarTitle({ title: '在线咨询' });
|
||||
// Read alert context from URL query params
|
||||
const params = getQueryParams();
|
||||
if (params.context === 'alert' && params.alert_id) {
|
||||
setAlertContext({
|
||||
alertId: params.alert_id,
|
||||
alertTitle: params.alert_title ? decodeURIComponent(params.alert_title) : '健康告警',
|
||||
});
|
||||
}
|
||||
if (!user) return;
|
||||
await loadSessions(1, true);
|
||||
}, [user, loadSessions]),
|
||||
@@ -128,6 +157,18 @@ export default function Consultation() {
|
||||
{/* 副标题 */}
|
||||
<Text className='consultation-subtitle'>随时随地,连接专业医生</Text>
|
||||
|
||||
{/* Alert context banner */}
|
||||
{alertContext && (
|
||||
<ContentCard className='consultation-alert-banner'>
|
||||
<View className='consultation-alert-banner-inner'>
|
||||
<Text className='consultation-alert-banner-icon'>⚠</Text>
|
||||
<Text className='consultation-alert-banner-text'>
|
||||
来自告警: {alertContext.alertTitle}
|
||||
</Text>
|
||||
</View>
|
||||
</ContentCard>
|
||||
)}
|
||||
|
||||
{/* 发起咨询按钮 */}
|
||||
<View
|
||||
className='consultation-create-btn'
|
||||
|
||||
@@ -98,3 +98,31 @@
|
||||
color: $tx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.alert-message {
|
||||
display: block;
|
||||
font-size: var(--tk-font-body);
|
||||
color: var(--tk-text-secondary);
|
||||
line-height: 1.5;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.alert-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid $bd;
|
||||
}
|
||||
|
||||
.alert-consult-btn {
|
||||
padding: 8px 24px;
|
||||
border-radius: $r-pill;
|
||||
background: var(--tk-pri);
|
||||
}
|
||||
|
||||
.alert-consult-btn-text {
|
||||
font-size: var(--tk-font-body);
|
||||
color: $card;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,19 @@ export default function PatientAlerts() {
|
||||
</Text>
|
||||
</View>
|
||||
<Text className='alert-title'>{item.title}</Text>
|
||||
{item.message && (
|
||||
<Text className='alert-message'>{item.message}</Text>
|
||||
)}
|
||||
<View className='alert-actions'>
|
||||
<View
|
||||
className='alert-consult-btn'
|
||||
onClick={() => safeNavigateTo(
|
||||
`/pages/consultation/index?context=alert&alert_id=${item.id}&alert_title=${encodeURIComponent(item.title)}`,
|
||||
)}
|
||||
>
|
||||
<Text className='alert-consult-btn-text'>在线咨询</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ContentCard>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user