From 7733d0a7f4d874c559e10387fab2ab8daab5fa09 Mon Sep 17 00:00:00 2001 From: hw Date: Wed, 12 Nov 2025 16:56:18 +0800 Subject: [PATCH 01/25] =?UTF-8?q?fix:=20todo=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/.env.development | 4 +- apps/web-antd/src/api/mp/draft/index.ts | 10 +- .../mp/autoReply/components/ReplyForm.vue | 138 -------- apps/web-antd/src/views/mp/autoReply/data.ts | 94 ++++- .../web-antd/src/views/mp/autoReply/index.vue | 232 ++++++------- .../ReplyTable.vue => modules/content.vue} | 15 +- .../src/views/mp/autoReply/modules/form.vue | 158 +++++---- .../mp/autoReply/{components => }/types.ts | 0 apps/web-antd/src/views/mp/draft/data.ts | 21 +- apps/web-antd/src/views/mp/draft/index.vue | 214 ++++-------- .../{components => modules}/cover-select.vue | 106 ++---- .../{components => modules}/draft-table.vue | 4 +- .../src/views/mp/draft/modules/form.vue | 54 ++- .../{components => modules}/news-form.vue | 163 +++------ .../mp/draft/{components => modules}/types.ts | 2 +- .../src/views/mp/menu/components/index.ts | 5 - .../views/mp/menu/components/menuOptions.ts | 43 --- apps/web-antd/src/views/mp/menu/data.ts | 22 ++ apps/web-antd/src/views/mp/menu/index.vue | 207 +++++------ .../assets/iphone_backImg.png | Bin .../assets/menu_foot.png | Bin .../assets/menu_head.png | Bin .../menu-editor.vue => modules/editor.vue} | 154 +++------ .../src/views/mp/menu/modules/index.ts | 5 + .../previewer.vue} | 111 ++---- .../mp/menu/{components => modules}/types.ts | 44 +++ apps/web-antd/src/views/mp/modules/index.ts | 20 ++ .../wx-location.vue => location/location.vue} | 2 +- .../material-select/material-select.vue | 324 ++++++++++++++++++ .../views/mp/modules/material-select/types.ts | 4 + .../mp/modules/{wx-msg => msg}/msg-event.vue | 0 .../mp/modules/{wx-msg => msg}/msg-list.vue | 9 +- .../views/mp/modules/{wx-msg => msg}/msg.vue | 24 +- .../views/mp/modules/{wx-msg => msg}/types.ts | 0 .../wx-music.vue => music/music.vue} | 23 +- .../src/views/mp/modules/news/news.vue | 68 ++++ .../wx-reply.vue => reply/reply.vue} | 48 +-- .../modules/{wx-reply => reply}/tab-image.vue | 12 +- .../modules/{wx-reply => reply}/tab-music.vue | 12 +- .../modules/{wx-reply => reply}/tab-news.vue | 9 +- .../modules/{wx-reply => reply}/tab-text.vue | 0 .../modules/{wx-reply => reply}/tab-video.vue | 7 +- .../modules/{wx-reply => reply}/tab-voice.vue | 15 +- .../mp/modules/{wx-reply => reply}/types.ts | 7 +- .../video-play.vue} | 13 +- .../voice-play.vue} | 28 +- .../mp/modules/wx-account-select/index.ts | 2 - .../wx-account-select/wx-account-select.vue | 123 ------- .../src/views/mp/modules/wx-location/index.ts | 1 - .../mp/modules/wx-material-select/index.ts | 3 - .../mp/modules/wx-material-select/types.ts | 12 - .../wx-material-select/wx-material-select.vue | 282 --------------- .../src/views/mp/modules/wx-msg/card.scss | 116 ------- .../src/views/mp/modules/wx-msg/comment.scss | 109 ------ .../src/views/mp/modules/wx-msg/index.ts | 3 - .../src/views/mp/modules/wx-msg/wx-msg.vue | 197 ----------- .../src/views/mp/modules/wx-music/index.ts | 1 - .../src/views/mp/modules/wx-news/index.ts | 1 - .../src/views/mp/modules/wx-news/wx-news.vue | 127 ------- .../src/views/mp/modules/wx-reply/index.ts | 2 - .../views/mp/modules/wx-video-play/index.ts | 1 - .../views/mp/modules/wx-voice-play/index.ts | 1 - apps/web-antd/src/views/mp/tag/data.ts | 1 + 63 files changed, 1211 insertions(+), 2202 deletions(-) delete mode 100644 apps/web-antd/src/views/mp/autoReply/components/ReplyForm.vue rename apps/web-antd/src/views/mp/autoReply/{components/ReplyTable.vue => modules/content.vue} (70%) rename apps/web-antd/src/views/mp/autoReply/{components => }/types.ts (100%) rename apps/web-antd/src/views/mp/draft/{components => modules}/cover-select.vue (63%) rename apps/web-antd/src/views/mp/draft/{components => modules}/draft-table.vue (73%) rename apps/web-antd/src/views/mp/draft/{components => modules}/news-form.vue (68%) rename apps/web-antd/src/views/mp/draft/{components => modules}/types.ts (92%) delete mode 100644 apps/web-antd/src/views/mp/menu/components/index.ts delete mode 100644 apps/web-antd/src/views/mp/menu/components/menuOptions.ts rename apps/web-antd/src/views/mp/menu/{components => modules}/assets/iphone_backImg.png (100%) rename apps/web-antd/src/views/mp/menu/{components => modules}/assets/menu_foot.png (100%) rename apps/web-antd/src/views/mp/menu/{components => modules}/assets/menu_head.png (100%) rename apps/web-antd/src/views/mp/menu/{components/menu-editor.vue => modules/editor.vue} (64%) create mode 100644 apps/web-antd/src/views/mp/menu/modules/index.ts rename apps/web-antd/src/views/mp/menu/{components/menu-previewer.vue => modules/previewer.vue} (68%) rename apps/web-antd/src/views/mp/menu/{components => modules}/types.ts (63%) create mode 100644 apps/web-antd/src/views/mp/modules/index.ts rename apps/web-antd/src/views/mp/modules/{wx-location/wx-location.vue => location/location.vue} (97%) create mode 100644 apps/web-antd/src/views/mp/modules/material-select/material-select.vue create mode 100644 apps/web-antd/src/views/mp/modules/material-select/types.ts rename apps/web-antd/src/views/mp/modules/{wx-msg => msg}/msg-event.vue (100%) rename apps/web-antd/src/views/mp/modules/{wx-msg => msg}/msg-list.vue (87%) rename apps/web-antd/src/views/mp/modules/{wx-msg => msg}/msg.vue (78%) rename apps/web-antd/src/views/mp/modules/{wx-msg => msg}/types.ts (100%) rename apps/web-antd/src/views/mp/modules/{wx-music/wx-music.vue => music/music.vue} (56%) create mode 100644 apps/web-antd/src/views/mp/modules/news/news.vue rename apps/web-antd/src/views/mp/modules/{wx-reply/wx-reply.vue => reply/reply.vue} (71%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-image.vue (93%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-music.vue (92%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-news.vue (89%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-text.vue (100%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-video.vue (95%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/tab-voice.vue (90%) rename apps/web-antd/src/views/mp/modules/{wx-reply => reply}/types.ts (90%) rename apps/web-antd/src/views/mp/modules/{wx-video-play/wx-video-play.vue => video-play/video-play.vue} (90%) rename apps/web-antd/src/views/mp/modules/{wx-voice-play/wx-voice-play.vue => voice-play/voice-play.vue} (83%) delete mode 100644 apps/web-antd/src/views/mp/modules/wx-account-select/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-account-select/wx-account-select.vue delete mode 100644 apps/web-antd/src/views/mp/modules/wx-location/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-material-select/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-material-select/types.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-material-select/wx-material-select.vue delete mode 100644 apps/web-antd/src/views/mp/modules/wx-msg/card.scss delete mode 100644 apps/web-antd/src/views/mp/modules/wx-msg/comment.scss delete mode 100644 apps/web-antd/src/views/mp/modules/wx-msg/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-msg/wx-msg.vue delete mode 100644 apps/web-antd/src/views/mp/modules/wx-music/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-news/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-news/wx-news.vue delete mode 100644 apps/web-antd/src/views/mp/modules/wx-reply/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-video-play/index.ts delete mode 100644 apps/web-antd/src/views/mp/modules/wx-voice-play/index.ts diff --git a/apps/web-antd/.env.development b/apps/web-antd/.env.development index cff255764..fe07e867c 100644 --- a/apps/web-antd/.env.development +++ b/apps/web-antd/.env.development @@ -4,9 +4,9 @@ VITE_PORT=5666 VITE_BASE=/ # 请求路径 -VITE_BASE_URL=http://127.0.0.1:48080 +VITE_BASE_URL=http://47.103.66.220:48080 # 接口地址 -VITE_GLOB_API_URL=/admin-api +VITE_GLOB_API_URL=http://47.103.66.220:48080/admin-api # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务 VITE_UPLOAD_TYPE=server # 是否打开 devtools,true 为打开,false 为关闭 diff --git a/apps/web-antd/src/api/mp/draft/index.ts b/apps/web-antd/src/api/mp/draft/index.ts index 9032ffd57..70b7c0e83 100644 --- a/apps/web-antd/src/api/mp/draft/index.ts +++ b/apps/web-antd/src/api/mp/draft/index.ts @@ -50,13 +50,9 @@ export function updateDraft( mediaId: string, articles: MpDraftApi.Article[], ) { - return requestClient.put( - '/mp/draft/update', - { articles }, - { - params: { accountId, mediaId }, - }, - ); + return requestClient.put('/mp/draft/update', articles, { + params: { accountId, mediaId }, + }); } /** 删除草稿 */ diff --git a/apps/web-antd/src/views/mp/autoReply/components/ReplyForm.vue b/apps/web-antd/src/views/mp/autoReply/components/ReplyForm.vue deleted file mode 100644 index d90e51a34..000000000 --- a/apps/web-antd/src/views/mp/autoReply/components/ReplyForm.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/mp/autoReply/data.ts b/apps/web-antd/src/views/mp/autoReply/data.ts index e3cbef345..8056cd2c4 100644 --- a/apps/web-antd/src/views/mp/autoReply/data.ts +++ b/apps/web-antd/src/views/mp/autoReply/data.ts @@ -1,13 +1,30 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeGridPropTypes } from '#/adapter/vxe-table'; +import type { MpAccountApi } from '#/api/mp/account'; import { markRaw } from 'vue'; import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; -import { WxAccountSelect } from '#/views/mp/modules/wx-account-select'; +import { getSimpleAccountList } from '#/api/mp/account'; +import { ReplySelect } from '#/views/mp/modules'; -import { MsgType } from './components/types'; +import { MsgType } from './types'; + +/** 关联数据 */ +let accountList: MpAccountApi.AccountSimple[] = []; +getSimpleAccountList().then((data) => (accountList = data)); + +const RequestMessageTypes = new Set([ + 'image', + 'link', + 'location', + 'shortvideo', + 'text', + 'video', + 'voice', +]); // 允许选择的请求消息类型 /** 获取表格列配置 */ export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns { @@ -76,13 +93,84 @@ export function useGridColumns(msgType: MsgType): VxeGridPropTypes.Columns { return columns; } +/** 新增/修改的表单 */ +export function useFormSchema(msgType: MsgType): VbenFormSchema[] { + const schema: VbenFormSchema[] = []; + + // 消息类型(仅消息回复显示) + if (msgType === MsgType.Message) { + schema.push({ + fieldName: 'requestMessageType', + label: '消息类型', + component: 'Select', + componentProps: { + placeholder: '请选择', + options: getDictOptions(DICT_TYPE.MP_MESSAGE_TYPE).filter((d) => + RequestMessageTypes.has(d.value as string), + ), + }, + }); + } + + // 匹配类型(仅关键词回复显示) + if (msgType === MsgType.Keyword) { + schema.push({ + fieldName: 'requestMatch', + label: '匹配类型', + component: 'Select', + componentProps: { + placeholder: '请选择匹配类型', + allowClear: true, + options: getDictOptions( + DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH, + 'number', + ), + }, + rules: 'required', + }); + } + + // 关键词(仅关键词回复显示) + if (msgType === MsgType.Keyword) { + schema.push({ + fieldName: 'requestKeyword', + label: '关键词', + component: 'Input', + componentProps: { + placeholder: '请输入内容', + allowClear: true, + }, + rules: 'required', + }); + } + // 回复消息 + schema.push({ + fieldName: 'reply', + label: '回复消息', + component: markRaw(ReplySelect), + // componentProps: { + // modelValue: { type: 'video', content: '12456' }, + // }, + // modelPropName: 'modelValue', + }); + return schema; +} + /** 列表的搜索表单 */ export function useGridFormSchema(): VbenFormSchema[] { return [ { fieldName: 'accountId', label: '公众号', - component: markRaw(WxAccountSelect), + component: 'ApiSelect', + componentProps: { + options: accountList.map((item) => ({ + label: item.name, + value: item.id, + })), + placeholder: '请选择公众号', + }, + defaultValue: accountList[0]?.id, }, ]; } diff --git a/apps/web-antd/src/views/mp/autoReply/index.vue b/apps/web-antd/src/views/mp/autoReply/index.vue index 504f79dd7..ae1043f2f 100644 --- a/apps/web-antd/src/views/mp/autoReply/index.vue +++ b/apps/web-antd/src/views/mp/autoReply/index.vue @@ -1,15 +1,9 @@ diff --git a/apps/web-antd/src/views/mp/autoReply/components/ReplyTable.vue b/apps/web-antd/src/views/mp/autoReply/modules/content.vue similarity index 70% rename from apps/web-antd/src/views/mp/autoReply/components/ReplyTable.vue rename to apps/web-antd/src/views/mp/autoReply/modules/content.vue index 5948a91cc..1d2a5187b 100644 --- a/apps/web-antd/src/views/mp/autoReply/components/ReplyTable.vue +++ b/apps/web-antd/src/views/mp/autoReply/modules/content.vue @@ -1,9 +1,6 @@ diff --git a/apps/web-antd/src/views/mp/autoReply/components/types.ts b/apps/web-antd/src/views/mp/autoReply/types.ts similarity index 100% rename from apps/web-antd/src/views/mp/autoReply/components/types.ts rename to apps/web-antd/src/views/mp/autoReply/types.ts diff --git a/apps/web-antd/src/views/mp/draft/data.ts b/apps/web-antd/src/views/mp/draft/data.ts index 2ee398fd1..cd8bf01c1 100644 --- a/apps/web-antd/src/views/mp/draft/data.ts +++ b/apps/web-antd/src/views/mp/draft/data.ts @@ -1,9 +1,12 @@ import type { VbenFormSchema } from '#/adapter/form'; import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MpAccountApi } from '#/api/mp/account'; -import { markRaw } from 'vue'; +import { getSimpleAccountList } from '#/api/mp/account'; -import { WxAccountSelect } from '#/views/mp/modules/wx-account-select'; +/** 关联数据 */ +let accountList: MpAccountApi.AccountSimple[] = []; +getSimpleAccountList().then((data) => (accountList = data)); /** 获取表格列配置 */ export function useGridColumns(): VxeTableGridOptions['columns'] { @@ -18,7 +21,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { field: 'updateTime', title: '更新时间', minWidth: 180, - formatter: 'formatDateTime', + formatter: 'formatDateTime', // TODO @YunaiV 接口返回数据不对,需要乘1000 }, { title: '操作', @@ -30,13 +33,21 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { } /** 列表的搜索表单 */ -// TODO @hw:这里的公众号选择,要改参考 /Users/yunai/Java/yudao-ui-admin-vben-v5/apps/web-antd/src/views/mp/tag/data.ts;相关联的代码还简单点~ +// DONE @hw:这里的公众号选择,要改参考 /apps/web-antd/src/views/mp/tag/data.ts;相关联的代码还简单点~ export function useGridFormSchema(): VbenFormSchema[] { return [ { fieldName: 'accountId', label: '公众号', - component: markRaw(WxAccountSelect), + component: 'ApiSelect', + componentProps: { + options: accountList.map((item) => ({ + label: item.name, + value: item.id, + })), + placeholder: '请选择公众号', + }, + defaultValue: accountList[0]?.id, }, ]; } diff --git a/apps/web-antd/src/views/mp/draft/index.vue b/apps/web-antd/src/views/mp/draft/index.vue index e1185adcc..bf28472d5 100644 --- a/apps/web-antd/src/views/mp/draft/index.vue +++ b/apps/web-antd/src/views/mp/draft/index.vue @@ -1,10 +1,8 @@ + + diff --git a/apps/web-antd/src/views/mp/modules/wx-msg/types.ts b/apps/web-antd/src/views/mp/modules/msg/types.ts similarity index 100% rename from apps/web-antd/src/views/mp/modules/wx-msg/types.ts rename to apps/web-antd/src/views/mp/modules/msg/types.ts diff --git a/apps/web-antd/src/views/mp/modules/wx-music/wx-music.vue b/apps/web-antd/src/views/mp/modules/music/music.vue similarity index 56% rename from apps/web-antd/src/views/mp/modules/wx-music/wx-music.vue rename to apps/web-antd/src/views/mp/modules/music/music.vue index 381292e6f..f0433d40f 100644 --- a/apps/web-antd/src/views/mp/modules/wx-music/wx-music.vue +++ b/apps/web-antd/src/views/mp/modules/music/music.vue @@ -2,7 +2,7 @@ 【微信消息 - 音乐】 --> + + diff --git a/apps/web-antd/src/views/mp/modules/wx-reply/wx-reply.vue b/apps/web-antd/src/views/mp/modules/reply/reply.vue similarity index 71% rename from apps/web-antd/src/views/mp/modules/wx-reply/wx-reply.vue rename to apps/web-antd/src/views/mp/modules/reply/reply.vue index 225e8ab35..233487ffe 100644 --- a/apps/web-antd/src/views/mp/modules/wx-reply/wx-reply.vue +++ b/apps/web-antd/src/views/mp/modules/reply/reply.vue @@ -10,21 +10,22 @@ diff --git a/apps/web-ele/src/api/erp/sale/customer/index.ts b/apps/web-ele/src/api/erp/sale/customer/index.ts new file mode 100644 index 000000000..1bcd1b31a --- /dev/null +++ b/apps/web-ele/src/api/erp/sale/customer/index.ts @@ -0,0 +1,66 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpCustomerApi { + /** 客户信息 */ + export interface Customer { + id?: number; // 客户编号 + name: string; // 客户名称 + contact: string; // 联系人 + mobile: string; // 手机号码 + telephone: string; // 联系电话 + email: string; // 电子邮箱 + fax: string; // 传真 + remark: string; // 备注 + status: number; // 开启状态 + sort: number; // 排序 + taxNo: string; // 纳税人识别号 + taxPercent: number; // 税率 + bankName: string; // 开户行 + bankAccount: string; // 开户账号 + bankAddress: string; // 开户地址 + } +} + +/** 查询客户分页 */ +export function getCustomerPage(params: PageParam) { + return requestClient.get>( + '/erp/customer/page', + { params }, + ); +} + +/** 查询客户精简列表 */ +export function getCustomerSimpleList() { + return requestClient.get( + '/erp/customer/simple-list', + ); +} + +/** 查询客户详情 */ +export function getCustomer(id: number) { + return requestClient.get( + `/erp/customer/get?id=${id}`, + ); +} + +/** 新增客户 */ +export function createCustomer(data: ErpCustomerApi.Customer) { + return requestClient.post('/erp/customer/create', data); +} + +/** 修改客户 */ +export function updateCustomer(data: ErpCustomerApi.Customer) { + return requestClient.put('/erp/customer/update', data); +} + +/** 删除客户 */ +export function deleteCustomer(id: number) { + return requestClient.delete(`/erp/customer/delete?id=${id}`); +} + +/** 导出客户 Excel */ +export function exportCustomer(params: any) { + return requestClient.download('/erp/customer/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/erp/sale/order/index.ts b/apps/web-ele/src/api/erp/sale/order/index.ts new file mode 100644 index 000000000..c190a3dc1 --- /dev/null +++ b/apps/web-ele/src/api/erp/sale/order/index.ts @@ -0,0 +1,98 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpSaleOrderApi { + /** 销售订单信息 */ + export interface SaleOrder { + id?: number; // 订单工单编号 + no: string; // 销售订单号 + customerId: number; // 客户编号 + accountId?: number; // 收款账户编号 + orderTime: Date; // 订单时间 + totalCount: number; // 合计数量 + totalPrice: number; // 合计金额,单位:元 + status: number; // 状态 + remark: string; // 备注 + outCount: number; // 销售出库数量 + fileUrl?: string; // 附件地址 + inCount?: number; // 采购入库数量 + returnCount: number; // 销售退货数量 + totalProductPrice?: number; // 产品金额,单位:元 + discountPercent?: number; // 优惠率,百分比 + discountPrice?: number; // 优惠金额,单位:元 + depositPrice?: number; // 定金金额,单位:元 + items?: SaleOrderItem[]; // 销售订单产品明细列表 + } + + /** 销售订单项 */ + export interface SaleOrderItem { + id?: number; // 订单项编号 + orderId?: number; // 采购订单编号 + productId?: number; // 产品编号 + productName?: string; // 产品名称 + productBarCode?: string; // 产品条码 + productUnitId?: number; // 产品单位编号 + productUnitName?: string; // 产品单位名称 + productPrice?: number; // 产品单价,单位:元 + totalProductPrice?: number; // 产品总价,单位:元 + count?: number; // 数量 + totalPrice?: number; // 总价,单位:元 + taxPercent?: number; // 税率,百分比 + taxPrice?: number; // 税额,单位:元 + totalTaxPrice?: number; // 含税总价,单位:元 + remark?: string; // 备注 + stockCount?: number; // 库存数量(显示字段) + } +} + +/** 查询销售订单分页 */ +export function getSaleOrderPage(params: PageParam) { + return requestClient.get>( + '/erp/sale-order/page', + { params }, + ); +} + +/** 查询销售订单详情 */ +export function getSaleOrder(id: number) { + return requestClient.get( + `/erp/sale-order/get?id=${id}`, + ); +} + +/** 查询销售订单项列表 */ +export function getSaleOrderItemListByOrderId(orderId: number) { + return requestClient.get( + `/erp/sale-order/item/list-by-order-id?orderId=${orderId}`, + ); +} + +/** 新增销售订单 */ +export function createSaleOrder(data: ErpSaleOrderApi.SaleOrder) { + return requestClient.post('/erp/sale-order/create', data); +} + +/** 修改销售订单 */ +export function updateSaleOrder(data: ErpSaleOrderApi.SaleOrder) { + return requestClient.put('/erp/sale-order/update', data); +} + +/** 更新销售订单的状态 */ +export function updateSaleOrderStatus(id: number, status: number) { + return requestClient.put('/erp/sale-order/update-status', null, { + params: { id, status }, + }); +} + +/** 删除销售订单 */ +export function deleteSaleOrder(ids: number[]) { + return requestClient.delete('/erp/sale-order/delete', { + params: { ids: ids.join(',') }, + }); +} + +/** 导出销售订单 Excel */ +export function exportSaleOrder(params: any) { + return requestClient.download('/erp/sale-order/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/erp/sale/out/index.ts b/apps/web-ele/src/api/erp/sale/out/index.ts new file mode 100644 index 000000000..a3e335af6 --- /dev/null +++ b/apps/web-ele/src/api/erp/sale/out/index.ts @@ -0,0 +1,95 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpSaleOutApi { + /** 销售出库信息 */ + export interface SaleOut { + id?: number; // 销售出库编号 + no?: string; // 销售出库号 + customerId?: number; // 客户编号 + saleUserId?: number; // 客户编号 + outTime?: Date; // 出库时间 + totalCount?: number; // 合计数量 + totalPrice?: number; // 合计金额,单位:元 + status?: number; // 状态 + remark?: string; // 备注 + discountPercent?: number; // 折扣百分比 + discountPrice?: number; // 折扣金额 + otherPrice?: number; // 其他费用 + totalProductPrice?: number; // 合计商品金额 + taxPrice?: number; // 合计税额 + totalTaxPrice?: number; // 合计税额 + fileUrl?: string; // 附件地址 + items?: SaleOutItem[]; + } + + /** 销售出库项 */ + export interface SaleOutItem { + count?: number; + id?: number; + orderItemId?: number; + productBarCode?: string; + productId?: number; + productName: string; + productPrice: number; + productUnitId?: number; + productUnitName?: string; + totalProductPrice?: number; + remark: string; + stockCount?: number; + taxPercent?: number; + taxPrice?: number; + totalPrice?: number; + warehouseId?: number; + outCount?: number; + } +} + +/** 查询销售出库分页 */ +export function getSaleOutPage(params: PageParam) { + return requestClient.get>( + '/erp/sale-out/page', + { + params, + }, + ); +} + +/** 查询销售出库详情 */ +export function getSaleOut(id: number) { + return requestClient.get(`/erp/sale-out/get?id=${id}`); +} + +/** 新增销售出库 */ +export function createSaleOut(data: ErpSaleOutApi.SaleOut) { + return requestClient.post('/erp/sale-out/create', data); +} + +/** 修改销售出库 */ +export function updateSaleOut(data: ErpSaleOutApi.SaleOut) { + return requestClient.put('/erp/sale-out/update', data); +} + +/** 更新销售出库的状态 */ +export function updateSaleOutStatus(id: number, status: number) { + return requestClient.put('/erp/sale-out/update-status', null, { + params: { id, status }, + }); +} + +/** 删除销售出库 */ +export function deleteSaleOut(ids: number[]) { + return requestClient.delete('/erp/sale-out/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出销售出库 Excel */ +export function exportSaleOut(params: any) { + return requestClient.download('/erp/sale-out/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/sale/return/index.ts b/apps/web-ele/src/api/erp/sale/return/index.ts new file mode 100644 index 000000000..a0624cba2 --- /dev/null +++ b/apps/web-ele/src/api/erp/sale/return/index.ts @@ -0,0 +1,96 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpSaleReturnApi { + /** 销售退货信息 */ + export interface SaleReturn { + id?: number; // 销售退货编号 + no?: string; // 销售退货号 + customerId?: number; // 客户编号 + returnTime?: Date; // 退货时间 + totalCount?: number; // 合计数量 + totalPrice?: number; // 合计金额,单位:元 + status?: number; // 状态 + remark?: string; // 备注 + discountPercent?: number; // 折扣百分比 + discountPrice?: number; // 折扣金额 + otherPrice?: number; // 其他费用 + totalProductPrice?: number; // 合计商品金额 + taxPrice?: number; // 合计税额 + totalTaxPrice?: number; // 合计税额 + fileUrl?: string; // 附件地址 + items?: SaleReturnItem[]; + } + + /** 销售退货项 */ + export interface SaleReturnItem { + count?: number; + id?: number; + orderItemId?: number; + productBarCode?: string; + productId?: number; + productName: string; + productPrice: number; + productUnitId?: number; + productUnitName?: string; + totalProductPrice?: number; + remark: string; + stockCount?: number; + taxPercent?: number; + taxPrice?: number; + totalPrice?: number; + warehouseId?: number; + returnCount?: number; + } +} + +/** 查询销售退货分页 */ +export function getSaleReturnPage(params: PageParam) { + return requestClient.get>( + '/erp/sale-return/page', + { + params, + }, + ); +} + +/** 查询销售退货详情 */ +export function getSaleReturn(id: number) { + return requestClient.get( + `/erp/sale-return/get?id=${id}`, + ); +} + +/** 新增销售退货 */ +export function createSaleReturn(data: ErpSaleReturnApi.SaleReturn) { + return requestClient.post('/erp/sale-return/create', data); +} + +/** 修改销售退货 */ +export function updateSaleReturn(data: ErpSaleReturnApi.SaleReturn) { + return requestClient.put('/erp/sale-return/update', data); +} + +/** 更新销售退货的状态 */ +export function updateSaleReturnStatus(id: number, status: number) { + return requestClient.put('/erp/sale-return/update-status', null, { + params: { id, status }, + }); +} + +/** 删除销售退货 */ +export function deleteSaleReturn(ids: number[]) { + return requestClient.delete('/erp/sale-return/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出销售退货 Excel */ +export function exportSaleReturn(params: any) { + return requestClient.download('/erp/sale-return/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/views/erp/finance/receipt/data.ts b/apps/web-ele/src/views/erp/finance/receipt/data.ts new file mode 100644 index 000000000..28f23c400 --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/data.ts @@ -0,0 +1,590 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { erpPriceInputFormatter } from '@vben/utils'; + +import { getAccountSimpleList } from '#/api/erp/finance/account'; +import { getCustomerSimpleList } from '#/api/erp/sale/customer'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '收款单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'receiptTime', + label: '收款时间', + component: 'DatePicker', + componentProps: { + disabled: formType === 'detail', + placeholder: '选择收款时间', + type: 'datetime', + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + disabled: formType === 'detail', + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'financeUserId', + label: '财务人员', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择财务人员', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '销售出库、退货单', + component: 'Input', + formItemClass: 'col-span-3', + }, + { + fieldName: 'accountId', + label: '收款账户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择收款账户', + allowClear: true, + showSearch: true, + api: getAccountSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'totalPrice', + label: '合计收款', + component: 'InputNumber', + componentProps: { + placeholder: '合计收款', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'discountPrice', + label: '优惠金额', + component: 'InputNumber', + componentProps: { + disabled: formType === 'detail', + placeholder: '请输入优惠金额', + precision: 2, + formatter: erpPriceInputFormatter, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'receiptPrice', + label: '实际收款', + component: 'InputNumber', + componentProps: { + placeholder: '实际收款', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + dependencies: { + triggerFields: ['totalPrice', 'discountPrice'], + componentProps: (values) => { + const totalPrice = values.totalPrice || 0; + const discountPrice = values.discountPrice || 0; + values.receiptPrice = totalPrice - discountPrice; + return {}; + }, + }, + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'bizNo', + title: '销售单据编号', + minWidth: 200, + }, + { + field: 'totalPrice', + title: '应收金额', + minWidth: 100, + formatter: 'formatAmount2', + }, + { + field: 'receiptedPrice', + title: '已收金额', + minWidth: 100, + formatter: 'formatAmount2', + }, + { + field: 'receiptPrice', + title: '本次收款', + minWidth: 115, + fixed: 'right', + slots: { default: 'receiptPrice' }, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '收款单号', + component: 'Input', + componentProps: { + placeholder: '请输入收款单号', + allowClear: true, + }, + }, + { + fieldName: 'receiptTime', + label: '收款时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'financeUserId', + label: '财务人员', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择财务人员', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'accountId', + label: '收款账户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择收款账户', + allowClear: true, + showSearch: true, + api: getAccountSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + { + fieldName: 'bizNo', + label: '销售单号', + component: 'Input', + componentProps: { + placeholder: '请输入销售单号', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '收款单号', + width: 180, + fixed: 'left', + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'receiptTime', + title: '收款时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'financeUserName', + title: '财务人员', + minWidth: 120, + }, + { + field: 'accountName', + title: '收款账户', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '合计收款', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'discountPrice', + title: '优惠金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'receiptPrice', + title: '实际收款', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 90, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 销售出库单选择表单的配置项 */ +export function useSaleOutGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '出库单号', + component: 'Input', + componentProps: { + placeholder: '请输入出库单号', + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '已自动选择客户', + }, + }, + { + fieldName: 'receiptStatus', + label: '收款状态', + component: 'Select', + componentProps: { + options: [ + { label: '未收款', value: 0 }, + { label: '部分收款', value: 1 }, + { label: '全部收款', value: 2 }, + ], + placeholder: '请选择收款状态', + allowClear: true, + }, + }, + ]; +} + +/** 销售出库单选择列表的字段 */ +export function useSaleOutGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '出库单号', + width: 200, + fixed: 'left', + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'outTime', + title: '出库时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'totalPrice', + title: '应收金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'receiptPrice', + title: '已收金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'unReceiptPrice', + title: '未收金额', + formatter: ({ row }) => { + return erpPriceInputFormatter(row.totalPrice - row.receiptPrice || 0); + }, + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + ]; +} + +/** 销售退货单选择表单的配置项 */ +export function useSaleReturnGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '退货单号', + component: 'Input', + componentProps: { + placeholder: '请输入退货单号', + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '已自动选择客户', + }, + }, + { + fieldName: 'refundStatus', + label: '退款状态', + component: 'Select', + componentProps: { + options: [ + { label: '未退款', value: 0 }, + { label: '部分退款', value: 1 }, + { label: '全部退款', value: 2 }, + ], + placeholder: '请选择退款状态', + allowClear: true, + }, + }, + ]; +} + +/** 销售退货单选择列表的字段 */ +export function useSaleReturnGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '退货单号', + width: 200, + fixed: 'left', + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'returnTime', + title: '退货时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'totalPrice', + title: '应退金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'refundPrice', + title: '已退金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'unRefundPrice', + title: '未退金额', + formatter: ({ row }) => { + return erpPriceInputFormatter(row.totalPrice - row.refundPrice || 0); + }, + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/finance/receipt/index.vue b/apps/web-ele/src/views/erp/finance/receipt/index.vue new file mode 100644 index 000000000..53a84eecf --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/index.vue @@ -0,0 +1,226 @@ + + + diff --git a/apps/web-ele/src/views/erp/finance/receipt/modules/form.vue b/apps/web-ele/src/views/erp/finance/receipt/modules/form.vue new file mode 100644 index 000000000..8464cceb4 --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/modules/form.vue @@ -0,0 +1,209 @@ + + + diff --git a/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue b/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue new file mode 100644 index 000000000..c82383f32 --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/modules/item-form.vue @@ -0,0 +1,299 @@ + + + diff --git a/apps/web-ele/src/views/erp/finance/receipt/modules/sale-out-select.vue b/apps/web-ele/src/views/erp/finance/receipt/modules/sale-out-select.vue new file mode 100644 index 000000000..b5d2def59 --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/modules/sale-out-select.vue @@ -0,0 +1,110 @@ + + + diff --git a/apps/web-ele/src/views/erp/finance/receipt/modules/sale-return-select.vue b/apps/web-ele/src/views/erp/finance/receipt/modules/sale-return-select.vue new file mode 100644 index 000000000..8bef7177d --- /dev/null +++ b/apps/web-ele/src/views/erp/finance/receipt/modules/sale-return-select.vue @@ -0,0 +1,114 @@ + + + From 8d3dd06266abef1b95f112137a0fc16fed6d741f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 15:48:39 +0800 Subject: [PATCH 11/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=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 @@ + + + From 008f7cdbbf5c897b4359e8a49d887a1bfafe7945 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 16:29:15 +0800 Subject: [PATCH 12/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91stock=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8810%=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web-antd/src/api/erp/stock/check/index.ts | 43 +-- apps/web-antd/src/api/erp/stock/in/index.ts | 39 +-- apps/web-antd/src/api/erp/stock/move/index.ts | 38 +- apps/web-antd/src/api/erp/stock/out/index.ts | 39 +-- .../src/api/erp/stock/record/index.ts | 20 +- .../web-antd/src/api/erp/stock/stock/index.ts | 48 +-- .../src/api/erp/stock/warehouse/index.ts | 10 +- apps/web-ele/src/api/erp/stock/check/index.ts | 87 +++++ apps/web-ele/src/api/erp/stock/in/index.ts | 86 +++++ apps/web-ele/src/api/erp/stock/move/index.ts | 87 +++++ apps/web-ele/src/api/erp/stock/out/index.ts | 85 +++++ .../web-ele/src/api/erp/stock/record/index.ts | 31 ++ apps/web-ele/src/api/erp/stock/stock/index.ts | 51 +++ .../src/api/erp/stock/warehouse/index.ts | 71 ++++ .../web-ele/src/views/erp/stock/check/data.ts | 305 ++++++++++++++++ .../src/views/erp/stock/check/index.vue | 215 ++++++++++++ .../views/erp/stock/check/modules/form.vue | 132 +++++++ .../erp/stock/check/modules/item-form.vue | 313 +++++++++++++++++ apps/web-ele/src/views/erp/stock/in/data.ts | 330 ++++++++++++++++++ apps/web-ele/src/views/erp/stock/in/index.vue | 212 +++++++++++ .../src/views/erp/stock/in/modules/form.vue | 128 +++++++ .../views/erp/stock/in/modules/item-form.vue | 302 ++++++++++++++++ apps/web-ele/src/views/erp/stock/move/data.ts | 316 +++++++++++++++++ .../src/views/erp/stock/move/index.vue | 215 ++++++++++++ .../src/views/erp/stock/move/modules/form.vue | 132 +++++++ .../erp/stock/move/modules/item-form.vue | 323 +++++++++++++++++ apps/web-ele/src/views/erp/stock/out/data.ts | 330 ++++++++++++++++++ .../web-ele/src/views/erp/stock/out/index.vue | 215 ++++++++++++ .../src/views/erp/stock/out/modules/form.vue | 132 +++++++ .../views/erp/stock/out/modules/item-form.vue | 300 ++++++++++++++++ .../src/views/erp/stock/record/data.ts | 133 +++++++ .../src/views/erp/stock/record/index.vue | 79 +++++ .../web-ele/src/views/erp/stock/stock/data.ts | 69 ++++ .../src/views/erp/stock/stock/index.vue | 79 +++++ .../src/views/erp/stock/warehouse/data.ts | 209 +++++++++++ .../src/views/erp/stock/warehouse/index.vue | 178 ++++++++++ .../erp/stock/warehouse/modules/form.vue | 88 +++++ 37 files changed, 5282 insertions(+), 188 deletions(-) create mode 100644 apps/web-ele/src/api/erp/stock/check/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/in/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/move/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/out/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/record/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/stock/index.ts create mode 100644 apps/web-ele/src/api/erp/stock/warehouse/index.ts create mode 100644 apps/web-ele/src/views/erp/stock/check/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/check/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/check/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/stock/check/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/stock/in/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/in/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/in/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/stock/in/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/stock/move/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/move/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/move/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/stock/move/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/stock/out/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/out/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/out/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/stock/out/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/stock/record/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/record/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/stock/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/stock/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/warehouse/data.ts create mode 100644 apps/web-ele/src/views/erp/stock/warehouse/index.vue create mode 100644 apps/web-ele/src/views/erp/stock/warehouse/modules/form.vue diff --git a/apps/web-antd/src/api/erp/stock/check/index.ts b/apps/web-antd/src/api/erp/stock/check/index.ts index 386948432..b6f9d0bea 100644 --- a/apps/web-antd/src/api/erp/stock/check/index.ts +++ b/apps/web-antd/src/api/erp/stock/check/index.ts @@ -18,6 +18,7 @@ export namespace ErpStockCheckApi { items?: StockCheckItem[]; // 盘点产品清单 } + /** 库存盘点项 */ export interface StockCheckItem { id?: number; // 编号 warehouseId?: number; // 仓库编号 @@ -33,20 +34,10 @@ export namespace ErpStockCheckApi { stockCount?: number; // 账面库存 remark?: string; // 备注 } - - /** 库存盘点单分页查询参数 */ - export interface StockCheckPageParams extends PageParam { - no?: string; - status?: number; - } } -/** - * 查询库存盘点单分页 - */ -export function getStockCheckPage( - params: ErpStockCheckApi.StockCheckPageParams, -) { +/** 查询库存盘点单分页 */ +export function getStockCheckPage(params: PageParam) { return requestClient.get>( '/erp/stock-check/page', { @@ -55,41 +46,31 @@ export function getStockCheckPage( ); } -/** - * 查询库存盘点单详情 - */ +/** 查询库存盘点单详情 */ export function getStockCheck(id: number) { return requestClient.get( `/erp/stock-check/get?id=${id}`, ); } -/** - * 新增库存盘点单 - */ +/** 新增库存盘点单 */ export function createStockCheck(data: ErpStockCheckApi.StockCheck) { return requestClient.post('/erp/stock-check/create', data); } -/** - * 修改库存盘点单 - */ +/** 修改库存盘点单 */ export function updateStockCheck(data: ErpStockCheckApi.StockCheck) { return requestClient.put('/erp/stock-check/update', data); } -/** - * 更新库存盘点单的状态 - */ +/** 更新库存盘点单的状态 */ export function updateStockCheckStatus(id: number, status: number) { return requestClient.put('/erp/stock-check/update-status', null, { params: { id, status }, }); } -/** - * 删除库存盘点单 - */ +/** 删除库存盘点 */ export function deleteStockCheck(ids: number[]) { return requestClient.delete('/erp/stock-check/delete', { params: { @@ -98,12 +79,8 @@ export function deleteStockCheck(ids: number[]) { }); } -/** - * 导出库存盘点单 Excel - */ -export function exportStockCheck( - params: ErpStockCheckApi.StockCheckPageParams, -) { +/** 导出库存盘点单 Excel */ +export function exportStockCheck(params: any) { return requestClient.download('/erp/stock-check/export-excel', { params, }); diff --git a/apps/web-antd/src/api/erp/stock/in/index.ts b/apps/web-antd/src/api/erp/stock/in/index.ts index 18e109314..e68c05b36 100644 --- a/apps/web-antd/src/api/erp/stock/in/index.ts +++ b/apps/web-antd/src/api/erp/stock/in/index.ts @@ -35,19 +35,10 @@ export namespace ErpStockInApi { stockCount?: number; // 库存数量 remark?: string; // 备注 } - - /** 其它入库单分页查询参数 */ - export interface StockInPageParams extends PageParam { - no?: string; - supplierId?: number; - status?: number; - } } -/** - * 查询其它入库单分页 - */ -export function getStockInPage(params: ErpStockInApi.StockInPageParams) { +/** 查询其它入库单分页 */ +export function getStockInPage(params: PageParam) { return requestClient.get>( '/erp/stock-in/page', { @@ -56,39 +47,29 @@ export function getStockInPage(params: ErpStockInApi.StockInPageParams) { ); } -/** - * 查询其它入库单详情 - */ +/** 查询其它入库单详情 */ export function getStockIn(id: number) { return requestClient.get(`/erp/stock-in/get?id=${id}`); } -/** - * 新增其它入库单 - */ +/** 新增其它入库单 */ export function createStockIn(data: ErpStockInApi.StockIn) { return requestClient.post('/erp/stock-in/create', data); } -/** - * 修改其它入库单 - */ +/** 修改其它入库单 */ export function updateStockIn(data: ErpStockInApi.StockIn) { return requestClient.put('/erp/stock-in/update', data); } -/** - * 更新其它入库单的状态 - */ +/** 更新其它入库单的状态 */ export function updateStockInStatus(id: number, status: number) { return requestClient.put('/erp/stock-in/update-status', null, { params: { id, status }, }); } -/** - * 删除其它入库单 - */ +/** 删除其它入库单 */ export function deleteStockIn(ids: number[]) { return requestClient.delete('/erp/stock-in/delete', { params: { @@ -97,10 +78,8 @@ export function deleteStockIn(ids: number[]) { }); } -/** - * 导出其它入库单 Excel - */ -export function exportStockIn(params: ErpStockInApi.StockInPageParams) { +/** 导出其它入库单 Excel */ +export function exportStockIn(params: any) { return requestClient.download('/erp/stock-in/export-excel', { params, }); diff --git a/apps/web-antd/src/api/erp/stock/move/index.ts b/apps/web-antd/src/api/erp/stock/move/index.ts index 04bb46ee4..0120a9b45 100644 --- a/apps/web-antd/src/api/erp/stock/move/index.ts +++ b/apps/web-antd/src/api/erp/stock/move/index.ts @@ -36,18 +36,10 @@ export namespace ErpStockMoveApi { toWarehouseId?: number; // 目标仓库ID totalPrice?: number; // 总价 } - - /** 库存调拨单分页查询参数 */ - export interface StockMovePageParams extends PageParam { - no?: string; - status?: number; - } } -/** - * 查询库存调拨单分页 - */ -export function getStockMovePage(params: ErpStockMoveApi.StockMovePageParams) { +/** 查询库存调拨单分页 */ +export function getStockMovePage(params: PageParam) { return requestClient.get>( '/erp/stock-move/page', { @@ -56,41 +48,31 @@ export function getStockMovePage(params: ErpStockMoveApi.StockMovePageParams) { ); } -/** - * 查询库存调拨单详情 - */ +/** 查询库存调拨单详情 */ export function getStockMove(id: number) { return requestClient.get( `/erp/stock-move/get?id=${id}`, ); } -/** - * 新增库存调拨单 - */ +/** 新增库存调拨单 */ export function createStockMove(data: ErpStockMoveApi.StockMove) { return requestClient.post('/erp/stock-move/create', data); } -/** - * 修改库存调拨单 - */ +/** 修改库存调拨单 */ export function updateStockMove(data: ErpStockMoveApi.StockMove) { return requestClient.put('/erp/stock-move/update', data); } -/** - * 更新库存调拨单的状态 - */ +/** 更新库存调拨单的状态 */ export function updateStockMoveStatus(id: number, status: number) { return requestClient.put('/erp/stock-move/update-status', null, { params: { id, status }, }); } -/** - * 删除库存调拨单 - */ +/** 删除库存调拨单 */ export function deleteStockMove(ids: number[]) { return requestClient.delete('/erp/stock-move/delete', { params: { @@ -99,9 +81,7 @@ export function deleteStockMove(ids: number[]) { }); } -/** - * 导出库存调拨单 Excel - */ -export function exportStockMove(params: ErpStockMoveApi.StockMovePageParams) { +/** 导出库存调拨单 Excel */ +export function exportStockMove(params: any) { return requestClient.download('/erp/stock-move/export-excel', { params }); } diff --git a/apps/web-antd/src/api/erp/stock/out/index.ts b/apps/web-antd/src/api/erp/stock/out/index.ts index 2f64ff867..1ecb89233 100644 --- a/apps/web-antd/src/api/erp/stock/out/index.ts +++ b/apps/web-antd/src/api/erp/stock/out/index.ts @@ -32,19 +32,10 @@ export namespace ErpStockOutApi { stockCount?: number; // 库存数量 remark?: string; // 备注 } - - /** 其它出库单分页查询参数 */ - export interface StockOutPageParams extends PageParam { - no?: string; - customerId?: number; - status?: number; - } } -/** - * 查询其它出库单分页 - */ -export function getStockOutPage(params: ErpStockOutApi.StockOutPageParams) { +/** 查询其它出库单分页 */ +export function getStockOutPage(params: PageParam) { return requestClient.get>( '/erp/stock-out/page', { @@ -53,41 +44,31 @@ export function getStockOutPage(params: ErpStockOutApi.StockOutPageParams) { ); } -/** - * 查询其它出库单详情 - */ +/** 查询其它出库单详情 */ export function getStockOut(id: number) { return requestClient.get( `/erp/stock-out/get?id=${id}`, ); } -/** - * 新增其它出库单 - */ +/** 新增其它出库单 */ export function createStockOut(data: ErpStockOutApi.StockOut) { return requestClient.post('/erp/stock-out/create', data); } -/** - * 修改其它出库单 - */ +/** 修改其它出库单 */ export function updateStockOut(data: ErpStockOutApi.StockOut) { return requestClient.put('/erp/stock-out/update', data); } -/** - * 更新其它出库单的状态 - */ +/** 更新其它出库单的状态 */ export function updateStockOutStatus(id: number, status: number) { return requestClient.put('/erp/stock-out/update-status', null, { params: { id, status }, }); } -/** - * 删除其它出库单 - */ +/** 删除其它出库单 */ export function deleteStockOut(ids: number[]) { return requestClient.delete('/erp/stock-out/delete', { params: { @@ -96,10 +77,8 @@ export function deleteStockOut(ids: number[]) { }); } -/** - * 导出其它出库单 Excel - */ -export function exportStockOut(params: ErpStockOutApi.StockOutPageParams) { +/** 导出其它出库单 Excel */ +export function exportStockOut(params: any) { return requestClient.download('/erp/stock-out/export-excel', { params, }); diff --git a/apps/web-antd/src/api/erp/stock/record/index.ts b/apps/web-antd/src/api/erp/stock/record/index.ts index 364091bfb..30bc9dae0 100644 --- a/apps/web-antd/src/api/erp/stock/record/index.ts +++ b/apps/web-antd/src/api/erp/stock/record/index.ts @@ -3,7 +3,7 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace ErpStockRecordApi { - /** ERP 产品库存明细 */ + /** 产品库存明细 */ export interface StockRecord { id?: number; // 编号 productId: number; // 产品编号 @@ -15,32 +15,16 @@ export namespace ErpStockRecordApi { bizItemId: number; // 业务项编号 bizNo: string; // 业务单号 } - - /** 库存记录分页查询参数 */ - export interface StockRecordPageParam extends PageParam { - productId?: number; - warehouseId?: number; - bizType?: number; - } } /** 查询产品库存明细分页 */ -export function getStockRecordPage( - params: ErpStockRecordApi.StockRecordPageParam, -) { +export function getStockRecordPage(params: PageParam) { return requestClient.get>( '/erp/stock-record/page', { params }, ); } -/** 查询产品库存明细详情 */ -export function getStockRecord(id: number) { - return requestClient.get( - `/erp/stock-record/get?id=${id}`, - ); -} - /** 导出产品库存明细 Excel */ export function exportStockRecord(params: any) { return requestClient.download('/erp/stock-record/export-excel', { params }); diff --git a/apps/web-antd/src/api/erp/stock/stock/index.ts b/apps/web-antd/src/api/erp/stock/stock/index.ts index df8aaaa9b..7335c6d34 100644 --- a/apps/web-antd/src/api/erp/stock/stock/index.ts +++ b/apps/web-antd/src/api/erp/stock/stock/index.ts @@ -11,49 +11,21 @@ export namespace ErpStockApi { count: number; // 库存数量 } - /** 产品库存分页查询参数 */ - export interface StockPageParams extends PageParam { - productId?: number; - warehouseId?: number; - } - /** 产品库存查询参数 */ - export interface StockQueryParams { + export interface StockQueryReqVO { productId: number; warehouseId: number; } } -/** - * 查询产品库存分页 - */ -export function getStockPage(params: ErpStockApi.StockPageParams) { +/** 查询产品库存分页 */ +export function getStockPage(params: PageParam) { return requestClient.get>('/erp/stock/page', { params, }); } -/** - * 查询产品库存详情 - */ -export function getStock(id: number) { - return requestClient.get(`/erp/stock/get?id=${id}`); -} - -/** - * 根据产品和仓库查询库存详情 - */ -export function getStockByProductAndWarehouse( - params: ErpStockApi.StockQueryParams, -) { - return requestClient.get('/erp/stock/get', { - params, - }); -} - -/** - * 获得产品库存数量 - */ +/** 获得产品库存数量 */ export function getStockCount(productId: number, warehouseId?: number) { const params: any = { productId }; if (warehouseId !== undefined) { @@ -64,19 +36,15 @@ export function getStockCount(productId: number, warehouseId?: number) { }); } -/** - * 导出产品库存 Excel - */ -export function exportStock(params: ErpStockApi.StockPageParams) { +/** 导出产品库存 Excel */ +export function exportStock(params: any) { return requestClient.download('/erp/stock/export-excel', { params, }); } -/** - * 获取库存数量 - */ -export function getWarehouseStockCount(params: ErpStockApi.StockQueryParams) { +/** 获取库存数量 */ +export function getWarehouseStockCount(params: ErpStockApi.StockQueryReqVO) { return requestClient.get('/erp/stock/get-count', { params, }); diff --git a/apps/web-antd/src/api/erp/stock/warehouse/index.ts b/apps/web-antd/src/api/erp/stock/warehouse/index.ts index a1cac8ead..e5d6e1a49 100644 --- a/apps/web-antd/src/api/erp/stock/warehouse/index.ts +++ b/apps/web-antd/src/api/erp/stock/warehouse/index.ts @@ -3,7 +3,7 @@ import type { PageParam, PageResult } from '@vben/request'; import { requestClient } from '#/api/request'; export namespace ErpWarehouseApi { - /** ERP 仓库信息 */ + /** 仓库信息 */ export interface Warehouse { id?: number; // 仓库编号 name: string; // 仓库名称 @@ -16,16 +16,10 @@ export namespace ErpWarehouseApi { status: number; // 开启状态 defaultStatus: boolean; // 是否默认 } - - /** 仓库分页查询参数 */ - export interface WarehousePageParam extends PageParam { - name?: string; - status?: number; - } } /** 查询仓库分页 */ -export function getWarehousePage(params: ErpWarehouseApi.WarehousePageParam) { +export function getWarehousePage(params: PageParam) { return requestClient.get>( '/erp/warehouse/page', { params }, diff --git a/apps/web-ele/src/api/erp/stock/check/index.ts b/apps/web-ele/src/api/erp/stock/check/index.ts new file mode 100644 index 000000000..b6f9d0bea --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/check/index.ts @@ -0,0 +1,87 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockCheckApi { + /** 库存盘点单信息 */ + export interface StockCheck { + id?: number; // 盘点编号 + no: string; // 盘点单号 + checkTime: Date; // 盘点时间 + totalCount: number; // 合计数量 + totalPrice: number; // 合计金额,单位:元 + status: number; // 状态 + remark: string; // 备注 + fileUrl?: string; // 附件 + productNames?: string; // 产品信息 + creatorName?: string; // 创建人 + items?: StockCheckItem[]; // 盘点产品清单 + } + + /** 库存盘点项 */ + export interface StockCheckItem { + id?: number; // 编号 + warehouseId?: number; // 仓库编号 + productId?: number; // 产品编号 + productName?: string; // 产品名称 + productUnitId?: number; // 产品单位编号 + productUnitName?: string; // 产品单位名称 + productBarCode?: string; // 产品条码 + count?: number; // 盈亏数量 + actualCount?: number; // 实际库存 + productPrice?: number; // 产品单价 + totalPrice?: number; // 总价 + stockCount?: number; // 账面库存 + remark?: string; // 备注 + } +} + +/** 查询库存盘点单分页 */ +export function getStockCheckPage(params: PageParam) { + return requestClient.get>( + '/erp/stock-check/page', + { + params, + }, + ); +} + +/** 查询库存盘点单详情 */ +export function getStockCheck(id: number) { + return requestClient.get( + `/erp/stock-check/get?id=${id}`, + ); +} + +/** 新增库存盘点单 */ +export function createStockCheck(data: ErpStockCheckApi.StockCheck) { + return requestClient.post('/erp/stock-check/create', data); +} + +/** 修改库存盘点单 */ +export function updateStockCheck(data: ErpStockCheckApi.StockCheck) { + return requestClient.put('/erp/stock-check/update', data); +} + +/** 更新库存盘点单的状态 */ +export function updateStockCheckStatus(id: number, status: number) { + return requestClient.put('/erp/stock-check/update-status', null, { + params: { id, status }, + }); +} + +/** 删除库存盘点 */ +export function deleteStockCheck(ids: number[]) { + return requestClient.delete('/erp/stock-check/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出库存盘点单 Excel */ +export function exportStockCheck(params: any) { + return requestClient.download('/erp/stock-check/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/stock/in/index.ts b/apps/web-ele/src/api/erp/stock/in/index.ts new file mode 100644 index 000000000..e68c05b36 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/in/index.ts @@ -0,0 +1,86 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockInApi { + /** 其它入库单信息 */ + export interface StockIn { + id?: number; // 入库编号 + no: string; // 入库单号 + supplierId: number; // 供应商编号 + supplierName?: string; // 供应商名称 + inTime: Date; // 入库时间 + totalCount: number; // 合计数量 + totalPrice: number; // 合计金额,单位:元 + status: number; // 状态 + remark: string; // 备注 + fileUrl?: string; // 附件 + productNames?: string; // 产品信息 + creatorName?: string; // 创建人 + items?: StockInItem[]; // 入库产品清单 + } + + /** 其它入库单产品信息 */ + export interface StockInItem { + id?: number; // 编号 + warehouseId: number; // 仓库编号 + productId: number; // 产品编号 + productName?: string; // 产品名称 + productUnitId?: number; // 产品单位编号 + productUnitName?: string; // 产品单位名称 + productBarCode?: string; // 产品条码 + count: number; // 数量 + productPrice: number; // 产品单价 + totalPrice: number; // 总价 + stockCount?: number; // 库存数量 + remark?: string; // 备注 + } +} + +/** 查询其它入库单分页 */ +export function getStockInPage(params: PageParam) { + return requestClient.get>( + '/erp/stock-in/page', + { + params, + }, + ); +} + +/** 查询其它入库单详情 */ +export function getStockIn(id: number) { + return requestClient.get(`/erp/stock-in/get?id=${id}`); +} + +/** 新增其它入库单 */ +export function createStockIn(data: ErpStockInApi.StockIn) { + return requestClient.post('/erp/stock-in/create', data); +} + +/** 修改其它入库单 */ +export function updateStockIn(data: ErpStockInApi.StockIn) { + return requestClient.put('/erp/stock-in/update', data); +} + +/** 更新其它入库单的状态 */ +export function updateStockInStatus(id: number, status: number) { + return requestClient.put('/erp/stock-in/update-status', null, { + params: { id, status }, + }); +} + +/** 删除其它入库单 */ +export function deleteStockIn(ids: number[]) { + return requestClient.delete('/erp/stock-in/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出其它入库单 Excel */ +export function exportStockIn(params: any) { + return requestClient.download('/erp/stock-in/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/stock/move/index.ts b/apps/web-ele/src/api/erp/stock/move/index.ts new file mode 100644 index 000000000..0120a9b45 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/move/index.ts @@ -0,0 +1,87 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockMoveApi { + /** 库存调拨单信息 */ + export interface StockMove { + id?: number; // 调拨编号 + no: string; // 调拨单号 + outTime: Date; // 调拨时间 + totalCount: number; // 合计数量 + totalPrice: number; // 合计金额,单位:元 + status: number; // 状态 + remark: string; // 备注 + fileUrl?: string; // 附件 + fromWarehouseId?: number; // 来源仓库编号 + createTime: Date; // 创建时间 + creator: string; // 创建人 + creatorName: string; // 创建人名称 + productNames: string; // 产品名称 + items?: StockMoveItem[]; // 子表信息 + } + + /** 库存调拨单子表信息 */ + export interface StockMoveItem { + count: number; // 数量 + fromWarehouseId?: number; // 来源仓库ID + id?: number; // ID + productBarCode: string; // 产品条形码 + productId?: number; // 产品ID + productName?: string; // 产品名称 + productPrice: number; // 产品单价 + productUnitName?: string; // 产品单位 + remark?: string; // 备注 + stockCount: number; // 库存数量 + toWarehouseId?: number; // 目标仓库ID + totalPrice?: number; // 总价 + } +} + +/** 查询库存调拨单分页 */ +export function getStockMovePage(params: PageParam) { + return requestClient.get>( + '/erp/stock-move/page', + { + params, + }, + ); +} + +/** 查询库存调拨单详情 */ +export function getStockMove(id: number) { + return requestClient.get( + `/erp/stock-move/get?id=${id}`, + ); +} + +/** 新增库存调拨单 */ +export function createStockMove(data: ErpStockMoveApi.StockMove) { + return requestClient.post('/erp/stock-move/create', data); +} + +/** 修改库存调拨单 */ +export function updateStockMove(data: ErpStockMoveApi.StockMove) { + return requestClient.put('/erp/stock-move/update', data); +} + +/** 更新库存调拨单的状态 */ +export function updateStockMoveStatus(id: number, status: number) { + return requestClient.put('/erp/stock-move/update-status', null, { + params: { id, status }, + }); +} + +/** 删除库存调拨单 */ +export function deleteStockMove(ids: number[]) { + return requestClient.delete('/erp/stock-move/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出库存调拨单 Excel */ +export function exportStockMove(params: any) { + return requestClient.download('/erp/stock-move/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/erp/stock/out/index.ts b/apps/web-ele/src/api/erp/stock/out/index.ts new file mode 100644 index 000000000..1ecb89233 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/out/index.ts @@ -0,0 +1,85 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockOutApi { + /** 其它出库单信息 */ + export interface StockOut { + id?: number; // 出库编号 + no: string; // 出库单号 + customerId: number; // 客户编号 + outTime: Date; // 出库时间 + totalCount: number; // 合计数量 + totalPrice: number; // 合计金额,单位:元 + status: number; // 状态 + remark: string; // 备注 + fileUrl?: string; // 附件 + items?: StockOutItem[]; // 出库产品清单 + } + + /** 其它出库单产品信息 */ + export interface StockOutItem { + id?: number; // 编号 + warehouseId?: number; // 仓库编号 + productId?: number; // 产品编号 + productName?: string; // 产品名称 + productUnitId?: number; // 产品单位编号 + productUnitName?: string; // 产品单位名称 + productBarCode?: string; // 产品条码 + count: number; // 数量 + productPrice: number; // 产品单价 + totalPrice: number; // 总价 + stockCount?: number; // 库存数量 + remark?: string; // 备注 + } +} + +/** 查询其它出库单分页 */ +export function getStockOutPage(params: PageParam) { + return requestClient.get>( + '/erp/stock-out/page', + { + params, + }, + ); +} + +/** 查询其它出库单详情 */ +export function getStockOut(id: number) { + return requestClient.get( + `/erp/stock-out/get?id=${id}`, + ); +} + +/** 新增其它出库单 */ +export function createStockOut(data: ErpStockOutApi.StockOut) { + return requestClient.post('/erp/stock-out/create', data); +} + +/** 修改其它出库单 */ +export function updateStockOut(data: ErpStockOutApi.StockOut) { + return requestClient.put('/erp/stock-out/update', data); +} + +/** 更新其它出库单的状态 */ +export function updateStockOutStatus(id: number, status: number) { + return requestClient.put('/erp/stock-out/update-status', null, { + params: { id, status }, + }); +} + +/** 删除其它出库单 */ +export function deleteStockOut(ids: number[]) { + return requestClient.delete('/erp/stock-out/delete', { + params: { + ids: ids.join(','), + }, + }); +} + +/** 导出其它出库单 Excel */ +export function exportStockOut(params: any) { + return requestClient.download('/erp/stock-out/export-excel', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/stock/record/index.ts b/apps/web-ele/src/api/erp/stock/record/index.ts new file mode 100644 index 000000000..30bc9dae0 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/record/index.ts @@ -0,0 +1,31 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockRecordApi { + /** 产品库存明细 */ + export interface StockRecord { + id?: number; // 编号 + productId: number; // 产品编号 + warehouseId: number; // 仓库编号 + count: number; // 出入库数量 + totalCount: number; // 总库存量 + bizType: number; // 业务类型 + bizId: number; // 业务编号 + bizItemId: number; // 业务项编号 + bizNo: string; // 业务单号 + } +} + +/** 查询产品库存明细分页 */ +export function getStockRecordPage(params: PageParam) { + return requestClient.get>( + '/erp/stock-record/page', + { params }, + ); +} + +/** 导出产品库存明细 Excel */ +export function exportStockRecord(params: any) { + return requestClient.download('/erp/stock-record/export-excel', { params }); +} diff --git a/apps/web-ele/src/api/erp/stock/stock/index.ts b/apps/web-ele/src/api/erp/stock/stock/index.ts new file mode 100644 index 000000000..7335c6d34 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/stock/index.ts @@ -0,0 +1,51 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpStockApi { + /** 产品库存信息 */ + export interface Stock { + id?: number; // 编号 + productId: number; // 产品编号 + warehouseId: number; // 仓库编号 + count: number; // 库存数量 + } + + /** 产品库存查询参数 */ + export interface StockQueryReqVO { + productId: number; + warehouseId: number; + } +} + +/** 查询产品库存分页 */ +export function getStockPage(params: PageParam) { + return requestClient.get>('/erp/stock/page', { + params, + }); +} + +/** 获得产品库存数量 */ +export function getStockCount(productId: number, warehouseId?: number) { + const params: any = { productId }; + if (warehouseId !== undefined) { + params.warehouseId = warehouseId; + } + return requestClient.get('/erp/stock/get-count', { + params, + }); +} + +/** 导出产品库存 Excel */ +export function exportStock(params: any) { + return requestClient.download('/erp/stock/export-excel', { + params, + }); +} + +/** 获取库存数量 */ +export function getWarehouseStockCount(params: ErpStockApi.StockQueryReqVO) { + return requestClient.get('/erp/stock/get-count', { + params, + }); +} diff --git a/apps/web-ele/src/api/erp/stock/warehouse/index.ts b/apps/web-ele/src/api/erp/stock/warehouse/index.ts new file mode 100644 index 000000000..e5d6e1a49 --- /dev/null +++ b/apps/web-ele/src/api/erp/stock/warehouse/index.ts @@ -0,0 +1,71 @@ +import type { PageParam, PageResult } from '@vben/request'; + +import { requestClient } from '#/api/request'; + +export namespace ErpWarehouseApi { + /** 仓库信息 */ + export interface Warehouse { + id?: number; // 仓库编号 + name: string; // 仓库名称 + address: string; // 仓库地址 + sort: number; // 排序 + remark: string; // 备注 + principal: string; // 负责人 + warehousePrice: number; // 仓储费,单位:元 + truckagePrice: number; // 搬运费,单位:元 + status: number; // 开启状态 + defaultStatus: boolean; // 是否默认 + } +} + +/** 查询仓库分页 */ +export function getWarehousePage(params: PageParam) { + return requestClient.get>( + '/erp/warehouse/page', + { params }, + ); +} + +/** 查询仓库精简列表 */ +export function getWarehouseSimpleList() { + return requestClient.get( + '/erp/warehouse/simple-list', + ); +} + +/** 查询仓库详情 */ +export function getWarehouse(id: number) { + return requestClient.get( + `/erp/warehouse/get?id=${id}`, + ); +} + +/** 新增仓库 */ +export function createWarehouse(data: ErpWarehouseApi.Warehouse) { + return requestClient.post('/erp/warehouse/create', data); +} + +/** 修改仓库 */ +export function updateWarehouse(data: ErpWarehouseApi.Warehouse) { + return requestClient.put('/erp/warehouse/update', data); +} + +/** 修改仓库默认状态 */ +export function updateWarehouseDefaultStatus( + id: number, + defaultStatus: boolean, +) { + return requestClient.put('/erp/warehouse/update-default-status', null, { + params: { id, defaultStatus }, + }); +} + +/** 删除仓库 */ +export function deleteWarehouse(id: number) { + return requestClient.delete(`/erp/warehouse/delete?id=${id}`); +} + +/** 导出仓库 Excel */ +export function exportWarehouse(params: any) { + return requestClient.download('/erp/warehouse/export-excel', { params }); +} diff --git a/apps/web-ele/src/views/erp/stock/check/data.ts b/apps/web-ele/src/views/erp/stock/check/data.ts new file mode 100644 index 000000000..685e940ef --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/check/data.ts @@ -0,0 +1,305 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '盘点单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'checkTime', + label: '盘点时间', + component: 'DatePicker', + componentProps: { + placeholder: '选择盘点时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'warehouseId', + title: '仓库名称', + minWidth: 150, + slots: { default: 'warehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '账面库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'actualCount', + title: '实际库存', + minWidth: 120, + fixed: 'right', + slots: { default: 'actualCount' }, + formatter: 'formatAmount3', + }, + { + field: 'count', + title: '盈亏数量', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount3', + }, + { + field: 'productPrice', + title: '产品单价', + minWidth: 120, + fixed: 'right', + slots: { default: 'productPrice' }, + }, + { + field: 'totalPrice', + title: '金额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '盘点单号', + component: 'Input', + componentProps: { + placeholder: '请输入盘点单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'checkTime', + label: '盘点时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '盘点单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'checkTime', + title: '盘点时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '总金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/check/index.vue b/apps/web-ele/src/views/erp/stock/check/index.vue new file mode 100644 index 000000000..d9f46eb5a --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/check/index.vue @@ -0,0 +1,215 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/check/modules/form.vue b/apps/web-ele/src/views/erp/stock/check/modules/form.vue new file mode 100644 index 000000000..72e504a73 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/check/modules/form.vue @@ -0,0 +1,132 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue new file mode 100644 index 000000000..010326580 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue @@ -0,0 +1,313 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/in/data.ts b/apps/web-ele/src/views/erp/stock/in/data.ts new file mode 100644 index 000000000..caa252a4a --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/in/data.ts @@ -0,0 +1,330 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getSupplierSimpleList } from '#/api/erp/purchase/supplier'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '入库单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'inTime', + label: '入库时间', + component: 'DatePicker', + componentProps: { + placeholder: '选择入库时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + label: '供应商', + fieldName: 'supplierId', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择供应商', + allowClear: true, + showSearch: true, + api: getSupplierSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '入库产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'warehouseId', + title: '仓库名称', + minWidth: 150, + slots: { default: 'warehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + minWidth: 120, + fixed: 'right', + slots: { default: 'productPrice' }, + }, + { + field: 'totalPrice', + title: '金额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '入库单号', + component: 'Input', + componentProps: { + placeholder: '请输入入库单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'inTime', + label: '入库时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'supplierId', + label: '供应商', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择供应商', + allowClear: true, + showSearch: true, + api: getSupplierSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '入库单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'supplierName', + title: '供应商', + minWidth: 120, + }, + { + field: 'inTime', + title: '入库时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '总金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/in/index.vue b/apps/web-ele/src/views/erp/stock/in/index.vue new file mode 100644 index 000000000..e610753b1 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/in/index.vue @@ -0,0 +1,212 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/in/modules/form.vue b/apps/web-ele/src/views/erp/stock/in/modules/form.vue new file mode 100644 index 000000000..8d1e42091 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/in/modules/form.vue @@ -0,0 +1,128 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue new file mode 100644 index 000000000..b239ae826 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue @@ -0,0 +1,302 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/move/data.ts b/apps/web-ele/src/views/erp/stock/move/data.ts new file mode 100644 index 000000000..5830a7a8d --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/move/data.ts @@ -0,0 +1,316 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '调度单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'moveTime', + label: '调度时间', + component: 'DatePicker', + componentProps: { + placeholder: '选择调度时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'fromWarehouseId', + title: '调出仓库', + minWidth: 150, + slots: { default: 'fromWarehouseId' }, + }, + { + field: 'toWarehouseId', + title: '调入仓库', + minWidth: 150, + slots: { default: 'toWarehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + minWidth: 120, + fixed: 'right', + slots: { default: 'productPrice' }, + }, + { + field: 'totalPrice', + title: '金额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '调度单号', + component: 'Input', + componentProps: { + placeholder: '请输入调度单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'moveTime', + label: '调度时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'fromWarehouseId', + label: '调出仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择调出仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'toWarehouseId', + label: '调入仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择调入仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '调度单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'moveTime', + title: '调度时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '总金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/move/index.vue b/apps/web-ele/src/views/erp/stock/move/index.vue new file mode 100644 index 000000000..67c91a326 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/move/index.vue @@ -0,0 +1,215 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/move/modules/form.vue b/apps/web-ele/src/views/erp/stock/move/modules/form.vue new file mode 100644 index 000000000..94c879b99 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/move/modules/form.vue @@ -0,0 +1,132 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue new file mode 100644 index 000000000..3a06d56a1 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue @@ -0,0 +1,323 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/out/data.ts b/apps/web-ele/src/views/erp/stock/out/data.ts new file mode 100644 index 000000000..481e5ccbf --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/out/data.ts @@ -0,0 +1,330 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getCustomerSimpleList } from '#/api/erp/sale/customer'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '出库单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'outTime', + label: '出库时间', + component: 'DatePicker', + componentProps: { + placeholder: '选择出库时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + label: '客户', + fieldName: 'customerId', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '出库产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'warehouseId', + title: '仓库名称', + minWidth: 150, + slots: { default: 'warehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + minWidth: 120, + fixed: 'right', + slots: { default: 'productPrice' }, + }, + { + field: 'totalPrice', + title: '金额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '出库单号', + component: 'Input', + componentProps: { + placeholder: '请输入出库单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'outTime', + label: '出库时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '出库单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'outTime', + title: '出库时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '总金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/out/index.vue b/apps/web-ele/src/views/erp/stock/out/index.vue new file mode 100644 index 000000000..a44a8d93f --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/out/index.vue @@ -0,0 +1,215 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/out/modules/form.vue b/apps/web-ele/src/views/erp/stock/out/modules/form.vue new file mode 100644 index 000000000..4d84dd331 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/out/modules/form.vue @@ -0,0 +1,132 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue new file mode 100644 index 000000000..36c96a398 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue @@ -0,0 +1,300 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/record/data.ts b/apps/web-ele/src/views/erp/stock/record/data.ts new file mode 100644 index 000000000..e4e3d0ecd --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/record/data.ts @@ -0,0 +1,133 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'bizType', + label: '类型', + component: 'Select', + componentProps: { + placeholder: '请选择类型', + allowClear: true, + options: getDictOptions(DICT_TYPE.ERP_STOCK_RECORD_BIZ_TYPE, 'number'), + }, + }, + { + fieldName: 'bizNo', + label: '业务单号', + component: 'Input', + componentProps: { + placeholder: '请输入业务单号', + allowClear: true, + }, + }, + { + fieldName: 'createTime', + label: '创建时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'productName', + title: '产品名称', + minWidth: 150, + }, + { + field: 'categoryName', + title: '产品分类', + width: 120, + }, + { + field: 'unitName', + title: '产品单位', + width: 100, + }, + { + field: 'warehouseName', + title: '仓库', + width: 120, + }, + { + field: 'bizType', + title: '类型', + width: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_STOCK_RECORD_BIZ_TYPE }, + }, + }, + { + field: 'bizNo', + title: '出入库单号', + width: 200, + showOverflow: 'tooltip', + }, + { + field: 'createTime', + title: '出入库日期', + width: 180, + formatter: 'formatDateTime', + }, + { + field: 'count', + title: '出入库数量', + width: 120, + formatter: 'formatAmount3', + }, + { + field: 'totalCount', + title: '库存量', + width: 100, + formatter: 'formatAmount3', + }, + { + field: 'creatorName', + title: '操作人', + width: 100, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/record/index.vue b/apps/web-ele/src/views/erp/stock/record/index.vue new file mode 100644 index 000000000..8c975031a --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/record/index.vue @@ -0,0 +1,79 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/stock/data.ts b/apps/web-ele/src/views/erp/stock/stock/data.ts new file mode 100644 index 000000000..037bb9c45 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/stock/data.ts @@ -0,0 +1,69 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; + +/** 搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'productName', + title: '产品名称', + minWidth: 150, + }, + { + field: 'unitName', + title: '产品单位', + minWidth: 100, + }, + { + field: 'categoryName', + title: '产品分类', + minWidth: 120, + }, + { + field: 'count', + title: '库存量', + minWidth: 100, + formatter: 'formatAmount3', + }, + { + field: 'warehouseName', + title: '仓库', + minWidth: 120, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/stock/index.vue b/apps/web-ele/src/views/erp/stock/stock/index.vue new file mode 100644 index 000000000..2b20d7475 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/stock/index.vue @@ -0,0 +1,79 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/warehouse/data.ts b/apps/web-ele/src/views/erp/stock/warehouse/data.ts new file mode 100644 index 000000000..0f38019e0 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/warehouse/data.ts @@ -0,0 +1,209 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { ErpWarehouseApi } from '#/api/erp/stock/warehouse'; + +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, + }, + }, + { + fieldName: 'name', + label: '仓库名称', + component: 'Input', + componentProps: { + placeholder: '请输入仓库名称', + }, + rules: 'required', + }, + { + fieldName: 'address', + 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: 'warehousePrice', + label: '仓储费(元)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入仓储费,单位:元/天/KG', + min: 0, + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'truckagePrice', + label: '搬运费(元)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入搬运费,单位:元', + min: 0, + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'principal', + label: '负责人', + component: 'Input', + componentProps: { + placeholder: '请输入负责人', + }, + }, + { + fieldName: 'sort', + label: '排序', + component: 'InputNumber', + componentProps: { + placeholder: '请输入排序', + precision: 0, + controlsPosition: 'right', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + }, + }, + ]; +} + +/** 搜索表单 */ +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( + onDefaultStatusChange?: ( + newStatus: boolean, + row: ErpWarehouseApi.Warehouse, + ) => PromiseLike, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'name', + title: '仓库名称', + minWidth: 150, + }, + { + field: 'address', + title: '仓库地址', + minWidth: 200, + showOverflow: 'tooltip', + }, + { + field: 'warehousePrice', + title: '仓储费', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + field: 'truckagePrice', + title: '搬运费', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + field: 'principal', + title: '负责人', + minWidth: 100, + }, + { + field: 'sort', + title: '排序', + minWidth: 80, + }, + { + field: 'status', + title: '状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'defaultStatus', + title: '是否默认', + minWidth: 100, + cellRender: { + attrs: { beforeChange: onDefaultStatusChange }, + name: 'CellSwitch', + props: { + activeValue: true, + inactiveValue: false, + }, + }, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + showOverflow: 'tooltip', + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/stock/warehouse/index.vue b/apps/web-ele/src/views/erp/stock/warehouse/index.vue new file mode 100644 index 000000000..e75680388 --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/warehouse/index.vue @@ -0,0 +1,178 @@ + + + diff --git a/apps/web-ele/src/views/erp/stock/warehouse/modules/form.vue b/apps/web-ele/src/views/erp/stock/warehouse/modules/form.vue new file mode 100644 index 000000000..5bd04fded --- /dev/null +++ b/apps/web-ele/src/views/erp/stock/warehouse/modules/form.vue @@ -0,0 +1,88 @@ + + + From 14016b8d4e0863d6885c724fb3ca7dd60663bf53 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 17:48:44 +0800 Subject: [PATCH 13/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91stock=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8820%=EF=BC=89-=20warehouse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web-antd/src/views/erp/finance/account/index.vue | 1 + .../web-antd/src/views/erp/stock/warehouse/index.vue | 1 + apps/web-ele/src/api/erp/product/category/index.ts | 2 +- apps/web-ele/src/api/erp/product/unit/index.ts | 12 ++---------- apps/web-ele/src/views/erp/finance/account/index.vue | 1 + apps/web-ele/src/views/erp/stock/warehouse/index.vue | 1 + 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/apps/web-antd/src/views/erp/finance/account/index.vue b/apps/web-antd/src/views/erp/finance/account/index.vue index 9ef8f3f60..4ceb7abba 100644 --- a/apps/web-antd/src/views/erp/finance/account/index.vue +++ b/apps/web-antd/src/views/erp/finance/account/index.vue @@ -75,6 +75,7 @@ async function handleDefaultStatusChange( await updateAccountDefaultStatus(row.id!, newStatus); // 提示并返回成功 message.success(`${text}默认成功`); + handleRefresh(); resolve(true); }) .catch(() => { diff --git a/apps/web-antd/src/views/erp/stock/warehouse/index.vue b/apps/web-antd/src/views/erp/stock/warehouse/index.vue index ea59edce1..e567fd2ec 100644 --- a/apps/web-antd/src/views/erp/stock/warehouse/index.vue +++ b/apps/web-antd/src/views/erp/stock/warehouse/index.vue @@ -73,6 +73,7 @@ async function handleDefaultStatusChange( await updateWarehouseDefaultStatus(row.id!, newStatus); // 提示并返回成功 message.success(`${text}默认成功`); + handleRefresh(); resolve(true); }) .catch(() => { diff --git a/apps/web-ele/src/api/erp/product/category/index.ts b/apps/web-ele/src/api/erp/product/category/index.ts index 87c855319..3c96b5893 100644 --- a/apps/web-ele/src/api/erp/product/category/index.ts +++ b/apps/web-ele/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-ele/src/api/erp/product/unit/index.ts b/apps/web-ele/src/api/erp/product/unit/index.ts index 317c09c85..23514963b 100644 --- a/apps/web-ele/src/api/erp/product/unit/index.ts +++ b/apps/web-ele/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/views/erp/finance/account/index.vue b/apps/web-ele/src/views/erp/finance/account/index.vue index 4daedf709..1f5493980 100644 --- a/apps/web-ele/src/views/erp/finance/account/index.vue +++ b/apps/web-ele/src/views/erp/finance/account/index.vue @@ -74,6 +74,7 @@ async function handleDefaultStatusChange( await updateAccountDefaultStatus(row.id!, newStatus); // 提示并返回成功 ElMessage.success(`${text}默认成功`); + handleRefresh(); resolve(true); }) .catch(() => { diff --git a/apps/web-ele/src/views/erp/stock/warehouse/index.vue b/apps/web-ele/src/views/erp/stock/warehouse/index.vue index e75680388..48669e1f8 100644 --- a/apps/web-ele/src/views/erp/stock/warehouse/index.vue +++ b/apps/web-ele/src/views/erp/stock/warehouse/index.vue @@ -72,6 +72,7 @@ async function handleDefaultStatusChange( await updateWarehouseDefaultStatus(row.id!, newStatus); // 提示并返回成功 ElMessage.success(`${text}默认成功`); + handleRefresh(); resolve(true); }) .catch(() => { From 1810c5dc4a5e9b2efb59cf285d5bfdaf59324342 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 18:29:24 +0800 Subject: [PATCH 14/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91stock=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8830%=EF=BC=89-=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/erp/purchase/in/index.vue | 1 - apps/web-antd/src/views/erp/purchase/order/index.vue | 1 - apps/web-antd/src/views/erp/purchase/return/index.vue | 1 - apps/web-antd/src/views/erp/sale/order/index.vue | 1 - apps/web-antd/src/views/erp/sale/out/index.vue | 1 - apps/web-antd/src/views/erp/sale/return/index.vue | 1 - apps/web-antd/src/views/erp/stock/check/data.ts | 2 +- apps/web-antd/src/views/erp/stock/check/index.vue | 1 - apps/web-antd/src/views/erp/stock/in/index.vue | 1 - apps/web-antd/src/views/erp/stock/move/index.vue | 1 - apps/web-antd/src/views/erp/stock/out/index.vue | 1 - apps/web-ele/src/views/erp/stock/check/index.vue | 11 +++++++++++ 12 files changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/web-antd/src/views/erp/purchase/in/index.vue b/apps/web-antd/src/views/erp/purchase/in/index.vue index 2b4e3487a..008f92043 100644 --- a/apps/web-antd/src/views/erp/purchase/in/index.vue +++ b/apps/web-antd/src/views/erp/purchase/in/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:purchase-in:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/purchase/order/index.vue b/apps/web-antd/src/views/erp/purchase/order/index.vue index 7e427c0c0..613310ba8 100644 --- a/apps/web-antd/src/views/erp/purchase/order/index.vue +++ b/apps/web-antd/src/views/erp/purchase/order/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:purchase-order:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/purchase/return/index.vue b/apps/web-antd/src/views/erp/purchase/return/index.vue index d45f4e1e0..86eb975ec 100644 --- a/apps/web-antd/src/views/erp/purchase/return/index.vue +++ b/apps/web-antd/src/views/erp/purchase/return/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:purchase-return:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/sale/order/index.vue b/apps/web-antd/src/views/erp/sale/order/index.vue index 08051a651..4f85d4d16 100644 --- a/apps/web-antd/src/views/erp/sale/order/index.vue +++ b/apps/web-antd/src/views/erp/sale/order/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:sale-order:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/sale/out/index.vue b/apps/web-antd/src/views/erp/sale/out/index.vue index cb38ad9fe..79c1c923a 100644 --- a/apps/web-antd/src/views/erp/sale/out/index.vue +++ b/apps/web-antd/src/views/erp/sale/out/index.vue @@ -207,7 +207,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:sale-out:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/sale/return/index.vue b/apps/web-antd/src/views/erp/sale/return/index.vue index 5c4c297d6..3e874b429 100644 --- a/apps/web-antd/src/views/erp/sale/return/index.vue +++ b/apps/web-antd/src/views/erp/sale/return/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:sale-return:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/check/data.ts b/apps/web-antd/src/views/erp/stock/check/data.ts index 91a101b5e..67e3cfdca 100644 --- a/apps/web-antd/src/views/erp/stock/check/data.ts +++ b/apps/web-antd/src/views/erp/stock/check/data.ts @@ -296,7 +296,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/erp/stock/check/index.vue b/apps/web-antd/src/views/erp/stock/check/index.vue index c41d68332..de34ab122 100644 --- a/apps/web-antd/src/views/erp/stock/check/index.vue +++ b/apps/web-antd/src/views/erp/stock/check/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:stock-check:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/in/index.vue b/apps/web-antd/src/views/erp/stock/in/index.vue index 4d6910f71..a7045c392 100644 --- a/apps/web-antd/src/views/erp/stock/in/index.vue +++ b/apps/web-antd/src/views/erp/stock/in/index.vue @@ -207,7 +207,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:stock-in:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/move/index.vue b/apps/web-antd/src/views/erp/stock/move/index.vue index ad3214ac8..ee9b6177b 100644 --- a/apps/web-antd/src/views/erp/stock/move/index.vue +++ b/apps/web-antd/src/views/erp/stock/move/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:stock-move:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/out/index.vue b/apps/web-antd/src/views/erp/stock/out/index.vue index f323dec82..bcaa9cc26 100644 --- a/apps/web-antd/src/views/erp/stock/out/index.vue +++ b/apps/web-antd/src/views/erp/stock/out/index.vue @@ -210,7 +210,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, - color: 'error', auth: ['erp:stock-out:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-ele/src/views/erp/stock/check/index.vue b/apps/web-ele/src/views/erp/stock/check/index.vue index d9f46eb5a..cbfe22f1b 100644 --- a/apps/web-ele/src/views/erp/stock/check/index.vue +++ b/apps/web-ele/src/views/erp/stock/check/index.vue @@ -158,6 +158,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['erp:stock-check:export'], onClick: handleExport, }, + { + label: '批量删除', + type: 'danger', + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['erp:stock-check:delete'], + popConfirm: { + title: `是否删除所选中数据?`, + confirm: handleDelete.bind(null, checkedIds), + }, + }, ]" /> From cb9aaa338c4f218b216da5f73848ade107c9c68c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 18:36:53 +0800 Subject: [PATCH 15/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91stock=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8850%=EF=BC=89-=20in?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/erp/stock/check/index.vue | 2 ++ apps/web-antd/src/views/erp/stock/in/index.vue | 2 ++ apps/web-antd/src/views/erp/stock/move/index.vue | 2 ++ apps/web-antd/src/views/erp/stock/out/index.vue | 2 ++ apps/web-ele/src/views/erp/stock/check/index.vue | 2 +- .../src/views/erp/stock/check/modules/item-form.vue | 1 - apps/web-ele/src/views/erp/stock/in/index.vue | 13 ++++++++++++- .../src/views/erp/stock/in/modules/item-form.vue | 1 - .../src/views/erp/stock/move/modules/item-form.vue | 1 - .../src/views/erp/stock/out/modules/item-form.vue | 1 - 10 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/web-antd/src/views/erp/stock/check/index.vue b/apps/web-antd/src/views/erp/stock/check/index.vue index de34ab122..3edef5eb3 100644 --- a/apps/web-antd/src/views/erp/stock/check/index.vue +++ b/apps/web-antd/src/views/erp/stock/check/index.vue @@ -196,6 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-check:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -210,6 +211,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:stock-check:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/in/index.vue b/apps/web-antd/src/views/erp/stock/in/index.vue index a7045c392..4b362c25f 100644 --- a/apps/web-antd/src/views/erp/stock/in/index.vue +++ b/apps/web-antd/src/views/erp/stock/in/index.vue @@ -193,6 +193,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-in:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -207,6 +208,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:stock-in:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/move/index.vue b/apps/web-antd/src/views/erp/stock/move/index.vue index ee9b6177b..f5da612cd 100644 --- a/apps/web-antd/src/views/erp/stock/move/index.vue +++ b/apps/web-antd/src/views/erp/stock/move/index.vue @@ -196,6 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-move:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -210,6 +211,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:stock-move:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/stock/out/index.vue b/apps/web-antd/src/views/erp/stock/out/index.vue index bcaa9cc26..8cd238561 100644 --- a/apps/web-antd/src/views/erp/stock/out/index.vue +++ b/apps/web-antd/src/views/erp/stock/out/index.vue @@ -196,6 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-out:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -210,6 +211,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:stock-out:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-ele/src/views/erp/stock/check/index.vue b/apps/web-ele/src/views/erp/stock/check/index.vue index cbfe22f1b..144ab7619 100644 --- a/apps/web-ele/src/views/erp/stock/check/index.vue +++ b/apps/web-ele/src/views/erp/stock/check/index.vue @@ -196,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.AUDIT : ACTION_ICON.REJECT, + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-check:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue index 010326580..0239140c5 100644 --- a/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue +++ b/apps/web-ele/src/views/erp/stock/check/modules/item-form.vue @@ -275,7 +275,6 @@ onMounted(async () => { label: '删除', type: 'danger', link: true, - icon: 'ant-design:delete-outlined', popConfirm: { title: '确认删除该产品吗?', confirm: handleDelete.bind(null, row), diff --git a/apps/web-ele/src/views/erp/stock/in/index.vue b/apps/web-ele/src/views/erp/stock/in/index.vue index e610753b1..4f6e1da26 100644 --- a/apps/web-ele/src/views/erp/stock/in/index.vue +++ b/apps/web-ele/src/views/erp/stock/in/index.vue @@ -155,6 +155,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['erp:stock-in:export'], onClick: handleExport, }, + { + label: '批量删除', + type: 'danger', + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['erp:stock-in:delete'], + popConfirm: { + title: `是否删除所选中数据?`, + confirm: handleDelete.bind(null, checkedIds), + }, + }, ]" /> @@ -182,7 +193,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.AUDIT : ACTION_ICON.REJECT, + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-in:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue index b239ae826..5cda5f879 100644 --- a/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue +++ b/apps/web-ele/src/views/erp/stock/in/modules/item-form.vue @@ -264,7 +264,6 @@ onMounted(async () => { label: '删除', type: 'danger', link: true, - icon: 'ant-design:delete-outlined', popConfirm: { title: '确认删除该产品吗?', confirm: handleDelete.bind(null, row), diff --git a/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue index 3a06d56a1..4e94d1d44 100644 --- a/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue +++ b/apps/web-ele/src/views/erp/stock/move/modules/item-form.vue @@ -285,7 +285,6 @@ onMounted(async () => { label: '删除', type: 'danger', link: true, - icon: 'ant-design:delete-outlined', popConfirm: { title: '确认删除该产品吗?', confirm: handleDelete.bind(null, row), diff --git a/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue index 36c96a398..fb363f80f 100644 --- a/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue +++ b/apps/web-ele/src/views/erp/stock/out/modules/item-form.vue @@ -262,7 +262,6 @@ onMounted(async () => { label: '删除', type: 'danger', link: true, - icon: 'ant-design:delete-outlined', popConfirm: { title: '确认删除该产品吗?', confirm: handleDelete.bind(null, row), From bb749844fe77b497684133566fbb036fb0b0cbb4 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 18:41:46 +0800 Subject: [PATCH 16/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91stock=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=88100%=EF=BC=89-=20move=E3=80=81out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/erp/stock/move/data.ts | 2 +- apps/web-antd/src/views/erp/stock/out/data.ts | 2 +- apps/web-ele/src/views/erp/stock/move/index.vue | 13 ++++++++++++- apps/web-ele/src/views/erp/stock/out/index.vue | 13 ++++++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/web-antd/src/views/erp/stock/move/data.ts b/apps/web-antd/src/views/erp/stock/move/data.ts index 74c2db117..89a148a17 100644 --- a/apps/web-antd/src/views/erp/stock/move/data.ts +++ b/apps/web-antd/src/views/erp/stock/move/data.ts @@ -307,7 +307,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/erp/stock/out/data.ts b/apps/web-antd/src/views/erp/stock/out/data.ts index 3fb67b704..4a2668d93 100644 --- a/apps/web-antd/src/views/erp/stock/out/data.ts +++ b/apps/web-antd/src/views/erp/stock/out/data.ts @@ -331,7 +331,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-ele/src/views/erp/stock/move/index.vue b/apps/web-ele/src/views/erp/stock/move/index.vue index 67c91a326..c0a64812b 100644 --- a/apps/web-ele/src/views/erp/stock/move/index.vue +++ b/apps/web-ele/src/views/erp/stock/move/index.vue @@ -158,6 +158,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['erp:stock-move:export'], onClick: handleExport, }, + { + label: '批量删除', + type: 'danger', + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['erp:stock-move:delete'], + popConfirm: { + title: `是否删除所选中数据?`, + confirm: handleDelete.bind(null, checkedIds), + }, + }, ]" /> @@ -185,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.AUDIT : ACTION_ICON.REJECT, + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-move:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/stock/out/index.vue b/apps/web-ele/src/views/erp/stock/out/index.vue index a44a8d93f..96c244e09 100644 --- a/apps/web-ele/src/views/erp/stock/out/index.vue +++ b/apps/web-ele/src/views/erp/stock/out/index.vue @@ -158,6 +158,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ auth: ['erp:stock-out:export'], onClick: handleExport, }, + { + label: '批量删除', + type: 'danger', + disabled: isEmpty(checkedIds), + icon: ACTION_ICON.DELETE, + auth: ['erp:stock-out:delete'], + popConfirm: { + title: `是否删除所选中数据?`, + confirm: handleDelete.bind(null, checkedIds), + }, + }, ]" /> @@ -185,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.AUDIT : ACTION_ICON.REJECT, + icon: ACTION_ICON.AUDIT, auth: ['erp:stock-out:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, From 6e2e357feddd851b957ee5b178ac6f1ca48f33d1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 19:02:31 +0800 Subject: [PATCH 17/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91sale=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8810%=EF=BC=89-=20=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/erp/sale/customer/data.ts | 241 +++++++ .../src/views/erp/sale/customer/index.vue | 149 ++++ .../views/erp/sale/customer/modules/form.vue | 86 +++ apps/web-ele/src/views/erp/sale/order/data.ts | 465 +++++++++++++ .../src/views/erp/sale/order/index.vue | 226 +++++++ .../src/views/erp/sale/order/modules/form.vue | 162 +++++ .../erp/sale/order/modules/item-form.vue | 328 +++++++++ apps/web-ele/src/views/erp/sale/out/data.ts | 636 ++++++++++++++++++ apps/web-ele/src/views/erp/sale/out/index.vue | 223 ++++++ .../src/views/erp/sale/out/modules/form.vue | 226 +++++++ .../views/erp/sale/out/modules/item-form.vue | 310 +++++++++ .../sale/out/modules/sale-order-select.vue | 123 ++++ .../web-ele/src/views/erp/sale/return/data.ts | 623 +++++++++++++++++ .../src/views/erp/sale/return/index.vue | 226 +++++++ .../views/erp/sale/return/modules/form.vue | 231 +++++++ .../erp/sale/return/modules/item-form.vue | 310 +++++++++ .../sale/return/modules/sale-order-select.vue | 123 ++++ 17 files changed, 4688 insertions(+) create mode 100644 apps/web-ele/src/views/erp/sale/customer/data.ts create mode 100644 apps/web-ele/src/views/erp/sale/customer/index.vue create mode 100644 apps/web-ele/src/views/erp/sale/customer/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/sale/order/data.ts create mode 100644 apps/web-ele/src/views/erp/sale/order/index.vue create mode 100644 apps/web-ele/src/views/erp/sale/order/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/sale/order/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/sale/out/data.ts create mode 100644 apps/web-ele/src/views/erp/sale/out/index.vue create mode 100644 apps/web-ele/src/views/erp/sale/out/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/sale/out/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue create mode 100644 apps/web-ele/src/views/erp/sale/return/data.ts create mode 100644 apps/web-ele/src/views/erp/sale/return/index.vue create mode 100644 apps/web-ele/src/views/erp/sale/return/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/sale/return/modules/item-form.vue create mode 100644 apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue diff --git a/apps/web-ele/src/views/erp/sale/customer/data.ts b/apps/web-ele/src/views/erp/sale/customer/data.ts new file mode 100644 index 000000000..adfdd5675 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/customer/data.ts @@ -0,0 +1,241 @@ +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: 'contact', + label: '联系人', + component: 'Input', + componentProps: { + placeholder: '请输入联系人', + }, + }, + { + fieldName: 'mobile', + label: '手机号码', + component: 'Input', + componentProps: { + placeholder: '请输入手机号码', + }, + }, + { + fieldName: 'telephone', + label: '联系电话', + component: 'Input', + componentProps: { + placeholder: '请输入联系电话', + }, + }, + { + fieldName: 'email', + label: '电子邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入电子邮箱', + }, + }, + { + fieldName: 'fax', + 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: 'sort', + label: '排序', + component: 'InputNumber', + componentProps: { + placeholder: '请输入排序', + precision: 0, + controlsPosition: 'right', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'taxNo', + label: '纳税人识别号', + component: 'Input', + componentProps: { + placeholder: '请输入纳税人识别号', + }, + }, + { + fieldName: 'taxPercent', + label: '税率(%)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入税率', + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).max(100).optional(), + }, + { + fieldName: 'bankName', + label: '开户行名称', + component: 'Input', + componentProps: { + placeholder: '请输入开户行名称', + }, + }, + { + fieldName: 'bankAccount', + label: '开户行账号', + component: 'Input', + componentProps: { + placeholder: '请输入开户行账号', + }, + }, + { + fieldName: 'bankAddress', + label: '开户行地址', + component: 'Input', + componentProps: { + placeholder: '请输入开户行地址', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 3, + }, + formItemClass: 'col-span-2', + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'name', + label: '客户名称', + component: 'Input', + componentProps: { + placeholder: '请输入客户名称', + allowClear: true, + }, + }, + { + fieldName: 'mobile', + label: '手机号码', + component: 'Input', + componentProps: { + placeholder: '请输入手机号码', + allowClear: true, + }, + }, + { + fieldName: 'email', + label: '邮箱', + component: 'Input', + componentProps: { + placeholder: '请输入邮箱', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + field: 'name', + title: '客户名称', + minWidth: 150, + }, + { + field: 'contact', + title: '联系人', + minWidth: 120, + }, + { + field: 'mobile', + title: '手机号码', + minWidth: 130, + }, + { + field: 'telephone', + title: '联系电话', + minWidth: 130, + }, + { + field: 'email', + title: '电子邮箱', + minWidth: 180, + }, + { + field: 'status', + title: '状态', + minWidth: 100, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'sort', + title: '排序', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + showOverflow: 'tooltip', + }, + { + field: 'createTime', + title: '创建时间', + minWidth: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 130, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/sale/customer/index.vue b/apps/web-ele/src/views/erp/sale/customer/index.vue new file mode 100644 index 000000000..c2e3bc90a --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/customer/index.vue @@ -0,0 +1,149 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/customer/modules/form.vue b/apps/web-ele/src/views/erp/sale/customer/modules/form.vue new file mode 100644 index 000000000..d7445569d --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/customer/modules/form.vue @@ -0,0 +1,86 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/order/data.ts b/apps/web-ele/src/views/erp/sale/order/data.ts new file mode 100644 index 000000000..36a472ff3 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/order/data.ts @@ -0,0 +1,465 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { erpPriceInputFormatter } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getAccountSimpleList } from '#/api/erp/finance/account'; +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getCustomerSimpleList } from '#/api/erp/sale/customer'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '订单单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'orderTime', + label: '订单时间', + component: 'DatePicker', + componentProps: { + placeholder: '选择订单时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + label: '客户', + fieldName: 'customerId', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'saleUserId', + label: '销售人员', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择销售人员', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '销售产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + { + fieldName: 'discountPercent', + label: '优惠率(%)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入优惠率', + min: 0, + max: 100, + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).optional(), + }, + { + fieldName: 'discountPrice', + label: '付款优惠', + component: 'InputNumber', + componentProps: { + placeholder: '收款优惠', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'totalPrice', + label: '优惠后金额', + component: 'InputNumber', + componentProps: { + placeholder: '优惠后金额', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'accountId', + label: '结算账户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择结算账户', + allowClear: true, + showSearch: true, + api: getAccountSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + component: 'InputNumber', + componentProps: { + placeholder: '请输入收取订金', + precision: 2, + min: 0, + controlsPosition: 'right', + class: '!w-full', + }, + fieldName: 'depositPrice', + label: '收取订金', + rules: z.number().min(0).optional(), + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + minWidth: 120, + fixed: 'right', + slots: { default: 'productPrice' }, + }, + { + field: 'totalProductPrice', + title: '金额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + field: 'taxPercent', + title: '税率(%)', + minWidth: 105, + fixed: 'right', + slots: { default: 'taxPercent' }, + }, + { + field: 'taxPrice', + title: '税额', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + field: 'totalPrice', + title: '税额合计', + minWidth: 120, + fixed: 'right', + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '订单单号', + component: 'Input', + componentProps: { + placeholder: '请输入订单单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'orderTime', + label: '订单时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'supplierId', + label: '客户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + { + fieldName: 'outStatus', + label: '出库状态', + component: 'Select', + componentProps: { + options: [ + { label: '未出库', value: 0 }, + { label: '部分出库', value: 1 }, + { label: '全部出库', value: 2 }, + ], + placeholder: '请选择出库状态', + allowClear: true, + }, + }, + { + fieldName: 'returnStatus', + label: '退货状态', + component: 'Select', + componentProps: { + options: [ + { label: '未退货', value: 0 }, + { label: '部分退货', value: 1 }, + { label: '全部退货', value: 2 }, + ], + placeholder: '请选择退货状态', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '订单单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'orderTime', + title: '订单时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'outCount', + title: '出库数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'returnCount', + title: '退货数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalProductPrice', + title: '金额合计', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '含税金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'depositPrice', + title: '收取订金', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'status', + title: '状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/sale/order/index.vue b/apps/web-ele/src/views/erp/sale/order/index.vue new file mode 100644 index 000000000..592078854 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/order/index.vue @@ -0,0 +1,226 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/order/modules/form.vue b/apps/web-ele/src/views/erp/sale/order/modules/form.vue new file mode 100644 index 000000000..53dd591fe --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/order/modules/form.vue @@ -0,0 +1,162 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue new file mode 100644 index 000000000..282e5d7c5 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/order/modules/item-form.vue @@ -0,0 +1,328 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/out/data.ts b/apps/web-ele/src/views/erp/sale/out/data.ts new file mode 100644 index 000000000..824c14a46 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/out/data.ts @@ -0,0 +1,636 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { erpNumberFormatter, erpPriceInputFormatter } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getAccountSimpleList } from '#/api/erp/finance/account'; +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getCustomerSimpleList } from '#/api/erp/sale/customer'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '出库单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'outTime', + label: '出库时间', + component: 'DatePicker', + componentProps: { + disabled: formType === 'detail', + placeholder: '选择出库时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'orderNo', + label: '关联订单', + component: 'Input', + formItemClass: 'col-span-1', + rules: 'required', + componentProps: { + placeholder: '请选择关联订单', + disabled: formType === 'detail', + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + disabled: true, + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + fieldNames: { + label: 'name', + value: 'id', + }, + }, + rules: 'required', + }, + { + fieldName: 'saleUserId', + label: '销售人员', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择销售人员', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + fieldNames: { + label: 'nickname', + value: 'id', + }, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '出库产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + { + fieldName: 'discountPercent', + label: '优惠率(%)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入优惠率', + min: 0, + max: 100, + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).optional(), + }, + { + fieldName: 'discountPrice', + label: '收款优惠', + component: 'InputNumber', + componentProps: { + placeholder: '付款优惠', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'discountedPrice', + label: '优惠后金额', + component: 'InputNumber', + componentProps: { + placeholder: '优惠后金额', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + dependencies: { + triggerFields: ['totalPrice', 'otherPrice'], + componentProps: (values) => { + const totalPrice = values.totalPrice || 0; + const otherPrice = values.otherPrice || 0; + values.discountedPrice = totalPrice - otherPrice; + return {}; + }, + }, + }, + { + fieldName: 'otherPrice', + label: '其他费用', + component: 'InputNumber', + componentProps: { + disabled: formType === 'detail', + placeholder: '请输入其他费用', + precision: 2, + formatter: erpPriceInputFormatter, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'accountId', + label: '结算账户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择结算账户', + disabled: true, + allowClear: true, + showSearch: true, + api: getAccountSimpleList, + fieldNames: { + label: 'name', + value: 'id', + }, + }, + }, + { + fieldName: 'totalPrice', + label: '应收金额', + component: 'InputNumber', + componentProps: { + precision: 2, + min: 0, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).optional(), + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns( + formData?: any[], +): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'warehouseId', + title: '仓库名称', + minWidth: 200, + slots: { default: 'warehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'totalCount', + title: '原数量', + formatter: 'formatAmount3', + minWidth: 120, + fixed: 'right', + visible: formData && formData[0]?.outCount !== undefined, + }, + { + field: 'outCount', + title: '已出库', + formatter: 'formatAmount3', + minWidth: 120, + fixed: 'right', + visible: formData && formData[0]?.returnCount !== undefined, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + fixed: 'right', + minWidth: 120, + slots: { default: 'productPrice' }, + }, + { + field: 'totalProductPrice', + fixed: 'right', + title: '产品金额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + fixed: 'right', + field: 'taxPercent', + title: '税率(%)', + minWidth: 105, + slots: { default: 'taxPercent' }, + }, + { + fixed: 'right', + field: 'taxPrice', + title: '税额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + field: 'totalPrice', + fixed: 'right', + title: '合计金额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '出库单号', + component: 'Input', + componentProps: { + placeholder: '请输入出库单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + fieldNames: { + label: 'name', + value: 'id', + }, + }, + }, + { + fieldName: 'outTime', + label: '出库时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + fieldNames: { + label: 'name', + value: 'id', + }, + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + fieldNames: { + label: 'nickname', + value: 'id', + }, + }, + }, + { + fieldName: 'orderNo', + label: '关联订单', + component: 'Input', + componentProps: { + placeholder: '请输入关联订单号', + allowClear: true, + }, + }, + { + fieldName: 'receiptStatus', + label: '收款状态', + component: 'Select', + componentProps: { + options: [ + { label: '未收款', value: 0 }, + { label: '部分收款', value: 1 }, + { label: '全部收款', value: 2 }, + ], + placeholder: '请选择收款状态', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '审批状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择审批状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '出库单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'outTime', + title: '出库时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '应收金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'receiptPrice', + title: '已收金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'unReceiptPrice', + title: '未收金额', + formatter: ({ row }) => { + return `${erpNumberFormatter(row.totalPrice - row.receiptPrice, 2)}元`; + }, + minWidth: 120, + }, + { + field: 'status', + title: '审批状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useOrderGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '订单单号', + component: 'Input', + componentProps: { + placeholder: '请输入订单单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'orderTime', + label: '订单时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useOrderGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'radio', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '订单单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'orderTime', + title: '订单时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'outCount', + title: '出库数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalProductPrice', + title: '金额合计', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '含税金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/sale/out/index.vue b/apps/web-ele/src/views/erp/sale/out/index.vue new file mode 100644 index 000000000..360bddc71 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/out/index.vue @@ -0,0 +1,223 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/out/modules/form.vue b/apps/web-ele/src/views/erp/sale/out/modules/form.vue new file mode 100644 index 000000000..123f2f38b --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/out/modules/form.vue @@ -0,0 +1,226 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue new file mode 100644 index 000000000..958349c54 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/out/modules/item-form.vue @@ -0,0 +1,310 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue b/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue new file mode 100644 index 000000000..250244e74 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue @@ -0,0 +1,123 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/return/data.ts b/apps/web-ele/src/views/erp/sale/return/data.ts new file mode 100644 index 000000000..36309ef51 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/return/data.ts @@ -0,0 +1,623 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { erpNumberFormatter, erpPriceInputFormatter } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getAccountSimpleList } from '#/api/erp/finance/account'; +import { getProductSimpleList } from '#/api/erp/product/product'; +import { getCustomerSimpleList } from '#/api/erp/sale/customer'; +import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse'; +import { getSimpleUserList } from '#/api/system/user'; +import { getRangePickerDefaultProps } from '#/utils'; + +/** 表单的配置项 */ +export function useFormSchema(formType: string): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'no', + label: '退货单号', + component: 'Input', + componentProps: { + placeholder: '系统自动生成', + disabled: true, + }, + }, + { + fieldName: 'returnTime', + label: '退货时间', + component: 'DatePicker', + componentProps: { + disabled: formType === 'detail', + placeholder: '选择退货时间', + showTime: true, + format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', + class: '!w-full', + }, + rules: 'required', + }, + { + fieldName: 'orderNo', + label: '关联订单', + component: 'Input', + formItemClass: 'col-span-1', + rules: 'required', + componentProps: { + placeholder: '请选择关联订单', + disabled: formType === 'detail', + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + disabled: true, + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + rules: 'required', + }, + { + fieldName: 'saleUserId', + label: '销售人员', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择销售人员', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + autoSize: { minRows: 1, maxRows: 1 }, + disabled: formType === 'detail', + }, + formItemClass: 'col-span-2', + }, + { + fieldName: 'fileUrl', + label: '附件', + component: 'FileUpload', + componentProps: { + maxNumber: 1, + maxSize: 10, + accept: [ + 'pdf', + 'doc', + 'docx', + 'xls', + 'xlsx', + 'txt', + 'jpg', + 'jpeg', + 'png', + ], + showDescription: formType !== 'detail', + disabled: formType === 'detail', + }, + formItemClass: 'col-span-3', + }, + { + fieldName: 'items', + label: '退货产品清单', + component: 'Input', + formItemClass: 'col-span-3', + }, + { + fieldName: 'discountPercent', + label: '优惠率(%)', + component: 'InputNumber', + componentProps: { + placeholder: '请输入优惠率', + min: 0, + max: 100, + precision: 2, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).optional(), + }, + { + fieldName: 'discountPrice', + label: '退款优惠', + component: 'InputNumber', + componentProps: { + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'discountedPrice', + label: '优惠后金额', + component: 'InputNumber', + componentProps: { + placeholder: '优惠后金额', + precision: 2, + formatter: erpPriceInputFormatter, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + dependencies: { + triggerFields: ['totalPrice', 'otherPrice'], + componentProps: (values) => { + const totalPrice = values.totalPrice || 0; + const otherPrice = values.otherPrice || 0; + values.discountedPrice = totalPrice - otherPrice; + return {}; + }, + }, + }, + { + fieldName: 'otherPrice', + label: '其他费用', + component: 'InputNumber', + componentProps: { + disabled: formType === 'detail', + placeholder: '请输入其他费用', + precision: 2, + formatter: erpPriceInputFormatter, + controlsPosition: 'right', + class: '!w-full', + }, + }, + { + fieldName: 'accountId', + label: '结算账户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择结算账户', + disabled: true, + allowClear: true, + showSearch: true, + api: getAccountSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'totalPrice', + label: '应收金额', + component: 'InputNumber', + componentProps: { + precision: 2, + min: 0, + disabled: true, + controlsPosition: 'right', + class: '!w-full', + }, + rules: z.number().min(0).optional(), + }, + ]; +} + +/** 表单的明细表格列 */ +export function useFormItemColumns( + formData?: any[], +): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', title: '序号', minWidth: 50, fixed: 'left' }, + { + field: 'warehouseId', + title: '仓库名称', + minWidth: 200, + slots: { default: 'warehouseId' }, + }, + { + field: 'productId', + title: '产品名称', + minWidth: 200, + slots: { default: 'productId' }, + }, + { + field: 'stockCount', + title: '库存', + minWidth: 80, + formatter: 'formatAmount3', + }, + { + field: 'productBarCode', + title: '条码', + minWidth: 120, + }, + { + field: 'productUnitName', + title: '单位', + minWidth: 80, + }, + { + field: 'remark', + title: '备注', + minWidth: 150, + slots: { default: 'remark' }, + }, + { + field: 'totalCount', + title: '已出库', + formatter: 'formatAmount3', + minWidth: 120, + fixed: 'right', + visible: formData && formData[0]?.outCount !== undefined, + }, + { + field: 'returnCount', + title: '已退货', + formatter: 'formatAmount3', + minWidth: 120, + fixed: 'right', + visible: formData && formData[0]?.returnCount !== undefined, + }, + { + field: 'count', + title: '数量', + minWidth: 120, + fixed: 'right', + slots: { default: 'count' }, + }, + { + field: 'productPrice', + title: '产品单价', + fixed: 'right', + minWidth: 120, + slots: { default: 'productPrice' }, + }, + { + field: 'totalProductPrice', + fixed: 'right', + title: '产品金额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + fixed: 'right', + field: 'taxPercent', + title: '税率(%)', + minWidth: 105, + slots: { default: 'taxPercent' }, + }, + { + fixed: 'right', + field: 'taxPrice', + title: '税额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + field: 'totalPrice', + fixed: 'right', + title: '合计金额', + minWidth: 120, + formatter: 'formatAmount2', + }, + { + title: '操作', + width: 50, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '退货单号', + component: 'Input', + componentProps: { + placeholder: '请输入退货单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'returnTime', + label: '退货时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + { + fieldName: 'customerId', + label: '客户', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择客户', + allowClear: true, + showSearch: true, + api: getCustomerSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择仓库', + allowClear: true, + showSearch: true, + api: getWarehouseSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'creator', + label: '创建人', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择创建人', + allowClear: true, + showSearch: true, + api: getSimpleUserList, + labelField: 'nickname', + valueField: 'id', + }, + }, + { + fieldName: 'orderNo', + label: '关联订单', + component: 'Input', + componentProps: { + placeholder: '请输入关联订单号', + allowClear: true, + }, + }, + { + fieldName: 'refundStatus', + label: '退款状态', + component: 'Select', + componentProps: { + options: [ + { label: '未退款', value: 0 }, + { label: '部分退款', value: 1 }, + { label: '全部退款', value: 2 }, + ], + placeholder: '请选择退款状态', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '审批状态', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.ERP_AUDIT_STATUS, 'number'), + placeholder: '请选择审批状态', + allowClear: true, + }, + }, + { + fieldName: 'remark', + label: '备注', + component: 'Input', + componentProps: { + placeholder: '请输入备注', + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '退货单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '退货产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'returnTime', + title: '退货时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '应收金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'refundPrice', + title: '已退金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'unRefundPrice', + title: '未退金额', + formatter: ({ row }) => { + return `${erpNumberFormatter(row.totalPrice - row.refundPrice, 2)}元`; + }, + minWidth: 120, + }, + { + field: 'status', + title: '审批状态', + minWidth: 120, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.ERP_AUDIT_STATUS }, + }, + }, + { + title: '操作', + width: 260, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useOrderGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'no', + label: '订单单号', + component: 'Input', + componentProps: { + placeholder: '请输入订单单号', + allowClear: true, + }, + }, + { + fieldName: 'productId', + label: '产品', + component: 'ApiSelect', + componentProps: { + placeholder: '请选择产品', + allowClear: true, + showSearch: true, + api: getProductSimpleList, + labelField: 'name', + valueField: 'id', + }, + }, + { + fieldName: 'orderTime', + label: '订单时间', + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + }, + ]; +} + +/** 列表的字段 */ +export function useOrderGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'radio', + width: 50, + fixed: 'left', + }, + { + field: 'no', + title: '订单单号', + width: 200, + fixed: 'left', + }, + { + field: 'productNames', + title: '产品信息', + showOverflow: 'tooltip', + minWidth: 120, + }, + { + field: 'customerName', + title: '客户', + minWidth: 120, + }, + { + field: 'orderTime', + title: '订单时间', + width: 160, + formatter: 'formatDate', + }, + { + field: 'creatorName', + title: '创建人', + minWidth: 120, + }, + { + field: 'totalCount', + title: '总数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'returnCount', + title: '已退货数量', + formatter: 'formatAmount3', + minWidth: 120, + }, + { + field: 'totalProductPrice', + title: '金额合计', + formatter: 'formatAmount2', + minWidth: 120, + }, + { + field: 'totalPrice', + title: '含税金额', + formatter: 'formatAmount2', + minWidth: 120, + }, + ]; +} diff --git a/apps/web-ele/src/views/erp/sale/return/index.vue b/apps/web-ele/src/views/erp/sale/return/index.vue new file mode 100644 index 000000000..b62d479b1 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/return/index.vue @@ -0,0 +1,226 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/return/modules/form.vue b/apps/web-ele/src/views/erp/sale/return/modules/form.vue new file mode 100644 index 000000000..35f59a95d --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/return/modules/form.vue @@ -0,0 +1,231 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue b/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue new file mode 100644 index 000000000..90ca380b3 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/return/modules/item-form.vue @@ -0,0 +1,310 @@ + + + diff --git a/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue new file mode 100644 index 000000000..0b8628d78 --- /dev/null +++ b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue @@ -0,0 +1,123 @@ + + + From 94a0c2e5812a8191a5cee2a273a898ff21902403 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 19:10:11 +0800 Subject: [PATCH 18/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91sale=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8830%=EF=BC=89-=20order?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/views/erp/sale/order/data.ts | 2 +- apps/web-antd/src/views/erp/sale/order/index.vue | 2 ++ apps/web-antd/src/views/erp/sale/out/data.ts | 2 +- apps/web-antd/src/views/erp/sale/out/index.vue | 2 ++ apps/web-antd/src/views/erp/sale/return/data.ts | 2 +- apps/web-antd/src/views/erp/sale/return/index.vue | 2 ++ apps/web-ele/src/views/erp/finance/payment/data.ts | 1 - apps/web-ele/src/views/erp/finance/receipt/data.ts | 1 - apps/web-ele/src/views/erp/sale/order/data.ts | 1 - apps/web-ele/src/views/erp/sale/order/index.vue | 2 +- apps/web-ele/src/views/erp/sale/out/data.ts | 1 - apps/web-ele/src/views/erp/sale/return/data.ts | 1 - apps/web-ele/src/views/erp/stock/check/data.ts | 1 - apps/web-ele/src/views/erp/stock/in/data.ts | 1 - apps/web-ele/src/views/erp/stock/move/data.ts | 1 - apps/web-ele/src/views/erp/stock/out/data.ts | 1 - 16 files changed, 10 insertions(+), 13 deletions(-) diff --git a/apps/web-antd/src/views/erp/sale/order/data.ts b/apps/web-antd/src/views/erp/sale/order/data.ts index 03f0686a1..0bc3f4649 100644 --- a/apps/web-antd/src/views/erp/sale/order/data.ts +++ b/apps/web-antd/src/views/erp/sale/order/data.ts @@ -448,7 +448,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/erp/sale/order/index.vue b/apps/web-antd/src/views/erp/sale/order/index.vue index 4f85d4d16..f0fa24c08 100644 --- a/apps/web-antd/src/views/erp/sale/order/index.vue +++ b/apps/web-antd/src/views/erp/sale/order/index.vue @@ -196,6 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-order:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -210,6 +211,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:sale-order:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/sale/out/data.ts b/apps/web-antd/src/views/erp/sale/out/data.ts index 54e0f56d0..d567994bf 100644 --- a/apps/web-antd/src/views/erp/sale/out/data.ts +++ b/apps/web-antd/src/views/erp/sale/out/data.ts @@ -517,7 +517,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/erp/sale/out/index.vue b/apps/web-antd/src/views/erp/sale/out/index.vue index 79c1c923a..06f21645b 100644 --- a/apps/web-antd/src/views/erp/sale/out/index.vue +++ b/apps/web-antd/src/views/erp/sale/out/index.vue @@ -193,6 +193,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-out:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -207,6 +208,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:sale-out:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-antd/src/views/erp/sale/return/data.ts b/apps/web-antd/src/views/erp/sale/return/data.ts index 47540944f..a3390c872 100644 --- a/apps/web-antd/src/views/erp/sale/return/data.ts +++ b/apps/web-antd/src/views/erp/sale/return/data.ts @@ -504,7 +504,7 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { }, { title: '操作', - width: 220, + width: 260, fixed: 'right', slots: { default: 'actions' }, }, diff --git a/apps/web-antd/src/views/erp/sale/return/index.vue b/apps/web-antd/src/views/erp/sale/return/index.vue index 3e874b429..9d63d0dd0 100644 --- a/apps/web-antd/src/views/erp/sale/return/index.vue +++ b/apps/web-antd/src/views/erp/sale/return/index.vue @@ -196,6 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ { label: row.status === 10 ? '审批' : '反审批', type: 'link', + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-return:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, @@ -210,6 +211,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: $t('common.delete'), type: 'link', danger: true, + icon: ACTION_ICON.DELETE, auth: ['erp:sale-return:delete'], popConfirm: { title: $t('ui.actionMessage.deleteConfirm', [row.no]), diff --git a/apps/web-ele/src/views/erp/finance/payment/data.ts b/apps/web-ele/src/views/erp/finance/payment/data.ts index d51c1d087..f81f932ef 100644 --- a/apps/web-ele/src/views/erp/finance/payment/data.ts +++ b/apps/web-ele/src/views/erp/finance/payment/data.ts @@ -37,7 +37,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { componentProps: { disabled: formType === 'detail', placeholder: '选择付款时间', - type: 'datetime', format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/finance/receipt/data.ts b/apps/web-ele/src/views/erp/finance/receipt/data.ts index 28f23c400..de929dfd7 100644 --- a/apps/web-ele/src/views/erp/finance/receipt/data.ts +++ b/apps/web-ele/src/views/erp/finance/receipt/data.ts @@ -37,7 +37,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { componentProps: { disabled: formType === 'detail', placeholder: '选择收款时间', - type: 'datetime', format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/sale/order/data.ts b/apps/web-ele/src/views/erp/sale/order/data.ts index 36a472ff3..43c6bbc5b 100644 --- a/apps/web-ele/src/views/erp/sale/order/data.ts +++ b/apps/web-ele/src/views/erp/sale/order/data.ts @@ -38,7 +38,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { component: 'DatePicker', componentProps: { placeholder: '选择订单时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/sale/order/index.vue b/apps/web-ele/src/views/erp/sale/order/index.vue index 592078854..e681b8696 100644 --- a/apps/web-ele/src/views/erp/sale/order/index.vue +++ b/apps/web-ele/src/views/erp/sale/order/index.vue @@ -196,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.CHECK : ACTION_ICON.CLOSE, + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-order:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/sale/out/data.ts b/apps/web-ele/src/views/erp/sale/out/data.ts index 824c14a46..8b53f113f 100644 --- a/apps/web-ele/src/views/erp/sale/out/data.ts +++ b/apps/web-ele/src/views/erp/sale/out/data.ts @@ -40,7 +40,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { componentProps: { disabled: formType === 'detail', placeholder: '选择出库时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/sale/return/data.ts b/apps/web-ele/src/views/erp/sale/return/data.ts index 36309ef51..b7729a921 100644 --- a/apps/web-ele/src/views/erp/sale/return/data.ts +++ b/apps/web-ele/src/views/erp/sale/return/data.ts @@ -40,7 +40,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { componentProps: { disabled: formType === 'detail', placeholder: '选择退货时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/stock/check/data.ts b/apps/web-ele/src/views/erp/stock/check/data.ts index 685e940ef..a3c4a3ad9 100644 --- a/apps/web-ele/src/views/erp/stock/check/data.ts +++ b/apps/web-ele/src/views/erp/stock/check/data.ts @@ -35,7 +35,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { component: 'DatePicker', componentProps: { placeholder: '选择盘点时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/stock/in/data.ts b/apps/web-ele/src/views/erp/stock/in/data.ts index caa252a4a..47ec60a76 100644 --- a/apps/web-ele/src/views/erp/stock/in/data.ts +++ b/apps/web-ele/src/views/erp/stock/in/data.ts @@ -36,7 +36,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { component: 'DatePicker', componentProps: { placeholder: '选择入库时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/stock/move/data.ts b/apps/web-ele/src/views/erp/stock/move/data.ts index 5830a7a8d..3bbbf24b6 100644 --- a/apps/web-ele/src/views/erp/stock/move/data.ts +++ b/apps/web-ele/src/views/erp/stock/move/data.ts @@ -35,7 +35,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { component: 'DatePicker', componentProps: { placeholder: '选择调度时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', diff --git a/apps/web-ele/src/views/erp/stock/out/data.ts b/apps/web-ele/src/views/erp/stock/out/data.ts index 481e5ccbf..804c99758 100644 --- a/apps/web-ele/src/views/erp/stock/out/data.ts +++ b/apps/web-ele/src/views/erp/stock/out/data.ts @@ -36,7 +36,6 @@ export function useFormSchema(formType: string): VbenFormSchema[] { component: 'DatePicker', componentProps: { placeholder: '选择出库时间', - showTime: true, format: 'YYYY-MM-DD HH:mm:ss', valueFormat: 'x', class: '!w-full', From 6fa33f4a6296cb0139972c35ee79ede45b15a189 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 19:53:41 +0800 Subject: [PATCH 19/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91sale=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=88100%=EF=BC=89-=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-ele/src/views/erp/sale/out/index.vue | 2 +- .../views/erp/sale/out/modules/sale-order-select.vue | 11 ++++++----- apps/web-ele/src/views/erp/sale/return/index.vue | 2 +- .../erp/sale/return/modules/sale-order-select.vue | 11 ++++++----- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/apps/web-ele/src/views/erp/sale/out/index.vue b/apps/web-ele/src/views/erp/sale/out/index.vue index 360bddc71..528e7f5b3 100644 --- a/apps/web-ele/src/views/erp/sale/out/index.vue +++ b/apps/web-ele/src/views/erp/sale/out/index.vue @@ -193,7 +193,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.CHECK : ACTION_ICON.CLOSE, + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-out:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue b/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue index 250244e74..de1912674 100644 --- a/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue +++ b/apps/web-ele/src/views/erp/sale/out/modules/sale-order-select.vue @@ -6,7 +6,7 @@ import { ref } from 'vue'; import { IconifyIcon } from '@vben/icons'; -import { ElInput, ElMessage } from 'element-plus'; +import { ElButton, ElDialog, ElInput, ElMessage } from 'element-plus'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { getSaleOrderPage } from '#/api/erp/sale/order'; @@ -107,17 +107,18 @@ function handleOk() { - - + diff --git a/apps/web-ele/src/views/erp/sale/return/index.vue b/apps/web-ele/src/views/erp/sale/return/index.vue index b62d479b1..5a76a96b3 100644 --- a/apps/web-ele/src/views/erp/sale/return/index.vue +++ b/apps/web-ele/src/views/erp/sale/return/index.vue @@ -196,7 +196,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ label: row.status === 10 ? '审批' : '反审批', type: 'primary', link: true, - icon: row.status === 10 ? ACTION_ICON.CHECK : ACTION_ICON.CLOSE, + icon: ACTION_ICON.AUDIT, auth: ['erp:sale-return:update-status'], popConfirm: { title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, diff --git a/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue index 0b8628d78..05d4746cd 100644 --- a/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue +++ b/apps/web-ele/src/views/erp/sale/return/modules/sale-order-select.vue @@ -6,7 +6,7 @@ import { ref } from 'vue'; import { IconifyIcon } from '@vben/icons'; -import { ElInput, ElMessage } from 'element-plus'; +import { ElButton, ElDialog, ElInput, ElMessage } from 'element-plus'; import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { getSaleOrderPage } from '#/api/erp/sale/order'; @@ -107,17 +107,18 @@ function handleOk() { - - + From e9164912e527e7d22bd0a1cce8e225287743f7bb Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 20:02:53 +0800 Subject: [PATCH 20/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91home=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=88100%=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/erp/statistics/purchase/index.ts | 16 +- .../src/api/erp/statistics/sale/index.ts | 12 +- apps/web-antd/src/views/erp/home/index.vue | 6 +- .../{SummaryCard.vue => summary-card.vue} | 0 ...ummaryChart.vue => time-summary-chart.vue} | 8 +- .../src/api/erp/statistics/purchase/index.ts | 31 ++++ .../src/api/erp/statistics/sale/index.ts | 31 ++++ apps/web-ele/src/views/erp/home/index.vue | 51 ++++++ .../views/erp/home/modules/summary-card.vue | 69 ++++++++ .../erp/home/modules/time-summary-chart.vue | 161 ++++++++++++++++++ 10 files changed, 364 insertions(+), 21 deletions(-) rename apps/web-antd/src/views/erp/home/modules/{SummaryCard.vue => summary-card.vue} (100%) rename apps/web-antd/src/views/erp/home/modules/{TimeSummaryChart.vue => time-summary-chart.vue} (93%) create mode 100644 apps/web-ele/src/api/erp/statistics/purchase/index.ts create mode 100644 apps/web-ele/src/api/erp/statistics/sale/index.ts create mode 100644 apps/web-ele/src/views/erp/home/index.vue create mode 100644 apps/web-ele/src/views/erp/home/modules/summary-card.vue create mode 100644 apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue diff --git a/apps/web-antd/src/api/erp/statistics/purchase/index.ts b/apps/web-antd/src/api/erp/statistics/purchase/index.ts index 170b9c117..126b6f283 100644 --- a/apps/web-antd/src/api/erp/statistics/purchase/index.ts +++ b/apps/web-antd/src/api/erp/statistics/purchase/index.ts @@ -1,16 +1,16 @@ import { requestClient } from '#/api/request'; export namespace ErpPurchaseStatisticsApi { - /** ERP 采购全局统计 */ - export interface PurchaseSummary { + /** 采购全局统计 */ + export interface PurchaseSummaryRespVO { todayPrice: number; // 今日采购金额 yesterdayPrice: number; // 昨日采购金额 monthPrice: number; // 本月采购金额 yearPrice: number; // 今年采购金额 } - /** ERP 采购时间段统计 */ - export interface PurchaseTimeSummary { + /** 采购时间段统计 */ + export interface PurchaseTimeSummaryRespVO { time: string; // 时间 price: number; // 采购金额 } @@ -18,14 +18,14 @@ export namespace ErpPurchaseStatisticsApi { /** 获得采购统计 */ export function getPurchaseSummary() { - return requestClient.get( + return requestClient.get( '/erp/purchase-statistics/summary', ); } /** 获得采购时间段统计 */ export function getPurchaseTimeSummary() { - return requestClient.get( - '/erp/purchase-statistics/time-summary', - ); + return requestClient.get< + ErpPurchaseStatisticsApi.PurchaseTimeSummaryRespVO[] + >('/erp/purchase-statistics/time-summary'); } diff --git a/apps/web-antd/src/api/erp/statistics/sale/index.ts b/apps/web-antd/src/api/erp/statistics/sale/index.ts index c4c7986a8..209c1c938 100644 --- a/apps/web-antd/src/api/erp/statistics/sale/index.ts +++ b/apps/web-antd/src/api/erp/statistics/sale/index.ts @@ -1,16 +1,16 @@ import { requestClient } from '#/api/request'; export namespace ErpSaleStatisticsApi { - /** ERP 销售全局统计 */ - export interface SaleSummary { + /** 销售全局统计 */ + export interface SaleSummaryRespVO { todayPrice: number; // 今日销售金额 yesterdayPrice: number; // 昨日销售金额 monthPrice: number; // 本月销售金额 yearPrice: number; // 今年销售金额 } - /** ERP 销售时间段统计 */ - export interface SaleTimeSummary { + /** 销售时间段统计 */ + export interface SaleTimeSummaryRespVO { time: string; // 时间 price: number; // 销售金额 } @@ -18,14 +18,14 @@ export namespace ErpSaleStatisticsApi { /** 获得销售统计 */ export function getSaleSummary() { - return requestClient.get( + return requestClient.get( '/erp/sale-statistics/summary', ); } /** 获得销售时间段统计 */ export function getSaleTimeSummary() { - return requestClient.get( + return requestClient.get( '/erp/sale-statistics/time-summary', ); } diff --git a/apps/web-antd/src/views/erp/home/index.vue b/apps/web-antd/src/views/erp/home/index.vue index 7b9d86e26..efb49045b 100644 --- a/apps/web-antd/src/views/erp/home/index.vue +++ b/apps/web-antd/src/views/erp/home/index.vue @@ -5,10 +5,10 @@ import { DocAlert, Page } from '@vben/common-ui'; import { Col, Row, Spin } from 'ant-design-vue'; -import SummaryCard from './modules/SummaryCard.vue'; -import TimeSummaryChart from './modules/TimeSummaryChart.vue'; +import SummaryCard from './modules/summary-card.vue'; +import TimeSummaryChart from './modules/time-summary-chart.vue'; -/** ERP首页 */ +/** ERP 首页 */ defineOptions({ name: 'ErpHome' }); const loading = ref(false); // 加载中 diff --git a/apps/web-antd/src/views/erp/home/modules/SummaryCard.vue b/apps/web-antd/src/views/erp/home/modules/summary-card.vue similarity index 100% rename from apps/web-antd/src/views/erp/home/modules/SummaryCard.vue rename to apps/web-antd/src/views/erp/home/modules/summary-card.vue diff --git a/apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue b/apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue similarity index 93% rename from apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue rename to apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue index 9bdc96eed..ef15eaaf1 100644 --- a/apps/web-antd/src/views/erp/home/modules/TimeSummaryChart.vue +++ b/apps/web-antd/src/views/erp/home/modules/time-summary-chart.vue @@ -26,17 +26,17 @@ const props = withDefaults(defineProps(), { }); /** 销售统计数据 */ -const saleSummary = ref(); // 销售概况统计 -const saleTimeSummaryList = ref(); // 销售时段统计 +const saleSummary = ref(); // 销售概况统计 +const saleTimeSummaryList = ref(); // 销售时段统计 const getSaleStatistics = async () => { saleSummary.value = await getSaleSummary(); saleTimeSummaryList.value = await getSaleTimeSummary(); }; /** 采购统计数据 */ -const purchaseSummary = ref(); // 采购概况统计 +const purchaseSummary = ref(); // 采购概况统计 const purchaseTimeSummaryList = - ref(); // 采购时段统计 + ref(); // 采购时段统计 const getPurchaseStatistics = async () => { purchaseSummary.value = await getPurchaseSummary(); purchaseTimeSummaryList.value = await getPurchaseTimeSummary(); diff --git a/apps/web-ele/src/api/erp/statistics/purchase/index.ts b/apps/web-ele/src/api/erp/statistics/purchase/index.ts new file mode 100644 index 000000000..126b6f283 --- /dev/null +++ b/apps/web-ele/src/api/erp/statistics/purchase/index.ts @@ -0,0 +1,31 @@ +import { requestClient } from '#/api/request'; + +export namespace ErpPurchaseStatisticsApi { + /** 采购全局统计 */ + export interface PurchaseSummaryRespVO { + todayPrice: number; // 今日采购金额 + yesterdayPrice: number; // 昨日采购金额 + monthPrice: number; // 本月采购金额 + yearPrice: number; // 今年采购金额 + } + + /** 采购时间段统计 */ + export interface PurchaseTimeSummaryRespVO { + time: string; // 时间 + price: number; // 采购金额 + } +} + +/** 获得采购统计 */ +export function getPurchaseSummary() { + return requestClient.get( + '/erp/purchase-statistics/summary', + ); +} + +/** 获得采购时间段统计 */ +export function getPurchaseTimeSummary() { + return requestClient.get< + ErpPurchaseStatisticsApi.PurchaseTimeSummaryRespVO[] + >('/erp/purchase-statistics/time-summary'); +} diff --git a/apps/web-ele/src/api/erp/statistics/sale/index.ts b/apps/web-ele/src/api/erp/statistics/sale/index.ts new file mode 100644 index 000000000..209c1c938 --- /dev/null +++ b/apps/web-ele/src/api/erp/statistics/sale/index.ts @@ -0,0 +1,31 @@ +import { requestClient } from '#/api/request'; + +export namespace ErpSaleStatisticsApi { + /** 销售全局统计 */ + export interface SaleSummaryRespVO { + todayPrice: number; // 今日销售金额 + yesterdayPrice: number; // 昨日销售金额 + monthPrice: number; // 本月销售金额 + yearPrice: number; // 今年销售金额 + } + + /** 销售时间段统计 */ + export interface SaleTimeSummaryRespVO { + time: string; // 时间 + price: number; // 销售金额 + } +} + +/** 获得销售统计 */ +export function getSaleSummary() { + return requestClient.get( + '/erp/sale-statistics/summary', + ); +} + +/** 获得销售时间段统计 */ +export function getSaleTimeSummary() { + return requestClient.get( + '/erp/sale-statistics/time-summary', + ); +} diff --git a/apps/web-ele/src/views/erp/home/index.vue b/apps/web-ele/src/views/erp/home/index.vue new file mode 100644 index 000000000..9f6f2ea14 --- /dev/null +++ b/apps/web-ele/src/views/erp/home/index.vue @@ -0,0 +1,51 @@ + + + diff --git a/apps/web-ele/src/views/erp/home/modules/summary-card.vue b/apps/web-ele/src/views/erp/home/modules/summary-card.vue new file mode 100644 index 000000000..ff98e556a --- /dev/null +++ b/apps/web-ele/src/views/erp/home/modules/summary-card.vue @@ -0,0 +1,69 @@ + + + diff --git a/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue b/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue new file mode 100644 index 000000000..fe164eb29 --- /dev/null +++ b/apps/web-ele/src/views/erp/home/modules/time-summary-chart.vue @@ -0,0 +1,161 @@ + + + From 2973e0b70fc058b338f42f378dd9b5ec4739ad68 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 16 Nov 2025 20:27:30 +0800 Subject: [PATCH 21/25] =?UTF-8?q?feat=EF=BC=9A=E3=80=90ele=E3=80=91?= =?UTF-8?q?=E3=80=90erp=E3=80=91purchase=20=E7=9A=84=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=EF=BC=8820%=EF=BC=89-=20supplier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/erp/purchase/supplier/index.vue | 1 - .../views/erp/purchase/in/modules/form.vue | 231 +++++++++++++++++ .../src/views/erp/purchase/supplier/data.ts | 234 ++++++++++++++++++ .../src/views/erp/purchase/supplier/index.vue | 153 ++++++++++++ .../erp/purchase/supplier/modules/form.vue | 90 +++++++ 5 files changed, 708 insertions(+), 1 deletion(-) create mode 100644 apps/web-ele/src/views/erp/purchase/in/modules/form.vue create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/data.ts create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/index.vue create mode 100644 apps/web-ele/src/views/erp/purchase/supplier/modules/form.vue diff --git a/apps/web-antd/src/views/erp/purchase/supplier/index.vue b/apps/web-antd/src/views/erp/purchase/supplier/index.vue index 64cb81aaf..e012568b8 100644 --- a/apps/web-antd/src/views/erp/purchase/supplier/index.vue +++ b/apps/web-antd/src/views/erp/purchase/supplier/index.vue @@ -124,7 +124,6 @@ const [Grid, gridApi] = useVbenVxeGrid({ ]" /> -