Browse Source

Merge remote-tracking branch 'yudao/master'

# Conflicts:
#	src/api/infra/demo/demo03/erp/index.ts
#	src/api/infra/demo/demo03/inner/index.ts
#	src/api/infra/demo/demo03/normal/index.ts
#	src/views/infra/demo/demo03/erp/components/Demo03CourseList.vue
#	src/views/infra/demo/demo03/erp/components/Demo03GradeList.vue
#	src/views/infra/demo/demo03/erp/index.vue
puhui999 8 months ago
parent
commit
c351a69371
100 changed files with 14349 additions and 466 deletions
  1. 8 0
      .env
  2. 0 19
      .env.base
  3. 20 14
      .env.dev
  4. 0 34
      .env.front
  5. 34 0
      .env.local
  6. 10 7
      .env.pro
  7. 9 6
      .env.stage
  8. 10 7
      .env.static
  9. 3 1
      .eslintrc.js
  10. 0 2
      .gitignore
  11. BIN
      .image/common/ai-feature.png
  12. BIN
      .image/common/ai-preview.gif
  13. BIN
      .image/common/bpm-feature.png
  14. BIN
      .image/common/crm-feature.png
  15. BIN
      .image/common/erp-feature.png
  16. BIN
      .image/common/infra-feature.png
  17. BIN
      .image/common/system-feature.png
  18. BIN
      .image/demo/vue3-ep.png
  19. BIN
      .image/工作流设计器-bpmn.jpg
  20. BIN
      .image/工作流设计器-simple.jpg
  21. 0 1
      .vscode/extensions.json
  22. 3 2
      .vscode/settings.json
  23. 110 62
      README.md
  24. 1 2
      build/vite/index.ts
  25. 12 1
      build/vite/optimize.ts
  26. 73 64
      package.json
  27. 10526 0
      pnpm-lock.yaml
  28. BIN
      public/home.png
  29. 65 0
      src/api/ai/chat/conversation/index.ts
  30. 90 0
      src/api/ai/chat/message/index.ts
  31. 102 0
      src/api/ai/image/index.ts
  32. 54 0
      src/api/ai/knowledge/document/index.ts
  33. 44 0
      src/api/ai/knowledge/knowledge/index.ts
  34. 75 0
      src/api/ai/knowledge/segment/index.ts
  35. 60 0
      src/api/ai/mindmap/index.ts
  36. 44 0
      src/api/ai/model/apiKey/index.ts
  37. 82 0
      src/api/ai/model/chatRole/index.ts
  38. 54 0
      src/api/ai/model/model/index.ts
  39. 42 0
      src/api/ai/model/tool/index.ts
  40. 41 0
      src/api/ai/music/index.ts
  41. 25 0
      src/api/ai/workflow/index.ts
  42. 85 0
      src/api/ai/write/index.ts
  43. 0 8
      src/api/bpm/activity/index.ts
  44. 53 0
      src/api/bpm/category/index.ts
  45. 9 2
      src/api/bpm/definition/index.ts
  46. 2 2
      src/api/bpm/form/index.ts
  47. 1 1
      src/api/bpm/leave/index.ts
  48. 22 3
      src/api/bpm/model/index.ts
  49. 42 0
      src/api/bpm/processExpression/index.ts
  50. 73 5
      src/api/bpm/processInstance/index.ts
  51. 40 0
      src/api/bpm/processListener/index.ts
  52. 15 0
      src/api/bpm/simple/index.ts
  53. 76 44
      src/api/bpm/task/index.ts
  54. 0 29
      src/api/bpm/taskAssignRule/index.ts
  55. 3 3
      src/api/bpm/userGroup/index.ts
  56. 98 0
      src/api/crm/business/index.ts
  57. 68 0
      src/api/crm/business/status/index.ts
  58. 45 13
      src/api/crm/clue/index.ts
  59. 85 39
      src/api/crm/contact/index.ts
  60. 16 0
      src/api/crm/contract/config/index.ts
  61. 75 14
      src/api/crm/contract/index.ts
  62. 97 33
      src/api/crm/customer/index.ts
  63. 14 0
      src/api/crm/customerLimitConfig/index.ts
  64. 3 3
      src/api/crm/customerPoolConf/index.ts
  65. 43 0
      src/api/crm/followup/index.ts
  66. 11 0
      src/api/crm/operateLog/index.ts
  67. 47 23
      src/api/crm/permission/index.ts
  68. 0 0
      src/api/crm/product/category/index.ts
  69. 7 1
      src/api/crm/product/index.ts
  70. 38 16
      src/api/crm/receivable/index.ts
  71. 30 5
      src/api/crm/receivablePlan/index.ts
  72. 168 0
      src/api/crm/statistics/customer.ts
  73. 58 0
      src/api/crm/statistics/funnel.ts
  74. 33 0
      src/api/crm/statistics/performance.ts
  75. 60 0
      src/api/crm/statistics/portrait.ts
  76. 67 0
      src/api/crm/statistics/rank.ts
  77. 61 0
      src/api/erp/finance/account/index.ts
  78. 61 0
      src/api/erp/finance/payment/index.ts
  79. 61 0
      src/api/erp/finance/receipt/index.ts
  80. 49 0
      src/api/erp/product/category/index.ts
  81. 57 0
      src/api/erp/product/product/index.ts
  82. 46 0
      src/api/erp/product/unit/index.ts
  83. 64 0
      src/api/erp/purchase/in/index.ts
  84. 64 0
      src/api/erp/purchase/order/index.ts
  85. 62 0
      src/api/erp/purchase/return/index.ts
  86. 58 0
      src/api/erp/purchase/supplier/index.ts
  87. 58 0
      src/api/erp/sale/customer/index.ts
  88. 64 0
      src/api/erp/sale/order/index.ts
  89. 62 0
      src/api/erp/sale/out/index.ts
  90. 62 0
      src/api/erp/sale/return/index.ts
  91. 28 0
      src/api/erp/statistics/purchase/index.ts
  92. 28 0
      src/api/erp/statistics/sale/index.ts
  93. 61 0
      src/api/erp/stock/check/index.ts
  94. 62 0
      src/api/erp/stock/in/index.ts
  95. 61 0
      src/api/erp/stock/move/index.ts
  96. 62 0
      src/api/erp/stock/out/index.ts
  97. 32 0
      src/api/erp/stock/record/index.ts
  98. 41 0
      src/api/erp/stock/stock/index.ts
  99. 64 0
      src/api/erp/stock/warehouse/index.ts
  100. 0 0
      src/api/infra/apiAccessLog/index.ts

+ 8 - 0
.env

@@ -13,5 +13,13 @@ VITE_APP_TENANT_ENABLE=true
 # 验证码的开关
 VITE_APP_CAPTCHA_ENABLE=true
 
+# 文档地址的开关
+VITE_APP_DOCALERT_ENABLE=true
+
 # 百度统计
 VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc
+
+# 默认账户密码
+VITE_APP_DEFAULT_LOGIN_TENANT = 芋道源码
+VITE_APP_DEFAULT_LOGIN_USERNAME = admin
+VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123

+ 0 - 19
.env.base

@@ -1,19 +0,0 @@
-# 本地开发环境
-NODE_ENV=development
-
-VITE_DEV=true
-
-# 请求路径
-VITE_BASE_URL='http://127.0.0.1:48080'
-
-# 上传路径
-VITE_UPLOAD_URL='http://127.0.0.1:48080/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=/dev-api
-
-# 接口地址
-VITE_API_URL=/admin-api
-
-# 打包路径
-VITE_BASE_PATH=/

+ 20 - 14
.env.dev

@@ -1,31 +1,37 @@
-# 开发环境
-NODE_ENV=development
+# 开发环境:本地只启动前端项目,依赖开发环境(后端、APP)
+NODE_ENV=production
 
-VITE_DEV=false
+VITE_DEV=true
 
 # 请求路径
-VITE_BASE_URL='http://localhost:48080'
+VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
 
-# 上传路径
-VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=/dev-api
+# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
+VITE_UPLOAD_TYPE=server
 
 # 接口地址
 VITE_API_URL=/admin-api
 
-# 打包路径
-VITE_BASE_PATH=/
-
 # 是否删除debugger
-VITE_DROP_DEBUGGER=true
+VITE_DROP_DEBUGGER=false
 
 # 是否删除console.log
 VITE_DROP_CONSOLE=false
 
 # 是否sourcemap
-VITE_SOURCEMAP=false
+VITE_SOURCEMAP=true
+
+# 打包路径
+VITE_BASE_PATH=/
 
 # 输出路径
 VITE_OUT_DIR=dist
+
+# 商城H5会员端域名
+VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
+
+# 验证码的开关
+VITE_APP_CAPTCHA_ENABLE=true
+
+# GoView域名
+VITE_GOVIEW_URL='http://127.0.0.1:3000'

+ 0 - 34
.env.front

@@ -1,34 +0,0 @@
-# 本地开发环境
-NODE_ENV=development
-
-VITE_DEV=true
-
-# 请求路径
-VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
-
-# 上传路径
-VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=/dev-api
-
-# 接口地址
-VITE_API_URL=/admin-api
-
-# 打包路径
-VITE_BASE_PATH=/
-
-# 项目本地运行端口号, 与.vscode/launch.json配合
-VITE_PORT=80
-
-# 是否删除debugger
-VITE_DROP_DEBUGGER=false
-
-# 是否删除console.log
-VITE_DROP_CONSOLE=false
-
-# 是否sourcemap
-VITE_SOURCEMAP=true
-
-# 验证码的开关
-VITE_APP_CAPTCHA_ENABLE=false

+ 34 - 0
.env.local

@@ -0,0 +1,34 @@
+# 本地开发环境:本地启动所有项目(前端、后端、APP)时使用,不依赖外部环境
+NODE_ENV=development
+
+VITE_DEV=true
+
+# 请求路径
+VITE_BASE_URL='http://localhost:48080'
+
+# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
+VITE_UPLOAD_TYPE=server
+
+# 接口地址
+VITE_API_URL=/admin-api
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER=false
+
+# 是否删除console.log
+VITE_DROP_CONSOLE=false
+
+# 是否sourcemap
+VITE_SOURCEMAP=false
+
+# 打包路径
+VITE_BASE_PATH=/
+
+# 商城H5会员端域名
+VITE_MALL_H5_DOMAIN='http://localhost:3000'
+
+# 验证码的开关
+VITE_APP_CAPTCHA_ENABLE=false
+
+# GoView域名
+VITE_GOVIEW_URL='http://127.0.0.1:3000'

+ 10 - 7
.env.pro

@@ -1,4 +1,4 @@
-# 生产环境
+# 生产环境:只在打包时使用
 NODE_ENV=production
 
 VITE_DEV=false
@@ -6,11 +6,8 @@ VITE_DEV=false
 # 请求路径
 VITE_BASE_URL='http://localhost:48080'
 
-# 上传路径
-VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=
+# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
+VITE_UPLOAD_TYPE=server
 
 # 接口地址
 VITE_API_URL=/admin-api
@@ -28,4 +25,10 @@ VITE_SOURCEMAP=false
 VITE_BASE_PATH=/
 
 # 输出路径
-VITE_OUT_DIR=dist-pro
+VITE_OUT_DIR=dist-prod
+
+# 商城H5会员端域名
+VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
+
+# GoView域名
+VITE_GOVIEW_URL='http://127.0.0.1:3000'

+ 9 - 6
.env.stage

@@ -1,4 +1,4 @@
-# 生产环境
+# 预发布环境:只在打包时使用
 NODE_ENV=production
 
 VITE_DEV=false
@@ -6,11 +6,8 @@ VITE_DEV=false
 # 请求路径
 VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
 
-# 上传路径
-VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=
+# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
+VITE_UPLOAD_TYPE=server
 
 # 接口地址
 VITE_API_URL=/admin-api
@@ -29,3 +26,9 @@ VITE_BASE_PATH='http://static-vue3.yudao.iocoder.cn/'
 
 # 输出路径
 VITE_OUT_DIR=dist-stage
+
+# 商城H5会员端域名
+VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
+
+# GoView域名
+VITE_GOVIEW_URL='http://127.0.0.1:3000'

+ 10 - 7
.env.static

@@ -1,4 +1,4 @@
-# 开发环境
+# 测试环境:只在打包时使用
 NODE_ENV=production
 
 VITE_DEV=false
@@ -6,11 +6,8 @@ VITE_DEV=false
 # 请求路径
 VITE_BASE_URL='http://localhost:48080'
 
-# 上传路径
-VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
-
-# 接口前缀
-VITE_API_BASEPATH=
+# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
+VITE_UPLOAD_TYPE=server
 
 # 接口地址
 VITE_API_URL=/admin-api
@@ -28,4 +25,10 @@ VITE_SOURCEMAP=false
 VITE_BASE_PATH=/admin-ui-vue3/
 
 # 输出路径
-VITE_OUT_DIR=dist-dev
+VITE_OUT_DIR=dist-test
+
+# 商城H5会员端域名
+VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
+
+# GoView域名
+VITE_GOVIEW_URL='http://127.0.0.1:3000'

+ 3 - 1
.eslintrc.js

@@ -68,6 +68,8 @@ module.exports = defineConfig({
     ],
     'vue/multi-word-component-names': 'off',
     'vue/no-v-html': 'off',
-    'prettier/prettier': 'off' // 芋艿:默认关闭 prettier 的 ESLint 校验,因为我们使用的是 IDE 的 Prettier 插件
+    'prettier/prettier': 'off', // 芋艿:默认关闭 prettier 的 ESLint 校验,因为我们使用的是 IDE 的 Prettier 插件
+    '@unocss/order': 'off', // 芋艿:禁用 unocss 【css】顺序的提示,因为暂时不需要这么严格,警告也有点繁琐
+    '@unocss/order-attributify': 'off' // 芋艿:禁用 unocss 【属性】顺序的提示,因为暂时不需要这么严格,警告也有点繁琐
   }
 })

+ 0 - 2
.gitignore

@@ -2,9 +2,7 @@ node_modules
 .DS_Store
 dist
 dist-ssr
-*.local
 /dist*
-*-lock.*
 pnpm-debug
 auto-*.d.ts
 .idea

BIN
.image/common/ai-feature.png


BIN
.image/common/ai-preview.gif


BIN
.image/common/bpm-feature.png


BIN
.image/common/crm-feature.png


BIN
.image/common/erp-feature.png


BIN
.image/common/infra-feature.png


BIN
.image/common/system-feature.png


BIN
.image/demo/vue3-ep.png


BIN
.image/工作流设计器-bpmn.jpg


BIN
.image/工作流设计器-simple.jpg


+ 0 - 1
.vscode/extensions.json

@@ -3,7 +3,6 @@
     "christian-kohler.path-intellisense",
     "vscode-icons-team.vscode-icons",
     "davidanson.vscode-markdownlint",
-    "stylelint.vscode-stylelint",
     "dbaeumer.vscode-eslint",
     "esbenp.prettier-vscode",
     "mrmlnc.vscode-less",

+ 3 - 2
.vscode/settings.json

@@ -83,10 +83,11 @@
     "editor.defaultFormatter": "esbenp.prettier-vscode"
   },
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": true
+    "source.fixAll.eslint": "explicit",
+    "source.fixAll.stylelint": "explicit"
   },
   "[vue]": {
-    "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
+    "editor.defaultFormatter": "octref.vetur"
   },
   "i18n-ally.localesPaths": ["src/locales"],
   "i18n-ally.keystyle": "nested",

+ 110 - 62
README.md

@@ -11,7 +11,7 @@
 
 * nodejs > 16.18.0 && pnpm > 8.6.0 (强制使用pnpm)
 * 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn>
-* 演示地址【Vue3 + vben(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
+* 演示地址【Vue3 + vben5.0(ant-design-vue)】:<http://dashboard-vben.yudao.iocoder.cn>
 * 演示地址【Vue2 + element-ui】:<http://dashboard.yudao.iocoder.cn>
 * 启动文档:<https://doc.iocoder.cn/quick-start/>
 * 视频教程:<https://doc.iocoder.cn/video/>
@@ -24,7 +24,7 @@
 * 改换 saas,自动引入等功能
 * 使用 Element Plus 免费开源的中后台模版,具备如下特性:
 
-![首页](public/home.png)
+![首页](.image/demo/vue3-ep.png)
 
 * **最新技术栈**:使用 Vue3、Vite4 等前端前沿技术开发
 * **TypeScript**: 应用程序级 JavaScript 的语言
@@ -38,15 +38,15 @@
 
 | 框架                                                                   | 说明               | 版本     |
 |----------------------------------------------------------------------|------------------|--------|
-| [Vue](https://staging-cn.vuejs.org/)                                 | Vue 框架           | 3.3.8 |
+| [Vue](https://staging-cn.vuejs.org/)                                 | Vue 框架           | 3.3.8  |
 | [Vite](https://cn.vitejs.dev//)                                      | 开发与构建工具          | 4.5.0  |
-| [Element Plus](https://element-plus.org/zh-CN/)                      | Element Plus     | 2.4.2 |
+| [Element Plus](https://element-plus.org/zh-CN/)                      | Element Plus     | 2.4.2  |
 | [TypeScript](https://www.typescriptlang.org/docs/)                   | JavaScript 的超集   | 5.2.2  |
-| [pinia](https://pinia.vuejs.org/)                                    | Vue 存储库 替代 vuex5 | 2.1.7 |
+| [pinia](https://pinia.vuejs.org/)                                    | Vue 存储库 替代 vuex5 | 2.1.7  |
 | [vueuse](https://vueuse.org/)                                        | 常用工具集            | 10.6.1 |
 | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化              | 9.6.5  |
 | [vue-router](https://router.vuejs.org/)                              | Vue 路由           | 4.2.5  |
-| [unocss](https://uno.antfu.me/)                                      | 原子 css          | 0.57.4  |
+| [unocss](https://uno.antfu.me/)                                      | 原子 css           | 0.57.4 |
 | [iconify](https://icon-sets.iconify.design/)                         | 在线图标库            | 3.1.1  |
 | [wangeditor](https://www.wangeditor.com/)                            | 富文本编辑器           | 5.1.23 |
 
@@ -54,27 +54,26 @@
 
 推荐 VS Code 开发,配合插件如下:
 
-| 插件名                           | 功能                       |
-|-------------------------------|--------------------------|
-| TypeScript Vue Plugin (Volar) | 用于 TypeScript 的 Vue 插件  |
-| Vue Language Features (Volar) | Vue3.0 语法支持              |
-| unocss                        | unocss for vscode           |
-| Iconify IntelliSense          | Iconify 预览和搜索           |
-| i18n Ally                     | 国际化智能提示               |
-| Stylelint                     | Css    格式化               |
-| Prettier                      | 代码格式化                   |
-| ESLint                        | 脚本代码检查                  |
-| DotENV                        | env 文件高亮                 |
+| 插件名                           | 功能                  |
+|-------------------------------|---------------------|
+| Vue - Official                | Vue 与 TypeScript 支持 |
+| unocss                        | unocss for vscode   |
+| Iconify IntelliSense          | Iconify 预览和搜索       |
+| i18n Ally                     | 国际化智能提示             |
+| Stylelint                     | Css    格式化          |
+| Prettier                      | 代码格式化               |
+| ESLint                        | 脚本代码检查              |
+| DotENV                        | env 文件高亮            |
 
 ## 🔥 后端架构
 
 支持 Spring Boot、Spring Cloud 两种架构:
 
-① Spring Boot 单体架构:<https://github.com/YunaiV/ruoyi-vue-pro>
+① Spring Boot 单体架构:<https://doc.iocoder.cn>
 
 ![架构图](/.image/common/ruoyi-vue-pro-architecture.png)
 
-② Spring Cloud 微服务架构:<https://github.com/YunaiV/yudao-cloud>
+② Spring Cloud 微服务架构:<https://cloud.iocoder.cn>
 
 ![架构图](/.image/common/yudao-cloud-architecture.png)
 
@@ -82,14 +81,13 @@
 
 系统内置多种多种业务功能,可以用于快速你的业务系统:
 
-* 系统功能
-* 基础设施
-* 工作流程
-* 支付系统
-* 会员中心
-* 数据报表
-* 商城系统
-* 微信公众号
+系统内置多种多种业务功能,可以用于快速你的业务系统:
+
+![功能分层](/.image/common/ruoyi-vue-pro-biz.png)
+
+* 通用模块(必选):系统功能、基础设施
+* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
+* 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
 
 ### 系统功能
 
@@ -115,52 +113,83 @@
 | 🚀  | 应用管理  | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 |
 | 🚀  | 地区管理  | 展示省份、城市、区镇等城市信息,支持 IP 对应城市      |
 
+![功能图](/.image/common/system-feature.png)
+
 ### 工作流程
 
-|     | 功能    | 描述                                     |
-|-----|-------|----------------------------------------|
-| 🚀  | 流程模型  | 配置工作流的流程模型,支持文件导入与在线设计流程图,提供 7 种任务分配规则 |
-| 🚀  | 流程表单  | 拖动表单元素生成相应的工作流表单,覆盖 Element UI 所有的表单组件 |
-| 🚀  | 用户分组  | 自定义用户分组,可用于工作流的审批分组                    |
-| 🚀  | 我的流程  | 查看我发起的工作流程,支持新建、取消流程等操作,高亮流程图、审批时间线    |
-| 🚀  | 待办任务  | 查看自己【未】审批的工作任务,支持通过、不通过、转发、委派、退回等操作    |
-| 🚀  | 已办任务  | 查看自己【已】审批的工作任务,未来会支持回退操作               |
-| 🚀  | OA 请假 | 作为业务自定义接入工作流的使用示例,只需创建请求对应的工作流程,即可进行审批 |
+![功能图](/.image/common/bpm-feature.png)
+
+基于 Flowable 构建,可支持信创(国产)数据库,满足中国特色流程操作:
+
+| BPMN 设计器                    | 钉钉/飞书设计器                      |
+|-----------------------------|-------------------------------|
+| ![](.image/工作流设计器-bpmn.jpg) | ![](.image/工作流设计器-simple.jpg) |
+
+> 历经头部企业生产验证,工作流引擎须标配仿钉钉/飞书 + BPMN 双设计器!!!
+>
+> 前者支持轻量配置简单流程,后者实现复杂场景深度编排
+
+| 功能列表       | 功能描述                                                                                | 是否完成 |
+|------------|-------------------------------------------------------------------------------------|------|
+| SIMPLE 设计器 | 仿钉钉/飞书设计器,支持拖拽搭建表单流程,10 分钟快速完成审批流程配置                                                | ✅    |
+| BPMN 设计器   | 基于 BPMN 标准开发,适配复杂业务场景,满足多层级审批及流程自动化需求                                               | ✅    |
+| 会签         | 同一个审批节点设置多个人(如 A、B、C 三人,三人会同时收到待办任务),需全部同意之后,审批才可到下一审批节点                            | ✅    |
+| 或签         | 同一个审批节点设置多个人,任意一个人处理后,就能进入下一个节点                                                     | ✅    |
+| 依次审批       | (顺序会签)同一个审批节点设置多个人(如 A、B、C 三人),三人按顺序依次收到待办,即 A 先审批,A 提交后 B 才能审批,需全部同意之后,审批才可到下一审批节点 | ✅    |
+| 抄送         | 将审批结果通知给抄送人,同一个审批默认排重,不重复抄送给同一人                                                     | ✅    |
+| 驳回         | (退回)将审批重置发送给某节点,重新审批。可驳回至发起人、上一节点、任意节点                                              | ✅    |
+| 转办         | A 转给其 B 审批,B 审批后,进入下一节点                                                             | ✅    |
+| 委派         | A 转给其 B 审批,B 审批后,转给 A,A 继续审批后进入下一节点                                                 | ✅    |
+| 加签         | 允许当前审批人根据需要,自行增加当前节点的审批人,支持向前、向后加签                                                  | ✅    |
+| 减签         | (取消加签)在当前审批人操作之前,减少审批人                                                              | ✅    |
+| 撤销         | (取消流程)流程发起人,可以对流程进行撤销处理                                                             | ✅    |
+| 终止         | 系统管理员,在任意节点终止流程实例                                                                   | ✅    |
+| 表单权限       | 支持拖拉拽配置表单,每个审批节点可配置只读、编辑、隐藏权限                                                       | ✅    |
+| 超时审批       | 配置超时审批时间,超时后自动触发审批通过、不通过、驳回等操作                                                      | ✅    |
+| 自动提醒       | 配置提醒时间,到达时间后自动触发短信、邮箱、站内信等通知提醒,支持自定义重复提醒频次                                          | ✅    |
+| 父子流程       | 主流程设置子流程节点,子流程节点会自动触发子流程。子流程结束后,主流程才会执行(继续往下下执行),支持同步子流程、异步子流程                      | ✅    |
+| 条件分支       | (排它分支)用于在流程中实现决策,即根据条件选择一个分支执行                                                      | ✅    |
+| 并行分支       | 允许将流程分成多条分支,不进行条件判断,所有分支都会执行                                                        | ✅    |
+| 包容分支       | (条件分支 + 并行分支的结合体)允许基于条件选择多条分支执行,但如果没有任何一个分支满足条件,则可以选择默认分支                           | ✅    |
+| 路由分支       | 根据条件选择一个分支执行(重定向到指定配置节点),也可以选择默认分支执行(继续往下执行)                                        | ✅    |
+| 触发节点       | 执行到该节点,触发 HTTP 请求、HTTP 回调、更新数据、删除数据等                                                | ✅    |
+| 延迟节点       | 执行到该节点,审批等待一段时间再执行,支持固定时长、固定日期等                                                     | ✅    |
+| 拓展设置       | 流程前置/后置通知,节点(任务)前置、后置通知,流程报表,自动审批去重,自定流程编号、标题、摘要,流程报表等                              | ✅    |
 
 ### 支付系统
 
 |     | 功能   | 描述                        |
 |-----|------|---------------------------|
-| 🚀  | 商户信息 | 管理商户信息,支持 Saas 场景下的多商户功能  |
 | 🚀  | 应用信息 | 配置商户的应用信息,对接支付宝、微信等多个支付渠道 |
 | 🚀  | 支付订单 | 查看用户发起的支付宝、微信等的【支付】订单     |
 | 🚀  | 退款订单 | 查看用户发起的支付宝、微信等的【退款】订单     |
-
-ps:核心功能已经实现,正在对接微信小程序中...
+| 🚀  | 回调通知 | 查看支付回调业务的【支付】【退款】的通知结果    |
+| 🚀  | 接入示例 | 提供接入支付系统的【支付】【退款】的功能实战    |
 
 ### 基础设施
 
-|     | 功能       | 描述                                           |
-|-----|----------|----------------------------------------------|
-| 🚀  | 代码生成     | 前后端代码的生成(Java、Vue、SQL、单元测试),支持 CRUD 下载       |
-| 🚀  | 系统接口     | 基于 Swagger 自动生成相关的 RESTful API 接口文档          |
-| 🚀  | 数据库文档    | 基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式      |
-|     | 表单构建     | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件         |
-| 🚀  | 配置管理     | 对系统动态配置常用参数,支持 SpringBoot 加载                 |
-| ⭐️  | 定时任务     | 在线(添加、修改、删除)任务调度包含执行结果日志                     |
-| 🚀  | 文件服务     | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等   |
-| 🚀  | API 日志   | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题   |
-|     | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈              |
-|     | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理           |
-| 🚀  | 消息队列     | 基于 Redis 实现消息队列,Stream 提供集群消费,Pub/Sub 提供广播消费 |
-| 🚀  | Java 监控  | 基于 Spring Boot Admin 实现 Java 应用的监控           |
-| 🚀  | 链路追踪     | 接入 SkyWalking 组件,实现链路追踪                      |
-| 🚀  | 日志中心     | 接入 SkyWalking 组件,实现日志中心                      |
-| 🚀  | 分布式锁     | 基于 Redis 实现分布式锁,满足并发场景                       |
-| 🚀  | 幂等组件     | 基于 Redis 实现幂等组件,解决重复请求问题                     |
-| 🚀  | 服务保障     | 基于 Resilience4j 实现服务的稳定性,包括限流、熔断等功能          |
-| 🚀  | 日志服务     | 轻量级日志中心,查看远程服务器的日志                           |
-| 🚀  | 单元测试     | 基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等    |
+|     | 功能        | 描述                                           |
+|-----|-----------|----------------------------------------------|
+| 🚀  | 代码生成      | 前后端代码的生成(Java、Vue、SQL、单元测试),支持 CRUD 下载       |
+| 🚀  | 系统接口      | 基于 Swagger 自动生成相关的 RESTful API 接口文档          |
+| 🚀  | 数据库文档     | 基于 Screw 自动生成数据库文档,支持导出 Word、HTML、MD 格式      |
+|     | 表单构建      | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件         |
+| 🚀  | 配置管理      | 对系统动态配置常用参数,支持 SpringBoot 加载                 |
+| ⭐️  | 定时任务      | 在线(添加、修改、删除)任务调度包含执行结果日志                     |
+| 🚀  | 文件服务      | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等   | 
+| 🚀  | WebSocket | 提供 WebSocket 接入示例,支持一对一、一对多发送方式              | 
+| 🚀  | API 日志    | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题   |
+|     | MySQL 监控  | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈              |
+|     | Redis 监控  | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理           |
+| 🚀  | 消息队列      | 基于 Redis 实现消息队列,Stream 提供集群消费,Pub/Sub 提供广播消费 |
+| 🚀  | Java 监控   | 基于 Spring Boot Admin 实现 Java 应用的监控           |
+| 🚀  | 链路追踪      | 接入 SkyWalking 组件,实现链路追踪                      |
+| 🚀  | 日志中心      | 接入 SkyWalking 组件,实现日志中心                      |
+| 🚀  | 服务保障      | 基于 Redis 实现分布式锁、幂等、限流功能,满足高并发场景              |
+| 🚀  | 日志服务      | 轻量级日志中心,查看远程服务器的日志                           |
+| 🚀  | 单元测试      | 基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等    |
+
+![功能图](/.image/common/infra-feature.png)
 
 ### 数据报表
 
@@ -186,13 +215,31 @@ ps:核心功能已经实现,正在对接微信小程序中...
 
 ### 商城系统
 
+演示地址:<https://doc.iocoder.cn/mall-preview/>
+
 ![功能图](/.image/common/mall-feature.png)
 
 ![功能图](/.image/common/mall-preview.png)
 
-_前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋道快速开发平台_
+### ERP 系统
 
-演示地址:<https://doc.iocoder.cn/mall-preview/>
+演示地址:<https://doc.iocoder.cn/erp-preview/>
+
+![功能图](/.image/common/erp-feature.png)
+
+### CRM 系统
+
+演示地址:<https://doc.iocoder.cn/crm-preview/>
+
+![功能图](/.image/common/crm-feature.png)
+
+### AI 大模型
+
+演示地址:<https://doc.iocoder.cn/ai-preview/>
+
+![功能图](/.image/common/ai-feature.png)
+
+![功能图](/.image/common/ai-preview.gif)
 
 ## 🐷 演示图
 
@@ -238,6 +285,7 @@ _前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋
 |---------|---------------------------|---------------------------------|---------------------------------|
 | 商家 & 应用 | ![商户信息](/.image/商户信息.jpg) | ![应用信息-列表](/.image/应用信息-列表.jpg) | ![应用信息-编辑](/.image/应用信息-编辑.jpg) |
 | 支付 & 退款 | ![支付订单](/.image/支付订单.jpg) | ![退款订单](/.image/退款订单.jpg)       | ---                             |
+
 ### 数据报表
 
 | 模块    | biu                             | biu                             | biu                                   |

+ 1 - 2
build/vite/index.ts

@@ -13,7 +13,7 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 import viteCompression from 'vite-plugin-compression'
 import topLevelAwait from 'vite-plugin-top-level-await'
 import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
-import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons-ng'
 import UnoCSS from 'unocss/vite'
 
 export function createVitePlugins() {
@@ -78,7 +78,6 @@ export function createVitePlugins() {
     createSvgIconsPlugin({
       iconDirs: [pathResolve('src/assets/svgs')],
       symbolId: 'icon-[dir]-[name]',
-      svgoOptions: true
     }),
     viteCompression({
       verbose: true, // 是否在控制台输出压缩结果

+ 12 - 1
build/vite/optimize.ts

@@ -27,6 +27,12 @@ const include = [
   'echarts-wordcloud',
   '@wangeditor/editor',
   '@wangeditor/editor-for-vue',
+  '@microsoft/fetch-event-source',
+  'markdown-it',
+  'markmap-view',
+  'markmap-lib',
+  'markmap-toolbar',
+  'highlight.js',
   'element-plus',
   'element-plus/es',
   'element-plus/es/locale/lang/zh-cn',
@@ -104,7 +110,12 @@ const include = [
   'element-plus/es/components/collapse/style/css',
   'element-plus/es/components/collapse-item/style/css',
   'element-plus/es/components/button-group/style/css',
-  'element-plus/es/components/text/style/css'
+  'element-plus/es/components/text/style/css',
+  'element-plus/es/components/segmented/style/css',
+  '@element-plus/icons-vue',
+  'element-plus/es/components/footer/style/css',
+  'element-plus/es/components/empty/style/css',
+  'element-plus/es/components/mention/style/css'
 ]
 
 const exclude = ['@iconify/json']

+ 73 - 64
package.json

@@ -1,23 +1,22 @@
 {
   "name": "yudao-ui-admin-vue3",
-  "version": "1.8.3-snapshot",
+  "version": "2.6.0-snapshot",
   "description": "基于vue3、vite4、element-plus、typesScript",
   "author": "xingyu",
   "private": false,
   "scripts": {
     "i": "pnpm install",
-    "dev": "vite --mode base",
-    "front": "vite --mode front",
+    "dev": "vite --mode env.local",
+    "dev-server": "vite --mode dev",
     "ts:check": "vue-tsc --noEmit",
-    "build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro",
-    "build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev",
-    "build:base": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode base",
-    "build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage",
-    "build:static": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode static",
-    "build:front": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode front",
-    "serve:pro": "vite preview --mode pro",
+    "build:local": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build",
+    "build:dev": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode dev",
+    "build:test": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode test",
+    "build:stage": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode stage",
+    "build:prod": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build --mode prod",
     "serve:dev": "vite preview --mode dev",
-    "preview": "pnpm build:base && vite preview",
+    "serve:prod": "vite preview --mode prod",
+    "preview": "pnpm build:local && vite preview",
     "clean": "npx rimraf node_modules",
     "clean:cache": "npx rimraf node_modules/.cache",
     "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
@@ -27,107 +26,117 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.1.0",
-    "@form-create/designer": "^3.1.3",
-    "@form-create/element-ui": "^3.1.24",
+    "@form-create/designer": "^3.2.6",
+    "@form-create/element-ui": "^3.2.11",
     "@iconify/iconify": "^3.1.1",
+    "@microsoft/fetch-event-source": "^2.0.1",
     "@videojs-player/vue": "^1.0.0",
-    "@vueuse/core": "^10.6.1",
+    "@vueuse/core": "^10.9.0",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^5.1.10",
     "@zxcvbn-ts/core": "^3.0.4",
     "animate.css": "^4.1.1",
-    "axios": "^1.6.1",
+    "axios": "^1.6.8",
     "benz-amr-recorder": "^1.1.5",
-    "bpmn-js-token-simulation": "^0.10.0",
+    "bpmn-js-token-simulation": "^0.36.0",
     "camunda-bpmn-moddle": "^7.0.1",
     "cropperjs": "^1.6.1",
     "crypto-js": "^4.2.0",
     "dayjs": "^1.11.10",
     "diagram-js": "^12.8.0",
     "driver.js": "^1.3.1",
-    "echarts": "^5.4.3",
+    "echarts": "^5.5.0",
     "echarts-wordcloud": "^2.1.0",
-    "element-plus": "2.4.2",
+    "element-plus": "2.9.1",
     "fast-xml-parser": "^4.3.2",
     "highlight.js": "^11.9.0",
     "jsencrypt": "^3.3.2",
     "lodash-es": "^4.17.21",
+    "markdown-it": "^14.1.0",
+    "markmap-common": "^0.16.0",
+    "markmap-lib": "^0.16.1",
+    "markmap-toolbar": "^0.17.0",
+    "markmap-view": "^0.16.0",
     "min-dash": "^4.1.1",
     "mitt": "^3.0.1",
     "nprogress": "^0.2.0",
     "pinia": "^2.1.7",
+    "pinia-plugin-persistedstate": "^3.2.1",
     "qrcode": "^1.5.3",
-    "qs": "^6.11.2",
-    "sortablejs": "^1.15.0",
+    "qs": "^6.12.0",
+    "sortablejs": "^1.15.3",
     "steady-xml": "^0.1.0",
     "url": "^0.11.3",
+    "v3-jsoneditor": "^0.0.6",
     "video.js": "^7.21.5",
-    "vue": "^3.3.8",
+    "vue": "3.5.12",
     "vue-dompurify-html": "^4.1.4",
-    "vue-i18n": "^9.6.5",
-    "vue-router": "^4.2.5",
+    "vue-i18n": "9.10.2",
+    "vue-router": "4.4.5",
     "vue-types": "^5.1.1",
+    "vue3-signature": "^0.2.4",
     "vuedraggable": "^4.1.0",
     "web-storage-cache": "^1.1.1",
     "xml-js": "^1.6.11"
   },
   "devDependencies": {
-    "@commitlint/cli": "^18.4.1",
-    "@commitlint/config-conventional": "^18.4.0",
-    "@iconify/json": "^2.2.142",
-    "@intlify/unplugin-vue-i18n": "^1.5.0",
+    "@commitlint/cli": "^19.0.1",
+    "@commitlint/config-conventional": "^19.0.0",
+    "@iconify/json": "^2.2.187",
+    "@intlify/unplugin-vue-i18n": "^2.0.0",
     "@purge-icons/generated": "^0.9.0",
-    "@types/lodash-es": "^4.17.11",
-    "@types/node": "^20.9.0",
+    "@types/lodash-es": "^4.17.12",
+    "@types/node": "^20.11.21",
     "@types/nprogress": "^0.2.3",
     "@types/qrcode": "^1.5.5",
-    "@types/qs": "^6.9.10",
-    "@types/sortablejs": "^1.15.5",
-    "@typescript-eslint/eslint-plugin": "^6.11.0",
-    "@typescript-eslint/parser": "^6.11.0",
-    "@unocss/transformer-variant-group": "^0.57.4",
+    "@types/qs": "^6.9.12",
+    "@typescript-eslint/eslint-plugin": "^7.1.0",
+    "@typescript-eslint/parser": "^7.1.0",
     "@unocss/eslint-config": "^0.57.4",
-    "@vitejs/plugin-legacy": "^4.1.1",
-    "@vitejs/plugin-vue": "^4.4.1",
-    "@vitejs/plugin-vue-jsx": "^3.0.2",
-    "autoprefixer": "^10.4.16",
-    "bpmn-js": "8.9.0",
-    "bpmn-js-properties-panel": "0.46.0",
+    "@unocss/eslint-plugin": "66.1.0-beta.5",
+    "@unocss/transformer-variant-group": "^0.58.5",
+    "@vitejs/plugin-legacy": "^5.3.1",
+    "@vitejs/plugin-vue": "^5.0.4",
+    "@vitejs/plugin-vue-jsx": "^3.1.0",
+    "autoprefixer": "^10.4.17",
+    "bpmn-js": "^17.9.2",
+    "bpmn-js-properties-panel": "5.23.0",
     "consola": "^3.2.3",
-    "eslint": "^8.53.0",
-    "eslint-config-prettier": "^9.0.0",
-    "eslint-define-config": "^1.24.1",
-    "eslint-plugin-prettier": "^5.0.1",
-    "eslint-plugin-vue": "^9.18.1",
-    "lint-staged": "^15.1.0",
-    "postcss": "^8.4.31",
-    "postcss-html": "^1.5.0",
+    "eslint": "^8.57.0",
+    "eslint-config-prettier": "^9.1.0",
+    "eslint-define-config": "^2.1.0",
+    "eslint-plugin-prettier": "^5.1.3",
+    "eslint-plugin-vue": "^9.22.0",
+    "lint-staged": "^15.2.2",
+    "postcss": "^8.4.35",
+    "postcss-html": "^1.6.0",
     "postcss-scss": "^4.0.9",
-    "prettier": "^3.1.0",
+    "prettier": "^3.2.5",
+    "prettier-eslint": "^16.3.0",
     "rimraf": "^5.0.5",
-    "rollup": "^4.4.1",
+    "rollup": "^4.12.0",
     "sass": "^1.69.5",
-    "stylelint": "^15.11.0",
+    "stylelint": "^16.2.1",
     "stylelint-config-html": "^1.1.0",
-    "stylelint-config-recommended": "^13.0.0",
-    "stylelint-config-standard": "^34.0.0",
-    "stylelint-order": "^6.0.3",
-    "terser": "^5.24.0",
-    "typescript": "5.2.2",
-    "unocss": "^0.57.4",
+    "stylelint-config-recommended": "^14.0.0",
+    "stylelint-config-standard": "^36.0.0",
+    "stylelint-order": "^6.0.4",
+    "terser": "^5.28.1",
+    "typescript": "5.3.3",
+    "unocss": "^0.58.5",
     "unplugin-auto-import": "^0.16.7",
     "unplugin-element-plus": "^0.8.0",
     "unplugin-vue-components": "^0.25.2",
-    "vite": "4.5.0",
+    "vite": "5.1.4",
     "vite-plugin-compression": "^0.5.1",
-    "vite-plugin-ejs": "^1.6.4",
+    "vite-plugin-ejs": "^1.7.0",
     "vite-plugin-eslint": "^1.8.1",
     "vite-plugin-progress": "^0.0.7",
-    "vite-plugin-purge-icons": "^0.9.2",
-    "vite-plugin-svg-icons": "^2.0.1",
-    "vite-plugin-top-level-await": "^1.3.1",
+    "vite-plugin-purge-icons": "^0.10.0",
+    "vite-plugin-svg-icons-ng": "^1.3.1",
+    "vite-plugin-top-level-await": "^1.4.4",
     "vue-eslint-parser": "^9.3.2",
-    "vue-tsc": "^1.8.22"
+    "vue-tsc": "^1.8.27"
   },
   "license": "MIT",
   "repository": {
@@ -138,7 +147,7 @@
     "url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues"
   },
   "homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3",
-  "packageManager": "pnpm@8.6.0",
+  "web-types": "./web-types.json",
   "engines": {
     "node": ">= 16.0.0",
     "pnpm": ">=8.6.0"

File diff suppressed because it is too large
+ 10526 - 0
pnpm-lock.yaml


BIN
public/home.png


+ 65 - 0
src/api/ai/chat/conversation/index.ts

@@ -0,0 +1,65 @@
+import request from '@/config/axios'
+
+// AI 聊天对话 VO
+export interface ChatConversationVO {
+  id: number // ID 编号
+  userId: number // 用户编号
+  title: string // 对话标题
+  pinned: boolean // 是否置顶
+  roleId: number // 角色编号
+  modelId: number // 模型编号
+  model: string // 模型标志
+  temperature: number // 温度参数
+  maxTokens: number // 单条回复的最大 Token 数量
+  maxContexts: number // 上下文的最大 Message 数量
+  createTime?: Date // 创建时间
+  // 额外字段
+  systemMessage?: string // 角色设定
+  modelName?: string // 模型名字
+  roleAvatar?: string // 角色头像
+  modelMaxTokens?: string // 模型的单条回复的最大 Token 数量
+  modelMaxContexts?: string // 模型的上下文的最大 Message 数量
+}
+
+// AI 聊天对话 API
+export const ChatConversationApi = {
+  // 获得【我的】聊天对话
+  getChatConversationMy: async (id: number) => {
+    return await request.get({ url: `/ai/chat/conversation/get-my?id=${id}` })
+  },
+
+  // 新增【我的】聊天对话
+  createChatConversationMy: async (data?: ChatConversationVO) => {
+    return await request.post({ url: `/ai/chat/conversation/create-my`, data })
+  },
+
+  // 更新【我的】聊天对话
+  updateChatConversationMy: async (data: ChatConversationVO) => {
+    return await request.put({ url: `/ai/chat/conversation/update-my`, data })
+  },
+
+  // 删除【我的】聊天对话
+  deleteChatConversationMy: async (id: string) => {
+    return await request.delete({ url: `/ai/chat/conversation/delete-my?id=${id}` })
+  },
+
+  // 删除【我的】所有对话,置顶除外
+  deleteChatConversationMyByUnpinned: async () => {
+    return await request.delete({ url: `/ai/chat/conversation/delete-by-unpinned` })
+  },
+
+  // 获得【我的】聊天对话列表
+  getChatConversationMyList: async () => {
+    return await request.get({ url: `/ai/chat/conversation/my-list` })
+  },
+
+  // 获得对话分页
+  getChatConversationPage: async (params: any) => {
+    return await request.get({ url: `/ai/chat/conversation/page`, params })
+  },
+
+  // 管理员删除消息
+  deleteChatConversationByAdmin: async (id: number) => {
+    return await request.delete({ url: `/ai/chat/conversation/delete-by-admin?id=${id}` })
+  }
+}

+ 90 - 0
src/api/ai/chat/message/index.ts

@@ -0,0 +1,90 @@
+import request from '@/config/axios'
+import { fetchEventSource } from '@microsoft/fetch-event-source'
+import { getAccessToken } from '@/utils/auth'
+import { config } from '@/config/axios/config'
+
+// 聊天VO
+export interface ChatMessageVO {
+  id: number // 编号
+  conversationId: number // 对话编号
+  type: string // 消息类型
+  userId: string // 用户编号
+  roleId: string // 角色编号
+  model: number // 模型标志
+  modelId: number // 模型编号
+  content: string // 聊天内容
+  tokens: number // 消耗 Token 数量
+  segmentIds?: number[] // 段落编号
+  segments?: {
+    id: number // 段落编号
+    content: string // 段落内容
+    documentId: number // 文档编号
+    documentName: string // 文档名称
+  }[]
+  createTime: Date // 创建时间
+  roleAvatar: string // 角色头像
+  userAvatar: string // 用户头像
+}
+
+// AI chat 聊天
+export const ChatMessageApi = {
+  // 消息列表
+  getChatMessageListByConversationId: async (conversationId: number | null) => {
+    return await request.get({
+      url: `/ai/chat/message/list-by-conversation-id?conversationId=${conversationId}`
+    })
+  },
+
+  // 发送 Stream 消息
+  // 为什么不用 axios 呢?因为它不支持 SSE 调用
+  sendChatMessageStream: async (
+    conversationId: number,
+    content: string,
+    ctrl,
+    enableContext: boolean,
+    onMessage,
+    onError,
+    onClose
+  ) => {
+    const token = getAccessToken()
+    return fetchEventSource(`${config.base_url}/ai/chat/message/send-stream`, {
+      method: 'post',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: `Bearer ${token}`
+      },
+      openWhenHidden: true,
+      body: JSON.stringify({
+        conversationId,
+        content,
+        useContext: enableContext
+      }),
+      onmessage: onMessage,
+      onerror: onError,
+      onclose: onClose,
+      signal: ctrl.signal
+    })
+  },
+
+  // 删除消息
+  deleteChatMessage: async (id: string) => {
+    return await request.delete({ url: `/ai/chat/message/delete?id=${id}` })
+  },
+
+  // 删除指定对话的消息
+  deleteByConversationId: async (conversationId: number) => {
+    return await request.delete({
+      url: `/ai/chat/message/delete-by-conversation-id?conversationId=${conversationId}`
+    })
+  },
+
+  // 获得消息分页
+  getChatMessagePage: async (params: any) => {
+    return await request.get({ url: '/ai/chat/message/page', params })
+  },
+
+  // 管理员删除消息
+  deleteChatMessageByAdmin: async (id: number) => {
+    return await request.delete({ url: `/ai/chat/message/delete-by-admin?id=${id}` })
+  }
+}

+ 102 - 0
src/api/ai/image/index.ts

@@ -0,0 +1,102 @@
+import request from '@/config/axios'
+
+// AI 绘图 VO
+export interface ImageVO {
+  id: number // 编号
+  platform: string // 平台
+  model: string // 模型
+  prompt: string // 提示词
+  width: number // 图片宽度
+  height: number // 图片高度
+  status: number // 状态
+  publicStatus: boolean // 公开状态
+  picUrl: string // 任务地址
+  errorMessage: string // 错误信息
+  options: any // 配置 Map<string, string>
+  taskId: number // 任务编号
+  buttons: ImageMidjourneyButtonsVO[] // mj 操作按钮
+  createTime: Date // 创建时间
+  finishTime: Date // 完成时间
+}
+
+export interface ImageDrawReqVO {
+  prompt: string // 提示词
+  modelId: number // 模型
+  style: string // 图像生成的风格
+  width: string // 图片宽度
+  height: string // 图片高度
+  options: object // 绘制参数,Map<String, String>
+}
+
+export interface ImageMidjourneyImagineReqVO {
+  prompt: string // 提示词
+  modelId: number // 模型
+  base64Array: string[] // size不能为空
+  width: string // 图片宽度
+  height: string // 图片高度
+  version: string // 版本
+}
+
+export interface ImageMidjourneyActionVO {
+  id: number // 图片编号
+  customId: string // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
+}
+
+export interface ImageMidjourneyButtonsVO {
+  customId: string // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
+  emoji: string // 图标 emoji
+  label: string // Make Variations 文本
+  style: number // 样式: 2(Primary)、3(Green)
+}
+
+// AI 图片 API
+export const ImageApi = {
+  // 获取【我的】绘图分页
+  getImagePageMy: async (params: any) => {
+    return await request.get({ url: `/ai/image/my-page`, params })
+  },
+  // 获取【我的】绘图记录
+  getImageMy: async (id: number) => {
+    return await request.get({ url: `/ai/image/get-my?id=${id}` })
+  },
+  // 获取【我的】绘图记录列表
+  getImageListMyByIds: async (ids: number[]) => {
+    return await request.get({ url: `/ai/image/my-list-by-ids`, params: { ids: ids.join(',') } })
+  },
+  // 生成图片
+  drawImage: async (data: ImageDrawReqVO) => {
+    return await request.post({ url: `/ai/image/draw`, data })
+  },
+  // 删除【我的】绘画记录
+  deleteImageMy: async (id: number) => {
+    return await request.delete({ url: `/ai/image/delete-my?id=${id}` })
+  },
+
+  // ================ midjourney 专属 ================
+
+  // 【Midjourney】生成图片
+  midjourneyImagine: async (data: ImageMidjourneyImagineReqVO) => {
+    return await request.post({ url: `/ai/image/midjourney/imagine`, data })
+  },
+  // 【Midjourney】Action 操作(二次生成图片)
+  midjourneyAction: async (data: ImageMidjourneyActionVO) => {
+    return await request.post({ url: `/ai/image/midjourney/action`, data })
+  },
+
+  // ================ 绘图管理 ================
+
+  // 查询绘画分页
+  getImagePage: async (params: any) => {
+    return await request.get({ url: `/ai/image/page`, params })
+  },
+
+  // 更新绘画发布状态
+  updateImage: async (data: any) => {
+    return await request.put({ url: '/ai/image/update', data })
+  },
+
+  // 删除绘画
+  deleteImage: async (id: number) => {
+    return await request.delete({ url: `/ai/image/delete?id=` + id })
+  }
+}

+ 54 - 0
src/api/ai/knowledge/document/index.ts

@@ -0,0 +1,54 @@
+import request from '@/config/axios'
+
+// AI 知识库文档 VO
+export interface KnowledgeDocumentVO {
+  id: number // 编号
+  knowledgeId: number // 知识库编号
+  name: string // 文档名称
+  contentLength: number // 字符数
+  tokens: number // token 数
+  segmentMaxTokens: number // 分片最大 token 数
+  retrievalCount: number // 召回次数
+  status: number // 是否启用
+}
+
+// AI 知识库文档 API
+export const KnowledgeDocumentApi = {
+  // 查询知识库文档分页
+  getKnowledgeDocumentPage: async (params: any) => {
+    return await request.get({ url: `/ai/knowledge/document/page`, params })
+  },
+
+  // 查询知识库文档详情
+  getKnowledgeDocument: async (id: number) => {
+    return await request.get({ url: `/ai/knowledge/document/get?id=` + id })
+  },
+
+  // 新增知识库文档(单个)
+  createKnowledgeDocument: async (data: any) => {
+    return await request.post({ url: `/ai/knowledge/document/create`, data })
+  },
+
+  // 新增知识库文档(多个)
+  createKnowledgeDocumentList: async (data: any) => {
+    return await request.post({ url: `/ai/knowledge/document/create-list`, data })
+  },
+
+  // 修改知识库文档
+  updateKnowledgeDocument: async (data: any) => {
+    return await request.put({ url: `/ai/knowledge/document/update`, data })
+  },
+
+  // 修改知识库文档状态
+  updateKnowledgeDocumentStatus: async (data: any) => {
+    return await request.put({
+      url: `/ai/knowledge/document/update-status`,
+      data
+    })
+  },
+
+  // 删除知识库文档
+  deleteKnowledgeDocument: async (id: number) => {
+    return await request.delete({ url: `/ai/knowledge/document/delete?id=` + id })
+  }
+}

+ 44 - 0
src/api/ai/knowledge/knowledge/index.ts

@@ -0,0 +1,44 @@
+import request from '@/config/axios'
+
+// AI 知识库 VO
+export interface KnowledgeVO {
+  id: number // 编号
+  name: string // 知识库名称
+  description: string // 知识库描述
+  embeddingModelId: number // 嵌入模型编号,高质量模式时维护
+  topK: number // topK
+  similarityThreshold: number // 相似度阈值
+}
+
+// AI 知识库 API
+export const KnowledgeApi = {
+  // 查询知识库分页
+  getKnowledgePage: async (params: any) => {
+    return await request.get({ url: `/ai/knowledge/page`, params })
+  },
+
+  // 查询知识库详情
+  getKnowledge: async (id: number) => {
+    return await request.get({ url: `/ai/knowledge/get?id=` + id })
+  },
+
+  // 新增知识库
+  createKnowledge: async (data: KnowledgeVO) => {
+    return await request.post({ url: `/ai/knowledge/create`, data })
+  },
+
+  // 修改知识库
+  updateKnowledge: async (data: KnowledgeVO) => {
+    return await request.put({ url: `/ai/knowledge/update`, data })
+  },
+
+  // 删除知识库
+  deleteKnowledge: async (id: number) => {
+    return await request.delete({ url: `/ai/knowledge/delete?id=` + id })
+  },
+
+  // 获取知识库简单列表
+  getSimpleKnowledgeList: async () => {
+    return await request.get({ url: `/ai/knowledge/simple-list` })
+  }
+}

+ 75 - 0
src/api/ai/knowledge/segment/index.ts

@@ -0,0 +1,75 @@
+import request from '@/config/axios'
+
+// AI 知识库分段 VO
+export interface KnowledgeSegmentVO {
+  id: number // 编号
+  documentId: number // 文档编号
+  knowledgeId: number // 知识库编号
+  vectorId: string // 向量库编号
+  content: string // 切片内容
+  contentLength: number // 切片内容长度
+  tokens: number // token 数量
+  retrievalCount: number // 召回次数
+  status: number // 文档状态
+  createTime: number // 创建时间
+}
+
+// AI 知识库分段 API
+export const KnowledgeSegmentApi = {
+  // 查询知识库分段分页
+  getKnowledgeSegmentPage: async (params: any) => {
+    return await request.get({ url: `/ai/knowledge/segment/page`, params })
+  },
+
+  // 查询知识库分段详情
+  getKnowledgeSegment: async (id: number) => {
+    return await request.get({ url: `/ai/knowledge/segment/get?id=` + id })
+  },
+
+  // 删除知识库分段
+  deleteKnowledgeSegment: async (id: number) => {
+    return await request.delete({ url: `/ai/knowledge/segment/delete?id=` + id })
+  },
+
+  // 新增知识库分段
+  createKnowledgeSegment: async (data: KnowledgeSegmentVO) => {
+    return await request.post({ url: `/ai/knowledge/segment/create`, data })
+  },
+
+  // 修改知识库分段
+  updateKnowledgeSegment: async (data: KnowledgeSegmentVO) => {
+    return await request.put({ url: `/ai/knowledge/segment/update`, data })
+  },
+
+  // 修改知识库分段状态
+  updateKnowledgeSegmentStatus: async (data: any) => {
+    return await request.put({
+      url: `/ai/knowledge/segment/update-status`,
+      data
+    })
+  },
+
+  // 切片内容
+  splitContent: async (url: string, segmentMaxTokens: number) => {
+    return await request.get({
+      url: `/ai/knowledge/segment/split`,
+      params: { url, segmentMaxTokens }
+    })
+  },
+
+  // 获取文档处理列表
+  getKnowledgeSegmentProcessList: async (documentIds: number[]) => {
+    return await request.get({
+      url: `/ai/knowledge/segment/get-process-list`,
+      params: { documentIds: documentIds.join(',') }
+    })
+  },
+
+  // 搜索知识库分段
+  searchKnowledgeSegment: async (params: any) => {
+    return await request.get({
+      url: `/ai/knowledge/segment/search`,
+      params
+    })
+  }
+}

+ 60 - 0
src/api/ai/mindmap/index.ts

@@ -0,0 +1,60 @@
+import { getAccessToken } from '@/utils/auth'
+import { fetchEventSource } from '@microsoft/fetch-event-source'
+import { config } from '@/config/axios/config'
+import request from '@/config/axios' // AI 思维导图 VO
+
+// AI 思维导图 VO
+export interface MindMapVO {
+  id: number // 编号
+  userId: number // 用户编号
+  prompt: string // 生成内容提示
+  generatedContent: string // 生成的思维导图内容
+  platform: string // 平台
+  model: string // 模型
+  errorMessage: string // 错误信息
+}
+
+// AI 思维导图生成 VO
+export interface AiMindMapGenerateReqVO {
+  prompt: string
+}
+
+export const AiMindMapApi = {
+  generateMindMap: ({
+    data,
+    onClose,
+    onMessage,
+    onError,
+    ctrl
+  }: {
+    data: AiMindMapGenerateReqVO
+    onMessage?: (res: any) => void
+    onError?: (...args: any[]) => void
+    onClose?: (...args: any[]) => void
+    ctrl: AbortController
+  }) => {
+    const token = getAccessToken()
+    return fetchEventSource(`${config.base_url}/ai/mind-map/generate-stream`, {
+      method: 'post',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: `Bearer ${token}`
+      },
+      openWhenHidden: true,
+      body: JSON.stringify(data),
+      onmessage: onMessage,
+      onerror: onError,
+      onclose: onClose,
+      signal: ctrl.signal
+    })
+  },
+
+  // 查询思维导图分页
+  getMindMapPage: async (params: any) => {
+    return await request.get({ url: `/ai/mind-map/page`, params })
+  },
+  // 删除思维导图
+  deleteMindMap: async (id: number) => {
+    return await request.delete({ url: `/ai/mind-map/delete?id=` + id })
+  }
+}

+ 44 - 0
src/api/ai/model/apiKey/index.ts

@@ -0,0 +1,44 @@
+import request from '@/config/axios'
+
+// AI API 密钥 VO
+export interface ApiKeyVO {
+  id: number // 编号
+  name: string // 名称
+  apiKey: string // 密钥
+  platform: string // 平台
+  url: string // 自定义 API 地址
+  status: number // 状态
+}
+
+// AI API 密钥 API
+export const ApiKeyApi = {
+  // 查询 API 密钥分页
+  getApiKeyPage: async (params: any) => {
+    return await request.get({ url: `/ai/api-key/page`, params })
+  },
+
+  // 获得 API 密钥列表
+  getApiKeySimpleList: async () => {
+    return await request.get({ url: `/ai/api-key/simple-list` })
+  },
+
+  // 查询 API 密钥详情
+  getApiKey: async (id: number) => {
+    return await request.get({ url: `/ai/api-key/get?id=` + id })
+  },
+
+  // 新增 API 密钥
+  createApiKey: async (data: ApiKeyVO) => {
+    return await request.post({ url: `/ai/api-key/create`, data })
+  },
+
+  // 修改 API 密钥
+  updateApiKey: async (data: ApiKeyVO) => {
+    return await request.put({ url: `/ai/api-key/update`, data })
+  },
+
+  // 删除 API 密钥
+  deleteApiKey: async (id: number) => {
+    return await request.delete({ url: `/ai/api-key/delete?id=` + id })
+  }
+}

+ 82 - 0
src/api/ai/model/chatRole/index.ts

@@ -0,0 +1,82 @@
+import request from '@/config/axios'
+
+// AI 聊天角色 VO
+export interface ChatRoleVO {
+  id: number // 角色编号
+  modelId: number // 模型编号
+  name: string // 角色名称
+  avatar: string // 角色头像
+  category: string // 角色类别
+  sort: number // 角色排序
+  description: string // 角色描述
+  systemMessage: string // 角色设定
+  welcomeMessage: string // 角色设定
+  publicStatus: boolean // 是否公开
+  status: number // 状态
+  knowledgeIds?: number[] // 引用的知识库 ID 列表
+  toolIds?: number[] // 引用的工具 ID 列表
+}
+
+// AI 聊天角色 分页请求 vo
+export interface ChatRolePageReqVO {
+  name?: string // 角色名称
+  category?: string // 角色类别
+  publicStatus: boolean // 是否公开
+  pageNo: number // 是否公开
+  pageSize: number // 是否公开
+}
+
+// AI 聊天角色 API
+export const ChatRoleApi = {
+  // 查询聊天角色分页
+  getChatRolePage: async (params: any) => {
+    return await request.get({ url: `/ai/chat-role/page`, params })
+  },
+
+  // 查询聊天角色详情
+  getChatRole: async (id: number) => {
+    return await request.get({ url: `/ai/chat-role/get?id=` + id })
+  },
+
+  // 新增聊天角色
+  createChatRole: async (data: ChatRoleVO) => {
+    return await request.post({ url: `/ai/chat-role/create`, data })
+  },
+
+  // 修改聊天角色
+  updateChatRole: async (data: ChatRoleVO) => {
+    return await request.put({ url: `/ai/chat-role/update`, data })
+  },
+
+  // 删除聊天角色
+  deleteChatRole: async (id: number) => {
+    return await request.delete({ url: `/ai/chat-role/delete?id=` + id })
+  },
+
+  // ======= chat 聊天
+
+  // 获取 my role
+  getMyPage: async (params: ChatRolePageReqVO) => {
+    return await request.get({ url: `/ai/chat-role/my-page`, params})
+  },
+
+  // 获取角色分类
+  getCategoryList: async () => {
+    return await request.get({ url: `/ai/chat-role/category-list`})
+  },
+
+  // 创建角色
+  createMy: async (data: ChatRoleVO) => {
+    return await request.post({ url: `/ai/chat-role/create-my`, data})
+  },
+
+  // 更新角色
+  updateMy: async (data: ChatRoleVO) => {
+    return await request.put({ url: `/ai/chat-role/update-my`, data})
+  },
+
+  // 删除角色 my
+  deleteMy: async (id: number) => {
+    return await request.delete({ url: `/ai/chat-role/delete-my?id=` + id })
+  },
+}

+ 54 - 0
src/api/ai/model/model/index.ts

@@ -0,0 +1,54 @@
+import request from '@/config/axios'
+
+// AI 模型 VO
+export interface ModelVO {
+  id: number // 编号
+  keyId: number // API 秘钥编号
+  name: string // 模型名字
+  model: string // 模型标识
+  platform: string // 模型平台
+  type: number // 模型类型
+  sort: number // 排序
+  status: number // 状态
+  temperature?: number // 温度参数
+  maxTokens?: number // 单条回复的最大 Token 数量
+  maxContexts?: number // 上下文的最大 Message 数量
+}
+
+// AI 模型 API
+export const ModelApi = {
+  // 查询模型分页
+  getModelPage: async (params: any) => {
+    return await request.get({ url: `/ai/model/page`, params })
+  },
+
+  // 获得模型列表
+  getModelSimpleList: async (type?: number) => {
+    return await request.get({
+      url: `/ai/model/simple-list`,
+      params: {
+        type
+      }
+    })
+  },
+
+  // 查询模型详情
+  getModel: async (id: number) => {
+    return await request.get({ url: `/ai/model/get?id=` + id })
+  },
+
+  // 新增模型
+  createModel: async (data: ModelVO) => {
+    return await request.post({ url: `/ai/model/create`, data })
+  },
+
+  // 修改模型
+  updateModel: async (data: ModelVO) => {
+    return await request.put({ url: `/ai/model/update`, data })
+  },
+
+  // 删除模型
+  deleteModel: async (id: number) => {
+    return await request.delete({ url: `/ai/model/delete?id=` + id })
+  }
+}

+ 42 - 0
src/api/ai/model/tool/index.ts

@@ -0,0 +1,42 @@
+import request from '@/config/axios'
+
+// AI 工具 VO
+export interface ToolVO {
+  id: number // 工具编号
+  name: string // 工具名称
+  description: string // 工具描述
+  status: number // 状态
+}
+
+// AI 工具 API
+export const ToolApi = {
+  // 查询工具分页
+  getToolPage: async (params: any) => {
+    return await request.get({ url: `/ai/tool/page`, params })
+  },
+
+  // 查询工具详情
+  getTool: async (id: number) => {
+    return await request.get({ url: `/ai/tool/get?id=` + id })
+  },
+
+  // 新增工具
+  createTool: async (data: ToolVO) => {
+    return await request.post({ url: `/ai/tool/create`, data })
+  },
+
+  // 修改工具
+  updateTool: async (data: ToolVO) => {
+    return await request.put({ url: `/ai/tool/update`, data })
+  },
+
+  // 删除工具
+  deleteTool: async (id: number) => {
+    return await request.delete({ url: `/ai/tool/delete?id=` + id })
+  },
+
+  // 获取工具简单列表
+  getToolSimpleList: async () => {
+    return await request.get({ url: `/ai/tool/simple-list` })
+  }
+}

+ 41 - 0
src/api/ai/music/index.ts

@@ -0,0 +1,41 @@
+import request from '@/config/axios'
+
+// AI 音乐 VO
+export interface MusicVO {
+  id: number // 编号
+  userId: number // 用户编号
+  title: string // 音乐名称
+  lyric: string // 歌词
+  imageUrl: string // 图片地址
+  audioUrl: string // 音频地址
+  videoUrl: string // 视频地址
+  status: number // 音乐状态
+  gptDescriptionPrompt: string // 描述词
+  prompt: string // 提示词
+  platform: string // 模型平台
+  model: string // 模型
+  generateMode: number // 生成模式
+  tags: string // 音乐风格标签
+  duration: number // 音乐时长
+  publicStatus: boolean // 是否发布
+  taskId: string // 任务id
+  errorMessage: string // 错误信息
+}
+
+// AI 音乐 API
+export const MusicApi = {
+  // 查询音乐分页
+  getMusicPage: async (params: any) => {
+    return await request.get({ url: `/ai/music/page`, params })
+  },
+
+  // 更新音乐
+  updateMusic: async (data: any) => {
+    return await request.put({ url: '/ai/music/update', data })
+  },
+
+  // 删除音乐
+  deleteMusic: async (id: number) => {
+    return await request.delete({ url: `/ai/music/delete?id=` + id })
+  }
+}

+ 25 - 0
src/api/ai/workflow/index.ts

@@ -0,0 +1,25 @@
+import request from '@/config/axios'
+
+export const getWorkflowPage = async (params) => {
+  return await request.get({ url: '/ai/workflow/page', params })
+}
+
+export const getWorkflow = async (id) => {
+  return await request.get({ url: '/ai/workflow/get?id=' + id })
+}
+
+export const createWorkflow = async (data) => {
+  return await request.post({ url: '/ai/workflow/create', data })
+}
+
+export const updateWorkflow = async (data) => {
+  return await request.put({ url: '/ai/workflow/update', data })
+}
+
+export const deleteWorkflow = async (id) => {
+  return await request.delete({ url: '/ai/workflow/delete?id=' + id })
+}
+
+export const testWorkflow = async (data) => {
+  return await request.post({ url: '/ai/workflow/test', data })
+}

+ 85 - 0
src/api/ai/write/index.ts

@@ -0,0 +1,85 @@
+import { fetchEventSource } from '@microsoft/fetch-event-source'
+
+import { getAccessToken } from '@/utils/auth'
+import { config } from '@/config/axios/config'
+import { AiWriteTypeEnum } from '@/views/ai/utils/constants'
+import request from '@/config/axios'
+
+export interface WriteVO {
+  type: AiWriteTypeEnum.WRITING | AiWriteTypeEnum.REPLY // 1:撰写 2:回复
+  prompt: string // 写作内容提示 1。撰写 2回复
+  originalContent: string // 原文
+  length: number // 长度
+  format: number // 格式
+  tone: number // 语气
+  language: number // 语言
+  userId?: number // 用户编号
+  platform?: string // 平台
+  model?: string // 模型
+  generatedContent?: string // 生成的内容
+  errorMessage?: string // 错误信息
+  createTime?: Date // 创建时间
+}
+
+export interface AiWritePageReqVO extends PageParam {
+  userId?: number // 用户编号
+  type?: AiWriteTypeEnum //  写作类型
+  platform?: string // 平台
+  createTime?: [string, string] // 创建时间
+}
+
+export interface AiWriteRespVo {
+  id: number
+  userId: number
+  type: number
+  platform: string
+  model: string
+  prompt: string
+  generatedContent: string
+  originalContent: string
+  length: number
+  format: number
+  tone: number
+  language: number
+  errorMessage: string
+  createTime: string
+}
+
+export const WriteApi = {
+  writeStream: ({
+    data,
+    onClose,
+    onMessage,
+    onError,
+    ctrl
+  }: {
+    data: WriteVO
+    onMessage?: (res: any) => void
+    onError?: (...args: any[]) => void
+    onClose?: (...args: any[]) => void
+    ctrl: AbortController
+  }) => {
+    const token = getAccessToken()
+    return fetchEventSource(`${config.base_url}/ai/write/generate-stream`, {
+      method: 'post',
+      headers: {
+        'Content-Type': 'application/json',
+        Authorization: `Bearer ${token}`
+      },
+      openWhenHidden: true,
+      body: JSON.stringify(data),
+      onmessage: onMessage,
+      onerror: onError,
+      onclose: onClose,
+      signal: ctrl.signal
+    })
+  },
+  // 获取写作列表
+  getWritePage: (params: AiWritePageReqVO) => {
+    return request.get<PageResult<AiWriteRespVo[]>>({ url: `/ai/write/page`, params })
+  },
+  // 删除写作
+  deleteWrite(id: number) {
+    return request.delete({ url: `/ai/write/delete`, params: { id } })
+  }
+}

+ 0 - 8
src/api/bpm/activity/index.ts

@@ -1,8 +0,0 @@
-import request from '@/config/axios'
-
-export const getActivityList = async (params) => {
-  return await request.get({
-    url: '/bpm/activity/list',
-    params
-  })
-}

+ 53 - 0
src/api/bpm/category/index.ts

@@ -0,0 +1,53 @@
+import request from '@/config/axios'
+
+// BPM 流程分类 VO
+export interface CategoryVO {
+  id: number // 分类编号
+  name: string // 分类名
+  code: string // 分类标志
+  status: number // 分类状态
+  sort: number // 分类排序
+}
+
+// BPM 流程分类 API
+export const CategoryApi = {
+  // 查询流程分类分页
+  getCategoryPage: async (params: any) => {
+    return await request.get({ url: `/bpm/category/page`, params })
+  },
+
+  // 查询流程分类列表
+  getCategorySimpleList: async () => {
+    return await request.get({ url: `/bpm/category/simple-list` })
+  },
+
+  // 查询流程分类详情
+  getCategory: async (id: number) => {
+    return await request.get({ url: `/bpm/category/get?id=` + id })
+  },
+
+  // 新增流程分类
+  createCategory: async (data: CategoryVO) => {
+    return await request.post({ url: `/bpm/category/create`, data })
+  },
+
+  // 修改流程分类
+  updateCategory: async (data: CategoryVO) => {
+    return await request.put({ url: `/bpm/category/update`, data })
+  },
+
+  // 批量修改流程分类的排序
+  updateCategorySortBatch: async (ids: number[]) => {
+    return await request.put({
+      url: `/bpm/category/update-sort-batch`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 删除流程分类
+  deleteCategory: async (id: number) => {
+    return await request.delete({ url: `/bpm/category/delete?id=` + id })
+  }
+}

+ 9 - 2
src/api/bpm/definition/index.ts

@@ -1,8 +1,9 @@
 import request from '@/config/axios'
 
-export const getProcessDefinitionBpmnXML = async (id: number) => {
+export const getProcessDefinition = async (id?: string, key?: string) => {
   return await request.get({
-    url: '/bpm/process-definition/get-bpmn-xml?id=' + id
+    url: '/bpm/process-definition/get',
+    params: { id, key }
   })
 }
 
@@ -19,3 +20,9 @@ export const getProcessDefinitionList = async (params) => {
     params
   })
 }
+
+export const getSimpleProcessDefinitionList = async () => {
+  return await request.get({
+    url: '/bpm/process-definition/simple-list'
+  })
+}

+ 2 - 2
src/api/bpm/form/index.ts

@@ -49,8 +49,8 @@ export const getFormPage = async (params) => {
 }
 
 // 获得动态表单的精简列表
-export const getSimpleFormList = async () => {
+export const getFormSimpleList = async () => {
   return await request.get({
-    url: '/bpm/form/list-all-simple'
+    url: '/bpm/form/simple-list'
   })
 }

+ 1 - 1
src/api/bpm/leave/index.ts

@@ -2,7 +2,7 @@ import request from '@/config/axios'
 
 export type LeaveVO = {
   id: number
-  result: number
+  status: number
   type: number
   reason: string
   processInstanceId: string

+ 22 - 3
src/api/bpm/model/index.ts

@@ -5,6 +5,7 @@ export type ProcessDefinitionVO = {
   version: number
   deploymentTIme: string
   suspensionState: number
+  formType?: number
 }
 
 export type ModelVO = {
@@ -25,11 +26,11 @@ export type ModelVO = {
   bpmnXml: string
 }
 
-export const getModelPage = async (params) => {
-  return await request.get({ url: '/bpm/model/page', params })
+export const getModelList = async (name: string | undefined) => {
+  return await request.get({ url: '/bpm/model/list', params: { name } })
 }
 
-export const getModel = async (id: number) => {
+export const getModel = async (id: string) => {
   return await request.get({ url: '/bpm/model/get?id=' + id })
 }
 
@@ -37,6 +38,20 @@ export const updateModel = async (data: ModelVO) => {
   return await request.put({ url: '/bpm/model/update', data: data })
 }
 
+// 批量修改流程分类的排序
+export const updateModelSortBatch = async (ids: number[]) => {
+  return await request.put({
+    url: `/bpm/model/update-sort-batch`,
+    params: {
+      ids: ids.join(',')
+    }
+  })
+}
+
+export const updateModelBpmn = async (data: ModelVO) => {
+  return await request.put({ url: '/bpm/model/update-bpmn', data: data })
+}
+
 // 任务状态修改
 export const updateModelState = async (id: number, state: number) => {
   const data = {
@@ -57,3 +72,7 @@ export const deleteModel = async (id: number) => {
 export const deployModel = async (id: number) => {
   return await request.post({ url: '/bpm/model/deploy?id=' + id })
 }
+
+export const cleanModel = async (id: number) => {
+  return await request.delete({ url: '/bpm/model/clean?id=' + id })
+}

+ 42 - 0
src/api/bpm/processExpression/index.ts

@@ -0,0 +1,42 @@
+import request from '@/config/axios'
+
+// BPM 流程表达式 VO
+export interface ProcessExpressionVO {
+  id: number // 编号
+  name: string // 表达式名字
+  status: number // 表达式状态
+  expression: string // 表达式
+}
+
+// BPM 流程表达式 API
+export const ProcessExpressionApi = {
+  // 查询BPM 流程表达式分页
+  getProcessExpressionPage: async (params: any) => {
+    return await request.get({ url: `/bpm/process-expression/page`, params })
+  },
+
+  // 查询BPM 流程表达式详情
+  getProcessExpression: async (id: number) => {
+    return await request.get({ url: `/bpm/process-expression/get?id=` + id })
+  },
+
+  // 新增BPM 流程表达式
+  createProcessExpression: async (data: ProcessExpressionVO) => {
+    return await request.post({ url: `/bpm/process-expression/create`, data })
+  },
+
+  // 修改BPM 流程表达式
+  updateProcessExpression: async (data: ProcessExpressionVO) => {
+    return await request.put({ url: `/bpm/process-expression/update`, data })
+  },
+
+  // 删除BPM 流程表达式
+  deleteProcessExpression: async (id: number) => {
+    return await request.delete({ url: `/bpm/process-expression/delete?id=` + id })
+  },
+
+  // 导出BPM 流程表达式 Excel
+  exportProcessExpression: async (params) => {
+    return await request.download({ url: `/bpm/process-expression/export-excel`, params })
+  }
+}

+ 73 - 5
src/api/bpm/processInstance/index.ts

@@ -1,5 +1,6 @@
 import request from '@/config/axios'
-
+import { ProcessDefinitionVO } from '@/api/bpm/model'
+import { NodeType, CandidateStrategy } from '@/components/SimpleProcessDesignerV2/src/consts'
 export type Task = {
   id: string
   name: string
@@ -18,24 +19,91 @@ export type ProcessInstanceVO = {
   businessKey: string
   createTime: string
   endTime: string
+  processDefinition?: ProcessDefinitionVO
+}
+
+// 用户信息
+export type User = {
+  id: number
+  nickname: string
+  avatar: string
+}
+
+// 审批任务信息
+export type ApprovalTaskInfo = {
+  id: number
+  ownerUser: User
+  assigneeUser: User
+  status: number
+  reason: string
+  signPicUrl: string
 }
 
-export const getMyProcessInstancePage = async (params) => {
+// 审批节点信息
+export type ApprovalNodeInfo = {
+  id: number
+  name: string
+  nodeType: NodeType
+  candidateStrategy?: CandidateStrategy
+  status: number
+  startTime?: Date
+  endTime?: Date
+  candidateUsers?: User[]
+  tasks: ApprovalTaskInfo[]
+}
+
+export const getProcessInstanceMyPage = async (params: any) => {
   return await request.get({ url: '/bpm/process-instance/my-page', params })
 }
 
+export const getProcessInstanceManagerPage = async (params: any) => {
+  return await request.get({ url: '/bpm/process-instance/manager-page', params })
+}
+
 export const createProcessInstance = async (data) => {
   return await request.post({ url: '/bpm/process-instance/create', data: data })
 }
 
-export const cancelProcessInstance = async (id: number, reason: string) => {
+export const cancelProcessInstanceByStartUser = async (id: number, reason: string) => {
   const data = {
     id: id,
     reason: reason
   }
-  return await request.delete({ url: '/bpm/process-instance/cancel', data: data })
+  return await request.delete({ url: '/bpm/process-instance/cancel-by-start-user', data: data })
 }
 
-export const getProcessInstance = async (id: number) => {
+export const cancelProcessInstanceByAdmin = async (id: number, reason: string) => {
+  const data = {
+    id: id,
+    reason: reason
+  }
+  return await request.delete({ url: '/bpm/process-instance/cancel-by-admin', data: data })
+}
+
+export const getProcessInstance = async (id: string) => {
   return await request.get({ url: '/bpm/process-instance/get?id=' + id })
 }
+
+export const getProcessInstanceCopyPage = async (params: any) => {
+  return await request.get({ url: '/bpm/process-instance/copy/page', params })
+}
+
+// 获取审批详情
+export const getApprovalDetail = async (params: any) => {
+  return await request.get({ url: '/bpm/process-instance/get-approval-detail', params })
+}
+
+// 获取下一个执行的流程节点
+export const getNextApprovalNodes = async (params: any) => {
+  return await request.get({ url: '/bpm/process-instance/get-next-approval-nodes', params })
+}
+
+// 获取表单字段权限
+export const getFormFieldsPermission = async (params: any) => {
+  return await request.get({ url: '/bpm/process-instance/get-form-fields-permission', params })
+}
+
+// 获取流程实例的 BPMN 模型视图
+export const getProcessInstanceBpmnModelView = async (id: string) => {
+  return await request.get({ url: '/bpm/process-instance/get-bpmn-model-view?id=' + id })
+}

+ 40 - 0
src/api/bpm/processListener/index.ts

@@ -0,0 +1,40 @@
+import request from '@/config/axios'
+
+// BPM 流程监听器 VO
+export interface ProcessListenerVO {
+  id: number // 编号
+  name: string // 监听器名字
+  type: string // 监听器类型
+  status: number // 监听器状态
+  event: string // 监听事件
+  valueType: string // 监听器值类型
+  value: string // 监听器值
+}
+
+// BPM 流程监听器 API
+export const ProcessListenerApi = {
+  // 查询流程监听器分页
+  getProcessListenerPage: async (params: any) => {
+    return await request.get({ url: `/bpm/process-listener/page`, params })
+  },
+
+  // 查询流程监听器详情
+  getProcessListener: async (id: number) => {
+    return await request.get({ url: `/bpm/process-listener/get?id=` + id })
+  },
+
+  // 新增流程监听器
+  createProcessListener: async (data: ProcessListenerVO) => {
+    return await request.post({ url: `/bpm/process-listener/create`, data })
+  },
+
+  // 修改流程监听器
+  updateProcessListener: async (data: ProcessListenerVO) => {
+    return await request.put({ url: `/bpm/process-listener/update`, data })
+  },
+
+  // 删除流程监听器
+  deleteProcessListener: async (id: number) => {
+    return await request.delete({ url: `/bpm/process-listener/delete?id=` + id })
+  }
+}

+ 15 - 0
src/api/bpm/simple/index.ts

@@ -0,0 +1,15 @@
+import request from '@/config/axios'
+
+
+export const updateBpmSimpleModel = async (data) => {
+  return await request.post({
+    url: '/bpm/model/simple/update',
+    data: data
+  })
+}
+
+export const getBpmSimpleModel = async (id) => {
+  return await request.get({
+    url: '/bpm/model/simple/get?id=' + id
+  })
+}

+ 76 - 44
src/api/bpm/task/index.ts

@@ -1,81 +1,113 @@
 import request from '@/config/axios'
 
-export type TaskVO = {
-  id: number
+/**
+ * 任务状态枚举
+ */
+export enum TaskStatusEnum {
+  /**
+   * 未开始
+   */
+  NOT_START = -1,
+
+  /**
+   * 待审批
+   */
+  WAIT = 0,
+  /**
+   * 审批中
+   */
+  RUNNING = 1,
+  /**
+   * 审批通过
+   */
+  APPROVE = 2,
+
+  /**
+   * 审批不通过
+   */
+  REJECT = 3,
+
+  /**
+   * 已取消
+   */
+  CANCEL = 4,
+  /**
+   * 已退回
+   */
+  RETURN = 5,
+  /**
+   * 审批通过中
+   */
+  APPROVING = 7
 }
 
-export const getTodoTaskPage = async (params) => {
+export const getTaskTodoPage = async (params: any) => {
   return await request.get({ url: '/bpm/task/todo-page', params })
 }
 
-export const getDoneTaskPage = async (params) => {
+export const getTaskDonePage = async (params: any) => {
   return await request.get({ url: '/bpm/task/done-page', params })
 }
 
-export const completeTask = async (data) => {
-  return await request.put({ url: '/bpm/task/complete', data })
+export const getTaskManagerPage = async (params: any) => {
+  return await request.get({ url: '/bpm/task/manager-page', params })
 }
 
-export const approveTask = async (data) => {
+export const approveTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/approve', data })
 }
 
-export const rejectTask = async (data) => {
+export const rejectTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/reject', data })
 }
-export const backTask = async (data) => {
-  return await request.put({ url: '/bpm/task/back', data })
-}
-
-export const updateTaskAssignee = async (data) => {
-  return await request.put({ url: '/bpm/task/update-assignee', data })
-}
 
-export const getTaskListByProcessInstanceId = async (processInstanceId) => {
+export const getTaskListByProcessInstanceId = async (processInstanceId: string) => {
   return await request.get({
     url: '/bpm/task/list-by-process-instance-id?processInstanceId=' + processInstanceId
   })
 }
 
-// 导出任务
-export const exportTask = async (params) => {
-  return await request.download({ url: '/bpm/task/export', params })
-}
-
-// 获取所有可回退的节点
-export const getReturnList = async (params) => {
-  return await request.get({ url: '/bpm/task/get-return-list', params })
+// 获取所有可退回的节点
+export const getTaskListByReturn = async (id: string) => {
+  return await request.get({ url: '/bpm/task/list-by-return', params: { id } })
 }
 
-// 退
-export const returnTask = async (data) => {
+// 退回
+export const returnTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/return', data })
 }
 
-/**
- * 委派
- */
-export const delegateTask = async (data) => {
+// 委派
+export const delegateTask = async (data: any) => {
   return await request.put({ url: '/bpm/task/delegate', data })
 }
 
-/**
- * 加签
- */
-export const taskAddSign = async (data) => {
-  return await request.put({ url: '/bpm/task/create-sign', data })
+// 转派
+export const transferTask = async (data: any) => {
+  return await request.put({ url: '/bpm/task/transfer', data })
 }
 
-/**
- * 获取减签任务列表
- */
-export const getChildrenTaskList = async (id: string) => {
-  return await request.get({ url: '/bpm/task/children-list?taskId=' + id })
+// 加签
+export const signCreateTask = async (data: any) => {
+  return await request.put({ url: '/bpm/task/create-sign', data })
 }
 
-/**
- * 减签
- */
-export const taskSubSign = async (data) => {
+// 减签
+export const signDeleteTask = async (data: any) => {
   return await request.delete({ url: '/bpm/task/delete-sign', data })
 }
+
+// 抄送
+export const copyTask = async (data: any) => {
+  return await request.put({ url: '/bpm/task/copy', data })
+}
+
+// 获取我的待办任务
+export const myTodoTask = async (processInstanceId: string) => {
+  return await request.get({ url: '/bpm/task/my-todo?processInstanceId=' + processInstanceId })
+}
+
+// 获取减签任务列表
+export const getChildrenTaskList = async (id: string) => {
+  return await request.get({ url: '/bpm/task/list-by-parent-task-id?parentTaskId=' + id })
+}

+ 0 - 29
src/api/bpm/taskAssignRule/index.ts

@@ -1,29 +0,0 @@
-import request from '@/config/axios'
-
-export type TaskAssignVO = {
-  id: number
-  modelId: string
-  processDefinitionId: string
-  taskDefinitionKey: string
-  taskDefinitionName: string
-  options: string[]
-  type: number
-}
-
-export const getTaskAssignRuleList = async (params) => {
-  return await request.get({ url: '/bpm/task-assign-rule/list', params })
-}
-
-export const createTaskAssignRule = async (data: TaskAssignVO) => {
-  return await request.post({
-    url: '/bpm/task-assign-rule/create',
-    data: data
-  })
-}
-
-export const updateTaskAssignRule = async (data: TaskAssignVO) => {
-  return await request.put({
-    url: '/bpm/task-assign-rule/update',
-    data: data
-  })
-}

+ 3 - 3
src/api/bpm/userGroup/index.ts

@@ -4,7 +4,7 @@ export type UserGroupVO = {
   id: number
   name: string
   description: string
-  memberUserIds: number[]
+  userIds: number[]
   status: number
   remark: string
   createTime: string
@@ -42,6 +42,6 @@ export const getUserGroupPage = async (params) => {
 }
 
 // 获取用户组精简信息列表
-export const getSimpleUserGroupList = async (): Promise<UserGroupVO[]> => {
-  return await request.get({ url: '/bpm/user-group/list-all-simple' })
+export const getUserGroupSimpleList = async (): Promise<UserGroupVO[]> => {
+  return await request.get({ url: '/bpm/user-group/simple-list' })
 }

+ 98 - 0
src/api/crm/business/index.ts

@@ -0,0 +1,98 @@
+import request from '@/config/axios'
+import { TransferReqVO } from '@/api/crm/permission'
+
+export interface BusinessVO {
+  id: number
+  name: string
+  customerId: number
+  customerName?: string
+  followUpStatus: boolean
+  contactLastTime: Date
+  contactNextTime: Date
+  ownerUserId: number
+  ownerUserName?: string // 负责人的用户名称
+  ownerUserDept?: string // 负责人的部门名称
+  statusTypeId: number
+  statusTypeName?: string
+  statusId: number
+  statusName?: string
+  endStatus: number
+  endRemark: string
+  dealTime: Date
+  totalProductPrice: number
+  totalPrice: number
+  discountPercent: number
+  remark: string
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
+  products?: [
+    {
+      id: number
+      productId: number
+      productName: string
+      productNo: string
+      productUnit: number
+      productPrice: number
+      businessPrice: number
+      count: number
+      totalPrice: number
+    }
+  ]
+}
+
+// 查询 CRM 商机列表
+export const getBusinessPage = async (params) => {
+  return await request.get({ url: `/crm/business/page`, params })
+}
+
+// 查询 CRM 商机列表,基于指定客户
+export const getBusinessPageByCustomer = async (params) => {
+  return await request.get({ url: `/crm/business/page-by-customer`, params })
+}
+
+// 查询 CRM 商机详情
+export const getBusiness = async (id: number) => {
+  return await request.get({ url: `/crm/business/get?id=` + id })
+}
+
+// 获得 CRM 商机列表(精简)
+export const getSimpleBusinessList = async () => {
+  return await request.get({ url: `/crm/business/simple-all-list` })
+}
+
+// 新增 CRM 商机
+export const createBusiness = async (data: BusinessVO) => {
+  return await request.post({ url: `/crm/business/create`, data })
+}
+
+// 修改 CRM 商机
+export const updateBusiness = async (data: BusinessVO) => {
+  return await request.put({ url: `/crm/business/update`, data })
+}
+
+// 修改 CRM 商机状态
+export const updateBusinessStatus = async (data: BusinessVO) => {
+  return await request.put({ url: `/crm/business/update-status`, data })
+}
+
+// 删除 CRM 商机
+export const deleteBusiness = async (id: number) => {
+  return await request.delete({ url: `/crm/business/delete?id=` + id })
+}
+
+// 导出 CRM 商机 Excel
+export const exportBusiness = async (params) => {
+  return await request.download({ url: `/crm/business/export-excel`, params })
+}
+
+// 联系人关联商机列表
+export const getBusinessPageByContact = async (params) => {
+  return await request.get({ url: `/crm/business/page-by-contact`, params })
+}
+
+// 商机转移
+export const transferBusiness = async (data: TransferReqVO) => {
+  return await request.put({ url: '/crm/business/transfer', data })
+}

+ 68 - 0
src/api/crm/business/status/index.ts

@@ -0,0 +1,68 @@
+import request from '@/config/axios'
+
+export interface BusinessStatusTypeVO {
+  id: number
+  name: string
+  deptIds: number[]
+  statuses?: {
+    id: number
+    name: string
+    percent: number
+  }
+}
+
+export const DEFAULT_STATUSES = [
+  {
+    endStatus: 1,
+    key: '结束',
+    name: '赢单',
+    percent: 100
+  },
+  {
+    endStatus: 2,
+    key: '结束',
+    name: '输单',
+    percent: 0
+  },
+  {
+    endStatus: 3,
+    key: '结束',
+    name: '无效',
+    percent: 0
+  }
+]
+
+// 查询商机状态组列表
+export const getBusinessStatusPage = async (params: any) => {
+  return await request.get({ url: `/crm/business-status/page`, params })
+}
+
+// 新增商机状态组
+export const createBusinessStatus = async (data: BusinessStatusTypeVO) => {
+  return await request.post({ url: `/crm/business-status/create`, data })
+}
+
+// 修改商机状态组
+export const updateBusinessStatus = async (data: BusinessStatusTypeVO) => {
+  return await request.put({ url: `/crm/business-status/update`, data })
+}
+
+// 查询商机状态类型详情
+export const getBusinessStatus = async (id: number) => {
+  return await request.get({ url: `/crm/business-status/get?id=` + id })
+}
+
+// 删除商机状态
+export const deleteBusinessStatus = async (id: number) => {
+  return await request.delete({ url: `/crm/business-status/delete?id=` + id })
+}
+
+// 获得商机状态组列表
+export const getBusinessStatusTypeSimpleList = async () => {
+  return await request.get({ url: `/crm/business-status/type-simple-list` })
+}
+
+// 获得商机阶段列表
+export const getBusinessStatusSimpleList = async (typeId: number) => {
+  return await request.get({ url: `/crm/business-status/status-simple-list`, params: { typeId } })
+}

+ 45 - 13
src/api/crm/clue/index.ts

@@ -1,22 +1,39 @@
 import request from '@/config/axios'
+import { TransferReqVO } from '@/api/crm/permission'
 
 export interface ClueVO {
-  id: number
-  transformStatus: boolean
-  followUpStatus: boolean
-  name: string
-  customerId: number
-  contactNextTime: Date
-  telephone: string
-  mobile: string
-  address: string
-  ownerUserId: number
-  contactLastTime: Date
-  remark: string
+  id: number // 编号
+  name: string // 线索名称
+  followUpStatus: boolean // 跟进状态
+  contactLastTime: Date // 最后跟进时间
+  contactLastContent: string // 最后跟进内容
+  contactNextTime: Date // 下次联系时间
+  ownerUserId: number // 负责人的用户编号
+  ownerUserName?: string // 负责人的用户名称
+  ownerUserDept?: string // 负责人的部门名称
+  transformStatus: boolean // 转化状态
+  customerId: number // 客户编号
+  customerName?: string // 客户名称
+  mobile: string // 手机号
+  telephone: string // 电话
+  qq: string // QQ
+  wechat: string // wechat
+  email: string // email
+  areaId: number // 所在地
+  areaName?: string // 所在地名称
+  detailAddress: string // 详细地址
+  industryId: number // 所属行业
+  level: number // 客户等级
+  source: number // 客户来源
+  remark: string // 备注
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
 }
 
 // 查询线索列表
-export const getCluePage = async (params) => {
+export const getCluePage = async (params: any) => {
   return await request.get({ url: `/crm/clue/page`, params })
 }
 
@@ -44,3 +61,18 @@ export const deleteClue = async (id: number) => {
 export const exportClue = async (params) => {
   return await request.download({ url: `/crm/clue/export-excel`, params })
 }
+
+// 线索转移
+export const transferClue = async (data: TransferReqVO) => {
+  return await request.put({ url: '/crm/clue/transfer', data })
+}
+
+// 线索转化为客户
+export const transformClue = async (id: number) => {
+  return await request.put({ url: '/crm/clue/transform', params: { id } })
+}
+
+// 获得分配给我的、待跟进的线索数量
+export const getFollowClueCount = async () => {
+  return await request.get({ url: '/crm/clue/follow-count' })
+}

+ 85 - 39
src/api/crm/contact/index.ts

@@ -1,67 +1,113 @@
-/*
- * @Author: zyna
- * @Date: 2023-11-05 13:34:41
- * @LastEditTime: 2023-11-26 20:47:04
- * @FilePath: \yudao-ui-admin-vue3\src\api\crm\contact\index.ts
- * @Description:
- */
 import request from '@/config/axios'
+import { TransferReqVO } from '@/api/crm/permission'
 
 export interface ContactVO {
-  name: string
-  nextTime: Date
-  mobile: string
-  telephone: string
-  email: string
-  post: string
-  customerId: number
-  address: string
-  remark: string
-  ownerUserId: string
-  lastTime: Date
-  id: number
-  parentId: number
-  qq: number
-  wechat: string
-  sex: number
-  master: boolean
-  creatorName: string
-  updateTime?: Date
-  createTime?: Date
-  customerName: string,
-  areaName: string,
-  ownerUserName: string
-}
-
-// 查询crm联系人列表
+  id: number // 编号
+  name: string // 联系人名称
+  customerId: number // 客户编号
+  customerName?: string // 客户名称
+  contactLastTime: Date // 最后跟进时间
+  contactLastContent: string // 最后跟进内容
+  contactNextTime: Date // 下次联系时间
+  ownerUserId: number // 负责人的用户编号
+  ownerUserName?: string // 负责人的用户名称
+  ownerUserDept?: string // 负责人的部门名称
+  mobile: string // 手机号
+  telephone: string // 电话
+  qq: string // QQ
+  wechat: string // wechat
+  email: string // email
+  areaId: number // 所在地
+  areaName?: string // 所在地名称
+  detailAddress: string // 详细地址
+  sex: number // 性别
+  master: boolean // 是否主联系人
+  post: string // 职务
+  parentId: number // 上级联系人编号
+  parentName?: string // 上级联系人名称
+  remark: string // 备注
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
+}
+
+export interface ContactBusinessReqVO {
+  contactId: number
+  businessIds: number[]
+}
+
+export interface ContactBusiness2ReqVO {
+  businessId: number
+  contactIds: number[]
+}
+
+// 查询 CRM 联系人列表
 export const getContactPage = async (params) => {
   return await request.get({ url: `/crm/contact/page`, params })
 }
 
-// 查询crm联系人详情
+// 查询 CRM 联系人列表,基于指定客户
+export const getContactPageByCustomer = async (params: any) => {
+  return await request.get({ url: `/crm/contact/page-by-customer`, params })
+}
+
+// 查询 CRM 联系人列表,基于指定商机
+export const getContactPageByBusiness = async (params: any) => {
+  return await request.get({ url: `/crm/contact/page-by-business`, params })
+}
+
+// 查询 CRM 联系人详情
 export const getContact = async (id: number) => {
   return await request.get({ url: `/crm/contact/get?id=` + id })
 }
 
-// 新增crm联系人
+// 新增 CRM 联系人
 export const createContact = async (data: ContactVO) => {
   return await request.post({ url: `/crm/contact/create`, data })
 }
 
-// 修改crm联系人
+// 修改 CRM 联系人
 export const updateContact = async (data: ContactVO) => {
   return await request.put({ url: `/crm/contact/update`, data })
 }
 
-// 删除crm联系人
+// 删除 CRM 联系人
 export const deleteContact = async (id: number) => {
   return await request.delete({ url: `/crm/contact/delete?id=` + id })
 }
 
-// 导出crm联系人 Excel
+// 导出 CRM 联系人 Excel
 export const exportContact = async (params) => {
   return await request.download({ url: `/crm/contact/export-excel`, params })
 }
-export const simpleAllList = async () => {
+
+// 获得 CRM 联系人列表(精简)
+export const getSimpleContactList = async () => {
   return await request.get({ url: `/crm/contact/simple-all-list` })
 }
+
+// 批量新增联系人商机关联
+export const createContactBusinessList = async (data: ContactBusinessReqVO) => {
+  return await request.post({ url: `/crm/contact/create-business-list`, data })
+}
+
+// 批量新增联系人商机关联
+export const createContactBusinessList2 = async (data: ContactBusiness2ReqVO) => {
+  return await request.post({ url: `/crm/contact/create-business-list2`, data })
+}
+
+// 解除联系人商机关联
+export const deleteContactBusinessList = async (data: ContactBusinessReqVO) => {
+  return await request.delete({ url: `/crm/contact/delete-business-list`, data })
+}
+
+// 解除联系人商机关联
+export const deleteContactBusinessList2 = async (data: ContactBusiness2ReqVO) => {
+  return await request.delete({ url: `/crm/contact/delete-business-list2`, data })
+}
+
+// 联系人转移
+export const transferContact = async (data: TransferReqVO) => {
+  return await request.put({ url: '/crm/contact/transfer', data })
+}

+ 16 - 0
src/api/crm/contract/config/index.ts

@@ -0,0 +1,16 @@
+import request from '@/config/axios'
+
+export interface ContractConfigVO {
+  notifyEnabled?: boolean
+  notifyDays?: number
+}
+
+// 获取合同配置
+export const getContractConfig = async () => {
+  return await request.get({ url: `/crm/contract-config/get` })
+}
+
+// 更新合同配置
+export const saveContractConfig = async (data: ContractConfigVO) => {
+  return await request.put({ url: `/crm/contract-config/save`, data })
+}

+ 75 - 14
src/api/crm/contract/index.ts

@@ -1,53 +1,114 @@
 import request from '@/config/axios'
+import { TransferReqVO } from '@/api/crm/permission'
 
 export interface ContractVO {
   id: number
   name: string
+  no: string
   customerId: number
+  customerName?: string
   businessId: number
+  businessName: string
+  contactLastTime: Date
+  ownerUserId: number
+  ownerUserName?: string
+  ownerUserDeptName?: string
   processInstanceId: number
+  auditStatus: number
   orderDate: Date
-  ownerUserId: number
-  no: string
   startTime: Date
   endTime: Date
-  price: number
+  totalProductPrice: number
   discountPercent: number
-  productPrice: number
-  roUserIds: string
-  rwUserIds: string
-  contactId: number
+  totalPrice: number
+  totalReceivablePrice: number
+  signContactId: number
+  signContactName?: string
   signUserId: number
-  contactLastTime: Date
+  signUserName: string
   remark: string
+  createTime?: Date
+  creator: string
+  creatorName: string
+  updateTime?: Date
+  products?: [
+    {
+      id: number
+      productId: number
+      productName: string
+      productNo: string
+      productUnit: number
+      productPrice: number
+      contractPrice: number
+      count: number
+      totalPrice: number
+    }
+  ]
 }
 
-// 查询合同列表
+// 查询 CRM 合同列表
 export const getContractPage = async (params) => {
   return await request.get({ url: `/crm/contract/page`, params })
 }
 
-// 查询合同详情
+// 查询 CRM 联系人列表,基于指定客户
+export const getContractPageByCustomer = async (params: any) => {
+  return await request.get({ url: `/crm/contract/page-by-customer`, params })
+}
+
+// 查询 CRM 联系人列表,基于指定商机
+export const getContractPageByBusiness = async (params: any) => {
+  return await request.get({ url: `/crm/contract/page-by-business`, params })
+}
+
+// 查询 CRM 合同详情
 export const getContract = async (id: number) => {
   return await request.get({ url: `/crm/contract/get?id=` + id })
 }
 
-// 新增合同
+// 查询 CRM 合同下拉列表
+export const getContractSimpleList = async (customerId: number) => {
+  return await request.get({
+    url: `/crm/contract/simple-list?customerId=${customerId}`
+  })
+}
+
+// 新增 CRM 合同
 export const createContract = async (data: ContractVO) => {
   return await request.post({ url: `/crm/contract/create`, data })
 }
 
-// 修改合同
+// 修改 CRM 合同
 export const updateContract = async (data: ContractVO) => {
   return await request.put({ url: `/crm/contract/update`, data })
 }
 
-// 删除合同
+// 删除 CRM 合同
 export const deleteContract = async (id: number) => {
   return await request.delete({ url: `/crm/contract/delete?id=` + id })
 }
 
-// 导出合同 Excel
+// 导出 CRM 合同 Excel
 export const exportContract = async (params) => {
   return await request.download({ url: `/crm/contract/export-excel`, params })
 }
+
+// 提交审核
+export const submitContract = async (id: number) => {
+  return await request.put({ url: `/crm/contract/submit?id=${id}` })
+}
+
+// 合同转移
+export const transferContract = async (data: TransferReqVO) => {
+  return await request.put({ url: '/crm/contract/transfer', data })
+}
+
+// 获得待审核合同数量
+export const getAuditContractCount = async () => {
+  return await request.get({ url: '/crm/contract/audit-count' })
+}
+
+// 获得即将到期(提醒)的合同数量
+export const getRemindContractCount = async () => {
+  return await request.get({ url: '/crm/contract/remind-count' })
+}

+ 97 - 33
src/api/crm/customer/index.ts

@@ -1,36 +1,34 @@
 import request from '@/config/axios'
+import { TransferReqVO } from '@/api/crm/permission'
 
 export interface CustomerVO {
-  id?: number
-  name: string
-  industryId: number
-  level: number
-  source: number
-  followUpStatus?: boolean
+  id: number // 编号
+  name: string // 客户名称
+  followUpStatus: boolean // 跟进状态
+  contactLastTime: Date // 最后跟进时间
+  contactLastContent: string // 最后跟进内容
+  contactNextTime: Date // 下次联系时间
+  ownerUserId: number // 负责人的用户编号
+  ownerUserName?: string // 负责人的用户名称
+  ownerUserDept?: string // 负责人的部门名称
   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
+  mobile: string // 手机号
+  telephone: string // 电话
+  qq: string // QQ
+  wechat: string // wechat
+  email: string // email
+  areaId: number // 所在地
+  areaName?: string // 所在地名称
+  detailAddress: string // 详细地址
+  industryId: number // 所属行业
+  level: number // 客户等级
+  source: number // 客户来源
+  remark: string // 备注
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
 }
 
 // 查询客户列表
@@ -38,6 +36,26 @@ export const getCustomerPage = async (params) => {
   return await request.get({ url: `/crm/customer/page`, params })
 }
 
+// 进入公海客户提醒的客户列表
+export const getPutPoolRemindCustomerPage = async (params) => {
+  return await request.get({ url: `/crm/customer/put-pool-remind-page`, params })
+}
+
+// 获得待进入公海客户数量
+export const getPutPoolRemindCustomerCount = async () => {
+  return await request.get({ url: `/crm/customer/put-pool-remind-count` })
+}
+
+// 获得今日需联系客户数量
+export const getTodayContactCustomerCount = async () => {
+  return await request.get({ url: `/crm/customer/today-contact-count` })
+}
+
+// 获得分配给我、待跟进的线索数量的客户数量
+export const getFollowCustomerCount = async () => {
+  return await request.get({ url: `/crm/customer/follow-count` })
+}
+
 // 查询客户详情
 export const getCustomer = async (id: number) => {
   return await request.get({ url: `/crm/customer/get?id=` + id })
@@ -53,16 +71,62 @@ export const updateCustomer = async (data: CustomerVO) => {
   return await request.put({ url: `/crm/customer/update`, data })
 }
 
+// 更新客户的成交状态
+export const updateCustomerDealStatus = async (id: number, dealStatus: boolean) => {
+  return await request.put({ url: `/crm/customer/update-deal-status`, params: { id, dealStatus } })
+}
+
 // 删除客户
 export const deleteCustomer = async (id: number) => {
   return await request.delete({ url: `/crm/customer/delete?id=` + id })
 }
 
 // 导出客户 Excel
-export const exportCustomer = async (params) => {
+export const exportCustomer = async (params: any) => {
   return await request.download({ url: `/crm/customer/export-excel`, params })
 }
-//客户列表
-export const queryAllList = async () => {
-  return await request.get({ url: `/crm/customer/query-all-list` })
-}
+
+// 下载客户导入模板
+export const importCustomerTemplate = () => {
+  return request.download({ url: '/crm/customer/get-import-template' })
+}
+
+// 导入客户
+export const handleImport = async (formData) => {
+  return await request.upload({ url: `/crm/customer/import`, data: formData })
+}
+
+// 客户列表
+export const getCustomerSimpleList = async () => {
+  return await request.get({ url: `/crm/customer/simple-list` })
+}
+
+// ======================= 业务操作 =======================
+
+// 客户转移
+export const transferCustomer = async (data: TransferReqVO) => {
+  return await request.put({ url: '/crm/customer/transfer', data })
+}
+
+// 锁定/解锁客户
+export const lockCustomer = async (id: number, lockStatus: boolean) => {
+  return await request.put({ url: `/crm/customer/lock`, data: { id, lockStatus } })
+}
+
+// 领取公海客户
+export const receiveCustomer = async (ids: any[]) => {
+  return await request.put({ url: '/crm/customer/receive', params: { ids: ids.join(',') } })
+}
+
+// 分配公海给对应负责人
+export const distributeCustomer = async (ids: any[], ownerUserId: number) => {
+  return await request.put({
+    url: '/crm/customer/distribute',
+    data: { ids: ids, ownerUserId }
+  })
+}
+
+// 客户放入公海
+export const putCustomerPool = async (id: number) => {
+  return await request.put({ url: `/crm/customer/put-pool?id=${id}` })
+}

+ 14 - 0
src/api/crm/customerLimitConfig/index.ts

@@ -9,6 +9,20 @@ export interface CustomerLimitConfigVO {
   dealCountEnabled?: boolean
 }
 
+/**
+ * 客户限制配置类型
+ */
+export enum LimitConfType {
+  /**
+   * 拥有客户数限制
+   */
+  CUSTOMER_QUANTITY_LIMIT = 1,
+  /**
+   * 锁定客户数限制
+   */
+  CUSTOMER_LOCK_LIMIT = 2
+}
+
 // 查询客户限制配置列表
 export const getCustomerLimitConfigPage = async (params) => {
   return await request.get({ url: `/crm/customer-limit-config/page`, params })

+ 3 - 3
src/api/crm/customerPoolConf/index.ts

@@ -5,7 +5,7 @@ export interface CustomerPoolConfigVO {
   contactExpireDays?: number
   dealExpireDays?: number
   notifyEnabled?: boolean
-  notifyDays: number
+  notifyDays?: number
 }
 
 // 获取客户公海规则设置
@@ -14,6 +14,6 @@ export const getCustomerPoolConfig = async () => {
 }
 
 // 更新客户公海规则设置
-export const updateCustomerPoolConfig = async (data: ConfigVO) => {
-  return await request.put({ url: `/crm/customer-pool-config/update`, data })
+export const saveCustomerPoolConfig = async (data: CustomerPoolConfigVO) => {
+  return await request.put({ url: `/crm/customer-pool-config/save`, data })
 }

+ 43 - 0
src/api/crm/followup/index.ts

@@ -0,0 +1,43 @@
+import request from '@/config/axios'
+
+// 跟进记录 VO
+export interface FollowUpRecordVO {
+  id: number // 编号
+  bizType: number // 数据类型
+  bizId: number // 数据编号
+  type: number // 跟进类型
+  content: string // 跟进内容
+  picUrls: string[] // 图片
+  fileUrls: string[] // 附件
+  nextTime: Date // 下次联系时间
+  businessIds: number[] // 关联的商机编号数组
+  businesses: {
+    id: number
+    name: string
+  }[] // 关联的商机数组
+  contactIds: number[] // 关联的联系人编号数组
+  contacts: {
+    id: number
+    name: string
+  }[] // 关联的联系人数组
+  creator: string
+  creatorName?: string
+}
+
+// 跟进记录 API
+export const FollowUpRecordApi = {
+  // 查询跟进记录分页
+  getFollowUpRecordPage: async (params: any) => {
+    return await request.get({ url: `/crm/follow-up-record/page`, params })
+  },
+
+  // 新增跟进记录
+  createFollowUpRecord: async (data: FollowUpRecordVO) => {
+    return await request.post({ url: `/crm/follow-up-record/create`, data })
+  },
+
+  // 删除跟进记录
+  deleteFollowUpRecord: async (id: number) => {
+    return await request.delete({ url: `/crm/follow-up-record/delete?id=` + id })
+  }
+}

+ 11 - 0
src/api/crm/operateLog/index.ts

@@ -0,0 +1,11 @@
+import request from '@/config/axios'
+
+export interface OperateLogVO extends PageParam {
+  bizType: number
+  bizId: number
+}
+
+// 获得操作日志
+export const getOperateLogPage = async (params: OperateLogVO) => {
+  return await request.get({ url: `/crm/operate-log/page`, params })
+}

+ 47 - 23
src/api/crm/permission/index.ts

@@ -2,47 +2,71 @@ 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 // 权限级别
+  toBizTypes?: number[] // 同时添加至
   deptName?: string // 部门名称
   nickname?: string // 用户昵称
   postNames?: string[] // 岗位名称数组
   createTime?: Date
+  ids?: number[]
 }
 
-// 查询团队成员列表
+export interface TransferReqVO {
+  id: number // 模块编号
+  newOwnerUserId: number // 新负责人的用户编号
+  oldOwnerPermissionLevel?: number // 老负责人加入团队后的权限级别
+  toBizTypes?: number[] // 转移客户时,需要额外有【联系人】【商机】【合同】的 checkbox 选择
+}
+
+/**
+ * CRM 业务类型枚举
+ *
+ * @author HUIHUI
+ */
+export enum BizTypeEnum {
+  CRM_CLUE = 1, // 线索
+  CRM_CUSTOMER = 2, // 客户
+  CRM_CONTACT = 3, // 联系人
+  CRM_BUSINESS = 4, // 商机
+  CRM_CONTRACT = 5, // 合同
+  CRM_PRODUCT = 6, // 产品
+  CRM_RECEIVABLE = 7, // 回款
+  CRM_RECEIVABLE_PLAN = 8 // 回款计划
+}
+
+/**
+ * CRM 数据权限级别枚举
+ */
+export enum PermissionLevelEnum {
+  OWNER = 1, // 负责人
+  READ = 2, // 只读
+  WRITE = 3 // 读写
+}
+
+// 获得数据权限列表(查询团队成员列表)
 export const getPermissionList = async (params) => {
   return await request.get({ url: `/crm/permission/list`, params })
 }
 
-// 新增团队成员
+// 创建数据权限(新增团队成员
 export const createPermission = async (data: PermissionVO) => {
   return await request.post({ url: `/crm/permission/create`, data })
 }
 
-// 修改团队成员权限级别
+// 编辑数据权限(修改团队成员权限级别
 export const updatePermission = async (data) => {
   return await request.put({ url: `/crm/permission/update`, data })
 }
 
-// 删除团队成员
-export const deletePermission = async (params) => {
-  return await request.delete({ url: '/crm/permission/delete', params })
-}
-
-// 退出团队
-export const quitTeam = async (id) => {
-  return await request.delete({ url: '/crm/permission/quit-team?id=' + id })
-}
-
-// 领取公海数据
-export const receive = async (data: { bizType: number; bizId: number }) => {
-  return await request.put({ url: `/crm/permission/receive`, data })
+// 删除数据权限(删除团队成员)
+export const deletePermissionBatch = async (val: number[]) => {
+  return await request.delete({ url: '/crm/permission/delete?ids=' + val.join(',') })
 }
 
-// 数据放入公海
-export const putPool = async (data: { bizType: number; bizId: number }) => {
-  return await request.put({ url: `/crm/permission/put-pool`, data })
+// 删除自己的数据权限(退出团队)
+export const deleteSelfPermission = async (id: number) => {
+  return await request.delete({ url: '/crm/permission/delete-self?id=' + id })
 }

src/api/crm/productCategory/index.ts → src/api/crm/product/category/index.ts


+ 7 - 1
src/api/crm/product/index.ts

@@ -4,10 +4,11 @@ export interface ProductVO {
   id: number
   name: string
   no: string
-  unit: string
+  unit: number
   price: number
   status: number
   categoryId: number
+  categoryName?: string
   description: string
   ownerUserId: number
 }
@@ -17,6 +18,11 @@ export const getProductPage = async (params) => {
   return await request.get({ url: `/crm/product/page`, params })
 }
 
+// 获得产品精简列表
+export const getProductSimpleList = async () => {
+  return await request.get({ url: `/crm/product/simple-list` })
+}
+
 // 查询产品详情
 export const getProduct = async (id: number) => {
   return await request.get({ url: `/crm/product/get?id=` + id })

+ 38 - 16
src/api/crm/receivable/index.ts

@@ -3,49 +3,71 @@ import request from '@/config/axios'
 export interface ReceivableVO {
   id: number
   no: string
-  planId: number
-  customerId: number
-  contractId: number
-  checkStatus: number
+  planId?: number
+  customerId?: number
+  customerName?: string
+  contractId?: number
+  contract?: {
+    id?: number
+    name?: string
+    no: string
+    totalPrice: number
+  }
+  auditStatus: number
   processInstanceId: number
   returnTime: Date
-  returnType: string
+  returnType: number
   price: number
   ownerUserId: number
-  batchId: number
-  sort: number
-  dataScope: number
-  dataScopeDeptIds: string
-  status: number
+  ownerUserName?: string
   remark: string
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
 }
 
-// 查询回款管理列表
+// 查询回款列表
 export const getReceivablePage = async (params) => {
   return await request.get({ url: `/crm/receivable/page`, params })
 }
 
-// 查询回款管理详情
+// 查询回款列表
+export const getReceivablePageByCustomer = async (params) => {
+  return await request.get({ url: `/crm/receivable/page-by-customer`, params })
+}
+
+// 查询回款详情
 export const getReceivable = async (id: number) => {
   return await request.get({ url: `/crm/receivable/get?id=` + id })
 }
 
-// 新增回款管理
+// 新增回款
 export const createReceivable = async (data: ReceivableVO) => {
   return await request.post({ url: `/crm/receivable/create`, data })
 }
 
-// 修改回款管理
+// 修改回款
 export const updateReceivable = async (data: ReceivableVO) => {
   return await request.put({ url: `/crm/receivable/update`, data })
 }
 
-// 删除回款管理
+// 删除回款
 export const deleteReceivable = async (id: number) => {
   return await request.delete({ url: `/crm/receivable/delete?id=` + id })
 }
 
-// 导出回款管理 Excel
+// 导出回款 Excel
 export const exportReceivable = async (params) => {
   return await request.download({ url: `/crm/receivable/export-excel`, params })
 }
+
+// 提交审核
+export const submitReceivable = async (id: number) => {
+  return await request.put({ url: `/crm/receivable/submit?id=${id}` })
+}
+
+// 获得待审核回款数量
+export const getAuditReceivableCount = async () => {
+  return await request.get({ url: '/crm/receivable/audit-count' })
+}

+ 30 - 5
src/api/crm/receivablePlan/index.ts

@@ -4,18 +4,26 @@ export interface ReceivablePlanVO {
   id: number
   period: number
   receivableId: number
-  status: number
-  checkStatus: string
-  processInstanceId: number
   price: number
   returnTime: Date
   remindDays: number
+  returnType: number
   remindTime: Date
   customerId: number
-  contractId: number
+  customerName?: string
+  contractId?: number
+  contractNo?: string
   ownerUserId: number
-  sort: number
+  ownerUserName?: string
   remark: string
+  creator: string // 创建人
+  creatorName?: string // 创建人名称
+  createTime: Date // 创建时间
+  updateTime: Date // 更新时间
+  receivable?: {
+    price: number
+    returnTime: Date
+  }
 }
 
 // 查询回款计划列表
@@ -23,11 +31,23 @@ export const getReceivablePlanPage = async (params) => {
   return await request.get({ url: `/crm/receivable-plan/page`, params })
 }
 
+// 查询回款计划列表
+export const getReceivablePlanPageByCustomer = async (params) => {
+  return await request.get({ url: `/crm/receivable-plan/page-by-customer`, params })
+}
+
 // 查询回款计划详情
 export const getReceivablePlan = async (id: number) => {
   return await request.get({ url: `/crm/receivable-plan/get?id=` + id })
 }
 
+// 查询回款计划下拉数据
+export const getReceivablePlanSimpleList = async (customerId: number, contractId: number) => {
+  return await request.get({
+    url: `/crm/receivable-plan/simple-list?customerId=${customerId}&contractId=${contractId}`
+  })
+}
+
 // 新增回款计划
 export const createReceivablePlan = async (data: ReceivablePlanVO) => {
   return await request.post({ url: `/crm/receivable-plan/create`, data })
@@ -47,3 +67,8 @@ export const deleteReceivablePlan = async (id: number) => {
 export const exportReceivablePlan = async (params) => {
   return await request.download({ url: `/crm/receivable-plan/export-excel`, params })
 }
+
+// 获得待回款提醒数量
+export const getReceivablePlanRemindCount = async () => {
+  return await request.get({ url: '/crm/receivable-plan/remind-count' })
+}

+ 168 - 0
src/api/crm/statistics/customer.ts

@@ -0,0 +1,168 @@
+import request from '@/config/axios'
+
+export interface CrmStatisticsCustomerSummaryByDateRespVO {
+  time: string
+  customerCreateCount: number
+  customerDealCount: number
+}
+
+export interface CrmStatisticsCustomerSummaryByUserRespVO {
+  ownerUserName: string
+  customerCreateCount: number
+  customerDealCount: number
+  contractPrice: number
+  receivablePrice: number
+}
+
+export interface CrmStatisticsFollowUpSummaryByDateRespVO {
+  time: string
+  followUpRecordCount: number
+  followUpCustomerCount: number
+}
+
+export interface CrmStatisticsFollowUpSummaryByUserRespVO {
+  ownerUserName: string
+  followupRecordCount: number
+  followupCustomerCount: number
+}
+
+export interface CrmStatisticsFollowUpSummaryByTypeRespVO {
+  followUpType: string
+  followUpRecordCount: number
+}
+
+export interface CrmStatisticsCustomerContractSummaryRespVO {
+  customerName: string
+  contractName: string
+  totalPrice: number
+  receivablePrice: number
+  customerType: string
+  customerSource: string
+  ownerUserName: string
+  creatorUserName: string
+  createTime: Date
+  orderDate: Date
+}
+
+export interface CrmStatisticsPoolSummaryByDateRespVO {
+  time: string
+  customerPutCount: number
+  customerTakeCount: number
+}
+
+export interface CrmStatisticsPoolSummaryByUserRespVO {
+  ownerUserName: string
+  customerPutCount: number
+  customerTakeCount: number
+}
+
+export interface CrmStatisticsCustomerDealCycleByDateRespVO {
+  time: string
+  customerDealCycle: number
+}
+
+export interface CrmStatisticsCustomerDealCycleByUserRespVO {
+  ownerUserName: string
+  customerDealCycle: number
+  customerDealCount: number
+}
+
+export interface CrmStatisticsCustomerDealCycleByAreaRespVO {
+  areaName: string
+  customerDealCycle: number
+  customerDealCount: number
+}
+
+export interface CrmStatisticsCustomerDealCycleByProductRespVO {
+  productName: string
+  customerDealCycle: number
+  customerDealCount: number
+}
+
+// 客户分析 API
+export const StatisticsCustomerApi = {
+  // 1.1 客户总量分析(按日期)
+  getCustomerSummaryByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-summary-by-date',
+      params
+    })
+  },
+  // 1.2 客户总量分析(按用户)
+  getCustomerSummaryByUser: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-summary-by-user',
+      params
+    })
+  },
+  // 2.1 客户跟进次数分析(按日期)
+  getFollowUpSummaryByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-follow-up-summary-by-date',
+      params
+    })
+  },
+  // 2.2 客户跟进次数分析(按用户)
+  getFollowUpSummaryByUser: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-follow-up-summary-by-user',
+      params
+    })
+  },
+  // 3.1 获取客户跟进方式统计数
+  getFollowUpSummaryByType: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-follow-up-summary-by-type',
+      params
+    })
+  },
+  // 4.1 合同摘要信息(客户转化率页面)
+  getContractSummary: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-contract-summary',
+      params
+    })
+  },
+  // 5.1 获取客户公海分析(按日期)
+  getPoolSummaryByDate: (param: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-pool-summary-by-date',
+      params: param
+    })
+  },
+  // 5.2 获取客户公海分析(按用户)
+  getPoolSummaryByUser: (param: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-pool-summary-by-user',
+      params: param
+    })
+  },
+  // 6.1 获取客户成交周期(按日期)
+  getCustomerDealCycleByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-deal-cycle-by-date',
+      params
+    })
+  },
+  // 6.2 获取客户成交周期(按用户)
+  getCustomerDealCycleByUser: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-deal-cycle-by-user',
+      params
+    })
+  },
+  // 6.2 获取客户成交周期(按用户)
+  getCustomerDealCycleByArea: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-deal-cycle-by-area',
+      params
+    })
+  },
+  // 6.2 获取客户成交周期(按用户)
+  getCustomerDealCycleByProduct: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-customer/get-customer-deal-cycle-by-product',
+      params
+    })
+  }
+}

+ 58 - 0
src/api/crm/statistics/funnel.ts

@@ -0,0 +1,58 @@
+import request from '@/config/axios'
+
+export interface CrmStatisticFunnelRespVO {
+  customerCount: number // 客户数
+  businessCount: number // 商机数
+  businessWinCount: number // 赢单数
+}
+
+export interface CrmStatisticsBusinessSummaryByDateRespVO {
+  time: string // 时间
+  businessCreateCount: number // 商机数
+  totalPrice: number | string // 商机金额
+}
+
+export interface CrmStatisticsBusinessInversionRateSummaryByDateRespVO {
+  time: string // 时间
+  businessCount: number // 商机数量
+  businessWinCount: number // 赢单商机数
+}
+
+// 客户分析 API
+export const StatisticFunnelApi = {
+  // 1. 获取销售漏斗统计数据
+  getFunnelSummary: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-funnel/get-funnel-summary',
+      params
+    })
+  },
+  // 2. 获取商机结束状态统计
+  getBusinessSummaryByEndStatus: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-funnel/get-business-summary-by-end-status',
+      params
+    })
+  },
+  // 3. 获取新增商机分析(按日期)
+  getBusinessSummaryByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-funnel/get-business-summary-by-date',
+      params
+    })
+  },
+  // 4. 获取商机转化率分析(按日期)
+  getBusinessInversionRateSummaryByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-funnel/get-business-inversion-rate-summary-by-date',
+      params
+    })
+  },
+  // 5. 获取商机列表(按日期)
+  getBusinessPageByDate: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-funnel/get-business-page-by-date',
+      params
+    })
+  }
+}

+ 33 - 0
src/api/crm/statistics/performance.ts

@@ -0,0 +1,33 @@
+import request from '@/config/axios'
+
+export interface StatisticsPerformanceRespVO {
+  time: string
+  currentMonthCount: number
+  lastMonthCount: number
+  lastYearCount: number
+}
+
+// 排行 API
+export const StatisticsPerformanceApi = {
+  // 员工获得合同金额统计
+  getContractPricePerformance: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-performance/get-contract-price-performance',
+      params
+    })
+  },
+  // 员工获得回款统计
+  getReceivablePricePerformance: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-performance/get-receivable-price-performance',
+      params
+    })
+  },
+  //员工获得签约合同数量统计
+  getContractCountPerformance: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-performance/get-contract-count-performance',
+      params
+    })
+  }
+}

+ 60 - 0
src/api/crm/statistics/portrait.ts

@@ -0,0 +1,60 @@
+import request from '@/config/axios'
+
+export interface CrmStatisticCustomerBaseRespVO {
+  customerCount: number
+  dealCount: number
+  dealPortion: string | number
+}
+
+export interface CrmStatisticCustomerIndustryRespVO extends CrmStatisticCustomerBaseRespVO {
+  industryId: number
+  industryPortion: string | number
+}
+
+export interface CrmStatisticCustomerSourceRespVO extends CrmStatisticCustomerBaseRespVO {
+  source: number
+  sourcePortion: string | number
+}
+
+export interface CrmStatisticCustomerLevelRespVO extends CrmStatisticCustomerBaseRespVO {
+  level: number
+  levelPortion: string | number
+}
+
+export interface CrmStatisticCustomerAreaRespVO extends CrmStatisticCustomerBaseRespVO {
+  areaId: number
+  areaName: string
+  areaPortion: string | number
+}
+
+// 客户分析 API
+export const StatisticsPortraitApi = {
+  // 1. 获取客户行业统计数据
+  getCustomerIndustry: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-portrait/get-customer-industry-summary',
+      params
+    })
+  },
+  // 2. 获取客户来源统计数据
+  getCustomerSource: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-portrait/get-customer-source-summary',
+      params
+    })
+  },
+  // 3. 获取客户级别统计数据
+  getCustomerLevel: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-portrait/get-customer-level-summary',
+      params
+    })
+  },
+  // 4. 获取客户地区统计数据
+  getCustomerArea: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-portrait/get-customer-area-summary',
+      params
+    })
+  }
+}

+ 67 - 0
src/api/crm/statistics/rank.ts

@@ -0,0 +1,67 @@
+import request from '@/config/axios'
+
+export interface StatisticsRankRespVO {
+  count: number
+  nickname: string
+  deptName: string
+}
+
+// 排行 API
+export const StatisticsRankApi = {
+  // 获得合同排行榜
+  getContractPriceRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-contract-price-rank',
+      params
+    })
+  },
+  // 获得回款排行榜
+  getReceivablePriceRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-receivable-price-rank',
+      params
+    })
+  },
+  // 签约合同排行
+  getContractCountRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-contract-count-rank',
+      params
+    })
+  },
+  // 产品销量排行
+  getProductSalesRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-product-sales-rank',
+      params
+    })
+  },
+  // 新增客户数排行
+  getCustomerCountRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-customer-count-rank',
+      params
+    })
+  },
+  // 新增联系人数排行
+  getContactsCountRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-contacts-count-rank',
+      params
+    })
+  },
+  // 跟进次数排行
+  getFollowCountRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-follow-count-rank',
+      params
+    })
+  },
+  // 跟进客户数排行
+  getFollowCustomerCountRank: (params: any) => {
+    return request.get({
+      url: '/crm/statistics-rank/get-follow-customer-count-rank',
+      params
+    })
+  }
+}

+ 61 - 0
src/api/erp/finance/account/index.ts

@@ -0,0 +1,61 @@
+import request from '@/config/axios'
+
+// ERP 结算账户 VO
+export interface AccountVO {
+  id: number // 结算账户编号
+  no: string // 账户编码
+  remark: string // 备注
+  status: number // 开启状态
+  sort: number // 排序
+  defaultStatus: boolean // 是否默认
+  name: string // 账户名称
+}
+
+// ERP 结算账户 API
+export const AccountApi = {
+  // 查询结算账户分页
+  getAccountPage: async (params: any) => {
+    return await request.get({ url: `/erp/account/page`, params })
+  },
+
+  // 查询结算账户精简列表
+  getAccountSimpleList: async () => {
+    return await request.get({ url: `/erp/account/simple-list` })
+  },
+
+  // 查询结算账户详情
+  getAccount: async (id: number) => {
+    return await request.get({ url: `/erp/account/get?id=` + id })
+  },
+
+  // 新增结算账户
+  createAccount: async (data: AccountVO) => {
+    return await request.post({ url: `/erp/account/create`, data })
+  },
+
+  // 修改结算账户
+  updateAccount: async (data: AccountVO) => {
+    return await request.put({ url: `/erp/account/update`, data })
+  },
+
+  // 修改结算账户默认状态
+  updateAccountDefaultStatus: async (id: number, defaultStatus: boolean) => {
+    return await request.put({
+      url: `/erp/account/update-default-status`,
+      params: {
+        id,
+        defaultStatus
+      }
+    })
+  },
+
+  // 删除结算账户
+  deleteAccount: async (id: number) => {
+    return await request.delete({ url: `/erp/account/delete?id=` + id })
+  },
+
+  // 导出结算账户 Excel
+  exportAccount: async (params: any) => {
+    return await request.download({ url: `/erp/account/export-excel`, params })
+  }
+}

+ 61 - 0
src/api/erp/finance/payment/index.ts

@@ -0,0 +1,61 @@
+import request from '@/config/axios'
+
+// ERP 付款单 VO
+export interface FinancePaymentVO {
+  id: number // 付款单编号
+  no: string // 付款单号
+  supplierId: number // 供应商编号
+  paymentTime: Date // 付款时间
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 付款单 API
+export const FinancePaymentApi = {
+  // 查询付款单分页
+  getFinancePaymentPage: async (params: any) => {
+    return await request.get({ url: `/erp/finance-payment/page`, params })
+  },
+
+  // 查询付款单详情
+  getFinancePayment: async (id: number) => {
+    return await request.get({ url: `/erp/finance-payment/get?id=` + id })
+  },
+
+  // 新增付款单
+  createFinancePayment: async (data: FinancePaymentVO) => {
+    return await request.post({ url: `/erp/finance-payment/create`, data })
+  },
+
+  // 修改付款单
+  updateFinancePayment: async (data: FinancePaymentVO) => {
+    return await request.put({ url: `/erp/finance-payment/update`, data })
+  },
+
+  // 更新付款单的状态
+  updateFinancePaymentStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/finance-payment/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除付款单
+  deleteFinancePayment: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/finance-payment/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出付款单 Excel
+  exportFinancePayment: async (params: any) => {
+    return await request.download({ url: `/erp/finance-payment/export-excel`, params })
+  }
+}

+ 61 - 0
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 })
+  }
+}

+ 49 - 0
src/api/erp/product/category/index.ts

@@ -0,0 +1,49 @@
+import request from '@/config/axios'
+
+// ERP 产品分类 VO
+export interface ProductCategoryVO {
+  id: number // 分类编号
+  parentId: number // 父分类编号
+  name: string // 分类名称
+  code: string // 分类编码
+  sort: number // 分类排序
+  status: number // 开启状态
+}
+
+// ERP 产品分类 API
+export const ProductCategoryApi = {
+  // 查询产品分类列表
+  getProductCategoryList: async () => {
+    return await request.get({ url: `/erp/product-category/list` })
+  },
+
+  // 查询产品分类精简列表
+  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
+  exportProductCategory: async (params) => {
+    return await request.download({ url: `/erp/product-category/export-excel`, params })
+  }
+}

+ 57 - 0
src/api/erp/product/product/index.ts

@@ -0,0 +1,57 @@
+import request from '@/config/axios'
+
+// ERP 产品 VO
+export interface ProductVO {
+  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 // 最低价格,单位:元
+}
+
+// ERP 产品 API
+export const ProductApi = {
+  // 查询产品分页
+  getProductPage: async (params: any) => {
+    return await request.get({ url: `/erp/product/page`, params })
+  },
+
+  // 查询产品精简列表
+  getProductSimpleList: async () => {
+    return await request.get({ url: `/erp/product/simple-list` })
+  },
+
+  // 查询产品详情
+  getProduct: async (id: number) => {
+    return await request.get({ url: `/erp/product/get?id=` + id })
+  },
+
+  // 新增产品
+  createProduct: async (data: ProductVO) => {
+    return await request.post({ url: `/erp/product/create`, data })
+  },
+
+  // 修改产品
+  updateProduct: async (data: ProductVO) => {
+    return await request.put({ url: `/erp/product/update`, data })
+  },
+
+  // 删除产品
+  deleteProduct: async (id: number) => {
+    return await request.delete({ url: `/erp/product/delete?id=` + id })
+  },
+
+  // 导出产品 Excel
+  exportProduct: async (params) => {
+    return await request.download({ url: `/erp/product/export-excel`, params })
+  }
+}

+ 46 - 0
src/api/erp/product/unit/index.ts

@@ -0,0 +1,46 @@
+import request from '@/config/axios'
+
+// ERP 产品单位 VO
+export interface ProductUnitVO {
+  id: number // 单位编号
+  name: string // 单位名字
+  status: number // 单位状态
+}
+
+// ERP 产品单位 API
+export const ProductUnitApi = {
+  // 查询产品单位分页
+  getProductUnitPage: async (params: any) => {
+    return await request.get({ url: `/erp/product-unit/page`, params })
+  },
+
+  // 查询产品单位精简列表
+  getProductUnitSimpleList: async () => {
+    return await request.get({ url: `/erp/product-unit/simple-list` })
+  },
+
+  // 查询产品单位详情
+  getProductUnit: async (id: number) => {
+    return await request.get({ url: `/erp/product-unit/get?id=` + id })
+  },
+
+  // 新增产品单位
+  createProductUnit: async (data: ProductUnitVO) => {
+    return await request.post({ url: `/erp/product-unit/create`, data })
+  },
+
+  // 修改产品单位
+  updateProductUnit: async (data: ProductUnitVO) => {
+    return await request.put({ url: `/erp/product-unit/update`, data })
+  },
+
+  // 删除产品单位
+  deleteProductUnit: async (id: number) => {
+    return await request.delete({ url: `/erp/product-unit/delete?id=` + id })
+  },
+
+  // 导出产品单位 Excel
+  exportProductUnit: async (params) => {
+    return await request.download({ url: `/erp/product-unit/export-excel`, params })
+  }
+}

+ 64 - 0
src/api/erp/purchase/in/index.ts

@@ -0,0 +1,64 @@
+import request from '@/config/axios'
+
+// ERP 采购入库 VO
+export interface PurchaseInVO {
+  id: number // 入库工单编号
+  no: string // 采购入库号
+  customerId: number // 客户编号
+  inTime: Date // 入库时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+  outCount: number // 采购出库数量
+  returnCount: number // 采购退货数量
+}
+
+// ERP 采购入库 API
+export const PurchaseInApi = {
+  // 查询采购入库分页
+  getPurchaseInPage: async (params: any) => {
+    return await request.get({ url: `/erp/purchase-in/page`, params })
+  },
+
+  // 查询采购入库详情
+  getPurchaseIn: async (id: number) => {
+    return await request.get({ url: `/erp/purchase-in/get?id=` + id })
+  },
+
+  // 新增采购入库
+  createPurchaseIn: async (data: PurchaseInVO) => {
+    return await request.post({ url: `/erp/purchase-in/create`, data })
+  },
+
+  // 修改采购入库
+  updatePurchaseIn: async (data: PurchaseInVO) => {
+    return await request.put({ url: `/erp/purchase-in/update`, data })
+  },
+
+  // 更新采购入库的状态
+  updatePurchaseInStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/purchase-in/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除采购入库
+  deletePurchaseIn: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/purchase-in/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出采购入库 Excel
+  exportPurchaseIn: async (params: any) => {
+    return await request.download({ url: `/erp/purchase-in/export-excel`, params })
+  }
+}

+ 64 - 0
src/api/erp/purchase/order/index.ts

@@ -0,0 +1,64 @@
+import request from '@/config/axios'
+
+// ERP 采购订单 VO
+export interface PurchaseOrderVO {
+  id: number // 订单工单编号
+  no: string // 采购订单号
+  customerId: number // 客户编号
+  orderTime: Date // 订单时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+  outCount: number // 采购出库数量
+  returnCount: number // 采购退货数量
+}
+
+// ERP 采购订单 API
+export const PurchaseOrderApi = {
+  // 查询采购订单分页
+  getPurchaseOrderPage: async (params: any) => {
+    return await request.get({ url: `/erp/purchase-order/page`, params })
+  },
+
+  // 查询采购订单详情
+  getPurchaseOrder: async (id: number) => {
+    return await request.get({ url: `/erp/purchase-order/get?id=` + id })
+  },
+
+  // 新增采购订单
+  createPurchaseOrder: async (data: PurchaseOrderVO) => {
+    return await request.post({ url: `/erp/purchase-order/create`, data })
+  },
+
+  // 修改采购订单
+  updatePurchaseOrder: async (data: PurchaseOrderVO) => {
+    return await request.put({ url: `/erp/purchase-order/update`, data })
+  },
+
+  // 更新采购订单的状态
+  updatePurchaseOrderStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/purchase-order/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除采购订单
+  deletePurchaseOrder: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/purchase-order/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出采购订单 Excel
+  exportPurchaseOrder: async (params: any) => {
+    return await request.download({ url: `/erp/purchase-order/export-excel`, params })
+  }
+}

+ 62 - 0
src/api/erp/purchase/return/index.ts

@@ -0,0 +1,62 @@
+import request from '@/config/axios'
+
+// ERP 采购退货 VO
+export interface PurchaseReturnVO {
+  id: number // 采购退货编号
+  no: string // 采购退货号
+  customerId: number // 客户编号
+  returnTime: Date // 退货时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 采购退货 API
+export const PurchaseReturnApi = {
+  // 查询采购退货分页
+  getPurchaseReturnPage: async (params: any) => {
+    return await request.get({ url: `/erp/purchase-return/page`, params })
+  },
+
+  // 查询采购退货详情
+  getPurchaseReturn: async (id: number) => {
+    return await request.get({ url: `/erp/purchase-return/get?id=` + id })
+  },
+
+  // 新增采购退货
+  createPurchaseReturn: async (data: PurchaseReturnVO) => {
+    return await request.post({ url: `/erp/purchase-return/create`, data })
+  },
+
+  // 修改采购退货
+  updatePurchaseReturn: async (data: PurchaseReturnVO) => {
+    return await request.put({ url: `/erp/purchase-return/update`, data })
+  },
+
+  // 更新采购退货的状态
+  updatePurchaseReturnStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/purchase-return/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除采购退货
+  deletePurchaseReturn: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/purchase-return/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出采购退货 Excel
+  exportPurchaseReturn: async (params: any) => {
+    return await request.download({ url: `/erp/purchase-return/export-excel`, params })
+  }
+}

+ 58 - 0
src/api/erp/purchase/supplier/index.ts

@@ -0,0 +1,58 @@
+import request from '@/config/axios'
+
+// ERP 供应商 VO
+export interface SupplierVO {
+  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 // 开户地址
+}
+
+// ERP 供应商 API
+export const SupplierApi = {
+  // 查询供应商分页
+  getSupplierPage: async (params: any) => {
+    return await request.get({ url: `/erp/supplier/page`, params })
+  },
+
+  // 获得供应商精简列表
+  getSupplierSimpleList: async () => {
+    return await request.get({ url: `/erp/supplier/simple-list` })
+  },
+
+  // 查询供应商详情
+  getSupplier: async (id: number) => {
+    return await request.get({ url: `/erp/supplier/get?id=` + id })
+  },
+
+  // 新增供应商
+  createSupplier: async (data: SupplierVO) => {
+    return await request.post({ url: `/erp/supplier/create`, data })
+  },
+
+  // 修改供应商
+  updateSupplier: async (data: SupplierVO) => {
+    return await request.put({ url: `/erp/supplier/update`, data })
+  },
+
+  // 删除供应商
+  deleteSupplier: async (id: number) => {
+    return await request.delete({ url: `/erp/supplier/delete?id=` + id })
+  },
+
+  // 导出供应商 Excel
+  exportSupplier: async (params) => {
+    return await request.download({ url: `/erp/supplier/export-excel`, params })
+  }
+}

+ 58 - 0
src/api/erp/sale/customer/index.ts

@@ -0,0 +1,58 @@
+import request from '@/config/axios'
+
+// ERP 客户 VO
+export interface CustomerVO {
+  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 // 开户地址
+}
+
+// ERP 客户 API
+export const CustomerApi = {
+  // 查询客户分页
+  getCustomerPage: async (params: any) => {
+    return await request.get({ url: `/erp/customer/page`, params })
+  },
+
+  // 查询客户精简列表
+  getCustomerSimpleList: async () => {
+    return await request.get({ url: `/erp/customer/simple-list` })
+  },
+
+  // 查询客户详情
+  getCustomer: async (id: number) => {
+    return await request.get({ url: `/erp/customer/get?id=` + id })
+  },
+
+  // 新增客户
+  createCustomer: async (data: CustomerVO) => {
+    return await request.post({ url: `/erp/customer/create`, data })
+  },
+
+  // 修改客户
+  updateCustomer: async (data: CustomerVO) => {
+    return await request.put({ url: `/erp/customer/update`, data })
+  },
+
+  // 删除客户
+  deleteCustomer: async (id: number) => {
+    return await request.delete({ url: `/erp/customer/delete?id=` + id })
+  },
+
+  // 导出客户 Excel
+  exportCustomer: async (params) => {
+    return await request.download({ url: `/erp/customer/export-excel`, params })
+  }
+}

+ 64 - 0
src/api/erp/sale/order/index.ts

@@ -0,0 +1,64 @@
+import request from '@/config/axios'
+
+// ERP 销售订单 VO
+export interface SaleOrderVO {
+  id: number // 订单工单编号
+  no: string // 销售订单号
+  customerId: number // 客户编号
+  orderTime: Date // 订单时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+  outCount: number // 销售出库数量
+  returnCount: number // 销售退货数量
+}
+
+// ERP 销售订单 API
+export const SaleOrderApi = {
+  // 查询销售订单分页
+  getSaleOrderPage: async (params: any) => {
+    return await request.get({ url: `/erp/sale-order/page`, params })
+  },
+
+  // 查询销售订单详情
+  getSaleOrder: async (id: number) => {
+    return await request.get({ url: `/erp/sale-order/get?id=` + id })
+  },
+
+  // 新增销售订单
+  createSaleOrder: async (data: SaleOrderVO) => {
+    return await request.post({ url: `/erp/sale-order/create`, data })
+  },
+
+  // 修改销售订单
+  updateSaleOrder: async (data: SaleOrderVO) => {
+    return await request.put({ url: `/erp/sale-order/update`, data })
+  },
+
+  // 更新销售订单的状态
+  updateSaleOrderStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/sale-order/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除销售订单
+  deleteSaleOrder: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/sale-order/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出销售订单 Excel
+  exportSaleOrder: async (params: any) => {
+    return await request.download({ url: `/erp/sale-order/export-excel`, params })
+  }
+}

+ 62 - 0
src/api/erp/sale/out/index.ts

@@ -0,0 +1,62 @@
+import request from '@/config/axios'
+
+// ERP 销售出库 VO
+export interface SaleOutVO {
+  id: number // 销售出库编号
+  no: string // 销售出库号
+  customerId: number // 客户编号
+  outTime: Date // 出库时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 销售出库 API
+export const SaleOutApi = {
+  // 查询销售出库分页
+  getSaleOutPage: async (params: any) => {
+    return await request.get({ url: `/erp/sale-out/page`, params })
+  },
+
+  // 查询销售出库详情
+  getSaleOut: async (id: number) => {
+    return await request.get({ url: `/erp/sale-out/get?id=` + id })
+  },
+
+  // 新增销售出库
+  createSaleOut: async (data: SaleOutVO) => {
+    return await request.post({ url: `/erp/sale-out/create`, data })
+  },
+
+  // 修改销售出库
+  updateSaleOut: async (data: SaleOutVO) => {
+    return await request.put({ url: `/erp/sale-out/update`, data })
+  },
+
+  // 更新销售出库的状态
+  updateSaleOutStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/sale-out/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除销售出库
+  deleteSaleOut: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/sale-out/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出销售出库 Excel
+  exportSaleOut: async (params: any) => {
+    return await request.download({ url: `/erp/sale-out/export-excel`, params })
+  }
+}

+ 62 - 0
src/api/erp/sale/return/index.ts

@@ -0,0 +1,62 @@
+import request from '@/config/axios'
+
+// ERP 销售退货 VO
+export interface SaleReturnVO {
+  id: number // 销售退货编号
+  no: string // 销售退货号
+  customerId: number // 客户编号
+  returnTime: Date // 退货时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 销售退货 API
+export const SaleReturnApi = {
+  // 查询销售退货分页
+  getSaleReturnPage: async (params: any) => {
+    return await request.get({ url: `/erp/sale-return/page`, params })
+  },
+
+  // 查询销售退货详情
+  getSaleReturn: async (id: number) => {
+    return await request.get({ url: `/erp/sale-return/get?id=` + id })
+  },
+
+  // 新增销售退货
+  createSaleReturn: async (data: SaleReturnVO) => {
+    return await request.post({ url: `/erp/sale-return/create`, data })
+  },
+
+  // 修改销售退货
+  updateSaleReturn: async (data: SaleReturnVO) => {
+    return await request.put({ url: `/erp/sale-return/update`, data })
+  },
+
+  // 更新销售退货的状态
+  updateSaleReturnStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/sale-return/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除销售退货
+  deleteSaleReturn: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/sale-return/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出销售退货 Excel
+  exportSaleReturn: async (params: any) => {
+    return await request.download({ url: `/erp/sale-return/export-excel`, params })
+  }
+}

+ 28 - 0
src/api/erp/statistics/purchase/index.ts

@@ -0,0 +1,28 @@
+import request from '@/config/axios'
+
+// ERP 采购全局统计 VO
+export interface ErpPurchaseSummaryRespVO {
+  todayPrice: number // 今日采购金额
+  yesterdayPrice: number // 昨日采购金额
+  monthPrice: number // 本月采购金额
+  yearPrice: number // 今年采购金额
+}
+
+// ERP 采购时间段统计 VO
+export interface ErpPurchaseTimeSummaryRespVO {
+  time: string // 时间
+  price: number // 采购金额
+}
+
+// ERP 采购统计 API
+export const PurchaseStatisticsApi = {
+  // 获得采购统计
+  getPurchaseSummary: async (): Promise<ErpPurchaseSummaryRespVO> => {
+    return await request.get({ url: `/erp/purchase-statistics/summary` })
+  },
+
+  // 获得采购时间段统计
+  getPurchaseTimeSummary: async (): Promise<ErpPurchaseTimeSummaryRespVO[]> => {
+    return await request.get({ url: `/erp/purchase-statistics/time-summary` })
+  }
+}

+ 28 - 0
src/api/erp/statistics/sale/index.ts

@@ -0,0 +1,28 @@
+import request from '@/config/axios'
+
+// ERP 销售全局统计 VO
+export interface ErpSaleSummaryRespVO {
+  todayPrice: number // 今日销售金额
+  yesterdayPrice: number // 昨日销售金额
+  monthPrice: number // 本月销售金额
+  yearPrice: number // 今年销售金额
+}
+
+// ERP 销售时间段统计 VO
+export interface ErpSaleTimeSummaryRespVO {
+  time: string // 时间
+  price: number // 销售金额
+}
+
+// ERP 销售统计 API
+export const SaleStatisticsApi = {
+  // 获得销售统计
+  getSaleSummary: async (): Promise<ErpSaleSummaryRespVO> => {
+    return await request.get({ url: `/erp/sale-statistics/summary` })
+  },
+
+  // 获得销售时间段统计
+  getSaleTimeSummary: async (): Promise<ErpSaleTimeSummaryRespVO[]> => {
+    return await request.get({ url: `/erp/sale-statistics/time-summary` })
+  }
+}

+ 61 - 0
src/api/erp/stock/check/index.ts

@@ -0,0 +1,61 @@
+import request from '@/config/axios'
+
+// ERP 库存盘点单 VO
+export interface StockCheckVO {
+  id: number // 出库编号
+  no: string // 出库单号
+  outTime: Date // 出库时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 库存盘点单 API
+export const StockCheckApi = {
+  // 查询库存盘点单分页
+  getStockCheckPage: async (params: any) => {
+    return await request.get({ url: `/erp/stock-check/page`, params })
+  },
+
+  // 查询库存盘点单详情
+  getStockCheck: async (id: number) => {
+    return await request.get({ url: `/erp/stock-check/get?id=` + id })
+  },
+
+  // 新增库存盘点单
+  createStockCheck: async (data: StockCheckVO) => {
+    return await request.post({ url: `/erp/stock-check/create`, data })
+  },
+
+  // 修改库存盘点单
+  updateStockCheck: async (data: StockCheckVO) => {
+    return await request.put({ url: `/erp/stock-check/update`, data })
+  },
+
+  // 更新库存盘点单的状态
+  updateStockCheckStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/stock-check/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除库存盘点单
+  deleteStockCheck: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/stock-check/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出库存盘点单 Excel
+  exportStockCheck: async (params) => {
+    return await request.download({ url: `/erp/stock-check/export-excel`, params })
+  }
+}

+ 62 - 0
src/api/erp/stock/in/index.ts

@@ -0,0 +1,62 @@
+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 // 备注
+}
+
+// ERP 其它入库单 API
+export const StockInApi = {
+  // 查询其它入库单分页
+  getStockInPage: async (params: any) => {
+    return await request.get({ url: `/erp/stock-in/page`, params })
+  },
+
+  // 查询其它入库单详情
+  getStockIn: async (id: number) => {
+    return await request.get({ url: `/erp/stock-in/get?id=` + id })
+  },
+
+  // 新增其它入库单
+  createStockIn: async (data: StockInVO) => {
+    return await request.post({ url: `/erp/stock-in/create`, data })
+  },
+
+  // 修改其它入库单
+  updateStockIn: async (data: StockInVO) => {
+    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 (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/stock-in/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出其它入库单 Excel
+  exportStockIn: async (params) => {
+    return await request.download({ url: `/erp/stock-in/export-excel`, params })
+  }
+}

+ 61 - 0
src/api/erp/stock/move/index.ts

@@ -0,0 +1,61 @@
+import request from '@/config/axios'
+
+// ERP 库存调度单 VO
+export interface StockMoveVO {
+  id: number // 出库编号
+  no: string // 出库单号
+  outTime: Date // 出库时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 库存调度单 API
+export const StockMoveApi = {
+  // 查询库存调度单分页
+  getStockMovePage: async (params: any) => {
+    return await request.get({ url: `/erp/stock-move/page`, params })
+  },
+
+  // 查询库存调度单详情
+  getStockMove: async (id: number) => {
+    return await request.get({ url: `/erp/stock-move/get?id=` + id })
+  },
+
+  // 新增库存调度单
+  createStockMove: async (data: StockMoveVO) => {
+    return await request.post({ url: `/erp/stock-move/create`, data })
+  },
+
+  // 修改库存调度单
+  updateStockMove: async (data: StockMoveVO) => {
+    return await request.put({ url: `/erp/stock-move/update`, data })
+  },
+
+  // 更新库存调度单的状态
+  updateStockMoveStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/stock-move/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除库存调度单
+  deleteStockMove: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/stock-move/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出库存调度单 Excel
+  exportStockMove: async (params) => {
+    return await request.download({ url: `/erp/stock-move/export-excel`, params })
+  }
+}

+ 62 - 0
src/api/erp/stock/out/index.ts

@@ -0,0 +1,62 @@
+import request from '@/config/axios'
+
+// ERP 其它出库单 VO
+export interface StockOutVO {
+  id: number // 出库编号
+  no: string // 出库单号
+  customerId: number // 客户编号
+  outTime: Date // 出库时间
+  totalCount: number // 合计数量
+  totalPrice: number // 合计金额,单位:元
+  status: number // 状态
+  remark: string // 备注
+}
+
+// ERP 其它出库单 API
+export const StockOutApi = {
+  // 查询其它出库单分页
+  getStockOutPage: async (params: any) => {
+    return await request.get({ url: `/erp/stock-out/page`, params })
+  },
+
+  // 查询其它出库单详情
+  getStockOut: async (id: number) => {
+    return await request.get({ url: `/erp/stock-out/get?id=` + id })
+  },
+
+  // 新增其它出库单
+  createStockOut: async (data: StockOutVO) => {
+    return await request.post({ url: `/erp/stock-out/create`, data })
+  },
+
+  // 修改其它出库单
+  updateStockOut: async (data: StockOutVO) => {
+    return await request.put({ url: `/erp/stock-out/update`, data })
+  },
+
+  // 更新其它出库单的状态
+  updateStockOutStatus: async (id: number, status: number) => {
+    return await request.put({
+      url: `/erp/stock-out/update-status`,
+      params: {
+        id,
+        status
+      }
+    })
+  },
+
+  // 删除其它出库单
+  deleteStockOut: async (ids: number[]) => {
+    return await request.delete({
+      url: `/erp/stock-out/delete`,
+      params: {
+        ids: ids.join(',')
+      }
+    })
+  },
+
+  // 导出其它出库单 Excel
+  exportStockOut: async (params) => {
+    return await request.download({ url: `/erp/stock-out/export-excel`, params })
+  }
+}

+ 32 - 0
src/api/erp/stock/record/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 })
+  }
+}

+ 41 - 0
src/api/erp/stock/stock/index.ts

@@ -0,0 +1,41 @@
+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 })
+  },
+
+  // 查询产品库存详情
+  getStock2: async (productId: number, warehouseId: number) => {
+    return await request.get({ url: `/erp/stock/get`, params: { productId, warehouseId } })
+  },
+
+  // 获得产品库存数量
+  getStockCount: async (productId: number) => {
+    return await request.get({ url: `/erp/stock/get-count`, params: { productId } })
+  },
+
+  // 导出产品库存 Excel
+  exportStock: async (params) => {
+    return await request.download({ url: `/erp/stock/export-excel`, params })
+  }
+}

+ 64 - 0
src/api/erp/stock/warehouse/index.ts

@@ -0,0 +1,64 @@
+import request from '@/config/axios'
+
+// ERP 仓库 VO
+export interface WarehouseVO {
+  id: number // 仓库编号
+  name: string // 仓库名称
+  address: string // 仓库地址
+  sort: number // 排序
+  remark: string // 备注
+  principal: string // 负责人
+  warehousePrice: number // 仓储费,单位:元
+  truckagePrice: number // 搬运费,单位:元
+  status: number // 开启状态
+  defaultStatus: boolean // 是否默认
+}
+
+// ERP 仓库 API
+export const WarehouseApi = {
+  // 查询仓库分页
+  getWarehousePage: async (params: any) => {
+    return await request.get({ url: `/erp/warehouse/page`, params })
+  },
+
+  // 查询仓库精简列表
+  getWarehouseSimpleList: async () => {
+    return await request.get({ url: `/erp/warehouse/simple-list` })
+  },
+
+  // 查询仓库详情
+  getWarehouse: async (id: number) => {
+    return await request.get({ url: `/erp/warehouse/get?id=` + id })
+  },
+
+  // 新增仓库
+  createWarehouse: async (data: WarehouseVO) => {
+    return await request.post({ url: `/erp/warehouse/create`, data })
+  },
+
+  // 修改仓库
+  updateWarehouse: async (data: WarehouseVO) => {
+    return await request.put({ url: `/erp/warehouse/update`, data })
+  },
+
+  // 修改仓库默认状态
+  updateWarehouseDefaultStatus: async (id: number, defaultStatus: boolean) => {
+    return await request.put({
+      url: `/erp/warehouse/update-default-status`,
+      params: {
+        id,
+        defaultStatus
+      }
+    })
+  },
+
+  // 删除仓库
+  deleteWarehouse: async (id: number) => {
+    return await request.delete({ url: `/erp/warehouse/delete?id=` + id })
+  },
+
+  // 导出仓库 Excel
+  exportWarehouse: async (params) => {
+    return await request.download({ url: `/erp/warehouse/export-excel`, params })
+  }
+}

+ 0 - 0
src/api/infra/apiAccessLog/index.ts


Some files were not shown because too many files changed in this diff