From 2bd750a3d60e1bb1f4fff5466d89c0290e65aa9a Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Fri, 19 May 2023 15:23:41 +0800 Subject: [PATCH 01/11] chore: update deps --- package.json | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 7a00c122..fdd251a2 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "serve:pro": "vite preview --mode pro", "serve:dev": "vite preview --mode dev", "serve:test": "vite preview --mode test", + "preview": "pnpm build:front && vite preview", "npm:check": "npx npm-check-updates", "clean": "npx rimraf node_modules", "clean:cache": "npx rimraf node_modules/.cache", @@ -33,12 +34,12 @@ "@form-create/element-ui": "^3.1.17", "@iconify/iconify": "^3.1.0", "@videojs-player/vue": "^1.0.0", - "@vueuse/core": "^10.1.0", + "@vueuse/core": "^10.1.2", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", - "@zxcvbn-ts/core": "^2.2.1", + "@zxcvbn-ts/core": "^3.0.1", "animate.css": "^4.1.1", - "axios": "^1.3.6", + "axios": "^1.4.0", "benz-amr-recorder": "^1.1.5", "bpmn-js-token-simulation": "^0.10.0", "camunda-bpmn-moddle": "^7.0.1", @@ -48,34 +49,34 @@ "diagram-js": "^11.6.0", "echarts": "^5.4.2", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.3.3", + "element-plus": "2.3.4", "fast-xml-parser": "^4.2.2", - "highlight.js": "^11.7.0", + "highlight.js": "^11.8.0", "intro.js": "^7.0.1", "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", - "min-dash": "^4.1.0", + "min-dash": "^4.1.1", "mitt": "^3.0.0", "nprogress": "^0.2.0", - "pinia": "^2.0.35", + "pinia": "^2.1.3", "qrcode": "^1.5.3", - "qs": "^6.11.1", + "qs": "^6.11.2", "steady-xml": "^0.1.0", "url": "^0.11.0", - "video.js": "^8.0.4", - "vue": "3.2.47", + "video.js": "^8.3.0", + "vue": "3.3.4", "vue-i18n": "9.2.2", - "vue-router": "^4.1.6", - "vue-types": "^5.0.2", + "vue-router": "^4.2.1", + "vue-types": "^5.0.3", "vuedraggable": "^4.1.0", "web-storage-cache": "^1.1.1", "xe-utils": "^3.5.7", "xml-js": "^1.6.11" }, "devDependencies": { - "@commitlint/cli": "^17.6.1", - "@commitlint/config-conventional": "^17.6.1", - "@iconify/json": "^2.2.54", + "@commitlint/cli": "^17.6.3", + "@commitlint/config-conventional": "^17.6.3", + "@iconify/json": "^2.2.67", "@intlify/unplugin-vue-i18n": "^0.10.0", "@purge-icons/generated": "^0.9.0", "@types/intro.js": "^5.1.1", @@ -84,39 +85,39 @@ "@types/nprogress": "^0.2.0", "@types/qrcode": "^1.5.0", "@types/qs": "^6.9.7", - "@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", + "@typescript-eslint/eslint-plugin": "^5.59.6", + "@typescript-eslint/parser": "^5.59.6", + "@vitejs/plugin-legacy": "^4.0.3", + "@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue-jsx": "^3.0.1", "autoprefixer": "^10.4.14", "bpmn-js": "^8.9.0", "bpmn-js-properties-panel": "^0.46.0", "consola": "^3.1.0", - "eslint": "^8.39.0", + "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-define-config": "^1.18.0", + "eslint-define-config": "^1.20.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-vue": "^9.11.0", - "lint-staged": "^13.2.1", + "eslint-plugin-vue": "^9.13.0", + "lint-staged": "^13.2.2", "postcss": "^8.4.23", "postcss-html": "^1.5.0", "postcss-scss": "^4.0.6", "prettier": "^2.8.8", - "rimraf": "^5.0.0", - "rollup": "^3.20.7", - "sass": "^1.62.0", - "stylelint": "^15.6.0", + "rimraf": "^5.0.1", + "rollup": "^3.22.0", + "sass": "^1.62.1", + "stylelint": "^15.6.2", "stylelint-config-html": "^1.1.0", "stylelint-config-recommended": "^12.0.0", "stylelint-config-standard": "^33.0.0", "stylelint-order": "^6.0.3", - "terser": "^5.17.1", + "terser": "^5.17.4", "typescript": "5.0.4", - "unplugin-auto-import": "^0.15.3", + "unplugin-auto-import": "^0.16.0", "unplugin-element-plus": "^0.7.1", "unplugin-vue-components": "^0.24.1", - "vite": "4.3.1", + "vite": "4.3.8", "vite-plugin-compression": "^0.5.1", "vite-plugin-ejs": "^1.6.4", "vite-plugin-eslint": "^1.8.1", @@ -125,8 +126,8 @@ "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.4.4", + "vite-plugin-windicss": "^1.9.0", + "vue-tsc": "^1.6.5", "windicss": "^3.5.6" }, "engines": { From 45ee4116b7b84ca5d76ed099ae5a0167a5cb7689 Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Fri, 19 May 2023 15:24:01 +0800 Subject: [PATCH 02/11] fix: echart --- src/components/Echart/src/Echart.vue | 2 +- src/plugins/echarts/index.ts | 10 +++++++--- src/views/infra/redis/index.vue | 7 +------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/Echart/src/Echart.vue b/src/components/Echart/src/Echart.vue index 31f2eea0..cec28e42 100644 --- a/src/components/Echart/src/Echart.vue +++ b/src/components/Echart/src/Echart.vue @@ -27,7 +27,7 @@ const props = defineProps({ const isDark = computed(() => appStore.getIsDark) const theme = computed(() => { - const echartTheme: boolean | string = unref(isDark) ? true : 'auto' + const echartTheme: boolean | string = unref(isDark) ? true : 'inherit' return echartTheme }) diff --git a/src/plugins/echarts/index.ts b/src/plugins/echarts/index.ts index 34f756f6..bfccbb48 100644 --- a/src/plugins/echarts/index.ts +++ b/src/plugins/echarts/index.ts @@ -6,7 +6,8 @@ import { PieChart, MapChart, PictorialBarChart, - RadarChart + RadarChart, + GaugeChart } from 'echarts/charts' import { @@ -16,7 +17,8 @@ import { PolarComponent, AriaComponent, ParallelComponent, - LegendComponent + LegendComponent, + ToolboxComponent } from 'echarts/components' import { CanvasRenderer } from 'echarts/renderers' @@ -25,6 +27,7 @@ echarts.use([ LegendComponent, TitleComponent, TooltipComponent, + ToolboxComponent, GridComponent, PolarComponent, AriaComponent, @@ -35,7 +38,8 @@ echarts.use([ MapChart, CanvasRenderer, PictorialBarChart, - RadarChart + RadarChart, + GaugeChart ]) export default echarts diff --git a/src/views/infra/redis/index.vue b/src/views/infra/redis/index.vue index 011f8e59..f98f2f30 100644 --- a/src/views/infra/redis/index.vue +++ b/src/views/infra/redis/index.vue @@ -63,9 +63,6 @@ </el-scrollbar> </template> <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>() @@ -77,7 +74,7 @@ const readRedisInfo = async () => { } // 内存使用情况 -const usedmemoryEchartChika = reactive({ +const usedmemoryEchartChika = reactive<any>({ title: { // 仪表盘标题。 text: '内存使用情况', @@ -263,8 +260,6 @@ const usedMemoryInstance = async () => { /** 初始化 **/ onMounted(() => { - echarts.use([ToolboxComponent]) - echarts.use([GaugeChart]) // 读取 redis 信息 readRedisInfo() // 加载数据 From ba33d8bfd5f60007cf1054db9cf505364f306f06 Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Fri, 19 May 2023 15:25:09 +0800 Subject: [PATCH 03/11] docs: update deps --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f5619e8b..4a0de6ae 100644 --- a/README.md +++ b/README.md @@ -38,14 +38,14 @@ | 框架 | 说明 | 版本 | |----------------------------------------------------------------------|------------------|--------| -| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.47 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.1 | -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.3 | +| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.8 | +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.4 | | [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 | +| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.3 | +| [vueuse](https://vueuse.org/) | 常用工具集 | 10.1.2 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | -| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.1.6 | +| [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.1 | | [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | | [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 3.1.0 | | [wangeditor](https://www.wangeditor.com/) | 富文本编辑器 | 5.1.23 | From 8b3980400aa7c902829e9259a846096d7d1ce4f9 Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Fri, 19 May 2023 15:27:07 +0800 Subject: [PATCH 04/11] chore: preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fdd251a2..06ce76df 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "serve:pro": "vite preview --mode pro", "serve:dev": "vite preview --mode dev", "serve:test": "vite preview --mode test", - "preview": "pnpm build:front && vite preview", + "preview": "pnpm build && vite preview", "npm:check": "npx npm-check-updates", "clean": "npx rimraf node_modules", "clean:cache": "npx rimraf node_modules/.cache", From 9f0065f89f312b4003f2b2154728a537c499c7b6 Mon Sep 17 00:00:00 2001 From: xingyu <xingyu4j@vip.qq.com> Date: Fri, 19 May 2023 15:37:01 +0800 Subject: [PATCH 05/11] fix: echart color --- src/components/Echart/src/Echart.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Echart/src/Echart.vue b/src/components/Echart/src/Echart.vue index cec28e42..31f2eea0 100644 --- a/src/components/Echart/src/Echart.vue +++ b/src/components/Echart/src/Echart.vue @@ -27,7 +27,7 @@ const props = defineProps({ const isDark = computed(() => appStore.getIsDark) const theme = computed(() => { - const echartTheme: boolean | string = unref(isDark) ? true : 'inherit' + const echartTheme: boolean | string = unref(isDark) ? true : 'auto' return echartTheme }) From 6768cdea0588478b0f0048676c8eb9d37dc61696 Mon Sep 17 00:00:00 2001 From: wangding <857299269.com> Date: Mon, 29 May 2023 11:05:46 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 3 ++ src/components/RouterSearch/index.vue | 76 +++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/components/RouterSearch/index.vue diff --git a/src/App.vue b/src/App.vue index 75edd24f..c40f767e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,6 +3,8 @@ import { isDark } from '@/utils/is' import { useAppStore } from '@/store/modules/app' import { useDesign } from '@/hooks/web/useDesign' import { CACHE_KEY, useCache } from '@/hooks/web/useCache' +import routerSearch from '@/components/RouterSearch' + const { getPrefixCls } = useDesign() const prefixCls = getPrefixCls('app') @@ -24,6 +26,7 @@ setDefaultTheme() <template> <ConfigGlobal :size="currentSize"> <RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" /> + <routerSearch/> </ConfigGlobal> </template> <style lang="scss"> diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue new file mode 100644 index 00000000..0f984ef7 --- /dev/null +++ b/src/components/RouterSearch/index.vue @@ -0,0 +1,76 @@ +<template> + <ElDialog v-model="showSearch" :show-close="false" title="菜单搜索"> + <el-select + filterable + :reserve-keyword="false" + remote + placeholder="请输入菜单内容" + :remote-method="remoteMethod" + style="width: 100%;" + @change="handleChange" + > + <el-option + v-for="item in options" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </ElDialog> +</template> + +<script setup lang="ts"> +const router = useRouter() // 路由对象 +const showSearch = ref(false) // 是否显示弹框 +const value:Ref = ref('') // 用户输入的值 + +const routers = router.getRoutes() // 路由对象 +const options = computed(() => { // 提示选项 + if(!value.value) { + return [] + } + const list = routers.filter((item:any) => { + if(item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) { + return true + } + }) + return list.map((item) => { + return { + label: `${item.meta.title}${item.path}`, + value: item.path + } + }) +}) + + +function remoteMethod(data) { + // 这里可以执行相应的操作(例如打开搜索框等) + value.value = data +} + +function handleChange(path) { + router.push({path}) +} + +onMounted(() => { + window.addEventListener('keydown', listenKey) +}) + +onUnmounted(() => { + window.removeEventListener('keydown', listenKey) +}) + +// 监听 ctrl + k +function listenKey(event) { + if ((event.ctrlKey || event.metaKey) && event.key === 'k') { + showSearch.value = !showSearch.value + // 这里可以执行相应的操作(例如打开搜索框等) + } +} + +defineExpose({ + openSearch: () => { + showSearch.value = true + } +}) +</script> \ No newline at end of file From 43f3c6743483544343eb814dfe98419e19cfc52e Mon Sep 17 00:00:00 2001 From: wangding <857299269.com> Date: Mon, 29 May 2023 11:26:51 +0800 Subject: [PATCH 07/11] add router search --- .vscode/settings.json | 2 +- src/App.vue | 6 +- src/components/RouterSearch/index.vue | 94 +++++++++++++-------------- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3036ebf1..5b3aa477 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,7 @@ "source.fixAll.eslint": true }, "[vue]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "Vue.volar" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" diff --git a/src/App.vue b/src/App.vue index c40f767e..f75478cd 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,8 +3,7 @@ import { isDark } from '@/utils/is' import { useAppStore } from '@/store/modules/app' import { useDesign } from '@/hooks/web/useDesign' import { CACHE_KEY, useCache } from '@/hooks/web/useCache' -import routerSearch from '@/components/RouterSearch' - +import routerSearch from '@/components/RouterSearch/index.vue' const { getPrefixCls } = useDesign() const prefixCls = getPrefixCls('app') @@ -26,11 +25,12 @@ setDefaultTheme() <template> <ConfigGlobal :size="currentSize"> <RouterView :class="greyMode ? `${prefixCls}-grey-mode` : ''" /> - <routerSearch/> + <routerSearch /> </ConfigGlobal> </template> <style lang="scss"> $prefix-cls: #{$namespace}-app; + .size { width: 100%; height: 100%; diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue index 0f984ef7..d44ce267 100644 --- a/src/components/RouterSearch/index.vue +++ b/src/components/RouterSearch/index.vue @@ -1,76 +1,76 @@ <template> - <ElDialog v-model="showSearch" :show-close="false" title="菜单搜索"> - <el-select - filterable - :reserve-keyword="false" - remote - placeholder="请输入菜单内容" - :remote-method="remoteMethod" - style="width: 100%;" - @change="handleChange" - > - <el-option - v-for="item in options" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> - </ElDialog> + <ElDialog v-model="showSearch" :show-close="false" title="菜单搜索"> + <el-select + filterable + :reserve-keyword="false" + remote + placeholder="请输入菜单内容" + :remote-method="remoteMethod" + style="width: 100%" + @change="handleChange" + > + <el-option + v-for="item in options" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </ElDialog> </template> <script setup lang="ts"> const router = useRouter() // 路由对象 const showSearch = ref(false) // 是否显示弹框 -const value:Ref = ref('') // 用户输入的值 +const value: Ref = ref('') // 用户输入的值 const routers = router.getRoutes() // 路由对象 -const options = computed(() => { // 提示选项 - if(!value.value) { - return [] +const options = computed(() => { + // 提示选项 + if (!value.value) { + return [] + } + const list = routers.filter((item: any) => { + if (item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) { + return true } - const list = routers.filter((item:any) => { - if(item.meta.title?.indexOf(value.value) > -1 || item.path.indexOf(value.value) > -1) { - return true - } - }) - return list.map((item) => { - return { - label: `${item.meta.title}${item.path}`, - value: item.path - } - }) + }) + return list.map((item) => { + return { + label: `${item.meta.title}${item.path}`, + value: item.path + } + }) }) - function remoteMethod(data) { - // 这里可以执行相应的操作(例如打开搜索框等) - value.value = data + // 这里可以执行相应的操作(例如打开搜索框等) + value.value = data } function handleChange(path) { - router.push({path}) + router.push({ path }) } onMounted(() => { - window.addEventListener('keydown', listenKey) + window.addEventListener('keydown', listenKey) }) onUnmounted(() => { - window.removeEventListener('keydown', listenKey) + window.removeEventListener('keydown', listenKey) }) // 监听 ctrl + k function listenKey(event) { - if ((event.ctrlKey || event.metaKey) && event.key === 'k') { - showSearch.value = !showSearch.value - // 这里可以执行相应的操作(例如打开搜索框等) - } + if ((event.ctrlKey || event.metaKey) && event.key === 'k') { + showSearch.value = !showSearch.value + // 这里可以执行相应的操作(例如打开搜索框等) + } } defineExpose({ - openSearch: () => { - showSearch.value = true - } + openSearch: () => { + showSearch.value = true + } }) -</script> \ No newline at end of file +</script> From 12e6f08f1f1329107ad01d333c354ccc2e77c04b Mon Sep 17 00:00:00 2001 From: qiuhuanran <qiuhuanran@qq.com> Date: Mon, 29 May 2023 16:58:56 +0800 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3vue=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=B8=8Epinia=E7=89=88=E6=9C=AC=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a00c122..82a154dd 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "steady-xml": "^0.1.0", "url": "^0.11.0", "video.js": "^8.0.4", - "vue": "3.2.47", + "vue": "3.3.0", "vue-i18n": "9.2.2", "vue-router": "^4.1.6", "vue-types": "^5.0.2", From 257ad9f79f5b28c42addbb012c096829365fe1d0 Mon Sep 17 00:00:00 2001 From: lour6498 <lour6498@gmail.com> Date: Mon, 29 May 2023 18:44:55 +0800 Subject: [PATCH 09/11] =?UTF-8?q?fix:=20=E5=85=AC=E5=91=8A=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E4=B8=8D=E8=83=BD=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/notice/NoticeForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/system/notice/NoticeForm.vue b/src/views/system/notice/NoticeForm.vue index 42060abd..c1962f19 100644 --- a/src/views/system/notice/NoticeForm.vue +++ b/src/views/system/notice/NoticeForm.vue @@ -11,7 +11,7 @@ <el-input v-model="formData.title" placeholder="请输入公告标题" /> </el-form-item> <el-form-item label="公告内容" prop="content"> - <Editor :model-value="formData.content" height="150px" /> + <Editor v-model="formData.content" height="150px" /> </el-form-item> <el-form-item label="公告类型" prop="type"> <el-select v-model="formData.type" clearable placeholder="请选择公告类型"> From 3e549a6862e14c433d162a109292a57f59b73e04 Mon Sep 17 00:00:00 2001 From: YunaiV <zhijiantianya@gmail.com> Date: Mon, 29 May 2023 23:04:11 +0800 Subject: [PATCH 10/11] =?UTF-8?q?v1.7.3=20=E7=89=88=E6=9C=AC=E5=8F=91?= =?UTF-8?q?=E5=B8=83=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 06ce76df..74f7959f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "1.7.2-snapshot", + "version": "1.7.3-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, From 1dca8476b35962c278124075acc731319fca60cb Mon Sep 17 00:00:00 2001 From: xiaqing <xiaqing@bonc> Date: Sat, 10 Jun 2023 20:57:16 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E6=A8=A1=E5=9D=97=201.=E7=A7=AF=E5=88=86=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=AE=A1=E7=90=86=202.=E7=A7=AF=E5=88=86=E7=AD=BE?= =?UTF-8?q?=E5=88=B0=E8=A7=84=E5=88=99=E7=AE=A1=E7=90=86=203.=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=A7=AF=E5=88=86=E8=AE=B0=E5=BD=95=E7=AE=A1=E7=90=86?= =?UTF-8?q?=204.=E7=94=A8=E6=88=B7=E7=AD=BE=E5=88=B0=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/point/config/index.ts | 39 +++ src/api/point/record/index.ts | 47 ++++ src/api/point/signInConfig/index.ts | 37 +++ src/api/point/signInRecord/index.ts | 38 +++ src/utils/dict.ts | 5 +- src/views/point/config/ConfigForm.vue | 122 +++++++++ src/views/point/config/index.vue | 199 ++++++++++++++ src/views/point/record/RecordForm.vue | 179 ++++++++++++ src/views/point/record/index.vue | 259 ++++++++++++++++++ .../point/signInConfig/SignInConfigForm.vue | 97 +++++++ src/views/point/signInConfig/index.vue | 171 ++++++++++++ .../point/signInRecord/SignInRecordForm.vue | 99 +++++++ src/views/point/signInRecord/index.vue | 194 +++++++++++++ 13 files changed, 1485 insertions(+), 1 deletion(-) create mode 100644 src/api/point/config/index.ts create mode 100644 src/api/point/record/index.ts create mode 100644 src/api/point/signInConfig/index.ts create mode 100644 src/api/point/signInRecord/index.ts create mode 100644 src/views/point/config/ConfigForm.vue create mode 100644 src/views/point/config/index.vue create mode 100644 src/views/point/record/RecordForm.vue create mode 100644 src/views/point/record/index.vue create mode 100644 src/views/point/signInConfig/SignInConfigForm.vue create mode 100644 src/views/point/signInConfig/index.vue create mode 100644 src/views/point/signInRecord/SignInRecordForm.vue create mode 100644 src/views/point/signInRecord/index.vue diff --git a/src/api/point/config/index.ts b/src/api/point/config/index.ts new file mode 100644 index 00000000..1bf7b094 --- /dev/null +++ b/src/api/point/config/index.ts @@ -0,0 +1,39 @@ +import request from '@/config/axios' + +export interface ConfigVO { + id: number + tradeDeductEnable: number + tradeDeductUnitPrice: number + tradeDeductMaxPrice: number + tradeGivePoint: number +} + +// 查询积分设置列表 +export const getConfigPage = async (params) => { + return await request.get({ url: `/point/config/page`, params }) +} + +// 查询积分设置详情 +export const getConfig = async (id: number) => { + return await request.get({ url: `/point/config/get?id=` + id }) +} + +// 新增积分设置 +export const createConfig = async (data: ConfigVO) => { + return await request.post({ url: `/point/config/create`, data }) +} + +// 修改积分设置 +export const updateConfig = async (data: ConfigVO) => { + return await request.put({ url: `/point/config/update`, data }) +} + +// 删除积分设置 +export const deleteConfig = async (id: number) => { + return await request.delete({ url: `/point/config/delete?id=` + id }) +} + +// 导出积分设置 Excel +export const exportConfig = async (params) => { + return await request.download({ url: `/point/config/export-excel`, params }) +} diff --git a/src/api/point/record/index.ts b/src/api/point/record/index.ts new file mode 100644 index 00000000..15eaff35 --- /dev/null +++ b/src/api/point/record/index.ts @@ -0,0 +1,47 @@ +import request from '@/config/axios' + +export interface RecordVO { + id: number + bizId: string + bizType: string + type: string + title: string + description: string + point: number + totalPoint: number + status: number + userId: number + freezingTime: Date + thawingTime: Date + createDate: Date +} + +// 查询用户积分记录列表 +export const getRecordPage = async (params) => { + return await request.get({ url: `/point/record/page`, params }) +} + +// 查询用户积分记录详情 +export const getRecord = async (id: number) => { + return await request.get({ url: `/point/record/get?id=` + id }) +} + +// 新增用户积分记录 +export const createRecord = async (data: RecordVO) => { + return await request.post({ url: `/point/record/create`, data }) +} + +// 修改用户积分记录 +export const updateRecord = async (data: RecordVO) => { + return await request.put({ url: `/point/record/update`, data }) +} + +// 删除用户积分记录 +export const deleteRecord = async (id: number) => { + return await request.delete({ url: `/point/record/delete?id=` + id }) +} + +// 导出用户积分记录 Excel +export const exportRecord = async (params) => { + return await request.download({ url: `/point/record/export-excel`, params }) +} diff --git a/src/api/point/signInConfig/index.ts b/src/api/point/signInConfig/index.ts new file mode 100644 index 00000000..3786c06e --- /dev/null +++ b/src/api/point/signInConfig/index.ts @@ -0,0 +1,37 @@ +import request from '@/config/axios' + +export interface SignInConfigVO { + id: number + day: number + point: number +} + +// 查询积分签到规则列表 +export const getSignInConfigPage = async (params) => { + return await request.get({ url: `/point/sign-in-config/page`, params }) +} + +// 查询积分签到规则详情 +export const getSignInConfig = async (id: number) => { + return await request.get({ url: `/point/sign-in-config/get?id=` + id }) +} + +// 新增积分签到规则 +export const createSignInConfig = async (data: SignInConfigVO) => { + return await request.post({ url: `/point/sign-in-config/create`, data }) +} + +// 修改积分签到规则 +export const updateSignInConfig = async (data: SignInConfigVO) => { + return await request.put({ url: `/point/sign-in-config/update`, data }) +} + +// 删除积分签到规则 +export const deleteSignInConfig = async (id: number) => { + return await request.delete({ url: `/point/sign-in-config/delete?id=` + id }) +} + +// 导出积分签到规则 Excel +export const exportSignInConfig = async (params) => { + return await request.download({ url: `/point/sign-in-config/export-excel`, params }) +} diff --git a/src/api/point/signInRecord/index.ts b/src/api/point/signInRecord/index.ts new file mode 100644 index 00000000..0f9b9f64 --- /dev/null +++ b/src/api/point/signInRecord/index.ts @@ -0,0 +1,38 @@ +import request from '@/config/axios' + +export interface SignInRecordVO { + id: number + userId: number + day: number + point: number +} + +// 查询用户签到积分列表 +export const getSignInRecordPage = async (params) => { + return await request.get({ url: `/point/sign-in-record/page`, params }) +} + +// 查询用户签到积分详情 +export const getSignInRecord = async (id: number) => { + return await request.get({ url: `/point/sign-in-record/get?id=` + id }) +} + +// 新增用户签到积分 +export const createSignInRecord = async (data: SignInRecordVO) => { + return await request.post({ url: `/point/sign-in-record/create`, data }) +} + +// 修改用户签到积分 +export const updateSignInRecord = async (data: SignInRecordVO) => { + return await request.put({ url: `/point/sign-in-record/update`, data }) +} + +// 删除用户签到积分 +export const deleteSignInRecord = async (id: number) => { + return await request.delete({ url: `/point/sign-in-record/delete?id=` + id }) +} + +// 导出用户签到积分 Excel +export const exportSignInRecord = async (params) => { + return await request.download({ url: `/point/sign-in-record/export-excel`, params }) +} diff --git a/src/utils/dict.ts b/src/utils/dict.ts index c742274f..55e6de4a 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -150,5 +150,8 @@ export enum DICT_TYPE { PRODUCT_UNIT = 'product_unit', // 商品单位 PRODUCT_SPU_STATUS = 'product_spu_status', //商品状态 // ========== MALL 交易模块 ========== - EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode' //快递的计费方式 + EXPRESS_CHARGE_MODE = 'trade_delivery_express_charge_mode', //快递的计费方式 + //积分模块// + POINT_BIZ_TYPE = 'point_biz_type', + POINT_STATUS = 'point_status' } diff --git a/src/views/point/config/ConfigForm.vue b/src/views/point/config/ConfigForm.vue new file mode 100644 index 00000000..0b7f3747 --- /dev/null +++ b/src/views/point/config/ConfigForm.vue @@ -0,0 +1,122 @@ +<template> + <Dialog :title="dialogTitle" v-model="dialogVisible" style="width: 600px"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="120px" + v-loading="formLoading" + > + <el-form-item label="积分抵扣" prop="tradeDeductEnable"> + <el-select v-model="formData.tradeDeductEnable" placeholder="请选择是否开启"> + <el-option + v-for="dict in options" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="抵扣单位(元)" prop="tradeDeductUnitPrice"> + <el-input v-model="formData.tradeDeductUnitPrice" placeholder="请输入抵扣单位(元)" /> + </el-form-item> + <el-form-item label="积分抵扣最大值" prop="tradeDeductMaxPrice"> + <el-input v-model="formData.tradeDeductMaxPrice" placeholder="请输入积分抵扣最大值" /> + </el-form-item> + <el-form-item label="1元赠送多少分" prop="tradeGivePoint"> + <el-input v-model="formData.tradeGivePoint" placeholder="请输入1元赠送多少分" /> + </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"> +import * as ConfigApi from '@/api/point/config' + +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, + tradeDeductEnable: undefined, + tradeDeductUnitPrice: undefined, + tradeDeductMaxPrice: undefined, + tradeGivePoint: undefined +}) +const formRules = reactive({}) +const formRef = ref() // 表单 Ref + +const options = [ + { + value: '1', + label: '是' + }, + { + value: '0', + label: '否' + } +] + +/** 打开弹窗 */ +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 ConfigApi.getConfig(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 unknown as ConfigApi.ConfigVO + if (formType.value === 'create') { + await ConfigApi.createConfig(data) + message.success(t('common.createSuccess')) + } else { + await ConfigApi.updateConfig(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: undefined, + tradeDeductEnable: undefined, + tradeDeductUnitPrice: undefined, + tradeDeductMaxPrice: undefined, + tradeGivePoint: undefined + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/point/config/index.vue b/src/views/point/config/index.vue new file mode 100644 index 00000000..b8259831 --- /dev/null +++ b/src/views/point/config/index.vue @@ -0,0 +1,199 @@ +<template> + <ContentWrap> + <!-- 搜索工作栏 --> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="68px" + > + <el-form-item label="是否开启" prop="tradeDeductEnable"> + <el-select + v-model="queryParams.tradeDeductEnable" + placeholder="请选择是否开启" + clearable + class="!w-240px" + > + <el-option + v-for="dict in options" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </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" @click="openForm('create')" v-hasPermi="['point:config:create']"> + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['point:config: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="序号" align="center" prop="id" /> + <el-table-column + label="积分抵扣(是否开启)" + align="center" + prop="tradeDeductEnable" + :formatter="tradeDeductFormat" + /> + <el-table-column label="抵扣单位(元)" align="center" prop="tradeDeductUnitPrice" /> + <el-table-column label="积分抵扣最大值" align="center" prop="tradeDeductMaxPrice" /> + <el-table-column label="1元赠送多少分" align="center" prop="tradeGivePoint" /> + <el-table-column + label="创建时间" + align="center" + prop="createTime" + :formatter="dateFormatter" + /> + <el-table-column + label="变更时间" + align="center" + prop="updateTime" + :formatter="dateFormatter" + /> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openForm('update', scope.row.id)" + v-hasPermi="['point:config:update']" + > + 编辑 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['point:config:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <ConfigForm ref="formRef" @success="getList" /> +</template> + +<script setup lang="ts" name="PointConfig"> +import { dateFormatter } from '@/utils/formatTime' +import download from '@/utils/download' +import * as ConfigApi from '@/api/point/config' +import ConfigForm from './ConfigForm.vue' +const message = useMessage() // 消息弹窗 +const { t } = useI18n() // 国际化 + +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + tradeDeductEnable: null +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 + +const options = [ + { + value: '1', + label: '是' + }, + { + value: '0', + label: '否' + } +] + +const tradeDeductFormat = (row, column, cellValue) => { + return cellValue === 1 ? '是' : '否' +} +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await ConfigApi.getConfigPage(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 ConfigApi.deleteConfig(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await ConfigApi.exportConfig(queryParams) + download.excel(data, '积分设置.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(() => { + getList() +}) +</script> diff --git a/src/views/point/record/RecordForm.vue b/src/views/point/record/RecordForm.vue new file mode 100644 index 00000000..6da630eb --- /dev/null +++ b/src/views/point/record/RecordForm.vue @@ -0,0 +1,179 @@ +<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="bizId"> + <el-input v-model="formData.bizId" placeholder="请输入业务编码" /> + </el-form-item> + <el-form-item label="业务类型" prop="bizType"> + <el-select v-model="formData.bizType" placeholder="请选择业务类型"> + <el-option + v-for="dict in getStrDictOptions(DICT_TYPE.POINT_BIZ_TYPE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="操作类型" prop="type"> + <el-select v-model="formData.type" placeholder="操作类型"> + <el-option label="增加" value="1" /> + <el-option label="扣减" value="0" /> + </el-select> + </el-form-item> + <el-form-item label="积分标题" prop="title"> + <el-input v-model="formData.title" placeholder="请输入积分标题" /> + </el-form-item> + <el-form-item label="积分描述"> + <Editor :model-value="formData.description" height="150px" /> + </el-form-item> + <el-form-item label="积分" prop="point"> + <el-input v-model="formData.point" placeholder="请输入积分" /> + </el-form-item> + <el-form-item label="变动后的积分" prop="totalPoint"> + <el-input v-model="formData.totalPoint" placeholder="请输入变动后的积分" /> + </el-form-item> + <el-form-item label="积分状态" prop="status"> + <el-select v-model="formData.status" placeholder="积分状态"> + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.POINT_STATUS)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="用户id" prop="userId"> + <el-input v-model="formData.userId" placeholder="请输入用户id" /> + </el-form-item> + <el-form-item label="冻结时间" prop="freezingTime"> + <el-date-picker + v-model="formData.freezingTime" + type="date" + value-format="x" + placeholder="选择冻结时间" + /> + </el-form-item> + <el-form-item label="解冻时间" prop="thawingTime"> + <el-date-picker + v-model="formData.thawingTime" + type="date" + value-format="x" + placeholder="选择解冻时间" + /> + </el-form-item> + <el-form-item label="发生时间" prop="createDate"> + <el-date-picker + v-model="formData.createDate" + type="date" + value-format="x" + placeholder="选择发生时间" + /> + </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"> +import { DICT_TYPE, getStrDictOptions, getIntDictOptions } from '@/utils/dict' +import * as RecordApi from '@/api/point/record' + +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, + bizId: undefined, + bizType: undefined, + type: undefined, + title: undefined, + description: undefined, + point: undefined, + totalPoint: undefined, + status: undefined, + userId: undefined, + freezingTime: undefined, + thawingTime: undefined, + createDate: undefined +}) +const formRules = reactive({ + totalPoint: [{ 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 RecordApi.getRecord(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 unknown as RecordApi.RecordVO + if (formType.value === 'create') { + await RecordApi.createRecord(data) + message.success(t('common.createSuccess')) + } else { + await RecordApi.updateRecord(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: undefined, + bizId: undefined, + bizType: undefined, + type: undefined, + title: undefined, + description: undefined, + point: undefined, + totalPoint: undefined, + status: undefined, + userId: undefined, + freezingTime: undefined, + thawingTime: undefined, + createDate: undefined + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/point/record/index.vue b/src/views/point/record/index.vue new file mode 100644 index 00000000..94db7d92 --- /dev/null +++ b/src/views/point/record/index.vue @@ -0,0 +1,259 @@ +<template> + <ContentWrap> + <!-- 搜索工作栏 --> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="68px" + > + <el-form-item label="业务编码" prop="bizId"> + <el-input + v-model="queryParams.bizId" + placeholder="请输入业务编码" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item label="业务类型" prop="bizType"> + <el-select + v-model="queryParams.bizType" + placeholder="请选择业务类型" + clearable + class="!w-240px" + > + <el-option + v-for="dict in getStrDictOptions(DICT_TYPE.POINT_BIZ_TYPE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="操作类型" prop="type"> + <el-select v-model="queryParams.type" placeholder="操作类型" clearable class="!w-240px"> + <el-option label="增加" value="1" /> + <el-option label="扣减" value="0" /> + </el-select> + </el-form-item> + <el-form-item label="积分标题" prop="title"> + <el-input + v-model="queryParams.title" + placeholder="请输入积分标题" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item label="积分状态" prop="status"> + <el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px"> + <el-option + v-for="dict in getIntDictOptions(DICT_TYPE.POINT_STATUS)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + <el-form-item label="发生时间" prop="createDate"> + <el-date-picker + v-model="queryParams.createDate" + value-format="YYYY-MM-DD HH:mm:ss" + type="daterange" + start-placeholder="开始日期" + end-placeholder="结束日期" + :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" + 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" @click="openForm('create')" v-hasPermi="['point:record:create']"> + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['point:record: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="序号" align="center" prop="id" /> + <el-table-column label="业务编码" align="center" prop="bizId" /> + <el-table-column label="业务类型" align="center" prop="bizType"> + <template #default="scope"> + <dict-tag :type="DICT_TYPE.POINT_BIZ_TYPE" :value="scope.row.bizType" /> + </template> + </el-table-column> + <el-table-column + label="操作类型" + align="center" + prop="type" + :formatter=" + (a, b, c) => { + return c === '1' ? '增加' : '扣减' + } + " + /> + <el-table-column label="积分标题" align="center" prop="title" /> + <el-table-column label="积分描述" align="center" prop="description" /> + <el-table-column label="积分" align="center" prop="point" /> + <el-table-column label="变动后的积分" align="center" prop="totalPoint" /> + <el-table-column label="状态" align="center" prop="status"> + <template #default="scope"> + <dict-tag :type="DICT_TYPE.POINT_STATUS" :value="scope.row.status" /> + </template> + </el-table-column> + <el-table-column label="用户id" align="center" prop="userId" /> + <el-table-column + label="冻结时间" + align="center" + prop="freezingTime" + :formatter="dateFormatter" + /> + <el-table-column + label="解冻时间" + align="center" + prop="thawingTime" + :formatter="dateFormatter" + /> + <el-table-column + label="发生时间" + align="center" + prop="createDate" + :formatter="dateFormatter" + /> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openForm('update', scope.row.id)" + v-hasPermi="['point:record:update']" + > + 编辑 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['point:record:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <RecordForm ref="formRef" @success="getList" /> +</template> + +<script setup lang="ts" name="PointRecord"> +import { DICT_TYPE, getStrDictOptions, getIntDictOptions } from '@/utils/dict' +import { dateFormatter } from '@/utils/formatTime' +import download from '@/utils/download' +import * as RecordApi from '@/api/point/record' +import RecordForm from './RecordForm.vue' +const message = useMessage() // 消息弹窗 +const { t } = useI18n() // 国际化 + +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + bizId: null, + bizType: null, + type: null, + title: null, + status: null, + createDate: [] +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 + +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await RecordApi.getRecordPage(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 RecordApi.deleteRecord(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await RecordApi.exportRecord(queryParams) + download.excel(data, '用户积分记录.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(() => { + getList() +}) +</script> diff --git a/src/views/point/signInConfig/SignInConfigForm.vue b/src/views/point/signInConfig/SignInConfigForm.vue new file mode 100644 index 00000000..345da7df --- /dev/null +++ b/src/views/point/signInConfig/SignInConfigForm.vue @@ -0,0 +1,97 @@ +<template> + <Dialog :title="dialogTitle" v-model="dialogVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="100px" + v-loading="formLoading" + > + <el-form-item label="签到天数" prop="day"> + <el-input-number v-model="formData.day" :min="1" :max="7" :precision="0" /> + <el-text class="mx-1" style="margin-left: 10px" type="danger"> + 只允许设置1-7,默认签到7天为一个周期</el-text + > + </el-form-item> + <el-form-item label="签到分数" prop="point"> + <el-input-number v-model="formData.point" :precision="0" /> + </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"> +import * as SignInConfigApi from '@/api/point/signInConfig' + +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, + day: undefined, + point: undefined +}) +const formRules = reactive({}) +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 SignInConfigApi.getSignInConfig(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 unknown as SignInConfigApi.SignInConfigVO + if (formType.value === 'create') { + await SignInConfigApi.createSignInConfig(data) + message.success(t('common.createSuccess')) + } else { + await SignInConfigApi.updateSignInConfig(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: undefined, + day: undefined, + point: undefined + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/point/signInConfig/index.vue b/src/views/point/signInConfig/index.vue new file mode 100644 index 00000000..cd34d0c9 --- /dev/null +++ b/src/views/point/signInConfig/index.vue @@ -0,0 +1,171 @@ +<template> + <ContentWrap> + <!-- 搜索工作栏 --> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="68px" + > + <el-form-item label="签到天数" prop="day"> + <el-input + v-model="queryParams.day" + 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="['point:sign-in-config:create']" + > + <Icon icon="ep:plus" class="mr-5px" /> 新增 + </el-button> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['point:sign-in-config: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="序号" align="center" prop="id" v-if="false" /> + <el-table-column label="签到天数" align="center" prop="day" /> + <el-table-column label="签到分数" align="center" prop="point" /> + <el-table-column + label="创建时间" + align="center" + prop="createTime" + :formatter="dateFormatter" + /> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openForm('update', scope.row.id)" + v-hasPermi="['point:sign-in-config:update']" + > + 编辑 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['point:sign-in-config:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <SignInConfigForm ref="formRef" @success="getList" /> +</template> + +<script setup lang="ts" name="SignInConfig"> +import { dateFormatter } from '@/utils/formatTime' +import download from '@/utils/download' +import * as SignInConfigApi from '@/api/point/signInConfig' +import SignInConfigForm from './SignInConfigForm.vue' +const message = useMessage() // 消息弹窗 +const { t } = useI18n() // 国际化 + +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + day: null +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 + +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await SignInConfigApi.getSignInConfigPage(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 SignInConfigApi.deleteSignInConfig(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await SignInConfigApi.exportSignInConfig(queryParams) + download.excel(data, '积分签到规则.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(() => { + getList() +}) +</script> diff --git a/src/views/point/signInRecord/SignInRecordForm.vue b/src/views/point/signInRecord/SignInRecordForm.vue new file mode 100644 index 00000000..99f6122b --- /dev/null +++ b/src/views/point/signInRecord/SignInRecordForm.vue @@ -0,0 +1,99 @@ +<template> + <Dialog :title="dialogTitle" v-model="dialogVisible"> + <el-form + ref="formRef" + :model="formData" + :rules="formRules" + label-width="100px" + v-loading="formLoading" + > + <el-form-item label="签到用户" prop="userId"> + <el-input v-model="formData.userId" placeholder="请输入签到用户" /> + </el-form-item> + <el-form-item label="签到天数" prop="day"> + <el-input v-model="formData.day" placeholder="请输入签到天数" /> + </el-form-item> + <el-form-item label="签到的分数" prop="point"> + <el-input v-model="formData.point" placeholder="请输入签到的分数" /> + </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"> +import * as SignInRecordApi from '@/api/point/signInRecord' + +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, + userId: undefined, + day: undefined, + point: undefined +}) +const formRules = reactive({}) +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 SignInRecordApi.getSignInRecord(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 unknown as SignInRecordApi.SignInRecordVO + if (formType.value === 'create') { + await SignInRecordApi.createSignInRecord(data) + message.success(t('common.createSuccess')) + } else { + await SignInRecordApi.updateSignInRecord(data) + message.success(t('common.updateSuccess')) + } + dialogVisible.value = false + // 发送操作成功的事件 + emit('success') + } finally { + formLoading.value = false + } +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { + id: undefined, + userId: undefined, + day: undefined, + point: undefined + } + formRef.value?.resetFields() +} +</script> diff --git a/src/views/point/signInRecord/index.vue b/src/views/point/signInRecord/index.vue new file mode 100644 index 00000000..a79b2987 --- /dev/null +++ b/src/views/point/signInRecord/index.vue @@ -0,0 +1,194 @@ +<template> + <ContentWrap> + <!-- 搜索工作栏 --> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="68px" + > + <el-form-item label="签到用户" prop="userId"> + <el-input + v-model="queryParams.userId" + placeholder="请输入签到用户" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item label="签到天数" prop="day"> + <el-input + v-model="queryParams.day" + placeholder="请输入签到天数" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item label="签到时间" prop="createTime"> + <el-date-picker + v-model="queryParams.createTime" + value-format="YYYY-MM-DD HH:mm:ss" + type="daterange" + start-placeholder="开始日期" + end-placeholder="结束日期" + :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" + 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="['point:sign-in-record:create']"--> + <!-- >--> + <!-- <Icon icon="ep:plus" class="mr-5px" /> 新增--> + <!-- </el-button>--> + <el-button + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['point:sign-in-record: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="序号" align="center" prop="id" /> + <el-table-column label="签到用户" align="center" prop="userId" /> + <el-table-column label="签到天数" align="center" prop="day" /> + <el-table-column label="签到的分数" align="center" prop="point" /> + <el-table-column + label="签到时间" + align="center" + prop="createTime" + :formatter="dateFormatter" + /> + <el-table-column label="操作" align="center"> + <template #default="scope"> + <!-- <el-button--> + <!-- link--> + <!-- type="primary"--> + <!-- @click="openForm('update', scope.row.id)"--> + <!-- v-hasPermi="['point:sign-in-record:update']"--> + <!-- >--> + <!-- 编辑--> + <!-- </el-button>--> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + v-hasPermi="['point:sign-in-record:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + </ContentWrap> + + <!-- 表单弹窗:添加/修改 --> + <SignInRecordForm ref="formRef" @success="getList" /> +</template> + +<script setup lang="ts" name="SignInRecord"> +import { dateFormatter } from '@/utils/formatTime' +import download from '@/utils/download' +import * as SignInRecordApi from '@/api/point/signInRecord' +import SignInRecordForm from './SignInRecordForm.vue' +const message = useMessage() // 消息弹窗 +const { t } = useI18n() // 国际化 + +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + userId: null, + day: null, + createTime: [] +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 + +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await SignInRecordApi.getSignInRecordPage(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 SignInRecordApi.deleteSignInRecord(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await getList() + } catch {} +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await SignInRecordApi.exportSignInRecord(queryParams) + download.excel(data, '用户签到积分.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(() => { + getList() +}) +</script>