13 小时以前 bbce6db600e6bb0cf2a3bb78bdf5ccff70b737a8
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<script lang="ts" setup>
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
import type { MesProWorkOrderProcessApi } from '#/api/mes/pro/workorder/process';
 
import { computed, ref } from 'vue';
 
import { useVbenModal } from '@vben/common-ui';
 
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 { getWorkOrderProcessListByWorkOrderId } from '#/api/mes/pro/workorder/process';
 
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<MesProWorkOrderProcessApi.WorkOrderProcess[]>([]);
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(workOrderId: number, productId: number) {
  const woProcesses = await getWorkOrderProcessListByWorkOrderId(workOrderId);
  if (!woProcesses || woProcesses.length === 0) {
    message.warning('当前订单未配置工序,请先在工单中维护工序信息');
    return;
  }
  routeProcessList.value = [...woProcesses].toSorted(
    (a, b) => (a.sort ?? 0) - (b.sort ?? 0),
  );
  // 确定工艺路线ID:工单路线 → 产品路线
  if (workOrder.value?.routeId) {
    currentRouteId.value = workOrder.value.routeId;
  } else {
    const processes = await getRouteProcessListByProduct(productId);
    currentRouteId.value = processes?.[0]?.routeId ?? 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.id!,
          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="rp.outputItemId || 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">
        <template v-if="formType === 'schedule'">
          <Popconfirm
            v-if="routeProcessList.length > 0"
            title="确认要完成该订单吗?完成后订单下所有任务将标记为已完成。"
            @confirm="handleFinish"
          >
            <Button type="primary">完成</Button>
          </Popconfirm>
          <span v-else class="text-gray-400 text-sm">
            当前订单未配置工序,请先在工单中维护工序信息后再完成
          </span>
        </template>
      </div>
    </template>
  </Modal>
</template>