新指派医助提示

This commit is contained in:
2026-05-11 15:04:24 +08:00
parent 1774a87dd7
commit d8d4da197e
7 changed files with 54 additions and 13 deletions
+6 -4
View File
@@ -151,12 +151,14 @@
stripe stripe
> >
<el-table-column type="selection" width="48" align="center" /> <el-table-column type="selection" width="48" align="center" />
<el-table-column label="ID" min-width="50"> <el-table-column label="ID" min-width="70">
<template #default="{ row }"> <template #default="{ row }">
<div class="patient-cell"> <div class="patient-cell">
<!-- <div class="patient-avatar">{{ (row.patient_name || '患').charAt(0) }}</div> -->
<div class="patient-info"> <div class="patient-info">
<div class="patient-name">{{ row.id }}</div> <div class="patient-name">
{{ row.id }}
<el-tag v-if="row.assign_read_at === null && row.assistant_id > 0" type="danger" size="small" effect="dark" class="ml-1">NEW</el-tag>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -1352,7 +1354,7 @@ const handleSingleAssign = (row: any) => {
currentRow.value = row currentRow.value = row
batchAssignIds.value = [] batchAssignIds.value = []
// 确保类型一致,转换为数字 // 确保类型一致,转换为数字
assignForm.value.assistant_id = row.assistant_id ? Number(row.assistant_id) : null assignForm.value.assistant_id = Number(row.assistant_id) > 0 ? Number(row.assistant_id) : null
assignDialogVisible.value = true assignDialogVisible.value = true
} }
@@ -130,6 +130,7 @@
</div> </div>
<div class="dh5-card-sub"> <div class="dh5-card-sub">
#{{ row.id }} · {{ row.diagnosis_date_text || formatDateTime(row.create_time) }} #{{ row.id }} · {{ row.diagnosis_date_text || formatDateTime(row.create_time) }}
<span v-if="row.assign_read_at === null && row.assistant_id > 0" class="dh5-tag-new">NEW</span>
</div> </div>
</div> </div>
<div class="dh5-card-tags"> <div class="dh5-card-tags">
@@ -1672,6 +1673,18 @@ $dh5-card-bg: #ffffff;
flex-wrap: wrap; flex-wrap: wrap;
} }
.dh5-tag-new {
display: inline-block;
background: #ef4444;
color: #fff;
font-size: 10px;
font-weight: 700;
padding: 1px 4px;
border-radius: 3px;
margin-left: 4px;
vertical-align: middle;
}
.dh5-meta-gender, .dh5-meta-gender,
.dh5-meta-age { .dh5-meta-age {
font-size: 12px; font-size: 12px;
+6 -4
View File
@@ -97,12 +97,14 @@
stripe stripe
> >
<el-table-column type="selection" width="48" align="center" /> <el-table-column type="selection" width="48" align="center" />
<el-table-column label="ID" min-width="50"> <el-table-column label="ID" min-width="70">
<template #default="{ row }"> <template #default="{ row }">
<div class="patient-cell"> <div class="patient-cell">
<!-- <div class="patient-avatar">{{ (row.patient_name || '患').charAt(0) }}</div> -->
<div class="patient-info"> <div class="patient-info">
<div class="patient-name">{{ row.id }}</div> <div class="patient-name">
{{ row.id }}
<el-tag v-if="row.assign_read_at === null && row.assistant_id > 0" type="danger" size="small" effect="dark" class="ml-1">NEW</el-tag>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -1088,7 +1090,7 @@ const handleSingleAssign = (row: any) => {
assignMode.value = 'single' assignMode.value = 'single'
currentRow.value = row currentRow.value = row
// 确保类型一致,转换为数字 // 确保类型一致,转换为数字
assignForm.value.assistant_id = row.assistant_id ? Number(row.assistant_id) : null assignForm.value.assistant_id = Number(row.assistant_id) > 0 ? Number(row.assistant_id) : null
assignDialogVisible.value = true assignDialogVisible.value = true
} }
@@ -117,6 +117,7 @@ class DiagnosisController extends BaseAdminController
$params = (new DiagnosisValidate())->goCheck('id'); $params = (new DiagnosisValidate())->goCheck('id');
$result = DiagnosisLogic::detail($params); $result = DiagnosisLogic::detail($params);
DiagnosisLogic::markAssignRead((int) ($params['id'] ?? 0), $this->adminId);
return $this->data($result); return $this->data($result);
} }
@@ -135,7 +136,7 @@ class DiagnosisController extends BaseAdminController
if (empty($result)) { if (empty($result)) {
return $this->fail(DiagnosisLogic::getError() ?: '诊单不存在或无权访问'); return $this->fail(DiagnosisLogic::getError() ?: '诊单不存在或无权访问');
} }
DiagnosisLogic::markAssignRead((int) ($params['id'] ?? 0), $this->adminId);
return $this->data($result); return $this->data($result);
} }
@@ -177,14 +177,14 @@ class DiagnosisLists extends BaseAdminDataLists implements ListsSearchInterface
$isCompletedTab = !$pendingWideSearch && isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1'; $isCompletedTab = !$pendingWideSearch && isset($this->params['completed_appointment']) && (string) $this->params['completed_appointment'] === '1';
if ($isCompletedTab) { if ($isCompletedTab) {
$maxCompletedAptExpr = '(SELECT MAX(CONCAT(apt.appointment_date, \' \', IFNULL(NULLIF(TRIM(apt.appointment_time), \'\'), \'00:00:00\'))) FROM ' . $aptTbl . ' apt WHERE apt.patient_id = ' . $diagTbl . '.id AND apt.status = 3' . $minAptDateCond . ')'; $maxCompletedAptExpr = '(SELECT MAX(CONCAT(apt.appointment_date, \' \', IFNULL(NULLIF(TRIM(apt.appointment_time), \'\'), \'00:00:00\'))) FROM ' . $aptTbl . ' apt WHERE apt.patient_id = ' . $diagTbl . '.id AND apt.status = 3' . $minAptDateCond . ')';
$orderRaw = 'IFNULL(' . $maxCompletedAptExpr . ", '1970-01-01 00:00:00') DESC, {$diagTbl}.id DESC"; $orderRaw = $diagTbl . '.assign_read_at IS NULL DESC, IFNULL(' . $maxCompletedAptExpr . ", '1970-01-01 00:00:00') DESC, {$diagTbl}.id DESC";
} else { } else {
$orderRaw = 'CASE IFNULL(' . $minAptStatusExpr . ', 999) WHEN 4 THEN 1 WHEN 1 THEN 2 WHEN 3 THEN 3 ELSE 4 END ASC, IFNULL(' . $minAptExpr . ", '9999-12-31 23:59:59') ASC, {$diagTbl}.id DESC"; $orderRaw = $diagTbl . '.assign_read_at IS NULL DESC, CASE IFNULL(' . $minAptStatusExpr . ', 999) WHEN 4 THEN 1 WHEN 1 THEN 2 WHEN 3 THEN 3 ELSE 4 END ASC, IFNULL(' . $minAptExpr . ", '9999-12-31 23:59:59') ASC, {$diagTbl}.id DESC";
} }
$lists = $query $lists = $query
->with(['DiagnosisViewRecord']) ->with(['DiagnosisViewRecord'])
->field(['id', 'patient_id', 'patient_name', 'id_card', 'phone', 'gender', 'age', 'diagnosis_date', 'diagnosis_type', 'syndrome_type', 'assistant_id', 'status', 'create_time', 'update_time']) ->field(['id', 'patient_id', 'patient_name', 'id_card', 'phone', 'gender', 'age', 'diagnosis_date', 'diagnosis_type', 'syndrome_type', 'assistant_id', 'assign_read_at', 'status', 'create_time', 'update_time'])
->append(['gender_desc', 'status_desc', 'diagnosis_date_text']) ->append(['gender_desc', 'status_desc', 'diagnosis_date_text'])
->orderRaw($orderRaw) ->orderRaw($orderRaw)
->limit($this->limitOffset, $this->limitLength) ->limit($this->limitOffset, $this->limitLength)
@@ -535,6 +535,19 @@ class DiagnosisLogic extends BaseLogic
return 0; return 0;
} }
public static function markAssignRead(int $diagnosisId, int $adminId): void
{
if ($diagnosisId <= 0 || $adminId <= 0) {
return;
}
Db::name('tcm_diagnosis')
->where('id', $diagnosisId)
->where('assistant_id', $adminId)
->whereNull('assign_read_at')
->whereNull('delete_time')
->update(['assign_read_at' => time()]);
}
/** /**
* @notes 指派医助(每次成功更新写入一条操作记录,批量指派为多次接口调用各记一条)。 * @notes 指派医助(每次成功更新写入一条操作记录,批量指派为多次接口调用各记一条)。
* **原医助**:优先诊单 `assistant_id`;若为 0 且本次为指派到某人,则从**最近一条**指派日志推断(覆盖发货释放后库为 0、业务上仍有「前任」医助的情况)。 * **原医助**:优先诊单 `assistant_id`;若为 0 且本次为指派到某人,则从**最近一条**指派日志推断(覆盖发货释放后库为 0、业务上仍有「前任」医助的情况)。
@@ -588,7 +601,10 @@ class DiagnosisLogic extends BaseLogic
Db::name('tcm_diagnosis') Db::name('tcm_diagnosis')
->where('id', $id) ->where('id', $id)
->whereNull('delete_time') ->whereNull('delete_time')
->update(['assistant_id' => $toAssistantId]); ->update([
'assistant_id' => $toAssistantId,
'assign_read_at' => $toAssistantId > 0 ? null : 0,
]);
$req = request(); $req = request();
$admin = $req->adminInfo ?? []; $admin = $req->adminInfo ?? [];
@@ -0,0 +1,7 @@
-- 二诊医助:新指派患者已读标记
ALTER TABLE `zyt_tcm_diagnosis`
ADD COLUMN `assign_read_at` int(10) unsigned DEFAULT NULL
COMMENT '医助查看指派时间戳,NULL=未读(新指派红旗)' AFTER `assistant_id`;
-- 已有数据标记为已读,避免全部显示红旗
UPDATE `zyt_tcm_diagnosis` SET `assign_read_at` = UNIX_TIMESTAMP() WHERE `assistant_id` > 0;