spring
2026-07-03 2540d86f0dbd77f654f558c3bf9d5ddbe7422f16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<script lang="ts" setup>
import type { MesProRouteProcessApi } from '#/api/mes/pro/route/process';
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
 
import { computed, ref } from 'vue';
 
import { useVbenModal } from '../../../../../packages/effects/common-ui/src';
 
import { Button, Card, message, Popconfirm, Steps } from 'ant-design-vue';
 
import { useVbenForm } from '#/adapter/form';
import { getRouteProcessListByProduct } from '#/api/mes/pro/route/process';
import { finishWorkOrder, getWorkOrder } from '#/api/mes/pro/workorder';
 
import { useScheduleFormSchema } from '../data';
import TaskList from './task-list.vue';
 
const emit = defineEmits(['success']);
const formType = ref<'detail' | 'schedule'>('schedule');
const workOrder = ref<MesProWorkOrderApi.WorkOrder>(); // 当前订单详情
const routeProcessList = ref<MesProRouteProcessApi.RouteProcess[]>([]); // 工艺路线工序列表
const activeProcessStep = ref(0); // 当前工序步骤索引
const currentRouteId = ref(0); // 当前工艺路线编号
 
const isReadonly = computed(() => formType.value === 'detail'); // 详情态只读
const getTitle = computed(() =>
  formType.value === 'detail' ? '订单详情' : '生产排产',
);
 
const [Form, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-1',
    labelWidth: 100,
  },
  layout: 'horizontal',
  schema: useScheduleFormSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-3',
});
 
/** 加载工艺路线工序列表 */
async function loadRouteProcesses(productId: number) {
  const processes = await getRouteProcessListByProduct(productId);
  if (!processes || processes.length === 0) {
    message.warning('当前产品未配置工艺路线,请先在工艺路线中维护');
    return;
  }
  currentRouteId.value = processes[0]!.routeId ?? 0;
  routeProcessList.value = [...processes].toSorted(
    (a, b) => (a.sort ?? 0) - (b.sort ?? 0),
  );
}
 
/** 完成订单 */
async function handleFinish() {
  if (!workOrder.value?.id) {
    return;
  }
  modalApi.lock();
  try {
    await finishWorkOrder(workOrder.value.id);
    message.success('订单已完成');
    await modalApi.close();
    emit('success');
  } finally {
    modalApi.unlock();
  }
}
 
const [Modal, modalApi] = useVbenModal({
  showConfirmButton: false,
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      workOrder.value = undefined;
      routeProcessList.value = [];
      activeProcessStep.value = 0;
      currentRouteId.value = 0;
      return;
    }
    // 加载数据
    const data = modalApi.getData<{
      formType: 'detail' | 'schedule';
      id: number;
    }>();
    formType.value = data.formType;
    activeProcessStep.value = 0;
    routeProcessList.value = [];
    modalApi.lock();
    try {
      workOrder.value = await getWorkOrder(data.id);
      // 设置到 values
      await formApi.setValues(workOrder.value);
      if (workOrder.value.productId) {
        await loadRouteProcesses(workOrder.value.productId);
      }
    } finally {
      modalApi.unlock();
    }
  },
});
</script>
 
<template>
  <Modal :title="getTitle" class="w-4/5">
    <Form class="mx-4" />
    <!-- 工序步骤导航 + 当前工序任务列表 -->
    <template v-if="routeProcessList.length > 0 && workOrder?.id">
      <Steps
        v-model:current="activeProcessStep"
        class="my-4 px-4"
        size="small"
        type="navigation"
      >
        <Steps.Step
          v-for="rp in routeProcessList"
          :key="rp.processId"
          :title="rp.processName"
        />
      </Steps>
      <Card
        v-for="(rp, index) in routeProcessList"
        v-show="activeProcessStep === index"
        :key="rp.processId"
        class="mx-4"
      >
        <TaskList
          :color-code="rp.colorCode"
          :disabled="isReadonly"
          :item-id="workOrder.productId"
          :process-id="rp.processId!"
          :route-id="currentRouteId"
          :work-order-id="workOrder.id!"
        />
      </Card>
    </template>
    <template #prepend-footer>
      <div class="flex flex-auto items-center gap-2">
        <Popconfirm
          v-if="formType === 'schedule'"
          title="确认要完成该订单吗?完成后订单下所有任务将标记为已完成。"
          @confirm="handleFinish"
        >
          <Button type="primary">完成</Button>
        </Popconfirm>
      </div>
    </template>
  </Modal>
</template>