diff --git a/.docker-compose/nginx/conf.d/my.conf b/.docker-compose/nginx/conf.d/my.conf new file mode 100644 index 0000000..9a1685d --- /dev/null +++ b/.docker-compose/nginx/conf.d/my.conf @@ -0,0 +1,26 @@ +server { + listen 8080; + server_name localhost; + + #charset koi8-r; + #access_log logs/host.access.log main; + + location / { + root /usr/share/nginx/html; + add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + rewrite ^/api/(.*)$ /$1 break; #重写 + proxy_pass http://177.7.0.12:8888; # 设置代理服务器的协议和地址 + } + + location /api/swagger/index.html { + proxy_pass http://127.0.0.1:8888/swagger/index.html; + } + } \ No newline at end of file diff --git a/.docker-compose/nginx/conf.d/nginx.conf b/.docker-compose/nginx/conf.d/nginx.conf new file mode 100644 index 0000000..29f68b8 --- /dev/null +++ b/.docker-compose/nginx/conf.d/nginx.conf @@ -0,0 +1,32 @@ +server { + listen 80; + server_name localhost; + + #charset koi8-r; + #access_log logs/host.access.log main; + + location / { + root /usr/share/nginx/html/dist; + add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + rewrite ^/api/(.*)$ /$1 break; #重写 + proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址 + } + location /form-generator { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:8888; + } + location /api/swagger/index.html { + proxy_pass http://127.0.0.1:8888/swagger/index.html; + } + } \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..1a8757f --- /dev/null +++ b/.env.development @@ -0,0 +1,10 @@ +ENV = 'development' +VITE_CLI_PORT = 8080 +VITE_SERVER_PORT = 8888 +VITE_BASE_API = /api +VITE_BASE_PATH = http://127.0.0.1 +VITE_EDITOR = vscode +// VITE_EDITOR = webstorm 如果使用webstorm开发且要使用dom定位到代码行功能 请先自定添加 webstorm到环境变量 再将VITE_EDITOR值修改为webstorm +// 如果使用docker-compose开发模式,设置为下面的地址或本机主机IP +//VITE_BASE_PATH = http://177.7.0.12 + diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..2e3d72d --- /dev/null +++ b/.env.production @@ -0,0 +1,7 @@ +ENV = 'production' + +VITE_CLI_PORT = 8080 +VITE_SERVER_PORT = 8888 +VITE_BASE_API = /api +#下方修改为你的线上ip +VITE_BASE_PATH = https://demo.gin-vue-admin.com diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e6529fc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +build/*.js +src/assets +public +dist diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..4d39f36 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,273 @@ +//@author: [bstdn](https://github.com/bstdn) +//@description: ESlint 语法检测 +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + globals: { + defineProps: "readonly", + defineEmits: "readonly", + defineExpose: "readonly", + withDefaults: "readonly", + }, + rules: { + 'vue/no-v-model-argument':'off', + 'vue/max-attributes-per-line': [ + 2, + { + singleline: 10, + multiline: { + max: 1, + allowFirstLine: false + } + } + ], + 'vue/singleline-html-element-content-newline': 'off', + 'vue/multiline-html-element-content-newline': 'off', + 'vue/name-property-casing': ['error', 'PascalCase'], + 'vue/no-v-html': 'off', + 'accessor-pairs': 2, + 'arrow-spacing': [ + 2, + { + before: true, + after: true + } + ], + 'block-spacing': [2, 'always'], + 'brace-style': [ + 2, + '1tbs', + { + allowSingleLine: true + } + ], + camelcase: [ + 0, + { + properties: 'always' + } + ], + 'comma-dangle': [2, 'only-multiline'], + 'comma-spacing': [ + 2, + { + before: false, + after: true + } + ], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + curly: [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + eqeqeq: ['error', 'always', { null: 'ignore' }], + 'generator-star-spacing': [ + 2, + { + before: true, + after: true + } + ], + 'handle-callback-err': [2, '^(err|error)$'], + indent: [ + 2, + 2, + { + SwitchCase: 1 + } + ], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [ + 2, + { + beforeColon: false, + afterColon: true + } + ], + 'keyword-spacing': [ + 2, + { + before: true, + after: true + } + ], + 'new-cap': [ + 2, + { + newIsCap: true, + capIsNew: false + } + ], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [ + 2, + { + allowLoop: false, + allowSwitch: false + } + ], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [ + 2, + { + max: 1 + } + ], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 'off', + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [ + 2, + { + defaultAssignment: false + } + ], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [ + 2, + { + vars: 'all', + args: 'none' + } + ], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [ + 2, + { + initialized: 'never' + } + ], + 'operator-linebreak': [ + 2, + 'after', + { + overrides: { + '?': 'before', + ':': 'before' + } + } + ], + 'padded-blocks': [2, 'never'], + quotes: [ + 2, + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true + } + ], + semi: [2, 'never'], + 'semi-spacing': [ + 2, + { + before: false, + after: true + } + ], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [ + 2, + { + words: true, + nonwords: false + } + ], + 'spaced-comment': [ + 2, + 'always', + { + markers: ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + } + ], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + yoda: [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [ + 2, + 'always', + { + objectsInObjects: false + } + ], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..31f329c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM node:16 + +WORKDIR /gva_web/ +COPY . . + +RUN yarn && yarn build + +FROM nginx:alpine +LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com" + +COPY .docker-compose/nginx/conf.d/my.conf /etc/nginx/conf.d/my.conf +COPY --from=0 /gva_web/dist /usr/share/nginx/html +RUN cat /etc/nginx/nginx.conf +RUN cat /etc/nginx/conf.d/my.conf +RUN ls -al /usr/share/nginx/html diff --git a/README-CN.md b/README-CN.md new file mode 100644 index 0000000..c947159 --- /dev/null +++ b/README-CN.md @@ -0,0 +1,104 @@ +# qm-plus-vue-page + +## Project setup +``` +npm install +``` + +### Compiles and hot-reloads for development +``` +npm run serve +``` + +### Compiles and minifies for production +``` +npm run build +``` + +### Run your tests +``` +npm run test +``` + +### Lints and fixes files +``` +npm run lint +``` + +### Customize configuration +See [Configuration Reference](https://cli.vuejs.org/config/). + +整理代码结构 +``` lua +web + ├── babel.config.js + ├── Dockerfile + ├── favicon.ico + ├── index.html -- 主页面 + ├── limit.js -- 助手代码 + ├── package.json -- 包管理器代码 + ├── src -- 源代码 + │ ├── api -- api 组 + │ ├── App.vue -- 主页面 + │ ├── assets -- 静态资源 + │ ├── components -- 全局组件 + │ ├── core -- gva 组件包 + │ │ ├── config.js -- gva网站配置文件 + │ │ ├── gin-vue-admin.js -- 注册欢迎文件 + │ │ └── global.js -- 统一导入文件 + │ ├── directive -- v-auth 注册文件 + │ ├── main.js -- 主文件 + │ ├── permission.js -- 路由中间件 + │ ├── pinia -- pinia 状态管理器,取代vuex + │ │ ├── index.js -- 入口文件 + │ │ └── modules -- modules + │ │ ├── dictionary.js + │ │ ├── router.js + │ │ └── user.js + │ ├── router -- 路由声明文件 + │ │ └── index.js + │ ├── style -- 全局样式 + │ │ ├── base.scss + │ │ ├── basics.scss + │ │ ├── element_visiable.scss -- 此处可以全局覆盖 element-plus 样式 + │ │ ├── iconfont.css -- 顶部几个icon的样式文件 + │ │ ├── main.scss + │ │ ├── mobile.scss + │ │ └── newLogin.scss + │ ├── utils -- 方法包库 + │ │ ├── asyncRouter.js -- 动态路由相关 + │ │ ├── btnAuth.js -- 动态权限按钮相关 + │ │ ├── bus.js -- 全局mitt声明文件 + │ │ ├── date.js -- 日期相关 + │ │ ├── dictionary.js -- 获取字典方法 + │ │ ├── downloadImg.js -- 下载图片方法 + │ │ ├── format.js -- 格式整理相关 + │ │ ├── image.js -- 图片相关方法 + │ │ ├── page.js -- 设置页面标题 + │ │ ├── request.js -- 请求 + │ │ └── stringFun.js -- 字符串文件 + | ├── view -- 主要view代码 + | | ├── about -- 关于我们 + | | ├── dashboard -- 面板 + | | ├── error -- 错误 + | | ├── example --上传案例 + | | ├── iconList -- icon列表 + | | ├── init -- 初始化数据 + | | | ├── index -- 新版本 + | | | ├── init -- 旧版本 + | | ├── layout -- layout约束页面 + | | | ├── aside + | | | ├── bottomInfo -- bottomInfo + | | | ├── screenfull -- 全屏设置 + | | | ├── setting -- 系统设置 + | | | └── index.vue -- base 约束 + | | ├── login --登录 + | | ├── person --个人中心 + | | ├── superAdmin -- 超级管理员操作 + | | ├── system -- 系统检测页面 + | | ├── systemTools -- 系统配置相关页面 + | | └── routerHolder.vue -- page 入口页面 + ├── vite.config.js -- vite 配置文件 + └── yarn.lock + +``` \ No newline at end of file diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..f064a5a --- /dev/null +++ b/babel.config.js @@ -0,0 +1,8 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ], + 'plugins': [ + + ] +} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..ee520ce Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..2b92c29 --- /dev/null +++ b/index.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/limit.js b/limit.js new file mode 100644 index 0000000..d857ee3 --- /dev/null +++ b/limit.js @@ -0,0 +1,37 @@ +// 运行项目前通过node执行此脚本 (此脚本与 node_modules 目录同级) +const fs = require('fs') +const path = require('path') +const wfPath = path.resolve(__dirname, './node_modules/.bin') + +fs.readdir(wfPath, (err, files) => { + if (err) { + console.log(err) + } else { + if (files.length != 0) { + files.forEach((item) => { + if (item.split('.')[1] === 'cmd') { + replaceStr(`${wfPath}/${item}`, /"%_prog%"/, '%_prog%') + } + }) + } + } +}) + +// 参数:[文件路径、 需要修改的字符串、修改后的字符串] (替换对应文件内字符串的公共函数) +function replaceStr(filePath, sourceRegx, targetSrt) { + fs.readFile(filePath, (err, data) => { + if (err) { + console.log(err) + } else { + let str = data.toString() + str = str.replace(sourceRegx, targetSrt) + fs.writeFile(filePath, str, (err) => { + if(err){ + console.log(err) + }else{ + console.log("\x1B[42m%s\x1B[0m","文件修改成功") + } + }) + } + }) +} \ No newline at end of file diff --git a/openDocument.js b/openDocument.js new file mode 100644 index 0000000..2d52541 --- /dev/null +++ b/openDocument.js @@ -0,0 +1,23 @@ +/* + 商用代码公司自用产品无需授权 + 若作为代码出售的产品(任何涉及代码交付第三方作为后续开发)必须保留此脚本 + 或标注原作者信息 + 否则将依法维权 +*/ + +var child_process = require('child_process') + +var url = 'https://www.gin-vue-admin.com' +var cmd = '' +console.log(process.platform) +switch (process.platform) { + case 'win32': + cmd = 'start' + child_process.exec(cmd + ' ' + url) + break + + case 'darwin': + cmd = 'open' + child_process.exec(cmd + ' ' + url) + break +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b90138c --- /dev/null +++ b/package.json @@ -0,0 +1,52 @@ +{ + "name": "gin-vue-admin", + "version": "2.5.5", + "private": true, + "scripts": { + "serve": "node openDocument.js && vite --host --mode development", + "build": "vite build --mode production", + "limit-build": "npm install increase-memory-limit-fixbug cross-env -g && npm run fix-memory-limit && node ./limit && npm run build", + "preview": "vite preview", + "fix-memory-limit": "cross-env LIMIT=4096 increase-memory-limit" + }, + "dependencies": { + "@element-plus/icons-vue": "^0.2.7", + "axios": "^0.19.2", + "core-js": "^3.6.5", + "echarts": "5.3.2", + "element-plus": "2.2.9", + "highlight.js": "^10.6.0", + "marked": "^2.0.0", + "mitt": "^3.0.0", + "nprogress": "^0.2.0", + "path": "^0.12.7", + "pinia": "^2.0.9", + "qs": "^6.8.0", + "quill": "^1.3.7", + "screenfull": "^5.0.2", + "spark-md5": "^3.0.1", + "vue": "^3.2.25", + "vue-router": "^4.0.0-0" + }, + "devDependencies": { + "@vitejs/plugin-legacy": "^2.0.0", + "@vitejs/plugin-vue": "^3.0.1", + "@vue/cli-plugin-babel": "~4.5.0", + "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-router": "~4.5.0", + "@vue/cli-plugin-vuex": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/compiler-sfc": "^3.1.5", + "babel-eslint": "^10.1.0", + "babel-plugin-import": "^1.13.3", + "chalk": "^4.1.2", + "dotenv": "^10.0.0", + "eslint": "^6.7.2", + "eslint-plugin-vue": "^7.0.0", + "sass": "^1.54.0", + "terser": "^5.4.0", + "vite": "^3.0.1", + "vite-plugin-banner": "^0.1.3", + "vite-plugin-importer": "^0.2.5" + } +} \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..9eaaf40 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/api/api.js b/src/api/api.js new file mode 100644 index 0000000..78554ac --- /dev/null +++ b/src/api/api.js @@ -0,0 +1,132 @@ +import service from '@/utils/request' + +// @Tags api +// @Summary 分页获取角色列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body modelInterface.PageInfo true "分页获取用户列表" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /api/getApiList [post] +// { +// page int +// pageSize int +// } +export const getApiList = (data) => { + return service({ + url: '/api/getApiList', + method: 'post', + data + }) +} + +// @Tags Api +// @Summary 创建基础api +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateApiParams true "创建api" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /api/createApi [post] +export const createApi = (data) => { + return service({ + url: '/api/createApi', + method: 'post', + data + }) +} + +// @Tags menu +// @Summary 根据id获取菜单 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.GetById true "根据id获取菜单" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /menu/getApiById [post] +export const getApiById = (data) => { + return service({ + url: '/api/getApiById', + method: 'post', + data + }) +} + +// @Tags Api +// @Summary 更新api +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateApiParams true "更新api" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}" +// @Router /api/updateApi [post] +export const updateApi = (data) => { + return service({ + url: '/api/updateApi', + method: 'post', + data + }) +} + +// @Tags Api +// @Summary 更新api +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateApiParams true "更新api" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}" +// @Router /api/setAuthApi [post] +export const setAuthApi = (data) => { + return service({ + url: '/api/setAuthApi', + method: 'post', + data + }) +} + +// @Tags Api +// @Summary 获取所有的Api 不分页 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /api/getAllApis [post] +export const getAllApis = (data) => { + return service({ + url: '/api/getAllApis', + method: 'post', + data + }) +} + +// @Tags Api +// @Summary 删除指定api +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body dbModel.Api true "删除api" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /api/deleteApi [post] +export const deleteApi = (data) => { + return service({ + url: '/api/deleteApi', + method: 'post', + data + }) +} + +// @Tags SysApi +// @Summary 删除选中Api +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.IdsReq true "ID" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /api/deleteApisByIds [delete] +export const deleteApisByIds = (data) => { + return service({ + url: '/api/deleteApisByIds', + method: 'delete', + data + }) +} diff --git a/src/api/authority.js b/src/api/authority.js new file mode 100644 index 0000000..0401273 --- /dev/null +++ b/src/api/authority.js @@ -0,0 +1,85 @@ +import service from '@/utils/request' +// @Router /authority/getAuthorityList [post] +export const getAuthorityList = (data) => { + return service({ + url: '/authority/getAuthorityList', + method: 'post', + data + }) +} + +// @Summary 删除角色 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body {authorityId uint} true "删除角色" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /authority/deleteAuthority [post] +export const deleteAuthority = (data) => { + return service({ + url: '/authority/deleteAuthority', + method: 'post', + data + }) +} + +// @Summary 创建角色 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateAuthorityPatams true "创建角色" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /authority/createAuthority [post] +export const createAuthority = (data) => { + return service({ + url: '/authority/createAuthority', + method: 'post', + data + }) +} + +// @Tags authority +// @Summary 拷贝角色 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateAuthorityPatams true "拷贝角色" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"拷贝成功"}" +// @Router /authority/copyAuthority [post] +export const copyAuthority = (data) => { + return service({ + url: '/authority/copyAuthority', + method: 'post', + data + }) +} + +// @Summary 设置角色资源权限 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body sysModel.SysAuthority true "设置角色资源权限" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}" +// @Router /authority/setDataAuthority [post] +export const setDataAuthority = (data) => { + return service({ + url: '/authority/setDataAuthority', + method: 'post', + data + }) +} + +// @Summary 修改角色 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysAuthority true "修改角色" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}" +// @Router /authority/setDataAuthority [post] +export const updateAuthority = (data) => { + return service({ + url: '/authority/updateAuthority', + method: 'put', + data + }) +} diff --git a/src/api/authorityBtn.js b/src/api/authorityBtn.js new file mode 100644 index 0000000..9fe73bf --- /dev/null +++ b/src/api/authorityBtn.js @@ -0,0 +1,27 @@ + +import service from '@/utils/request' + +export const getAuthorityBtnApi = (data) => { + return service({ + url: '/authorityBtn/getAuthorityBtn', + method: 'post', + data + }) +} + +export const setAuthorityBtnApi = (data) => { + return service({ + url: '/authorityBtn/setAuthorityBtn', + method: 'post', + data + }) +} + +export const canRemoveAuthorityBtnApi = (params) => { + return service({ + url: '/authorityBtn/canRemoveAuthorityBtn', + method: 'post', + params + }) +} + diff --git a/src/api/autoCode.js b/src/api/autoCode.js new file mode 100644 index 0000000..08f456a --- /dev/null +++ b/src/api/autoCode.js @@ -0,0 +1,134 @@ +import service from '@/utils/request' + +export const preview = (data) => { + return service({ + url: '/autoCode/preview', + method: 'post', + data + }) +} + +export const createTemp = (data) => { + return service({ + url: '/autoCode/createTemp', + method: 'post', + data, + responseType: 'blob' + }) +} + +// @Tags SysApi +// @Summary 获取当前所有数据库 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /autoCode/getDatabase [get] +export const getDB = (params) => { + return service({ + url: '/autoCode/getDB', + method: 'get', + params + }) +} + +// @Tags SysApi +// @Summary 获取当前数据库所有表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /autoCode/getTables [get] +export const getTable = (params) => { + return service({ + url: '/autoCode/getTables', + method: 'get', + params + }) +} + +// @Tags SysApi +// @Summary 获取当前数据库所有表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}" +// @Router /autoCode/getColumn [get] +export const getColumn = (params) => { + return service({ + url: '/autoCode/getColumn', + method: 'get', + params + }) +} + +export const getSysHistory = (data) => { + return service({ + url: '/autoCode/getSysHistory', + method: 'post', + data + }) +} + +export const rollback = (data) => { + return service({ + url: '/autoCode/rollback', + method: 'post', + data + }) +} + +export const getMeta = (data) => { + return service({ + url: '/autoCode/getMeta', + method: 'post', + data + }) +} + +export const delSysHistory = (data) => { + return service({ + url: '/autoCode/delSysHistory', + method: 'post', + data + }) +} + +export const createPackageApi = (data) => { + return service({ + url: '/autoCode/createPackage', + method: 'post', + data + }) +} + +export const getPackageApi = () => { + return service({ + url: '/autoCode/getPackage', + method: 'post' + }) +} + +export const deletePackageApi = (data) => { + return service({ + url: '/autoCode/delPackage', + method: 'post', + data + }) +} + +export const createPlugApi = (data) => { + return service({ + url: '/autoCode/createPlug', + method: 'post', + data + }) +} + +export const installPlug = (data) => { + return service({ + url: '/autoCode/installPlug', + method: 'post', + data + }) +} diff --git a/src/api/breakpoint.js b/src/api/breakpoint.js new file mode 100644 index 0000000..1dbfba2 --- /dev/null +++ b/src/api/breakpoint.js @@ -0,0 +1,43 @@ +import service from '@/utils/request' +// @Summary 设置角色资源权限 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body sysModel.SysAuthority true "设置角色资源权限" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}" +// @Router /authority/setDataAuthority [post] + +export const findFile = (params) => { + return service({ + url: '/fileUploadAndDownload/findFile', + method: 'get', + params + }) +} + +export const breakpointContinue = (data) => { + return service({ + url: '/fileUploadAndDownload/breakpointContinue', + method: 'post', + donNotShowLoading: true, + headers: { 'Content-Type': 'multipart/form-data' }, + data + }) +} + +export const breakpointContinueFinish = (params) => { + return service({ + url: '/fileUploadAndDownload/breakpointContinueFinish', + method: 'post', + params + }) +} + +export const removeChunk = (data, params) => { + return service({ + url: '/fileUploadAndDownload/removeChunk', + method: 'post', + data, + params + }) +} diff --git a/src/api/casbin.js b/src/api/casbin.js new file mode 100644 index 0000000..802e130 --- /dev/null +++ b/src/api/casbin.js @@ -0,0 +1,32 @@ +import service from '@/utils/request' +// @Tags authority +// @Summary 更改角色api权限 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateAuthorityPatams true "更改角色api权限" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /casbin/UpdateCasbin [post] +export const UpdateCasbin = (data) => { + return service({ + url: '/casbin/updateCasbin', + method: 'post', + data + }) +} + +// @Tags casbin +// @Summary 获取权限列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.CreateAuthorityPatams true "获取权限列表" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /casbin/getPolicyPathByAuthorityId [post] +export const getPolicyPathByAuthorityId = (data) => { + return service({ + url: '/casbin/getPolicyPathByAuthorityId', + method: 'post', + data + }) +} diff --git a/src/api/customer.js b/src/api/customer.js new file mode 100644 index 0000000..4776f1c --- /dev/null +++ b/src/api/customer.js @@ -0,0 +1,80 @@ +import service from '@/utils/request' +// @Tags SysApi +// @Summary 删除客户 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body dbModel.ExaCustomer true "删除客户" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /customer/customer [post] +export const createExaCustomer = (data) => { + return service({ + url: '/customer/customer', + method: 'post', + data + }) +} + +// @Tags SysApi +// @Summary 更新客户信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body dbModel.ExaCustomer true "更新客户信息" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /customer/customer [put] +export const updateExaCustomer = (data) => { + return service({ + url: '/customer/customer', + method: 'put', + data + }) +} + +// @Tags SysApi +// @Summary 创建客户 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body dbModel.ExaCustomer true "创建客户" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /customer/customer [delete] +export const deleteExaCustomer = (data) => { + return service({ + url: '/customer/customer', + method: 'delete', + data + }) +} + +// @Tags SysApi +// @Summary 获取单一客户信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body dbModel.ExaCustomer true "获取单一客户信息" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /customer/customer [get] +export const getExaCustomer = (params) => { + return service({ + url: '/customer/customer', + method: 'get', + params + }) +} + +// @Tags SysApi +// @Summary 获取权限客户列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body modelInterface.PageInfo true "获取权限客户列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /customer/customerList [get] +export const getExaCustomerList = (params) => { + return service({ + url: '/customer/customerList', + method: 'get', + params + }) +} diff --git a/src/api/email.js b/src/api/email.js new file mode 100644 index 0000000..c2f16f4 --- /dev/null +++ b/src/api/email.js @@ -0,0 +1,14 @@ +import service from '@/utils/request' +// @Tags email +// @Summary 发送测试邮件 +// @Security ApiKeyAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}" +// @Router /email/emailTest [post] +export const emailTest = (data) => { + return service({ + url: '/email/emailTest', + method: 'post', + data + }) +} diff --git a/src/api/fileUploadAndDownload.js b/src/api/fileUploadAndDownload.js new file mode 100644 index 0000000..0a5d021 --- /dev/null +++ b/src/api/fileUploadAndDownload.js @@ -0,0 +1,44 @@ +import service from '@/utils/request' +// @Tags FileUploadAndDownload +// @Summary 分页文件列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body modelInterface.PageInfo true "分页获取文件户列表" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /fileUploadAndDownload/getFileList [post] +export const getFileList = (data) => { + return service({ + url: '/fileUploadAndDownload/getFileList', + method: 'post', + data + }) +} + +// @Tags FileUploadAndDownload +// @Summary 删除文件 +// @Security ApiKeyAuth +// @Produce application/json +// @Param data body dbModel.FileUploadAndDownload true "传入文件里面id即可" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"返回成功"}" +// @Router /fileUploadAndDownload/deleteFile [post] +export const deleteFile = (data) => { + return service({ + url: '/fileUploadAndDownload/deleteFile', + method: 'post', + data + }) +} + +/** + * 编辑文件名或者备注 + * @param data + * @returns {*} + */ +export const editFileName = (data) => { + return service({ + url: '/fileUploadAndDownload/editFileName', + method: 'post', + data + }) +} diff --git a/src/api/github.js b/src/api/github.js new file mode 100644 index 0000000..4dc4eed --- /dev/null +++ b/src/api/github.js @@ -0,0 +1,17 @@ +import axios from 'axios' + +const service = axios.create() + +export function Commits(page) { + return service({ + url: 'https://api.github.com/repos/flipped-aurora/gin-vue-admin/commits?page=' + page, + method: 'get' + }) +} + +export function Members() { + return service({ + url: 'https://api.github.com/orgs/FLIPPED-AURORA/members', + method: 'get' + }) +} diff --git a/src/api/initdb.js b/src/api/initdb.js new file mode 100644 index 0000000..ff009c7 --- /dev/null +++ b/src/api/initdb.js @@ -0,0 +1,26 @@ +import service from '@/utils/request' +// @Tags InitDB +// @Summary 初始化用户数据库 +// @Produce application/json +// @Param data body request.InitDB true "初始化数据库参数" +// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}" +// @Router /init/initdb [post] +export const initDB = (data) => { + return service({ + url: '/init/initdb', + method: 'post', + data + }) +} + +// @Tags CheckDB +// @Summary 初始化用户数据库 +// @Produce application/json +// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}" +// @Router /init/checkdb [post] +export const checkDB = () => { + return service({ + url: '/init/checkdb', + method: 'post' + }) +} diff --git a/src/api/jwt.js b/src/api/jwt.js new file mode 100644 index 0000000..811ffc4 --- /dev/null +++ b/src/api/jwt.js @@ -0,0 +1,14 @@ +import service from '@/utils/request' +// @Tags jwt +// @Summary jwt加入黑名单 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}" +// @Router /jwt/jsonInBlacklist [post] +export const jsonInBlacklist = () => { + return service({ + url: '/jwt/jsonInBlacklist', + method: 'post' + }) +} diff --git a/src/api/menu.js b/src/api/menu.js new file mode 100644 index 0000000..163b5a6 --- /dev/null +++ b/src/api/menu.js @@ -0,0 +1,113 @@ +import service from '@/utils/request' +// @Summary 用户登录 获取动态路由 +// @Produce application/json +// @Param 可以什么都不填 调一下即可 +// @Router /menu/getMenu [post] +export const asyncMenu = () => { + return service({ + url: '/menu/getMenu', + method: 'post' + }) +} + +// @Summary 获取menu列表 +// @Produce application/json +// @Param { +// page int +// pageSize int +// } +// @Router /menu/getMenuList [post] +export const getMenuList = (data) => { + return service({ + url: '/menu/getMenuList', + method: 'post', + data + }) +} + +// @Summary 新增基础menu +// @Produce application/json +// @Param menu Object +// @Router /menu/getMenuList [post] +export const addBaseMenu = (data) => { + return service({ + url: '/menu/addBaseMenu', + method: 'post', + data + }) +} + +// @Summary 获取基础路由列表 +// @Produce application/json +// @Param 可以什么都不填 调一下即可 +// @Router /menu/getBaseMenuTree [post] +export const getBaseMenuTree = () => { + return service({ + url: '/menu/getBaseMenuTree', + method: 'post' + }) +} + +// @Summary 添加用户menu关联关系 +// @Produce application/json +// @Param menus Object authorityId string +// @Router /menu/getMenuList [post] +export const addMenuAuthority = (data) => { + return service({ + url: '/menu/addMenuAuthority', + method: 'post', + data + }) +} + +// @Summary 获取用户menu关联关系 +// @Produce application/json +// @Param authorityId string +// @Router /menu/getMenuAuthority [post] +export const getMenuAuthority = (data) => { + return service({ + url: '/menu/getMenuAuthority', + method: 'post', + data + }) +} + +// @Summary 删除menu +// @Produce application/json +// @Param ID float64 +// @Router /menu/deleteBaseMenu [post] +export const deleteBaseMenu = (data) => { + return service({ + url: '/menu/deleteBaseMenu', + method: 'post', + data + }) +} + +// @Summary 修改menu列表 +// @Produce application/json +// @Param menu Object +// @Router /menu/updateBaseMenu [post] +export const updateBaseMenu = (data) => { + return service({ + url: '/menu/updateBaseMenu', + method: 'post', + data + }) +} + +// @Tags menu +// @Summary 根据id获取菜单 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.GetById true "根据id获取菜单" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /menu/getBaseMenuById [post] +export const getBaseMenuById = (data) => { + return service({ + url: '/menu/getBaseMenuById', + method: 'post', + data + }) +} diff --git a/src/api/sysDictionary.js b/src/api/sysDictionary.js new file mode 100644 index 0000000..f5d6c86 --- /dev/null +++ b/src/api/sysDictionary.js @@ -0,0 +1,80 @@ +import service from '@/utils/request' +// @Tags SysDictionary +// @Summary 创建SysDictionary +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionary true "创建SysDictionary" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /sysDictionary/createSysDictionary [post] +export const createSysDictionary = (data) => { + return service({ + url: '/sysDictionary/createSysDictionary', + method: 'post', + data + }) +} + +// @Tags SysDictionary +// @Summary 删除SysDictionary +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionary true "删除SysDictionary" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /sysDictionary/deleteSysDictionary [delete] +export const deleteSysDictionary = (data) => { + return service({ + url: '/sysDictionary/deleteSysDictionary', + method: 'delete', + data + }) +} + +// @Tags SysDictionary +// @Summary 更新SysDictionary +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionary true "更新SysDictionary" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}" +// @Router /sysDictionary/updateSysDictionary [put] +export const updateSysDictionary = (data) => { + return service({ + url: '/sysDictionary/updateSysDictionary', + method: 'put', + data + }) +} + +// @Tags SysDictionary +// @Summary 用id查询SysDictionary +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionary true "用id查询SysDictionary" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}" +// @Router /sysDictionary/findSysDictionary [get] +export const findSysDictionary = (params) => { + return service({ + url: '/sysDictionary/findSysDictionary', + method: 'get', + params + }) +} + +// @Tags SysDictionary +// @Summary 分页获取SysDictionary列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.PageInfo true "分页获取SysDictionary列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /sysDictionary/getSysDictionaryList [get] +export const getSysDictionaryList = (params) => { + return service({ + url: '/sysDictionary/getSysDictionaryList', + method: 'get', + params + }) +} diff --git a/src/api/sysDictionaryDetail.js b/src/api/sysDictionaryDetail.js new file mode 100644 index 0000000..d4f8772 --- /dev/null +++ b/src/api/sysDictionaryDetail.js @@ -0,0 +1,80 @@ +import service from '@/utils/request' +// @Tags SysDictionaryDetail +// @Summary 创建SysDictionaryDetail +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionaryDetail true "创建SysDictionaryDetail" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /sysDictionaryDetail/createSysDictionaryDetail [post] +export const createSysDictionaryDetail = (data) => { + return service({ + url: '/sysDictionaryDetail/createSysDictionaryDetail', + method: 'post', + data + }) +} + +// @Tags SysDictionaryDetail +// @Summary 删除SysDictionaryDetail +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionaryDetail true "删除SysDictionaryDetail" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete] +export const deleteSysDictionaryDetail = (data) => { + return service({ + url: '/sysDictionaryDetail/deleteSysDictionaryDetail', + method: 'delete', + data + }) +} + +// @Tags SysDictionaryDetail +// @Summary 更新SysDictionaryDetail +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}" +// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put] +export const updateSysDictionaryDetail = (data) => { + return service({ + url: '/sysDictionaryDetail/updateSysDictionaryDetail', + method: 'put', + data + }) +} + +// @Tags SysDictionaryDetail +// @Summary 用id查询SysDictionaryDetail +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}" +// @Router /sysDictionaryDetail/findSysDictionaryDetail [get] +export const findSysDictionaryDetail = (params) => { + return service({ + url: '/sysDictionaryDetail/findSysDictionaryDetail', + method: 'get', + params + }) +} + +// @Tags SysDictionaryDetail +// @Summary 分页获取SysDictionaryDetail列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.PageInfo true "分页获取SysDictionaryDetail列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get] +export const getSysDictionaryDetailList = (params) => { + return service({ + url: '/sysDictionaryDetail/getSysDictionaryDetailList', + method: 'get', + params + }) +} diff --git a/src/api/sysOperationRecord.js b/src/api/sysOperationRecord.js new file mode 100644 index 0000000..4428c03 --- /dev/null +++ b/src/api/sysOperationRecord.js @@ -0,0 +1,48 @@ +import service from '@/utils/request' +// @Tags SysOperationRecord +// @Summary 删除SysOperationRecord +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysOperationRecord true "删除SysOperationRecord" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /sysOperationRecord/deleteSysOperationRecord [delete] +export const deleteSysOperationRecord = (data) => { + return service({ + url: '/sysOperationRecord/deleteSysOperationRecord', + method: 'delete', + data + }) +} + +// @Tags SysOperationRecord +// @Summary 删除SysOperationRecord +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.IdsReq true "删除SysOperationRecord" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}" +// @Router /sysOperationRecord/deleteSysOperationRecord [delete] +export const deleteSysOperationRecordByIds = (data) => { + return service({ + url: '/sysOperationRecord/deleteSysOperationRecordByIds', + method: 'delete', + data + }) +} + +// @Tags SysOperationRecord +// @Summary 分页获取SysOperationRecord列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.PageInfo true "分页获取SysOperationRecord列表" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /sysOperationRecord/getSysOperationRecordList [get] +export const getSysOperationRecordList = (params) => { + return service({ + url: '/sysOperationRecord/getSysOperationRecordList', + method: 'get', + params + }) +} diff --git a/src/api/system.js b/src/api/system.js new file mode 100644 index 0000000..27b715e --- /dev/null +++ b/src/api/system.js @@ -0,0 +1,42 @@ +import service from '@/utils/request' +// @Tags systrm +// @Summary 获取配置文件内容 +// @Security ApiKeyAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}" +// @Router /system/getSystemConfig [post] +export const getSystemConfig = () => { + return service({ + url: '/system/getSystemConfig', + method: 'post' + }) +} + +// @Tags system +// @Summary 设置配置文件内容 +// @Security ApiKeyAuth +// @Produce application/json +// @Param data body sysModel.System true +// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}" +// @Router /system/setSystemConfig [post] +export const setSystemConfig = (data) => { + return service({ + url: '/system/setSystemConfig', + method: 'post', + data + }) +} + +// @Tags system +// @Summary 获取服务器运行状态 +// @Security ApiKeyAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"返回成功"}" +// @Router /system/getServerInfo [post] +export const getSystemState = () => { + return service({ + url: '/system/getServerInfo', + method: 'post', + donNotShowLoading: true + }) +} diff --git a/src/api/user.js b/src/api/user.js new file mode 100644 index 0000000..befd20e --- /dev/null +++ b/src/api/user.js @@ -0,0 +1,166 @@ +import service from '@/utils/request' +// @Summary 用户登录 +// @Produce application/json +// @Param data body {username:"string",password:"string"} +// @Router /base/login [post] +export const login = (data) => { + return service({ + url: '/base/login', + method: 'post', + data: data + }) +} + +// @Summary 获取验证码 +// @Produce application/json +// @Param data body {username:"string",password:"string"} +// @Router /base/captcha [post] +export const captcha = (data) => { + return service({ + url: '/base/captcha', + method: 'post', + data: data + }) +} + +// @Summary 用户注册 +// @Produce application/json +// @Param data body {username:"string",password:"string"} +// @Router /base/resige [post] +export const register = (data) => { + return service({ + url: '/user/admin_register', + method: 'post', + data: data + }) +} + +// @Summary 修改密码 +// @Produce application/json +// @Param data body {username:"string",password:"string",newPassword:"string"} +// @Router /user/changePassword [post] +export const changePassword = (data) => { + return service({ + url: '/user/changePassword', + method: 'post', + data: data + }) +} + +// @Tags User +// @Summary 分页获取用户列表 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body modelInterface.PageInfo true "分页获取用户列表" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /user/getUserList [post] +export const getUserList = (data) => { + return service({ + url: '/user/getUserList', + method: 'post', + data: data + }) +} + +// @Tags User +// @Summary 设置用户权限 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.SetUserAuth true "设置用户权限" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/setUserAuthority [post] +export const setUserAuthority = (data) => { + return service({ + url: '/user/setUserAuthority', + method: 'post', + data: data + }) +} + +// @Tags SysUser +// @Summary 删除用户 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body request.SetUserAuth true "删除用户" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/deleteUser [delete] +export const deleteUser = (data) => { + return service({ + url: '/user/deleteUser', + method: 'delete', + data: data + }) +} + +// @Tags SysUser +// @Summary 设置用户信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysUser true "设置用户信息" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/setUserInfo [put] +export const setUserInfo = (data) => { + return service({ + url: '/user/setUserInfo', + method: 'put', + data: data + }) +} + +// @Tags SysUser +// @Summary 设置用户信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body model.SysUser true "设置用户信息" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/setSelfInfo [put] +export const setSelfInfo = (data) => { + return service({ + url: '/user/setSelfInfo', + method: 'put', + data: data + }) +} + +// @Tags User +// @Summary 设置用户权限 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Param data body api.setUserAuthorities true "设置用户权限" +// @Success 200 {string} json "{"success":true,"data":{},"msg":"修改成功"}" +// @Router /user/setUserAuthorities [post] +export const setUserAuthorities = (data) => { + return service({ + url: '/user/setUserAuthorities', + method: 'post', + data: data + }) +} + +// @Tags User +// @Summary 获取用户信息 +// @Security ApiKeyAuth +// @accept application/json +// @Produce application/json +// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}" +// @Router /user/getUserInfo [get] +export const getUserInfo = () => { + return service({ + url: '/user/getUserInfo', + method: 'get' + }) +} + +export const resetPassword = (data) => { + return service({ + url: '/user/resetPassword', + method: 'post', + data: data + }) +} diff --git a/src/assets/background.svg b/src/assets/background.svg new file mode 100644 index 0000000..7375bb5 --- /dev/null +++ b/src/assets/background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/dashboard.png b/src/assets/dashboard.png new file mode 100644 index 0000000..64981d0 Binary files /dev/null and b/src/assets/dashboard.png differ diff --git a/src/assets/docs.png b/src/assets/docs.png new file mode 100644 index 0000000..bb98d6e Binary files /dev/null and b/src/assets/docs.png differ diff --git a/src/assets/flipped-aurora.png b/src/assets/flipped-aurora.png new file mode 100644 index 0000000..c94033b Binary files /dev/null and b/src/assets/flipped-aurora.png differ diff --git a/src/assets/github.png b/src/assets/github.png new file mode 100644 index 0000000..d1d200e Binary files /dev/null and b/src/assets/github.png differ diff --git a/src/assets/kefu.png b/src/assets/kefu.png new file mode 100644 index 0000000..47cab15 Binary files /dev/null and b/src/assets/kefu.png differ diff --git a/src/assets/login_background.jpg b/src/assets/login_background.jpg new file mode 100644 index 0000000..e601f24 Binary files /dev/null and b/src/assets/login_background.jpg differ diff --git a/src/assets/login_background.svg b/src/assets/login_background.svg new file mode 100644 index 0000000..0a9514b --- /dev/null +++ b/src/assets/login_background.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/login_left.svg b/src/assets/login_left.svg new file mode 100644 index 0000000..9c48b0b --- /dev/null +++ b/src/assets/login_left.svg @@ -0,0 +1,123 @@ + + + 搭建网站 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/logo.jpg b/src/assets/logo.jpg new file mode 100644 index 0000000..09502d5 Binary files /dev/null and b/src/assets/logo.jpg differ diff --git a/src/assets/logo.png b/src/assets/logo.png new file mode 100644 index 0000000..b497ee0 Binary files /dev/null and b/src/assets/logo.png differ diff --git a/src/assets/logo_login.png b/src/assets/logo_login.png new file mode 100644 index 0000000..e330458 Binary files /dev/null and b/src/assets/logo_login.png differ diff --git a/src/assets/nav_logo.png b/src/assets/nav_logo.png new file mode 100644 index 0000000..468cdab Binary files /dev/null and b/src/assets/nav_logo.png differ diff --git a/src/assets/noBody.png b/src/assets/noBody.png new file mode 100644 index 0000000..e16488e Binary files /dev/null and b/src/assets/noBody.png differ diff --git a/src/assets/notFound.png b/src/assets/notFound.png new file mode 100644 index 0000000..59ca9f0 Binary files /dev/null and b/src/assets/notFound.png differ diff --git a/src/assets/qm.png b/src/assets/qm.png new file mode 100644 index 0000000..9f598ca Binary files /dev/null and b/src/assets/qm.png differ diff --git a/src/assets/video.png b/src/assets/video.png new file mode 100644 index 0000000..af4d35f Binary files /dev/null and b/src/assets/video.png differ diff --git a/src/components/chooseImg/index.vue b/src/components/chooseImg/index.vue new file mode 100644 index 0000000..c3b4163 --- /dev/null +++ b/src/components/chooseImg/index.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/src/components/customPic/index.vue b/src/components/customPic/index.vue new file mode 100644 index 0000000..3952e7a --- /dev/null +++ b/src/components/customPic/index.vue @@ -0,0 +1,79 @@ + + + + + + + diff --git a/src/components/upload/common.vue b/src/components/upload/common.vue new file mode 100644 index 0000000..e6e20fd --- /dev/null +++ b/src/components/upload/common.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/components/upload/image.vue b/src/components/upload/image.vue new file mode 100644 index 0000000..d36e1aa --- /dev/null +++ b/src/components/upload/image.vue @@ -0,0 +1,104 @@ + + + + + + + + diff --git a/src/components/warningBar/warningBar.vue b/src/components/warningBar/warningBar.vue new file mode 100644 index 0000000..8d0ee7e --- /dev/null +++ b/src/components/warningBar/warningBar.vue @@ -0,0 +1,56 @@ + + + diff --git a/src/core/config.js b/src/core/config.js new file mode 100644 index 0000000..9afbdb6 --- /dev/null +++ b/src/core/config.js @@ -0,0 +1,58 @@ +/** + * 网站配置文件 + */ + +const config = { + appName: 'Gin-Vue-Admin', + appLogo: 'https://www.gin-vue-admin.com/img/logo.png', + showViteLogo: true +} + +export const viteLogo = (env) => { + if (config.showViteLogo) { + const chalk = require('chalk') + console.log( + chalk.green( + `> 欢迎使用Gin-Vue-Admin,开源地址:https://github.com/flipped-aurora/gin-vue-admin` + ) + ) + console.log( + chalk.green( + `> 当前版本:v2.5.5` + ) + ) + console.log( + chalk.green( + `> 加群方式:微信:shouzi_1994 QQ群:622360840` + ) + ) + console.log( + chalk.green( + `> GVA讨论社区:https://support.qq.com/products/371961` + ) + ) + console.log( + chalk.green( + `> 插件市场:https://plugin.gin-vue-admin.com` + ) + ) + console.log( + chalk.green( + `> 默认自动化文档地址:http://127.0.0.1:${env.VITE_SERVER_PORT}/swagger/index.html` + ) + ) + console.log( + chalk.green( + `> 默认前端文件运行地址:http://127.0.0.1:${env.VITE_CLI_PORT}` + ) + ) + console.log( + chalk.green( + `> 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html` + ) + ) + console.log('\n') + } +} + +export default config \ No newline at end of file diff --git a/src/core/gin-vue-admin.js b/src/core/gin-vue-admin.js new file mode 100644 index 0000000..1b07731 --- /dev/null +++ b/src/core/gin-vue-admin.js @@ -0,0 +1,22 @@ +/* + * gin-vue-admin web框架组 + * + * */ +// 加载网站配置文件夹 +import { register } from './global' + +export default { + install: (app) => { + register(app) + console.log(` + 欢迎使用 Gin-Vue-Admin + 当前版本:v2.5.5 + 加群方式:微信:shouzi_1994 QQ群:622360840 + GVA讨论社区:https://support.qq.com/products/371961 + 插件市场:https://plugin.gin-vue-admin.com + 默认自动化文档地址:http://127.0.0.1:${import.meta.env.VITE_SERVER_PORT}/swagger/index.html + 默认前端文件运行地址:http://127.0.0.1:${import.meta.env.VITE_CLI_PORT} + 如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html + `) + } +} \ No newline at end of file diff --git a/src/core/global.js b/src/core/global.js new file mode 100644 index 0000000..0d9c19e --- /dev/null +++ b/src/core/global.js @@ -0,0 +1,13 @@ +import config from './config' + +// 统一导入el-icon图标 +import * as ElIconModules from '@element-plus/icons-vue' +// 导入转换图标名称的函数 + +export const register = (app) => { + // 统一注册el-icon图标 + for (const iconName in ElIconModules) { + app.component(iconName, ElIconModules[iconName]) + } + app.config.globalProperties.$GIN_VUE_ADMIN = config +} diff --git a/src/directive/auth.js b/src/directive/auth.js new file mode 100644 index 0000000..50594d4 --- /dev/null +++ b/src/directive/auth.js @@ -0,0 +1,41 @@ +// 权限按钮展示指令 +import { useUserStore } from '@/pinia/modules/user' +export default { + install: (app) => { + const userStore = useUserStore() + app.directive('auth', { + // 当被绑定的元素插入到 DOM 中时…… + mounted: function(el, binding) { + const userInfo = userStore.userInfo + let type = '' + switch (Object.prototype.toString.call(binding.value)) { + case '[object Array]': + type = 'Array' + break + case '[object String]': + type = 'String' + break + case '[object Number]': + type = 'Number' + break + default: + type = '' + break + } + if (type === '') { + el.parentNode.removeChild(el) + return + } + const waitUse = binding.value.toString().split(',') + let flag = waitUse.some(item => Number(item) === userInfo.authorityId) + if (binding.modifiers.not) { + flag = !flag + } + if (!flag) { + el.parentNode.removeChild(el) + } + } + }) + } +} + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..a4a02a8 --- /dev/null +++ b/src/main.js @@ -0,0 +1,41 @@ +import { createApp } from 'vue' +import 'element-plus/dist/index.css' +import './style/element_visiable.scss' +import ElementPlus from 'element-plus' +import zhCn from 'element-plus/es/locale/lang/zh-cn' +// 引入gin-vue-admin前端初始化相关内容 +import './core/gin-vue-admin' +// 引入封装的router +import router from '@/router/index' +import '@/permission' +import run from '@/core/gin-vue-admin.js' +import auth from '@/directive/auth' +import { store } from '@/pinia' +import App from './App.vue' +import { initDom } from './utils/positionToCode' +initDom() +/** + * @description 导入加载进度条,防止首屏加载时间过长,用户等待 + * + * */ +import Nprogress from 'nprogress' +import 'nprogress/nprogress.css' +Nprogress.configure({ showSpinner: false, ease: 'ease', speed: 500 }) +Nprogress.start() + +/** + * 无需在这块结束,会在路由中间件中结束此块内容 + * */ + +const app = createApp(App) +app.config.productionTip = false + +app + .use(run) + .use(store) + .use(auth) + .use(router) + .use(ElementPlus, { locale: zhCn }) + .mount('#app') + +export default app diff --git a/src/permission.js b/src/permission.js new file mode 100644 index 0000000..954cfd5 --- /dev/null +++ b/src/permission.js @@ -0,0 +1,113 @@ +import { useUserStore } from '@/pinia/modules/user' +import { useRouterStore } from '@/pinia/modules/router' +import getPageTitle from '@/utils/page' +import router from '@/router' +import Nprogress from 'nprogress' + +let asyncRouterFlag = 0 + +const whiteList = ['Login', 'Init'] + +const getRouter = async(userStore) => { + const routerStore = useRouterStore() + await routerStore.SetAsyncRouter() + await userStore.GetUserInfo() + const asyncRouters = routerStore.asyncRouters + asyncRouters.forEach(asyncRouter => { + router.addRoute(asyncRouter) + }) +} + +async function handleKeepAlive(to) { + if (to.matched.some(item => item.meta.keepAlive)) { + if (to.matched && to.matched.length > 2) { + for (let i = 1; i < to.matched.length; i++) { + const element = to.matched[i - 1] + if (element.name === 'layout') { + to.matched.splice(i, 1) + await handleKeepAlive(to) + } + // 如果没有按需加载完成则等待加载 + if (typeof element.components.default === 'function') { + await element.components.default() + await handleKeepAlive(to) + } + } + } + } +} + +router.beforeEach(async(to, from) => { + Nprogress.start() + const userStore = useUserStore() + to.meta.matched = [...to.matched] + handleKeepAlive(to) + const token = userStore.token + // 在白名单中的判断情况 + document.title = getPageTitle(to.meta.title, to) + if (whiteList.indexOf(to.name) > -1) { + if (token) { + if (!asyncRouterFlag && whiteList.indexOf(from.name) < 0) { + asyncRouterFlag++ + await getRouter(userStore) + } + // token 可以解析但是却是不存在的用户 id 或角色 id 会导致无限调用 + if (userStore.userInfo?.authority?.defaultRouter != null) { + return { name: userStore.userInfo.authority.defaultRouter } + } else { + // 强制退出账号 + userStore.ClearStorage() + return { + name: 'Login', + query: { + redirect: document.location.hash + } + } + } + } else { + return true + } + } else { + // 不在白名单中并且已经登录的时候 + if (token) { + // 添加flag防止多次获取动态路由和栈溢出 + if (!asyncRouterFlag && whiteList.indexOf(from.name) < 0) { + asyncRouterFlag++ + await getRouter(userStore) + if (userStore.token) { + return { ...to, replace: true } + } else { + return { + name: 'Login', + query: { redirect: to.href } + } + } + } else { + if (to.matched.length) { + return true + } else { + return { path: '/layout/404' } + } + } + } + // 不在白名单中并且未登录的时候 + if (!token) { + return { + name: 'Login', + query: { + redirect: document.location.hash + } + } + } + } +}) + +router.afterEach(() => { + // 路由加载完成后关闭进度条 + Nprogress.done() +}) + +router.onError(() => { + // 路由发生错误后销毁进度条 + Nprogress.remove() +}) diff --git a/src/pinia/index.js b/src/pinia/index.js new file mode 100644 index 0000000..a6063cf --- /dev/null +++ b/src/pinia/index.js @@ -0,0 +1,7 @@ +import { createPinia } from 'pinia' + +const store = createPinia() + +export { + store +} diff --git a/src/pinia/modules/dictionary.js b/src/pinia/modules/dictionary.js new file mode 100644 index 0000000..5369222 --- /dev/null +++ b/src/pinia/modules/dictionary.js @@ -0,0 +1,39 @@ +import { findSysDictionary } from '@/api/sysDictionary' + +import { defineStore } from 'pinia' +import { ref } from 'vue' + +export const useDictionaryStore = defineStore('dictionary', () => { + const dictionaryMap = ref({}) + + const setDictionaryMap = (dictionaryRes) => { + dictionaryMap.value = { ...dictionaryMap.value, ...dictionaryRes } + } + + const getDictionary = async(type) => { + if (dictionaryMap.value[type] && dictionaryMap.value[type].length) { + return dictionaryMap.value[type] + } else { + const res = await findSysDictionary({ type }) + if (res.code === 0) { + const dictionaryRes = {} + const dict = [] + res.data.resysDictionary.sysDictionaryDetails && res.data.resysDictionary.sysDictionaryDetails.forEach(item => { + dict.push({ + label: item.label, + value: item.value + }) + }) + dictionaryRes[res.data.resysDictionary.type] = dict + setDictionaryMap(dictionaryRes) + return dictionaryMap.value[type] + } + } + } + + return { + dictionaryMap, + setDictionaryMap, + getDictionary + } +}) diff --git a/src/pinia/modules/router.js b/src/pinia/modules/router.js new file mode 100644 index 0000000..981116a --- /dev/null +++ b/src/pinia/modules/router.js @@ -0,0 +1,121 @@ +import { asyncRouterHandle } from '@/utils/asyncRouter' +import { emitter } from '@/utils/bus.js' +import { asyncMenu } from '@/api/menu' +import { defineStore } from 'pinia' +import { ref } from 'vue' + +const routerListArr = [] +const notLayoutRouterArr = [] +const keepAliveRoutersArr = [] +const nameMap = {} + +const formatRouter = (routes, routeMap) => { + routes && routes.forEach(item => { + if ((!item.children || item.children.every(ch => ch.hidden)) && item.name !== '404' && !item.hidden) { + routerListArr.push({ label: item.meta.title, value: item.name }) + } + item.meta.btns = item.btns + item.meta.hidden = item.hidden + if (item.meta.defaultMenu === true) { + notLayoutRouterArr.push({ + ...item, + path: `/${item.path}`, + }) + } else { + routeMap[item.name] = item + if (item.children && item.children.length > 0) { + formatRouter(item.children, routeMap) + } + } + }) +} + +const KeepAliveFilter = (routes) => { + routes && routes.forEach(item => { + // 子菜单中有 keep-alive 的,父菜单也必须 keep-alive,否则无效。这里将子菜单中有 keep-alive 的父菜单也加入。 + if ((item.children && item.children.some(ch => ch.meta.keepAlive) || item.meta.keepAlive)) { + item.component && item.component().then(val => { + keepAliveRoutersArr.push(val.default.name) + nameMap[item.name] = val.default.name + }) + } + if (item.children && item.children.length > 0) { + KeepAliveFilter(item.children) + } + }) +} + +export const useRouterStore = defineStore('router', () => { + const keepAliveRouters = ref([]) + const setKeepAliveRouters = (history) => { + const keepArrTemp = [] + history.forEach(item => { + if (nameMap[item.name]) { + keepArrTemp.push(nameMap[item.name]) + } + }) + keepAliveRouters.value = Array.from(new Set(keepArrTemp)) + } + emitter.on('setKeepAlive', setKeepAliveRouters) + + const asyncRouters = ref([]) + const routerList = ref(routerListArr) + const routeMap = ({}) + // 从后台获取动态路由 + const SetAsyncRouter = async() => { + const baseRouter = [{ + path: '/layout', + name: 'layout', + component: 'view/layout/index.vue', + meta: { + title: '底层layout' + }, + children: [] + }] + const asyncRouterRes = await asyncMenu() + const asyncRouter = asyncRouterRes.data.menus + asyncRouter && asyncRouter.push({ + path: '404', + name: '404', + hidden: true, + meta: { + title: '迷路了*。*', + closeTab: true, + }, + component: 'view/error/index.vue' + }, { + path: 'reload', + name: 'Reload', + hidden: true, + meta: { + title: '', + closeTab: true, + }, + component: 'view/error/reload.vue' + }) + formatRouter(asyncRouter, routeMap) + baseRouter[0].children = asyncRouter + if (notLayoutRouterArr.length !== 0) { + baseRouter.push(...notLayoutRouterArr) + } + baseRouter.push({ + path: '/:catchAll(.*)', + redirect: '/layout/404' + + }) + asyncRouterHandle(baseRouter) + KeepAliveFilter(asyncRouter) + asyncRouters.value = baseRouter + routerList.value = routerListArr + return true + } + + return { + asyncRouters, + routerList, + keepAliveRouters, + SetAsyncRouter, + routeMap + } +}) + diff --git a/src/pinia/modules/user.js b/src/pinia/modules/user.js new file mode 100644 index 0000000..a1e87f1 --- /dev/null +++ b/src/pinia/modules/user.js @@ -0,0 +1,153 @@ +import { login, getUserInfo, setSelfInfo } from '@/api/user' +import { jsonInBlacklist } from '@/api/jwt' +import router from '@/router/index' +import { ElLoading, ElMessage } from 'element-plus' +import { defineStore } from 'pinia' +import { ref, computed, watch } from 'vue' +import { useRouterStore } from './router' + +export const useUserStore = defineStore('user', () => { + const loadingInstance = ref(null) + + const userInfo = ref({ + uuid: '', + nickName: '', + headerImg: '', + authority: {}, + sideMode: 'dark', + activeColor: '#4D70FF', + baseColor: '#fff' + }) + const token = ref(window.localStorage.getItem('token') || '') + const setUserInfo = (val) => { + userInfo.value = val + } + + const setToken = (val) => { + token.value = val + } + + const NeedInit = () => { + token.value = '' + window.localStorage.removeItem('token') + localStorage.clear() + router.push({ name: 'Init', replace: true }) + } + + const ResetUserInfo = (value = {}) => { + userInfo.value = { + ...userInfo.value, + ...value + } + } + /* 获取用户信息*/ + const GetUserInfo = async() => { + const res = await getUserInfo() + if (res.code === 0) { + setUserInfo(res.data.userInfo) + } + return res + } + /* 登录*/ + const LoginIn = async(loginInfo) => { + loadingInstance.value = ElLoading.service({ + fullscreen: true, + text: '登录中,请稍候...', + }) + try { + const res = await login(loginInfo) + if (res.code === 0) { + setUserInfo(res.data.user) + setToken(res.data.token) + const routerStore = useRouterStore() + await routerStore.SetAsyncRouter() + const asyncRouters = routerStore.asyncRouters + asyncRouters.forEach(asyncRouter => { + router.addRoute(asyncRouter) + }) + await router.push({ name: userInfo.value.authority.defaultRouter }) + loadingInstance.value.close() + return true + } + } catch (e) { + loadingInstance.value.close() + } + loadingInstance.value.close() + } + /* 登出*/ + const LoginOut = async() => { + const res = await jsonInBlacklist() + if (res.code === 0) { + token.value = '' + sessionStorage.clear() + localStorage.clear() + router.push({ name: 'Login', replace: true }) + window.location.reload() + } + } + /* 清理数据 */ + const ClearStorage = async() => { + token.value = '' + sessionStorage.clear() + localStorage.clear() + } + /* 设置侧边栏模式*/ + const changeSideMode = async(data) => { + const res = await setSelfInfo({ sideMode: data }) + if (res.code === 0) { + userInfo.value.sideMode = data + ElMessage({ + type: 'success', + message: '设置成功' + }) + } + } + + const mode = computed(() => userInfo.value.sideMode) + const sideMode = computed(() => { + if (userInfo.value.sideMode === 'dark') { + return '#191a23' + } else if (userInfo.value.sideMode === 'light') { + return '#fff' + } else { + return userInfo.value.sideMode + } + }) + const baseColor = computed(() => { + if (userInfo.value.sideMode === 'dark') { + return '#fff' + } else if (userInfo.value.sideMode === 'light') { + return '#191a23' + } else { + return userInfo.value.baseColor + } + }) + const activeColor = computed(() => { + if (userInfo.value.sideMode === 'dark' || userInfo.value.sideMode === 'light') { + return '#4D70FF' + } + return userInfo.activeColor + }) + + watch(() => token.value, () => { + window.localStorage.setItem('token', token.value) + }) + + return { + userInfo, + token, + NeedInit, + ResetUserInfo, + GetUserInfo, + LoginIn, + LoginOut, + changeSideMode, + mode, + sideMode, + setToken, + baseColor, + activeColor, + loadingInstance, + ClearStorage + } +}) diff --git a/src/plugin/email/api/email.js b/src/plugin/email/api/email.js new file mode 100644 index 0000000..590c862 --- /dev/null +++ b/src/plugin/email/api/email.js @@ -0,0 +1,30 @@ +import service from '@/utils/request' +// @Tags System +// @Summary 发送测试邮件 +// @Security ApiKeyAuth +// @Produce application/json +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}" +// @Router /email/emailTest [post] +export const emailTest = (data) => { + return service({ + url: '/email/emailTest', + method: 'post', + data + }) +} + +// @Tags System +// @Summary 发送邮件 +// @Security ApiKeyAuth +// @Produce application/json +// @Param data body email_response.Email true "发送邮件必须的参数" +// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}" +// @Router /email/sendEmail [post] +export const sendEmail = (data) => { + return service({ + url: '/email/sendEmail', + method: 'post', + data + }) +} + diff --git a/src/plugin/email/view/index.vue b/src/plugin/email/view/index.vue new file mode 100644 index 0000000..50cc884 --- /dev/null +++ b/src/plugin/email/view/index.vue @@ -0,0 +1,56 @@ + + + + + + diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..290e931 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,24 @@ +import { createRouter, createWebHashHistory } from 'vue-router' + +const routes = [{ + path: '/', + redirect: '/login' +}, +{ + path: '/init', + name: 'Init', + component: () => import('@/view/init/index.vue') +}, +{ + path: '/login', + name: 'Login', + component: () => import('@/view/login/index.vue') +} +] + +const router = createRouter({ + history: createWebHashHistory(), + routes +}) + +export default router diff --git a/src/style/base.scss b/src/style/base.scss new file mode 100644 index 0000000..b3bda02 --- /dev/null +++ b/src/style/base.scss @@ -0,0 +1,65 @@ +.clearfix:after { + content: ''; + display: block; + height: 0; + visibility: hidden; + clear: both; +} + +.fl-left { + float: left; +} + +.fl-right { + float: right; +} + +.mg { + margin: 10px !important; +} + +.left-mg-xs { + margin-left: 6px !important; +} + +.left-mg-sm { + margin-left: 10px !important; +} + +.left-mg-md { + margin-left: 14px !important; +} + +.top-mg-lg { + margin-top: 20px !important; +} + +.tb-mg-lg { + margin: 20px 0 !important; +} + +.bottom-mg-lg { + margin-bottom: 20px !important; +} + +.left-mg-lg { + margin-left: 18px !important; +} + +.title-1 { + text-align: center; + font-size: 32px; +} + +.title-3 { + text-align: center; +} + +.keyword{ + width: 220px; + margin: 0 0 0 30px; +} + +#nprogress .bar { + background: #4D70FF !important; //自定义颜色 +} diff --git a/src/style/basics.scss b/src/style/basics.scss new file mode 100644 index 0000000..2d859a3 --- /dev/null +++ b/src/style/basics.scss @@ -0,0 +1,36 @@ +// basice +$font-size: 14px; +$icon-size:18px; +$active-color:#1890ff; +$bg-main:#f0f2f5; +$border-color: #f4f4f4; +$white-bg:#fff; +$el-icon-small:30px; +$el-icon-mini:24px; +// aside +$width-aside:220px; +$width-hideside-aside:54px; +$width-mobile-aside:210px; +$color-aside:rgba(255, 255, 255, .9); +$icon-arrow-size-aside:12px; +$width-submenu-aside:55px; +$height-aside-tilte:60px; +$height-aside-img:30px; +$width-aside-img:30px; +// header +$height-header: 60px; +// nav-scroll +$height-nav-scroll:40px; +$active-bg-tabs-item-nav-scroll:#409eff; +$bg-tabs-item-nav-scroll:#ddd; +// table +$bg-color-table-thead:#fafafa; +$border-color-table:#ededed; +$height-table-cell:45px; +$color-table-tbody:#595959; +$color-table-thead:#262626; +// dashboard +$height-car:68px; +// mobile +$padding-xs: 5px; +$margin-xs: 5px; \ No newline at end of file diff --git a/src/style/button.scss b/src/style/button.scss new file mode 100644 index 0000000..9c3e7c5 --- /dev/null +++ b/src/style/button.scss @@ -0,0 +1,9 @@ +.sticky-button { + position: sticky; + top: 2px; + z-index: 2; + background-color: #fff; +} +.fitler{ + width: 60%; +} \ No newline at end of file diff --git a/src/style/element_visiable.scss b/src/style/element_visiable.scss new file mode 100644 index 0000000..a65e84f --- /dev/null +++ b/src/style/element_visiable.scss @@ -0,0 +1,227 @@ +/* 改变主题色变量 */ + +#app { + .el-button { + font-weight: 400; + border-radius: 2px; + } +} + +.el-dialog { + border-radius: 2px; +} + +::-webkit-scrollbar-track-piece { + background-color: #f8f8f8; +} + +::-webkit-scrollbar { + width: 9px; + height: 9px; +} + +::-webkit-scrollbar-thumb { + background-color: #dddddd; + background-clip: padding-box; + min-height: 28px; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background-color: #bbb; +} + +.el-button--primary { + --el-button-font-color: #ffffff; + --el-button-background-color: #4D70FF; + --el-button-border-color: #4D70FF; + --el-button-hover-color: #0d84ff; + --el-button-active-font-color: #e6e6e6; + --el-button-active-background-color: #0d84ff; + --el-button-active-border-color: #0d84ff; +} + +.el-button--primary { + --el-button-font-color: #ffffff; + --el-button-background-color: #4D70FF; + --el-button-border-color: #4D70FF; + --el-button-hover-color: #0d84ff; + --el-button-active-font-color: #e6e6e6; + --el-button-active-background-color: #0d84ff; + --el-button-active-border-color: #0d84ff; +} + +:root { + --el-color-primary: #4D70FF; + --el-menu-item-height:56px ; +} + +.gva-search-box { + .el-collapse { + border: none; + .el-collapse-item__header, + .el-collapse-item__wrap { + border-bottom: none; + } + } + padding: 24px; + padding-bottom: 2px; + background-color: #fff; + border-radius: 2px; + margin-bottom: 12px; +} + +.el-form--inline{ + .el-form-item{ + margin-right: 24px; + } +} + +.el-input__inner{ + height: 40px; + line-height: 40px; +} + +.gva-form-box { + padding: 24px; + background-color: #fff; + border-radius: 2px; +} + +.gva-table-box { + padding: 24px; + background-color: #fff; + border-radius: 2px; +} + +.gva-pagination { + display: flex; + justify-content: flex-end; + .el-pagination__editor { + .el-input__inner { + height: 32px; + } + } + .el-pagination__total { + line-height: 32px !important; + } + //小屏幕不显示 + @media (max-width: 750px) { + .el-pagination__sizes{ + display: none !important; + } + } + .btn-prev { + padding-right: 6px; + display: inline-flex; + justify-content: center; + align-items: center; + width: 32px; + height: 32px; + } + .number { + display: inline-flex; + justify-content: center; + align-items: center; + width: 32px; + height: 32px; + } + .btn-quicknext { + display: inline-flex; + justify-content: center; + align-items: center; + width: 32px; + height: 32px; + } + .btn-next { + padding-left: 6px; + width: 32px; + height: 32px; + display: inline-flex; + justify-content: center; + align-items: center; + } + // 兼容久版用户升级 + .active { + background: #4D70FF; + border-radius: 2px; + color: #ffffff !important; + } + .el-pager li.active+li { + border-left: 1px solid #ddd !important; + } + // end + + + .is-active { + background: #4D70FF; + border-radius: 2px; + color: #ffffff !important; + } + .el-pager li.is-active+li { + border-left: 1px solid #ddd !important; + } + .el-pagination__sizes { + .el-input { + .el-input__suffix { + margin-top: 2px; + } + } + } +} + +.el-button--small { + min-height: 32px; + font-size: 12px !important; +} + +.el-checkbox{ + height: auto; +} + +.el-button { + padding: 8px 16px; + border-radius: 2px; + &.el-button--text { + padding: 8px 0; + } +} + +.el-dialog { + padding: 12px; + .el-dialog__body { + padding: 12px 6px; + } + .el-dialog__header { + .el-dialog__title { + font-size: 14px; + font-weight: 500; + } + padding: 2px 20px 12px 20px; + border-bottom: 1px solid #E4E4E4; + } + .el-dialog__footer { + padding: 0 16px 16px 0; + .dialog-footer { + .el-button { + padding-left: 24px; + padding-right: 24px; + } + .el-button+.el-button { + margin-left: 30px; + } + } + } +} + +.el-drawer__body { + padding: 0; +} + +.el-date-editor .el-range-separator { + line-height: 24px; +} + +.el-select .el-input .el-select__caret.el-icon { + height: 38px; +} \ No newline at end of file diff --git a/src/style/iconfont.css b/src/style/iconfont.css new file mode 100644 index 0000000..bc091a0 --- /dev/null +++ b/src/style/iconfont.css @@ -0,0 +1,47 @@ +@font-face { + font-family: 'gvaIcon'; + src: url('data:font/ttf;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTZJUyU8AAA14AAAAHEdERUYAKQARAAANWAAAAB5PUy8yPJpJTAAAAVgAAABgY21hcM0T0L4AAAHYAAABWmdhc3D//wADAAANUAAAAAhnbHlmRk3UvwAAA0wAAAbYaGVhZB/a5jgAAADcAAAANmhoZWEHngOFAAABFAAAACRobXR4DaoBrAAAAbgAAAAebG9jYQbMCGgAAAM0AAAAGG1heHABGgB+AAABOAAAACBuYW1lXoIBAgAACiQAAAKCcG9zdN15OnUAAAyoAAAAqAABAAAAAQAA+a916l8PPPUACwQAAAAAAN5YUSMAAAAA3lhRIwBL/8ADwAM1AAAACAACAAAAAAAAAAEAAAOA/4AAXAQAAAAAAAPAAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAALAHIABQAAAAAAAgAAAAoACgAAAP8AAAAAAAAABAQAAZAABQAAAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZADA5mXmfQOA/4AAAAPcAIAAAAABAAAAAAAAAAAAAAAgAAEEAAAAAAAAAAQAAAAEAACLAIoAYAB1AHYASwBLAGAAAAAAAAMAAAADAAAAHAABAAAAAABUAAMAAQAAABwABAA4AAAACgAIAAIAAuZm5mrmduZ9//8AAOZl5mrmdeZ7//8ZnhmbGZEZjQABAAAAAAAAAAAAAAAAAQYAAAEAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEYAigEcAbgCUAK6AxoDbAACAIsAIANsAswAEQAjAAAlIicBJjQ3ATYeAQYHCQEeAQYhIicBJjQ3ATYeAQYHCQEeAQYDSw0J/qsLCwFVChsSAgr+xAE8CgIV/qkNCP6qCgoBVgkbEgIK/sUBOwoCFCAJATULGQsBNQoCExwI/uL+4ggbFAkBNQsZCwE1CgITHAj+4v7iCRoUAAAAAAIAigAgA2sCzAARACIAAAE0JwEmDgEWFwkBDgEWMjcBNiUBJg4BFhcJAQ4BFjI3ATY0AiAL/qsJHBECCQE8/sQJAhQZCQFVCwFA/qsKGxICCgE8/sQKAhUZCQFVCwF1DQsBNQoCExwI/uL+4gkaFAkBNQskATUKAhMcCP7i/uIJGhQJATULGQADAGD/wAOgAzUATABcAGwAAAE1NCcmJyYiBwYHBh0BDgEdARQWOwEyNj0BNCYrATU0NzY3NjIXFhcWHQEjIgYdARQWOwEGBwYHLgEjIgYUFjMyNjc2NzY3PgE9ATQmBRUUBisBIiY9ATQ2OwEyFgUUBisBIiY9ATQ2OwEyFhUDYDAvT1O+U08vMBslLB9VHi0tHiAoJkFDnENBJiggHi0tHhUPJC5SChwRHCQkHBEeCHJAMxAfKiX9kAYFVQUGBgVVBQYCVQYFVQUGBgVVBQYByQxgUlAuMDAuUFJgDAQqG6seLCweqx4tCk5DQScnJydBQ04KLR6rHiwrGiAGDxElNiUSEAc1KkUBKx6rGyhFqwQGBgSrBQYGsAQGBgSrBQYGBQAABAB1//UDjQMLABsANwBSAHEAABMyNj0BFxYyNjQvATMyNjQmKwEiBwYHBh0BFBYFIgYdAScmIgYUHwEjIgYUFjsBMjc2NzY9ATYmJQc1NCYiBh0BFBcWFxY7ATI2NCYrATc2NCYGATQ1FSYnJisBIgYUFjsBBwYUFjI/ARUUFjI2PQEnJpUNE7wJHRMKvIcMFBQM1ggCDAgCFALiDRPJCRoTCcmJDBQUDNYIAg8CAwES/gbJExkUAggKBAbWDBQUDInJCRMXAgEHCwQG2AwUFAyJvAkSHgi8ExoTAgEB9RQMibwIEhkKvBMZFAIGDAQI1gwU6hQMickJExoJyRMZFAIICgQG2AwUIsmHDBQUDNYIAg8CAxQZE8kKGRMBAcABAQIOAwMUGRO8ChkTCbyHDBQUDNYFBAAABAB2//cDjgMMABoANQBRAG0AAAEjIgYUFjsBMjc2NzY9ATQmIgYdAScmIgYUFwEzMjY0JisBIgcGBwYdARQWMjY9ARcWMjY0JyUmJyYrASIGFBY7AQcGFBYyPwEVFBYyNj0BLgE3FhcWOwEyNjQmKwE3NjQmIg8BNTQmIgYdAR4BATqJDRMTDdUJAg8CAhMaE7cKGRQKAjeJDRMTDdUJAg8CAhMaE8gJHhIK/i8HCgQH1w0TEw2JyQoTHQnIFBkTAQKoBwoEBtYNExMNibwKFBkKvBMZFAICAhoUGRMCBwoEBtYNExMNib4KExoK/iAUGRMCBwoEB9UNExMNickIEhkK8w8CAhMZFMgKGRMJyYkNExMN1QIJzQ8CAhMZFLsKGhMKvIkNExMN1QMIAAAAAAUAS//LA7UDNQAUACkAKgA3AEQAAAEiBwYHBhQXFhcWMjc2NzY0JyYnJgMiJyYnJjQ3Njc2MhcWFxYUBwYHBgMjFB4BMj4BNC4BIg4BFyIGHQEUFjI2PQE0JgIAd2ZiOzs7O2Jm7mZiOzs7O2Jmd2VXVDIzMzJUV8pXVDIzMzJUV2UrDBQWFAwMFBYUDCsNExMaExMDNTs7YmbuZmI7Ozs7YmbuZmI7O/zWMzJUV8pXVDIzMzJUV8pXVDIzAjULFAwMFBYUDAwUgBQM6w0TEw3rDBQAAQBL/+ADwAMgAD0AAAEmBg8BLgEjIgcGBwYUFxYXFjMyPgE3Ni4BBgcOAiMiJyYnJjQ3Njc2MzIeARcnJg4BFh8BMj8BNj8BNCYDpgwXAxc5yXZyY184Ojo4X2NyWaB4HgULGhcFGWaJS2FUUTAwMTBRU2FIhGQbgA0WBw4NwgUIBAwDMQ0CsQMODFhmeDk3XmHiYV43OUV9UQ0XCQsMRWo6MC9PUr9TTy8wNmNBJQMOGhYDMwMBCAu6DRYAAAAAAgBg/8YDugMiAB4AMwAABSc+ATU0JyYnJiIHBgcGFBcWFxYzMjc2NxcWMjc2JiUiJyYnJjQ3Njc2MhcWFxYUBwYHBgOxviouNDFVV8lXVTIzMzJVV2RDPzwzvgkeCAcB/hxUSEYpKiopRkioSEYpKyspRkgCvjB9RGRYVDIzNDJVWMlXVTE0GBYqvgkJChuBKylGSKhIRikqKilGSKhIRikrAAAAABIA3gABAAAAAAAAABMAKAABAAAAAAABAAgATgABAAAAAAACAAcAZwABAAAAAAADAAgAgQABAAAAAAAEAAgAnAABAAAAAAAFAAsAvQABAAAAAAAGAAgA2wABAAAAAAAKACsBPAABAAAAAAALABMBkAADAAEECQAAACYAAAADAAEECQABABAAPAADAAEECQACAA4AVwADAAEECQADABAAbwADAAEECQAEABAAigADAAEECQAFABYApQADAAEECQAGABAAyQADAAEECQAKAFYA5AADAAEECQALACYBaABDAHIAZQBhAHQAZQBkACAAYgB5ACAAaQBjAG8AbgBmAG8AbgB0AABDcmVhdGVkIGJ5IGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAABHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuAABoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAABodHRwOi8vZm9udGVsbG8uY29tAAAAAAIAAAAAAAAACgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAACwAAAAEAAgECAQMBBAEFAQYBBwEIAQkRYXJyb3ctZG91YmxlLWxlZnQSYXJyb3ctZG91YmxlLXJpZ2h0EGN1c3RvbWVyLXNlcnZpY2URZnVsbHNjcmVlbi1leHBhbmQRZnVsbHNjcmVlbi1zaHJpbmsGcHJvbXB0B3JlZnJlc2gGc2VhcmNoAAAAAf//AAIAAQAAAAwAAAAWAAAAAgABAAMACgABAAQAAAACAAAAAAAAAAEAAAAA1aQnCAAAAADeWFEjAAAAAN5YUSM=') format('truetype'); + font-weight: 600; + font-style: normal; + font-display: swap; +} +.gvaIcon { + font-family: "gvaIcon" !important; + font-size: 16px; + font-style: normal; + font-weight: 800; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + +.gvaIcon-arrow-double-left:before { + content: "\e665"; + } + +.gvaIcon-arrow-double-right:before { + content: "\e666"; +} + +.gvaIcon-fullscreen-shrink:before { + content: "\e676"; +} +.gvaIcon-customer-service:before { + content: "\e66a"; + } + +.gvaIcon-fullscreen-expand:before { + content: "\e675"; +} + +.gvaIcon-prompt:before { + content: "\e67b"; +} + +.gvaIcon-refresh:before { + content: "\e67c"; +} + +.gvaIcon-search:before { + content: "\e67d"; +} + diff --git a/src/style/main.scss b/src/style/main.scss new file mode 100644 index 0000000..9282bef --- /dev/null +++ b/src/style/main.scss @@ -0,0 +1,1226 @@ +/* Document + ========================================================================== */ + + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +@import '@/style/basics.scss'; +@import '@/style/iconfont.css'; +html { + line-height: 1.15; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ +} + + +/* Sections + ========================================================================== */ + + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + + +/* Grouping content + ========================================================================== */ + + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ +} + + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + + +/* Text-level semantics + ========================================================================== */ + + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + text-decoration: underline dotted; + /* 2 */ +} + + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + + +/* Embedded content + ========================================================================== */ + + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + + +/* Forms + ========================================================================== */ + + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + line-height: 1.15; + /* 1 */ + margin: 0; + /* 2 */ +} + + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { + /* 1 */ + overflow: visible; +} + + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { + /* 1 */ + text-transform: none; +} + + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; + /* 1 */ + color: inherit; + /* 2 */ + display: table; + /* 1 */ + max-width: 100%; + /* 1 */ + padding: 0; + /* 3 */ + white-space: normal; + /* 1 */ +} + + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ +} + + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + + +/* Interactive + ========================================================================== */ + + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + + +/* Misc + ========================================================================== */ + + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} + +HTML, +body, +div, +ul, +ol, +dl, +li, +dt, +dd, +p, +blockquote, +pre, +form, +fieldset, +table, +th, +td { + border: none; + font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif; + font-size: 14px; + margin: 0px; + padding: 0px; +} + +html, +body { + height: 100%; + width: 100%; +} + +address, +caption, +cite, +code, +th, +var { + font-style: normal; + font-weight: normal; +} + +a { + text-decoration: none; +} + +input::-ms-clear { + display: none; +} + +input::-ms-reveal { + display: none; +} + +input { + -webkit-appearance: none; + margin: 0; + outline: none; + padding: 0; +} + +input::-webkit-input-placeholder { + color: #ccc; +} + +input::-ms-input-placeholder { + color: #ccc; +} + +input::-moz-placeholder { + color: #ccc; +} + +input[type=submit], +input[type=button] { + cursor: pointer; +} + +button[disabled], +input[disabled] { + cursor: default; +} + +img { + border: none; +} + +ul, +ol, +li { + list-style-type: none; +} + +// 导航 +#app { + .pd-lr-15 { + padding: 0 15px; + } + .height-full { + height: 100%; + } + .width-full { + width: 100%; + } + .dp-flex { + display: flex; + } + .justify-content-center { + justify-content: center; + } + .align-items { + align-items: center; + } + .pd-0 { + padding: 0; + } + .el-container { + position: relative; + height: 100%; + width: 100%; + } + .el-container.mobile.openside { + position: fixed; + top: 0; + } + .gva-aside { + -webkit-transition: width .2s; + transition: width .2s; + width: $width-aside; + height: 100%; + position: fixed; + font-size: 0; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + .el-menu { + border-right: none; + } + .tilte { + min-height: $height-aside-tilte; + line-height: $height-aside-tilte; + text-align: center; + transition: all 0.3s; + display: flex; + align-items: center; + justify-content: center; + .logoimg { + width: $width-aside-img; + height: $height-aside-img; + background: #fff; + border-radius: 50%; + padding: 3px; + } + .tit-text { + display: inline-block; + color: #fff; + font-weight: 600; + font-size: 20px; + padding-left: 10px; + } + } + } + .aside { + .el-menu--collapse { + >.el-menu-item { + display: flex; + justify-content: center; + } + } + .el-sub-menu { + .el-menu { + .is-active { + // 关闭三级菜单二级菜单样式 + ul { + border: none; + } + } + // 关闭三级菜单二级菜单样式 + .is-active.is-opened { + ul { + border: none; + } + } + } + } + } + .hideside { + .aside { + width: $width-hideside-aside; + } + } + .mobile.hideside { + .gva-aside { + -webkit-transition-duration: .2s; + transition-duration: .2s; + -webkit-transform: translate3d(-210px, 0, 0); + transform: translate3d(-220px, 0, 0); + } + } + .mobile { + .gva-aside { + -webkit-transition: -webkit-transform .28s; + transition: -webkit-transform .28s; + transition: transform .28s; + transition: transform .28s, -webkit-transform .28s; + width: $width-mobile-aside; + } + } + .main-cont.el-main { + min-height: 100%; + margin-left: $width-aside; + position: relative; + } + .hideside { + .main-cont.el-main { + margin-left: 54px; + } + } + .mobile { + .main-cont.el-main { + margin-left: 0px; + } + } + .openside.mobile { + .shadowBg { + background: #000; + opacity: .3; + width: 100%; + top: 0; + height: 100%; + position: absolute; + z-index: 999; + left: 0; + } + } +} + +// layout +.layout-cont { + .main-cont { + position: relative; + &.el-main { + background-color: $bg-main; + padding: 0; + } + } +} + +.admin-box { + min-height: calc(100vh - 200px); + padding: 12px 16px; + margin: 100px 2px 20px; + .el-table--border { + border-radius: 4px; + margin-bottom: 14px; + } + .el-table { + thead { + color: $color-table-thead; + } + th { + padding: 6px 0; + .cell { + color: rgba($color: #000000, $alpha: 0.85); + font-size: 14px; + line-height: 40px; + min-height: 40px; + } + } + td { + padding: 6px 0; + .cell { + min-height: 40px; + line-height: 40px; + color: rgba($color: #000000, $alpha: 0.65); + } + } + td.is-leaf { + border-bottom: 1px solid #e8e8e8; + } + th.is-leaf { + background: #F7FBFF; + border-bottom: none; + } + } + .el-pagination { + padding: 20px 0 0 0; + } + .upload-demo, + .upload { + padding: 0; + } + .edit_container, + .edit { + padding: 0; + } + .el-input { + .el-input__suffix { + margin-top: -3px; + } + &.is-disabled { + .el-input__suffix { + margin-top: 0px; + } + } + } + .el-cascader { + .el-input { + .el-input__suffix { + margin-top: 0px; + } + } + } + .el-input__inner { + border-color: rgba($color: #000000, $alpha: 0.15); + height: 32px; + border-radius: 2px; + } +} + +.admin-box:after, +.admin-box:before { + content: ""; + display: block; + clear: both; +} + +.button-box { + background: $white-bg; + border: none; + padding: 0 0 10px 0px; +} + +// table +.has-gutter { + tr { + th { + background-color: #fafafa; + } + } +} + +.el-table--striped { + .el-table__body { + tr.el-table__row--striped { + td { + background: #fff !important; + } + } + } +} + +.el-table th, +.el-table tr { + background-color: #ffffff; +} + +.el-pagination { + .btn-prev, + .btn-next { + border: 1px solid #ddd; + border-radius: 4px; + } + .el-pager { + li { + color: #666; + font-size: 12px; + margin: 0 5px; + border: 1px solid #ddd; + border-radius: 4px; + } + } + padding: 20px 0 !important; +} + +.el-row { + padding: 10px 0; + .el-col>label { + line-height: 30px; + text-align: right; + width: 80%; + padding-right: 15px; + display: inline-block; + } + .line { + line-height: 30px; + text-align: center; + } +} + +.edit_container { + background-color: $white-bg; + padding: 15px; + .el-button { + margin: 15px 0; + } +} + +.edit { + background-color: $white-bg; + .el-button { + margin: 15px 0; + } +} + +.el-container { + .tips { + margin-top: 10px; + font-size: 14px; + font-weight: 400; + color: #606266; + } +} + +.el-container.layout-cont { + .main-cont.el-main { + background-color: $bg-main; + .menu-total { + cursor: pointer; + font-size: 24px; + color: #000000; + margin-top: 16px; + } + } +} + +.el-container.layout-cont { + .main-cont { + .router-history { + // box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); + background: #fff; + padding: 0 6px; + border-top: 1px solid $border-color; + padding: 0; + .el-tabs__header { + margin: 0px 0 0 0; + .el-tabs__item { + height: $height-nav-scroll; + height: $height-nav-scroll; + border: none; + border-left: 1px solid $border-color; + border-right: 1px solid $border-color; + +.el-tabs__item { + border-left: 0px solid $border-color; + } + } + .el-tabs__item.is-active { + background-color: rgba(64, 158, 255, .08); + } + .el-tabs__nav { + border: none; + } + } + } + } +} + +.el-table__row { + .el-button.el-button--text.el-button--small { + position: relative; + } + // .el-button.el-button--text.el-button--small::after { + // content: ''; + // position: absolute; + // width: 1px; + // height: 50%; + // top: 5px; + // margin-left: 15px; + // background-color: #e8e8e8; + // } + .cell { + button:last-child::after { + content: '' !important; + position: absolute !important; + width: 0px !important; + } + } +} + +.clear:after, +.clear:before { + content: ""; + display: block; + clear: both; +} + +.el-table--striped .el-table__body tr.el-table__row--level-1 td:first-child { + .cell { + .el-table__indent { + border-right: 1.5px solid #ccc; + margin-left: 6px; + } + .el-table__placeholder { + width: 10px; + } + } +} + +.el-table--striped .el-table__body tr.el-table__row--level-2 td:first-child { + .cell { + .el-table__indent { + border-right: 1.5px solid #ccc; + margin-left: 6px; + } + .el-table__placeholder { + width: 10px; + } + } +} + +$headerHigh: 52px; +$mainHight: 100vh; +.dropdown-group { + min-width: 100px; +} + +.topfix { + position: fixed; + top: 0; + box-sizing: border-box; + z-index: 999; + >.el-row { + padding: 0; + .el-col-lg-14 { + height: 60px; + } + } +} + +.layout-cont { + .right-box { + padding-top: 16px; + display: flex; + justify-content: flex-end; + align-items: center; + img { + vertical-align: middle; + border: 1px solid #ccc; + border-radius: 6px; + } + } + .header-cont { + padding: 0 16px; + height: $height-header; + background: #fff; + } + .main-cont { + .breadcrumb { + height: $height-header; + line-height: $height-header; + display: inline-block; + padding: 0; + margin-left: 46px; + font-size: 16px; + .el-breadcrumb__item { + .el-breadcrumb__inner { + color: rgba($color: #000000, $alpha: 0.45); + } + } + .el-breadcrumb__item:nth-last-child(1) { + .el-breadcrumb__inner { + color: rgba($color: #000000, $alpha: 0.65); + } + } + } + &.el-main { + overflow: auto; + background: #fff; + } + height: $mainHight !important; + overflow: visible; + position: relative; + .menu-total { + margin-left: 6px; + cursor: pointer; + float: left; + margin-top: 10px; + width: 30px; + height: 30px; + line-height: 30px; + font-size: 30px; + } + .aside { + overflow: auto; + // background: #fff; + &::-webkit-scrollbar { + display: none; + } + } + .el-menu-vertical { + height: calc(100vh - 60px) !important; + visibility: auto; + &:not(.el-menu--collapse) { + width: 220px; + } + } + .el-menu--collapse { + width: 54px; + li { + .el-tooltip, + .el-sub-menu__title { + padding: 0px 15px !important; + } + } + } + &::-webkit-scrollbar { + display: none; + } + &.main-left { + width: auto !important; + } + &.main-right { + .admin-title { + float: left; + font-size: 16px; + vertical-align: middle; + margin-left: 20px; + img { + vertical-align: middle; + } + &.collapse { + width: 53px; + } + } + } + } +} + +.header-avatar { + display: flex; + justify-content: center; + align-items: center; +} + +.search-component { + display: inline-flex; + overflow: hidden; + text-align: center; + .el-input__inner { + border: none; + border-bottom: 1px solid #606266; + } + .el-dropdown-link { + cursor: pointer; + } + .search-icon { + font-size: $icon-size; + display: inline-block; + vertical-align: middle; + box-sizing: border-box; + color: rgba($color: #000000, $alpha: 0.65); + } + .dropdown-group { + min-width: 100px; + } + .user-box { + cursor: pointer; + margin-right: 24px; + color: rgba($color: #000000, $alpha: 0.65); + } +} + +.transition-box { + overflow: hidden; + width: 160px; + margin-right: 32px; + text-align: center; + margin-top: -12px; + .el-input__wrapper{ + .el-input__inner{ + height: 100%; + } + box-shadow: none !important; + } + .el-select .el-input .el-input__wrapper.is-focus{ + box-shadow: none !important; + } + .el-select .el-input.is-focus .el-input__wrapper{ + box-shadow: none !important; + } +} + +.screenfull { + overflow: hidden; + color: rgba($color: #000000, $alpha: 0.65); +} + +.el-dropdown { + overflow: hidden; +} + +// dashboard +.card { + background-color: $white-bg; + padding: 20px; + border-radius: 4px; + overflow: hidden; + .car-left { + height: $height-car; + // width: 70%; + // float: left; + } + .car-right { + height: $height-car; + // width: 29%; + // float: left; + .flow, + .user-number, + .feedback { + width: $el-icon-mini; + height: $el-icon-mini; + display: inline-block; + border-radius: 50%; + line-height: $el-icon-mini; + text-align: center; + font-size: 13px; + margin-right: 5px; + } + .flow { + background-color: #fff7e8; + border-color: #feefd0; + color: #faad14; + } + .user-number { + background-color: #ecf5ff; + border-color: #d9ecff; + color: #409eff; + } + .feedback { + background-color: #eef9e8; + border-color: #dcf3d1; + color: #52c41a; + } + .card-item { + padding-right: 20px; + text-align: right; + margin-top: 12px; + b { + margin-top: 6px; + display: block; + } + } + } + .card-img { + width: $height-car; + height: $height-car; + display: inline-block; + float: left; + overflow: hidden; + img { + width: 100%; + height: 100%; + border-radius: 50%; + } + } + .text { + height: $height-car; + margin-left: 10px; + float: left; + margin-top: 14px; + h4 { + font-size: 20px; + color: #262626; + font-weight: 500; + white-space: nowrap; + word-break: break-all; + text-overflow: ellipsis; + } + .tips-text { + color: #8c8c8c; + margin-top: 8px; + .el-icon { + margin-right: 8px; + display: inline-block; + } + } + } +} + +.shadow { + margin: 4px 0; + .grid-content { + background-color: $white-bg; + border-radius: 4px; + text-align: center; + padding: 10px 0; + cursor: pointer; + .el-icon { + width: $el-icon-small; + height: $el-icon-small; + font-size: $el-icon-small; + margin-bottom: 8px; + } + } +} + +.gva-btn-list { + margin-bottom: 12px; + display: flex; + .el-button+.el-button { + margin-left: 12px; + } +} + +.justify-content-flex-end { + justify-content: flex-end; +} \ No newline at end of file diff --git a/src/style/mobile.scss b/src/style/mobile.scss new file mode 100644 index 0000000..a593f2c --- /dev/null +++ b/src/style/mobile.scss @@ -0,0 +1,77 @@ +@import '@/style/basics.scss'; +@media screen and (min-width: 320px)and (max-width: 750px) { + .el-header { + padding: 0 $padding-xs; + } + .layout-cont { + .main-cont { + .breadcrumb { + padding: 0 $padding-xs; + } + } + } + .layout-cont { + .right-box { + margin-right: $margin-xs; + } + } + .el-main { + .admin-box { + margin-left: 0; + margin-right: 0; + } + .big.admin-box { + padding: 0; + } + .big { + .bottom { + .chart-player { + height: auto!important; + margin-bottom: 15px; + } + .todoapp { + background-color: #fff; + padding-bottom: 10px; + } + } + } + } + .card .car-left, + .card .car-right { + width: 100%; + height: 100%; + } + .card { + padding-left: $padding-xs; + padding-right: $padding-xs; + } + .card { + .text { + width: 100%; + h4 { + white-space: break-spaces; + } + } + } + .shadow { + margin-left: 4px; + margin-right: 4px; + .grid-content { + margin-bottom: 10px; + padding: 0; + } + } + .el-dialog { + width: 90%; + } + .el-transfer { + .el-transfer-panel { + width: 40%; + display: inline-block; + } + .el-transfer__buttons { + padding: 0 5px; + display: inline-block; + } + } +} \ No newline at end of file diff --git a/src/style/newLogin.scss b/src/style/newLogin.scss new file mode 100644 index 0000000..5d89b3c --- /dev/null +++ b/src/style/newLogin.scss @@ -0,0 +1,105 @@ +#userLayout { + margin: 0; + padding: 0; + background-image: url("@/assets/login_background.jpg"); + background-size: cover; + width: 100%; + height: 100%; + position: relative; + .input-icon { + padding-right: 6px; + padding-top: 4px; + } + .login_panel { + position: absolute; + top: 3vh; + left: 2vw; + width: 96vw; + height: 94vh; + background-color: rgba(255, 255, 255, .8); + border-radius: 10px; + display: flex; + align-items: center; + justify-content: space-evenly; + .login_panel_right { + background-image: url("@/assets/login_left.svg"); + background-size: cover; + width: 40%; + height: 60%; + float: right !important; + } + .login_panel_form { + width: 420px; + background-color: #fff; + padding: 40px 40px 40px 40px; + border-radius: 10px; + box-shadow: 2px 3px 7px rgba(0, 0, 0, .2); + .login_panel_form_title { + display: flex; + align-items: center; + margin: 30px 0; + .login_panel_form_title_logo { + width: 90px; + height: 72px; + } + .login_panel_form_title_p { + font-size: 40px; + padding-left: 20px; + } + } + .vPicBox { + display: flex; + justify-content: space-between; + width: 100%; + } + .vPic { + width: 33%; + height: 38px; + background: #ccc; + img { + width: 100%; + height: 100%; + vertical-align: middle; + } + } + } + .login_panel_foot { + position: absolute; + bottom: 20px; + .links { + display: flex; + align-items: center; + justify-content: space-between; + .link-icon { + width: 30px; + height: 30px; + } + } + .copyright { + color: #777777; + margin-top: 5px; + } + } + } +} + +//小屏幕不显示右侧,将登录框居中 +@media (max-width: 750px) { + .login_panel_right { + display: none; + } + .login_panel { + width: 100vw; + height: 100vh; + top: 0; + left: 0; + } + .login_panel_form { + width: 100%; + } +} + + +/* + powerBy : bypanghu@163.com +*/ \ No newline at end of file diff --git a/src/utils/asyncRouter.js b/src/utils/asyncRouter.js new file mode 100644 index 0000000..48809ed --- /dev/null +++ b/src/utils/asyncRouter.js @@ -0,0 +1,33 @@ +const viewModules = import.meta.glob('../view/**/*.vue') +const pluginModules = import.meta.glob('../plugin/**/*.vue') + +export const asyncRouterHandle = (asyncRouter) => { + asyncRouter.forEach(item => { + if (item.component) { + if (item.component.split('/')[0] === 'view') { + item.component = dynamicImport(viewModules, item.component) + } else if (item.component.split('/')[0] === 'plugin') { + item.component = dynamicImport(pluginModules, item.component) + } + } else { + delete item['component'] + } + if (item.children) { + asyncRouterHandle(item.children) + } + }) +} + +function dynamicImport( + dynamicViewsModules, + component +) { + const keys = Object.keys(dynamicViewsModules) + const matchKeys = keys.filter((key) => { + const k = key.replace('../', '') + return k === component + }) + const matchKey = matchKeys[0] + + return dynamicViewsModules[matchKey] +} diff --git a/src/utils/btnAuth.js b/src/utils/btnAuth.js new file mode 100644 index 0000000..f94fa9b --- /dev/null +++ b/src/utils/btnAuth.js @@ -0,0 +1,6 @@ +import { useRoute } from 'vue-router' +import { reactive } from 'vue' +export const useBtnAuth = () => { + const route = useRoute() + return route.meta.btns || reactive({}) +} diff --git a/src/utils/bus.js b/src/utils/bus.js new file mode 100644 index 0000000..4b673fa --- /dev/null +++ b/src/utils/bus.js @@ -0,0 +1,6 @@ + +// using ES6 modules +import mitt from 'mitt' + +export const emitter = mitt() + diff --git a/src/utils/closeThisPage.js b/src/utils/closeThisPage.js new file mode 100644 index 0000000..b2a0c05 --- /dev/null +++ b/src/utils/closeThisPage.js @@ -0,0 +1,5 @@ +import { emitter } from '@/utils/bus.js' + +export const closeThisPage = () => { + emitter.emit('closeThisPage') +} diff --git a/src/utils/date.js b/src/utils/date.js new file mode 100644 index 0000000..6bb8570 --- /dev/null +++ b/src/utils/date.js @@ -0,0 +1,30 @@ +// 对Date的扩展,将 Date 转化为指定格式的String +// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, +// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) +// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 +// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 +// eslint-disable-next-line no-extend-native +Date.prototype.Format = function(fmt) { + var o = { + 'M+': this.getMonth() + 1, // 月份 + 'd+': this.getDate(), // 日 + 'h+': this.getHours(), // 小时 + 'm+': this.getMinutes(), // 分 + 's+': this.getSeconds(), // 秒 + 'q+': Math.floor((this.getMonth() + 3) / 3), // 季度 + 'S': this.getMilliseconds() // 毫秒 + } + if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)) } + for (var k in o) { + if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) } + } + return fmt +} + +export function formatTimeToStr(times, pattern) { + var d = new Date(times).Format('yyyy-MM-dd hh:mm:ss') + if (pattern) { + d = new Date(times).Format(pattern) + } + return d.toLocaleString() +} diff --git a/src/utils/dictionary.js b/src/utils/dictionary.js new file mode 100644 index 0000000..1b0dba8 --- /dev/null +++ b/src/utils/dictionary.js @@ -0,0 +1,19 @@ +import { useDictionaryStore } from '@/pinia/modules/dictionary' +// 获取字典方法 使用示例 getDict('sex').then(res) 或者 async函数下 const res = await getDict('sex') +export const getDict = async(type) => { + const dictionaryStore = useDictionaryStore() + await dictionaryStore.getDictionary(type) + return dictionaryStore.dictionaryMap[type] +} + +// 字典文字展示方法 +export const showDictLabel = (dict, code) => { + if (!dict) { + return '' + } + const dictMap = {} + dict.forEach(item => { + dictMap[item.value] = item.label + }) + return dictMap[code] +} diff --git a/src/utils/downloadImg.js b/src/utils/downloadImg.js new file mode 100644 index 0000000..93fb222 --- /dev/null +++ b/src/utils/downloadImg.js @@ -0,0 +1,19 @@ +export const downloadImage = (imgsrc, name) => { // 下载图片地址和图片名 + var image = new Image() + image.setAttribute('crossOrigin', 'anonymous') + image.onload = function() { + var canvas = document.createElement('canvas') + canvas.width = image.width + canvas.height = image.height + var context = canvas.getContext('2d') + context.drawImage(image, 0, 0, image.width, image.height) + var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据 + + var a = document.createElement('a') // 生成一个a元素 + var event = new MouseEvent('click') // 创建一个单击事件 + a.download = name || 'photo' // 设置图片名称 + a.href = url // 将生成的URL设置为a.href属性 + a.dispatchEvent(event) // 触发a的单击事件 + } + image.src = imgsrc +} diff --git a/src/utils/fmtRouterTitle.js b/src/utils/fmtRouterTitle.js new file mode 100644 index 0000000..bcaeb67 --- /dev/null +++ b/src/utils/fmtRouterTitle.js @@ -0,0 +1,13 @@ +export const fmtTitle = (title, now) => { + const reg = /\$\{(.+?)\}/ + const reg_g = /\$\{(.+?)\}/g + const result = title.match(reg_g) + if (result) { + result.forEach((item) => { + const key = item.match(reg)[1] + const value = now.params[key] || now.query[key] + title = title.replace(item, value) + }) + } + return title +} diff --git a/src/utils/format.js b/src/utils/format.js new file mode 100644 index 0000000..b8361be --- /dev/null +++ b/src/utils/format.js @@ -0,0 +1,28 @@ +import { formatTimeToStr } from '@/utils/date' +import { getDict } from '@/utils/dictionary' + +export const formatBoolean = (bool) => { + if (bool !== null) { + return bool ? '是' : '否' + } else { + return '' + } +} +export const formatDate = (time) => { + if (time !== null && time !== '') { + var date = new Date(time) + return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss') + } else { + return '' + } +} + +export const filterDict = (value, options) => { + const rowLabel = options && options.filter(item => item.value === value) + return rowLabel && rowLabel[0] && rowLabel[0].label +} + +export const getDictFunc = async(type) => { + const dicts = await getDict(type) + return dicts +} diff --git a/src/utils/image.js b/src/utils/image.js new file mode 100644 index 0000000..6e0d1e8 --- /dev/null +++ b/src/utils/image.js @@ -0,0 +1,92 @@ +export default class ImageCompress { + constructor(file, fileSize, maxWH = 1920) { + this.file = file + this.fileSize = fileSize + this.maxWH = maxWH // 最大长宽 + } + + compress() { + // 压缩 + const fileType = this.file.type + const fileSize = this.file.size / 1024 + return new Promise(resolve => { + const reader = new FileReader() + reader.readAsDataURL(this.file) + reader.onload = () => { + const canvas = document.createElement('canvas') + const img = document.createElement('img') + img.src = reader.result + img.onload = () => { + const ctx = canvas.getContext('2d') + const _dWH = this.dWH(img.width, img.height, this.maxWH) + canvas.width = _dWH.width + canvas.height = _dWH.height + + // 清空后, 重写画布 + ctx.clearRect(0, 0, canvas.width, canvas.height) + ctx.drawImage(img, 0, 0, canvas.width, canvas.height) + + const newImgData = canvas.toDataURL(fileType, 0.90) + + // 压缩宽高后的图像大小 + const newImgSize = this.fileSizeKB(newImgData) + + if (newImgSize > this.fileSize) { + console.log('图片尺寸太大!' + fileSize + ' >> ' + newImgSize) + } + + const blob = this.dataURLtoBlob(newImgData, fileType) + const nfile = new File([blob], this.file.name) + resolve(nfile) + } + } + }) + } + + /** + * 长宽等比缩小 + * 图像的一边(长或宽)为最大目标值 + */ + dWH(srcW, srcH, dMax) { + const defaults = { + width: srcW, + height: srcH + } + if (Math.max(srcW, srcH) > dMax) { + if (srcW > srcH) { + defaults.width = dMax + defaults.height = Math.round(srcH * (dMax / srcW)) + return defaults + } else { + defaults.height = dMax + defaults.width = Math.round(srcW * (dMax / srcH)) + return defaults + } + } else { + return defaults + } + } + + fileSizeKB(dataURL) { + let sizeKB = 0 + sizeKB = Math.round((dataURL.split(',')[1].length * 3 / 4) / 1024) + return sizeKB + } + + /** + * 转为Blob + */ + dataURLtoBlob(dataURL, fileType) { + const byteString = atob(dataURL.split(',')[1]) + let mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0] + const ab = new ArrayBuffer(byteString.length) + const ia = new Uint8Array(ab) + for (let i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i) + } + if (fileType) { + mimeString = fileType + } + return new Blob([ab], { type: mimeString, lastModifiedDate: new Date() }) + } +} diff --git a/src/utils/page.js b/src/utils/page.js new file mode 100644 index 0000000..6a3c6d8 --- /dev/null +++ b/src/utils/page.js @@ -0,0 +1,9 @@ +import { fmtTitle } from '@/utils/fmtRouterTitle' +import config from '@/core/config' +export default function getPageTitle(pageTitle, route) { + if (pageTitle) { + const title = fmtTitle(pageTitle, route) + return `${title} - ${config.appName}` + } + return `${config.appName}` +} diff --git a/src/utils/positionToCode.js b/src/utils/positionToCode.js new file mode 100644 index 0000000..3fb1f9f --- /dev/null +++ b/src/utils/positionToCode.js @@ -0,0 +1,36 @@ +export const initDom = () => { + if (import.meta.env.MODE === 'development') { + document.onmousedown = function(e) { + if (e.shiftKey && e.button === 0) { + e.preventDefault() + sendRequestToOpenFileInEditor(getFilePath(e)) + } + } + } +} + +const getFilePath = (e) => { + let element = e + if (e.target) { + element = e.target + } + if (!element || !element.getAttribute) return null + if (element.getAttribute('code-location')) { + return element.getAttribute('code-location') + } + return getFilePath(element.parentNode) +} + +const sendRequestToOpenFileInEditor = (filePath) => { + const protocol = window.location.protocol + ? window.location.protocol + : 'http:' + const hostname = window.location.hostname + ? window.location.hostname + : 'localhost' + const port = window.location.port ? window.location.port : '80' + fetch(`${protocol}//${hostname}:${port}/gvaPositionCode?filePath=${filePath}`) + .catch((error) => { + console.log(error) + }) +} diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..6ca0ef7 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,141 @@ +import axios from 'axios' // 引入axios +import { ElMessage, ElMessageBox } from 'element-plus' +import { useUserStore } from '@/pinia/modules/user' +import { emitter } from '@/utils/bus.js' +import router from '@/router/index' + +const service = axios.create({ + baseURL: import.meta.env.VITE_BASE_API, + timeout: 99999 +}) +let acitveAxios = 0 +let timer +const showLoading = () => { + acitveAxios++ + if (timer) { + clearTimeout(timer) + } + timer = setTimeout(() => { + if (acitveAxios > 0) { + emitter.emit('showLoading') + } + }, 400) +} + +const closeLoading = () => { + acitveAxios-- + if (acitveAxios <= 0) { + clearTimeout(timer) + emitter.emit('closeLoading') + } +} +// http request 拦截器 +service.interceptors.request.use( + config => { + if (!config.donNotShowLoading) { + showLoading() + } + const userStore = useUserStore() + config.headers = { + 'Content-Type': 'application/json', + 'x-token': userStore.token, + 'x-user-id': userStore.userInfo.ID, + ...config.headers + } + return config + }, + error => { + if (!error.config.donNotShowLoading) { + closeLoading() + } + ElMessage({ + showClose: true, + message: error, + type: 'error' + }) + return error + } +) + +// http response 拦截器 +service.interceptors.response.use( + response => { + const userStore = useUserStore() + if (!response.config.donNotShowLoading) { + closeLoading() + } + if (response.headers['new-token']) { + userStore.setToken(response.headers['new-token']) + } + if (response.data.code === 0 || response.headers.success === 'true') { + if (response.headers.msg) { + response.data.msg = decodeURI(response.headers.msg) + } + return response.data + } else { + ElMessage({ + showClose: true, + message: response.data.msg || decodeURI(response.headers.msg), + type: 'error' + }) + if (response.data.data && response.data.data.reload) { + userStore.token = '' + localStorage.clear() + router.push({ name: 'Login', replace: true }) + } + return response.data.msg ? response.data : response + } + }, + error => { + if (!error.config.donNotShowLoading) { + closeLoading() + } + + if (!error.response) { + ElMessageBox.confirm(` +

检测到请求错误

+

${error}

+ `, '请求报错', { + dangerouslyUseHTMLString: true, + distinguishCancelAndClose: true, + confirmButtonText: '稍后重试', + cancelButtonText: '取消' + }) + return + } + + switch (error.response.status) { + case 500: + ElMessageBox.confirm(` +

检测到接口错误${error}

+

错误码 500 :此类错误内容常见于后台panic,请先查看后台日志,如果影响您正常使用可强制登出清理缓存

+ `, '接口报错', { + dangerouslyUseHTMLString: true, + distinguishCancelAndClose: true, + confirmButtonText: '清理缓存', + cancelButtonText: '取消' + }) + .then(() => { + const userStore = useUserStore() + userStore.token = '' + localStorage.clear() + router.push({ name: 'Login', replace: true }) + }) + break + case 404: + ElMessageBox.confirm(` +

检测到接口错误${error}

+

错误码 404 :此类错误多为接口未注册(或未重启)或者请求路径(方法)与api路径(方法)不符--如果为自动化代码请检查是否存在空格

+ `, '接口报错', { + dangerouslyUseHTMLString: true, + distinguishCancelAndClose: true, + confirmButtonText: '我知道了', + cancelButtonText: '取消' + }) + break + } + + return error + } +) +export default service diff --git a/src/utils/stringFun.js b/src/utils/stringFun.js new file mode 100644 index 0000000..eac4179 --- /dev/null +++ b/src/utils/stringFun.js @@ -0,0 +1,29 @@ +/* eslint-disable */ +export const toUpperCase = (str) => { + if (str[0]) { + return str.replace(str[0], str[0].toUpperCase()) + } else { + return '' + } +} + +export const toLowerCase = (str) => { + if (str[0]) { + return str.replace(str[0], str[0].toLowerCase()) + } else { + return '' + } +} + +// 驼峰转换下划线 +export const toSQLLine = (str) => { + if (str === 'ID') return 'ID' + return str.replace(/([A-Z])/g, "_$1").toLowerCase(); +} + +// 下划线转换驼峰 +export const toHump = (name) => { + return name.replace(/\_(\w)/g, function(all, letter) { + return letter.toUpperCase(); + }); +} \ No newline at end of file diff --git a/src/view/about/index.vue b/src/view/about/index.vue new file mode 100644 index 0000000..7506471 --- /dev/null +++ b/src/view/about/index.vue @@ -0,0 +1,191 @@ + + + + + + + diff --git a/src/view/dashboard/dashboardCharts/echartsLine.vue b/src/view/dashboard/dashboardCharts/echartsLine.vue new file mode 100644 index 0000000..f525619 --- /dev/null +++ b/src/view/dashboard/dashboardCharts/echartsLine.vue @@ -0,0 +1,129 @@ + + + diff --git a/src/view/dashboard/dashboardTable/dashboardTable.vue b/src/view/dashboard/dashboardTable/dashboardTable.vue new file mode 100644 index 0000000..4a6bb09 --- /dev/null +++ b/src/view/dashboard/dashboardTable/dashboardTable.vue @@ -0,0 +1,112 @@ + + + + + + diff --git a/src/view/dashboard/index.vue b/src/view/dashboard/index.vue new file mode 100644 index 0000000..b966deb --- /dev/null +++ b/src/view/dashboard/index.vue @@ -0,0 +1,329 @@ + + + + + + diff --git a/src/view/dashboard/weather.js b/src/view/dashboard/weather.js new file mode 100644 index 0000000..11b2152 --- /dev/null +++ b/src/view/dashboard/weather.js @@ -0,0 +1,31 @@ + +import axios from 'axios' +import { ref } from 'vue' + +const weatherInfo = ref('今日晴,0℃ - 10℃,天气寒冷,注意添加衣物。') +const amapKey = '8e8baa8a7317586c29ec694895de6e0a' + +export const useWeatherInfo = () => { + ip() + return weatherInfo +} + +export const ip = async() => { + // key换成你自己的 https://console.amap.com/dev/index + if (amapKey === '') { + return false + } + const res = await axios.get('https://restapi.amap.com/v3/ip?key=' + amapKey) + if (res.data.adcode) { + getWeather(res.data.adcode) + } +} + +const getWeather = async(code) => { + const response = await axios.get('https://restapi.amap.com/v3/weather/weatherInfo?key=' + amapKey + '&extensions=base&city=' + code) + if (response.data.status === '1') { + const s = response.data.lives[0] + weatherInfo.value = s.city + ' 天气:' + s.weather + ' 温度:' + s.temperature + '摄氏度 风向:' + s.winddirection + ' 风力:' + s.windpower + '级 空气湿度:' + s.humidity + } +} + diff --git a/src/view/error/index.vue b/src/view/error/index.vue new file mode 100644 index 0000000..4a10d83 --- /dev/null +++ b/src/view/error/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/view/error/reload.vue b/src/view/error/reload.vue new file mode 100644 index 0000000..fdeb8ce --- /dev/null +++ b/src/view/error/reload.vue @@ -0,0 +1,14 @@ + + + + diff --git a/src/view/example/breakpoint/breakpoint.vue b/src/view/example/breakpoint/breakpoint.vue new file mode 100644 index 0000000..5f683ad --- /dev/null +++ b/src/view/example/breakpoint/breakpoint.vue @@ -0,0 +1,266 @@ + + + + + + + diff --git a/src/view/example/customer/customer.vue b/src/view/example/customer/customer.vue new file mode 100644 index 0000000..215fe8f --- /dev/null +++ b/src/view/example/customer/customer.vue @@ -0,0 +1,182 @@ + + + + + + + diff --git a/src/view/example/index.vue b/src/view/example/index.vue new file mode 100644 index 0000000..554852f --- /dev/null +++ b/src/view/example/index.vue @@ -0,0 +1,21 @@ + + + + diff --git a/src/view/example/upload/upload.vue b/src/view/example/upload/upload.vue new file mode 100644 index 0000000..cfab617 --- /dev/null +++ b/src/view/example/upload/upload.vue @@ -0,0 +1,210 @@ + + + + + + diff --git a/src/view/init/index.vue b/src/view/init/index.vue new file mode 100644 index 0000000..a3261ae --- /dev/null +++ b/src/view/init/index.vue @@ -0,0 +1,320 @@ + + + + + + + diff --git a/src/view/layout/aside/asideComponent/asyncSubmenu.vue b/src/view/layout/aside/asideComponent/asyncSubmenu.vue new file mode 100644 index 0000000..7bbbd29 --- /dev/null +++ b/src/view/layout/aside/asideComponent/asyncSubmenu.vue @@ -0,0 +1,95 @@ + + + + + + + diff --git a/src/view/layout/aside/asideComponent/index.vue b/src/view/layout/aside/asideComponent/index.vue new file mode 100644 index 0000000..2b34bae --- /dev/null +++ b/src/view/layout/aside/asideComponent/index.vue @@ -0,0 +1,59 @@ + + + + + + diff --git a/src/view/layout/aside/asideComponent/menuItem.vue b/src/view/layout/aside/asideComponent/menuItem.vue new file mode 100644 index 0000000..8d4abbd --- /dev/null +++ b/src/view/layout/aside/asideComponent/menuItem.vue @@ -0,0 +1,121 @@ + + + + + + + diff --git a/src/view/layout/aside/historyComponent/history.vue b/src/view/layout/aside/historyComponent/history.vue new file mode 100644 index 0000000..f9d6dce --- /dev/null +++ b/src/view/layout/aside/historyComponent/history.vue @@ -0,0 +1,363 @@ + + + + + + + diff --git a/src/view/layout/aside/index.vue b/src/view/layout/aside/index.vue new file mode 100644 index 0000000..270614c --- /dev/null +++ b/src/view/layout/aside/index.vue @@ -0,0 +1,151 @@ + + + + + + + diff --git a/src/view/layout/bottomInfo/bottomInfo.vue b/src/view/layout/bottomInfo/bottomInfo.vue new file mode 100644 index 0000000..0346424 --- /dev/null +++ b/src/view/layout/bottomInfo/bottomInfo.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/view/layout/index.vue b/src/view/layout/index.vue new file mode 100644 index 0000000..6e58323 --- /dev/null +++ b/src/view/layout/index.vue @@ -0,0 +1,258 @@ + + + + + + + diff --git a/src/view/layout/screenfull/index.vue b/src/view/layout/screenfull/index.vue new file mode 100644 index 0000000..66491a0 --- /dev/null +++ b/src/view/layout/screenfull/index.vue @@ -0,0 +1,64 @@ + + + + + + + diff --git a/src/view/layout/search/search.vue b/src/view/layout/search/search.vue new file mode 100644 index 0000000..a4d8f10 --- /dev/null +++ b/src/view/layout/search/search.vue @@ -0,0 +1,129 @@ + + + + + + diff --git a/src/view/layout/setting/index.vue b/src/view/layout/setting/index.vue new file mode 100644 index 0000000..0140a25 --- /dev/null +++ b/src/view/layout/setting/index.vue @@ -0,0 +1,137 @@ + + + + + + + diff --git a/src/view/login/index.vue b/src/view/login/index.vue new file mode 100644 index 0000000..4a0ce38 --- /dev/null +++ b/src/view/login/index.vue @@ -0,0 +1,228 @@ + + + + + + + diff --git a/src/view/person/person.vue b/src/view/person/person.vue new file mode 100644 index 0000000..fa874b3 --- /dev/null +++ b/src/view/person/person.vue @@ -0,0 +1,561 @@ + + + + + + + diff --git a/src/view/routerHolder.vue b/src/view/routerHolder.vue new file mode 100644 index 0000000..d65fc4e --- /dev/null +++ b/src/view/routerHolder.vue @@ -0,0 +1,23 @@ + + + + + + diff --git a/src/view/superAdmin/api/api.vue b/src/view/superAdmin/api/api.vue new file mode 100644 index 0000000..0c2b76a --- /dev/null +++ b/src/view/superAdmin/api/api.vue @@ -0,0 +1,391 @@ + + + + + + + diff --git a/src/view/superAdmin/authority/authority.vue b/src/view/superAdmin/authority/authority.vue new file mode 100644 index 0000000..1d80c5f --- /dev/null +++ b/src/view/superAdmin/authority/authority.vue @@ -0,0 +1,410 @@ + + + + + + + diff --git a/src/view/superAdmin/authority/components/apis.vue b/src/view/superAdmin/authority/components/apis.vue new file mode 100644 index 0000000..dd1c522 --- /dev/null +++ b/src/view/superAdmin/authority/components/apis.vue @@ -0,0 +1,139 @@ + + + + + + diff --git a/src/view/superAdmin/authority/components/datas.vue b/src/view/superAdmin/authority/components/datas.vue new file mode 100644 index 0000000..4f2facd --- /dev/null +++ b/src/view/superAdmin/authority/components/datas.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/view/superAdmin/authority/components/menus.vue b/src/view/superAdmin/authority/components/menus.vue new file mode 100644 index 0000000..31c73cc --- /dev/null +++ b/src/view/superAdmin/authority/components/menus.vue @@ -0,0 +1,225 @@ + + + + + + + diff --git a/src/view/superAdmin/dictionary/sysDictionary.vue b/src/view/superAdmin/dictionary/sysDictionary.vue new file mode 100644 index 0000000..5b4377e --- /dev/null +++ b/src/view/superAdmin/dictionary/sysDictionary.vue @@ -0,0 +1,375 @@ + + + + + + + diff --git a/src/view/superAdmin/dictionary/sysDictionaryDetail.vue b/src/view/superAdmin/dictionary/sysDictionaryDetail.vue new file mode 100644 index 0000000..4e2d55d --- /dev/null +++ b/src/view/superAdmin/dictionary/sysDictionaryDetail.vue @@ -0,0 +1,291 @@ + + + + + + + diff --git a/src/view/superAdmin/index.vue b/src/view/superAdmin/index.vue new file mode 100644 index 0000000..28c4fde --- /dev/null +++ b/src/view/superAdmin/index.vue @@ -0,0 +1,21 @@ + + + + diff --git a/src/view/superAdmin/menu/icon.vue b/src/view/superAdmin/menu/icon.vue new file mode 100644 index 0000000..0b97b75 --- /dev/null +++ b/src/view/superAdmin/menu/icon.vue @@ -0,0 +1,1190 @@ + + + + + + + diff --git a/src/view/superAdmin/menu/menu.vue b/src/view/superAdmin/menu/menu.vue new file mode 100644 index 0000000..7698953 --- /dev/null +++ b/src/view/superAdmin/menu/menu.vue @@ -0,0 +1,529 @@ + + + + + + + diff --git a/src/view/superAdmin/operation/sysOperationRecord.vue b/src/view/superAdmin/operation/sysOperationRecord.vue new file mode 100644 index 0000000..6bc43eb --- /dev/null +++ b/src/view/superAdmin/operation/sysOperationRecord.vue @@ -0,0 +1,257 @@ + + + + + + + diff --git a/src/view/superAdmin/user/user.vue b/src/view/superAdmin/user/user.vue new file mode 100644 index 0000000..9a96400 --- /dev/null +++ b/src/view/superAdmin/user/user.vue @@ -0,0 +1,446 @@ + + + + + + + diff --git a/src/view/system/state.vue b/src/view/system/state.vue new file mode 100644 index 0000000..a7afd7c --- /dev/null +++ b/src/view/system/state.vue @@ -0,0 +1,183 @@ + + + + + + + diff --git a/src/view/systemTools/autoCode/component/fieldDialog.vue b/src/view/systemTools/autoCode/component/fieldDialog.vue new file mode 100644 index 0000000..8435bae --- /dev/null +++ b/src/view/systemTools/autoCode/component/fieldDialog.vue @@ -0,0 +1,234 @@ + + + + + + diff --git a/src/view/systemTools/autoCode/component/previewCodeDialg.vue b/src/view/systemTools/autoCode/component/previewCodeDialg.vue new file mode 100644 index 0000000..a33d3cb --- /dev/null +++ b/src/view/systemTools/autoCode/component/previewCodeDialg.vue @@ -0,0 +1,93 @@ + + + + + + + diff --git a/src/view/systemTools/autoCode/index.vue b/src/view/systemTools/autoCode/index.vue new file mode 100644 index 0000000..b73dbf1 --- /dev/null +++ b/src/view/systemTools/autoCode/index.vue @@ -0,0 +1,723 @@ + + + + + + + diff --git a/src/view/systemTools/autoCodeAdmin/index.vue b/src/view/systemTools/autoCodeAdmin/index.vue new file mode 100644 index 0000000..6895e17 --- /dev/null +++ b/src/view/systemTools/autoCodeAdmin/index.vue @@ -0,0 +1,188 @@ + + + + + + + diff --git a/src/view/systemTools/autoPkg/autoPkg.vue b/src/view/systemTools/autoPkg/autoPkg.vue new file mode 100644 index 0000000..3cb5c22 --- /dev/null +++ b/src/view/systemTools/autoPkg/autoPkg.vue @@ -0,0 +1,160 @@ + + + + + + + diff --git a/src/view/systemTools/autoPlug/autoPlug.vue b/src/view/systemTools/autoPlug/autoPlug.vue new file mode 100644 index 0000000..7f42dbe --- /dev/null +++ b/src/view/systemTools/autoPlug/autoPlug.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/src/view/systemTools/formCreate/index.vue b/src/view/systemTools/formCreate/index.vue new file mode 100644 index 0000000..9e273b6 --- /dev/null +++ b/src/view/systemTools/formCreate/index.vue @@ -0,0 +1,17 @@ +