| | |
| | | import { z } from '#/adapter/form'; |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { getTemplatePage } from '#/api/mes/pro/processdesign/template'; |
| | | import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse'; |
| | | import { getWarehouseAreaSimpleList } from '#/api/mes/wm/warehouse/area'; |
| | | import { getWarehouseLocationSimpleList } from '#/api/mes/wm/warehouse/location'; |
| | | import { |
| | | MdItemSelect, |
| | | MdProductBomSelect, |
| | | } from '#/views/mes/md/item/components'; |
| | | |
| | | import { RouteColorPicker } from './components'; |
| | | import { RouteColorPicker, RouteOutputAttribution } from './components'; |
| | | |
| | | /** 表单类型 */ |
| | | export type FormType = 'create' | 'detail' | 'update'; |
| | |
| | | field: 'createTime', |
| | | title: '创建时间', |
| | | width: 180, |
| | | formatter: 'formatDate', |
| | | formatter: 'formatDateTime', |
| | | }, |
| | | { |
| | | title: '操作', |
| | |
| | | /** 工艺路线工序明细表单 */ |
| | | export function useRouteProcessFormSchema( |
| | | processOptions: Array<{ label: string; value: number }>, |
| | | products: MesProRouteProductApi.RouteProduct[] = [], |
| | | ): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | |
| | | }, |
| | | { |
| | | fieldName: 'yieldRate', |
| | | label: '收率', |
| | | label: '工序收率', |
| | | component: 'InputNumber', |
| | | help: '产出量 ÷ 投入量;未填写按 100% 参与排产计算。', |
| | | componentProps: { |
| | | class: '!w-full', |
| | | min: 0.0001, |
| | | max: 1, |
| | | step: 0.01, |
| | | precision: 4, |
| | | placeholder: '产出/投入,如 0.98', |
| | | placeholder: '如 0.98(98%)', |
| | | }, |
| | | rules: z.number().min(0.0001).max(1).nullish(), |
| | | }, |
| | | { |
| | | fieldName: 'outputs', |
| | | label: '本工序产出', |
| | | component: markRaw(RouteOutputAttribution), |
| | | componentProps: { |
| | | products, |
| | | }, |
| | | formItemClass: 'col-span-2', |
| | | }, |
| | | { |
| | | fieldName: 'linkType', |
| | | label: '与下道工序关系', |
| | | component: 'Select', |
| | | help: () => |
| | | h( |
| | | 'div', |
| | | { |
| | | style: |
| | | 'white-space: pre-line; max-width: 320px; line-height: 1.6;', |
| | | }, |
| | | '0=开始-开始(SS):本工序开始后,下道工序才能开始(可重叠并行开工)\n1=结束-结束(FF):下道工序必须等到本工序结束才能结束(并行但同步完工)\n2=开始-结束(SF):本工序开始后,下道工序才能结束\n3=结束-开始(FS):本工序结束后,下道工序才能开始(默认值)', |
| | | ), |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.MES_PRO_LINK_TYPE, 'number'), |
| | | placeholder: '请选择', |
| | | }, |
| | | rules: z.number().optional(), |
| | | rules: z.number().default(3), |
| | | }, |
| | | { |
| | | fieldName: 'colorCode', |
| | |
| | | componentProps: { |
| | | checkedChildren: '是', |
| | | unCheckedChildren: '否', |
| | | }, |
| | | rules: z.boolean().default(false), |
| | | }, |
| | | { |
| | | fieldName: 'backflushFlag', |
| | | label: '报工自动扣料', |
| | | component: 'Switch', |
| | | componentProps: { |
| | | checkedChildren: '自动', |
| | | unCheckedChildren: '手动', |
| | | }, |
| | | rules: z.boolean().default(false), |
| | | }, |
| | |
| | | { field: 'sort', title: '序号', width: 70, align: 'center', fixed: 'left' }, |
| | | { field: 'processCode', title: '工序编码', width: 140, fixed: 'left' }, |
| | | { field: 'processName', title: '工序名称', width: 140, fixed: 'left' }, |
| | | { |
| | | field: 'outputItemNames', |
| | | title: '本工序产出', |
| | | minWidth: 240, |
| | | formatter: ({ cellValue, row }) => { |
| | | const outputs = row.outputs ?? []; |
| | | if (!outputs.length) { |
| | | return cellValue ?? ''; |
| | | } |
| | | return outputs |
| | | .map((output) => { |
| | | const name = output.itemName ?? output.itemCode ?? output.itemId; |
| | | return output.productId == null |
| | | ? `${name}(通用)` |
| | | : `${name}(${output.productName ?? output.productId})`; |
| | | }) |
| | | .join('、'); |
| | | }, |
| | | }, |
| | | { field: 'nextProcessName', title: '下一道工序', width: 140 }, |
| | | { |
| | | field: 'linkType', |
| | |
| | | props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, |
| | | }, |
| | | }, |
| | | { |
| | | field: 'backflushFlag', |
| | | title: '自动扣料', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING }, |
| | | }, |
| | | }, |
| | | { field: 'prepareTime', title: '准备时间(分)', width: 110 }, |
| | | { field: 'waitTime', title: '等待时间(分)', width: 110 }, |
| | | { |
| | |
| | | /** 工艺路线产品列表字段 */ |
| | | export function useRouteProductGridColumns(): VxeTableGridOptions<MesProRouteProductApi.RouteProduct>['columns'] { |
| | | return [ |
| | | { field: 'itemCode', title: '产品物料编码', width: 150 }, |
| | | { field: 'itemName', title: '产品物料名称', width: 150 }, |
| | | { 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: 'warehouseName', title: '报工入库仓', width: 140 }, |
| | | { field: 'locationName', title: '入库库区', width: 120 }, |
| | | { field: 'areaName', title: '入库库位', width: 120 }, |
| | | { |
| | | field: 'productionTime', |
| | | title: '生产用时', |
| | |
| | | /** 工艺路线产品 BOM 列表字段 */ |
| | | export function useRouteProductBomGridColumns(): VxeTableGridOptions<MesProRouteProductBomApi.RouteProductBom>['columns'] { |
| | | return [ |
| | | { field: 'itemCode', title: 'BOM 物料编码', width: 150 }, |
| | | { field: 'itemName', title: 'BOM 物料名称', width: 150 }, |
| | | { 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 }, |
| | |
| | | /** 工艺路线产品表单 */ |
| | | export function useRouteProductFormSchema( |
| | | onItemChange?: (item: any) => void, |
| | | getFormApi?: () => VbenFormApi, |
| | | ): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | |
| | | // 产品物料:使用业务自定义选择器,change 回填编码/名称/规格/单位 |
| | | { |
| | | fieldName: 'itemId', |
| | | label: '产品', |
| | | label: '产出物料', |
| | | component: markRaw(MdItemSelect), |
| | | componentProps: { |
| | | onChange: onItemChange, |
| | | }, |
| | | help: '可选择主数据类型为成品或半成品的物料,也兼容 MES 成品/半成品分类;已有路线产品可继续修改仓位。', |
| | | formItemClass: 'col-span-2', |
| | | rules: 'selectRequired', |
| | | }, |
| | |
| | | rules: z.number().default(1), |
| | | }, |
| | | { |
| | | fieldName: 'warehouseId', |
| | | label: '报工仓库', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | api: getWarehouseSimpleList, |
| | | labelField: 'name', |
| | | valueField: 'id', |
| | | placeholder: '请选择报工产出仓库', |
| | | onChange: async () => { |
| | | await getFormApi?.().setFieldValue('locationId', undefined); |
| | | await getFormApi?.().setFieldValue('areaId', undefined); |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'locationId', |
| | | label: '报工库区', |
| | | component: 'Select', |
| | | dependencies: { |
| | | triggerFields: ['warehouseId'], |
| | | disabled: (values) => !values.warehouseId, |
| | | async componentProps(values) { |
| | | const options = values.warehouseId |
| | | ? await getWarehouseLocationSimpleList(values.warehouseId) |
| | | : []; |
| | | return { |
| | | fieldNames: { label: 'name', value: 'id' }, |
| | | options, |
| | | placeholder: '请选择报工产出库区', |
| | | onChange: async () => getFormApi?.().setFieldValue('areaId', undefined), |
| | | }; |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'areaId', |
| | | label: '报工库位', |
| | | component: 'Select', |
| | | dependencies: { |
| | | triggerFields: ['locationId'], |
| | | disabled: (values) => !values.locationId, |
| | | async componentProps(values) { |
| | | const options = values.locationId |
| | | ? await getWarehouseAreaSimpleList(values.locationId) |
| | | : []; |
| | | return { |
| | | fieldNames: { label: 'name', value: 'id' }, |
| | | options, |
| | | placeholder: '请选择报工产出库位', |
| | | }; |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'productionTime', |
| | | label: '生产用时', |
| | | component: 'InputNumber', |