├── .env ├── .env.development ├── .env.production ├── .env.testing ├── .eslintrc.cjs ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── index.html ├── package.json ├── public └── favicon.ico ├── src ├── App.vue ├── api │ ├── adminer-notice │ │ └── index.js │ ├── adminer │ │ └── index.js │ ├── auth │ │ └── index.js │ ├── backup │ │ └── index.js │ ├── data-source │ │ └── index.js │ ├── dept │ │ └── index.js │ ├── dict │ │ └── index.js │ ├── error-log │ │ └── index.js │ ├── file │ │ └── index.js │ ├── generator │ │ └── index.js │ ├── home │ │ └── index.js │ ├── index.js │ ├── ip │ │ └── index.js │ ├── job-log │ │ └── index.js │ ├── job │ │ └── index.js │ ├── login-log │ │ └── index.js │ ├── mail-account │ │ └── index.js │ ├── mail-template │ │ └── index.js │ ├── mail │ │ └── index.js │ ├── menu │ │ └── index.js │ ├── notice-template │ │ └── index.js │ ├── notice │ │ └── index.js │ ├── online │ │ └── index.js │ ├── operate-log │ │ └── index.js │ ├── package │ │ └── index.js │ ├── panel │ │ └── index.js │ ├── post │ │ └── index.js │ ├── region │ │ └── index.js │ ├── role │ │ └── index.js │ ├── tenant │ │ └── index.js │ ├── test │ │ └── index.js │ ├── user │ │ └── index.js │ └── wechat-applet │ │ └── index.js ├── assets │ ├── fonts │ │ ├── AppleChancery.ttf │ │ ├── BarbaraHand.ttf │ │ └── SimpleScript.ttf │ └── sass │ │ ├── _animation.scss │ │ ├── _element.scss │ │ ├── _font.scss │ │ ├── _global.scss │ │ ├── _normalize.scss │ │ ├── _root.scss │ │ ├── _transition.scss │ │ ├── _variable.scss │ │ └── index.scss ├── common │ ├── constants │ │ └── index.js │ ├── enums │ │ └── index.js │ └── utils │ │ ├── cache.js │ │ ├── index.js │ │ ├── regular.js │ │ ├── storage.js │ │ ├── uploader.js │ │ └── websocket.js ├── components │ ├── collapse │ │ └── index.vue │ ├── container-custom │ │ └── index.vue │ ├── container-sidebar │ │ └── index.vue │ ├── count-to │ │ ├── index.js │ │ └── index.vue │ ├── editor │ │ ├── quill │ │ │ ├── config.js │ │ │ └── index.vue │ │ └── wang │ │ │ ├── config.js │ │ │ └── index.vue │ ├── global │ │ ├── container │ │ │ └── index.vue │ │ ├── date-range-picker │ │ │ └── index.vue │ │ ├── dict-radio │ │ │ └── index.vue │ │ ├── dict-select │ │ │ └── index.vue │ │ ├── iconfont │ │ │ └── index.vue │ │ ├── index.js │ │ ├── page │ │ │ └── index.vue │ │ ├── test │ │ │ └── index.vue │ │ └── view │ │ │ └── index.vue │ ├── icon-select-input │ │ └── index.vue │ ├── region │ │ └── index.vue │ ├── tenant-sidebar │ │ └── index.vue │ ├── upload-image │ │ └── index.vue │ └── upload │ │ └── index.vue ├── directive │ ├── drag-resize │ │ └── index.js │ ├── index.js │ ├── permission │ │ └── index.js │ ├── repeat │ │ └── index.js │ └── resize │ │ └── index.js ├── hooks │ ├── bind-exposed.js │ ├── dict.js │ └── model.js ├── main.js ├── router │ └── index.js ├── stores │ ├── index.js │ ├── modules │ │ ├── adminer.js │ │ ├── auth.js │ │ ├── dict.js │ │ ├── menu.js │ │ ├── notice.js │ │ ├── tabs.js │ │ ├── theme.js │ │ └── websocket.js │ └── root.js └── views │ ├── constant │ ├── 401.vue │ ├── 404.vue │ ├── 500.vue │ ├── identify.vue │ └── login.vue │ ├── layout │ ├── components │ │ ├── headbar │ │ │ ├── components │ │ │ │ ├── action │ │ │ │ │ └── index.vue │ │ │ │ ├── crumb │ │ │ │ │ └── index.vue │ │ │ │ ├── menu │ │ │ │ │ └── index.vue │ │ │ │ ├── notice │ │ │ │ │ └── index.vue │ │ │ │ └── theme │ │ │ │ │ └── index.vue │ │ │ └── index.vue │ │ ├── logo │ │ │ └── index.vue │ │ ├── navigation │ │ │ ├── active │ │ │ │ └── index.vue │ │ │ └── fixed │ │ │ │ └── index.vue │ │ ├── sidebar │ │ │ ├── components │ │ │ │ ├── classic │ │ │ │ │ └── index.vue │ │ │ │ └── subfield │ │ │ │ │ └── index.vue │ │ │ └── index.vue │ │ ├── sub-menu │ │ │ └── index.vue │ │ ├── tabsbar │ │ │ └── index.vue │ │ └── websocket │ │ │ └── index.vue │ └── index.vue │ └── modules │ ├── develop │ ├── data-source │ │ ├── components │ │ │ └── add-edit.vue │ │ └── index.vue │ ├── dict │ │ ├── components │ │ │ ├── add-edit.vue │ │ │ ├── sidebar.vue │ │ │ └── sub-add-edit.vue │ │ └── index.vue │ ├── generator │ │ └── index.vue │ ├── job │ │ ├── components │ │ │ └── add-edit.vue │ │ └── index.vue │ └── menu │ │ ├── components │ │ └── sidebar.vue │ │ ├── index.js │ │ └── index.vue │ ├── home │ ├── components │ │ ├── applet.vue │ │ ├── interacted.vue │ │ ├── introduction.vue │ │ ├── project.vue │ │ ├── user-counting.vue │ │ ├── user-growth.vue │ │ ├── user-region.vue │ │ └── user-visits.vue │ └── index.vue │ ├── iframe │ └── index.vue │ ├── infrastructure │ ├── backup │ │ ├── components │ │ │ └── details.vue │ │ └── index.vue │ ├── file │ │ ├── config │ │ │ ├── components │ │ │ │ └── add-edit.vue │ │ │ └── index.vue │ │ └── list │ │ │ └── index.vue │ ├── ip │ │ └── index.vue │ ├── mail │ │ ├── account │ │ │ ├── components │ │ │ │ └── add-edit.vue │ │ │ └── index.vue │ │ ├── list │ │ │ ├── components │ │ │ │ ├── details.vue │ │ │ │ └── send.vue │ │ │ └── index.vue │ │ └── template │ │ │ ├── components │ │ │ └── add-edit.vue │ │ │ └── index.vue │ ├── notice │ │ ├── list │ │ │ ├── components │ │ │ │ └── send.vue │ │ │ └── index.vue │ │ └── template │ │ │ ├── components │ │ │ └── add-edit.vue │ │ │ └── index.vue │ ├── online │ │ └── index.vue │ └── region │ │ ├── components │ │ └── add-edit.vue │ │ └── index.vue │ ├── log │ ├── error │ │ ├── components │ │ │ └── details.vue │ │ └── index.vue │ ├── job │ │ └── index.vue │ ├── login │ │ └── index.vue │ └── operate │ │ └── index.vue │ ├── nest-router │ ├── index.vue │ └── modules │ │ ├── router1.vue │ │ └── router2.vue │ ├── personal │ ├── components │ │ ├── basic-info.vue │ │ ├── edit-password.vue │ │ ├── info-panel.vue │ │ ├── login-log.vue │ │ ├── notice.vue │ │ └── operate-log.vue │ └── index.vue │ ├── system │ ├── adminer │ │ ├── components │ │ │ ├── add-edit.vue │ │ │ ├── set-role.vue │ │ │ └── sidebar.vue │ │ └── index.vue │ ├── dept │ │ ├── components │ │ │ ├── add-edit.vue │ │ │ ├── set-data-permission.vue │ │ │ └── set-menu-permission.vue │ │ └── index.vue │ ├── package │ │ ├── components │ │ │ └── add-edit.vue │ │ └── index.vue │ ├── post │ │ ├── components │ │ │ └── add-edit.vue │ │ └── index.vue │ ├── role │ │ ├── components │ │ │ ├── add-edit.vue │ │ │ ├── set-data-permission.vue │ │ │ └── set-menu-permission.vue │ │ └── index.vue │ └── tenant │ │ ├── components │ │ └── add-edit.vue │ │ └── index.vue │ ├── test │ ├── components │ │ └── add-edit.vue │ └── index.vue │ ├── user │ ├── details │ │ └── index.vue │ └── list │ │ └── index.vue │ └── wechat │ └── applet │ ├── components │ └── add-edit.vue │ └── index.vue └── vite.config.js /.env: -------------------------------------------------------------------------------- 1 | # 项目启动端口 2 | VITE_PORT = '9585' 3 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmingchen/agile-admin/e6f5db8f28be74de5dce9436881373cee519420a/.env.development -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.env.testing: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | dist.zip 5 | admin 6 | admin.zip 7 | deploy 8 | 9 | 10 | # local env files 11 | .env.local 12 | .env.*.local 13 | package-lock.json 14 | .eslintrc-auto-import.json 15 | 16 | # Log files 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | pnpm-debug.log* 21 | 22 | # Editor directories and files 23 | .idea 24 | .vscode 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | 31 | # # 表示此为注释,将被Git忽略 32 | # *.a 表示忽略所有 .a 结尾的文件 33 | # !lib.a 表示但lib.a除外 34 | # /TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO 35 | # build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹; 36 | # doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt 37 | # bin/: 表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件 38 | # /bin: 表示忽略根目录下的bin文件 39 | # /*.c: 表示忽略cat.c,不忽略 build/cat.c 40 | # debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj 41 | # **/foo: 表示忽略/foo,a/foo,a/b/foo等 42 | # a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等 43 | # !/bin/run.sh 表示不忽略bin目录下的run.sh文件 44 | # *.log: 表示忽略所有 .log 文件 45 | # config.php: 表示忽略当前路径的 config.php 文件 46 | # /mtk/ 表示过滤整个文件夹 47 | # *.zip 表示过滤所有.zip文件 48 | # /mtk/do.c 表示过滤某个具体文件 49 | # 被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。 50 | # 需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下: 51 | # !*.zip 52 | # !/mtk/one.txt 53 | # 唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。为什么要有两种规则呢? 54 | # 想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么.gitignore规则应写为:: 55 | # /mtk/* 56 | # !/mtk/one.txt 57 | # 假设我们只有过滤规则,而没有添加规则,那么我们就需要把/mtk/目录下除了one.txt以外的所有文件都写出来! 58 | # 注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效! 59 | # ---------------------------------------------------------------------------------- 60 | # 还有一些规则如下: 61 | # fd1/* 62 | # 说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略; 63 | # /fd1/* 64 | # 说明:忽略根目录下的 /fd1/ 目录的全部内容; 65 | # /* 66 | # !.gitignore 67 | # !/fw/ 68 | # /fw/* 69 | # !/fw/bin/ 70 | # !/fw/sf/ 71 | # 说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;注意要先对bin/的父目录使用!规则,使其不被排除。 72 | # git rm -r --cached . 清除缓存 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 1240235512 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 63 | 72 | 73 | 74 |
75 |

76 | A 77 | g 78 | i 79 | l 80 | e 81 | A 82 | d 83 | m 84 | i 85 | n 86 |

87 |
88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-element-plus-admin", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite --mode development --host", 6 | "prod": "vite --mode production", 7 | "test": "vite --mode testing", 8 | "build:dev": "vite build --mode development", 9 | "build:prod": "vite build --mode production", 10 | "build:test": "vite build --mode testing", 11 | "deploy": "vite build --mode production && cross-env NODE_ENV=production node ./deploy", 12 | "preview": "vite preview --port 4173", 13 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore" 14 | }, 15 | "dependencies": { 16 | "@vueuse/core": "^10.11.0", 17 | "@wangeditor/editor-for-vue": "^5.1.12", 18 | "axios": "^1.7.2", 19 | "codemirror-editor-vue3": "^2.1.7", 20 | "element-plus": "^2.7.2", 21 | "js-cookie": "^3.0.5", 22 | "json-editor-vue3": "^1.0.8", 23 | "nprogress": "^0.2.0", 24 | "pinia": "^2.1.7", 25 | "spark-md5": "^3.0.2", 26 | "vue": "^3.4.31", 27 | "vue-router": "^4.4.0" 28 | }, 29 | "devDependencies": { 30 | "@vitejs/plugin-vue": "^5.0.5", 31 | "@vitejs/plugin-vue-jsx": "^4.0.0", 32 | "cross-env": "^7.0.3", 33 | "echarts": "^5.4.2", 34 | "eslint": "^8.57.0", 35 | "eslint-plugin-vue": "^9.27.0", 36 | "ora": "^5.4.1", 37 | "qs": "^6.11.1", 38 | "sass": "^1.77.6", 39 | "sass-loader": "^14.2.1", 40 | "scp2": "^0.5.0", 41 | "unplugin-auto-import": "^0.17.6", 42 | "unplugin-vue-components": "^0.27.0", 43 | "vite": "^5.3.3", 44 | "vite-plugin-vue-devtools": "^7.3.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmingchen/agile-admin/e6f5db8f28be74de5dce9436881373cee519420a/public/favicon.ico -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | 20 | 32 | -------------------------------------------------------------------------------- /src/api/adminer-notice/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 管理员-通知 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-05-15 17:24:38 6 | */ 7 | import service from '..' 8 | 9 | /** 10 | * @description: 分页列表 11 | * @param {*} 12 | * @return {*} 13 | */ 14 | export function pageApi(params) { 15 | return service({ 16 | url: '/admin/adminer/notice/page', 17 | method: 'get', 18 | params: params 19 | }) 20 | } 21 | 22 | /** 23 | * @description: 分页列表 24 | * @param {*} 25 | * @return {*} 26 | */ 27 | export function unreadPageApi(params) { 28 | return service({ 29 | url: '/admin/adminer/notice/unread/page', 30 | method: 'get', 31 | params: params 32 | }) 33 | } 34 | 35 | /** 36 | * @description: 删除 37 | * @param {*} 38 | * @return {*} 39 | */ 40 | export function deleteApi(data) { 41 | return service({ 42 | url: '/admin/adminer/notice/delete', 43 | method: 'post', 44 | data 45 | }) 46 | } 47 | 48 | /** 49 | * @description: 设置已读 50 | * @param {*} 51 | * @return {*} 52 | */ 53 | export function statusApi(data) { 54 | return service({ 55 | url: '/admin/adminer/notice/status', 56 | method: 'post', 57 | data 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /src/api/adminer/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/adminer/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/adminer/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/adminer/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/adminer/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/adminer/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/adminer/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 设置角色 84 | * @param {*} data 85 | * @returns 86 | */ 87 | export function setRoleApi(data) { 88 | return service({ 89 | url: '/admin/adminer/role', 90 | method: 'post', 91 | data 92 | }) 93 | } 94 | 95 | /** 96 | * 重置密码 97 | * @param {*} data 98 | * @returns 99 | */ 100 | export function resetPasswordApi(data) { 101 | return service({ 102 | url: '/admin/adminer/reset', 103 | method: 'post', 104 | data 105 | }) 106 | } 107 | 108 | /** 109 | * 选择列表 110 | * @param {*} data 111 | * @returns 112 | */ 113 | export function selectApi(params) { 114 | return service({ 115 | url: '/admin/adminer/select', 116 | method: 'get', 117 | params 118 | }) 119 | } 120 | 121 | /** 122 | * 导出 123 | * @returns 124 | */ 125 | export async function exportApi(params) { 126 | const r = await service({ 127 | url: 'admin/adminer/export', 128 | method: 'get', 129 | responseType: 'blob', 130 | params 131 | }) 132 | if (r) { 133 | const { blob, name } = r 134 | download(blob, name) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/api/auth/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * 登录验证码 5 | * @param {*} params 6 | * @returns 7 | */ 8 | export function captchaApi(params) { 9 | return service({ 10 | url: '/admin/auth/captcha', 11 | method: 'get', 12 | params 13 | }) 14 | } 15 | /** 16 | * 登录 17 | * @param {*} data 18 | * @returns 19 | */ 20 | export function loginApi(data) { 21 | return service({ 22 | url: '/admin/auth/login', 23 | method: 'post', 24 | data 25 | }) 26 | } 27 | /** 28 | * 获取登录管理员信息 29 | * @param {*} data 30 | * @returns 31 | */ 32 | export function adminerInfoApi() { 33 | return service({ 34 | url: '/admin/auth/info', 35 | method: 'get' 36 | }) 37 | } 38 | /** 39 | * 获取登录管理员菜单权限 40 | * @param {*} data 41 | * @returns 42 | */ 43 | export function adminerMenuApi() { 44 | return service({ 45 | url: '/admin/auth/menu', 46 | method: 'get' 47 | }) 48 | } 49 | /** 50 | * 修改基础信息 51 | * @param {*} data 52 | * @returns 53 | */ 54 | export function updateBasicApi(data) { 55 | return service({ 56 | url: '/admin/auth/update/basic', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | /** 62 | * 修改密码 63 | * @param {*} data 64 | * @returns 65 | */ 66 | export function updatePasswordApi(data) { 67 | return service({ 68 | url: '/admin/auth/update/password', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | /** 74 | * 退出登录 75 | * @param {*} data 76 | * @returns 77 | */ 78 | export function logoutApi() { 79 | return service({ 80 | url: '/admin/auth/logout', 81 | method: 'post' 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /src/api/backup/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 数据库备份 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-02 13:17:23 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/backup/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/backup/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 删除 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function deleteApi(data) { 42 | return service({ 43 | url: '/admin/backup/delete', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 备份 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function backupApi() { 55 | return service({ 56 | url: '/admin/backup/backup', 57 | method: 'post' 58 | }) 59 | } 60 | 61 | /** 62 | * @description: 恢复 63 | * @param {*} 64 | * @return {*} 65 | */ 66 | export function recoveryApi(data) { 67 | return service({ 68 | url: '/admin/backup/recovery', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | 74 | /** 75 | * 导出 76 | * @returns 77 | */ 78 | export async function exportApi(params) { 79 | const r = await service({ 80 | url: 'admin/backup/export', 81 | method: 'get', 82 | responseType: 'blob', 83 | params 84 | }) 85 | if (r) { 86 | const { blob, name } = r 87 | download(blob, name) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/api/data-source/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 数据源 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-16 11:22:49 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/datasource/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/datasource/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/datasource/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/datasource/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/datasource/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * @description: 状态切换 77 | * @param {*} 78 | * @return {*} 79 | */ 80 | export function setStatusApi(data) { 81 | return service({ 82 | url: '/admin/datasource/status', 83 | method: 'post', 84 | data 85 | }) 86 | } 87 | 88 | /** 89 | * @description: 选择列表 90 | * @param {*} 91 | * @return {*} 92 | */ 93 | export function selectApi(params) { 94 | return service({ 95 | url: '/admin/datasource/select', 96 | method: 'get', 97 | params 98 | }) 99 | } 100 | 101 | /** 102 | * 导出 103 | * @returns 104 | */ 105 | export async function exportApi(params) { 106 | const r = await service({ 107 | url: '/admin/datasource/export', 108 | method: 'get', 109 | responseType: 'blob', 110 | params 111 | }) 112 | if (r) { 113 | const { blob, name } = r 114 | download(blob, name) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/dept/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 列表 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function listApi(params) { 10 | return service({ 11 | url: '/admin/dept/list', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/dept/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/dept/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/dept/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/dept/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/dept/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 设置数据权限 84 | * @param {*} data 85 | * @returns 86 | */ 87 | export function setDataPermissionApi(data) { 88 | return service({ 89 | url: '/admin/dept/data', 90 | method: 'post', 91 | data 92 | }) 93 | } 94 | 95 | /** 96 | * 选择列表 97 | * @param {*} data 98 | * @returns 99 | */ 100 | export function selectApi(params) { 101 | return service({ 102 | url: '/admin/dept/select', 103 | method: 'get', 104 | params 105 | }) 106 | } 107 | 108 | /** 109 | * 导出 110 | * @returns 111 | */ 112 | export async function exportApi(params) { 113 | const r = await service({ 114 | url: 'admin/dept/export', 115 | method: 'get', 116 | responseType: 'blob', 117 | params 118 | }) 119 | if (r) { 120 | const { blob, name } = r 121 | download(blob, name) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/api/dict/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * 所有数据 5 | * @returns 6 | */ 7 | export function listApi() { 8 | return service({ 9 | url: '/admin/dict/list', 10 | method: 'get' 11 | }) 12 | } 13 | 14 | /** 15 | * 详情 16 | * @param {*} params 17 | * @returns 18 | */ 19 | export function infoApi(params) { 20 | return service({ 21 | url: '/admin/dict/info', 22 | method: 'get', 23 | params 24 | }) 25 | } 26 | 27 | /** 28 | * 新增 29 | * @param {*} data 30 | * @returns 31 | */ 32 | export function createApi(data) { 33 | return service({ 34 | url: '/admin/dict/create', 35 | method: 'post', 36 | data 37 | }) 38 | } 39 | 40 | /** 41 | * 更新 42 | * @param {*} data 43 | * @returns 44 | */ 45 | export function updateApi(data) { 46 | return service({ 47 | url: '/admin/dict/update', 48 | method: 'post', 49 | data 50 | }) 51 | } 52 | 53 | /** 54 | * 删除 55 | * @param {*} data 56 | * @returns 57 | */ 58 | export function deleteApi(data) { 59 | return service({ 60 | url: '/admin/dict/delete', 61 | method: 'post', 62 | data 63 | }) 64 | } 65 | 66 | /* ****************************************************************************************** */ 67 | 68 | /** 69 | * 副表所有数据 70 | * @param {*} params 71 | * @returns 72 | */ 73 | export function subListApi(params) { 74 | return service({ 75 | url: '/admin/dict/sub/list', 76 | method: 'get', 77 | params 78 | }) 79 | } 80 | 81 | /** 82 | * 详情 83 | * @param {*} params 84 | * @returns 85 | */ 86 | export function subInfoApi(params) { 87 | return service({ 88 | url: '/admin/dict/sub/info', 89 | method: 'get', 90 | params 91 | }) 92 | } 93 | 94 | /** 95 | * 新增 96 | * @param {*} data 97 | * @returns 98 | */ 99 | export function subCreateApi(data) { 100 | return service({ 101 | url: '/admin/dict/sub/create', 102 | method: 'post', 103 | data 104 | }) 105 | } 106 | 107 | /** 108 | * 更新 109 | * @param {*} data 110 | * @returns 111 | */ 112 | export function subUpdateApi(data) { 113 | return service({ 114 | url: '/admin/dict/sub/update', 115 | method: 'post', 116 | data 117 | }) 118 | } 119 | 120 | /** 121 | * 删除 122 | * @param {*} data 123 | * @returns 124 | */ 125 | export function subDeleteApi(data) { 126 | return service({ 127 | url: '/admin/dict/sub/delete', 128 | method: 'post', 129 | data 130 | }) 131 | } 132 | 133 | /** 134 | * 状态切换 135 | * @param {*} data 136 | * @returns 137 | */ 138 | export function subSetStatusApi(data) { 139 | return service({ 140 | url: '/admin/dict/sub/status', 141 | method: 'post', 142 | data 143 | }) 144 | } 145 | 146 | /** 147 | * 通过字典编码查询有效数据 148 | * @param {*} data 149 | * @returns 150 | */ 151 | export function subSelectListApi(data) { 152 | return service({ 153 | url: '/admin/dict/sub/select/list', 154 | method: 'post', 155 | data 156 | }) 157 | } 158 | -------------------------------------------------------------------------------- /src/api/error-log/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * @description: 分页 6 | * @param {*} 7 | * @return {*} 8 | * @author: gumingchen 9 | */ 10 | export function pageApi(params) { 11 | return service({ 12 | url: '/admin/log/error/page', 13 | method: 'get', 14 | params: params 15 | }) 16 | } 17 | 18 | /** 19 | * @description: 信息 20 | * @param {*} 21 | * @return {*} 22 | * @author: gumingchen 23 | */ 24 | export function infoApi(params) { 25 | return service({ 26 | url: '/admin/log/error/info', 27 | method: 'get', 28 | params: params 29 | }) 30 | } 31 | 32 | /** 33 | * 导出 34 | * @returns 35 | */ 36 | export async function exportApi(params) { 37 | const r = await service({ 38 | url: 'admin/log/error/export', 39 | method: 'get', 40 | responseType: 'blob', 41 | params 42 | }) 43 | if (r) { 44 | const { blob, name } = r 45 | download(blob, name) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/api/file/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { parseJson2Param, download } from '@utils' 3 | import { ContentType } from '@enums' 4 | import { MAPPING } from '@constants' 5 | 6 | /** 7 | * 配置分页 8 | * @param {*} params 9 | * @returns 10 | */ 11 | export function configPageApi(params) { 12 | return service({ 13 | url: '/admin/file/config/page', 14 | method: 'get', 15 | params 16 | }) 17 | } 18 | 19 | /** 20 | * 详情 21 | * @param {*} params 22 | * @returns 23 | */ 24 | export function configInfoApi(params) { 25 | return service({ 26 | url: '/admin/file/config/info', 27 | method: 'get', 28 | params 29 | }) 30 | } 31 | 32 | /** 33 | * 新增 34 | * @param {*} data 35 | * @returns 36 | */ 37 | export function configCreateApi(data) { 38 | return service({ 39 | url: '/admin/file/config/create', 40 | method: 'post', 41 | data 42 | }) 43 | } 44 | 45 | /** 46 | * 更新 47 | * @param {*} data 48 | * @returns 49 | */ 50 | export function configUpdateApi(data) { 51 | return service({ 52 | url: '/admin/file/config/update', 53 | method: 'post', 54 | data 55 | }) 56 | } 57 | 58 | /** 59 | * 删除 60 | * @param {*} data 61 | * @returns 62 | */ 63 | export function configDeleteApi(data) { 64 | return service({ 65 | url: '/admin/file/config/delete', 66 | method: 'post', 67 | data 68 | }) 69 | } 70 | 71 | /** 72 | * 设置主配置 73 | * @param {*} data 74 | * @returns 75 | */ 76 | export function configSetMasterApi(data) { 77 | return service({ 78 | url: '/admin/file/config/master', 79 | method: 'post', 80 | data 81 | }) 82 | } 83 | 84 | /** 85 | * 导出 86 | * @returns 87 | */ 88 | export async function configExportApi(params) { 89 | const r = await service({ 90 | url: 'admin/file/config/export', 91 | method: 'get', 92 | responseType: 'blob', 93 | params 94 | }) 95 | if (r) { 96 | const { blob, name } = r 97 | download(blob, name) 98 | } 99 | } 100 | 101 | /* ****************************************************************************************** */ 102 | 103 | /** 104 | * @description: 分页列表 105 | * @param {*} 106 | * @return {*} 107 | * @author: gumingchen 108 | */ 109 | export function pageApi(params) { 110 | return service({ 111 | url: '/admin/file/page', 112 | method: 'get', 113 | params: params 114 | }) 115 | } 116 | 117 | /** 118 | * @description: 上传 119 | * @param {*} 120 | * @return {*} 121 | * @author: gumingchen 122 | */ 123 | export function uploadUrlApi(params) { 124 | let result = '' 125 | const options = { 126 | url: '/admin/file/upload', 127 | method: 'post', 128 | params: params 129 | } 130 | result = `${ MAPPING + options.url }${ options.params ? parseJson2Param(options.params) : '' }` 131 | return result 132 | } 133 | 134 | /** 135 | * @description: 文件上传 136 | * @param {*} 137 | * @return {*} 138 | * @author: gumingchen 139 | */ 140 | export function uploadApi(params) { 141 | const formData = new FormData() 142 | for (const key in params) { 143 | formData.append(key, params[key]) 144 | } 145 | return service({ 146 | url: '/admin/file/upload', 147 | method: 'post', 148 | data: formData, 149 | headers: { 150 | 'Content-Type': ContentType.UPLOAD 151 | } 152 | }) 153 | } 154 | 155 | /** 156 | * @description: 删除 157 | * @param {*} params 158 | * @return {*} 159 | * @author: gumingchen 160 | */ 161 | export function deleteApi(params) { 162 | return service({ 163 | url: '/admin/file/delete', 164 | method: 'post', 165 | data: params 166 | }) 167 | } 168 | -------------------------------------------------------------------------------- /src/api/generator/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * @description: 表格分页列表 6 | * @param {*} 7 | * @return {*} 8 | * @author: gumingchen 9 | */ 10 | export function pageApi(params) { 11 | return service({ 12 | url: '/admin/generator/page', 13 | method: 'get', 14 | params 15 | }) 16 | } 17 | 18 | /** 19 | * @description: 代码生成 20 | * @param {*} 21 | * @return {*} 22 | * @author: gumingchen 23 | */ 24 | export async function generateApi(data) { 25 | const r = await service({ 26 | url: '/admin/generator/generate', 27 | method: 'post', 28 | responseType: 'blob', 29 | data 30 | }) 31 | if (r) { 32 | const { blob, name } = r 33 | download(blob, name) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/api/home/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * 用户量统计 5 | * @param {*} params 6 | * @returns 7 | */ 8 | export function userCountingApi(params) { 9 | return service({ 10 | url: '/admin/home/user/counting', 11 | method: 'get', 12 | params 13 | }) 14 | } 15 | 16 | /** 17 | * 用户区域统计 18 | * @param {*} params 19 | * @returns 20 | */ 21 | export function userRegionApi(params) { 22 | return service({ 23 | url: '/admin/home/user/region', 24 | method: 'get', 25 | params 26 | }) 27 | } 28 | 29 | /** 30 | * 近一个月用户访问量统计 31 | * @param {*} params 32 | * @returns 33 | */ 34 | export function userVisitsApi(params) { 35 | return service({ 36 | url: '/admin/home/user/visits', 37 | method: 'get', 38 | params 39 | }) 40 | } 41 | 42 | /** 43 | * 近一个月用户增长量统计 44 | * @param {*} params 45 | * @returns 46 | */ 47 | export function userGrowthApi(params) { 48 | return service({ 49 | url: '/admin/home/user/growth', 50 | method: 'get', 51 | params 52 | }) 53 | } 54 | -------------------------------------------------------------------------------- /src/api/ip/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: IP地址 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-03 15:28:12 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/ip/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * 导出 25 | * @returns 26 | */ 27 | export async function exportApi(params) { 28 | const r = await service({ 29 | url: 'admin/ip/export', 30 | method: 'get', 31 | responseType: 'blob', 32 | params 33 | }) 34 | if (r) { 35 | const { blob, name } = r 36 | download(blob, name) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/api/job-log/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * @description: 分页 6 | * @param {*} 7 | * @return {*} 8 | * @author: gumingchen 9 | */ 10 | export function pageApi(params) { 11 | return service({ 12 | url: '/admin/log/job/page', 13 | method: 'get', 14 | params: params 15 | }) 16 | } 17 | 18 | /** 19 | * 导出 20 | * @returns 21 | */ 22 | export async function exportApi(params) { 23 | const r = await service({ 24 | url: 'admin/log/job/export', 25 | method: 'get', 26 | responseType: 'blob', 27 | params 28 | }) 29 | if (r) { 30 | const { blob, name } = r 31 | download(blob, name) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/api/job/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * 配置分页 5 | * @param {*} params 6 | * @returns 7 | */ 8 | export function pageApi(params) { 9 | return service({ 10 | url: '/admin/job/page', 11 | method: 'get', 12 | params 13 | }) 14 | } 15 | 16 | /** 17 | * 详情 18 | * @param {*} params 19 | * @returns 20 | */ 21 | export function infoApi(params) { 22 | return service({ 23 | url: '/admin/job/info', 24 | method: 'get', 25 | params 26 | }) 27 | } 28 | 29 | /** 30 | * 新增 31 | * @param {*} data 32 | * @returns 33 | */ 34 | export function createApi(data) { 35 | return service({ 36 | url: '/admin/job/create', 37 | method: 'post', 38 | data 39 | }) 40 | } 41 | 42 | /** 43 | * 更新 44 | * @param {*} data 45 | * @returns 46 | */ 47 | export function updateApi(data) { 48 | return service({ 49 | url: '/admin/job/update', 50 | method: 'post', 51 | data 52 | }) 53 | } 54 | 55 | /** 56 | * 删除 57 | * @param {*} data 58 | * @returns 59 | */ 60 | export function deleteApi(data) { 61 | return service({ 62 | url: '/admin/job/delete', 63 | method: 'post', 64 | data 65 | }) 66 | } 67 | 68 | /** 69 | * 执行 70 | * @param {*} data 71 | * @returns 72 | */ 73 | export function runApi(data) { 74 | return service({ 75 | url: '/admin/job/run', 76 | method: 'post', 77 | data 78 | }) 79 | } 80 | 81 | /** 82 | * 恢复 83 | * @param {*} data 84 | * @returns 85 | */ 86 | export function resumeApi(data) { 87 | return service({ 88 | url: '/admin/job/resume', 89 | method: 'post', 90 | data 91 | }) 92 | } 93 | 94 | /** 95 | * 暂停 96 | * @param {*} data 97 | * @returns 98 | */ 99 | export function pauseApi(data) { 100 | return service({ 101 | url: '/admin/job/pause', 102 | method: 'post', 103 | data 104 | }) 105 | } 106 | 107 | -------------------------------------------------------------------------------- /src/api/login-log/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/log/login/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 当前管理员最近登录日志列表 19 | * @returns 20 | */ 21 | export function latestApi() { 22 | return service({ 23 | url: '/admin/log/login/latest', 24 | method: 'get' 25 | }) 26 | } 27 | 28 | /** 29 | * 导出 30 | * @returns 31 | */ 32 | export async function exportApi(params) { 33 | const r = await service({ 34 | url: '/admin/log/login/export', 35 | method: 'get', 36 | responseType: 'blob', 37 | params 38 | }) 39 | if (r) { 40 | const { blob, name } = r 41 | download(blob, name) 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/api/mail-account/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 邮箱帐号 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-05-30 10:03:49 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/mail/account/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/mail/account/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/mail/account/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/mail/account/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/mail/account/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * 设置主配置 77 | * @param {*} data 78 | * @returns 79 | */ 80 | export function setMasterApi(data) { 81 | return service({ 82 | url: '/admin/mail/account/master', 83 | method: 'post', 84 | data 85 | }) 86 | } 87 | 88 | /** 89 | * 导出 90 | * @returns 91 | */ 92 | export async function exportApi(params) { 93 | const r = await service({ 94 | url: 'admin/mail/account/export', 95 | method: 'get', 96 | responseType: 'blob', 97 | params 98 | }) 99 | if (r) { 100 | const { blob, name } = r 101 | download(blob, name) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/api/mail-template/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 邮箱模版 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-05-30 18:52:43 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/mail/template/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/mail/template/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/mail/template/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/mail/template/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/mail/template/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * @description: 状态切换 77 | * @param {*} 78 | * @return {*} 79 | */ 80 | export function setStatusApi(data) { 81 | return service({ 82 | url: '/admin/mail/template/status', 83 | method: 'post', 84 | data 85 | }) 86 | } 87 | 88 | /** 89 | * @description: 选择列表 90 | * @param {*} 91 | * @return {*} 92 | */ 93 | export function selectApi(params) { 94 | return service({ 95 | url: '/admin/mail/template/select', 96 | method: 'get', 97 | params: params 98 | }) 99 | } 100 | 101 | /** 102 | * 导出 103 | * @returns 104 | */ 105 | export async function exportApi(params) { 106 | const r = await service({ 107 | url: 'admin/mail/template/export', 108 | method: 'get', 109 | responseType: 'blob', 110 | params 111 | }) 112 | if (r) { 113 | const { blob, name } = r 114 | download(blob, name) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/mail/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 邮件记录 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-01 09:16:10 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/mail/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/mail/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 删除 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function deleteApi(data) { 42 | return service({ 43 | url: '/admin/mail/delete', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 推送 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function sendApi(data) { 55 | return service({ 56 | url: '/admin/mail/send', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * 导出 64 | * @returns 65 | */ 66 | export async function exportApi(params) { 67 | const r = await service({ 68 | url: 'admin/mail/export', 69 | method: 'get', 70 | responseType: 'blob', 71 | params 72 | }) 73 | if (r) { 74 | const { blob, name } = r 75 | download(blob, name) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/api/menu/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * @description: 获取所有菜单 5 | * @param {*} 6 | * @return {*} 7 | * @author: gumingchen 8 | */ 9 | export function listApi() { 10 | return service({ 11 | url: '/admin/menu/list', 12 | method: 'get' 13 | }) 14 | } 15 | 16 | /** 17 | * @description: 信息 18 | * @param {*} 19 | * @return {*} 20 | * @author: gumingchen 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/menu/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * @description: 新增 32 | * @param {*} 33 | * @return {*} 34 | * @author: gumingchen 35 | */ 36 | export function createApi(params) { 37 | return service({ 38 | url: `/admin/menu/create`, 39 | method: 'post', 40 | data: params 41 | }) 42 | } 43 | 44 | /** 45 | * @description: 编辑 46 | * @param {*} 47 | * @return {*} 48 | * @author: gumingchen 49 | */ 50 | export function updateApi(params) { 51 | return service({ 52 | url: `/admin/menu/update`, 53 | method: 'post', 54 | data: params 55 | }) 56 | } 57 | 58 | /** 59 | * @description: 删除 60 | * @param {*} 61 | * @return {*} 62 | * @author: gumingchen 63 | */ 64 | export function deleteApi(params) { 65 | return service({ 66 | url: `/admin/menu/delete`, 67 | method: 'post', 68 | data: params 69 | }) 70 | } 71 | 72 | /** 73 | * @description: 拖拽 更新 父级ID 和 排序 74 | * @param {*} 75 | * @return {*} 76 | * @author: gumingchen 77 | */ 78 | export function dragApi(params) { 79 | return service({ 80 | url: `/admin/menu/drag`, 81 | method: 'post', 82 | data: params 83 | }) 84 | } 85 | 86 | /** 87 | * @description: 获取未禁用的所有菜单 88 | * @param {*} 89 | * @return {*} 90 | * @author: gumingchen 91 | */ 92 | export function selectApi() { 93 | return service({ 94 | url: '/admin/menu/select', 95 | method: 'get' 96 | }) 97 | } 98 | -------------------------------------------------------------------------------- /src/api/notice-template/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 消息通知(站内通知) 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-05-13 08:54:12 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/notice/template/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/notice/template/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/notice/template/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/notice/template/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/notice/template/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * @description: 状态切换 77 | * @param {*} 78 | * @return {*} 79 | */ 80 | export function setStatusApi(data) { 81 | return service({ 82 | url: '/admin/notice/template/status', 83 | method: 'post', 84 | data 85 | }) 86 | } 87 | 88 | /** 89 | * @description: 选择列表 90 | * @param {*} 91 | * @return {*} 92 | */ 93 | export function selectApi(params) { 94 | return service({ 95 | url: '/admin/notice/template/select', 96 | method: 'get', 97 | params: params 98 | }) 99 | } 100 | 101 | /** 102 | * 导出 103 | * @returns 104 | */ 105 | export async function exportApi(params) { 106 | const r = await service({ 107 | url: 'admin/notice/template/export', 108 | method: 'get', 109 | responseType: 'blob', 110 | params 111 | }) 112 | if (r) { 113 | const { blob, name } = r 114 | download(blob, name) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/notice/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 消息通知(站内通知) 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-05-15 17:24:38 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/notice/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 删除 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function deleteApi(data) { 29 | return service({ 30 | url: '/admin/notice/delete', 31 | method: 'post', 32 | data 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 推送 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function pushApi(data) { 42 | return service({ 43 | url: '/admin/notice/push', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * 导出 51 | * @returns 52 | */ 53 | export async function exportApi(params) { 54 | const r = await service({ 55 | url: 'admin/notice/export', 56 | method: 'get', 57 | responseType: 'blob', 58 | params 59 | }) 60 | if (r) { 61 | const { blob, name } = r 62 | download(blob, name) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/api/online/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | 3 | /** 4 | * 分页 5 | * @param {*} params 6 | * @returns 7 | */ 8 | export function pageApi(params) { 9 | return service({ 10 | url: '/admin/online/page', 11 | method: 'get', 12 | params 13 | }) 14 | } 15 | 16 | /** 17 | * 强制退出 18 | * @param {*} data 19 | * @returns 20 | */ 21 | export function logoutApi(data) { 22 | return service({ 23 | url: '/admin/online/logout', 24 | method: 'post', 25 | data 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /src/api/operate-log/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/log/operate/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 当前管理员最近操作日志列表 19 | * @returns 20 | */ 21 | export function latestApi() { 22 | return service({ 23 | url: '/admin/log/operate/latest', 24 | method: 'get' 25 | }) 26 | } 27 | 28 | /** 29 | * 导出 30 | * @returns 31 | */ 32 | export async function exportApi(params) { 33 | const r = await service({ 34 | url: 'admin/log/operate/export', 35 | method: 'get', 36 | responseType: 'blob', 37 | params 38 | }) 39 | if (r) { 40 | const { blob, name } = r 41 | download(blob, name) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/api/package/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 配置分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/package/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/package/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/package/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/package/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/package/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/package/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 选择列表 84 | * @param {*} data 85 | * @returns 86 | */ 87 | export function selectApi() { 88 | return service({ 89 | url: '/admin/package/select', 90 | method: 'get' 91 | }) 92 | } 93 | 94 | /** 95 | * 导出 96 | * @returns 97 | */ 98 | export async function exportApi(params) { 99 | const r = await service({ 100 | url: 'admin/package/export', 101 | method: 'get', 102 | responseType: 'blob', 103 | params 104 | }) 105 | if (r) { 106 | const { blob, name } = r 107 | download(blob, name) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/api/panel/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * @description: 分页列表 6 | * @param {*} 7 | * @return {*} 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/panel/page', 12 | method: 'get', 13 | params: params 14 | }) 15 | } 16 | 17 | /** 18 | * @description: 信息 19 | * @param {*} 20 | * @return {*} 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/panel/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * @description: 新增 32 | * @param {*} 33 | * @return {*} 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/panel/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * @description: 更新 45 | * @param {*} 46 | * @return {*} 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/panel/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * @description: 删除 58 | * @param {*} 59 | * @return {*} 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/panel/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * @description: 状态切换 71 | * @param {*} 72 | * @return {*} 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/panel/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 导出 84 | * @returns 85 | */ 86 | export async function exportApi(params) { 87 | const r = await service({ 88 | url: '/admin/panel/export', 89 | method: 'get', 90 | responseType: 'blob', 91 | params 92 | }) 93 | if (r) { 94 | const { blob, name } = r 95 | download(blob, name) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/api/post/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/post/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/post/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/post/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/post/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/post/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/post/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 选择列表 84 | * @param {*} data 85 | * @returns 86 | */ 87 | export function selectApi() { 88 | return service({ 89 | url: '/admin/post/select', 90 | method: 'get' 91 | }) 92 | } 93 | 94 | /** 95 | * 导出 96 | * @returns 97 | */ 98 | export async function exportApi(params) { 99 | const r = await service({ 100 | url: 'admin/post/export', 101 | method: 'get', 102 | responseType: 'blob', 103 | params 104 | }) 105 | if (r) { 106 | const { blob, name } = r 107 | download(blob, name) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/api/region/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 全国区域 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-02 09:14:46 6 | */ 7 | import service from '..' 8 | 9 | /** 10 | * @description: 分页列表 11 | * @param {*} 12 | * @return {*} 13 | */ 14 | export function listApi(params) { 15 | return service({ 16 | url: '/admin/region/list', 17 | method: 'get', 18 | params: params 19 | }) 20 | } 21 | 22 | /** 23 | * @description: 信息 24 | * @param {*} 25 | * @return {*} 26 | */ 27 | export function infoApi(params) { 28 | return service({ 29 | url: '/admin/region/info', 30 | method: 'get', 31 | params 32 | }) 33 | } 34 | 35 | /** 36 | * @description: 新增 37 | * @param {*} 38 | * @return {*} 39 | */ 40 | export function createApi(data) { 41 | return service({ 42 | url: '/admin/region/create', 43 | method: 'post', 44 | data 45 | }) 46 | } 47 | 48 | /** 49 | * @description: 更新 50 | * @param {*} 51 | * @return {*} 52 | */ 53 | export function updateApi(data) { 54 | return service({ 55 | url: '/admin/region/update', 56 | method: 'post', 57 | data 58 | }) 59 | } 60 | 61 | /** 62 | * @description: 删除 63 | * @param {*} 64 | * @return {*} 65 | */ 66 | export function deleteApi(data) { 67 | return service({ 68 | url: '/admin/region/delete', 69 | method: 'post', 70 | data 71 | }) 72 | } 73 | 74 | /** 75 | * @description: 选择列表 76 | * @param {*} 77 | * @return {*} 78 | */ 79 | export function selectApi(params) { 80 | return service({ 81 | url: '/admin/region/select', 82 | method: 'get', 83 | params 84 | }) 85 | } 86 | -------------------------------------------------------------------------------- /src/api/role/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/role/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/role/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/role/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/role/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/role/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/role/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 设置菜单权限 84 | * @param {*} data 85 | * @returns 86 | */ 87 | export function setMenuPermissionApi(data) { 88 | return service({ 89 | url: '/admin/role/menu', 90 | method: 'post', 91 | data 92 | }) 93 | } 94 | 95 | /** 96 | * 设置数据权限 97 | * @param {*} data 98 | * @returns 99 | */ 100 | export function setDataPermissionApi(data) { 101 | return service({ 102 | url: '/admin/role/data', 103 | method: 'post', 104 | data 105 | }) 106 | } 107 | 108 | /** 109 | * 选择列表 110 | * @param {*} data 111 | * @returns 112 | */ 113 | export function selectApi() { 114 | return service({ 115 | url: '/admin/role/select', 116 | method: 'get' 117 | }) 118 | } 119 | 120 | /** 121 | * 导出 122 | * @returns 123 | */ 124 | export async function exportApi(params) { 125 | const r = await service({ 126 | url: 'admin/role/export', 127 | method: 'get', 128 | responseType: 'blob', 129 | params 130 | }) 131 | if (r) { 132 | const { blob, name } = r 133 | download(blob, name) 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/api/tenant/index.js: -------------------------------------------------------------------------------- 1 | import service from '..' 2 | import { download } from '@utils' 3 | 4 | /** 5 | * 分页 6 | * @param {*} params 7 | * @returns 8 | */ 9 | export function pageApi(params) { 10 | return service({ 11 | url: '/admin/tenant/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 详情 19 | * @param {*} params 20 | * @returns 21 | */ 22 | export function infoApi(params) { 23 | return service({ 24 | url: '/admin/tenant/info', 25 | method: 'get', 26 | params 27 | }) 28 | } 29 | 30 | /** 31 | * 新增 32 | * @param {*} data 33 | * @returns 34 | */ 35 | export function createApi(data) { 36 | return service({ 37 | url: '/admin/tenant/create', 38 | method: 'post', 39 | data 40 | }) 41 | } 42 | 43 | /** 44 | * 更新 45 | * @param {*} data 46 | * @returns 47 | */ 48 | export function updateApi(data) { 49 | return service({ 50 | url: '/admin/tenant/update', 51 | method: 'post', 52 | data 53 | }) 54 | } 55 | 56 | /** 57 | * 删除 58 | * @param {*} data 59 | * @returns 60 | */ 61 | export function deleteApi(data) { 62 | return service({ 63 | url: '/admin/tenant/delete', 64 | method: 'post', 65 | data 66 | }) 67 | } 68 | 69 | /** 70 | * 状态切换 71 | * @param {*} data 72 | * @returns 73 | */ 74 | export function setStatusApi(data) { 75 | return service({ 76 | url: '/admin/tenant/status', 77 | method: 'post', 78 | data 79 | }) 80 | } 81 | 82 | /** 83 | * 选择分页 84 | * @param {*} params 85 | * @returns 86 | */ 87 | export function selectPageApi(params) { 88 | return service({ 89 | url: '/admin/tenant/select/page', 90 | method: 'get', 91 | params 92 | }) 93 | } 94 | 95 | /** 96 | * 导出 97 | * @returns 98 | */ 99 | export async function exportApi(params) { 100 | const r = await service({ 101 | url: 'admin/tenant/export', 102 | method: 'get', 103 | responseType: 'blob', 104 | params 105 | }) 106 | if (r) { 107 | const { blob, name } = r 108 | download(blob, name) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/api/test/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 测试表 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-06-14 17:21:09 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/test/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/test/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/test/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/test/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/test/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * 导出 77 | * @returns 78 | */ 79 | export async function exportApi(params) { 80 | const r = await service({ 81 | url: '/admin/test/export', 82 | method: 'get', 83 | responseType: 'blob', 84 | params 85 | }) 86 | if (r) { 87 | const { blob, name } = r 88 | download(blob, name) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/api/user/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 用户 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-07-22 17:36:32 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/user/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/user/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/user/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/user/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/user/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * @description: 状态切换 77 | * @param {*} 78 | * @return {*} 79 | */ 80 | export function setStatusApi(data) { 81 | return service({ 82 | url: '/admin/user/status', 83 | method: 'post', 84 | data 85 | }) 86 | } 87 | 88 | /** 89 | * @description: 选择列表 90 | * @param {*} 91 | * @return {*} 92 | */ 93 | export function selectApi(params) { 94 | return service({ 95 | url: '/admin/user/select', 96 | method: 'get', 97 | params 98 | }) 99 | } 100 | 101 | /** 102 | * 导出 103 | * @returns 104 | */ 105 | export async function exportApi(params) { 106 | const r = await service({ 107 | url: '/admin/user/export', 108 | method: 'get', 109 | responseType: 'blob', 110 | params 111 | }) 112 | if (r) { 113 | const { blob, name } = r 114 | download(blob, name) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/wechat-applet/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Description: 微信小程序 3 | * @Author: 拖孩 4 | * @Email: 1240235512@qq.com 5 | * @Date: 2023-07-26 21:31:45 6 | */ 7 | import service from '..' 8 | import { download } from '@utils' 9 | 10 | /** 11 | * @description: 分页列表 12 | * @param {*} 13 | * @return {*} 14 | */ 15 | export function pageApi(params) { 16 | return service({ 17 | url: '/admin/wechat/applet/page', 18 | method: 'get', 19 | params: params 20 | }) 21 | } 22 | 23 | /** 24 | * @description: 信息 25 | * @param {*} 26 | * @return {*} 27 | */ 28 | export function infoApi(params) { 29 | return service({ 30 | url: '/admin/wechat/applet/info', 31 | method: 'get', 32 | params 33 | }) 34 | } 35 | 36 | /** 37 | * @description: 新增 38 | * @param {*} 39 | * @return {*} 40 | */ 41 | export function createApi(data) { 42 | return service({ 43 | url: '/admin/wechat/applet/create', 44 | method: 'post', 45 | data 46 | }) 47 | } 48 | 49 | /** 50 | * @description: 更新 51 | * @param {*} 52 | * @return {*} 53 | */ 54 | export function updateApi(data) { 55 | return service({ 56 | url: '/admin/wechat/applet/update', 57 | method: 'post', 58 | data 59 | }) 60 | } 61 | 62 | /** 63 | * @description: 删除 64 | * @param {*} 65 | * @return {*} 66 | */ 67 | export function deleteApi(data) { 68 | return service({ 69 | url: '/admin/wechat/applet/delete', 70 | method: 'post', 71 | data 72 | }) 73 | } 74 | 75 | /** 76 | * 导出 77 | * @returns 78 | */ 79 | export async function exportApi(params) { 80 | const r = await service({ 81 | url: '/admin/wechat/applet/export', 82 | method: 'get', 83 | responseType: 'blob', 84 | params 85 | }) 86 | if (r) { 87 | const { blob, name } = r 88 | download(blob, name) 89 | } 90 | } 91 | 92 | /** 93 | * @description: 生成二维码 94 | * @param {*} 95 | * @return {*} 96 | */ 97 | export function qrcodeApi(data) { 98 | return service({ 99 | url: '/admin/wechat/applet/qrcode', 100 | method: 'post', 101 | data 102 | }) 103 | } 104 | -------------------------------------------------------------------------------- /src/assets/fonts/AppleChancery.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmingchen/agile-admin/e6f5db8f28be74de5dce9436881373cee519420a/src/assets/fonts/AppleChancery.ttf -------------------------------------------------------------------------------- /src/assets/fonts/BarbaraHand.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmingchen/agile-admin/e6f5db8f28be74de5dce9436881373cee519420a/src/assets/fonts/BarbaraHand.ttf -------------------------------------------------------------------------------- /src/assets/fonts/SimpleScript.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmingchen/agile-admin/e6f5db8f28be74de5dce9436881373cee519420a/src/assets/fonts/SimpleScript.ttf -------------------------------------------------------------------------------- /src/assets/sass/_animation.scss: -------------------------------------------------------------------------------- 1 | // 顺时针选择 360 2 | @keyframes rotateAlong360 { 3 | 100% { 4 | transform: rotate(360deg); 5 | } 6 | } 7 | // 逆时针选择 360 8 | @keyframes rotateAgainst360 { 9 | 100% { 10 | transform: rotate(-360deg); 11 | } 12 | } 13 | 14 | // 旋转 15 | @keyframes rotate { 16 | from { 17 | transform: rotate(0deg) 18 | } 19 | to { 20 | transform: rotate(360deg) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/sass/_element.scss: -------------------------------------------------------------------------------- 1 | @forward "element-plus/theme-chalk/src/common/var.scss" with ( 2 | $colors: ( 3 | 'white': #fff, 4 | 'black': #000, 5 | 'primary': ( 6 | 'base': #409eff, 7 | ), 8 | 'success': ( 9 | 'base': #67c23a, 10 | ), 11 | 'warning': ( 12 | 'base': #e6a23c, 13 | ), 14 | 'danger': ( 15 | 'base': #f56c6c, 16 | ), 17 | 'error': ( 18 | 'base': #f56c6c, 19 | ), 20 | 'info': ( 21 | 'base': #909399, 22 | ), 23 | ), 24 | $text-color: ( 25 | ( 26 | 'primary': #303133, 27 | 'regular': #606266, 28 | 'secondary': #909399, 29 | 'placeholder': #a8abb2, 30 | 'disabled': #c0c4cc, 31 | ) 32 | ), 33 | ); 34 | 35 | @import "element-plus/theme-chalk/src/index.scss"; 36 | 37 | /* Element - 暗黑主题 */ 38 | @import 'element-plus/theme-chalk/src/dark/css-vars.scss'; 39 | html.dark { 40 | --gl-sidebar-background-color: var(--el-bg-color); 41 | 42 | --gl-headbar-background-color: var(--el-bg-color); 43 | 44 | --gl-tabsbar-background-color: var(--el-bg-color); 45 | 46 | --gl-content-background-color: #222222; 47 | --gl-content-panel-background-color: var(--el-bg-color); 48 | 49 | .el-table .el-table__body-wrapper {background: var(--el-bg-color);} 50 | } 51 | 52 | // 修复 消息确认弹窗样式 53 | .el-message-box__status { 54 | position: absolute !important; 55 | } 56 | // 修复 通知弹窗样式 57 | .el-notification { 58 | &__icon { 59 | height: var(--el-notification-icon-size)!important; 60 | width: var(--el-notification-icon-size)!important; 61 | font-size: var(--el-notification-icon-size)!important; 62 | } 63 | &--success, &--warning, &--info, &--error { 64 | color: var(--el-notification-icon-color)!important; 65 | } 66 | &__closeBtn { 67 | position: absolute !important; 68 | } 69 | } 70 | // 弹窗处理 添加滚动条 71 | .el-dialog { 72 | max-height: 100%; 73 | display: flex; 74 | flex-direction: column; 75 | .el-dialog__body { 76 | // 移除 弹窗 body 的上下padding 77 | padding-top: 0px !important; 78 | padding-bottom: 1px !important; // 设置为1是为了处理滚动条的问题 79 | overflow: auto; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/assets/sass/_font.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'BarbaraHand'; 3 | src: url("../fonts/BarbaraHand.ttf") format('truetype'); 4 | } 5 | @font-face { 6 | font-family: 'AppleChancery'; 7 | src: url("../fonts/AppleChancery.ttf") format('truetype'); 8 | } 9 | @font-face { 10 | font-family: 'SimpleScript'; 11 | src: url("../fonts/SimpleScript.ttf") format('truetype'); 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/sass/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --gl-sidebar-classic-width:250px; 3 | --gl-sidebar-classic-collapse-width:64px; 4 | --gl-sidebar-subfield-width:300px; 5 | --gl-sidebar-subfield-side-width:80px; 6 | --gl-sidebar-subfield-menu-width:220px; 7 | --gl-sidebar-subfield-collapse-width:64px; 8 | --gl-sidebar-background-color:#fff; 9 | 10 | --gl-headbar-height:50px; 11 | --gl-headbar-background-color:#fff; 12 | 13 | --gl-tabsbar-height:50px; 14 | --gl-tabsbar-background-color:#fff; 15 | 16 | --gl-content-background-color:#f1f4f6; 17 | --gl-content-panel-background-color:#fff; 18 | } 19 | -------------------------------------------------------------------------------- /src/assets/sass/_transition.scss: -------------------------------------------------------------------------------- 1 | // 浅入浅出 2 | .shallow-in-out-enter-active, 3 | .shallow-in-out-leave-active { 4 | transition: opacity 0.3s; 5 | } 6 | .shallow-in-out-enter, 7 | .shallow-in-out-leave-to { 8 | opacity: 0; 9 | } 10 | 11 | // 左浅入右浅出 12 | .left-in-right-out-enter-active, 13 | .left-in-right-out-leave-active { 14 | transition: all 0.3s; 15 | } 16 | .left-in-right-out-enter-active { 17 | opacity: 0; 18 | transform: translateX(-20px); 19 | } 20 | .left-in-right-out-enter-to { 21 | opacity: 1; 22 | transform: translateX(0px); 23 | } 24 | .left-in-right-out-leave-to { 25 | opacity: 0; 26 | transform: translateX(20px); 27 | } 28 | 29 | // 右浅入浅出 30 | .right-in-out-move, 31 | .right-in-out-enter-active, 32 | .right-in-out-leave-active { 33 | transition: all 0.3s; 34 | } 35 | .right-in-out-enter-active { 36 | transition-delay: 0.3s; 37 | opacity: 0; 38 | transform: translateX(50px); 39 | } 40 | .right-in-out-enter-to { 41 | opacity: 1; 42 | transform: translateX(0px); 43 | } 44 | .right-in-out-leave-to { 45 | opacity: 0; 46 | transform: translateX(50px); 47 | } 48 | -------------------------------------------------------------------------------- /src/assets/sass/_variable.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/sass/index.scss: -------------------------------------------------------------------------------- 1 | @import "normalize"; /* 页面标准化文件导入 */ 2 | @import "element"; /* element */ 3 | @import "font"; /* 字体 */ 4 | @import "transition"; 5 | @import "global"; 6 | @import "root"; 7 | 8 | -------------------------------------------------------------------------------- /src/common/constants/index.js: -------------------------------------------------------------------------------- 1 | import { ContentType, AuthKey, StorageType, SuccessCode, RequestMapping, WebsocketMapping, ModelBinding } from '@enums' 2 | 3 | // request Mapping 4 | export const MAPPING = RequestMapping.SLIPPER 5 | // websocket Mapping 6 | export const WEBSOCKET_MAPPING = MAPPING + WebsocketMapping.WEBSOCKET 7 | // 请求数据类型 8 | export const CONTENT_TYPE = ContentType.JSON 9 | // 请求超时时长 10 | export const TIME_OUT = 50000 11 | // 访问秘钥 存储 12 | export const AUTH_KEY = AuthKey.TOKEN 13 | // 秘钥本地存储类型 14 | export const AUTH_STORAGE = StorageType.COOKIE 15 | // 租户ID键值 16 | export const TNEANT_KEY = 'tenant-id' 17 | // 菜单本地存储类型 18 | export const MENU_STORAGE = StorageType.SESSION 19 | export const LOAD_MENU_KEY = 'load' 20 | export const MENU_KEY = 'menus' 21 | export const PERMISSION_KEY = 'permissions' 22 | // 主题本地存储类型 23 | export const THEME_STORAGE = StorageType.LOCAL 24 | export const THEME_KEY = 'theme' 25 | export const THEME_MODE_KEY = 'themeMode' 26 | export const LAYOUT_KEY = 'layout' 27 | // 请求成功响应code 28 | export const SUCCESS_CODE = [SuccessCode.ZERO, SuccessCode.TWO_HUNDRED] 29 | // 双向绑定方法名 30 | export const MODEL_NAME = 'modelValue' 31 | export const UPDATE_MODEL_EVENT = ModelBinding.MODEL_VALUE 32 | -------------------------------------------------------------------------------- /src/common/enums/index.js: -------------------------------------------------------------------------------- 1 | // 请求头-内容类型 2 | export const ContentType = { 3 | JSON: 'application/json;charset=UTF-8', 4 | FORM: 'application/x-www-form-urlencoded;charset=UTF-8', 5 | UPLOAD: 'multipart/form-data', 6 | STREAM: 'application/octet-stream' 7 | } 8 | // 令牌键值 9 | export const AuthKey = { 10 | TOKEN: 'token', 11 | ACCESS: 'access' 12 | } 13 | // 本地存储类型 14 | export const StorageType = { 15 | COOKIE: 'cookie', 16 | SESSION: 'sessionStorage', 17 | LOCAL: 'localStorage' 18 | } 19 | // 请求成功状态码 20 | export const SuccessCode = { 21 | ZERO: 0, 22 | TWO_HUNDRED: 200 23 | } 24 | // 请求 mapping 25 | export const RequestMapping = { 26 | SLIPPER: '/slipper', 27 | API: '/api' 28 | } 29 | // websocket mapping 30 | export const WebsocketMapping = { 31 | WEBSOCKET: '/websocket', 32 | } 33 | // 双向绑定名 34 | export const ModelBinding = { 35 | MODEL_VALUE: 'update:modelValue', 36 | MODEL_EVENT: 'update:modelEvent' 37 | } 38 | // 主题模式 39 | export const ThemeMode = { 40 | DARK: 'dark', 41 | LIGHT: 'light' 42 | } 43 | // 通用状态枚举 44 | export const Status = { 45 | DISABLE: 0, 46 | ENABLE: 1 47 | } 48 | // 是否 49 | export const Whether = { 50 | NO: 0, 51 | YES: 1 52 | } 53 | // 菜单类型 54 | export const MenuType = { 55 | CATALOG: 0, 56 | MENU: 1, 57 | BUTTON: 2, 58 | IFRAME: 3, 59 | URL: 4, 60 | GROUP: 5, 61 | ROUTER: 6 62 | } 63 | // 文件存储类型 64 | export const FileStorageType = { 65 | LOCAL: 0, 66 | KODO: 1, 67 | OSS: 2, 68 | COS: 3 69 | } 70 | // 数据权限 71 | export const DataPermission = { 72 | ALL: 0, 73 | SELF: 1, 74 | IN: 2, 75 | BELOW: 3, 76 | CUSTOM: 4 77 | } 78 | // 性别 79 | export const Sex = { 80 | FEMALE: 0, 81 | MALE: 1, 82 | UNKNOWN: 2 83 | } 84 | // 通知范围 85 | export const NoticeScope = { 86 | ALL: 0, 87 | ADMINER: 1, 88 | DEPT: 2 89 | } 90 | // 通知范围 91 | export const NoticeType = { 92 | SYSTEM: 0, 93 | NOTICE: 1 94 | } 95 | // 通知状态 96 | export const NoticeStatus = { 97 | UNREAD: 0, 98 | READ: 1 99 | } 100 | // 操作状态 101 | export const OperationalStatus = { 102 | FAIL: 0, 103 | SUCCESS: 1, 104 | RUNNING: 2 105 | } 106 | // 审核状态 107 | export const ReviewStatus = { 108 | ING: 0, 109 | PASS: 1, 110 | REJECT: 2, 111 | REVOKE: 3 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/common/utils/cache.js: -------------------------------------------------------------------------------- 1 | // 缓存 2 | const cacheMap = new Map() 3 | 4 | /** 5 | * 根据路由名称、query和params参数 转成组件名称 6 | * @param {*} name 路由名称 7 | * @param {*} query 路由query参数 8 | * @param {*} params 路由params参数 9 | */ 10 | const routeToComponentName = (name, query, params) => { 11 | let result = name 12 | for (const key in query) { 13 | result += `&${ key }=${ query[key] }` 14 | } 15 | for (const key in params) { 16 | result += `&${ key }=${ params[key] }` 17 | } 18 | return result 19 | } 20 | /** 21 | * 根据标签页的value 转成JSON对象 22 | * @param {*} value tab value 值 23 | */ 24 | const tabValueToJson = (value) => { 25 | const values = value.split('&') 26 | const name = values[0] 27 | const query = JSON.parse(values[2]) 28 | const params = JSON.parse(values[3]) 29 | return { name, query, params } 30 | } 31 | /** 32 | * 根据标签页的value 转成组件名称 33 | * @param {*} value tab value 值 34 | */ 35 | const tabValueToComponentName = (value) => { 36 | const { name, query, params } = tabValueToJson(value) 37 | return routeToComponentName(name, query, params) 38 | } 39 | 40 | /** 41 | * 组件缓存处理 42 | * @param {*} component 组件 43 | */ 44 | export const cacheHandle = (component, route) => { 45 | const { name, query, params, meta: { multiple } } = route 46 | if (multiple) { 47 | const key = routeToComponentName(name, query, params) 48 | let cache 49 | if (cacheMap.has(key)) { 50 | cache = cacheMap.get(key) 51 | } else { 52 | cache = { 53 | name: key, 54 | render: () => h(component) 55 | } 56 | cacheMap.set(key, cache) 57 | } 58 | return cache 59 | } 60 | return component 61 | } 62 | 63 | /** 64 | * 递归查询需要缓存的组件名称 65 | * @param {*} menus 可以缓存的菜单列表 66 | */ 67 | export const findKeepaliveName = (tabs, menus) => { 68 | const list = [] 69 | for (let i = 0; i < menus.length; i++) { 70 | const { id, componentName, multiple, children } = menus[i] 71 | for (let j = 0; j < tabs.length; j++) { 72 | const { menuId, value } = tabs[j] 73 | if (menuId === id) { 74 | let name = componentName 75 | if (multiple) { 76 | name = tabValueToComponentName(value) 77 | } 78 | list.push(name) 79 | } 80 | } 81 | if (children && children.length) { 82 | const arr = findKeepaliveName(tabs, children) 83 | if (arr.length) { 84 | componentName && list.push(componentName) 85 | list.push(...arr) 86 | } 87 | } 88 | } 89 | return list 90 | } 91 | -------------------------------------------------------------------------------- /src/common/utils/regular.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description: 整数 3 | * @param {*} input 4 | * @return {*} 5 | * @author: gumingchen 6 | */ 7 | export function isInteger(input) { 8 | const reg = /^-?[1-9]\d*$/ 9 | return reg.test(input) 10 | } 11 | 12 | /** 13 | * @description: 正整数 14 | * @param {*} input 15 | * @return {*} 16 | * @author: gumingchen 17 | */ 18 | export function isPositiveInteger(input) { 19 | const reg = /^[1-9]\d*$/ 20 | return reg.test(input) 21 | } 22 | 23 | /** 24 | * @description: 负整数 25 | * @param {*} input 26 | * @return {*} 27 | * @author: gumingchen 28 | */ 29 | export function isNegtiveInteger(input) { 30 | const reg = /^-[1-9]\d*$/ 31 | return reg.test(input) 32 | } 33 | 34 | /** 35 | * @description: 两位小数 36 | * @param {*} input 37 | * @return {*} 38 | * @author: gumingchen 39 | */ 40 | export function isTwoDecimal(input) { 41 | const reg = /^-?\d*(\.\d{1,2})?$/ 42 | return reg.test(input) 43 | } 44 | 45 | /** 46 | * @description: 邮箱 47 | * @param {*} input 48 | * @return {*} 49 | * @author: gumingchen 50 | */ 51 | export function isEmail(input) { 52 | const reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/ 53 | return reg.test(input) 54 | } 55 | 56 | /** 57 | * @description: URL地址 58 | * @param {*} input 59 | * @return {*} 60 | * @author: gumingchen 61 | */ 62 | export function isURL(input) { 63 | const reg = /^http[s]?:\/\/.*/ 64 | return reg.test(input) 65 | } 66 | 67 | /** 68 | * @description: 域名(带协议) 69 | * @param {*} input 70 | * @return {*} 71 | * @author: gumingchen 72 | */ 73 | export function isDomain(input) { 74 | const reg = /^http[s]?:\/\/[a-zA-Z0-9][-a-zA-Z0-9]*(\.[a-zA-Z0-9][-a-zA-Z0-9]*)+$/ 75 | return reg.test(input) 76 | } 77 | 78 | /** 79 | * @description: 端口 80 | * @param {*} input 81 | * @return {*} 82 | * @author: gumingchen 83 | */ 84 | export function isPort(input) { 85 | const reg = /^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]{1}|6553[0-5])$/ 86 | return reg.test(input) 87 | } 88 | 89 | /** 90 | * 手机号码 91 | * @param {*} input 92 | */ 93 | export function isMobile(input) { 94 | const reg = /^1[0-9]{10}$/ 95 | return reg.test(input) 96 | } 97 | 98 | /** 99 | * 用户名 100 | * @param {*} input 101 | */ 102 | export function isUsername(input) { 103 | const reg = /^[a-zA-Z]\w{3,11}$/ 104 | return reg.test(input) 105 | } 106 | 107 | /** 108 | * 密码 109 | * @param {*} input 110 | */ 111 | export function isPassword(input) { 112 | const reg = /^[a-zA-Z0-9_-]{8,16}$/ 113 | return reg.test(input) 114 | } 115 | 116 | /** 117 | * json 字符串 118 | * @param {*} input 119 | */ 120 | export function isJson(input) { 121 | if (typeof input === 'string') { 122 | try { 123 | const obj = JSON.parse(input) 124 | if (typeof obj === 'object' && obj) { 125 | return true 126 | } else { 127 | return false 128 | } 129 | } catch (e) { 130 | return false 131 | } 132 | } 133 | } 134 | 135 | -------------------------------------------------------------------------------- /src/common/utils/websocket.js: -------------------------------------------------------------------------------- 1 | export default class WebsocketClass { 2 | /** 3 | * @description: 初始化参数 4 | * @param {*} url ws资源路径 5 | * @param {*} callback 服务端信息回调 6 | * @return {*} 7 | * @author: gumingchen 8 | */ 9 | constructor(url, callback) { 10 | this.url = url 11 | this.callback = callback 12 | this.ws = null // websocket 对象 13 | this.status = 0 // 连接状态: 0-关闭 1-连接 2-手动关闭 14 | this.ping = 10000 // 心跳时长 15 | this.pingInterval = null // 心跳定时器 16 | this.reconnect = 5000 // 重连间隔 17 | } 18 | 19 | /** 20 | * @description: 连接 21 | * @param {*} 22 | * @return {*} 23 | * @author: gumingchen 24 | */ 25 | connect() { 26 | this.ws = new WebSocket(this.url) 27 | // 监听socket连接 28 | this.ws.onopen = () => { 29 | this.status = 1 30 | this.heartHandler() 31 | } 32 | // 监听socket消息 33 | this.ws.onmessage = (e) => { 34 | this.callback(JSON.parse(e.data)) 35 | } 36 | // 监听socket错误信息 37 | this.ws.onerror = (e) => { 38 | console.log(e) 39 | } 40 | // 监听socket关闭 41 | this.ws.onclose = (e) => { 42 | this.onClose(e) 43 | } 44 | } 45 | 46 | /** 47 | * @description: 发送消息 48 | * @param {*} data 49 | * @return {*} 50 | * @author: gumingchen 51 | */ 52 | send(data) { 53 | return this.ws.send(JSON.stringify(data)) 54 | } 55 | 56 | /** 57 | * @description: 关闭weibsocket 主动关闭不会触发重连 58 | * @param {*} 59 | * @return {*} 60 | * @author: gumingchen 61 | */ 62 | close() { 63 | this.status = 2 64 | this.ws.close() 65 | } 66 | 67 | /** 68 | * @description: socket关闭事件 69 | * @param {*} 70 | * @return {*} 71 | * @author: gumingchen 72 | */ 73 | onClose(e) { 74 | console.error(e) 75 | this.status = this.status === 2 ? this.status : 0 76 | setTimeout(() => { 77 | if (this.status === 0) { 78 | this.connect() 79 | } 80 | }, this.reconnect) 81 | } 82 | 83 | /** 84 | * @description: 心跳机制 85 | * @param {*} 86 | * @return {*} 87 | * @author: gumingchen 88 | */ 89 | heartHandler() { 90 | const data = { 91 | type: -1 92 | } 93 | this.pingInterval = setInterval(() => { 94 | if (this.status === 1) { 95 | this.ws.send(JSON.stringify(data)) 96 | } else { 97 | clearInterval(this.pingInterval) 98 | } 99 | }, this.ping) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/components/collapse/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 35 | 36 | 39 | -------------------------------------------------------------------------------- /src/components/container-custom/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 33 | 34 | 39 | -------------------------------------------------------------------------------- /src/components/container-sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 69 | 70 | 89 | -------------------------------------------------------------------------------- /src/components/count-to/index.js: -------------------------------------------------------------------------------- 1 | let lastTime = 0 2 | const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀 3 | 4 | let requestAnimationFrame 5 | let cancelAnimationFrame 6 | 7 | const isServer = typeof window === 'undefined' 8 | if (isServer) { 9 | requestAnimationFrame = function() { 10 | return null 11 | } 12 | cancelAnimationFrame = function() { 13 | return null 14 | } 15 | } else { 16 | requestAnimationFrame = window.requestAnimationFrame 17 | cancelAnimationFrame = window.cancelAnimationFrame 18 | let prefix 19 | // 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式 20 | for (let i = 0; i < prefixes.length; i++) { 21 | if (requestAnimationFrame && cancelAnimationFrame) { break } 22 | prefix = prefixes[i] 23 | requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame'] 24 | cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame'] 25 | } 26 | 27 | // 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout 28 | if (!requestAnimationFrame || !cancelAnimationFrame) { 29 | requestAnimationFrame = function(callback) { 30 | const currTime = new Date().getTime() 31 | // 为了使setTimteout的尽可能的接近每秒60帧的效果 32 | const timeToCall = Math.max(0, 16 - (currTime - lastTime)) 33 | const id = window.setTimeout(() => { 34 | callback(currTime + timeToCall) 35 | }, timeToCall) 36 | lastTime = currTime + timeToCall 37 | return id 38 | } 39 | 40 | cancelAnimationFrame = function(id) { 41 | window.clearTimeout(id) 42 | } 43 | } 44 | } 45 | 46 | export { requestAnimationFrame, cancelAnimationFrame } 47 | -------------------------------------------------------------------------------- /src/components/editor/quill/config.js: -------------------------------------------------------------------------------- 1 | import { uploadApi } from '@/api/file' 2 | import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html' 3 | 4 | // const QuillDeltaToHtmlConverter = require('quill-delta-to-html').QuillDeltaToHtmlConverter 5 | 6 | // toolbar工具栏的工具选项(默认展示全部) 7 | export const toolOptions = [ 8 | ['bold'], // 加粗 9 | ['italic'], // 斜体 10 | ['strike'], // 中横线 11 | ['underline'], // 加粗 12 | [{ 'font': [] }], // 下横线 13 | [{ 'size': [] }], // 字体大小 14 | [{ 'color': [] }], // 字体颜色 15 | [{ 'background': [] }], // 背景色 16 | [{ 'script': 'sub' }], // 脚本位置-上 17 | [{ 'script': 'super' }], // 脚本位置-下 18 | [{ 'header': [1, 2, 3, 4, 5, 6] }], // H标签 19 | [{ 'indent': '-1' }], // 行缩进-向左 20 | [{ 'indent': '+1' }], // 行缩进-向右 21 | [{ 'align': [] }], // 居中方式 22 | ['blockquote'], // 块引用 23 | [{ 'list': 'ordered' }], // 列表-数字 24 | [{ 'list': 'bullet' }], // 列表-点 25 | [{ 'direction': 'rtl' }], // 方向 26 | // ['code-block'], // 代码块 27 | ['link'], // 超链接 28 | // ['formula'], // 公式 29 | ['image'], // 上传图片 30 | ['video'], // 上传视频 31 | ['clean'] // 清除 32 | ] 33 | export const handlers = { 34 | image: function image () { 35 | const self = this 36 | let fileInput = this.container.querySelector('input.ql-image[type=file]') 37 | if (fileInput === null) { 38 | // 创建图片上传input标签 39 | fileInput = document.createElement('input') 40 | fileInput.setAttribute('type', 'file') 41 | // 设置图片参数名 42 | fileInput.setAttribute('name', 'file') 43 | // 可设置上传图片的格式 44 | fileInput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon') 45 | fileInput.classList.add('ql-image') 46 | // 监听选择文件 47 | fileInput.addEventListener('change', function () { 48 | const params = { 49 | file: fileInput.files[0] 50 | } 51 | uploadApi(params).then(r => { 52 | if (r) { 53 | const length = self.quill.getSelection(true).index 54 | self.quill.insertEmbed(length, 'image', r.data.url) 55 | self.quill.setSelection(length + 1) 56 | } 57 | }) 58 | }) 59 | this.container.appendChild(fileInput) 60 | } 61 | fileInput.click() 62 | } 63 | } 64 | 65 | export const options = { 66 | debug: 'warn', 67 | theme: 'snow', // 主题 snow / bubble 68 | placeholder: '请输入...', 69 | readOnly: false, 70 | modules: { 71 | toolbar: { 72 | container: toolOptions, 73 | handlers: handlers 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * 获取html字符串 80 | */ 81 | export const delta2Html = (delta) => { 82 | const deltaOptions = { 83 | inlineStyles: { 84 | align: (val) => { 85 | return `text-align: ${ val }` 86 | } 87 | } 88 | } 89 | const html = new QuillDeltaToHtmlConverter(delta.ops, deltaOptions).convert() 90 | return html 91 | } 92 | -------------------------------------------------------------------------------- /src/components/global/container/index.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 59 | 60 | 93 | -------------------------------------------------------------------------------- /src/components/global/date-range-picker/index.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 53 | -------------------------------------------------------------------------------- /src/components/global/dict-radio/index.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 33 | -------------------------------------------------------------------------------- /src/components/global/dict-select/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 34 | 35 | 40 | -------------------------------------------------------------------------------- /src/components/global/iconfont/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 12 | 21 | 45 | 46 | 49 | -------------------------------------------------------------------------------- /src/components/global/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | install: function (app) { 3 | const globalComponents = import.meta.glob('./**/index.(js|vue)', { eager: true }) 4 | for (const key in globalComponents) { 5 | if (key === './index.js') return 6 | const component = globalComponents[key] 7 | let name = key.replace(/\.\/|\/index.vue/g, '') 8 | name = name.slice(0, 1).toUpperCase() + name.slice(1) 9 | app.component(`${ name }`, component.default || component) 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/components/global/page/index.vue: -------------------------------------------------------------------------------- 1 | 47 | 48 | 66 | -------------------------------------------------------------------------------- /src/components/global/test/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /src/components/global/view/index.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 61 | -------------------------------------------------------------------------------- /src/components/icon-select-input/index.vue: -------------------------------------------------------------------------------- 1 | 69 | 70 | 107 | 108 | 111 | -------------------------------------------------------------------------------- /src/components/region/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 63 | 64 | 67 | -------------------------------------------------------------------------------- /src/components/tenant-sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 102 | 103 | 113 | -------------------------------------------------------------------------------- /src/components/upload-image/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 17 | 18 | 36 | -------------------------------------------------------------------------------- /src/components/upload/index.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 50 | 51 | 54 | -------------------------------------------------------------------------------- /src/directive/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | install: function (app) { 3 | const directives = import.meta.glob('./**/index.js', { eager: true }) 4 | for (const key in directives) { 5 | if (key === './index.js') return 6 | const directive = directives[key] 7 | const name = key.replace(/\.\/|\/index.js/g, '') 8 | app.directive(name, directive.default || directive) 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/directive/permission/index.js: -------------------------------------------------------------------------------- 1 | import { havePermission } from '@utils' 2 | /** 3 | * @description: 权限控制指令 4 | * @param {*} 5 | * @return {*} 6 | * @author: gumingchen 7 | */ 8 | export default { 9 | mounted: (el, binding, vnode) => { 10 | const permission = binding.value 11 | const result = havePermission(permission) 12 | const tagName = el.localName 13 | if (!result) { 14 | switch (tagName) { 15 | case 'button': // 按钮权限控制-删除tag 16 | el.remove() 17 | break 18 | case 'div': // element-plus switch 组件权限控制 19 | if (vnode.props && vnode.props.class && vnode.props.class.includes('el-switch')) { 20 | nextTick(() => { 21 | el.className += ' is-disabled' // 设置禁用样式 22 | const tag = el.cloneNode(true) // 深拷贝节点以解除绑定事件 23 | const parent = el.parentNode 24 | el.remove() 25 | parent.append(tag) 26 | }) 27 | } else { 28 | el.remove() 29 | } 30 | break 31 | default: 32 | el.remove() 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/directive/repeat/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description: 表单防止重复提交指令 3 | * @param {*} 4 | * @return {*} 5 | * @author: gumingchen 6 | */ 7 | export default { 8 | mounted(el, binding) { 9 | el.addEventListener('click', () => { 10 | if (!el.disabled) { 11 | el.disabled = true 12 | setTimeout(() => { 13 | el.disabled = false 14 | }, binding.value || 2000) 15 | } 16 | }) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/directive/resize/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description: Element 尺寸变化监听指令 3 | * @param {*} 4 | * @return {*} 5 | * @author: gumingchen 6 | */ 7 | const args = ['borderBoxSize', 'contentBoxSize', 'contentRect', 'devicePixelContentBoxSize'] 8 | 9 | const weakMap = new WeakMap() 10 | 11 | const resizeObserver = new ResizeObserver((entries) => { 12 | for (const entry of entries) { 13 | const value = weakMap.get(entry.target) 14 | if (value) { 15 | let { arg } = value 16 | arg = arg || args[1] 17 | let params = entry[arg] 18 | if (arg !== args[2]) { 19 | const { blockSize, inlineSize } = entry[arg][0] 20 | params = { 21 | height: blockSize, 22 | width: inlineSize 23 | } 24 | } 25 | value.handler(params) 26 | } 27 | } 28 | }) 29 | 30 | export default { 31 | mounted(el, binding) { 32 | const { arg, value } = binding 33 | if (typeof value !== 'function') { 34 | console.warn('[Directive warn]: Invalid value: validation failed for value. Must be a function.') 35 | return 36 | } 37 | if (arg && !args.includes(arg)) { 38 | console.warn(`[Directive warn]: Invalid arg: validation failed for arg. Expected one of ${ JSON.stringify(args) }, got value "${ arg }".`) 39 | return 40 | } 41 | resizeObserver.observe(el) 42 | weakMap.set(el, { arg, handler: binding.value }) 43 | }, 44 | unmounted(el) { 45 | resizeObserver.unobserve(el) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/hooks/bind-exposed.js: -------------------------------------------------------------------------------- 1 | export default function bindExposed(ref) { 2 | const instance = getCurrentInstance() 3 | if (ref.value.$.exposed) { 4 | const entries = Object.entries(ref.value.$.exposed) 5 | for (const [key, value] of entries) { 6 | if (instance.exposed) { 7 | instance.exposed[key] = value 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/hooks/dict.js: -------------------------------------------------------------------------------- 1 | import { delay } from '@utils' 2 | 3 | // 页面多次复用组件第一次会重复请求处理 4 | const pending = {} 5 | 6 | export default function () { 7 | const dictStore = useDictStore() 8 | 9 | const dict = ref([]) 10 | const dicts = ref({}) 11 | 12 | const getDict = async (code) => { 13 | while (pending[code] === 1) { 14 | await delay() 15 | } 16 | 17 | pending[code] = 1 18 | const result = await dictStore.getDict(code) 19 | dict.value = result 20 | pending[code] = 0 21 | return result 22 | } 23 | 24 | const getDicts = async (...codes) => { 25 | while (codes.some(code => pending[code] === 1)) { 26 | await delay() 27 | } 28 | codes.forEach(code => { pending[code] = 1 }) 29 | const result = await dictStore.getDicts(...codes) 30 | dicts.value = result 31 | codes.forEach(code => { pending[code] = 0 }) 32 | return result 33 | } 34 | 35 | return { 36 | dict, 37 | getDict, 38 | dicts, 39 | getDicts 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/hooks/model.js: -------------------------------------------------------------------------------- 1 | import { MODEL_NAME, UPDATE_MODEL_EVENT } from '@constants' 2 | 3 | export default function (props, key) { 4 | const vm = getCurrentInstance().proxy 5 | return computed({ 6 | get() { 7 | return props[key || MODEL_NAME] 8 | }, 9 | set(value) { 10 | const event = key ? `update:${ key }` : UPDATE_MODEL_EVENT 11 | vm.$emit(event, value) 12 | } 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | 3 | import App from './App.vue' 4 | import router from './router' 5 | import pinia from './stores' 6 | 7 | import '@/assets/sass/index.scss' // 全局样式 8 | import components from '@/components/global/index' // 全局自定义组件 9 | import Directive from '@/directive' // 自定义指令 10 | 11 | const app = createApp(App) 12 | 13 | app.use(router) 14 | .use(pinia) 15 | .use(components) 16 | .use(Directive) 17 | .mount('#app') 18 | 19 | -------------------------------------------------------------------------------- /src/stores/index.js: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia' 2 | 3 | const pinia = createPinia() 4 | 5 | export default pinia 6 | -------------------------------------------------------------------------------- /src/stores/modules/adminer.js: -------------------------------------------------------------------------------- 1 | import { clearJson } from '@utils' 2 | 3 | import { adminerInfoApi, logoutApi } from '@/api/auth' 4 | 5 | export const useAdminerStore = defineStore('adminer', { 6 | state: () => ({ 7 | id: '', 8 | username: '', 9 | nickname: '', 10 | avatar: '', 11 | mobile: '', 12 | email: '', 13 | sex: '', 14 | sex_dict: '', 15 | roles: '', 16 | posts: '', 17 | dept: '', 18 | tenant: '', 19 | token: '', 20 | expireAt: '' 21 | }), 22 | getters: { 23 | }, 24 | actions: { 25 | /** 26 | * 获取当前用户信息 27 | * @returns 28 | */ 29 | async getAdminer() { 30 | const r = await adminerInfoApi() 31 | if (r) { 32 | this.$state = r.data 33 | } 34 | return r ? r.data : null 35 | }, 36 | /** 37 | * 退出当前账户 38 | * @returns 39 | */ 40 | async logout() { 41 | const r = await logoutApi() 42 | return r 43 | }, 44 | /** 45 | * 清除登录用户信息 46 | */ 47 | clear() { 48 | clearJson(this.$state) 49 | } 50 | } 51 | }) 52 | -------------------------------------------------------------------------------- /src/stores/modules/auth.js: -------------------------------------------------------------------------------- 1 | import { loginApi, logoutApi } from '@/api/auth' 2 | 3 | import { getAuth, setAuth, clearAuth } from '@utils/storage' 4 | import { clearJson } from '@utils' 5 | 6 | const auth = getAuth() 7 | 8 | export const useAuthStore = defineStore('auth', { 9 | state: () => ({ 10 | adminerId: '', 11 | tenantId: '', 12 | token: '', 13 | expiredAt: '', 14 | ...auth 15 | }), 16 | actions: { 17 | /** 18 | * 登录 19 | * @param {*} params 20 | * @returns 21 | */ 22 | async login(params) { 23 | const r = await loginApi(params) 24 | if (r) { 25 | setAuth(r.data) 26 | this.$state = r.data 27 | } 28 | return r 29 | }, 30 | /** 31 | * 退出登录 32 | */ 33 | async logout() { 34 | const r = await logoutApi() 35 | return r.data 36 | }, 37 | /** 38 | * 清除数据 39 | */ 40 | clear() { 41 | clearAuth() 42 | clearJson(this.$state) 43 | } 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /src/stores/modules/dict.js: -------------------------------------------------------------------------------- 1 | import { subSelectListApi } from '@/api/dict' 2 | 3 | /** 4 | * 处理数据 5 | * @param {*} data 6 | * @returns 7 | */ 8 | const dictHandle = (data) => { 9 | const result = {} 10 | for (const key in data) { 11 | if (Object.hasOwnProperty.call(data, key)) { 12 | const dict = data[key] 13 | const list = dict.map(item => { 14 | return { 15 | value: /^[0-9]+.?[0-9]*$/.test(item.code) ? +item.code : item.code, // 判断是否是数字 如果是数字则用数字 16 | label: item.name 17 | } 18 | }) 19 | result[key] = list 20 | } 21 | } 22 | return result 23 | } 24 | 25 | export const useDictStore = defineStore('dict', { 26 | state: () => ({ 27 | }), 28 | actions: { 29 | async getDict(code) { 30 | const dict = this.$state[code] 31 | if (dict && JSON.stringify(dict) !== '{}') { 32 | return dict 33 | } else { 34 | const r = await subSelectListApi([code]) 35 | if (r) { 36 | const data = dictHandle(r.data) 37 | this.$state[code] = data[code] 38 | return data[code] 39 | } else { 40 | return [] 41 | } 42 | } 43 | }, 44 | async getDicts(...codes) { 45 | let result = {} 46 | const codeList = [] 47 | 48 | codes.forEach(code => { 49 | const dict = this.$state[code] 50 | if (dict && JSON.stringify(dict) !== '{}') { 51 | result[code] = dict 52 | } else { 53 | codeList.push(code) 54 | } 55 | }) 56 | if (codeList.length) { 57 | const r = await subSelectListApi(codeList) 58 | if (r) { 59 | const data = dictHandle(r.data) 60 | this.$state = { ...this.$state, ...data } 61 | result = { ...result, ...data } 62 | } 63 | } 64 | return result 65 | } 66 | } 67 | }) 68 | -------------------------------------------------------------------------------- /src/stores/modules/menu.js: -------------------------------------------------------------------------------- 1 | import { adminerMenuApi } from '@/api/auth' 2 | import { useTabsStore } from './tabs' 3 | 4 | import { getLoad, setLoad, clearLoad, getMenuAndPermission, setMenuAndPermission, clearMenuAndPermission } from '@utils/storage' 5 | import { MENU_KEY, PERMISSION_KEY } from '@constants' 6 | import { MenuType } from '@enums' 7 | import { parseData2Tree, clearJson } from '@utils' 8 | import { findKeepaliveName } from '@utils/cache' 9 | 10 | const load = getLoad() 11 | const data = getMenuAndPermission() 12 | /** 13 | * 格式化菜单 14 | * @param {*} menu 菜单 15 | * @returns 16 | */ 17 | const formatMenu = (menu) => { 18 | const { id, name, icon, url, routePath, routeName, componentName, parentId, type, tab, keepalive, multiple } = menu 19 | const defaultValue = url ? url.substring(1, url.length).replace(/\//g, '-') : '' 20 | return { 21 | label: name, 22 | path: type === 3 ? `/i-${ id }` : routePath || (url ? `/${ defaultValue }` : ''), 23 | name: type === 3 ? `i-${ id }` : routeName || (url ? defaultValue : ''), 24 | children: [], 25 | id, icon, type, url, componentName, tab, keepalive, multiple, parentId 26 | } 27 | } 28 | 29 | export const useMenuStore = defineStore('menu', { 30 | state: () => ({ 31 | load: load, 32 | menus: data[MENU_KEY], 33 | permissions: data[PERMISSION_KEY], 34 | active: '', 35 | collapse: false 36 | }), 37 | getters: { 38 | displayedMenus: (state) => { 39 | const reulst = state.menus.filter(item => item.show && item.type !== MenuType.BUTTON).map(item => { 40 | return formatMenu(item) 41 | }) 42 | return parseData2Tree(reulst) 43 | }, 44 | allMenus: (state) => { 45 | const reulst = state.menus.map(item => { 46 | return formatMenu(item) 47 | }) 48 | return parseData2Tree(reulst) 49 | }, 50 | keepaliveMenus: (state) => { 51 | const list = state.menus.filter(item => item.keepalive && item.componentName && item.componentName.trim()).map(item => { 52 | return formatMenu(item) 53 | }) 54 | return parseData2Tree(list) 55 | }, 56 | keepaliveNames: (state) => { 57 | return findKeepaliveName(useTabsStore().tabs, state.keepaliveMenus) 58 | } 59 | }, 60 | actions: { 61 | /** 62 | * 设置是否加载 63 | * @param {*} val 64 | */ 65 | setLoad(val) { 66 | this.load = val 67 | setLoad(val) 68 | }, 69 | /** 70 | * 获取菜单权限 71 | * @returns 72 | */ 73 | async getMenuAndPermission() { 74 | const r = await adminerMenuApi() 75 | if (r) { 76 | const { menus, permissions } = r.data 77 | this.menus = menus 78 | this.permissions = permissions 79 | this.load = true 80 | setLoad(true) 81 | setMenuAndPermission(r.data) 82 | } 83 | return r.data 84 | }, 85 | /** 86 | * 清除数据 87 | */ 88 | clear() { 89 | clearLoad() 90 | clearMenuAndPermission() 91 | this.load = false 92 | this.menus = [] 93 | this.permissions = [] 94 | this.active = '' 95 | this.collapse = false 96 | } 97 | } 98 | }) 99 | -------------------------------------------------------------------------------- /src/stores/modules/notice.js: -------------------------------------------------------------------------------- 1 | 2 | import { unreadPageApi, statusApi } from '@/api/adminer-notice' 3 | 4 | export const useNoticeStore = defineStore('notice', { 5 | state: () => ({ 6 | list: [], 7 | page: { 8 | current: 1, 9 | size: 10, 10 | total: -1 11 | } 12 | }), 13 | getters: {}, 14 | actions: { 15 | /** 16 | * 获取未读消息 17 | * @returns 18 | */ 19 | async getList(current) { 20 | if (current) { 21 | this.page.current = current 22 | } 23 | const params = { 24 | current: this.page.current, 25 | size: this.page.size 26 | } 27 | const r = await unreadPageApi(params) 28 | if (r) { 29 | if (current === 1) { 30 | this.list = r.data.list 31 | } else { 32 | this.list.push(...r.data.list) 33 | } 34 | this.page.total = r.data.total 35 | } 36 | return r 37 | }, 38 | /** 39 | * 设置已读 40 | * @param {*} ids 管理员 推送消息关联ID 41 | */ 42 | async read(ids) { 43 | const params = { 44 | keys: ids 45 | } 46 | const r = await statusApi(params) 47 | if (r) { 48 | this.page.current = 1 49 | this.getList() 50 | } 51 | }, 52 | /** 53 | * 清除数据 54 | */ 55 | clear() { 56 | this.list = [] 57 | this.page.total = 0 58 | } 59 | } 60 | }) 61 | -------------------------------------------------------------------------------- /src/stores/modules/tabs.js: -------------------------------------------------------------------------------- 1 | import router from '@/router' 2 | 3 | // todo: ITab value 格式:{a}&{b}&{c}&{d} 4 | // todo: a: 路由name b: 菜单ID c: 路由query字符串 d: 路由params字符串 5 | // todo: c、d 支持多开的时候需要 6 | const defaultTabs = [{ 7 | value: 'home&home&{}&{}', 8 | label: '首页', 9 | name: 'home', 10 | path: '/home', 11 | query: {}, // 路由参数 12 | params: {}, // 路由参数 13 | closable: false, // true:可以关闭 14 | menuId: 'home' 15 | }] 16 | 17 | export const useTabsStore = defineStore('tabs', { 18 | state: () => ({ 19 | active: '', 20 | tabs: [] 21 | }), 22 | getters: { 23 | activeTab: (state) => { 24 | const exists = state.tabs.filter(tab => tab.value === state.active) 25 | return exists.length ? exists[0] : {} 26 | } 27 | }, 28 | actions: { 29 | /** 30 | * 路由变化事件 设置当前选中、添加标签 31 | * @param {*} route 32 | */ 33 | changeHandle(route) { 34 | const meta = route.meta 35 | let val = `${ route.name }&${ meta.id }` 36 | if (meta.tab) { 37 | if (meta.multiple) { 38 | const queryStr = JSON.stringify(route.query) 39 | const paramsStr = JSON.stringify(route.params) 40 | val += `&${ queryStr }&${ paramsStr }` 41 | } else { 42 | val += `&{}&{}` 43 | } 44 | // 如果不存在则添加 45 | if (this.tabs.every(item => item.value !== val)) { 46 | // 自定义标题 47 | const label = meta.label + (route.query.custom ? `-${ route.query.custom }` : '') 48 | const tab = { 49 | value: val, 50 | menuId: meta.id, 51 | label: label, 52 | name: route.name, 53 | path: route.path, 54 | query: route.query, 55 | params: route.params 56 | } 57 | this.tabs.push(tab) 58 | } 59 | } 60 | this.active = val 61 | }, 62 | /** 63 | * 删除tabs 64 | * @param {*} values 65 | */ 66 | removeHandle(values) { 67 | // 过滤出不用删除的标签页 68 | let tabs = this.tabs.filter(item => { 69 | return values.indexOf(item.value) === -1 70 | }) 71 | // 至少保留一个标签页 72 | if (tabs.length === 0) { 73 | tabs = [this.tabs[0]] 74 | } 75 | // 若删除的包含当前页则跳转其他页 76 | if (tabs.every(item => item.value !== this.active)) { 77 | const tab = tabs[tabs.length - 1] 78 | router.push({ 79 | name: tab.name, 80 | query: tab.query, 81 | params: tab.params 82 | }) 83 | } 84 | // 设置当前未删除的标签页 85 | this.tabs = JSON.parse(JSON.stringify(tabs)) 86 | }, 87 | /** 88 | * 清除标签页 89 | */ 90 | clear() { 91 | this.active = '' 92 | this.tabs = [] 93 | } 94 | } 95 | }) 96 | -------------------------------------------------------------------------------- /src/stores/modules/websocket.js: -------------------------------------------------------------------------------- 1 | import { getWebsocketOrigin } from '@utils' 2 | import WebsocketClass from '@utils/websocket' 3 | import { WEBSOCKET_MAPPING } from '@constants' 4 | import { useAuthStore } from './auth' 5 | 6 | 7 | export const useWebsocketStore = defineStore('websocket', { 8 | state: () => ({ 9 | response: null, 10 | socket: null 11 | }), 12 | getters: {}, 13 | actions: { 14 | /** 15 | * 初始化websocket 16 | */ 17 | init() { 18 | if (!this.socket) { 19 | const url = `${ getWebsocketOrigin() }${ WEBSOCKET_MAPPING }/${ useAuthStore().token }` 20 | this.socket = new WebsocketClass(url, data => { 21 | this.response = data 22 | if (data.data) { 23 | switch (data.data.type) { 24 | case -1: 25 | break 26 | default: 27 | console.log('🚲~~:', data) 28 | break 29 | } 30 | } else { 31 | console.log('🚲~~:', data) 32 | } 33 | }) 34 | this.socket.connect() 35 | } 36 | }, 37 | /** 38 | * 发送信息 39 | * @param {*} data 40 | */ 41 | send(data) { 42 | const params = { 43 | type: 1, 44 | requestBody: data 45 | } 46 | console.log('✈️:~~', params) 47 | this.socket.send(params) 48 | }, 49 | /** 50 | * 手动断开websocket 51 | */ 52 | close() { 53 | if (this.socket) { 54 | this.socket.close() 55 | } 56 | this.response = null 57 | this.socket = null 58 | } 59 | } 60 | }) 61 | -------------------------------------------------------------------------------- /src/stores/root.js: -------------------------------------------------------------------------------- 1 | import { ElLoading } from 'element-plus' 2 | 3 | export const useRootStore = defineStore('root', { 4 | state: () => ({}), 5 | getters: {}, 6 | actions: { 7 | /** 8 | * 清除数据 用户信息 菜单 权限 标签页 主题 9 | * @param {*} 10 | */ 11 | clearData() { 12 | useAdminerStore().clear() 13 | useMenuStore().clear() 14 | useTabsStore().clear() 15 | }, 16 | /** 17 | * 清除缓存 18 | * @returns 19 | */ 20 | clear() { 21 | ElLoading.service({ 22 | lock: true, 23 | text: '清理缓存...', 24 | background: 'rgba(0, 0, 0, 0.3)' 25 | }) 26 | this.clearData() 27 | useThemeStore().clear() 28 | window.location.reload() 29 | }, 30 | /** 31 | * 退出登录清除 用户信息 菜单 权限 登录凭证 32 | * @param {*} param0 33 | */ 34 | logout() { 35 | this.clearData() 36 | useAuthStore().clear() 37 | } 38 | } 39 | }) 40 | -------------------------------------------------------------------------------- /src/views/constant/401.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 54 | 55 | 110 | -------------------------------------------------------------------------------- /src/views/constant/404.vue: -------------------------------------------------------------------------------- 1 | 9 | 21 | 22 | 63 | 64 | 94 | -------------------------------------------------------------------------------- /src/views/constant/500.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 58 | 59 | 113 | -------------------------------------------------------------------------------- /src/views/constant/identify.vue: -------------------------------------------------------------------------------- 1 | 77 | 78 | 116 | 117 | 122 | -------------------------------------------------------------------------------- /src/views/layout/components/headbar/components/crumb/index.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 58 | 59 | 69 | -------------------------------------------------------------------------------- /src/views/layout/components/headbar/components/menu/index.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 49 | 50 | 70 | -------------------------------------------------------------------------------- /src/views/layout/components/headbar/index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 51 | 52 | 60 | -------------------------------------------------------------------------------- /src/views/layout/components/logo/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 34 | 35 | 43 | -------------------------------------------------------------------------------- /src/views/layout/components/navigation/active/index.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /src/views/layout/components/navigation/fixed/index.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /src/views/layout/components/sidebar/components/classic/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 33 | 34 | 60 | -------------------------------------------------------------------------------- /src/views/layout/components/sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 46 | 47 | 50 | -------------------------------------------------------------------------------- /src/views/layout/components/sub-menu/index.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 53 | -------------------------------------------------------------------------------- /src/views/layout/components/tabsbar/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 46 | 47 | 64 | 65 | 82 | -------------------------------------------------------------------------------- /src/views/layout/components/websocket/index.vue: -------------------------------------------------------------------------------- 1 | 72 | -------------------------------------------------------------------------------- /src/views/layout/index.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 53 | 54 | 63 | -------------------------------------------------------------------------------- /src/views/modules/develop/menu/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 虚拟ID 3 | */ 4 | export const VIRTUAL_ID_KEY = 'virtual-' 5 | -------------------------------------------------------------------------------- /src/views/modules/home/components/applet.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 67 | 68 | 83 | -------------------------------------------------------------------------------- /src/views/modules/home/components/interacted.vue: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 42 | 43 | 63 | -------------------------------------------------------------------------------- /src/views/modules/home/components/introduction.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 30 | 31 | 47 | -------------------------------------------------------------------------------- /src/views/modules/home/components/project.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 64 | 65 | 82 | -------------------------------------------------------------------------------- /src/views/modules/home/components/user-growth.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 72 | 73 | 87 | -------------------------------------------------------------------------------- /src/views/modules/home/components/user-region.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 79 | 80 | 94 | -------------------------------------------------------------------------------- /src/views/modules/home/components/user-visits.vue: -------------------------------------------------------------------------------- 1 | 62 | 63 | 73 | 74 | 88 | -------------------------------------------------------------------------------- /src/views/modules/home/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 38 | 39 | 42 | -------------------------------------------------------------------------------- /src/views/modules/iframe/index.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 |