diff --git a/admin/src/api/tcm.ts b/admin/src/api/tcm.ts index 9f749516..d1215643 100644 --- a/admin/src/api/tcm.ts +++ b/admin/src/api/tcm.ts @@ -61,6 +61,14 @@ export function tcmDiagnosisDetail(params: any) { return request.get({ url: '/tcm.diagnosis/detail', params }) } +/** 设置复诊接诊率统计起始偏移(统计诊次=实单序号+偏移;1=二诊起,2=三诊起) */ +export function tcmDiagnosisSetRevisitSlotStartOffset(params: { + id: number + revisit_slot_start_offset: number +}) { + return request.post({ url: '/tcm.diagnosis/setRevisitSlotStartOffset', params }) +} + /** 诊单挂号 / 取消挂号 操作日志 */ export function tcmDiagnosisGuahaoLogList(params: { id: number }) { return request.get({ url: '/tcm.diagnosis/guahaoLogList', params }) diff --git a/admin/src/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue b/admin/src/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue index 37a8e4ad..053b7c2c 100644 --- a/admin/src/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue +++ b/admin/src/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue @@ -1290,11 +1290,15 @@ const detailFullAddress = computed(() => { const servicePackageOptions = ref([]) async function loadServicePackageOptions() { + if (servicePackageOptions.value.length > 0) return try { const data: any = await getDictData({ type: 'server_order' }) - servicePackageOptions.value = normalizeServicePackageOptions(data?.server_order) + const opts = normalizeServicePackageOptions(data?.server_order) + if (opts.length > 0) { + servicePackageOptions.value = opts + } } catch { - servicePackageOptions.value = [] + /* 请求被同参数请求取消或失败时保留现值,open() 时会重试 */ } } @@ -1639,6 +1643,8 @@ async function updateJdLogistics() { // ─── 打开 / 刷新 ─── async function open(id: number) { + // 页面级同参数字典请求会取消抽屉挂载时的那次(axios 去重取消),打开时兜底重试 + void loadServicePackageOptions() // 显式彻底清空缓存,防止前一次弹窗的数据残留 detailData.value = null detailUnlinkedPayOrders.value = [] diff --git a/admin/src/views/consumer/prescription/order_list.vue b/admin/src/views/consumer/prescription/order_list.vue index 96a823e0..b8408da2 100644 --- a/admin/src/views/consumer/prescription/order_list.vue +++ b/admin/src/views/consumer/prescription/order_list.vue @@ -298,7 +298,7 @@ :fetch-fun="prescriptionOrderExport" :params="prescriptionOrderExportParams" :page-size="pager.size" - export-hint="导出范围与上方筛选一致(履约状态、创建时间及其他条件均会生效)。含「自媒体渠道(挂号渠道来源)」:优先取该单关联处方登记的挂号;无则诊单下同患者挂号取 id 最大的一条(与前台挂号选择的记录一致);业绩侧栏带渠道筛选导出时与同页列表高亮挂号同源。「服务套餐」按字典 server_order 解析展示。「处方」导出主方/辅方药材明细;「主方/辅方服用方式、天数」与详情侧栏、处方笺同口径(天数优先取订单 medication_days,缺省回退处方 usage_days / 辅方 aux_usage)。「关联收款记录」与详情侧栏同源(已支付/已退款/待审核),每笔两行展示(摘要行+明细行),多笔空行分隔,单元格自动换行。「签收日期」与详情/业绩看板同源,仅读物流库(轨迹/签收时间):导出不再实时查快递100,速度只取决于数据库;签收时间由 `tcm:backfill-sign-time` 命令与物流自动更新定时任务落库,刚发货尚未同步的单子会暂时为空,待下次回填/定时任务刷新后显示。" + export-hint="导出范围与上方筛选一致(履约状态、创建时间及其他条件均会生效)。含「自媒体渠道(挂号渠道来源)」:优先取该单关联处方登记的挂号;无则诊单下同患者挂号取 id 最大的一条(与前台挂号选择的记录一致);业绩侧栏带渠道筛选导出时与同页列表高亮挂号同源。「服务套餐」按字典 server_order 解析展示。「处方」导出主方/辅方药材明细;「主方/辅方服用方式、天数」与详情侧栏同口径(主方/辅方天数分别取处方 usage_days、辅方 aux_usage.usage_days;「天数」列为订单 medication_days)。「关联收款记录」与详情侧栏同源(已支付/已退款/待审核),每笔两行展示(摘要行+明细行),多笔空行分隔,单元格自动换行。「签收日期」与详情/业绩看板同源,仅读物流库(轨迹/签收时间):导出不再实时查快递100,速度只取决于数据库;签收时间由 `tcm:backfill-sign-time` 命令与物流自动更新定时任务落库,刚发货尚未同步的单子会暂时为空,待下次回填/定时任务刷新后显示。" /> diff --git a/admin/src/views/stats/revisit_rate/index.vue b/admin/src/views/stats/revisit_rate/index.vue index 95cc95b2..00ece189 100644 --- a/admin/src/views/stats/revisit_rate/index.vue +++ b/admin/src/views/stats/revisit_rate/index.vue @@ -46,7 +46,7 @@ 当月被指派总数:当月内诊单被指派给医助(按指派操作时间落月,剔除勾选「继承」的指派)的诊单数,按「医助 × 诊单」去重;部门行 / 合计行按诊单去重。

- 诊次(第 N 次下单):患者(诊单)名下计入业绩的业务订单(剔除已取消 / 拒收 / 退款)按下单时间升序的全局序号,跨月累计不重置——如 5 月指派后旗下成交 4 单为二诊~五诊,下月再成交即为六诊。 + 诊次(第 N 次下单):患者(诊单)名下计入业绩的业务订单(剔除已取消 / 拒收 / 退款)按下单时间升序编号为「实单序号」,统计诊次 = 实单序号 + 诊单偏移(默认偏移 1 → 第 1 笔实单为二诊;偏移 2 → 第 1 笔实单为三诊,5 笔实单等价七诊)。诊次跨月累计不重置。诊单可在「业务订单」tab 配置偏移量。

当月 N 诊单数:当月内下单且诊次为 N 的订单数,归属下单时点持有该患者的医助(指派可在往月;释放后不再归属;「继承」指派会转移持有人但不计被指派数)。 diff --git a/admin/src/views/tcm/appointment/list.vue b/admin/src/views/tcm/appointment/list.vue index 4be8fade..9672425f 100644 --- a/admin/src/views/tcm/appointment/list.vue +++ b/admin/src/views/tcm/appointment/list.vue @@ -83,6 +83,23 @@ 未确认 +

+ 部门 + +
([]) +const assistantDeptTreeProps = { + value: 'id', + label: 'name', + children: 'children' +} + const activeTab = ref('1') const dateCustomVisible = ref(false) const statusCount = ref>({ @@ -721,6 +748,12 @@ const handleDiagnosisConfirmedChange = () => { loadData() } +// 部门筛选变更 +const handleAssistantDeptChange = () => { + pager.page = 1 + loadData() +} + // 快捷日期变更 const handleDatePresetChange = (val: string | number | boolean | undefined) => { const v = String(val || '') @@ -770,6 +803,7 @@ const handleReset = () => { formData.doctor_name = '' formData.date_preset = 'today' formData.diagnosis_confirmed = '' + formData.assistant_dept_id = '' const t = new Date() const p = (n: number) => String(n).padStart(2, '0') formData.start_date = `${t.getFullYear()}-${p(t.getMonth() + 1)}-${p(t.getDate())}` @@ -1099,7 +1133,13 @@ formData.start_date = `${_today.getFullYear()}-${_pad(_today.getMonth() + 1)}-${ formData.end_date = formData.start_date formData.status = 1 -onMounted(() => { +onMounted(async () => { + try { + const deptTree = await deptAll() + departmentTreeRaw.value = Array.isArray(deptTree) ? deptTree : [] + } catch { + departmentTreeRaw.value = [] + } loadData() listPollTimer = setInterval(() => { loadData({ silent: true }) @@ -1228,6 +1268,10 @@ onUnmounted(() => { padding: 6px 14px; } } + + .filter-dept-select { + width: 200px; + } } } diff --git a/admin/src/views/tcm/diagnosis/components/PatientOrderList.vue b/admin/src/views/tcm/diagnosis/components/PatientOrderList.vue index d78824ff..cd522ee9 100644 --- a/admin/src/views/tcm/diagnosis/components/PatientOrderList.vue +++ b/admin/src/views/tcm/diagnosis/components/PatientOrderList.vue @@ -4,6 +4,43 @@