diff --git a/apps/web-antd/src/api/mes/md/client/index.ts b/apps/web-antd/src/api/mes/md/client/index.ts new file mode 100644 index 000000000..9be868d69 --- /dev/null +++ b/apps/web-antd/src/api/mes/md/client/index.ts @@ -0,0 +1,86 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdClientApi { + /** MES 客户 */ + export interface Client { + id?: number; // 客户编号 + code?: string; // 客户编码 + name?: string; // 客户名称 + nickname?: string; // 客户简称 + englishName?: string; // 客户英文名称 + description?: string; // 客户简介 + logo?: string; // 客户 LOGO 地址 + type?: number; // 客户类型 + address?: string; // 客户地址 + website?: string; // 客户官网地址 + email?: string; // 客户邮箱地址 + telephone?: string; // 客户电话 + contact1Name?: string; // 联系人1 + contact1Telephone?: string; // 联系人1电话 + contact1Email?: string; // 联系人1邮箱 + contact2Name?: string; // 联系人2 + contact2Telephone?: string; // 联系人2电话 + contact2Email?: string; // 联系人2邮箱 + creditCode?: string; // 统一社会信用代码 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } + + /** 客户导入结果 */ + export interface ClientImportRespVO { + createCodes?: string[]; // 新增成功的客户编码 + updateCodes?: string[]; // 更新成功的客户编码 + failureCodes?: Record; // 导入失败的客户编码及原因 + } +} + +/** 查询客户分页 */ +export function getClientPage(params: PageParam) { + return requestClient.get>( + '/mes/md-client/page', + { params }, + ); +} + +/** 查询客户详情 */ +export function getClient(id: number) { + return requestClient.get( + `/mes/md-client/get?id=${id}`, + ); +} + +/** 新增客户 */ +export function createClient(data: MesMdClientApi.Client) { + return requestClient.post('/mes/md-client/create', data); +} + +/** 修改客户 */ +export function updateClient(data: MesMdClientApi.Client) { + return requestClient.put('/mes/md-client/update', data); +} + +/** 删除客户 */ +export function deleteClient(id: number) { + return requestClient.delete(`/mes/md-client/delete?id=${id}`); +} + +/** 导出客户 */ +export function exportClient(params: any) { + return requestClient.download('/mes/md-client/export-excel', { params }); +} + +/** 下载客户导入模板 */ +export function importClientTemplate() { + return requestClient.download('/mes/md-client/get-import-template'); +} + +/** 导入客户 */ +export function importClient(file: File, updateSupport: boolean) { + return requestClient.upload( + `/mes/md-client/import?updateSupport=${updateSupport}`, + { file }, + ); +} diff --git a/apps/web-antd/src/api/mes/md/vendor/index.ts b/apps/web-antd/src/api/mes/md/vendor/index.ts new file mode 100644 index 000000000..e64845f53 --- /dev/null +++ b/apps/web-antd/src/api/mes/md/vendor/index.ts @@ -0,0 +1,87 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdVendorApi { + /** MES 供应商 */ + export interface Vendor { + id?: number; // 供应商编号 + code?: string; // 供应商编码 + name?: string; // 供应商名称 + nickname?: string; // 供应商简称 + englishName?: string; // 供应商英文名称 + description?: string; // 供应商简介 + logo?: string; // 供应商 LOGO 地址 + level?: string; // 供应商等级 + score?: number; // 供应商评分 + address?: string; // 供应商地址 + website?: string; // 供应商官网地址 + email?: string; // 供应商邮箱地址 + telephone?: string; // 供应商电话 + contact1Name?: string; // 联系人1 + contact1Telephone?: string; // 联系人1电话 + contact1Email?: string; // 联系人1邮箱 + contact2Name?: string; // 联系人2 + contact2Telephone?: string; // 联系人2电话 + contact2Email?: string; // 联系人2邮箱 + creditCode?: string; // 统一社会信用代码 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } + + /** 供应商导入结果 */ + export interface VendorImportRespVO { + createCodes?: string[]; // 新增成功的供应商编码 + updateCodes?: string[]; // 更新成功的供应商编码 + failureCodes?: Record; // 导入失败的供应商编码及原因 + } +} + +/** 查询供应商分页 */ +export function getVendorPage(params: PageParam) { + return requestClient.get>( + '/mes/md-vendor/page', + { params }, + ); +} + +/** 查询供应商详情 */ +export function getVendor(id: number) { + return requestClient.get( + `/mes/md-vendor/get?id=${id}`, + ); +} + +/** 新增供应商 */ +export function createVendor(data: MesMdVendorApi.Vendor) { + return requestClient.post('/mes/md-vendor/create', data); +} + +/** 修改供应商 */ +export function updateVendor(data: MesMdVendorApi.Vendor) { + return requestClient.put('/mes/md-vendor/update', data); +} + +/** 删除供应商 */ +export function deleteVendor(id: number) { + return requestClient.delete(`/mes/md-vendor/delete?id=${id}`); +} + +/** 导出供应商 */ +export function exportVendor(params: any) { + return requestClient.download('/mes/md-vendor/export-excel', { params }); +} + +/** 下载供应商导入模板 */ +export function importVendorTemplate() { + return requestClient.download('/mes/md-vendor/get-import-template'); +} + +/** 导入供应商 */ +export function importVendor(file: File, updateSupport: boolean) { + return requestClient.upload( + `/mes/md-vendor/import?updateSupport=${updateSupport}`, + { file }, + ); +} diff --git a/apps/web-antd/src/api/mes/md/workstation/workshop/index.ts b/apps/web-antd/src/api/mes/md/workstation/workshop/index.ts new file mode 100644 index 000000000..5a96399c9 --- /dev/null +++ b/apps/web-antd/src/api/mes/md/workstation/workshop/index.ts @@ -0,0 +1,60 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdWorkshopApi { + /** MES 车间 */ + export interface Workshop { + id?: number; // 车间编号 + code?: string; // 车间编码 + name?: string; // 车间名称 + area?: number; // 面积 + chargeUserId?: number; // 负责人用户编号 + chargeUserName?: string; // 负责人名称 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } +} + +/** 查询车间分页 */ +export function getWorkshopPage(params: PageParam) { + return requestClient.get>( + '/mes/md-workshop/page', + { params }, + ); +} + +/** 查询车间精简列表 */ +export function getWorkshopSimpleList() { + return requestClient.get( + '/mes/md-workshop/simple-list', + ); +} + +/** 查询车间详情 */ +export function getWorkshop(id: number) { + return requestClient.get( + `/mes/md-workshop/get?id=${id}`, + ); +} + +/** 新增车间 */ +export function createWorkshop(data: MesMdWorkshopApi.Workshop) { + return requestClient.post('/mes/md-workshop/create', data); +} + +/** 修改车间 */ +export function updateWorkshop(data: MesMdWorkshopApi.Workshop) { + return requestClient.put('/mes/md-workshop/update', data); +} + +/** 删除车间 */ +export function deleteWorkshop(id: number) { + return requestClient.delete(`/mes/md-workshop/delete?id=${id}`); +} + +/** 导出车间 */ +export function exportWorkshop(params: any) { + return requestClient.download('/mes/md-workshop/export-excel', { params }); +} diff --git a/apps/web-antd/src/api/mes/wm/itemreceipt/line/index.ts b/apps/web-antd/src/api/mes/wm/itemreceipt/line/index.ts new file mode 100644 index 000000000..55562e84c --- /dev/null +++ b/apps/web-antd/src/api/mes/wm/itemreceipt/line/index.ts @@ -0,0 +1,28 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmItemReceiptLineApi { + /** MES 物料接收单行 */ + export interface ItemReceiptLine { + id?: number; // 行编号 + receiptId?: number; // 入库单编号 + receiptCode?: string; // 入库单编码 + purchaseOrderCode?: string; // 采购订单号 + itemId?: number; // 物料编号 + itemCode?: string; // 物料编码 + itemName?: string; // 物料名称 + specification?: string; // 规格型号 + unitMeasureName?: string; // 单位 + receivedQuantity?: number; // 入库数量 + batchCode?: string; // 批次号 + } +} + +/** 查询物料接收单行分页 */ +export function getItemReceiptLinePage(params: PageParam) { + return requestClient.get>( + '/mes/wm/item-receipt-line/page', + { params }, + ); +} diff --git a/apps/web-antd/src/api/mes/wm/productsales/index.ts b/apps/web-antd/src/api/mes/wm/productsales/index.ts new file mode 100644 index 000000000..aa00d4556 --- /dev/null +++ b/apps/web-antd/src/api/mes/wm/productsales/index.ts @@ -0,0 +1,23 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmProductSalesApi { + /** MES 销售出库单 */ + export interface ProductSales { + id?: number; // 销售出库单编号 + code?: string; // 出库单编号 + name?: string; // 出库单名称 + salesOrderCode?: string; // 销售订单编号 + salesDate?: Date; // 出库日期 + status?: number; // 单据状态 + } +} + +/** 查询销售出库单分页 */ +export function getProductSalesPage(params: PageParam) { + return requestClient.get>( + '/mes/wm/product-sales/page', + { params }, + ); +} diff --git a/apps/web-antd/src/api/mes/wm/productsales/line/index.ts b/apps/web-antd/src/api/mes/wm/productsales/line/index.ts new file mode 100644 index 000000000..b66ef6ba7 --- /dev/null +++ b/apps/web-antd/src/api/mes/wm/productsales/line/index.ts @@ -0,0 +1,24 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmProductSalesLineApi { + /** MES 销售出库单行 */ + export interface ProductSalesLine { + id?: number; // 行编号 + itemId?: number; // 物料编号 + itemCode?: string; // 物料编码 + itemName?: string; // 物料名称 + specification?: string; // 规格型号 + unitMeasureName?: string; // 单位 + quantity?: number; // 出库数量 + batchCode?: string; // 批次号 + } +} + +/** 查询销售出库单行分页 */ +export function getProductSalesLinePage(params: PageParam) { + return requestClient.get< + PageResult + >('/mes/wm/product-sales-line/page', { params }); +} diff --git a/apps/web-antd/src/views/mes/md/client/components/md-client-select-dialog.vue b/apps/web-antd/src/views/mes/md/client/components/md-client-select-dialog.vue new file mode 100644 index 000000000..88b094580 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/components/md-client-select-dialog.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/components/md-client-select.vue b/apps/web-antd/src/views/mes/md/client/components/md-client-select.vue new file mode 100644 index 000000000..a53b3757d --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/components/md-client-select.vue @@ -0,0 +1,136 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/index.vue b/apps/web-antd/src/views/mes/md/client/index.vue new file mode 100644 index 000000000..d1d2b0b25 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/index.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/modules/form.vue b/apps/web-antd/src/views/mes/md/client/modules/form.vue new file mode 100644 index 000000000..5b4cc4fee --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/modules/form.vue @@ -0,0 +1,118 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/modules/import-form.vue b/apps/web-antd/src/views/mes/md/client/modules/import-form.vue new file mode 100644 index 000000000..05db5d089 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/modules/import-form.vue @@ -0,0 +1,101 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/modules/product-sales-line-list.vue b/apps/web-antd/src/views/mes/md/client/modules/product-sales-line-list.vue new file mode 100644 index 000000000..849d5d304 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/modules/product-sales-line-list.vue @@ -0,0 +1,75 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/client/modules/product-sales-list.vue b/apps/web-antd/src/views/mes/md/client/modules/product-sales-list.vue new file mode 100644 index 000000000..0f7b55f8c --- /dev/null +++ b/apps/web-antd/src/views/mes/md/client/modules/product-sales-list.vue @@ -0,0 +1,62 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue b/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue new file mode 100644 index 000000000..c3bcba5a9 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select.vue b/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select.vue new file mode 100644 index 000000000..5f0746bab --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/components/md-vendor-select.vue @@ -0,0 +1,136 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/data.ts b/apps/web-antd/src/views/mes/md/vendor/data.ts new file mode 100644 index 000000000..592240cb5 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/data.ts @@ -0,0 +1,473 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesMdVendorApi } from '#/api/mes/md/vendor'; + +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?: any): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + placeholder: '请输入供应商编码', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + disabled: !!values.id, + }), + }, + rules: 'required', + suffix: () => + h( + Button, + { + type: 'default', + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.MD_VENDOR_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '自动生成' }, + ), + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商名称', + }, + rules: z.string().min(1, '供应商名称不能为空').max(100), + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商英文名称', + }, + }, + { + fieldName: 'level', + label: '供应商等级', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_VENDOR_LEVEL), + placeholder: '请选择供应商等级', + }, + }, + { + fieldName: 'description', + label: '供应商简介', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入供应商简介', + rows: 2, + }, + }, + { + fieldName: 'address', + label: '供应商地址', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入供应商地址', + rows: 2, + }, + }, + { + fieldName: 'website', + label: '官网地址', + component: 'Input', + componentProps: { + placeholder: '请输入供应商官网地址', + }, + }, + { + fieldName: 'email', + label: '邮箱地址', + component: 'Input', + componentProps: { + placeholder: '请输入供应商邮箱地址', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'telephone', + label: '供应商电话', + component: 'Input', + componentProps: { + placeholder: '请输入供应商电话', + }, + }, + { + fieldName: 'score', + label: '供应商评分', + component: 'InputNumber', + componentProps: { + class: '!w-full', + max: 100, + min: 0, + precision: 0, + }, + }, + { + fieldName: 'contact1Name', + label: '联系人1', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1', + }, + }, + { + fieldName: 'contact1Telephone', + label: '联系人1电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1电话', + }, + }, + { + fieldName: 'contact1Email', + label: '联系人1邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'contact2Name', + label: '联系人2', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2', + }, + }, + { + fieldName: 'contact2Telephone', + label: '联系人2电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2电话', + }, + }, + { + fieldName: 'contact2Email', + label: '联系人2邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'creditCode', + label: '社会信用代码', + component: 'Input', + componentProps: { + placeholder: '请输入统一社会信用代码', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + optionType: 'button', + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'logo', + label: '供应商 LOGO', + component: 'Input', + componentProps: { + placeholder: '请输入供应商 LOGO 地址', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 导入供应商的表单 */ +export function useImportFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'file', + label: '供应商数据', + component: 'Upload', + rules: 'required', + help: '仅允许导入 xls、xlsx 格式文件', + }, + { + fieldName: 'updateSupport', + label: '是否覆盖', + component: 'Switch', + componentProps: { + checkedChildren: '是', + unCheckedChildren: '否', + }, + rules: z.boolean().default(false), + help: '是否更新已经存在的供应商数据', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商编码', + }, + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商名称', + }, + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + 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: 'nickname', + title: '供应商简称', + width: 120, + }, + { + field: 'level', + title: '供应商等级', + width: 130, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_VENDOR_LEVEL }, + }, + }, + { + field: 'score', + title: '供应商评分', + width: 120, + }, + { + field: 'telephone', + title: '供应商电话', + minWidth: 140, + }, + { + field: 'status', + title: '状态', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 180, + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 供应商选择弹窗的搜索表单 */ +export function useVendorSelectGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商编码', + }, + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商名称', + }, + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入英文名称', + }, + }, + ]; +} + +/** 供应商选择弹窗的字段 */ +export function useVendorSelectGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 50 }, + { + field: 'code', + title: '供应商编码', + minWidth: 160, + }, + { + field: 'name', + title: '供应商名称', + minWidth: 170, + }, + { + field: 'nickname', + title: '供应商简称', + width: 120, + }, + { + field: 'level', + title: '供应商等级', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_VENDOR_LEVEL }, + }, + }, + { + field: 'score', + title: '供应商评分', + width: 110, + }, + { + field: 'telephone', + title: '联系电话', + width: 140, + }, + { + field: 'status', + title: '状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 140, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/md/vendor/index.vue b/apps/web-antd/src/views/mes/md/vendor/index.vue new file mode 100644 index 000000000..e33be1f86 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/index.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/modules/form.vue b/apps/web-antd/src/views/mes/md/vendor/modules/form.vue new file mode 100644 index 000000000..4546b8372 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/modules/form.vue @@ -0,0 +1,118 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/modules/import-form.vue b/apps/web-antd/src/views/mes/md/vendor/modules/import-form.vue new file mode 100644 index 000000000..25fe54399 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/modules/import-form.vue @@ -0,0 +1,101 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-line-list.vue b/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-line-list.vue new file mode 100644 index 000000000..c1d536884 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-line-list.vue @@ -0,0 +1,75 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-list.vue b/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-list.vue new file mode 100644 index 000000000..86635ab07 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/vendor/modules/item-receipt-list.vue @@ -0,0 +1,49 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/workstation/workshop/data.ts b/apps/web-antd/src/views/mes/md/workstation/workshop/data.ts new file mode 100644 index 000000000..32eb95f38 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/workstation/workshop/data.ts @@ -0,0 +1,195 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesMdWorkshopApi } from '#/api/mes/md/workstation/workshop'; + +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 { getSimpleUserList } from '#/api/system/user'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 新增/修改车间的表单 */ +export function useFormSchema(formApi?: any): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '车间编码', + component: 'Input', + componentProps: { + placeholder: '请输入车间编码', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + disabled: !!values.id, + }), + }, + rules: 'required', + suffix: () => + h( + Button, + { + type: 'default', + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.MD_WORKSHOP_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '自动生成' }, + ), + }, + { + fieldName: 'name', + label: '车间名称', + component: 'Input', + componentProps: { + placeholder: '请输入车间名称', + }, + rules: 'required', + }, + { + fieldName: 'area', + label: '面积', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 0, + precision: 2, + }, + }, + { + fieldName: 'chargeUserId', + label: '负责人', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择负责人', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + optionType: 'button', + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-2', + componentProps: { + 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: 150, + }, + { + field: 'area', + title: '面积', + width: 120, + }, + { + field: 'chargeUserName', + title: '负责人', + width: 140, + }, + { + field: 'status', + title: '状态', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 180, + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/md/workstation/workshop/index.vue b/apps/web-antd/src/views/mes/md/workstation/workshop/index.vue new file mode 100644 index 000000000..9e12e4af5 --- /dev/null +++ b/apps/web-antd/src/views/mes/md/workstation/workshop/index.vue @@ -0,0 +1,145 @@ + + + diff --git a/apps/web-antd/src/views/mes/md/workstation/workshop/modules/form.vue b/apps/web-antd/src/views/mes/md/workstation/workshop/modules/form.vue new file mode 100644 index 000000000..b6c39452f --- /dev/null +++ b/apps/web-antd/src/views/mes/md/workstation/workshop/modules/form.vue @@ -0,0 +1,128 @@ + + + diff --git a/apps/web-antd/src/views/mes/utils/constants.ts b/apps/web-antd/src/views/mes/utils/constants.ts index 32f282f22..a69326c01 100644 --- a/apps/web-antd/src/views/mes/utils/constants.ts +++ b/apps/web-antd/src/views/mes/utils/constants.ts @@ -12,8 +12,11 @@ export const MesItemOrProductEnum = { /** MES 自动编码规则 Code 枚举 */ export const MesAutoCodeRuleCode = { + MD_CLIENT_CODE: 'MD_CLIENT_CODE', MD_ITEM_TYPE_CODE: 'MD_ITEM_TYPE_CODE', MD_ITEM_CODE: 'MD_ITEM_CODE', + MD_VENDOR_CODE: 'MD_VENDOR_CODE', + MD_WORKSHOP_CODE: 'MD_WORKSHOP_CODE', } as const; /** MES 条码格式枚举 */ diff --git a/apps/web-ele/src/api/iot/thingmodel/index.ts b/apps/web-ele/src/api/iot/thingmodel/index.ts index 5a3e4e499..210e8d08b 100644 --- a/apps/web-ele/src/api/iot/thingmodel/index.ts +++ b/apps/web-ele/src/api/iot/thingmodel/index.ts @@ -195,7 +195,9 @@ export const ThingModelFormRules: Record = { trigger: 'blur', }, ], - accessMode: [{ required: true, message: '请选择读写类型', trigger: 'change' }], + accessMode: [ + { required: true, message: '请选择读写类型', trigger: 'change' }, + ], callType: [{ required: true, message: '请选择调用方式', trigger: 'change' }], eventType: [{ required: true, message: '请选择事件类型', trigger: 'change' }], }; diff --git a/apps/web-ele/src/api/mes/md/client/index.ts b/apps/web-ele/src/api/mes/md/client/index.ts new file mode 100644 index 000000000..9be868d69 --- /dev/null +++ b/apps/web-ele/src/api/mes/md/client/index.ts @@ -0,0 +1,86 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdClientApi { + /** MES 客户 */ + export interface Client { + id?: number; // 客户编号 + code?: string; // 客户编码 + name?: string; // 客户名称 + nickname?: string; // 客户简称 + englishName?: string; // 客户英文名称 + description?: string; // 客户简介 + logo?: string; // 客户 LOGO 地址 + type?: number; // 客户类型 + address?: string; // 客户地址 + website?: string; // 客户官网地址 + email?: string; // 客户邮箱地址 + telephone?: string; // 客户电话 + contact1Name?: string; // 联系人1 + contact1Telephone?: string; // 联系人1电话 + contact1Email?: string; // 联系人1邮箱 + contact2Name?: string; // 联系人2 + contact2Telephone?: string; // 联系人2电话 + contact2Email?: string; // 联系人2邮箱 + creditCode?: string; // 统一社会信用代码 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } + + /** 客户导入结果 */ + export interface ClientImportRespVO { + createCodes?: string[]; // 新增成功的客户编码 + updateCodes?: string[]; // 更新成功的客户编码 + failureCodes?: Record; // 导入失败的客户编码及原因 + } +} + +/** 查询客户分页 */ +export function getClientPage(params: PageParam) { + return requestClient.get>( + '/mes/md-client/page', + { params }, + ); +} + +/** 查询客户详情 */ +export function getClient(id: number) { + return requestClient.get( + `/mes/md-client/get?id=${id}`, + ); +} + +/** 新增客户 */ +export function createClient(data: MesMdClientApi.Client) { + return requestClient.post('/mes/md-client/create', data); +} + +/** 修改客户 */ +export function updateClient(data: MesMdClientApi.Client) { + return requestClient.put('/mes/md-client/update', data); +} + +/** 删除客户 */ +export function deleteClient(id: number) { + return requestClient.delete(`/mes/md-client/delete?id=${id}`); +} + +/** 导出客户 */ +export function exportClient(params: any) { + return requestClient.download('/mes/md-client/export-excel', { params }); +} + +/** 下载客户导入模板 */ +export function importClientTemplate() { + return requestClient.download('/mes/md-client/get-import-template'); +} + +/** 导入客户 */ +export function importClient(file: File, updateSupport: boolean) { + return requestClient.upload( + `/mes/md-client/import?updateSupport=${updateSupport}`, + { file }, + ); +} diff --git a/apps/web-ele/src/api/mes/md/vendor/index.ts b/apps/web-ele/src/api/mes/md/vendor/index.ts new file mode 100644 index 000000000..e64845f53 --- /dev/null +++ b/apps/web-ele/src/api/mes/md/vendor/index.ts @@ -0,0 +1,87 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdVendorApi { + /** MES 供应商 */ + export interface Vendor { + id?: number; // 供应商编号 + code?: string; // 供应商编码 + name?: string; // 供应商名称 + nickname?: string; // 供应商简称 + englishName?: string; // 供应商英文名称 + description?: string; // 供应商简介 + logo?: string; // 供应商 LOGO 地址 + level?: string; // 供应商等级 + score?: number; // 供应商评分 + address?: string; // 供应商地址 + website?: string; // 供应商官网地址 + email?: string; // 供应商邮箱地址 + telephone?: string; // 供应商电话 + contact1Name?: string; // 联系人1 + contact1Telephone?: string; // 联系人1电话 + contact1Email?: string; // 联系人1邮箱 + contact2Name?: string; // 联系人2 + contact2Telephone?: string; // 联系人2电话 + contact2Email?: string; // 联系人2邮箱 + creditCode?: string; // 统一社会信用代码 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } + + /** 供应商导入结果 */ + export interface VendorImportRespVO { + createCodes?: string[]; // 新增成功的供应商编码 + updateCodes?: string[]; // 更新成功的供应商编码 + failureCodes?: Record; // 导入失败的供应商编码及原因 + } +} + +/** 查询供应商分页 */ +export function getVendorPage(params: PageParam) { + return requestClient.get>( + '/mes/md-vendor/page', + { params }, + ); +} + +/** 查询供应商详情 */ +export function getVendor(id: number) { + return requestClient.get( + `/mes/md-vendor/get?id=${id}`, + ); +} + +/** 新增供应商 */ +export function createVendor(data: MesMdVendorApi.Vendor) { + return requestClient.post('/mes/md-vendor/create', data); +} + +/** 修改供应商 */ +export function updateVendor(data: MesMdVendorApi.Vendor) { + return requestClient.put('/mes/md-vendor/update', data); +} + +/** 删除供应商 */ +export function deleteVendor(id: number) { + return requestClient.delete(`/mes/md-vendor/delete?id=${id}`); +} + +/** 导出供应商 */ +export function exportVendor(params: any) { + return requestClient.download('/mes/md-vendor/export-excel', { params }); +} + +/** 下载供应商导入模板 */ +export function importVendorTemplate() { + return requestClient.download('/mes/md-vendor/get-import-template'); +} + +/** 导入供应商 */ +export function importVendor(file: File, updateSupport: boolean) { + return requestClient.upload( + `/mes/md-vendor/import?updateSupport=${updateSupport}`, + { file }, + ); +} diff --git a/apps/web-ele/src/api/mes/md/workstation/workshop/index.ts b/apps/web-ele/src/api/mes/md/workstation/workshop/index.ts new file mode 100644 index 000000000..5a96399c9 --- /dev/null +++ b/apps/web-ele/src/api/mes/md/workstation/workshop/index.ts @@ -0,0 +1,60 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesMdWorkshopApi { + /** MES 车间 */ + export interface Workshop { + id?: number; // 车间编号 + code?: string; // 车间编码 + name?: string; // 车间名称 + area?: number; // 面积 + chargeUserId?: number; // 负责人用户编号 + chargeUserName?: string; // 负责人名称 + status?: number; // 状态 + remark?: string; // 备注 + createTime?: Date; // 创建时间 + } +} + +/** 查询车间分页 */ +export function getWorkshopPage(params: PageParam) { + return requestClient.get>( + '/mes/md-workshop/page', + { params }, + ); +} + +/** 查询车间精简列表 */ +export function getWorkshopSimpleList() { + return requestClient.get( + '/mes/md-workshop/simple-list', + ); +} + +/** 查询车间详情 */ +export function getWorkshop(id: number) { + return requestClient.get( + `/mes/md-workshop/get?id=${id}`, + ); +} + +/** 新增车间 */ +export function createWorkshop(data: MesMdWorkshopApi.Workshop) { + return requestClient.post('/mes/md-workshop/create', data); +} + +/** 修改车间 */ +export function updateWorkshop(data: MesMdWorkshopApi.Workshop) { + return requestClient.put('/mes/md-workshop/update', data); +} + +/** 删除车间 */ +export function deleteWorkshop(id: number) { + return requestClient.delete(`/mes/md-workshop/delete?id=${id}`); +} + +/** 导出车间 */ +export function exportWorkshop(params: any) { + return requestClient.download('/mes/md-workshop/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/mes/wm/itemreceipt/line/index.ts b/apps/web-ele/src/api/mes/wm/itemreceipt/line/index.ts new file mode 100644 index 000000000..55562e84c --- /dev/null +++ b/apps/web-ele/src/api/mes/wm/itemreceipt/line/index.ts @@ -0,0 +1,28 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmItemReceiptLineApi { + /** MES 物料接收单行 */ + export interface ItemReceiptLine { + id?: number; // 行编号 + receiptId?: number; // 入库单编号 + receiptCode?: string; // 入库单编码 + purchaseOrderCode?: string; // 采购订单号 + itemId?: number; // 物料编号 + itemCode?: string; // 物料编码 + itemName?: string; // 物料名称 + specification?: string; // 规格型号 + unitMeasureName?: string; // 单位 + receivedQuantity?: number; // 入库数量 + batchCode?: string; // 批次号 + } +} + +/** 查询物料接收单行分页 */ +export function getItemReceiptLinePage(params: PageParam) { + return requestClient.get>( + '/mes/wm/item-receipt-line/page', + { params }, + ); +} diff --git a/apps/web-ele/src/api/mes/wm/productsales/index.ts b/apps/web-ele/src/api/mes/wm/productsales/index.ts new file mode 100644 index 000000000..aa00d4556 --- /dev/null +++ b/apps/web-ele/src/api/mes/wm/productsales/index.ts @@ -0,0 +1,23 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmProductSalesApi { + /** MES 销售出库单 */ + export interface ProductSales { + id?: number; // 销售出库单编号 + code?: string; // 出库单编号 + name?: string; // 出库单名称 + salesOrderCode?: string; // 销售订单编号 + salesDate?: Date; // 出库日期 + status?: number; // 单据状态 + } +} + +/** 查询销售出库单分页 */ +export function getProductSalesPage(params: PageParam) { + return requestClient.get>( + '/mes/wm/product-sales/page', + { params }, + ); +} diff --git a/apps/web-ele/src/api/mes/wm/productsales/line/index.ts b/apps/web-ele/src/api/mes/wm/productsales/line/index.ts new file mode 100644 index 000000000..b66ef6ba7 --- /dev/null +++ b/apps/web-ele/src/api/mes/wm/productsales/line/index.ts @@ -0,0 +1,24 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace MesWmProductSalesLineApi { + /** MES 销售出库单行 */ + export interface ProductSalesLine { + id?: number; // 行编号 + itemId?: number; // 物料编号 + itemCode?: string; // 物料编码 + itemName?: string; // 物料名称 + specification?: string; // 规格型号 + unitMeasureName?: string; // 单位 + quantity?: number; // 出库数量 + batchCode?: string; // 批次号 + } +} + +/** 查询销售出库单行分页 */ +export function getProductSalesLinePage(params: PageParam) { + return requestClient.get< + PageResult + >('/mes/wm/product-sales-line/page', { params }); +} diff --git a/apps/web-ele/src/views/mes/md/client/components/md-client-select-dialog.vue b/apps/web-ele/src/views/mes/md/client/components/md-client-select-dialog.vue new file mode 100644 index 000000000..37d273f00 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/components/md-client-select-dialog.vue @@ -0,0 +1,179 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/components/md-client-select.vue b/apps/web-ele/src/views/mes/md/client/components/md-client-select.vue new file mode 100644 index 000000000..707c54373 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/components/md-client-select.vue @@ -0,0 +1,134 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/data.ts b/apps/web-ele/src/views/mes/md/client/data.ts new file mode 100644 index 000000000..1c4a8091d --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/data.ts @@ -0,0 +1,477 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesMdClientApi } from '#/api/mes/md/client'; + +import { h } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { z } from '#/adapter/form'; +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 新增/修改客户的表单 */ +export function useFormSchema(formApi?: any): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '客户编码', + component: 'Input', + componentProps: { + placeholder: '请输入客户编码', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + disabled: !!values.id, + }), + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.MD_CLIENT_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '自动生成' }, + ), + }, + { + fieldName: 'name', + label: '客户名称', + component: 'Input', + componentProps: { + placeholder: '请输入客户名称', + }, + rules: z.string().min(1, '客户名称不能为空').max(100), + }, + { + fieldName: 'nickname', + label: '客户简称', + component: 'Input', + componentProps: { + placeholder: '请输入客户简称', + }, + }, + { + fieldName: 'englishName', + label: '客户英文名称', + component: 'Input', + componentProps: { + placeholder: '请输入客户英文名称', + }, + }, + { + fieldName: 'type', + label: '客户类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_CLIENT_TYPE, 'number'), + placeholder: '请选择客户类型', + }, + rules: 'selectRequired', + }, + { + fieldName: 'description', + label: '客户简介', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入客户简介', + rows: 2, + }, + }, + { + fieldName: 'address', + label: '客户地址', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入客户地址', + rows: 2, + }, + }, + { + fieldName: 'website', + label: '客户官网地址', + component: 'Input', + componentProps: { + placeholder: '请输入客户官网地址', + }, + }, + { + fieldName: 'email', + label: '客户邮箱地址', + component: 'Input', + componentProps: { + placeholder: '请输入客户邮箱地址', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'telephone', + label: '客户电话', + component: 'Input', + componentProps: { + placeholder: '请输入客户电话', + }, + }, + { + fieldName: 'logo', + label: '客户 LOGO', + component: 'Input', + componentProps: { + placeholder: '请输入客户 LOGO 地址', + }, + }, + { + fieldName: 'contact1Name', + label: '联系人1', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1', + }, + }, + { + fieldName: 'contact1Telephone', + label: '联系人1电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1电话', + }, + }, + { + fieldName: 'contact1Email', + label: '联系人1邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'contact2Name', + label: '联系人2', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2', + }, + }, + { + fieldName: 'contact2Telephone', + label: '联系人2电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2电话', + }, + }, + { + fieldName: 'contact2Email', + label: '联系人2邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'creditCode', + label: '社会信用代码', + component: 'Input', + componentProps: { + placeholder: '请输入统一社会信用代码', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 导入客户的表单 */ +export function useImportFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'file', + label: '客户数据', + component: 'Upload', + rules: 'required', + help: '仅允许导入 xls、xlsx 格式文件', + }, + { + fieldName: 'updateSupport', + label: '是否覆盖', + component: 'Switch', + componentProps: { + activeText: '是', + inactiveText: '否', + inlinePrompt: true, + }, + rules: z.boolean().default(false), + help: '是否更新已经存在的客户数据', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '客户编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户编码', + }, + }, + { + fieldName: 'name', + label: '客户名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户名称', + }, + }, + { + fieldName: 'nickname', + label: '客户简称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户英文名称', + }, + }, + { + fieldName: 'type', + label: '客户类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_CLIENT_TYPE, 'number'), + placeholder: '请选择客户类型', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + clearable: 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: 160, + }, + { + field: 'nickname', + title: '客户简称', + minWidth: 130, + }, + { + field: 'type', + title: '客户类型', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_CLIENT_TYPE }, + }, + }, + { + field: 'telephone', + title: '客户电话', + minWidth: 140, + }, + { + field: 'contact1Name', + title: '联系人1', + width: 120, + }, + { + field: 'contact1Telephone', + title: '联系人1电话', + minWidth: 140, + }, + { + field: 'status', + title: '状态', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 客户选择弹窗的搜索表单 */ +export function useClientSelectGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '客户编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户编码', + }, + }, + { + fieldName: 'name', + label: '客户名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户名称', + }, + }, + { + fieldName: 'nickname', + label: '客户简称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入客户英文名称', + }, + }, + ]; +} + +/** 客户选择弹窗的字段 */ +export function useClientSelectGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 50 }, + { + field: 'code', + title: '客户编码', + minWidth: 160, + }, + { + field: 'name', + title: '客户名称', + minWidth: 160, + }, + { + field: 'nickname', + title: '客户简称', + width: 120, + }, + { + field: 'type', + title: '客户类型', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_CLIENT_TYPE }, + }, + }, + { + field: 'contact1Name', + title: '联系人', + width: 120, + }, + { + field: 'telephone', + title: '联系电话', + width: 140, + }, + { + field: 'contact1Telephone', + title: '联系人电话', + width: 140, + }, + { + field: 'status', + title: '状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/md/client/index.vue b/apps/web-ele/src/views/mes/md/client/index.vue new file mode 100644 index 000000000..b7250ddb9 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/index.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/modules/form.vue b/apps/web-ele/src/views/mes/md/client/modules/form.vue new file mode 100644 index 000000000..1c003ef0c --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/modules/form.vue @@ -0,0 +1,118 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/modules/import-form.vue b/apps/web-ele/src/views/mes/md/client/modules/import-form.vue new file mode 100644 index 000000000..894fc93ca --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/modules/import-form.vue @@ -0,0 +1,101 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/modules/product-sales-line-list.vue b/apps/web-ele/src/views/mes/md/client/modules/product-sales-line-list.vue new file mode 100644 index 000000000..8ddb50d30 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/modules/product-sales-line-list.vue @@ -0,0 +1,75 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/client/modules/product-sales-list.vue b/apps/web-ele/src/views/mes/md/client/modules/product-sales-list.vue new file mode 100644 index 000000000..0f7b55f8c --- /dev/null +++ b/apps/web-ele/src/views/mes/md/client/modules/product-sales-list.vue @@ -0,0 +1,62 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue b/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue new file mode 100644 index 000000000..c2d19a7c4 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select-dialog.vue @@ -0,0 +1,179 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select.vue b/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select.vue new file mode 100644 index 000000000..92a8eb138 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/components/md-vendor-select.vue @@ -0,0 +1,134 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/data.ts b/apps/web-ele/src/views/mes/md/vendor/data.ts new file mode 100644 index 000000000..79516e648 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/data.ts @@ -0,0 +1,472 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesMdVendorApi } from '#/api/mes/md/vendor'; + +import { h } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { z } from '#/adapter/form'; +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 新增/修改供应商的表单 */ +export function useFormSchema(formApi?: any): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + placeholder: '请输入供应商编码', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + disabled: !!values.id, + }), + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.MD_VENDOR_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '自动生成' }, + ), + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商名称', + }, + rules: z.string().min(1, '供应商名称不能为空').max(100), + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + placeholder: '请输入供应商英文名称', + }, + }, + { + fieldName: 'level', + label: '供应商等级', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_VENDOR_LEVEL), + placeholder: '请选择供应商等级', + }, + }, + { + fieldName: 'description', + label: '供应商简介', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入供应商简介', + rows: 2, + }, + }, + { + fieldName: 'address', + label: '供应商地址', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入供应商地址', + rows: 2, + }, + }, + { + fieldName: 'website', + label: '官网地址', + component: 'Input', + componentProps: { + placeholder: '请输入供应商官网地址', + }, + }, + { + fieldName: 'email', + label: '邮箱地址', + component: 'Input', + componentProps: { + placeholder: '请输入供应商邮箱地址', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'telephone', + label: '供应商电话', + component: 'Input', + componentProps: { + placeholder: '请输入供应商电话', + }, + }, + { + fieldName: 'score', + label: '供应商评分', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + max: 100, + min: 0, + precision: 0, + }, + }, + { + fieldName: 'contact1Name', + label: '联系人1', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1', + }, + }, + { + fieldName: 'contact1Telephone', + label: '联系人1电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1电话', + }, + }, + { + fieldName: 'contact1Email', + label: '联系人1邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人1邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'contact2Name', + label: '联系人2', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2', + }, + }, + { + fieldName: 'contact2Telephone', + label: '联系人2电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2电话', + }, + }, + { + fieldName: 'contact2Email', + label: '联系人2邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入联系人2邮箱', + }, + rules: z.string().email('邮箱格式不正确').or(z.literal('')).optional(), + }, + { + fieldName: 'creditCode', + label: '社会信用代码', + component: 'Input', + componentProps: { + placeholder: '请输入统一社会信用代码', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'logo', + label: '供应商 LOGO', + component: 'Input', + componentProps: { + placeholder: '请输入供应商 LOGO 地址', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-3', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 导入供应商的表单 */ +export function useImportFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'file', + label: '供应商数据', + component: 'Upload', + rules: 'required', + help: '仅允许导入 xls、xlsx 格式文件', + }, + { + fieldName: 'updateSupport', + label: '是否覆盖', + component: 'Switch', + componentProps: { + activeText: '是', + inactiveText: '否', + inlinePrompt: true, + }, + rules: z.boolean().default(false), + help: '是否更新已经存在的供应商数据', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商编码', + }, + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商名称', + }, + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入英文名称', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + clearable: 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: 'nickname', + title: '供应商简称', + width: 120, + }, + { + field: 'level', + title: '供应商等级', + width: 130, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_VENDOR_LEVEL }, + }, + }, + { + field: 'score', + title: '供应商评分', + width: 120, + }, + { + field: 'telephone', + title: '供应商电话', + minWidth: 140, + }, + { + field: 'status', + title: '状态', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 180, + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 供应商选择弹窗的搜索表单 */ +export function useVendorSelectGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '供应商编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商编码', + }, + }, + { + fieldName: 'name', + label: '供应商名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商名称', + }, + }, + { + fieldName: 'nickname', + label: '供应商简称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入供应商简称', + }, + }, + { + fieldName: 'englishName', + label: '英文名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入英文名称', + }, + }, + ]; +} + +/** 供应商选择弹窗的字段 */ +export function useVendorSelectGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 50 }, + { + field: 'code', + title: '供应商编码', + minWidth: 160, + }, + { + field: 'name', + title: '供应商名称', + minWidth: 170, + }, + { + field: 'nickname', + title: '供应商简称', + width: 120, + }, + { + field: 'level', + title: '供应商等级', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_VENDOR_LEVEL }, + }, + }, + { + field: 'score', + title: '供应商评分', + width: 110, + }, + { + field: 'telephone', + title: '联系电话', + width: 140, + }, + { + field: 'status', + title: '状态', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 140, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/md/vendor/index.vue b/apps/web-ele/src/views/mes/md/vendor/index.vue new file mode 100644 index 000000000..53e593583 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/index.vue @@ -0,0 +1,176 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/modules/form.vue b/apps/web-ele/src/views/mes/md/vendor/modules/form.vue new file mode 100644 index 000000000..daca13f95 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/modules/form.vue @@ -0,0 +1,118 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/modules/import-form.vue b/apps/web-ele/src/views/mes/md/vendor/modules/import-form.vue new file mode 100644 index 000000000..7a84fcd3b --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/modules/import-form.vue @@ -0,0 +1,101 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-line-list.vue b/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-line-list.vue new file mode 100644 index 000000000..43b29d30d --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-line-list.vue @@ -0,0 +1,75 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-list.vue b/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-list.vue new file mode 100644 index 000000000..86635ab07 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/vendor/modules/item-receipt-list.vue @@ -0,0 +1,49 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/workstation/workshop/data.ts b/apps/web-ele/src/views/mes/md/workstation/workshop/data.ts new file mode 100644 index 000000000..d8958abdb --- /dev/null +++ b/apps/web-ele/src/views/mes/md/workstation/workshop/data.ts @@ -0,0 +1,193 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesMdWorkshopApi } from '#/api/mes/md/workstation/workshop'; + +import { h } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { ElButton } from 'element-plus'; + +import { z } from '#/adapter/form'; +import { generateAutoCode } from '#/api/mes/md/autocode/record'; +import { getSimpleUserList } from '#/api/system/user'; +import { MesAutoCodeRuleCode } from '#/views/mes/utils/constants'; + +/** 新增/修改车间的表单 */ +export function useFormSchema(formApi?: any): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'code', + label: '车间编码', + component: 'Input', + componentProps: { + placeholder: '请输入车间编码', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + disabled: !!values.id, + }), + }, + rules: 'required', + suffix: () => + h( + ElButton, + { + onClick: async () => { + try { + const code = await generateAutoCode( + MesAutoCodeRuleCode.MD_WORKSHOP_CODE, + ); + await formApi?.setFieldValue('code', code); + } catch (error) { + console.error(error); + } + }, + }, + { default: () => '自动生成' }, + ), + }, + { + fieldName: 'name', + label: '车间名称', + component: 'Input', + componentProps: { + placeholder: '请输入车间名称', + }, + rules: 'required', + }, + { + fieldName: 'area', + label: '面积', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 0, + precision: 2, + }, + }, + { + fieldName: 'chargeUserId', + label: '负责人', + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + labelField: 'nickname', + placeholder: '请选择负责人', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + formItemClass: 'col-span-2', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'code', + label: '车间编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入车间编码', + }, + }, + { + fieldName: 'name', + label: '车间名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入车间名称', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + clearable: 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: 150, + }, + { + field: 'area', + title: '面积', + width: 120, + }, + { + field: 'chargeUserName', + title: '负责人', + width: 140, + }, + { + field: 'status', + title: '状态', + width: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 180, + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/md/workstation/workshop/index.vue b/apps/web-ele/src/views/mes/md/workstation/workshop/index.vue new file mode 100644 index 000000000..fd9f51c42 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/workstation/workshop/index.vue @@ -0,0 +1,145 @@ + + + diff --git a/apps/web-ele/src/views/mes/md/workstation/workshop/modules/form.vue b/apps/web-ele/src/views/mes/md/workstation/workshop/modules/form.vue new file mode 100644 index 000000000..b2a7b3a96 --- /dev/null +++ b/apps/web-ele/src/views/mes/md/workstation/workshop/modules/form.vue @@ -0,0 +1,128 @@ + + +