From 48693b50f2a50b904198ce787b9abd069d7c2a64 Mon Sep 17 00:00:00 2001 From: dhb52 Date: Mon, 15 Jan 2024 22:45:12 +0800 Subject: [PATCH 01/83] =?UTF-8?q?wip:=20CRM-=E4=BB=A3=E5=8A=9E=E6=B6=88?= =?UTF-8?q?=E6=81=AF-=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9D=97=E4=B8=BAbacklog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/crm/backlog/index.ts | 18 +++++++++ src/api/crm/message/index.ts | 40 ------------------- src/router/modules/remaining.ts | 6 +-- src/views/crm/{message => backlog}/index.vue | 18 +++++++-- .../tables/FollowLeads.vue | 1 + .../tables/TodayCustomer.vue | 34 ++++------------ 6 files changed, 45 insertions(+), 72 deletions(-) create mode 100644 src/api/crm/backlog/index.ts delete mode 100644 src/api/crm/message/index.ts rename src/views/crm/{message => backlog}/index.vue (78%) rename src/views/crm/{message => backlog}/tables/FollowLeads.vue (82%) rename src/views/crm/{message => backlog}/tables/TodayCustomer.vue (84%) diff --git a/src/api/crm/backlog/index.ts b/src/api/crm/backlog/index.ts new file mode 100644 index 000000000..8e70f7454 --- /dev/null +++ b/src/api/crm/backlog/index.ts @@ -0,0 +1,18 @@ +import request from '@/config/axios' + +import { type CustomerVO } from '../customer' +import { type ClueVO } from '../clue' + + +// 查询客户列表 +// TODO @芋艿:看看是不是后续融合到 getCustomerPage 里; +export const getTodayCustomerPage = async (params) => { + return await request.get({ url: `/crm/backlog/today-customer-page`, params }) +} + +// 查询线索列表 +export const getFollowLeadsPage = async (params) => { + return await request.get({ url: `/crm/backlog/page`, params }) +} + +export { type CustomerVO, type ClueVO } diff --git a/src/api/crm/message/index.ts b/src/api/crm/message/index.ts deleted file mode 100644 index 098729eb8..000000000 --- a/src/api/crm/message/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import request from '@/config/axios' - -export interface CustomerVO { - id?: number - name: string - industryId: number - level: number - source: number - followUpStatus?: boolean - lockStatus?: boolean - dealStatus?: boolean - mobile: string - telephone: string - website: string - qq: string - wechat: string - email: string - description: string - remark: string - ownerUserId?: number - ownerUserName?: string - ownerUserDept?: string - roUserIds?: string - rwUserIds?: string - areaId?: number - areaName?: string - detailAddress: string - contactLastTime?: Date - contactNextTime: Date - createTime?: Date - updateTime?: Date - creator?: string - creatorName?: string -} - -// 查询客户列表 -// TODO @芋艿:看看是不是后续融合到 getCustomerPage 里; -export const getTodayCustomerPage = async (params) => { - return await request.get({ url: `/crm/message/todayCustomer`, params }) -} diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 7e8051598..7bcd81d22 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -530,15 +530,15 @@ const remainingRouter: AppRouteRecordRaw[] = [ component: () => import('@/views/crm/product/detail/index.vue') }, { - path: 'message', - name: 'CrmMessage', + path: 'backlog', + name: 'CrmBacklog', meta: { title: '待办事项', noCache: true, hidden: true }, // TODO @db52:后面搞,搞成菜单 - component: () => import('@/views/crm/message/index.vue') + component: () => import('@/views/crm/backlog/index.vue') } ] } diff --git a/src/views/crm/message/index.vue b/src/views/crm/backlog/index.vue similarity index 78% rename from src/views/crm/message/index.vue rename to src/views/crm/backlog/index.vue index 1dd972aaf..bbaf3f165 100644 --- a/src/views/crm/message/index.vue +++ b/src/views/crm/backlog/index.vue @@ -17,13 +17,25 @@ + + + + + + - + + + diff --git a/src/views/crm/backlog/tables/CheckReceivables.vue b/src/views/crm/backlog/tables/CheckReceivables.vue new file mode 100644 index 000000000..2e9189052 --- /dev/null +++ b/src/views/crm/backlog/tables/CheckReceivables.vue @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/views/crm/backlog/tables/EndContract.vue b/src/views/crm/backlog/tables/EndContract.vue new file mode 100644 index 000000000..1910c9707 --- /dev/null +++ b/src/views/crm/backlog/tables/EndContract.vue @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/views/crm/backlog/tables/FollowCustomer.vue b/src/views/crm/backlog/tables/FollowCustomer.vue new file mode 100644 index 000000000..5d98c04d2 --- /dev/null +++ b/src/views/crm/backlog/tables/FollowCustomer.vue @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/views/crm/backlog/tables/PutInPoolRemind.vue b/src/views/crm/backlog/tables/PutInPoolRemind.vue new file mode 100644 index 000000000..bb9b17a51 --- /dev/null +++ b/src/views/crm/backlog/tables/PutInPoolRemind.vue @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/views/crm/backlog/tables/RemindReceivables.vue b/src/views/crm/backlog/tables/RemindReceivables.vue new file mode 100644 index 000000000..fd99b9e6a --- /dev/null +++ b/src/views/crm/backlog/tables/RemindReceivables.vue @@ -0,0 +1,15 @@ + + + + + + + -- Gitee From f88b26e3c3b4f602bd53e463e06520b4158f6bb9 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 20 Jan 2024 17:31:10 +0800 Subject: [PATCH 03/83] =?UTF-8?q?=E5=A4=9A=E5=9B=BE=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/crm/followup/index.ts | 2 + src/components/UploadFile/src/UploadImgs.vue | 68 ++++++++++++------- src/views/crm/followup/FollowUpRecordForm.vue | 53 ++++++--------- .../crm/message/tables/TodayCustomer.vue | 8 +-- .../mall/product/comment/CommentForm.vue | 23 +++---- src/views/mall/product/spu/form/InfoForm.vue | 34 ++++------ .../mall/promotion/diy/page/DiyPageForm.vue | 22 ++---- .../diy/template/DiyTemplateForm.vue | 23 ++----- src/views/mall/trade/config/index.vue | 61 ++++++++--------- 9 files changed, 134 insertions(+), 160 deletions(-) diff --git a/src/api/crm/followup/index.ts b/src/api/crm/followup/index.ts index f6b661057..852d8079e 100644 --- a/src/api/crm/followup/index.ts +++ b/src/api/crm/followup/index.ts @@ -7,6 +7,8 @@ export interface FollowUpRecordVO { bizId: number // 数据编号 type: number // 跟进类型 content: string // 跟进内容 + picUrls: string[] + fileUrls: string[] nextTime: Date // 下次联系时间 businessIds: number[] // 关联的商机编号数组 contactIds: number[] // 关联的联系人编号数组 diff --git a/src/components/UploadFile/src/UploadImgs.vue b/src/components/UploadFile/src/UploadImgs.vue index 041c8ca5f..aa465b562 100644 --- a/src/components/UploadFile/src/UploadImgs.vue +++ b/src/components/UploadFile/src/UploadImgs.vue @@ -28,7 +28,7 @@ 查看 -
+
删除
@@ -46,7 +46,6 @@
diff --git a/src/views/crm/followup/components/BusinessTableSelect.vue b/src/views/crm/followup/components/BusinessTableSelect.vue new file mode 100644 index 000000000..5a34484ed --- /dev/null +++ b/src/views/crm/followup/components/BusinessTableSelect.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/views/crm/followup/components/ContactList.vue b/src/views/crm/followup/components/ContactList.vue index 2cd7ccf05..5e31718ad 100644 --- a/src/views/crm/followup/components/ContactList.vue +++ b/src/views/crm/followup/components/ContactList.vue @@ -69,7 +69,7 @@ const props = withDefaults(defineProps<{ contactIds: number[] }>(), { const list = ref([] as ContactApi.ContactVO[]) const getContactList = async () => { list.value = (await ContactApi.getContactListByIds( - props.contactIds + unref(props.contactIds) )) as unknown as ContactApi.ContactVO[] } watch( diff --git a/src/views/crm/followup/components/ContactTableSelect.vue b/src/views/crm/followup/components/ContactTableSelect.vue new file mode 100644 index 000000000..6790d6e1f --- /dev/null +++ b/src/views/crm/followup/components/ContactTableSelect.vue @@ -0,0 +1,83 @@ + + + diff --git a/src/views/crm/followup/components/index.ts b/src/views/crm/followup/components/index.ts index b3e7f257a..48d90daa1 100644 --- a/src/views/crm/followup/components/index.ts +++ b/src/views/crm/followup/components/index.ts @@ -1,4 +1,6 @@ import BusinessList from './BusinessList.vue' +import BusinessTableSelect from './BusinessTableSelect.vue' import ContactList from './ContactList.vue' +import ContactTableSelect from './ContactTableSelect.vue' -export { BusinessList, ContactList } +export { BusinessList, BusinessTableSelect, ContactList, ContactTableSelect } -- Gitee From d735f782fcb3fa63f625bbc53aeb0169731b1302 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 20 Jan 2024 22:46:52 +0800 Subject: [PATCH 05/83] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20CRM=20?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/crm/permission/index.ts | 17 ++++---- src/views/crm/customer/detail/index.vue | 1 + .../permission/components/PermissionForm.vue | 42 ++++++++++++------- .../permission/components/PermissionList.vue | 33 ++++++++++----- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/api/crm/permission/index.ts b/src/api/crm/permission/index.ts index 9a098b81c..e616a4042 100644 --- a/src/api/crm/permission/index.ts +++ b/src/api/crm/permission/index.ts @@ -2,14 +2,15 @@ import request from '@/config/axios' export interface PermissionVO { id?: number // 数据权限编号 - userId: number | undefined // 用户编号 - bizType: number | undefined // Crm 类型 - bizId: number | undefined // Crm 类型数据编号 - level: number | undefined // 权限级别 + userId: number // 用户编号 + bizType: number // Crm 类型 + bizId: number // Crm 类型数据编号 + level: number // 权限级别 deptName?: string // 部门名称 nickname?: string // 用户昵称 postNames?: string[] // 岗位名称数组 createTime?: Date + ids?: number[] } /** @@ -50,11 +51,11 @@ export const updatePermission = async (data) => { } // 删除数据权限(删除团队成员) -export const deletePermissionBatch = async (params) => { - return await request.delete({ url: '/crm/permission/delete', params }) +export const deletePermissionBatch = async (val: number[]) => { + return await request.delete({ url: '/crm/permission/delete?ids=' + val.join(',') }) } // 删除自己的数据权限(退出团队) -export const deleteSelfPermission = async (id) => { - return await request.delete({ url: '/crm/permission/quit-team?id=' + id }) +export const deleteSelfPermission = async (id: number) => { + return await request.delete({ url: '/crm/permission/delete-self?id=' + id }) } diff --git a/src/views/crm/customer/detail/index.vue b/src/views/crm/customer/detail/index.vue index 41b9a0beb..23c169f64 100644 --- a/src/views/crm/customer/detail/index.vue +++ b/src/views/crm/customer/detail/index.vue @@ -51,6 +51,7 @@ :biz-id="customer.id!" :biz-type="BizTypeEnum.CRM_CUSTOMER" :show-action="!permissionListRef?.isPool || false" + @quit-team="close" /> diff --git a/src/views/crm/permission/components/PermissionForm.vue b/src/views/crm/permission/components/PermissionForm.vue index fa73b22a3..aced2f483 100644 --- a/src/views/crm/permission/components/PermissionForm.vue +++ b/src/views/crm/permission/components/PermissionForm.vue @@ -17,7 +17,6 @@ /> - diff --git a/src/views/crm/bi/rank/FollowCountRank.vue b/src/views/crm/bi/rank/FollowCountRank.vue new file mode 100644 index 000000000..207947efc --- /dev/null +++ b/src/views/crm/bi/rank/FollowCountRank.vue @@ -0,0 +1,98 @@ + + + diff --git a/src/views/crm/bi/rank/FollowCustomerCountRank.vue b/src/views/crm/bi/rank/FollowCustomerCountRank.vue new file mode 100644 index 000000000..c54088b6a --- /dev/null +++ b/src/views/crm/bi/rank/FollowCustomerCountRank.vue @@ -0,0 +1,98 @@ + + + diff --git a/src/views/crm/bi/rank/ProductSalesRank.vue b/src/views/crm/bi/rank/ProductSalesRank.vue new file mode 100644 index 000000000..4de062923 --- /dev/null +++ b/src/views/crm/bi/rank/ProductSalesRank.vue @@ -0,0 +1,98 @@ + + + diff --git a/src/views/crm/bi/rank/ReceivablePriceRank.vue b/src/views/crm/bi/rank/ReceivablePriceRank.vue index 9eb838074..e7e5cff0d 100644 --- a/src/views/crm/bi/rank/ReceivablePriceRank.vue +++ b/src/views/crm/bi/rank/ReceivablePriceRank.vue @@ -13,21 +13,13 @@ - + diff --git a/src/views/erp/product/unit/ProductUnitForm.vue b/src/views/erp/product/unit/ProductUnitForm.vue index 65fe5701f..ca14ff439 100644 --- a/src/views/erp/product/unit/ProductUnitForm.vue +++ b/src/views/erp/product/unit/ProductUnitForm.vue @@ -12,7 +12,13 @@ - 请选择字典生成 + + {{ dict.label }} + @@ -24,6 +30,8 @@ diff --git a/src/views/erp/stock/warehouse/index.vue b/src/views/erp/stock/warehouse/index.vue new file mode 100644 index 000000000..27a13a427 --- /dev/null +++ b/src/views/erp/stock/warehouse/index.vue @@ -0,0 +1,230 @@ + + + + -- Gitee From 26343635e4b25eb5e2969244fae7569fecde7efe Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 5 Feb 2024 19:24:26 +0800 Subject: [PATCH 37/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E6=88=90=20stock=20=E4=BA=A7=E5=93=81=E5=BA=93=E5=AD=98?= =?UTF-8?q?=E3=80=81=E5=BA=93=E5=AD=98=E6=98=8E=E7=BB=86=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/product/{ => product}/index.ts | 5 + src/api/erp/stock/stock/index.ts | 31 +++ src/api/erp/stock/stockRecord/index.ts | 32 +++ src/api/erp/stock/warehouse/index.ts | 5 + src/utils/dict.ts | 4 +- .../erp/product/{ => product}/ProductForm.vue | 2 +- src/views/erp/product/{ => product}/index.vue | 2 +- src/views/erp/product/unit/index.vue | 3 +- src/views/erp/stock/stock/index.vue | 176 +++++++++++++ src/views/erp/stock/stockRecord/index.vue | 231 ++++++++++++++++++ src/views/erp/stock/warehouse/index.vue | 3 +- 11 files changed, 486 insertions(+), 8 deletions(-) rename src/api/erp/product/{ => product}/index.ts (90%) create mode 100644 src/api/erp/stock/stock/index.ts create mode 100644 src/api/erp/stock/stockRecord/index.ts rename src/views/erp/product/{ => product}/ProductForm.vue (99%) rename src/views/erp/product/{ => product}/index.vue (98%) create mode 100644 src/views/erp/stock/stock/index.vue create mode 100644 src/views/erp/stock/stockRecord/index.vue diff --git a/src/api/erp/product/index.ts b/src/api/erp/product/product/index.ts similarity index 90% rename from src/api/erp/product/index.ts rename to src/api/erp/product/product/index.ts index e37e7712d..226fc38c5 100644 --- a/src/api/erp/product/index.ts +++ b/src/api/erp/product/product/index.ts @@ -24,6 +24,11 @@ export const ProductApi = { return await request.get({ url: `/erp/product/page`, params }) }, + // 查询产品精简列表 + getProductSimpleList: async (params: any) => { + return await request.get({ url: `/erp/product/simple-list`, params }) + }, + // 查询产品详情 getProduct: async (id: number) => { return await request.get({ url: `/erp/product/get?id=` + id }) diff --git a/src/api/erp/stock/stock/index.ts b/src/api/erp/stock/stock/index.ts new file mode 100644 index 000000000..2c5bf5eca --- /dev/null +++ b/src/api/erp/stock/stock/index.ts @@ -0,0 +1,31 @@ +import request from '@/config/axios' + +// ERP 产品库存 VO +export interface StockVO { + // 编号 + id: number + // 产品编号 + productId: number + // 仓库编号 + warehouseId: number + // 库存数量 + count: number +} + +// ERP 产品库存 API +export const StockApi = { + // 查询产品库存分页 + getStockPage: async (params: any) => { + return await request.get({ url: `/erp/stock/page`, params }) + }, + + // 查询产品库存详情 + getStock: async (id: number) => { + return await request.get({ url: `/erp/stock/get?id=` + id }) + }, + + // 导出产品库存 Excel + exportStock: async (params) => { + return await request.download({ url: `/erp/stock/export-excel`, params }) + } +} diff --git a/src/api/erp/stock/stockRecord/index.ts b/src/api/erp/stock/stockRecord/index.ts new file mode 100644 index 000000000..a758eb49c --- /dev/null +++ b/src/api/erp/stock/stockRecord/index.ts @@ -0,0 +1,32 @@ +import request from '@/config/axios' + +// ERP 产品库存明细 VO +export interface StockRecordVO { + id: number // 编号 + productId: number // 产品编号 + warehouseId: number // 仓库编号 + count: number // 出入库数量 + totalCount: number // 总库存量 + bizType: number // 业务类型 + bizId: number // 业务编号 + bizItemId: number // 业务项编号 + bizNo: string // 业务单号 +} + +// ERP 产品库存明细 API +export const StockRecordApi = { + // 查询产品库存明细分页 + getStockRecordPage: async (params: any) => { + return await request.get({ url: `/erp/stock-record/page`, params }) + }, + + // 查询产品库存明细详情 + getStockRecord: async (id: number) => { + return await request.get({ url: `/erp/stock-record/get?id=` + id }) + }, + + // 导出产品库存明细 Excel + exportStockRecord: async (params) => { + return await request.download({ url: `/erp/stock-record/export-excel`, params }) + } +} diff --git a/src/api/erp/stock/warehouse/index.ts b/src/api/erp/stock/warehouse/index.ts index 198d19af2..0f493f8ee 100644 --- a/src/api/erp/stock/warehouse/index.ts +++ b/src/api/erp/stock/warehouse/index.ts @@ -21,6 +21,11 @@ export const WarehouseApi = { return await request.get({ url: `/erp/warehouse/page`, params }) }, + // 查询仓库精简列表 + getWarehouseSimpleList: async (params: any) => { + return await request.get({ url: `/erp/warehouse/simple-list`, params }) + }, + // 查询仓库详情 getWarehouse: async (id: number) => { return await request.get({ url: `/erp/warehouse/get?id=` + id }) diff --git a/src/utils/dict.ts b/src/utils/dict.ts index 4c490f59f..14c3d67e6 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -205,6 +205,6 @@ export enum DICT_TYPE { CRM_PRODUCT_UNIT = 'crm_product_unit', // 产品单位 CRM_FOLLOW_UP_TYPE = 'crm_follow_up_type', // 跟进方式 - // ========== BI - 商业智能模块 ========== - BI_ANALYZE_TYPE = 'bi_analyze_type' // 分析类型 + // ========== ERP - 企业资源计划模块 ========== + ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type' // 库存明细的业务类型 } diff --git a/src/views/erp/product/ProductForm.vue b/src/views/erp/product/product/ProductForm.vue similarity index 99% rename from src/views/erp/product/ProductForm.vue rename to src/views/erp/product/product/ProductForm.vue index b981c0dc0..3f9de0ad1 100644 --- a/src/views/erp/product/ProductForm.vue +++ b/src/views/erp/product/product/ProductForm.vue @@ -130,7 +130,7 @@ diff --git a/src/views/erp/stock/stockRecord/index.vue b/src/views/erp/stock/stockRecord/index.vue new file mode 100644 index 000000000..6b4c189f6 --- /dev/null +++ b/src/views/erp/stock/stockRecord/index.vue @@ -0,0 +1,231 @@ + + + + diff --git a/src/views/erp/stock/warehouse/index.vue b/src/views/erp/stock/warehouse/index.vue index 27a13a427..ebd87b3e2 100644 --- a/src/views/erp/stock/warehouse/index.vue +++ b/src/views/erp/stock/warehouse/index.vue @@ -138,8 +138,7 @@ const { t } = useI18n() // 国际化 const loading = ref(true) // 列表的加载中 const list = ref([]) // 列表的数据 -// 列表的总页数 -const total = ref(0) +const total = ref(0) // 列表的总页数 const queryParams = reactive({ pageNo: 1, pageSize: 10, -- Gitee From d92404f351cca80174d44a843dfdd97e57360752 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 6 Feb 2024 00:56:43 +0800 Subject: [PATCH 38/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=85=B6=E5=AE=83=E5=85=A5=E5=BA=93=E7=9A=84?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=2020%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/stock/in/index.ts | 54 ++++ src/views/erp/stock/in/StockInForm.vue | 168 ++++++++++++ .../stock/in/components/StockInItemForm.vue | 163 ++++++++++++ src/views/erp/stock/in/index.vue | 247 ++++++++++++++++++ 4 files changed, 632 insertions(+) create mode 100644 src/api/erp/stock/in/index.ts create mode 100644 src/views/erp/stock/in/StockInForm.vue create mode 100644 src/views/erp/stock/in/components/StockInItemForm.vue create mode 100644 src/views/erp/stock/in/index.vue diff --git a/src/api/erp/stock/in/index.ts b/src/api/erp/stock/in/index.ts new file mode 100644 index 000000000..fc989c7d3 --- /dev/null +++ b/src/api/erp/stock/in/index.ts @@ -0,0 +1,54 @@ +import request from '@/config/axios' + +// ERP 其它入库单 VO +export interface StockInVO { + id: number // 入库编号 + no: string // 入库单号 + supplierId: number // 供应商编号 + inTime: Date // 入库时间 + totalCount: number // 合计数量 + totalPrice: number // 合计金额,单位:元 + status: number // 状态 + remark: string // 备注 +} + +// TODO 芋艿:稍后清理字段 +// ERP 其它入库单 API +export const StockInApi = { + // 查询ERP 其它入库单分页 + getStockInPage: async (params: any) => { + return await request.get({ url: `/erp/stock-in/page`, params }) + }, + + // 查询ERP 其它入库单详情 + getStockIn: async (id: number) => { + return await request.get({ url: `/erp/stock-in/get?id=` + id }) + }, + + // 新增ERP 其它入库单 + createStockIn: async (data: StockInVO) => { + return await request.post({ url: `/erp/stock-in/create`, data }) + }, + + // 修改ERP 其它入库单 + updateStockIn: async (data: StockInVO) => { + return await request.put({ url: `/erp/stock-in/update`, data }) + }, + + // 删除ERP 其它入库单 + deleteStockIn: async (id: number) => { + return await request.delete({ url: `/erp/stock-in/delete?id=` + id }) + }, + + // 导出ERP 其它入库单 Excel + exportStockIn: async (params) => { + return await request.download({ url: `/erp/stock-in/export-excel`, params }) + }, + + // ==================== 子表(ERP 其它入库单项) ==================== + + // 获得ERP 其它入库单项列表 + getStockInItemListByInId: async (inId) => { + return await request.get({ url: `/erp/stock-in/stock-in-item/list-by-in-id?inId=` + inId }) + } +} diff --git a/src/views/erp/stock/in/StockInForm.vue b/src/views/erp/stock/in/StockInForm.vue new file mode 100644 index 000000000..fe9cb68fa --- /dev/null +++ b/src/views/erp/stock/in/StockInForm.vue @@ -0,0 +1,168 @@ + + diff --git a/src/views/erp/stock/in/components/StockInItemForm.vue b/src/views/erp/stock/in/components/StockInItemForm.vue new file mode 100644 index 000000000..b38211234 --- /dev/null +++ b/src/views/erp/stock/in/components/StockInItemForm.vue @@ -0,0 +1,163 @@ + + diff --git a/src/views/erp/stock/in/index.vue b/src/views/erp/stock/in/index.vue new file mode 100644 index 000000000..66ac31f9d --- /dev/null +++ b/src/views/erp/stock/in/index.vue @@ -0,0 +1,247 @@ + + + -- Gitee From 53c94af0271aba3dd0620970745b997a19bf4797 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 6 Feb 2024 12:44:39 +0800 Subject: [PATCH 39/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=85=B6=E5=AE=83=E5=85=A5=E5=BA=93=E7=9A=84?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=2040%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/stock/stock/index.ts | 5 + src/components/UploadFile/src/UploadFile.vue | 2 +- src/views/erp/stock/in/StockInForm.vue | 79 ++++---- .../stock/in/components/StockInItemForm.vue | 172 +++++++++++++----- 4 files changed, 167 insertions(+), 91 deletions(-) diff --git a/src/api/erp/stock/stock/index.ts b/src/api/erp/stock/stock/index.ts index 2c5bf5eca..9296efa0d 100644 --- a/src/api/erp/stock/stock/index.ts +++ b/src/api/erp/stock/stock/index.ts @@ -24,6 +24,11 @@ export const StockApi = { return await request.get({ url: `/erp/stock/get?id=` + id }) }, + // 查询产品库存详情 + getStock2: async (productId: number, warehouseId: number) => { + return await request.get({ url: `/erp/stock/get`, params: { productId, warehouseId } }) + }, + // 导出产品库存 Excel exportStock: async (params) => { return await request.download({ url: `/erp/stock/export-excel`, params }) diff --git a/src/components/UploadFile/src/UploadFile.vue b/src/components/UploadFile/src/UploadFile.vue index a0ef08d6f..5e9c8f3a8 100644 --- a/src/components/UploadFile/src/UploadFile.vue +++ b/src/components/UploadFile/src/UploadFile.vue @@ -160,7 +160,7 @@ const emitUpdateModelValue = () => { // 情况1:数组结果 let result: string | string[] = fileList.value.map((file) => file.url!) // 情况2:逗号分隔的字符串 - if (isString(props.modelValue)) { + if (props.limit === 1 || isString(props.modelValue)) { result = result.join(',') } emit('update:modelValue', result) diff --git a/src/views/erp/stock/in/StockInForm.vue b/src/views/erp/stock/in/StockInForm.vue index fe9cb68fa..fb0f66ab1 100644 --- a/src/views/erp/stock/in/StockInForm.vue +++ b/src/views/erp/stock/in/StockInForm.vue @@ -8,54 +8,54 @@ v-loading="formLoading" > - + + - + - + + - + - - + - + + + + + + - - - - - - - - - - - - - + + + + + + + -- Gitee From 9cbdfe0ecbf4d6391d24f32cfba0dab1e9c7292f Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 6 Feb 2024 15:58:25 +0800 Subject: [PATCH 40/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=85=B6=E5=AE=83=E5=85=A5=E5=BA=93=E7=9A=84?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=2050%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/product/category/index.ts | 18 +++++++++--------- src/api/erp/product/unit/index.ts | 2 +- .../erp/stock/{stockRecord => record}/index.ts | 0 .../stock/in/components/StockInItemForm.vue | 4 ++-- src/views/erp/stock/in/index.vue | 15 ++++----------- .../stock/{stockRecord => recrod}/index.vue | 4 ++-- src/views/erp/stock/warehouse/index.vue | 2 +- 7 files changed, 19 insertions(+), 26 deletions(-) rename src/api/erp/stock/{stockRecord => record}/index.ts (100%) rename src/views/erp/stock/{stockRecord => recrod}/index.vue (98%) diff --git a/src/api/erp/product/category/index.ts b/src/api/erp/product/category/index.ts index dd8a1dc27..72f47dc9c 100644 --- a/src/api/erp/product/category/index.ts +++ b/src/api/erp/product/category/index.ts @@ -1,6 +1,6 @@ import request from '@/config/axios' -// ERP 商品分类 VO +// ERP 产品分类 VO export interface ProductCategoryVO { id: number // 分类编号 parentId: number // 父分类编号 @@ -10,39 +10,39 @@ export interface ProductCategoryVO { status: number // 开启状态 } -// ERP 商品分类 API +// ERP 产品分类 API export const ProductCategoryApi = { - // 查询商品分类列表 + // 查询产品分类列表 getProductCategoryList: async (params) => { return await request.get({ url: `/erp/product-category/list`, params }) }, - // 查询商品分类精简列表 + // 查询产品分类精简列表 getProductCategorySimpleList: async () => { return await request.get({ url: `/erp/product-category/simple-list` }) }, - // 查询商品分类详情 + // 查询产品分类详情 getProductCategory: async (id: number) => { return await request.get({ url: `/erp/product-category/get?id=` + id }) }, - // 新增商品分类 + // 新增产品分类 createProductCategory: async (data: ProductCategoryVO) => { return await request.post({ url: `/erp/product-category/create`, data }) }, - // 修改商品分类 + // 修改产品分类 updateProductCategory: async (data: ProductCategoryVO) => { return await request.put({ url: `/erp/product-category/update`, data }) }, - // 删除商品分类 + // 删除产品分类 deleteProductCategory: async (id: number) => { return await request.delete({ url: `/erp/product-category/delete?id=` + id }) }, - // 导出商品分类 Excel + // 导出产品分类 Excel exportProductCategory: async (params) => { return await request.download({ url: `/erp/product-category/export-excel`, params }) } diff --git a/src/api/erp/product/unit/index.ts b/src/api/erp/product/unit/index.ts index e6af61259..1e1c8ac3d 100644 --- a/src/api/erp/product/unit/index.ts +++ b/src/api/erp/product/unit/index.ts @@ -14,7 +14,7 @@ export const ProductUnitApi = { return await request.get({ url: `/erp/product-unit/page`, params }) }, - // 查询商品单位精简列表 + // 查询产品单位精简列表 getProductUnitSimpleList: async () => { return await request.get({ url: `/erp/product-unit/simple-list` }) }, diff --git a/src/api/erp/stock/stockRecord/index.ts b/src/api/erp/stock/record/index.ts similarity index 100% rename from src/api/erp/stock/stockRecord/index.ts rename to src/api/erp/stock/record/index.ts diff --git a/src/views/erp/stock/in/components/StockInItemForm.vue b/src/views/erp/stock/in/components/StockInItemForm.vue index a3adc1b8e..8b67d5475 100644 --- a/src/views/erp/stock/in/components/StockInItemForm.vue +++ b/src/views/erp/stock/in/components/StockInItemForm.vue @@ -84,7 +84,7 @@ - + diff --git a/src/views/erp/stock/recrod/index.vue b/src/views/erp/stock/record/index.vue similarity index 100% rename from src/views/erp/stock/recrod/index.vue rename to src/views/erp/stock/record/index.vue -- Gitee From 361c06bd6f4d530e16414e466fd29f0fa4300627 Mon Sep 17 00:00:00 2001 From: dhb52 Date: Tue, 6 Feb 2024 22:58:33 +0800 Subject: [PATCH 42/83] =?UTF-8?q?feat:=20crm-backlog=20=E5=BE=85=E5=AE=A1?= =?UTF-8?q?=E6=A0=B8=E5=90=88=E5=90=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/backlog/tables/CheckContract.vue | 174 +++++++++++++++++- src/views/crm/backlog/tables/common.ts | 6 + 2 files changed, 173 insertions(+), 7 deletions(-) diff --git a/src/views/crm/backlog/tables/CheckContract.vue b/src/views/crm/backlog/tables/CheckContract.vue index 2cea0f397..591bebd78 100644 --- a/src/views/crm/backlog/tables/CheckContract.vue +++ b/src/views/crm/backlog/tables/CheckContract.vue @@ -1,15 +1,175 @@ - +const { push } = useRouter() // 路由 + +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + auditStatus: 20 +}) +const queryFormRef = ref() // 搜索的表单 + +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await ContractApi.getContractPage(queryParams) + list.value = data.list + total.value = data.total + } finally { + loading.value = false + } +} - + diff --git a/src/views/crm/backlog/tables/common.ts b/src/views/crm/backlog/tables/common.ts index ec999fca1..f2ac36a98 100644 --- a/src/views/crm/backlog/tables/common.ts +++ b/src/views/crm/backlog/tables/common.ts @@ -17,3 +17,9 @@ export const CONTACT_STATUS = [ { label: '已逾期', value: 2 }, { label: '已联系', value: 3 } ] + +/** 合同审批状态 */ +export const CONTRACT_AUDIT_STATUS = [ + { label: '已审批', value: 20 }, + { label: '待审批', value: 10 } +] -- Gitee From 115c30ea40b209e64c300d928f5a97e03203aac1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 6 Feb 2024 23:28:48 +0800 Subject: [PATCH 43/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=BA=93=E5=8D=95=E7=9A=84=E5=AE=A1=E6=89=B9?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/stock/in/index.ts | 20 ++++- src/views/erp/stock/in/StockInForm.vue | 10 ++- .../stock/in/components/StockInItemForm.vue | 24 +++--- src/views/erp/stock/in/index.vue | 76 +++++++++++++++++-- 4 files changed, 107 insertions(+), 23 deletions(-) diff --git a/src/api/erp/stock/in/index.ts b/src/api/erp/stock/in/index.ts index 3c91ab6f3..148b64f21 100644 --- a/src/api/erp/stock/in/index.ts +++ b/src/api/erp/stock/in/index.ts @@ -34,9 +34,25 @@ export const StockInApi = { return await request.put({ url: `/erp/stock-in/update`, data }) }, + // 更新其它入库单的状态 + updateStockInStatus: async (id: number, status: number) => { + return await request.put({ + url: `/erp/stock-in/update-status`, + params: { + id, + status + } + }) + }, + // 删除其它入库单 - deleteStockIn: async (id: number) => { - return await request.delete({ url: `/erp/stock-in/delete?id=` + id }) + deleteStockIn: async (ids: number[]) => { + return await request.delete({ + url: `/erp/stock-in/delete`, + params: { + ids: ids.join(',') + } + }) }, // 导出其它入库单 Excel diff --git a/src/views/erp/stock/in/StockInForm.vue b/src/views/erp/stock/in/StockInForm.vue index fc11ea257..38b9ec968 100644 --- a/src/views/erp/stock/in/StockInForm.vue +++ b/src/views/erp/stock/in/StockInForm.vue @@ -6,6 +6,7 @@ :rules="formRules" label-width="100px" v-loading="formLoading" + :disabled="disabled" > @@ -63,12 +64,14 @@ - + @@ -87,7 +90,7 @@ const message = useMessage() // 消息弹窗 const dialogVisible = ref(false) // 弹窗的是否展示 const dialogTitle = ref('') // 弹窗的标题 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 -const formType = ref('') // 表单的类型:create - 新增;update - 修改 +const formType = ref('') // 表单的类型:create - 新增;update - 修改;detail - 详情 const formData = ref({ id: undefined, no: undefined, @@ -101,6 +104,7 @@ const formRules = reactive({ no: [{ required: true, message: '入库单号不能为空', trigger: 'blur' }], inTime: [{ required: true, message: '入库时间不能为空', trigger: 'blur' }] }) +const disabled = computed(() => formType.value === 'detail') const formRef = ref() // 表单 Ref const supplierList = ref([]) // 供应商列表 diff --git a/src/views/erp/stock/in/components/StockInItemForm.vue b/src/views/erp/stock/in/components/StockInItemForm.vue index 8b67d5475..74095ca1d 100644 --- a/src/views/erp/stock/in/components/StockInItemForm.vue +++ b/src/views/erp/stock/in/components/StockInItemForm.vue @@ -6,6 +6,7 @@ v-loading="formLoading" label-width="0px" :inline-message="true" + :disabled="disabled" > @@ -120,18 +121,18 @@ - + + 添加入库产品 diff --git a/src/views/erp/stock/in/index.vue b/src/views/erp/stock/in/index.vue index cbfe0d81c..91a66f23a 100644 --- a/src/views/erp/stock/in/index.vue +++ b/src/views/erp/stock/in/index.vue @@ -127,13 +127,29 @@ > 导出 + + 删除 + - + + @@ -146,14 +162,21 @@ /> - + - + diff --git a/src/views/erp/sale/out/SaleOutForm.vue b/src/views/erp/sale/out/SaleOutForm.vue index e83b8d19a..f07e71f02 100644 --- a/src/views/erp/sale/out/SaleOutForm.vue +++ b/src/views/erp/sale/out/SaleOutForm.vue @@ -42,6 +42,7 @@ v-model="formData.customerId" clearable filterable + disabled placeholder="请选择客户" class="!w-1/1" > diff --git a/src/views/erp/sale/return/SaleReturnForm.vue b/src/views/erp/sale/return/SaleReturnForm.vue index 724faa503..2d298a84b 100644 --- a/src/views/erp/sale/return/SaleReturnForm.vue +++ b/src/views/erp/sale/return/SaleReturnForm.vue @@ -15,7 +15,7 @@ - + @@ -176,7 +177,7 @@ - + diff --git a/src/views/erp/purchase/order/components/SaleOrderItemForm.vue b/src/views/erp/purchase/order/components/SaleOrderItemForm.vue new file mode 100644 index 000000000..b94097a95 --- /dev/null +++ b/src/views/erp/purchase/order/components/SaleOrderItemForm.vue @@ -0,0 +1,271 @@ + + diff --git a/src/views/erp/purchase/order/components/SaleOrderOutEnableList.vue b/src/views/erp/purchase/order/components/SaleOrderOutEnableList.vue new file mode 100644 index 000000000..b8fcd5612 --- /dev/null +++ b/src/views/erp/purchase/order/components/SaleOrderOutEnableList.vue @@ -0,0 +1,206 @@ + + + + diff --git a/src/views/erp/purchase/order/components/SaleOrderReturnEnableList.vue b/src/views/erp/purchase/order/components/SaleOrderReturnEnableList.vue new file mode 100644 index 000000000..c8037b862 --- /dev/null +++ b/src/views/erp/purchase/order/components/SaleOrderReturnEnableList.vue @@ -0,0 +1,212 @@ + + + + diff --git a/src/views/erp/purchase/order/index.vue b/src/views/erp/purchase/order/index.vue new file mode 100644 index 000000000..b7bad7910 --- /dev/null +++ b/src/views/erp/purchase/order/index.vue @@ -0,0 +1,405 @@ + + + diff --git a/src/views/erp/sale/order/index.vue b/src/views/erp/sale/order/index.vue index 01e977d6c..e260896fc 100644 --- a/src/views/erp/sale/order/index.vue +++ b/src/views/erp/sale/order/index.vue @@ -95,21 +95,21 @@ class="!w-240px" /> - + - - - + + + - + Date: Mon, 12 Feb 2024 10:00:09 +0800 Subject: [PATCH 67/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E5=AE=8C=E6=88=90=E9=87=87=E8=B4=AD=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=20100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...aleOrderForm.vue => PurchaseOrderForm.vue} | 64 +++++++------------ ...ItemForm.vue => PurchaseOrderItemForm.vue} | 6 +- .../components/SaleOrderOutEnableList.vue | 10 +-- .../components/SaleOrderReturnEnableList.vue | 10 +-- src/views/erp/purchase/order/index.vue | 8 +-- .../order/components/SaleOrderItemForm.vue | 4 +- .../sale/out/components/SaleOutItemForm.vue | 2 +- .../return/components/SaleReturnItemForm.vue | 2 +- 8 files changed, 43 insertions(+), 63 deletions(-) rename src/views/erp/purchase/order/{SaleOrderForm.vue => PurchaseOrderForm.vue} (81%) rename src/views/erp/purchase/order/components/{SaleOrderItemForm.vue => PurchaseOrderItemForm.vue} (98%) diff --git a/src/views/erp/purchase/order/SaleOrderForm.vue b/src/views/erp/purchase/order/PurchaseOrderForm.vue similarity index 81% rename from src/views/erp/purchase/order/SaleOrderForm.vue rename to src/views/erp/purchase/order/PurchaseOrderForm.vue index 30b2b3028..8ba6d37c8 100644 --- a/src/views/erp/purchase/order/SaleOrderForm.vue +++ b/src/views/erp/purchase/order/PurchaseOrderForm.vue @@ -26,16 +26,16 @@ - + - - - - - - - - + @@ -131,13 +113,13 @@ - + @@ -153,15 +135,15 @@ diff --git a/src/views/erp/purchase/in/components/PurchaseInItemForm.vue b/src/views/erp/purchase/in/components/PurchaseInItemForm.vue new file mode 100644 index 000000000..64377bc71 --- /dev/null +++ b/src/views/erp/purchase/in/components/PurchaseInItemForm.vue @@ -0,0 +1,300 @@ + + diff --git a/src/views/erp/purchase/in/index.vue b/src/views/erp/purchase/in/index.vue new file mode 100644 index 000000000..b0787cacb --- /dev/null +++ b/src/views/erp/purchase/in/index.vue @@ -0,0 +1,444 @@ + + + -- Gitee From 57044cb716d33d01d19ed92003b7fb902964673b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 12 Feb 2024 16:51:18 +0800 Subject: [PATCH 69/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E9=87=87?= =?UTF-8?q?=E8=B4=AD=E5=85=A5=E5=BA=93=20100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/erp/purchase/in/PurchaseInForm.vue | 72 +++++++------------ src/views/erp/purchase/in/index.vue | 6 +- .../erp/purchase/order/PurchaseOrderForm.vue | 2 +- ...List.vue => PurchaseOrderInEnableList.vue} | 7 +- .../components/SaleOrderReturnEnableList.vue | 4 +- src/views/erp/purchase/order/index.vue | 6 +- 6 files changed, 38 insertions(+), 59 deletions(-) rename src/views/erp/purchase/order/components/{SaleOrderOutEnableList.vue => PurchaseOrderInEnableList.vue} (98%) diff --git a/src/views/erp/purchase/in/PurchaseInForm.vue b/src/views/erp/purchase/in/PurchaseInForm.vue index 527069846..9affc6c0d 100644 --- a/src/views/erp/purchase/in/PurchaseInForm.vue +++ b/src/views/erp/purchase/in/PurchaseInForm.vue @@ -37,9 +37,9 @@ - + - - - - - - - - + - + @@ -177,10 +159,10 @@ - - - - + diff --git a/src/views/erp/purchase/return/components/SaleReturnItemForm.vue b/src/views/erp/purchase/return/components/SaleReturnItemForm.vue new file mode 100644 index 000000000..2d3e8c58b --- /dev/null +++ b/src/views/erp/purchase/return/components/SaleReturnItemForm.vue @@ -0,0 +1,300 @@ + + diff --git a/src/views/erp/purchase/return/index.vue b/src/views/erp/purchase/return/index.vue new file mode 100644 index 000000000..6d8bafe33 --- /dev/null +++ b/src/views/erp/purchase/return/index.vue @@ -0,0 +1,432 @@ + + + -- Gitee From db446330c3462e143c6dab498a771f19b9495c67 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 12 Feb 2024 21:03:29 +0800 Subject: [PATCH 71/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E9=87=87?= =?UTF-8?q?=E8=B4=AD=E9=80=80=E8=B4=A7=2070%=EF=BC=88=E8=AF=A6=E6=83=85?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/erp/purchase/in/PurchaseInForm.vue | 5 +- src/views/erp/purchase/in/index.vue | 6 +- .../components/PurchaseOrderInEnableList.vue | 2 +- .../components/SaleOrderReturnEnableList.vue | 2 +- ...eReturnForm.vue => PurchaseReturnForm.vue} | 55 ++++++------------- ...temForm.vue => PurchaseReturnItemForm.vue} | 0 src/views/erp/purchase/return/index.vue | 4 +- 7 files changed, 26 insertions(+), 48 deletions(-) rename src/views/erp/purchase/return/{SaleReturnForm.vue => PurchaseReturnForm.vue} (87%) rename src/views/erp/purchase/return/components/{SaleReturnItemForm.vue => PurchaseReturnItemForm.vue} (100%) diff --git a/src/views/erp/purchase/in/PurchaseInForm.vue b/src/views/erp/purchase/in/PurchaseInForm.vue index 9affc6c0d..29f38813f 100644 --- a/src/views/erp/purchase/in/PurchaseInForm.vue +++ b/src/views/erp/purchase/in/PurchaseInForm.vue @@ -167,13 +167,12 @@ -- Gitee From d7427bf49cd4c33f62b60f085d827b6d5860b483 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 14 Feb 2024 11:25:55 +0800 Subject: [PATCH 75/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E4=BB=98?= =?UTF-8?q?=E6=AC=BE=E5=8D=95=2050%=EF=BC=88=E8=AF=A6=E6=83=85=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../finance/payment/FinancePaymentForm.vue | 279 ++++++++++++++++++ .../components/FinancePaymentItemForm.vue | 140 +++++++++ src/views/erp/finance/payment/index.vue | 6 +- 3 files changed, 422 insertions(+), 3 deletions(-) create mode 100644 src/views/erp/finance/payment/FinancePaymentForm.vue create mode 100644 src/views/erp/finance/payment/components/FinancePaymentItemForm.vue diff --git a/src/views/erp/finance/payment/FinancePaymentForm.vue b/src/views/erp/finance/payment/FinancePaymentForm.vue new file mode 100644 index 000000000..adfadd21c --- /dev/null +++ b/src/views/erp/finance/payment/FinancePaymentForm.vue @@ -0,0 +1,279 @@ + + diff --git a/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue b/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue new file mode 100644 index 000000000..54dcb8b98 --- /dev/null +++ b/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue @@ -0,0 +1,140 @@ + + diff --git a/src/views/erp/finance/payment/index.vue b/src/views/erp/finance/payment/index.vue index 1bfc9618c..ce575fd01 100644 --- a/src/views/erp/finance/payment/index.vue +++ b/src/views/erp/finance/payment/index.vue @@ -255,7 +255,7 @@ - + diff --git a/src/views/erp/purchase/order/components/PurchaseOrderInEnableList.vue b/src/views/erp/purchase/order/components/PurchaseOrderInEnableList.vue index 85d1fda3c..e10694a0a 100644 --- a/src/views/erp/purchase/order/components/PurchaseOrderInEnableList.vue +++ b/src/views/erp/purchase/order/components/PurchaseOrderInEnableList.vue @@ -73,7 +73,7 @@ - + Date: Wed, 14 Feb 2024 17:13:55 +0800 Subject: [PATCH 77/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E6=88=90=20payment=20=E4=BB=98=E6=AC=BE=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FinancePaymentItemForm.vue | 34 ++- src/views/erp/finance/payment/index.vue | 6 +- .../PurchaseReturnRefundEnableList.vue | 200 ++++++++++++++++++ 3 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 src/views/erp/purchase/return/components/PurchaseReturnRefundEnableList.vue diff --git a/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue b/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue index 03f53eab8..ea0e085e2 100644 --- a/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue +++ b/src/views/erp/finance/payment/components/FinancePaymentItemForm.vue @@ -37,7 +37,6 @@ @@ -60,20 +59,28 @@ + 添加采购入库单 - + 添加采购退货单 + + 添加采购退货单 + + + -- Gitee From e07e19106cc7154337f552161b0050204d3564a3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 15 Feb 2024 09:16:18 +0800 Subject: [PATCH 78/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E9=94=80?= =?UTF-8?q?=E5=94=AE=E8=AE=A2=E5=8D=95=E7=9A=84=20receiptPrice=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=8C=E4=B8=BA=E6=8E=A5=E5=85=A5=E8=B4=A2=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E6=94=B6=E6=AC=BE=E5=8D=95=E5=81=9A=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/erp/sale/order/index.vue | 2 +- src/views/erp/sale/out/SaleOutForm.vue | 30 ++++-------- src/views/erp/sale/out/index.vue | 44 +++++++---------- src/views/erp/sale/return/SaleReturnForm.vue | 31 ++++-------- src/views/erp/sale/return/index.vue | 51 ++++++++++++-------- 5 files changed, 67 insertions(+), 91 deletions(-) diff --git a/src/views/erp/sale/order/index.vue b/src/views/erp/sale/order/index.vue index e260896fc..a8a85ef6b 100644 --- a/src/views/erp/sale/order/index.vue +++ b/src/views/erp/sale/order/index.vue @@ -41,7 +41,7 @@ start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" + class="!w-220px" /> diff --git a/src/views/erp/sale/out/SaleOutForm.vue b/src/views/erp/sale/out/SaleOutForm.vue index f07e71f02..7d47713a4 100644 --- a/src/views/erp/sale/out/SaleOutForm.vue +++ b/src/views/erp/sale/out/SaleOutForm.vue @@ -121,7 +121,11 @@ - + @@ -155,15 +159,8 @@ - - + + @@ -211,15 +208,13 @@ const formData = ref({ discountPrice: 0, totalPrice: 0, otherPrice: 0, - payPrice: undefined, orderNo: undefined, items: [], no: undefined // 出库单号,后端返回 }) const formRules = reactive({ customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], - outTime: [{ required: true, message: '出库时间不能为空', trigger: 'blur' }], - payPrice: [{ required: true, message: '本次收款不能为空', trigger: 'blur' }] + outTime: [{ required: true, message: '出库时间不能为空', trigger: 'blur' }] }) const disabled = computed(() => formType.value === 'detail') const formRef = ref() // 表单 Ref @@ -242,14 +237,8 @@ watch( const totalPrice = val.items.reduce((prev, curr) => prev + curr.totalPrice, 0) const discountPrice = val.discountPercent != null ? erpPriceMultiply(totalPrice, val.discountPercent / 100.0) : 0 - // debugger - // TODO 芋艿:payPrice 自动计算会有问题,界面上看到修改了,传递到后端还是没改过来 - // const payPrice = totalPrice - discountPrice + val.otherPrice - // 赋值 formData.value.discountPrice = discountPrice - formData.value.totalPrice = totalPrice - discountPrice - // val.payPrice = payPrice - // formData.value.payPrice = payPrice + formData.value.totalPrice = totalPrice - discountPrice + val.otherPrice }, { deep: true } ) @@ -347,7 +336,6 @@ const resetForm = () => { discountPrice: 0, totalPrice: 0, otherPrice: 0, - payPrice: undefined, items: [] } formRef.value?.resetFields() diff --git a/src/views/erp/sale/out/index.vue b/src/views/erp/sale/out/index.vue index af8f8a3a8..9e1ff3cf0 100644 --- a/src/views/erp/sale/out/index.vue +++ b/src/views/erp/sale/out/index.vue @@ -41,7 +41,7 @@ start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" + class="!w-220px" /> @@ -117,18 +117,19 @@ /> - + - - + + + - + - - - - - + - + @@ -337,7 +329,7 @@ const queryParams = reactive({ warehouseId: undefined, outTime: [], orderNo: undefined, - debtStatus: undefined, + receiptStatus: undefined, accountId: undefined, status: undefined, remark: undefined, diff --git a/src/views/erp/sale/return/SaleReturnForm.vue b/src/views/erp/sale/return/SaleReturnForm.vue index 2d298a84b..b10403b80 100644 --- a/src/views/erp/sale/return/SaleReturnForm.vue +++ b/src/views/erp/sale/return/SaleReturnForm.vue @@ -121,7 +121,11 @@ - + @@ -155,15 +159,8 @@ - - + + @@ -211,15 +208,13 @@ const formData = ref({ discountPrice: 0, totalPrice: 0, otherPrice: 0, - refundPrice: undefined, orderNo: undefined, items: [], no: undefined // 退货单号,后端返回 }) const formRules = reactive({ customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], - returnTime: [{ required: true, message: '退货时间不能为空', trigger: 'blur' }], - refundPrice: [{ required: true, message: '本次退款不能为空', trigger: 'blur' }] + returnTime: [{ required: true, message: '退货时间不能为空', trigger: 'blur' }] }) const disabled = computed(() => formType.value === 'detail') const formRef = ref() // 表单 Ref @@ -242,14 +237,7 @@ watch( const totalPrice = val.items.reduce((prev, curr) => prev + curr.totalPrice, 0) const discountPrice = val.discountPercent != null ? erpPriceMultiply(totalPrice, val.discountPercent / 100.0) : 0 - // debugger - // TODO 芋艿:refundPrice 自动计算会有问题,界面上看到修改了,传递到后端还是没改过来 - // const refundPrice = totalPrice - discountPrice + val.otherPrice - // 赋值 - formData.value.discountPrice = discountPrice - formData.value.totalPrice = totalPrice - discountPrice - // val.refundPrice = refundPrice - // formData.value.refundPrice = refundPrice + formData.value.totalPrice = totalPrice - discountPrice + val.otherPrice }, { deep: true } ) @@ -346,7 +334,6 @@ const resetForm = () => { discountPrice: 0, totalPrice: 0, otherPrice: 0, - refundPrice: undefined, items: [] } formRef.value?.resetFields() diff --git a/src/views/erp/sale/return/index.vue b/src/views/erp/sale/return/index.vue index 2b3ca3e91..6b3b1b37f 100644 --- a/src/views/erp/sale/return/index.vue +++ b/src/views/erp/sale/return/index.vue @@ -41,7 +41,7 @@ start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" + class="!w-220px" /> @@ -117,8 +117,25 @@ /> - - + + + + + + + + + - - - - - + - + @@ -329,7 +337,8 @@ const queryParams = reactive({ accountId: undefined, status: undefined, remark: undefined, - creator: undefined + creator: undefined, + refundStatus: undefined }) const queryFormRef = ref() // 搜索的表单 const exportLoading = ref(false) // 导出的加载中 -- Gitee From c18b24e6115f7d75f2c9b93d936ae27006df2f87 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 16 Feb 2024 08:13:25 +0800 Subject: [PATCH 79/83] =?UTF-8?q?=E2=9C=A8=20ERP=EF=BC=9A=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=20receipt=20=E6=94=B6=E6=AC=BE=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91=20100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/erp/finance/receipt/index.ts | 61 +++ .../finance/receipt/FinanceReceiptForm.vue | 278 +++++++++++++ .../components/FinanceReceiptItemForm.vue | 176 ++++++++ src/views/erp/finance/receipt/index.vue | 389 ++++++++++++++++++ .../PurchaseReturnRefundEnableList.vue | 12 +- .../components/SaleOutReceiptEnableList.vue | 199 +++++++++ .../components/SaleReturnRefundEnableList.vue | 199 +++++++++ 7 files changed, 1308 insertions(+), 6 deletions(-) create mode 100644 src/api/erp/finance/receipt/index.ts create mode 100644 src/views/erp/finance/receipt/FinanceReceiptForm.vue create mode 100644 src/views/erp/finance/receipt/components/FinanceReceiptItemForm.vue create mode 100644 src/views/erp/finance/receipt/index.vue create mode 100644 src/views/erp/sale/out/components/SaleOutReceiptEnableList.vue create mode 100644 src/views/erp/sale/return/components/SaleReturnRefundEnableList.vue diff --git a/src/api/erp/finance/receipt/index.ts b/src/api/erp/finance/receipt/index.ts new file mode 100644 index 000000000..4de28ca77 --- /dev/null +++ b/src/api/erp/finance/receipt/index.ts @@ -0,0 +1,61 @@ +import request from '@/config/axios' + +// ERP 收款单 VO +export interface FinanceReceiptVO { + id: number // 收款单编号 + no: string // 收款单号 + customerId: number // 客户编号 + receiptTime: Date // 收款时间 + totalPrice: number // 合计金额,单位:元 + status: number // 状态 + remark: string // 备注 +} + +// ERP 收款单 API +export const FinanceReceiptApi = { + // 查询收款单分页 + getFinanceReceiptPage: async (params: any) => { + return await request.get({ url: `/erp/finance-receipt/page`, params }) + }, + + // 查询收款单详情 + getFinanceReceipt: async (id: number) => { + return await request.get({ url: `/erp/finance-receipt/get?id=` + id }) + }, + + // 新增收款单 + createFinanceReceipt: async (data: FinanceReceiptVO) => { + return await request.post({ url: `/erp/finance-receipt/create`, data }) + }, + + // 修改收款单 + updateFinanceReceipt: async (data: FinanceReceiptVO) => { + return await request.put({ url: `/erp/finance-receipt/update`, data }) + }, + + // 更新收款单的状态 + updateFinanceReceiptStatus: async (id: number, status: number) => { + return await request.put({ + url: `/erp/finance-receipt/update-status`, + params: { + id, + status + } + }) + }, + + // 删除收款单 + deleteFinanceReceipt: async (ids: number[]) => { + return await request.delete({ + url: `/erp/finance-receipt/delete`, + params: { + ids: ids.join(',') + } + }) + }, + + // 导出收款单 Excel + exportFinanceReceipt: async (params: any) => { + return await request.download({ url: `/erp/finance-receipt/export-excel`, params }) + } +} diff --git a/src/views/erp/finance/receipt/FinanceReceiptForm.vue b/src/views/erp/finance/receipt/FinanceReceiptForm.vue new file mode 100644 index 000000000..96826eb24 --- /dev/null +++ b/src/views/erp/finance/receipt/FinanceReceiptForm.vue @@ -0,0 +1,278 @@ + + diff --git a/src/views/erp/finance/receipt/components/FinanceReceiptItemForm.vue b/src/views/erp/finance/receipt/components/FinanceReceiptItemForm.vue new file mode 100644 index 000000000..1a48b4181 --- /dev/null +++ b/src/views/erp/finance/receipt/components/FinanceReceiptItemForm.vue @@ -0,0 +1,176 @@ + + diff --git a/src/views/erp/finance/receipt/index.vue b/src/views/erp/finance/receipt/index.vue new file mode 100644 index 000000000..c85b398b6 --- /dev/null +++ b/src/views/erp/finance/receipt/index.vue @@ -0,0 +1,389 @@ + + + diff --git a/src/views/erp/purchase/return/components/PurchaseReturnRefundEnableList.vue b/src/views/erp/purchase/return/components/PurchaseReturnRefundEnableList.vue index a26d90144..a95749eae 100644 --- a/src/views/erp/purchase/return/components/PurchaseReturnRefundEnableList.vue +++ b/src/views/erp/purchase/return/components/PurchaseReturnRefundEnableList.vue @@ -43,7 +43,7 @@ ([]) // 产品列表 /** 选中操作 */ -const selectionList = ref([]) -const handleSelectionChange = (rows: PurchaseInVO[]) => { +const selectionList = ref([]) +const handleSelectionChange = (rows: SaleReturnVO[]) => { selectionList.value = rows } @@ -162,7 +162,7 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗 /** 提交选择 */ const emits = defineEmits<{ - (e: 'success', value: PurchaseInVO[]): void + (e: 'success', value: SaleReturnVO[]): void }>() const submitForm = () => { try { diff --git a/src/views/erp/sale/out/components/SaleOutReceiptEnableList.vue b/src/views/erp/sale/out/components/SaleOutReceiptEnableList.vue new file mode 100644 index 000000000..0c4a21d11 --- /dev/null +++ b/src/views/erp/sale/out/components/SaleOutReceiptEnableList.vue @@ -0,0 +1,199 @@ + + + diff --git a/src/views/erp/sale/return/components/SaleReturnRefundEnableList.vue b/src/views/erp/sale/return/components/SaleReturnRefundEnableList.vue new file mode 100644 index 000000000..dc875e693 --- /dev/null +++ b/src/views/erp/sale/return/components/SaleReturnRefundEnableList.vue @@ -0,0 +1,199 @@ + + + -- Gitee From bb6d6dac798d0db3c3a2f878200129667e94864b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Feb 2024 10:12:01 +0800 Subject: [PATCH 80/83] =?UTF-8?q?=E2=9C=A8=20=E5=A2=9E=E5=8A=A0=20ERP=20?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=9A=84=E4=BB=8B=E7=BB=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .image/common/erp-feature.png | Bin 0 -> 47016 bytes README.md | 9 +++++++++ src/views/erp/stock/in/index.vue | 2 +- src/views/erp/stock/record/index.vue | 6 +++++- 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .image/common/erp-feature.png diff --git a/.image/common/erp-feature.png b/.image/common/erp-feature.png new file mode 100644 index 0000000000000000000000000000000000000000..d30b30eed9d4e072c61ebf3bb63809b2b5593078 GIT binary patch literal 47016 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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 6c0cc78dc..db78baa90 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ * 数据报表 * 商城系统 * 微信公众号 +* ERP 系统 +* CRM 系统 ### 系统功能 @@ -194,6 +196,12 @@ _前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋 演示地址: +### ERP 系统 + +![功能图](/.image/common/erp-feature.png) + +演示地址: + ## 🐷 演示图 ### 系统功能 @@ -238,6 +246,7 @@ _前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋 |---------|---------------------------|---------------------------------|---------------------------------| | 商家 & 应用 | ![商户信息](/.image/商户信息.jpg) | ![应用信息-列表](/.image/应用信息-列表.jpg) | ![应用信息-编辑](/.image/应用信息-编辑.jpg) | | 支付 & 退款 | ![支付订单](/.image/支付订单.jpg) | ![退款订单](/.image/退款订单.jpg) | --- | + ### 数据报表 | 模块 | biu | biu | biu | diff --git a/src/views/erp/stock/in/index.vue b/src/views/erp/stock/in/index.vue index 6da0e803b..6ad80f965 100644 --- a/src/views/erp/stock/in/index.vue +++ b/src/views/erp/stock/in/index.vue @@ -41,7 +41,7 @@ start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" + class="!w-220px" /> diff --git a/src/views/erp/stock/record/index.vue b/src/views/erp/stock/record/index.vue index c2ceaeda9..cbd48bd17 100644 --- a/src/views/erp/stock/record/index.vue +++ b/src/views/erp/stock/record/index.vue @@ -73,7 +73,7 @@ start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" - class="!w-240px" + class="!w-220px" /> @@ -235,6 +235,10 @@ const handleExport = async () => { } /** 初始化 **/ +onActivated(() => { + getList() +}) + onMounted(async () => { await getList() // 加载产品、仓库列表 -- Gitee From 06e2019adf164b2562911ced48287e72505d65d8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 17 Feb 2024 18:02:40 +0800 Subject: [PATCH 81/83] =?UTF-8?q?=F0=9F=93=96=20CRM=EF=BC=9Acode=20review?= =?UTF-8?q?=20=E5=BE=85=E5=8A=9E=E9=A1=B9=E7=9B=AE=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/modules/remaining.ts | 11 ----------- src/views/crm/backlog/index.vue | 7 ++----- src/views/crm/backlog/tables/CheckContract.vue | 3 +-- src/views/crm/backlog/tables/TodayCustomer.vue | 8 +++++--- src/views/crm/customer/index.vue | 6 +++--- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index edda38207..4eec8cd49 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -539,17 +539,6 @@ const remainingRouter: AppRouteRecordRaw[] = [ activeMenu: '/crm/product' }, component: () => import('@/views/crm/product/detail/index.vue') - }, - { - path: 'backlog', - name: 'CrmBacklog', - meta: { - title: '待办事项', - noCache: true, - hidden: true - }, - // TODO @db52:后面搞,搞成菜单 - component: () => import('@/views/crm/backlog/index.vue') } ] } diff --git a/src/views/crm/backlog/index.vue b/src/views/crm/backlog/index.vue index 5fb539609..0d42c960e 100644 --- a/src/views/crm/backlog/index.vue +++ b/src/views/crm/backlog/index.vue @@ -1,4 +1,3 @@ -