@ -0,0 +1,14 @@
|
|||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = false
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
# just a flag
|
||||||
|
ENV = 'development'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = ''
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
# just a flag
|
||||||
|
ENV = 'production'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = '/prod-api'
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
NODE_ENV = production
|
||||||
|
|
||||||
|
# just a flag
|
||||||
|
ENV = 'staging'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = '/stage-api'
|
||||||
|
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
build/*.js
|
||||||
|
src/assets
|
||||||
|
public
|
||||||
|
dist
|
||||||
@ -0,0 +1,198 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parserOptions: {
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
},
|
||||||
|
extends: ['plugin:vue/recommended', 'eslint:recommended'],
|
||||||
|
|
||||||
|
// add your custom rules here
|
||||||
|
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||||
|
rules: {
|
||||||
|
"vue/max-attributes-per-line": [2, {
|
||||||
|
"singleline": 10,
|
||||||
|
"multiline": {
|
||||||
|
"max": 1,
|
||||||
|
"allowFirstLine": false
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"vue/singleline-html-element-content-newline": "off",
|
||||||
|
"vue/multiline-html-element-content-newline":"off",
|
||||||
|
"vue/name-property-casing": ["error", "PascalCase"],
|
||||||
|
"vue/no-v-html": "off",
|
||||||
|
'accessor-pairs': 2,
|
||||||
|
'arrow-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'block-spacing': [2, 'always'],
|
||||||
|
'brace-style': [2, '1tbs', {
|
||||||
|
'allowSingleLine': true
|
||||||
|
}],
|
||||||
|
'camelcase': [0, {
|
||||||
|
'properties': 'always'
|
||||||
|
}],
|
||||||
|
'comma-dangle': [2, 'never'],
|
||||||
|
'comma-spacing': [2, {
|
||||||
|
'before': false,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'comma-style': [2, 'last'],
|
||||||
|
'constructor-super': 2,
|
||||||
|
'curly': [2, 'multi-line'],
|
||||||
|
'dot-location': [2, 'property'],
|
||||||
|
'eol-last': 2,
|
||||||
|
'eqeqeq': ["error", "always", {"null": "ignore"}],
|
||||||
|
'generator-star-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'handle-callback-err': [2, '^(err|error)$'],
|
||||||
|
'indent': [2, 2, {
|
||||||
|
'SwitchCase': 1
|
||||||
|
}],
|
||||||
|
'jsx-quotes': [2, 'prefer-single'],
|
||||||
|
'key-spacing': [2, {
|
||||||
|
'beforeColon': false,
|
||||||
|
'afterColon': true
|
||||||
|
}],
|
||||||
|
'keyword-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'new-cap': [2, {
|
||||||
|
'newIsCap': true,
|
||||||
|
'capIsNew': false
|
||||||
|
}],
|
||||||
|
'new-parens': 2,
|
||||||
|
'no-array-constructor': 2,
|
||||||
|
'no-caller': 2,
|
||||||
|
'no-console': 'off',
|
||||||
|
'no-class-assign': 2,
|
||||||
|
'no-cond-assign': 2,
|
||||||
|
'no-const-assign': 2,
|
||||||
|
'no-control-regex': 0,
|
||||||
|
'no-delete-var': 2,
|
||||||
|
'no-dupe-args': 2,
|
||||||
|
'no-dupe-class-members': 2,
|
||||||
|
'no-dupe-keys': 2,
|
||||||
|
'no-duplicate-case': 2,
|
||||||
|
'no-empty-character-class': 2,
|
||||||
|
'no-empty-pattern': 2,
|
||||||
|
'no-eval': 2,
|
||||||
|
'no-ex-assign': 2,
|
||||||
|
'no-extend-native': 2,
|
||||||
|
'no-extra-bind': 2,
|
||||||
|
'no-extra-boolean-cast': 2,
|
||||||
|
'no-extra-parens': [2, 'functions'],
|
||||||
|
'no-fallthrough': 2,
|
||||||
|
'no-floating-decimal': 2,
|
||||||
|
'no-func-assign': 2,
|
||||||
|
'no-implied-eval': 2,
|
||||||
|
'no-inner-declarations': [2, 'functions'],
|
||||||
|
'no-invalid-regexp': 2,
|
||||||
|
'no-irregular-whitespace': 2,
|
||||||
|
'no-iterator': 2,
|
||||||
|
'no-label-var': 2,
|
||||||
|
'no-labels': [2, {
|
||||||
|
'allowLoop': false,
|
||||||
|
'allowSwitch': false
|
||||||
|
}],
|
||||||
|
'no-lone-blocks': 2,
|
||||||
|
'no-mixed-spaces-and-tabs': 2,
|
||||||
|
'no-multi-spaces': 2,
|
||||||
|
'no-multi-str': 2,
|
||||||
|
'no-multiple-empty-lines': [2, {
|
||||||
|
'max': 1
|
||||||
|
}],
|
||||||
|
'no-native-reassign': 2,
|
||||||
|
'no-negated-in-lhs': 2,
|
||||||
|
'no-new-object': 2,
|
||||||
|
'no-new-require': 2,
|
||||||
|
'no-new-symbol': 2,
|
||||||
|
'no-new-wrappers': 2,
|
||||||
|
'no-obj-calls': 2,
|
||||||
|
'no-octal': 2,
|
||||||
|
'no-octal-escape': 2,
|
||||||
|
'no-path-concat': 2,
|
||||||
|
'no-proto': 2,
|
||||||
|
'no-redeclare': 2,
|
||||||
|
'no-regex-spaces': 2,
|
||||||
|
'no-return-assign': [2, 'except-parens'],
|
||||||
|
'no-self-assign': 2,
|
||||||
|
'no-self-compare': 2,
|
||||||
|
'no-sequences': 2,
|
||||||
|
'no-shadow-restricted-names': 2,
|
||||||
|
'no-spaced-func': 2,
|
||||||
|
'no-sparse-arrays': 2,
|
||||||
|
'no-this-before-super': 2,
|
||||||
|
'no-throw-literal': 2,
|
||||||
|
'no-trailing-spaces': 2,
|
||||||
|
'no-undef': 2,
|
||||||
|
'no-undef-init': 2,
|
||||||
|
'no-unexpected-multiline': 2,
|
||||||
|
'no-unmodified-loop-condition': 2,
|
||||||
|
'no-unneeded-ternary': [2, {
|
||||||
|
'defaultAssignment': false
|
||||||
|
}],
|
||||||
|
'no-unreachable': 2,
|
||||||
|
'no-unsafe-finally': 2,
|
||||||
|
'no-unused-vars': [2, {
|
||||||
|
'vars': 'all',
|
||||||
|
'args': 'none'
|
||||||
|
}],
|
||||||
|
'no-useless-call': 2,
|
||||||
|
'no-useless-computed-key': 2,
|
||||||
|
'no-useless-constructor': 2,
|
||||||
|
'no-useless-escape': 0,
|
||||||
|
'no-whitespace-before-property': 2,
|
||||||
|
'no-with': 2,
|
||||||
|
'one-var': [2, {
|
||||||
|
'initialized': 'never'
|
||||||
|
}],
|
||||||
|
'operator-linebreak': [2, 'after', {
|
||||||
|
'overrides': {
|
||||||
|
'?': 'before',
|
||||||
|
':': 'before'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'padded-blocks': [2, 'never'],
|
||||||
|
'quotes': [2, 'single', {
|
||||||
|
'avoidEscape': true,
|
||||||
|
'allowTemplateLiterals': true
|
||||||
|
}],
|
||||||
|
'semi': [2, 'never'],
|
||||||
|
'semi-spacing': [2, {
|
||||||
|
'before': false,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'space-before-blocks': [2, 'always'],
|
||||||
|
'space-before-function-paren': [2, 'never'],
|
||||||
|
'space-in-parens': [2, 'never'],
|
||||||
|
'space-infix-ops': 2,
|
||||||
|
'space-unary-ops': [2, {
|
||||||
|
'words': true,
|
||||||
|
'nonwords': false
|
||||||
|
}],
|
||||||
|
'spaced-comment': [2, 'always', {
|
||||||
|
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
||||||
|
}],
|
||||||
|
'template-curly-spacing': [2, 'never'],
|
||||||
|
'use-isnan': 2,
|
||||||
|
'valid-typeof': 2,
|
||||||
|
'wrap-iife': [2, 'any'],
|
||||||
|
'yield-star-spacing': [2, 'both'],
|
||||||
|
'yoda': [2, 'never'],
|
||||||
|
'prefer-const': 2,
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||||
|
'object-curly-spacing': [2, 'always', {
|
||||||
|
objectsInObjects: false
|
||||||
|
}],
|
||||||
|
'array-bracket-spacing': [2, 'never']
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
package-lock.json
|
||||||
|
tests/**/coverage/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js: 10
|
||||||
|
script: npm run test
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017-present PanJiaChen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
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.
|
||||||
|
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
|
||||||
|
'plugins': ['dynamic-import-node']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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}`)
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
module.exports = {
|
||||||
|
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.vue$': 'vue-jest',
|
||||||
|
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
|
||||||
|
'jest-transform-stub',
|
||||||
|
'^.+\\.jsx?$': 'babel-jest'
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^@/(.*)$': '<rootDir>/src/$1'
|
||||||
|
},
|
||||||
|
snapshotSerializers: ['jest-serializer-vue'],
|
||||||
|
testMatch: [
|
||||||
|
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||||
|
],
|
||||||
|
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
|
||||||
|
coverageDirectory: '<rootDir>/tests/unit/coverage',
|
||||||
|
// 'collectCoverage': true,
|
||||||
|
'coverageReporters': [
|
||||||
|
'lcov',
|
||||||
|
'text-summary'
|
||||||
|
],
|
||||||
|
testURL: 'http://localhost/'
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
const Mock = require('mockjs')
|
||||||
|
const { param2Obj } = require('./utils')
|
||||||
|
|
||||||
|
const user = require('./user')
|
||||||
|
const table = require('./table')
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
...user,
|
||||||
|
...table
|
||||||
|
]
|
||||||
|
|
||||||
|
// for front mock
|
||||||
|
// please use it cautiously, it will redefine XMLHttpRequest,
|
||||||
|
// which will cause many of your third-party libraries to be invalidated(like progress event).
|
||||||
|
function mockXHR() {
|
||||||
|
// mock patch
|
||||||
|
// https://github.com/nuysoft/Mock/issues/300
|
||||||
|
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
||||||
|
Mock.XHR.prototype.send = function() {
|
||||||
|
if (this.custom.xhr) {
|
||||||
|
this.custom.xhr.withCredentials = this.withCredentials || false
|
||||||
|
|
||||||
|
if (this.responseType) {
|
||||||
|
this.custom.xhr.responseType = this.responseType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.proxy_send(...arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function XHR2ExpressReqWrap(respond) {
|
||||||
|
return function(options) {
|
||||||
|
let result = null
|
||||||
|
if (respond instanceof Function) {
|
||||||
|
const { body, type, url } = options
|
||||||
|
// https://expressjs.com/en/4x/api.html#req
|
||||||
|
result = respond({
|
||||||
|
method: type,
|
||||||
|
body: JSON.parse(body),
|
||||||
|
query: param2Obj(url)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
result = respond
|
||||||
|
}
|
||||||
|
return Mock.mock(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const i of mocks) {
|
||||||
|
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mocks,
|
||||||
|
mockXHR
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
const chokidar = require('chokidar')
|
||||||
|
const bodyParser = require('body-parser')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const path = require('path')
|
||||||
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
|
const mockDir = path.join(process.cwd(), 'mock')
|
||||||
|
|
||||||
|
function registerRoutes(app) {
|
||||||
|
let mockLastIndex
|
||||||
|
const { mocks } = require('./index.js')
|
||||||
|
const mocksForServer = mocks.map(route => {
|
||||||
|
return responseFake(route.url, route.type, route.response)
|
||||||
|
})
|
||||||
|
for (const mock of mocksForServer) {
|
||||||
|
app[mock.type](mock.url, mock.response)
|
||||||
|
mockLastIndex = app._router.stack.length
|
||||||
|
}
|
||||||
|
const mockRoutesLength = Object.keys(mocksForServer).length
|
||||||
|
return {
|
||||||
|
mockRoutesLength: mockRoutesLength,
|
||||||
|
mockStartIndex: mockLastIndex - mockRoutesLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unregisterRoutes() {
|
||||||
|
Object.keys(require.cache).forEach(i => {
|
||||||
|
if (i.includes(mockDir)) {
|
||||||
|
delete require.cache[require.resolve(i)]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// for mock server
|
||||||
|
const responseFake = (url, type, respond) => {
|
||||||
|
return {
|
||||||
|
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
|
||||||
|
type: type || 'get',
|
||||||
|
response(req, res) {
|
||||||
|
console.log('request invoke:' + req.path)
|
||||||
|
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = app => {
|
||||||
|
// parse app.body
|
||||||
|
// https://expressjs.com/en/4x/api.html#req.body
|
||||||
|
app.use(bodyParser.json())
|
||||||
|
app.use(bodyParser.urlencoded({
|
||||||
|
extended: true
|
||||||
|
}))
|
||||||
|
|
||||||
|
const mockRoutes = registerRoutes(app)
|
||||||
|
var mockRoutesLength = mockRoutes.mockRoutesLength
|
||||||
|
var mockStartIndex = mockRoutes.mockStartIndex
|
||||||
|
|
||||||
|
// watch files, hot reload mock server
|
||||||
|
chokidar.watch(mockDir, {
|
||||||
|
ignored: /mock-server/,
|
||||||
|
ignoreInitial: true
|
||||||
|
}).on('all', (event, path) => {
|
||||||
|
if (event === 'change' || event === 'add') {
|
||||||
|
try {
|
||||||
|
// remove mock routes stack
|
||||||
|
app._router.stack.splice(mockStartIndex, mockRoutesLength)
|
||||||
|
|
||||||
|
// clear routes cache
|
||||||
|
unregisterRoutes()
|
||||||
|
|
||||||
|
const mockRoutes = registerRoutes(app)
|
||||||
|
mockRoutesLength = mockRoutes.mockRoutesLength
|
||||||
|
mockStartIndex = mockRoutes.mockStartIndex
|
||||||
|
|
||||||
|
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
|
||||||
|
} catch (error) {
|
||||||
|
console.log(chalk.redBright(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
const Mock = require('mockjs')
|
||||||
|
|
||||||
|
const data = Mock.mock({
|
||||||
|
'items|30': [{
|
||||||
|
id: '@id',
|
||||||
|
title: '@sentence(10, 20)',
|
||||||
|
'status|1': ['published', 'draft', 'deleted'],
|
||||||
|
author: 'name',
|
||||||
|
display_time: '@datetime',
|
||||||
|
pageviews: '@integer(300, 5000)'
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
url: '/vue-admin-template/table/list',
|
||||||
|
type: 'get',
|
||||||
|
response: config => {
|
||||||
|
const items = data.items
|
||||||
|
return {
|
||||||
|
code: 20000,
|
||||||
|
data: {
|
||||||
|
total: items.length,
|
||||||
|
items: items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
const tokens = {
|
||||||
|
admin: {
|
||||||
|
token: 'admin-token'
|
||||||
|
},
|
||||||
|
editor: {
|
||||||
|
token: 'editor-token'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const users = {
|
||||||
|
'admin-token': {
|
||||||
|
roles: ['admin'],
|
||||||
|
introduction: 'I am a super administrator',
|
||||||
|
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
|
||||||
|
name: 'Super Admin'
|
||||||
|
},
|
||||||
|
'editor-token': {
|
||||||
|
roles: ['editor'],
|
||||||
|
introduction: 'I am an editor',
|
||||||
|
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
|
||||||
|
name: 'Normal Editor'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
// user login
|
||||||
|
{
|
||||||
|
url: '/vue-admin-template/user/login',
|
||||||
|
type: 'post',
|
||||||
|
response: config => {
|
||||||
|
const { username } = config.body
|
||||||
|
const token = tokens[username]
|
||||||
|
|
||||||
|
// mock error
|
||||||
|
if (!token) {
|
||||||
|
return {
|
||||||
|
code: 60204,
|
||||||
|
message: 'Account and password are incorrect.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 20000,
|
||||||
|
data: token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// get user info
|
||||||
|
{
|
||||||
|
url: '/vue-admin-template/user/info\.*',
|
||||||
|
type: 'get',
|
||||||
|
response: config => {
|
||||||
|
const { token } = config.query
|
||||||
|
const info = users[token]
|
||||||
|
|
||||||
|
// mock error
|
||||||
|
if (!info) {
|
||||||
|
return {
|
||||||
|
code: 50008,
|
||||||
|
message: 'Login failed, unable to get user details.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 20000,
|
||||||
|
data: info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// user logout
|
||||||
|
{
|
||||||
|
url: '/vue-admin-template/user/logout',
|
||||||
|
type: 'post',
|
||||||
|
response: _ => {
|
||||||
|
return {
|
||||||
|
code: 20000,
|
||||||
|
data: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
param2Obj
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "vue-admin-template",
|
||||||
|
"version": "4.4.0",
|
||||||
|
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
|
||||||
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
|
"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",
|
||||||
|
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
|
||||||
|
"lint": "eslint --ext .js,.vue src",
|
||||||
|
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||||
|
"test:ci": "npm run lint && npm run test:unit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "0.18.1",
|
||||||
|
"core-js": "3.6.5",
|
||||||
|
"echarts": "^4.2.1",
|
||||||
|
"element-ui": "2.13.2",
|
||||||
|
"js-cookie": "2.2.0",
|
||||||
|
"less-loader": "^5.0.0",
|
||||||
|
"moment": "^2.29.2",
|
||||||
|
"normalize.css": "7.0.0",
|
||||||
|
"nprogress": "0.2.0",
|
||||||
|
"path-to-regexp": "2.4.0",
|
||||||
|
"view-design": "^4.7.0",
|
||||||
|
"vue": "2.6.10",
|
||||||
|
"vue-count-to": "^1.0.13",
|
||||||
|
"vue-router": "3.0.6",
|
||||||
|
"vuex": "3.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "4.4.4",
|
||||||
|
"@vue/cli-plugin-eslint": "4.4.4",
|
||||||
|
"@vue/cli-plugin-unit-jest": "4.4.4",
|
||||||
|
"@vue/cli-service": "4.4.4",
|
||||||
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
|
"autoprefixer": "9.5.1",
|
||||||
|
"babel-eslint": "10.1.0",
|
||||||
|
"babel-jest": "23.6.0",
|
||||||
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
|
"chalk": "2.4.2",
|
||||||
|
"connect": "3.6.6",
|
||||||
|
"eslint": "6.7.2",
|
||||||
|
"eslint-plugin-vue": "6.2.2",
|
||||||
|
"html-webpack-plugin": "3.2.0",
|
||||||
|
"mockjs": "1.0.1-beta3",
|
||||||
|
"runjs": "4.3.2",
|
||||||
|
"sass": "1.26.8",
|
||||||
|
"sass-loader": "8.0.2",
|
||||||
|
"script-ext-html-webpack-plugin": "2.1.3",
|
||||||
|
"serve-static": "1.13.2",
|
||||||
|
"svg-sprite-loader": "4.1.3",
|
||||||
|
"svgo": "1.2.2",
|
||||||
|
"vue-template-compiler": "2.6.10"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.9",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
},
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
'plugins': {
|
||||||
|
// to edit target browsers: use "browserslist" field in package.json
|
||||||
|
'autoprefixer': {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= webpackConfig.name %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'App'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function getCounts() {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/get-counts',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getChartsData(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/get-charts-data',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/menu/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listmenu() {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/menu',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/menu/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function setPermissions(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/role/set-permissions',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/role/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function list() {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/role',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/role/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/admin/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listuser() {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/admin',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/admin/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setRoles(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/admin/set-roles',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listTool(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/tool',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/tool/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/tool/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doimport(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/tool/do-import',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function previewimport(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/tool/preview-import',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listrecord(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/record',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listClientTools(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/record/get-client-tools/' + params.client_id,
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listnoReturn(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/exception/no-return',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listMaintain(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/exception/maintain',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
//工具箱数据同步
|
||||||
|
export function syncData(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/sync-data/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//工具箱数据库结构比对
|
||||||
|
export function checkStructure(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/check-structure/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//工具箱数据库连接测试
|
||||||
|
export function testConnection(id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/test-connection/' + id,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function listToolbox(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function listToolboxtool(params, id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/get-tools/' + id,
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doimport(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/do-import',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function previewimport(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client/preview-import',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listclientTouch(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client-touch',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listTouchTypes(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/client-touch/get-types',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function listUser(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function save(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user/save',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setPermission(data, id) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user/' + id + '/set-permissions',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function doimport(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user/do-import',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function del(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user/delete',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function previewimport(params) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/user/preview-import',
|
||||||
|
method: 'get',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function login(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/auth/login',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getInfo(token) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/auth/me',
|
||||||
|
method: 'post',
|
||||||
|
params: { token }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/auth/logout',
|
||||||
|
method: 'post'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAuthMenu(token) {
|
||||||
|
return request({
|
||||||
|
url: '/api/admin/auth/permissions',
|
||||||
|
method: 'get',
|
||||||
|
params: { token }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||||
|
<transition-group name="breadcrumb">
|
||||||
|
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||||
|
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1"
|
||||||
|
class="no-redirect">{{ item.meta.title }}</span>
|
||||||
|
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</transition-group>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import pathToRegexp from 'path-to-regexp'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
levelList: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route() {
|
||||||
|
this.getBreadcrumb()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getBreadcrumb()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getBreadcrumb() {
|
||||||
|
// only show routes with meta.title
|
||||||
|
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||||
|
const first = matched[0]
|
||||||
|
|
||||||
|
if (!this.isDashboard(first)) {
|
||||||
|
matched = [{
|
||||||
|
path: '/dashboard',
|
||||||
|
meta: {
|
||||||
|
title: '系统首页'
|
||||||
|
}
|
||||||
|
}].concat(matched)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||||
|
},
|
||||||
|
isDashboard(route) {
|
||||||
|
const name = route && route.name
|
||||||
|
if (!name) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return name.trim().toLocaleLowerCase() === '系统首页'.toLocaleLowerCase()
|
||||||
|
},
|
||||||
|
pathCompile(path) {
|
||||||
|
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||||
|
const {
|
||||||
|
params
|
||||||
|
} = this.$route
|
||||||
|
var toPath = pathToRegexp.compile(path)
|
||||||
|
return toPath(params)
|
||||||
|
},
|
||||||
|
handleLink(item) {
|
||||||
|
const {
|
||||||
|
redirect,
|
||||||
|
path
|
||||||
|
} = item
|
||||||
|
if (redirect) {
|
||||||
|
this.$router.push(redirect)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$router.push(this.pathCompile(path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-breadcrumb.el-breadcrumb {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
.no-redirect {
|
||||||
|
color: #97a8be;
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,155 @@
|
|||||||
|
<template>
|
||||||
|
<div :id="id" :class="className" :style="{height:height,width:width}" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import echarts from 'echarts'
|
||||||
|
import resize from './mixins/resize'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [resize],
|
||||||
|
props: {
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (!this.chart) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.chart.dispose()
|
||||||
|
this.chart = null
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initChart() {
|
||||||
|
this.chart = echarts.init(document.getElementById(this.id))
|
||||||
|
|
||||||
|
const xAxisData = []
|
||||||
|
const data = []
|
||||||
|
const data2 = []
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
xAxisData.push(i)
|
||||||
|
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
|
||||||
|
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
|
||||||
|
}
|
||||||
|
this.chart.setOption({
|
||||||
|
backgroundColor: '#08263a',
|
||||||
|
grid: {
|
||||||
|
left: '5%',
|
||||||
|
right: '5%'
|
||||||
|
},
|
||||||
|
xAxis: [{
|
||||||
|
show: false,
|
||||||
|
data: xAxisData
|
||||||
|
}, {
|
||||||
|
show: false,
|
||||||
|
data: xAxisData
|
||||||
|
}],
|
||||||
|
visualMap: {
|
||||||
|
show: false,
|
||||||
|
min: 0,
|
||||||
|
max: 50,
|
||||||
|
dimension: 0,
|
||||||
|
inRange: {
|
||||||
|
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#4a657a'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#08263f'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: 'back',
|
||||||
|
type: 'bar',
|
||||||
|
data: data2,
|
||||||
|
z: 1,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
opacity: 0.4,
|
||||||
|
barBorderRadius: 5,
|
||||||
|
shadowBlur: 3,
|
||||||
|
shadowColor: '#111'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: 'Simulate Shadow',
|
||||||
|
type: 'line',
|
||||||
|
data,
|
||||||
|
z: 2,
|
||||||
|
showSymbol: false,
|
||||||
|
animationDelay: 0,
|
||||||
|
animationEasing: 'linear',
|
||||||
|
animationDuration: 1200,
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#08263a',
|
||||||
|
shadowBlur: 50,
|
||||||
|
shadowColor: '#000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: 'front',
|
||||||
|
type: 'bar',
|
||||||
|
data,
|
||||||
|
xAxisIndex: 1,
|
||||||
|
z: 3,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
barBorderRadius: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
animationEasing: 'elasticOut',
|
||||||
|
animationEasingUpdate: 'elasticOut',
|
||||||
|
animationDelay(idx) {
|
||||||
|
return idx * 20
|
||||||
|
},
|
||||||
|
animationDelayUpdate(idx) {
|
||||||
|
return idx * 20
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
<template>
|
||||||
|
<div :id="id" :class="className" :style="{height:height,width:width}" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import echarts from 'echarts'
|
||||||
|
import resize from './mixins/resize'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [resize],
|
||||||
|
props: {
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (!this.chart) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.chart.dispose()
|
||||||
|
this.chart = null
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initChart() {
|
||||||
|
this.chart = echarts.init(document.getElementById(this.id))
|
||||||
|
|
||||||
|
this.chart.setOption({
|
||||||
|
backgroundColor: '#394056',
|
||||||
|
title: {
|
||||||
|
top: 20,
|
||||||
|
text: 'Requests',
|
||||||
|
textStyle: {
|
||||||
|
fontWeight: 'normal',
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#F1F1F3'
|
||||||
|
},
|
||||||
|
left: '1%'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#57617B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: 20,
|
||||||
|
icon: 'rect',
|
||||||
|
itemWidth: 14,
|
||||||
|
itemHeight: 5,
|
||||||
|
itemGap: 13,
|
||||||
|
data: ['CMCC', 'CTCC', 'CUCC'],
|
||||||
|
right: '4%',
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#F1F1F3'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: 100,
|
||||||
|
left: '2%',
|
||||||
|
right: '2%',
|
||||||
|
bottom: '2%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: [{
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#57617B'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
|
||||||
|
}],
|
||||||
|
yAxis: [{
|
||||||
|
type: 'value',
|
||||||
|
name: '(%)',
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#57617B'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
margin: 10,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#57617B'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
series: [{
|
||||||
|
name: 'CMCC',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 5,
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
width: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(137, 189, 27, 0.3)'
|
||||||
|
}, {
|
||||||
|
offset: 0.8,
|
||||||
|
color: 'rgba(137, 189, 27, 0)'
|
||||||
|
}], false),
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
shadowBlur: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgb(137,189,27)',
|
||||||
|
borderColor: 'rgba(137,189,2,0.27)',
|
||||||
|
borderWidth: 12
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
|
||||||
|
}, {
|
||||||
|
name: 'CTCC',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 5,
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
width: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(0, 136, 212, 0.3)'
|
||||||
|
}, {
|
||||||
|
offset: 0.8,
|
||||||
|
color: 'rgba(0, 136, 212, 0)'
|
||||||
|
}], false),
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
shadowBlur: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgb(0,136,212)',
|
||||||
|
borderColor: 'rgba(0,136,212,0.2)',
|
||||||
|
borderWidth: 12
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
|
||||||
|
}, {
|
||||||
|
name: 'CUCC',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 5,
|
||||||
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
width: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(219, 50, 51, 0.3)'
|
||||||
|
}, {
|
||||||
|
offset: 0.8,
|
||||||
|
color: 'rgba(219, 50, 51, 0)'
|
||||||
|
}], false),
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
shadowBlur: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgb(219,50,51)',
|
||||||
|
borderColor: 'rgba(219,50,51,0.2)',
|
||||||
|
borderWidth: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,271 @@
|
|||||||
|
<template>
|
||||||
|
<div :id="id" :class="className" :style="{height:height,width:width}" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import echarts from 'echarts'
|
||||||
|
import resize from './mixins/resize'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [resize],
|
||||||
|
props: {
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: 'chart'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: '200px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initChart()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (!this.chart) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.chart.dispose()
|
||||||
|
this.chart = null
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initChart() {
|
||||||
|
this.chart = echarts.init(document.getElementById(this.id))
|
||||||
|
const xData = (function() {
|
||||||
|
const data = []
|
||||||
|
for (let i = 1; i < 13; i++) {
|
||||||
|
data.push(i + 'month')
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}())
|
||||||
|
this.chart.setOption({
|
||||||
|
backgroundColor: '#344b58',
|
||||||
|
title: {
|
||||||
|
text: 'statistics',
|
||||||
|
x: '20',
|
||||||
|
top: '20',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '22'
|
||||||
|
},
|
||||||
|
subtextStyle: {
|
||||||
|
color: '#90979c',
|
||||||
|
fontSize: '16'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
borderWidth: 0,
|
||||||
|
top: 150,
|
||||||
|
bottom: 95,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
x: '5%',
|
||||||
|
top: '10%',
|
||||||
|
textStyle: {
|
||||||
|
color: '#90979c'
|
||||||
|
},
|
||||||
|
data: ['female', 'male', 'average']
|
||||||
|
},
|
||||||
|
calculable: true,
|
||||||
|
xAxis: [{
|
||||||
|
type: 'category',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#90979c'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
interval: 0
|
||||||
|
|
||||||
|
},
|
||||||
|
data: xData
|
||||||
|
}],
|
||||||
|
yAxis: [{
|
||||||
|
type: 'value',
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#90979c'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
interval: 0
|
||||||
|
},
|
||||||
|
splitArea: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
dataZoom: [{
|
||||||
|
show: true,
|
||||||
|
height: 30,
|
||||||
|
xAxisIndex: [
|
||||||
|
0
|
||||||
|
],
|
||||||
|
bottom: 30,
|
||||||
|
start: 10,
|
||||||
|
end: 80,
|
||||||
|
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
|
||||||
|
handleSize: '110%',
|
||||||
|
handleStyle: {
|
||||||
|
color: '#d3dee5'
|
||||||
|
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff' },
|
||||||
|
borderColor: '#90979c'
|
||||||
|
|
||||||
|
}, {
|
||||||
|
type: 'inside',
|
||||||
|
show: true,
|
||||||
|
height: 15,
|
||||||
|
start: 1,
|
||||||
|
end: 35
|
||||||
|
}],
|
||||||
|
series: [{
|
||||||
|
name: 'female',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
barMaxWidth: 35,
|
||||||
|
barGap: '10%',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgba(255,144,128,1)',
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff'
|
||||||
|
},
|
||||||
|
position: 'insideTop',
|
||||||
|
formatter(p) {
|
||||||
|
return p.value > 0 ? p.value : ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
709,
|
||||||
|
1917,
|
||||||
|
2455,
|
||||||
|
2610,
|
||||||
|
1719,
|
||||||
|
1433,
|
||||||
|
1544,
|
||||||
|
3285,
|
||||||
|
5208,
|
||||||
|
3372,
|
||||||
|
2484,
|
||||||
|
4078
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'male',
|
||||||
|
type: 'bar',
|
||||||
|
stack: 'total',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgba(0,191,183,1)',
|
||||||
|
barBorderRadius: 0,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
formatter(p) {
|
||||||
|
return p.value > 0 ? p.value : ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
327,
|
||||||
|
1776,
|
||||||
|
507,
|
||||||
|
1200,
|
||||||
|
800,
|
||||||
|
482,
|
||||||
|
204,
|
||||||
|
1390,
|
||||||
|
1001,
|
||||||
|
951,
|
||||||
|
381,
|
||||||
|
220
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
name: 'average',
|
||||||
|
type: 'line',
|
||||||
|
stack: 'total',
|
||||||
|
symbolSize: 10,
|
||||||
|
symbol: 'circle',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: 'rgba(252,230,48,1)',
|
||||||
|
barBorderRadius: 0,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'top',
|
||||||
|
formatter(p) {
|
||||||
|
return p.value > 0 ? p.value : ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
1036,
|
||||||
|
3693,
|
||||||
|
2962,
|
||||||
|
3810,
|
||||||
|
2519,
|
||||||
|
1915,
|
||||||
|
1748,
|
||||||
|
4675,
|
||||||
|
6209,
|
||||||
|
4323,
|
||||||
|
2865,
|
||||||
|
4298
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div style="padding: 0 15px;" @click="toggleClick">
|
||||||
|
<svg
|
||||||
|
:class="{'is-active':isActive}"
|
||||||
|
class="hamburger"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
>
|
||||||
|
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Hamburger',
|
||||||
|
props: {
|
||||||
|
isActive: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleClick() {
|
||||||
|
this.$emit('toggleClick')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hamburger {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hamburger.is-active {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div class="v-header">
|
||||||
|
<div class="v-left-text">
|
||||||
|
<Icon size="20" :type="icon" />
|
||||||
|
<span>{{text}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<slot name="content"></slot>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="v-right-content">
|
||||||
|
<slot></slot>
|
||||||
|
</div> -->
|
||||||
|
<div class="selerchcontent">
|
||||||
|
<slot ></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: "未定义名称"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.v-header {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #dcdee2;
|
||||||
|
flex-direction: column;
|
||||||
|
.v-left-text {
|
||||||
|
margin-top: 3px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
// padding-top: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #122583;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-bottom: 2px solid #122583;
|
||||||
|
> span {
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
line-height: 25px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding: 6px 0 0 10px;
|
||||||
|
}
|
||||||
|
.v-right-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selerchcontent{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
export default {
|
||||||
|
name: "TableExpand",
|
||||||
|
functional: true,
|
||||||
|
props: {
|
||||||
|
render: Function,
|
||||||
|
row: {},//当前行的数据
|
||||||
|
column: {},//当前行的配置信息
|
||||||
|
index: { type: Number, default: 0 }//当前所在行
|
||||||
|
},
|
||||||
|
render: (h, ctx) => {
|
||||||
|
const params = {
|
||||||
|
row: ctx.props.row, column: ctx.props.column, index: ctx.props.index
|
||||||
|
}
|
||||||
|
return ctx.props.render(h, params); //h();
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div :style="{zIndex:zIndex,height:height,width:width}" class="pan-item">
|
||||||
|
<div class="pan-info">
|
||||||
|
<div class="pan-info-roles-container">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- eslint-disable-next-line -->
|
||||||
|
<div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'PanThumb',
|
||||||
|
props: {
|
||||||
|
image: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
zIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
default: '150px'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: '150px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.pan-item {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
cursor: default;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-info-roles-container {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-thumb {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 95% 40%;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .pan-thumb:after {
|
||||||
|
content: '';
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 40%;
|
||||||
|
left: 95%;
|
||||||
|
margin: -4px 0 0 -4px;
|
||||||
|
background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%);
|
||||||
|
box-shadow: 0 0 1px rgba(255, 255, 255, 0.9);
|
||||||
|
} */
|
||||||
|
|
||||||
|
.pan-info {
|
||||||
|
position: absolute;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-info h3 {
|
||||||
|
color: #fff;
|
||||||
|
text-transform: uppercase;
|
||||||
|
position: relative;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 0 60px;
|
||||||
|
padding: 22px 0 0 0;
|
||||||
|
height: 85px;
|
||||||
|
font-family: 'Open Sans', Arial, sans-serif;
|
||||||
|
text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-info p {
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 5px;
|
||||||
|
font-style: italic;
|
||||||
|
margin: 0 30px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-info p a {
|
||||||
|
display: block;
|
||||||
|
color: #333;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 9px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
padding-top: 24px;
|
||||||
|
margin: 7px auto 0;
|
||||||
|
font-family: 'Open Sans', Arial, sans-serif;
|
||||||
|
opacity: 0;
|
||||||
|
transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s;
|
||||||
|
transform: translateX(60px) rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-info p a:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-item:hover .pan-thumb {
|
||||||
|
transform: rotate(-110deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pan-item:hover .pan-info p a {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0px) rotate(0deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||||
|
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||||
|
<use :xlink:href="iconName" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
|
||||||
|
import { isExternal } from '@/utils/validate'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SvgIcon',
|
||||||
|
props: {
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isExternal() {
|
||||||
|
return isExternal(this.iconClass)
|
||||||
|
},
|
||||||
|
iconName() {
|
||||||
|
return `#icon-${this.iconClass}`
|
||||||
|
},
|
||||||
|
svgClass() {
|
||||||
|
if (this.className) {
|
||||||
|
return 'svg-icon ' + this.className
|
||||||
|
} else {
|
||||||
|
return 'svg-icon'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
styleExternalIcon() {
|
||||||
|
return {
|
||||||
|
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||||
|
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.svg-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
fill: currentColor;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-external-icon {
|
||||||
|
background-color: currentColor;
|
||||||
|
mask-size: cover!important;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<a :class="className" class="link--mallki" href="#">
|
||||||
|
{{ text }}
|
||||||
|
<span :data-letters="text" />
|
||||||
|
<span :data-letters="text" />
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Mallki */
|
||||||
|
|
||||||
|
.link--mallki {
|
||||||
|
font-weight: 800;
|
||||||
|
color: #4dd9d5;
|
||||||
|
font-family: 'Dosis', sans-serif;
|
||||||
|
-webkit-transition: color 0.5s 0.25s;
|
||||||
|
transition: color 0.5s 0.25s;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
|
outline: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki:hover {
|
||||||
|
-webkit-transition: none;
|
||||||
|
transition: none;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki::before {
|
||||||
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 6px;
|
||||||
|
margin: -3px 0 0 0;
|
||||||
|
background: #3888fa;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
-webkit-transform: translate3d(-100%, 0, 0);
|
||||||
|
transform: translate3d(-100%, 0, 0);
|
||||||
|
-webkit-transition: -webkit-transform 0.4s;
|
||||||
|
transition: transform 0.4s;
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
|
||||||
|
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki:hover::before {
|
||||||
|
-webkit-transform: translate3d(100%, 0, 0);
|
||||||
|
transform: translate3d(100%, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki span {
|
||||||
|
position: absolute;
|
||||||
|
height: 50%;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki span::before {
|
||||||
|
content: attr(data-letters);
|
||||||
|
color: red;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: #3888fa;
|
||||||
|
-webkit-transition: -webkit-transform 0.5s;
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki span:nth-child(2) {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki span:first-child::before {
|
||||||
|
top: 0;
|
||||||
|
-webkit-transform: translate3d(0, 100%, 0);
|
||||||
|
transform: translate3d(0, 100%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki span:nth-child(2)::before {
|
||||||
|
bottom: 0;
|
||||||
|
-webkit-transform: translate3d(0, -100%, 0);
|
||||||
|
transform: translate3d(0, -100%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link--mallki:hover span::before {
|
||||||
|
-webkit-transition-delay: 0.3s;
|
||||||
|
transition-delay: 0.3s;
|
||||||
|
-webkit-transform: translate3d(0, 0, 0);
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
|
||||||
|
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,175 @@
|
|||||||
|
<template>
|
||||||
|
<el-color-picker
|
||||||
|
v-model="theme"
|
||||||
|
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
|
||||||
|
class="theme-picker"
|
||||||
|
popper-class="theme-picker-dropdown"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const version = require('element-ui/package.json').version // element-ui version from node_modules
|
||||||
|
const ORIGINAL_THEME = '#409EFF' // default color
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chalk: '', // content of theme-chalk css
|
||||||
|
theme: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
defaultTheme() {
|
||||||
|
return this.$store.state.settings.theme
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
defaultTheme: {
|
||||||
|
handler: function(val, oldVal) {
|
||||||
|
this.theme = val
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
async theme(val) {
|
||||||
|
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
|
||||||
|
if (typeof val !== 'string') return
|
||||||
|
const themeCluster = this.getThemeCluster(val.replace('#', ''))
|
||||||
|
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
|
||||||
|
console.log(themeCluster, originalCluster)
|
||||||
|
|
||||||
|
const $message = this.$message({
|
||||||
|
message: ' Compiling the theme',
|
||||||
|
customClass: 'theme-message',
|
||||||
|
type: 'success',
|
||||||
|
duration: 0,
|
||||||
|
iconClass: 'el-icon-loading'
|
||||||
|
})
|
||||||
|
|
||||||
|
const getHandler = (variable, id) => {
|
||||||
|
return () => {
|
||||||
|
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
|
||||||
|
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
|
||||||
|
|
||||||
|
let styleTag = document.getElementById(id)
|
||||||
|
if (!styleTag) {
|
||||||
|
styleTag = document.createElement('style')
|
||||||
|
styleTag.setAttribute('id', id)
|
||||||
|
document.head.appendChild(styleTag)
|
||||||
|
}
|
||||||
|
styleTag.innerText = newStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.chalk) {
|
||||||
|
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
|
||||||
|
await this.getCSSString(url, 'chalk')
|
||||||
|
}
|
||||||
|
|
||||||
|
const chalkHandler = getHandler('chalk', 'chalk-style')
|
||||||
|
|
||||||
|
chalkHandler()
|
||||||
|
|
||||||
|
const styles = [].slice.call(document.querySelectorAll('style'))
|
||||||
|
.filter(style => {
|
||||||
|
const text = style.innerText
|
||||||
|
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
|
||||||
|
})
|
||||||
|
styles.forEach(style => {
|
||||||
|
const { innerText } = style
|
||||||
|
if (typeof innerText !== 'string') return
|
||||||
|
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$emit('change', val)
|
||||||
|
|
||||||
|
$message.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
updateStyle(style, oldCluster, newCluster) {
|
||||||
|
let newStyle = style
|
||||||
|
oldCluster.forEach((color, index) => {
|
||||||
|
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
|
||||||
|
})
|
||||||
|
return newStyle
|
||||||
|
},
|
||||||
|
|
||||||
|
getCSSString(url, variable) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const xhr = new XMLHttpRequest()
|
||||||
|
xhr.onreadystatechange = () => {
|
||||||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||||
|
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.open('GET', url)
|
||||||
|
xhr.send()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getThemeCluster(theme) {
|
||||||
|
const tintColor = (color, tint) => {
|
||||||
|
let red = parseInt(color.slice(0, 2), 16)
|
||||||
|
let green = parseInt(color.slice(2, 4), 16)
|
||||||
|
let blue = parseInt(color.slice(4, 6), 16)
|
||||||
|
|
||||||
|
if (tint === 0) { // when primary color is in its rgb space
|
||||||
|
return [red, green, blue].join(',')
|
||||||
|
} else {
|
||||||
|
red += Math.round(tint * (255 - red))
|
||||||
|
green += Math.round(tint * (255 - green))
|
||||||
|
blue += Math.round(tint * (255 - blue))
|
||||||
|
|
||||||
|
red = red.toString(16)
|
||||||
|
green = green.toString(16)
|
||||||
|
blue = blue.toString(16)
|
||||||
|
|
||||||
|
return `#${red}${green}${blue}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shadeColor = (color, shade) => {
|
||||||
|
let red = parseInt(color.slice(0, 2), 16)
|
||||||
|
let green = parseInt(color.slice(2, 4), 16)
|
||||||
|
let blue = parseInt(color.slice(4, 6), 16)
|
||||||
|
|
||||||
|
red = Math.round((1 - shade) * red)
|
||||||
|
green = Math.round((1 - shade) * green)
|
||||||
|
blue = Math.round((1 - shade) * blue)
|
||||||
|
|
||||||
|
red = red.toString(16)
|
||||||
|
green = green.toString(16)
|
||||||
|
blue = blue.toString(16)
|
||||||
|
|
||||||
|
return `#${red}${green}${blue}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const clusters = [theme]
|
||||||
|
for (let i = 0; i <= 9; i++) {
|
||||||
|
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
|
||||||
|
}
|
||||||
|
clusters.push(shadeColor(theme, 0.1))
|
||||||
|
return clusters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.theme-message,
|
||||||
|
.theme-picker-dropdown {
|
||||||
|
z-index: 99999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-picker .el-color-picker__trigger {
|
||||||
|
height: 26px !important;
|
||||||
|
width: 26px !important;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -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)
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 179 B |
|
After Width: | Height: | Size: 971 B |
|
After Width: | Height: | Size: 319 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 418 B |
|
After Width: | Height: | Size: 356 B |
|
After Width: | Height: | Size: 818 B |
|
After Width: | Height: | Size: 627 B |
|
After Width: | Height: | Size: 347 B |
|
After Width: | Height: | Size: 497 B |
|
After Width: | Height: | Size: 459 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 944 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 421 B |
|
After Width: | Height: | Size: 320 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 1017 B |
|
After Width: | Height: | Size: 444 B |
|
After Width: | Height: | Size: 669 B |
|
After Width: | Height: | Size: 335 B |
|
After Width: | Height: | Size: 821 B |
|
After Width: | Height: | Size: 623 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.2 KiB |