diff --git a/README.md b/README.md index d4ddd4f2..f5619e8b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ * nodejs > 16.0.0 && pnpm > 7.30.0 * 演示地址【Vue3 + element-plus】:<http://dashboard-vue3.yudao.iocoder.cn> +* 演示地址【Vue3 + vben(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/> @@ -19,8 +20,8 @@ **芋道**,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。 -* 采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) -* 改换saas,自动引入等功能 [vue-element-plus-admin](https://gitee.com/yudaocode/vue-element-plus-admin) +* 采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) 实现 +* 改换 saas,自动引入等功能 * 使用 Element Plus 免费开源的中后台模版,具备如下特性:  @@ -38,11 +39,11 @@ | 框架 | 说明 | 版本 | |----------------------------------------------------------------------|------------------|--------| | [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.47 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.1.4 | -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.34 | -| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 4.9.5 | -| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.33 | -| [vueuse](https://vueuse.org/) | 常用工具集 | 9.13.0 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.1 | +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.3 | +| [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.4 | +| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.35 | +| [vueuse](https://vueuse.org/) | 常用工具集 | 10.1.0 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | | [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.1.6 | | [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | diff --git a/build/vite/optimize.ts b/build/vite/optimize.ts index 1a7a1b2f..9d576191 100644 --- a/build/vite/optimize.ts +++ b/build/vite/optimize.ts @@ -17,7 +17,6 @@ const include = [ 'cropperjs', 'lodash-es', 'nprogress', - 'animate.css', 'web-storage-cache', '@iconify/iconify', '@vueuse/core', @@ -33,38 +32,58 @@ const include = [ 'element-plus/es', 'element-plus/es/locale/lang/zh-cn', 'element-plus/es/locale/lang/en', - 'element-plus/es/components/backtop/style/index', - 'element-plus/es/components/form/style/index', - 'element-plus/es/components/radio-group/style/index', - 'element-plus/es/components/radio/style/index', - 'element-plus/es/components/checkbox/style/index', - 'element-plus/es/components/checkbox-group/style/index', - 'element-plus/es/components/switch/style/index', - 'element-plus/es/components/time-picker/style/index', - 'element-plus/es/components/date-picker/style/index', - 'element-plus/es/components/col/style/index', - 'element-plus/es/components/form-item/style/index', - 'element-plus/es/components/alert/style/index', - 'element-plus/es/components/breadcrumb/style/index', - 'element-plus/es/components/select/style/index', - 'element-plus/es/components/input/style/index', - 'element-plus/es/components/breadcrumb-item/style/index', - 'element-plus/es/components/tag/style/index', - 'element-plus/es/components/pagination/style/index', - 'element-plus/es/components/table/style/index', - 'element-plus/es/components/table-column/style/index', - 'element-plus/es/components/card/style/index', - 'element-plus/es/components/row/style/index', - 'element-plus/es/components/button/style/index', - 'element-plus/es/components/menu/style/index', - 'element-plus/es/components/sub-menu/style/index', - 'element-plus/es/components/menu-item/style/index', - 'element-plus/es/components/option/style/index', - 'element-plus/es/components/dropdown/style/index', - 'element-plus/es/components/dropdown-menu/style/index', - 'element-plus/es/components/dropdown-item/style/index', - 'element-plus/es/components/skeleton/style/index', - + 'element-plus/es/components/backtop/style/css', + 'element-plus/es/components/form/style/css', + 'element-plus/es/components/radio-group/style/css', + 'element-plus/es/components/radio/style/css', + 'element-plus/es/components/checkbox/style/css', + 'element-plus/es/components/checkbox-group/style/css', + 'element-plus/es/components/switch/style/css', + 'element-plus/es/components/time-picker/style/css', + 'element-plus/es/components/date-picker/style/css', + 'element-plus/es/components/descriptions/style/css', + 'element-plus/es/components/descriptions-item/style/css', + 'element-plus/es/components/link/style/css', + 'element-plus/es/components/tooltip/style/css', + 'element-plus/es/components/drawer/style/css', + 'element-plus/es/components/dialog/style/css', + 'element-plus/es/components/checkbox-button/style/css', + 'element-plus/es/components/option-group/style/css', + 'element-plus/es/components/radio-button/style/css', + 'element-plus/es/components/cascader/style/css', + 'element-plus/es/components/color-picker/style/css', + 'element-plus/es/components/input-number/style/css', + 'element-plus/es/components/rate/style/css', + 'element-plus/es/components/select-v2/style/css', + 'element-plus/es/components/tree-select/style/css', + 'element-plus/es/components/slider/style/css', + 'element-plus/es/components/time-select/style/css', + 'element-plus/es/components/autocomplete/style/css', + 'element-plus/es/components/image-viewer/style/css', + 'element-plus/es/components/upload/style/css', + 'element-plus/es/components/col/style/css', + 'element-plus/es/components/form-item/style/css', + 'element-plus/es/components/alert/style/css', + 'element-plus/es/components/breadcrumb/style/css', + 'element-plus/es/components/select/style/css', + 'element-plus/es/components/input/style/css', + 'element-plus/es/components/breadcrumb-item/style/css', + 'element-plus/es/components/tag/style/css', + 'element-plus/es/components/pagination/style/css', + 'element-plus/es/components/table/style/css', + 'element-plus/es/components/table-v2/style/css', + 'element-plus/es/components/table-column/style/css', + 'element-plus/es/components/card/style/css', + 'element-plus/es/components/row/style/css', + 'element-plus/es/components/button/style/css', + 'element-plus/es/components/menu/style/css', + 'element-plus/es/components/sub-menu/style/css', + 'element-plus/es/components/menu-item/style/css', + 'element-plus/es/components/option/style/css', + 'element-plus/es/components/dropdown/style/css', + 'element-plus/es/components/dropdown-menu/style/css', + 'element-plus/es/components/dropdown-item/style/css', + 'element-plus/es/components/skeleton/style/css', 'element-plus/es/components/skeleton/style/css', 'element-plus/es/components/backtop/style/css', 'element-plus/es/components/menu/style/css', @@ -78,20 +97,12 @@ const include = [ 'element-plus/es/components/breadcrumb/style/css', 'element-plus/es/components/breadcrumb-item/style/css', 'element-plus/es/components/image/style/css', - 'element-plus/es/components/tag/style/css', - 'element-plus/es/components/dialog/style/css', - 'element-plus/es/components/form/style/css', - 'element-plus/es/components/form-item/style/css', - 'element-plus/es/components/card/style/css', - 'element-plus/es/components/tooltip/style/css', - 'element-plus/es/components/radio-group/style/css', - 'element-plus/es/components/radio/style/css', - 'element-plus/es/components/input-number/style/css', - 'element-plus/es/components/tree-select/style/css', - 'element-plus/es/components/drawer/style/css', - 'element-plus/es/components/image-viewer/style/css', - 'element-plus/es/components/upload/style/css', - 'element-plus/es/components/switch/style/css' + 'element-plus/es/components/collapse-transition/style/css', + 'element-plus/es/components/timeline/style/css', + 'element-plus/es/components/timeline-item/style/css', + 'element-plus/es/components/collapse/style/css', + 'element-plus/es/components/collapse-item/style/css', + 'element-plus/es/components/button-group/style/css' ] const exclude = ['@iconify/json'] diff --git a/package.json b/package.json index 1a836c5a..7a00c122 100644 --- a/package.json +++ b/package.json @@ -33,12 +33,12 @@ "@form-create/element-ui": "^3.1.17", "@iconify/iconify": "^3.1.0", "@videojs-player/vue": "^1.0.0", - "@vueuse/core": "^9.13.0", + "@vueuse/core": "^10.1.0", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", "@zxcvbn-ts/core": "^2.2.1", "animate.css": "^4.1.1", - "axios": "^1.3.5", + "axios": "^1.3.6", "benz-amr-recorder": "^1.1.5", "bpmn-js-token-simulation": "^0.10.0", "camunda-bpmn-moddle": "^7.0.1", @@ -46,19 +46,19 @@ "crypto-js": "^4.1.1", "dayjs": "^1.11.7", "diagram-js": "^11.6.0", - "echarts": "^5.4.1", + "echarts": "^5.4.2", "echarts-wordcloud": "^2.1.0", "element-plus": "2.3.3", - "fast-xml-parser": "^4.1.3", + "fast-xml-parser": "^4.2.2", "highlight.js": "^11.7.0", "intro.js": "^7.0.1", "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", - "min-dash": "^4.0.0", + "min-dash": "^4.1.0", "mitt": "^3.0.0", "nprogress": "^0.2.0", - "pinia": "^2.0.34", - "qrcode": "^1.5.1", + "pinia": "^2.0.35", + "qrcode": "^1.5.3", "qs": "^6.11.1", "steady-xml": "^0.1.0", "url": "^0.11.0", @@ -73,61 +73,60 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "@commitlint/cli": "^17.5.0", - "@commitlint/config-conventional": "^17.4.4", - "@iconify/json": "^2.2.38", + "@commitlint/cli": "^17.6.1", + "@commitlint/config-conventional": "^17.6.1", + "@iconify/json": "^2.2.54", "@intlify/unplugin-vue-i18n": "^0.10.0", "@purge-icons/generated": "^0.9.0", "@types/intro.js": "^5.1.1", "@types/lodash-es": "^4.17.7", - "@types/node": "^18.15.5", + "@types/node": "^18.16.0", "@types/nprogress": "^0.2.0", "@types/qrcode": "^1.5.0", "@types/qs": "^6.9.7", - "@typescript-eslint/eslint-plugin": "^5.56.0", - "@typescript-eslint/parser": "^5.56.0", + "@typescript-eslint/eslint-plugin": "^5.59.0", + "@typescript-eslint/parser": "^5.59.0", "@vitejs/plugin-legacy": "^4.0.2", "@vitejs/plugin-vue": "^4.1.0", "@vitejs/plugin-vue-jsx": "^3.0.1", "autoprefixer": "^10.4.14", "bpmn-js": "^8.9.0", "bpmn-js-properties-panel": "^0.46.0", - "consola": "^2.15.3", - "eslint": "^8.36.0", + "consola": "^3.1.0", + "eslint": "^8.39.0", "eslint-config-prettier": "^8.8.0", - "eslint-define-config": "^1.17.0", + "eslint-define-config": "^1.18.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-vue": "^9.9.0", - "lint-staged": "^13.2.0", - "postcss": "^8.4.21", + "eslint-plugin-vue": "^9.11.0", + "lint-staged": "^13.2.1", + "postcss": "^8.4.23", "postcss-html": "^1.5.0", "postcss-scss": "^4.0.6", - "prettier": "^2.8.6", - "rimraf": "^4.4.1", - "rollup": "^3.20.0", - "sass": "^1.59.3", - "stylelint": "^15.3.0", + "prettier": "^2.8.8", + "rimraf": "^5.0.0", + "rollup": "^3.20.7", + "sass": "^1.62.0", + "stylelint": "^15.6.0", "stylelint-config-html": "^1.1.0", - "stylelint-config-prettier": "^9.0.5", - "stylelint-config-recommended": "^11.0.0", - "stylelint-config-standard": "^31.0.0", + "stylelint-config-recommended": "^12.0.0", + "stylelint-config-standard": "^33.0.0", "stylelint-order": "^6.0.3", - "terser": "^5.16.6", - "typescript": "5.0.2", - "unplugin-auto-import": "^0.15.1", - "unplugin-element-plus": "^0.7.0", + "terser": "^5.17.1", + "typescript": "5.0.4", + "unplugin-auto-import": "^0.15.3", + "unplugin-element-plus": "^0.7.1", "unplugin-vue-components": "^0.24.1", - "vite": "4.2.1", + "vite": "4.3.1", "vite-plugin-compression": "^0.5.1", "vite-plugin-ejs": "^1.6.4", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-progress": "^0.0.6", + "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.0", "vite-plugin-vue-setup-extend-plus": "^0.1.0", "vite-plugin-windicss": "^1.8.10", - "vue-tsc": "^1.2.0", + "vue-tsc": "^1.4.4", "windicss": "^3.5.6" }, "engines": { diff --git a/src/api/mall/trade/delivery/express/index.ts b/src/api/mall/trade/delivery/express/index.ts new file mode 100644 index 00000000..95429a40 --- /dev/null +++ b/src/api/mall/trade/delivery/express/index.ts @@ -0,0 +1,40 @@ +import request from '@/config/axios' + +export interface DeliveryExpressVO { + id: number + code: string + name: string + logo: string + sort: number + status: number +} + +// 查询快递公司列表 +export const getDeliveryExpressPage = async (params: PageParam) => { + return await request.get({ url: '/trade/delivery/express/page', params }) +} + +// 查询快递公司详情 +export const getDeliveryExpress = async (id: number) => { + return await request.get({ url: '/trade/delivery/express/get?id=' + id }) +} + +// 新增快递公司 +export const createDeliveryExpress = async (data: DeliveryExpressVO) => { + return await request.post({ url: '/trade/delivery/express/create', data }) +} + +// 修改快递公司 +export const updateDeliveryExpress = async (data: DeliveryExpressVO) => { + return await request.put({ url: '/trade/delivery/express/update', data }) +} + +// 删除快递公司 +export const deleteDeliveryExpress = async (id: number) => { + return await request.delete({ url: '/trade/delivery/express/delete?id=' + id }) +} + +// 导出快递公司 Excel +export const exportDeliveryExpressApi = async (params) => { + return await request.download({ url: '/trade/delivery/express/export-excel', params }) +} diff --git a/src/api/system/notify/template/index.ts b/src/api/system/notify/template/index.ts index 50196e85..cd0e1223 100644 --- a/src/api/system/notify/template/index.ts +++ b/src/api/system/notify/template/index.ts @@ -39,7 +39,7 @@ export const updateNotifyTemplate = async (data: NotifyTemplateVO) => { } // 删除站内信模板 -export const deleteNotifyTemplateApi = async (id: number) => { +export const deleteNotifyTemplate = async (id: number) => { return await request.delete({ url: '/system/notify-template/delete?id=' + id }) } diff --git a/src/api/system/oauth2/token.ts b/src/api/system/oauth2/token.ts index 8e9dca1e..ac89ae89 100644 --- a/src/api/system/oauth2/token.ts +++ b/src/api/system/oauth2/token.ts @@ -17,6 +17,6 @@ export const getAccessTokenPage = (params: PageParam) => { } // 删除 token -export const deleteAccessToken = (accessToken: number) => { +export const deleteAccessToken = (accessToken: string) => { return request.delete({ url: '/system/oauth2-token/delete?accessToken=' + accessToken }) } diff --git a/src/views/bpm/definition/index.vue b/src/views/bpm/definition/index.vue index c18e9a92..2580b1cd 100644 --- a/src/views/bpm/definition/index.vue +++ b/src/views/bpm/definition/index.vue @@ -87,7 +87,7 @@ <MyProcessViewer key="designer" v-model="bpmnXML" - :value="bpmnXML" + :value="bpmnXML as any" v-bind="bpmnControlForm" :prefix="bpmnControlForm.prefix" /> diff --git a/src/views/bpm/group/UserGroupForm.vue b/src/views/bpm/group/UserGroupForm.vue index 5a3ca804..f5ea479c 100644 --- a/src/views/bpm/group/UserGroupForm.vue +++ b/src/views/bpm/group/UserGroupForm.vue @@ -68,7 +68,7 @@ const formRules = reactive({ status: [{ required: true, message: '状态不能为空', trigger: 'blur' }] }) const formRef = ref() // 表单 Ref -const userList = ref([]) // 用户列表 +const userList = ref<any[]>([]) // 用户列表 /** 打开弹窗 */ const open = async (type: string, id?: number) => { diff --git a/src/views/bpm/group/index.vue b/src/views/bpm/group/index.vue index f2427f71..f1d6b271 100644 --- a/src/views/bpm/group/index.vue +++ b/src/views/bpm/group/index.vue @@ -117,6 +117,7 @@ import { dateFormatter } from '@/utils/formatTime' import * as UserGroupApi from '@/api/bpm/userGroup' import * as UserApi from '@/api/system/user' import UserGroupForm from './UserGroupForm.vue' +import { UserVO } from '@/api/system/user' const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 @@ -131,7 +132,7 @@ const queryParams = reactive({ createTime: [] }) const queryFormRef = ref() // 搜索的表单 -const userList = ref([]) // 用户列表 +const userList = ref<UserVO[]>([]) // 用户列表 /** 查询列表 */ const getList = async () => { diff --git a/src/views/bpm/model/editor/index.vue b/src/views/bpm/model/editor/index.vue index 24908ae5..dd135e72 100644 --- a/src/views/bpm/model/editor/index.vue +++ b/src/views/bpm/model/editor/index.vue @@ -16,7 +16,7 @@ <!-- 流程属性器,负责编辑每个流程节点的属性 --> <MyProcessPenal key="penal" - :bpmnModeler="modeler" + :bpmnModeler="modeler as any" :prefix="controlForm.prefix" class="process-panel" :model="model" diff --git a/src/views/bpm/model/index.vue b/src/views/bpm/model/index.vue index f8f5aa2a..d8e3cca3 100644 --- a/src/views/bpm/model/index.vue +++ b/src/views/bpm/model/index.vue @@ -219,7 +219,7 @@ <MyProcessViewer key="designer" v-model="bpmnXML" - :value="bpmnXML" + :value="bpmnXML as any" v-bind="bpmnControlForm" :prefix="bpmnControlForm.prefix" /> diff --git a/src/views/bpm/oa/leave/detail.vue b/src/views/bpm/oa/leave/detail.vue index a1b646a1..67ca7d7f 100644 --- a/src/views/bpm/oa/leave/detail.vue +++ b/src/views/bpm/oa/leave/detail.vue @@ -28,7 +28,7 @@ const props = defineProps({ id: propTypes.number.def(undefined) }) const detailLoading = ref(false) // 表单的加载中 -const detailData = ref({}) // 详情数据 +const detailData = ref<any>({}) // 详情数据 const queryId = query.id as unknown as number // 从 URL 传递过来的 id 编号 /** 获得数据 */ diff --git a/src/views/bpm/processInstance/create/index.vue b/src/views/bpm/processInstance/create/index.vue index 11cf929b..802b1a72 100644 --- a/src/views/bpm/processInstance/create/index.vue +++ b/src/views/bpm/processInstance/create/index.vue @@ -43,7 +43,7 @@ </el-col> </el-card> <!-- 流程图预览 --> - <ProcessInstanceBpmnViewer :bpmn-xml="bpmnXML" /> + <ProcessInstanceBpmnViewer :bpmn-xml="bpmnXML as any" /> </ContentWrap> </template> <script setup lang="ts" name="BpmProcessInstanceCreate"> diff --git a/src/views/infra/build/index.vue b/src/views/infra/build/index.vue index 9d420df9..c26c2e6c 100644 --- a/src/views/infra/build/index.vue +++ b/src/views/infra/build/index.vue @@ -33,6 +33,12 @@ import FcDesigner from '@form-create/designer' import { useClipboard } from '@vueuse/core' import { isString } from '@/utils/is' + +import hljs from 'highlight.js' // 导入代码高亮文件 +import 'highlight.js/styles/github.css' // 导入代码高亮样式 +import xml from 'highlight.js/lib/languages/java' +import json from 'highlight.js/lib/languages/json' + const { t } = useI18n() // 国际化 const message = useMessage() // 消息 @@ -112,10 +118,6 @@ const copy = async (text: string) => { /** * 代码高亮 */ -import hljs from 'highlight.js' // 导入代码高亮文件 -import 'highlight.js/styles/github.css' // 导入代码高亮样式 -import xml from 'highlight.js/lib/languages/java' -import json from 'highlight.js/lib/languages/json' const highlightedCode = (code) => { // 处理语言和代码 let language = 'json' diff --git a/src/views/infra/codegen/PreviewCode.vue b/src/views/infra/codegen/PreviewCode.vue index 12327b99..e27d790a 100644 --- a/src/views/infra/codegen/PreviewCode.vue +++ b/src/views/infra/codegen/PreviewCode.vue @@ -59,6 +59,14 @@ import { useClipboard } from '@vueuse/core' import { handleTree2 } from '@/utils/tree' import * as CodegenApi from '@/api/infra/codegen' +import hljs from 'highlight.js' // 导入代码高亮文件 +import 'highlight.js/styles/github.css' // 导入代码高亮样式 +import java from 'highlight.js/lib/languages/java' +import xml from 'highlight.js/lib/languages/java' +import javascript from 'highlight.js/lib/languages/javascript' +import sql from 'highlight.js/lib/languages/sql' +import typescript from 'highlight.js/lib/languages/typescript' + const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 @@ -184,13 +192,6 @@ const copy = async (text: string) => { /** * 代码高亮 */ -import hljs from 'highlight.js' // 导入代码高亮文件 -import 'highlight.js/styles/github.css' // 导入代码高亮样式 -import java from 'highlight.js/lib/languages/java' -import xml from 'highlight.js/lib/languages/java' -import javascript from 'highlight.js/lib/languages/javascript' -import sql from 'highlight.js/lib/languages/sql' -import typescript from 'highlight.js/lib/languages/typescript' const highlightedCode = (item) => { const language = item.filePath.substring(item.filePath.lastIndexOf('.') + 1) const result = hljs.highlight(language, item.code || '', true) diff --git a/src/views/infra/redis/index.vue b/src/views/infra/redis/index.vue index 8315a207..011f8e59 100644 --- a/src/views/infra/redis/index.vue +++ b/src/views/infra/redis/index.vue @@ -1,7 +1,6 @@ <template> <doc-alert title="Redis 缓存" url="https://doc.iocoder.cn/redis-cache/" /> <doc-alert title="本地缓存" url="https://doc.iocoder.cn/local-cache/" /> - <el-scrollbar height="calc(100vh - 88px - 40px - 50px)"> <el-row> <!-- 基本信息 --> @@ -51,127 +50,224 @@ <!-- 命令统计 --> <el-col :span="12" class="mt-3"> <el-card :gutter="12" shadow="hover"> - <div ref="commandStatsRef" class="h-88"></div> + <Echart :options="commandStatsRefChika" :height="420" /> </el-card> </el-col> <!-- 内存使用量统计 --> <el-col :span="12" class="mt-3"> <el-card class="ml-3" :gutter="12" shadow="hover"> - <div ref="usedmemory" class="h-88"></div> + <Echart :options="usedmemoryEchartChika" :height="420" /> </el-card> </el-col> </el-row> </el-scrollbar> </template> -<script setup lang="ts" name="InfraRedis"> -import * as echarts from 'echarts' +<script setup lang="ts"> +import echarts from '@/plugins/echarts' +import { GaugeChart } from 'echarts/charts' +import { ToolboxComponent } from 'echarts/components' import * as RedisApi from '@/api/infra/redis' import { RedisMonitorInfoVO } from '@/api/infra/redis/types' - const cache = ref<RedisMonitorInfoVO>() // 基本信息 const readRedisInfo = async () => { const data = await RedisApi.getCache() cache.value = data - loadEchartOptions(data.commandStats) } -// 图表 -const commandStatsRef = ref<HTMLElement>() -const usedmemory = ref<HTMLDivElement>() -const loadEchartOptions = (stats) => { - const commandStats = [] as any[] - const nameList = [] as string[] - stats.forEach((row) => { - commandStats.push({ - name: row.command, - value: row.calls - }) - nameList.push(row.command) - }) - - const commandStatsInstance = echarts.init(commandStatsRef.value!, 'macarons') - - commandStatsInstance.setOption({ - title: { - text: '命令统计', - left: 'center' - }, - tooltip: { - trigger: 'item', - formatter: '{a} <br/>{b} : {c} ({d}%)' - }, - legend: { - type: 'scroll', - orient: 'vertical', - right: 30, - top: 10, - bottom: 20, - data: nameList, - textStyle: { - color: '#a1a1a1' +// 内存使用情况 +const usedmemoryEchartChika = reactive({ + title: { + // 仪表盘标题。 + text: '内存使用情况', + left: 'center', + show: true, // 是否显示标题,默认 true。 + offsetCenter: [0, '20%'], //相对于仪表盘中心的偏移位置,数组第一项是水平方向的偏移,第二项是垂直方向的偏移。可以是绝对的数值,也可以是相对于仪表盘半径的百分比。 + color: 'yellow', // 文字的颜色,默认 #333。 + fontSize: 20 // 文字的字体大小,默认 15。 + }, + toolbox: { + show: false, + feature: { + restore: { show: true }, + saveAsImage: { show: true } + } + }, + series: [ + { + name: '峰值', + type: 'gauge', + min: 0, + max: 50, + splitNumber: 10, + //这是指针的颜色 + color: '#F5C74E', + radius: '85%', + center: ['50%', '50%'], + startAngle: 225, + endAngle: -45, + axisLine: { + // 坐标轴线 + lineStyle: { + // 属性lineStyle控制线条样式 + color: [ + [0.2, '#7FFF00'], + [0.8, '#00FFFF'], + [1, '#FF0000'] + ], + //width: 6 外框的大小(环的宽度) + width: 10 + } + }, + axisTick: { + // 坐标轴小标记 + //里面的线长是5(短线) + length: 5, // 属性length控制线长 + lineStyle: { + // 属性lineStyle控制线条样式 + color: '#76D9D7' + } + }, + splitLine: { + // 分隔线 + length: 20, // 属性length控制线长 + lineStyle: { + // 属性lineStyle(详见lineStyle)控制线条样式 + color: '#76D9D7' + } + }, + axisLabel: { + color: '#76D9D7', + distance: 15, + fontSize: 15 + }, + pointer: { + // 指针的大小 + width: 7, + show: true + }, + detail: { + textStyle: { + fontWeight: 'normal', + // 里面文字下的数值大小(50) + fontSize: 15, + color: '#FFFFFF' + }, + valueAnimation: true + }, + progress: { + show: true } - }, - series: [ - { - name: '命令', - type: 'pie', - radius: [20, 120], - center: ['40%', '60%'], - data: commandStats, - roseType: 'radius', + } + ] +}) + +// 指令使用情况 +const commandStatsRefChika = reactive({ + title: { + text: '命令统计', + left: 'center' + }, + tooltip: { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + legend: { + type: 'scroll', + orient: 'vertical', + right: 30, + top: 10, + bottom: 20, + data: [] as any[], + textStyle: { + color: '#a1a1a1' + } + }, + series: [ + { + name: '命令', + type: 'pie', + radius: [20, 120], + center: ['40%', '60%'], + data: [] as any[], + roseType: 'radius', + label: { + show: true + }, + emphasis: { label: { show: true }, - emphasis: { - label: { - show: true - }, - itemStyle: { - shadowBlur: 10, - shadowOffsetX: 0, - shadowColor: 'rgba(0, 0, 0, 0.5)' - } + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' } } - ] - }) + } + ] +}) - const usedMemoryInstance = echarts.init(usedmemory.value!, 'macarons') - usedMemoryInstance.setOption({ - title: { - text: '内存使用情况', - left: 'center' - }, - tooltip: { - formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human - }, - series: [ - { - name: '峰值', - type: 'gauge', - min: 0, - max: 100, - progress: { - show: true - }, - detail: { - formatter: cache.value!.info.used_memory_human - }, - data: [ - { - value: parseFloat(cache.value!.info.used_memory_human), - name: '内存消耗' - } - ] - } - ] - }) +/** 加载数据 */ +const getSummary = () => { + // 初始化命令图表 + initCommandStatsChart() + usedMemoryInstance() } -onBeforeMount(() => { - // TODO @hiiwbs 微信,优化使用 Echart 组件 +/** 命令使用情况 */ +const initCommandStatsChart = async () => { + usedmemoryEchartChika.series[0].data = [] + // 发起请求 + try { + const data = await RedisApi.getCache() + cache.value = data + // 处理数据 + const commandStats = [] as any[] + const nameList = [] as string[] + data.commandStats.forEach((row) => { + commandStats.push({ + name: row.command, + value: row.calls + }) + nameList.push(row.command) + }) + commandStatsRefChika.legend.data = nameList + commandStatsRefChika.series[0].data = commandStats + } catch {} +} +const usedMemoryInstance = async () => { + try { + const data = await RedisApi.getCache() + cache.value = data + // 仪表盘详情,用于显示数据。 + usedmemoryEchartChika.series[0].detail = { + show: true, // 是否显示详情,默认 true。 + offsetCenter: [0, '50%'], // 相对于仪表盘中心的偏移位置,数组第一项是水平方向的偏移,第二项是垂直方向的偏移。可以是绝对的数值,也可以是相对于仪表盘半径的百分比。 + color: 'auto', // 文字的颜色,默认 auto。 + fontSize: 30, // 文字的字体大小,默认 15。 + formatter: cache.value!.info.used_memory_human // 格式化函数或者字符串 + } + + usedmemoryEchartChika.series[0].data[0] = { + value: cache.value!.info.used_memory_human, + name: '内存消耗' + } + console.log(cache.value!.info) + usedmemoryEchartChika.tooltip = { + formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human + } + } catch {} +} + +/** 初始化 **/ +onMounted(() => { + echarts.use([ToolboxComponent]) + echarts.use([GaugeChart]) + // 读取 redis 信息 readRedisInfo() + // 加载数据 + getSummary() }) </script> diff --git a/src/views/mall/trade/delivery/express/ExpressForm.vue b/src/views/mall/trade/delivery/express/ExpressForm.vue new file mode 100644 index 00000000..48f7cc0d --- /dev/null +++ b/src/views/mall/trade/delivery/express/ExpressForm.vue @@ -0,0 +1,125 @@ +<template> + <Dialog :title="dialogTitle" v-model="dialogVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="120px" + v-loading="formLoading" + > + <el-form-item label="快递公司编码" prop="code"> + <el-input v-model="formData.code" placeholder="请输入快递编码" /> + </el-form-item> + <el-form-item label="快递公司名称" prop="name"> + <el-input v-model="formData.name" placeholder="请输入快递名称" /> + </el-form-item> + <el-form-item label="快递公司logo" prop="logo"> + <UploadImg v-model="formData.logo" :limit="1" :is-show-tip="false" /> + <div style="font-size: 10px" class="pl-10px">推荐 180x180 图片分辨率</div> + </el-form-item> + <el-form-item label="分类排序" prop="sort"> + <el-input-number v-model="formData.sort" controls-position="right" :min="0" /> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-radio-group v-model="formData.status"> + <el-radio + v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" + :key="dict.value" + :label="dict.value" + > + {{ dict.label }} + </el-radio> + </el-radio-group> + </el-form-item> + </el-form> + <template #footer> + <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> + <el-button @click="dialogVisible = false">取 消</el-button> + </template> + </Dialog> +</template> + +<script setup lang="ts" name="ExpressForm"> +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' +import { CommonStatusEnum } from '@/utils/constants' +import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express' +const { t } = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 + +const dialogVisible = ref(false) // 弹窗的是否展示 +const dialogTitle = ref('') // 弹窗的标题 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 +const formType = ref('') // 表单的类型:create - 新增;update - 修改 +const formData = ref({ + id: undefined, + code: '', + name: '', + logo: '', + sort: 0, + status: CommonStatusEnum.ENABLE +}) +const formRules = reactive({ + code: [{ required: true, message: '快递编码不能为空', trigger: 'blur' }], + name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }], + logo: [{ required: true, message: '分类图片不能为空', trigger: 'blur' }], + sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }], + status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }] +}) +const formRef = ref() // 表单 Ref + +/** 打开弹窗 */ +const open = async (type: string, id?: number) => { + dialogVisible.value = true + dialogTitle.value = t('action.' + type) + formType.value = type + resetForm() + // 修改时,设置数据 + if (id) { + formLoading.value = true + try { + formData.value = await DeliveryExpressApi.getDeliveryExpress(id) + } finally { + formLoading.value = false + } + } +} +defineExpose({ open }) // 提供 open 方法,用于打开弹窗 + +/** 提交表单 */ +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 +const submitForm = async () => { + // 校验表单 + if (!formRef) return + const valid = await formRef.value.validate() + if (!valid) return + // 提交请求 + formLoading.value = true + try { + const data = formData.value as DeliveryExpressApi.DeliveryExpressVO + if (formType.value === 'create') { + await DeliveryExpressApi.createDeliveryExpress(data) + message.success(t('common.createSuccess')) + } else { + await DeliveryExpressApi.updateDeliveryExpress(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: undefined, + name: '', + picUrl: '', + bigPicUrl: '', + status: CommonStatusEnum.ENABLE + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/mall/trade/delivery/express/index.vue b/src/views/mall/trade/delivery/express/index.vue new file mode 100644 index 00000000..ad8c5d41 --- /dev/null +++ b/src/views/mall/trade/delivery/express/index.vue @@ -0,0 +1,183 @@ +<template> + <!-- 搜索工作栏 --> + <ContentWrap> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="100px" + > + <el-form-item label="快递公司编码" prop="code"> + <el-input + v-model="queryParams.code" + placeholder="请输快递公司编码" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item label="快递公司名称" prop="name"> + <el-input + v-model="queryParams.name" + placeholder="请输快递公司名称" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item> + <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> + <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> + <el-button + type="primary" + plain + @click="openForm('create')" + v-hasPermi="['trade:delivery:express:create']" + > + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['trade:delivery:express:export']" + > + <Icon icon="ep:download" class="mr-5px" /> 导出 + </el-button> + </el-form-item> + </el-form> + </ContentWrap> + + <!-- 列表 --> + <ContentWrap> + <el-table v-loading="loading" :data="list"> + <el-table-column label="快递公司编号" prop="code" /> + <el-table-column label="快递公司名称" prop="name" /> + <el-table-column label="快递公司 logo " prop="logo"> + <template #default="scope"> + <img v-if="scope.row.logo" :src="scope.row.logo" alt="快递公司logo" class="h-25px" /> + </template> + </el-table-column> + <el-table-column label="排序" align="center" prop="sort" /> + <el-table-column label="开启状态" align="center" prop="status"> + <template #default="scope"> + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" /> + </template> + </el-table-column> + <el-table-column + label="创建时间" + align="center" + prop="createTime" + width="180" + :formatter="dateFormatter" + /> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openForm('update', scope.row.id)" + v-hasPermi="['trade:delivery:express:update']" + > + 编辑 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['trade:delivery:express:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <ExpressForm ref="formRef" @success="getList" /> +</template> +<script setup lang="ts" name="Express"> +import { DICT_TYPE } from '@/utils/dict' +import { dateFormatter } from '@/utils/formatTime' +import download from '@/utils/download' +import * as DeliveryExpressApi from '@/api/mall/trade/delivery/express' +import ExpressForm from './ExpressForm.vue' +const message = useMessage() // 消息弹窗 +const { t } = useI18n() // 国际化 +const total = ref(0) // 列表的总页数 +const loading = ref(true) // 列表的加载中 +const list = ref<any[]>([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + code: '', + name: '' +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await DeliveryExpressApi.getDeliveryExpressPage(queryParams) + list.value = data.list + total.value = data.total + } finally { + loading.value = false + } +} + +/** 搜索按钮操作 */ +const handleQuery = () => { + queryParams.pageNo = 1 + getList() +} + +/** 重置按钮操作 */ +const resetQuery = () => { + queryFormRef.value.resetFields() + handleQuery() +} + +/** 添加/修改操作 */ +const formRef = ref() +const openForm = (type: string, id?: number) => { + formRef.value.open(type, id) +} + +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await DeliveryExpressApi.deleteDeliveryExpress(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await DeliveryExpressApi.exportDeliveryExpressApi(queryParams) + download.excel(data, '快递公司.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(() => { + getList() +}) +</script> diff --git a/src/views/mp/autoReply/components/ReplyForm.vue b/src/views/mp/autoReply/components/ReplyForm.vue new file mode 100644 index 00000000..edcbc696 --- /dev/null +++ b/src/views/mp/autoReply/components/ReplyForm.vue @@ -0,0 +1,78 @@ +<template> + <div> + <el-form ref="formRef" :model="replyForm" :rules="rules" label-width="80px"> + <el-form-item label="消息类型" prop="requestMessageType" v-if="msgType === MsgType.Message"> + <el-select v-model="replyForm.requestMessageType" placeholder="请选择"> + <template v-for="dict in getDictOptions(DICT_TYPE.MP_MESSAGE_TYPE)" :key="dict.value"> + <el-option + v-if="RequestMessageTypes.includes(dict.value)" + :label="dict.label" + :value="dict.value" + /> + </template> + </el-select> + </el-form-item> + <el-form-item label="匹配类型" prop="requestMatch" v-if="msgType === MsgType.Keyword"> + <el-select v-model="replyForm.requestMatch" placeholder="请选择匹配类型" clearable> + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="关键词" prop="requestKeyword" v-if="msgType === MsgType.Keyword"> + <el-input v-model="replyForm.requestKeyword" placeholder="请输入内容" clearable /> + </el-form-item> + <el-form-item label="回复消息"> + <WxReplySelect v-model="reply" /> + </el-form-item> + </el-form> + </div> +</template> + +<script setup lang="ts" name="ReplyForm"> +import WxReplySelect, { type Reply } from '@/views/mp/components/wx-reply' +import type { FormInstance } from 'element-plus' +import { MsgType } from './types' +import { DICT_TYPE, getDictOptions, getIntDictOptions } from '@/utils/dict' + +const props = defineProps<{ + modelValue: any + reply: Reply + msgType: MsgType +}>() + +const emit = defineEmits<{ + (e: 'update:reply', v: Reply) + (e: 'update:modelValue', v: any) +}>() + +const reply = computed<Reply>({ + get: () => props.reply, + set: (val) => emit('update:reply', val) +}) + +const replyForm = computed<any>({ + get: () => props.modelValue, + set: (val) => emit('update:modelValue', val) +}) + +const formRef = ref<FormInstance | null>(null) // 表单 ref + +const RequestMessageTypes = ['text', 'image', 'voice', 'video', 'shortvideo', 'location', 'link'] // 允许选择的请求消息类型 + +// 表单校验 +const rules = { + requestKeyword: [{ required: true, message: '请求的关键字不能为空', trigger: 'blur' }], + requestMatch: [{ required: true, message: '请求的关键字的匹配不能为空', trigger: 'blur' }] +} + +defineExpose({ + resetFields: () => formRef.value?.resetFields(), + validate: async () => formRef.value?.validate() +}) +</script> + +<style scoped></style> diff --git a/src/views/mp/autoReply/index.vue b/src/views/mp/autoReply/index.vue index e2fcd7a0..b3826de5 100644 --- a/src/views/mp/autoReply/index.vue +++ b/src/views/mp/autoReply/index.vue @@ -53,38 +53,13 @@ @on-delete="onDelete" /> - <!-- 添加或修改自动回复的对话框 --> - <!-- TODO @Dhb52 --> - <el-dialog :title="dialogTitle" v-model="showFormDialog" width="800px" destroy-on-close> - <el-form ref="formRef" :model="replyForm" :rules="rules" label-width="80px"> - <el-form-item label="消息类型" prop="requestMessageType" v-if="msgType === MsgType.Message"> - <el-select v-model="replyForm.requestMessageType" placeholder="请选择"> - <template v-for="dict in getDictOptions(DICT_TYPE.MP_MESSAGE_TYPE)" :key="dict.value"> - <el-option - v-if="RequestMessageTypes.includes(dict.value)" - :label="dict.label" - :value="dict.value" - /> - </template> - </el-select> - </el-form-item> - <el-form-item label="匹配类型" prop="requestMatch" v-if="msgType === MsgType.Keyword"> - <el-select v-model="replyForm.requestMatch" placeholder="请选择匹配类型" clearable> - <el-option - v-for="dict in getIntDictOptions(DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH)" - :key="dict.value" - :label="dict.label" - :value="dict.value" - /> - </el-select> - </el-form-item> - <el-form-item label="关键词" prop="requestKeyword" v-if="msgType === MsgType.Keyword"> - <el-input v-model="replyForm.requestKeyword" placeholder="请输入内容" clearable /> - </el-form-item> - <el-form-item label="回复消息"> - <WxReplySelect v-model="reply" /> - </el-form-item> - </el-form> + <el-dialog + :title="isCreating ? '新增自动回复' : '修改自动回复'" + v-model="showDialog" + width="800px" + destroy-on-close + > + <ReplyForm v-model="replyForm" v-model:reply="reply" :msg-type="msgType" ref="formRef" /> <template #footer> <el-button @click="cancel">取 消</el-button> <el-button type="primary" @click="onSubmit">确 定</el-button> @@ -93,23 +68,22 @@ </ContentWrap> </template> <script setup lang="ts" name="MpAutoReply"> -import WxReplySelect, { type Reply, ReplyType } from '@/views/mp/components/wx-reply' +import ReplyForm from '@/views/mp/autoReply/components/ReplyForm.vue' +import { type Reply, ReplyType } from '@/views/mp/components/wx-reply' import WxAccountSelect from '@/views/mp/components/wx-account-select' import * as MpAutoReplyApi from '@/api/mp/autoReply' -import { DICT_TYPE, getDictOptions, getIntDictOptions } from '@/utils/dict' import { ContentWrap } from '@/components/ContentWrap' -import type { FormInstance, TabPaneName } from 'element-plus' +import type { TabPaneName } from 'element-plus' import ReplyTable from './components/ReplyTable.vue' import { MsgType } from './components/types' const message = useMessage() // 消息 const accountId = ref(-1) // 公众号ID const msgType = ref<MsgType>(MsgType.Keyword) // 消息类型 -const RequestMessageTypes = ['text', 'image', 'voice', 'video', 'shortvideo', 'location', 'link'] // 允许选择的请求消息类型 const loading = ref(true) // 遮罩层 const total = ref(0) // 总条数 const list = ref<any[]>([]) // 自动回复列表 -const formRef = ref<FormInstance | null>(null) // 表单 ref +const formRef = ref<InstanceType<typeof ReplyForm> | null>(null) // 表单 ref // 查询参数 const queryParams = reactive({ pageNo: 1, @@ -117,19 +91,14 @@ const queryParams = reactive({ accountId: accountId }) -const dialogTitle = ref('') // 弹出层标题 -const showFormDialog = ref(false) // 是否显示弹出层 +const isCreating = ref(false) // 是否新建(否则编辑) +const showDialog = ref(false) // 是否显示弹出层 const replyForm = ref<any>({}) // 表单参数 // 回复消息 const reply = ref<Reply>({ type: ReplyType.Text, accountId: -1 }) -// 表单校验 -const rules = { - requestKeyword: [{ required: true, message: '请求的关键字不能为空', trigger: 'blur' }], - requestMatch: [{ required: true, message: '请求的关键字的匹配不能为空', trigger: 'blur' }] -} /** 侦听账号变化 */ const onAccountChanged = (id: number) => { @@ -174,8 +143,8 @@ const onCreate = () => { accountId: queryParams.accountId } - dialogTitle.value = '新增自动回复' - showFormDialog.value = true + isCreating.value = true + showDialog.value = true } /** 修改按钮操作 */ @@ -207,8 +176,8 @@ const onUpdate = async (id: number) => { } // 打开表单 - dialogTitle.value = '修改自动回复' - showFormDialog.value = true + isCreating.value = false + showDialog.value = true } /** 删除按钮操作 */ @@ -220,8 +189,7 @@ const onDelete = async (id: number) => { } const onSubmit = async () => { - const valid = await formRef.value?.validate() - if (!valid) return + await formRef.value?.validate() // 处理回复消息 const submitForm: any = { ...replyForm.value } @@ -245,7 +213,7 @@ const onSubmit = async () => { message.success('新增成功') } - showFormDialog.value = false + showDialog.value = false await getList() } @@ -264,7 +232,7 @@ const reset = () => { // 取消按钮 const cancel = () => { - showFormDialog.value = false + showDialog.value = false reset() } </script> diff --git a/src/views/system/dict/data/DictDataForm.vue b/src/views/system/dict/data/DictDataForm.vue index 8b9bb1db..26932e5b 100644 --- a/src/views/system/dict/data/DictDataForm.vue +++ b/src/views/system/dict/data/DictDataForm.vue @@ -122,7 +122,9 @@ const open = async (type: string, id?: number, dictType?: string) => { dialogTitle.value = t('action.' + type) formType.value = type resetForm() - formData.value.dictType = dictType + if (dictType) { + formData.value.dictType = dictType + } // 修改时,设置数据 if (id) { formLoading.value = true diff --git a/src/views/system/notice/NoticeForm.vue b/src/views/system/notice/NoticeForm.vue index 114a2c81..42060abd 100644 --- a/src/views/system/notice/NoticeForm.vue +++ b/src/views/system/notice/NoticeForm.vue @@ -17,9 +17,9 @@ <el-select v-model="formData.type" clearable placeholder="请选择公告类型"> <el-option v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_NOTICE_TYPE)" - :key="parseInt(dict.value)" + :key="parseInt(dict.value as any)" :label="dict.label" - :value="parseInt(dict.value)" + :value="parseInt(dict.value as any)" /> </el-select> </el-form-item> @@ -27,9 +27,9 @@ <el-select v-model="formData.status" clearable placeholder="请选择状态"> <el-option v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" - :key="parseInt(dict.value)" + :key="parseInt(dict.value as any)" :label="dict.label" - :value="parseInt(dict.value)" + :value="parseInt(dict.value as any)" /> </el-select> </el-form-item> diff --git a/src/views/system/notify/template/NotifyTemplateSendForm.vue b/src/views/system/notify/template/NotifyTemplateSendForm.vue index 9e292a8d..78788f0d 100644 --- a/src/views/system/notify/template/NotifyTemplateSendForm.vue +++ b/src/views/system/notify/template/NotifyTemplateSendForm.vue @@ -44,7 +44,6 @@ </Dialog> </template> <script lang="ts" name="SystemNotifyTemplateSendForm" setup> -import * as SmsTemplateApi from '@/api/system/sms/smsTemplate' import * as UserApi from '@/api/system/user' import * as NotifyTemplateApi from '@/api/system/notify/template' const message = useMessage() // 消息弹窗 @@ -102,8 +101,8 @@ const submitForm = async () => { // 提交请求 formLoading.value = true try { - const data = formData.value as SmsTemplateApi.SendSmsReqVO - const logId = await SmsTemplateApi.sendSms(data) + const data = formData.value as unknown as NotifyTemplateApi.NotifySendReqVO + const logId = await NotifyTemplateApi.sendNotify(data) if (logId) { message.success('提交发送成功!发送结果,见发送日志编号:' + logId) } @@ -121,7 +120,7 @@ const resetForm = () => { mobile: '', templateCode: '', templateParams: new Map() - } + } as any formRef.value?.resetFields() } </script> diff --git a/src/views/system/oauth2/token/index.vue b/src/views/system/oauth2/token/index.vue index 803cd7d1..b97506ff 100644 --- a/src/views/system/oauth2/token/index.vue +++ b/src/views/system/oauth2/token/index.vue @@ -80,7 +80,7 @@ <el-button link type="danger" - @click="handleForceLogout(scope.row.id)" + @click="handleForceLogout(scope.row.accessToken)" v-hasPermi="['system:oauth2-token:delete']" > 强退 @@ -142,12 +142,12 @@ const resetQuery = () => { } /** 强制退出操作 */ -const handleForceLogout = async (id: number) => { +const handleForceLogout = async (accessToken: string) => { try { // 删除的二次确认 await message.confirm('是否要强制退出用户') // 发起删除 - await OAuth2AccessTokenApi.deleteAccessToken(id) + await OAuth2AccessTokenApi.deleteAccessToken(accessToken) message.success(t('common.success')) // 刷新列表 await getList() diff --git a/src/views/system/post/PostForm.vue b/src/views/system/post/PostForm.vue index e4ea8ad7..a314806b 100644 --- a/src/views/system/post/PostForm.vue +++ b/src/views/system/post/PostForm.vue @@ -117,7 +117,7 @@ const resetForm = () => { sort: undefined, status: CommonStatusEnum.ENABLE, remark: '' - } + } as any formRef.value?.resetFields() } </script> diff --git a/stylelint.config.js b/stylelint.config.js index d4005726..a8ba3d30 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -2,7 +2,7 @@ module.exports = { root: true, plugins: ['stylelint-order'], customSyntax: 'postcss-html', - extends: ['stylelint-config-standard', 'stylelint-config-prettier'], + extends: ['stylelint-config-standard'], rules: { 'selector-pseudo-class-no-unknown': [ true,