commit 943c4dd7cb517dec81d2e1a63b39ccebf658be88
Author: dute7liang <383200134@qq.com>
Date: Tue Dec 19 22:24:39 2023 +0800
init
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..7034f9b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,22 @@
+# 告诉EditorConfig插件,这是根文件,不用继续往上查找
+root = true
+
+# 匹配全部文件
+[*]
+# 设置字符集
+charset = utf-8
+# 缩进风格,可选space、tab
+indent_style = space
+# 缩进的空格数
+indent_size = 2
+# 结尾换行符,可选lf、cr、crlf
+end_of_line = lf
+# 在文件结尾插入新行
+insert_final_newline = true
+# 删除一行中的前后空格
+trim_trailing_whitespace = true
+
+# 匹配md结尾的文件
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/.env.development b/.env.development
new file mode 100644
index 0000000..0ca147a
--- /dev/null
+++ b/.env.development
@@ -0,0 +1,11 @@
+# 页面标题
+VUE_APP_TITLE = 后台管理系统
+
+# 开发环境配置
+ENV = 'development'
+
+# 若依管理系统/开发环境
+VUE_APP_BASE_API = '/dev-api'
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true
diff --git a/.env.production b/.env.production
new file mode 100644
index 0000000..494479f
--- /dev/null
+++ b/.env.production
@@ -0,0 +1,8 @@
+# 页面标题
+VUE_APP_TITLE = 后台管理系统
+
+# 生产环境配置
+ENV = 'production'
+
+# 若依管理系统/生产环境
+VUE_APP_BASE_API = '/prod-api'
diff --git a/.env.staging b/.env.staging
new file mode 100644
index 0000000..adffd6c
--- /dev/null
+++ b/.env.staging
@@ -0,0 +1,10 @@
+# 页面标题
+VUE_APP_TITLE = 后台管理系统
+
+NODE_ENV = production
+
+# 测试环境配置
+ENV = 'staging'
+
+# 若依管理系统/测试环境
+VUE_APP_BASE_API = '/stage-api'
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..89be6f6
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,10 @@
+# 忽略build目录下类型为js的文件的语法检查
+build/*.js
+# 忽略src/assets目录下文件的语法检查
+src/assets
+# 忽略public目录下文件的语法检查
+public
+# 忽略当前目录下为js的文件的语法检查
+*.js
+# 忽略当前目录下为vue的文件的语法检查
+*.vue
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..82bbdee
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,199 @@
+// ESlint 检查配置
+module.exports = {
+ root: true,
+ parserOptions: {
+ parser: 'babel-eslint',
+ sourceType: 'module'
+ },
+ env: {
+ browser: true,
+ node: true,
+ es6: true,
+ },
+ extends: ['plugin:vue/recommended', 'eslint:recommended'],
+
+ // add your custom rules here
+ //it is base on https://github.com/vuejs/eslint-config-vue
+ rules: {
+ "vue/max-attributes-per-line": [2, {
+ "singleline": 10,
+ "multiline": {
+ "max": 1,
+ "allowFirstLine": false
+ }
+ }],
+ "vue/singleline-html-element-content-newline": "off",
+ "vue/multiline-html-element-content-newline":"off",
+ "vue/name-property-casing": ["error", "PascalCase"],
+ "vue/no-v-html": "off",
+ 'accessor-pairs': 2,
+ 'arrow-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'block-spacing': [2, 'always'],
+ 'brace-style': [2, '1tbs', {
+ 'allowSingleLine': true
+ }],
+ 'camelcase': [0, {
+ 'properties': 'always'
+ }],
+ 'comma-dangle': [2, 'never'],
+ 'comma-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'comma-style': [2, 'last'],
+ 'constructor-super': 2,
+ 'curly': [2, 'multi-line'],
+ 'dot-location': [2, 'property'],
+ 'eol-last': 2,
+ 'eqeqeq': ["error", "always", {"null": "ignore"}],
+ 'generator-star-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'handle-callback-err': [2, '^(err|error)$'],
+ 'indent': [2, 2, {
+ 'SwitchCase': 1
+ }],
+ 'jsx-quotes': [2, 'prefer-single'],
+ 'key-spacing': [2, {
+ 'beforeColon': false,
+ 'afterColon': true
+ }],
+ 'keyword-spacing': [2, {
+ 'before': true,
+ 'after': true
+ }],
+ 'new-cap': [2, {
+ 'newIsCap': true,
+ 'capIsNew': false
+ }],
+ 'new-parens': 2,
+ 'no-array-constructor': 2,
+ 'no-caller': 2,
+ 'no-console': 'off',
+ 'no-class-assign': 2,
+ 'no-cond-assign': 2,
+ 'no-const-assign': 2,
+ 'no-control-regex': 0,
+ 'no-delete-var': 2,
+ 'no-dupe-args': 2,
+ 'no-dupe-class-members': 2,
+ 'no-dupe-keys': 2,
+ 'no-duplicate-case': 2,
+ 'no-empty-character-class': 2,
+ 'no-empty-pattern': 2,
+ 'no-eval': 2,
+ 'no-ex-assign': 2,
+ 'no-extend-native': 2,
+ 'no-extra-bind': 2,
+ 'no-extra-boolean-cast': 2,
+ 'no-extra-parens': [2, 'functions'],
+ 'no-fallthrough': 2,
+ 'no-floating-decimal': 2,
+ 'no-func-assign': 2,
+ 'no-implied-eval': 2,
+ 'no-inner-declarations': [2, 'functions'],
+ 'no-invalid-regexp': 2,
+ 'no-irregular-whitespace': 2,
+ 'no-iterator': 2,
+ 'no-label-var': 2,
+ 'no-labels': [2, {
+ 'allowLoop': false,
+ 'allowSwitch': false
+ }],
+ 'no-lone-blocks': 2,
+ 'no-mixed-spaces-and-tabs': 2,
+ 'no-multi-spaces': 2,
+ 'no-multi-str': 2,
+ 'no-multiple-empty-lines': [2, {
+ 'max': 1
+ }],
+ 'no-native-reassign': 2,
+ 'no-negated-in-lhs': 2,
+ 'no-new-object': 2,
+ 'no-new-require': 2,
+ 'no-new-symbol': 2,
+ 'no-new-wrappers': 2,
+ 'no-obj-calls': 2,
+ 'no-octal': 2,
+ 'no-octal-escape': 2,
+ 'no-path-concat': 2,
+ 'no-proto': 2,
+ 'no-redeclare': 2,
+ 'no-regex-spaces': 2,
+ 'no-return-assign': [2, 'except-parens'],
+ 'no-self-assign': 2,
+ 'no-self-compare': 2,
+ 'no-sequences': 2,
+ 'no-shadow-restricted-names': 2,
+ 'no-spaced-func': 2,
+ 'no-sparse-arrays': 2,
+ 'no-this-before-super': 2,
+ 'no-throw-literal': 2,
+ 'no-trailing-spaces': 2,
+ 'no-undef': 2,
+ 'no-undef-init': 2,
+ 'no-unexpected-multiline': 2,
+ 'no-unmodified-loop-condition': 2,
+ 'no-unneeded-ternary': [2, {
+ 'defaultAssignment': false
+ }],
+ 'no-unreachable': 2,
+ 'no-unsafe-finally': 2,
+ 'no-unused-vars': [2, {
+ 'vars': 'all',
+ 'args': 'none'
+ }],
+ 'no-useless-call': 2,
+ 'no-useless-computed-key': 2,
+ 'no-useless-constructor': 2,
+ 'no-useless-escape': 0,
+ 'no-whitespace-before-property': 2,
+ 'no-with': 2,
+ 'one-var': [2, {
+ 'initialized': 'never'
+ }],
+ 'operator-linebreak': [2, 'after', {
+ 'overrides': {
+ '?': 'before',
+ ':': 'before'
+ }
+ }],
+ 'padded-blocks': [2, 'never'],
+ 'quotes': [2, 'single', {
+ 'avoidEscape': true,
+ 'allowTemplateLiterals': true
+ }],
+ 'semi': [2, 'never'],
+ 'semi-spacing': [2, {
+ 'before': false,
+ 'after': true
+ }],
+ 'space-before-blocks': [2, 'always'],
+ 'space-before-function-paren': [2, 'never'],
+ 'space-in-parens': [2, 'never'],
+ 'space-infix-ops': 2,
+ 'space-unary-ops': [2, {
+ 'words': true,
+ 'nonwords': false
+ }],
+ 'spaced-comment': [2, 'always', {
+ 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
+ }],
+ 'template-curly-spacing': [2, 'never'],
+ 'use-isnan': 2,
+ 'valid-typeof': 2,
+ 'wrap-iife': [2, 'any'],
+ 'yield-star-spacing': [2, 'both'],
+ 'yoda': [2, 'never'],
+ 'prefer-const': 2,
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
+ 'object-curly-spacing': [2, 'always', {
+ objectsInObjects: false
+ }],
+ 'array-bracket-spacing': [2, 'never']
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bca2b77
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+
+dist.zip
+.DS_Store
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+**/*.log
+
+tests/**/coverage/
+tests/e2e/reports
+selenium-debug.log
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.local
+
+package-lock.json
+yarn.lock
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a857617
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+## 开发
+
+```bash
+# 克隆项目
+git clone https://gitee.com/y_project/RuoYi-Vue
+
+# 进入项目目录
+cd ruoyi-ui
+
+# 安装依赖
+npm install
+
+# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
+npm install --registry=https://registry.npm.taobao.org
+
+# 启动服务
+npm run dev
+```
+
+浏览器访问 http://localhost:80
+
+## 发布
+
+```bash
+# 构建测试环境
+npm run build:stage
+
+# 构建生产环境
+npm run build:prod
+```
\ No newline at end of file
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..b99f001
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,13 @@
+module.exports = {
+ presets: [
+ // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
+ '@vue/cli-plugin-babel/preset'
+ ],
+ 'env': {
+ 'development': {
+ // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
+ // This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
+ 'plugins': ['dynamic-import-node']
+ }
+ }
+}
diff --git a/bin/build.bat b/bin/build.bat
new file mode 100644
index 0000000..dda590d
--- /dev/null
+++ b/bin/build.bat
@@ -0,0 +1,12 @@
+@echo off
+echo.
+echo [Ϣ] Weḅdistļ
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+npm run build:prod
+
+pause
\ No newline at end of file
diff --git a/bin/package.bat b/bin/package.bat
new file mode 100644
index 0000000..8281749
--- /dev/null
+++ b/bin/package.bat
@@ -0,0 +1,12 @@
+@echo off
+echo.
+echo [Ϣ] װWeḅnode_modulesļ
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+npm install --registry=https://registry.npm.taobao.org
+
+pause
\ No newline at end of file
diff --git a/bin/run-web.bat b/bin/run-web.bat
new file mode 100644
index 0000000..a938e89
--- /dev/null
+++ b/bin/run-web.bat
@@ -0,0 +1,12 @@
+@echo off
+echo.
+echo [Ϣ] ʹ Vue Web ̡
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+npm run dev
+
+pause
\ No newline at end of file
diff --git a/build/index.js b/build/index.js
new file mode 100644
index 0000000..0c57de2
--- /dev/null
+++ b/build/index.js
@@ -0,0 +1,35 @@
+const { run } = require('runjs')
+const chalk = require('chalk')
+const config = require('../vue.config.js')
+const rawArgv = process.argv.slice(2)
+const args = rawArgv.join(' ')
+
+if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
+ const report = rawArgv.includes('--report')
+
+ run(`vue-cli-service build ${args}`)
+
+ const port = 9526
+ const publicPath = config.publicPath
+
+ var connect = require('connect')
+ var serveStatic = require('serve-static')
+ const app = connect()
+
+ app.use(
+ publicPath,
+ serveStatic('./dist', {
+ index: ['index.html', '/']
+ })
+ )
+
+ app.listen(port, function () {
+ console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
+ if (report) {
+ console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
+ }
+
+ })
+} else {
+ run(`vue-cli-service build ${args}`)
+}
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..2d28b24
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ },
+},
+ "include": [
+ "src/**/*"
+],
+ "exclude": [
+ "node_modules"
+]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d13dbea
--- /dev/null
+++ b/package.json
@@ -0,0 +1,92 @@
+{
+ "name": "ruoyi-vue-plus",
+ "version": "2.4.0",
+ "description": "RuoYi-Vue-Plus后台管理系统",
+ "author": "LionLi",
+ "license": "MIT",
+ "scripts": {
+ "dev": "vue-cli-service serve",
+ "build:prod": "vue-cli-service build",
+ "build:stage": "vue-cli-service build --mode staging",
+ "preview": "node build/index.js --preview",
+ "lint": "eslint --ext .js,.vue src"
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "lint-staged"
+ }
+ },
+ "lint-staged": {
+ "src/**/*.{js,vue}": [
+ "eslint --fix",
+ "git add"
+ ]
+ },
+ "keywords": [
+ "vue",
+ "admin",
+ "dashboard",
+ "element-ui",
+ "boilerplate",
+ "admin-template",
+ "management-system"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://gitee.com/y_project/RuoYi-Vue.git"
+ },
+ "dependencies": {
+ "@amap/amap-vue": "^2.0.13",
+ "@riophae/vue-treeselect": "0.4.0",
+ "axios": "0.21.0",
+ "clipboard": "2.0.6",
+ "core-js": "3.8.1",
+ "echarts": "4.9.0",
+ "element-ui": "^2.15.5",
+ "file-saver": "2.0.4",
+ "fuse.js": "6.4.3",
+ "highlight.js": "9.18.5",
+ "js-beautify": "1.13.0",
+ "js-cookie": "2.2.1",
+ "jsencrypt": "3.0.0-rc.1",
+ "nprogress": "0.2.0",
+ "quill": "1.3.7",
+ "screenfull": "5.0.2",
+ "sortablejs": "1.10.2",
+ "vue": "2.6.12",
+ "vue-amap": "^0.5.10",
+ "vue-count-to": "1.0.13",
+ "vue-cropper": "0.5.5",
+ "vue-json-viewer": "^2.2.19",
+ "vue-meta": "^2.4.0",
+ "vue-router": "3.4.9",
+ "vuedraggable": "2.24.3",
+ "vuex": "3.6.0",
+ "wangeditor": "^4.7.8"
+ },
+ "devDependencies": {
+ "@vue/cli-plugin-babel": "4.4.6",
+ "@vue/cli-plugin-eslint": "4.4.6",
+ "@vue/cli-service": "4.4.6",
+ "babel-eslint": "10.1.0",
+ "chalk": "4.1.0",
+ "connect": "3.6.6",
+ "eslint": "7.15.0",
+ "eslint-plugin-vue": "7.2.0",
+ "lint-staged": "10.5.3",
+ "runjs": "4.4.2",
+ "sass": "1.32.0",
+ "sass-loader": "10.1.0",
+ "script-ext-html-webpack-plugin": "2.1.5",
+ "svg-sprite-loader": "5.1.1",
+ "vue-template-compiler": "2.6.12"
+ },
+ "engines": {
+ "node": ">=8.9",
+ "npm": ">= 3.0.0"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ]
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e263760
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/html/ie.html b/public/html/ie.html
new file mode 100644
index 0000000..052ffcd
--- /dev/null
+++ b/public/html/ie.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+ 请升级您的浏览器
+
+
+
+
+
+
+请升级您的浏览器,以便我们更好的为您提供服务!
+您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。
+
+请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束
+自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明 。
+
+您可以选择更先进的浏览器
+推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。
+
+
+
+
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..925455c
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+
+
+ <%= 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..391d951
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/src/api/business/banner.js b/src/api/business/banner.js
new file mode 100644
index 0000000..a8db13a
--- /dev/null
+++ b/src/api/business/banner.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询banner图列表
+export function listBanner(query) {
+ return request({
+ url: '/business/banner/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询banner图详细
+export function getBanner(id) {
+ return request({
+ url: '/business/banner/' + id,
+ method: 'get'
+ })
+}
+
+// 新增banner图
+export function addBanner(data) {
+ return request({
+ url: '/business/banner',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改banner图
+export function updateBanner(data) {
+ return request({
+ url: '/business/banner',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除banner图
+export function delBanner(id) {
+ return request({
+ url: '/business/banner/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出banner图
+export function exportBanner(query) {
+ return request({
+ url: '/business/banner/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/blackList.js b/src/api/business/blackList.js
new file mode 100644
index 0000000..ab410c9
--- /dev/null
+++ b/src/api/business/blackList.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询黑名单列表
+export function listBlackList(query) {
+ return request({
+ url: '/business/blackList/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询黑名单详细
+export function getBlackList(id) {
+ return request({
+ url: '/business/blackList/' + id,
+ method: 'get'
+ })
+}
+
+// 新增黑名单
+export function addBlackList(data) {
+ return request({
+ url: '/business/blackList',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改黑名单
+export function updateBlackList(data) {
+ return request({
+ url: '/business/blackList',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除黑名单
+export function delBlackList(id) {
+ return request({
+ url: '/business/blackList/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出黑名单
+export function exportBlackList(query) {
+ return request({
+ url: '/business/blackList/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/count.js b/src/api/business/count.js
new file mode 100644
index 0000000..fd12a00
--- /dev/null
+++ b/src/api/business/count.js
@@ -0,0 +1,23 @@
+import request from '@/utils/request'
+
+export function countAll() {
+ return request({
+ url: '/business/count/all',
+ method: 'get',
+ })
+}
+
+export function lineData() {
+ return request({
+ url: '/business/count/lineData',
+ method: 'get',
+ })
+}
+
+export function pieData(params) {
+ return request({
+ url: '/business/count/pieData',
+ method: 'get',
+ params:params,
+ })
+}
diff --git a/src/api/business/coupon.js b/src/api/business/coupon.js
new file mode 100644
index 0000000..38c9db1
--- /dev/null
+++ b/src/api/business/coupon.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询优惠券中心列表
+export function listCoupon(query) {
+ return request({
+ url: '/business/coupon/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询优惠券中心详细
+export function getCoupon(id) {
+ return request({
+ url: '/business/coupon/' + id,
+ method: 'get'
+ })
+}
+
+// 新增优惠券中心
+export function addCoupon(data) {
+ return request({
+ url: '/business/coupon',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改优惠券中心
+export function updateCoupon(data) {
+ return request({
+ url: '/business/coupon',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除优惠券中心
+export function delCoupon(id) {
+ return request({
+ url: '/business/coupon/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出优惠券中心
+export function exportCoupon(query) {
+ return request({
+ url: '/business/coupon/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/cultivate.js b/src/api/business/cultivate.js
new file mode 100644
index 0000000..952ba9c
--- /dev/null
+++ b/src/api/business/cultivate.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询培训视频列表
+export function listCultivate(query) {
+ return request({
+ url: '/business/cultivate/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询培训视频详细
+export function getCultivate(id) {
+ return request({
+ url: '/business/cultivate/' + id,
+ method: 'get'
+ })
+}
+
+// 新增培训视频
+export function addCultivate(data) {
+ return request({
+ url: '/business/cultivate',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改培训视频
+export function updateCultivate(data) {
+ return request({
+ url: '/business/cultivate',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除培训视频
+export function delCultivate(id) {
+ return request({
+ url: '/business/cultivate/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出培训视频
+export function exportCultivate(query) {
+ return request({
+ url: '/business/cultivate/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/cultivateOrder.js b/src/api/business/cultivateOrder.js
new file mode 100644
index 0000000..8b4a3bd
--- /dev/null
+++ b/src/api/business/cultivateOrder.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询培训购买订单列表
+export function listCultivateOrder(query) {
+ return request({
+ url: '/business/cultivateOrder/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询培训购买订单详细
+export function getCultivateOrder(id) {
+ return request({
+ url: '/business/cultivateOrder/' + id,
+ method: 'get'
+ })
+}
+
+// 新增培训购买订单
+export function addCultivateOrder(data) {
+ return request({
+ url: '/business/cultivateOrder',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改培训购买订单
+export function updateCultivateOrder(data) {
+ return request({
+ url: '/business/cultivateOrder',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除培训购买订单
+export function delCultivateOrder(id) {
+ return request({
+ url: '/business/cultivateOrder/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出培训购买订单
+export function exportCultivateOrder(query) {
+ return request({
+ url: '/business/cultivateOrder/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/cultivateUser.js b/src/api/business/cultivateUser.js
new file mode 100644
index 0000000..870f92c
--- /dev/null
+++ b/src/api/business/cultivateUser.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询培训用户关联列表
+export function listCultivateUser(query) {
+ return request({
+ url: '/business/cultivateUser/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询培训用户关联详细
+export function getCultivateUser(id) {
+ return request({
+ url: '/business/cultivateUser/' + id,
+ method: 'get'
+ })
+}
+
+// 新增培训用户关联
+export function addCultivateUser(data) {
+ return request({
+ url: '/business/cultivateUser',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改培训用户关联
+export function updateCultivateUser(data) {
+ return request({
+ url: '/business/cultivateUser',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除培训用户关联
+export function delCultivateUser(id) {
+ return request({
+ url: '/business/cultivateUser/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出培训用户关联
+export function exportCultivateUser(query) {
+ return request({
+ url: '/business/cultivateUser/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/customer.js b/src/api/business/customer.js
new file mode 100644
index 0000000..c06f9a4
--- /dev/null
+++ b/src/api/business/customer.js
@@ -0,0 +1,62 @@
+import request from '@/utils/request'
+
+// 查询客户管理列表
+export function listCustomer(query) {
+ return request({
+ url: '/business/customer/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询客户管理详细
+export function getCustomer(id) {
+ return request({
+ url: '/business/customer/' + id,
+ method: 'get'
+ })
+}
+
+// 新增客户管理
+export function addCustomer(data) {
+ return request({
+ url: '/business/customer',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改客户管理
+export function updateCustomer(data) {
+ return request({
+ url: '/business/customer',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除客户管理
+export function delCustomer(id) {
+ return request({
+ url: '/business/customer/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出客户管理
+export function exportCustomer(query) {
+ return request({
+ url: '/business/customer/export',
+ method: 'get',
+ params: query
+ })
+}
+
+// 修改商家管理
+export function giveVip(query) {
+ return request({
+ url: '/business/customer/giveVip',
+ method: 'post',
+ params: query
+ })
+}
diff --git a/src/api/business/evaluation.js b/src/api/business/evaluation.js
new file mode 100644
index 0000000..82ac216
--- /dev/null
+++ b/src/api/business/evaluation.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询评价管理列表
+export function listEvaluation(query) {
+ return request({
+ url: '/business/evaluation/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询评价管理详细
+export function getEvaluation(id) {
+ return request({
+ url: '/business/evaluation/' + id,
+ method: 'get'
+ })
+}
+
+// 新增评价管理
+export function addEvaluation(data) {
+ return request({
+ url: '/business/evaluation',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改评价管理
+export function updateEvaluation(data) {
+ return request({
+ url: '/business/evaluation',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除评价管理
+export function delEvaluation(id) {
+ return request({
+ url: '/business/evaluation/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出评价管理
+export function exportEvaluation(query) {
+ return request({
+ url: '/business/evaluation/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/home.js b/src/api/business/home.js
new file mode 100644
index 0000000..adf4a45
--- /dev/null
+++ b/src/api/business/home.js
@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+export function homeCount(query) {
+ return request({
+ url: '/home/audit/count',
+ method: 'get',
+ params: query
+ })
+}
+
diff --git a/src/api/business/iosConfig.js b/src/api/business/iosConfig.js
new file mode 100644
index 0000000..286154a
--- /dev/null
+++ b/src/api/business/iosConfig.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询苹果端系统设置列表
+export function listIosConfig(query) {
+ return request({
+ url: '/business/iosConfig/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询苹果端系统设置详细
+export function getIosConfig(id) {
+ return request({
+ url: '/business/iosConfig/' + id,
+ method: 'get'
+ })
+}
+
+// 新增苹果端系统设置
+export function addIosConfig(data) {
+ return request({
+ url: '/business/iosConfig',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改苹果端系统设置
+export function updateIosConfig(data) {
+ return request({
+ url: '/business/iosConfig',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除苹果端系统设置
+export function delIosConfig(id) {
+ return request({
+ url: '/business/iosConfig/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出苹果端系统设置
+export function exportIosConfig(query) {
+ return request({
+ url: '/business/iosConfig/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/joinMechanic.js b/src/api/business/joinMechanic.js
new file mode 100644
index 0000000..36174fd
--- /dev/null
+++ b/src/api/business/joinMechanic.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询技师入驻列表
+export function listJoinMechanic(query) {
+ return request({
+ url: '/business/joinMechanic/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询技师入驻详细
+export function getJoinMechanic(id) {
+ return request({
+ url: '/business/joinMechanic/' + id,
+ method: 'get'
+ })
+}
+
+// 新增技师入驻
+export function addJoinMechanic(data) {
+ return request({
+ url: '/business/joinMechanic',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改技师入驻
+export function updateJoinMechanic(data) {
+ return request({
+ url: '/business/joinMechanic',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除技师入驻
+export function delJoinMechanic(id) {
+ return request({
+ url: '/business/joinMechanic/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出技师入驻
+export function exportJoinMechanic(query) {
+ return request({
+ url: '/business/joinMechanic/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/joinShop.js b/src/api/business/joinShop.js
new file mode 100644
index 0000000..c03c388
--- /dev/null
+++ b/src/api/business/joinShop.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询商家入驻列表
+export function listJoinShop(query) {
+ return request({
+ url: '/business/joinShop/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询商家入驻详细
+export function getJoinShop(id) {
+ return request({
+ url: '/business/joinShop/' + id,
+ method: 'get'
+ })
+}
+
+// 新增商家入驻
+export function addJoinShop(data) {
+ return request({
+ url: '/business/joinShop',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改商家入驻
+export function updateJoinShop(data) {
+ return request({
+ url: '/business/joinShop',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除商家入驻
+export function delJoinShop(id) {
+ return request({
+ url: '/business/joinShop/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出商家入驻
+export function exportJoinShop(query) {
+ return request({
+ url: '/business/joinShop/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/mechanic.js b/src/api/business/mechanic.js
new file mode 100644
index 0000000..ab0486d
--- /dev/null
+++ b/src/api/business/mechanic.js
@@ -0,0 +1,94 @@
+import request from '@/utils/request'
+
+// 查询技师管理列表
+export function listMechanic(query) {
+ return request({
+ url: '/business/mechanic/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function listMechanicAudit(query) {
+ return request({
+ url: '/business/mechanic/audit/list',
+ method: 'get',
+ params: query
+ })
+}
+
+
+// 查询技师管理详细
+export function getMechanic(id) {
+ return request({
+ url: '/business/mechanic/' + id,
+ method: 'get'
+ })
+}
+
+// 新增技师管理
+export function addMechanic(data) {
+ return request({
+ url: '/business/mechanic',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改技师管理
+export function updateMechanic(data) {
+ return request({
+ url: '/business/mechanic',
+ method: 'put',
+ data: data
+ })
+}
+
+export function auditMechanicAvatar(data) {
+ return request({
+ url: '/business/mechanic/avatar/audit',
+ method: 'put',
+ data: data
+ })
+}
+
+export function auditMechanic(data) {
+ return request({
+ url: '/business/mechanic/audit',
+ method: 'put',
+ data: data
+ })
+}
+
+export function createEvaluation(params) {
+ return request({
+ url: '/business/mechanic/createEvaluation',
+ method: 'get',
+ params: params
+ })
+}
+
+export function updateAppType(params) {
+ return request({
+ url: '/business/mechanic/updateAppType',
+ method: 'get',
+ params: params
+ })
+}
+
+// 删除技师管理
+export function delMechanic(id) {
+ return request({
+ url: '/business/mechanic/' + id,
+ method: 'delete'
+ })
+}
+
+// 删除技师管理
+export function batchUpdateMechanicServiceStatus(data) {
+ return request({
+ url: '/business/mechanic/batchUpdateMechanicServiceStatus',
+ method: 'post',
+ data
+ })
+}
diff --git a/src/api/business/mechanicInfo.js b/src/api/business/mechanicInfo.js
new file mode 100644
index 0000000..5bb38f7
--- /dev/null
+++ b/src/api/business/mechanicInfo.js
@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+// 查询技师照片-视频管理列表
+export function listMechanicInfo(query) {
+ return request({
+ url: '/business/mechanicInfo/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function mechanicInfoListV2(query) {
+ return request({
+ url: '/business/mechanicInfo/v2/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询技师照片-视频管理详细
+export function getMechanicInfo(id) {
+ return request({
+ url: '/business/mechanicInfo/' + id,
+ method: 'get'
+ })
+}
+
+// 新增技师照片-视频管理
+export function addMechanicInfo(data) {
+ return request({
+ url: '/business/mechanicInfo',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改技师照片-视频管理
+export function updateMechanicInfo(data) {
+ return request({
+ url: '/business/mechanicInfo',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除技师照片-视频管理
+export function delMechanicInfo(id) {
+ return request({
+ url: '/business/mechanicInfo/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出技师照片-视频管理
+export function exportMechanicInfo(query) {
+ return request({
+ url: '/business/mechanicInfo/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/business/order.js b/src/api/business/order.js
new file mode 100644
index 0000000..3c340e2
--- /dev/null
+++ b/src/api/business/order.js
@@ -0,0 +1,93 @@
+import request from '@/utils/request'
+
+// 查询订单管理列表
+export function listOrder(query) {
+ return request({
+ url: '/business/order/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询订单管理详细
+export function getOrder(id) {
+ return request({
+ url: '/business/order/' + id,
+ method: 'get'
+ })
+}
+
+// 新增订单管理
+export function addOrder(data) {
+ return request({
+ url: '/business/order',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改订单管理
+export function updateOrder(data) {
+ return request({
+ url: '/business/order',
+ method: 'put',
+ data: data
+ })
+}
+
+export function orderLogsByOrderId(params) {
+ return request({
+ url: '/business/order/orderLogsByOrderId',
+ method: 'get',
+ params: params
+ })
+}
+
+export function payOrder(data) {
+ return request({
+ url: '/business/order/pay',
+ method: 'get',
+ params: data
+ })
+}
+export function receiveOrder(data) {
+ return request({
+ url: '/app/order/receive',
+ method: 'get',
+ params: data
+ })
+}
+
+export function commitOrder(data) {
+ return request({
+ url: '/app/order/commit',
+ method: 'get',
+ params: data
+ })
+}
+
+
+// 删除订单管理
+export function delOrder(id) {
+ return request({
+ url: '/business/order/' + id,
+ method: 'delete'
+ })
+}
+
+// 删除订单管理
+export function refund(data) {
+ return request({
+ url: '/business/order/refund',
+ method: 'get',
+ params: data
+ })
+}
+
+export function orderSearch(params) {
+ return request({
+ url: '/business/order/search',
+ method: 'get',
+ params: params
+ })
+}
diff --git a/src/api/business/orderDelete.js b/src/api/business/orderDelete.js
new file mode 100644
index 0000000..4906653
--- /dev/null
+++ b/src/api/business/orderDelete.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询以删除订单列表
+export function listOrderDelete(query) {
+ return request({
+ url: '/business/orderDelete/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询以删除订单详细
+export function getOrderDelete(id) {
+ return request({
+ url: '/business/orderDelete/' + id,
+ method: 'get'
+ })
+}
+
+// 新增以删除订单
+export function addOrderDelete(data) {
+ return request({
+ url: '/business/orderDelete',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改以删除订单
+export function updateOrderDelete(data) {
+ return request({
+ url: '/business/orderDelete',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除以删除订单
+export function delOrderDelete(id) {
+ return request({
+ url: '/business/orderDelete/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出以删除订单
+export function exportOrderDelete(query) {
+ return request({
+ url: '/business/orderDelete/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/qualification-apply.js b/src/api/business/qualification-apply.js
new file mode 100644
index 0000000..b754cd2
--- /dev/null
+++ b/src/api/business/qualification-apply.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 查询证书申请列表
+export function listQualificationApply(query) {
+ return request({
+ url: '/business/qualification-apply/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询证书申请详细
+export function getQualificationApply(id) {
+ return request({
+ url: '/business/qualification-apply/' + id,
+ method: 'get'
+ })
+}
+
+// 修改证书申请
+export function updateQualificationApply(data) {
+ return request({
+ url: '/business/qualification-apply',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除证书申请
+export function delQualificationApply(id) {
+ return request({
+ url: '/business/qualification-apply/' + id,
+ method: 'delete'
+ })
+}
diff --git a/src/api/business/serviceItem.js b/src/api/business/serviceItem.js
new file mode 100644
index 0000000..bc9aa28
--- /dev/null
+++ b/src/api/business/serviceItem.js
@@ -0,0 +1,72 @@
+import request from '@/utils/request'
+
+
+// 查询服务管理列表
+export function listByMechanicId(query) {
+ return request({
+ url: '/business/serviceItem/listByMechanicId',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询服务管理列表
+export function listByShopId(query) {
+ return request({
+ url: '/business/serviceItem/listByShopId',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询服务管理列表
+export function listServiceItem(query) {
+ return request({
+ url: '/business/serviceItem/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询服务管理详细
+export function getServiceItem(id) {
+ return request({
+ url: '/business/serviceItem/' + id,
+ method: 'get'
+ })
+}
+
+// 新增服务管理
+export function addServiceItem(data) {
+ return request({
+ url: '/business/serviceItem',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改服务管理
+export function updateServiceItem(data) {
+ return request({
+ url: '/business/serviceItem',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除服务管理
+export function delServiceItem(id) {
+ return request({
+ url: '/business/serviceItem/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出服务管理
+export function exportServiceItem(query) {
+ return request({
+ url: '/business/serviceItem/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/business/shop.js b/src/api/business/shop.js
new file mode 100644
index 0000000..68d2ebd
--- /dev/null
+++ b/src/api/business/shop.js
@@ -0,0 +1,90 @@
+import request from '@/utils/request'
+
+// 查询商家管理列表
+export function listShop(query) {
+ return request({
+ url: '/business/shop/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询商家管理详细
+export function getShop(id) {
+ return request({
+ url: '/business/shop/' + id,
+ method: 'get'
+ })
+}
+
+// 新增商家管理
+export function addShop(data) {
+ return request({
+ url: '/business/shop',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改商家管理
+export function updateShop(data) {
+ return request({
+ url: '/business/shop',
+ method: 'put',
+ data: data
+ })
+}
+
+// 修改商家电话管理
+export function updateShopPhone(data) {
+ return request({
+ url: '/business/shop/updatePhone',
+ method: 'get',
+ params: data
+ })
+}
+
+export function auditShop(data) {
+ return request({
+ url: '/business/shop/audit',
+ method: 'put',
+ data: data
+ })
+}
+
+
+// 删除商家管理
+export function delShop(id) {
+ return request({
+ url: '/business/shop/' + id,
+ method: 'delete'
+ })
+}
+
+// 检查商家管理
+export function checkShop(id) {
+ return request({
+ url: '/business/shop/checkShop',
+ method: 'get',
+ params:{id:id}
+ })
+}
+
+// 修改商家金额
+export function initAmountShop(data) {
+ return request({
+ url: '/business/shop/updateInitAmount',
+ method: 'post',
+ data: data
+ })
+}
+
+
+// 查询商家管理列表
+export function listIncsShopLogs(query) {
+ return request({
+ url: '/business/shop/initAmount/page',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/business/shopAudit.js b/src/api/business/shopAudit.js
new file mode 100644
index 0000000..16a6094
--- /dev/null
+++ b/src/api/business/shopAudit.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询商家修改审核列表
+export function listShopAudit(query) {
+ return request({
+ url: '/business/shopAudit/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询商家修改审核详细
+export function getShopAudit(id) {
+ return request({
+ url: '/business/shopAudit/' + id,
+ method: 'get'
+ })
+}
+
+// 新增商家修改审核
+export function addShopAudit(data) {
+ return request({
+ url: '/business/shopAudit',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改商家修改审核
+export function updateShopAudit(data) {
+ return request({
+ url: '/business/shopAudit',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除商家修改审核
+export function delShopAudit(id) {
+ return request({
+ url: '/business/shopAudit/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出商家修改审核
+export function exportShopAudit(query) {
+ return request({
+ url: '/business/shopAudit/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/shopInLogs.js b/src/api/business/shopInLogs.js
new file mode 100644
index 0000000..571e5a5
--- /dev/null
+++ b/src/api/business/shopInLogs.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function listShopInLogs(query) {
+ return request({
+ url: '/business/shopInLogs/list',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/business/systemConfig.js b/src/api/business/systemConfig.js
new file mode 100644
index 0000000..4b12899
--- /dev/null
+++ b/src/api/business/systemConfig.js
@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+
+
+// 查询系统设置详细
+export function getSystemConfig(id) {
+ return request({
+ url: '/business/systemConfig/' + id,
+ method: 'get'
+ })
+}
+
+// 修改系统设置
+export function updateSystemConfig(data) {
+ return request({
+ url: '/business/systemConfig',
+ method: 'put',
+ data: data
+ })
+}
+
+// 获取平台数据
+export function auditPlatform() {
+ return request({
+ url: '/business/systemConfig/auditPlatform',
+ method: 'get',
+ })
+}
+
diff --git a/src/api/business/vipOrder.js b/src/api/business/vipOrder.js
new file mode 100644
index 0000000..c6980d9
--- /dev/null
+++ b/src/api/business/vipOrder.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询VIP订单管理列表
+export function listVipOrder(query) {
+ return request({
+ url: '/business/vipOrder/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询VIP订单管理详细
+export function getVipOrder(id) {
+ return request({
+ url: '/business/vipOrder/' + id,
+ method: 'get'
+ })
+}
+
+// 新增VIP订单管理
+export function addVipOrder(data) {
+ return request({
+ url: '/business/vipOrder',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改VIP订单管理
+export function updateVipOrder(data) {
+ return request({
+ url: '/business/vipOrder',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除VIP订单管理
+export function delVipOrder(id) {
+ return request({
+ url: '/business/vipOrder/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出VIP订单管理
+export function exportVipOrder(query) {
+ return request({
+ url: '/business/vipOrder/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/business/withdraw.js b/src/api/business/withdraw.js
new file mode 100644
index 0000000..57e4543
--- /dev/null
+++ b/src/api/business/withdraw.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 查询提现订单管理列表
+export function listWithdraw(query) {
+ return request({
+ url: '/business/withdraw/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询提现订单管理详细
+export function getWithdraw(id) {
+ return request({
+ url: '/business/withdraw/' + id,
+ method: 'get'
+ })
+}
+
+// 修改提现订单管理
+export function auditWithdraw(data) {
+ return request({
+ url: '/business/withdraw/audit',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除提现订单管理
+export function delWithdraw(id) {
+ return request({
+ url: '/business/withdraw/' + id,
+ method: 'delete'
+ })
+}
diff --git a/src/api/demo/demo.js b/src/api/demo/demo.js
new file mode 100644
index 0000000..fc9937d
--- /dev/null
+++ b/src/api/demo/demo.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询测试单表列表
+export function listDemo(query) {
+ return request({
+ url: '/demo/demo/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询测试单表详细
+export function getDemo(id) {
+ return request({
+ url: '/demo/demo/' + id,
+ method: 'get'
+ })
+}
+
+// 新增测试单表
+export function addDemo(data) {
+ return request({
+ url: '/demo/demo',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改测试单表
+export function updateDemo(data) {
+ return request({
+ url: '/demo/demo',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除测试单表
+export function delDemo(id) {
+ return request({
+ url: '/demo/demo/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出测试单表
+export function exportDemo(query) {
+ return request({
+ url: '/demo/demo/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/demo/tree.js b/src/api/demo/tree.js
new file mode 100644
index 0000000..d597e72
--- /dev/null
+++ b/src/api/demo/tree.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询测试树表列表
+export function listTree(query) {
+ return request({
+ url: '/demo/tree/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询测试树表详细
+export function getTree(id) {
+ return request({
+ url: '/demo/tree/' + id,
+ method: 'get'
+ })
+}
+
+// 新增测试树表
+export function addTree(data) {
+ return request({
+ url: '/demo/tree',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改测试树表
+export function updateTree(data) {
+ return request({
+ url: '/demo/tree',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除测试树表
+export function delTree(id) {
+ return request({
+ url: '/demo/tree/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出测试树表
+export function exportTree(query) {
+ return request({
+ url: '/demo/tree/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/dk/AgreementSetting.js b/src/api/dk/AgreementSetting.js
new file mode 100644
index 0000000..eab2243
--- /dev/null
+++ b/src/api/dk/AgreementSetting.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 查询协议设置详细
+export function getAgreementSetting() {
+ return request({
+ url: '/dk/AgreementSetting/info',
+ method: 'get'
+ })
+}
+
+// 修改协议设置
+export function updateAgreementSetting(data) {
+ return request({
+ url: '/dk/AgreementSetting',
+ method: 'put',
+ data: data
+ })
+}
diff --git a/src/api/dk/BorrowStatus.js b/src/api/dk/BorrowStatus.js
new file mode 100644
index 0000000..2d64160
--- /dev/null
+++ b/src/api/dk/BorrowStatus.js
@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 查询借款状态列表
+export function listBorrowStatus(query) {
+ return request({
+ url: '/dk/BorrowStatus/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function bankType(query) {
+ return request({
+ url: '/dk/BorrowStatus/bankType',
+ method: 'get',
+ params: query
+ })
+}
+
+export function all(query) {
+ return request({
+ url: '/dk/BorrowStatus/all',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询借款状态详细
+export function getBorrowStatus(id) {
+ return request({
+ url: '/dk/BorrowStatus/' + id,
+ method: 'get'
+ })
+}
+
+// 新增借款状态
+export function addBorrowStatus(data) {
+ return request({
+ url: '/dk/BorrowStatus',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改借款状态
+export function updateBorrowStatus(data) {
+ return request({
+ url: '/dk/BorrowStatus',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除借款状态
+export function delBorrowStatus(id) {
+ return request({
+ url: '/dk/BorrowStatus/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出借款状态
+export function exportBorrowStatus(query) {
+ return request({
+ url: '/dk/BorrowStatus/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/dk/HomeSetting.js b/src/api/dk/HomeSetting.js
new file mode 100644
index 0000000..0701c63
--- /dev/null
+++ b/src/api/dk/HomeSetting.js
@@ -0,0 +1,21 @@
+import request from '@/utils/request'
+
+// 查询常规设置详细
+export function getHomeSetting() {
+ return request({
+ url: '/dk/HomeSetting/info',
+ method: 'get'
+ })
+}
+
+// 修改常规设置
+export function updateHomeSetting(data) {
+ return request({
+ url: '/dk/HomeSetting',
+ method: 'put',
+ data: data
+ })
+}
+
+export class delHomeSetting {
+}
diff --git a/src/api/dk/LoansSetting.js b/src/api/dk/LoansSetting.js
new file mode 100644
index 0000000..5c29a12
--- /dev/null
+++ b/src/api/dk/LoansSetting.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 查询贷款设置详细
+export function getLoansSetting() {
+ return request({
+ url: '/dk/LoansSetting/info',
+ method: 'get'
+ })
+}
+
+// 修改贷款设置
+export function updateLoansSetting(data) {
+ return request({
+ url: '/dk/LoansSetting',
+ method: 'put',
+ data: data
+ })
+}
diff --git a/src/api/dk/borrow.js b/src/api/dk/borrow.js
new file mode 100644
index 0000000..ae73f73
--- /dev/null
+++ b/src/api/dk/borrow.js
@@ -0,0 +1,86 @@
+import request from '@/utils/request'
+
+// 查询借款计划列表
+export function listBorrow(query) {
+ return request({
+ url: '/dk/borrow/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询借款计划详细
+export function getBorrow(id) {
+ return request({
+ url: '/dk/borrow/' + id,
+ method: 'get'
+ })
+}
+
+export function getContract(tradeNo) {
+ return request({
+ url: '/dk/borrow/getContract',
+ method: 'get',
+ params: {
+ tradeNo
+ }
+ })
+}
+
+// 新增借款计划
+export function addBorrow(data) {
+ return request({
+ url: '/dk/borrow',
+ method: 'post',
+ data: data
+ })
+}
+
+export function updateBorrowLoan(data) {
+ return request({
+ url: '/dk/borrow/updateLoan',
+ method: 'post',
+ data: data
+ })
+}
+
+export function updateBorrowStatus(data) {
+ return request({
+ url: '/dk/borrow/updateStatus',
+ method: 'post',
+ data: data
+ })
+}
+
+export function updateBorrow(data) {
+ return request({
+ url: '/dk/borrow',
+ method: 'put',
+ data: data
+ })
+}
+
+export function updateBank(data) {
+ return request({
+ url: '/dk/borrow/updateBank',
+ method: 'post',
+ data: data
+ })
+}
+
+// 删除借款计划
+export function delBorrow(id) {
+ return request({
+ url: '/dk/borrow/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出借款计划
+export function exportBorrow(query) {
+ return request({
+ url: '/dk/borrow/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/dk/dkCustomer.js b/src/api/dk/dkCustomer.js
new file mode 100644
index 0000000..5165381
--- /dev/null
+++ b/src/api/dk/dkCustomer.js
@@ -0,0 +1,58 @@
+import request from '@/utils/request'
+
+// 查询客户列表
+export function listDkCustomer(query) {
+ return request({
+ url: '/dk/dkCustomer/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询客户详细
+export function getDkCustomer(id) {
+ return request({
+ url: '/dk/dkCustomer/' + id,
+ method: 'get'
+ })
+}
+
+// 用户密码重置
+export function resetCustomerPwd(customerId, password) {
+ const data = {
+ customerId,
+ password
+ }
+ return request({
+ url: '/dk/dkCustomer/resetPwd',
+ method: 'post',
+ data: data
+ })
+}
+
+
+// 修改客户
+export function updateDkCustomer(data) {
+ return request({
+ url: '/dk/dkCustomer',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除客户
+export function delDkCustomer(id) {
+ return request({
+ url: '/dk/dkCustomer/' + id,
+ method: 'delete'
+ })
+}
+
+// 导出客户
+export function exportDkCustomer(query) {
+ return request({
+ url: '/dk/dkCustomer/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/dk/dkCustomerInfo.js b/src/api/dk/dkCustomerInfo.js
new file mode 100644
index 0000000..9ae55d9
--- /dev/null
+++ b/src/api/dk/dkCustomerInfo.js
@@ -0,0 +1,58 @@
+import request from '@/utils/request'
+
+// 查询客户资料列表
+export function listDkCustomerInfo(query) {
+ return request({
+ url: '/dk/dkCustomerInfo/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询客户资料详细
+export function getDkCustomerInfo(id) {
+ return request({
+ url: '/dk/dkCustomerInfo/' + id,
+ method: 'get'
+ })
+}
+
+export function updateAllowSignature(data) {
+ return request({
+ url: '/dk/dkCustomerInfo/updateAllowSignature',
+ method: 'post',
+ data
+ })
+}
+
+
+export function getInfoByCustomerId(query) {
+ return request({
+ url: '/dk/dkCustomerInfo/getInfoByCustomerId',
+ method: 'get',
+ params: query
+ })
+}
+
+
+
+// 新增客户资料
+export function addDkCustomerInfo(data) {
+ return request({
+ url: '/dk/dkCustomerInfo',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改客户资料
+export function updateDkCustomerInfo(data) {
+ return request({
+ url: '/dk/dkCustomerInfo',
+ method: 'put',
+ data: data
+ })
+}
+
+
+
diff --git a/src/api/login.js b/src/api/login.js
new file mode 100644
index 0000000..869cd9f
--- /dev/null
+++ b/src/api/login.js
@@ -0,0 +1,40 @@
+import request from '@/utils/request'
+
+// 登录方法
+export function login(username, password, code, uuid) {
+ const data = {
+ username,
+ password,
+ code,
+ uuid
+ }
+ return request({
+ url: '/login',
+ method: 'post',
+ data: data
+ })
+}
+
+// 获取用户详细信息
+export function getInfo() {
+ return request({
+ url: '/getInfo',
+ method: 'get'
+ })
+}
+
+// 退出方法
+export function logout() {
+ return request({
+ url: '/logout',
+ method: 'post'
+ })
+}
+
+// 获取验证码
+export function getCodeImg() {
+ return request({
+ url: '/captchaImage',
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/src/api/menu.js b/src/api/menu.js
new file mode 100644
index 0000000..faef101
--- /dev/null
+++ b/src/api/menu.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+// 获取路由
+export const getRouters = () => {
+ return request({
+ url: '/getRouters',
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/src/api/monitor/cache.js b/src/api/monitor/cache.js
new file mode 100644
index 0000000..59d3505
--- /dev/null
+++ b/src/api/monitor/cache.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+// 查询缓存详细
+export function getCache() {
+ return request({
+ url: '/monitor/cache',
+ method: 'get'
+ })
+}
diff --git a/src/api/monitor/job.js b/src/api/monitor/job.js
new file mode 100644
index 0000000..58c4343
--- /dev/null
+++ b/src/api/monitor/job.js
@@ -0,0 +1,80 @@
+import request from '@/utils/request'
+
+// 查询定时任务调度列表
+export function listJob(query) {
+ return request({
+ url: '/monitor/job/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询定时任务调度详细
+export function getJob(jobId) {
+ return request({
+ url: '/monitor/job/' + jobId,
+ method: 'get'
+ })
+}
+
+// 新增定时任务调度
+export function addJob(data) {
+ return request({
+ url: '/monitor/job',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改定时任务调度
+export function updateJob(data) {
+ return request({
+ url: '/monitor/job',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除定时任务调度
+export function delJob(jobId) {
+ return request({
+ url: '/monitor/job/' + jobId,
+ method: 'delete'
+ })
+}
+
+// 导出定时任务调度
+export function exportJob(query) {
+ return request({
+ url: '/monitor/job/export',
+ method: 'get',
+ params: query
+ })
+}
+
+// 任务状态修改
+export function changeJobStatus(jobId, status) {
+ const data = {
+ jobId,
+ status
+ }
+ return request({
+ url: '/monitor/job/changeStatus',
+ method: 'put',
+ data: data
+ })
+}
+
+
+// 定时任务立即执行一次
+export function runJob(jobId, jobGroup) {
+ const data = {
+ jobId,
+ jobGroup
+ }
+ return request({
+ url: '/monitor/job/run',
+ method: 'put',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/src/api/monitor/jobLog.js b/src/api/monitor/jobLog.js
new file mode 100644
index 0000000..be1fffd
--- /dev/null
+++ b/src/api/monitor/jobLog.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 查询调度日志列表
+export function listJobLog(query) {
+ return request({
+ url: '/monitor/jobLog/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 删除调度日志
+export function delJobLog(jobLogId) {
+ return request({
+ url: '/monitor/jobLog/' + jobLogId,
+ method: 'delete'
+ })
+}
+
+// 清空调度日志
+export function cleanJobLog() {
+ return request({
+ url: '/monitor/jobLog/clean',
+ method: 'delete'
+ })
+}
+
+// 导出调度日志
+export function exportJobLog(query) {
+ return request({
+ url: '/monitor/jobLog/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/monitor/logininfor.js b/src/api/monitor/logininfor.js
new file mode 100644
index 0000000..383d61f
--- /dev/null
+++ b/src/api/monitor/logininfor.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 查询登录日志列表
+export function list(query) {
+ return request({
+ url: '/monitor/logininfor/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 删除登录日志
+export function delLogininfor(infoId) {
+ return request({
+ url: '/monitor/logininfor/' + infoId,
+ method: 'delete'
+ })
+}
+
+// 清空登录日志
+export function cleanLogininfor() {
+ return request({
+ url: '/monitor/logininfor/clean',
+ method: 'delete'
+ })
+}
+
+// 导出登录日志
+export function exportLogininfor(query) {
+ return request({
+ url: '/monitor/logininfor/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/monitor/online.js b/src/api/monitor/online.js
new file mode 100644
index 0000000..bd22137
--- /dev/null
+++ b/src/api/monitor/online.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 查询在线用户列表
+export function list(query) {
+ return request({
+ url: '/monitor/online/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 强退用户
+export function forceLogout(tokenId) {
+ return request({
+ url: '/monitor/online/' + tokenId,
+ method: 'delete'
+ })
+}
diff --git a/src/api/monitor/operlog.js b/src/api/monitor/operlog.js
new file mode 100644
index 0000000..f09b8ed
--- /dev/null
+++ b/src/api/monitor/operlog.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 查询操作日志列表
+export function list(query) {
+ return request({
+ url: '/monitor/operlog/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 删除操作日志
+export function delOperlog(operId) {
+ return request({
+ url: '/monitor/operlog/' + operId,
+ method: 'delete'
+ })
+}
+
+// 清空操作日志
+export function cleanOperlog() {
+ return request({
+ url: '/monitor/operlog/clean',
+ method: 'delete'
+ })
+}
+
+// 导出操作日志
+export function exportOperlog(query) {
+ return request({
+ url: '/monitor/operlog/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/monitor/server.js b/src/api/monitor/server.js
new file mode 100644
index 0000000..feed783
--- /dev/null
+++ b/src/api/monitor/server.js
@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+// 查询服务器详细
+export function getServer() {
+ return request({
+ url: '/monitor/server',
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/config.js b/src/api/system/config.js
new file mode 100644
index 0000000..4c5cb6b
--- /dev/null
+++ b/src/api/system/config.js
@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 查询参数列表
+export function listConfig(query) {
+ return request({
+ url: '/system/config/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询参数详细
+export function getConfig(configId) {
+ return request({
+ url: '/system/config/' + configId,
+ method: 'get'
+ })
+}
+
+// 根据参数键名查询参数值
+export function getConfigKey(configKey) {
+ return request({
+ url: '/system/config/configKey/' + configKey,
+ method: 'get'
+ })
+}
+
+// 新增参数配置
+export function addConfig(data) {
+ return request({
+ url: '/system/config',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改参数配置
+export function updateConfig(data) {
+ return request({
+ url: '/system/config',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除参数配置
+export function delConfig(configId) {
+ return request({
+ url: '/system/config/' + configId,
+ method: 'delete'
+ })
+}
+
+// 刷新参数缓存
+export function refreshCache() {
+ return request({
+ url: '/system/config/refreshCache',
+ method: 'delete'
+ })
+}
+
+// 导出参数
+export function exportConfig(query) {
+ return request({
+ url: '/system/config/export',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/system/dept.js b/src/api/system/dept.js
new file mode 100644
index 0000000..2804676
--- /dev/null
+++ b/src/api/system/dept.js
@@ -0,0 +1,68 @@
+import request from '@/utils/request'
+
+// 查询部门列表
+export function listDept(query) {
+ return request({
+ url: '/system/dept/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询部门列表(排除节点)
+export function listDeptExcludeChild(deptId) {
+ return request({
+ url: '/system/dept/list/exclude/' + deptId,
+ method: 'get'
+ })
+}
+
+// 查询部门详细
+export function getDept(deptId) {
+ return request({
+ url: '/system/dept/' + deptId,
+ method: 'get'
+ })
+}
+
+// 查询部门下拉树结构
+export function treeselect() {
+ return request({
+ url: '/system/dept/treeselect',
+ method: 'get'
+ })
+}
+
+// 根据角色ID查询部门树结构
+export function roleDeptTreeselect(roleId) {
+ return request({
+ url: '/system/dept/roleDeptTreeselect/' + roleId,
+ method: 'get'
+ })
+}
+
+// 新增部门
+export function addDept(data) {
+ return request({
+ url: '/system/dept',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改部门
+export function updateDept(data) {
+ return request({
+ url: '/system/dept',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除部门
+export function delDept(deptId) {
+ return request({
+ url: '/system/dept/' + deptId,
+ method: 'delete'
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/dict/data.js b/src/api/system/dict/data.js
new file mode 100644
index 0000000..d7aca89
--- /dev/null
+++ b/src/api/system/dict/data.js
@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+// 查询字典数据列表
+export function listData(query) {
+ return request({
+ url: '/system/dict/data/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询字典数据详细
+export function getData(dictCode) {
+ return request({
+ url: '/system/dict/data/' + dictCode,
+ method: 'get'
+ })
+}
+
+// 根据字典类型查询字典数据信息
+export function getDicts(dictType) {
+ return request({
+ url: '/system/dict/data/type/' + dictType,
+ method: 'get'
+ })
+}
+
+// 新增字典数据
+export function addData(data) {
+ return request({
+ url: '/system/dict/data',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改字典数据
+export function updateData(data) {
+ return request({
+ url: '/system/dict/data',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除字典数据
+export function delData(dictCode) {
+ return request({
+ url: '/system/dict/data/' + dictCode,
+ method: 'delete'
+ })
+}
+
+// 导出字典数据
+export function exportData(query) {
+ return request({
+ url: '/system/dict/data/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/dict/type.js b/src/api/system/dict/type.js
new file mode 100644
index 0000000..2f0532d
--- /dev/null
+++ b/src/api/system/dict/type.js
@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 查询字典类型列表
+export function listType(query) {
+ return request({
+ url: '/system/dict/type/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询字典类型详细
+export function getType(dictId) {
+ return request({
+ url: '/system/dict/type/' + dictId,
+ method: 'get'
+ })
+}
+
+// 新增字典类型
+export function addType(data) {
+ return request({
+ url: '/system/dict/type',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改字典类型
+export function updateType(data) {
+ return request({
+ url: '/system/dict/type',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除字典类型
+export function delType(dictId) {
+ return request({
+ url: '/system/dict/type/' + dictId,
+ method: 'delete'
+ })
+}
+
+// 刷新字典缓存
+export function refreshCache() {
+ return request({
+ url: '/system/dict/type/refreshCache',
+ method: 'delete'
+ })
+}
+
+// 导出字典类型
+export function exportType(query) {
+ return request({
+ url: '/system/dict/type/export',
+ method: 'get',
+ params: query
+ })
+}
+
+// 获取字典选择框列表
+export function optionselect() {
+ return request({
+ url: '/system/dict/type/optionselect',
+ method: 'get'
+ })
+}
diff --git a/src/api/system/menu.js b/src/api/system/menu.js
new file mode 100644
index 0000000..f6415c6
--- /dev/null
+++ b/src/api/system/menu.js
@@ -0,0 +1,60 @@
+import request from '@/utils/request'
+
+// 查询菜单列表
+export function listMenu(query) {
+ return request({
+ url: '/system/menu/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询菜单详细
+export function getMenu(menuId) {
+ return request({
+ url: '/system/menu/' + menuId,
+ method: 'get'
+ })
+}
+
+// 查询菜单下拉树结构
+export function treeselect() {
+ return request({
+ url: '/system/menu/treeselect',
+ method: 'get'
+ })
+}
+
+// 根据角色ID查询菜单下拉树结构
+export function roleMenuTreeselect(roleId) {
+ return request({
+ url: '/system/menu/roleMenuTreeselect/' + roleId,
+ method: 'get'
+ })
+}
+
+// 新增菜单
+export function addMenu(data) {
+ return request({
+ url: '/system/menu',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改菜单
+export function updateMenu(data) {
+ return request({
+ url: '/system/menu',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除菜单
+export function delMenu(menuId) {
+ return request({
+ url: '/system/menu/' + menuId,
+ method: 'delete'
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/notice.js b/src/api/system/notice.js
new file mode 100644
index 0000000..c274ea5
--- /dev/null
+++ b/src/api/system/notice.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询公告列表
+export function listNotice(query) {
+ return request({
+ url: '/system/notice/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询公告详细
+export function getNotice(noticeId) {
+ return request({
+ url: '/system/notice/' + noticeId,
+ method: 'get'
+ })
+}
+
+// 新增公告
+export function addNotice(data) {
+ return request({
+ url: '/system/notice',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改公告
+export function updateNotice(data) {
+ return request({
+ url: '/system/notice',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除公告
+export function delNotice(noticeId) {
+ return request({
+ url: '/system/notice/' + noticeId,
+ method: 'delete'
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/post.js b/src/api/system/post.js
new file mode 100644
index 0000000..434cd35
--- /dev/null
+++ b/src/api/system/post.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询岗位列表
+export function listPost(query) {
+ return request({
+ url: '/system/post/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询岗位详细
+export function getPost(postId) {
+ return request({
+ url: '/system/post/' + postId,
+ method: 'get'
+ })
+}
+
+// 新增岗位
+export function addPost(data) {
+ return request({
+ url: '/system/post',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改岗位
+export function updatePost(data) {
+ return request({
+ url: '/system/post',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除岗位
+export function delPost(postId) {
+ return request({
+ url: '/system/post/' + postId,
+ method: 'delete'
+ })
+}
+
+// 导出岗位
+export function exportPost(query) {
+ return request({
+ url: '/system/post/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/role.js b/src/api/system/role.js
new file mode 100644
index 0000000..463501c
--- /dev/null
+++ b/src/api/system/role.js
@@ -0,0 +1,75 @@
+import request from '@/utils/request'
+
+// 查询角色列表
+export function listRole(query) {
+ return request({
+ url: '/system/role/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询角色详细
+export function getRole(roleId) {
+ return request({
+ url: '/system/role/' + roleId,
+ method: 'get'
+ })
+}
+
+// 新增角色
+export function addRole(data) {
+ return request({
+ url: '/system/role',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改角色
+export function updateRole(data) {
+ return request({
+ url: '/system/role',
+ method: 'put',
+ data: data
+ })
+}
+
+// 角色数据权限
+export function dataScope(data) {
+ return request({
+ url: '/system/role/dataScope',
+ method: 'put',
+ data: data
+ })
+}
+
+// 角色状态修改
+export function changeRoleStatus(roleId, status) {
+ const data = {
+ roleId,
+ status
+ }
+ return request({
+ url: '/system/role/changeStatus',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除角色
+export function delRole(roleId) {
+ return request({
+ url: '/system/role/' + roleId,
+ method: 'delete'
+ })
+}
+
+// 导出角色
+export function exportRole(query) {
+ return request({
+ url: '/system/role/export',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/system/user.js b/src/api/system/user.js
new file mode 100644
index 0000000..d507cea
--- /dev/null
+++ b/src/api/system/user.js
@@ -0,0 +1,135 @@
+import request from '@/utils/request'
+import { praseStrEmpty } from "@/utils/ruoyi";
+
+// 查询用户列表
+export function listUser(query) {
+ return request({
+ url: '/system/user/list',
+ method: 'get',
+ params: query
+ })
+}
+
+export function updateUserCity(data) {
+ return request({
+ url: '/system/user/updateUserCity',
+ method: 'post',
+ data: data
+ })
+}
+
+// 查询用户详细
+export function getUser(userId) {
+ return request({
+ url: '/system/user/' + praseStrEmpty(userId),
+ method: 'get'
+ })
+}
+
+// 新增用户
+export function addUser(data) {
+ return request({
+ url: '/system/user',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改用户
+export function updateUser(data) {
+ return request({
+ url: '/system/user',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除用户
+export function delUser(userId) {
+ return request({
+ url: '/system/user/' + userId,
+ method: 'delete'
+ })
+}
+
+// 导出用户
+export function exportUser(query) {
+ return request({
+ url: '/system/user/export',
+ method: 'get',
+ params: query
+ })
+}
+
+// 用户密码重置
+export function resetUserPwd(userId, password) {
+ const data = {
+ userId,
+ password
+ }
+ return request({
+ url: '/system/user/resetPwd',
+ method: 'put',
+ data: data
+ })
+}
+
+// 用户状态修改
+export function changeUserStatus(userId, status) {
+ const data = {
+ userId,
+ status
+ }
+ return request({
+ url: '/system/user/changeStatus',
+ method: 'put',
+ data: data
+ })
+}
+
+// 查询用户个人信息
+export function getUserProfile() {
+ return request({
+ url: '/system/user/profile',
+ method: 'get'
+ })
+}
+
+// 修改用户个人信息
+export function updateUserProfile(data) {
+ return request({
+ url: '/system/user/profile',
+ method: 'put',
+ data: data
+ })
+}
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+ const data = {
+ oldPassword,
+ newPassword
+ }
+ return request({
+ url: '/system/user/profile/updatePwd',
+ method: 'put',
+ params: data
+ })
+}
+
+// 用户头像上传
+export function uploadAvatar(data) {
+ return request({
+ url: '/system/user/profile/avatar',
+ method: 'post',
+ data: data
+ })
+}
+
+// 下载用户导入模板
+export function importTemplate() {
+ return request({
+ url: '/system/user/importTemplate',
+ method: 'get'
+ })
+}
diff --git a/src/api/tool/gen.js b/src/api/tool/gen.js
new file mode 100644
index 0000000..4506927
--- /dev/null
+++ b/src/api/tool/gen.js
@@ -0,0 +1,76 @@
+import request from '@/utils/request'
+
+// 查询生成表数据
+export function listTable(query) {
+ return request({
+ url: '/tool/gen/list',
+ method: 'get',
+ params: query
+ })
+}
+// 查询db数据库列表
+export function listDbTable(query) {
+ return request({
+ url: '/tool/gen/db/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询表详细信息
+export function getGenTable(tableId) {
+ return request({
+ url: '/tool/gen/' + tableId,
+ method: 'get'
+ })
+}
+
+// 修改代码生成信息
+export function updateGenTable(data) {
+ return request({
+ url: '/tool/gen',
+ method: 'put',
+ data: data
+ })
+}
+
+// 导入表
+export function importTable(data) {
+ return request({
+ url: '/tool/gen/importTable',
+ method: 'post',
+ params: data
+ })
+}
+
+// 预览生成代码
+export function previewTable(tableId) {
+ return request({
+ url: '/tool/gen/preview/' + tableId,
+ method: 'get'
+ })
+}
+
+// 删除表数据
+export function delTable(tableId) {
+ return request({
+ url: '/tool/gen/' + tableId,
+ method: 'delete'
+ })
+}
+
+// 生成代码(自定义路径)
+export function genCode(tableName) {
+ return request({
+ url: '/tool/gen/genCode/' + tableName,
+ method: 'get'
+ })
+}
+
+// 同步数据库
+export function synchDb(tableName) {
+ return request({
+ url: '/tool/gen/synchDb/' + tableName,
+ method: 'get'
+ })
+}
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/404.svg b/src/assets/icons/svg/404.svg
new file mode 100644
index 0000000..6df5019
--- /dev/null
+++ b/src/assets/icons/svg/404.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/bug.svg b/src/assets/icons/svg/bug.svg
new file mode 100644
index 0000000..05a150d
--- /dev/null
+++ b/src/assets/icons/svg/bug.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/build.svg b/src/assets/icons/svg/build.svg
new file mode 100644
index 0000000..97c4688
--- /dev/null
+++ b/src/assets/icons/svg/build.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/button.svg b/src/assets/icons/svg/button.svg
new file mode 100644
index 0000000..904fddc
--- /dev/null
+++ b/src/assets/icons/svg/button.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/cascader.svg b/src/assets/icons/svg/cascader.svg
new file mode 100644
index 0000000..e256024
--- /dev/null
+++ b/src/assets/icons/svg/cascader.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/checkbox.svg b/src/assets/icons/svg/checkbox.svg
new file mode 100644
index 0000000..013fd3a
--- /dev/null
+++ b/src/assets/icons/svg/checkbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/clipboard.svg b/src/assets/icons/svg/clipboard.svg
new file mode 100644
index 0000000..90923ff
--- /dev/null
+++ b/src/assets/icons/svg/clipboard.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/code.svg b/src/assets/icons/svg/code.svg
new file mode 100644
index 0000000..ed4d23c
--- /dev/null
+++ b/src/assets/icons/svg/code.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/color.svg b/src/assets/icons/svg/color.svg
new file mode 100644
index 0000000..44a81aa
--- /dev/null
+++ b/src/assets/icons/svg/color.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/component.svg b/src/assets/icons/svg/component.svg
new file mode 100644
index 0000000..29c3458
--- /dev/null
+++ b/src/assets/icons/svg/component.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/date-range.svg b/src/assets/icons/svg/date-range.svg
new file mode 100644
index 0000000..fda571e
--- /dev/null
+++ b/src/assets/icons/svg/date-range.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..52dc73e
--- /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/dict.svg b/src/assets/icons/svg/dict.svg
new file mode 100644
index 0000000..4849377
--- /dev/null
+++ b/src/assets/icons/svg/dict.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/documentation.svg b/src/assets/icons/svg/documentation.svg
new file mode 100644
index 0000000..7043122
--- /dev/null
+++ b/src/assets/icons/svg/documentation.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..c896951
--- /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/drag.svg b/src/assets/icons/svg/drag.svg
new file mode 100644
index 0000000..4185d3c
--- /dev/null
+++ b/src/assets/icons/svg/drag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/druid.svg b/src/assets/icons/svg/druid.svg
new file mode 100644
index 0000000..a2b4b4e
--- /dev/null
+++ b/src/assets/icons/svg/druid.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..74d25e2
--- /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/example.svg b/src/assets/icons/svg/example.svg
new file mode 100644
index 0000000..46f42b5
--- /dev/null
+++ b/src/assets/icons/svg/example.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/excel.svg b/src/assets/icons/svg/excel.svg
new file mode 100644
index 0000000..74d97b8
--- /dev/null
+++ b/src/assets/icons/svg/excel.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/eye-open.svg b/src/assets/icons/svg/eye-open.svg
new file mode 100644
index 0000000..88dcc98
--- /dev/null
+++ b/src/assets/icons/svg/eye-open.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/eye.svg b/src/assets/icons/svg/eye.svg
new file mode 100644
index 0000000..16ed2d8
--- /dev/null
+++ b/src/assets/icons/svg/eye.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/form.svg b/src/assets/icons/svg/form.svg
new file mode 100644
index 0000000..dcbaa18
--- /dev/null
+++ b/src/assets/icons/svg/form.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/github.svg b/src/assets/icons/svg/github.svg
new file mode 100644
index 0000000..db0a0d4
--- /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/guide.svg b/src/assets/icons/svg/guide.svg
new file mode 100644
index 0000000..b271001
--- /dev/null
+++ b/src/assets/icons/svg/guide.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..82be8ee
--- /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/input.svg b/src/assets/icons/svg/input.svg
new file mode 100644
index 0000000..ab91381
--- /dev/null
+++ b/src/assets/icons/svg/input.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/job.svg b/src/assets/icons/svg/job.svg
new file mode 100644
index 0000000..2a93a25
--- /dev/null
+++ b/src/assets/icons/svg/job.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/language.svg b/src/assets/icons/svg/language.svg
new file mode 100644
index 0000000..0082b57
--- /dev/null
+++ b/src/assets/icons/svg/language.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..74fee54
--- /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..d879d33
--- /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/logininfor.svg b/src/assets/icons/svg/logininfor.svg
new file mode 100644
index 0000000..267f844
--- /dev/null
+++ b/src/assets/icons/svg/logininfor.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/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..bc308cb
--- /dev/null
+++ b/src/assets/icons/svg/monitor.svg
@@ -0,0 +1,2 @@
+
\ 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/number.svg b/src/assets/icons/svg/number.svg
new file mode 100644
index 0000000..ad5ce9a
--- /dev/null
+++ b/src/assets/icons/svg/number.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/online.svg b/src/assets/icons/svg/online.svg
new file mode 100644
index 0000000..330a202
--- /dev/null
+++ b/src/assets/icons/svg/online.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..6c64def
--- /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/pdf.svg b/src/assets/icons/svg/pdf.svg
new file mode 100644
index 0000000..957aa0c
--- /dev/null
+++ b/src/assets/icons/svg/pdf.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..aab852e
--- /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/phone.svg b/src/assets/icons/svg/phone.svg
new file mode 100644
index 0000000..ab8e8c4
--- /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/post.svg b/src/assets/icons/svg/post.svg
new file mode 100644
index 0000000..2922c61
--- /dev/null
+++ b/src/assets/icons/svg/post.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/qq.svg b/src/assets/icons/svg/qq.svg
new file mode 100644
index 0000000..ee13d4e
--- /dev/null
+++ b/src/assets/icons/svg/qq.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/question.svg b/src/assets/icons/svg/question.svg
new file mode 100644
index 0000000..cf75bd4
--- /dev/null
+++ b/src/assets/icons/svg/question.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/radio.svg b/src/assets/icons/svg/radio.svg
new file mode 100644
index 0000000..0cde345
--- /dev/null
+++ b/src/assets/icons/svg/radio.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/rate.svg b/src/assets/icons/svg/rate.svg
new file mode 100644
index 0000000..aa3b14d
--- /dev/null
+++ b/src/assets/icons/svg/rate.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..2f1d62d
--- /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/row.svg b/src/assets/icons/svg/row.svg
new file mode 100644
index 0000000..0780992
--- /dev/null
+++ b/src/assets/icons/svg/row.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/select.svg b/src/assets/icons/svg/select.svg
new file mode 100644
index 0000000..d628382
--- /dev/null
+++ b/src/assets/icons/svg/select.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..ca37b00
--- /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/slider.svg b/src/assets/icons/svg/slider.svg
new file mode 100644
index 0000000..fbe4f39
--- /dev/null
+++ b/src/assets/icons/svg/slider.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/star.svg b/src/assets/icons/svg/star.svg
new file mode 100644
index 0000000..6cf86e6
--- /dev/null
+++ b/src/assets/icons/svg/star.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..05d4e7b
--- /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/switch.svg b/src/assets/icons/svg/switch.svg
new file mode 100644
index 0000000..0ba61e3
--- /dev/null
+++ b/src/assets/icons/svg/switch.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..dba28cf
--- /dev/null
+++ b/src/assets/icons/svg/system.svg
@@ -0,0 +1,2 @@
+
\ 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/table.svg b/src/assets/icons/svg/table.svg
new file mode 100644
index 0000000..0e3dc9d
--- /dev/null
+++ b/src/assets/icons/svg/table.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/textarea.svg b/src/assets/icons/svg/textarea.svg
new file mode 100644
index 0000000..2709f29
--- /dev/null
+++ b/src/assets/icons/svg/textarea.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/time-range.svg b/src/assets/icons/svg/time-range.svg
new file mode 100644
index 0000000..13c1202
--- /dev/null
+++ b/src/assets/icons/svg/time-range.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/time.svg b/src/assets/icons/svg/time.svg
new file mode 100644
index 0000000..b376e32
--- /dev/null
+++ b/src/assets/icons/svg/time.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/svg/tool.svg b/src/assets/icons/svg/tool.svg
new file mode 100644
index 0000000..c813067
--- /dev/null
+++ b/src/assets/icons/svg/tool.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/upload.svg b/src/assets/icons/svg/upload.svg
new file mode 100644
index 0000000..bae49c0
--- /dev/null
+++ b/src/assets/icons/svg/upload.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..0ba0716
--- /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/validCode.svg b/src/assets/icons/svg/validCode.svg
new file mode 100644
index 0000000..cfb1021
--- /dev/null
+++ b/src/assets/icons/svg/validCode.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/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/zip.svg b/src/assets/icons/svg/zip.svg
new file mode 100644
index 0000000..f806fc4
--- /dev/null
+++ b/src/assets/icons/svg/zip.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/dark.svg b/src/assets/images/dark.svg
new file mode 100644
index 0000000..f646bd7
--- /dev/null
+++ b/src/assets/images/dark.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/images/hd_bg.png b/src/assets/images/hd_bg.png
new file mode 100644
index 0000000..7e9e92d
Binary files /dev/null and b/src/assets/images/hd_bg.png differ
diff --git a/src/assets/images/hd_bg1.png b/src/assets/images/hd_bg1.png
new file mode 100644
index 0000000..d859058
Binary files /dev/null and b/src/assets/images/hd_bg1.png differ
diff --git a/src/assets/images/light.svg b/src/assets/images/light.svg
new file mode 100644
index 0000000..ab7cc08
--- /dev/null
+++ b/src/assets/images/light.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/assets/images/login-background.jpg b/src/assets/images/login-background.jpg
new file mode 100644
index 0000000..8c876d5
Binary files /dev/null and b/src/assets/images/login-background.jpg differ
diff --git a/src/assets/images/login-background1.jpg b/src/assets/images/login-background1.jpg
new file mode 100644
index 0000000..8a89eb8
Binary files /dev/null and b/src/assets/images/login-background1.jpg differ
diff --git a/src/assets/images/login-background2.jpg b/src/assets/images/login-background2.jpg
new file mode 100644
index 0000000..9a5f149
Binary files /dev/null and b/src/assets/images/login-background2.jpg differ
diff --git a/src/assets/images/profile.jpg b/src/assets/images/profile.jpg
new file mode 100644
index 0000000..b3a940b
Binary files /dev/null and b/src/assets/images/profile.jpg differ
diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png
new file mode 100644
index 0000000..e263760
Binary files /dev/null and b/src/assets/logo/logo.png differ
diff --git a/src/assets/mp3/dingdantishi.mp3 b/src/assets/mp3/dingdantishi.mp3
new file mode 100644
index 0000000..1438f2e
Binary files /dev/null and b/src/assets/mp3/dingdantishi.mp3 differ
diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss
new file mode 100644
index 0000000..e6ba1a8
--- /dev/null
+++ b/src/assets/styles/btn.scss
@@ -0,0 +1,99 @@
+@import './variables.scss';
+
+@mixin colorBtn($color) {
+ background: $color;
+
+ &:hover {
+ color: $color;
+
+ &:before,
+ &:after {
+ background: $color;
+ }
+ }
+}
+
+.blue-btn {
+ @include colorBtn($blue)
+}
+
+.light-blue-btn {
+ @include colorBtn($light-blue)
+}
+
+.red-btn {
+ @include colorBtn($red)
+}
+
+.pink-btn {
+ @include colorBtn($pink)
+}
+
+.green-btn {
+ @include colorBtn($green)
+}
+
+.tiffany-btn {
+ @include colorBtn($tiffany)
+}
+
+.yellow-btn {
+ @include colorBtn($yellow)
+}
+
+.pan-btn {
+ font-size: 14px;
+ color: #fff;
+ padding: 14px 36px;
+ border-radius: 8px;
+ border: none;
+ outline: none;
+ transition: 600ms ease all;
+ position: relative;
+ display: inline-block;
+
+ &:hover {
+ background: #fff;
+
+ &:before,
+ &:after {
+ width: 100%;
+ transition: 600ms ease all;
+ }
+ }
+
+ &:before,
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 2px;
+ width: 0;
+ transition: 400ms ease all;
+ }
+
+ &::after {
+ right: inherit;
+ top: inherit;
+ left: 0;
+ bottom: 0;
+ }
+}
+
+.custom-button {
+ display: inline-block;
+ line-height: 1;
+ white-space: nowrap;
+ cursor: pointer;
+ background: #fff;
+ color: #fff;
+ -webkit-appearance: none;
+ text-align: center;
+ box-sizing: border-box;
+ outline: 0;
+ margin: 0;
+ padding: 10px 15px;
+ font-size: 14px;
+ border-radius: 4px;
+}
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
new file mode 100644
index 0000000..363092a
--- /dev/null
+++ b/src/assets/styles/element-ui.scss
@@ -0,0 +1,92 @@
+// 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: 0px;
+ }
+}
+
+.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: 0px;
+ }
+ }
+}
+
+// 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;
+}
+
+// to fix el-date-picker css style
+.el-range-separator {
+ box-sizing: content-box;
+}
+
+.el-menu--collapse
+ > div
+ > .el-submenu
+ > .el-submenu__title
+ .el-submenu__icon-arrow {
+ display: none;
+}
\ No newline at end of file
diff --git a/src/assets/styles/element-variables.scss b/src/assets/styles/element-variables.scss
new file mode 100644
index 0000000..8b7a48e
--- /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: #1890ff;
+$--color-success: #13ce66;
+$--color-warning: #ffba00;
+$--color-danger: #ff4949;
+// $--color-info: #1E1E1E;
+
+$--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 "~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..96095ef
--- /dev/null
+++ b/src/assets/styles/index.scss
@@ -0,0 +1,191 @@
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+@import './btn.scss';
+
+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: 0px !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;
+}
+
+.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);
+ }
+}
+
+.filter-container {
+ padding-bottom: 10px;
+
+ .filter-item {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 10px;
+ }
+}
+
+//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/ruoyi.scss b/src/assets/styles/ruoyi.scss
new file mode 100644
index 0000000..dee6d09
--- /dev/null
+++ b/src/assets/styles/ruoyi.scss
@@ -0,0 +1,248 @@
+ /**
+ * 通用css样式布局处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+ /** 基础通用 **/
+.pt5 {
+ padding-top: 5px;
+}
+.pr5 {
+ padding-right: 5px;
+}
+.pb5 {
+ padding-bottom: 5px;
+}
+.mt5 {
+ margin-top: 5px;
+}
+.mr5 {
+ margin-right: 5px;
+}
+.mb5 {
+ margin-bottom: 5px;
+}
+.mb8 {
+ margin-bottom: 8px;
+}
+.ml5 {
+ margin-left: 5px;
+}
+.mt10 {
+ margin-top: 10px;
+}
+.mr10 {
+ margin-right: 10px;
+}
+.mb10 {
+ margin-bottom: 10px;
+}
+.ml0 {
+ margin-left: 10px;
+}
+.mt20 {
+ margin-top: 20px;
+}
+.mr20 {
+ margin-right: 20px;
+}
+.mb20 {
+ margin-bottom: 20px;
+}
+.m20 {
+ margin-left: 20px;
+}
+
+.el-dialog:not(.is-fullscreen){
+ margin-top: 6vh !important;
+}
+
+.el-table {
+ .el-table__header-wrapper, .el-table__fixed-header-wrapper {
+ th {
+ word-break: break-word;
+ background-color: #f8f8f9;
+ color: #515a6e;
+ height: 40px;
+ font-size: 13px;
+ }
+ }
+ .el-table__body-wrapper {
+ .el-button [class*="el-icon-"] + span {
+ margin-left: 1px;
+ }
+ }
+}
+
+/** 表单布局 **/
+.form-header {
+ font-size:15px;
+ color:#6379bb;
+ border-bottom:1px solid #ddd;
+ margin:8px 10px 25px 10px;
+ padding-bottom:5px
+}
+
+/** 表格布局 **/
+.pagination-container {
+ position: relative;
+ height: 25px;
+ margin-bottom: 10px;
+ margin-top: 15px;
+ padding: 10px 20px !important;
+}
+
+/* tree border */
+.tree-border {
+ margin-top: 5px;
+ border: 1px solid #e5e6e7;
+ background: #FFFFFF none;
+ border-radius:4px;
+}
+
+.pagination-container .el-pagination {
+ right: 0;
+ position: absolute;
+}
+
+@media ( max-width : 768px) {
+ .pagination-container .el-pagination > .el-pagination__jump {
+ display: none !important;
+ }
+ .pagination-container .el-pagination > .el-pagination__sizes {
+ display: none !important;
+ }
+}
+
+.el-table .fixed-width .el-button--mini {
+ padding-left: 0;
+ padding-right: 0;
+ width: inherit;
+}
+
+.el-tree-node__content > .el-checkbox {
+ margin-right: 8px;
+}
+
+.list-group-striped > .list-group-item {
+ border-left: 0;
+ border-right: 0;
+ border-radius: 0;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+.list-group {
+ padding-left: 0px;
+ list-style: none;
+}
+
+.list-group-item {
+ border-bottom: 1px solid #e7eaec;
+ border-top: 1px solid #e7eaec;
+ margin-bottom: -1px;
+ padding: 11px 0px;
+ font-size: 13px;
+}
+
+.pull-right {
+ float: right !important;
+}
+
+.el-card__header {
+ padding: 14px 15px 7px;
+ min-height: 40px;
+}
+
+.el-card__body {
+ padding: 15px 20px 20px 20px;
+}
+
+.card-box {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-bottom: 10px;
+}
+
+/* button color */
+.el-button--cyan.is-active,
+.el-button--cyan:active {
+ background: #20B2AA;
+ border-color: #20B2AA;
+ color: #FFFFFF;
+}
+
+.el-button--cyan:focus,
+.el-button--cyan:hover {
+ background: #48D1CC;
+ border-color: #48D1CC;
+ color: #FFFFFF;
+}
+
+.el-button--cyan {
+ background-color: #20B2AA;
+ border-color: #20B2AA;
+ color: #FFFFFF;
+}
+
+/* text color */
+.text-navy {
+ color: #1ab394;
+}
+
+.text-primary {
+ color: inherit;
+}
+
+.text-success {
+ color: #1c84c6;
+}
+
+.text-info {
+ color: #23c6c8;
+}
+
+.text-warning {
+ color: #f8ac59;
+}
+
+.text-danger {
+ color: #ed5565;
+}
+
+.text-muted {
+ color: #888888;
+}
+
+/* image */
+.img-circle {
+ border-radius: 50%;
+}
+
+.img-lg {
+ width: 120px;
+ height: 120px;
+}
+
+.avatar-upload-preview {
+ position: absolute;
+ top: 50%;
+ transform: translate(50%, -50%);
+ width: 200px;
+ height: 200px;
+ border-radius: 50%;
+ box-shadow: 0 0 4px #ccc;
+ overflow: hidden;
+}
+
+/* 拖拽列样式 */
+.sortable-ghost{
+ opacity: .8;
+ color: #fff!important;
+ background: #42b983!important;
+}
+
+.top-right-btn {
+ position: relative;
+ float: right;
+}
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
new file mode 100644
index 0000000..2f368c3
--- /dev/null
+++ b/src/assets/styles/sidebar.scss
@@ -0,0 +1,223 @@
+#app {
+
+ .main-container {
+ min-height: 100%;
+ transition: margin-left .28s;
+ margin-left: $sideBarWidth;
+ position: relative;
+ }
+
+ .sidebar-container {
+ -webkit-transition: width .28s;
+ transition: width 0.28s;
+ width: $sideBarWidth !important;
+ background-color: $menuBg;
+ height: 100%;
+ position: fixed;
+ font-size: 0px;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1001;
+ overflow: hidden;
+ -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
+ box-shadow: 2px 0 6px rgba(0,21,41,.35);
+
+ // 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: 0px;
+ }
+
+ .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;
+ }
+
+ .el-menu-item, .el-submenu__title {
+ overflow: hidden !important;
+ text-overflow: ellipsis !important;
+ white-space: nowrap !important;
+ }
+
+ // menu hover
+ .submenu-title-noDropdown,
+ .el-submenu__title {
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+ }
+ }
+
+ & .theme-dark .is-active > .el-submenu__title {
+ color: $subMenuActiveText !important;
+ }
+
+ & .nest-menu .el-submenu>.el-submenu__title,
+ & .el-submenu .el-menu-item {
+ min-width: $sideBarWidth !important;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.06) !important;
+ }
+ }
+
+ & .theme-dark .nest-menu .el-submenu>.el-submenu__title,
+ & .theme-dark .el-submenu .el-menu-item {
+ 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-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: 0px;
+ }
+
+ .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: rgba(0, 0, 0, 0.06) !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..452a1ec
--- /dev/null
+++ b/src/assets/styles/variables.scss
@@ -0,0 +1,44 @@
+// 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;
+$sidebarTitle: #ffffff;
+
+$menuLightBg:#ffffff;
+$menuLightHover:#f0f1f5;
+$sidebarLightTitle: #001529;
+
+$subMenuBg:#1f2d3d;
+$subMenuHover:#001528;
+
+$sideBarWidth: 200px;
+
+// 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;
+ menuLightBg: $menuLightBg;
+ menuLightHover: $menuLightHover;
+ subMenuBg: $subMenuBg;
+ subMenuHover: $subMenuHover;
+ sideBarWidth: $sideBarWidth;
+ sidebarTitle: $sidebarTitle;
+ sidebarLightTitle: $sidebarLightTitle
+}
diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue
new file mode 100644
index 0000000..b313fdd
--- /dev/null
+++ b/src/components/Breadcrumb/index.vue
@@ -0,0 +1,74 @@
+
+
+
+
+ {{ item.meta.title }}
+ {{ item.meta.title }}
+
+
+
+
+
+
+
+
diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue
new file mode 100644
index 0000000..7431bbb
--- /dev/null
+++ b/src/components/DictTag/index.vue
@@ -0,0 +1,51 @@
+
+
+
+
+ {{ item.dictLabel }}
+
+ {{ item.dictLabel }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue
new file mode 100644
index 0000000..d63a48d
--- /dev/null
+++ b/src/components/Editor/index.vue
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+
diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue
new file mode 100644
index 0000000..a9bdc01
--- /dev/null
+++ b/src/components/FileUpload/index.vue
@@ -0,0 +1,179 @@
+
+
+
+
+ 选取文件
+
+
+ 请上传
+ 大小不超过 {{ fileSize }}MB
+ 格式为 {{ fileType.join("/") }}
+ 的文件
+
+
+
+
+
+
+
+ {{ getFileName(file.name) }}
+
+
+ 删除
+
+
+
+
+
+
+
+
+
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..ce9f305
--- /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..b0ec9fa
--- /dev/null
+++ b/src/components/IconSelect/index.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
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/ImagePreview/index.vue b/src/components/ImagePreview/index.vue
new file mode 100644
index 0000000..f7b3988
--- /dev/null
+++ b/src/components/ImagePreview/index.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue
new file mode 100644
index 0000000..d3b2626
--- /dev/null
+++ b/src/components/ImageUpload/index.vue
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+ 请上传
+ 大小不超过 {{ fileSize }}MB
+ 格式为 {{ fileType.join("/") }}
+ 的文件
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue
new file mode 100644
index 0000000..5e5d890
--- /dev/null
+++ b/src/components/Pagination/index.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
diff --git a/src/components/PanThumb/index.vue b/src/components/PanThumb/index.vue
new file mode 100644
index 0000000..1bcf417
--- /dev/null
+++ b/src/components/PanThumb/index.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue
new file mode 100644
index 0000000..7bf6148
--- /dev/null
+++ b/src/components/ParentView/index.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/components/RightPanel/index.vue b/src/components/RightPanel/index.vue
new file mode 100644
index 0000000..fbf27eb
--- /dev/null
+++ b/src/components/RightPanel/index.vue
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue
new file mode 100644
index 0000000..e3e1286
--- /dev/null
+++ b/src/components/RightToolbar/index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RuoYi/Doc/index.vue b/src/components/RuoYi/Doc/index.vue
new file mode 100644
index 0000000..a6187f3
--- /dev/null
+++ b/src/components/RuoYi/Doc/index.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/RuoYi/Git/index.vue b/src/components/RuoYi/Git/index.vue
new file mode 100644
index 0000000..1d09a77
--- /dev/null
+++ b/src/components/RuoYi/Git/index.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Screenfull/index.vue b/src/components/Screenfull/index.vue
new file mode 100644
index 0000000..d4e539c
--- /dev/null
+++ b/src/components/Screenfull/index.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue
new file mode 100644
index 0000000..e88065b
--- /dev/null
+++ b/src/components/SizeSelect/index.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+ {{
+ item.label }}
+
+
+
+
+
+
diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue
new file mode 100644
index 0000000..e4bf5ad
--- /dev/null
+++ b/src/components/SvgIcon/index.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ThemePicker/index.vue b/src/components/ThemePicker/index.vue
new file mode 100644
index 0000000..b0df471
--- /dev/null
+++ b/src/components/ThemePicker/index.vue
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+
diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue
new file mode 100644
index 0000000..d89930a
--- /dev/null
+++ b/src/components/TopNav/index.vue
@@ -0,0 +1,182 @@
+
+
+
+
+ {{ item.meta.title }}
+
+
+
+
+ 更多菜单
+
+
+ {{ item.meta.title }}
+
+
+
+
+
+
+
+
diff --git a/src/components/WangEdit/index.vue b/src/components/WangEdit/index.vue
new file mode 100644
index 0000000..10eabda
--- /dev/null
+++ b/src/components/WangEdit/index.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
diff --git a/src/components/ZlDictTag/index.vue b/src/components/ZlDictTag/index.vue
new file mode 100644
index 0000000..d8d7c9c
--- /dev/null
+++ b/src/components/ZlDictTag/index.vue
@@ -0,0 +1,52 @@
+
+
+
+
+ {{ item.label }}
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue
new file mode 100644
index 0000000..426857f
--- /dev/null
+++ b/src/components/iFrame/index.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
diff --git a/src/constant/city.js b/src/constant/city.js
new file mode 100644
index 0000000..70fe7f2
--- /dev/null
+++ b/src/constant/city.js
@@ -0,0 +1,3413 @@
+export const cityList = [
+ {
+ "citycode": [],
+ "adcode": "410000",
+ "name": "河南省",
+ "center": "113.753094,34.767052",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0379",
+ "adcode": "410300",
+ "name": "洛阳市",
+ "center": "112.453895,34.619702",
+ "level": "city",
+ },
+ {
+ "citycode": "0398",
+ "adcode": "411200",
+ "name": "三门峡市",
+ "center": "111.200482,34.773196",
+ "level": "city",
+ },
+ {
+ "citycode": "0395",
+ "adcode": "411100",
+ "name": "漯河市",
+ "center": "114.0166,33.58038",
+ "level": "city",
+ },
+ {
+ "citycode": "0374",
+ "adcode": "411000",
+ "name": "许昌市",
+ "center": "113.852004,34.03732",
+ "level": "city",
+ },
+ {
+ "citycode": "0376",
+ "adcode": "411500",
+ "name": "信阳市",
+ "center": "114.091058,32.148624",
+ "level": "city",
+ },
+ {
+ "citycode": "0377",
+ "adcode": "411300",
+ "name": "南阳市",
+ "center": "112.528549,32.990218",
+ "level": "city",
+ },
+ {
+ "citycode": "0396",
+ "adcode": "411700",
+ "name": "驻马店市",
+ "center": "114.021988,33.014038",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0394",
+ "adcode": "411600",
+ "name": "周口市",
+ "center": "114.701222,33.634652",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0372",
+ "adcode": "410500",
+ "name": "安阳市",
+ "center": "114.39248,36.098779",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0392",
+ "adcode": "410600",
+ "name": "鹤壁市",
+ "center": "114.297305,35.748329",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0393",
+ "adcode": "410900",
+ "name": "濮阳市",
+ "center": "115.029246,35.762731",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1391",
+ "adcode": "419001",
+ "name": "济源市",
+ "center": "112.602347,35.069057",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0375",
+ "adcode": "410400",
+ "name": "平顶山市",
+ "center": "113.192595,33.766554",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0378",
+ "adcode": "410200",
+ "name": "开封市",
+ "center": "114.314278,34.798083",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0371",
+ "adcode": "410100",
+ "name": "郑州市",
+ "center": "113.625351,34.746303",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0370",
+ "adcode": "411400",
+ "name": "商丘市",
+ "center": "115.656358,34.415165",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0391",
+ "adcode": "410800",
+ "name": "焦作市",
+ "center": "113.241902,35.215726",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0373",
+ "adcode": "410700",
+ "name": "新乡市",
+ "center": "113.92679,35.303589",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "440000",
+ "name": "广东省",
+ "center": "113.266887,23.133306",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0754",
+ "adcode": "440500",
+ "name": "汕头市",
+ "center": "116.681956,23.354152",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0757",
+ "adcode": "440600",
+ "name": "佛山市",
+ "center": "113.121586,23.021351",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0758",
+ "adcode": "441200",
+ "name": "肇庆市",
+ "center": "112.465245,23.047747",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0752",
+ "adcode": "441300",
+ "name": "惠州市",
+ "center": "114.415587,23.112368",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0755",
+ "adcode": "440300",
+ "name": "深圳市",
+ "center": "114.057939,22.543527",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0756",
+ "adcode": "440400",
+ "name": "珠海市",
+ "center": "113.576892,22.271644",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0759",
+ "adcode": "440800",
+ "name": "湛江市",
+ "center": "110.357538,21.270108",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0750",
+ "adcode": "440700",
+ "name": "江门市",
+ "center": "113.081548,22.578948",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0662",
+ "adcode": "441700",
+ "name": "阳江市",
+ "center": "111.98343,21.856853",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0668",
+ "adcode": "440900",
+ "name": "茂名市",
+ "center": "110.925533,21.662728",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0660",
+ "adcode": "441500",
+ "name": "汕尾市",
+ "center": "115.375557,22.787204",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0766",
+ "adcode": "445300",
+ "name": "云浮市",
+ "center": "112.044524,22.915163",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0762",
+ "adcode": "441600",
+ "name": "河源市",
+ "center": "114.700215,23.744276",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0768",
+ "adcode": "445100",
+ "name": "潮州市",
+ "center": "116.621901,23.657662",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0663",
+ "adcode": "445200",
+ "name": "揭阳市",
+ "center": "116.372732,23.550968",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0751",
+ "adcode": "440200",
+ "name": "韶关市",
+ "center": "113.597324,24.810977",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0763",
+ "adcode": "441800",
+ "name": "清远市",
+ "center": "113.056098,23.682064",
+ "level": "city",
+
+ },
+ {
+ "citycode": "020",
+ "adcode": "440100",
+ "name": "广州市",
+ "center": "113.264499,23.130061",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0760",
+ "adcode": "442000",
+ "name": "中山市",
+ "center": "113.392517,22.517024",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0769",
+ "adcode": "441900",
+ "name": "东莞市",
+ "center": "113.751884,23.021016",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0753",
+ "adcode": "441400",
+ "name": "梅州市",
+ "center": "116.122046,24.288832",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "150000",
+ "name": "内蒙古自治区",
+ "center": "111.765226,40.818233",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0473",
+ "adcode": "150300",
+ "name": "乌海市",
+ "center": "106.79415,39.655048",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0478",
+ "adcode": "150800",
+ "name": "巴彦淖尔市",
+ "center": "107.387767,40.742987",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0472",
+ "adcode": "150200",
+ "name": "包头市",
+ "center": "109.95315,40.621327",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0470",
+ "adcode": "150700",
+ "name": "呼伦贝尔市",
+ "center": "119.77845,49.166536",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0483",
+ "adcode": "152900",
+ "name": "阿拉善盟",
+ "center": "105.729135,38.851554",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0482",
+ "adcode": "152200",
+ "name": "兴安盟",
+ "center": "122.037796,46.082373",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0471",
+ "adcode": "150100",
+ "name": "呼和浩特市",
+ "center": "111.748814,40.842127",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0474",
+ "adcode": "150900",
+ "name": "乌兰察布市",
+ "center": "113.132227,40.994526",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0477",
+ "adcode": "150600",
+ "name": "鄂尔多斯市",
+ "center": "109.782473,39.608744",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0479",
+ "adcode": "152500",
+ "name": "锡林郭勒盟",
+ "center": "116.047387,43.933212",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0475",
+ "adcode": "150500",
+ "name": "通辽市",
+ "center": "122.243309,43.653566",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0476",
+ "adcode": "150400",
+ "name": "赤峰市",
+ "center": "118.887613,42.256876",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "230000",
+ "name": "黑龙江省",
+ "center": "126.661998,45.742253",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0457",
+ "adcode": "232700",
+ "name": "大兴安岭地区",
+ "center": "124.11786,50.41129",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0468",
+ "adcode": "230400",
+ "name": "鹤岗市",
+ "center": "130.297687,47.350659",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0464",
+ "adcode": "230900",
+ "name": "七台河市",
+ "center": "131.003015,45.771178",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0451",
+ "adcode": "230100",
+ "name": "哈尔滨市",
+ "center": "126.53505,45.802981",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0454",
+ "adcode": "230800",
+ "name": "佳木斯市",
+ "center": "130.318916,46.800002",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0469",
+ "adcode": "230500",
+ "name": "双鸭山市",
+ "center": "131.141563,46.676157",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0456",
+ "adcode": "231100",
+ "name": "黑河市",
+ "center": "127.528226,50.244887",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0453",
+ "adcode": "231000",
+ "name": "牡丹江市",
+ "center": "129.632928,44.551486",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0455",
+ "adcode": "231200",
+ "name": "绥化市",
+ "center": "126.968714,46.654147",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0458",
+ "adcode": "230700",
+ "name": "伊春市",
+ "center": "128.840863,47.728332",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0459",
+ "adcode": "230600",
+ "name": "大庆市",
+ "center": "125.104078,46.589498",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0467",
+ "adcode": "230300",
+ "name": "鸡西市",
+ "center": "130.969385,45.295087",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0452",
+ "adcode": "230200",
+ "name": "齐齐哈尔市",
+ "center": "123.918193,47.354892",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "650000",
+ "name": "新疆维吾尔自治区",
+ "center": "87.628579,43.793301",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "1906",
+ "adcode": "659005",
+ "name": "北屯市",
+ "center": "87.834419,47.326733",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1996",
+ "adcode": "659006",
+ "name": "铁门关市",
+ "center": "85.670291,41.862997",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1999",
+ "adcode": "659008",
+ "name": "可克达拉市",
+ "center": "80.994153,43.940381",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1909",
+ "adcode": "659007",
+ "name": "双河市",
+ "center": "82.35365587,44.84052409",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0909",
+ "adcode": "652700",
+ "name": "博尔塔拉蒙古自治州",
+ "center": "82.066363,44.906039",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0901",
+ "adcode": "654200",
+ "name": "塔城地区",
+ "center": "82.980316,46.745364",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0903",
+ "adcode": "653200",
+ "name": "和田地区",
+ "center": "79.921646,37.114406",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1903",
+ "adcode": "659009",
+ "name": "昆玉市",
+ "center": "79.270193,37.215372",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0906",
+ "adcode": "654300",
+ "name": "阿勒泰地区",
+ "center": "88.141253,47.844924",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0993",
+ "adcode": "659001",
+ "name": "石河子市",
+ "center": "86.080397,44.305368",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0994",
+ "adcode": "652300",
+ "name": "昌吉回族自治州",
+ "center": "87.308995,44.011044",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1994",
+ "adcode": "659004",
+ "name": "五家渠市",
+ "center": "87.542852,44.166489",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0996",
+ "adcode": "652800",
+ "name": "巴音郭楞蒙古自治州",
+ "center": "86.145298,41.764115",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0999",
+ "adcode": "654000",
+ "name": "伊犁哈萨克自治州",
+ "center": "81.323691,43.917106",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1997",
+ "adcode": "659002",
+ "name": "阿拉尔市",
+ "center": "81.280532,40.547205",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0908",
+ "adcode": "653000",
+ "name": "克孜勒苏柯尔克孜自治州",
+ "center": "76.167327,39.714734",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0998",
+ "adcode": "653100",
+ "name": "喀什地区",
+ "center": "75.989746,39.470492",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0990",
+ "adcode": "650200",
+ "name": "克拉玛依市",
+ "center": "84.889239,45.577712",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0995",
+ "adcode": "650400",
+ "name": "吐鲁番市",
+ "center": "89.190374,42.950736",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0902",
+ "adcode": "650500",
+ "name": "哈密市",
+ "center": "93.515053,42.819346",
+ "level": "city",
+
+ },
+ {
+ "citycode": "2940",
+ "adcode": "659011",
+ "name": "新星市",
+ "center": "93.74831,42.797043",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1998",
+ "adcode": "659003",
+ "name": "图木舒克市",
+ "center": "79.074965,39.867776",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0997",
+ "adcode": "652900",
+ "name": "阿克苏地区",
+ "center": "80.265068,41.170712",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0991",
+ "adcode": "650100",
+ "name": "乌鲁木齐市",
+ "center": "87.616824,43.825377",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0992",
+ "adcode": "659010",
+ "name": "胡杨河市",
+ "center": "84.827592,44.692894",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "420000",
+ "name": "湖北省",
+ "center": "114.341552,30.546222",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0710",
+ "adcode": "420600",
+ "name": "襄阳市",
+ "center": "112.121743,32.010161",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0719",
+ "adcode": "420300",
+ "name": "十堰市",
+ "center": "110.798921,32.629057",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0717",
+ "adcode": "420500",
+ "name": "宜昌市",
+ "center": "111.286962,30.69217",
+ "level": "city",
+
+ },
+ {
+ "citycode": "027",
+ "adcode": "420100",
+ "name": "武汉市",
+ "center": "114.304569,30.593354",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0713",
+ "adcode": "421100",
+ "name": "黄冈市",
+ "center": "114.872425,30.453722",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1728",
+ "adcode": "429006",
+ "name": "天门市",
+ "center": "113.166545,30.663706",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0728",
+ "adcode": "429004",
+ "name": "仙桃市",
+ "center": "113.442973,30.328407",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0724",
+ "adcode": "420800",
+ "name": "荆门市",
+ "center": "112.199009,31.035445",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0712",
+ "adcode": "420900",
+ "name": "孝感市",
+ "center": "113.956962,30.918311",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0718",
+ "adcode": "422800",
+ "name": "恩施土家族苗族自治州",
+ "center": "109.488076,30.272104",
+ "level": "city",
+
+ },
+ {
+ "citycode": "2728",
+ "adcode": "429005",
+ "name": "潜江市",
+ "center": "112.900279,30.401954",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0716",
+ "adcode": "421000",
+ "name": "荆州市",
+ "center": "112.24143,30.336282",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0715",
+ "adcode": "421200",
+ "name": "咸宁市",
+ "center": "114.322601,29.84135",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1719",
+ "adcode": "429021",
+ "name": "神农架林区",
+ "center": "110.675879,31.745103",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0722",
+ "adcode": "421300",
+ "name": "随州市",
+ "center": "113.382324,31.690275",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0714",
+ "adcode": "420200",
+ "name": "黄石市",
+ "center": "115.038999,30.201082",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0711",
+ "adcode": "420700",
+ "name": "鄂州市",
+ "center": "114.894909,30.391461",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "210000",
+ "name": "辽宁省",
+ "center": "123.435093,41.836743",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0429",
+ "adcode": "211400",
+ "name": "葫芦岛市",
+ "center": "120.836783,40.710974",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0411",
+ "adcode": "210200",
+ "name": "大连市",
+ "center": "121.614786,38.913962",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0415",
+ "adcode": "210600",
+ "name": "丹东市",
+ "center": "124.354419,40.000646",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0416",
+ "adcode": "210700",
+ "name": "锦州市",
+ "center": "121.126859,41.096114",
+ "level": "city",
+
+ },
+ {
+ "citycode": "024",
+ "adcode": "210100",
+ "name": "沈阳市",
+ "center": "123.464675,41.677576",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0410",
+ "adcode": "211200",
+ "name": "铁岭市",
+ "center": "123.726008,42.223709",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0418",
+ "adcode": "210900",
+ "name": "阜新市",
+ "center": "121.670052,42.022028",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0414",
+ "adcode": "210500",
+ "name": "本溪市",
+ "center": "123.684984,41.486834",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0419",
+ "adcode": "211000",
+ "name": "辽阳市",
+ "center": "123.239669,41.267396",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0413",
+ "adcode": "210400",
+ "name": "抚顺市",
+ "center": "123.957053,41.881311",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0417",
+ "adcode": "210800",
+ "name": "营口市",
+ "center": "122.219148,40.625027",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0421",
+ "adcode": "211300",
+ "name": "朝阳市",
+ "center": "120.488801,41.601855",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0412",
+ "adcode": "210300",
+ "name": "鞍山市",
+ "center": "122.994183,41.108239",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0427",
+ "adcode": "211100",
+ "name": "盘锦市",
+ "center": "122.170729,40.71956",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "370000",
+ "name": "山东省",
+ "center": "117.020725,36.670201",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0533",
+ "adcode": "370300",
+ "name": "淄博市",
+ "center": "118.054994,36.813787",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0546",
+ "adcode": "370500",
+ "name": "东营市",
+ "center": "118.674633,37.433992",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0543",
+ "adcode": "371600",
+ "name": "滨州市",
+ "center": "117.970731,37.382687",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0535",
+ "adcode": "370600",
+ "name": "烟台市",
+ "center": "121.447755,37.464551",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0631",
+ "adcode": "371000",
+ "name": "威海市",
+ "center": "122.120519,37.513315",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0635",
+ "adcode": "371500",
+ "name": "聊城市",
+ "center": "115.985238,36.455857",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0633",
+ "adcode": "371100",
+ "name": "日照市",
+ "center": "119.52685,35.416912",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0536",
+ "adcode": "370700",
+ "name": "潍坊市",
+ "center": "119.161721,36.707668",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0530",
+ "adcode": "371700",
+ "name": "菏泽市",
+ "center": "115.479646,35.234309",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0539",
+ "adcode": "371300",
+ "name": "临沂市",
+ "center": "118.356464,35.103771",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0531",
+ "adcode": "370100",
+ "name": "济南市",
+ "center": "117.120128,36.652069",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0534",
+ "adcode": "371400",
+ "name": "德州市",
+ "center": "116.359244,37.436492",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0532",
+ "adcode": "370200",
+ "name": "青岛市",
+ "center": "120.382665,36.066938",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0538",
+ "adcode": "370900",
+ "name": "泰安市",
+ "center": "117.086963,36.201784",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0537",
+ "adcode": "370800",
+ "name": "济宁市",
+ "center": "116.587116,35.415117",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0632",
+ "adcode": "370400",
+ "name": "枣庄市",
+ "center": "117.323759,34.810858",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "610000",
+ "name": "陕西省",
+ "center": "108.953939,34.266611",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0914",
+ "adcode": "611000",
+ "name": "商洛市",
+ "center": "109.918646,33.873358",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0916",
+ "adcode": "610700",
+ "name": "汉中市",
+ "center": "107.02319,33.066373",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0919",
+ "adcode": "610200",
+ "name": "铜川市",
+ "center": "108.945116,34.897133",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0911",
+ "adcode": "610600",
+ "name": "延安市",
+ "center": "109.49468,36.650109",
+ "level": "city",
+
+ },
+ {
+ "citycode": "029",
+ "adcode": "610100",
+ "name": "西安市",
+ "center": "108.939645,34.343207",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0913",
+ "adcode": "610500",
+ "name": "渭南市",
+ "center": "109.470962,34.520632",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0915",
+ "adcode": "610900",
+ "name": "安康市",
+ "center": "109.029017,32.685435",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0912",
+ "adcode": "610800",
+ "name": "榆林市",
+ "center": "109.734104,38.28576",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0910",
+ "adcode": "610400",
+ "name": "咸阳市",
+ "center": "108.708837,34.329896",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0917",
+ "adcode": "610300",
+ "name": "宝鸡市",
+ "center": "107.237682,34.362862",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": "021",
+ "adcode": "310000",
+ "name": "上海市",
+ "center": "121.473667,31.230525",
+ "level": "province",
+ },
+ {
+ "citycode": [],
+ "adcode": "520000",
+ "name": "贵州省",
+ "center": "106.705251,26.600328",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0852",
+ "adcode": "520300",
+ "name": "遵义市",
+ "center": "107.031922,27.721931",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0856",
+ "adcode": "520600",
+ "name": "铜仁市",
+ "center": "109.189528,27.731555",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0858",
+ "adcode": "520200",
+ "name": "六盘水市",
+ "center": "104.830357,26.592538",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0854",
+ "adcode": "522700",
+ "name": "黔南布依族苗族自治州",
+ "center": "107.522303,26.253136",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0853",
+ "adcode": "520400",
+ "name": "安顺市",
+ "center": "105.9476,26.253103",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0859",
+ "adcode": "522300",
+ "name": "黔西南布依族苗族自治州",
+ "center": "104.906419,25.087733",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0855",
+ "adcode": "522600",
+ "name": "黔东南苗族侗族自治州",
+ "center": "107.982838,26.583759",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0857",
+ "adcode": "520500",
+ "name": "毕节市",
+ "center": "105.291544,27.283615",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0851",
+ "adcode": "520100",
+ "name": "贵阳市",
+ "center": "106.628201,26.646694",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": "023",
+ "adcode": "500000",
+ "name": "重庆市",
+ "center": "106.550483,29.563707",
+ "level": "province"
+ },
+ {
+ "citycode": [],
+ "adcode": "340000",
+ "name": "安徽省",
+ "center": "117.330139,31.734559",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0562",
+ "adcode": "340700",
+ "name": "铜陵市",
+ "center": "117.811298,30.945214",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0566",
+ "adcode": "341700",
+ "name": "池州市",
+ "center": "117.495663,30.674264",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0556",
+ "adcode": "340800",
+ "name": "安庆市",
+ "center": "117.115349,30.531828",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0561",
+ "adcode": "340600",
+ "name": "淮北市",
+ "center": "116.798362,33.956264",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0555",
+ "adcode": "340500",
+ "name": "马鞍山市",
+ "center": "118.50685,31.668765",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0553",
+ "adcode": "340200",
+ "name": "芜湖市",
+ "center": "118.433065,31.352614",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0564",
+ "adcode": "341500",
+ "name": "六安市",
+ "center": "116.519729,31.735892",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0558",
+ "adcode": "341600",
+ "name": "亳州市",
+ "center": "115.778588,33.846285",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0559",
+ "adcode": "341000",
+ "name": "黄山市",
+ "center": "118.337643,29.714886",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0552",
+ "adcode": "340300",
+ "name": "蚌埠市",
+ "center": "117.388566,32.91682",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0563",
+ "adcode": "341800",
+ "name": "宣城市",
+ "center": "118.759127,30.939278",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0550",
+ "adcode": "341100",
+ "name": "滁州市",
+ "center": "118.333439,32.255904",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0557",
+ "adcode": "341300",
+ "name": "宿州市",
+ "center": "116.96419,33.647726",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1558",
+ "adcode": "341200",
+ "name": "阜阳市",
+ "center": "115.814252,32.891032",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0554",
+ "adcode": "340400",
+ "name": "淮南市",
+ "center": "117.018603,32.585384",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0551",
+ "adcode": "340100",
+ "name": "合肥市",
+ "center": "117.227267,31.820567",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "350000",
+ "name": "福建省",
+ "center": "119.296194,26.101082",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0591",
+ "adcode": "350100",
+ "name": "福州市",
+ "center": "119.296411,26.074286",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0593",
+ "adcode": "350900",
+ "name": "宁德市",
+ "center": "119.547729,26.666222",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0594",
+ "adcode": "350300",
+ "name": "莆田市",
+ "center": "119.007662,25.454202",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0595",
+ "adcode": "350500",
+ "name": "泉州市",
+ "center": "118.675724,24.874452",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0592",
+ "adcode": "350200",
+ "name": "厦门市",
+ "center": "118.08891,24.479627",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0596",
+ "adcode": "350600",
+ "name": "漳州市",
+ "center": "117.647298,24.515297",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0597",
+ "adcode": "350800",
+ "name": "龙岩市",
+ "center": "117.017362,25.075884",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0599",
+ "adcode": "350700",
+ "name": "南平市",
+ "center": "118.081325,27.382829",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0598",
+ "adcode": "350400",
+ "name": "三明市",
+ "center": "117.638919,26.263455",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "430000",
+ "name": "湖南省",
+ "center": "112.982951,28.116007",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0730",
+ "adcode": "430600",
+ "name": "岳阳市",
+ "center": "113.128922,29.35648",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0744",
+ "adcode": "430800",
+ "name": "张家界市",
+ "center": "110.478887,29.117343",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0745",
+ "adcode": "431200",
+ "name": "怀化市",
+ "center": "110.001598,27.569813",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0743",
+ "adcode": "433100",
+ "name": "湘西土家族苗族自治州",
+ "center": "109.737428,28.312592",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0736",
+ "adcode": "430700",
+ "name": "常德市",
+ "center": "111.69905,29.031446",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0737",
+ "adcode": "430900",
+ "name": "益阳市",
+ "center": "112.355994,28.554853",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0739",
+ "adcode": "430500",
+ "name": "邵阳市",
+ "center": "111.467855,27.239528",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0734",
+ "adcode": "430400",
+ "name": "衡阳市",
+ "center": "112.572016,26.894216",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0731",
+ "adcode": "430100",
+ "name": "长沙市",
+ "center": "112.938882,28.228304",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0732",
+ "adcode": "430300",
+ "name": "湘潭市",
+ "center": "112.945439,27.83136",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0733",
+ "adcode": "430200",
+ "name": "株洲市",
+ "center": "113.132783,27.828862",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0738",
+ "adcode": "431300",
+ "name": "娄底市",
+ "center": "111.994468,27.699838",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0746",
+ "adcode": "431100",
+ "name": "永州市",
+ "center": "111.613482,26.419861",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0735",
+ "adcode": "431000",
+ "name": "郴州市",
+ "center": "113.015517,25.770117",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "460000",
+ "name": "海南省",
+ "center": "110.348781,20.018639",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "1896",
+ "adcode": "469024",
+ "name": "临高县",
+ "center": "109.690508,19.912025",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1892",
+ "adcode": "469022",
+ "name": "屯昌县",
+ "center": "110.101667,19.351662",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0802",
+ "adcode": "469025",
+ "name": "白沙黎族自治县",
+ "center": "109.4429,19.221641",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1894",
+ "adcode": "469002",
+ "name": "琼海市",
+ "center": "110.474524,19.259112",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1899",
+ "adcode": "469030",
+ "name": "琼中黎族苗族自治县",
+ "center": "109.838423,19.03327",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0807",
+ "adcode": "469007",
+ "name": "东方市",
+ "center": "108.651829,19.095187",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1898",
+ "adcode": "469006",
+ "name": "万宁市",
+ "center": "110.392605,18.793697",
+ "level": "city",
+
+ },
+ {
+ "citycode": "2802",
+ "adcode": "469027",
+ "name": "乐东黎族自治县",
+ "center": "109.173384,18.750063",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0809",
+ "adcode": "469028",
+ "name": "陵水黎族自治县",
+ "center": "110.037553,18.506045",
+ "level": "city",
+
+ },
+ {
+ "citycode": "2898",
+ "adcode": "460300",
+ "name": "三沙市",
+ "center": "112.338649,16.831004",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1893",
+ "adcode": "469005",
+ "name": "文昌市",
+ "center": "110.797473,19.544234",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0805",
+ "adcode": "460400",
+ "name": "儋州市",
+ "center": "109.580812,19.520948",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0899",
+ "adcode": "460200",
+ "name": "三亚市",
+ "center": "109.511709,18.252865",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0801",
+ "adcode": "469029",
+ "name": "保亭黎族苗族自治县",
+ "center": "109.700279,18.640339",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1897",
+ "adcode": "469001",
+ "name": "五指山市",
+ "center": "109.516784,18.774827",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0898",
+ "adcode": "460100",
+ "name": "海口市",
+ "center": "110.198418,20.045805",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0803",
+ "adcode": "469026",
+ "name": "昌江黎族自治县",
+ "center": "109.055783,19.298139",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0806",
+ "adcode": "469021",
+ "name": "定安县",
+ "center": "110.358001,19.681215",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0804",
+ "adcode": "469023",
+ "name": "澄迈县",
+ "center": "110.007497,19.738885",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "320000",
+ "name": "江苏省",
+ "center": "118.763563,32.061377",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0518",
+ "adcode": "320700",
+ "name": "连云港市",
+ "center": "119.221487,34.596639",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0513",
+ "adcode": "320600",
+ "name": "南通市",
+ "center": "120.894522,31.981269",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0527",
+ "adcode": "321300",
+ "name": "宿迁市",
+ "center": "118.275228,33.963186",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0517",
+ "adcode": "320800",
+ "name": "淮安市",
+ "center": "119.113166,33.551495",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0511",
+ "adcode": "321100",
+ "name": "镇江市",
+ "center": "119.424441,32.188141",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0514",
+ "adcode": "321000",
+ "name": "扬州市",
+ "center": "119.412834,32.394404",
+ "level": "city",
+
+ },
+ {
+ "citycode": "025",
+ "adcode": "320100",
+ "name": "南京市",
+ "center": "118.796624,32.059344",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0515",
+ "adcode": "320900",
+ "name": "盐城市",
+ "center": "120.16263,33.348176",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0516",
+ "adcode": "320300",
+ "name": "徐州市",
+ "center": "117.283752,34.204224",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0523",
+ "adcode": "321200",
+ "name": "泰州市",
+ "center": "119.922883,32.456692",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0512",
+ "adcode": "320500",
+ "name": "苏州市",
+ "center": "120.585294,31.299758",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0510",
+ "adcode": "320200",
+ "name": "无锡市",
+ "center": "120.311889,31.491064",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0519",
+ "adcode": "320400",
+ "name": "常州市",
+ "center": "119.974092,31.811313",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "630000",
+ "name": "青海省",
+ "center": "101.780482,36.622538",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0972",
+ "adcode": "630200",
+ "name": "海东市",
+ "center": "102.41064,36.473448",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0974",
+ "adcode": "632500",
+ "name": "海南藏族自治州",
+ "center": "100.622647,36.296399",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0977",
+ "adcode": "632800",
+ "name": "海西蒙古族藏族自治州",
+ "center": "97.33197,37.348114",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0976",
+ "adcode": "632700",
+ "name": "玉树藏族自治州",
+ "center": "97.006292,33.006308",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0973",
+ "adcode": "632300",
+ "name": "黄南藏族自治州",
+ "center": "102.015397,35.519317",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0975",
+ "adcode": "632600",
+ "name": "果洛藏族自治州",
+ "center": "100.245161,34.472179",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0971",
+ "adcode": "630100",
+ "name": "西宁市",
+ "center": "101.777795,36.616621",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0970",
+ "adcode": "632200",
+ "name": "海北藏族自治州",
+ "center": "100.900944,36.954612",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "450000",
+ "name": "广西壮族自治区",
+ "center": "108.327537,22.816659",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0776",
+ "adcode": "451000",
+ "name": "百色市",
+ "center": "106.61869,23.90307",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0777",
+ "adcode": "450700",
+ "name": "钦州市",
+ "center": "108.654355,21.980894",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0779",
+ "adcode": "450500",
+ "name": "北海市",
+ "center": "109.120248,21.481305",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0774",
+ "adcode": "450400",
+ "name": "梧州市",
+ "center": "111.279022,23.476733",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1771",
+ "adcode": "451400",
+ "name": "崇左市",
+ "center": "107.364973,22.377139",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0770",
+ "adcode": "450600",
+ "name": "防城港市",
+ "center": "108.35467,21.686732",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0771",
+ "adcode": "450100",
+ "name": "南宁市",
+ "center": "108.366407,22.8177",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1772",
+ "adcode": "451300",
+ "name": "来宾市",
+ "center": "109.221243,23.750105",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0773",
+ "adcode": "450300",
+ "name": "桂林市",
+ "center": "110.179752,25.235615",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1774",
+ "adcode": "451100",
+ "name": "贺州市",
+ "center": "111.567216,24.404182",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1755",
+ "adcode": "450800",
+ "name": "贵港市",
+ "center": "109.598903,23.11182",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0775",
+ "adcode": "450900",
+ "name": "玉林市",
+ "center": "110.18097,22.654001",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0778",
+ "adcode": "451200",
+ "name": "河池市",
+ "center": "108.63639,24.48523",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0772",
+ "adcode": "450200",
+ "name": "柳州市",
+ "center": "109.428071,24.326442",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "640000",
+ "name": "宁夏回族自治区",
+ "center": "106.258889,38.472273",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0954",
+ "adcode": "640400",
+ "name": "固原市",
+ "center": "106.24267,36.01628",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0952",
+ "adcode": "640200",
+ "name": "石嘴山市",
+ "center": "106.382792,38.984632",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0953",
+ "adcode": "640300",
+ "name": "吴忠市",
+ "center": "106.198613,37.997755",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0951",
+ "adcode": "640100",
+ "name": "银川市",
+ "center": "106.230977,38.487783",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1953",
+ "adcode": "640500",
+ "name": "中卫市",
+ "center": "105.19677,37.500185",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "330000",
+ "name": "浙江省",
+ "center": "120.152575,30.266619",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0580",
+ "adcode": "330900",
+ "name": "舟山市",
+ "center": "122.207395,29.985578",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0573",
+ "adcode": "330400",
+ "name": "嘉兴市",
+ "center": "120.755623,30.746814",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0574",
+ "adcode": "330200",
+ "name": "宁波市",
+ "center": "121.62454,29.860258",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0576",
+ "adcode": "331000",
+ "name": "台州市",
+ "center": "121.42079,28.655716",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0577",
+ "adcode": "330300",
+ "name": "温州市",
+ "center": "120.699279,27.993849",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0570",
+ "adcode": "330800",
+ "name": "衢州市",
+ "center": "118.859307,28.970229",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0572",
+ "adcode": "330500",
+ "name": "湖州市",
+ "center": "120.086881,30.894178",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0579",
+ "adcode": "330700",
+ "name": "金华市",
+ "center": "119.647265,29.079195",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0578",
+ "adcode": "331100",
+ "name": "丽水市",
+ "center": "119.923249,28.467694",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0575",
+ "adcode": "330600",
+ "name": "绍兴市",
+ "center": "120.582886,30.051549",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0571",
+ "adcode": "330100",
+ "name": "杭州市",
+ "center": "120.210792,30.246026",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "130000",
+ "name": "河北省",
+ "center": "114.530399,38.037707",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0315",
+ "adcode": "130200",
+ "name": "唐山市",
+ "center": "118.180149,39.63068",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0335",
+ "adcode": "130300",
+ "name": "秦皇岛市",
+ "center": "119.52022,39.888243",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0314",
+ "adcode": "130800",
+ "name": "承德市",
+ "center": "117.962749,40.952942",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0311",
+ "adcode": "130100",
+ "name": "石家庄市",
+ "center": "114.514976,38.042007",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0319",
+ "adcode": "130500",
+ "name": "邢台市",
+ "center": "114.49742,37.060227",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0316",
+ "adcode": "131000",
+ "name": "廊坊市",
+ "center": "116.683546,39.538304",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0310",
+ "adcode": "130400",
+ "name": "邯郸市",
+ "center": "114.53915,36.625849",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0312",
+ "adcode": "130600",
+ "name": "保定市",
+ "center": "115.464523,38.874476",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0318",
+ "adcode": "131100",
+ "name": "衡水市",
+ "center": "115.668987,37.739367",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0317",
+ "adcode": "130900",
+ "name": "沧州市",
+ "center": "116.838715,38.304676",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0313",
+ "adcode": "130700",
+ "name": "张家口市",
+ "center": "114.885895,40.768931",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810000",
+ "name": "香港特别行政区",
+ "center": "114.171203,22.277468",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "1852",
+ "adcode": "810015",
+ "name": "西贡区",
+ "center": "114.264645,22.31421306",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810013",
+ "name": "北区",
+ "center": "114.1473639,22.49610389",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810014",
+ "name": "大埔区",
+ "center": "114.1717431,22.44565306",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810016",
+ "name": "沙田区",
+ "center": "114.1953653,22.37953167",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810008",
+ "name": "黄大仙区",
+ "center": "114.2038856,22.33632056",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810018",
+ "name": "离岛区",
+ "center": "113.94612,22.28640778",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810006",
+ "name": "深水埗区",
+ "center": "114.1632417,22.33385417",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810011",
+ "name": "屯门区",
+ "center": "113.9765742,22.39384417",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810007",
+ "name": "九龙城区",
+ "center": "114.1928467,22.31251",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810009",
+ "name": "观塘区",
+ "center": "114.2140542,22.32083778",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810001",
+ "name": "中西区",
+ "center": "114.1543731,22.28198083",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810005",
+ "name": "油尖旺区",
+ "center": "114.1733317,22.31170389",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810003",
+ "name": "东区",
+ "center": "114.2260031,22.27969306",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810002",
+ "name": "湾仔区",
+ "center": "114.1829153,22.27638889",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810004",
+ "name": "南区",
+ "center": "114.1600117,22.24589667",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810012",
+ "name": "元朗区",
+ "center": "114.0324381,22.44142833",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810010",
+ "name": "荃湾区",
+ "center": "114.1210792,22.36830667",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1852",
+ "adcode": "810017",
+ "name": "葵青区",
+ "center": "114.1393194,22.36387667",
+ "level": "district",
+
+ }
+ ]
+ },
+ {
+ "citycode": "1886",
+ "adcode": "710000",
+ "name": "台湾省",
+ "center": "121.509062,25.044332",
+ "level": "province",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820000",
+ "name": "澳门特别行政区",
+ "center": "113.543076,22.186927",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "1853",
+ "adcode": "820008",
+ "name": "圣方济各堂区",
+ "center": "113.5599542,22.12348639",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820007",
+ "name": "路凼填海区",
+ "center": "113.5695992,22.13663",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820005",
+ "name": "风顺堂区",
+ "center": "113.5419278,22.18736806",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820006",
+ "name": "嘉模堂区",
+ "center": "113.5587044,22.15375944",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820001",
+ "name": "花地玛堂区",
+ "center": "113.5528956,22.20787",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820002",
+ "name": "花王堂区",
+ "center": "113.5489608,22.1992075",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820003",
+ "name": "望德堂区",
+ "center": "113.5501828,22.19372083",
+ "level": "district",
+
+ },
+ {
+ "citycode": "1853",
+ "adcode": "820004",
+ "name": "大堂区",
+ "center": "113.5536475,22.18853944",
+ "level": "district",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "620000",
+ "name": "甘肃省",
+ "center": "103.826777,36.060634",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0937",
+ "adcode": "620900",
+ "name": "酒泉市",
+ "center": "98.49432,39.733416",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1937",
+ "adcode": "620200",
+ "name": "嘉峪关市",
+ "center": "98.2882,39.77325",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0935",
+ "adcode": "620300",
+ "name": "金昌市",
+ "center": "102.187972,38.521468",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0931",
+ "adcode": "620100",
+ "name": "兰州市",
+ "center": "103.834228,36.060798",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0933",
+ "adcode": "620800",
+ "name": "平凉市",
+ "center": "106.664913,35.542417",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0936",
+ "adcode": "620700",
+ "name": "张掖市",
+ "center": "100.449858,38.924766",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0934",
+ "adcode": "621000",
+ "name": "庆阳市",
+ "center": "107.643433,35.709459",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0943",
+ "adcode": "620400",
+ "name": "白银市",
+ "center": "104.138872,36.545123",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1935",
+ "adcode": "620600",
+ "name": "武威市",
+ "center": "102.637821,37.92898",
+ "level": "city",
+
+ },
+ {
+ "citycode": "2935",
+ "adcode": "621200",
+ "name": "陇南市",
+ "center": "104.960296,33.370174",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0932",
+ "adcode": "621100",
+ "name": "定西市",
+ "center": "104.592342,35.607947",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0938",
+ "adcode": "620500",
+ "name": "天水市",
+ "center": "105.724828,34.581514",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0930",
+ "adcode": "622900",
+ "name": "临夏回族自治州",
+ "center": "103.210386,35.601792",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0941",
+ "adcode": "623000",
+ "name": "甘南藏族自治州",
+ "center": "102.911736,34.983266",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "510000",
+ "name": "四川省",
+ "center": "104.076452,30.651696",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0839",
+ "adcode": "510800",
+ "name": "广元市",
+ "center": "105.844004,32.435774",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0817",
+ "adcode": "511300",
+ "name": "南充市",
+ "center": "106.110565,30.837235",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0827",
+ "adcode": "511900",
+ "name": "巴中市",
+ "center": "106.747548,31.867853",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0838",
+ "adcode": "510600",
+ "name": "德阳市",
+ "center": "104.397795,31.127449",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0816",
+ "adcode": "510700",
+ "name": "绵阳市",
+ "center": "104.679127,31.467673",
+ "level": "city",
+
+ },
+ {
+ "citycode": "028",
+ "adcode": "510100",
+ "name": "成都市",
+ "center": "104.066301,30.572961",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0826",
+ "adcode": "511600",
+ "name": "广安市",
+ "center": "106.632647,30.456354",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0818",
+ "adcode": "511700",
+ "name": "达州市",
+ "center": "107.46778,31.209278",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0825",
+ "adcode": "510900",
+ "name": "遂宁市",
+ "center": "105.592602,30.53268",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0832",
+ "adcode": "512000",
+ "name": "资阳市",
+ "center": "104.627265,30.129236",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1833",
+ "adcode": "511400",
+ "name": "眉山市",
+ "center": "103.848417,30.077113",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1832",
+ "adcode": "511000",
+ "name": "内江市",
+ "center": "105.057992,29.58021",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0833",
+ "adcode": "511100",
+ "name": "乐山市",
+ "center": "103.766085,29.552275",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0813",
+ "adcode": "510300",
+ "name": "自贡市",
+ "center": "104.779307,29.33924",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0830",
+ "adcode": "510500",
+ "name": "泸州市",
+ "center": "105.441866,28.87098",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0831",
+ "adcode": "511500",
+ "name": "宜宾市",
+ "center": "104.642826,28.752354",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0834",
+ "adcode": "513400",
+ "name": "凉山彝族自治州",
+ "center": "102.267713,27.881396",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0812",
+ "adcode": "510400",
+ "name": "攀枝花市",
+ "center": "101.71846,26.582417",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0836",
+ "adcode": "513300",
+ "name": "甘孜藏族自治州",
+ "center": "101.96231,30.04952",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0837",
+ "adcode": "513200",
+ "name": "阿坝藏族羌族自治州",
+ "center": "102.224504,31.899427",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0835",
+ "adcode": "511800",
+ "name": "雅安市",
+ "center": "103.041538,30.009998",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": "022",
+ "adcode": "120000",
+ "name": "天津市",
+ "center": "117.201509,39.085318",
+ "level": "province",
+ },
+ {
+ "citycode": [],
+ "adcode": "360000",
+ "name": "江西省",
+ "center": "115.816587,28.637234",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0790",
+ "adcode": "360500",
+ "name": "新余市",
+ "center": "114.916665,27.818553",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0791",
+ "adcode": "360100",
+ "name": "南昌市",
+ "center": "115.857972,28.682976",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0792",
+ "adcode": "360400",
+ "name": "九江市",
+ "center": "115.95356,29.66116",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0798",
+ "adcode": "360200",
+ "name": "景德镇市",
+ "center": "117.184892,29.2744",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0701",
+ "adcode": "360600",
+ "name": "鹰潭市",
+ "center": "117.039532,28.272092",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0796",
+ "adcode": "360800",
+ "name": "吉安市",
+ "center": "114.96681,27.091243",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0797",
+ "adcode": "360700",
+ "name": "赣州市",
+ "center": "114.933494,25.831139",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0795",
+ "adcode": "360900",
+ "name": "宜春市",
+ "center": "114.416826,27.816245",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0799",
+ "adcode": "360300",
+ "name": "萍乡市",
+ "center": "113.887147,27.658721",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0794",
+ "adcode": "361000",
+ "name": "抚州市",
+ "center": "116.358054,27.948979",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0793",
+ "adcode": "361100",
+ "name": "上饶市",
+ "center": "117.943064,28.45513",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "140000",
+ "name": "山西省",
+ "center": "112.578781,37.813948",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0353",
+ "adcode": "140300",
+ "name": "阳泉市",
+ "center": "113.580426,37.857094",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0355",
+ "adcode": "140400",
+ "name": "长治市",
+ "center": "113.117394,36.195142",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0349",
+ "adcode": "140600",
+ "name": "朔州市",
+ "center": "112.432906,39.331734",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0356",
+ "adcode": "140500",
+ "name": "晋城市",
+ "center": "112.852022,35.491315",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0350",
+ "adcode": "140900",
+ "name": "忻州市",
+ "center": "112.734149,38.415958",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0358",
+ "adcode": "141100",
+ "name": "吕梁市",
+ "center": "111.14454,37.518996",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0359",
+ "adcode": "140800",
+ "name": "运城市",
+ "center": "111.007051,35.02667",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0357",
+ "adcode": "141000",
+ "name": "临汾市",
+ "center": "111.51931,36.088581",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0352",
+ "adcode": "140200",
+ "name": "大同市",
+ "center": "113.366749,40.09711",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0354",
+ "adcode": "140700",
+ "name": "晋中市",
+ "center": "112.752633,37.688006",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0351",
+ "adcode": "140100",
+ "name": "太原市",
+ "center": "112.549656,37.870451",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": "010",
+ "adcode": "110000",
+ "name": "北京市",
+ "center": "116.407387,39.904179",
+ "level": "province",
+ },
+ {
+ "citycode": [],
+ "adcode": "540000",
+ "name": "西藏自治区",
+ "center": "91.117449,29.648694",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0895",
+ "adcode": "540300",
+ "name": "昌都市",
+ "center": "97.170425,31.142879",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0896",
+ "adcode": "540600",
+ "name": "那曲市",
+ "center": "92.05151,31.477905",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0891",
+ "adcode": "540100",
+ "name": "拉萨市",
+ "center": "91.171924,29.653491",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0892",
+ "adcode": "540200",
+ "name": "日喀则市",
+ "center": "88.880423,29.266838",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0893",
+ "adcode": "540500",
+ "name": "山南市",
+ "center": "91.771426,29.237722",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0894",
+ "adcode": "540400",
+ "name": "林芝市",
+ "center": "94.361436,29.64875",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0897",
+ "adcode": "542500",
+ "name": "阿里地区",
+ "center": "80.105786,32.500987",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "220000",
+ "name": "吉林省",
+ "center": "125.325802,43.896942",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0432",
+ "adcode": "220200",
+ "name": "吉林市",
+ "center": "126.549719,43.838132",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0431",
+ "adcode": "220100",
+ "name": "长春市",
+ "center": "125.323643,43.816996",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0436",
+ "adcode": "220800",
+ "name": "白城市",
+ "center": "122.838102,45.620131",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0437",
+ "adcode": "220400",
+ "name": "辽源市",
+ "center": "125.144676,42.887961",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0435",
+ "adcode": "220500",
+ "name": "通化市",
+ "center": "125.939721,41.728312",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0438",
+ "adcode": "220700",
+ "name": "松原市",
+ "center": "124.825321,45.14191",
+ "level": "city",
+
+ },
+ {
+ "citycode": "1433",
+ "adcode": "222400",
+ "name": "延边朝鲜族自治州",
+ "center": "129.470605,42.909426",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0434",
+ "adcode": "220300",
+ "name": "四平市",
+ "center": "124.350599,43.166764",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0439",
+ "adcode": "220600",
+ "name": "白山市",
+ "center": "126.414274,41.944132",
+ "level": "city",
+
+ }
+ ]
+ },
+ {
+ "citycode": [],
+ "adcode": "530000",
+ "name": "云南省",
+ "center": "102.709372,25.046432",
+ "level": "province",
+ "districts": [
+ {
+ "citycode": "0870",
+ "adcode": "530600",
+ "name": "昭通市",
+ "center": "103.717078,27.338185",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0874",
+ "adcode": "530300",
+ "name": "曲靖市",
+ "center": "103.796288,25.490866",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0873",
+ "adcode": "532500",
+ "name": "红河哈尼族彝族自治州",
+ "center": "103.374873,23.363129",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0886",
+ "adcode": "533300",
+ "name": "怒江傈僳族自治州",
+ "center": "98.8566,25.817555",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0691",
+ "adcode": "532800",
+ "name": "西双版纳傣族自治州",
+ "center": "100.797002,22.009037",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0877",
+ "adcode": "530400",
+ "name": "玉溪市",
+ "center": "102.526673,24.346786",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0888",
+ "adcode": "530700",
+ "name": "丽江市",
+ "center": "100.225936,26.855165",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0875",
+ "adcode": "530500",
+ "name": "保山市",
+ "center": "99.161489,25.112018",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0883",
+ "adcode": "530900",
+ "name": "临沧市",
+ "center": "100.088837,23.884175",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0872",
+ "adcode": "532900",
+ "name": "大理白族自治州",
+ "center": "100.267608,25.606548",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0879",
+ "adcode": "530800",
+ "name": "普洱市",
+ "center": "100.966011,22.825229",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0887",
+ "adcode": "533400",
+ "name": "迪庆藏族自治州",
+ "center": "99.70211,27.819149",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0878",
+ "adcode": "532300",
+ "name": "楚雄彝族自治州",
+ "center": "101.528304,25.045678",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0871",
+ "adcode": "530100",
+ "name": "昆明市",
+ "center": "102.833669,24.88149",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0876",
+ "adcode": "532600",
+ "name": "文山壮族苗族自治州",
+ "center": "104.21567,23.400983",
+ "level": "city",
+
+ },
+ {
+ "citycode": "0692",
+ "adcode": "533100",
+ "name": "德宏傣族景颇族自治州",
+ "center": "98.585621,24.433146",
+ "level": "city",
+
+ }
+ ]
+ }
+]
diff --git a/src/constant/enum.js b/src/constant/enum.js
new file mode 100644
index 0000000..4a54b47
--- /dev/null
+++ b/src/constant/enum.js
@@ -0,0 +1,28 @@
+const EnumUtil = {}
+
+EnumUtil.install = function (Vue, data) {
+ const constantInfo = data || {}
+ const Enum = { ...data }
+ /**
+ * 根据枚举值获取描述
+ * @param {*} constantName 枚举对象的名字
+ * @param {*} value 枚举值
+ * @param {*} desc 枚举值所对应的描述
+ */
+ Enum.getDescByValue = function (constantName, value) {
+ if (!constantInfo.hasOwnProperty(constantName)) {
+ return ''
+ }
+ let constantItem = constantInfo[constantName] // 通过传进来的名字拿到所对应的常量项
+ for (let item in constantItem) {
+ // 循环常量项
+ if (constantItem[item].value === value) {
+ return constantItem[item].desc
+ }
+ }
+ }
+
+ Vue.prototype.$enum = Enum // 挂在原型上,方便使用
+}
+
+export default EnumUtil
diff --git a/src/constant/global.js b/src/constant/global.js
new file mode 100644
index 0000000..cdac474
--- /dev/null
+++ b/src/constant/global.js
@@ -0,0 +1,8 @@
+export const listClass = {
+ danger: 'danger',
+ primary: 'primary',
+ default: 'default',
+ success: 'success',
+ info: 'info',
+ warning: 'warning',
+}
diff --git a/src/constant/index.js b/src/constant/index.js
new file mode 100644
index 0000000..f3afd57
--- /dev/null
+++ b/src/constant/index.js
@@ -0,0 +1,5 @@
+/* import Vue from 'vue'
+import EnumModule from './module'
+import Enum from './enum'
+
+Vue.use(EnumModule,Enum) */
diff --git a/src/constant/module/index.js b/src/constant/module/index.js
new file mode 100644
index 0000000..45dbf35
--- /dev/null
+++ b/src/constant/module/index.js
@@ -0,0 +1,18 @@
+/** module/index.js
+ * 常量枚举池
+ * 可以根据文件对枚举所属的模块进行拆分
+ * 此文件主要是收集模块常量然后统一暴露出去
+ */
+/* const EnumModule = {}
+
+const req = context => context.keys().map(context)
+
+const options = req(require.context('./', true, /\.js$/)) // 批量导入当前文件所在目录下的.js文件
+
+options.forEach(option => {
+ Object.assign(EnumModule, {
+ ...option
+ })
+})
+
+export default EnumModule */
diff --git a/src/constant/module/statusMap.js b/src/constant/module/statusMap.js
new file mode 100644
index 0000000..6b7c0ff
--- /dev/null
+++ b/src/constant/module/statusMap.js
@@ -0,0 +1,141 @@
+import { listClass } from '@/constant/global'
+
+const arrToMap = arr =>
+ arr.reduce((res, cur) => {
+ res[cur.value] = cur.label
+ return res
+ }, {})
+
+export const kinsfolkRefList = [
+ { value: "1", label: '父母' },
+ { value: "2", label: '配偶' },
+ { value: "3", label: '子女' },
+ { value: "4", label: '祖父母' },
+]
+
+export const bankTypeList = [
+ { value: "1", label: '父母' },
+ { value: "2", label: '配偶' },
+ { value: "3", label: '子女' },
+ { value: "4", label: '祖父母' },
+]
+
+// 启用状态
+export const enableStatusList = [
+ { value: 0, label: '禁用', listClass: listClass.danger },
+ { value: 1, label: '启用', listClass: listClass.primary }
+]
+// 启用状态
+export const onlineStatusList = [
+ { value: 0, label: '下线', listClass: listClass.danger },
+ { value: 1, label: '上线', listClass: listClass.primary },
+ { value: 2, label: '服务中', listClass: listClass.warning }
+]
+
+export const yesOrNoList = [
+ { value: 0, label: '否', listClass: listClass.primary },
+ { value: 1, label: '是', listClass: listClass.primary }
+]
+
+export const booleanList = [
+ { value: false, label: '否', listClass: listClass.warning },
+ { value: true, label: '是', listClass: listClass.primary }
+]
+
+export const appraiseList = [
+ { value: false, label: '待评价', listClass: listClass.warning },
+ { value: true, label: '已评价', listClass: listClass.success }
+]
+
+export const genderList = [
+ { value: -1, label: '未知', listClass: listClass.warning },
+ { value: 0, label: '男', listClass: listClass.primary },
+ { value: 1, label: '女', listClass: listClass.danger }
+]
+
+export const stopStatusList = [
+ { value: 1, label: '封禁', listClass: listClass.danger },
+ { value: 0, label: '正常', listClass: listClass.primary }
+]
+
+export const deleteFlagList = [
+ { value: 1, label: '删除' },
+ { value: 0, label: '正常' }
+]
+
+export const talentInfoTypeList = [
+ { value: 1, label: '图片' },
+ { value: 2, label: '视频' },
+ { value: 3, label: '语音' }
+]
+
+export const auditStatusList = [
+ { value: 0, label: '待审核' , listClass: listClass.danger },
+ { value: 1, label: '通过' , listClass: listClass.primary },
+ { value: -1, label: '不通过' , listClass: listClass.warning }
+]
+
+export const payTypeList = [
+ { value: 1, label: '支付宝' , listClass: listClass.primary},
+ { value: 2, label: '微信' , listClass: listClass.success},
+ { value: 3, label: 'IOS支付', listClass: listClass.danger }
+]
+
+export const payStatusList = [
+ { value: 0, label: '待支付', listClass: listClass.warning },
+ { value: 1, label: '已支付', listClass: listClass.primary },
+ { value: 2, label: '已退款', listClass: listClass.danger }
+ // {value:3,label:'退款审核中'},
+]
+
+export const orderServiceStatusList = [
+ { value: 0, label: '待支付', listClass: listClass.warning },
+ { value: 1, label: '待接单', listClass: listClass.danger },
+ { value: 2, label: '待消费', listClass: listClass.danger },
+ { value: 90, label: '待评价', listClass: listClass.success },
+ { value: 99, label: '已完成', listClass: listClass.success },
+ { value: -1, label: '已取消', listClass: listClass.info },
+ { value: -2, label: '已退款', listClass: listClass.info }
+]
+
+export const applyStatusList = [
+ { value: 0, label: '待处理', listClass: listClass.warning },
+ { value: 1, label: '已处理', listClass: listClass.success },
+ { value: -1, label: '不予处理', listClass: listClass.info },
+]
+
+export const goodStatusList = [
+ { value: 1, label: '好评' },
+ { value: 2, label: '中评' },
+ { value: 3, label: '差评' }
+]
+
+export const appTypeList = [
+ { value: 'TBS', label: '泰巴士' }
+]
+
+/* export const Enums = {
+ ...enableStatusList,
+ ...onlineStatusList,
+ ...yesOrNoList,
+ ...booleanList,
+ ...appraiseList,
+ ...stopStatusList,
+ ...genderList,
+ ...deleteFlagList,
+ ...talentInfoTypeList,
+ ...auditStatusList,
+ ...payTypeList,
+ ...payStatusList,
+ ...orderServiceStatusList,
+ ...goodStatusList,
+ ...appTypeList,
+} */
+
+export const enableStatusMap = arrToMap(enableStatusList)
+export const yesOrNoMap = arrToMap(yesOrNoList)
+export const booleanMap = arrToMap(booleanList)
+export const genderMap = arrToMap(genderList)
+export const talentInfoTypeMap = arrToMap(talentInfoTypeList)
+export const orderServiceStatusMap = arrToMap(orderServiceStatusList)
+export const goodStatusMap = arrToMap(goodStatusList)
diff --git a/src/directive/permission/hasPermi.js b/src/directive/permission/hasPermi.js
new file mode 100644
index 0000000..d7107ce
--- /dev/null
+++ b/src/directive/permission/hasPermi.js
@@ -0,0 +1,28 @@
+ /**
+ * 操作权限处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+import store from '@/store'
+
+export default {
+ inserted(el, binding, vnode) {
+ const { value } = binding
+ const all_permission = "*:*:*";
+ const permissions = store.getters && store.getters.permissions
+
+ if (value && value instanceof Array && value.length > 0) {
+ const permissionFlag = value
+
+ const hasPermissions = permissions.some(permission => {
+ return all_permission === permission || permissionFlag.includes(permission)
+ })
+
+ if (!hasPermissions) {
+ el.parentNode && el.parentNode.removeChild(el)
+ }
+ } else {
+ throw new Error(`请设置操作权限标签值`)
+ }
+ }
+}
diff --git a/src/directive/permission/hasRole.js b/src/directive/permission/hasRole.js
new file mode 100644
index 0000000..1303809
--- /dev/null
+++ b/src/directive/permission/hasRole.js
@@ -0,0 +1,28 @@
+ /**
+ * 角色权限处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+import store from '@/store'
+
+export default {
+ inserted(el, binding, vnode) {
+ const { value } = binding
+ const super_admin = "admin";
+ const roles = store.getters && store.getters.roles
+
+ if (value && value instanceof Array && value.length > 0) {
+ const roleFlag = value
+
+ const hasRole = roles.some(role => {
+ return super_admin === role || roleFlag.includes(role)
+ })
+
+ if (!hasRole) {
+ el.parentNode && el.parentNode.removeChild(el)
+ }
+ } else {
+ throw new Error(`请设置角色权限标签值"`)
+ }
+ }
+}
diff --git a/src/directive/permission/index.js b/src/directive/permission/index.js
new file mode 100644
index 0000000..e3d76d3
--- /dev/null
+++ b/src/directive/permission/index.js
@@ -0,0 +1,15 @@
+import hasRole from './hasRole'
+import hasPermi from './hasPermi'
+
+const install = function(Vue) {
+ Vue.directive('hasRole', hasRole)
+ Vue.directive('hasPermi', hasPermi)
+}
+
+if (window.Vue) {
+ window['hasRole'] = hasRole
+ window['hasPermi'] = hasPermi
+ Vue.use(install); // eslint-disable-line
+}
+
+export default install
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
new file mode 100644
index 0000000..a897638
--- /dev/null
+++ b/src/layout/components/AppMain.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
new file mode 100644
index 0000000..f5ecb9e
--- /dev/null
+++ b/src/layout/components/Navbar.vue
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue
new file mode 100644
index 0000000..a96b73f
--- /dev/null
+++ b/src/layout/components/Settings/index.vue
@@ -0,0 +1,268 @@
+
+
+
+
+
+
主题风格设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 主题颜色
+
+
+
+
+
+
+
系统布局配置
+
+
+ 开启 TopNav
+
+
+
+
+ 开启 Tags-Views
+
+
+
+
+ 固定 Header
+
+
+
+
+ 显示 Logo
+
+
+
+
+ 动态标题
+
+
+
+
+
+
保存配置
+
重置配置
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/FixiOSBug.js b/src/layout/components/Sidebar/FixiOSBug.js
new file mode 100644
index 0000000..6823726
--- /dev/null
+++ b/src/layout/components/Sidebar/FixiOSBug.js
@@ -0,0 +1,25 @@
+export default {
+ computed: {
+ device() {
+ return this.$store.state.app.device
+ }
+ },
+ mounted() {
+ // In order to fix the click on menu on the ios device will trigger the mouseleave bug
+ this.fixBugIniOS()
+ },
+ methods: {
+ fixBugIniOS() {
+ const $subMenu = this.$refs.subMenu
+ if ($subMenu) {
+ const handleMouseleave = $subMenu.handleMouseleave
+ $subMenu.handleMouseleave = (e) => {
+ if (this.device === 'mobile') {
+ return
+ }
+ handleMouseleave(e)
+ }
+ }
+ }
+ }
+}
diff --git a/src/layout/components/Sidebar/Item.vue b/src/layout/components/Sidebar/Item.vue
new file mode 100644
index 0000000..b515f61
--- /dev/null
+++ b/src/layout/components/Sidebar/Item.vue
@@ -0,0 +1,29 @@
+
diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue
new file mode 100644
index 0000000..530b3d5
--- /dev/null
+++ b/src/layout/components/Sidebar/Link.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
new file mode 100644
index 0000000..a8c6c57
--- /dev/null
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
new file mode 100644
index 0000000..c4febee
--- /dev/null
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
new file mode 100644
index 0000000..9e5d2bb
--- /dev/null
+++ b/src/layout/components/Sidebar/index.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue
new file mode 100644
index 0000000..bb753a1
--- /dev/null
+++ b/src/layout/components/TagsView/ScrollPane.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue
new file mode 100644
index 0000000..6caf350
--- /dev/null
+++ b/src/layout/components/TagsView/index.vue
@@ -0,0 +1,318 @@
+
+
+
+
+ {{ tag.title }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/index.js b/src/layout/components/index.js
new file mode 100644
index 0000000..104bd3a
--- /dev/null
+++ b/src/layout/components/index.js
@@ -0,0 +1,5 @@
+export { default as AppMain } from './AppMain'
+export { default as Navbar } from './Navbar'
+export { default as Settings } from './Settings'
+export { default as Sidebar } from './Sidebar/index.vue'
+export { default as TagsView } from './TagsView/index.vue'
diff --git a/src/layout/index.vue b/src/layout/index.vue
new file mode 100644
index 0000000..d490771
--- /dev/null
+++ b/src/layout/index.vue
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
diff --git a/src/layout/mixin/ResizeHandler.js b/src/layout/mixin/ResizeHandler.js
new file mode 100644
index 0000000..e8d0df8
--- /dev/null
+++ b/src/layout/mixin/ResizeHandler.js
@@ -0,0 +1,45 @@
+import store from '@/store'
+
+const { body } = document
+const WIDTH = 992 // refer to Bootstrap's responsive design
+
+export default {
+ watch: {
+ $route(route) {
+ if (this.device === 'mobile' && this.sidebar.opened) {
+ store.dispatch('app/closeSideBar', { withoutAnimation: false })
+ }
+ }
+ },
+ beforeMount() {
+ window.addEventListener('resize', this.$_resizeHandler)
+ },
+ beforeDestroy() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ },
+ mounted() {
+ const isMobile = this.$_isMobile()
+ if (isMobile) {
+ store.dispatch('app/toggleDevice', 'mobile')
+ store.dispatch('app/closeSideBar', { withoutAnimation: true })
+ }
+ },
+ methods: {
+ // use $_ for mixins properties
+ // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+ $_isMobile() {
+ const rect = body.getBoundingClientRect()
+ return rect.width - 1 < WIDTH
+ },
+ $_resizeHandler() {
+ if (!document.hidden) {
+ const isMobile = this.$_isMobile()
+ store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
+
+ if (isMobile) {
+ store.dispatch('app/closeSideBar', { withoutAnimation: true })
+ }
+ }
+ }
+ }
+}
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..3dde9e8
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,110 @@
+import Vue from 'vue'
+import VueAMap from 'vue-amap';
+
+import Cookies from 'js-cookie'
+
+import Element from 'element-ui'
+import './assets/styles/element-variables.scss'
+
+import '@/assets/styles/index.scss' // global css
+import '@/assets/styles/ruoyi.scss' // ruoyi css
+import plugins from './plugins' // plugins
+import App from './App'
+import store from './store'
+import router from './router'
+import permission from './directive/permission'
+
+import './assets/icons' // icon
+import './permission' // permission control
+import { getDicts } from "@/api/system/dict/data";
+import { getConfigKey } from "@/api/system/config";
+import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi";
+import Pagination from "@/components/Pagination";
+// 自定义表格工具组件
+import RightToolbar from "@/components/RightToolbar"
+import FileUpload from "@/components/FileUpload"
+// 图片预览组件
+import ImagePreview from "@/components/ImagePreview"
+// import './constant/'
+// 字典标签组件
+import DictTag from '@/components/DictTag'
+import ZlDictTag from "@/components/ZlDictTag";
+// 头部标签组件
+import VueMeta from 'vue-meta'
+
+// 全局方法挂载
+Vue.prototype.getDicts = getDicts
+Vue.prototype.getConfigKey = getConfigKey
+Vue.prototype.parseTime = parseTime
+Vue.prototype.resetForm = resetForm
+Vue.prototype.addDateRange = addDateRange
+Vue.prototype.selectDictLabel = selectDictLabel
+Vue.prototype.selectDictLabels = selectDictLabels
+Vue.prototype.download = download
+Vue.prototype.handleTree = handleTree
+
+Vue.prototype.msgSuccess = function (msg) {
+ this.$message({ showClose: true, message: msg, type: "success" });
+}
+
+Vue.prototype.msgError = function (msg) {
+ this.$message({ showClose: true, message: msg, type: "error" });
+}
+
+Vue.prototype.msgInfo = function (msg) {
+ this.$message.info(msg);
+}
+
+// 全局组件挂载
+Vue.component('DictTag', DictTag)
+Vue.component('Pagination', Pagination)
+Vue.component('RightToolbar', RightToolbar)
+Vue.component('ImagePreview', ImagePreview)
+Vue.component('ZlDictTag', ZlDictTag)
+Vue.component('FileUpload', FileUpload)
+
+
+Vue.use(permission)
+Vue.use(plugins)
+Vue.use(VueMeta)
+Vue.use(VueAMap)
+VueAMap.initAMapApiLoader({
+ key: '420eb8f07455581c6016a0cc76ad4987',
+ // plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor'],
+ plugin:[
+ 'AMap.Geocoder',
+ 'AMap.Autocomplete', // 输入提示插件
+ 'AMap.PlaceSearch', // POI搜索插件
+ 'AMap.Scale', // 右下角缩略图插件 比例尺
+ 'AMap.OverView', // 地图鹰眼插件
+ 'AMap.ToolBar', // 地图工具条
+ 'AMap.MapType', // 类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
+ 'AMap.PolyEditor', // 编辑 折线多,边形
+ 'AMap.CircleEditor', // 圆形编辑器插件
+ 'AMap.Geolocation' // 定位控件,用来获取和展示用户主机所在的经纬度位置
+ ],
+ // 默认高德 sdk 版本为 1.4.4
+ v: '1.4.4'
+});
+
+/**
+ * If you don't want to use mock-server
+ * you want to use MockJs for mock api
+ * you can execute: mockXHR()
+ *
+ * Currently MockJs will be used in the production environment,
+ * please remove it before going online! ! !
+ */
+
+Vue.use(Element, {
+ size: Cookies.get('size') || 'medium' // set element-ui default size
+})
+
+Vue.config.productionTip = false
+
+new Vue({
+ el: '#app',
+ router,
+ store,
+ render: h => h(App)
+})
diff --git a/src/mixins/common-util.js b/src/mixins/common-util.js
new file mode 100644
index 0000000..ceb1b64
--- /dev/null
+++ b/src/mixins/common-util.js
@@ -0,0 +1,19 @@
+import { numberFormat } from '@/utils/ruoyi'
+
+export default {
+ data(){
+
+ },
+ methods: {
+ yuanFormatTable(row,column){
+ if(row[column.property]){
+ return numberFormat(row[column.property] / 100, 2, '.', ',');
+ }else{
+ return '0.00'
+ }
+ },
+ yuanFormat(value){
+ return numberFormat(value/100, 2, '.', ',');
+ },
+ }
+}
diff --git a/src/permission.js b/src/permission.js
new file mode 100644
index 0000000..7e770d4
--- /dev/null
+++ b/src/permission.js
@@ -0,0 +1,53 @@
+import router from './router'
+import store from './store'
+import { Message } from 'element-ui'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
+import { getToken } from '@/utils/auth'
+
+NProgress.configure({ showSpinner: false })
+
+const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
+
+router.beforeEach((to, from, next) => {
+ NProgress.start()
+ if (getToken()) {
+ to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
+ /* has token*/
+ if (to.path === '/login') {
+ next({ path: '/' })
+ NProgress.done()
+ } else {
+ if (store.getters.roles.length === 0) {
+ // 判断当前用户是否已拉取完user_info信息
+ store.dispatch('GetInfo').then(() => {
+ store.dispatch('GenerateRoutes').then(accessRoutes => {
+ // 根据roles权限生成可访问的路由表
+ router.addRoutes(accessRoutes) // 动态添加可访问路由表
+ next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
+ })
+ }).catch(err => {
+ store.dispatch('LogOut').then(() => {
+ Message.error(err)
+ next({ path: '/' })
+ })
+ })
+ } else {
+ next()
+ }
+ }
+ } else {
+ // 没有token
+ if (whiteList.indexOf(to.path) !== -1) {
+ // 在免登录白名单,直接进入
+ next()
+ } else {
+ next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
+ NProgress.done()
+ }
+ }
+})
+
+router.afterEach(() => {
+ NProgress.done()
+})
diff --git a/src/plugins/index.js b/src/plugins/index.js
new file mode 100644
index 0000000..76a83e5
--- /dev/null
+++ b/src/plugins/index.js
@@ -0,0 +1,8 @@
+import modal from './modal'
+
+export default {
+ install(Vue) {
+ // 模态框对象
+ Vue.prototype.$modal = modal
+ }
+}
diff --git a/src/plugins/modal.js b/src/plugins/modal.js
new file mode 100644
index 0000000..b37ca14
--- /dev/null
+++ b/src/plugins/modal.js
@@ -0,0 +1,83 @@
+import { Message, MessageBox, Notification, Loading } from 'element-ui'
+
+let loadingInstance;
+
+export default {
+ // 消息提示
+ msg(content) {
+ Message.info(content)
+ },
+ // 错误消息
+ msgError(content) {
+ Message.error(content)
+ },
+ // 成功消息
+ msgSuccess(content) {
+ Message.success(content)
+ },
+ // 警告消息
+ msgWarning(content) {
+ Message.warning(content)
+ },
+ // 弹出提示
+ alert(content) {
+ MessageBox.alert(content, "系统提示")
+ },
+ // 错误提示
+ alertError(content) {
+ MessageBox.alert(content, "系统提示", { type: 'error' })
+ },
+ // 成功提示
+ alertSuccess(content) {
+ MessageBox.alert(content, "系统提示", { type: 'success' })
+ },
+ // 警告提示
+ alertWarning(content) {
+ MessageBox.alert(content, "系统提示", { type: 'warning' })
+ },
+ // 通知提示
+ notify(content) {
+ Notification.info(content)
+ },
+ // 错误通知
+ notifyError(content) {
+ Notification.error(content);
+ },
+ // 成功通知
+ notifySuccess(content) {
+ Notification.success(content)
+ },
+ // 警告通知
+ notifyWarning(content) {
+ Notification.warning(content)
+ },
+ // 确认窗体
+ confirm(content) {
+ return MessageBox.confirm(content, "系统提示", {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: "warning",
+ })
+ },
+ // 提交内容
+ prompt(content) {
+ return MessageBox.prompt(content, "系统提示", {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: "warning",
+ })
+ },
+ // 打开遮罩层
+ loading(content) {
+ loadingInstance = Loading.service({
+ lock: true,
+ text: content,
+ spinner: "el-icon-loading",
+ background: "rgba(0, 0, 0, 0.7)",
+ })
+ },
+ // 关闭遮罩层
+ closeLoading() {
+ loadingInstance.close();
+ }
+}
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..dffdb79
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,153 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+
+Vue.use(Router)
+
+/* Layout */
+import Layout from '@/layout'
+import ParentView from '@/components/ParentView';
+
+/**
+ * Note: 路由配置项
+ *
+ * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
+ * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
+ * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
+ * // 若你想不管路由下面的 children 声明的个数都显示你的根路由
+ * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
+ * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
+ * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题
+ * meta : {
+ noCache: true // 如果设置为true,则不会被 缓存(默认 false)
+ title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
+ icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg
+ breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
+ }
+ */
+
+// 公共路由
+export const constantRoutes = [
+ {
+ path: '/redirect',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: '/redirect/:path(.*)',
+ component: (resolve) => require(['@/views/redirect'], resolve)
+ }
+ ]
+ },
+ {
+ path: '/login',
+ component: (resolve) => require(['@/views/login'], resolve),
+ hidden: true
+ },
+ {
+ path: '/404',
+ component: (resolve) => require(['@/views/error/404'], resolve),
+ hidden: true
+ },
+ {
+ path: '/401',
+ component: (resolve) => require(['@/views/error/401'], resolve),
+ hidden: true
+ },
+ {
+ path: '',
+ component: Layout,
+ redirect: 'index',
+ children: [
+ {
+ path: 'index',
+ component: (resolve) => require(['@/views/index'], resolve),
+ name: '首页',
+ meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
+ }
+ ]
+ },
+ {
+ path: '/user',
+ component: Layout,
+ hidden: true,
+ redirect: 'noredirect',
+ children: [
+ {
+ path: 'profile',
+ component: (resolve) => require(['@/views/system/user/profile/index'], resolve),
+ name: 'Profile',
+ meta: { title: '个人中心', icon: 'user' }
+ }
+ ]
+ },
+ {
+ path: '/dict',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'type/data/:dictId(\\d+)',
+ component: (resolve) => require(['@/views/system/dict/data'], resolve),
+ name: 'Data',
+ meta: { title: '字典数据', icon: '' }
+ }
+ ]
+ },
+ {
+ path: '/job',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'log',
+ component: (resolve) => require(['@/views/monitor/job/log'], resolve),
+ name: 'JobLog',
+ meta: { title: '调度日志' }
+ }
+ ]
+ },
+ {
+ path: '/gen',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'edit/:tableId(\\d+)',
+ component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
+ name: 'GenEdit',
+ meta: { title: '修改生成配置' }
+ }
+ ]
+ },
+ {
+ path: '/dk',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: 'transAccount/:borrowId(\\d+)',
+ component: (resolve) => require(['@/views/dk/borrow/trans-account'], resolve),
+ name: 'TransAccount',
+ meta: { title: '转账记录' }
+ },
+ {
+ path: 'contract/:borrowId(\\d+)',
+ component: (resolve) => require(['@/views/dk/borrow/contract'], resolve),
+ name: 'Contract',
+ meta: { title: '合同保单' }
+ },
+ {
+ path: 'contractTemplate/:borrowTradeNo(\\w+)',
+ component: (resolve) => require(['@/views/dk/borrow/contract-template'], resolve),
+ name: 'ContractTemplate',
+ meta: { title: '合同' }
+ }
+ ]
+ }
+]
+
+export default new Router({
+ mode: 'history', // 去掉url中的#
+ scrollBehavior: () => ({ y: 0 }),
+ routes: constantRoutes
+})
diff --git a/src/settings.js b/src/settings.js
new file mode 100644
index 0000000..6a0b09f
--- /dev/null
+++ b/src/settings.js
@@ -0,0 +1,44 @@
+module.exports = {
+ /**
+ * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
+ */
+ sideTheme: 'theme-dark',
+
+ /**
+ * 是否系统布局配置
+ */
+ showSettings: false,
+
+ /**
+ * 是否显示顶部导航
+ */
+ topNav: false,
+
+ /**
+ * 是否显示 tagsView
+ */
+ tagsView: true,
+
+ /**
+ * 是否固定头部
+ */
+ fixedHeader: false,
+
+ /**
+ * 是否显示logo
+ */
+ sidebarLogo: true,
+
+ /**
+ * 是否显示动态标题
+ */
+ dynamicTitle: false,
+
+ /**
+ * @type {string | array} 'production' | ['production', 'development']
+ * @description Need show err logs component.
+ * The default is only used in the production env
+ * If you want to also use it in dev, you can pass ['production', 'development']
+ */
+ errorLog: 'production'
+}
diff --git a/src/store/getters.js b/src/store/getters.js
new file mode 100644
index 0000000..1de1002
--- /dev/null
+++ b/src/store/getters.js
@@ -0,0 +1,20 @@
+const getters = {
+ sidebar: state => state.app.sidebar,
+ size: state => state.app.size,
+ device: state => state.app.device,
+ visitedViews: state => state.tagsView.visitedViews,
+ cachedViews: state => state.tagsView.cachedViews,
+ token: state => state.user.token,
+ avatar: state => state.user.avatar,
+ name: state => state.user.name,
+ deptId: state => state.user.deptId,
+ introduction: state => state.user.introduction,
+ roles: state => state.user.roles,
+ city: state => state.user.city,
+ permissions: state => state.user.permissions,
+ permission_routes: state => state.permission.routes,
+ topbarRouters:state => state.permission.topbarRouters,
+ defaultRoutes:state => state.permission.defaultRoutes,
+ sidebarRouters:state => state.permission.sidebarRouters,
+}
+export default getters
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 0000000..53b8437
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,23 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import app from './modules/app'
+import user from './modules/user'
+import tagsView from './modules/tagsView'
+import permission from './modules/permission'
+import settings from './modules/settings'
+import getters from './getters'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+ modules: {
+ app,
+ user,
+ tagsView,
+ permission,
+ settings
+ },
+ getters
+})
+
+export default store
diff --git a/src/store/modules/app.js b/src/store/modules/app.js
new file mode 100644
index 0000000..45d89bb
--- /dev/null
+++ b/src/store/modules/app.js
@@ -0,0 +1,56 @@
+import Cookies from 'js-cookie'
+
+const state = {
+ sidebar: {
+ opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+ withoutAnimation: false
+ },
+ device: 'desktop',
+ size: Cookies.get('size') || 'medium'
+}
+
+const mutations = {
+ TOGGLE_SIDEBAR: state => {
+ state.sidebar.opened = !state.sidebar.opened
+ state.sidebar.withoutAnimation = false
+ if (state.sidebar.opened) {
+ Cookies.set('sidebarStatus', 1)
+ } else {
+ Cookies.set('sidebarStatus', 0)
+ }
+ },
+ CLOSE_SIDEBAR: (state, withoutAnimation) => {
+ Cookies.set('sidebarStatus', 0)
+ state.sidebar.opened = false
+ state.sidebar.withoutAnimation = withoutAnimation
+ },
+ TOGGLE_DEVICE: (state, device) => {
+ state.device = device
+ },
+ SET_SIZE: (state, size) => {
+ state.size = size
+ Cookies.set('size', size)
+ }
+}
+
+const actions = {
+ toggleSideBar({ commit }) {
+ commit('TOGGLE_SIDEBAR')
+ },
+ closeSideBar({ commit }, { withoutAnimation }) {
+ commit('CLOSE_SIDEBAR', withoutAnimation)
+ },
+ toggleDevice({ commit }, device) {
+ commit('TOGGLE_DEVICE', device)
+ },
+ setSize({ commit }, size) {
+ commit('SET_SIZE', size)
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js
new file mode 100644
index 0000000..aacfc8c
--- /dev/null
+++ b/src/store/modules/permission.js
@@ -0,0 +1,110 @@
+import { constantRoutes } from '@/router'
+import { getRouters } from '@/api/menu'
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView';
+
+const permission = {
+ state: {
+ routes: [],
+ addRoutes: [],
+ defaultRoutes: [],
+ topbarRouters: [],
+ sidebarRouters: []
+ },
+ mutations: {
+ SET_ROUTES: (state, routes) => {
+ state.addRoutes = routes
+ state.routes = constantRoutes.concat(routes)
+ },
+ SET_DEFAULT_ROUTES: (state, routes) => {
+ state.defaultRoutes = constantRoutes.concat(routes)
+ },
+ SET_TOPBAR_ROUTES: (state, routes) => {
+ // 顶部导航菜单默认添加统计报表栏指向首页
+ const index = [{
+ path: 'index',
+ meta: { title: '统计报表', icon: 'dashboard'}
+ }]
+ state.topbarRouters = routes.concat(index);
+ },
+ SET_SIDEBAR_ROUTERS: (state, routes) => {
+ state.sidebarRouters = routes
+ },
+ },
+ actions: {
+ // 生成路由
+ GenerateRoutes({ commit }) {
+ return new Promise(resolve => {
+ // 向后端请求路由数据
+ getRouters().then(res => {
+ const sdata = JSON.parse(JSON.stringify(res.data))
+ const rdata = JSON.parse(JSON.stringify(res.data))
+ const sidebarRoutes = filterAsyncRouter(sdata)
+ const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+ rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
+ commit('SET_ROUTES', rewriteRoutes)
+ commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
+ commit('SET_DEFAULT_ROUTES', sidebarRoutes)
+ commit('SET_TOPBAR_ROUTES', sidebarRoutes)
+ resolve(rewriteRoutes)
+ })
+ })
+ }
+ }
+}
+
+// 遍历后台传来的路由字符串,转换为组件对象
+function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
+ return asyncRouterMap.filter(route => {
+ if (type && route.children) {
+ route.children = filterChildren(route.children)
+ }
+ if (route.component) {
+ // Layout ParentView 组件特殊处理
+ if (route.component === 'Layout') {
+ route.component = Layout
+ } else if (route.component === 'ParentView') {
+ route.component = ParentView
+ } else {
+ route.component = loadView(route.component)
+ }
+ }
+ if (route.children != null && route.children && route.children.length) {
+ route.children = filterAsyncRouter(route.children, route, type)
+ } else {
+ delete route['children']
+ delete route['redirect']
+ }
+ return true
+ })
+}
+
+function filterChildren(childrenMap, lastRouter = false) {
+ var children = []
+ childrenMap.forEach((el, index) => {
+ if (el.children && el.children.length) {
+ if (el.component === 'ParentView') {
+ el.children.forEach(c => {
+ c.path = el.path + '/' + c.path
+ if (c.children && c.children.length) {
+ children = children.concat(filterChildren(c.children, c))
+ return
+ }
+ children.push(c)
+ })
+ return
+ }
+ }
+ if (lastRouter) {
+ el.path = lastRouter.path + '/' + el.path
+ }
+ children = children.concat(el)
+ })
+ return children
+}
+
+export const loadView = (view) => { // 路由懒加载
+ return (resolve) => require([`@/views/${view}`], resolve)
+}
+
+export default permission
diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js
new file mode 100644
index 0000000..647a8ce
--- /dev/null
+++ b/src/store/modules/settings.js
@@ -0,0 +1,43 @@
+import variables from '@/assets/styles/element-variables.scss'
+import defaultSettings from '@/settings'
+
+const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
+
+const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
+const state = {
+ title: '',
+ theme: storageSetting.theme || variables.theme,
+ sideTheme: storageSetting.sideTheme || sideTheme,
+ showSettings: showSettings,
+ topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
+ tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
+ fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
+ sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
+ dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
+}
+const mutations = {
+ CHANGE_SETTING: (state, { key, value }) => {
+ if (state.hasOwnProperty(key)) {
+ state[key] = value
+ }
+ }
+}
+
+const actions = {
+ // 修改布局设置
+ changeSetting({ commit }, data) {
+ commit('CHANGE_SETTING', data)
+ },
+ // 设置网页标题
+ setTitle({ commit }, title) {
+ state.title = title
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
+
diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js
new file mode 100644
index 0000000..68bb81d
--- /dev/null
+++ b/src/store/modules/tagsView.js
@@ -0,0 +1,183 @@
+const state = {
+ visitedViews: [],
+ cachedViews: []
+}
+
+const mutations = {
+ ADD_VISITED_VIEW: (state, view) => {
+ if (state.visitedViews.some(v => v.path === view.path)) return
+ state.visitedViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ ADD_CACHED_VIEW: (state, view) => {
+ if (state.cachedViews.includes(view.name)) return
+ if (!view.meta.noCache) {
+ state.cachedViews.push(view.name)
+ }
+ },
+
+ DEL_VISITED_VIEW: (state, view) => {
+ for (const [i, v] of state.visitedViews.entries()) {
+ if (v.path === view.path) {
+ state.visitedViews.splice(i, 1)
+ break
+ }
+ }
+ },
+ DEL_CACHED_VIEW: (state, view) => {
+ const index = state.cachedViews.indexOf(view.name)
+ index > -1 && state.cachedViews.splice(index, 1)
+ },
+
+ DEL_OTHERS_VISITED_VIEWS: (state, view) => {
+ state.visitedViews = state.visitedViews.filter(v => {
+ return v.meta.affix || v.path === view.path
+ })
+ },
+ DEL_OTHERS_CACHED_VIEWS: (state, view) => {
+ const index = state.cachedViews.indexOf(view.name)
+ if (index > -1) {
+ state.cachedViews = state.cachedViews.slice(index, index + 1)
+ } else {
+ state.cachedViews = []
+ }
+ },
+
+ DEL_ALL_VISITED_VIEWS: state => {
+ // keep affix tags
+ const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
+ state.visitedViews = affixTags
+ },
+ DEL_ALL_CACHED_VIEWS: state => {
+ state.cachedViews = []
+ },
+
+ UPDATE_VISITED_VIEW: (state, view) => {
+ for (let v of state.visitedViews) {
+ if (v.path === view.path) {
+ v = Object.assign(v, view)
+ break
+ }
+ }
+ },
+
+ DEL_RIGHT_VIEWS: (state, view) => {
+ const index = state.visitedViews.findIndex(v => v.path === view.path)
+ if (index === -1) {
+ return
+ }
+ state.visitedViews = state.visitedViews.filter((item, idx) => {
+ if (idx <= index || (item.meta && item.meta.affix)) {
+ return true
+ }
+ const i = state.cachedViews.indexOf(item.name)
+ if (i > -1) {
+ state.cachedViews.splice(i, 1)
+ }
+ return false
+ })
+ }
+}
+
+const actions = {
+ addView({ dispatch }, view) {
+ dispatch('addVisitedView', view)
+ dispatch('addCachedView', view)
+ },
+ addVisitedView({ commit }, view) {
+ commit('ADD_VISITED_VIEW', view)
+ },
+ addCachedView({ commit }, view) {
+ commit('ADD_CACHED_VIEW', view)
+ },
+
+ delView({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delVisitedView', view)
+ dispatch('delCachedView', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delVisitedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_VISITED_VIEW', view)
+ resolve([...state.visitedViews])
+ })
+ },
+ delCachedView({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_CACHED_VIEW', view)
+ resolve([...state.cachedViews])
+ })
+ },
+
+ delOthersViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delOthersVisitedViews', view)
+ dispatch('delOthersCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delOthersVisitedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_VISITED_VIEWS', view)
+ resolve([...state.visitedViews])
+ })
+ },
+ delOthersCachedViews({ commit, state }, view) {
+ return new Promise(resolve => {
+ commit('DEL_OTHERS_CACHED_VIEWS', view)
+ resolve([...state.cachedViews])
+ })
+ },
+
+ delAllViews({ dispatch, state }, view) {
+ return new Promise(resolve => {
+ dispatch('delAllVisitedViews', view)
+ dispatch('delAllCachedViews', view)
+ resolve({
+ visitedViews: [...state.visitedViews],
+ cachedViews: [...state.cachedViews]
+ })
+ })
+ },
+ delAllVisitedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_VISITED_VIEWS')
+ resolve([...state.visitedViews])
+ })
+ },
+ delAllCachedViews({ commit, state }) {
+ return new Promise(resolve => {
+ commit('DEL_ALL_CACHED_VIEWS')
+ resolve([...state.cachedViews])
+ })
+ },
+
+ updateVisitedView({ commit }, view) {
+ commit('UPDATE_VISITED_VIEW', view)
+ },
+
+ delRightTags({ commit }, view) {
+ return new Promise(resolve => {
+ commit('DEL_RIGHT_VIEWS', view)
+ resolve([...state.visitedViews])
+ })
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
new file mode 100644
index 0000000..b14d3eb
--- /dev/null
+++ b/src/store/modules/user.js
@@ -0,0 +1,106 @@
+import { login, logout, getInfo } from '@/api/login'
+import { getToken, setToken, removeToken } from '@/utils/auth'
+
+const user = {
+ state: {
+ token: getToken(),
+ name: '',
+ avatar: '',
+ deptId: '',
+ city: '',
+ roles: [],
+ permissions: []
+ },
+
+ mutations: {
+ SET_TOKEN: (state, token) => {
+ state.token = token
+ },
+ SET_NAME: (state, name) => {
+ state.name = name
+ },
+ SET_AVATAR: (state, avatar) => {
+ state.avatar = avatar
+ },
+ SET_ROLES: (state, roles) => {
+ state.roles = roles
+ },
+ SET_DEPT_ID: (state, deptId) => {
+ state.deptId = deptId
+ },
+ SET_CITY: (state, city) => {
+ state.city = city
+ },
+ SET_PERMISSIONS: (state, permissions) => {
+ state.permissions = permissions
+ }
+ },
+
+ actions: {
+ // 登录
+ Login({ commit }, userInfo) {
+ const username = userInfo.username.trim()
+ const password = userInfo.password
+ const code = userInfo.code
+ const uuid = userInfo.uuid
+ return new Promise((resolve, reject) => {
+ login(username, password, code, uuid).then(res => {
+ setToken(res.data.token)
+ commit('SET_TOKEN', res.data.token)
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 获取用户信息
+ GetInfo({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ getInfo().then(res => {
+ const user = res.data.user
+ const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
+ if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
+ commit('SET_ROLES', res.data.roles)
+ commit('SET_PERMISSIONS', res.data.permissions)
+ } else {
+ commit('SET_ROLES', ['ROLE_DEFAULT'])
+ }
+ commit('SET_NAME', user.userName)
+ commit('SET_CITY', user.city)
+ commit('SET_AVATAR', avatar)
+ commit('SET_DEPT_ID', user.deptId)
+ resolve(res)
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 退出系统
+ LogOut({ commit, state }) {
+ return new Promise((resolve, reject) => {
+ logout(state.token).then(() => {
+ commit('SET_TOKEN', '')
+ commit('SET_ROLES', [])
+ commit('SET_PERMISSIONS', [])
+ removeToken()
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+
+ // 前端 登出
+ FedLogOut({ commit }) {
+ return new Promise(resolve => {
+ commit('SET_TOKEN', '')
+ removeToken()
+ resolve()
+ })
+ }
+ }
+}
+
+export default user
diff --git a/src/utils/auth.js b/src/utils/auth.js
new file mode 100644
index 0000000..08a43d6
--- /dev/null
+++ b/src/utils/auth.js
@@ -0,0 +1,15 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'Admin-Token'
+
+export function getToken() {
+ return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+ return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+ return Cookies.remove(TokenKey)
+}
diff --git a/src/utils/errorCode.js b/src/utils/errorCode.js
new file mode 100644
index 0000000..d2111ee
--- /dev/null
+++ b/src/utils/errorCode.js
@@ -0,0 +1,6 @@
+export default {
+ '401': '认证失败,无法访问系统资源',
+ '403': '当前操作没有权限',
+ '404': '访问资源不存在',
+ 'default': '系统未知错误,请反馈给管理员'
+}
diff --git a/src/utils/generator/config.js b/src/utils/generator/config.js
new file mode 100644
index 0000000..7abf227
--- /dev/null
+++ b/src/utils/generator/config.js
@@ -0,0 +1,438 @@
+export const formConf = {
+ formRef: 'elForm',
+ formModel: 'formData',
+ size: 'medium',
+ labelPosition: 'right',
+ labelWidth: 100,
+ formRules: 'rules',
+ gutter: 15,
+ disabled: false,
+ span: 24,
+ formBtns: true
+}
+
+export const inputComponents = [
+ {
+ label: '单行文本',
+ tag: 'el-input',
+ tagIcon: 'input',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '多行文本',
+ tag: 'el-input',
+ tagIcon: 'textarea',
+ type: 'textarea',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ autosize: {
+ minRows: 4,
+ maxRows: 4
+ },
+ style: { width: '100%' },
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '密码',
+ tag: 'el-input',
+ tagIcon: 'password',
+ placeholder: '请输入',
+ defaultValue: undefined,
+ span: 24,
+ 'show-password': true,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': '',
+ 'suffix-icon': '',
+ maxlength: null,
+ 'show-word-limit': false,
+ readonly: false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input'
+ },
+ {
+ label: '计数器',
+ tag: 'el-input-number',
+ tagIcon: 'number',
+ placeholder: '',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ min: undefined,
+ max: undefined,
+ step: undefined,
+ 'step-strictly': false,
+ precision: undefined,
+ 'controls-position': '',
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/input-number'
+ }
+]
+
+export const selectComponents = [
+ {
+ label: '下拉选择',
+ tag: 'el-select',
+ tagIcon: 'select',
+ placeholder: '请选择',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ clearable: true,
+ disabled: false,
+ required: true,
+ filterable: false,
+ multiple: false,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/select'
+ },
+ {
+ label: '级联选择',
+ tag: 'el-cascader',
+ tagIcon: 'cascader',
+ placeholder: '请选择',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ props: {
+ props: {
+ multiple: false
+ }
+ },
+ 'show-all-levels': true,
+ disabled: false,
+ clearable: true,
+ filterable: false,
+ required: true,
+ options: [{
+ id: 1,
+ value: 1,
+ label: '选项1',
+ children: [{
+ id: 2,
+ value: 2,
+ label: '选项1-1'
+ }]
+ }],
+ dataType: 'dynamic',
+ labelKey: 'label',
+ valueKey: 'value',
+ childrenKey: 'children',
+ separator: '/',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/cascader'
+ },
+ {
+ label: '单选框组',
+ tag: 'el-radio-group',
+ tagIcon: 'radio',
+ defaultValue: undefined,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/radio'
+ },
+ {
+ label: '多选框组',
+ tag: 'el-checkbox-group',
+ tagIcon: 'checkbox',
+ defaultValue: [],
+ span: 24,
+ labelWidth: null,
+ style: {},
+ optionType: 'default',
+ border: false,
+ size: 'medium',
+ disabled: false,
+ required: true,
+ options: [{
+ label: '选项一',
+ value: 1
+ }, {
+ label: '选项二',
+ value: 2
+ }],
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/checkbox'
+ },
+ {
+ label: '开关',
+ tag: 'el-switch',
+ tagIcon: 'switch',
+ defaultValue: false,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ disabled: false,
+ required: true,
+ 'active-text': '',
+ 'inactive-text': '',
+ 'active-color': null,
+ 'inactive-color': null,
+ 'active-value': true,
+ 'inactive-value': false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/switch'
+ },
+ {
+ label: '滑块',
+ tag: 'el-slider',
+ tagIcon: 'slider',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ min: 0,
+ max: 100,
+ step: 1,
+ 'show-stops': false,
+ range: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/slider'
+ },
+ {
+ label: '时间选择',
+ tag: 'el-time-picker',
+ tagIcon: 'time',
+ placeholder: '请选择',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'picker-options': {
+ selectableRange: '00:00:00-23:59:59'
+ },
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '时间范围',
+ tag: 'el-time-picker',
+ tagIcon: 'time-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ 'is-range': true,
+ 'range-separator': '至',
+ 'start-placeholder': '开始时间',
+ 'end-placeholder': '结束时间',
+ format: 'HH:mm:ss',
+ 'value-format': 'HH:mm:ss',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/time-picker'
+ },
+ {
+ label: '日期选择',
+ tag: 'el-date-picker',
+ tagIcon: 'date',
+ placeholder: '请选择',
+ defaultValue: null,
+ type: 'date',
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '日期范围',
+ tag: 'el-date-picker',
+ tagIcon: 'date-range',
+ defaultValue: null,
+ span: 24,
+ labelWidth: null,
+ style: { width: '100%' },
+ type: 'daterange',
+ 'range-separator': '至',
+ 'start-placeholder': '开始日期',
+ 'end-placeholder': '结束日期',
+ disabled: false,
+ clearable: true,
+ required: true,
+ format: 'yyyy-MM-dd',
+ 'value-format': 'yyyy-MM-dd',
+ readonly: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/date-picker'
+ },
+ {
+ label: '评分',
+ tag: 'el-rate',
+ tagIcon: 'rate',
+ defaultValue: 0,
+ span: 24,
+ labelWidth: null,
+ style: {},
+ max: 5,
+ 'allow-half': false,
+ 'show-text': false,
+ 'show-score': false,
+ disabled: false,
+ required: true,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/rate'
+ },
+ {
+ label: '颜色选择',
+ tag: 'el-color-picker',
+ tagIcon: 'color',
+ defaultValue: null,
+ labelWidth: null,
+ 'show-alpha': false,
+ 'color-format': '',
+ disabled: false,
+ required: true,
+ size: 'medium',
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/color-picker'
+ },
+ {
+ label: '上传',
+ tag: 'el-upload',
+ tagIcon: 'upload',
+ action: 'https://jsonplaceholder.typicode.com/posts/',
+ defaultValue: null,
+ labelWidth: null,
+ disabled: false,
+ required: true,
+ accept: '',
+ name: 'file',
+ 'auto-upload': true,
+ showTip: false,
+ buttonText: '点击上传',
+ fileSize: 2,
+ sizeUnit: 'MB',
+ 'list-type': 'text',
+ multiple: false,
+ regList: [],
+ changeTag: true,
+ document: 'https://element.eleme.cn/#/zh-CN/component/upload'
+ }
+]
+
+export const layoutComponents = [
+ {
+ layout: 'rowFormItem',
+ tagIcon: 'row',
+ type: 'default',
+ justify: 'start',
+ align: 'top',
+ label: '行容器',
+ layoutTree: true,
+ children: [],
+ document: 'https://element.eleme.cn/#/zh-CN/component/layout'
+ },
+ {
+ layout: 'colFormItem',
+ label: '按钮',
+ changeTag: true,
+ labelWidth: null,
+ tag: 'el-button',
+ tagIcon: 'button',
+ span: 24,
+ default: '主要按钮',
+ type: 'primary',
+ icon: 'el-icon-search',
+ size: 'medium',
+ disabled: false,
+ document: 'https://element.eleme.cn/#/zh-CN/component/button'
+ }
+]
+
+// 组件rule的触发方式,无触发方式的组件不生成rule
+export const trigger = {
+ 'el-input': 'blur',
+ 'el-input-number': 'blur',
+ 'el-select': 'change',
+ 'el-radio-group': 'change',
+ 'el-checkbox-group': 'change',
+ 'el-cascader': 'change',
+ 'el-time-picker': 'change',
+ 'el-date-picker': 'change',
+ 'el-rate': 'change'
+}
diff --git a/src/utils/generator/css.js b/src/utils/generator/css.js
new file mode 100644
index 0000000..c1c62e6
--- /dev/null
+++ b/src/utils/generator/css.js
@@ -0,0 +1,18 @@
+const styles = {
+ 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}',
+ 'el-upload': '.el-upload__tip{line-height: 1.2;}'
+}
+
+function addCss(cssList, el) {
+ const css = styles[el.tag]
+ css && cssList.indexOf(css) === -1 && cssList.push(css)
+ if (el.children) {
+ el.children.forEach(el2 => addCss(cssList, el2))
+ }
+}
+
+export function makeUpCss(conf) {
+ const cssList = []
+ conf.fields.forEach(el => addCss(cssList, el))
+ return cssList.join('\n')
+}
diff --git a/src/utils/generator/drawingDefalut.js b/src/utils/generator/drawingDefalut.js
new file mode 100644
index 0000000..09f133c
--- /dev/null
+++ b/src/utils/generator/drawingDefalut.js
@@ -0,0 +1,29 @@
+export default [
+ {
+ layout: 'colFormItem',
+ tagIcon: 'input',
+ label: '手机号',
+ vModel: 'mobile',
+ formId: 6,
+ tag: 'el-input',
+ placeholder: '请输入手机号',
+ defaultValue: '',
+ span: 24,
+ style: { width: '100%' },
+ clearable: true,
+ prepend: '',
+ append: '',
+ 'prefix-icon': 'el-icon-mobile',
+ 'suffix-icon': '',
+ maxlength: 11,
+ 'show-word-limit': true,
+ readonly: false,
+ disabled: false,
+ required: true,
+ changeTag: true,
+ regList: [{
+ pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
+ message: '手机号格式错误'
+ }]
+ }
+]
diff --git a/src/utils/generator/html.js b/src/utils/generator/html.js
new file mode 100644
index 0000000..ebf628d
--- /dev/null
+++ b/src/utils/generator/html.js
@@ -0,0 +1,359 @@
+/* eslint-disable max-len */
+import { trigger } from './config'
+
+let confGlobal
+let someSpanIsNot24
+
+export function dialogWrapper(str) {
+ return `
+ ${str}
+
+ 取消
+ 确定
+
+ `
+}
+
+export function vueTemplate(str) {
+ return `
+
+ ${str}
+
+ `
+}
+
+export function vueScript(str) {
+ return ``
+}
+
+export function cssStyle(cssStr) {
+ return ``
+}
+
+function buildFormTemplate(conf, child, type) {
+ let labelPosition = ''
+ if (conf.labelPosition !== 'right') {
+ labelPosition = `label-position="${conf.labelPosition}"`
+ }
+ const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : ''
+ let str = `
+ ${child}
+ ${buildFromBtns(conf, type)}
+ `
+ if (someSpanIsNot24) {
+ str = `
+ ${str}
+ `
+ }
+ return str
+}
+
+function buildFromBtns(conf, type) {
+ let str = ''
+ if (conf.formBtns && type === 'file') {
+ str = `
+ 提交
+ 重置
+ `
+ if (someSpanIsNot24) {
+ str = `
+ ${str}
+ `
+ }
+ }
+ return str
+}
+
+// span不为24的用el-col包裹
+function colWrapper(element, str) {
+ if (someSpanIsNot24 || element.span !== 24) {
+ return `
+ ${str}
+ `
+ }
+ return str
+}
+
+const layouts = {
+ colFormItem(element) {
+ let labelWidth = ''
+ if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) {
+ labelWidth = `label-width="${element.labelWidth}px"`
+ }
+ const required = !trigger[element.tag] && element.required ? 'required' : ''
+ const tagDom = tags[element.tag] ? tags[element.tag](element) : null
+ let str = `
+ ${tagDom}
+ `
+ str = colWrapper(element, str)
+ return str
+ },
+ rowFormItem(element) {
+ const type = element.type === 'default' ? '' : `type="${element.type}"`
+ const justify = element.type === 'default' ? '' : `justify="${element.justify}"`
+ const align = element.type === 'default' ? '' : `align="${element.align}"`
+ const gutter = element.gutter ? `gutter="${element.gutter}"` : ''
+ const children = element.children.map(el => layouts[el.layout](el))
+ let str = `
+ ${children.join('\n')}
+ `
+ str = colWrapper(element, str)
+ return str
+ }
+}
+
+const tags = {
+ 'el-button': el => {
+ const {
+ tag, disabled
+ } = attrBuilder(el)
+ const type = el.type ? `type="${el.type}"` : ''
+ const icon = el.icon ? `icon="${el.icon}"` : ''
+ const size = el.size ? `size="${el.size}"` : ''
+ let child = buildElButtonChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-input': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : ''
+ const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : ''
+ const readonly = el.readonly ? 'readonly' : ''
+ const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : ''
+ const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : ''
+ const showPassword = el['show-password'] ? 'show-password' : ''
+ const type = el.type ? `type="${el.type}"` : ''
+ const autosize = el.autosize && el.autosize.minRows
+ ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"`
+ : ''
+ let child = buildElInputChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}${el.tag}>`
+ },
+ 'el-input-number': el => {
+ const { disabled, vModel, placeholder } = attrBuilder(el)
+ const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : ''
+ const min = el.min ? `:min='${el.min}'` : ''
+ const max = el.max ? `:max='${el.max}'` : ''
+ const step = el.step ? `:step='${el.step}'` : ''
+ const stepStrictly = el['step-strictly'] ? 'step-strictly' : ''
+ const precision = el.precision ? `:precision='${el.precision}'` : ''
+
+ return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}>${el.tag}>`
+ },
+ 'el-select': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const filterable = el.filterable ? 'filterable' : ''
+ const multiple = el.multiple ? 'multiple' : ''
+ let child = buildElSelectChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}${el.tag}>`
+ },
+ 'el-radio-group': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ let child = buildElRadioGroupChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-checkbox-group': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ const min = el.min ? `:min="${el.min}"` : ''
+ const max = el.max ? `:max="${el.max}"` : ''
+ let child = buildElCheckboxGroupChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}${el.tag}>`
+ },
+ 'el-switch': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : ''
+ const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : ''
+ const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : ''
+ const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : ''
+ const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : ''
+ const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : ''
+
+ return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}>${el.tag}>`
+ },
+ 'el-cascader': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const options = el.options ? `:options="${el.vModel}Options"` : ''
+ const props = el.props ? `:props="${el.vModel}Props"` : ''
+ const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"'
+ const filterable = el.filterable ? 'filterable' : ''
+ const separator = el.separator === '/' ? '' : `separator="${el.separator}"`
+
+ return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}>${el.tag}>`
+ },
+ 'el-slider': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const min = el.min ? `:min='${el.min}'` : ''
+ const max = el.max ? `:max='${el.max}'` : ''
+ const step = el.step ? `:step='${el.step}'` : ''
+ const range = el.range ? 'range' : ''
+ const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : ''
+
+ return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}>${el.tag}>`
+ },
+ 'el-time-picker': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
+ const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
+ const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
+ const isRange = el['is-range'] ? 'is-range' : ''
+ const format = el.format ? `format="${el.format}"` : ''
+ const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
+ const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : ''
+
+ return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}>${el.tag}>`
+ },
+ 'el-date-picker': el => {
+ const {
+ disabled, vModel, clearable, placeholder, width
+ } = attrBuilder(el)
+ const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : ''
+ const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : ''
+ const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : ''
+ const format = el.format ? `format="${el.format}"` : ''
+ const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : ''
+ const type = el.type === 'date' ? '' : `type="${el.type}"`
+ const readonly = el.readonly ? 'readonly' : ''
+
+ return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}>${el.tag}>`
+ },
+ 'el-rate': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const max = el.max ? `:max='${el.max}'` : ''
+ const allowHalf = el['allow-half'] ? 'allow-half' : ''
+ const showText = el['show-text'] ? 'show-text' : ''
+ const showScore = el['show-score'] ? 'show-score' : ''
+
+ return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}>${el.tag}>`
+ },
+ 'el-color-picker': el => {
+ const { disabled, vModel } = attrBuilder(el)
+ const size = `size="${el.size}"`
+ const showAlpha = el['show-alpha'] ? 'show-alpha' : ''
+ const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : ''
+
+ return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}>${el.tag}>`
+ },
+ 'el-upload': el => {
+ const disabled = el.disabled ? ':disabled=\'true\'' : ''
+ const action = el.action ? `:action="${el.vModel}Action"` : ''
+ const multiple = el.multiple ? 'multiple' : ''
+ const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : ''
+ const accept = el.accept ? `accept="${el.accept}"` : ''
+ const name = el.name !== 'file' ? `name="${el.name}"` : ''
+ const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : ''
+ const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"`
+ const fileList = `:file-list="${el.vModel}fileList"`
+ const ref = `ref="${el.vModel}"`
+ let child = buildElUploadChild(el)
+
+ if (child) child = `\n${child}\n` // 换行
+ return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}${el.tag}>`
+ }
+}
+
+function attrBuilder(el) {
+ return {
+ vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`,
+ clearable: el.clearable ? 'clearable' : '',
+ placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '',
+ width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '',
+ disabled: el.disabled ? ':disabled=\'true\'' : ''
+ }
+}
+
+// el-buttin 子级
+function buildElButtonChild(conf) {
+ const children = []
+ if (conf.default) {
+ children.push(conf.default)
+ }
+ return children.join('\n')
+}
+
+// el-input innerHTML
+function buildElInputChild(conf) {
+ const children = []
+ if (conf.prepend) {
+ children.push(`${conf.prepend} `)
+ }
+ if (conf.append) {
+ children.push(`${conf.append} `)
+ }
+ return children.join('\n')
+}
+
+function buildElSelectChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ children.push(` `)
+ }
+ return children.join('\n')
+}
+
+function buildElRadioGroupChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio'
+ const border = conf.border ? 'border' : ''
+ children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}${tag}>`)
+ }
+ return children.join('\n')
+}
+
+function buildElCheckboxGroupChild(conf) {
+ const children = []
+ if (conf.options && conf.options.length) {
+ const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox'
+ const border = conf.border ? 'border' : ''
+ children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}${tag}>`)
+ }
+ return children.join('\n')
+}
+
+function buildElUploadChild(conf) {
+ const list = []
+ if (conf['list-type'] === 'picture-card') list.push(' ')
+ else list.push(`${conf.buttonText} `)
+ if (conf.showTip) list.push(`只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件
`)
+ return list.join('\n')
+}
+
+export function makeUpHtml(conf, type) {
+ const htmlList = []
+ confGlobal = conf
+ someSpanIsNot24 = conf.fields.some(item => item.span !== 24)
+ conf.fields.forEach(el => {
+ htmlList.push(layouts[el.layout](el))
+ })
+ const htmlStr = htmlList.join('\n')
+
+ let temp = buildFormTemplate(conf, htmlStr, type)
+ if (type === 'dialog') {
+ temp = dialogWrapper(temp)
+ }
+ confGlobal = null
+ return temp
+}
diff --git a/src/utils/generator/icon.json b/src/utils/generator/icon.json
new file mode 100644
index 0000000..2d9999a
--- /dev/null
+++ b/src/utils/generator/icon.json
@@ -0,0 +1 @@
+["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"]
\ No newline at end of file
diff --git a/src/utils/generator/js.js b/src/utils/generator/js.js
new file mode 100644
index 0000000..c6c06a9
--- /dev/null
+++ b/src/utils/generator/js.js
@@ -0,0 +1,236 @@
+import { isArray } from 'util'
+import { exportDefault, titleCase } from '@/utils/index'
+import { trigger } from './config'
+
+const units = {
+ KB: '1024',
+ MB: '1024 / 1024',
+ GB: '1024 / 1024 / 1024'
+}
+let confGlobal
+const inheritAttrs = {
+ file: '',
+ dialog: 'inheritAttrs: false,'
+}
+
+
+export function makeUpJs(conf, type) {
+ confGlobal = conf = JSON.parse(JSON.stringify(conf))
+ const dataList = []
+ const ruleList = []
+ const optionsList = []
+ const propsList = []
+ const methodList = mixinMethod(type)
+ const uploadVarList = []
+
+ conf.fields.forEach(el => {
+ buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
+ })
+
+ const script = buildexport(
+ conf,
+ type,
+ dataList.join('\n'),
+ ruleList.join('\n'),
+ optionsList.join('\n'),
+ uploadVarList.join('\n'),
+ propsList.join('\n'),
+ methodList.join('\n')
+ )
+ confGlobal = null
+ return script
+}
+
+function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) {
+ buildData(el, dataList)
+ buildRules(el, ruleList)
+
+ if (el.options && el.options.length) {
+ buildOptions(el, optionsList)
+ if (el.dataType === 'dynamic') {
+ const model = `${el.vModel}Options`
+ const options = titleCase(model)
+ buildOptionMethod(`get${options}`, model, methodList)
+ }
+ }
+
+ if (el.props && el.props.props) {
+ buildProps(el, propsList)
+ }
+
+ if (el.action && el.tag === 'el-upload') {
+ uploadVarList.push(
+ `${el.vModel}Action: '${el.action}',
+ ${el.vModel}fileList: [],`
+ )
+ methodList.push(buildBeforeUpload(el))
+ if (!el['auto-upload']) {
+ methodList.push(buildSubmitUpload(el))
+ }
+ }
+
+ if (el.children) {
+ el.children.forEach(el2 => {
+ buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList)
+ })
+ }
+}
+
+function mixinMethod(type) {
+ const list = []; const
+ minxins = {
+ file: confGlobal.formBtns ? {
+ submitForm: `submitForm() {
+ this.$refs['${confGlobal.formRef}'].validate(valid => {
+ if(!valid) return
+ // TODO 提交表单
+ })
+ },`,
+ resetForm: `resetForm() {
+ this.$refs['${confGlobal.formRef}'].resetFields()
+ },`
+ } : null,
+ dialog: {
+ onOpen: 'onOpen() {},',
+ onClose: `onClose() {
+ this.$refs['${confGlobal.formRef}'].resetFields()
+ },`,
+ close: `close() {
+ this.$emit('update:visible', false)
+ },`,
+ handelConfirm: `handelConfirm() {
+ this.$refs['${confGlobal.formRef}'].validate(valid => {
+ if(!valid) return
+ this.close()
+ })
+ },`
+ }
+ }
+
+ const methods = minxins[type]
+ if (methods) {
+ Object.keys(methods).forEach(key => {
+ list.push(methods[key])
+ })
+ }
+
+ return list
+}
+
+function buildData(conf, dataList) {
+ if (conf.vModel === undefined) return
+ let defaultValue
+ if (typeof (conf.defaultValue) === 'string' && !conf.multiple) {
+ defaultValue = `'${conf.defaultValue}'`
+ } else {
+ defaultValue = `${JSON.stringify(conf.defaultValue)}`
+ }
+ dataList.push(`${conf.vModel}: ${defaultValue},`)
+}
+
+function buildRules(conf, ruleList) {
+ if (conf.vModel === undefined) return
+ const rules = []
+ if (trigger[conf.tag]) {
+ if (conf.required) {
+ const type = isArray(conf.defaultValue) ? 'type: \'array\',' : ''
+ let message = isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder
+ if (message === undefined) message = `${conf.label}不能为空`
+ rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`)
+ }
+ if (conf.regList && isArray(conf.regList)) {
+ conf.regList.forEach(item => {
+ if (item.pattern) {
+ rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`)
+ }
+ })
+ }
+ ruleList.push(`${conf.vModel}: [${rules.join(',')}],`)
+ }
+}
+
+function buildOptions(conf, optionsList) {
+ if (conf.vModel === undefined) return
+ if (conf.dataType === 'dynamic') { conf.options = [] }
+ const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},`
+ optionsList.push(str)
+}
+
+function buildProps(conf, propsList) {
+ if (conf.dataType === 'dynamic') {
+ conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey)
+ conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey)
+ conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey)
+ }
+ const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},`
+ propsList.push(str)
+}
+
+function buildBeforeUpload(conf) {
+ const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const
+ returnList = []
+ if (conf.fileSize) {
+ rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize}
+ if(!isRightSize){
+ this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}')
+ }`
+ returnList.push('isRightSize')
+ }
+ if (conf.accept) {
+ acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type)
+ if(!isAccept){
+ this.$message.error('应该选择${conf.accept}类型的文件')
+ }`
+ returnList.push('isAccept')
+ }
+ const str = `${conf.vModel}BeforeUpload(file) {
+ ${rightSizeCode}
+ ${acceptCode}
+ return ${returnList.join('&&')}
+ },`
+ return returnList.length ? str : ''
+}
+
+function buildSubmitUpload(conf) {
+ const str = `submitUpload() {
+ this.$refs['${conf.vModel}'].submit()
+ },`
+ return str
+}
+
+function buildOptionMethod(methodName, model, methodList) {
+ const str = `${methodName}() {
+ // TODO 发起请求获取数据
+ this.${model}
+ },`
+ methodList.push(str)
+}
+
+function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) {
+ const str = `${exportDefault}{
+ ${inheritAttrs[type]}
+ components: {},
+ props: [],
+ data () {
+ return {
+ ${conf.formModel}: {
+ ${data}
+ },
+ ${conf.formRules}: {
+ ${rules}
+ },
+ ${uploadVar}
+ ${selectOptions}
+ ${props}
+ }
+ },
+ computed: {},
+ watch: {},
+ created () {},
+ mounted () {},
+ methods: {
+ ${methods}
+ }
+}`
+ return str
+}
diff --git a/src/utils/generator/render.js b/src/utils/generator/render.js
new file mode 100644
index 0000000..e8640f0
--- /dev/null
+++ b/src/utils/generator/render.js
@@ -0,0 +1,126 @@
+import { makeMap } from '@/utils/index'
+
+// 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js
+const isAttr = makeMap(
+ 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,'
+ + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,'
+ + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,'
+ + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,'
+ + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,'
+ + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,'
+ + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,'
+ + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,'
+ + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,'
+ + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,'
+ + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,'
+ + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,'
+ + 'target,title,type,usemap,value,width,wrap'
+)
+
+function vModel(self, dataObject, defaultValue) {
+ dataObject.props.value = defaultValue
+
+ dataObject.on.input = val => {
+ self.$emit('input', val)
+ }
+}
+
+const componentChild = {
+ 'el-button': {
+ default(h, conf, key) {
+ return conf[key]
+ },
+ },
+ 'el-input': {
+ prepend(h, conf, key) {
+ return {conf[key]}
+ },
+ append(h, conf, key) {
+ return {conf[key]}
+ }
+ },
+ 'el-select': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ list.push( )
+ })
+ return list
+ }
+ },
+ 'el-radio-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') list.push({item.label} )
+ else list.push({item.label} )
+ })
+ return list
+ }
+ },
+ 'el-checkbox-group': {
+ options(h, conf, key) {
+ const list = []
+ conf.options.forEach(item => {
+ if (conf.optionType === 'button') {
+ list.push({item.label} )
+ } else {
+ list.push({item.label} )
+ }
+ })
+ return list
+ }
+ },
+ 'el-upload': {
+ 'list-type': (h, conf, key) => {
+ const list = []
+ if (conf['list-type'] === 'picture-card') {
+ list.push( )
+ } else {
+ list.push({conf.buttonText} )
+ }
+ if (conf.showTip) {
+ list.push(只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件
)
+ }
+ return list
+ }
+ }
+}
+
+export default {
+ render(h) {
+ const dataObject = {
+ attrs: {},
+ props: {},
+ on: {},
+ style: {}
+ }
+ const confClone = JSON.parse(JSON.stringify(this.conf))
+ const children = []
+
+ const childObjs = componentChild[confClone.tag]
+ if (childObjs) {
+ Object.keys(childObjs).forEach(key => {
+ const childFunc = childObjs[key]
+ if (confClone[key]) {
+ children.push(childFunc(h, confClone, key))
+ }
+ })
+ }
+
+ Object.keys(confClone).forEach(key => {
+ const val = confClone[key]
+ if (key === 'vModel') {
+ vModel(this, dataObject, confClone.defaultValue)
+ } else if (dataObject[key]) {
+ dataObject[key] = val
+ } else if (!isAttr(key)) {
+ dataObject.props[key] = val
+ } else {
+ dataObject.attrs[key] = val
+ }
+ })
+ return h(this.conf.tag, dataObject, children)
+ },
+ props: ['conf']
+}
diff --git a/src/utils/index.js b/src/utils/index.js
new file mode 100644
index 0000000..918580f
--- /dev/null
+++ b/src/utils/index.js
@@ -0,0 +1,390 @@
+import { parseTime } from './ruoyi'
+
+/**
+ * 表格时间格式化
+ */
+export function formatDate(cellValue) {
+ if (cellValue == null || cellValue == "") return "";
+ var date = new Date(cellValue)
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+}
+
+/**
+ * @param {number} time
+ * @param {string} option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+ if (('' + time).length === 10) {
+ time = parseInt(time) * 1000
+ } else {
+ time = +time
+ }
+ const d = new Date(time)
+ const now = Date.now()
+
+ const diff = (now - d) / 1000
+
+ if (diff < 30) {
+ return '刚刚'
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + '分钟前'
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + '小时前'
+ } else if (diff < 3600 * 24 * 2) {
+ return '1天前'
+ }
+ if (option) {
+ return parseTime(time, option)
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
+ }
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function getQueryObject(url) {
+ url = url == null ? window.location.href : url
+ const search = url.substring(url.lastIndexOf('?') + 1)
+ const obj = {}
+ const reg = /([^?&=]+)=([^?&=]*)/g
+ search.replace(reg, (rs, $1, $2) => {
+ const name = decodeURIComponent($1)
+ let val = decodeURIComponent($2)
+ val = String(val)
+ obj[name] = val
+ return rs
+ })
+ return obj
+}
+
+/**
+ * @param {string} input value
+ * @returns {number} output value
+ */
+export function byteLength(str) {
+ // returns the byte length of an utf8 string
+ let s = str.length
+ for (var i = str.length - 1; i >= 0; i--) {
+ const code = str.charCodeAt(i)
+ if (code > 0x7f && code <= 0x7ff) s++
+ else if (code > 0x7ff && code <= 0xffff) s += 2
+ if (code >= 0xDC00 && code <= 0xDFFF) i--
+ }
+ return s
+}
+
+/**
+ * @param {Array} actual
+ * @returns {Array}
+ */
+export function cleanArray(actual) {
+ const newArray = []
+ for (let i = 0; i < actual.length; i++) {
+ if (actual[i]) {
+ newArray.push(actual[i])
+ }
+ }
+ return newArray
+}
+
+/**
+ * @param {Object} json
+ * @returns {Array}
+ */
+export function param(json) {
+ if (!json) return ''
+ return cleanArray(
+ Object.keys(json).map(key => {
+ if (json[key] === undefined) return ''
+ return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+ })
+ ).join('&')
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function param2Obj(url) {
+ const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+ if (!search) {
+ return {}
+ }
+ const obj = {}
+ const searchArr = search.split('&')
+ searchArr.forEach(v => {
+ const index = v.indexOf('=')
+ if (index !== -1) {
+ const name = v.substring(0, index)
+ const val = v.substring(index + 1, v.length)
+ obj[name] = val
+ }
+ })
+ return obj
+}
+
+/**
+ * @param {string} val
+ * @returns {string}
+ */
+export function html2Text(val) {
+ const div = document.createElement('div')
+ div.innerHTML = val
+ return div.textContent || div.innerText
+}
+
+/**
+ * Merges two objects, giving the last one precedence
+ * @param {Object} target
+ * @param {(Object|Array)} source
+ * @returns {Object}
+ */
+export function objectMerge(target, source) {
+ if (typeof target !== 'object') {
+ target = {}
+ }
+ if (Array.isArray(source)) {
+ return source.slice()
+ }
+ Object.keys(source).forEach(property => {
+ const sourceProperty = source[property]
+ if (typeof sourceProperty === 'object') {
+ target[property] = objectMerge(target[property], sourceProperty)
+ } else {
+ target[property] = sourceProperty
+ }
+ })
+ return target
+}
+
+/**
+ * @param {HTMLElement} element
+ * @param {string} className
+ */
+export function toggleClass(element, className) {
+ if (!element || !className) {
+ return
+ }
+ let classString = element.className
+ const nameIndex = classString.indexOf(className)
+ if (nameIndex === -1) {
+ classString += '' + className
+ } else {
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
+ }
+ element.className = classString
+}
+
+/**
+ * @param {string} type
+ * @returns {Date}
+ */
+export function getTime(type) {
+ if (type === 'start') {
+ return new Date().getTime() - 3600 * 1000 * 24 * 90
+ } else {
+ return new Date(new Date().toDateString())
+ }
+}
+
+/**
+ * @param {Function} func
+ * @param {number} wait
+ * @param {boolean} immediate
+ * @return {*}
+ */
+export function debounce(func, wait, immediate) {
+ let timeout, args, context, timestamp, result
+
+ const later = function() {
+ // 据上一次触发时间间隔
+ const last = +new Date() - timestamp
+
+ // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last)
+ } else {
+ timeout = null
+ // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+ if (!immediate) {
+ result = func.apply(context, args)
+ if (!timeout) context = args = null
+ }
+ }
+ }
+
+ return function(...args) {
+ context = this
+ timestamp = +new Date()
+ const callNow = immediate && !timeout
+ // 如果延时不存在,重新设定延时
+ if (!timeout) timeout = setTimeout(later, wait)
+ if (callNow) {
+ result = func.apply(context, args)
+ context = args = null
+ }
+
+ return result
+ }
+}
+
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ * @param {Object} source
+ * @returns {Object}
+ */
+export function deepClone(source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'deepClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+/**
+ * @param {Array} arr
+ * @returns {Array}
+ */
+export function uniqueArr(arr) {
+ return Array.from(new Set(arr))
+}
+
+/**
+ * @returns {string}
+ */
+export function createUniqueString() {
+ const timestamp = +new Date() + ''
+ const randomNum = parseInt((1 + Math.random()) * 65536) + ''
+ return (+(randomNum + timestamp)).toString(32)
+}
+
+/**
+ * Check if an element has a class
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ * @returns {boolean}
+ */
+export function hasClass(ele, cls) {
+ return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+}
+
+/**
+ * Add class to element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function addClass(ele, cls) {
+ if (!hasClass(ele, cls)) ele.className += ' ' + cls
+}
+
+/**
+ * Remove class from element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function removeClass(ele, cls) {
+ if (hasClass(ele, cls)) {
+ const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
+ ele.className = ele.className.replace(reg, ' ')
+ }
+}
+
+export function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null)
+ const list = str.split(',')
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true
+ }
+ return expectsLowerCase
+ ? val => map[val.toLowerCase()]
+ : val => map[val]
+}
+
+export const exportDefault = 'export default '
+
+export const beautifierConf = {
+ html: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'separate',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: false,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ },
+ js: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'normal',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: true,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ }
+}
+
+// 首字母大小
+export function titleCase(str) {
+ return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+}
+
+// 下划转驼峰
+export function camelCase(str) {
+ return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+}
+
+export function isNumberStr(str) {
+ return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+}
+
diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js
new file mode 100644
index 0000000..78d9523
--- /dev/null
+++ b/src/utils/jsencrypt.js
@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+ 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+ '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+ 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+ 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+ 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+ 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+ 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+ 'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPublicKey(publicKey) // 设置公钥
+ return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPrivateKey(privateKey) // 设置私钥
+ return encryptor.decrypt(txt) // 对数据进行解密
+}
+
diff --git a/src/utils/permission.js b/src/utils/permission.js
new file mode 100644
index 0000000..bd4c066
--- /dev/null
+++ b/src/utils/permission.js
@@ -0,0 +1,51 @@
+import store from '@/store'
+
+/**
+ * 字符权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkPermi(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const permissions = store.getters && store.getters.permissions
+ const permissionDatas = value
+ const all_permission = "*:*:*";
+
+ const hasPermission = permissions.some(permission => {
+ return all_permission === permission || permissionDatas.includes(permission)
+ })
+
+ if (!hasPermission) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
+ return false
+ }
+}
+
+/**
+ * 角色权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkRole(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const roles = store.getters && store.getters.roles
+ const permissionRoles = value
+ const super_admin = "admin";
+
+ const hasRole = roles.some(role => {
+ return super_admin === role || permissionRoles.includes(role)
+ })
+
+ if (!hasRole) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkRole="['admin','editor']"`)
+ return false
+ }
+}
diff --git a/src/utils/request.js b/src/utils/request.js
new file mode 100644
index 0000000..a510d2d
--- /dev/null
+++ b/src/utils/request.js
@@ -0,0 +1,103 @@
+import axios from 'axios'
+import { Notification, MessageBox, Message } from 'element-ui'
+import store from '@/store'
+import { getToken } from '@/utils/auth'
+import errorCode from '@/utils/errorCode'
+
+axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+// 创建axios实例
+const service = axios.create({
+ // axios中请求配置有baseURL选项,表示请求URL公共部分
+ baseURL: process.env.VUE_APP_BASE_API,
+ // 超时
+ timeout: 10000
+})
+// request拦截器
+service.interceptors.request.use(config => {
+ // 是否需要设置 token
+ const isToken = (config.headers || {}).isToken === false
+ if (getToken() && !isToken) {
+ config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+ }
+ // get请求映射params参数
+ if (config.method === 'get' && config.params) {
+ let url = config.url + '?';
+ for (const propName of Object.keys(config.params)) {
+ const value = config.params[propName];
+ var part = encodeURIComponent(propName) + "=";
+ if (value !== null && typeof(value) !== "undefined") {
+ if (typeof value === 'object') {
+ for (const key of Object.keys(value)) {
+ let params = propName + '[' + key + ']';
+ var subPart = encodeURIComponent(params) + "=";
+ url += subPart + encodeURIComponent(value[key]) + "&";
+ }
+ } else {
+ url += part + encodeURIComponent(value) + "&";
+ }
+ }
+ }
+ url = url.slice(0, -1);
+ config.params = {};
+ config.url = url;
+ }
+ return config
+}, error => {
+ console.log(error)
+ Promise.reject(error)
+})
+
+// 响应拦截器
+service.interceptors.response.use(res => {
+ // 未设置状态码则默认成功状态
+ const code = res.data.code || 200;
+ // 获取错误信息
+ const msg = errorCode[code] || res.data.msg || errorCode['default']
+ if (code === 401) {
+ MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
+ confirmButtonText: '重新登录',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }
+ ).then(() => {
+ store.dispatch('LogOut').then(() => {
+ location.href = '/index';
+ })
+ }).catch(() => {});
+ } else if (code === 500) {
+ Message({
+ message: msg,
+ type: 'error'
+ })
+ return Promise.reject(new Error(msg))
+ } else if (code !== 200) {
+ Notification.error({
+ title: msg
+ })
+ return Promise.reject('error')
+ } else {
+ return res.data
+ }
+ },
+ error => {
+ console.log('err' + error)
+ let { message } = error;
+ if (message == "Network Error") {
+ message = "后端接口连接异常";
+ }
+ else if (message.includes("timeout")) {
+ message = "系统接口请求超时";
+ }
+ else if (message.includes("Request failed with status code")) {
+ message = "系统接口" + message.substr(message.length - 3) + "异常";
+ }
+ Message({
+ message: message,
+ type: 'error',
+ duration: 5 * 1000
+ })
+ return Promise.reject(error)
+ }
+)
+
+export default service
diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js
new file mode 100644
index 0000000..e86215a
--- /dev/null
+++ b/src/utils/ruoyi.js
@@ -0,0 +1,210 @@
+/**
+ * 通用js方法封装处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+const baseURL = process.env.VUE_APP_BASE_API
+
+/*
+* 参数说明:
+* number:要格式化的数字
+* decimals:保留几位小数
+* dec_point:小数点符号
+* thousands_sep:千分位符号
+* roundtag:舍入参数,默认 'ceil' 向上取,'floor'向下取,'round' 四舍五入
+* */
+export function numberFormat (number, decimals, decPoint, thousandsSep, roundtag) {
+ number = (number + '').replace(/[^0-9+-Ee.]/g, '')
+ roundtag = roundtag || 'ceil' // 'ceil','floor','round'
+ var n = !isFinite(+number) ? 0 : +number
+ var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
+ var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep
+ var dec = (typeof decPoint === 'undefined') ? '.' : decPoint
+ var s = ''
+ var toFixedFix = function (n, prec) {
+ var k = Math.pow(10, prec)
+ console.log()
+
+ return '' + parseFloat(Math[roundtag](parseFloat((n * k).toFixed(prec * 2))).toFixed(prec * 2)) / k
+ }
+ s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
+ var re = /(-?\d+)(\d{3})/
+ while (re.test(s[0])) {
+ s[0] = s[0].replace(re, '$1' + sep + '$2')
+ }
+
+ if ((s[1] || '').length < prec) {
+ s[1] = s[1] || ''
+ s[1] += new Array(prec - s[1].length + 1).join('0')
+ }
+ return s.join(dec)
+}
+
+// 日期格式化
+export function parseTime(time, pattern) {
+ if (arguments.length === 0 || !time) {
+ return null
+ }
+ const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+ time = parseInt(time)
+ } else if (typeof time === 'string') {
+ time = time.replace(new RegExp(/-/gm), '/');
+ }
+ if ((typeof time === 'number') && (time.toString().length === 10)) {
+ time = time * 1000
+ }
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+ if (this.$refs[refName]) {
+ this.$refs[refName].resetFields();
+ }
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+ var search = params;
+ search.params = {};
+ if (null != dateRange && '' != dateRange) {
+ if (typeof (propName) === "undefined") {
+ search.params["beginTime"] = dateRange[0];
+ search.params["endTime"] = dateRange[1];
+ } else {
+ search.params["begin" + propName] = dateRange[0];
+ search.params["end" + propName] = dateRange[1];
+ }
+ }
+ return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+ var actions = [];
+ Object.keys(datas).some((key) => {
+ if (datas[key].dictValue == ('' + value)) {
+ actions.push(datas[key].dictLabel);
+ return true;
+ }
+ })
+ return actions.join('');
+}
+
+// 回显数据字典(字符串数组)
+export function selectDictLabels(datas, value, separator) {
+ var actions = [];
+ var currentSeparator = undefined === separator ? "," : separator;
+ var temp = value.split(currentSeparator);
+ Object.keys(value.split(currentSeparator)).some((val) => {
+ Object.keys(datas).some((key) => {
+ if (datas[key].dictValue == ('' + temp[val])) {
+ actions.push(datas[key].dictLabel + currentSeparator);
+ }
+ })
+ })
+ return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 通用下载方法
+export function download(fileName) {
+ window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+ var args = arguments, flag = true, i = 1;
+ str = str.replace(/%s/g, function () {
+ var arg = args[i++];
+ if (typeof arg === 'undefined') {
+ flag = false;
+ return '';
+ }
+ return arg;
+ });
+ return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function praseStrEmpty(str) {
+ if (!str || str == "undefined" || str == "null") {
+ return "";
+ }
+ return str;
+}
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+ let config = {
+ id: id || 'id',
+ parentId: parentId || 'parentId',
+ childrenList: children || 'children'
+ };
+
+ var childrenListMap = {};
+ var nodeIds = {};
+ var tree = [];
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (childrenListMap[parentId] == null) {
+ childrenListMap[parentId] = [];
+ }
+ nodeIds[d[config.id]] = d;
+ childrenListMap[parentId].push(d);
+ }
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (nodeIds[parentId] == null) {
+ tree.push(d);
+ }
+ }
+
+ for (let t of tree) {
+ adaptToChildrenList(t);
+ }
+
+ function adaptToChildrenList(o) {
+ if (childrenListMap[o[config.id]] !== null) {
+ o[config.childrenList] = childrenListMap[o[config.id]];
+ }
+ if (o[config.childrenList]) {
+ for (let c of o[config.childrenList]) {
+ adaptToChildrenList(c);
+ }
+ }
+ }
+ return tree;
+}
diff --git a/src/utils/scroll-to.js b/src/utils/scroll-to.js
new file mode 100644
index 0000000..c5d8e04
--- /dev/null
+++ b/src/utils/scroll-to.js
@@ -0,0 +1,58 @@
+Math.easeInOutQuad = function(t, b, c, d) {
+ t /= d / 2
+ if (t < 1) {
+ return c / 2 * t * t + b
+ }
+ t--
+ return -c / 2 * (t * (t - 2) - 1) + b
+}
+
+// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
+var requestAnimFrame = (function() {
+ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
+})()
+
+/**
+ * Because it's so fucking difficult to detect the scrolling element, just move them all
+ * @param {number} amount
+ */
+function move(amount) {
+ document.documentElement.scrollTop = amount
+ document.body.parentNode.scrollTop = amount
+ document.body.scrollTop = amount
+}
+
+function position() {
+ return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
+}
+
+/**
+ * @param {number} to
+ * @param {number} duration
+ * @param {Function} callback
+ */
+export function scrollTo(to, duration, callback) {
+ const start = position()
+ const change = to - start
+ const increment = 20
+ let currentTime = 0
+ duration = (typeof (duration) === 'undefined') ? 500 : duration
+ var animateScroll = function() {
+ // increment the time
+ currentTime += increment
+ // find the value with the quadratic in-out easing function
+ var val = Math.easeInOutQuad(currentTime, start, change, duration)
+ // move the document.body
+ move(val)
+ // do the animation unless its over
+ if (currentTime < duration) {
+ requestAnimFrame(animateScroll)
+ } else {
+ if (callback && typeof (callback) === 'function') {
+ // the animation is done so lets callback
+ callback()
+ }
+ }
+ }
+ animateScroll()
+}
diff --git a/src/utils/validate.js b/src/utils/validate.js
new file mode 100644
index 0000000..adfa254
--- /dev/null
+++ b/src/utils/validate.js
@@ -0,0 +1,83 @@
+/**
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
+}
+
+/**
+ * @param {string} url
+ * @returns {Boolean}
+ */
+export function validURL(url) {
+ const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
+ return reg.test(url)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validLowerCase(str) {
+ const reg = /^[a-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUpperCase(str) {
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validAlphabets(str) {
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} email
+ * @returns {Boolean}
+ */
+export function validEmail(email) {
+ const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return reg.test(email)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function isString(str) {
+ if (typeof str === 'string' || str instanceof String) {
+ return true
+ }
+ return false
+}
+
+/**
+ * @param {Array} arg
+ * @returns {Boolean}
+ */
+export function isArray(arg) {
+ if (typeof Array.isArray === 'undefined') {
+ return Object.prototype.toString.call(arg) === '[object Array]'
+ }
+ return Array.isArray(arg)
+}
diff --git a/src/utils/zipdownload.js b/src/utils/zipdownload.js
new file mode 100644
index 0000000..fff4873
--- /dev/null
+++ b/src/utils/zipdownload.js
@@ -0,0 +1,40 @@
+import axios from 'axios'
+import { getToken } from '@/utils/auth'
+
+const mimeMap = {
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ zip: 'application/zip'
+}
+
+const baseUrl = process.env.VUE_APP_BASE_API
+export function downLoadZip(str, filename) {
+ var url = baseUrl + str
+ axios({
+ method: 'get',
+ url: url,
+ responseType: 'blob',
+ headers: { 'Authorization': 'Bearer ' + getToken() }
+ }).then(res => {
+ resolveBlob(res, mimeMap.zip)
+ })
+}
+/**
+ * 解析blob响应内容并下载
+ * @param {*} res blob响应内容
+ * @param {String} mimeType MIME类型
+ */
+export function resolveBlob(res, mimeType) {
+ const aLink = document.createElement('a')
+ var blob = new Blob([res.data], { type: mimeType })
+ // //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
+ var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
+ var contentDisposition = decodeURI(res.headers['content-disposition'])
+ var result = patt.exec(contentDisposition)
+ var fileName = result[1]
+ fileName = fileName.replace(/\"/g, '')
+ aLink.href = URL.createObjectURL(blob)
+ aLink.setAttribute('download', fileName) // 设置下载文件名称
+ document.body.appendChild(aLink)
+ aLink.click()
+ document.body.removeChild(aLink);
+}
diff --git a/src/views/components/icons/element-icons.js b/src/views/components/icons/element-icons.js
new file mode 100644
index 0000000..9ea4d63
--- /dev/null
+++ b/src/views/components/icons/element-icons.js
@@ -0,0 +1,3 @@
+const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
+
+export default elementIcons
diff --git a/src/views/components/icons/index.vue b/src/views/components/icons/index.vue
new file mode 100644
index 0000000..d3c9a71
--- /dev/null
+++ b/src/views/components/icons/index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+ {{ generateIconCode(item) }}
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+ {{ generateElementIconCode(item) }}
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/components/icons/svg-icons.js b/src/views/components/icons/svg-icons.js
new file mode 100644
index 0000000..724cd8e
--- /dev/null
+++ b/src/views/components/icons/svg-icons.js
@@ -0,0 +1,10 @@
+const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
+const requireAll = requireContext => requireContext.keys()
+
+const re = /\.\/(.*)\.svg/
+
+const svgIcons = requireAll(req).map(i => {
+ return i.match(re)[1]
+})
+
+export default svgIcons
diff --git a/src/views/dashboard/BarChart.vue b/src/views/dashboard/BarChart.vue
new file mode 100644
index 0000000..be0af34
--- /dev/null
+++ b/src/views/dashboard/BarChart.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
diff --git a/src/views/dashboard/LineChart.vue b/src/views/dashboard/LineChart.vue
new file mode 100644
index 0000000..e654168
--- /dev/null
+++ b/src/views/dashboard/LineChart.vue
@@ -0,0 +1,135 @@
+
+
+
+
+
diff --git a/src/views/dashboard/PanelGroup.vue b/src/views/dashboard/PanelGroup.vue
new file mode 100644
index 0000000..b965618
--- /dev/null
+++ b/src/views/dashboard/PanelGroup.vue
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dashboard/PieChart.vue b/src/views/dashboard/PieChart.vue
new file mode 100644
index 0000000..4d2ef32
--- /dev/null
+++ b/src/views/dashboard/PieChart.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
diff --git a/src/views/dashboard/RaddarChart.vue b/src/views/dashboard/RaddarChart.vue
new file mode 100644
index 0000000..6823af3
--- /dev/null
+++ b/src/views/dashboard/RaddarChart.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
diff --git a/src/views/dashboard/mixins/resize.js b/src/views/dashboard/mixins/resize.js
new file mode 100644
index 0000000..b1e76e9
--- /dev/null
+++ b/src/views/dashboard/mixins/resize.js
@@ -0,0 +1,56 @@
+import { debounce } from '@/utils'
+
+export default {
+ data() {
+ return {
+ $_sidebarElm: null,
+ $_resizeHandler: null
+ }
+ },
+ mounted() {
+ this.initListener()
+ },
+ activated() {
+ if (!this.$_resizeHandler) {
+ // avoid duplication init
+ this.initListener()
+ }
+
+ // when keep-alive chart activated, auto resize
+ this.resize()
+ },
+ beforeDestroy() {
+ this.destroyListener()
+ },
+ deactivated() {
+ this.destroyListener()
+ },
+ methods: {
+ // use $_ for mixins properties
+ // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
+ $_sidebarResizeHandler(e) {
+ if (e.propertyName === 'width') {
+ this.$_resizeHandler()
+ }
+ },
+ initListener() {
+ this.$_resizeHandler = debounce(() => {
+ this.resize()
+ }, 100)
+ window.addEventListener('resize', this.$_resizeHandler)
+
+ this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
+ this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ destroyListener() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ this.$_resizeHandler = null
+
+ this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ resize() {
+ const { chart } = this
+ chart && chart.resize()
+ }
+ }
+}
diff --git a/src/views/demo/demo/index.vue b/src/views/demo/demo/index.vue
new file mode 100644
index 0000000..68c0938
--- /dev/null
+++ b/src/views/demo/demo/index.vue
@@ -0,0 +1,356 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ {{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/demo/tree/index.vue b/src/views/demo/tree/index.vue
new file mode 100644
index 0000000..8afaec2
--- /dev/null
+++ b/src/views/demo/tree/index.vue
@@ -0,0 +1,291 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/AgreementSetting/index.vue b/src/views/dk/AgreementSetting/index.vue
new file mode 100644
index 0000000..b3958d1
--- /dev/null
+++ b/src/views/dk/AgreementSetting/index.vue
@@ -0,0 +1,101 @@
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/BorrowStatus/index.vue b/src/views/dk/BorrowStatus/index.vue
new file mode 100644
index 0000000..650577d
--- /dev/null
+++ b/src/views/dk/BorrowStatus/index.vue
@@ -0,0 +1,300 @@
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.borrowName}}
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/HomeSetting/index.vue b/src/views/dk/HomeSetting/index.vue
new file mode 100644
index 0000000..4dccf98
--- /dev/null
+++ b/src/views/dk/HomeSetting/index.vue
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
+
+
+
diff --git a/src/views/dk/LoansSetting/index.vue b/src/views/dk/LoansSetting/index.vue
new file mode 100644
index 0000000..53bbe52
--- /dev/null
+++ b/src/views/dk/LoansSetting/index.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 保存
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/contract-template.vue b/src/views/dk/borrow/contract-template.vue
new file mode 100644
index 0000000..91cb6cf
--- /dev/null
+++ b/src/views/dk/borrow/contract-template.vue
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/contract.vue b/src/views/dk/borrow/contract.vue
new file mode 100644
index 0000000..2c94aeb
--- /dev/null
+++ b/src/views/dk/borrow/contract.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/index.vue b/src/views/dk/borrow/index.vue
new file mode 100644
index 0000000..2746b6c
--- /dev/null
+++ b/src/views/dk/borrow/index.vue
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 姓名: {{scope.row.realName}}
+ 用户: {{scope.row.customerLoginName}}
+
+
+
+
+ 总贷款额: {{scope.row.totalLoanMoney}}
+ 还款月数: {{scope.row.totalMonth}}
+ 每月还款额: {{scope.row.avgRepayment}}
+ 月利率: {{scope.row.loanMonthRate}}
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.borrowName}}
+
+
+
+
+
+ 转账记录
+ 修改转账备注
+ 合同保单
+ 合同
+
+
+
+
+ 修改状态
+ 修改银行
+ 修改贷款
+ 客户资料
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/trans-account.vue b/src/views/dk/borrow/trans-account.vue
new file mode 100644
index 0000000..7daaa71
--- /dev/null
+++ b/src/views/dk/borrow/trans-account.vue
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
转出账户:
622203***********308
+
+
收款人姓名:
{{ info.realName }}
+
+
收款账户:
{{ info.backCardNum }}
+
+
转账金额:
{{ info.totalLoanMoney }}
+
转账时间:
{{ parseDate(info.createTime, '{y}/{m}/{d}') }}
+
+
+
+
银行备注:
{{ info.transRemark }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/update-bank.vue b/src/views/dk/borrow/update-bank.vue
new file mode 100644
index 0000000..2ea93b4
--- /dev/null
+++ b/src/views/dk/borrow/update-bank.vue
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/update-loan.vue b/src/views/dk/borrow/update-loan.vue
new file mode 100644
index 0000000..30d9f7a
--- /dev/null
+++ b/src/views/dk/borrow/update-loan.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/update-status.vue b/src/views/dk/borrow/update-status.vue
new file mode 100644
index 0000000..d3ebf6f
--- /dev/null
+++ b/src/views/dk/borrow/update-status.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+ {{ borrowStatus.borrowName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/borrow/update-trans-remark.vue b/src/views/dk/borrow/update-trans-remark.vue
new file mode 100644
index 0000000..6041b04
--- /dev/null
+++ b/src/views/dk/borrow/update-trans-remark.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/dkCustomer/index.vue b/src/views/dk/dkCustomer/index.vue
new file mode 100644
index 0000000..3aa2986
--- /dev/null
+++ b/src/views/dk/dkCustomer/index.vue
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改余额
+
+ 详情
+
+ 重置密码
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/dkCustomer/info.vue b/src/views/dk/dkCustomer/info.vue
new file mode 100644
index 0000000..15c985c
--- /dev/null
+++ b/src/views/dk/dkCustomer/info.vue
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+ {{info.phoneNumber}}
+
+
+ {{info.nickName}}
+
+
+ {{info.realNameAuth}}
+
+
+ {{info.loansFlag}}
+
+
+ {{info.withdrawFlag}}
+
+
+ {{yuanFormat(info.account)}}
+
+
+ {{yuanFormat(info.withdrawAccount)}}
+
+
+
+
+
+ {{customerInfo.realName}}
+
+
+
+ {{customerInfo.cardNum}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{customerInfo.companyName}}
+
+
+ {{customerInfo.companyTitle}}
+
+
+ {{customerInfo.companyPhone}}
+
+
+ {{customerInfo.companyYear}}
+
+
+ {{customerInfo.incomeWan}}
+
+
+ {{customerInfo.companyAddress}}
+
+
+ {{customerInfo.companyAddressInfo}}
+
+
+ {{customerInfo.customerAddress}}
+
+
+ {{customerInfo.customerAddressInfo}}
+
+
+
+
+
+ {{customerInfo.kinsfolkName}}
+
+
+ {{customerInfo.kinsfolkPhone}}
+
+
+
+
+
+
+ {{customerInfo.bankType}}
+
+
+ {{customerInfo.backCardNum}}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/dk/dkCustomer/update-amount.vue b/src/views/dk/dkCustomer/update-amount.vue
new file mode 100644
index 0000000..a5ce02f
--- /dev/null
+++ b/src/views/dk/dkCustomer/update-amount.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/error/401.vue b/src/views/error/401.vue
new file mode 100644
index 0000000..448b6ec
--- /dev/null
+++ b/src/views/error/401.vue
@@ -0,0 +1,88 @@
+
+
+
+ 返回
+
+
+
+
+ 401错误!
+
+ 您没有访问权限!
+ 对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/error/404.vue b/src/views/error/404.vue
new file mode 100644
index 0000000..96f075c
--- /dev/null
+++ b/src/views/error/404.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+ 404错误!
+
+
+ {{ message }}
+
+
+ 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
+
+
+ 返回首页
+
+
+
+
+
+
+
+
+
diff --git a/src/views/index.vue b/src/views/index.vue
new file mode 100644
index 0000000..783d9e3
--- /dev/null
+++ b/src/views/index.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/src/views/login.vue b/src/views/login.vue
new file mode 100644
index 0000000..700c529
--- /dev/null
+++ b/src/views/login.vue
@@ -0,0 +1,207 @@
+
+
+
+ 后台系统管理
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 记住密码
+
+
+ 登 录
+ 登 录 中...
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/admin/index.vue b/src/views/monitor/admin/index.vue
new file mode 100644
index 0000000..f1d48b0
--- /dev/null
+++ b/src/views/monitor/admin/index.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue
new file mode 100644
index 0000000..df0cb1e
--- /dev/null
+++ b/src/views/monitor/cache/index.vue
@@ -0,0 +1,153 @@
+
+
+
+
+
+ 基本信息
+
+
+
+
+ Redis版本
+ {{ cache.info.redis_version }}
+ 运行模式
+ {{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}
+ 端口
+ {{ cache.info.tcp_port }}
+ 客户端数
+ {{ cache.info.connected_clients }}
+
+
+ 运行时间(天)
+ {{ cache.info.uptime_in_days }}
+ 使用内存
+ {{ cache.info.used_memory_human }}
+ 使用CPU
+ {{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}
+ 内存配置
+ {{ cache.info.maxmemory_human }}
+
+
+ AOF是否开启
+ {{ cache.info.aof_enabled == "0" ? "否" : "是" }}
+ RDB是否成功
+ {{ cache.info.rdb_last_bgsave_status }}
+ Key数量
+ {{ cache.dbSize }}
+ 网络入口/出口
+ {{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps
+
+
+
+
+
+
+
+
+
+ 命令统计
+
+
+
+
+
+
+
+ 内存信息
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/druid/index.vue b/src/views/monitor/druid/index.vue
new file mode 100644
index 0000000..c6ad585
--- /dev/null
+++ b/src/views/monitor/druid/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue
new file mode 100644
index 0000000..4315eca
--- /dev/null
+++ b/src/views/monitor/job/index.vue
@@ -0,0 +1,493 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 日志
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 执行一次
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 调用方法
+
+
+ Bean调用示例:ryTask.ryParams('ry')
+ Class类调用示例:com.ruoyi.quartz.task.RyTask.ryParams('ry')
+ 参数说明:支持字符串,布尔类型,长整型,浮点型,整型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+
+
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobId }}
+ {{ form.jobName }}
+
+
+ {{ jobGroupFormat(form) }}
+ {{ form.createTime }}
+
+
+ {{ form.cronExpression }}
+
+
+ {{ parseTime(form.nextValidTime) }}
+
+
+ {{ form.invokeTarget }}
+
+
+
+ 正常
+ 失败
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+ 默认策略
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue
new file mode 100644
index 0000000..6abb9fe
--- /dev/null
+++ b/src/views/monitor/job/log.vue
@@ -0,0 +1,304 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobLogId }}
+ {{ form.jobName }}
+
+
+ {{ form.jobGroup }}
+ {{ form.createTime }}
+
+
+ {{ form.invokeTarget }}
+
+
+ {{ form.jobMessage }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ form.exceptionInfo }}
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue
new file mode 100644
index 0000000..9773876
--- /dev/null
+++ b/src/views/monitor/logininfor/index.vue
@@ -0,0 +1,247 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue
new file mode 100644
index 0000000..6880c2c
--- /dev/null
+++ b/src/views/monitor/online/index.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ {{(pageNum - 1) * pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+ 强退
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue
new file mode 100644
index 0000000..21e9dd5
--- /dev/null
+++ b/src/views/monitor/operlog/index.vue
@@ -0,0 +1,335 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.operTime) }}
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.title }} / {{ typeFormat(form) }}
+ {{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+
+
+ {{ form.operUrl }}
+ {{ form.requestMethod }}
+
+
+ {{ form.method }}
+
+
+ {{ form.operParam }}
+
+
+ {{ form.jsonResult }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ parseTime(form.operTime) }}
+
+
+ {{ form.errorMsg }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/redirect.vue b/src/views/redirect.vue
new file mode 100644
index 0000000..db4c1d6
--- /dev/null
+++ b/src/views/redirect.vue
@@ -0,0 +1,12 @@
+
diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue
new file mode 100644
index 0000000..3f726c8
--- /dev/null
+++ b/src/views/system/config/index.vue
@@ -0,0 +1,366 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
new file mode 100644
index 0000000..09740f8
--- /dev/null
+++ b/src/views/system/dept/index.vue
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue
new file mode 100644
index 0000000..75fe300
--- /dev/null
+++ b/src/views/system/dict/data.vue
@@ -0,0 +1,406 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+ {{scope.row.dictLabel}}
+ {{scope.row.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
new file mode 100644
index 0000000..bdf42ef
--- /dev/null
+++ b/src/views/system/dict/index.vue
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
new file mode 100644
index 0000000..486373d
--- /dev/null
+++ b/src/views/system/menu/index.vue
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 目录
+ 菜单
+ 按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+ 缓存
+ 不缓存
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue
new file mode 100644
index 0000000..cab7c3d
--- /dev/null
+++ b/src/views/system/notice/index.vue
@@ -0,0 +1,343 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
new file mode 100644
index 0000000..68ab48d
--- /dev/null
+++ b/src/views/system/post/index.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
new file mode 100644
index 0000000..9e7394a
--- /dev/null
+++ b/src/views/system/role/index.vue
@@ -0,0 +1,615 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 数据权限
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
new file mode 100644
index 0000000..2229a8f
--- /dev/null
+++ b/src/views/system/user/index.vue
@@ -0,0 +1,684 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导入
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{dict.dictLabel}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或
+ 点击上传
+
+
+ 是否更新已经存在的用户数据
+ 下载模板
+
+ 提示:仅允许导入“xls”或“xlsx”格式文件!
+
+
+
+
+
+
+
diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue
new file mode 100644
index 0000000..7a3e295
--- /dev/null
+++ b/src/views/system/user/profile/index.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+ 个人信息
+
+
+
+
+
+
+
+ 基本资料
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue
new file mode 100644
index 0000000..ee65240
--- /dev/null
+++ b/src/views/system/user/profile/resetPwd.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue
new file mode 100644
index 0000000..6ed6314
--- /dev/null
+++ b/src/views/system/user/profile/userAvatar.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提 交
+
+
+
+
+
+
+
+
diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue
new file mode 100644
index 0000000..bde2423
--- /dev/null
+++ b/src/views/system/user/profile/userInfo.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 男
+ 女
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/src/views/tool/build/CodeTypeDialog.vue b/src/views/tool/build/CodeTypeDialog.vue
new file mode 100644
index 0000000..941ec36
--- /dev/null
+++ b/src/views/tool/build/CodeTypeDialog.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+
+
+ 确定
+
+
+
+
+
+
diff --git a/src/views/tool/build/DraggableItem.vue b/src/views/tool/build/DraggableItem.vue
new file mode 100644
index 0000000..e881778
--- /dev/null
+++ b/src/views/tool/build/DraggableItem.vue
@@ -0,0 +1,100 @@
+
diff --git a/src/views/tool/build/IconsDialog.vue b/src/views/tool/build/IconsDialog.vue
new file mode 100644
index 0000000..958be50
--- /dev/null
+++ b/src/views/tool/build/IconsDialog.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
diff --git a/src/views/tool/build/RightPanel.vue b/src/views/tool/build/RightPanel.vue
new file mode 100644
index 0000000..7e67936
--- /dev/null
+++ b/src/views/tool/build/RightPanel.vue
@@ -0,0 +1,946 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+ {{ activeData.componentName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 默认
+
+
+ 右侧
+
+
+
+
+
+
+ 个字符
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text
+
+
+ picture
+
+
+ picture-card
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选项
+
+
+
+
+
+ 添加选项
+
+
+
+
+
+
+ 选项
+
+
+
+ 动态数据
+
+
+ 静态数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加父级
+
+
+
+
+
+
+
+
+ 默认
+
+
+ 按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 中等
+
+
+ 较小
+
+
+ 迷你
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 布局结构树
+
+
+
+
+ {{ node.label }}
+
+
+
+
+
+
+ 正则校验
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加规则
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 中等
+
+
+ 较小
+
+
+ 迷你
+
+
+
+
+
+
+ 左对齐
+
+
+ 右对齐
+
+
+ 顶部对齐
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/build/TreeNodeDialog.vue b/src/views/tool/build/TreeNodeDialog.vue
new file mode 100644
index 0000000..c225c4c
--- /dev/null
+++ b/src/views/tool/build/TreeNodeDialog.vue
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定
+
+
+ 取消
+
+
+
+
+
+
diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue
new file mode 100644
index 0000000..1f8b361
--- /dev/null
+++ b/src/views/tool/build/index.vue
@@ -0,0 +1,794 @@
+
+
+
+
+
+
Form Generator
+
+
+
+
+
+ 输入型组件
+
+
+
+
+
+ {{ element.label }}
+
+
+
+
+ 选择型组件
+
+
+
+
+
+ {{ element.label }}
+
+
+
+
+ 布局型组件
+
+
+
+
+
+ {{ element.label }}
+
+
+
+
+
+
+
+
+
+
+ 导出vue文件
+
+
+ 复制代码
+
+
+ 清空
+
+
+
+
+
+
+
+
+
+ 从左侧拖入或点选组件进行表单设计
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue
new file mode 100644
index 0000000..757962c
--- /dev/null
+++ b/src/views/tool/gen/basicInfoForm.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue
new file mode 100644
index 0000000..dd76525
--- /dev/null
+++ b/src/views/tool/gen/editTable.vue
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.dictName }}
+ {{ dict.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue
new file mode 100644
index 0000000..f227156
--- /dev/null
+++ b/src/views/tool/gen/genInfoForm.vue
@@ -0,0 +1,300 @@
+
+
+
+
+
+ 生成模板
+
+
+
+
+
+
+
+
+
+
+
+ 生成包路径
+
+
+
+
+
+
+
+
+
+
+
+ 生成模块名
+
+
+
+
+
+
+
+
+
+
+
+ 生成业务名
+
+
+
+
+
+
+
+
+
+
+
+ 生成功能名
+
+
+
+
+
+
+
+
+
+
+
+ 上级菜单
+
+
+
+
+
+
+
+
+
+
+
+ 生成代码方式
+
+
+
+
+ zip压缩包
+ 自定义路径
+
+
+
+
+
+
+ 自定义路径
+
+
+
+
+
+
+
+ 最近路径快速选择
+
+
+
+ 恢复默认的生成基础路径
+
+
+
+
+
+
+
+
+
+
+
+
+ 树编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树父编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树名称字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 关联子表的表名
+
+
+
+
+
+
+
+
+
+
+
+
+ 子表关联的外键名
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue
new file mode 100644
index 0000000..56b2c0c
--- /dev/null
+++ b/src/views/tool/gen/importTable.vue
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
new file mode 100644
index 0000000..c3aef75
--- /dev/null
+++ b/src/views/tool/gen/index.vue
@@ -0,0 +1,340 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 生成
+
+
+ 导入
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+ {{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+
+ 预览
+ 编辑
+ 删除
+ 同步
+ 生成代码
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/tool/swagger/index.vue b/src/views/tool/swagger/index.vue
new file mode 100644
index 0000000..b782968
--- /dev/null
+++ b/src/views/tool/swagger/index.vue
@@ -0,0 +1,15 @@
+
+
+
+
diff --git a/vue.config.js b/vue.config.js
new file mode 100644
index 0000000..d5f7053
--- /dev/null
+++ b/vue.config.js
@@ -0,0 +1,118 @@
+'use strict'
+const path = require('path')
+
+function resolve(dir) {
+ return path.join(__dirname, dir)
+}
+
+const name = process.env.VUE_APP_TITLE || 'RuoYi-Vue-Plus后台管理系统' // 网页标题
+
+const port = process.env.port || process.env.npm_config_port || 80 // 端口
+
+// vue.config.js 配置说明
+//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
+// 这里只列一部分,具体配置参考文档
+module.exports = {
+ // 部署生产环境和开发环境下的URL。
+ // 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
+ // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
+ publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
+ // 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
+ outputDir: 'dist',
+ // 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
+ assetsDir: 'static',
+ // 是否开启eslint保存检测,有效值:ture | false | 'error'
+ lintOnSave: process.env.NODE_ENV === 'development',
+ // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
+ productionSourceMap: false,
+ // webpack-dev-server 相关配置
+ devServer: {
+ host: '0.0.0.0',
+ port: port,
+ open: true,
+ proxy: {
+ // detail: https://cli.vuejs.org/config/#devserver-proxy
+ [process.env.VUE_APP_BASE_API]: {
+ // target: `http://localhost:8082`,
+ target: `http://124.222.254.188:8887/prod-api`,
+ changeOrigin: true,
+ pathRewrite: {
+ ['^' + process.env.VUE_APP_BASE_API]: ''
+ }
+ }
+ },
+ disableHostCheck: true
+ },
+ configureWebpack: {
+ name: name,
+ resolve: {
+ alias: {
+ '@': resolve('src')
+ }
+ }
+ },
+ chainWebpack(config) {
+ config.plugins.delete('preload') // TODO: need test
+ config.plugins.delete('prefetch') // TODO: need test
+
+ // set svg-sprite-loader
+ config.module
+ .rule('svg')
+ .exclude.add(resolve('src/assets/icons'))
+ .end()
+ config.module
+ .rule('icons')
+ .test(/\.svg$/)
+ .include.add(resolve('src/assets/icons'))
+ .end()
+ .use('svg-sprite-loader')
+ .loader('svg-sprite-loader')
+ .options({
+ symbolId: 'icon-[name]'
+ })
+ .end()
+
+ config
+ .when(process.env.NODE_ENV !== 'development',
+ config => {
+ config
+ .plugin('ScriptExtHtmlWebpackPlugin')
+ .after('html')
+ .use('script-ext-html-webpack-plugin', [{
+ // `runtime` must same as runtimeChunk name. default is `runtime`
+ inline: /runtime\..*\.js$/
+ }])
+ .end()
+ config
+ .optimization.splitChunks({
+ chunks: 'all',
+ cacheGroups: {
+ libs: {
+ name: 'chunk-libs',
+ test: /[\\/]node_modules[\\/]/,
+ priority: 10,
+ chunks: 'initial' // only package third parties that are initially dependent
+ },
+ elementUI: {
+ name: 'chunk-elementUI', // split elementUI into a single package
+ priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
+ test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
+ },
+ commons: {
+ name: 'chunk-commons',
+ test: resolve('src/components'), // can customize your rules
+ minChunks: 3, // minimum common number
+ priority: 5,
+ reuseExistingChunk: true
+ }
+ }
+ })
+ config.optimization.runtimeChunk('single'),
+ {
+ from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
+ to: './', //到根目录下
+ }
+ }
+ )
+ }
+}
diff --git a/后台-ui.zip b/后台-ui.zip
new file mode 100644
index 0000000..d72729b
Binary files /dev/null and b/后台-ui.zip differ