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()
})