From 01a1d3e0014764ad1395825506f2e3d112d0b5f5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 25 May 2026 09:09:14 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feat(mes)=EF=BC=9A=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=AE=9A=E4=B9=89=EF=BC=88pro=5Fprocess?= =?UTF-8?q?=EF=BC=89=E3=80=81=E5=B7=A5=E8=89=BA=E8=B7=AF=E7=BA=BF=EF=BC=88?= =?UTF-8?q?pro=5Froute=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/mes/pro/process/content/index.ts | 49 +++ apps/web-antd/src/api/mes/pro/route/index.ts | 65 ++++ .../src/api/mes/pro/route/process/index.ts | 70 ++++ .../src/api/mes/pro/route/product/index.ts | 48 +++ .../src/api/mes/pro/route/productbom/index.ts | 57 +++ .../src/views/mes/pro/process/data.ts | 272 ++++++++++++++ .../src/views/mes/pro/process/index.vue | 158 ++++++++ .../mes/pro/process/modules/content-form.vue | 99 +++++ .../mes/pro/process/modules/content-list.vue | 132 +++++++ .../views/mes/pro/process/modules/form.vue | 117 ++++++ apps/web-antd/src/views/mes/pro/route/data.ts | 335 +++++++++++++++++ .../src/views/mes/pro/route/index.vue | 198 ++++++++++ .../src/views/mes/pro/route/modules/form.vue | 122 ++++++ .../mes/pro/route/modules/process-form.vue | 113 ++++++ .../mes/pro/route/modules/process-list.vue | 133 +++++++ .../pro/route/modules/product-bom-list.vue | 265 +++++++++++++ .../mes/pro/route/modules/product-form.vue | 193 ++++++++++ .../mes/pro/route/modules/product-list.vue | 128 +++++++ .../src/api/mes/pro/process/content/index.ts | 49 +++ apps/web-ele/src/api/mes/pro/route/index.ts | 65 ++++ .../src/api/mes/pro/route/process/index.ts | 70 ++++ .../src/api/mes/pro/route/product/index.ts | 48 +++ .../src/api/mes/pro/route/productbom/index.ts | 57 +++ .../web-ele/src/views/mes/pro/process/data.ts | 271 ++++++++++++++ .../src/views/mes/pro/process/index.vue | 160 ++++++++ .../mes/pro/process/modules/content-form.vue | 99 +++++ .../mes/pro/process/modules/content-list.vue | 133 +++++++ .../views/mes/pro/process/modules/form.vue | 117 ++++++ apps/web-ele/src/views/mes/pro/route/data.ts | 350 ++++++++++++++++++ .../web-ele/src/views/mes/pro/route/index.vue | 195 ++++++++++ .../src/views/mes/pro/route/modules/form.vue | 118 ++++++ .../mes/pro/route/modules/process-form.vue | 112 ++++++ .../mes/pro/route/modules/process-list.vue | 136 +++++++ .../pro/route/modules/product-bom-list.vue | 278 ++++++++++++++ .../mes/pro/route/modules/product-form.vue | 198 ++++++++++ .../mes/pro/route/modules/product-list.vue | 131 +++++++ 36 files changed, 5141 insertions(+) create mode 100644 apps/web-antd/src/api/mes/pro/process/content/index.ts create mode 100644 apps/web-antd/src/api/mes/pro/route/index.ts create mode 100644 apps/web-antd/src/api/mes/pro/route/process/index.ts create mode 100644 apps/web-antd/src/api/mes/pro/route/product/index.ts create mode 100644 apps/web-antd/src/api/mes/pro/route/productbom/index.ts create mode 100644 apps/web-antd/src/views/mes/pro/process/data.ts create mode 100644 apps/web-antd/src/views/mes/pro/process/index.vue create mode 100644 apps/web-antd/src/views/mes/pro/process/modules/content-form.vue create mode 100644 apps/web-antd/src/views/mes/pro/process/modules/content-list.vue create mode 100644 apps/web-antd/src/views/mes/pro/process/modules/form.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/data.ts create mode 100644 apps/web-antd/src/views/mes/pro/route/index.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/form.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/process-form.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/process-list.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/product-bom-list.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/product-form.vue create mode 100644 apps/web-antd/src/views/mes/pro/route/modules/product-list.vue create mode 100644 apps/web-ele/src/api/mes/pro/process/content/index.ts create mode 100644 apps/web-ele/src/api/mes/pro/route/index.ts create mode 100644 apps/web-ele/src/api/mes/pro/route/process/index.ts create mode 100644 apps/web-ele/src/api/mes/pro/route/product/index.ts create mode 100644 apps/web-ele/src/api/mes/pro/route/productbom/index.ts create mode 100644 apps/web-ele/src/views/mes/pro/process/data.ts create mode 100644 apps/web-ele/src/views/mes/pro/process/index.vue create mode 100644 apps/web-ele/src/views/mes/pro/process/modules/content-form.vue create mode 100644 apps/web-ele/src/views/mes/pro/process/modules/content-list.vue create mode 100644 apps/web-ele/src/views/mes/pro/process/modules/form.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/data.ts create mode 100644 apps/web-ele/src/views/mes/pro/route/index.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/form.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/process-form.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/process-list.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/product-bom-list.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/product-form.vue create mode 100644 apps/web-ele/src/views/mes/pro/route/modules/product-list.vue diff --git a/apps/web-antd/src/api/mes/pro/process/content/index.ts b/apps/web-antd/src/api/mes/pro/process/content/index.ts new file mode 100644 index 000000000..8a4c15e59 --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/process/content/index.ts @@ -0,0 +1,49 @@ +import { requestClient } from '#/api/request'; + +export namespace MesProProcessContentApi { + /** MES 生产工序内容(操作步骤) */ + export interface ProcessContent { + id?: number; + processId?: number; + sort?: number; + content?: string; + device?: string; + material?: string; + docUrl?: string; + remark?: string; + createTime?: Date; + } +} + +/** 按工序编号查询工序内容列表 */ +export function getProcessContentListByProcessId(processId: number) { + return requestClient.get( + `/mes/pro/process-content/list-by-process?processId=${processId}`, + ); +} + +/** 查询工序内容详情 */ +export function getProcessContent(id: number) { + return requestClient.get( + `/mes/pro/process-content/get?id=${id}`, + ); +} + +/** 新增工序内容 */ +export function createProcessContent( + data: MesProProcessContentApi.ProcessContent, +) { + return requestClient.post('/mes/pro/process-content/create', data); +} + +/** 修改工序内容 */ +export function updateProcessContent( + data: MesProProcessContentApi.ProcessContent, +) { + return requestClient.put('/mes/pro/process-content/update', data); +} + +/** 删除工序内容 */ +export function deleteProcessContent(id: number) { + return requestClient.delete(`/mes/pro/process-content/delete?id=${id}`); +} diff --git a/apps/web-antd/src/api/mes/pro/route/index.ts b/apps/web-antd/src/api/mes/pro/route/index.ts new file mode 100644 index 000000000..56baff6b5 --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/route/index.ts @@ -0,0 +1,65 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesProRouteApi { + /** MES 工艺路线 */ + export interface Route { + id?: number; + code?: string; + name?: string; + description?: string; + status?: number; + remark?: string; + createTime?: Date; + } +} + +/** 查询工艺路线分页 */ +export function getRoutePage(params: PageParam) { + return requestClient.get>( + '/mes/pro/route/page', + { params }, + ); +} + +/** 查询工艺路线精简列表 */ +export function getRouteSimpleList() { + return requestClient.get( + '/mes/pro/route/simple-list', + ); +} + +/** 查询工艺路线详情 */ +export function getRoute(id: number) { + return requestClient.get( + `/mes/pro/route/get?id=${id}`, + ); +} + +/** 新增工艺路线 */ +export function createRoute(data: MesProRouteApi.Route) { + return requestClient.post('/mes/pro/route/create', data); +} + +/** 修改工艺路线 */ +export function updateRoute(data: MesProRouteApi.Route) { + return requestClient.put('/mes/pro/route/update', data); +} + +/** 修改工艺路线状态 */ +export function updateRouteStatus(id: number, status: number) { + return requestClient.put( + `/mes/pro/route/update-status?id=${id}&status=${status}`, + ); +} + +/** 删除工艺路线 */ +export function deleteRoute(id: number) { + return requestClient.delete(`/mes/pro/route/delete?id=${id}`); +} + +/** 导出工艺路线 Excel */ +export function exportRoute(params: any) { + return requestClient.download('/mes/pro/route/export-excel', { params }); +} diff --git a/apps/web-antd/src/api/mes/pro/route/process/index.ts b/apps/web-antd/src/api/mes/pro/route/process/index.ts new file mode 100644 index 000000000..fee0ce9c4 --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/route/process/index.ts @@ -0,0 +1,70 @@ +import { requestClient } from '#/api/request'; + +export namespace MesProRouteProcessApi { + /** MES 工艺路线工序 */ + export interface RouteProcess { + id?: number; + routeId?: number; + processId?: number; + processCode?: string; + processName?: string; + sort?: number; + nextProcessId?: number; + nextProcessName?: string; + linkType?: number; + prepareTime?: number; + waitTime?: number; + colorCode?: string; + keyFlag?: boolean; + checkFlag?: boolean; + remark?: string; + createTime?: Date; + } +} + +/** 按工艺路线查询工序列表 */ +export function getRouteProcessListByRoute(routeId: number) { + return requestClient.get( + `/mes/pro/route-process/list-by-route?routeId=${routeId}`, + ); +} + +/** 按产品查询工序列表(自动查找关联的工艺路线) */ +export function getRouteProcessListByProduct(productId: number) { + return requestClient.get( + `/mes/pro/route-process/list-by-product?productId=${productId}`, + ); +} + +/** 查询工艺路线工序详情 */ +export function getRouteProcess(id: number) { + return requestClient.get( + `/mes/pro/route-process/get?id=${id}`, + ); +} + +/** 按工艺路线 + 工序精确查询工序配置 */ +export function getRouteProcessByRouteAndProcess( + routeId: number, + processId: number, +) { + return requestClient.get( + '/mes/pro/route-process/get-by-route-and-process', + { params: { processId, routeId } }, + ); +} + +/** 新增工艺路线工序 */ +export function createRouteProcess(data: MesProRouteProcessApi.RouteProcess) { + return requestClient.post('/mes/pro/route-process/create', data); +} + +/** 修改工艺路线工序 */ +export function updateRouteProcess(data: MesProRouteProcessApi.RouteProcess) { + return requestClient.put('/mes/pro/route-process/update', data); +} + +/** 删除工艺路线工序 */ +export function deleteRouteProcess(id: number) { + return requestClient.delete(`/mes/pro/route-process/delete?id=${id}`); +} diff --git a/apps/web-antd/src/api/mes/pro/route/product/index.ts b/apps/web-antd/src/api/mes/pro/route/product/index.ts new file mode 100644 index 000000000..2312f688c --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/route/product/index.ts @@ -0,0 +1,48 @@ +import { requestClient } from '#/api/request'; + +export namespace MesProRouteProductApi { + /** MES 工艺路线产品 */ + export interface RouteProduct { + id?: number; + routeId?: number; + itemId?: number; + itemCode?: string; + itemName?: string; + specification?: string; + unitName?: string; + quantity?: number; + productionTime?: number; + timeUnitType?: string; + remark?: string; + createTime?: Date; + } +} + +/** 按工艺路线查询产品列表 */ +export function getRouteProductListByRoute(routeId: number) { + return requestClient.get( + `/mes/pro/route-product/list-by-route?routeId=${routeId}`, + ); +} + +/** 查询工艺路线产品详情 */ +export function getRouteProduct(id: number) { + return requestClient.get( + `/mes/pro/route-product/get?id=${id}`, + ); +} + +/** 新增工艺路线产品 */ +export function createRouteProduct(data: MesProRouteProductApi.RouteProduct) { + return requestClient.post('/mes/pro/route-product/create', data); +} + +/** 修改工艺路线产品 */ +export function updateRouteProduct(data: MesProRouteProductApi.RouteProduct) { + return requestClient.put('/mes/pro/route-product/update', data); +} + +/** 删除工艺路线产品 */ +export function deleteRouteProduct(id: number) { + return requestClient.delete(`/mes/pro/route-product/delete?id=${id}`); +} diff --git a/apps/web-antd/src/api/mes/pro/route/productbom/index.ts b/apps/web-antd/src/api/mes/pro/route/productbom/index.ts new file mode 100644 index 000000000..7cfcbcc85 --- /dev/null +++ b/apps/web-antd/src/api/mes/pro/route/productbom/index.ts @@ -0,0 +1,57 @@ +import { requestClient } from '#/api/request'; + +export namespace MesProRouteProductBomApi { + /** MES 工艺路线产品 BOM */ + export interface RouteProductBom { + id?: number; + routeId?: number; + processId?: number; + productId?: number; + itemId?: number; + itemCode?: string; + itemName?: string; + specification?: string; + unitName?: string; + quantity?: number; + remark?: string; + createTime?: Date; + } +} + +/** 查询工艺路线产品 BOM 列表 */ +export function getRouteProductBomList(params: { + processId?: number; + productId?: number; + routeId: number; +}) { + return requestClient.get( + '/mes/pro/route-product-bom/list', + { params }, + ); +} + +/** 查询工艺路线产品 BOM 详情 */ +export function getRouteProductBom(id: number) { + return requestClient.get( + `/mes/pro/route-product-bom/get?id=${id}`, + ); +} + +/** 新增工艺路线产品 BOM */ +export function createRouteProductBom( + data: MesProRouteProductBomApi.RouteProductBom, +) { + return requestClient.post('/mes/pro/route-product-bom/create', data); +} + +/** 修改工艺路线产品 BOM */ +export function updateRouteProductBom( + data: MesProRouteProductBomApi.RouteProductBom, +) { + return requestClient.put('/mes/pro/route-product-bom/update', data); +} + +/** 删除工艺路线产品 BOM */ +export function deleteRouteProductBom(id: number) { + return requestClient.delete(`/mes/pro/route-product-bom/delete?id=${id}`); +} diff --git a/apps/web-antd/src/views/mes/pro/process/data.ts b/apps/web-antd/src/views/mes/pro/process/data.ts new file mode 100644 index 000000000..ff8089acd --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/process/data.ts @@ -0,0 +1,272 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesProProcessApi } from '#/api/mes/pro/process'; +import type { MesProProcessContentApi } from '#/api/mes/pro/process/content'; + +import { h } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { Button } from 'ant-design-vue'; + +import { z } from '#/adapter/form'; +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 新增/修改生产工序的表单 */ +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 () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.PRO_PROCESS_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '生成' }, + ), + }, + { + fieldName: 'name', + label: '工序名称', + component: 'Input', + componentProps: { + maxLength: 100, + placeholder: '请输入工序名称', + }, + rules: z.string().min(1, '工序名称不能为空').max(100), + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + optionType: 'button', + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'attention', + label: '工序说明', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + maxLength: 500, + placeholder: '请输入工序说明', + rows: 3, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + maxLength: 250, + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +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(): VxeTableGridOptions['columns'] { + return [ + { + field: 'code', + title: '工序编码', + minWidth: 150, + slots: { + default: 'code', + }, + }, + { field: 'name', title: '工序名称', minWidth: 180 }, + { + field: 'status', + title: '状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { field: 'remark', title: '备注', minWidth: 180 }, + { + field: 'createTime', + title: '创建时间', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 150, + fixed: 'right', + slots: { + default: 'actions', + }, + }, + ]; +} + +/** 工序内容(操作步骤)表单 */ +export function useContentFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'processId', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'sort', + label: '序号', + component: 'InputNumber', + componentProps: { + class: '!w-full', + max: 999, + min: 1, + precision: 0, + }, + rules: z.number().default(1), + }, + { + fieldName: 'content', + label: '步骤说明', + component: 'Textarea', + componentProps: { + maxLength: 500, + placeholder: '请输入步骤说明', + rows: 3, + }, + }, + { + fieldName: 'device', + label: '辅助设备', + component: 'Input', + componentProps: { + maxLength: 100, + placeholder: '请输入辅助设备', + }, + }, + { + fieldName: 'material', + label: '辅助材料', + component: 'Input', + componentProps: { + maxLength: 100, + placeholder: '请输入辅助材料', + }, + }, + { + fieldName: 'docUrl', + label: '材料文档 URL', + component: 'Input', + componentProps: { + maxLength: 250, + placeholder: '请输入材料文档 URL', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + maxLength: 250, + placeholder: '请输入备注', + rows: 2, + }, + }, + ]; +} + +/** 工序内容列表的字段 */ +export function useContentGridColumns(): VxeTableGridOptions['columns'] { + return [ + { field: 'sort', title: '序号', width: 80, align: 'center' }, + { field: 'content', title: '步骤说明', minWidth: 220 }, + { field: 'device', title: '辅助设备', width: 150 }, + { field: 'material', title: '辅助材料', width: 150 }, + { field: 'docUrl', title: '材料文档', minWidth: 180 }, + { field: 'remark', title: '备注', minWidth: 160 }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/pro/process/index.vue b/apps/web-antd/src/views/mes/pro/process/index.vue new file mode 100644 index 000000000..dcd291410 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/process/index.vue @@ -0,0 +1,158 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/process/modules/content-form.vue b/apps/web-antd/src/views/mes/pro/process/modules/content-form.vue new file mode 100644 index 000000000..eb4270b25 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/process/modules/content-form.vue @@ -0,0 +1,99 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/process/modules/content-list.vue b/apps/web-antd/src/views/mes/pro/process/modules/content-list.vue new file mode 100644 index 000000000..b54968069 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/process/modules/content-list.vue @@ -0,0 +1,132 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/process/modules/form.vue b/apps/web-antd/src/views/mes/pro/process/modules/form.vue new file mode 100644 index 000000000..247ec05a7 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/process/modules/form.vue @@ -0,0 +1,117 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/route/data.ts b/apps/web-antd/src/views/mes/pro/route/data.ts new file mode 100644 index 000000000..f7565ce9f --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/data.ts @@ -0,0 +1,335 @@ +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 } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { Button } from 'ant-design-vue'; + +import { z } from '#/adapter/form'; +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 工艺路线表单 */ +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 () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.PRO_ROUTE_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { 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(): VxeTableGridOptions['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, + slots: { default: 'status' }, + }, + { 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: 'Input', + componentProps: { + maxLength: 16, + placeholder: '请输入颜色 hex,例如 #00AEF3', + }, + }, + { + 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['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['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['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' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/pro/route/index.vue b/apps/web-antd/src/views/mes/pro/route/index.vue new file mode 100644 index 000000000..cdfc72f71 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/index.vue @@ -0,0 +1,198 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/route/modules/form.vue b/apps/web-antd/src/views/mes/pro/route/modules/form.vue new file mode 100644 index 000000000..baf0d7921 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/modules/form.vue @@ -0,0 +1,122 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/route/modules/process-form.vue b/apps/web-antd/src/views/mes/pro/route/modules/process-form.vue new file mode 100644 index 000000000..5b1411c9b --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/modules/process-form.vue @@ -0,0 +1,113 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/route/modules/process-list.vue b/apps/web-antd/src/views/mes/pro/route/modules/process-list.vue new file mode 100644 index 000000000..31b2dad8c --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/modules/process-list.vue @@ -0,0 +1,133 @@ + + + diff --git a/apps/web-antd/src/views/mes/pro/route/modules/product-bom-list.vue b/apps/web-antd/src/views/mes/pro/route/modules/product-bom-list.vue new file mode 100644 index 000000000..e9f66f9b5 --- /dev/null +++ b/apps/web-antd/src/views/mes/pro/route/modules/product-bom-list.vue @@ -0,0 +1,265 @@ + + +