Files
zyt/.trellis/tasks/archive/2026-05/05-05-tcm-diagnosis-unserved-days/prd.md
T

88 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T3 · 诊单列表「未服务天数」
> 来源:~/.claude/plans/6-7-fluffy-sunset.mdT3 节)— 拆分版
> 范围:本 PR 仅完成 **后端字段 + 前端列**;「查看」按钮 + 行双击留到 T1+T2 上线时一并加(避免在 readonly 路由不存在的窗口期产生 404)。
## 用户故事
二中心医助每天开诊单列表时,要一眼看出「这个患者多少天没打卡血糖」,便于优先回访。**口径**:未服务天数 = 当天 − 该患者最近一条血糖记录日期(天,向下取整)。以血糖(`zyt_tcm_blood_record.record_date` MAX)为唯一锚点,不混合其它打卡表。
## 后端改动
文件:`server/app/adminapi/lists/tcm/DiagnosisLists.php`
`lists()` 末尾(拼装完所有其它字段之后):
```php
$diagIds = array_filter(array_unique(array_column($lists, 'id')));
$maxRows = [];
if (!empty($diagIds)) {
$maxRows = BloodRecord::whereIn('diagnosis_id', $diagIds)
->whereNull('delete_time')
->group('diagnosis_id')
->column('MAX(record_date)', 'diagnosis_id');
}
$now = time();
foreach ($lists as &$item) {
$last = (int) ($maxRows[(int) $item['id']] ?? 0);
$item['last_blood_record_at'] = $last > 0 ? date('Y-m-d', $last) : null;
$item['unserved_days'] = $last > 0 ? max(0, (int) floor(($now - $last) / 86400)) : null;
}
```
字段语义:
- `last_blood_record_at``Y-m-d` 字符串,无打卡 → `null`
- `unserved_days`:整数,无打卡 → `null`
## 前端改动
文件:`admin/src/views/tcm/diagnosis/index.vue`
在「开方」列后、「视频旁观」列前,新增列:
```html
<el-table-column label="未服务天数" width="110" align="center">
<template #default="{ row }">
<span :class="unservedDaysClass(row.unserved_days)">
{{ row.unserved_days ?? '—' }}
</span>
</template>
</el-table-column>
```
颜色规则(计划原文):
- `null/undefined` → 灰
- `>=7` → 红
- `3-6` → 橙
- `<=2` → 绿
```ts
const unservedDaysClass = (n: unknown) => {
if (n === null || n === undefined) return 'unserved-muted'
const num = Number(n)
if (!Number.isFinite(num)) return 'unserved-muted'
if (num >= 7) return 'unserved-red'
if (num >= 3) return 'unserved-orange'
return 'unserved-green'
}
```
CSS 加 4 个 class(红 #dc2626 / 橙 #ea580c / 绿 #16a34a / 灰 #94a3b8)。
## 不做(边界)
- 不加「查看」按钮(依赖 T1 readonly 页)
- 不加 `@row-dblclick`(同上)
- 不加 `?sort=unserved_days&order=desc` 排序白名单(这是计划原文的可选项;当前没有用户反馈需要排序,先简化)
- 不动 `count()` 函数(仅展示字段,不影响过滤/分页)
## 验收
1. 在诊单列表里能看到「未服务天数」列
2. 没有任何血糖打卡的诊单 → 显示 `—`(灰)
3. 7 天前打过卡 → 红色(如 9
4. 3-6 天前打过卡 → 橙色
5. ≤ 2 天打过卡 → 绿色
6. 列表分页 / 搜索 / Tab 切换不受影响
7. 性能:单页面查询多一次 `WHERE IN + GROUP BY``idx_diagnosis_id`N+1 不会出现