From 8d3dd06266abef1b95f112137a0fc16fed6d741f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 15:48:39 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91=E3=80=90erp?= =?UTF-8?q?=E3=80=91product=20=E7=9A=84=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/erp/product/category/index.ts | 2 +- .../src/api/erp/product/product/index.ts | 2 +- .../src/api/erp/product/unit/index.ts | 12 +- .../src/api/erp/product/category/index.ts | 62 +++++ .../src/api/erp/product/product/index.ts | 61 +++++ .../web-ele/src/api/erp/product/unit/index.ts | 62 +++++ .../src/views/erp/product/category/data.ts | 149 ++++++++++ .../src/views/erp/product/category/index.vue | 183 +++++++++++++ .../erp/product/category/modules/form.vue | 91 ++++++ .../src/views/erp/product/product/data.ts | 258 ++++++++++++++++++ .../src/views/erp/product/product/index.vue | 150 ++++++++++ .../erp/product/product/modules/form.vue | 85 ++++++ .../src/views/erp/product/unit/data.ts | 101 +++++++ .../src/views/erp/product/unit/index.vue | 149 ++++++++++ .../views/erp/product/unit/modules/form.vue | 88 ++++++ 15 files changed, 1443 insertions(+), 12 deletions(-) create mode 100644 apps/web-ele/src/api/erp/product/category/index.ts create mode 100644 apps/web-ele/src/api/erp/product/product/index.ts create mode 100644 apps/web-ele/src/api/erp/product/unit/index.ts create mode 100644 apps/web-ele/src/views/erp/product/category/data.ts create mode 100644 apps/web-ele/src/views/erp/product/category/index.vue create mode 100644 apps/web-ele/src/views/erp/product/category/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/product/product/data.ts create mode 100644 apps/web-ele/src/views/erp/product/product/index.vue create mode 100644 apps/web-ele/src/views/erp/product/product/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/product/unit/data.ts create mode 100644 apps/web-ele/src/views/erp/product/unit/index.vue create mode 100644 apps/web-ele/src/views/erp/product/unit/modules/form.vue diff --git a/apps/web-antd/src/api/erp/product/category/index.ts b/apps/web-antd/src/api/erp/product/category/index.ts index 87c855319..3c96b5893 100644 --- a/apps/web-antd/src/api/erp/product/category/index.ts +++ b/apps/web-antd/src/api/erp/product/category/index.ts @@ -1,7 +1,7 @@ import { requestClient } from '#/api/request'; export namespace ErpProductCategoryApi { - /** ERP 产品分类信息 */ + /** 产品分类信息 */ export interface ProductCategory { id?: number; // 分类编号 parentId?: number; // 父分类编号 diff --git a/apps/web-antd/src/api/erp/product/product/index.ts b/apps/web-antd/src/api/erp/product/product/index.ts index 157827fff..a9ca836f9 100644 --- a/apps/web-antd/src/api/erp/product/product/index.ts +++ b/apps/web-antd/src/api/erp/product/product/index.ts @@ -3,7 +3,7 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace ErpProductApi { - /** ERP 产品信息 */ + /** 产品信息 */ export interface Product { id?: number; // 产品编号 name: string; // 产品名称 diff --git a/apps/web-antd/src/api/erp/product/unit/index.ts b/apps/web-antd/src/api/erp/product/unit/index.ts index 317c09c85..23514963b 100644 --- a/apps/web-antd/src/api/erp/product/unit/index.ts +++ b/apps/web-antd/src/api/erp/product/unit/index.ts @@ -3,24 +3,16 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace ErpProductUnitApi { - /** ERP 产品单位信息 */ + /** 产品单位信息 */ export interface ProductUnit { id?: number; // 单位编号 name: string; // 单位名字 status: number; // 单位状态 } - - /** 产品单位分页查询参数 */ - export interface ProductUnitPageParam extends PageParam { - name?: string; - status?: number; - } } /** 查询产品单位分页 */ -export function getProductUnitPage( - params: ErpProductUnitApi.ProductUnitPageParam, -) { +export function getProductUnitPage(params: PageParam) { return requestClient.get>( '/erp/product-unit/page', { params }, diff --git a/apps/web-ele/src/api/erp/product/category/index.ts b/apps/web-ele/src/api/erp/product/category/index.ts new file mode 100644 index 000000000..87c855319 --- /dev/null +++ b/apps/web-ele/src/api/erp/product/category/index.ts @@ -0,0 +1,62 @@ +import { requestClient } from '#/api/request'; + +export namespace ErpProductCategoryApi { + /** ERP 产品分类信息 */ + export interface ProductCategory { + id?: number; // 分类编号 + parentId?: number; // 父分类编号 + name: string; // 分类名称 + code?: string; // 分类编码 + sort?: number; // 分类排序 + status?: number; // 开启状态 + children?: ProductCategory[]; // 子分类 + } +} + +/** 查询产品分类列表 */ +export function getProductCategoryList(params?: any) { + return requestClient.get( + '/erp/product-category/list', + { params }, + ); +} + +/** 查询产品分类精简列表 */ +export function getProductCategorySimpleList() { + return requestClient.get( + '/erp/product-category/simple-list', + ); +} + +/** 查询产品分类详情 */ +export function getProductCategory(id: number) { + return requestClient.get( + `/erp/product-category/get?id=${id}`, + ); +} + +/** 新增产品分类 */ +export function createProductCategory( + data: ErpProductCategoryApi.ProductCategory, +) { + return requestClient.post('/erp/product-category/create', data); +} + +/** 修改产品分类 */ +export function updateProductCategory( + data: ErpProductCategoryApi.ProductCategory, +) { + return requestClient.put('/erp/product-category/update', data); +} + +/** 删除产品分类 */ +export function deleteProductCategory(id: number) { + return requestClient.delete(`/erp/product-category/delete?id=${id}`); +} + +/** 导出产品分类 Excel */ +export function exportProductCategory(params: any) { + return requestClient.download('/erp/product-category/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/product/product/index.ts b/apps/web-ele/src/api/erp/product/product/index.ts new file mode 100644 index 000000000..a9ca836f9 --- /dev/null +++ b/apps/web-ele/src/api/erp/product/product/index.ts @@ -0,0 +1,61 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpProductApi { + /** 产品信息 */ + export interface Product { + id?: number; // 产品编号 + name: string; // 产品名称 + barCode: string; // 产品条码 + categoryId: number; // 产品类型编号 + unitId: number; // 单位编号 + unitName?: string; // 单位名字 + status: number; // 产品状态 + standard: string; // 产品规格 + remark: string; // 产品备注 + expiryDay: number; // 保质期天数 + weight: number; // 重量(kg) + purchasePrice: number; // 采购价格,单位:元 + salePrice: number; // 销售价格,单位:元 + minPrice: number; // 最低价格,单位:元 + } +} + +/** 查询产品分页 */ +export function getProductPage(params: PageParam) { + return requestClient.get>( + '/erp/product/page', + { params }, + ); +} + +/** 查询产品精简列表 */ +export function getProductSimpleList() { + return requestClient.get('/erp/product/simple-list'); +} + +/** 查询产品详情 */ +export function getProduct(id: number) { + return requestClient.get(`/erp/product/get?id=${id}`); +} + +/** 新增产品 */ +export function createProduct(data: ErpProductApi.Product) { + return requestClient.post('/erp/product/create', data); +} + +/** 修改产品 */ +export function updateProduct(data: ErpProductApi.Product) { + return requestClient.put('/erp/product/update', data); +} + +/** 删除产品 */ +export function deleteProduct(id: number) { + return requestClient.delete(`/erp/product/delete?id=${id}`); +} + +/** 导出产品 Excel */ +export function exportProduct(params: any) { + return requestClient.download('/erp/product/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/erp/product/unit/index.ts b/apps/web-ele/src/api/erp/product/unit/index.ts new file mode 100644 index 000000000..317c09c85 --- /dev/null +++ b/apps/web-ele/src/api/erp/product/unit/index.ts @@ -0,0 +1,62 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpProductUnitApi { + /** ERP 产品单位信息 */ + export interface ProductUnit { + id?: number; // 单位编号 + name: string; // 单位名字 + status: number; // 单位状态 + } + + /** 产品单位分页查询参数 */ + export interface ProductUnitPageParam extends PageParam { + name?: string; + status?: number; + } +} + +/** 查询产品单位分页 */ +export function getProductUnitPage( + params: ErpProductUnitApi.ProductUnitPageParam, +) { + return requestClient.get>( + '/erp/product-unit/page', + { params }, + ); +} + +/** 查询产品单位精简列表 */ +export function getProductUnitSimpleList() { + return requestClient.get( + '/erp/product-unit/simple-list', + ); +} + +/** 查询产品单位详情 */ +export function getProductUnit(id: number) { + return requestClient.get( + `/erp/product-unit/get?id=${id}`, + ); +} + +/** 新增产品单位 */ +export function createProductUnit(data: ErpProductUnitApi.ProductUnit) { + return requestClient.post('/erp/product-unit/create', data); +} + +/** 修改产品单位 */ +export function updateProductUnit(data: ErpProductUnitApi.ProductUnit) { + return requestClient.put('/erp/product-unit/update', data); +} + +/** 删除产品单位 */ +export function deleteProductUnit(id: number) { + return requestClient.delete(`/erp/product-unit/delete?id=${id}`); +} + +/** 导出产品单位 Excel */ +export function exportProductUnit(params: any) { + return requestClient.download('/erp/product-unit/export-excel', { params }); +} diff --git a/apps/web-ele/src/views/erp/product/category/data.ts b/apps/web-ele/src/views/erp/product/category/data.ts new file mode 100644 index 000000000..e6b13c900 --- /dev/null +++ b/apps/web-ele/src/views/erp/product/category/data.ts @@ -0,0 +1,149 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { ErpProductCategoryApi } from '#/api/erp/product/category'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { handleTree } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getProductCategoryList } from '#/api/erp/product/category'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'parentId', + label: '上级分类', + component: 'ApiTreeSelect', + componentProps: { + allowClear: true, + api: async () => { + const data = await getProductCategoryList(); + data.unshift({ + id: 0, + name: '顶级分类', + }); + return handleTree(data); + }, + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择上级分类', + treeDefaultExpandAll: true, + }, + rules: 'selectRequired', + }, + { + fieldName: 'name', + label: '分类名称', + component: 'Input', + componentProps: { + placeholder: '请输入分类名称', + }, + rules: 'required', + }, + { + fieldName: 'code', + label: '分类编码', + component: 'Input', + componentProps: { + placeholder: '请输入分类编码', + }, + rules: 'required', + }, + { + fieldName: 'sort', + label: '显示顺序', + component: 'InputNumber', + componentProps: { + min: 0, + placeholder: '请输入显示顺序', + controlsPosition: 'right', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + ]; +} + +/** 查询表单 */ +export function useQueryFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'name', + label: '分类名称', + componentProps: { + placeholder: '请输入分类名称', + allowClear: true, + }, + }, + { + component: 'Select', + fieldName: 'status', + label: '开启状态', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + placeholder: '请选择开启状态', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'name', + title: '分类名称', + align: 'left', + treeNode: true, + }, + { + field: 'code', + title: '分类编码', + }, + { + field: 'sort', + title: '显示顺序', + }, + { + field: 'status', + title: '分类状态', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 220, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/product/category/index.vue b/apps/web-ele/src/views/erp/product/category/index.vue new file mode 100644 index 000000000..19c20d37b --- /dev/null +++ b/apps/web-ele/src/views/erp/product/category/index.vue @@ -0,0 +1,183 @@ + + + diff --git a/apps/web-ele/src/views/erp/product/category/modules/form.vue b/apps/web-ele/src/views/erp/product/category/modules/form.vue new file mode 100644 index 000000000..981feb5cd --- /dev/null +++ b/apps/web-ele/src/views/erp/product/category/modules/form.vue @@ -0,0 +1,91 @@ + + + diff --git a/apps/web-ele/src/views/erp/product/product/data.ts b/apps/web-ele/src/views/erp/product/product/data.ts new file mode 100644 index 000000000..8bfa9ebfe --- /dev/null +++ b/apps/web-ele/src/views/erp/product/product/data.ts @@ -0,0 +1,258 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { handleTree } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getProductCategorySimpleList } from '#/api/erp/product/category'; +import { getProductUnitSimpleList } from '#/api/erp/product/unit'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'name', + label: '名称', + rules: 'required', + componentProps: { + placeholder: '请输入名称', + }, + }, + { + fieldName: 'barCode', + label: '条码', + component: 'Input', + rules: 'required', + componentProps: { + placeholder: '请输入条码', + }, + }, + { + fieldName: 'categoryId', + label: '分类', + component: 'ApiTreeSelect', + componentProps: { + api: async () => { + const data = await getProductCategorySimpleList(); + return handleTree(data); + }, + + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择分类', + treeDefaultExpandAll: true, + }, + rules: 'required', + }, + { + fieldName: 'unitId', + label: '单位', + component: 'ApiSelect', + componentProps: { + api: getProductUnitSimpleList, + labelField: 'name', + valueField: 'id', + placeholder: '请选择单位', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'standard', + label: '规格', + component: 'Input', + componentProps: { + placeholder: '请输入规格', + }, + }, + { + fieldName: 'expiryDay', + label: '保质期天数', + component: 'InputNumber', + componentProps: { + placeholder: '请输入保质期天数', + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'weight', + label: '重量(kg)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入重量(kg)', + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'purchasePrice', + label: '采购价格', + component: 'InputNumber', + componentProps: { + placeholder: '请输入采购价格,单位:元', + precision: 2, + min: 0, + step: 0.01, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'salePrice', + label: '销售价格', + component: 'InputNumber', + componentProps: { + placeholder: '请输入销售价格,单位:元', + precision: 2, + min: 0, + step: 0.01, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'minPrice', + label: '最低价格', + component: 'InputNumber', + componentProps: { + placeholder: '请输入最低价格,单位:元', + precision: 2, + min: 0, + step: 0.01, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '名称', + component: 'Input', + componentProps: { + placeholder: '请输入名称', + allowClear: true, + }, + }, + { + fieldName: 'categoryId', + label: '分类', + component: 'ApiTreeSelect', + componentProps: { + api: async () => { + const data = await getProductCategorySimpleList(); + return handleTree(data); + }, + + labelField: 'name', + valueField: 'id', + childrenField: 'children', + placeholder: '请选择分类', + treeDefaultExpandAll: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'barCode', + title: '条码', + minWidth: 120, + }, + { + field: 'name', + title: '名称', + minWidth: 200, + }, + { + field: 'standard', + title: '规格', + minWidth: 100, + }, + { + field: 'categoryName', + title: '分类', + minWidth: 120, + }, + { + field: 'unitName', + title: '单位', + minWidth: 100, + }, + { + field: 'purchasePrice', + title: '采购价格', + minWidth: 100, + formatter: 'formatAmount2', + }, + { + field: 'salePrice', + title: '销售价格', + minWidth: 100, + formatter: 'formatAmount2', + }, + { + field: 'minPrice', + title: '最低价格', + minWidth: 100, + formatter: 'formatAmount2', + }, + { + field: 'status', + title: '状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/product/product/index.vue b/apps/web-ele/src/views/erp/product/product/index.vue new file mode 100644 index 000000000..f6bce71be --- /dev/null +++ b/apps/web-ele/src/views/erp/product/product/index.vue @@ -0,0 +1,150 @@ + + + diff --git a/apps/web-ele/src/views/erp/product/product/modules/form.vue b/apps/web-ele/src/views/erp/product/product/modules/form.vue new file mode 100644 index 000000000..baed5a71e --- /dev/null +++ b/apps/web-ele/src/views/erp/product/product/modules/form.vue @@ -0,0 +1,85 @@ + + + diff --git a/apps/web-ele/src/views/erp/product/unit/data.ts b/apps/web-ele/src/views/erp/product/unit/data.ts new file mode 100644 index 000000000..0914528aa --- /dev/null +++ b/apps/web-ele/src/views/erp/product/unit/data.ts @@ -0,0 +1,101 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; + +/** 新增/修改的表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'id', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + component: 'Input', + fieldName: 'name', + label: '单位名称', + rules: 'required', + componentProps: { + placeholder: '请输入单位名称', + }, + }, + { + fieldName: 'status', + label: '单位状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '单位名称', + component: 'Input', + componentProps: { + placeholder: '请输入单位名称', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '单位状态', + component: 'Select', + componentProps: { + placeholder: '请选择单位状态', + allowClear: true, + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '单位编号', + minWidth: 100, + }, + { + field: 'name', + title: '单位名称', + minWidth: 200, + }, + { + field: 'status', + title: '单位状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/product/unit/index.vue b/apps/web-ele/src/views/erp/product/unit/index.vue new file mode 100644 index 000000000..19972401c --- /dev/null +++ b/apps/web-ele/src/views/erp/product/unit/index.vue @@ -0,0 +1,149 @@ + + + diff --git a/apps/web-ele/src/views/erp/product/unit/modules/form.vue b/apps/web-ele/src/views/erp/product/unit/modules/form.vue new file mode 100644 index 000000000..70b3a9821 --- /dev/null +++ b/apps/web-ele/src/views/erp/product/unit/modules/form.vue @@ -0,0 +1,88 @@ + + +