From 2ae7aec8618e36fb6222b45cdeaf1a9c1692b773 Mon Sep 17 00:00:00 2001 From: liuyun Date: Wed, 21 Oct 2026 11:36:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(schedule):=20=E7=94=9F=E6=88=90=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=20UI=20=E5=85=A5=E5=8F=A3=EF=BC=88=E6=89=93=E9=80=9A?= =?UTF-8?q?=E8=AE=A1=E5=88=92=E2=86=92=E6=B4=BE=E5=8D=95=E9=97=AD=E7=8E=AF?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- src/pages/ltc/schedule/index.vue | 127 +++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/pages/ltc/schedule/index.vue b/src/pages/ltc/schedule/index.vue index 1727bc6..16f4575 100644 --- a/src/pages/ltc/schedule/index.vue +++ b/src/pages/ltc/schedule/index.vue @@ -4,6 +4,7 @@
刷新 + 生成工单 批量推荐 横轴时段 08:00–18:00 · 纵轴护理员 · 冲突红框 · 空缺橙框
@@ -116,6 +117,50 @@ 选择工单后自动带入老人与时段,逐条确认后才派 + + + + + + + + + +
+ + + + +
+
+ + + + + + + + + +
+ +
@@ -124,10 +169,12 @@ import { computed, onMounted, reactive, ref } from 'vue' import { ElMessage } from 'element-plus' import { ApiError } from '@/api/http' import { listElders, type Elder } from '@/api/elder' +import { listPlansByElder, type Plan } from '@/api/plan' import { listStaff, type Staff } from '@/api/staff' import { assignOrder, batchRecommend, + generateOrder, listOrders, reassignOrder, type BatchRecommendItem, @@ -164,6 +211,22 @@ const recommending = ref(false) const recommendations = ref([]) const recommendForm = reactive({ elderId: '', timeSlotStart: '', timeSlotEnd: '', orderId: '' }) +// ---- 生成工单 ---- +const generateVisible = ref(false) +const generating = ref(false) +const generatePlans = ref([]) +const generatePlansLoading = ref(false) +const generateForm = reactive({ + elderId: '', + planId: '', + serviceDate: todayStr(), + timeSlotStart: '09:00:00', + timeSlotEnd: '10:00:00', +}) + +/** 老人名下生效中的计划(plan_status === active)。 */ +const activePlans = computed(() => generatePlans.value.filter((p) => p.planStatus === 'active')) + /** 当日待派(to_assign)工单,供「待派工单」下拉选择。 */ const toAssignOrders = computed(() => orders.value.filter((o) => o.orderStatus === 'to_assign')) @@ -182,6 +245,12 @@ function fmtTime(ms?: number | null): string { return `${pad(d.getHours())}:${pad(d.getMinutes())}` } +function fmtDate(ms?: number | null): string { + if (ms == null) return '-' + const d = new Date(ms) + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +} + /** 毫秒时间戳 → 'YYYY-MM-DDTHH:mm:ss'(用于 datetime picker 的 value-format)。 */ function toDateTimeStr(ms?: number | null): string { if (ms == null) return '' @@ -365,6 +434,64 @@ async function confirmRecommend(staffId: string, name: string): Promise { } } +// ---- 生成工单 ---- +function planLabel(p: Plan): string { + return `${fmtDate(p.planPeriodStart)} ~ ${fmtDate(p.planPeriodEnd)} · ${p.careLevel}` +} + +function openGenerate(): void { + generateForm.elderId = '' + generateForm.planId = '' + generateForm.serviceDate = todayStr() + generateForm.timeSlotStart = '09:00:00' + generateForm.timeSlotEnd = '10:00:00' + generatePlans.value = [] + generateVisible.value = true +} + +/** 选中老人后加载其计划列表,仅 active 计划可生成工单。 */ +async function onGenerateElderChange(elderId: string): Promise { + generateForm.planId = '' + generatePlans.value = [] + if (!elderId) return + generatePlansLoading.value = true + try { + generatePlans.value = await listPlansByElder(elderId) + } catch (e) { + if (e instanceof ApiError) ElMessage.error(e.message) + } finally { + generatePlansLoading.value = false + } +} + +async function confirmGenerate(): Promise { + if (!generateForm.elderId) { + ElMessage.warning('请选择老人') + return + } + if (!generateForm.planId) { + ElMessage.warning('请选择生效中的计划') + return + } + generating.value = true + try { + await generateOrder({ + elderId: generateForm.elderId, + planId: generateForm.planId, + serviceDate: generateForm.serviceDate, + timeSlotStart: `${generateForm.serviceDate}T${generateForm.timeSlotStart}`, + timeSlotEnd: `${generateForm.serviceDate}T${generateForm.timeSlotEnd}`, + }) + ElMessage.success('已生成待派工单') + generateVisible.value = false + await refresh() + } catch (e) { + if (e instanceof ApiError) ElMessage.error(e.message) + } finally { + generating.value = false + } +} + onMounted(() => { void refresh() })