diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3454886 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..9c7da8a --- /dev/null +++ b/.env.development @@ -0,0 +1,15 @@ +ENV = 'development' + +# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http,wss 改为 ws +# 默认接口地址:SSO模块 +VUE_APP_BASE_API = 'http://localhost:28000' +VUE_APP_WS_API = 'ws://localhost:28000' + +# 扩展Base接口地址 +VUE_APP_DEVOPS_BASE_API = 'http://localhost:28000' + +# 扩展Ws接口地址 +VUE_APP_DEVOPS_WS_API = 'ws://localhost:28000' + +# 是否启用 babel-plugin-dynamic-import-node插件 +VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..3f0d6aa --- /dev/null +++ b/.env.production @@ -0,0 +1,12 @@ +ENV = 'production' + +# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http,wss 改为 ws +# 默认接口地址:SSO模块 +VUE_APP_BASE_API = 'https://kenaito-config-api.odboy.com' +VUE_APP_WS_API = 'wss://kenaito-config-api.odboy.com' + +# 扩展Base接口地址 +VUE_APP_DEVOPS_BASE_API = 'https://kenaito-config-api.odboy.com' + +# 扩展Ws接口地址 +VUE_APP_DEVOPS_WS_API = 'wss://kenaito-config-api.odboy.com' diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..74f996b --- /dev/null +++ b/.env.staging @@ -0,0 +1,14 @@ +ENV = 'staging' + +# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http,wss 改为 ws +# 默认接口地址:SSO模块 +VUE_APP_BASE_API = 'http://kenaito-config-api.odboy.com' +VUE_APP_WS_API = 'ws://kenaito-config-api.odboy.com' + +# 扩展Base接口地址 +VUE_APP_DEVOPS_BASE_API = 'http://kenaito-config-api.odboy.com' + +# 扩展Ws接口地址 +VUE_APP_DEVOPS_WS_API = 'ws://kenaito-config-api.odboy.com' + + diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e6529fc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +build/*.js +src/assets +public +dist diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..c977505 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,198 @@ +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..1978bc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +.DS_Store +node_modules/ +dist/ +demo/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f4be7a0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: 10 +script: npm run test +notifications: + email: false diff --git a/LICENSE b/LICENSE index 81489bb..58996ff 100644 --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,21 @@ MIT License -Copyright (c) 2024 odboy +Copyright (c) 2024 Odboy -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: +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 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. +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 index 67c2f22..9a0c3c0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,146 @@ # kenaito-config-front -配置中心前端 \ No newline at end of file +## 前端模板 + +初始模板基于: [https://github.com/PanJiaChen/vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) + +模板文档: [https://panjiachen.github.io/vue-element-admin-site/zh/guide/](https://panjiachen.github.io/vue-element-admin-site/zh/guide/) + +## 依赖组件 + +| 名称 | 功能 | 官网地址 | +|-----------------------|---------------------------------------------|--------------------------------------------------------------| +| sortable.js | js拖拽库 | https://sortablejs.github.io/Vue.Draggable/#/simple | +| vue-treeselect | 下拉树组件 | https://vue-treeselect.js.org/ | +| wangeditor/editor | 富文本编辑工具 | https://www.wangeditor.com/ | +| mavon-editor | 富文本编辑工具 | https://www.jianshu.com/p/fba836bf1499 | +| clipboard | 一键复制 | https://www.jianshu.com/p/0140e7b3f253 | +| vue-codemirror | 代码高亮编辑器 | https://codemirror.net/ | +| echarts | 数据可视化图表 | https://echarts.apache.org/zh/index.html | +| file-saver | 前端导出文件 | https://blog.csdn.net/xyphf/article/details/135146811 | +| fuse.js | 模糊搜索库 | https://www.jb51.net/javascript/313000abq.htm | +| jsencrypt | RSA加密和解密 | https://blog.csdn.net/randy521520/article/details/134346184 | +| jszip | zip压缩库 | https://www.jb51.net/javascript/3184036rq.htm | +| nprogress | 页面加载用进度条 | https://blog.csdn.net/qq_31968791/article/details/106790179 | +| qs | 增加了一些安全性的查询字符串解析和序列化字符串的库。可以进行对象与字符串之间的一个转换 | https://www.cnblogs.com/xinlightchaser/p/17721983.html | +| vue-count-to | 数字滚动插件 | https://www.cnblogs.com/duhui/p/10509585.html | +| vue-cropper | 图片裁剪 | https://www.cnblogs.com/dihongjingyan/p/16401862.html | +| vue-image-crop-upload | 头像裁剪上传 | https://www.cnblogs.com/luo1240465012/p/15398825.html | +| vue-splitpane | 可拖拽分割面板 | https://www.cnblogs.com/e0yu/p/10906900.html?ivk_sa=1024320u | +| vuedraggable | 拖拽插件 | https://www.jianshu.com/p/2164378fba35 | + +## Build Setup + +**推荐 node 版本:12-16** + +``` bash +# 安装依赖 +npm install --registry https://registry.npmmirror.com + +# 启动服务 localhost:28001 +npm run dev + +# (或) 启动服务 localhost:28001 +IDEA -> Current File -> Edit Configurations... -> Add New Configuration -> npm -> Script选dev -> Apply -> Ok + +# 构建生产环境 +npm run build:prod +``` + +## 默认密码 + +```text +admin/123456 +``` + +## 常见问题的解决方案 +- linux 系统在安装依赖的时候会出现 node-sass 无法安装的问题 + ``` + 1. 单独安装:npm install --unsafe-perm node-sass + 2. 直接使用:npm install --unsafe-perm + ``` + +## 如何增加子系统模块 +#### 新增子系统请求路径 +```shell +# .env.development +VUE_APP_{子系统编码}_BASE_API = 'http://localhost:服务端口号' +VUE_APP_{子系统编码}_WS_API = 'ws://localhost:服务端口号' + +# .env.staging +VUE_APP_{子系统编码}_BASE_API = 'http://localhost:服务端口号' +VUE_APP_{子系统编码}_WS_API = 'ws://localhost:服务端口号' + +# .env.production +VUE_APP_{子系统编码}_BASE_API = 'https://kenaito-api.odboy.cn' +VUE_APP_{子系统编码}_WS_API = 'wss://kenaito-api.odboy.cn' +``` +#### 新增代理配置 -> vue.config.js +```js +module.exports = { + devServer: { + proxy: { + '/kenaito-{子系统编码}/': { + target: process.env.VUE_APP_{子系统编码}_BASE_API, + changeOrigin: true, + pathRewrite: { + '^/kenaito-{子系统编码}': '/api/{子系统编码}' + } + }, + } + } +} +``` +#### 新增请求服务类 -> utils/request{子系统编码}.js +```js +const service = axios.create({ + // 关键修改点 baseURL + baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_{子系统编码}_BASE_API : '/', + timeout: Config.timeout +}) +``` +#### 前端Service -> api(写法1) +```shell +# 所在路径 +/src/api/{子系统编码}/{子模块编码}.js + +# 子模块.js -> 可参考 src/api/config/productLine.js 的 queryPage 方法 +import request from '@/utils/request{子系统编码}' +export function queryPage(data) { + return request({ + // 这里的 'kenaito-{子系统编码}' 参考上面的 '新增代理配置' + url: 'kenaito-{子系统编码}/{子模块编码}/queryPage', + method: 'post', + data: data + }) +} +``` + +#### 前端Service -> api(写法2) +```shell +# 所在路径 +/src/api/{子系统编码}/{子模块}.js + +# 子模块.js -> 可参考 src/api/config/productLine.js 的 getTree 方法 +import createService from '@/utils/requestMulti' +export function queryPage() { + const service = createService('{子系统编码}') + // 这里的 'kenaito-{子系统编码}' 参考上面的 '新增代理配置' + return service({ + url: 'kenaito-{子系统编码}/{子模块编码}/queryPage', + method: 'post' + }) +} +``` +#### 后端API请求路径 -> controller +```java +// 可参考后端 kenaito-config-service/src/main/java/cn/odboy/rest/AppController.java 中的 queryPage 方法 +@RestController +@RequestMapping("/api/{子系统编码}/{子模块编码}") +public class AppController { + @PostMapping("/querySomething") + public ResponseEntity querySomething(@RequestBody PageArgs args) { + return new ResponseEntity<>(null, HttpStatus.OK); + } +} +``` diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..804632a --- /dev/null +++ b/babel.config.js @@ -0,0 +1,11 @@ +const plugins = ['@vue/babel-plugin-transform-vue-jsx'] +// 生产环境移除console +if (process.env.NODE_ENV === 'production') { + plugins.push('transform-remove-console') +} +module.exports = { + plugins: plugins, + presets: [ + '@vue/app' + ] +} diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..60021f3 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,30 @@ +module.exports = { + moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], + transform: { + '^.+\\.vue$': 'vue-jest', + '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': + 'jest-transform-stub', + '^.+\\.jsx?$': 'babel-jest' + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + snapshotSerializers: ['jest-serializer-vue'], + testMatch: [ + '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' + ], + // 表示测试哪些代码 + collectCoverageFrom: [ + 'src/utils/**/*.{js,vue}', + '!src/utils/auth.js', + '!src/utils/request*.js', + 'src/components/**/*.{js,vue}' + ], + coverageDirectory: '/tests/unit/coverage', + // 'collectCoverage': true, + 'coverageReporters': [ + 'lcov', + 'text-summary' + ], + testURL: 'http://localhost/' +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..005f317 --- /dev/null +++ b/package.json @@ -0,0 +1,114 @@ +{ + "name": "kenaito-config-front", + "version": "1.0.0", + "description": "kenaito-config 前端源码", + "author": "Odboy", + "license": "Apache-2.0", + "scripts": { + "dev": "vue-cli-service serve", + "build:daily": "vue-cli-service build --mode development", + "build:stage": "vue-cli-service build --mode staging", + "build:prod": "vue-cli-service build --mode production", + "preview": "node build/index.js --preview", + "lint": "eslint --ext .js,.vue src", + "test:unit": "jest --clearCache && vue-cli-service test:unit", + "svgo": "svgo -f src/assets/icons/svg --config=src/assets/icons/svgo.yml", + "new": "plop" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "repository": { + "type": "git", + "url": "https://gitea.odboy.cn/odboy/kenaito-config-front.git" + }, + "dependencies": { + "@riophae/vue-treeselect": "^0.4.0", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-vue": "^1.0.2", + "axios": "^1.6.0", + "clipboard": "2.0.4", + "codemirror": "^5.49.2", + "core-js": "^2.6.12", + "echarts": "^4.2.1", + "echarts-wordcloud": "^1.1.3", + "element-ui": "^2.15.8", + "file-saver": "1.3.8", + "fuse.js": "3.4.4", + "js-beautify": "^1.10.2", + "js-cookie": "2.2.0", + "jsencrypt": "^3.0.0-rc.1", + "jszip": "^3.7.1", + "mavon-editor": "^2.9.1", + "normalize.css": "7.0.0", + "nprogress": "0.2.0", + "path-to-regexp": "2.4.0", + "qs": "^6.10.1", + "screenfull": "4.2.0", + "sortablejs": "1.8.4", + "vue": "^2.6.14", + "vue-clipboard2": "^0.3.3", + "vue-count-to": "^1.0.13", + "vue-cropper": "0.4.9", + "vue-echarts": "^5.0.0-beta.0", + "vue-image-crop-upload": "^2.5.0", + "vue-router": "3.0.2", + "vue-splitpane": "1.0.4", + "vuedraggable": "2.20.0", + "vuex": "3.1.0", + "wangeditor": "^4.7.11", + "webpack": "^4.46.0" + }, + "devDependencies": { + "@babel/parser": "^7.7.4", + "@babel/register": "7.0.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-eslint": "^3.9.1", + "@vue/cli-plugin-unit-jest": "3.5.3", + "@vue/cli-service": "3.5.3", + "@vue/test-utils": "1.0.0-beta.29", + "autoprefixer": "^9.5.1", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "10.0.1", + "babel-jest": "23.6.0", + "babel-plugin-dynamic-import-node": "2.3.0", + "babel-plugin-transform-remove-console": "^6.9.4", + "chalk": "2.4.2", + "chokidar": "2.1.5", + "compression-webpack-plugin": "5.0.2", + "connect": "3.6.6", + "eslint": "5.15.3", + "eslint-plugin-vue": "5.2.2", + "html-webpack-plugin": "3.2.0", + "http-proxy-middleware": "^0.19.1", + "husky": "1.3.1", + "lint-staged": "8.1.5", + "plop": "2.3.0", + "sass": "1.32.13", + "sass-loader": "10.2.0", + "script-ext-html-webpack-plugin": "2.1.3", + "script-loader": "0.7.2", + "serve-static": "^1.13.2", + "svg-sprite-loader": "4.1.3", + "svgo": "1.2.0", + "tasksfile": "^5.1.1", + "vue-template-compiler": "2.6.14" + }, + "engines": { + "node": ">=8.9", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} diff --git a/plopfile.js b/plopfile.js new file mode 100644 index 0000000..9f3147e --- /dev/null +++ b/plopfile.js @@ -0,0 +1,7 @@ +const viewGenerator = require('./plop-templates/view/prompt') +const componentGenerator = require('./plop-templates/component/prompt') + +module.exports = function(plop) { + plop.setGenerator('view', viewGenerator) + plop.setGenerator('component', componentGenerator) +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..961986e --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..fcb6999 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..e918500 --- /dev/null +++ b/public/index.html @@ -0,0 +1,15 @@ + + + + + + + + + <%= webpackConfig.name %> + + +
+ + + diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..cb237d2 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,12 @@ + + + + diff --git a/src/api/config/base/devopsUser.js b/src/api/config/base/devopsUser.js new file mode 100644 index 0000000..d269970 --- /dev/null +++ b/src/api/config/base/devopsUser.js @@ -0,0 +1,9 @@ +import request from '@/utils/requestDevops' + +export function queryList(data) { + return request({ + url: 'kenaito-config/user/pageList', + method: 'post', + data: data + }) +} diff --git a/src/api/data.js b/src/api/data.js new file mode 100644 index 0000000..0692765 --- /dev/null +++ b/src/api/data.js @@ -0,0 +1,17 @@ +import request from '@/utils/requestSso' +import qs from 'qs' + +export function initData(url, params) { + return request({ + url: url + '?' + qs.stringify(params, { indices: false }), + method: 'get' + }) +} + +export function download(url, params) { + return request({ + url: url + '?' + qs.stringify(params, { indices: false }), + method: 'get', + responseType: 'blob' + }) +} diff --git a/src/api/generator/genConfig.js b/src/api/generator/genConfig.js new file mode 100644 index 0000000..5146ebb --- /dev/null +++ b/src/api/generator/genConfig.js @@ -0,0 +1,16 @@ +import request from '@/utils/requestSso' + +export function get(tableName) { + return request({ + url: 'api/genConfig/' + tableName, + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/genConfig', + data, + method: 'put' + }) +} diff --git a/src/api/generator/generator.js b/src/api/generator/generator.js new file mode 100644 index 0000000..3d5ad36 --- /dev/null +++ b/src/api/generator/generator.js @@ -0,0 +1,26 @@ +import request from '@/utils/requestSso' + +export function generator(tableName, type) { + return request({ + url: 'api/generator/' + tableName + '/' + type, + method: 'post', + responseType: type === 2 ? 'blob' : '' + }) +} + +export function save(data) { + return request({ + url: 'api/generator', + data, + method: 'put' + }) +} + +export function sync(tables) { + return request({ + url: 'api/generator/sync', + method: 'post', + data: tables + }) +} + diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..dcdbc07 --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,35 @@ +import request from '@/utils/requestSso' + +export function login(username, password, code, uuid) { + return request({ + url: 'auth/login', + method: 'post', + data: { + username, + password, + code, + uuid + } + }) +} + +export function getInfo() { + return request({ + url: 'auth/info', + method: 'get' + }) +} + +export function getCodeImg() { + return request({ + url: 'auth/code', + method: 'get' + }) +} + +export function logout() { + return request({ + url: 'auth/logout', + method: 'delete' + }) +} diff --git a/src/api/monitor/online.js b/src/api/monitor/online.js new file mode 100644 index 0000000..f5402f7 --- /dev/null +++ b/src/api/monitor/online.js @@ -0,0 +1,9 @@ +import request from '@/utils/requestSso' + +export function del(keys) { + return request({ + url: 'auth/online', + method: 'delete', + data: keys + }) +} diff --git a/src/api/system/code.js b/src/api/system/code.js new file mode 100644 index 0000000..7f1b0e8 --- /dev/null +++ b/src/api/system/code.js @@ -0,0 +1,15 @@ +import request from '@/utils/requestSso' + +export function resetEmail(data) { + return request({ + url: 'api/code/resetEmail?email=' + data, + method: 'post' + }) +} + +export function updatePass(pass) { + return request({ + url: 'api/users/updatePass/' + pass, + method: 'get' + }) +} diff --git a/src/api/system/dept.js b/src/api/system/dept.js new file mode 100644 index 0000000..9cf5af6 --- /dev/null +++ b/src/api/system/dept.js @@ -0,0 +1,45 @@ +import request from '@/utils/requestSso' + +export function getDepts(params) { + return request({ + url: 'api/dept', + method: 'get', + params + }) +} + +export function getDeptSuperior(ids, exclude) { + exclude = exclude !== undefined ? exclude : false + const data = ids.length || ids.length === 0 ? ids : Array.of(ids) + return request({ + url: 'api/dept/superior?exclude=' + exclude, + method: 'post', + data + }) +} + +export function add(data) { + return request({ + url: 'api/dept', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/dept', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/dept', + method: 'put', + data + }) +} + +export default { add, edit, del, getDepts, getDeptSuperior } diff --git a/src/api/system/dict.js b/src/api/system/dict.js new file mode 100644 index 0000000..c49dc02 --- /dev/null +++ b/src/api/system/dict.js @@ -0,0 +1,34 @@ +import request from '@/utils/requestSso' + +export function getDicts() { + return request({ + url: 'api/dict/all', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/dict', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/dict/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/dict', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/src/api/system/dictDetail.js b/src/api/system/dictDetail.js new file mode 100644 index 0000000..b690d9d --- /dev/null +++ b/src/api/system/dictDetail.js @@ -0,0 +1,52 @@ +import request from '@/utils/requestSso' + +export function get(dictName) { + const params = { + dictName, + page: 0, + size: 9999 + } + return request({ + url: 'api/dictDetail', + method: 'get', + params + }) +} + +export function getDictMap(dictName) { + const params = { + dictName, + page: 0, + size: 9999 + } + return request({ + url: 'api/dictDetail/map', + method: 'get', + params + }) +} + +export function add(data) { + return request({ + url: 'api/dictDetail', + method: 'post', + data + }) +} + +export function del(id) { + return request({ + url: 'api/dictDetail/' + id, + method: 'delete' + }) +} + +export function edit(data) { + return request({ + url: 'api/dictDetail', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/src/api/system/job.js b/src/api/system/job.js new file mode 100644 index 0000000..fd85cd5 --- /dev/null +++ b/src/api/system/job.js @@ -0,0 +1,40 @@ +import request from '@/utils/requestSso' + +export function getAllJob() { + const params = { + page: 0, + size: 9999, + enabled: true + } + return request({ + url: 'api/job', + method: 'get', + params + }) +} + +export function add(data) { + return request({ + url: 'api/job', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/job', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/job', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/src/api/system/menu.js b/src/api/system/menu.js new file mode 100644 index 0000000..16e1b82 --- /dev/null +++ b/src/api/system/menu.js @@ -0,0 +1,65 @@ +import request from '@/utils/requestSso' + +export function getMenusTree(pid) { + return request({ + url: 'api/menus/lazy?pid=' + pid, + method: 'get' + }) +} + +export function getMenus(params) { + return request({ + url: 'api/menus', + method: 'get', + params + }) +} + +export function getMenuSuperior(ids) { + const data = Array.isArray(ids) || ids.length === 0 ? ids : Array.of(ids) + return request({ + url: 'api/menus/superior', + method: 'post', + data + }) +} + +export function getChild(id) { + return request({ + url: 'api/menus/child?id=' + id, + method: 'get' + }) +} + +export function buildMenus() { + return request({ + url: 'api/menus/build', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/menus', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/menus', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/menus', + method: 'put', + data + }) +} + +export default { add, edit, del, getMenusTree, getMenuSuperior, getMenus, getChild } diff --git a/src/api/system/role.js b/src/api/system/role.js new file mode 100644 index 0000000..0825ce5 --- /dev/null +++ b/src/api/system/role.js @@ -0,0 +1,57 @@ +import request from '@/utils/requestSso' + +// 获取所有的Role +export function getAll() { + return request({ + url: 'api/roles/all', + method: 'get' + }) +} + +export function add(data) { + return request({ + url: 'api/roles', + method: 'post', + data + }) +} + +export function get(id) { + return request({ + url: 'api/roles/' + id, + method: 'get' + }) +} + +export function getLevel() { + return request({ + url: 'api/roles/level', + method: 'get' + }) +} + +export function del(ids) { + return request({ + url: 'api/roles', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/roles', + method: 'put', + data + }) +} + +export function editMenu(data) { + return request({ + url: 'api/roles/menu', + method: 'put', + data + }) +} + +export default { add, edit, del, get, editMenu, getLevel } diff --git a/src/api/system/timing.js b/src/api/system/timing.js new file mode 100644 index 0000000..6ebe9d0 --- /dev/null +++ b/src/api/system/timing.js @@ -0,0 +1,48 @@ +import request from '@/utils/requestSso' + +export function add(data) { + return request({ + url: 'api/jobs', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/jobs', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/jobs', + method: 'put', + data + }) +} + +export function updateIsPause(id) { + return request({ + url: 'api/jobs/' + id, + method: 'put' + }) +} + +export function execution(id) { + return request({ + url: 'api/jobs/exec/' + id, + method: 'put' + }) +} + +export function queryModules() { + return request({ + url: 'api/jobs/modules', + method: 'get' + }) +} + +export default { del, updateIsPause, execution, add, edit, queryModules } diff --git a/src/api/system/user.js b/src/api/system/user.js new file mode 100644 index 0000000..7d0be37 --- /dev/null +++ b/src/api/system/user.js @@ -0,0 +1,69 @@ +import request from '@/utils/requestSso' +import { encrypt } from '@/utils/rsaEncrypt' + +export function add(data) { + return request({ + url: 'api/users', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/users', + method: 'delete', + data: ids + }) +} + +export function resetPwd(ids) { + return request({ + url: 'api/users/resetPwd', + method: 'put', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/users', + method: 'put', + data + }) +} + +export function editUser(data) { + return request({ + url: 'api/users/center', + method: 'put', + data + }) +} + +export function updatePass(user) { + const data = { + oldPass: encrypt(user.oldPass), + newPass: encrypt(user.newPass) + } + return request({ + url: 'api/users/updatePass/', + method: 'post', + data + }) +} + +export function updateEmail(form) { + const data = { + password: encrypt(form.pass), + email: form.email + } + return request({ + url: 'api/users/updateEmail/' + form.code, + method: 'post', + data + }) +} + +export default { add, edit, del, resetPwd } + diff --git a/src/api/tools/email.js b/src/api/tools/email.js new file mode 100644 index 0000000..40a5c08 --- /dev/null +++ b/src/api/tools/email.js @@ -0,0 +1,24 @@ +import request from '@/utils/requestSso' + +export function get() { + return request({ + url: 'api/email', + method: 'get' + }) +} + +export function update(data) { + return request({ + url: 'api/email', + data, + method: 'put' + }) +} + +export function send(data) { + return request({ + url: 'api/email', + data, + method: 'post' + }) +} diff --git a/src/api/tools/localStorage.js b/src/api/tools/localStorage.js new file mode 100644 index 0000000..3bb5155 --- /dev/null +++ b/src/api/tools/localStorage.js @@ -0,0 +1,27 @@ +import request from '@/utils/requestSso' + +export function add(data) { + return request({ + url: 'api/localStorage', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/localStorage/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/localStorage', + method: 'put', + data + }) +} + +export default { add, edit, del } diff --git a/src/api/tools/minioStorage.js b/src/api/tools/minioStorage.js new file mode 100644 index 0000000..7ca1040 --- /dev/null +++ b/src/api/tools/minioStorage.js @@ -0,0 +1,35 @@ +import request from '@/utils/requestSso' + +export function add(data) { + return request({ + url: 'api/minioStorage', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/minioStorage/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/minioStorage', + method: 'put', + data + }) +} + +export function downloadFile(id) { + return request({ + url: 'api/minioStorage/downloadFile', + method: 'post', + data: id + }) +} + +export default { add, edit, del, downloadFile } 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/icons/index.js b/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/src/assets/icons/index.js @@ -0,0 +1,9 @@ +import Vue from 'vue' +import SvgIcon from '@/components/SvgIcon'// svg component + +// register globally +Vue.component('svg-icon', SvgIcon) + +const req = require.context('./svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys().map(requireContext) +requireAll(req) diff --git a/src/assets/icons/svg/Steve-Jobs.svg b/src/assets/icons/svg/Steve-Jobs.svg new file mode 100644 index 0000000..53843e2 --- /dev/null +++ b/src/assets/icons/svg/Steve-Jobs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/alipay.svg b/src/assets/icons/svg/alipay.svg new file mode 100644 index 0000000..9138981 --- /dev/null +++ b/src/assets/icons/svg/alipay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/anq.svg b/src/assets/icons/svg/anq.svg new file mode 100644 index 0000000..a466608 --- /dev/null +++ b/src/assets/icons/svg/anq.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/app.svg b/src/assets/icons/svg/app.svg new file mode 100644 index 0000000..0796da3 --- /dev/null +++ b/src/assets/icons/svg/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/backup.svg b/src/assets/icons/svg/backup.svg new file mode 100644 index 0000000..a3272a4 --- /dev/null +++ b/src/assets/icons/svg/backup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/blog.svg b/src/assets/icons/svg/blog.svg new file mode 100644 index 0000000..a990eba --- /dev/null +++ b/src/assets/icons/svg/blog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/chain.svg b/src/assets/icons/svg/chain.svg new file mode 100644 index 0000000..ed3317f --- /dev/null +++ b/src/assets/icons/svg/chain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/chart.svg b/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/codeConsole.svg b/src/assets/icons/svg/codeConsole.svg new file mode 100644 index 0000000..672ec6e --- /dev/null +++ b/src/assets/icons/svg/codeConsole.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dashboard.svg b/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/database.svg b/src/assets/icons/svg/database.svg new file mode 100644 index 0000000..7fbad9b --- /dev/null +++ b/src/assets/icons/svg/database.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/date.svg b/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..0540e99 --- /dev/null +++ b/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/deploy.svg b/src/assets/icons/svg/deploy.svg new file mode 100644 index 0000000..f4a1c56 --- /dev/null +++ b/src/assets/icons/svg/deploy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dept.svg b/src/assets/icons/svg/dept.svg new file mode 100644 index 0000000..894e4bf --- /dev/null +++ b/src/assets/icons/svg/dept.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dev.svg b/src/assets/icons/svg/dev.svg new file mode 100644 index 0000000..ed4d23c --- /dev/null +++ b/src/assets/icons/svg/dev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/develop.svg b/src/assets/icons/svg/develop.svg new file mode 100644 index 0000000..e189223 --- /dev/null +++ b/src/assets/icons/svg/develop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dictionary.svg b/src/assets/icons/svg/dictionary.svg new file mode 100644 index 0000000..6e83c43 --- /dev/null +++ b/src/assets/icons/svg/dictionary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/doc.svg b/src/assets/icons/svg/doc.svg new file mode 100644 index 0000000..9160de8 --- /dev/null +++ b/src/assets/icons/svg/doc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/download.svg b/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..0243c6a --- /dev/null +++ b/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/edit.svg b/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/education.svg b/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/email.svg b/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..f1cf3ae --- /dev/null +++ b/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/error.svg b/src/assets/icons/svg/error.svg new file mode 100644 index 0000000..fd935da --- /dev/null +++ b/src/assets/icons/svg/error.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/fullscreen.svg b/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/fwb.svg b/src/assets/icons/svg/fwb.svg new file mode 100644 index 0000000..59933fc --- /dev/null +++ b/src/assets/icons/svg/fwb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/github.svg b/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..8145e95 --- /dev/null +++ b/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/gonggao.svg b/src/assets/icons/svg/gonggao.svg new file mode 100644 index 0000000..22aed08 --- /dev/null +++ b/src/assets/icons/svg/gonggao.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/icon.svg b/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82fbdd9 --- /dev/null +++ b/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/image.svg b/src/assets/icons/svg/image.svg new file mode 100644 index 0000000..16d572f --- /dev/null +++ b/src/assets/icons/svg/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/index.svg b/src/assets/icons/svg/index.svg new file mode 100644 index 0000000..fdb3826 --- /dev/null +++ b/src/assets/icons/svg/index.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/international.svg b/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/ipvisits.svg b/src/assets/icons/svg/ipvisits.svg new file mode 100644 index 0000000..4ca473d --- /dev/null +++ b/src/assets/icons/svg/ipvisits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/java.svg b/src/assets/icons/svg/java.svg new file mode 100644 index 0000000..e2effbb --- /dev/null +++ b/src/assets/icons/svg/java.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/link.svg b/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/list.svg b/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/lock.svg b/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..0f842ea --- /dev/null +++ b/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/log.svg b/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..4fefe74 --- /dev/null +++ b/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/login.svg b/src/assets/icons/svg/login.svg new file mode 100644 index 0000000..cc5a854 --- /dev/null +++ b/src/assets/icons/svg/login.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/markdown.svg b/src/assets/icons/svg/markdown.svg new file mode 100644 index 0000000..7cd6747 --- /dev/null +++ b/src/assets/icons/svg/markdown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/menu.svg b/src/assets/icons/svg/menu.svg new file mode 100644 index 0000000..e4360a0 --- /dev/null +++ b/src/assets/icons/svg/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/message.svg b/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/mnt.svg b/src/assets/icons/svg/mnt.svg new file mode 100644 index 0000000..936ce29 --- /dev/null +++ b/src/assets/icons/svg/mnt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/money.svg b/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/monitor.svg b/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..339370a --- /dev/null +++ b/src/assets/icons/svg/monitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nested.svg b/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/password.svg b/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..4ab451f --- /dev/null +++ b/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/people.svg b/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/peoples.svg b/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..2c91161 --- /dev/null +++ b/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/permission.svg b/src/assets/icons/svg/permission.svg new file mode 100644 index 0000000..c4c7409 --- /dev/null +++ b/src/assets/icons/svg/permission.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/phone.svg b/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..da339f9 --- /dev/null +++ b/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/qiniu.svg b/src/assets/icons/svg/qiniu.svg new file mode 100644 index 0000000..c2f9f8b --- /dev/null +++ b/src/assets/icons/svg/qiniu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/redis.svg b/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..bef111b --- /dev/null +++ b/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/role.svg b/src/assets/icons/svg/role.svg new file mode 100644 index 0000000..76cb18f --- /dev/null +++ b/src/assets/icons/svg/role.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/search.svg b/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/server.svg b/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..db6dcdf --- /dev/null +++ b/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/shopping.svg b/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/size.svg b/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/skill.svg b/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/source.svg b/src/assets/icons/svg/source.svg new file mode 100644 index 0000000..1c3a038 --- /dev/null +++ b/src/assets/icons/svg/source.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sqlMonitor.svg b/src/assets/icons/svg/sqlMonitor.svg new file mode 100644 index 0000000..950a430 --- /dev/null +++ b/src/assets/icons/svg/sqlMonitor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/swagger.svg b/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..ded7de8 --- /dev/null +++ b/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sys-tools.svg b/src/assets/icons/svg/sys-tools.svg new file mode 100644 index 0000000..8f9055e --- /dev/null +++ b/src/assets/icons/svg/sys-tools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/system.svg b/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..9333c60 --- /dev/null +++ b/src/assets/icons/svg/system.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/svg/system1.svg b/src/assets/icons/svg/system1.svg new file mode 100644 index 0000000..37b0a0a --- /dev/null +++ b/src/assets/icons/svg/system1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tab.svg b/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/theme.svg b/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/timing.svg b/src/assets/icons/svg/timing.svg new file mode 100644 index 0000000..f8fdc6d --- /dev/null +++ b/src/assets/icons/svg/timing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tools.svg b/src/assets/icons/svg/tools.svg new file mode 100644 index 0000000..aba1a40 --- /dev/null +++ b/src/assets/icons/svg/tools.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tree-table.svg b/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tree.svg b/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/unlock.svg b/src/assets/icons/svg/unlock.svg new file mode 100644 index 0000000..1219e41 --- /dev/null +++ b/src/assets/icons/svg/unlock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/user.svg b/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..09d7a81 --- /dev/null +++ b/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/user1.svg b/src/assets/icons/svg/user1.svg new file mode 100644 index 0000000..14ca51e --- /dev/null +++ b/src/assets/icons/svg/user1.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..a1feb74 --- /dev/null +++ b/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/visits.svg b/src/assets/icons/svg/visits.svg new file mode 100644 index 0000000..8425662 --- /dev/null +++ b/src/assets/icons/svg/visits.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/web.svg b/src/assets/icons/svg/web.svg new file mode 100644 index 0000000..9c57415 --- /dev/null +++ b/src/assets/icons/svg/web.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/wechat.svg b/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/weixin.svg b/src/assets/icons/svg/weixin.svg new file mode 100644 index 0000000..8dbcfa5 --- /dev/null +++ b/src/assets/icons/svg/weixin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/zujian.svg b/src/assets/icons/svg/zujian.svg new file mode 100644 index 0000000..2aba32f --- /dev/null +++ b/src/assets/icons/svg/zujian.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svgo.yml b/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/src/assets/icons/svgo.yml @@ -0,0 +1,22 @@ +# replace default config + +# multipass: true +# full: true + +plugins: + + # - name + # + # or: + # - name: false + # - name: true + # + # or: + # - name: + # param1: 1 + # param2: 2 + +- removeAttrs: + attrs: + - 'fill' + - 'fill-rule' diff --git a/src/assets/images/avatar.png b/src/assets/images/avatar.png new file mode 100644 index 0000000..b92fd39 Binary files /dev/null and b/src/assets/images/avatar.png differ diff --git a/src/assets/images/background.jpeg b/src/assets/images/background.jpeg new file mode 100644 index 0000000..cf6d023 Binary files /dev/null and b/src/assets/images/background.jpeg differ diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png new file mode 100644 index 0000000..c1b0a2e Binary files /dev/null and b/src/assets/images/logo.png differ diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..8f47f2c --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import 'variables'; + +@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/core.scss b/src/assets/styles/core.scss new file mode 100644 index 0000000..b9ae18d --- /dev/null +++ b/src/assets/styles/core.scss @@ -0,0 +1,117 @@ +.head-container { + padding-bottom: 10px; + .filter-item { + display: inline-block; + vertical-align: middle; + margin: 0 3px 10px 0; + input { + height: 30.5px; + line-height: 30.5px; + } + } + .el-form-item-label { + margin: 0 3px 9px 0; + display: inline-block; + text-align: right; + vertical-align: middle; + font-size: 14px; + color: #606266; + line-height: 30.5px; + padding: 0 7px 0 7px; + } + .el-button+.el-button { + margin-left: 0 !important; + } + .el-select__caret.el-input__icon.el-icon-arrow-up{ + line-height: 30.5px; + } + .date-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + height: 30.5px !important; + width: 230px !important; + } +} +.el-avatar { + display: inline-block; + text-align: center; + background: #ccc; + color: #fff; + white-space: nowrap; + position: relative; + overflow: hidden; + vertical-align: middle; + width: 32px; + height: 32px; + line-height: 32px; + border-radius: 16px; +} + +.logo-con{ + height: 60px; + padding: 13px 0 0; + img{ + height: 32px; + width: 135px; + display: block; + //margin: 0 auto; + } +} + +#el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #fff; + font-family: Arial, serif; + font-size: 12px; + letter-spacing: 1px; +} + +#el-main-footer { + background: none repeat scroll 0 0 white; + border-top: 1px solid #e7eaec; + overflow: hidden; + padding: 10px 6px 0 6px; + height: 33px; + font-size: 0.7rem !important; + color: #7a8b9a; + letter-spacing: 0.8px; + font-family: Arial, sans-serif !important; + position: fixed; + bottom: 0; + z-index: 99; + width: 100%; +} +.my-upload { + border: 1px dashed #c0ccda; + border-radius: 5px; + height: 45px; + line-height: 45px; + width: 368px; +} +.my-blockquote{ + margin: 0 0 10px; + padding: 15px; + line-height: 22px; + border-left: 5px solid #00437B; + border-radius: 0 2px 2px 0; + background-color: #f2f2f2; +} +.my-code{ + position: relative; + padding: 15px; + line-height: 20px; + border-left: 5px solid #ddd; + color: #333; + font-family: Courier New, serif; + font-size: 12px +} + +.el-tabs{ + margin-bottom: 25px; +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..8f7881c --- /dev/null +++ b/src/assets/styles/element-ui.scss @@ -0,0 +1,79 @@ +// cover some element-ui styles + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type="file"] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0; + } + } +} + +// to fixed https://github.com/ElemeFE/element/issues/2461 +.el-dialog { + transform: none; + left: 0; + position: relative; + margin: 0 auto; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} diff --git a/src/assets/styles/element-variables.scss b/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..a69f953 --- /dev/null +++ b/src/assets/styles/element-variables.scss @@ -0,0 +1,31 @@ +/** +* I think element-ui's default theme color is too light for long-term use. +* So I modified the default color and you can modify it to your liking. +**/ + +/* theme color */ +$--color-primary: rgba(24, 144, 255, 0.9); +$--color-success: rgba(19, 206, 102, 0.9); +$--color-warning: rgba(255, 186, 0, 0.9); +$--color-danger: rgba(255, 73, 73, 0.9); +$--color-info: rgba(30, 30, 30, 0.9); + +$--button-font-weight: 400; + +// $--color-text-regular: #1f2d3d; + +$--border-color-light: #dfe4ed; +$--border-color-lighter: #e6ebf5; + +$--table-border:1px solid#dfe6ec; + +/* icon font path, required */ +$--font-path: '~element-ui/lib/theme-chalk/fonts'; + +@import "../../../node_modules/element-ui/packages/theme-chalk/src/index"; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + theme: $--color-primary; +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss new file mode 100644 index 0000000..e36cd75 --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,182 @@ +@import 'variables'; +@import 'mixin'; +@import 'transition'; +@import 'element-ui'; +@import 'sidebar'; +@import 'btn'; +@import 'core'; + +body { + height: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; +} + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*: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; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container全局样式 +.app-container { + padding: 20px 20px 45px 20px; +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +.pagination-container { + margin-top: 30px; +} + +.text-center { + text-align: center +} + +.sub-navbar { + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + + .subtitle { + font-size: 20px; + color: #fff; + } + + &.draft { + background: #d0d0d0; + } + + &.deleted { + background: #d0d0d0; + } +} + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +//refine vue-multiselect plugin +.multiselect { + line-height: 16px; +} + +.multiselect--active { + z-index: 1000 !important; +} 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..17381fc --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,209 @@ +#app { + + .main-container { + min-height: 100%; + transition: margin-left .28s; + margin-left: $sideBarWidth; + position: relative; + } + + .sidebar-container { + transition: width 0.28s; + width: $sideBarWidth !important; + background-color: $menuBg; + height: 100%; + position: fixed; + font-size: 0; + top: 0; + bottom: 0; + left: 0; + z-index: 1001; + overflow: hidden; + + // reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .svg-icon { + margin-right: 16px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + // menu hover + .submenu-title-noDropdown, + .el-submenu__title { + &:hover { + background-color: $menuHover !important; + } + } + + .is-active>.el-submenu__title { + color: $subMenuActiveText !important; + } + + & .nest-menu .el-submenu>.el-submenu__title, + & .el-submenu .el-menu-item { + min-width: $sideBarWidth !important; + background-color: $subMenuBg !important; + + &:hover { + background-color: $subMenuHover !important; + } + } + } + + .hideSidebar { + .sidebar-container { + width: 54px !important; + } + + .main-container { + margin-left: 54px; + } + + .submenu-title-noDropdown { + padding: 0 !important; + position: relative; + + .el-tooltip { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + } + } + + .el-submenu { + overflow: hidden; + + &>.el-submenu__title { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + + .el-submenu__icon-arrow { + display: none; + } + } + } + + .el-menu--collapse { + .el-submenu { + &>.el-submenu__title { + &>span { + height: 0; + width: 0; + overflow: hidden; + visibility: hidden; + display: inline-block; + } + } + } + } + } + + .el-menu--collapse .el-menu .el-submenu { + min-width: $sideBarWidth !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0; + } + + .sidebar-container { + transition: transform .28s; + width: $sideBarWidth !important; + } + + &.hideSidebar { + .sidebar-container { + pointer-events: none; + transition-duration: 0.3s; + transform: translate3d(-$sideBarWidth, 0, 0); + } + } + } + + .withoutAnimation { + + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + &>.el-menu { + .svg-icon { + margin-right: 16px; + } + } + + .nest-menu .el-submenu>.el-submenu__title, + .el-menu-item { + &:hover { + // you can use $subMenuHover + background-color: $menuHover !important; + } + } + + // the scroll bar appears when the subMenu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } +} 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.scss b/src/assets/styles/variables.scss new file mode 100644 index 0000000..9dfed30 --- /dev/null +++ b/src/assets/styles/variables.scss @@ -0,0 +1,35 @@ +// base color +$blue:#324157; +$light-blue:#3A71A8; +$red:#C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow:#FEC171; +$panGreen: #30B08F; + +// sidebar +$menuText:#bfcbd9; +$menuActiveText:#409EFF; +$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 + +$menuBg:#304156; +$menuHover:#263445; + +$subMenuBg:#1f2d3d; +$subMenuHover:#001528; +// 左侧菜单宽度 +$sideBarWidth: 240px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuText: $menuText; + menuActiveText: $menuActiveText; + subMenuActiveText: $subMenuActiveText; + menuBg: $menuBg; + menuHover: $menuHover; + subMenuBg: $subMenuBg; + subMenuHover: $subMenuHover; + sideBarWidth: $sideBarWidth; +} diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..204ea59 --- /dev/null +++ b/src/components/Breadcrumb/index.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/src/components/Crud/CRUD.operation.vue b/src/components/Crud/CRUD.operation.vue new file mode 100644 index 0000000..33d2077 --- /dev/null +++ b/src/components/Crud/CRUD.operation.vue @@ -0,0 +1,268 @@ + + + + diff --git a/src/components/Crud/Pagination.vue b/src/components/Crud/Pagination.vue new file mode 100644 index 0000000..d4482fb --- /dev/null +++ b/src/components/Crud/Pagination.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/Crud/RR.operation.vue b/src/components/Crud/RR.operation.vue new file mode 100644 index 0000000..df2c138 --- /dev/null +++ b/src/components/Crud/RR.operation.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/Crud/UD.operation.vue b/src/components/Crud/UD.operation.vue new file mode 100644 index 0000000..3dbc833 --- /dev/null +++ b/src/components/Crud/UD.operation.vue @@ -0,0 +1,73 @@ + + diff --git a/src/components/Crud/crud.js b/src/components/Crud/crud.js new file mode 100644 index 0000000..e5f20f3 --- /dev/null +++ b/src/components/Crud/crud.js @@ -0,0 +1,865 @@ +import { initData, download } from '@/api/data' +import { parseTime, downloadFile } from '@/utils/index' +import Vue from 'vue' + +/** + * CRUD配置 + * @author moxun + * @param {*} options
+ * @return crud instance. + * @example + * 要使用多crud时,请在关联crud的组件处使用crud-tag进行标记,如: + */ +function CRUD(options) { + const defaultOptions = { + tag: 'default', + // id字段名 + idField: 'id', + // 标题 + title: '', + // 请求数据的url + url: '', + // 表格数据 + data: [], + // 选择项 + selections: [], + // 待查询的对象 + query: {}, + // 查询数据的参数 + params: {}, + // Form 表单 + form: {}, + // 重置表单 + defaultForm: () => {}, + // 等待时间 + time: 50, + // CRUD Method + crudMethod: { + add: (form) => {}, + del: (id) => {}, + edit: (form) => {}, + get: (id) => {} + }, + // 主页操作栏显示哪些按钮 + optShow: { + add: true, + edit: true, + del: true, + download: true, + reset: true + }, + // 自定义一些扩展属性 + props: {}, + // 在主页准备 + queryOnPresenterCreated: true, + // 调试开关 + debug: false + } + options = mergeOptions(defaultOptions, options) + const data = { + ...options, + // 记录数据状态 + dataStatus: {}, + status: { + add: CRUD.STATUS.NORMAL, + edit: CRUD.STATUS.NORMAL, + // 添加或编辑状态 + get cu() { + if (this.add === CRUD.STATUS.NORMAL && this.edit === CRUD.STATUS.NORMAL) { + return CRUD.STATUS.NORMAL + } else if (this.add === CRUD.STATUS.PREPARED || this.edit === CRUD.STATUS.PREPARED) { + return CRUD.STATUS.PREPARED + } else if (this.add === CRUD.STATUS.PROCESSING || this.edit === CRUD.STATUS.PROCESSING) { + return CRUD.STATUS.PROCESSING + } + throw new Error('wrong crud\'s cu status') + }, + // 标题 + get title() { + return this.add > CRUD.STATUS.NORMAL ? `新增${crud.title}` : this.edit > CRUD.STATUS.NORMAL ? `编辑${crud.title}` : crud.title + } + }, + msg: { + submit: '提交成功', + add: '新增成功', + edit: '编辑成功', + del: '删除成功' + }, + page: { + // 页码 + page: 1, + // 每页数据条数 + size: 10, + // 总数据条数 + total: 0 + }, + // 整体loading + loading: false, + // 导出的 Loading + downloadLoading: false, + // 删除的 Loading + delAllLoading: false + } + const methods = { + /** + * 通用的提示 + */ + submitSuccessNotify() { + crud.notify(crud.msg.submit, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + addSuccessNotify() { + crud.notify(crud.msg.add, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + editSuccessNotify() { + crud.notify(crud.msg.edit, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + delSuccessNotify() { + crud.notify(crud.msg.del, CRUD.NOTIFICATION_TYPE.SUCCESS) + }, + // 搜索 + toQuery() { + crud.page.page = 1 + crud.refresh() + }, + // 刷新 + refresh() { + if (!callVmHook(crud, CRUD.HOOK.beforeRefresh)) { + return + } + return new Promise((resolve, reject) => { + crud.loading = true + // 请求数据 + initData(crud.url, crud.getQueryParams()).then(data => { + const table = crud.getTable() + if (table && table.lazy) { // 懒加载子节点数据,清掉已加载的数据 + table.store.states.treeData = {} + table.store.states.lazyTreeNodeMap = {} + } + crud.page.total = data.totalElements + crud.data = data.content + crud.resetDataStatus() + // time 毫秒后显示表格 + setTimeout(() => { + crud.loading = false + callVmHook(crud, CRUD.HOOK.afterRefresh) + }, crud.time) + resolve(data) + }).catch(err => { + crud.loading = false + reject(err) + }) + }) + }, + /** + * 启动添加 + */ + toAdd() { + crud.resetForm() + if (!(callVmHook(crud, CRUD.HOOK.beforeToAdd, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) { + return + } + crud.status.add = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterToAdd, crud.form) + callVmHook(crud, CRUD.HOOK.afterToCU, crud.form) + }, + /** + * 启动编辑 + * @param {*} data 数据项 + */ + toEdit(data) { + crud.resetForm(JSON.parse(JSON.stringify(data))) + if (!(callVmHook(crud, CRUD.HOOK.beforeToEdit, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) { + return + } + crud.status.edit = CRUD.STATUS.PREPARED + crud.getDataStatus(crud.getDataId(data)).edit = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterToEdit, crud.form) + callVmHook(crud, CRUD.HOOK.afterToCU, crud.form) + }, + /** + * 启动删除 + * @param {*} data 数据项 + */ + toDelete(data) { + crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.PREPARED + }, + /** + * 取消删除 + * @param {*} data 数据项 + */ + cancelDelete(data) { + if (!callVmHook(crud, CRUD.HOOK.beforeDeleteCancel, data)) { + return + } + crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.NORMAL + callVmHook(crud, CRUD.HOOK.afterDeleteCancel, data) + }, + /** + * 取消新增/编辑 + */ + cancelCU() { + const addStatus = crud.status.add + const editStatus = crud.status.edit + if (addStatus === CRUD.STATUS.PREPARED) { + if (!callVmHook(crud, CRUD.HOOK.beforeAddCancel, crud.form)) { + return + } + crud.status.add = CRUD.STATUS.NORMAL + } + if (editStatus === CRUD.STATUS.PREPARED) { + if (!callVmHook(crud, CRUD.HOOK.beforeEditCancel, crud.form)) { + return + } + crud.status.edit = CRUD.STATUS.NORMAL + crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL + } + crud.resetForm() + if (addStatus === CRUD.STATUS.PREPARED) { + callVmHook(crud, CRUD.HOOK.afterAddCancel, crud.form) + } + if (editStatus === CRUD.STATUS.PREPARED) { + callVmHook(crud, CRUD.HOOK.afterEditCancel, crud.form) + } + // 清除表单验证 + if (crud.findVM('form').$refs['form']) { + crud.findVM('form').$refs['form'].clearValidate() + } + }, + /** + * 提交新增/编辑 + */ + submitCU() { + if (!callVmHook(crud, CRUD.HOOK.beforeValidateCU)) { + return + } + crud.findVM('form').$refs['form'].validate(valid => { + if (!valid) { + return + } + if (!callVmHook(crud, CRUD.HOOK.afterValidateCU)) { + return + } + if (crud.status.add === CRUD.STATUS.PREPARED) { + crud.doAdd() + } else if (crud.status.edit === CRUD.STATUS.PREPARED) { + crud.doEdit() + } + }) + }, + /** + * 执行添加 + */ + doAdd() { + if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) { + return + } + crud.status.add = CRUD.STATUS.PROCESSING + crud.crudMethod.add(crud.form).then(() => { + crud.status.add = CRUD.STATUS.NORMAL + crud.resetForm() + crud.addSuccessNotify() + callVmHook(crud, CRUD.HOOK.afterSubmit) + crud.toQuery() + }).catch(() => { + crud.status.add = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterAddError) + }) + }, + /** + * 执行编辑 + */ + doEdit() { + if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) { + return + } + crud.status.edit = CRUD.STATUS.PROCESSING + crud.crudMethod.edit(crud.form).then(() => { + crud.status.edit = CRUD.STATUS.NORMAL + crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL + crud.editSuccessNotify() + crud.resetForm() + callVmHook(crud, CRUD.HOOK.afterSubmit) + crud.refresh() + }).catch(() => { + crud.status.edit = CRUD.STATUS.PREPARED + callVmHook(crud, CRUD.HOOK.afterEditError) + }) + }, + /** + * 执行删除 + * @param {*} data 数据项 + */ + doDelete(data) { + let delAll = false + let dataStatus + const ids = [] + if (data instanceof Array) { + delAll = true + data.forEach(val => { + ids.push(this.getDataId(val)) + }) + } else { + ids.push(this.getDataId(data)) + dataStatus = crud.getDataStatus(this.getDataId(data)) + } + if (!callVmHook(crud, CRUD.HOOK.beforeDelete, data)) { + return + } + if (!delAll) { + dataStatus.delete = CRUD.STATUS.PROCESSING + } + return crud.crudMethod.del(ids).then(() => { + if (delAll) { + crud.delAllLoading = false + } else dataStatus.delete = CRUD.STATUS.PREPARED + crud.dleChangePage(1) + crud.delSuccessNotify() + callVmHook(crud, CRUD.HOOK.afterDelete, data) + crud.refresh() + }).catch(() => { + if (delAll) { + crud.delAllLoading = false + } else dataStatus.delete = CRUD.STATUS.PREPARED + }) + }, + /** + * 通用导出 + */ + doExport() { + crud.downloadLoading = true + download(crud.url + '/download', crud.getQueryParams()).then(result => { + downloadFile(result, crud.title + '数据', 'xlsx') + crud.downloadLoading = false + }).catch(() => { + crud.downloadLoading = false + }) + }, + /** + * 获取查询参数 + */ + getQueryParams: function() { + // 清除参数无值的情况 + Object.keys(crud.query).length !== 0 && Object.keys(crud.query).forEach(item => { + if (crud.query[item] === null || crud.query[item] === '') crud.query[item] = undefined + }) + Object.keys(crud.params).length !== 0 && Object.keys(crud.params).forEach(item => { + if (crud.params[item] === null || crud.params[item] === '') crud.params[item] = undefined + }) + return { + current: crud.page.page, + size: crud.page.size, + ...crud.query, + ...crud.params + } + }, + // 当前页改变 + pageChangeHandler(e) { + crud.page.page = e + crud.refresh() + }, + // 每页条数改变 + sizeChangeHandler(e) { + crud.page.size = e + crud.page.page = 1 + crud.refresh() + }, + // 预防删除第二页最后一条数据时,或者多选删除第二页的数据时,页码错误导致请求无数据 + dleChangePage(size) { + if (crud.data.length === size && crud.page.page !== 1) { + crud.page.page -= 1 + } + }, + // 选择改变 + selectionChangeHandler(val) { + crud.selections = val + }, + /** + * 重置查询参数 + * @param {Boolean} toQuery 重置后进行查询操作 + */ + resetQuery(toQuery = true) { + const defaultQuery = JSON.parse(JSON.stringify(crud.defaultQuery)) + const query = crud.query + Object.keys(query).forEach(key => { + query[key] = defaultQuery[key] + }) + // 重置参数 + this.params = {} + if (toQuery) { + crud.toQuery() + } + }, + /** + * 重置表单 + * @param {Array} data 数据 + */ + resetForm(data) { + delete crud.form['createTime'] + delete crud.form['updateTime'] + delete crud.form['createBy'] + delete crud.form['updateBy'] + const form = data || (typeof crud.defaultForm === 'object' ? JSON.parse(JSON.stringify(crud.defaultForm)) : crud.defaultForm.apply(crud.findVM('form'))) + const crudFrom = crud.form + for (const key in form) { + if (crudFrom.hasOwnProperty(key)) { + crudFrom[key] = form[key] + } else { + Vue.set(crudFrom, key, form[key]) + } + } + // add by ghl 2020-10-04 页面重复添加信息时,下拉框的校验会存在,需要找工取消 + if (crud.findVM('form').$refs['form']) { + crud.findVM('form').$refs['form'].clearValidate() + } + }, + /** + * 重置数据状态 + */ + resetDataStatus() { + const dataStatus = {} + function resetStatus(datas) { + datas.forEach(e => { + dataStatus[crud.getDataId(e)] = { + delete: 0, + edit: 0 + } + if (e.children) { + resetStatus(e.children) + } + }) + } + resetStatus(crud.data) + crud.dataStatus = dataStatus + }, + /** + * 获取数据状态 + * @param {Number | String} id 数据项id + */ + getDataStatus(id) { + return crud.dataStatus[id] + }, + /** + * 用于树形表格多选, 选中所有 + * @param selection + */ + selectAllChange(selection) { + // 如果选中的数目与请求到的数目相同就选中子节点,否则就清空选中 + if (selection && selection.length === crud.data.length) { + selection.forEach(val => { + crud.selectChange(selection, val) + }) + } else { + crud.getTable().clearSelection() + } + }, + /** + * 用于树形表格多选,单选的封装 + * @param selection + * @param row + */ + selectChange(selection, row) { + // 如果selection中存在row代表是选中,否则是取消选中 + if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) { + if (row.children) { + row.children.forEach(val => { + crud.getTable().toggleRowSelection(val, true) + selection.push(val) + if (val.children) { + crud.selectChange(selection, val) + } + }) + } + } else { + crud.toggleRowSelection(selection, row) + } + }, + /** + * 切换选中状态 + * @param selection + * @param data + */ + toggleRowSelection(selection, data) { + if (data.children) { + data.children.forEach(val => { + selection.splice(selection.findIndex(item => this.getDataId(item) === this.getDataId(val)), 1) + crud.getTable().toggleRowSelection(val, false) + if (val.children) { + crud.toggleRowSelection(selection, val) + } + }) + } + }, + findVM(type) { + return crud.vms.find(vm => vm && vm.type === type).vm + }, + notify(title, type = CRUD.NOTIFICATION_TYPE.INFO) { + crud.vms[0].vm.$notify({ + title, + type, + duration: 2500 + }) + }, + updateProp(name, value) { + Vue.set(crud.props, name, value) + }, + getDataId(data) { + return data[this.idField] + }, + getTable() { + return this.findVM('presenter').$refs.table + }, + attchTable() { + const table = this.getTable() + this.updateProp('table', table) + const that = this + table.$on('expand-change', (row, expanded) => { + if (!expanded) { + return + } + const lazyTreeNodeMap = table.store.states.lazyTreeNodeMap + row.children = lazyTreeNodeMap[crud.getDataId(row)] + if (row.children) { + row.children.forEach(ele => { + const id = crud.getDataId(ele) + if (that.dataStatus[id] === undefined) { + that.dataStatus[id] = { + delete: 0, + edit: 0 + } + } + }) + } + }) + } + } + const crud = Object.assign({}, data) + // 可观测化 + Vue.observable(crud) + // 附加方法 + Object.assign(crud, methods) + // 记录初始默认的查询参数,后续重置查询时使用 + Object.assign(crud, { + defaultQuery: JSON.parse(JSON.stringify(data.query)), + // 预留4位存储:组件 主页、头部、分页、表单,调试查看也方便找 + vms: Array(4), + /** + * 注册组件实例 + * @param {String} type 类型 + * @param {*} vm 组件实例 + * @param {Number} index 该参数内部使用 + */ + registerVM(type, vm, index = -1) { + const vmObj = { + type, + vm: vm + } + if (index < 0) { + this.vms.push(vmObj) + return + } + if (index < 4) { // 内置预留vm数 + this.vms[index] = vmObj + return + } + this.vms.length = Math.max(this.vms.length, index) + this.vms.splice(index, 1, vmObj) + }, + /** + * 取消注册组件实例 + * @param {*} vm 组件实例 + */ + unregisterVM(type, vm) { + for (let i = this.vms.length - 1; i >= 0; i--) { + if (this.vms[i] === undefined) { + continue + } + if (this.vms[i].type === type && this.vms[i].vm === vm) { + if (i < 4) { // 内置预留vm数 + this.vms[i] = undefined + } else { + this.vms.splice(i, 1) + } + break + } + } + } + }) + // 冻结处理,需要扩展数据的话,使用crud.updateProp(name, value),以crud.props.name形式访问,这个是响应式的,可以做数据绑定 + Object.freeze(crud) + return crud +} + +// hook VM +function callVmHook(crud, hook) { + if (crud.debug) { + console.log('callVmHook: ' + hook) + } + const tagHook = crud.tag ? hook + '$' + crud.tag : null + let ret = true + const nargs = [crud] + for (let i = 2; i < arguments.length; ++i) { + nargs.push(arguments[i]) + } + // 有些组件扮演了多个角色,调用钩子时,需要去重 + const vmSet = new Set() + crud.vms.forEach(vm => vm && vmSet.add(vm.vm)) + vmSet.forEach(vm => { + if (vm[hook]) { + ret = vm[hook].apply(vm, nargs) !== false && ret + } + if (tagHook && vm[tagHook]) { + ret = vm[tagHook].apply(vm, nargs) !== false && ret + } + }) + return ret +} + +function mergeOptions(src, opts) { + const optsRet = { + ...src + } + for (const key in src) { + if (opts.hasOwnProperty(key)) { + optsRet[key] = opts[key] + } + } + return optsRet +} + +/** + * 查找crud + * @param {*} vm + * @param {string} tag + */ +function lookupCrud(vm, tag) { + tag = tag || vm.$attrs['crud-tag'] || 'default' + // function lookupCrud(vm, tag) { + if (vm.$crud) { + const ret = vm.$crud[tag] + if (ret) { + return ret + } + } + return vm.$parent ? lookupCrud(vm.$parent, tag) : undefined +} + +/** + * crud主页 + */ +function presenter(crud) { + if (crud) { + console.warn('[CRUD warn]: ' + 'please use $options.cruds() { return CRUD(...) or [CRUD(...), ...] }') + } + return { + data() { + // 在data中返回crud,是为了将crud与当前实例关联,组件观测crud相关属性变化 + return { + crud: this.crud + } + }, + beforeCreate() { + this.$crud = this.$crud || {} + let cruds = this.$options.cruds instanceof Function ? this.$options.cruds() : crud + if (!(cruds instanceof Array)) { + cruds = [cruds] + } + cruds.forEach(ele => { + if (this.$crud[ele.tag]) { + console.error('[CRUD error]: ' + 'crud with tag [' + ele.tag + ' is already exist') + } + this.$crud[ele.tag] = ele + ele.registerVM('presenter', this, 0) + }) + this.crud = this.$crud['defalut'] || cruds[0] + }, + methods: { + parseTime + }, + created() { + for (const k in this.$crud) { + if (this.$crud[k].queryOnPresenterCreated) { + this.$crud[k].toQuery() + } + } + }, + destroyed() { + for (const k in this.$crud) { + this.$crud[k].unregisterVM('presenter', this) + } + }, + mounted() { + // 如果table未实例化(例如使用了v-if),请稍后在适当时机crud.attchTable刷新table信息 + if (this.$refs.table !== undefined) { + this.crud.attchTable() + } + } + } +} + +/** + * 头部 + */ +function header() { + return { + data() { + return { + crud: this.crud, + query: this.crud.query + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('header', this, 1) + }, + destroyed() { + this.crud.unregisterVM('header', this) + } + } +} + +/** + * 分页 + */ +function pagination() { + return { + data() { + return { + crud: this.crud, + page: this.crud.page + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('pagination', this, 2) + }, + destroyed() { + this.crud.unregisterVM('pagination', this) + } + } +} + +/** + * 表单 + */ +function form(defaultForm) { + return { + data() { + return { + crud: this.crud, + form: this.crud.form + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM('form', this, 3) + }, + created() { + this.crud.defaultForm = defaultForm + this.crud.resetForm() + }, + destroyed() { + this.crud.unregisterVM('form', this) + } + } +} + +/** + * crud + */ +function crud(options = {}) { + const defaultOptions = { + type: undefined + } + options = mergeOptions(defaultOptions, options) + return { + data() { + return { + crud: this.crud + } + }, + beforeCreate() { + this.crud = lookupCrud(this) + this.crud.registerVM(options.type, this) + }, + destroyed() { + this.crud.unregisterVM(options.type, this) + } + } +} + +/** + * CRUD钩子 + */ +CRUD.HOOK = { + /** 刷新 - 之前 */ + beforeRefresh: 'beforeCrudRefresh', + /** 刷新 - 之后 */ + afterRefresh: 'afterCrudRefresh', + /** 删除 - 之前 */ + beforeDelete: 'beforeCrudDelete', + /** 删除 - 之后 */ + afterDelete: 'afterCrudDelete', + /** 删除取消 - 之前 */ + beforeDeleteCancel: 'beforeCrudDeleteCancel', + /** 删除取消 - 之后 */ + afterDeleteCancel: 'afterCrudDeleteCancel', + /** 新建 - 之前 */ + beforeToAdd: 'beforeCrudToAdd', + /** 新建 - 之后 */ + afterToAdd: 'afterCrudToAdd', + /** 编辑 - 之前 */ + beforeToEdit: 'beforeCrudToEdit', + /** 编辑 - 之后 */ + afterToEdit: 'afterCrudToEdit', + /** 开始 "新建/编辑" - 之前 */ + beforeToCU: 'beforeCrudToCU', + /** 开始 "新建/编辑" - 之后 */ + afterToCU: 'afterCrudToCU', + /** "新建/编辑" 验证 - 之前 */ + beforeValidateCU: 'beforeCrudValidateCU', + /** "新建/编辑" 验证 - 之后 */ + afterValidateCU: 'afterCrudValidateCU', + /** 添加取消 - 之前 */ + beforeAddCancel: 'beforeCrudAddCancel', + /** 添加取消 - 之后 */ + afterAddCancel: 'afterCrudAddCancel', + /** 编辑取消 - 之前 */ + beforeEditCancel: 'beforeCrudEditCancel', + /** 编辑取消 - 之后 */ + afterEditCancel: 'afterCrudEditCancel', + /** 提交 - 之前 */ + beforeSubmit: 'beforeCrudSubmitCU', + /** 提交 - 之后 */ + afterSubmit: 'afterCrudSubmitCU', + afterAddError: 'afterCrudAddError', + afterEditError: 'afterCrudEditError' +} + +/** + * CRUD状态 + */ +CRUD.STATUS = { + NORMAL: 0, + PREPARED: 1, + PROCESSING: 2 +} + +/** + * CRUD通知类型 + */ +CRUD.NOTIFICATION_TYPE = { + SUCCESS: 'success', + WARNING: 'warning', + INFO: 'info', + ERROR: 'error' +} + +export default CRUD + +export { + presenter, + header, + form, + pagination, + crud +} diff --git a/src/components/DateRangePicker/index.vue b/src/components/DateRangePicker/index.vue new file mode 100644 index 0000000..8feea56 --- /dev/null +++ b/src/components/DateRangePicker/index.vue @@ -0,0 +1,45 @@ + diff --git a/src/components/Dict/Dict.js b/src/components/Dict/Dict.js new file mode 100644 index 0000000..48554de --- /dev/null +++ b/src/components/Dict/Dict.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import { get as getDictDetail } from '@/api/system/dictDetail' + +export default class Dict { + constructor(dict) { + this.dict = dict + } + + async init(names, completeCallback) { + if (names === undefined || name === null) { + throw new Error('need Dict names') + } + const ps = [] + names.forEach(n => { + Vue.set(this.dict.dict, n, {}) + Vue.set(this.dict.label, n, {}) + Vue.set(this.dict, n, []) + ps.push(getDictDetail(n).then(data => { + this.dict[n].splice(0, 0, ...data.content) + data.content.forEach(d => { + Vue.set(this.dict.dict[n], d.value, d) + Vue.set(this.dict.label[n], d.value, d.label) + }) + })) + }) + await Promise.all(ps) + completeCallback() + } +} diff --git a/src/components/Dict/index.js b/src/components/Dict/index.js new file mode 100644 index 0000000..0952f43 --- /dev/null +++ b/src/components/Dict/index.js @@ -0,0 +1,29 @@ +import Dict from './Dict' + +const install = function(Vue) { + Vue.mixin({ + data() { + if (this.$options.dicts instanceof Array) { + const dict = { + dict: {}, + label: {} + } + return { + dict + } + } + return {} + }, + created() { + if (this.$options.dicts instanceof Array) { + new Dict(this.dict).init(this.$options.dicts, () => { + this.$nextTick(() => { + this.$emit('dictReady') + }) + }) + } + } + }) +} + +export default { install } diff --git a/src/components/Echarts/BarChart.vue b/src/components/Echarts/BarChart.vue new file mode 100644 index 0000000..fa265ef --- /dev/null +++ b/src/components/Echarts/BarChart.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/components/Echarts/Category.vue b/src/components/Echarts/Category.vue new file mode 100644 index 0000000..5859114 --- /dev/null +++ b/src/components/Echarts/Category.vue @@ -0,0 +1,438 @@ + + + diff --git a/src/components/Echarts/Funnel.vue b/src/components/Echarts/Funnel.vue new file mode 100644 index 0000000..380b373 --- /dev/null +++ b/src/components/Echarts/Funnel.vue @@ -0,0 +1,120 @@ + + + diff --git a/src/components/Echarts/Gauge.vue b/src/components/Echarts/Gauge.vue new file mode 100644 index 0000000..40ce775 --- /dev/null +++ b/src/components/Echarts/Gauge.vue @@ -0,0 +1,74 @@ + + + diff --git a/src/components/Echarts/Graph.vue b/src/components/Echarts/Graph.vue new file mode 100644 index 0000000..a5a88b3 --- /dev/null +++ b/src/components/Echarts/Graph.vue @@ -0,0 +1,101 @@ + + + diff --git a/src/components/Echarts/HeatMap.vue b/src/components/Echarts/HeatMap.vue new file mode 100644 index 0000000..6606278 --- /dev/null +++ b/src/components/Echarts/HeatMap.vue @@ -0,0 +1,105 @@ + + + diff --git a/src/components/Echarts/PieChart.vue b/src/components/Echarts/PieChart.vue new file mode 100644 index 0000000..ff1bc52 --- /dev/null +++ b/src/components/Echarts/PieChart.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/components/Echarts/Point.vue b/src/components/Echarts/Point.vue new file mode 100644 index 0000000..5a6c777 --- /dev/null +++ b/src/components/Echarts/Point.vue @@ -0,0 +1,149 @@ + + + diff --git a/src/components/Echarts/RadarChart.vue b/src/components/Echarts/RadarChart.vue new file mode 100644 index 0000000..de70e52 --- /dev/null +++ b/src/components/Echarts/RadarChart.vue @@ -0,0 +1,120 @@ + + + diff --git a/src/components/Echarts/Rich.vue b/src/components/Echarts/Rich.vue new file mode 100644 index 0000000..1cf6bf2 --- /dev/null +++ b/src/components/Echarts/Rich.vue @@ -0,0 +1,149 @@ + + + diff --git a/src/components/Echarts/Sankey.vue b/src/components/Echarts/Sankey.vue new file mode 100644 index 0000000..49968c4 --- /dev/null +++ b/src/components/Echarts/Sankey.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/components/Echarts/Scatter.vue b/src/components/Echarts/Scatter.vue new file mode 100644 index 0000000..b776efb --- /dev/null +++ b/src/components/Echarts/Scatter.vue @@ -0,0 +1,143 @@ + + + diff --git a/src/components/Echarts/Sunburst.vue b/src/components/Echarts/Sunburst.vue new file mode 100644 index 0000000..fafc1a8 --- /dev/null +++ b/src/components/Echarts/Sunburst.vue @@ -0,0 +1,107 @@ + + + diff --git a/src/components/Echarts/ThemeRiver.vue b/src/components/Echarts/ThemeRiver.vue new file mode 100644 index 0000000..967fc05 --- /dev/null +++ b/src/components/Echarts/ThemeRiver.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/components/GithubCorner/index.vue b/src/components/GithubCorner/index.vue new file mode 100644 index 0000000..31e43a3 --- /dev/null +++ b/src/components/GithubCorner/index.vue @@ -0,0 +1,54 @@ + + + diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..c713efc --- /dev/null +++ b/src/components/HeaderSearch/index.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue new file mode 100644 index 0000000..92e4e2e --- /dev/null +++ b/src/components/IconSelect/index.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/components/IconSelect/requireIcons.js b/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/src/components/IconSelect/requireIcons.js @@ -0,0 +1,11 @@ + +const req = require.context('../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const icons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default icons diff --git a/src/components/Iframe/index.vue b/src/components/Iframe/index.vue new file mode 100644 index 0000000..cdd612b --- /dev/null +++ b/src/components/Iframe/index.vue @@ -0,0 +1,30 @@ +