commit 605c25acfa2e389422ae68ba7a12fbd9a949801e Author: lwh <2679599887@qq.com> Date: Thu May 25 19:15:22 2023 +0800 init diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7034f9b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# 告诉EditorConfig插件,这是根文件,不用继续往上查找 +root = true + +# 匹配全部文件 +[*] +# 设置字符集 +charset = utf-8 +# 缩进风格,可选space、tab +indent_style = space +# 缩进的空格数 +indent_size = 2 +# 结尾换行符,可选lf、cr、crlf +end_of_line = lf +# 在文件结尾插入新行 +insert_final_newline = true +# 删除一行中的前后空格 +trim_trailing_whitespace = true + +# 匹配md结尾的文件 +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env b/.env new file mode 100644 index 0000000..e919cf5 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ + +# 页面标题 +VITE_APP_TITLE = '阿尔文工具箱' \ No newline at end of file diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..488868c --- /dev/null +++ b/.env.development @@ -0,0 +1,16 @@ +# 开发环境配置 +ENV = 'development' + +VITE_APP_API_HOST = 'http://localhost:8888' + +# 开发环境 +VITE_APP_BASE_API = '/dev-api' + +# 路由前缀 +VITE_APP_ROUTER_PREFIX = '/' + +# 默认上传地址 +VITE_APP_UPLOAD_URL = '/Common/UploadFile' + +#socket API +VITE_APP_SOCKET_API = '/msghub' \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..069cc48 --- /dev/null +++ b/.env.production @@ -0,0 +1,15 @@ +# 生产环境配置 +ENV = 'production' + + +# 生产环境 +VITE_APP_BASE_API = '/prod-api' + +# 路由前缀 +VITE_APP_ROUTER_PREFIX = '/' + +# 默认上传地址 +VITE_APP_UPLOAD_URL = '/Common/UploadFile' + +#socket API +VITE_APP_SOCKET_API = '/msghub' \ No newline at end of file diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..62f968e --- /dev/null +++ b/.env.staging @@ -0,0 +1,18 @@ +# 测试环境配置 +ENV = 'staging' + + +# 测试环境 +VITE_APP_BASE_API = '/stage-api' + +# 路由前缀 +VITE_APP_ROUTER_PREFIX = '/' + +# 默认上传地址 +VITE_APP_UPLOAD_URL = '/Common/UploadFile' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip + +#socket API +VITE_APP_SOCKET_API = '/msghub' \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..cafab33 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,14 @@ +# 忽略build目录下类型为js的文件的语法检查 +build/*.js +# 忽略src/assets目录下文件的语法检查 +src/assets +# 忽略public目录下文件的语法检查 +public +# 忽略当前目录下为js的文件的语法检查 +# *.js +# 忽略当前目录下为vue的文件的语法检查 +# *.vue +/node_modules/ +/vite/ +.eslintrc.js +.prettierrc.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..82bbdee --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,199 @@ +// ESlint 检查配置 +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "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, 'never'], + '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': 2, + '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/.gitignore b/.gitignore new file mode 100644 index 0000000..308820b --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock +/deploy.js diff --git a/.jsbeautifyrc b/.jsbeautifyrc new file mode 100644 index 0000000..d79fae6 --- /dev/null +++ b/.jsbeautifyrc @@ -0,0 +1,12 @@ +{ + "brace_style": "none,preserve-inline", + "indent_size": 2, + "indent_char": " ", + "jslint_happy": true, + "unformatted": [ + "" + ], + "css": { + "indent_size": 2 + } +} \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..fae9475 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,38 @@ +module.exports = { + // 超过最大值换行 + printWidth: 148, + // 使用 2 个空格缩进 + tabWidth: 2, + // 不使用缩进符,而使用空格 + useTabs: false, + // 行尾不需要有分号 + semi: false, + // 使用单引号 + singleQuote: true, + // 对象的 key 仅在必要时用引号 + quoteProps: 'as-needed', + // jsx 不使用单引号,而使用双引号 + jsxSingleQuote: false, + // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"",默认none + trailingComma: 'none', + // 在对象,数组括号与文字之间加空格 "{ foo: bar }" + bracketSpacing: true, + // jsx 标签的反尖括号需要换行 + jsxBracketSameLine: true, + bracketSameLine: true, + // 箭头函数,always只有一个参数的时候,也需要括号,'avoid'箭头函数只有一个参数的时候可以忽略括号 + arrowParens: 'always', + // 每个文件格式化的范围是文件的全部内容 + rangeStart: 0, + rangeEnd: Infinity, + // 不需要写文件开头的 @prettier + requirePragma: false, + // 不需要自动在文件开头插入 @prettier + insertPragma: false, + // 使用默认的折行标准 + proseWrap: 'preserve', + // 根据显示样式决定 html 要不要折行 + htmlWhitespaceSensitivity: 'css', + // 换行符使用 lf 结尾是 可选值"" + endOfLine: 'auto' +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fff106c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,64 @@ +{ + "editor.fontSize": 15, + "editor.insertSpaces": false, + "editor.bracketPairColorization.enabled": true, + "editor.formatOnPaste": true, + "editor.formatOnType": true, + // 配置eslint适用于vue代码 + "eslint.validate": [ + "javascript", + "typescript", + "vue" + ], + "[vue]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[scss]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[ts]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[js]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + // 保存时 prettier 自动格式化 + "editor.formatOnSave": true, + // 保存时自动启用 eslint --fix 自动修复 + "editor.codeActionsOnSave": { + "source.fixAll": true, + "eslint.autoFixOnSave": true, + }, + "eslint.options": { + "overrideConfig": { + "env": { + "browser": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module", + "ecmaFeatures": { + "jsx": false + } + }, + "rules": { + "no-debugger": "off" + } + } + }, + "i18n-ally.displayLanguage": "zh-cn", + "i18n-ally.enabledParsers": ["json", "js"], + "i18n-ally.localesPaths": [ + "src/i18n/lang", + "src/i18n/pages/login", + "src/i18n/pages/menu", + ], + "i18n-ally.extract.parsers.html": { + "attributes": ["text", "title", "alt", "placeholder", "label", "aria-label"], + "ignoredTags": ["script", "style"], + "vBind": true, + "inlineText": true + }, + "i18n-ally.keystyle": "nested", +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3494239 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 791736813@qq.com zr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f7d0ab --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +

ZRAdmin.NET后台管理系统

+ +

+ + +

+ +## 🍟概述 +* 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。 +* 配套后端代码仓库地址[ZRAdmin.NET](https://gitee.com/izory/ZrAdminNetCore/) 版本。 +* 前端采用Vue3.0、Element UI Plus、vite、compisition api、Pinia等。 +* 支持加载动态权限菜单,多方式轻松权限控制 +* 腾讯云秒杀场:[点我进入](https://curl.qcloud.com/4yEoRquq)。 +* 腾讯云优惠券:[点我领取](https://curl.qcloud.com/5J4nag8D)。 +* 七牛云通用云产品优惠券:[点我进入](https://s.qiniu.com/FzEfay)。 +``` +如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,这样作者才有继续免费下去的动力,谢谢!~ +``` + +## 🍿在线体验 +- 官方文档:http://www.izhaorui.cn/doc +- 体验地址:http://www.izhaorui.cn/vue3 +- 管理员:admin +- 密 码:123456 + +``` +由于是个人项目,资金有限,体验服是低配,请大家爱惜,轻戳,不胜感激!!! +``` +## 🍁前端运行 + +```bash +# 克隆项目 +git clone https://gitee.com/izory/ZRAdmin-vue.git + +# 进入项目目录 +cd ZRAdmin-vue + +# 安装依赖 +yarn --registry=https://registry.npm.taobao.org + +# 启动服务 +yarn dev + +# 构建测试环境 yarn build:stage +# 构建生产环境 yarn build:prod +# 前端访问地址 http://localhost:8887 +``` + + +## 🍖内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。(支持多语言) +5. 角色管理:角色菜单权限分配。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +8. 登录日志:系统登录日志记录查询包含登录异常。 +9. 系统接口:使用swagger生成相关api接口文档。 +10. 参数设置:常用参数配置 +11. 发送邮件:可以对多个用户进行发送邮件 +12. 任务系统:基于Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。 +13. 文章管理:可以写文章记录。 +14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、SQL文件等),支持下载,自定义配置前端展示控件、让开发更快捷高效。 +15. 文件管理:可以进行上传文件管理,目前支持上传到本地、阿里云 +16. 通知管理:系统通知公告信息发布维护 +17. 参数管理:对系统动态配置常用参数。 +18. 多语言管理:动态修改多语言翻译 + +## 🎉优势 + +1. 前台系统不用编写登录、授权、认证模块;只负责编写业务模块即可 +2. 后台系统无需任何二次开发,直接发布即可使用 +3. 前台与后台系统分离,分别为不同的系统(域名可独立) +4. 全局异常统一处理 +5. 自定义的代码生成功能 +6. 国际化 + +## 💐 特别鸣谢 +- 👉Ruoyi.vue:[Ruoyi](http://www.ruoyi.vip/) + +## 🎀捐赠 +如果这个项目对您有所帮助,请扫下方二维码打赏作者喝杯咖啡。 + + +## 源码地址 +- [Gitee](https://gitee.com/izory/ZrAdminNetCore/) +- [Github](https://github.com/izhaorui/ZrAdmin.NET/) \ No newline at end of file diff --git a/bat/build.bat b/bat/build.bat new file mode 100644 index 0000000..ecbb454 --- /dev/null +++ b/bat/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅdistļ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn build:prod + +pause \ No newline at end of file diff --git a/bat/package.bat b/bat/package.bat new file mode 100644 index 0000000..965883a --- /dev/null +++ b/bat/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] װWeḅnode_modulesļ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn --registry=https://registry.npm.taobao.org + +pause \ No newline at end of file diff --git a/bat/run-web.bat b/bat/run-web.bat new file mode 100644 index 0000000..d2fe397 --- /dev/null +++ b/bat/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] ʹ Vite Web ̡ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn dev + +pause \ No newline at end of file diff --git a/html/ie.html b/html/ie.html new file mode 100644 index 0000000..052ffcd --- /dev/null +++ b/html/ie.html @@ -0,0 +1,46 @@ + + + + + + 请升级您的浏览器 + + + + + + +

请升级您的浏览器,以便我们更好的为您提供服务!

+

您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。

+
+

请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束

+

自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明

+
+

您可以选择更先进的浏览器

+

推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。

+ +
+ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..451837e --- /dev/null +++ b/index.html @@ -0,0 +1,139 @@ + + + + + + + + + + 阿尔文工具箱后台管理系统 + + + + + +
+
+
+ +
+
Loading...
+
+
+ + + + \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..86b1741 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,11 @@ +/* 主要作用是vscode导入使用别名时可以自动化提示文件路径 */ +{ + "compilerOptions": { + "experimentalDecorators": true, + "baseUrl": "./", + "paths": { + "@/*": ["src/*"] + } + }, + "exclude": ["node_modules", "dist", ".vscode"] +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..dafe052 --- /dev/null +++ b/package.json @@ -0,0 +1,55 @@ +{ + "name": "arw.admin", + "version": "3.8.2", + "description": "阿尔文后台管理系统", + "author": "Aerwen", + "license": "MIT", + "scripts": { + "dev": "vite", + "build:prod": "vite build", + "build:stage": "vite build --mode staging", + "preview": "vite preview" + }, + "repository": { + "type": "git", + "url": "https://gitee.com/izory/ZrAdminNetCore" + }, + "dependencies": { + "@amap/amap-jsapi-loader": "^1.0.1", + "@element-plus/icons-vue": "^0.2.7", + "@microsoft/signalr": "^6.0.5", + "@vueuse/core": "^8.9.4", + "@wangeditor/editor": "^5.1.1", + "@wangeditor/editor-for-vue": "^5.1.11", + "axios": "^0.27.2", + "countup.js": "^2.1.0", + "echarts": "5.2.2", + "element-plus": "^2.3.2", + "file-saver": "2.0.5", + "fuse.js": "6.4.6", + "highlight.js": "^11.5.1", + "js-cookie": "3.0.1", + "js-md5": "^0.7.3", + "jsencrypt": "3.2.1", + "md-editor-v3": "^1.11.11", + "nprogress": "0.2.0", + "pinia": "^2.0.33", + "qs": "^6.11.0", + "sortablejs": "^1.15.0", + "vue": "^3.2.47", + "vue-clipboard3": "^2.0.0", + "vue-cropper": "1.0.2", + "vue-i18n": "^9.2.2", + "vue-router": "^4.1.6" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.1.0", + "@vue/compiler-sfc": "^3.2.47", + "sass": "1.45.0", + "unplugin-auto-import": "0.5.3", + "vite": "^4.2.1", + "vite-plugin-compression": "^0.3.6", + "vite-plugin-svg-icons": "1.0.5", + "vite-plugin-vue-setup-extend": "^0.4.0" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..3c476d4 Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..c5ab5ef --- /dev/null +++ b/src/App.vue @@ -0,0 +1,56 @@ + + diff --git a/src/api/business/Project/ProjectFiless/projectfiles.js b/src/api/business/Project/ProjectFiless/projectfiles.js new file mode 100644 index 0000000..9ab0c4d --- /dev/null +++ b/src/api/business/Project/ProjectFiless/projectfiles.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 项目配置分页查询列表 +export function projectFilesList(query) { + return request({ + url: '/business/ProjectFiles/getProjectFilesList', + method: 'get', + params: query + }) +} + +// 项目配置新增或修改 +export function addOrUpdateProjectFiles(data) { + return request({ + url: '/business/ProjectFiles/addOrUpdateProjectFiles', + method: 'post', + data: data, + }) +} + +// 项目配置删除 +export function delProjectFiles(ids) { + return request({ + url: '/business/ProjectFiles/'+ ids, + method: 'delete' + }) +} + +// 项目配置导出 +export function exportProjectFiles(query) { + return request({ + url: 'business/ProjectFiles/exportProjectFiles', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/Project/ProjectGroups/projectgroup.js b/src/api/business/Project/ProjectGroups/projectgroup.js new file mode 100644 index 0000000..d5b3fc3 --- /dev/null +++ b/src/api/business/Project/ProjectGroups/projectgroup.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +/** +* 项目分组树形查询列表 +* @param {查询条件} data +*/ +export function projectGroupTreeList(query) { + return request({ + url: '/business/ProjectGroup/getProjectGroupTreeList', + method: 'get', + params: query + }) +} + +// 项目分组新增或修改 +export function addOrUpdateProjectGroup(data) { + return request({ + url: '/business/ProjectGroup/addOrUpdateProjectGroup', + method: 'post', + data: data, + }) +} + +// 项目分组删除 +export function delProjectGroup(ids) { + return request({ + url: '/business/ProjectGroup/'+ ids, + method: 'delete' + }) +} + +// 项目分组导出 +export function exportProjectGroup(query) { + return request({ + url: 'business/ProjectGroup/exportProjectGroup', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/Project/Projects/project.js b/src/api/business/Project/Projects/project.js new file mode 100644 index 0000000..e48ddb4 --- /dev/null +++ b/src/api/business/Project/Projects/project.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 项目分页查询列表 +export function projectList(query) { + return request({ + url: '/business/Project/getProjectList', + method: 'get', + params: query + }) +} + +// 项目新增或修改 +export function addOrUpdateProject(data) { + return request({ + url: '/business/Project/addOrUpdateProject', + method: 'post', + data: data, + }) +} + +// 项目删除 +export function delProject(ids) { + return request({ + url: '/business/Project/'+ ids, + method: 'delete' + }) +} + +// 项目导出 +export function exportProject(query) { + return request({ + url: 'business/Project/exportProject', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/Project/Projects/projectes.js b/src/api/business/Project/Projects/projectes.js new file mode 100644 index 0000000..edd9ccb --- /dev/null +++ b/src/api/business/Project/Projects/projectes.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 项目分页查询列表 +export function projectesList(query) { + return request({ + url: '/business/Projectes/getProjectesList', + method: 'get', + params: query + }) +} + +// 项目新增或修改 +export function addOrUpdateProjectes(data) { + return request({ + url: '/business/Projectes/addOrUpdateProjectes', + method: 'post', + data: data, + }) +} + +// 项目删除 +export function delProjectes(ids) { + return request({ + url: '/business/Projectes/'+ ids, + method: 'delete' + }) +} + +// 项目导出 +export function exportProjectes(query) { + return request({ + url: 'business/Projectes/exportProjectes', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/ToolCustomers/toolcustomer.js b/src/api/business/ToolCustomers/toolcustomer.js new file mode 100644 index 0000000..1cdbf58 --- /dev/null +++ b/src/api/business/ToolCustomers/toolcustomer.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// Tool客户分页查询列表 +export function toolCustomerList(query) { + return request({ + url: '/business/ToolCustomer/getToolCustomerList', + method: 'get', + params: query + }) +} + +// Tool客户新增或修改 +export function addOrUpdateToolCustomer(data) { + return request({ + url: '/business/ToolCustomer/addOrUpdateToolCustomer', + method: 'post', + data: data, + }) +} + +// Tool客户删除 +export function delToolCustomer(ids) { + return request({ + url: '/business/ToolCustomer/'+ ids, + method: 'delete' + }) +} + +// Tool客户导出 +export function exportToolCustomer(query) { + return request({ + url: 'business/ToolCustomer/exportToolCustomer', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/classess/classes.js b/src/api/business/classess/classes.js new file mode 100644 index 0000000..84effdd --- /dev/null +++ b/src/api/business/classess/classes.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 班级分页查询列表 +export function classesList(query) { + return request({ + url: '/business/Classes/getClassesList', + method: 'get', + params: query + }) +} + +// 班级新增或修改 +export function addOrUpdateClasses(data) { + return request({ + url: '/business/Classes/addOrUpdateClasses', + method: 'post', + data: data, + }) +} + +// 班级删除 +export function delClasses(ids) { + return request({ + url: '/business/Classes/'+ ids, + method: 'delete' + }) +} + +// 班级导出 +export function exportClasses(query) { + return request({ + url: 'business/Classes/exportClasses', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/customers/customer.js b/src/api/business/customers/customer.js new file mode 100644 index 0000000..9e1df9e --- /dev/null +++ b/src/api/business/customers/customer.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 小程序客户分页查询列表 +export function customerList(query) { + return request({ + url: '/business/Customer/getCustomerList', + method: 'get', + params: query + }) +} + + +// 小程序客户新增或修改 +export function addOrUpdateCustomer(data) { + return request({ + url: '/business/Customer/addOrUpdateCustomer', + method: 'post', + data: data, + }) +} + +// 小程序客户删除 +export function delCustomer(ids) { + return request({ + url: '/business/Customer/'+ ids, + method: 'delete' + }) +} + +// 小程序客户导出 +export function exportCustomer(query) { + return request({ + url: 'business/Customer/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/business/newss/news.js b/src/api/business/newss/news.js new file mode 100644 index 0000000..c0b266f --- /dev/null +++ b/src/api/business/newss/news.js @@ -0,0 +1,45 @@ +import request from '@/utils/request' + +// 新闻分页查询列表 +export function newsList(query) { + return request({ + url: '/business/News/getNewsList', + method: 'get', + params: query + }) +} + +// 新闻新增或修改 +export function addOrUpdateNews(data) { + return request({ + url: '/business/News/addOrUpdateNews', + method: 'post', + data: data, + }) +} + +// 新闻删除 +export function delNews(ids) { + return request({ + url: '/business/News/'+ ids, + method: 'delete' + }) +} + +// 新闻导出 +export function exportNews(query) { + return request({ + url: 'business/News/export', + method: 'get', + params: query + }) +} + +// 新闻审核 +export function audit(data) { + return request({ + url: 'business/News/audit', + method: 'put', + data: data + }) +} diff --git a/src/api/business/payments/payment.js b/src/api/business/payments/payment.js new file mode 100644 index 0000000..1c144be --- /dev/null +++ b/src/api/business/payments/payment.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 支付订单分页查询列表 +export function paymentList(query) { + return request({ + url: '/business/Payment/getPaymentList', + method: 'get', + params: query + }) +} + + +// 支付订单新增或修改 +export function addOrUpdatePayment(data) { + return request({ + url: '/business/Payment/addOrUpdatePayment', + method: 'post', + data: data, + }) +} + +// 支付订单删除 +export function delPayment(ids) { + return request({ + url: '/business/Payment/'+ ids, + method: 'delete' + }) +} + +// 支付订单导出 +export function exportPayment(query) { + return request({ + url: 'business/Payment/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/business/testDemo/Test/TestPartss/testparts.js b/src/api/business/testDemo/Test/TestPartss/testparts.js new file mode 100644 index 0000000..0dca172 --- /dev/null +++ b/src/api/business/testDemo/Test/TestPartss/testparts.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 测试配件分页查询列表 +export function testPartsList(query) { + return request({ + url: '/business/TestParts/getTestPartsList', + method: 'get', + params: query + }) +} + +// 测试配件新增或修改 +export function addOrUpdateTestParts(data) { + return request({ + url: '/business/TestParts/addOrUpdateTestParts', + method: 'post', + data: data, + }) +} + +// 测试配件删除 +export function delTestParts(ids) { + return request({ + url: '/business/TestParts/'+ ids, + method: 'delete' + }) +} + +// 测试配件导出 +export function exportTestParts(query) { + return request({ + url: 'business/TestParts/exportTestParts', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/testDemo/Test/TestTypes/testtype.js b/src/api/business/testDemo/Test/TestTypes/testtype.js new file mode 100644 index 0000000..d6e52b0 --- /dev/null +++ b/src/api/business/testDemo/Test/TestTypes/testtype.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +/** +* 测试类型树形查询列表 +* @param {查询条件} data +*/ +export function testTypeTreeList(query) { + return request({ + url: '/business/TestType/getTestTypeTreeList', + method: 'get', + params: query + }) +} + +// 测试类型新增或修改 +export function addOrUpdateTestType(data) { + return request({ + url: '/business/TestType/addOrUpdateTestType', + method: 'post', + data: data, + }) +} + +// 测试类型删除 +export function delTestType(ids) { + return request({ + url: '/business/TestType/'+ ids, + method: 'delete' + }) +} + +// 测试类型导出 +export function exportTestType(query) { + return request({ + url: 'business/TestType/exportTestType', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/testDemo/Test/Testds/testd.js b/src/api/business/testDemo/Test/Testds/testd.js new file mode 100644 index 0000000..7cee11a --- /dev/null +++ b/src/api/business/testDemo/Test/Testds/testd.js @@ -0,0 +1,46 @@ +import request from '@/utils/request' + +// 测试分页查询列表 +export function testdList(query) { + return request({ + url: '/business/Testd/getTestdList', + method: 'get', + params: query + }) +} + +// 测试未绑定分页列表 +export function getTestdListWithOutBind(query) { + return request({ + url: '/business/Testd/getTestdListWithOutBind', + method: 'get', + params: query + }) +} + +// 测试新增或修改 +export function addOrUpdateTestd(data) { + return request({ + url: '/business/Testd/addOrUpdateTestd', + method: 'post', + data: data, + }) +} + +// 测试删除 +export function delTestd(ids) { + return request({ + url: '/business/Testd/'+ ids, + method: 'delete' + }) +} + +// 测试导出 +export function exportTestd(query) { + return request({ + url: 'business/Testd/exportTestd', + method: 'get', + params: query + }) +} + diff --git a/src/api/business/testDemo/school/key.js b/src/api/business/testDemo/school/key.js new file mode 100644 index 0000000..962fff0 --- /dev/null +++ b/src/api/business/testDemo/school/key.js @@ -0,0 +1,45 @@ +import request from '@/utils/request' + +// 关键词分页查询列表 +export function keyList(query) { + return request({ + url: '/business/Key/getKeyList', + method: 'get', + params: query + }) +} + +// 关键词新增或修改 +export function addOrUpdateKey(data) { + return request({ + url: '/business/Key/addOrUpdateKey', + method: 'post', + data: data, + }) +} + +// 关键词删除 +export function delKey(ids) { + return request({ + url: '/business/Key/'+ ids, + method: 'delete' + }) +} + +// 关键词导出 +export function exportKey(query) { + return request({ + url: 'business/Key/export', + method: 'get', + params: query + }) +} + +// 关键词审核 +export function auditKey(data) { + return request({ + url: 'business/Key/auditKey', + method: 'put', + data: data + }) +} \ No newline at end of file diff --git a/src/api/business/testDemo/school/student.js b/src/api/business/testDemo/school/student.js new file mode 100644 index 0000000..2114b75 --- /dev/null +++ b/src/api/business/testDemo/school/student.js @@ -0,0 +1,72 @@ +import request from '@/utils/request' + +// 查询列表 +export function studentList(query) { + return request({ + url: '/business/student/GetStudentList', + method: 'get', + params: query + }) +} + +// 新增或修改 +export function addOrUpdateStudent(data) { + return request({ + url: '/business/student/addOrUpdateStudent', + method: 'post', + data: data, + }) +} + +// 删除 +export function delStudent(ids) { + return request({ + url: '/business/student/'+ ids, + method: 'delete' + }) +} + +// 查询班级列表 +export function getClassList(query) { + return request({ + url: '/business/student/getClassList', + method: 'get', + params: query + }) +} + +// 查询关键词列表 +export function getKeyList(query) { + return request({ + url: '/business/student/getKeyList', + method: 'get', + params: query + }) +} + +// 审核 +export function auditStudent(data) { + return request({ + url: '/business/student/auditStudent', + method: 'put', + data: data + }) +} + +// 导出学生目录 +export function exportStudent(query) { + return request({ + url: 'business/student/export', + method: 'get', + params: query + }) +} + +// 通过学生Guid查找学生服务 +export function findStudetnServiceByGuid(data) { + return request({ + url: '/business/student/findStudetnServiceByGuid', + method: 'post', + data: data, + }) +} \ No newline at end of file diff --git a/src/api/common.js b/src/api/common.js new file mode 100644 index 0000000..c57228f --- /dev/null +++ b/src/api/common.js @@ -0,0 +1,23 @@ +import request from '@/utils/request' + +export function upload(data) { + return request({ + url: '/common/UploadFile', + method: 'POST', + data: data, + headers: { "Content-Type": "multipart/form-data" }, + }) +} + +/** + * 发送邮件 + * @param {*} data + * @returns + */ +export function sendEmail(data) { + return request({ + url: '/common/SendEmail', + method: 'POST', + data: data, + }) +} diff --git a/src/api/monitor/cache.js b/src/api/monitor/cache.js new file mode 100644 index 0000000..59d3505 --- /dev/null +++ b/src/api/monitor/cache.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 查询缓存详细 +export function getCache() { + return request({ + url: '/monitor/cache', + method: 'get' + }) +} diff --git a/src/api/monitor/job.js b/src/api/monitor/job.js new file mode 100644 index 0000000..d40b293 --- /dev/null +++ b/src/api/monitor/job.js @@ -0,0 +1,114 @@ +import request from '@/utils/request' + +export function queryTasks(data) { + return request({ + url: '/system/tasks/list', + method: 'get', + params: data + }) +} + +export function getTasks(id) { + return request({ + url: '/system/tasks/get?id=' + id, + method: 'get' + }) +} + +/** + * + * 获取所有任务 + * @returns + */ +export function getAllTasks() { + return request({ + url: '/system/tasks/getAll', + method: 'get' + }) +} + +/** + * 创建任务 + * @param {*} data + * @returns + */ +export function createTasks(data) { + return request({ + url: '/system/tasks/create', + method: 'post', + data + }) +} + +/** + * 更新任务 + * @param {*} data + * @returns + */ +export function updateTasks(data) { + return request({ + url: '/system/tasks/update', + method: 'post', + data + }) +} + +/** + * 删除任务 + * @param {*} id + * @returns + */ +export function deleteTasks(id) { + return request({ + url: '/system/tasks/delete?id=' + id, + method: 'delete' + }) +} + +/** + * 启动任务 + * @param {*} id + * @returns + */ +export function startTasks(id) { + return request({ + url: '/system/tasks/start?id=' + id, + method: 'get' + }) +} + +/** + * 停止任务 + * @param {*} id + * @returns + */ +export function stopTasks(id) { + return request({ + url: '/system/tasks/stop?id=' + id, + method: 'get' + }) +} + +/** + * 运行一次 + * @param {*} id + * @returns + */ +export function runTasks(id) { + return request({ + url: '/system/tasks/run?id=' + id, + method: 'get' + }) +} +/** + * 导出 + * @returns + */ +export function exportTasks() { + return request({ + url: '/system/tasks/export', + method: 'get' + }) +} + +export default { queryTasks, getTasks, getAllTasks, createTasks, updateTasks, deleteTasks, startTasks, stopTasks, runTasks, exportTasks } diff --git a/src/api/monitor/jobLog.js b/src/api/monitor/jobLog.js new file mode 100644 index 0000000..be1fffd --- /dev/null +++ b/src/api/monitor/jobLog.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 查询调度日志列表 +export function listJobLog(query) { + return request({ + url: '/monitor/jobLog/list', + method: 'get', + params: query + }) +} + +// 删除调度日志 +export function delJobLog(jobLogId) { + return request({ + url: '/monitor/jobLog/' + jobLogId, + method: 'delete' + }) +} + +// 清空调度日志 +export function cleanJobLog() { + return request({ + url: '/monitor/jobLog/clean', + method: 'delete' + }) +} + +// 导出调度日志 +export function exportJobLog(query) { + return request({ + url: '/monitor/jobLog/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/monitor/logininfor.js b/src/api/monitor/logininfor.js new file mode 100644 index 0000000..7ff412d --- /dev/null +++ b/src/api/monitor/logininfor.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 查询登录日志列表 +export function list(query) { + return request({ + url: '/monitor/logininfor/list', + method: 'get', + params: query + }) +} + +// 删除登录日志 +export function delLogininfor(infoId) { + return request({ + url: '/monitor/logininfor/' + infoId, + method: 'delete' + }) +} + +// 清空登录日志 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} + +// 导出登录日志 +export function exportLogininfor(query) { + return request({ + url: '/monitor/logininfor/export', + method: 'get', + params: query + }) +} diff --git a/src/api/monitor/online.js b/src/api/monitor/online.js new file mode 100644 index 0000000..a6d20ec --- /dev/null +++ b/src/api/monitor/online.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' + +// 查询在线用户列表 +export function listOnline(query) { + return request({ + url: '/monitor/online/list', + method: 'get', + params: query + }) +} + +// 强退用户 +export function forceLogout(tokenId) { + return request({ + url: '/monitor/online/' + tokenId, + method: 'delete' + }) +} diff --git a/src/api/monitor/operlog.js b/src/api/monitor/operlog.js new file mode 100644 index 0000000..07e27ab --- /dev/null +++ b/src/api/monitor/operlog.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 查询操作日志列表 +export function list(query) { + return request({ + url: '/monitor/operlog/list', + method: 'get', + params: query + }) +} + +// 删除操作日志 +export function delOperlog(operId) { + return request({ + url: '/monitor/operlog/' + operId, + method: 'delete' + }) +} + +// 清空操作日志 +export function cleanOperlog() { + return request({ + url: '/monitor/operlog/clean', + method: 'delete' + }) +} + +// 导出操作日志 +export function exportOperlog(query) { + return request({ + url: '/monitor/operlog/export', + method: 'get', + params: query + }) +} diff --git a/src/api/monitor/server.js b/src/api/monitor/server.js new file mode 100644 index 0000000..bdcc62b --- /dev/null +++ b/src/api/monitor/server.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 查询服务器详细 +export function getServer() { + return request({ + url: '/monitor/server', + method: 'get' + }) +} diff --git a/src/api/system/commonlang.js b/src/api/system/commonlang.js new file mode 100644 index 0000000..28b5b34 --- /dev/null +++ b/src/api/system/commonlang.js @@ -0,0 +1,89 @@ +import request from '@/utils/request' + +/** + * 多语言配置分页查询 + * @param {查询条件} data + */ +export function listCommonLang(query) { + return request({ + url: 'system/CommonLang/list', + method: 'get', + params: query, + }) +} +/** + * 多语言配置查询 + * @param {查询条件} data + */ +export function listLangByLocale(locale) { + return request({ + url: 'system/CommonLang/list/' + locale, + method: 'get', + }) +} + +/** + * 新增多语言配置 + * @param data + */ +export function addCommonLang(data) { + return request({ + url: 'system/CommonLang', + method: 'post', + data: data, + }) +} + +/** + * 修改多语言配置 + * @param data + */ +export function updateCommonLang(data) { + return request({ + url: 'system/CommonLang', + method: 'PUT', + data: data, + }) +} + +/** + * 获取多语言配置详情 + * @param {Id} + */ +export function getCommonLang(id) { + return request({ + url: 'system/CommonLang/' + id, + method: 'get' + }) +} +/** + * 获取多语言配置详情 + * @param {key} + */ +export function getCommonLangByKey(key) { + return request({ + url: 'system/CommonLang/key/' + key, + method: 'get' + }) +} + + +/** + * 删除多语言配置 + * @param {主键} pid + */ +export function delCommonLang(pid) { + return request({ + url: 'system/CommonLang/' + pid, + method: 'delete' + }) +} + +// 导出多语言配置 +export function exportCommonLang(query) { + return request({ + url: 'system/CommonLang/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/system/config.js b/src/api/system/config.js new file mode 100644 index 0000000..3633ba1 --- /dev/null +++ b/src/api/system/config.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +// 查询参数列表 +export function listConfig(query) { + return request({ + url: '/system/config/list', + method: 'get', + params: query + }) +} + +// 查询参数详细 +export function getConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'get' + }) +} + +// 根据参数键名查询参数值 +export function getConfigKey(configKey) { + return request({ + url: '/system/config/configKey/' + configKey, + method: 'get' + }) +} + +// 新增参数配置 +export function addConfig(data) { + return request({ + url: '/system/config', + method: 'post', + data: data + }) +} + +// 修改参数配置 +export function updateConfig(data) { + return request({ + url: '/system/config', + method: 'put', + data: data + }) +} + +// 删除参数配置 +export function delConfig(configId) { + return request({ + url: '/system/config/' + configId, + method: 'delete' + }) +} + +// 刷新参数缓存 +export function refreshCache() { + return request({ + url: '/system/config/refreshCache', + method: 'delete' + }) +} + +// 导出参数 +// export function exportConfig(query) { +// return request({ +// url: '/system/config/export', +// method: 'get', +// params: query +// }) +// } diff --git a/src/api/system/dept.js b/src/api/system/dept.js new file mode 100644 index 0000000..2804676 --- /dev/null +++ b/src/api/system/dept.js @@ -0,0 +1,68 @@ +import request from '@/utils/request' + +// 查询部门列表 +export function listDept(query) { + return request({ + url: '/system/dept/list', + method: 'get', + params: query + }) +} + +// 查询部门列表(排除节点) +export function listDeptExcludeChild(deptId) { + return request({ + url: '/system/dept/list/exclude/' + deptId, + method: 'get' + }) +} + +// 查询部门详细 +export function getDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'get' + }) +} + +// 查询部门下拉树结构 +export function treeselect() { + return request({ + url: '/system/dept/treeselect', + method: 'get' + }) +} + +// 根据角色ID查询部门树结构 +export function roleDeptTreeselect(roleId) { + return request({ + url: '/system/dept/roleDeptTreeselect/' + roleId, + method: 'get' + }) +} + +// 新增部门 +export function addDept(data) { + return request({ + url: '/system/dept', + method: 'post', + data: data + }) +} + +// 修改部门 +export function updateDept(data) { + return request({ + url: '/system/dept', + method: 'put', + data: data + }) +} + +// 删除部门 +export function delDept(deptId) { + return request({ + url: '/system/dept/' + deptId, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/api/system/dict/data.js b/src/api/system/dict/data.js new file mode 100644 index 0000000..0351dd6 --- /dev/null +++ b/src/api/system/dict/data.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +// 查询字典数据列表 +export function listData(query) { + return request({ + url: '/system/dict/data/list', + method: 'get', + params: query + }) +} + +// 查询字典数据详细 +export function getData(dictCode) { + return request({ + url: '/system/dict/data/info/' + dictCode, + method: 'get' + }) +} + +// 根据字典类型查询字典数据信息 +export function getDicts(dictType) { + if (typeof (dictType) === "object") { + return request({ + url: '/system/dict/data/types', + data: dictType, + method: 'post' + }) + } else { + return request({ + url: '/system/dict/data/type/' + dictType, + method: 'get' + }) + } +} + +// 新增字典数据 +export function addData(data) { + return request({ + url: '/system/dict/data', + method: 'post', + data: data + }) +} + +// 修改字典数据 +export function updateData(data) { + return request({ + url: '/system/dict/data', + method: 'put', + data: data + }) +} + +// 删除字典数据 +export function delData(dictCode) { + return request({ + url: '/system/dict/data/' + dictCode, + method: 'delete' + }) +} + +// 导出字典数据 +export function exportData(query) { + return request({ + url: '/system/dict/data/export', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/system/dict/type.js b/src/api/system/dict/type.js new file mode 100644 index 0000000..27ae18f --- /dev/null +++ b/src/api/system/dict/type.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +// 查询字典类型列表 +export function listType(query) { + return request({ + url: '/system/dict/type/list', + method: 'get', + params: query + }) +} + +// 查询字典类型详细 +export function getType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'get' + }) +} + +// 新增字典类型 +export function addType(data) { + return request({ + url: '/system/dict/type/edit', + method: 'post', + data: data + }) +} + +// 修改字典类型 +export function updateType(data) { + return request({ + url: '/system/dict/type/edit', + method: 'put', + data: data + }) +} + +// 删除字典类型 +export function delType(dictId) { + return request({ + url: '/system/dict/type/' + dictId, + method: 'delete' + }) +} + +// 清理参数缓存 +export function clearCache() { + return request({ + url: '/system/dict/type/clearCache', + method: 'delete' + }) +} + +// 导出字典类型 +export function exportType(query) { + return request({ + url: '/system/dict/type/export', + method: 'get', + params: query + }) +} + +// 获取字典选择框列表 +export function optionselect() { + return request({ + url: '/system/dict/type/optionselect', + method: 'get' + }) +} diff --git a/src/api/system/login.js b/src/api/system/login.js new file mode 100644 index 0000000..303333a --- /dev/null +++ b/src/api/system/login.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +// 登录方法 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/login', + method: 'POST', + data: data, + headers: { + userName: username + } + }) +} + +// 获取用户详细信息 +export function getInfo() { + return request({ + url: '/getInfo', + method: 'get' + }) +} + +// 退出方法 +export function logout() { + return request({ + url: '/LogOut', + method: 'POST' + }) +} + +// 获取验证码 +export function getCodeImg() { + return request({ + url: '/captchaImage', + method: 'get' + }) +} +/** + * 注册 + * @returns + */ +export function register(data) { + return request({ + url: '/register', + method: 'post', + data: data + }) +} + +/** + * 三方授权回调 + * @param {*} data + * @param {*} params + * @returns + */ +export function oauthCallback(data, params) { + return request({ + url: '/auth/callback', + method: 'post', + data: data, + params: params + }) +} diff --git a/src/api/system/menu.js b/src/api/system/menu.js new file mode 100644 index 0000000..47d3ab1 --- /dev/null +++ b/src/api/system/menu.js @@ -0,0 +1,84 @@ +import request from '@/utils/request' + +// 查询菜单列表 +export function listMenu(query) { + return request({ + url: '/system/menu/list', + method: 'get', + params: query + }) +} +// 查询菜单列表 +export function listMenuById(menuId) { + return request({ + url: '/system/menu/list/' + menuId, + method: 'get', + }) +} +// 查询菜单详细 +export function getMenu(menuId) { + return request({ + url: '/system/menu/' + menuId, + method: 'get', + }) +} + +// 查询菜单下拉树结构 +export function treeselect() { + return request({ + url: '/system/Menu/treeSelect', + method: 'get' + }) +} + +// 根据角色ID查询菜单下拉树结构 +export function roleMenuTreeselect(roleId) { + return request({ + url: '/system/menu/roleMenuTreeselect/' + roleId, + method: 'get', + }) +} + +// 新增菜单 +export const addMenu = (data) => { + return request({ + url: '/system/menu/add', + method: 'put', + data: data, + }) +} + +// 修改菜单 +export function updateMenu(data) { + return request({ + url: '/system/Menu/edit', + method: 'post', + data: data + }) +} + +// 删除菜单 +export function delMenu(menuId) { + return request({ + url: '/system/Menu/' + menuId, + method: 'delete' + }) +} + +//排序 +export function changeMenuSort(data) { + return request({ + url: '/system/Menu/ChangeSort', + method: 'GET', + params: data + }) +} + +// 获取路由 +export const getRouters = (query) => { + return request({ + url: '/getRouters', + method: 'get', + params: query + }) +} diff --git a/src/api/system/notice.js b/src/api/system/notice.js new file mode 100644 index 0000000..fc80afb --- /dev/null +++ b/src/api/system/notice.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 导航栏查询公告列表 +export function queryNotice(query) { + return request({ + url: '/system/notice/queryNotice', + method: 'get', + params: query + }) +} + +// 查询公告列表 +export function listNotice(query) { + return request({ + url: '/system/notice/list', + method: 'get', + params: query + }) +} + +// 查询公告详细 +export function getNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'get' + }) +} + +// 新增公告 +export function addNotice(data) { + return request({ + url: '/system/notice', + method: 'post', + data: data + }) +} + +// 修改公告 +export function updateNotice(data) { + return request({ + url: '/system/notice', + method: 'put', + data: data + }) +} + +// 删除公告 +export function delNotice(noticeId) { + return request({ + url: '/system/notice/' + noticeId, + method: 'delete' + }) +} + +// 发送通知公告 +export function sendNotice(noticeId) { + return request({ + url: '/system/notice/send/' + noticeId, + method: 'PUT' + }) +} \ No newline at end of file diff --git a/src/api/system/post.js b/src/api/system/post.js new file mode 100644 index 0000000..8b9aff8 --- /dev/null +++ b/src/api/system/post.js @@ -0,0 +1,54 @@ +import request from '@/utils/request' +import { downFile } from '@/utils/request' +// 查询岗位列表 +export function listPost(query) { + return request({ + url: '/system/post/list', + method: 'get', + params: query + }) +} + +// 查询岗位详细 +export function getPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'get' + }) +} + +// 新增岗位 +export function addPost(data) { + return request({ + url: '/system/post', + method: 'post', + data: data + }) +} + +// 修改岗位 +export function updatePost(data) { + return request({ + url: '/system/post', + method: 'put', + data: data + }) +} + +// 删除岗位 +export function delPost(postId) { + return request({ + url: '/system/post/' + postId, + method: 'delete' + }) +} + +// 导出岗位 +export async function exportPost(query) { + // return request({ + // url: '/system/post/export', + // method: 'get', + // params: query + // }) + await downFile('/system/post/export', query) +} diff --git a/src/api/system/role.js b/src/api/system/role.js new file mode 100644 index 0000000..25b8d1e --- /dev/null +++ b/src/api/system/role.js @@ -0,0 +1,75 @@ +import request from '@/utils/request' + +// 查询角色列表 +export function listRole(query) { + return request({ + url: '/system/role/list', + method: 'get', + params: query + }) +} + +// 查询角色详细 +export function getRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'get' + }) +} + +// 新增角色 +export const addRole = (data) => { + return request({ + url: '/system/role/edit', + method: 'post', + data: data, + }) +} + +// 修改角色 +export function updateRole(data) { + return request({ + url: '/system/role/edit', + method: 'put', + data: data + }) +} + +// 角色数据权限 +export function dataScope(data) { + return request({ + url: '/system/role/dataScope', + method: 'put', + data: data + }) +} + +// 角色状态修改 +export function changeRoleStatus(roleId, status) { + const data = { + roleId, + status + } + return request({ + url: '/system/role/changeStatus', + method: 'put', + data: data + }) +} + +// 删除角色 +export function delRole(roleId) { + return request({ + url: '/system/role/' + roleId, + method: 'delete' + }) +} + +// 导出角色 +export function exportRole(query) { + return request({ + url: '/system/role/export', + method: 'get', + params: query + }) +} diff --git a/src/api/system/thirdaccount.js b/src/api/system/thirdaccount.js new file mode 100644 index 0000000..7637df3 --- /dev/null +++ b/src/api/system/thirdaccount.js @@ -0,0 +1,70 @@ +import request from '@/utils/request' + +/** +* 三方账号绑定分页查询 +* @param {查询条件} data +*/ +export function listThirdAccount(query) { + return request({ + url: 'system/ThirdAccount/list', + method: 'get', + params: query, + }) +} + + +/** +* 新增三方账号绑定 +* @param data +*/ +export function addThirdAccount(data) { + return request({ + url: 'system/ThirdAccount', + method: 'post', + data: data, + }) +} + +/** +* 修改三方账号绑定 +* @param data +*/ +export function updateThirdAccount(data) { + return request({ + url: 'system/ThirdAccount', + method: 'PUT', + data: data, + }) +} + +/** +* 获取三方账号绑定详情 +* @param {Id} +*/ +export function getThirdAccount(id) { + return request({ + url: 'system/ThirdAccount/' + id, + method: 'get' + }) +} + +/** +* 删除三方账号绑定 +* @param {主键} pid +*/ +export function delThirdAccount(pid) { + return request({ + url: 'system/ThirdAccount/' + pid, + method: 'delete' + }) +} + +// 导出三方账号绑定 +export function exportThirdAccount(query) { + return request({ + url: 'system/ThirdAccount/export', + method: 'get', + params: query + }) +} + diff --git a/src/api/system/user.js b/src/api/system/user.js new file mode 100644 index 0000000..c660261 --- /dev/null +++ b/src/api/system/user.js @@ -0,0 +1,130 @@ +import request from '@/utils/request' +import { praseStrZero } from '@/utils/ruoyi' +import { downFile } from '@/utils/request' + +// 查询用户列表 +export function listUser(query) { + return request({ + url: '/system/user/list', + method: 'get', + params: query + }) +} + +// 查询用户详细 +export function getUser(userId) { + return request({ + url: '/system/user/' + praseStrZero(userId), + method: 'get' + }) +} + +// 新增用户 +export function addUser(data) { + return request({ + url: '/system/user/edit', + method: 'post', + data: data + }) +} + +// 修改用户 +export function updateUser(data) { + return request({ + url: '/system/user/edit', + method: 'put', + data: data + }) +} + +// 删除用户 +export function delUser(userId) { + return request({ + url: '/system/user/' + userId, + method: 'delete' + }) +} + +// 导出用户 +export async function exportUser(query) { + // return request({ + // url: '/system/User/export', + // method: 'get', + // params: query + // }) + await downFile('/system/user/export', { ...query }) +} + +// 用户密码重置 +export function resetUserPwd(userId, password) { + const data = { + userId, + password + } + return request({ + url: '/system/user/resetPwd', + method: 'put', + data: data + }) +} + +// 用户状态修改 +export function changeUserStatus(userId, status) { + const data = { + userId, + status + } + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }) +} + +// 查询用户个人信息 +export function getUserProfile() { + return request({ + url: '/system/user/Profile', + method: 'get' + }) +} + +// 修改用户个人信息 +export function updateUserProfile(data) { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }) +} + +// 用户密码重置 +export function updateUserPwd(oldPassword, newPassword) { + const data = { + oldPassword, + newPassword + } + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + params: data + }) +} + +// 用户头像上传 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + data: data + }) +} + +// 下载用户导入模板 +export function importTemplate() { + return request({ + url: '/system/user/importTemplate', + method: 'get', + responseType: 'blob' //1.首先设置responseType对象格式为 blob: + }) +} diff --git a/src/api/system/userRoles.js b/src/api/system/userRoles.js new file mode 100644 index 0000000..d5d94b3 --- /dev/null +++ b/src/api/system/userRoles.js @@ -0,0 +1,37 @@ +import request from '@/utils/request' + +// 查询角色用户 +export function getRoleUsers(query) { + return request({ + url: '/system/userRole/list', + method: 'get', + params: query, + }) +} + +// 添加角色用户 +export function createRoleUsers(data) { + return request({ + url: '/system/userRole/create', + method: 'post', + data + }) +} +// 删除角色用户 +export function deleteRoleUsers(data) { + return request({ + url: '/system/userRole/delete', + method: 'post', + data + }) +} +// 查询角色未添加用户列表 +export function getExcludeUsers(query) { + return request({ + url: '/system/userRole/getExcludeUsers', + method: 'get', + params: query, + }) +} + +// export default { getRoleUsers, getExcludeUsers } diff --git a/src/api/tool/file.js b/src/api/tool/file.js new file mode 100644 index 0000000..03b64a8 --- /dev/null +++ b/src/api/tool/file.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +/** +* 文件存储分页查询 +* @param {查询条件} data +*/ +export function listSysfile(query) { + return request({ + url: 'tool/file/list', + method: 'get', + params: query, + }) +} + +/** +* 新增文件存储 +* @param data +*/ +export function addSysfile(data) { + return request({ + url: 'tool/file', + method: 'post', + data: data, + }) +} + +/** +* 修改文件存储 +* @param data +*/ +export function updateSysfile(data) { + return request({ + url: 'tool/file', + method: 'PUT', + data: data, + }) +} + +/** +* 获取文件存储详情 +* @param {Id} +*/ +export function getSysfile(id) { + return request({ + url: 'tool/file/' + id, + method: 'get' + }) +} + +/** +* 删除文件存储 +* @param {主键} pid +*/ +export function delSysfile(pid) { + return request({ + url: 'tool/file/' + pid, + method: 'delete' + }) +} + +// 导出文件存储 +export function exportSysfile(query) { + return request({ + url: 'tool/file/export', + method: 'get', + params: query + }) +} + diff --git a/src/api/tool/gen.js b/src/api/tool/gen.js new file mode 100644 index 0000000..04cd085 --- /dev/null +++ b/src/api/tool/gen.js @@ -0,0 +1,103 @@ +import request from '@/utils/request'; + +/** + * 获取数据库 + */ +export function codeGetDBList() { + return request({ + url: 'tool/gen/getDbList', + method: 'get', + }) +} +/** + * 获取数据库表 + */ +export function listDbTable(data) { + return request({ + url: 'tool/gen/getTableList', + method: 'get', + params: data, + }) +} +/** + * 生成代码 + */ +export async function codeGenerator(data) { + return await request({ + url: 'tool/gen/genCode', + method: 'POST', + data: data, + }) +} + +/** + * 获取表格列信息 + * @param {*} data + * @returns + */ +export function queryColumnInfo(tableId) { + return request({ + url: 'tool/gen/Column/' + tableId, + method: 'GET', + }) +} + +// 查询生成表数据 +export function listTable(params) { + return request({ + url: 'tool/gen/list', + method: 'get', + params: params + }) +} + +// 查询表详细信息 +export function getGenTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }) +} + +// 导入表 +export function importTable(data) { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }) +} +// 删除表数据 +export function delTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }) +} + +// 修改代码生成表信息 +export function updateGenTable(data) { + return request({ + url: '/tool/gen/', + method: 'put', + data: data + }) +} + +// 预览生成代码 +export function previewTable(tableId, data) { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'post', + params: data + }) +} + +// 同步数据库 +export function synchDb(tableId, data) { + return request({ + url: '/tool/gen/synchDb/' + tableId, + method: 'get', + params: data + }) +} \ No newline at end of file diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/src/assets/401_images/401.gif differ diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/assets/404_images/404.png differ diff --git a/src/assets/404_images/404_cloud.png b/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/assets/404_images/404_cloud.png differ diff --git a/src/assets/iconfont/iconfont.css b/src/assets/iconfont/iconfont.css new file mode 100644 index 0000000..188f4de --- /dev/null +++ b/src/assets/iconfont/iconfont.css @@ -0,0 +1,391 @@ +@font-face { + font-family: "iconfont"; /* Project id 4017520 */ + src: url('iconfont.woff2?t=1681548759797') format('woff2'), + url('iconfont.woff?t=1681548759797') format('woff'), + url('iconfont.ttf?t=1681548759797') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-tree-table:before { + content: "\e637"; +} + +.icon-unlock:before { + content: "\e654"; +} + +.icon-zujian:before { + content: "\e655"; +} + +.icon-theme:before { + content: "\e659"; +} + +.icon-swagger:before { + content: "\e65c"; +} + +.icon-star:before { + content: "\e661"; +} + +.icon-time:before { + content: "\e662"; +} + +.icon-upload:before { + content: "\e663"; +} + +.icon-weixin:before { + content: "\e664"; +} + +.icon-system:before { + content: "\e667"; +} + +.icon-web:before { + content: "\e668"; +} + +.icon-tree:before { + content: "\e669"; +} + +.icon-user:before { + content: "\e66a"; +} + +.icon-tool:before { + content: "\e66b"; +} + +.icon-zip:before { + content: "\e66c"; +} + +.icon-link:before { + content: "\e636"; +} + +.icon-list:before { + content: "\e638"; +} + +.icon-international:before { + content: "\e639"; +} + +.icon-language:before { + content: "\e63a"; +} + +.icon-index:before { + content: "\e63b"; +} + +.icon-ipvisits:before { + content: "\e63c"; +} + +.icon-money:before { + content: "\e63d"; +} + +.icon-message:before { + content: "\e63e"; +} + +.icon-login:before { + content: "\e63f"; +} + +.icon-lock:before { + content: "\e640"; +} + +.icon-menu:before { + content: "\e641"; +} + +.icon-log:before { + content: "\e643"; +} + +.icon-logininfor:before { + content: "\e644"; +} + +.icon-mnt:before { + content: "\e645"; +} + +.icon-password:before { + content: "\e646"; +} + +.icon-peoples:before { + content: "\e647"; +} + +.icon-post:before { + content: "\e648"; +} + +.icon-permission:before { + content: "\e649"; +} + +.icon-phone:before { + content: "\e64a"; +} + +.icon-people:before { + content: "\e64b"; +} + +.icon-online:before { + content: "\e64d"; +} + +.icon-pdf:before { + content: "\e64f"; +} + +.icon-redis:before { + content: "\e650"; +} + +.icon-size:before { + content: "\e651"; +} + +.icon-search:before { + content: "\e652"; +} + +.icon-server:before { + content: "\e653"; +} + +.icon-select:before { + content: "\e656"; +} + +.icon-question:before { + content: "\e657"; +} + +.icon-rate:before { + content: "\e658"; +} + +.icon-monitor:before { + content: "\e65a"; +} + +.icon-source:before { + content: "\e65b"; +} + +.icon-role:before { + content: "\e65d"; +} + +.icon-shopping:before { + content: "\e65e"; +} + +.icon-skill:before { + content: "\e65f"; +} + +.icon-number:before { + content: "\e660"; +} + +.icon-a-404:before { + content: "\e622"; +} + +.icon-email:before { + content: "\e623"; +} + +.icon-example:before { + content: "\e624"; +} + +.icon-error:before { + content: "\e625"; +} + +.icon-excel:before { + content: "\e626"; +} + +.icon-education:before { + content: "\e627"; +} + +.icon-eye-open:before { + content: "\e628"; +} + +.icon-eye:before { + content: "\e629"; +} + +.icon-github:before { + content: "\e62b"; +} + +.icon-guide:before { + content: "\e62c"; +} + +.icon-gonggao:before { + content: "\e62d"; +} + +.icon-icon1:before { + content: "\e62e"; +} + +.icon-fullscreen:before { + content: "\e62f"; +} + +.icon-icon:before { + content: "\e630"; +} + +.icon-image:before { + content: "\e631"; +} + +.icon-form:before { + content: "\e632"; +} + +.icon-job:before { + content: "\e635"; +} + +.icon-cascader:before { + content: "\e603"; +} + +.icon-alipay:before { + content: "\e604"; +} + +.icon-anq:before { + content: "\e605"; +} + +.icon-backup:before { + content: "\e606"; +} + +.icon-bug:before { + content: "\e607"; +} + +.icon-button:before { + content: "\e609"; +} + +.icon-chain:before { + content: "\e60b"; +} + +.icon-chart:before { + content: "\e60c"; +} + +.icon-checkbox:before { + content: "\e60d"; +} + +.icon-clipboard:before { + content: "\e60e"; +} + +.icon-codeConsole:before { + content: "\e60f"; +} + +.icon-code:before { + content: "\e610"; +} + +.icon-color:before { + content: "\e611"; +} + +.icon-database:before { + content: "\e612"; +} + +.icon-component:before { + content: "\e613"; +} + +.icon-dashboard:before { + content: "\e614"; +} + +.icon-date:before { + content: "\e615"; +} + +.icon-deploy:before { + content: "\e616"; +} + +.icon-develop:before { + content: "\e617"; +} + +.icon-dept:before { + content: "\e619"; +} + +.icon-dictionary:before { + content: "\e61a"; +} + +.icon-documentation:before { + content: "\e61b"; +} + +.icon-doc:before { + content: "\e61c"; +} + +.icon-download:before { + content: "\e61d"; +} + +.icon-dict:before { + content: "\e61e"; +} + +.icon-edit:before { + content: "\e620"; +} + +.icon-app:before { + content: "\e602"; +} + diff --git a/src/assets/iconfont/iconfont.js b/src/assets/iconfont/iconfont.js new file mode 100644 index 0000000..8706d38 --- /dev/null +++ b/src/assets/iconfont/iconfont.js @@ -0,0 +1 @@ +window._iconfont_svg_string_4017520='',function(a){var c=(c=document.getElementsByTagName("script"))[c.length-1],h=c.getAttribute("data-injectcss"),c=c.getAttribute("data-disable-injectsvg");if(!c){var l,v,o,t,m,z=function(c,h){h.parentNode.insertBefore(c,h)};if(h&&!a.__iconfont__svg__cssinject__){a.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}l=function(){var c,h=document.createElement("div");h.innerHTML=a._iconfont_svg_string_4017520,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(c=document.body).firstChild?z(h,c.firstChild):c.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(v=function(){document.removeEventListener("DOMContentLoaded",v,!1),l()},document.addEventListener("DOMContentLoaded",v,!1)):document.attachEvent&&(o=l,t=a.document,m=!1,s(),t.onreadystatechange=function(){"complete"==t.readyState&&(t.onreadystatechange=null,i())})}function i(){m||(m=!0,o())}function s(){try{t.documentElement.doScroll("left")}catch(c){return void setTimeout(s,50)}i()}}(window); \ No newline at end of file diff --git a/src/assets/iconfont/iconfont.json b/src/assets/iconfont/iconfont.json new file mode 100644 index 0000000..e47791c --- /dev/null +++ b/src/assets/iconfont/iconfont.json @@ -0,0 +1,667 @@ +{ + "id": "4017520", + "name": "admin", + "font_family": "iconfont", + "css_prefix_text": "icon-", + "description": "", + "glyphs": [ + { + "icon_id": "35076965", + "name": "tree-table", + "font_class": "tree-table", + "unicode": "e637", + "unicode_decimal": 58935 + }, + { + "icon_id": "35076967", + "name": "unlock", + "font_class": "unlock", + "unicode": "e654", + "unicode_decimal": 58964 + }, + { + "icon_id": "35076968", + "name": "zujian", + "font_class": "zujian", + "unicode": "e655", + "unicode_decimal": 58965 + }, + { + "icon_id": "35076969", + "name": "theme", + "font_class": "theme", + "unicode": "e659", + "unicode_decimal": 58969 + }, + { + "icon_id": "35076970", + "name": "swagger", + "font_class": "swagger", + "unicode": "e65c", + "unicode_decimal": 58972 + }, + { + "icon_id": "35076971", + "name": "star", + "font_class": "star", + "unicode": "e661", + "unicode_decimal": 58977 + }, + { + "icon_id": "35076972", + "name": "time", + "font_class": "time", + "unicode": "e662", + "unicode_decimal": 58978 + }, + { + "icon_id": "35076973", + "name": "upload", + "font_class": "upload", + "unicode": "e663", + "unicode_decimal": 58979 + }, + { + "icon_id": "35076974", + "name": "weixin", + "font_class": "weixin", + "unicode": "e664", + "unicode_decimal": 58980 + }, + { + "icon_id": "35076977", + "name": "system", + "font_class": "system", + "unicode": "e667", + "unicode_decimal": 58983 + }, + { + "icon_id": "35076979", + "name": "web", + "font_class": "web", + "unicode": "e668", + "unicode_decimal": 58984 + }, + { + "icon_id": "35076980", + "name": "tree", + "font_class": "tree", + "unicode": "e669", + "unicode_decimal": 58985 + }, + { + "icon_id": "35076981", + "name": "user", + "font_class": "user", + "unicode": "e66a", + "unicode_decimal": 58986 + }, + { + "icon_id": "35076982", + "name": "tool", + "font_class": "tool", + "unicode": "e66b", + "unicode_decimal": 58987 + }, + { + "icon_id": "35076986", + "name": "zip", + "font_class": "zip", + "unicode": "e66c", + "unicode_decimal": 58988 + }, + { + "icon_id": "35076492", + "name": "link", + "font_class": "link", + "unicode": "e636", + "unicode_decimal": 58934 + }, + { + "icon_id": "35076494", + "name": "list", + "font_class": "list", + "unicode": "e638", + "unicode_decimal": 58936 + }, + { + "icon_id": "35076495", + "name": "international", + "font_class": "international", + "unicode": "e639", + "unicode_decimal": 58937 + }, + { + "icon_id": "35076496", + "name": "language", + "font_class": "language", + "unicode": "e63a", + "unicode_decimal": 58938 + }, + { + "icon_id": "35076497", + "name": "index", + "font_class": "index", + "unicode": "e63b", + "unicode_decimal": 58939 + }, + { + "icon_id": "35076498", + "name": "ipvisits", + "font_class": "ipvisits", + "unicode": "e63c", + "unicode_decimal": 58940 + }, + { + "icon_id": "35076499", + "name": "money", + "font_class": "money", + "unicode": "e63d", + "unicode_decimal": 58941 + }, + { + "icon_id": "35076500", + "name": "message", + "font_class": "message", + "unicode": "e63e", + "unicode_decimal": 58942 + }, + { + "icon_id": "35076501", + "name": "login", + "font_class": "login", + "unicode": "e63f", + "unicode_decimal": 58943 + }, + { + "icon_id": "35076502", + "name": "lock", + "font_class": "lock", + "unicode": "e640", + "unicode_decimal": 58944 + }, + { + "icon_id": "35076503", + "name": "menu", + "font_class": "menu", + "unicode": "e641", + "unicode_decimal": 58945 + }, + { + "icon_id": "35076505", + "name": "log", + "font_class": "log", + "unicode": "e643", + "unicode_decimal": 58947 + }, + { + "icon_id": "35076506", + "name": "logininfor", + "font_class": "logininfor", + "unicode": "e644", + "unicode_decimal": 58948 + }, + { + "icon_id": "35076507", + "name": "mnt", + "font_class": "mnt", + "unicode": "e645", + "unicode_decimal": 58949 + }, + { + "icon_id": "35076509", + "name": "password", + "font_class": "password", + "unicode": "e646", + "unicode_decimal": 58950 + }, + { + "icon_id": "35076510", + "name": "peoples", + "font_class": "peoples", + "unicode": "e647", + "unicode_decimal": 58951 + }, + { + "icon_id": "35076511", + "name": "post", + "font_class": "post", + "unicode": "e648", + "unicode_decimal": 58952 + }, + { + "icon_id": "35076512", + "name": "permission", + "font_class": "permission", + "unicode": "e649", + "unicode_decimal": 58953 + }, + { + "icon_id": "35076513", + "name": "phone", + "font_class": "phone", + "unicode": "e64a", + "unicode_decimal": 58954 + }, + { + "icon_id": "35076514", + "name": "people", + "font_class": "people", + "unicode": "e64b", + "unicode_decimal": 58955 + }, + { + "icon_id": "35076516", + "name": "online", + "font_class": "online", + "unicode": "e64d", + "unicode_decimal": 58957 + }, + { + "icon_id": "35076518", + "name": "pdf", + "font_class": "pdf", + "unicode": "e64f", + "unicode_decimal": 58959 + }, + { + "icon_id": "35076519", + "name": "redis", + "font_class": "redis", + "unicode": "e650", + "unicode_decimal": 58960 + }, + { + "icon_id": "35076520", + "name": "size", + "font_class": "size", + "unicode": "e651", + "unicode_decimal": 58961 + }, + { + "icon_id": "35076521", + "name": "search", + "font_class": "search", + "unicode": "e652", + "unicode_decimal": 58962 + }, + { + "icon_id": "35076522", + "name": "server", + "font_class": "server", + "unicode": "e653", + "unicode_decimal": 58963 + }, + { + "icon_id": "35076525", + "name": "select", + "font_class": "select", + "unicode": "e656", + "unicode_decimal": 58966 + }, + { + "icon_id": "35076526", + "name": "question", + "font_class": "question", + "unicode": "e657", + "unicode_decimal": 58967 + }, + { + "icon_id": "35076527", + "name": "rate", + "font_class": "rate", + "unicode": "e658", + "unicode_decimal": 58968 + }, + { + "icon_id": "35076529", + "name": "monitor", + "font_class": "monitor", + "unicode": "e65a", + "unicode_decimal": 58970 + }, + { + "icon_id": "35076530", + "name": "source", + "font_class": "source", + "unicode": "e65b", + "unicode_decimal": 58971 + }, + { + "icon_id": "35076532", + "name": "role", + "font_class": "role", + "unicode": "e65d", + "unicode_decimal": 58973 + }, + { + "icon_id": "35076533", + "name": "shopping", + "font_class": "shopping", + "unicode": "e65e", + "unicode_decimal": 58974 + }, + { + "icon_id": "35076534", + "name": "skill", + "font_class": "skill", + "unicode": "e65f", + "unicode_decimal": 58975 + }, + { + "icon_id": "35076535", + "name": "number", + "font_class": "number", + "unicode": "e660", + "unicode_decimal": 58976 + }, + { + "icon_id": "35076366", + "name": "404", + "font_class": "a-404", + "unicode": "e622", + "unicode_decimal": 58914 + }, + { + "icon_id": "35076470", + "name": "email", + "font_class": "email", + "unicode": "e623", + "unicode_decimal": 58915 + }, + { + "icon_id": "35076471", + "name": "example", + "font_class": "example", + "unicode": "e624", + "unicode_decimal": 58916 + }, + { + "icon_id": "35076472", + "name": "error", + "font_class": "error", + "unicode": "e625", + "unicode_decimal": 58917 + }, + { + "icon_id": "35076473", + "name": "excel", + "font_class": "excel", + "unicode": "e626", + "unicode_decimal": 58918 + }, + { + "icon_id": "35076474", + "name": "education", + "font_class": "education", + "unicode": "e627", + "unicode_decimal": 58919 + }, + { + "icon_id": "35076475", + "name": "eye-open", + "font_class": "eye-open", + "unicode": "e628", + "unicode_decimal": 58920 + }, + { + "icon_id": "35076476", + "name": "eye", + "font_class": "eye", + "unicode": "e629", + "unicode_decimal": 58921 + }, + { + "icon_id": "35076480", + "name": "github", + "font_class": "github", + "unicode": "e62b", + "unicode_decimal": 58923 + }, + { + "icon_id": "35076481", + "name": "guide", + "font_class": "guide", + "unicode": "e62c", + "unicode_decimal": 58924 + }, + { + "icon_id": "35076482", + "name": "gonggao", + "font_class": "gonggao", + "unicode": "e62d", + "unicode_decimal": 58925 + }, + { + "icon_id": "35076483", + "name": "icon1", + "font_class": "icon1", + "unicode": "e62e", + "unicode_decimal": 58926 + }, + { + "icon_id": "35076484", + "name": "fullscreen", + "font_class": "fullscreen", + "unicode": "e62f", + "unicode_decimal": 58927 + }, + { + "icon_id": "35076485", + "name": "icon", + "font_class": "icon", + "unicode": "e630", + "unicode_decimal": 58928 + }, + { + "icon_id": "35076486", + "name": "image", + "font_class": "image", + "unicode": "e631", + "unicode_decimal": 58929 + }, + { + "icon_id": "35076487", + "name": "form", + "font_class": "form", + "unicode": "e632", + "unicode_decimal": 58930 + }, + { + "icon_id": "35076491", + "name": "job", + "font_class": "job", + "unicode": "e635", + "unicode_decimal": 58933 + }, + { + "icon_id": "35076284", + "name": "cascader", + "font_class": "cascader", + "unicode": "e603", + "unicode_decimal": 58883 + }, + { + "icon_id": "35076315", + "name": "alipay", + "font_class": "alipay", + "unicode": "e604", + "unicode_decimal": 58884 + }, + { + "icon_id": "35076316", + "name": "anq", + "font_class": "anq", + "unicode": "e605", + "unicode_decimal": 58885 + }, + { + "icon_id": "35076317", + "name": "backup", + "font_class": "backup", + "unicode": "e606", + "unicode_decimal": 58886 + }, + { + "icon_id": "35076318", + "name": "bug", + "font_class": "bug", + "unicode": "e607", + "unicode_decimal": 58887 + }, + { + "icon_id": "35076321", + "name": "button", + "font_class": "button", + "unicode": "e609", + "unicode_decimal": 58889 + }, + { + "icon_id": "35076323", + "name": "chain", + "font_class": "chain", + "unicode": "e60b", + "unicode_decimal": 58891 + }, + { + "icon_id": "35076324", + "name": "chart", + "font_class": "chart", + "unicode": "e60c", + "unicode_decimal": 58892 + }, + { + "icon_id": "35076325", + "name": "checkbox", + "font_class": "checkbox", + "unicode": "e60d", + "unicode_decimal": 58893 + }, + { + "icon_id": "35076326", + "name": "clipboard", + "font_class": "clipboard", + "unicode": "e60e", + "unicode_decimal": 58894 + }, + { + "icon_id": "35076327", + "name": "codeConsole", + "font_class": "codeConsole", + "unicode": "e60f", + "unicode_decimal": 58895 + }, + { + "icon_id": "35076328", + "name": "code", + "font_class": "code", + "unicode": "e610", + "unicode_decimal": 58896 + }, + { + "icon_id": "35076329", + "name": "color", + "font_class": "color", + "unicode": "e611", + "unicode_decimal": 58897 + }, + { + "icon_id": "35076330", + "name": "database", + "font_class": "database", + "unicode": "e612", + "unicode_decimal": 58898 + }, + { + "icon_id": "35076331", + "name": "component", + "font_class": "component", + "unicode": "e613", + "unicode_decimal": 58899 + }, + { + "icon_id": "35076332", + "name": "dashboard", + "font_class": "dashboard", + "unicode": "e614", + "unicode_decimal": 58900 + }, + { + "icon_id": "35076333", + "name": "date", + "font_class": "date", + "unicode": "e615", + "unicode_decimal": 58901 + }, + { + "icon_id": "35076334", + "name": "deploy", + "font_class": "deploy", + "unicode": "e616", + "unicode_decimal": 58902 + }, + { + "icon_id": "35076335", + "name": "develop", + "font_class": "develop", + "unicode": "e617", + "unicode_decimal": 58903 + }, + { + "icon_id": "35076337", + "name": "dept", + "font_class": "dept", + "unicode": "e619", + "unicode_decimal": 58905 + }, + { + "icon_id": "35076340", + "name": "dictionary", + "font_class": "dictionary", + "unicode": "e61a", + "unicode_decimal": 58906 + }, + { + "icon_id": "35076341", + "name": "documentation", + "font_class": "documentation", + "unicode": "e61b", + "unicode_decimal": 58907 + }, + { + "icon_id": "35076342", + "name": "doc", + "font_class": "doc", + "unicode": "e61c", + "unicode_decimal": 58908 + }, + { + "icon_id": "35076343", + "name": "download", + "font_class": "download", + "unicode": "e61d", + "unicode_decimal": 58909 + }, + { + "icon_id": "35076344", + "name": "dict", + "font_class": "dict", + "unicode": "e61e", + "unicode_decimal": 58910 + }, + { + "icon_id": "35076351", + "name": "edit", + "font_class": "edit", + "unicode": "e620", + "unicode_decimal": 58912 + }, + { + "icon_id": "35075963", + "name": "app", + "font_class": "app", + "unicode": "e602", + "unicode_decimal": 58882 + } + ] +} diff --git a/src/assets/iconfont/iconfont.ttf b/src/assets/iconfont/iconfont.ttf new file mode 100644 index 0000000..43c3557 Binary files /dev/null and b/src/assets/iconfont/iconfont.ttf differ diff --git a/src/assets/iconfont/iconfont.woff b/src/assets/iconfont/iconfont.woff new file mode 100644 index 0000000..bec21a3 Binary files /dev/null and b/src/assets/iconfont/iconfont.woff differ diff --git a/src/assets/iconfont/iconfont.woff2 b/src/assets/iconfont/iconfont.woff2 new file mode 100644 index 0000000..f67e7ce Binary files /dev/null and b/src/assets/iconfont/iconfont.woff2 differ diff --git a/src/assets/icons/gitee-fill-round.png b/src/assets/icons/gitee-fill-round.png new file mode 100644 index 0000000..458efa0 Binary files /dev/null and b/src/assets/icons/gitee-fill-round.png differ diff --git a/src/assets/icons/github-fill.png b/src/assets/icons/github-fill.png new file mode 100644 index 0000000..418b4bc Binary files /dev/null and b/src/assets/icons/github-fill.png differ diff --git a/src/assets/icons/svg/build.svg b/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/exit-fullscreen.svg b/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/gitee.svg b/src/assets/icons/svg/gitee.svg new file mode 100644 index 0000000..e2ffd2e --- /dev/null +++ b/src/assets/icons/svg/gitee.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/validCode.svg b/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..cfb1021 --- /dev/null +++ b/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/wechat-fill.png b/src/assets/icons/wechat-fill.png new file mode 100644 index 0000000..c32e4f1 Binary files /dev/null and b/src/assets/icons/wechat-fill.png differ diff --git a/src/assets/images/dark.svg b/src/assets/images/dark.svg new file mode 100644 index 0000000..f646bd7 --- /dev/null +++ b/src/assets/images/dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/light.svg b/src/assets/images/light.svg new file mode 100644 index 0000000..ab7cc08 --- /dev/null +++ b/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/profile.jpg b/src/assets/images/profile.jpg new file mode 100644 index 0000000..997732a Binary files /dev/null and b/src/assets/images/profile.jpg differ diff --git a/src/assets/images/reward.jpg b/src/assets/images/reward.jpg new file mode 100644 index 0000000..68fe0d3 Binary files /dev/null and b/src/assets/images/reward.jpg differ diff --git a/src/assets/logo/icon.png b/src/assets/logo/icon.png new file mode 100644 index 0000000..8d87889 Binary files /dev/null and b/src/assets/logo/icon.png differ diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png new file mode 100644 index 0000000..419a17b Binary files /dev/null and b/src/assets/logo/logo.png differ diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..3590d8d --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import './variables.module.scss'; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue) +} + +.light-blue-btn { + @include colorBtn($light-blue) +} + +.red-btn { + @include colorBtn($red) +} + +.pink-btn { + @include colorBtn($pink) +} + +.green-btn { + @include colorBtn($green) +} + +.tiffany-btn { + @include colorBtn($tiffany) +} + +.yellow-btn { + @include colorBtn($yellow) +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..ebd10da --- /dev/null +++ b/src/assets/styles/element-ui.scss @@ -0,0 +1,130 @@ +// cover some element-ui styles + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0px; + } +} + +// table 里面操作按钮样式覆盖 +.el-table__cell .cell { + .el-button.is-text { + padding: 8px 5px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0px; + } + } +} +// fix 2.2.0 版本label标签不居中 +// .el-form-item--small .el-form-item__label { +// line-height: 32px !important; +// } + +// element ui 移动端组件适配 +.el-icon { + vertical-align: middle; +} + +.el-header { + --el-header-padding: 0 0px !important; + // --el-header-height: 50px !important; +} +// el 2.2.0 text button +.el-button.is-text { + color: var(--el-color-primary) !important; +} +@media screen and (max-width: 500px) { + .el-message { + min-width: 300px !important; + } +} + +@media screen and (max-width: 500px) { + .el-message-box { + width: 300px !important; + } + + .el-pagination__jump { + display: none !important; + } + + .el-pagination__sizes { + display: none !important; + } +} + +// dialog +@media screen and (max-width: 700px) { + .el-dialog { + --el-dialog-width: 100% !important; + // --el-dialog-margin-top: 0 !important; + } + // .el-dialog:not(.is-fullscreen) { + // margin-top: 0 !important; + // } + .el-drawer { + width: 85% !important; + } +} + +/** 表格更多操作下拉样式 */ +.el-table .el-dropdown-link { + cursor: pointer; + color: #409eff; + margin-left: 5px; +} + +.el-table .el-dropdown, +.el-icon-arrow-down { + font-size: 12px; +} + +//适配完毕 + +// 隐藏picture-card 上传按钮 +.hide .el-upload--picture-card { + display: none; +} + +// 禁止菜单选中 +.el-sub-menu .el-sub-menu__title span, +.el-menu .el-menu-item { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +// fix 侧边栏二级导航缩小图标消失问题 +.el-sub-menu__title { + padding-right: unset !important; +} + +// fix 顶部导航更多样式问题 +.el-menu--horizontal .el-sub-menu .el-sub-menu__icon-arrow { + right: calc(0px - var(--el-menu-base-level-padding)) !important; +} + +// 弹出搜索框 +.header-search-select { + .el-select-dropdown__item { + height: unset !important; + line-height: unset !important; + margin-bottom: 5px; + display: flex; + align-items: center; + justify-content: space-between; + } +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss new file mode 100644 index 0000000..3615249 --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,276 @@ +@import './variables.module.scss'; +@import './mixin.scss'; +@import './transition.scss'; +@import './element-ui.scss'; +@import './sidebar.scss'; +@import './btn.scss'; +@import './waves.scss'; + +html, +body, +#app { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; + font-weight: 400; + -webkit-font-smoothing: antialiased; + -webkit-tap-highlight-color: transparent; + background-color: var(--base-bg-main); + // overflow: hidden; + position: relative; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0 !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: ' '; + clear: both; + height: 0; + } +} + +.text-center { + text-align: center; +} + +.link-type, +.link-type:focus { + color: var(--el-color-primary); + cursor: pointer; + + &:hover { + // color: rgb(32, 160, 255); + opacity: 0.3; + } +} + +/** 基础通用 **/ +.pt5 { + padding-top: 5px; +} + +.pr5 { + padding-right: 5px; +} + +.pb5 { + padding-bottom: 5px; +} +.pb20 { + padding-bottom: 20px; +} + +.mt5 { + margin-top: 5px; +} + +.mr5 { + margin-right: 5px; +} + +.mb5 { + margin-bottom: 5px; +} + +.mb8 { + margin-bottom: 8px; +} + +.ml5 { + margin-left: 5px; +} + +.mt10 { + margin-top: 10px; +} + +.mr10 { + margin-right: 10px; +} + +.mb10 { + margin-bottom: 10px; +} + +.ml10 { + margin-left: 10px; +} + +.mt20 { + margin-top: 20px; +} + +.mr20 { + margin-right: 20px; +} + +.mb20 { + margin-bottom: 20px; +} + +.ml20 { + margin-left: 20px; +} + +.ml { + margin-left: auto; +} + +.mr { + margin-right: auto; +} + +.mt { + margin-top: auto; +} + +.mb { + margin-bottom: auto; +} +.w20 { + width: 20%; +} +.w100 { + width: 100%; +} + +.pull-right { + float: right !important; +} + +/* text color */ +.text-navy { + color: #1ab394; +} +.text-pink { + color: pink; +} +.text-primary { + color: inherit; +} + +.text-success { + color: #1c84c6; +} + +.text-info { + color: #23c6c8; +} + +.text-warning { + color: #f8ac59; +} + +.text-danger { + color: #ff0000; +} + +.text-muted { + color: #888888; +} + +.text-orange { + color: #ff7d00; +} + +.text-hotpink { + color: hotpink; +} + +.text-green { + color: green; +} + +.text-greenyellow { + color: greenyellow; +} +.text-purple { + color: #ff00ff; +} + +/* image */ +.img-circle { + border-radius: 50%; +} + +.card-box { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 10px; +} + +.icon { + width: 100px; +} + +.table-td-thumb { + width: 56px; +} + +.flex-center { + flex-direction: column; + overflow: hidden; +} diff --git a/src/assets/styles/login.scss b/src/assets/styles/login.scss new file mode 100644 index 0000000..4c6580f --- /dev/null +++ b/src/assets/styles/login.scss @@ -0,0 +1,73 @@ +.login { + background: radial-gradient(220% 105% at top center, #1b2947 10%, #4b76a7 40%, #81acae 65%, #f7f7b6); + background-attachment: fixed; + overflow: hidden; + display: flex; + justify-content: center; + align-items: center; + height: 100%; + // background-image: url('@/assets/images/login-bg.jpg'); + background-size: cover; +} + +.title { + margin: 0px auto 30px auto; + text-align: center; + // color: #fff; +} + +.login-form { + border-radius: 6px; + background: #ffffff; + // background-color: hsla(0, 0%, 100%, 0.3); + width: var(--base-login-width); + padding: 25px 15px 5px 15px; + position: relative; + + .input-icon { + height: 39px; + width: 14px; + margin-left: 0px; + } +} + +.login-tip { + font-size: 13px; + text-align: center; + color: #bfbfbf; +} + +.login-code { + width: 33%; + height: 40px; + float: right; + + img { + width: 100%; + cursor: pointer; + vertical-align: middle; + } +} + +.el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #fff; + font-family: Arial; + font-size: 12px; + letter-spacing: 1px; +} + +.login-code-img { + height: 40px; + padding-left: 12px; +} +.langSet { + position: absolute; + right: 20px; + top: 10px; +} diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } + + @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..d399128 --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,106 @@ +#app { + .sidebar { + position: relative; + overflow-y: hidden; + z-index: 1001; + transition: width 0.28s ease; + background-color: var(--base-menu-background); + height: 100%; + display: flex; + flex-direction: column; + -webkit-box-shadow: 2px 0 14px rgb(0 21 41 / 10%); + box-shadow: 2px 0 14px rgb(0 21 41 / 10%); + + .el-scrollbar__bar.is-vertical { + right: 0px; + } + // 去掉el-menu边框 + .el-menu { + border: none; + } + + [class^='el-icon'] { + width: 1em; + height: 1em; + font-size: unset; + } + } + + // 展开sidebar状态设置svg-icon边距 + .openSidebar { + .sidebar { + transform: translate(0); + } + .sidebar .svg-icon { + margin-right: 5px; + } + } + + // 隐藏侧边栏样式 + .hideSidebar { + .el-aside { + --el-aside-width: 60px; + } + // 隐藏箭头 + .el-sub-menu { + overflow: hidden; + + & > .el-sub-menu__title { + .el-sub-menu__icon-arrow { + display: none; + } + } + } + // 折叠状态下 + .el-menu--collapse { + [class^='el-icon'] { + width: auto; + font-size: medium; + margin-right: 0; + } + .el-sub-menu { + & > .el-sub-menu__title { + & > span { + height: 3000px; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar { + transition: transform 0.28s; + position: fixed; + // background: var(--base-menu-background, #fff); + } + + &.hideSidebar { + .sidebar { + display: none; + } + } + } +} + +// when menu collapsed +.el-menu--vertical { + // the scroll bar appears when the subMenu is too long + > .el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar { + width: 6px; + } + } +} diff --git a/src/assets/styles/transition.scss b/src/assets/styles/transition.scss new file mode 100644 index 0000000..4cb27cc --- /dev/null +++ b/src/assets/styles/transition.scss @@ -0,0 +1,48 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss new file mode 100644 index 0000000..168ba7e --- /dev/null +++ b/src/assets/styles/variables.module.scss @@ -0,0 +1,45 @@ +// base color +$blue: #324157; +$light-blue: #3a71a8; +$red: #c03639; +$pink: #e65d6e; +$green: #30b08f; +$tiffany: #4ab7bd; +$yellow: #fec171; +$panGreen: #30b08f; + +// 默认菜单主题风格 +:root { + --base-text-color-rgba: rgba(0, 0, 0, 0.85); + --base-sidebar-width: 220px; + // 左侧菜单宽度 + --el-aside-width: 220px; + //底部高度 + --base-footer-height: 30px; + --base-tags-height: 34px; + --base-header-height: 50px; + //登录框宽度 + --base-login-width: 280px; +} + +/***侧边栏深色配置***/ +[data-theme='theme-dark'] { + --base-menu-background: #324157; + --base-logo-title-color: #ffffff; + // // el-ement ui 设置 + // --el-fill-color-blank: #304156; + --el-text-color-primary: #e5eaf3; + --el-menu-text-color: var(--el-text-color-primary); +} +html.dark { + /* custom dark bg color */ + // --el-bg-color: #141414; + --base-color-white: #ffffff; + --base-text-color-rgba: #ffffff; +} +html.cafe { + filter: sepia(0.9) hue-rotate(315deg) brightness(0.9); +} +html.contrast { + filter: contrast(2); +} diff --git a/src/assets/styles/waves.scss b/src/assets/styles/waves.scss new file mode 100644 index 0000000..23add2c --- /dev/null +++ b/src/assets/styles/waves.scss @@ -0,0 +1,101 @@ +/* Waves v0.6.0 +* http://fian.my.id/Waves +* +* Copyright 2014 Alfiana E. Sibuea and other contributors +* Released under the MIT license +* https://github.com/fians/Waves/blob/master/LICENSE +*/ +.waves-effect { + position: relative; + cursor: pointer; + display: inline-block; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + vertical-align: middle; + z-index: 1; + will-change: opacity, transform; + transition: all 0.3s ease-out; +} +.waves-effect .waves-ripple { + position: absolute; + border-radius: 50%; + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + opacity: 0; + background: rgba(0, 0, 0, 0.2); + transition: all 0.7s ease-out; + transition-property: opacity, -webkit-transform; + transition-property: transform, opacity; + transition-property: transform, opacity, -webkit-transform; + -webkit-transform: scale(0); + transform: scale(0); + pointer-events: none; +} +.waves-effect.waves-light .waves-ripple { + background-color: rgba(255, 255, 255, 0.45); +} +.waves-effect.waves-red .waves-ripple { + background-color: rgba(244, 67, 54, 0.7); +} +.waves-effect.waves-yellow .waves-ripple { + background-color: rgba(255, 235, 59, 0.7); +} +.waves-effect.waves-orange .waves-ripple { + background-color: rgba(255, 152, 0, 0.7); +} +.waves-effect.waves-purple .waves-ripple { + background-color: rgba(156, 39, 176, 0.7); +} +.waves-effect.waves-green .waves-ripple { + background-color: rgba(76, 175, 80, 0.7); +} +.waves-effect.waves-teal .waves-ripple { + background-color: rgba(0, 150, 136, 0.7); +} +.waves-effect input[type='button'], +.waves-effect input[type='reset'], +.waves-effect input[type='submit'] { + border: 0; + font-style: normal; + font-size: inherit; + text-transform: inherit; + background: none; +} +.waves-notransition { + transition: none !important; +} +.waves-circle { + -webkit-transform: translateZ(0); + transform: translateZ(0); + -webkit-mask-image: -webkit-radial-gradient(circle, #fff 100%, #000 100%); +} +.waves-input-wrapper { + border-radius: 0.2em; + vertical-align: bottom; +} +.waves-input-wrapper .waves-button-input { + position: relative; + top: 0; + left: 0; + z-index: 1; +} +.waves-circle { + text-align: center; + width: 2.5em; + height: 2.5em; + line-height: 2.5em; + border-radius: 50%; + -webkit-mask-image: none; +} +.waves-block { + display: block; +} +a.waves-effect .waves-ripple { + z-index: -1; +} diff --git a/src/auto-import.d.ts b/src/auto-import.d.ts new file mode 100644 index 0000000..5f28183 --- /dev/null +++ b/src/auto-import.d.ts @@ -0,0 +1,64 @@ +// Generated by 'unplugin-auto-import' +// We suggest you to commit this file into source control +declare global { + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const createPinia: typeof import('pinia')['createPinia'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineStore: typeof import('pinia')['defineStore'] + const effectScope: typeof import('vue')['effectScope'] + const EffectScope: typeof import('vue')['EffectScope'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouter: typeof import('vue-router')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] +} +export {} diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..98e6f71 --- /dev/null +++ b/src/components/Breadcrumb/index.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src/components/Crontab/day.vue b/src/components/Crontab/day.vue new file mode 100644 index 0000000..4c82e45 --- /dev/null +++ b/src/components/Crontab/day.vue @@ -0,0 +1,172 @@ + + + + diff --git a/src/components/Crontab/hour.vue b/src/components/Crontab/hour.vue new file mode 100644 index 0000000..a5839aa --- /dev/null +++ b/src/components/Crontab/hour.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/src/components/Crontab/index.vue b/src/components/Crontab/index.vue new file mode 100644 index 0000000..0fc068d --- /dev/null +++ b/src/components/Crontab/index.vue @@ -0,0 +1,280 @@ + + + + + diff --git a/src/components/Crontab/min.vue b/src/components/Crontab/min.vue new file mode 100644 index 0000000..1bfac91 --- /dev/null +++ b/src/components/Crontab/min.vue @@ -0,0 +1,128 @@ + + + + diff --git a/src/components/Crontab/month.vue b/src/components/Crontab/month.vue new file mode 100644 index 0000000..dd9d7ac --- /dev/null +++ b/src/components/Crontab/month.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/components/Crontab/result.vue b/src/components/Crontab/result.vue new file mode 100644 index 0000000..e3eb757 --- /dev/null +++ b/src/components/Crontab/result.vue @@ -0,0 +1,560 @@ + + + diff --git a/src/components/Crontab/second.vue b/src/components/Crontab/second.vue new file mode 100644 index 0000000..99b5939 --- /dev/null +++ b/src/components/Crontab/second.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/src/components/Crontab/week.vue b/src/components/Crontab/week.vue new file mode 100644 index 0000000..d3d83da --- /dev/null +++ b/src/components/Crontab/week.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/src/components/Crontab/year.vue b/src/components/Crontab/year.vue new file mode 100644 index 0000000..b560bb4 --- /dev/null +++ b/src/components/Crontab/year.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue new file mode 100644 index 0000000..8545d0e --- /dev/null +++ b/src/components/DictTag/index.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/src/components/Echarts/Gauge.vue b/src/components/Echarts/Gauge.vue new file mode 100644 index 0000000..25960e9 --- /dev/null +++ b/src/components/Echarts/Gauge.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue new file mode 100644 index 0000000..058ac5a --- /dev/null +++ b/src/components/Editor/index.vue @@ -0,0 +1,135 @@ + + \ No newline at end of file diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue new file mode 100644 index 0000000..d7bf228 --- /dev/null +++ b/src/components/FileUpload/index.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue new file mode 100644 index 0000000..01cb87f --- /dev/null +++ b/src/components/Hamburger/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..b6dfe92 --- /dev/null +++ b/src/components/HeaderSearch/index.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue new file mode 100644 index 0000000..ee5e9a1 --- /dev/null +++ b/src/components/IconSelect/index.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/src/components/IconSelect/requireIcons.js b/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..8286a05 --- /dev/null +++ b/src/components/IconSelect/requireIcons.js @@ -0,0 +1,14 @@ +let icons = [] +const modules = import.meta.glob('./../../assets/icons/svg/*.svg') +for (const path in modules) { + const p = path.split('assets/icons/svg/')[1].split('.svg')[0] + icons.push(p) +} + +// iconfont +import iconList from '@/assets/iconfont/iconfont.json' + +iconList.glyphs.forEach((element) => { + icons.push(element.name) +}) +export default icons diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..30fd088 --- /dev/null +++ b/src/components/ImagePreview/index.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..29db740 --- /dev/null +++ b/src/components/ImageUpload/index.vue @@ -0,0 +1,190 @@ + + + diff --git a/src/components/LangSelect/index.vue b/src/components/LangSelect/index.vue new file mode 100644 index 0000000..4c966b8 --- /dev/null +++ b/src/components/LangSelect/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/components/Map/index.vue b/src/components/Map/index.vue new file mode 100644 index 0000000..c7dadd4 --- /dev/null +++ b/src/components/Map/index.vue @@ -0,0 +1,247 @@ + + + + + diff --git a/src/components/Notice/Index.vue b/src/components/Notice/Index.vue new file mode 100644 index 0000000..3864a17 --- /dev/null +++ b/src/components/Notice/Index.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..9a25ecd --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,112 @@ + + + + diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue new file mode 100644 index 0000000..7bf6148 --- /dev/null +++ b/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..6571ac9 --- /dev/null +++ b/src/components/RightToolbar/index.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/components/Screenfull/index.vue b/src/components/Screenfull/index.vue new file mode 100644 index 0000000..61e2186 --- /dev/null +++ b/src/components/Screenfull/index.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..565d780 --- /dev/null +++ b/src/components/SizeSelect/index.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..44580f8 --- /dev/null +++ b/src/components/SvgIcon/index.vue @@ -0,0 +1,62 @@ + + + diff --git a/src/components/SvgIcon/svgicon.js b/src/components/SvgIcon/svgicon.js new file mode 100644 index 0000000..bb68b67 --- /dev/null +++ b/src/components/SvgIcon/svgicon.js @@ -0,0 +1,10 @@ +import * as components from '@element-plus/icons-vue' + +export default { + install: (app) => { + for (const key in components) { + const componentConfig = components[key]; + app.component(componentConfig.name, componentConfig); + } + }, +}; \ No newline at end of file diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue new file mode 100644 index 0000000..9a8300a --- /dev/null +++ b/src/components/TopNav/index.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue new file mode 100644 index 0000000..091b1a2 --- /dev/null +++ b/src/components/iFrame/index.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue new file mode 100644 index 0000000..70446a6 --- /dev/null +++ b/src/layout/components/Navbar.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..ef6264c --- /dev/null +++ b/src/layout/components/Settings/index.vue @@ -0,0 +1,348 @@ + + + + + diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..5566eee --- /dev/null +++ b/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..0e6e10f --- /dev/null +++ b/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..d0a08c4 --- /dev/null +++ b/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,105 @@ + + + diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..7683035 --- /dev/null +++ b/src/layout/components/Sidebar/index.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..a765e91 --- /dev/null +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..53ba73c --- /dev/null +++ b/src/layout/components/TagsView/index.vue @@ -0,0 +1,344 @@ + + + + + + + diff --git a/src/layout/components/index.js b/src/layout/components/index.js new file mode 100644 index 0000000..422accd --- /dev/null +++ b/src/layout/components/index.js @@ -0,0 +1,4 @@ +// export { default as AppMain } from './AppMain' +export { default as Navbar } from './Navbar' +export { default as Settings } from './Settings' +export { default as TagsView } from './TagsView/index.vue' diff --git a/src/layout/index.vue b/src/layout/index.vue new file mode 100644 index 0000000..de11d22 --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..71ea075 --- /dev/null +++ b/src/main.js @@ -0,0 +1,77 @@ +import { createApp } from 'vue' +// import Cookies from 'js-cookie' + +import ElementPlus from 'element-plus' +import 'dayjs/locale/zh-cn' +import '@/assets/styles/index.scss' // global css + +import App from './App' +import router from './router' +import directive from './directive' // directive +// 注册指令 +import plugins from './plugins' // plugins +import { downFile } from '@/utils/request' +import signalR from '@/utils/signalR' +import vueI18n from './i18n/index' +import pinia from '@/store/index' + +// svg图标 +import '@/assets/iconfont/iconfont.js' //iconfont +import 'virtual:svg-icons-register' +import SvgIcon from '@/components/SvgIcon/index.vue' +import elementIcons from '@/components/SvgIcon/svgicon' + +import './permission' // permission control + +import { getConfigKey } from '@/api/system/config' +import { getDicts } from '@/api/system/dict/data' +import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, download } from '@/utils/ruoyi' + +// 分页组件 +import Pagination from '@/components/Pagination' +// 自定义表格工具组件 +import RightToolbar from '@/components/RightToolbar' +// 文件上传组件 +import FileUpload from '@/components/FileUpload' +// 图片上传组件 +import ImageUpload from '@/components/ImageUpload' +// 图片预览组件 +import ImagePreview from '@/components/ImagePreview' +// 字典标签组件 +import DictTag from '@/components/DictTag' +// el-date-picker 快捷选项 +import dateOptions from '@/utils/dateOptions' +// 富文本 +import Editor from '@/components/Editor' +// 地图 +import Map from '@/components/Map/index.vue' + +const app = createApp(App) +signalR.init(import.meta.env.VITE_APP_SOCKET_API) +app.config.globalProperties.signalr = signalR +// 全局方法挂载 +app.config.globalProperties.getConfigKey = getConfigKey +app.config.globalProperties.getDicts = getDicts +app.config.globalProperties.download = download +app.config.globalProperties.downFile = downFile +app.config.globalProperties.parseTime = parseTime +app.config.globalProperties.resetForm = resetForm +app.config.globalProperties.handleTree = handleTree +app.config.globalProperties.addDateRange = addDateRange +app.config.globalProperties.selectDictLabel = selectDictLabel +app.config.globalProperties.dateOptions = dateOptions + +// 全局组件挂载 +app.component('DictTag', DictTag) +app.component('Pagination', Pagination) +app.component('UploadFile', FileUpload) +app.component('UploadImage', ImageUpload) +app.component('ImagePreview', ImagePreview) +app.component('RightToolbar', RightToolbar) +app.component('svg-icon', SvgIcon) +app.component('editor', Editor) +app.component('Map', Map) + +directive(app) + +app.use(pinia).use(router).use(plugins).use(ElementPlus, {}).use(elementIcons).use(vueI18n).mount('#app') diff --git a/src/permission.js b/src/permission.js new file mode 100644 index 0000000..31fe0e1 --- /dev/null +++ b/src/permission.js @@ -0,0 +1,59 @@ +import router from './router' +import { ElMessage } from 'element-plus' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +import { isHttp } from '@/utils/validate' +import useUserStore from '@/store/modules/user' +import useSettingsStore from '@/store/modules/settings' +import usePermissionStore from '@/store/modules/permission' +NProgress.configure({ showSpinner: false }); + +const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/socialLogin']; + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + to.meta.title && useSettingsStore().setTitle(to.meta.title) + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else { + if (useUserStore().roles.length === 0) { + // 判断当前用户是否已拉取完user_info信息 + useUserStore().getInfo().then(() => { + usePermissionStore().generateRoutes().then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + accessRoutes.forEach(route => { + if (!isHttp(route.path)) { + router.addRoute(route) // 动态添加可访问路由表 + } + }) + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) + }).catch(err => { + useUserStore().logOut().then(() => { + ElMessage.error(err != undefined ? err : '登录失败') + next({ path: '/' }) + }) + }) + } else { + next() + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) \ No newline at end of file diff --git a/src/plugins/auth.js b/src/plugins/auth.js new file mode 100644 index 0000000..1ec8c41 --- /dev/null +++ b/src/plugins/auth.js @@ -0,0 +1,60 @@ +import useUserStore from '@/store/modules/user' + +function authPermission(permission) { + const all_permission = "*:*:*"; + const permissions = useUserStore() && useUserStore().permissions + if (permission && permission.length > 0) { + return permissions.some(v => { + return all_permission === v || v === permission + }) + } else { + return false + } +} + +function authRole(role) { + const super_admin = "admin"; + const roles = useUserStore().roles + if (role && role.length > 0) { + return roles.some(v => { + return super_admin === v || v === role + }) + } else { + return false + } +} + +export default { + // 验证用户是否具备某权限 + hasPermi(permission) { + return authPermission(permission); + }, + // 验证用户是否含有指定权限,只需包含其中一个 + hasPermiOr(permissions) { + return permissions.some(item => { + return authPermission(item) + }) + }, + // 验证用户是否含有指定权限,必须全部拥有 + hasPermiAnd(permissions) { + return permissions.every(item => { + return authPermission(item) + }) + }, + // 验证用户是否具备某角色 + hasRole(role) { + return authRole(role); + }, + // 验证用户是否含有指定角色,只需包含其中一个 + hasRoleOr(roles) { + return roles.some(item => { + return authRole(item) + }) + }, + // 验证用户是否含有指定角色,必须全部拥有 + hasRoleAnd(roles) { + return roles.every(item => { + return authRole(item) + }) + } +} \ No newline at end of file diff --git a/src/plugins/cache.js b/src/plugins/cache.js new file mode 100644 index 0000000..492170d --- /dev/null +++ b/src/plugins/cache.js @@ -0,0 +1,96 @@ +const sessionCache = { + set(key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get(key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON(key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON(key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove(key) { + sessionStorage.removeItem(key); + } +} +const localCache = { + set(key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get(key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON(key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON(key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove(key) { + localStorage.removeItem(key); + } +} +import Cookies from 'js-cookie' + +const cookie = { + set(key, data, expires) { + Cookies.set(key, data, { expires: expires }) + }, + set(key, data) { + Cookies.set(key, data) + }, + remove(key) { + Cookies.remove(key) + }, + get(key) { + Cookies.get(key) + } +} +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache, + /** + * cookie存储 + */ + cookie: cookie +} \ No newline at end of file diff --git a/src/plugins/download.js b/src/plugins/download.js new file mode 100644 index 0000000..c31a064 --- /dev/null +++ b/src/plugins/download.js @@ -0,0 +1,72 @@ +import axios from 'axios' +import { ElMessage } from 'element-plus' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { blobValidate } from '@/utils/ruoyi' + +const baseURL = import.meta.env.VITE_APP_BASE_API + +export default { + name(name, isDelete = true) { + var url = baseURL + "/common/download?fileName=" + encodeURI(name) + "&delete=" + isDelete + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURI(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + resource(resource) { + var url = baseURL + "/common/download/resource?resource=" + encodeURI(resource); + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURI(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data); + } + }) + }, + zip(url, name) { + var url = baseURL + url + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + } else { + this.printErrMsg(res.data); + } + }) + }, + saveAs(text, name, opts) { + saveAs(text, name, opts); + }, + async printErrMsg(data) { + const resText = await data.text(); + const rspObj = JSON.parse(resText); + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + ElMessage.error(errMsg); + } +} + diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 0000000..bc20928 --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,27 @@ +import tab from './tab' +import auth from './auth' +import cache from './cache' +import modal from './modal' +import download from './download' + +export default function installPlugins(app) { + // 页签操作 + app.config.globalProperties.$tab = tab + // 认证对象 + app.config.globalProperties.$auth = auth + // 缓存对象 + app.config.globalProperties.$cache = cache + // 模态框对象 + app.config.globalProperties.$modal = modal + // 下载文件 + app.config.globalProperties.$download = download + + Array.prototype.showColumn = function (column) { + var item = this.find((x) => x.prop == column) + // console.log('showColumn方法', this, column, item) + if (item) { + return item.visible + } + return true + } +} diff --git a/src/plugins/modal.js b/src/plugins/modal.js new file mode 100644 index 0000000..e1d71be --- /dev/null +++ b/src/plugins/modal.js @@ -0,0 +1,82 @@ +import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus' + +let loadingInstance; + +export default { + // 消息提示 + msg(content) { + ElMessage.info(content) + }, + // 错误消息 + msgError(content) { + ElMessage.error(content) + }, + // 成功消息 + msgSuccess(content) { + ElMessage.success(content) + }, + // 警告消息 + msgWarning(content) { + ElMessage.warning(content) + }, + // 弹出提示 + alert(content) { + ElMessageBox.alert(content, "系统提示") + }, + // 错误提示 + alertError(content) { + ElMessageBox.alert(content, "系统提示", { type: 'error' }) + }, + // 成功提示 + alertSuccess(content) { + ElMessageBox.alert(content, "系统提示", { type: 'success' }) + }, + // 警告提示 + alertWarning(content) { + ElMessageBox.alert(content, "系统提示", { type: 'warning' }) + }, + // 通知提示 + notify(content) { + ElNotification.info(content) + }, + // 错误通知 + notifyError(content) { + ElNotification.error(content); + }, + // 成功通知 + notifySuccess(content) { + ElNotification.success(content) + }, + // 警告通知 + notifyWarning(content) { + ElNotification.warning(content) + }, + // 确认窗体 + confirm(content) { + return ElMessageBox.confirm(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 提交内容 + prompt(content) { + return ElMessageBox.prompt(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 打开遮罩层 + loading(content) { + loadingInstance = ElLoading.service({ + lock: true, + text: content, + background: "rgba(0, 0, 0, 0.7)", + }) + }, + // 关闭遮罩层 + closeLoading() { + loadingInstance.close(); + } +} \ No newline at end of file diff --git a/src/plugins/tab.js b/src/plugins/tab.js new file mode 100644 index 0000000..76f1eed --- /dev/null +++ b/src/plugins/tab.js @@ -0,0 +1,65 @@ +import useTagsViewStore from '@/store/modules/tagsView' +import router from '@/router' + +export default { + // 刷新当前tab页签 + refreshPage(obj) { + const { path, query, matched } = router.currentRoute.value; + if (obj === undefined) { + matched.forEach((m) => { + if (m.components && m.components.default && m.components.default.name) { + if (!['Layout', 'ParentView'].includes(m.components.default.name)) { + obj = { name: m.components.default.name, path: path, query: query }; + } + } + }); + } + return useTagsViewStore().delCachedView(obj).then(() => { + const { path, query } = obj + router.replace({ + path: '/redirect' + path, + query: query + }) + }) + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj) { + useTagsViewStore().delView(router.currentRoute.value); + if (obj !== undefined) { + return router.push(obj); + } + }, + // 关闭指定tab页签 + closePage(obj) { + if (obj === undefined) { + return useTagsViewStore().delView(router.currentRoute.value).then(({ lastPath }) => { + return router.push(lastPath || '/index'); + }); + } + return useTagsViewStore().delView(obj); + }, + // 关闭所有tab页签 + closeAllPage() { + return useTagsViewStore().delAllViews(); + }, + // 关闭左侧tab页签 + closeLeftPage(obj) { + return useTagsViewStore().delLeftTags(obj || router.currentRoute.value); + }, + // 关闭右侧tab页签 + closeRightPage(obj) { + return useTagsViewStore().delRightTags(obj || router.currentRoute.value); + }, + // 关闭其他tab页签 + closeOtherPage(obj) { + return useTagsViewStore().delOthersViews(obj || router.currentRoute.value); + }, + // 打开tab页签 + openPage(url) { + return router.push(url); + }, + // 修改tab页签 + updatePage(obj) { + return useTagsViewStore().updateVisitedView(obj); + } +} \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..5169aca --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,104 @@ +import { createWebHistory, createRouter } from 'vue-router' +import Layout from '@/layout' + +/** + * Note: 路由配置项 + * + * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 + * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 + * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 + * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 + * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 + * meta : { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + } + */ + +// 公共路由 +export const constantRoutes = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path(.*)', + component: () => import('@/views/redirect/index.vue') + } + ] + }, + { + path: '/login', + component: () => import('@/views/login'), + hidden: true + }, + { + path: '/sociallogin', + component: () => import('@/views/socialLogin'), + hidden: true + }, + { + path: '/register', + component: () => import('@/views/register'), + hidden: true + }, + { + path: '/:pathMatch(.*)*', + component: () => import('@/views/error/404'), + hidden: true + }, + { + path: '/401', + component: () => import('@/views/error/401'), + hidden: true + }, + { + path: '', + component: Layout, + redirect: '/index', + children: [ + { + path: '/index', + component: () => import('@/views/index'), + name: 'Index', + meta: { title: '首页', icon: 'dashboard', affix: true, titleKey: 'menu.home' } + } + ] + }, + { + path: '/user', + component: Layout, + hidden: true, + redirect: 'noredirect', + children: [ + { + path: 'profile', + component: () => import('@/views/system/user/profile/index'), + name: 'Profile', + meta: { title: '个人中心', icon: 'user', titleKey: 'menu.personalCenter' } + } + ] + }, + +] + +const router = createRouter({ + history: createWebHistory(import.meta.env.VITE_APP_ROUTER_PREFIX), + routes: constantRoutes, + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } else { + return { top: 0 } + } + } +}) + +export default router diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..ba53060 --- /dev/null +++ b/src/settings.js @@ -0,0 +1,83 @@ +export default { + /** + * 框架版本号 + */ + version: '3.8.2', + /** + * 网页标题 + */ + title: import.meta.env.VITE_APP_TITLE, + /** + * 侧边栏主题 深色主题theme-dark,浅色主题theme-light + */ + sideTheme: 'theme-dark', + /** + * 框架主题颜色值 + */ + theme: '#FF8C00', + /** + * 是否系统布局配置 + */ + showSettings: false, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView + */ + tagsView: true, + + /** + * 是否固定头部 + */ + fixedHeader: false, + + /** + * 是否显示logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: false, + + /** + * @type {string | array} 'production' | ['production', 'development'] + * @description Need show err logs component. + * The default is only used in the production env + * If you want to also use it in dev, you can pass ['production', 'development'] + */ + errorLog: 'production', + /** + * 版权信息 + */ + copyright: 'Copyright ©2023 阿尔文 All Rights Reserved.', + /** + * 是否显示底部栏 + */ + showFooter: true, + /** + * 是否显示水印 + */ + showWatermark: false, + /** + * 水印文案 + */ + watermarkText: 'ARWAdmin.NET', + /** + * 是否显示其他登录 + */ + showOtherLogin: false, + /** + * 默认大小 + */ + defaultSize: 'default', + /** + * 默认语言 + */ + defaultLang: 'zh-cn' +} diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..f10f389 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,3 @@ +const store = createPinia() + +export default store \ No newline at end of file diff --git a/src/store/modules/app.js b/src/store/modules/app.js new file mode 100644 index 0000000..567f0e4 --- /dev/null +++ b/src/store/modules/app.js @@ -0,0 +1,48 @@ +import Cookies from 'js-cookie' +import cache from '@/plugins/cache' +import defaultSettings from '@/settings' +const useAppStore = defineStore('app', { + state: () => ({ + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + // withoutAnimation: false, + hide: false + }, + device: 'desktop', + size: cache.local.get('size') || defaultSettings.defaultSize, + lang: cache.local.get('lang') || defaultSettings.defaultLang + }), + actions: { + toggleSideBar() { + if (this.sidebar.hide) { + return false + } + this.sidebar.opened = !this.sidebar.opened + if (this.sidebar.opened) { + Cookies.set('sidebarStatus', 1) + } else { + Cookies.set('sidebarStatus', 0) + } + }, + closeSideBar() { + Cookies.set('sidebarStatus', 0) + this.sidebar.opened = false + }, + toggleDevice(device) { + this.device = device + }, + setSize(size) { + this.size = size + cache.local.set('size', size) + }, + toggleSideBarHide(status) { + this.sidebar.hide = status + }, + setLang(lang) { + this.lang = lang + cache.local.set('lang', lang) + } + } +}) + +export default useAppStore diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js new file mode 100644 index 0000000..ca4bcea --- /dev/null +++ b/src/store/modules/permission.js @@ -0,0 +1,132 @@ +import { constantRoutes } from '@/router' +import { getRouters } from '@/api/system/menu' +import Layout from '@/layout/index' +import ParentView from '@/components/ParentView' +import InnerLink from '@/layout/components/InnerLink' +import cache from '@/plugins/cache' + +// 匹配views里面所有的.vue文件 +const modules = import.meta.glob('./../../views/**/*.vue') + +const usePermissionStore = defineStore('permission', { + state: () => ({ + routes: [], + defaultRoutes: [], + topbarRouters: [], + sidebarRouters: [], + commonlyUsedRoutes: [] //常用路由 + }), + actions: { + setRoutes(routes) { + this.addRoutes = routes + this.routes = constantRoutes.concat(routes) + }, + setDefaultRoutes(routes) { + this.defaultRoutes = constantRoutes.concat(routes) + }, + setTopbarRoutes(routes) { + this.topbarRouters = routes + }, + setSidebarRouters(routes) { + this.sidebarRouters = routes + }, + // 生成路由 + generateRoutes() { + return new Promise((resolve) => { + // 向后端请求路由数据 + getRouters().then((res) => { + const sdata = JSON.parse(JSON.stringify(res.data)) + const rdata = JSON.parse(JSON.stringify(res.data)) + const defaultData = JSON.parse(JSON.stringify(res.data)) + const sidebarRoutes = filterAsyncRouter(sdata) + const rewriteRoutes = filterAsyncRouter(rdata, false, true) + const defaultRoutes = filterAsyncRouter(defaultData) + this.setRoutes(rewriteRoutes) + this.setSidebarRouters(constantRoutes.concat(sidebarRoutes)) + this.setDefaultRoutes(sidebarRoutes) + this.setTopbarRoutes(defaultRoutes) + this.setCommonlyUsedRoutes() + resolve(rewriteRoutes) + }) + }) + }, + // 设置常用路由 + setCommonlyUsedRoutes() { + var arraryObjectLocal = cache.local.getJSON('commonlyUseMenu') || [] + this.commonlyUsedRoutes = arraryObjectLocal + }, + // 移除常用路由 + removeCommonlyUsedRoutes(item) { + var routes = this.commonlyUsedRoutes + + const fi = routes.findIndex((v) => v.path === item.path) + routes.splice(fi, 1) + cache.local.setJSON('commonlyUseMenu', routes) + } + } +}) + +// 遍历后台传来的路由字符串,转换为组件对象 +function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { + return asyncRouterMap.filter((route) => { + if (type && route.children) { + route.children = filterChildren(route.children) + } + if (route.component) { + // Layout ParentView 组件特殊处理 + if (route.component === 'Layout') { + route.component = Layout + } else if (route.component === 'ParentView') { + route.component = ParentView + } else if (route.component === 'InnerLink') { + route.component = InnerLink + } else { + route.component = loadView(route.component) + } + } + if (route.children != null && route.children && route.children.length) { + route.children = filterAsyncRouter(route.children, route, type) + } else { + delete route['children'] + delete route['redirect'] + } + return true + }) +} + +function filterChildren(childrenMap, lastRouter = false) { + var children = [] + childrenMap.forEach((el, index) => { + if (el.children && el.children.length) { + if (el.component === 'ParentView' && !lastRouter) { + el.children.forEach((c) => { + c.path = el.path + '/' + c.path + if (c.children && c.children.length) { + children = children.concat(filterChildren(c.children, c)) + return + } + children.push(c) + }) + return + } + } + if (lastRouter) { + el.path = lastRouter.path + '/' + el.path + } + children = children.concat(el) + }) + return children +} + +export const loadView = (view) => { + let res + for (const path in modules) { + const dir = path.split('views/')[1].split('.vue')[0] + if (dir === view) { + res = () => modules[path]() + } + } + return res +} + +export default usePermissionStore diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js new file mode 100644 index 0000000..82daafa --- /dev/null +++ b/src/store/modules/settings.js @@ -0,0 +1,39 @@ +import defaultSettings from '@/settings' +import { useDynamicTitle } from '@/utils/dynamicTitle' + +const { sideTheme, theme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, showFooter, showWatermark, watermarkText } = + defaultSettings + +const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' +const useSettingsStore = defineStore('settings', { + state: () => ({ + title: '', + theme: storageSetting.theme || theme, + sideTheme: storageSetting.sideTheme || sideTheme, + showSettings: showSettings, + topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, + tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, + fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, + sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, + dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle, + showFooter: storageSetting.showFooter === undefined ? showFooter : storageSetting.showFooter, + showWatermark: storageSetting.showWatermark === undefined ? showWatermark : storageSetting.showWatermark, + watermarkText: storageSetting.watermarkText === undefined ? watermarkText : storageSetting.watermarkText + }), + actions: { + // 修改布局设置 + changeSetting(data) { + const { key, value } = data + // if (this.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(this.$state, key)) { + this[key] = value + } + }, + // 设置网页标题 + setTitle(title) { + this.title = title + useDynamicTitle() + } + } +}) +export default useSettingsStore diff --git a/src/store/modules/socket.js b/src/store/modules/socket.js new file mode 100644 index 0000000..998e9d0 --- /dev/null +++ b/src/store/modules/socket.js @@ -0,0 +1,29 @@ +const useSocketStore = defineStore('socket', { + state: () => ({ + onlineNum: 0, + onlineUsers: [], + noticeList: [], + noticeDot: false + }), + actions: { + //更新在线人数 + setOnlineUserNum(num) { + this.onlineNum = num + }, + // 更新系统通知 + setNoticeList(data) { + this.noticeList = data + this.noticeDot = data.length > 0 + }, + // setOnlineUsers(data) { + // const { onlineNum, users } = data + // this.onlineUsers = users + // this.onlineNum = onlineNum + // }, + sendChat(data) { + const { proxy } = getCurrentInstance() + console.log(data) + } + } +}) +export default useSocketStore diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js new file mode 100644 index 0000000..93ae11a --- /dev/null +++ b/src/store/modules/tagsView.js @@ -0,0 +1,180 @@ +const useTagsViewStore = defineStore('tagsView', { + state: () => ({ + visitedViews: [], + cachedViews: [], + iframeViews: [] + }), + actions: { + addView(view) { + this.addVisitedView(view) + this.addCachedView(view) + }, + addIframeView(view) { + if (this.iframeViews.some((v) => v.path === view.path)) return + this.iframeViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + addVisitedView(view) { + if (this.visitedViews.some((v) => v.path === view.path)) return + this.visitedViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + addCachedView(view) { + if (this.cachedViews.includes(view.name)) return + if (!view.meta.noCache) { + this.cachedViews.push(view.name) + } + }, + delView(view) { + return new Promise((resolve) => { + this.delVisitedView(view) + this.delCachedView(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + delVisitedView(view) { + return new Promise((resolve) => { + for (const [i, v] of this.visitedViews.entries()) { + if (v.path === view.path) { + this.visitedViews.splice(i, 1) + break + } + } + this.iframeViews = this.iframeViews.filter((item) => item.path !== view.path) + resolve([...this.visitedViews]) + }) + }, + delIframeView(view) { + return new Promise((resolve) => { + this.iframeViews = this.iframeViews.filter((item) => item.path !== view.path) + resolve([...this.iframeViews]) + }) + }, + delCachedView(view) { + return new Promise((resolve) => { + const index = this.cachedViews.indexOf(view.name) + index > -1 && this.cachedViews.splice(index, 1) + resolve([...this.cachedViews]) + }) + }, + delOthersViews(view) { + return new Promise((resolve) => { + this.delOthersVisitedViews(view) + this.delOthersCachedViews(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + delOthersVisitedViews(view) { + return new Promise((resolve) => { + this.visitedViews = this.visitedViews.filter((v) => { + return v.meta.affix || v.path === view.path + }) + this.iframeViews = this.iframeViews.filter((item) => item.path === view.path) + resolve([...this.visitedViews]) + }) + }, + delOthersCachedViews(view) { + return new Promise((resolve) => { + const index = this.cachedViews.indexOf(view.name) + if (index > -1) { + this.cachedViews = this.cachedViews.slice(index, index + 1) + } else { + this.cachedViews = [] + } + resolve([...this.cachedViews]) + }) + }, + delAllViews(view) { + return new Promise((resolve) => { + this.delAllVisitedViews(view) + this.delAllCachedViews(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + delAllVisitedViews(view) { + return new Promise((resolve) => { + const affixTags = this.visitedViews.filter((tag) => tag.meta.affix) + this.visitedViews = affixTags + this.iframeViews = [] + resolve([...this.visitedViews]) + }) + }, + delAllCachedViews(view) { + return new Promise((resolve) => { + this.cachedViews = [] + resolve([...this.cachedViews]) + }) + }, + updateVisitedView(view) { + for (let v of this.visitedViews) { + if (v.path === view.path) { + v = Object.assign(v, view) + break + } + } + }, + delRightTags(view) { + return new Promise((resolve) => { + const index = this.visitedViews.findIndex((v) => v.path === view.path) + if (index === -1) { + return + } + this.visitedViews = this.visitedViews.filter((item, idx) => { + if (idx <= index || (item.meta && item.meta.affix)) { + return true + } + const i = this.cachedViews.indexOf(item.name) + if (i > -1) { + this.cachedViews.splice(i, 1) + } + if (item.meta.link) { + const fi = this.iframeViews.findIndex((v) => v.path === item.path) + this.iframeViews.splice(fi, 1) + } + return false + }) + resolve([...this.visitedViews]) + }) + }, + delLeftTags(view) { + return new Promise((resolve) => { + const index = this.visitedViews.findIndex((v) => v.path === view.path) + if (index === -1) { + return + } + this.visitedViews = this.visitedViews.filter((item, idx) => { + if (idx >= index || (item.meta && item.meta.affix)) { + return true + } + const i = this.cachedViews.indexOf(item.name) + if (i > -1) { + this.cachedViews.splice(i, 1) + } + if (item.meta.link) { + const fi = this.iframeViews.findIndex((v) => v.path === item.path) + this.iframeViews.splice(fi, 1) + } + return false + }) + resolve([...this.visitedViews]) + }) + } + } +}) + +export default useTagsViewStore diff --git a/src/store/modules/user.js b/src/store/modules/user.js new file mode 100644 index 0000000..d602d49 --- /dev/null +++ b/src/store/modules/user.js @@ -0,0 +1,127 @@ +import { login, logout, getInfo, oauthCallback } from '@/api/system/login' +import { getToken, setToken, removeToken } from '@/utils/auth' +import defAva from '@/assets/images/profile.jpg' +import md5 from 'js-md5' +const useUserStore = defineStore('user', { + state: () => ({ + userInfo: '', + token: getToken(), + name: '', + avatar: '', + roles: [], + permissions: [], + userId: 0, + authSource: '', + userName: '' + }), + actions: { + setAuthSource(source) { + this.authSource = source + }, + // 登录 + login(userInfo) { + const username = userInfo.username.trim() + const password = userInfo.password + const code = userInfo.code + const uuid = userInfo.uuid + return new Promise((resolve, reject) => { + login(username, password, code, uuid) + .then((res) => { + if (res.code == 200) { + setToken(res.data) + this.token = res.data + resolve() //then处理 + } else { + console.log('login error ', res) + reject(res) //catch处理 + } + }) + .catch((error) => { + reject(error) + }) + }) + }, + /** + * 三方授权登录 + * @param {*} data + * @param {*} param { authSource : ''} + * @returns + */ + oauthLogin(data, param) { + return new Promise((resolve, reject) => { + oauthCallback(data, param) + .then((res) => { + const { code, data } = res + if (code == 200) { + setToken(data.token) + this.token = data.token + // Cookies.set('username', data.userName, { expires: 30 }) + // Cookies.set('password', encrypt(data.password), { expires: 30 }) + // Cookies.set('rememberMe', true, { expires: 30 }) + resolve(res) //then处理 + } else { + console.log('login error ', res) + reject(res) //catch处理 + } + }) + .catch((err) => { + reject(err) + }) + }) + }, + // 获取用户信息 + getInfo() { + return new Promise((resolve, reject) => { + getInfo() + .then((res) => { + const data = res.data + const avatar = data.user.avatar == '' ? defAva : data.user.avatar + + if (data.roles && data.roles.length > 0) { + // 验证返回的roles是否是一个非空数组 + this.roles = data.roles + this.permissions = data.permissions + } else { + this.roles = ['ROLE_DEFAULT'] + } + + this.name = data.user.nickName + this.avatar = avatar + this.userInfo = data.user //新加 + this.userId = data.user.userId //新加 + this.userName = data.user.userName //新加 + resolve(res) + }) + .catch((error) => { + console.error(error) + reject('获取用户信息失败') + }) + }) + }, + // 退出系统 + logOut() { + return new Promise((resolve, reject) => { + logout(this.token) + .then((res) => { + this.token = '' + this.roles = [] + this.permissions = [] + removeToken() + resolve(res) + }) + .catch((error) => { + reject(error) + }) + }) + }, + // 前端 登出 + fedLogOut() { + return new Promise((resolve) => { + this.token = '' + removeToken() + resolve() + }) + } + } +}) +export default useUserStore diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..fa92d24 --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,15 @@ +// import Cookies from 'js-cookie' + +const TokenKey = 'ZR-Token' + +export function getToken() { + return localStorage.getItem(TokenKey) +} + +export function setToken(token) { + return localStorage.setItem(TokenKey, token) +} + +export function removeToken() { + return localStorage.removeItem(TokenKey) +} diff --git a/src/utils/dateOptions.js b/src/utils/dateOptions.js new file mode 100644 index 0000000..d886440 --- /dev/null +++ b/src/utils/dateOptions.js @@ -0,0 +1,85 @@ +// dayjs 参考:https://www.cnblogs.com/Airon-wei/p/14362160.html +import dayjs from 'dayjs' + +const dateOptions = [ + { + text: '昨天', + value: () => { + const start = dayjs().subtract(1, 'day').format('YYYY-MM-DD') + const end = start + ' 23:59:59' + + return [start, dayjs(end).toISOString()] + } + }, + { + text: '今天', + value: () => { + const start = dayjs().format('YYYY-MM-DD') + const end = start + ' 23:59:59' + + return [start, end] + } + }, + { + text: '本周', + value: () => { + const end = dayjs().endOf('week').add(1, 'day').format('YYYY-MM-DD') + ' 23:59:59' + const start = dayjs().startOf('week').add(1, 'day').format('YYYY-MM-DD') + return [start, end] + } + }, + { + text: '上周', + value: () => { + const start = dayjs().add(-1, 'week').startOf('week').add(1, 'day').format('YYYY-MM-DD') + const end = dayjs().add(-1, 'week').endOf('week').add(1, 'day').format('YYYY-MM-DD') + ' 23:59:59' + return [start, end] + } + }, + { + text: '本月', + value: () => { + const end = dayjs().endOf('month').format('YYYY-MM-DD') + const start = dayjs().startOf('month').format('YYYY-MM-DD') + + return [start, end + ' 23:59:59'] + } + }, + { + text: '上月', + value: () => { + const end = dayjs().startOf('month').format('YYYY-MM-DD') + const start = dayjs().add(-1, 'month').startOf('month').format('YYYY-MM-DD') + + return [start, end] + } + }, + { + text: '最近一周', + value: () => { + const end = dayjs().format('YYYY-MM-DD') + ' 23:59:59' + const start = new Date() + start.setTime(start.getTime() - 3600 * 1000 * 24 * 7) + return [dayjs(start).format('YYYY-MM-DD'), end] + } + }, + { + text: '最近一个月', + value: () => { + const end = dayjs().format('YYYY-MM-DD') + ' 23:59:59' + // const start = new Date() + //start.setTime(start.getTime() - 3600 * 1000 * 24 * 30) + return [dayjs().day(-30).format('YYYY-MM-DD'), end] + } + }, + { + text: '最近三个月', + value: () => { + const end = dayjs().format('YYYY-MM-DD') + ' 23:59:59' + // const start = new Date() + // start.setTime(start.getTime() - 3600 * 1000 * 24 * 90) + return [dayjs().day(-90).format('YYYY-MM-DD'), end] + } + } +] +export default dateOptions diff --git a/src/utils/dict.js b/src/utils/dict.js new file mode 100644 index 0000000..44eb728 --- /dev/null +++ b/src/utils/dict.js @@ -0,0 +1,17 @@ +import { getDicts } from '@/api/system/dict/data' + +/** + * 获取字典数据 + */ +export function useDict(...args) { + const res = ref({}); + return (() => { + args.forEach((d, index) => { + res.value[d] = []; + getDicts(d).then(resp => { + res.value[d] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, listClass: p.listClass, cssClass: p.cssClass })) + }) + }) + return toRefs(res.value); + })() +} \ No newline at end of file diff --git a/src/utils/dynamicTitle.js b/src/utils/dynamicTitle.js new file mode 100644 index 0000000..449d899 --- /dev/null +++ b/src/utils/dynamicTitle.js @@ -0,0 +1,14 @@ +import defaultSettings from '@/settings' +import useSettingsStore from '@/store/modules/settings' + +/** + * 动态修改标题 + */ +export function useDynamicTitle() { + const settingsStore = useSettingsStore() + if (settingsStore.dynamicTitle) { + document.title = settingsStore.title + ' - ' + defaultSettings.title; + } else { + document.title = defaultSettings.title; + } +} \ No newline at end of file diff --git a/src/utils/errorCode.js b/src/utils/errorCode.js new file mode 100644 index 0000000..d2111ee --- /dev/null +++ b/src/utils/errorCode.js @@ -0,0 +1,6 @@ +export default { + '401': '认证失败,无法访问系统资源', + '403': '当前操作没有权限', + '404': '访问资源不存在', + 'default': '系统未知错误,请反馈给管理员' +} diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..59f0c5b --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,390 @@ +import { parseTime } from './ruoyi' +import { useWebNotification } from '@vueuse/core' + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime(time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function getQueryObject(url) { + url = url == null ? window.location.href : url + const search = url.substring(url.lastIndexOf('?') + 1) + const obj = {} + const reg = /([^?&=]+)=([^?&=]*)/g + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1) + let val = decodeURIComponent($2) + val = String(val) + obj[name] = val + return rs + }) + return obj +} + +/** + * 清空数组 + * @param {Array} actual + * @returns {Array} + */ +export function cleanArray(actual) { + const newArray = [] + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]) + } + } + return newArray +} + +/** + * @param {Object} json + * @returns {Array} + */ +export function param(json) { + if (!json) return '' + return cleanArray( + Object.keys(json).map(key => { + if (json[key] === undefined) return '' + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) + }) + ).join('&') +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj(url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +/** + * @param {string} val + * @returns {string} + */ +export function html2Text(val) { + const div = document.createElement('div') + div.innerHTML = val + return div.textContent || div.innerText +} + +/** + * Merges two objects, giving the last one precedence + * @param {Object} target + * @param {(Object|Array)} source + * @returns {Object} + */ +export function objectMerge(target, source) { + if (typeof target !== 'object') { + target = {} + } + if (Array.isArray(source)) { + return source.slice() + } + Object.keys(source).forEach(property => { + const sourceProperty = source[property] + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty) + } else { + target[property] = sourceProperty + } + }) + return target +} + +/** + * @param {HTMLElement} element + * @param {string} className + */ +export function toggleClass(element, className) { + if (!element || !className) { + return + } + let classString = element.className + const nameIndex = classString.indexOf(className) + if (nameIndex === -1) { + classString += '' + className + } else { + classString = + classString.substr(0, nameIndex) + + classString.substr(nameIndex + className.length) + } + element.className = classString +} + +/** + * @param {string} type + * @returns {Date} + */ +export function getTime(type) { + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90 + } else { + return new Date(new Date().toDateString()) + } +} + +/** + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {*} + */ +export function debounce(func, wait, immediate) { + let timeout, args, context, timestamp, result + + const later = function () { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp + + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args) + if (!timeout) context = args = null + } + } + } + + return function (...args) { + context = this + timestamp = +new Date() + const callNow = immediate && !timeout + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait) + if (callNow) { + result = func.apply(context, args) + context = args = null + } + + return result + } +} + +/** + * This is just a simple version of deep copy + * Has a lot of edge cases bug + * If you want to use a perfect deep copy, use lodash's _.cloneDeep + * @param {Object} source + * @returns {Object} + */ +export function deepClone(source) { + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone') + } + const targetObj = source.constructor === Array ? [] : {} + Object.keys(source).forEach(keys => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]) + } else { + targetObj[keys] = source[keys] + } + }) + return targetObj +} + +/** + * @param {Array} arr + * @returns {Array} + */ +export function uniqueArr(arr) { + return Array.from(new Set(arr)) +} + +/** + * @returns {string} + */ +export function createUniqueString() { + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) +} + +/** + * Check if an element has a class + * @param {HTMLElement} elm + * @param {string} cls + * @returns {boolean} + */ +export function hasClass(ele, cls) { + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) +} + +/** + * Add class to element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function addClass(ele, cls) { + if (!hasClass(ele, cls)) ele.className += ' ' + cls +} + +/** + * Remove class from element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function removeClass(ele, cls) { + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') + ele.className = ele.className.replace(reg, ' ') + } +} + +export function makeMap(str, expectsLowerCase) { + const map = Object.create(null) + const list = str.split(',') + for (let i = 0; i < list.length; i++) { + map[list[i]] = true + } + return expectsLowerCase ? + val => map[val.toLowerCase()] : + val => map[val] +} + +// 首字母大小 +export function titleCase(str) { + return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) +} + +// 下划转驼峰 +export function camelCase(str) { + return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) +} + +// 是否数字 +export function isNumberStr(str) { + return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) +} + +/** + * 变浅颜色值 + * @param color 颜色值字符串 + * @param level 加深的程度,限0-1之间 + * @returns 返回处理后的颜色值 + */ +export function getLightColor(color, level) { + let reg = /^\#?[0-9A-Fa-f]{6}$/; + if (!reg.test(color)) return color; + let rgb = hexToRgb(color); + for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]); + return rgbToHex(rgb[0], rgb[1], rgb[2]); +} + +/** + * hex颜色转rgb颜色 + * @param str 颜色值字符串 + * @returns 返回处理后的颜色值 + */ +export function hexToRgb(str) { + let hexs = ''; + let reg = /^\#?[0-9A-Fa-f]{6}$/; + if (!reg.test(str)) return str; + str = str.replace('#', ''); + hexs = str.match(/../g); + for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16); + return hexs; +} + +/** + * rgb颜色转Hex颜色 + * @param r 代表红色 + * @param g 代表绿色 + * @param b 代表蓝色 + * @returns 返回处理后的颜色值 + */ +export function rgbToHex(r, g, b) { + let reg = /^\d{1,3}$/; + if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ""; + let hexs = [r.toString(16), g.toString(16), b.toString(16)]; + for (let i = 0; i < 3; i++) + if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`; + return `#${hexs.join('')}`; +} + +/** + * 浏览器Web通知 + * @param { title: 'title' } optinos + */ +export function webNotify(optinos) { + const { show, isSupported } = useWebNotification({ + title: optinos.title, + dir: 'auto', + lang: 'en', + renotify: true, + tag: 'tag', + body: optinos.body + }) + if (isSupported) { + show() + } +} + +/** + * 是否空对象 + * @param {Object} value + * @return {Boolean} + */ +export function isEmptyObject(value) { + return JSON.stringify(value) == '{}'; +} \ No newline at end of file diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js new file mode 100644 index 0000000..a758068 --- /dev/null +++ b/src/utils/jsencrypt.js @@ -0,0 +1,22 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' + +// 密钥对生成 http://web.chacuo.net/netrsakeypair + +const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALj0zjON+EVdBsnMcR4Uj+jOYgp5ZipftQZ1utW8KvVioz+RSaotF1JHt59q9SC/mZcWWpbpcEqQ3WyyyCC33msCAwEAAQ==' + +const privateKey = + 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAuPTOM434RV0GycxxHhSP6M5iCnlmKl+1BnW61bwq9WKjP5FJqi0XUke3n2r1IL+ZlxZalulwSpDdbLLIILfeawIDAQABAkB5PYAtq1KjpWddwPYlkbUEFsWNuCaQgExZ/7KJiN9gGjo/UfUZ3W39Orb8PITIYf1NbasReqgddAcsfJNyoDWBAiEA7K89DyTmbjNSmekdD3rejRDdMzzXYtcbo69ZjHoowMUCIQDIDN8eg6PcWk4kiRcRYcNEfriUJR7Fg07ellSPv821bwIhAJA5TEyxIJUgQwI0cZfgOELfdtrlBR5ek6IPlNKsEa89AiBbMVroexPQWC41A3VLjChKagXUKpO7b98dIqRLnyCz6wIgP3qpvnO4IOxY7f5XarfCVyIHZJAMt/R1f16P5OkKv+A=' + +// 加密 +export function encrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) // 设置公钥 + return encryptor.encrypt(txt) // 对数据进行加密 +} + +// 解密 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) // 设置私钥 + return encryptor.decrypt(txt) // 对数据进行解密 +} diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..db6f329 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,203 @@ +import axios from 'axios' +import { ElMessageBox, ElMessage, ElLoading } from 'element-plus' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import useUserStore from '@/store/modules/user' +import { blobValidate } from '@/utils/ruoyi' +import { saveAs } from 'file-saver' + +let downloadLoadingInstance +// 解决后端跨域获取不到cookie问题 +// axios.defaults.withCredentials = true +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: import.meta.env.VITE_APP_BASE_API, + // 超时 + timeout: 30000 +}) + +// request拦截器 +service.interceptors.request.use( + (config) => { + // 是否需要设置 token + if (getToken()) { + //将token放到请求头发送给服务器,将tokenkey放在请求头中 + config.headers['Authorization'] = 'Bearer ' + getToken() + config.headers['userid'] = useUserStore().userId + config.headers['userName'] = useUserStore().userName + } + return config + }, + (error) => { + console.log(error) + Promise.reject(error) + } +) + +// 响应拦截器 +service.interceptors.response.use( + (res) => { + if (res.status !== 200) { + Promise.reject('network error') + return + } + // 未设置状态码则默认成功状态 + const { code, msg } = res.data + // 二进制数据则直接返回 + if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { + return res + } + if (code == 401) { + ElMessageBox.confirm('登录状态已过期,请重新登录', '系统提示', { + confirmButtonText: '重新登陆', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + useUserStore() + .logOut() + .then(() => { + location.href = import.meta.env.VITE_APP_ROUTER_PREFIX + 'index' + }) + }) + + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code == 0 || code == 1 || code == 110 || code == 101 || code == 403 || code == 500 || code == 429) { + ElMessage({ + message: msg, + type: 'error' + }) + return Promise.reject(res.data) + } else { + //返回标准 code/msg/data字段 + return res.data + } + }, + (error) => { + console.log('axios err', error) + let { message } = error + if (message == 'Network Error') { + message = '后端接口连接异常' + } else if (message.includes('timeout')) { + message = '系统接口请求超时' + } else if (message.includes('Request failed with status code 429')) { + message = '请求过于频繁,请稍后再试' + } else if (message.includes('Request failed with status code')) { + message = '系统接口' + message.substr(message.length - 3) + '异常,请联系管理员' + } + ElMessage({ + message: message, + type: 'error', + duration: 3 * 1000, + grouping: true + }) + return Promise.reject(error) + } +) + +/** + * get方法,对应get请求 + * @param {String} url [请求的url地址] + * @param {Object} params [请求时携带的参数] + */ +export function get(url, params) { + return new Promise((resolve, reject) => { + axios + .get(url, { + params: params + }) + .then((res) => { + resolve(res.data) + }) + .catch((err) => { + reject(err) + }) + }) +} + +export function post(url, params) { + return new Promise((resolve, reject) => { + axios + .post(url, { + params: params + }) + .then((res) => { + resolve(res.data) + }) + .catch((err) => { + reject(err) + }) + }) +} + +/** + * 提交表单 + * @param {*} url + * @param {*} data + */ +export function postForm(url, data, config) { + return new Promise((resolve, reject) => { + axios + .post(url, data, config) + .then((res) => { + resolve(res.data) + }) + .catch((err) => { + reject(err) + }) + }) +} + +/** + * 通用下载方法 + * @param {*} url 请求地址 + * @param {*} params 请求参数 + * @param {*} config 配置 + * @returns + */ +export async function downFile(url, params, config) { + downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }) + + service + .get(url, { + params, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob', + ...config + }) + .then(async (resp) => { + const { data } = resp + + const isLogin = await blobValidate(data) + if (isLogin) { + var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') + var contentDisposition = decodeURI(resp.headers['content-disposition']) + var result = patt.exec(contentDisposition) + var fileName = result[1] + fileName = fileName.replace(/\"/g, '') + + const blob = new Blob([data]) + saveAs(blob, fileName) + } else { + const resText = await data.text() + const rspObj = JSON.parse(resText) + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + + ElMessage({ + message: errMsg, + type: 'error' + }) + } + downloadLoadingInstance.close() + }) + .catch((err) => { + ElMessage({ + message: '下载文件出现错误,请联系管理员!', + type: 'error' + }) + downloadLoadingInstance.close() + }) +} + +export default service diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js new file mode 100644 index 0000000..54fbb5d --- /dev/null +++ b/src/utils/ruoyi.js @@ -0,0 +1,284 @@ +const baseURL = import.meta.env.VITE_APP_BASE_API +import dayjs from 'dayjs' +/** + * 通用js方法封装处理 + * Copyright (c) 2019 ruoyi + */ + +/** + * 日期格式化 + * @param {*} time + * @param {* } pattern 'YYYY-MM-DD HH:mm:ss' + * @returns + */ +export function parseTime(time, pattern = 'YYYY-MM-DD HH:mm:ss') { + if (arguments.length === 0 || !time) { + return null + } + + return dayjs(time).format(pattern) +} + +// 表单重置 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields() + } +} + +/** + * 添加日期范围 + * @param { beginTime: '', endTime: '', page: 1} params + * @param {*} dateRange 日期范围数组 + * @param {*} propName C#属性名首字母大写 + * @returns + */ +// 添加日期范围 +export function addDateRange(params, dateRange, propName) { + let search = params + search = typeof search === 'object' && search !== null && !Array.isArray(search) ? search : {} + dateRange = Array.isArray(dateRange) ? dateRange : [] + if (typeof propName === 'undefined') { + search['beginTime'] = dateRange[0] + search['endTime'] = dateRange[1] + } else { + search['begin' + propName] = dateRange[0] + search['end' + propName] = dateRange[1] + } + return search +} + +// 回显数据字典 +export function selectDictLabel(datas, value) { + if (value === undefined) { + return '' + } + var actions = [] + Object.keys(datas).some((key) => { + if (datas[key].dictValue == '' + value) { + actions.push(datas[key].dictLabel) + return true + } + }) + if (actions.length === 0) { + actions.push(value) + } + return actions.join('') +} + +// 回显数据字典(字符串数组) +export function selectDictLabels(datas, value, separator) { + if (value === undefined) { + return '' + } + var actions = [] + var currentSeparator = undefined === separator ? ',' : separator + var temp = value.split(currentSeparator) + Object.keys(value.split(currentSeparator)).some((val) => { + Object.keys(datas).some((key) => { + if (datas[key].value == '' + temp[val]) { + actions.push(datas[key].label + currentSeparator) + } + }) + }) + return actions.join('').substring(0, actions.join('').length - 1) +} +// 通用下载方法 +export function download(fileName) { + // window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true; + // window.open(baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true) + window.open(baseURL + fileName) +} + +// 字符串格式化(%s ) +export function sprintf(str) { + var args = arguments, + flag = true, + i = 1 + str = str.replace(/%s/g, function () { + var arg = args[i++] + if (typeof arg === 'undefined') { + flag = false + return '' + } + return arg + }) + return flag ? str : '' +} + +// 转换字符串,undefined,null等转化为"" +export function parseStrEmpty(str) { + if (!str || str == 'undefined' || str == 'null') { + return '' + } + return str +} + +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]) + } else { + source[p] = target[p] + } + } catch (e) { + source[p] = target[p] + } + } + return source +} + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export function handleTree(data, id, parentId, children) { + let config = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + } + + var childrenListMap = {} + var nodeIds = {} + var tree = [] + + for (let d of data) { + let parentId = d[config.parentId] + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = [] + } + nodeIds[d[config.id]] = d + childrenListMap[parentId].push(d) + } + + for (let d of data) { + let parentId = d[config.parentId] + if (nodeIds[parentId] == null) { + tree.push(d) + } + } + + for (let t of tree) { + adaptToChildrenList(t) + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]] + } + if (o[config.childrenList]) { + for (let c of o[config.childrenList]) { + adaptToChildrenList(c) + } + } + } + return tree +} + +/** + * 参数处理 + * @param {*} params 参数 + */ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName] + var part = encodeURIComponent(propName) + '=' + if (value !== null && typeof value !== 'undefined') { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && typeof value[key] !== 'undefined') { + let params = propName + '[' + key + ']' + var subPart = encodeURIComponent(params) + '=' + result += subPart + encodeURIComponent(value[key]) + '&' + } + } + } else { + result += part + encodeURIComponent(value) + '&' + } + } + } + return result +} + +// 返回项目路径 +export function getNormalPath(p) { + if (p.length === 0 || !p || p == 'undefined') { + return p + } + let res = p.replace('//', '/') + if (res[res.length - 1] === '/') { + return res.slice(0, res.length - 1) + } + return res +} + +// 验证是否为blob格式 +export async function blobValidate(data) { + try { + const text = await data.text() + JSON.parse(text) + return false + } catch (error) { + return true + } +} + +// 转换字符串,undefined,null等转化为"" +export function praseStrEmpty(str) { + if (!str || str == 'undefined' || str == 'null') { + return '' + } + return str +} +export function praseStrZero(str) { + if (!str || str == 'undefined' || str == 'null') { + console.log('zero') + return 0 + } + return str +} + +/** + * 字符串是否为空 + * @param {*} obj + * @returns + */ +export function isEmpty(obj) { + if (typeof obj == 'undefined' || obj == null || obj === '') { + return true + } else { + return false + } +} + +/** + * 查找对象的唯一键值对(比如id)去判断是否存在某个数据中 + * @param {*} arr 数组 + * @param {*} key 对象键值名 + * @param {*} val + * @returns + */ +export function findItem(arr, key, val) { + for (let i = 0; i < arr.length; i++) { + if (arr[i][key] == val) { + return i + } + } + return -1 +} + +export function color16() { + //十六进制颜色随机 + const r = Math.floor(Math.random() * 256) + const g = Math.floor(Math.random() * 256) + const b = Math.floor(Math.random() * 256) + const color = `#${r.toString(16)}${g.toString(16)}${b.toString(16)}` + return color +} diff --git a/src/utils/scroll-to.js b/src/utils/scroll-to.js new file mode 100644 index 0000000..c5d8e04 --- /dev/null +++ b/src/utils/scroll-to.js @@ -0,0 +1,58 @@ +Math.easeInOutQuad = function(t, b, c, d) { + t /= d / 2 + if (t < 1) { + return c / 2 * t * t + b + } + t-- + return -c / 2 * (t * (t - 2) - 1) + b +} + +// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts +var requestAnimFrame = (function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } +})() + +/** + * Because it's so fucking difficult to detect the scrolling element, just move them all + * @param {number} amount + */ +function move(amount) { + document.documentElement.scrollTop = amount + document.body.parentNode.scrollTop = amount + document.body.scrollTop = amount +} + +function position() { + return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop +} + +/** + * @param {number} to + * @param {number} duration + * @param {Function} callback + */ +export function scrollTo(to, duration, callback) { + const start = position() + const change = to - start + const increment = 20 + let currentTime = 0 + duration = (typeof (duration) === 'undefined') ? 500 : duration + var animateScroll = function() { + // increment the time + currentTime += increment + // find the value with the quadratic in-out easing function + var val = Math.easeInOutQuad(currentTime, start, change, duration) + // move the document.body + move(val) + // do the animation unless its over + if (currentTime < duration) { + requestAnimFrame(animateScroll) + } else { + if (callback && typeof (callback) === 'function') { + // the animation is done so lets callback + callback() + } + } + } + animateScroll() +} diff --git a/src/utils/signalR.js b/src/utils/signalR.js new file mode 100644 index 0000000..e4cbe60 --- /dev/null +++ b/src/utils/signalR.js @@ -0,0 +1,119 @@ +// 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio +import * as signalR from '@microsoft/signalr' +import { getToken } from '@/utils/auth' +import { ElNotification, ElMessage } from 'element-plus' +import useSocketStore from '@/store/modules/socket' +import { webNotify } from './index' +export default { + // signalR对象 + SR: {}, + // 失败连接重试次数 + failNum: 4, + baseUrl: '', + init(url) { + var socketUrl = window.location.origin + url + const connection = new signalR.HubConnectionBuilder() + .withUrl(socketUrl, { accessTokenFactory: () => getToken() }) + .withAutomaticReconnect() //自动重新连接 + .configureLogging(signalR.LogLevel.Warning) + .build() + this.SR = connection + // 断线重连 + connection.onclose(async () => { + console.log('断开连接了') + console.assert(connection.state === signalR.HubConnectionState.Disconnected) + // 建议用户重新刷新浏览器 + await this.start() + }) + + connection.onreconnected(() => { + ElMessage({ + message: '与服务器通讯已连接成功', + type: 'success', + duration: 2000 + }) + console.log('断线重新连接成功') + }) + + connection.onreconnecting(async () => { + console.log('断线重新连接中... ') + + await this.start() + }) + + this.receiveMsg(connection) + // 启动 + // this.start(); + }, + /** + * 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")}) + * @returns + */ + async start() { + try { + console.log('signalR-1', this.SR.state) + //使用async和await 或 promise的then 和catch 处理来自服务端的异常 + if (this.SR.state === signalR.HubConnectionState.Disconnected) { + await this.SR.start() + } + + console.log('signalR-2', this.SR.state) + return true + } catch (error) { + console.error(error) + this.failNum-- + // console.log(`失败重试剩余次数${that.failNum}`, error) + if (this.failNum > 0 && this.SR.state.Disconnected) { + setTimeout(async () => { + await this.start() + }, 5000) + } + return false + } + }, + // 接收消息处理 + receiveMsg(connection) { + connection.on('onlineNum', (data) => { + useSocketStore().setOnlineUserNum(data) + }) + // 接收欢迎语 + connection.on('welcome', (data) => { + ElNotification.info(data) + }) + // 接收后台手动推送消息 + connection.on('receiveNotice', (title, data) => { + ElNotification({ + type: 'info', + title: title, + message: data, + dangerouslyUseHTMLString: true, + duration: 0 + }) + webNotify({ title: title, body: data }) + }) + // 接收系统通知/公告 + connection.on('moreNotice', (data) => { + if (data.code == 200) { + useSocketStore().setNoticeList(data.data) + } + }) + + // 接收在线用户 + // connection.on('onlineUser', (data) => { + // useSocketStore().setOnlineUsers(data) + // }) + + // 接收聊天数据 + connection.on('receiveChat', (data) => { + const title = `来自${data.userName}的消息通知` + ElNotification({ + title: title, + message: data.message, + type: 'success', + duration: 0 + }) + + webNotify({ title: title, body: data.message }) + }) + } +} diff --git a/src/utils/validate.js b/src/utils/validate.js new file mode 100644 index 0000000..b667bc3 --- /dev/null +++ b/src/utils/validate.js @@ -0,0 +1,98 @@ +/** + * 判断url是否是http或https + * @param {string} path + * @returns {Boolean} + */ +export function isHttp(url) { + if (url) { + return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 + } + return false +} + +/** + * 判断path是否为外链 + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUsername(str) { + const valid_map = ['admin', 'editor'] + return valid_map.indexOf(str.trim()) >= 0 +} + +/** + * @param {string} url + * @returns {Boolean} + */ +export function validURL(url) { + const reg = + /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return reg.test(url) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + +/** + * @param {string} email + * @returns {Boolean} + */ +export function validEmail(email) { + const reg = + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + return reg.test(email) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function isString(str) { + if (typeof str === 'string' || str instanceof String) { + return true + } + return false +} + +/** + * @param {Array} arg + * @returns {Boolean} + */ +export function isArray(arg) { + if (typeof Array.isArray === 'undefined') { + return Object.prototype.toString.call(arg) === '[object Array]' + } + return Array.isArray(arg) +} diff --git a/src/utils/wartermark.js b/src/utils/wartermark.js new file mode 100644 index 0000000..5d97e2a --- /dev/null +++ b/src/utils/wartermark.js @@ -0,0 +1,62 @@ +export const getmark = () => { + const setWatermark = (str) => { + const id = "1.23452384164.123412416"; + + if (document.getElementById(id) !== null) { + document.body.removeChild(document.getElementById(id)); + } + + //创建一个画布 + const can = document.createElement("canvas"); + //设置画布的长宽 + can.width = 150; + can.height = 120; + + const cans = can.getContext("2d"); + //旋转角度 + cans.rotate((-15 * Math.PI) / 180); + cans.font = "18px Vedana"; + //设置填充绘画的颜色、渐变或者模式 + cans.fillStyle = "rgba(200, 200, 200, 0.40)"; + //设置文本内容的当前对齐方式 + cans.textAlign = "left"; + //设置在绘制文本时使用的当前文本基线 + // cans.textBaseline = "Middle"; + //在画布上绘制填色的文本(输出的文本,开始绘制文本的X坐标位置,开始绘制文本的Y坐标位置) + cans.fillText(str, can.width / 8, can.height / 2); + + const div = document.createElement("div"); + div.id = id; + div.style.pointerEvents = "none"; + div.style.top = "30px"; + div.style.left = "0px"; + div.style.position = "fixed"; + div.style.zIndex = "100000"; + div.style.width = document.documentElement.clientWidth + "px"; + div.style.height = document.documentElement.clientHeight + "px"; + div.style.background = + "url(" + can.toDataURL("image/png") + ") left top repeat"; + document.body.appendChild(div); + return id; + }; + + // 该方法只允许调用一次 + const watermark = (str) => { + let id = setWatermark(str); + setInterval(() => { + if (document.getElementById(id) === null) { + id = setWatermark(str); + } + }, 500); + window.onresize = () => { + setWatermark(str); + }; + }; + const removeWatermark = () => { + const id = "1.23452384164.123412416"; + if (document.getElementById(id) !== null) { + document.body.removeChild(document.getElementById(id)); + } + } + return { setWatermark, watermark, removeWatermark }; +}; \ No newline at end of file diff --git a/src/views/business/Project/ProjectFiless/components/AddDialog.vue b/src/views/business/Project/ProjectFiless/components/AddDialog.vue new file mode 100644 index 0000000..9a6a29c --- /dev/null +++ b/src/views/business/Project/ProjectFiless/components/AddDialog.vue @@ -0,0 +1,171 @@ + + + + \ No newline at end of file diff --git a/src/views/business/Project/ProjectFiless/components/DetailDialog.vue b/src/views/business/Project/ProjectFiless/components/DetailDialog.vue new file mode 100644 index 0000000..93935f9 --- /dev/null +++ b/src/views/business/Project/ProjectFiless/components/DetailDialog.vue @@ -0,0 +1,147 @@ + + + diff --git a/src/views/business/Project/ProjectFiless/components/EditDialog.vue b/src/views/business/Project/ProjectFiless/components/EditDialog.vue new file mode 100644 index 0000000..1d6f712 --- /dev/null +++ b/src/views/business/Project/ProjectFiless/components/EditDialog.vue @@ -0,0 +1,193 @@ + + + diff --git a/src/views/business/Project/ProjectFiless/index.vue b/src/views/business/Project/ProjectFiless/index.vue new file mode 100644 index 0000000..707bc21 --- /dev/null +++ b/src/views/business/Project/ProjectFiless/index.vue @@ -0,0 +1,272 @@ + + + diff --git a/src/views/business/Project/ProjectGroups/components/AddDialog.vue b/src/views/business/Project/ProjectGroups/components/AddDialog.vue new file mode 100644 index 0000000..8692575 --- /dev/null +++ b/src/views/business/Project/ProjectGroups/components/AddDialog.vue @@ -0,0 +1,127 @@ + + + + \ No newline at end of file diff --git a/src/views/business/Project/ProjectGroups/components/DetailDialog.vue b/src/views/business/Project/ProjectGroups/components/DetailDialog.vue new file mode 100644 index 0000000..7f8b28d --- /dev/null +++ b/src/views/business/Project/ProjectGroups/components/DetailDialog.vue @@ -0,0 +1,91 @@ + + + diff --git a/src/views/business/Project/ProjectGroups/components/EditDialog.vue b/src/views/business/Project/ProjectGroups/components/EditDialog.vue new file mode 100644 index 0000000..8965586 --- /dev/null +++ b/src/views/business/Project/ProjectGroups/components/EditDialog.vue @@ -0,0 +1,129 @@ + + + diff --git a/src/views/business/Project/ProjectGroups/components/UploadDialog.vue b/src/views/business/Project/ProjectGroups/components/UploadDialog.vue new file mode 100644 index 0000000..9756699 --- /dev/null +++ b/src/views/business/Project/ProjectGroups/components/UploadDialog.vue @@ -0,0 +1,116 @@ + + + + \ No newline at end of file diff --git a/src/views/business/Project/ProjectGroups/index.vue b/src/views/business/Project/ProjectGroups/index.vue new file mode 100644 index 0000000..14d0dac --- /dev/null +++ b/src/views/business/Project/ProjectGroups/index.vue @@ -0,0 +1,262 @@ + + + diff --git a/src/views/business/Project/Projects/components/AddDialog.vue b/src/views/business/Project/Projects/components/AddDialog.vue new file mode 100644 index 0000000..c688fb9 --- /dev/null +++ b/src/views/business/Project/Projects/components/AddDialog.vue @@ -0,0 +1,118 @@ + + + + \ No newline at end of file diff --git a/src/views/business/Project/Projects/components/DetailDialog.vue b/src/views/business/Project/Projects/components/DetailDialog.vue new file mode 100644 index 0000000..045b3a1 --- /dev/null +++ b/src/views/business/Project/Projects/components/DetailDialog.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/views/business/Project/Projects/components/EditDialog.vue b/src/views/business/Project/Projects/components/EditDialog.vue new file mode 100644 index 0000000..90cf994 --- /dev/null +++ b/src/views/business/Project/Projects/components/EditDialog.vue @@ -0,0 +1,138 @@ + + + diff --git a/src/views/business/Project/Projects/components/UploadDialog.vue b/src/views/business/Project/Projects/components/UploadDialog.vue new file mode 100644 index 0000000..f98f6f2 --- /dev/null +++ b/src/views/business/Project/Projects/components/UploadDialog.vue @@ -0,0 +1,116 @@ + + + + \ No newline at end of file diff --git a/src/views/business/Project/Projects/index.vue b/src/views/business/Project/Projects/index.vue new file mode 100644 index 0000000..0a37b8e --- /dev/null +++ b/src/views/business/Project/Projects/index.vue @@ -0,0 +1,233 @@ + + + diff --git a/src/views/business/ToolCustomers/components/AddDialog.vue b/src/views/business/ToolCustomers/components/AddDialog.vue new file mode 100644 index 0000000..80fb3e4 --- /dev/null +++ b/src/views/business/ToolCustomers/components/AddDialog.vue @@ -0,0 +1,107 @@ + + + + \ No newline at end of file diff --git a/src/views/business/ToolCustomers/components/DetailDialog.vue b/src/views/business/ToolCustomers/components/DetailDialog.vue new file mode 100644 index 0000000..0f8d8d9 --- /dev/null +++ b/src/views/business/ToolCustomers/components/DetailDialog.vue @@ -0,0 +1,83 @@ + + + diff --git a/src/views/business/ToolCustomers/components/EditDialog.vue b/src/views/business/ToolCustomers/components/EditDialog.vue new file mode 100644 index 0000000..b12ac03 --- /dev/null +++ b/src/views/business/ToolCustomers/components/EditDialog.vue @@ -0,0 +1,124 @@ + + + diff --git a/src/views/business/ToolCustomers/index.vue b/src/views/business/ToolCustomers/index.vue new file mode 100644 index 0000000..9bfee96 --- /dev/null +++ b/src/views/business/ToolCustomers/index.vue @@ -0,0 +1,216 @@ + + + diff --git a/src/views/business/customers/components/AddDialog.vue b/src/views/business/customers/components/AddDialog.vue new file mode 100644 index 0000000..09918f6 --- /dev/null +++ b/src/views/business/customers/components/AddDialog.vue @@ -0,0 +1,126 @@ + + + + \ No newline at end of file diff --git a/src/views/business/customers/components/DetailDialog.vue b/src/views/business/customers/components/DetailDialog.vue new file mode 100644 index 0000000..2149cc2 --- /dev/null +++ b/src/views/business/customers/components/DetailDialog.vue @@ -0,0 +1,112 @@ + + + diff --git a/src/views/business/customers/components/EditDialog.vue b/src/views/business/customers/components/EditDialog.vue new file mode 100644 index 0000000..7910cd1 --- /dev/null +++ b/src/views/business/customers/components/EditDialog.vue @@ -0,0 +1,145 @@ + + + diff --git a/src/views/business/customers/index.vue b/src/views/business/customers/index.vue new file mode 100644 index 0000000..792dde3 --- /dev/null +++ b/src/views/business/customers/index.vue @@ -0,0 +1,178 @@ + + + diff --git a/src/views/business/news/components/AddDialog.vue b/src/views/business/news/components/AddDialog.vue new file mode 100644 index 0000000..1aa2e2c --- /dev/null +++ b/src/views/business/news/components/AddDialog.vue @@ -0,0 +1,169 @@ + + + + \ No newline at end of file diff --git a/src/views/business/news/components/DetailDialog.vue b/src/views/business/news/components/DetailDialog.vue new file mode 100644 index 0000000..435e7db --- /dev/null +++ b/src/views/business/news/components/DetailDialog.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/views/business/news/components/EditDialog.vue b/src/views/business/news/components/EditDialog.vue new file mode 100644 index 0000000..ad29403 --- /dev/null +++ b/src/views/business/news/components/EditDialog.vue @@ -0,0 +1,191 @@ + + + diff --git a/src/views/business/news/components/UploadDialog.vue b/src/views/business/news/components/UploadDialog.vue new file mode 100644 index 0000000..ecc0f90 --- /dev/null +++ b/src/views/business/news/components/UploadDialog.vue @@ -0,0 +1,103 @@ + + + + \ No newline at end of file diff --git a/src/views/business/news/index.vue b/src/views/business/news/index.vue new file mode 100644 index 0000000..beb4934 --- /dev/null +++ b/src/views/business/news/index.vue @@ -0,0 +1,333 @@ + + + diff --git a/src/views/business/payments/components/AddDialog.vue b/src/views/business/payments/components/AddDialog.vue new file mode 100644 index 0000000..cecc29f --- /dev/null +++ b/src/views/business/payments/components/AddDialog.vue @@ -0,0 +1,144 @@ + + + + \ No newline at end of file diff --git a/src/views/business/payments/components/DetailDialog.vue b/src/views/business/payments/components/DetailDialog.vue new file mode 100644 index 0000000..f8c5cca --- /dev/null +++ b/src/views/business/payments/components/DetailDialog.vue @@ -0,0 +1,131 @@ + + + diff --git a/src/views/business/payments/components/EditDialog.vue b/src/views/business/payments/components/EditDialog.vue new file mode 100644 index 0000000..b71469c --- /dev/null +++ b/src/views/business/payments/components/EditDialog.vue @@ -0,0 +1,168 @@ + + + diff --git a/src/views/business/payments/index.vue b/src/views/business/payments/index.vue new file mode 100644 index 0000000..4e4eef5 --- /dev/null +++ b/src/views/business/payments/index.vue @@ -0,0 +1,171 @@ + + + diff --git a/src/views/business/testDemo/Test/TestPartss/components/AddDialog.vue b/src/views/business/testDemo/Test/TestPartss/components/AddDialog.vue new file mode 100644 index 0000000..2094b0a --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/components/AddDialog.vue @@ -0,0 +1,129 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/TestPartss/components/ChooseTestDialog.vue b/src/views/business/testDemo/Test/TestPartss/components/ChooseTestDialog.vue new file mode 100644 index 0000000..905a2aa --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/components/ChooseTestDialog.vue @@ -0,0 +1,115 @@ + + + + diff --git a/src/views/business/testDemo/Test/TestPartss/components/DetailDialog.vue b/src/views/business/testDemo/Test/TestPartss/components/DetailDialog.vue new file mode 100644 index 0000000..c2236a7 --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/components/DetailDialog.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/views/business/testDemo/Test/TestPartss/components/EditDialog.vue b/src/views/business/testDemo/Test/TestPartss/components/EditDialog.vue new file mode 100644 index 0000000..761c9a1 --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/components/EditDialog.vue @@ -0,0 +1,126 @@ + + + diff --git a/src/views/business/testDemo/Test/TestPartss/components/UploadDialog.vue b/src/views/business/testDemo/Test/TestPartss/components/UploadDialog.vue new file mode 100644 index 0000000..4dcb33a --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/components/UploadDialog.vue @@ -0,0 +1,116 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/TestPartss/index.vue b/src/views/business/testDemo/Test/TestPartss/index.vue new file mode 100644 index 0000000..6c1d1a8 --- /dev/null +++ b/src/views/business/testDemo/Test/TestPartss/index.vue @@ -0,0 +1,259 @@ + + + diff --git a/src/views/business/testDemo/Test/TestTypes/components/AddDialog.vue b/src/views/business/testDemo/Test/TestTypes/components/AddDialog.vue new file mode 100644 index 0000000..eeb9c88 --- /dev/null +++ b/src/views/business/testDemo/Test/TestTypes/components/AddDialog.vue @@ -0,0 +1,124 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/TestTypes/components/DetailDialog.vue b/src/views/business/testDemo/Test/TestTypes/components/DetailDialog.vue new file mode 100644 index 0000000..88955c7 --- /dev/null +++ b/src/views/business/testDemo/Test/TestTypes/components/DetailDialog.vue @@ -0,0 +1,85 @@ + + + diff --git a/src/views/business/testDemo/Test/TestTypes/components/EditDialog.vue b/src/views/business/testDemo/Test/TestTypes/components/EditDialog.vue new file mode 100644 index 0000000..1c252f6 --- /dev/null +++ b/src/views/business/testDemo/Test/TestTypes/components/EditDialog.vue @@ -0,0 +1,127 @@ + + + diff --git a/src/views/business/testDemo/Test/TestTypes/components/UploadDialog.vue b/src/views/business/testDemo/Test/TestTypes/components/UploadDialog.vue new file mode 100644 index 0000000..70b6200 --- /dev/null +++ b/src/views/business/testDemo/Test/TestTypes/components/UploadDialog.vue @@ -0,0 +1,103 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/TestTypes/index.vue b/src/views/business/testDemo/Test/TestTypes/index.vue new file mode 100644 index 0000000..a81f785 --- /dev/null +++ b/src/views/business/testDemo/Test/TestTypes/index.vue @@ -0,0 +1,257 @@ + + + diff --git a/src/views/business/testDemo/Test/Testds/components/AddDialog.vue b/src/views/business/testDemo/Test/Testds/components/AddDialog.vue new file mode 100644 index 0000000..4467ab4 --- /dev/null +++ b/src/views/business/testDemo/Test/Testds/components/AddDialog.vue @@ -0,0 +1,138 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/Testds/components/DetailDialog.vue b/src/views/business/testDemo/Test/Testds/components/DetailDialog.vue new file mode 100644 index 0000000..31c64ec --- /dev/null +++ b/src/views/business/testDemo/Test/Testds/components/DetailDialog.vue @@ -0,0 +1,102 @@ + + + diff --git a/src/views/business/testDemo/Test/Testds/components/EditDialog.vue b/src/views/business/testDemo/Test/Testds/components/EditDialog.vue new file mode 100644 index 0000000..03cace7 --- /dev/null +++ b/src/views/business/testDemo/Test/Testds/components/EditDialog.vue @@ -0,0 +1,147 @@ + + + diff --git a/src/views/business/testDemo/Test/Testds/components/UploadDialog.vue b/src/views/business/testDemo/Test/Testds/components/UploadDialog.vue new file mode 100644 index 0000000..9da42f6 --- /dev/null +++ b/src/views/business/testDemo/Test/Testds/components/UploadDialog.vue @@ -0,0 +1,116 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/Test/Testds/index.vue b/src/views/business/testDemo/Test/Testds/index.vue new file mode 100644 index 0000000..2118ed8 --- /dev/null +++ b/src/views/business/testDemo/Test/Testds/index.vue @@ -0,0 +1,286 @@ + + + diff --git a/src/views/business/testDemo/school/classes/components/AddDialog.vue b/src/views/business/testDemo/school/classes/components/AddDialog.vue new file mode 100644 index 0000000..18743bc --- /dev/null +++ b/src/views/business/testDemo/school/classes/components/AddDialog.vue @@ -0,0 +1,90 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/classes/components/DetailDialog.vue b/src/views/business/testDemo/school/classes/components/DetailDialog.vue new file mode 100644 index 0000000..ddeceb1 --- /dev/null +++ b/src/views/business/testDemo/school/classes/components/DetailDialog.vue @@ -0,0 +1,65 @@ + + + diff --git a/src/views/business/testDemo/school/classes/components/EditDialog.vue b/src/views/business/testDemo/school/classes/components/EditDialog.vue new file mode 100644 index 0000000..d84d4a0 --- /dev/null +++ b/src/views/business/testDemo/school/classes/components/EditDialog.vue @@ -0,0 +1,104 @@ + + + diff --git a/src/views/business/testDemo/school/classes/components/UploadDialog.vue b/src/views/business/testDemo/school/classes/components/UploadDialog.vue new file mode 100644 index 0000000..01a51d3 --- /dev/null +++ b/src/views/business/testDemo/school/classes/components/UploadDialog.vue @@ -0,0 +1,103 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/classes/index.vue b/src/views/business/testDemo/school/classes/index.vue new file mode 100644 index 0000000..90b50d5 --- /dev/null +++ b/src/views/business/testDemo/school/classes/index.vue @@ -0,0 +1,222 @@ + + + diff --git a/src/views/business/testDemo/school/key/components/AddDialog.vue b/src/views/business/testDemo/school/key/components/AddDialog.vue new file mode 100644 index 0000000..faab5a9 --- /dev/null +++ b/src/views/business/testDemo/school/key/components/AddDialog.vue @@ -0,0 +1,86 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/key/components/DetailDialog.vue b/src/views/business/testDemo/school/key/components/DetailDialog.vue new file mode 100644 index 0000000..8c95335 --- /dev/null +++ b/src/views/business/testDemo/school/key/components/DetailDialog.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/views/business/testDemo/school/key/components/EditDialog.vue b/src/views/business/testDemo/school/key/components/EditDialog.vue new file mode 100644 index 0000000..9f876f5 --- /dev/null +++ b/src/views/business/testDemo/school/key/components/EditDialog.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/views/business/testDemo/school/key/components/UploadDialog.vue b/src/views/business/testDemo/school/key/components/UploadDialog.vue new file mode 100644 index 0000000..2b9bffe --- /dev/null +++ b/src/views/business/testDemo/school/key/components/UploadDialog.vue @@ -0,0 +1,103 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/key/index.vue b/src/views/business/testDemo/school/key/index.vue new file mode 100644 index 0000000..dcf1c02 --- /dev/null +++ b/src/views/business/testDemo/school/key/index.vue @@ -0,0 +1,295 @@ + + + diff --git a/src/views/business/testDemo/school/student/components/AddDialog.vue b/src/views/business/testDemo/school/student/components/AddDialog.vue new file mode 100644 index 0000000..5a34886 --- /dev/null +++ b/src/views/business/testDemo/school/student/components/AddDialog.vue @@ -0,0 +1,336 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/student/components/DemoDialog.vue b/src/views/business/testDemo/school/student/components/DemoDialog.vue new file mode 100644 index 0000000..b205c50 --- /dev/null +++ b/src/views/business/testDemo/school/student/components/DemoDialog.vue @@ -0,0 +1,107 @@ + + + diff --git a/src/views/business/testDemo/school/student/components/DetailDialog.vue b/src/views/business/testDemo/school/student/components/DetailDialog.vue new file mode 100644 index 0000000..abc1671 --- /dev/null +++ b/src/views/business/testDemo/school/student/components/DetailDialog.vue @@ -0,0 +1,193 @@ + + + diff --git a/src/views/business/testDemo/school/student/components/EditDialog.vue b/src/views/business/testDemo/school/student/components/EditDialog.vue new file mode 100644 index 0000000..d020a31 --- /dev/null +++ b/src/views/business/testDemo/school/student/components/EditDialog.vue @@ -0,0 +1,363 @@ + + + diff --git a/src/views/business/testDemo/school/student/components/StudentServiceDialog.vue b/src/views/business/testDemo/school/student/components/StudentServiceDialog.vue new file mode 100644 index 0000000..959473e --- /dev/null +++ b/src/views/business/testDemo/school/student/components/StudentServiceDialog.vue @@ -0,0 +1,117 @@ + + + + diff --git a/src/views/business/testDemo/school/student/components/UploadDialog.vue b/src/views/business/testDemo/school/student/components/UploadDialog.vue new file mode 100644 index 0000000..0a7a73f --- /dev/null +++ b/src/views/business/testDemo/school/student/components/UploadDialog.vue @@ -0,0 +1,101 @@ + + + + \ No newline at end of file diff --git a/src/views/business/testDemo/school/student/index.vue b/src/views/business/testDemo/school/student/index.vue new file mode 100644 index 0000000..fada5ef --- /dev/null +++ b/src/views/business/testDemo/school/student/index.vue @@ -0,0 +1,342 @@ + + diff --git a/src/views/components/CommonMenu/index.vue b/src/views/components/CommonMenu/index.vue new file mode 100644 index 0000000..5aff0a6 --- /dev/null +++ b/src/views/components/CommonMenu/index.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/views/components/dictData.vue b/src/views/components/dictData.vue new file mode 100644 index 0000000..5246ff3 --- /dev/null +++ b/src/views/components/dictData.vue @@ -0,0 +1,354 @@ + + diff --git a/src/views/components/icons/index.vue b/src/views/components/icons/index.vue new file mode 100644 index 0000000..8a28fe1 --- /dev/null +++ b/src/views/components/icons/index.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/views/components/starBackground.vue b/src/views/components/starBackground.vue new file mode 100644 index 0000000..8456a24 --- /dev/null +++ b/src/views/components/starBackground.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/src/views/dashboard/BarChart.vue b/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..91335e0 --- /dev/null +++ b/src/views/dashboard/BarChart.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/views/dashboard/LineChart.vue b/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..5bbb456 --- /dev/null +++ b/src/views/dashboard/LineChart.vue @@ -0,0 +1,121 @@ + + + diff --git a/src/views/dashboard/PanelGroup.vue b/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..847ef74 --- /dev/null +++ b/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,218 @@ + + + + + diff --git a/src/views/dashboard/PieChart.vue b/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..b06bdf2 --- /dev/null +++ b/src/views/dashboard/PieChart.vue @@ -0,0 +1,60 @@ + + + diff --git a/src/views/dashboard/RaddarChart.vue b/src/views/dashboard/RaddarChart.vue new file mode 100644 index 0000000..1d9dd30 --- /dev/null +++ b/src/views/dashboard/RaddarChart.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/views/dashboard/WordCloud.vue b/src/views/dashboard/WordCloud.vue new file mode 100644 index 0000000..9b9bbb5 --- /dev/null +++ b/src/views/dashboard/WordCloud.vue @@ -0,0 +1,96 @@ + + + diff --git a/src/views/error/401.vue b/src/views/error/401.vue new file mode 100644 index 0000000..1ba3792 --- /dev/null +++ b/src/views/error/401.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/views/error/404.vue b/src/views/error/404.vue new file mode 100644 index 0000000..f205303 --- /dev/null +++ b/src/views/error/404.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/views/index.vue b/src/views/index.vue new file mode 100644 index 0000000..fd040bf --- /dev/null +++ b/src/views/index.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..9e61228 --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..b0e2744 --- /dev/null +++ b/src/views/monitor/cache/index.vue @@ -0,0 +1,195 @@ + + + diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue new file mode 100644 index 0000000..fab5cbd --- /dev/null +++ b/src/views/monitor/job/index.vue @@ -0,0 +1,660 @@ + + + diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue new file mode 100644 index 0000000..be63b78 --- /dev/null +++ b/src/views/monitor/job/log.vue @@ -0,0 +1,260 @@ + + + diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..dfaf2f8 --- /dev/null +++ b/src/views/monitor/logininfor/index.vue @@ -0,0 +1,186 @@ + + + diff --git a/src/views/monitor/onlineuser/index.vue b/src/views/monitor/onlineuser/index.vue new file mode 100644 index 0000000..9465ef4 --- /dev/null +++ b/src/views/monitor/onlineuser/index.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..aca155a --- /dev/null +++ b/src/views/monitor/operlog/index.vue @@ -0,0 +1,337 @@ + + + diff --git a/src/views/monitor/server/index.vue b/src/views/monitor/server/index.vue new file mode 100644 index 0000000..279f814 --- /dev/null +++ b/src/views/monitor/server/index.vue @@ -0,0 +1,299 @@ + + + + diff --git a/src/views/redirect/index.vue b/src/views/redirect/index.vue new file mode 100644 index 0000000..ff34a98 --- /dev/null +++ b/src/views/redirect/index.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/views/register.vue b/src/views/register.vue new file mode 100644 index 0000000..6029890 --- /dev/null +++ b/src/views/register.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/src/views/socialLogin.vue b/src/views/socialLogin.vue new file mode 100644 index 0000000..bc0b0e7 --- /dev/null +++ b/src/views/socialLogin.vue @@ -0,0 +1,65 @@ + + + diff --git a/src/views/system/commonLang/index.vue b/src/views/system/commonLang/index.vue new file mode 100644 index 0000000..08d9f1d --- /dev/null +++ b/src/views/system/commonLang/index.vue @@ -0,0 +1,418 @@ + + + + diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue new file mode 100644 index 0000000..81d193c --- /dev/null +++ b/src/views/system/config/index.vue @@ -0,0 +1,258 @@ + + + diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue new file mode 100644 index 0000000..60ddf02 --- /dev/null +++ b/src/views/system/dept/index.vue @@ -0,0 +1,289 @@ + + + diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue new file mode 100644 index 0000000..27cafa9 --- /dev/null +++ b/src/views/system/dict/index.vue @@ -0,0 +1,323 @@ + + + diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue new file mode 100644 index 0000000..0b9b1c2 --- /dev/null +++ b/src/views/system/menu/index.vue @@ -0,0 +1,566 @@ + + + diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue new file mode 100644 index 0000000..38bd0b1 --- /dev/null +++ b/src/views/system/notice/index.vue @@ -0,0 +1,250 @@ + + + diff --git a/src/views/system/oauth/thirdAccount.vue b/src/views/system/oauth/thirdAccount.vue new file mode 100644 index 0000000..78a0c80 --- /dev/null +++ b/src/views/system/oauth/thirdAccount.vue @@ -0,0 +1,358 @@ + + + + diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue new file mode 100644 index 0000000..8e106bf --- /dev/null +++ b/src/views/system/post/index.vue @@ -0,0 +1,251 @@ + + + diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue new file mode 100644 index 0000000..0c5047b --- /dev/null +++ b/src/views/system/role/index.vue @@ -0,0 +1,616 @@ + + + + diff --git a/src/views/system/roleusers/index.vue b/src/views/system/roleusers/index.vue new file mode 100644 index 0000000..dbac283 --- /dev/null +++ b/src/views/system/roleusers/index.vue @@ -0,0 +1,300 @@ + + diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..aa25851 --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,580 @@ + + + diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..e6ad942 --- /dev/null +++ b/src/views/system/user/profile/index.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/src/views/system/user/profile/operLog.vue b/src/views/system/user/profile/operLog.vue new file mode 100644 index 0000000..b1bcdaf --- /dev/null +++ b/src/views/system/user/profile/operLog.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..dcb6463 --- /dev/null +++ b/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,63 @@ + + + diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..148e1e0 --- /dev/null +++ b/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,200 @@ + + + + + diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..1625e6a --- /dev/null +++ b/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue new file mode 100644 index 0000000..d07effb --- /dev/null +++ b/src/views/tool/build/index.vue @@ -0,0 +1,15 @@ + + diff --git a/src/views/tool/email/sendEmail.vue b/src/views/tool/email/sendEmail.vue new file mode 100644 index 0000000..d3083ad --- /dev/null +++ b/src/views/tool/email/sendEmail.vue @@ -0,0 +1,133 @@ + + + diff --git a/src/views/tool/file/index.vue b/src/views/tool/file/index.vue new file mode 100644 index 0000000..2cd6eee --- /dev/null +++ b/src/views/tool/file/index.vue @@ -0,0 +1,418 @@ + + + diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..695e995 --- /dev/null +++ b/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,46 @@ + + diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..8575fac --- /dev/null +++ b/src/views/tool/gen/editTable.vue @@ -0,0 +1,300 @@ + + diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..52ed2b4 --- /dev/null +++ b/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,426 @@ + + + diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..7a5f4ef --- /dev/null +++ b/src/views/tool/gen/importTable.vue @@ -0,0 +1,112 @@ + + + diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue new file mode 100644 index 0000000..148ab7d --- /dev/null +++ b/src/views/tool/gen/index.vue @@ -0,0 +1,310 @@ + + + + diff --git a/src/views/tool/swagger/index.vue b/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..0e82527 --- /dev/null +++ b/src/views/tool/swagger/index.vue @@ -0,0 +1,30 @@ +