commit
42b42a5e1c
|
@ -1,4 +1,4 @@
|
||||||
# http://editorconfig.org
|
# https://editorconfig.org
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
|
|
12
README.md
12
README.md
|
@ -30,11 +30,11 @@ English | [简体中文](./README.zh-CN.md)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
[vue-element-admin](http://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
|
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
|
||||||
|
|
||||||
It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
|
It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
|
||||||
|
|
||||||
- [Preview](http://panjiachen.github.io/vue-element-admin)
|
- [Preview](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
- [Documentation](https://panjiachen.github.io/vue-element-admin-site/)
|
- [Documentation](https://panjiachen.github.io/vue-element-admin-site/)
|
||||||
|
|
||||||
|
@ -50,13 +50,13 @@ It is a magical vue admin based on the newest development stack of vue, built-in
|
||||||
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||||
- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
|
- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
|
||||||
|
|
||||||
**The current version is `4.0-beta`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version - stable version, you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)**
|
**The current version is `v4.0+` build on `vue-cli`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), it does not rely on `vue-cli'**
|
||||||
|
|
||||||
**This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.**
|
**This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.**
|
||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
|
|
||||||
You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](http://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
|
You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
|
||||||
Understanding and learning this knowledge in advance will greatly help the use of this project.
|
Understanding and learning this knowledge in advance will greatly help the use of this project.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -187,7 +187,7 @@ Detailed changes for each release are documented in the [release notes](https://
|
||||||
|
|
||||||
## Online Demo
|
## Online Demo
|
||||||
|
|
||||||
[Preview](http://panjiachen.github.io/vue-element-admin)
|
[Preview](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ If you find this project useful, you can buy author a glass of juice :tropical_d
|
||||||
|
|
||||||
Modern browsers and Internet Explorer 10+.
|
Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
[vue-element-admin](http://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
|
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
|
||||||
|
|
||||||
- [在线预览](http://panjiachen.github.io/vue-element-admin)
|
- [在线预览](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
|
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||||
- Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
|
- Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
|
||||||
|
|
||||||
**目前版本为 `4.0-beta`,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本-稳定版,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)**
|
**目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0),它不依赖 `vue-cli`**
|
||||||
|
|
||||||
**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
|
**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ Detailed changes for each release are documented in the [release notes](https://
|
||||||
|
|
||||||
## Online Demo
|
## Online Demo
|
||||||
|
|
||||||
[在线 Demo](http://panjiachen.github.io/vue-element-admin)
|
[在线 Demo](https://panjiachen.github.io/vue-element-admin)
|
||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ Detailed changes for each release are documented in the [release notes](https://
|
||||||
|
|
||||||
Modern browsers and Internet Explorer 10+.
|
Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
| --------- | --------- | --------- | --------- |
|
| --------- | --------- | --------- | --------- |
|
||||||
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { param2Obj } from '../src/utils'
|
||||||
import user from './user'
|
import user from './user'
|
||||||
import role from './role'
|
import role from './role'
|
||||||
import article from './article'
|
import article from './article'
|
||||||
import search from './remoteSearch'
|
import search from './remote-search'
|
||||||
|
|
||||||
const mocks = [
|
const mocks = [
|
||||||
...user,
|
...user,
|
||||||
|
|
|
@ -3,12 +3,16 @@ const bodyParser = require('body-parser')
|
||||||
const chalk = require('chalk')
|
const chalk = require('chalk')
|
||||||
|
|
||||||
function registerRoutes(app) {
|
function registerRoutes(app) {
|
||||||
|
let mockLastIndex
|
||||||
const { default: mocks } = require('./index.js')
|
const { default: mocks } = require('./index.js')
|
||||||
for (const mock of mocks) {
|
for (const mock of mocks) {
|
||||||
app[mock.type](mock.url, mock.response)
|
app[mock.type](mock.url, mock.response)
|
||||||
|
mockLastIndex = app._router.stack.length
|
||||||
}
|
}
|
||||||
|
const mockRoutesLength = Object.keys(mocks).length
|
||||||
return {
|
return {
|
||||||
mockRoutesLength: Object.keys(mocks).length
|
mockRoutesLength: mockRoutesLength,
|
||||||
|
mockStartIndex: mockLastIndex - mockRoutesLength
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,40 +24,20 @@ function unregisterRoutes() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPath(path) {
|
|
||||||
var match = path.toString()
|
|
||||||
.replace('\\/?', '')
|
|
||||||
.replace('(?=\\/|$)', '$')
|
|
||||||
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
|
|
||||||
return match
|
|
||||||
? match[1].replace(/\\(.)/g, '$1').split('/')
|
|
||||||
: path.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMockRoutesIndex(app) {
|
|
||||||
for (let index = 0; index <= app._router.stack.length; index++) {
|
|
||||||
const r = app._router.stack[index]
|
|
||||||
if (r.route && r.route.path) {
|
|
||||||
const path = getPath(r.route.path)
|
|
||||||
if (path.includes('mock')) {
|
|
||||||
return index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = app => {
|
module.exports = app => {
|
||||||
// es6 polyfill
|
// es6 polyfill
|
||||||
require('@babel/register')
|
require('@babel/register')
|
||||||
|
|
||||||
// parse app.body
|
// parse app.body
|
||||||
// http://expressjs.com/en/4x/api.html#req.body
|
// https://expressjs.com/en/4x/api.html#req.body
|
||||||
app.use(bodyParser.json())
|
app.use(bodyParser.json())
|
||||||
app.use(bodyParser.urlencoded({
|
app.use(bodyParser.urlencoded({
|
||||||
extended: true
|
extended: true
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const { mockRoutesLength } = registerRoutes(app)
|
const mockRoutes = registerRoutes(app)
|
||||||
|
var mockRoutesLength = mockRoutes.mockRoutesLength
|
||||||
|
var mockStartIndex = mockRoutes.mockStartIndex
|
||||||
|
|
||||||
// watch files, hot reload mock server
|
// watch files, hot reload mock server
|
||||||
chokidar.watch(('./mock'), {
|
chokidar.watch(('./mock'), {
|
||||||
|
@ -62,16 +46,15 @@ module.exports = app => {
|
||||||
ignoreInitial: true
|
ignoreInitial: true
|
||||||
}).on('all', (event, path) => {
|
}).on('all', (event, path) => {
|
||||||
if (event === 'change' || event === 'add') {
|
if (event === 'change' || event === 'add') {
|
||||||
// find mock routes stack index
|
|
||||||
const index = getMockRoutesIndex(app)
|
|
||||||
|
|
||||||
// remove mock routes stack
|
// remove mock routes stack
|
||||||
app._router.stack.splice(index, mockRoutesLength)
|
app._router.stack.splice(mockStartIndex, mockRoutesLength)
|
||||||
|
|
||||||
// clear routes cache
|
// clear routes cache
|
||||||
unregisterRoutes()
|
unregisterRoutes()
|
||||||
|
|
||||||
registerRoutes(app)
|
const mockRoutes = registerRoutes(app)
|
||||||
|
mockRoutesLength = mockRoutes.mockRoutesLength
|
||||||
|
mockStartIndex = mockRoutes.mockStartIndex
|
||||||
|
|
||||||
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
|
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,17 @@ export const constantRoutes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/auth-redirect',
|
path: '/auth-redirect',
|
||||||
component: 'views/login/authRedirect',
|
component: 'views/login/auth-redirect',
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/404',
|
path: '/404',
|
||||||
component: 'views/errorPage/404',
|
component: 'views/error-page/404',
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/401',
|
path: '/401',
|
||||||
component: 'views/errorPage/401',
|
component: 'views/error-page/401',
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -150,19 +150,19 @@ export const asyncRoutes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'json-editor',
|
path: 'json-editor',
|
||||||
component: 'views/components-demo/jsonEditor',
|
component: 'views/components-demo/json-editor',
|
||||||
name: 'JsonEditorDemo',
|
name: 'JsonEditorDemo',
|
||||||
meta: { title: 'jsonEditor' }
|
meta: { title: 'jsonEditor' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'splitpane',
|
path: 'split-pane',
|
||||||
component: 'views/components-demo/splitpane',
|
component: 'views/components-demo/split-pane',
|
||||||
name: 'SplitpaneDemo',
|
name: 'SplitpaneDemo',
|
||||||
meta: { title: 'splitPane' }
|
meta: { title: 'splitPane' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'avatar-upload',
|
path: 'avatar-upload',
|
||||||
component: 'views/components-demo/avatarUpload',
|
component: 'views/components-demo/avatar-upload',
|
||||||
name: 'AvatarUploadDemo',
|
name: 'AvatarUploadDemo',
|
||||||
meta: { title: 'avatarUpload' }
|
meta: { title: 'avatarUpload' }
|
||||||
},
|
},
|
||||||
|
@ -180,7 +180,7 @@ export const asyncRoutes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'count-to',
|
path: 'count-to',
|
||||||
component: 'views/components-demo/countTo',
|
component: 'views/components-demo/count-to',
|
||||||
name: 'CountToDemo',
|
name: 'CountToDemo',
|
||||||
meta: { title: 'countTo' }
|
meta: { title: 'countTo' }
|
||||||
},
|
},
|
||||||
|
@ -192,31 +192,31 @@ export const asyncRoutes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'back-to-top',
|
path: 'back-to-top',
|
||||||
component: 'views/components-demo/backToTop',
|
component: 'views/components-demo/back-to-top',
|
||||||
name: 'BackToTopDemo',
|
name: 'BackToTopDemo',
|
||||||
meta: { title: 'backToTop' }
|
meta: { title: 'backToTop' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-dialog',
|
path: 'drag-dialog',
|
||||||
component: 'views/components-demo/dragDialog',
|
component: 'views/components-demo/drag-dialog',
|
||||||
name: 'DragDialogDemo',
|
name: 'DragDialogDemo',
|
||||||
meta: { title: 'dragDialog' }
|
meta: { title: 'dragDialog' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-select',
|
path: 'drag-select',
|
||||||
component: 'views/components-demo/dragSelect',
|
component: 'views/components-demo/drag-select',
|
||||||
name: 'DragSelectDemo',
|
name: 'DragSelectDemo',
|
||||||
meta: { title: 'dragSelect' }
|
meta: { title: 'dragSelect' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dnd-list',
|
path: 'dnd-list',
|
||||||
component: 'views/components-demo/dndList',
|
component: 'views/components-demo/dnd-list',
|
||||||
name: 'DndListDemo',
|
name: 'DndListDemo',
|
||||||
meta: { title: 'dndList' }
|
meta: { title: 'dndList' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-kanban',
|
path: 'drag-kanban',
|
||||||
component: 'views/components-demo/dragKanban',
|
component: 'views/components-demo/drag-kanban',
|
||||||
name: 'DragKanbanDemo',
|
name: 'DragKanbanDemo',
|
||||||
meta: { title: 'dragKanban' }
|
meta: { title: 'dragKanban' }
|
||||||
}
|
}
|
||||||
|
@ -370,13 +370,13 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '401',
|
path: '401',
|
||||||
component: 'views/errorPage/401',
|
component: 'views/error-page/401',
|
||||||
name: 'Page401',
|
name: 'Page401',
|
||||||
meta: { title: 'page401', noCache: true }
|
meta: { title: 'page401', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
component: 'views/errorPage/404',
|
component: 'views/error-page/404',
|
||||||
name: 'Page404',
|
name: 'Page404',
|
||||||
meta: { title: 'page404', noCache: true }
|
meta: { title: 'page404', noCache: true }
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'log',
|
path: 'log',
|
||||||
component: 'views/errorLog/index',
|
component: 'views/error-log/index',
|
||||||
name: 'ErrorLog',
|
name: 'ErrorLog',
|
||||||
meta: { title: 'errorLog', icon: 'bug' }
|
meta: { title: 'errorLog', icon: 'bug' }
|
||||||
}
|
}
|
||||||
|
@ -409,25 +409,25 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'export-excel',
|
path: 'export-excel',
|
||||||
component: 'views/excel/exportExcel',
|
component: 'views/excel/export-excel',
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
meta: { title: 'exportExcel' }
|
meta: { title: 'exportExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-selected-excel',
|
path: 'export-selected-excel',
|
||||||
component: 'views/excel/selectExcel',
|
component: 'views/excel/select-excel',
|
||||||
name: 'SelectExcel',
|
name: 'SelectExcel',
|
||||||
meta: { title: 'selectExcel' }
|
meta: { title: 'selectExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-merge-header',
|
path: 'export-merge-header',
|
||||||
component: 'views/excel/mergeHeader',
|
component: 'views/excel/merge-header',
|
||||||
name: 'MergeHeader',
|
name: 'MergeHeader',
|
||||||
meta: { title: 'mergeHeader' }
|
meta: { title: 'mergeHeader' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'upload-excel',
|
path: 'upload-excel',
|
||||||
component: 'views/excel/uploadExcel',
|
component: 'views/excel/upload-excel',
|
||||||
name: 'UploadExcel',
|
name: 'UploadExcel',
|
||||||
meta: { title: 'uploadExcel' }
|
meta: { title: 'uploadExcel' }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
@ -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>
|
|
@ -1,156 +0,0 @@
|
||||||
<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>
|
|
|
@ -3,7 +3,7 @@ import { debounce } from '@/utils'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
sidebarElm: null
|
$_sidebarElm: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -14,16 +14,18 @@ export default {
|
||||||
}, 100)
|
}, 100)
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
window.addEventListener('resize', this.__resizeHandler)
|
||||||
|
|
||||||
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
||||||
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
|
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
window.removeEventListener('resize', this.__resizeHandler)
|
||||||
|
|
||||||
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
|
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sidebarResizeHandler(e) {
|
// use $_ for mixins properties
|
||||||
|
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
||||||
|
$_sidebarResizeHandler(e) {
|
||||||
if (e.propertyName === 'width') {
|
if (e.propertyName === 'width') {
|
||||||
this.__resizeHandler()
|
this.__resizeHandler()
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,13 +49,13 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.drag-select >>> .sortable-ghost{
|
.drag-select >>> .sortable-ghost {
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
color: #fff!important;
|
color: #fff!important;
|
||||||
background: #42b983!important;
|
background: #42b983!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drag-select >>> .el-tag{
|
.drag-select >>> .el-tag {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import 'tui-editor/dist/tui-editor.css' // editor ui
|
||||||
import 'tui-editor/dist/tui-editor-contents.css' // editor content
|
import 'tui-editor/dist/tui-editor-contents.css' // editor content
|
||||||
|
|
||||||
import Editor from 'tui-editor'
|
import Editor from 'tui-editor'
|
||||||
import defaultOptions from './defaultOptions'
|
import defaultOptions from './default-options'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MarddownEditor',
|
name: 'MarddownEditor',
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { scrollTo } from '@/utils/scrollTo'
|
import { scrollTo } from '@/utils/scroll-to'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Pagination',
|
name: 'Pagination',
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import editorImage from './components/editorImage'
|
import editorImage from './components/EditorImage'
|
||||||
import plugins from './plugins'
|
import plugins from './plugins'
|
||||||
import toolbar from './toolbar'
|
import toolbar from './toolbar'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
// set function parseTime,formatTime to filter
|
// set function parseTime,formatTime to filter
|
||||||
export { parseTime, formatTime } from '@/utils'
|
export { parseTime, formatTime } from '@/utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show plural label if time is plural number
|
||||||
|
* @param {number} time
|
||||||
|
* @param {string} label
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
function pluralize(time, label) {
|
function pluralize(time, label) {
|
||||||
if (time === 1) {
|
if (time === 1) {
|
||||||
return time + label
|
return time + label
|
||||||
|
@ -8,6 +14,9 @@ function pluralize(time, label) {
|
||||||
return time + label + 's'
|
return time + label + 's'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} time
|
||||||
|
*/
|
||||||
export function timeAgo(time) {
|
export function timeAgo(time) {
|
||||||
const between = Date.now() / 1000 - Number(time)
|
const between = Date.now() / 1000 - Number(time)
|
||||||
if (between < 3600) {
|
if (between < 3600) {
|
||||||
|
@ -19,7 +28,12 @@ export function timeAgo(time) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 数字 格式化*/
|
/**
|
||||||
|
* Number formatting
|
||||||
|
* like 10000 => 10k
|
||||||
|
* @param {number} num
|
||||||
|
* @param {number} digits
|
||||||
|
*/
|
||||||
export function numberFormatter(num, digits) {
|
export function numberFormatter(num, digits) {
|
||||||
const si = [
|
const si = [
|
||||||
{ value: 1E18, symbol: 'E' },
|
{ value: 1E18, symbol: 'E' },
|
||||||
|
@ -37,6 +51,10 @@ export function numberFormatter(num, digits) {
|
||||||
return num.toString()
|
return num.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 10000 => "10,000"
|
||||||
|
* @param {number} num
|
||||||
|
*/
|
||||||
export function toThousandFilter(num) {
|
export function toThousandFilter(num) {
|
||||||
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
|
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,9 @@ export default {
|
||||||
if (isExternal(routePath)) {
|
if (isExternal(routePath)) {
|
||||||
return routePath
|
return routePath
|
||||||
}
|
}
|
||||||
|
if (isExternal(this.basePath)) {
|
||||||
|
return this.basePath
|
||||||
|
}
|
||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ export default {
|
||||||
closeSelectedTag(view) {
|
closeSelectedTag(view) {
|
||||||
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
|
||||||
if (this.isActive(view)) {
|
if (this.isActive(view)) {
|
||||||
this.toLastView(visitedViews)
|
this.toLastView(visitedViews, view)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -160,17 +160,23 @@ export default {
|
||||||
if (this.affixTags.some(tag => tag.path === view.path)) {
|
if (this.affixTags.some(tag => tag.path === view.path)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.toLastView(visitedViews)
|
this.toLastView(visitedViews, view)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
toLastView(visitedViews) {
|
toLastView(visitedViews, view) {
|
||||||
const latestView = visitedViews.slice(-1)[0]
|
const latestView = visitedViews.slice(-1)[0]
|
||||||
if (latestView) {
|
if (latestView) {
|
||||||
this.$router.push(latestView)
|
this.$router.push(latestView)
|
||||||
} else {
|
} else {
|
||||||
// You can set another route
|
// now the default is to redirect to the home page if there is no tags-view,
|
||||||
|
// you can adjust it according to your needs.
|
||||||
|
if (view.name === 'Dashboard') {
|
||||||
|
// to reload home page
|
||||||
|
this.$router.replace({ path: '/redirect' + view.fullPath })
|
||||||
|
} else {
|
||||||
this.$router.push('/')
|
this.$router.push('/')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
openMenu(tag, e) {
|
openMenu(tag, e) {
|
||||||
const menuMinWidth = 105
|
const menuMinWidth = 105
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
export { default as AppMain } from './AppMain'
|
||||||
export { default as Navbar } from './Navbar'
|
export { default as Navbar } from './Navbar'
|
||||||
|
export { default as Settings } from './Settings'
|
||||||
export { default as Sidebar } from './Sidebar/index.vue'
|
export { default as Sidebar } from './Sidebar/index.vue'
|
||||||
export { default as TagsView } from './TagsView/index.vue'
|
export { default as TagsView } from './TagsView/index.vue'
|
||||||
export { default as AppMain } from './AppMain'
|
|
||||||
export { default as Settings } from './Settings'
|
|
||||||
|
|
|
@ -17,19 +17,19 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import RightPanel from '@/components/RightPanel'
|
import RightPanel from '@/components/RightPanel'
|
||||||
import { Navbar, Sidebar, AppMain, TagsView, Settings } from './components'
|
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
||||||
import ResizeMixin from './mixin/ResizeHandler'
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
components: {
|
components: {
|
||||||
RightPanel,
|
|
||||||
Navbar,
|
|
||||||
Sidebar,
|
|
||||||
AppMain,
|
AppMain,
|
||||||
TagsView,
|
Navbar,
|
||||||
Settings
|
RightPanel,
|
||||||
|
Settings,
|
||||||
|
Sidebar,
|
||||||
|
TagsView
|
||||||
},
|
},
|
||||||
mixins: [ResizeMixin],
|
mixins: [ResizeMixin],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -12,26 +12,28 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
window.addEventListener('resize', this.resizeHandler)
|
window.addEventListener('resize', this.$_resizeHandler)
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener('resize', this.resizeHandler)
|
window.removeEventListener('resize', this.$_resizeHandler)
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const isMobile = this.isMobile()
|
const isMobile = this.$_isMobile()
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
store.dispatch('app/toggleDevice', 'mobile')
|
store.dispatch('app/toggleDevice', 'mobile')
|
||||||
store.dispatch('app/closeSideBar', { withoutAnimation: true })
|
store.dispatch('app/closeSideBar', { withoutAnimation: true })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isMobile() {
|
// use $_ for mixins properties
|
||||||
|
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
||||||
|
$_isMobile() {
|
||||||
const rect = body.getBoundingClientRect()
|
const rect = body.getBoundingClientRect()
|
||||||
return rect.width - 1 < WIDTH
|
return rect.width - 1 < WIDTH
|
||||||
},
|
},
|
||||||
resizeHandler() {
|
$_resizeHandler() {
|
||||||
if (!document.hidden) {
|
if (!document.hidden) {
|
||||||
const isMobile = this.isMobile()
|
const isMobile = this.$_isMobile()
|
||||||
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
|
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import router from './router'
|
||||||
import i18n from './lang' // Internationalization
|
import i18n from './lang' // Internationalization
|
||||||
import './icons' // icon
|
import './icons' // icon
|
||||||
import './permission' // permission control
|
import './permission' // permission control
|
||||||
import './utils/errorLog' // error log
|
import './utils/error-log' // error log
|
||||||
|
|
||||||
import * as filters from './filters' // global filters
|
import * as filters from './filters' // global filters
|
||||||
|
|
||||||
|
|
|
@ -57,17 +57,17 @@ export const constantRoutes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/auth-redirect',
|
path: '/auth-redirect',
|
||||||
component: () => import('@/views/login/authRedirect'),
|
component: () => import('@/views/login/auth-redirect'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/404',
|
path: '/404',
|
||||||
component: () => import('@/views/errorPage/404'),
|
component: () => import('@/views/error-page/404'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/401',
|
path: '/401',
|
||||||
component: () => import('@/views/errorPage/401'),
|
component: () => import('@/views/error-page/401'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -232,13 +232,13 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '401',
|
path: '401',
|
||||||
component: () => import('@/views/errorPage/401'),
|
component: () => import('@/views/error-page/401'),
|
||||||
name: 'Page401',
|
name: 'Page401',
|
||||||
meta: { title: 'page401', noCache: true }
|
meta: { title: 'page401', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
component: () => import('@/views/errorPage/404'),
|
component: () => import('@/views/error-page/404'),
|
||||||
name: 'Page404',
|
name: 'Page404',
|
||||||
meta: { title: 'page404', noCache: true }
|
meta: { title: 'page404', noCache: true }
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'log',
|
path: 'log',
|
||||||
component: () => import('@/views/errorLog/index'),
|
component: () => import('@/views/error-log/index'),
|
||||||
name: 'ErrorLog',
|
name: 'ErrorLog',
|
||||||
meta: { title: 'errorLog', icon: 'bug' }
|
meta: { title: 'errorLog', icon: 'bug' }
|
||||||
}
|
}
|
||||||
|
@ -271,25 +271,25 @@ export const asyncRoutes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'export-excel',
|
path: 'export-excel',
|
||||||
component: () => import('@/views/excel/exportExcel'),
|
component: () => import('@/views/excel/export-excel'),
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
meta: { title: 'exportExcel' }
|
meta: { title: 'exportExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-selected-excel',
|
path: 'export-selected-excel',
|
||||||
component: () => import('@/views/excel/selectExcel'),
|
component: () => import('@/views/excel/select-excel'),
|
||||||
name: 'SelectExcel',
|
name: 'SelectExcel',
|
||||||
meta: { title: 'selectExcel' }
|
meta: { title: 'selectExcel' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'export-merge-header',
|
path: 'export-merge-header',
|
||||||
component: () => import('@/views/excel/mergeHeader'),
|
component: () => import('@/views/excel/merge-header'),
|
||||||
name: 'MergeHeader',
|
name: 'MergeHeader',
|
||||||
meta: { title: 'mergeHeader' }
|
meta: { title: 'mergeHeader' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'upload-excel',
|
path: 'upload-excel',
|
||||||
component: () => import('@/views/excel/uploadExcel'),
|
component: () => import('@/views/excel/upload-excel'),
|
||||||
name: 'UploadExcel',
|
name: 'UploadExcel',
|
||||||
meta: { title: 'uploadExcel' }
|
meta: { title: 'uploadExcel' }
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ const chartsRouter = {
|
||||||
meta: { title: 'lineChart', noCache: true }
|
meta: { title: 'lineChart', noCache: true }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'mixchart',
|
path: 'mix-chart',
|
||||||
component: () => import('@/views/charts/mixChart'),
|
component: () => import('@/views/charts/mix-chart'),
|
||||||
name: 'MixChart',
|
name: 'MixChart',
|
||||||
meta: { title: 'mixChart', noCache: true }
|
meta: { title: 'mixChart', noCache: true }
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,19 +26,19 @@ const componentsRouter = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'json-editor',
|
path: 'json-editor',
|
||||||
component: () => import('@/views/components-demo/jsonEditor'),
|
component: () => import('@/views/components-demo/json-editor'),
|
||||||
name: 'JsonEditorDemo',
|
name: 'JsonEditorDemo',
|
||||||
meta: { title: 'jsonEditor' }
|
meta: { title: 'jsonEditor' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'splitpane',
|
path: 'split-pane',
|
||||||
component: () => import('@/views/components-demo/splitpane'),
|
component: () => import('@/views/components-demo/split-pane'),
|
||||||
name: 'SplitpaneDemo',
|
name: 'SplitpaneDemo',
|
||||||
meta: { title: 'splitPane' }
|
meta: { title: 'splitPane' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'avatar-upload',
|
path: 'avatar-upload',
|
||||||
component: () => import('@/views/components-demo/avatarUpload'),
|
component: () => import('@/views/components-demo/avatar-upload'),
|
||||||
name: 'AvatarUploadDemo',
|
name: 'AvatarUploadDemo',
|
||||||
meta: { title: 'avatarUpload' }
|
meta: { title: 'avatarUpload' }
|
||||||
},
|
},
|
||||||
|
@ -56,7 +56,7 @@ const componentsRouter = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'count-to',
|
path: 'count-to',
|
||||||
component: () => import('@/views/components-demo/countTo'),
|
component: () => import('@/views/components-demo/count-to'),
|
||||||
name: 'CountToDemo',
|
name: 'CountToDemo',
|
||||||
meta: { title: 'countTo' }
|
meta: { title: 'countTo' }
|
||||||
},
|
},
|
||||||
|
@ -68,31 +68,31 @@ const componentsRouter = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'back-to-top',
|
path: 'back-to-top',
|
||||||
component: () => import('@/views/components-demo/backToTop'),
|
component: () => import('@/views/components-demo/back-to-top'),
|
||||||
name: 'BackToTopDemo',
|
name: 'BackToTopDemo',
|
||||||
meta: { title: 'backToTop' }
|
meta: { title: 'backToTop' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-dialog',
|
path: 'drag-dialog',
|
||||||
component: () => import('@/views/components-demo/dragDialog'),
|
component: () => import('@/views/components-demo/drag-dialog'),
|
||||||
name: 'DragDialogDemo',
|
name: 'DragDialogDemo',
|
||||||
meta: { title: 'dragDialog' }
|
meta: { title: 'dragDialog' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-select',
|
path: 'drag-select',
|
||||||
component: () => import('@/views/components-demo/dragSelect'),
|
component: () => import('@/views/components-demo/drag-select'),
|
||||||
name: 'DragSelectDemo',
|
name: 'DragSelectDemo',
|
||||||
meta: { title: 'dragSelect' }
|
meta: { title: 'dragSelect' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'dnd-list',
|
path: 'dnd-list',
|
||||||
component: () => import('@/views/components-demo/dndList'),
|
component: () => import('@/views/components-demo/dnd-list'),
|
||||||
name: 'DndListDemo',
|
name: 'DndListDemo',
|
||||||
meta: { title: 'dndList' }
|
meta: { title: 'dndList' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-kanban',
|
path: 'drag-kanban',
|
||||||
component: () => import('@/views/components-demo/dragKanban'),
|
component: () => import('@/views/components-demo/drag-kanban'),
|
||||||
name: 'DragKanbanDemo',
|
name: 'DragKanbanDemo',
|
||||||
meta: { title: 'dragKanban' }
|
meta: { title: 'dragKanban' }
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,25 +14,25 @@ const tableRouter = {
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'dynamic-table',
|
path: 'dynamic-table',
|
||||||
component: () => import('@/views/table/dynamicTable/index'),
|
component: () => import('@/views/table/dynamic-table/index'),
|
||||||
name: 'DynamicTable',
|
name: 'DynamicTable',
|
||||||
meta: { title: 'dynamicTable' }
|
meta: { title: 'dynamicTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'drag-table',
|
path: 'drag-table',
|
||||||
component: () => import('@/views/table/dragTable'),
|
component: () => import('@/views/table/drag-table'),
|
||||||
name: 'DragTable',
|
name: 'DragTable',
|
||||||
meta: { title: 'dragTable' }
|
meta: { title: 'dragTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'inline-edit-table',
|
path: 'inline-edit-table',
|
||||||
component: () => import('@/views/table/inlineEditTable'),
|
component: () => import('@/views/table/inline-edit-table'),
|
||||||
name: 'InlineEditTable',
|
name: 'InlineEditTable',
|
||||||
meta: { title: 'inlineEditTable' }
|
meta: { title: 'inlineEditTable' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'complex-table',
|
path: 'complex-table',
|
||||||
component: () => import('@/views/table/complexTable'),
|
component: () => import('@/views/table/complex-table'),
|
||||||
name: 'ComplexTable',
|
name: 'ComplexTable',
|
||||||
meta: { title: 'complexTable' }
|
meta: { title: 'complexTable' }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
* Created by jiachenpan on 16/11/18.
|
* Created by jiachenpan on 16/11/18.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the time to string
|
||||||
|
* @param {(Object|string|number)} time
|
||||||
|
* @param {string} cFormat
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
export function parseTime(time, cFormat) {
|
export function parseTime(time, cFormat) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
return null
|
return null
|
||||||
|
@ -40,6 +46,11 @@ export function parseTime(time, cFormat) {
|
||||||
return time_str
|
return time_str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} time
|
||||||
|
* @param {string} option
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
export function formatTime(time, option) {
|
export function formatTime(time, option) {
|
||||||
if (('' + time).length === 10) {
|
if (('' + time).length === 10) {
|
||||||
time = parseInt(time) * 1000
|
time = parseInt(time) * 1000
|
||||||
|
@ -78,7 +89,10 @@ export function formatTime(time, option) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化时间
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
export function getQueryObject(url) {
|
export function getQueryObject(url) {
|
||||||
url = url == null ? window.location.href : url
|
url = url == null ? window.location.href : url
|
||||||
const search = url.substring(url.lastIndexOf('?') + 1)
|
const search = url.substring(url.lastIndexOf('?') + 1)
|
||||||
|
@ -95,7 +109,7 @@ export function getQueryObject(url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Sting} input value
|
* @param {string} input value
|
||||||
* @returns {number} output value
|
* @returns {number} output value
|
||||||
*/
|
*/
|
||||||
export function byteLength(str) {
|
export function byteLength(str) {
|
||||||
|
@ -110,6 +124,10 @@ export function byteLength(str) {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array} actual
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
export function cleanArray(actual) {
|
export function cleanArray(actual) {
|
||||||
const newArray = []
|
const newArray = []
|
||||||
for (let i = 0; i < actual.length; i++) {
|
for (let i = 0; i < actual.length; i++) {
|
||||||
|
@ -120,6 +138,10 @@ export function cleanArray(actual) {
|
||||||
return newArray
|
return newArray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} json
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
export function param(json) {
|
export function param(json) {
|
||||||
if (!json) return ''
|
if (!json) return ''
|
||||||
return cleanArray(
|
return cleanArray(
|
||||||
|
@ -130,6 +152,10 @@ export function param(json) {
|
||||||
).join('&')
|
).join('&')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
export function param2Obj(url) {
|
export function param2Obj(url) {
|
||||||
const search = url.split('?')[1]
|
const search = url.split('?')[1]
|
||||||
if (!search) {
|
if (!search) {
|
||||||
|
@ -146,16 +172,23 @@ export function param2Obj(url) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} val
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
export function html2Text(val) {
|
export function html2Text(val) {
|
||||||
const div = document.createElement('div')
|
const div = document.createElement('div')
|
||||||
div.innerHTML = val
|
div.innerHTML = val
|
||||||
return div.textContent || div.innerText
|
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) {
|
export function objectMerge(target, source) {
|
||||||
/* Merges two objects,
|
|
||||||
giving the last one precedence */
|
|
||||||
|
|
||||||
if (typeof target !== 'object') {
|
if (typeof target !== 'object') {
|
||||||
target = {}
|
target = {}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +206,10 @@ export function objectMerge(target, source) {
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {string} className
|
||||||
|
*/
|
||||||
export function toggleClass(element, className) {
|
export function toggleClass(element, className) {
|
||||||
if (!element || !className) {
|
if (!element || !className) {
|
||||||
return
|
return
|
||||||
|
@ -189,45 +226,10 @@ export function toggleClass(element, className) {
|
||||||
element.className = classString
|
element.className = classString
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pickerOptions = [
|
/**
|
||||||
{
|
* @param {string} type
|
||||||
text: '今天',
|
* @returns {Date}
|
||||||
onClick(picker) {
|
*/
|
||||||
const end = new Date()
|
|
||||||
const start = new Date(new Date().toDateString())
|
|
||||||
end.setTime(start.getTime())
|
|
||||||
picker.$emit('pick', [start, end])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '最近一周',
|
|
||||||
onClick(picker) {
|
|
||||||
const end = new Date(new Date().toDateString())
|
|
||||||
const start = new Date()
|
|
||||||
start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
|
|
||||||
picker.$emit('pick', [start, end])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '最近一个月',
|
|
||||||
onClick(picker) {
|
|
||||||
const end = new Date(new Date().toDateString())
|
|
||||||
const start = new Date()
|
|
||||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
|
||||||
picker.$emit('pick', [start, end])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '最近三个月',
|
|
||||||
onClick(picker) {
|
|
||||||
const end = new Date(new Date().toDateString())
|
|
||||||
const start = new Date()
|
|
||||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
|
|
||||||
picker.$emit('pick', [start, end])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
export function getTime(type) {
|
export function getTime(type) {
|
||||||
if (type === 'start') {
|
if (type === 'start') {
|
||||||
return new Date().getTime() - 3600 * 1000 * 24 * 90
|
return new Date().getTime() - 3600 * 1000 * 24 * 90
|
||||||
|
@ -236,6 +238,12 @@ export function getTime(type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Function} func
|
||||||
|
* @param {number} wait
|
||||||
|
* @param {boolean} immediate
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
export function debounce(func, wait, immediate) {
|
export function debounce(func, wait, immediate) {
|
||||||
let timeout, args, context, timestamp, result
|
let timeout, args, context, timestamp, result
|
||||||
|
|
||||||
|
@ -275,6 +283,8 @@ export function debounce(func, wait, immediate) {
|
||||||
* This is just a simple version of deep copy
|
* This is just a simple version of deep copy
|
||||||
* Has a lot of edge cases bug
|
* Has a lot of edge cases bug
|
||||||
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
|
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
|
||||||
|
* @param {Object} source
|
||||||
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
export function deepClone(source) {
|
export function deepClone(source) {
|
||||||
if (!source && typeof source !== 'object') {
|
if (!source && typeof source !== 'object') {
|
||||||
|
@ -291,22 +301,47 @@ export function deepClone(source) {
|
||||||
return targetObj
|
return targetObj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array} arr
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
export function uniqueArr(arr) {
|
export function uniqueArr(arr) {
|
||||||
return Array.from(new Set(arr))
|
return Array.from(new Set(arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
export function createUniqueString() {
|
export function createUniqueString() {
|
||||||
const timestamp = +new Date() + ''
|
const timestamp = +new Date() + ''
|
||||||
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
|
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
|
||||||
return (+(randomNum + timestamp)).toString(32)
|
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) {
|
export function hasClass(ele, cls) {
|
||||||
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
|
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add class to element
|
||||||
|
* @param {HTMLElement} elm
|
||||||
|
* @param {string} cls
|
||||||
|
*/
|
||||||
export function addClass(ele, cls) {
|
export function addClass(ele, cls) {
|
||||||
if (!hasClass(ele, cls)) ele.className += ' ' + cls
|
if (!hasClass(ele, cls)) ele.className += ' ' + cls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove class from element
|
||||||
|
* @param {HTMLElement} elm
|
||||||
|
* @param {string} cls
|
||||||
|
*/
|
||||||
export function removeClass(ele, cls) {
|
export function removeClass(ele, cls) {
|
||||||
if (hasClass(ele, cls)) {
|
if (hasClass(ele, cls)) {
|
||||||
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
|
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
* @param {Number} w
|
* @param {Number} w
|
||||||
* @param {Number} h
|
* @param {Number} h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function openWindow(url, title, w, h) {
|
export default function openWindow(url, title, w, h) {
|
||||||
// Fixes dual-screen position Most browsers Firefox
|
// Fixes dual-screen position Most browsers Firefox
|
||||||
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left
|
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left
|
|
@ -12,7 +12,10 @@ var requestAnimFrame = (function() {
|
||||||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
|
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
|
/**
|
||||||
|
* Because it's so fucking difficult to detect the scrolling element, just move them all
|
||||||
|
* @param {number} amount
|
||||||
|
*/
|
||||||
function move(amount) {
|
function move(amount) {
|
||||||
document.documentElement.scrollTop = amount
|
document.documentElement.scrollTop = amount
|
||||||
document.body.parentNode.scrollTop = amount
|
document.body.parentNode.scrollTop = amount
|
||||||
|
@ -23,6 +26,11 @@ function position() {
|
||||||
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
|
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) {
|
export function scrollTo(to, duration, callback) {
|
||||||
const start = position()
|
const start = position()
|
||||||
const change = to - start
|
const change = to - start
|
|
@ -1,41 +1,72 @@
|
||||||
/**
|
/**
|
||||||
* Created by jiachenpan on 16/11/18.
|
* Created by jiachenpan on 16/11/18.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function isExternal(path) {
|
export function isExternal(path) {
|
||||||
return /^(https?:|mailto:|tel:)/.test(path)
|
return /^(https?:|mailto:|tel:)/.test(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validUsername(str) {
|
export function validUsername(str) {
|
||||||
const valid_map = ['admin', 'editor']
|
const valid_map = ['admin', 'editor']
|
||||||
return valid_map.indexOf(str.trim()) >= 0
|
return valid_map.indexOf(str.trim()) >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} url
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validURL(url) {
|
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.,?'\\+&%$#=~_-]+))*$/
|
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)
|
return reg.test(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validLowerCase(str) {
|
export function validLowerCase(str) {
|
||||||
const reg = /^[a-z]+$/
|
const reg = /^[a-z]+$/
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validUpperCase(str) {
|
export function validUpperCase(str) {
|
||||||
const reg = /^[A-Z]+$/
|
const reg = /^[A-Z]+$/
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validAlphabets(str) {
|
export function validAlphabets(str) {
|
||||||
const reg = /^[A-Za-z]+$/
|
const reg = /^[A-Za-z]+$/
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} email
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function validEmail(email) {
|
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,}))$/
|
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)
|
return reg.test(email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function isString(str) {
|
export function isString(str) {
|
||||||
if (typeof str === 'string' || str instanceof String) {
|
if (typeof str === 'string' || str instanceof String) {
|
||||||
return true
|
return true
|
||||||
|
@ -43,6 +74,10 @@ export function isString(str) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array} arg
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
export function isArray(arg) {
|
export function isArray(arg) {
|
||||||
if (typeof Array.isArray === 'undefined') {
|
if (typeof Array.isArray === 'undefined') {
|
||||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Chart from '@/components/Charts/keyboard'
|
import Chart from '@/components/Charts/Keyboard'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'KeyboardChart',
|
name: 'KeyboardChart',
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Chart from '@/components/Charts/lineMarker'
|
import Chart from '@/components/Charts/LineMarker'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LineChart',
|
name: 'LineChart',
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Chart from '@/components/Charts/mixChart'
|
import Chart from '@/components/Charts/MixChart'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MixChart',
|
name: 'MixChart',
|
|
@ -17,7 +17,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import elDragDialog from '@/directive/el-dragDialog' // base on element-ui
|
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DragDialogDemo',
|
name: 'DragDialogDemo',
|
|
@ -115,7 +115,7 @@
|
||||||
import PanThumb from '@/components/PanThumb'
|
import PanThumb from '@/components/PanThumb'
|
||||||
import MdInput from '@/components/MDinput'
|
import MdInput from '@/components/MDinput'
|
||||||
import Mallki from '@/components/TextHoverEffect/Mallki'
|
import Mallki from '@/components/TextHoverEffect/Mallki'
|
||||||
import DropdownMenu from '@/components/Share/dropdownMenu'
|
import DropdownMenu from '@/components/Share/DropdownMenu'
|
||||||
import waves from '@/directive/waves/index.js' // 水波纹指令
|
import waves from '@/directive/waves/index.js' // 水波纹指令
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="components-container">
|
<div class="components-container">
|
||||||
<code><strong>SplitPane</strong> If you've used
|
<code><strong>SplitPane</strong> If you've used
|
||||||
<a href="http://codepen.io/" target="_blank"> codepen</a>,
|
<a href="https://codepen.io/" target="_blank"> codepen</a>,
|
||||||
<a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar.
|
<a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar.
|
||||||
<a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a>
|
<a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a>
|
||||||
</code>
|
</code>
|
|
@ -28,7 +28,7 @@
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
|
||||||
<div class="time-container">
|
<div class="time-container">
|
||||||
<el-date-picker v-model="time" :picker-options="pickerOptions" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" />
|
<el-date-picker v-model="time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button style="margin-left: 10px;" type="success">
|
<el-button style="margin-left: 10px;" type="success">
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { transactionList } from '@/api/remoteSearch'
|
import { transactionList } from '@/api/remote-search'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
filters: {
|
filters: {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import DropdownMenu from '@/components/Share/dropdownMenu'
|
import DropdownMenu from '@/components/Share/DropdownMenu'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Documentation',
|
name: 'Documentation',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="errPage-container">
|
<div class="errPage-container">
|
||||||
<errorA />
|
<ErrorA />
|
||||||
<errorB />
|
<ErrorB />
|
||||||
<!-- $t is vue-i18n global function to translate lang -->
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<h3>{{ $t('errorLog.tips') }}</h3>
|
<h3>{{ $t('errorLog.tips') }}</h3>
|
||||||
<code>
|
<code>
|
||||||
|
@ -17,12 +17,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import errorA from './errorTestA'
|
import ErrorA from './components/ErrorTestA'
|
||||||
import errorB from './errorTestB'
|
import ErrorB from './components/ErrorTestB'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ErrorLog',
|
name: 'ErrorLog',
|
||||||
components: { errorA, errorB }
|
components: { ErrorA, ErrorB }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -76,12 +76,12 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Tinymce from '@/components/Tinymce'
|
import Tinymce from '@/components/Tinymce'
|
||||||
import Upload from '@/components/Upload/singleImage3'
|
import Upload from '@/components/Upload/SingleImage3'
|
||||||
import MDinput from '@/components/MDinput'
|
import MDinput from '@/components/MDinput'
|
||||||
import Sticky from '@/components/Sticky' // 粘性header组件
|
import Sticky from '@/components/Sticky' // 粘性header组件
|
||||||
import { validURL } from '@/utils/validate'
|
import { validURL } from '@/utils/validate'
|
||||||
import { fetchArticle } from '@/api/article'
|
import { fetchArticle } from '@/api/article'
|
||||||
import { searchUser } from '@/api/remoteSearch'
|
import { searchUser } from '@/api/remote-search'
|
||||||
import Warning from './Warning'
|
import Warning from './Warning'
|
||||||
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
|
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<p class="warn-content">
|
<p class="warn-content">
|
||||||
{{ $t('guide.description') }}
|
{{ $t('guide.description') }}
|
||||||
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.
|
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
|
||||||
</a>
|
|
||||||
</p>
|
</p>
|
||||||
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
|
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
|
||||||
{{ $t('guide.button') }}
|
{{ $t('guide.button') }}
|
||||||
|
@ -14,7 +13,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Driver from 'driver.js' // import driver.js
|
import Driver from 'driver.js' // import driver.js
|
||||||
import 'driver.js/dist/driver.min.css' // import driver.js css
|
import 'driver.js/dist/driver.min.css' // import driver.js css
|
||||||
import steps from './defineSteps'
|
import steps from './steps'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Guide',
|
name: 'Guide',
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import openWindow from '@/utils/openWindow'
|
// import openWindow from '@/utils/open-window'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SocialSignin',
|
name: 'SocialSignin',
|
|
@ -81,7 +81,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { validUsername } from '@/utils/validate'
|
import { validUsername } from '@/utils/validate'
|
||||||
import LangSelect from '@/components/LangSelect'
|
import LangSelect from '@/components/LangSelect'
|
||||||
import SocialSign from './socialSignin'
|
import SocialSign from './components/SocialSignin'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import clipboard from '@/utils/clipboard'
|
import clipboard from '@/utils/clipboard'
|
||||||
import icons from './requireIcons'
|
import icons from './require-icons'
|
||||||
import elementIcons from './element-icon.json'
|
import elementIcons from './element-icon.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import tabPane from './components/tabPane'
|
import tabPane from './components/TabPane'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Tab',
|
name: 'Tab',
|
||||||
|
@ -39,7 +39,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.tab-container{
|
.tab-container {
|
||||||
margin: 30px;
|
margin: 30px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import fixedThead from './fixedThead'
|
import FixedThead from './components/FixedThead'
|
||||||
import unfixedThead from './unfixedThead'
|
import UnfixedThead from './components/UnfixedThead'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DynamicTable',
|
name: 'DynamicTable',
|
||||||
components: { fixedThead, unfixedThead }
|
components: { FixedThead, UnfixedThead }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue