feat: 升级结构化计分可信度
This commit is contained in:
@@ -32,6 +32,41 @@ function displayDate(value: string) {
|
||||
return new Date(value).toLocaleString('zh-CN', { hour12: false });
|
||||
}
|
||||
|
||||
function directionText(direction?: ScoreMetric['direction']) {
|
||||
switch (direction) {
|
||||
case 'risk':
|
||||
return '高分代表风险或困扰升高';
|
||||
case 'protective':
|
||||
return '高分代表改善或保护因素更高';
|
||||
case 'ability':
|
||||
return '高分代表表现更好';
|
||||
case 'trait':
|
||||
return '高分代表该特质更明显';
|
||||
case 'mixed':
|
||||
return '高分含义需按维度查看';
|
||||
default:
|
||||
return '高分含义需结合量表说明';
|
||||
}
|
||||
}
|
||||
|
||||
function changeText(current: ScoreMetric, previous?: ScoreMetric) {
|
||||
if (!previous) return '基线';
|
||||
const diff = current.value - previous.value;
|
||||
if (diff === 0) return '无变化';
|
||||
const signed = `${diff > 0 ? '+' : ''}${diff}`;
|
||||
switch (current.direction) {
|
||||
case 'risk':
|
||||
return diff > 0 ? `风险升高 ${signed}` : `风险降低 ${signed}`;
|
||||
case 'protective':
|
||||
case 'ability':
|
||||
return diff > 0 ? `改善 ${signed}` : `下降 ${signed}`;
|
||||
case 'trait':
|
||||
return diff > 0 ? `特质增强 ${signed}` : `特质减弱 ${signed}`;
|
||||
default:
|
||||
return `变化 ${signed}`;
|
||||
}
|
||||
}
|
||||
|
||||
function MetricBar({ metric }: { metric: ScoreMetric }) {
|
||||
const width = metric.max ? Math.max(0, Math.min(100, metric.value / metric.max * 100)) : 0;
|
||||
return (
|
||||
@@ -244,14 +279,15 @@ export function RecordsDashboard() {
|
||||
{trendGroups.map((group) => (
|
||||
<div key={group[0].questionnaireId}>
|
||||
<div className="mb-3 flex flex-wrap items-baseline justify-between gap-2"><h2 className="text-lg font-semibold">{group[0].questionnaireTitle}</h2>{group[0].recommendedInterval && <span className="text-sm text-muted-foreground">建议间隔:{group[0].recommendedInterval}</span>}</div>
|
||||
<p className="mb-3 text-sm text-muted-foreground">{group[0].scoreSummary.highScoreMeaning} · {directionText(group[0].scoreSummary.direction)}</p>
|
||||
<div className="overflow-x-auto border">
|
||||
<table className="w-full min-w-[540px] text-sm"><thead className="bg-muted/50"><tr><th className="p-3 text-left">时间</th><th className="p-3 text-left">分数</th><th className="p-3 text-left">与上次相比</th></tr></thead>
|
||||
<tbody>{group.map((record, index) => { const metrics = record.scoreSummary.primary ? [record.scoreSummary.primary] : record.scoreSummary.metrics; const previous = group[index - 1]?.scoreSummary.primary; return <tr key={record.id} className="border-t"><td className="p-3">{displayDate(record.completedAt)}</td><td className="p-3">{metrics.map((item) => <span key={item.key} className="mr-4">{item.label} {item.value}{item.max ? `/${item.max}` : ''}</span>)}</td><td className="p-3">{record.scoreSummary.primary && previous ? `${record.scoreSummary.primary.value - previous.value > 0 ? '+' : ''}${record.scoreSummary.primary.value - previous.value}` : '基线'}</td></tr>; })}</tbody>
|
||||
<table className="w-full min-w-[640px] text-sm"><thead className="bg-muted/50"><tr><th className="p-3 text-left">时间</th><th className="p-3 text-left">分数</th><th className="p-3 text-left">高分方向</th><th className="p-3 text-left">与上次相比</th></tr></thead>
|
||||
<tbody>{group.map((record, index) => { const metrics = record.scoreSummary.primary ? [record.scoreSummary.primary] : record.scoreSummary.metrics; const primary = record.scoreSummary.primary; const previous = group[index - 1]?.scoreSummary.primary; return <tr key={record.id} className="border-t"><td className="p-3">{displayDate(record.completedAt)}</td><td className="p-3">{metrics.map((item) => <span key={item.key} className="mr-4">{item.label} {item.value}{item.max ? `/${item.max}` : ''}</span>)}</td><td className="p-3">{directionText(primary?.direction || record.scoreSummary.direction)}</td><td className="p-3">{primary ? changeText(primary, previous) : '看各维度'}</td></tr>; })}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<p className="text-sm text-muted-foreground">趋势只呈现分数变化,不自动判断改善或恶化;不同量表的高分方向并不相同。</p>
|
||||
<p className="text-sm text-muted-foreground">趋势会按量表方向解释变化;敏感量表只作为自评追踪参考,不等同于诊断。</p>
|
||||
</section>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user