diff --git a/.eslintrc.js b/.eslintrc.js index 70c91784..b28255ca 100644 --- a/.eslintrc.js +++ b/.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 【属性】顺序的提示,因为暂时不需要这么严格,警告也有点繁琐 } }) diff --git a/.image/common/bpm-feature.png b/.image/common/bpm-feature.png new file mode 100644 index 00000000..23787fb4 Binary files /dev/null and b/.image/common/bpm-feature.png differ diff --git a/.image/common/infra-feature.png b/.image/common/infra-feature.png new file mode 100644 index 00000000..f5cef50c Binary files /dev/null and b/.image/common/infra-feature.png differ diff --git a/.image/common/system-feature.png b/.image/common/system-feature.png new file mode 100644 index 00000000..366087ce Binary files /dev/null and b/.image/common/system-feature.png differ diff --git a/README.md b/README.md index f78b0cba..7bac2225 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,8 @@ | 🚀 | 应用管理 | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 | | 🚀 | 地区管理 | 展示省份、城市、区镇等城市信息,支持 IP 对应城市 | +![功能图](/.image/common/system-feature.png) + ### 工作流程 | | 功能 | 描述 | @@ -129,6 +131,8 @@ | 🚀 | 已办任务 | 查看自己【已】审批的工作任务,未来会支持回退操作 | | 🚀 | OA 请假 | 作为业务自定义接入工作流的使用示例,只需创建请求对应的工作流程,即可进行审批 | +![功能图](/.image/common/bpm-feature.png) + ### 支付系统 | | 功能 | 描述 | @@ -164,6 +168,8 @@ ps:核心功能已经实现,正在对接微信小程序中... | 🚀 | 日志服务 | 轻量级日志中心,查看远程服务器的日志 | | 🚀 | 单元测试 | 基于 JUnit + Mockito 实现单元测试,保证功能的正确性、代码的质量等 | +![功能图](/.image/common/infra-feature.png) + ### 数据报表 | | 功能 | 描述 | diff --git a/package.json b/package.json index bafdf048..58460358 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "2.0.0-snapshot", + "version": "2.0.1-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, @@ -30,12 +30,12 @@ "@form-create/element-ui": "^3.1.24", "@iconify/iconify": "^3.1.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.7", "benz-amr-recorder": "^1.1.5", "bpmn-js-token-simulation": "^0.10.0", "camunda-bpmn-moddle": "^7.0.1", @@ -44,9 +44,9 @@ "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.5.3", "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", "jsencrypt": "^3.3.2", @@ -55,77 +55,78 @@ "mitt": "^3.0.1", "nprogress": "^0.2.0", "pinia": "^2.1.7", + "pinia-plugin-persistedstate": "^3.2.0", "qrcode": "^1.5.3", "qs": "^6.11.2", "steady-xml": "^0.1.0", "url": "^0.11.3", "video.js": "^7.21.5", - "vue": "^3.3.8", + "vue": "3.4.20", "vue-dompurify-html": "^4.1.4", - "vue-i18n": "^9.6.5", - "vue-router": "^4.2.5", + "vue-i18n": "9.9.1", + "vue-router": "^4.3.0", "vue-types": "^5.1.1", "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", - "@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/transformer-variant-group": "^0.58.5", "@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", + "@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": "8.9.0", "bpmn-js-properties-panel": "0.46.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-purge-icons": "^0.10.0", "vite-plugin-svg-icons": "^2.0.1", "vite-plugin-top-level-await": "^1.3.1", "vue-eslint-parser": "^9.3.2", - "vue-tsc": "^1.8.22" + "vue-tsc": "^1.8.27" }, "license": "MIT", "repository": { diff --git a/src/api/bpm/category/index.ts b/src/api/bpm/category/index.ts new file mode 100644 index 00000000..d1e109cb --- /dev/null +++ b/src/api/bpm/category/index.ts @@ -0,0 +1,43 @@ +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 }) + }, + + // 删除流程分类 + deleteCategory: async (id: number) => { + return await request.delete({ url: `/bpm/category/delete?id=` + id }) + } +} diff --git a/src/api/bpm/definition/index.ts b/src/api/bpm/definition/index.ts index c0e51fab..cb6d4271 100644 --- a/src/api/bpm/definition/index.ts +++ b/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: number, key: string) => { return await request.get({ - url: '/bpm/process-definition/get-bpmn-xml?id=' + id + url: '/bpm/process-definition/get', + params: { id, key } }) } diff --git a/src/api/bpm/form/index.ts b/src/api/bpm/form/index.ts index 142ed24c..7fce11fc 100644 --- a/src/api/bpm/form/index.ts +++ b/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' }) } diff --git a/src/api/bpm/leave/index.ts b/src/api/bpm/leave/index.ts index d4fe8d58..4f374b2f 100644 --- a/src/api/bpm/leave/index.ts +++ b/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 diff --git a/src/api/bpm/processExpression/index.ts b/src/api/bpm/processExpression/index.ts new file mode 100644 index 00000000..af6a7372 --- /dev/null +++ b/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 }) + } +} \ No newline at end of file diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts index a937eae2..81640625 100644 --- a/src/api/bpm/processInstance/index.ts +++ b/src/api/bpm/processInstance/index.ts @@ -20,51 +20,49 @@ export type ProcessInstanceVO = { endTime: string } -export type ProcessInstanceCCVO = { - type: number, - taskName: string, - taskKey: string, - processInstanceName: string, - processInstanceKey: string, - startUserId: string, - options:string [], +export type ProcessInstanceCopyVO = { + type: number + taskName: string + taskKey: string + processInstanceName: string + processInstanceKey: string + startUserId: string + options: string[] reason: string } -export const getMyProcessInstancePage = async (params) => { +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 }) } -/** - * 抄送 - * @param data 抄送数据 - * @returns 是否抄送成功 - */ -export const createProcessInstanceCC = async (data) => { - return await request.post({ url: '/bpm/process-instance/cc/create', data: data }) +export const getProcessInstanceCopyPage = async (params: any) => { + return await request.get({ url: '/bpm/process-instance/copy/page', params }) } - -/** - * 抄送列表 - * @param params - * @returns - */ -export const getProcessInstanceCCPage = async (params) => { - return await request.get({ url: '/bpm/process-instance/cc/my-page', params }) -} \ No newline at end of file diff --git a/src/api/bpm/processListener/index.ts b/src/api/bpm/processListener/index.ts new file mode 100644 index 00000000..dabaa476 --- /dev/null +++ b/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 }) + } +} diff --git a/src/api/bpm/task/index.ts b/src/api/bpm/task/index.ts index df6d8160..f3cda9f7 100644 --- a/src/api/bpm/task/index.ts +++ b/src/api/bpm/task/index.ts @@ -4,78 +4,63 @@ export type TaskVO = { id: number } -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/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) => { +// 转派 +export const transferTask = async (data: any) => { + return await request.put({ url: '/bpm/task/transfer', data }) +} + +// 加签 +export const signCreateTask = async (data: any) => { return await request.put({ url: '/bpm/task/create-sign', data }) } -/** - * 获取减签任务列表 - */ -export const getChildrenTaskList = async (id: string) => { - return await request.get({ url: '/bpm/task/children-list?taskId=' + id }) -} - -/** - * 减签 - */ -export const taskSubSign = async (data) => { +// 减签 +export const signDeleteTask = async (data: any) => { return await request.delete({ url: '/bpm/task/delete-sign', data }) } + +// 获取减签任务列表 +export const getChildrenTaskList = async (id: string) => { + return await request.get({ url: '/bpm/task/list-by-parent-task-id?parentTaskId=' + id }) +} diff --git a/src/api/bpm/taskAssignRule/index.ts b/src/api/bpm/taskAssignRule/index.ts deleted file mode 100644 index 5fbe342d..00000000 --- a/src/api/bpm/taskAssignRule/index.ts +++ /dev/null @@ -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 - }) -} diff --git a/src/api/bpm/userGroup/index.ts b/src/api/bpm/userGroup/index.ts index 035762bf..7d12755e 100644 --- a/src/api/bpm/userGroup/index.ts +++ b/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 => { - return await request.get({ url: '/bpm/user-group/list-all-simple' }) +export const getUserGroupSimpleList = async (): Promise => { + return await request.get({ url: '/bpm/user-group/simple-list' }) } diff --git a/src/api/crm/statistics/customer.ts b/src/api/crm/statistics/customer.ts index 4358db77..ebb9dfb3 100644 --- a/src/api/crm/statistics/customer.ts +++ b/src/api/crm/statistics/customer.ts @@ -14,21 +14,21 @@ export interface CrmStatisticsCustomerSummaryByUserRespVO { receivablePrice: number } -export interface CrmStatisticsFollowupSummaryByDateRespVO { +export interface CrmStatisticsFollowUpSummaryByDateRespVO { time: string - followupRecordCount: number - followupCustomerCount: number + followUpRecordCount: number + followUpCustomerCount: number } -export interface CrmStatisticsFollowupSummaryByUserRespVO { +export interface CrmStatisticsFollowUpSummaryByUserRespVO { ownerUserName: string followupRecordCount: number followupCustomerCount: number } -export interface CrmStatisticsFollowupSummaryByTypeRespVO { - followupType: string - followupRecordCount: number +export interface CrmStatisticsFollowUpSummaryByTypeRespVO { + followUpType: string + followUpRecordCount: number } export interface CrmStatisticsCustomerContractSummaryRespVO { @@ -72,23 +72,23 @@ export const StatisticsCustomerApi = { }) }, // 2.1 客户跟进次数分析(按日期) - getFollowupSummaryByDate: (params: any) => { + getFollowUpSummaryByDate: (params: any) => { return request.get({ - url: '/crm/statistics-customer/get-followup-summary-by-date', + url: '/crm/statistics-customer/get-follow-up-summary-by-date', params }) }, // 2.2 客户跟进次数分析(按用户) - getFollowupSummaryByUser: (params: any) => { + getFollowUpSummaryByUser: (params: any) => { return request.get({ - url: '/crm/statistics-customer/get-followup-summary-by-user', + url: '/crm/statistics-customer/get-follow-up-summary-by-user', params }) }, // 3.1 获取客户跟进方式统计数 - getFollowupSummaryByType: (params: any) => { + getFollowUpSummaryByType: (params: any) => { return request.get({ - url: '/crm/statistics-customer/get-followup-summary-by-type', + url: '/crm/statistics-customer/get-follow-up-summary-by-type', params }) }, diff --git a/src/api/crm/statistics/performance.ts b/src/api/crm/statistics/performance.ts new file mode 100644 index 00000000..2318505e --- /dev/null +++ b/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 + }) + } +} diff --git a/src/api/crm/statistics/portrait.ts b/src/api/crm/statistics/portrait.ts new file mode 100644 index 00000000..c7a25725 --- /dev/null +++ b/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 + }) + } +} diff --git a/src/api/infra/apiAccessLog/index.ts b/src/api/infra/apiAccessLog/index.ts index c6b4b45f..4fa50e17 100644 --- a/src/api/infra/apiAccessLog/index.ts +++ b/src/api/infra/apiAccessLog/index.ts @@ -8,11 +8,15 @@ export interface ApiAccessLogVO { applicationName: string requestMethod: string requestParams: string + responseBody: string requestUrl: string userIp: string userAgent: string + operateModule: string + operateName: string + operateType: number beginTime: Date - endTIme: Date + endTime: Date duration: number resultCode: number resultMsg: string diff --git a/src/api/mall/statistics/member.ts b/src/api/mall/statistics/member.ts index 92af031e..d9accf92 100644 --- a/src/api/mall/statistics/member.ts +++ b/src/api/mall/statistics/member.ts @@ -5,7 +5,7 @@ import { formatDate } from '@/utils/formatTime' /** 会员分析 Request VO */ export interface MemberAnalyseReqVO { - times: [dayjs.ConfigType, dayjs.ConfigType] + times: dayjs.ConfigType[] } /** 会员分析 Response VO */ diff --git a/src/api/report/ureport/index.ts b/src/api/report/ureport/index.ts deleted file mode 100644 index 2a9daea4..00000000 --- a/src/api/report/ureport/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -import request from '@/config/axios' - -export interface UReportDataVO { - id: number - name: string - status: number - content: string - remark: string -} - -// 查询Ureport2报表分页 -export const getUReportDataPage = async (params) => { - return await request.get({ url: `/report/ureport-data/page`, params }) -} - -// 查询Ureport2报表详情 -export const getUReportData = async (id: number) => { - return await request.get({ url: `/report/ureport-data/get?id=` + id }) -} - -// 新增Ureport2报表 -export const createUReportData = async (data: UReportDataVO) => { - return await request.post({ url: `/report/ureport-data/create`, data }) -} - -// 修改Ureport2报表 -export const updateUReportData = async (data: UReportDataVO) => { - return await request.put({ url: `/report/ureport-data/update`, data }) -} - -// 删除Ureport2报表 -export const deleteUReportData = async (id: number) => { - return await request.delete({ url: `/report/ureport-data/delete?id=` + id }) -} - -// 导出Ureport2报表 Excel -export const exportUReportData = async (params) => { - return await request.download({ url: `/report/ureport-data/export-excel`, params }) -} diff --git a/src/api/system/operatelog/index.ts b/src/api/system/operatelog/index.ts index e5d3d364..cdb713ea 100644 --- a/src/api/system/operatelog/index.ts +++ b/src/api/system/operatelog/index.ts @@ -2,30 +2,6 @@ import request from '@/config/axios' export type OperateLogVO = { id: number - userNickname: string - traceId: string - userId: number - module: string - name: string - type: number - content: string - exts: Map - requestMethod: string - requestUrl: string - userIp: string - userAgent: string - javaMethod: string - javaMethodArgs: string - startTime: Date - duration: number - resultCode: number - resultMsg: string - resultData: string -} - -export type OperateLogV2VO = { - id: number - userNickname: string traceId: string userType: number userId: number @@ -42,11 +18,6 @@ export type OperateLogV2VO = { creator: string creatorName: string createTime: Date - // 数据扩展,渲染时使用 - title: string // 操作标题(如果为空则取 name 值) - colSize: number // 变更记录行数 - contentStrList: string[] - tagsContentList: string[] } // 查询操作日志列表 @@ -54,6 +25,6 @@ export const getOperateLogPage = (params: PageParam) => { return request.get({ url: '/system/operate-log/page', params }) } // 导出操作日志 -export const exportOperateLog = (params) => { +export const exportOperateLog = (params: any) => { return request.download({ url: '/system/operate-log/export', params }) } diff --git a/src/assets/imgs/avatar.jpg b/src/assets/imgs/avatar.jpg new file mode 100644 index 00000000..d46a70a4 Binary files /dev/null and b/src/assets/imgs/avatar.jpg differ diff --git a/src/components/ContentWrap/src/ContentWrap.vue b/src/components/ContentWrap/src/ContentWrap.vue index e3bd5972..454e95c9 100644 --- a/src/components/ContentWrap/src/ContentWrap.vue +++ b/src/components/ContentWrap/src/ContentWrap.vue @@ -25,6 +25,9 @@ defineProps({ +
+ +
diff --git a/src/components/Crontab/src/Crontab.vue b/src/components/Crontab/src/Crontab.vue index 90b40b2f..e61fef89 100644 --- a/src/components/Crontab/src/Crontab.vue +++ b/src/components/Crontab/src/Crontab.vue @@ -503,9 +503,13 @@ const submit = () => { emit('update:modelValue', defaultValue.value) dialogVisible.value = false } + +const inputChange = () => { + emit('update:modelValue', defaultValue.value) +} diff --git a/src/views/system/operatelog/OperateLogDetail.vue b/src/views/system/operatelog/OperateLogDetail.vue index 3aa565d7..150edc85 100644 --- a/src/views/system/operatelog/OperateLogDetail.vue +++ b/src/views/system/operatelog/OperateLogDetail.vue @@ -4,14 +4,14 @@ {{ detailData.id }} - + {{ detailData.traceId }} {{ detailData.userId }} - {{ detailData.userNickname }} + {{ detailData.userName }} {{ detailData.userIp }} @@ -20,39 +20,25 @@ {{ detailData.userAgent }} - {{ detailData.module }} + {{ detailData.type }} - {{ detailData.name }} + {{ detailData.subType }} - - {{ detailData.content }} + + {{ detailData.action }} - - {{ detailData.exts }} + + {{ detailData.extra }} {{ detailData.requestMethod }} {{ detailData.requestUrl }} - - {{ detailData.javaMethod }} - - - {{ detailData.javaMethodArgs }} - - {{ formatDate(detailData.startTime) }} + {{ formatDate(detailData.createTime) }} - {{ detailData.duration }} ms - -
正常
-
失败({{ detailData.resultCode }})
-
- - {{ detailData.resultData }} - - - {{ detailData.resultMsg }} + + {{ detailData.bizId }} diff --git a/src/views/system/operatelog/index.vue b/src/views/system/operatelog/index.vue index 5af8c4e2..0e81b818 100644 --- a/src/views/system/operatelog/index.vue +++ b/src/views/system/operatelog/index.vue @@ -10,58 +10,65 @@ :inline="true" label-width="68px" > - - - - - - - + - - + - - - + /> - + + + + + + + + + + @@ -84,33 +91,21 @@ - - - - - - - - - - + + + + + - - - - + + + diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue index 44663263..8532cf20 100644 --- a/src/views/system/post/index.vue +++ b/src/views/system/post/index.vue @@ -41,7 +41,7 @@ type="primary" plain @click="openForm('create')" - v-hasPermi="['system:notice:create']" + v-hasPermi="['system:post:create']" > 新增 @@ -50,7 +50,7 @@ plain @click="handleExport" :loading="exportLoading" - v-hasPermi="['infra:config:export']" + v-hasPermi="['infra:post:export']" > 导出 diff --git a/src/views/system/role/RoleDataPermissionForm.vue b/src/views/system/role/RoleDataPermissionForm.vue index 32745e95..c00e3972 100644 --- a/src/views/system/role/RoleDataPermissionForm.vue +++ b/src/views/system/role/RoleDataPermissionForm.vue @@ -103,6 +103,10 @@ const open = async (row: RoleApi.RoleVO) => { formData.code = row.code formData.dataScope = row.dataScope await nextTick() + row.dataScopeDeptIds?.forEach((deptId: number): void => { + + await nextTick() + // 需要在 DOM 渲染完成后,再设置选中状态 row.dataScopeDeptIds?.forEach((deptId: number): void => { treeRef.value.setChecked(deptId, true, false) }) diff --git a/src/views/system/role/RoleForm.vue b/src/views/system/role/RoleForm.vue index 01f29b8b..161b7571 100644 --- a/src/views/system/role/RoleForm.vue +++ b/src/views/system/role/RoleForm.vue @@ -59,11 +59,11 @@ const formData = ref({ remark: '' }) const formRules = reactive({ - name: [{ required: true, message: '岗位标题不能为空', trigger: 'blur' }], - code: [{ required: true, message: '岗位编码不能为空', trigger: 'change' }], - sort: [{ required: true, message: '岗位顺序不能为空', trigger: 'change' }], - status: [{ required: true, message: '岗位状态不能为空', trigger: 'change' }], - remark: [{ required: false, message: '岗位内容不能为空', trigger: 'blur' }] + name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }], + code: [{ required: true, message: '角色标识不能为空', trigger: 'change' }], + sort: [{ required: true, message: '显示顺序不能为空', trigger: 'change' }], + status: [{ required: true, message: '状态不能为空', trigger: 'change' }], + remark: [{ required: false, message: '备注不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref diff --git a/src/views/system/user/components/UserSelect.vue b/src/views/system/user/components/UserSelect.vue new file mode 100644 index 00000000..4a94a745 --- /dev/null +++ b/src/views/system/user/components/UserSelect.vue @@ -0,0 +1,28 @@ + + + + diff --git a/types/global.d.ts b/types/global.d.ts index 5e292687..e91e1fe4 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -14,6 +14,9 @@ declare global { type LocaleType = 'zh-CN' | 'en' + declare type TimeoutHandle = ReturnType + declare type IntervalHandle = ReturnType + type AxiosHeaders = | 'application/json' | 'application/x-www-form-urlencoded' diff --git a/vite.config.ts b/vite.config.ts index fe2d7131..8cba9150 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,10 +25,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { root: root, // 服务端渲染 server: { - // 是否开启 https - https: false, - // 端口号 - port: env.VITE_PORT, + port: env.VITE_PORT, // 端口号 host: "0.0.0.0", open: env.VITE_OPEN === 'true', // 本地跨域代理. 目前注释的原因:暂时没有用途,server 端已经支持跨域