From f10cf167372f2d8c4c0e14f42f361d7ab96d8347 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期五, 03 七月 2026 13:59:00 +0800
Subject: [PATCH] Merge branch 'dev_pro2.0' of http://114.132.189.42:9002/r/mom-pro2-before into dev_pro2.0

---
 src/views/mes/process-design/route/data.ts |  517 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 517 insertions(+), 0 deletions(-)

diff --git a/src/views/mes/process-design/route/data.ts b/src/views/mes/process-design/route/data.ts
new file mode 100644
index 0000000..a6c6810
--- /dev/null
+++ b/src/views/mes/process-design/route/data.ts
@@ -0,0 +1,517 @@
+import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
+import type { VxeTableGridOptions } from '#/adapter/vxe-table';
+import type { MesProRouteApi } from '#/api/mes/pro/route';
+import type { MesProRouteProcessApi } from '#/api/mes/pro/route/process';
+import type { MesProRouteProductApi } from '#/api/mes/pro/route/product';
+import type { MesProRouteProductBomApi } from '#/api/mes/pro/route/productbom';
+
+import { h, markRaw } from 'vue';
+
+import {
+  CommonStatusEnum,
+  DICT_TYPE,
+  MesAutoCodeRuleCode,
+} from '../../../../packages/constants/src';
+import { getDictOptions } from '../../../../packages/effects/hooks/src';
+
+import { Button } from 'ant-design-vue';
+
+import { z } from '#/adapter/form';
+import { generateAutoCode } from '#/api/mes/md/autocode/record';
+import {
+  MdItemSelect,
+  MdProductBomSelect,
+} from '#/views/mes/md/item/components';
+
+import { RouteColorPicker } from './components';
+
+/** 琛ㄥ崟绫诲瀷 */
+export type FormType = 'create' | 'detail' | 'update';
+
+/** 宸ヨ壓璺嚎琛ㄥ崟 */
+export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
+  return [
+    {
+      fieldName: 'id',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'code',
+      label: '璺嚎缂栫爜',
+      component: 'Input',
+      componentProps: {
+        maxLength: 64,
+        placeholder: '璇疯緭鍏ュ伐鑹鸿矾绾跨紪鐮�',
+      },
+      rules: z.string().min(1, '璺嚎缂栫爜涓嶈兘涓虹┖').max(64),
+      suffix: () =>
+        h(
+          Button,
+          {
+            type: 'default',
+            onClick: async () => {
+              const code = await generateAutoCode(
+                MesAutoCodeRuleCode.PRO_ROUTE_CODE,
+              );
+              await formApi?.setFieldValue('code', code);
+            },
+          },
+          { default: () => '鐢熸垚' },
+        ),
+    },
+    {
+      fieldName: 'name',
+      label: '璺嚎鍚嶇О',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+        placeholder: '璇疯緭鍏ュ伐鑹鸿矾绾垮悕绉�',
+      },
+      rules: z.string().min(1, '璺嚎鍚嶇О涓嶈兘涓虹┖').max(100),
+    },
+    {
+      fieldName: 'description',
+      label: '璺嚎璇存槑',
+      component: 'Textarea',
+      formItemClass: 'col-span-2',
+      componentProps: {
+        maxLength: 500,
+        placeholder: '璇疯緭鍏ュ伐鑹鸿矾绾胯鏄�',
+        rows: 3,
+      },
+    },
+    {
+      fieldName: 'remark',
+      label: '澶囨敞',
+      component: 'Textarea',
+      formItemClass: 'col-span-2',
+      componentProps: {
+        maxLength: 250,
+        placeholder: '璇疯緭鍏ュ娉�',
+        rows: 2,
+      },
+    },
+  ];
+}
+
+/** 鍒楄〃鎼滅储琛ㄥ崟 */
+export function useGridFormSchema(): VbenFormSchema[] {
+  return [
+    {
+      fieldName: 'code',
+      label: '璺嚎缂栫爜',
+      component: 'Input',
+      componentProps: {
+        allowClear: true,
+        placeholder: '璇疯緭鍏ヨ矾绾跨紪鐮�',
+      },
+    },
+    {
+      fieldName: 'name',
+      label: '璺嚎鍚嶇О',
+      component: 'Input',
+      componentProps: {
+        allowClear: true,
+        placeholder: '璇疯緭鍏ヨ矾绾垮悕绉�',
+      },
+    },
+    {
+      fieldName: 'status',
+      label: '鐘舵��',
+      component: 'Select',
+      componentProps: {
+        allowClear: true,
+        options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
+        placeholder: '璇烽�夋嫨鐘舵��',
+      },
+    },
+  ];
+}
+
+/** 鍒楄〃瀛楁 */
+export function useGridColumns(
+  onStatusChange?: (
+    newStatus: number,
+    row: MesProRouteApi.Route,
+  ) => PromiseLike<boolean | undefined>,
+  statusEditable = true,
+): VxeTableGridOptions<MesProRouteApi.Route>['columns'] {
+  return [
+    {
+      field: 'code',
+      title: '璺嚎缂栫爜',
+      minWidth: 160,
+      slots: { default: 'code' },
+    },
+    { field: 'name', title: '璺嚎鍚嶇О', minWidth: 180 },
+    { field: 'description', title: '璺嚎璇存槑', minWidth: 200 },
+    {
+      field: 'status',
+      title: '鐘舵��',
+      width: 110,
+      align: 'center',
+      cellRender: {
+        attrs: { beforeChange: onStatusChange },
+        name: 'CellSwitch',
+        props: {
+          checkedValue: CommonStatusEnum.ENABLE,
+          disabled: !statusEditable,
+          unCheckedValue: CommonStatusEnum.DISABLE,
+        },
+      },
+    },
+    { field: 'remark', title: '澶囨敞', minWidth: 160 },
+    {
+      field: 'createTime',
+      title: '鍒涘缓鏃堕棿',
+      width: 180,
+      formatter: 'formatDateTime',
+    },
+    {
+      title: '鎿嶄綔',
+      width: 160,
+      fixed: 'right',
+      slots: { default: 'actions' },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎宸ュ簭鏄庣粏琛ㄥ崟 */
+export function useRouteProcessFormSchema(
+  processOptions: Array<{ label: string; value: number }>,
+): VbenFormSchema[] {
+  return [
+    {
+      fieldName: 'id',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'routeId',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'sort',
+      label: '搴忓彿',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 1,
+        precision: 0,
+      },
+      rules: z.number().default(1),
+    },
+    {
+      fieldName: 'processId',
+      label: '宸ュ簭',
+      component: 'Select',
+      componentProps: {
+        allowClear: true,
+        options: processOptions,
+        placeholder: '璇烽�夋嫨宸ュ簭',
+        showSearch: true,
+      },
+      rules: 'selectRequired',
+    },
+    {
+      fieldName: 'linkType',
+      label: '涓庝笅閬撳伐搴忓叧绯�',
+      component: 'Select',
+      componentProps: {
+        allowClear: true,
+        options: getDictOptions(DICT_TYPE.MES_PRO_LINK_TYPE, 'number'),
+        placeholder: '璇烽�夋嫨',
+      },
+      rules: z.number().default(3),
+    },
+    {
+      fieldName: 'colorCode',
+      label: '鐢樼壒鍥鹃鑹�',
+      component: RouteColorPicker,
+    },
+    {
+      fieldName: 'keyFlag',
+      label: '鏄惁鍏抽敭宸ュ簭',
+      component: 'Switch',
+      componentProps: {
+        checkedChildren: '鏄�',
+        unCheckedChildren: '鍚�',
+      },
+      rules: z.boolean().default(false),
+    },
+    {
+      fieldName: 'checkFlag',
+      label: '鏄惁璐ㄦ纭',
+      component: 'Switch',
+      componentProps: {
+        checkedChildren: '鏄�',
+        unCheckedChildren: '鍚�',
+      },
+      rules: z.boolean().default(false),
+    },
+    {
+      fieldName: 'prepareTime',
+      label: '鍑嗗鏃堕棿(鍒�)',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 0,
+        precision: 0,
+      },
+      rules: z.number().default(0),
+    },
+    {
+      fieldName: 'waitTime',
+      label: '绛夊緟鏃堕棿(鍒�)',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 0,
+        precision: 0,
+      },
+      rules: z.number().default(0),
+    },
+    {
+      fieldName: 'remark',
+      label: '澶囨敞',
+      component: 'Textarea',
+      formItemClass: 'col-span-2',
+      componentProps: {
+        maxLength: 250,
+        placeholder: '璇疯緭鍏ュ娉�',
+        rows: 2,
+      },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎宸ュ簭鍒楄〃瀛楁 */
+export function useRouteProcessGridColumns(): VxeTableGridOptions<MesProRouteProcessApi.RouteProcess>['columns'] {
+  return [
+    { field: 'sort', title: '搴忓彿', width: 70, align: 'center', fixed: 'left' },
+    { field: 'processCode', title: '宸ュ簭缂栫爜', width: 140, fixed: 'left' },
+    { field: 'processName', title: '宸ュ簭鍚嶇О', width: 140, fixed: 'left' },
+    { field: 'nextProcessName', title: '涓嬩竴閬撳伐搴�', width: 140 },
+    {
+      field: 'linkType',
+      title: '涓庝笅涓�閬撳伐搴忓叧绯�',
+      width: 160,
+      cellRender: {
+        name: 'CellDict',
+        props: { type: DICT_TYPE.MES_PRO_LINK_TYPE },
+      },
+    },
+    {
+      field: 'keyFlag',
+      title: '鍏抽敭宸ュ簭',
+      width: 90,
+      cellRender: {
+        name: 'CellDict',
+        props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
+      },
+    },
+    {
+      field: 'checkFlag',
+      title: '璐ㄦ纭',
+      width: 100,
+      cellRender: {
+        name: 'CellDict',
+        props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
+      },
+    },
+    { field: 'prepareTime', title: '鍑嗗鏃堕棿(鍒�)', width: 110 },
+    { field: 'waitTime', title: '绛夊緟鏃堕棿(鍒�)', width: 110 },
+    {
+      field: 'colorCode',
+      title: '鐢樼壒鍥鹃鑹�',
+      width: 130,
+      slots: { default: 'colorCode' },
+    },
+    { field: 'remark', title: '澶囨敞', minWidth: 160 },
+    {
+      title: '鎿嶄綔',
+      width: 130,
+      fixed: 'right',
+      slots: { default: 'actions' },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎浜у搧鍒楄〃瀛楁 */
+export function useRouteProductGridColumns(): VxeTableGridOptions<MesProRouteProductApi.RouteProduct>['columns'] {
+  return [
+    { field: 'itemCode', title: '浜у搧鐗╂枡缂栫爜', width: 150 },
+    { field: 'itemName', title: '浜у搧鐗╂枡鍚嶇О', width: 150 },
+    { field: 'specification', title: '瑙勬牸鍨嬪彿', width: 150 },
+    { field: 'unitName', title: '鍗曚綅', width: 80 },
+    { field: 'quantity', title: '鐢熶骇鏁伴噺', width: 100 },
+    {
+      field: 'productionTime',
+      title: '鐢熶骇鐢ㄦ椂',
+      width: 130,
+      slots: { default: 'productionTime' },
+    },
+    { field: 'remark', title: '澶囨敞', minWidth: 160 },
+    {
+      title: '鎿嶄綔',
+      width: 130,
+      fixed: 'right',
+      slots: { default: 'actions' },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎浜у搧 BOM 鍒楄〃瀛楁 */
+export function useRouteProductBomGridColumns(): VxeTableGridOptions<MesProRouteProductBomApi.RouteProductBom>['columns'] {
+  return [
+    { field: 'itemCode', title: 'BOM 鐗╂枡缂栫爜', width: 150 },
+    { field: 'itemName', title: 'BOM 鐗╂枡鍚嶇О', width: 150 },
+    { field: 'specification', title: '瑙勬牸鍨嬪彿', width: 150 },
+    { field: 'unitName', title: '鍗曚綅', width: 80 },
+    { field: 'quantity', title: '鐢ㄦ枡姣斾緥', width: 100 },
+    { field: 'remark', title: '澶囨敞', minWidth: 160 },
+    {
+      title: '鎿嶄綔',
+      width: 130,
+      fixed: 'right',
+      slots: { default: 'actions' },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎浜у搧琛ㄥ崟 */
+export function useRouteProductFormSchema(
+  onItemChange?: (item: any) => void,
+): VbenFormSchema[] {
+  return [
+    {
+      fieldName: 'id',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'routeId',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    // 浜у搧鐗╂枡锛氫娇鐢ㄤ笟鍔¤嚜瀹氫箟閫夋嫨鍣紝change 鍥炲~缂栫爜/鍚嶇О/瑙勬牸/鍗曚綅
+    {
+      fieldName: 'itemId',
+      label: '浜у搧',
+      component: markRaw(MdItemSelect),
+      componentProps: {
+        onChange: onItemChange,
+      },
+      formItemClass: 'col-span-2',
+      rules: 'selectRequired',
+    },
+    {
+      fieldName: 'quantity',
+      label: '鐢熶骇鏁伴噺',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 1,
+        precision: 0,
+      },
+      rules: z.number().default(1),
+    },
+    {
+      fieldName: 'productionTime',
+      label: '鐢熶骇鐢ㄦ椂',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 0,
+        precision: 2,
+      },
+      rules: z.number().default(1),
+    },
+    {
+      fieldName: 'timeUnitType',
+      label: '鏃堕棿鍗曚綅',
+      component: 'Select',
+      componentProps: {
+        allowClear: true,
+        options: getDictOptions(DICT_TYPE.MES_TIME_UNIT_TYPE),
+        placeholder: '璇烽�夋嫨',
+      },
+      rules: z.string().default('MINUTE'),
+    },
+    {
+      fieldName: 'remark',
+      label: '澶囨敞',
+      component: 'Textarea',
+      formItemClass: 'col-span-2',
+      componentProps: {
+        maxLength: 250,
+        placeholder: '璇疯緭鍏ュ娉�',
+        rows: 2,
+      },
+    },
+  ];
+}
+
+/** 宸ヨ壓璺嚎浜у搧 BOM 琛ㄥ崟 */
+export function useRouteProductBomFormSchema(
+  itemId: () => number,
+  onBomChange?: (bom: any) => void,
+): VbenFormSchema[] {
+  return [
+    {
+      fieldName: 'id',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'routeId',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'processId',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    {
+      fieldName: 'productId',
+      component: 'Input',
+      dependencies: { triggerFields: [''], show: () => false },
+    },
+    // BOM 鐗╂枡锛氫緷璧栦骇鍝佺墿鏂欙紝浣跨敤涓氬姟鑷畾涔夐�夋嫨鍣�
+    {
+      fieldName: 'itemId',
+      label: 'BOM 鐗╂枡',
+      component: markRaw(MdProductBomSelect),
+      componentProps: () => ({
+        itemId: itemId(),
+        onChange: onBomChange,
+        placeholder: '璇烽�夋嫨 BOM 鐗╂枡',
+      }),
+      rules: 'selectRequired',
+    },
+    {
+      fieldName: 'quantity',
+      label: '鐢ㄦ枡姣斾緥',
+      component: 'InputNumber',
+      componentProps: {
+        class: '!w-full',
+        min: 0,
+        precision: 2,
+      },
+      rules: z.number().default(1),
+    },
+    {
+      fieldName: 'remark',
+      label: '澶囨敞',
+      component: 'Textarea',
+      componentProps: {
+        maxLength: 250,
+        placeholder: '璇疯緭鍏ュ娉�',
+        rows: 2,
+      },
+    },
+  ];
+}

--
Gitblit v1.9.3