Compare commits

...

41 Commits

Author SHA1 Message Date
花裤衩
ec65202cb9 feat: add sandbox 2020-05-04 22:50:16 +08:00
Phạm Ngọc Hòa
a2784dd6ef perf: change default element-ui language to english (#2741) 2020-05-04 21:51:21 +08:00
花裤衩
fc26c3106f fix: compatibility with vetur (#1700) 2020-05-04 21:30:58 +08:00
ntnyq
9580c43a8e fix[element-variables]: missing space in element-variables (#3144) 2020-04-28 18:26:34 +08:00
Aisen
1b8f726529 perf[Tinymce]: editor try to keep these URLs intact (#3141) 2020-04-28 10:10:58 +08:00
花裤衩
d4405464ce fix: use vue-cli default source-map (#3097)
cheap-module-eval-source-map
2020-04-22 10:31:46 +08:00
Alex S
9d8c7edf91 fixed typo (#3091) 2020-04-04 15:53:26 +08:00
花裤衩
6eccffeb2f fix: svg support old broswer (#3085) 2020-03-28 11:16:41 +08:00
花裤衩
f7a9d21109 Update README.zh-CN.md 2020-03-27 12:32:30 +08:00
花裤衩
993a6c72e8 docs: add smallsticker 2020-03-27 11:57:40 +08:00
echofly
9e0435ac85 perf: format component names as PascalCase (#3074)
format: component names should be PascalCase
2020-03-24 10:17:18 +08:00
Aisen60
776f10e197 fix:fixed parseTime bug in ie and safari(#3066)
* /src/utils/index.js parseTime 添加IE浏览器(版本10以下,包括版本10)兼容。

* perf: update

Co-authored-by: aisen60 <aisen60@qq.com>
Co-authored-by: 花裤衩 <panfree23@gmail.com>
2020-03-20 21:24:31 +08:00
echofly
c2a5a15956 fix[profile/UserCard]: fixed wrong key name (#3056)
roles => role
2020-03-18 19:22:38 +08:00
花裤衩
a45e64fcb2 perf: change script-loader to dependencies 2020-02-12 10:01:27 +08:00
Shota Aratono
fec25fedba docs: improve Japanese translation (#2970) 2020-02-05 09:51:43 +08:00
RoBlues
d6816c547d perf[Mock]: set responseFake to mock-server.js(#2966)
* modify 把mock/index.js中与mock-server相关的代码转移到mock-server.js中去,实现两则功能分割
2020-02-02 19:39:40 +08:00
李小斐
6850312e89 fix: fixed redirect path regex (#2933) 2020-01-11 10:25:59 +08:00
花裤衩
d634e2ae2f fix: fixed require mock bug in production 2020-01-09 20:24:48 +08:00
花裤衩
b57f2008bd bump: update element-ui version 2020-01-09 17:36:49 +08:00
花裤衩
c9affcf2ad fix: fixed mock server (#2929)
* init

* refine

* update
2020-01-09 17:21:36 +08:00
花裤衩
fbad7f481b fix[Charts]: fix charts resize in keep-alive bug (#2922)
* fix[Charts]: fix charts resize in keep-alive bug

* refine
2020-01-09 16:49:57 +08:00
RussXD
088f64eecc perf: optimize checkCapslock method (#2635)
* optimize checkCapslock method

* update

Co-authored-by: 花裤衩 <panfree23@gmail.com>
2020-01-08 12:12:10 +08:00
AndyLZC/AndyLZC.github.io
55b1bbac99 perf[complex-table]:refine code (#2825)
* 解决无法删除列表的bug;优化代码;

* perf: refine

Co-authored-by: 花裤衩 <panfree23@gmail.com>
2020-01-07 22:30:07 +08:00
Kaitian Xie
fd5a2e8da2 perf[Menu]: remove unused menu-wrapper (#2903) 2020-01-06 22:34:14 +08:00
任羽飞
a0b39d5043 perf: import mockXHR only in production (#2910)
* 自动排除mock

生产环境,使用webpack的条件编译自动排除mock数据

* perf: refine

Co-authored-by: 花裤衩 <panfree23@gmail.com>
2020-01-06 22:22:37 +08:00
4f563a7bfe fix[Logout]: click blank area of ​​dropDown able to logout (#2896)
Fixed clicking blank area of ​​drop-down unable to log out
2019-12-31 14:14:34 +08:00
花裤衩
262c0ba08e perf[documentation]: refine css 2019-12-15 20:17:59 +08:00
flitrue
594fc58d0c fix[icons]:fixed eslint 1 error and 2 warnings (#2835) 2019-12-12 15:16:03 +08:00
monkeycf
65d8c451e8 feat: plop new generate store (#2805) 2019-12-04 10:34:23 +08:00
xuanzai
e1554fdbd0 perf[views/icons]: use grid (#2803) 2019-12-01 15:48:30 +08:00
Phạm Ngọc Hòa
53803d067d perf: format pdf download (#2791) 2019-11-27 10:06:28 +08:00
花裤衩
25dddbbce8 update 'MarkdownEditor' components name (#2743) 2019-11-12 17:25:12 +08:00
Phạm Ngọc Hòa
683f68b838 format: space in user card (#2744) 2019-11-12 17:24:30 +08:00
bbigcd
44203f88a7 update 'MarkdownEditor' components name 2019-11-12 12:08:45 +08:00
Phạm Ngọc Hòa
d5c013a48c perf: text i18n (#2739) 2019-11-11 19:39:59 +08:00
Phạm Ngọc Hòa
b11acb2171 perf: complex table (#2732)
Move ont format `{row}`
2019-11-08 11:26:53 +08:00
Phạm Ngọc Hòa
b2dd7caee6 perf: format drag table (#2733)
move one format `{row}`
2019-11-08 11:25:42 +08:00
Phạm Ngọc Hòa
a4fa1199ba perf: format inline edit table (#2725)
move one format `{row}`
2019-11-07 13:37:05 +08:00
Phạm Ngọc Hòa
6a194d1b4f perf: format dropdown menu code (#2720) 2019-11-05 14:26:24 +08:00
花裤衩
6739ab543b style: fix el-date-picker css style 2019-10-25 19:45:21 +08:00
BradyBromley
6a214f0eac docs: improved README.md (#2656) 2019-10-14 10:25:30 +08:00
45 changed files with 412 additions and 373 deletions

View File

@@ -30,7 +30,7 @@
## 概要
[vue-element-admin](https://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の多言語対応、可変ルート、権限、典型的なビジネスアプリテンプレートであり、豊富なコンポーネントを提供しています素早くビジネス用の管理画面の現型を構築に役立ちます。
- [デモページ](https://panjiachen.github.io/vue-element-admin)
@@ -44,18 +44,18 @@
- おすすめシンプルテンプレート: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
- デスクトップバージョン: [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))
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
**After the `v4.1.0+` version, the default master branch will not support i18n. Please use [i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), it will keep up with the master update**
**バージョン`v4.1.0+`以降について、デフォルトのmasterブランチではi18nをサポートしていません。masterブランチと共にアップデートされる[i18n Branch](https://github.com/PanJiaChen/vue-element-admin/tree/i18n)を使用してください。 **
**現在のバージョン `v4.0+` は `vue-cli` で構築バグ報告は[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)のissueでお願いします。旧バージョン[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)もあります。`vue-cli`に依存しないです。**
**現在のバージョン `v4.0+` は `vue-cli` で構築していて、バグ報告は[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)のissueでお願いします。旧バージョン[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)**
## 前準備
ローカル環境に [node](http://nodejs.org/) と [git](https://git-scm.com/)インストールが必要です。[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) [element-ui](https://github.com/ElemeFE/element)で開発しています。Requestは[Mock.js](https://github.com/nuysoft/Mock)のモックデータを使っています。
ローカル環境に [node](http://nodejs.org/) と [git](https://git-scm.com/)インストールが必要です。[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) [element-ui](https://github.com/ElemeFE/element)で開発しています。Requestは[Mock.js](https://github.com/nuysoft/Mock)のモックデータを使っています。
**バグ修正や新規機能追加のissue と pull requestは大歓迎です。**
@@ -87,9 +87,9 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
- 多言語切替
- テーマ切替
- サイトメニュー(ルートから生成)
- Breadcrumb Navigation
- Tag Navigation
- Svg Sprite Icon
- パンくずリストナビゲーション
- タブナビゲーション
- Svg Sprite アイコン
- ローカル/バックエンド モック データ
- Screenfull
@@ -104,33 +104,33 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
- リード
- Zip
- Table
- Dynamic Table
- Drag And Drop Table
- Inline Edit Table
- テーブル
- ダイナミックテーブル
- ドラッグアンドドロップテーブル
- インラインエディットテーブル
- Error Page
- エラーページ
- 401
- 404
- コンポーネント
- Avatar Upload
- Back To Top
- Drag Dialog
- Drag Select
- Drag Kanban
- Drag List
- SplitPane
- アバターアップロード
- トップに戻る
- ドラッグダイアログ
- ドラッグ選択
- ドラッグKanban
- ドラッグリスト
- ペインの分割
- Dropzone
- Sticky
- スティッキー
- CountTo
- Advanced Example
- Error Log
- Dashboard
- Guide Page
- 高度なサンプル
- エラーログ
- ダッシュボード
- ガイドページ
- ECharts
- Clipboard
- クリップボード
- Markdown to html
```
@@ -150,7 +150,7 @@ npm install
npm run dev
```
This will automatically open http://localhost:9527
http://localhost:9527 が自動的に開きます。
## Build
@@ -178,11 +178,11 @@ npm run lint
npm run lint -- --fix
```
Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
詳細は [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) を参照してください。
## Changelog
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
各リリースの詳細は [release notes](https://github.com/PanJiaChen/vue-element-admin/releases) にあります。
## Online Demo

View File

@@ -30,9 +30,9 @@ English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spa
## Introduction
[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).
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It is based on [vue](https://github.com/vuejs/vue) and uses 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.
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is based on the newest development stack of vue and it has a built-in i18n solution, typical templates for enterprise applications, and lots of awesome features. It helps you build large and complex Single-Page Applications. I believe whatever your needs are, this project will help you.
- [Preview](https://panjiachen.github.io/vue-element-admin)

View File

@@ -221,6 +221,10 @@ Detailed changes for each release are documented in the [release notes](https://
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
## 购买贴纸
你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,本项目将获得 2 元的捐赠。
## Browsers support
Modern browsers and Internet Explorer 10+.

View File

@@ -18,7 +18,7 @@ for (let i = 0; i < count; i++) {
forecast: '@float(0, 100, 2, 2)',
importance: '@integer(1, 3)',
'type|1': ['CN', 'US', 'JP', 'EU'],
'status|1': ['published', 'draft', 'deleted'],
'status|1': ['published', 'draft'],
display_time: '@datetime',
comment_disabled: true,
pageviews: '@integer(300, 5000)',
@@ -29,7 +29,7 @@ for (let i = 0; i < count; i++) {
export default [
{
url: '/article/list',
url: '/vue-element-admin/article/list',
type: 'get',
response: config => {
const { importance, type, title, page = 1, limit = 20, sort } = config.query
@@ -58,7 +58,7 @@ export default [
},
{
url: '/article/detail',
url: '/vue-element-admin/article/detail',
type: 'get',
response: config => {
const { id } = config.query
@@ -74,7 +74,7 @@ export default [
},
{
url: '/article/pv',
url: '/vue-element-admin/article/pv',
type: 'get',
response: _ => {
return {
@@ -92,7 +92,7 @@ export default [
},
{
url: '/article/create',
url: '/vue-element-admin/article/create',
type: 'post',
response: _ => {
return {
@@ -103,7 +103,7 @@ export default [
},
{
url: '/article/update',
url: '/vue-element-admin/article/update',
type: 'post',
response: _ => {
return {

View File

@@ -54,17 +54,4 @@ export function mockXHR() {
}
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`/mock${url}`),
type: type || 'get',
response(req, res) {
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
export default mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
export default mocks

View File

@@ -2,17 +2,21 @@ 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 { default: mocks } = require('./index.js')
for (const mock of mocks) {
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(mocks).length
const mockRoutesLength = Object.keys(mocksForServer).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
@@ -27,6 +31,18 @@ function unregisterRoutes() {
})
}
// 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 => {
// es6 polyfill
require('@babel/register')

View File

@@ -13,7 +13,7 @@ NameList.push({ name: 'mock-Pan' })
export default [
// username search
{
url: '/search/user',
url: '/vue-element-admin/search/user',
type: 'get',
response: config => {
const { name } = config.query
@@ -30,7 +30,7 @@ export default [
// transaction list
{
url: '/transaction/list',
url: '/vue-element-admin/transaction/list',
type: 'get',
response: _ => {
return {

View File

@@ -38,7 +38,7 @@ const roles = [
export default [
// mock get all routes form server
{
url: '/routes',
url: '/vue-element-admin/routes',
type: 'get',
response: _ => {
return {
@@ -50,7 +50,7 @@ export default [
// mock get all roles form server
{
url: '/roles',
url: '/vue-element-admin/roles',
type: 'get',
response: _ => {
return {
@@ -62,7 +62,7 @@ export default [
// add role
{
url: '/role',
url: '/vue-element-admin/role',
type: 'post',
response: {
code: 20000,
@@ -74,7 +74,7 @@ export default [
// update role
{
url: '/role/[A-Za-z0-9]',
url: '/vue-element-admin/role/[A-Za-z0-9]',
type: 'put',
response: {
code: 20000,
@@ -86,7 +86,7 @@ export default [
// delete role
{
url: '/role/[A-Za-z0-9]',
url: '/vue-element-admin/role/[A-Za-z0-9]',
type: 'delete',
response: {
code: 20000,

View File

@@ -26,7 +26,7 @@ const users = {
export default [
// user login
{
url: '/user/login',
url: '/vue-element-admin/user/login',
type: 'post',
response: config => {
const { username } = config.body
@@ -49,7 +49,7 @@ export default [
// get user info
{
url: '/user/info\.*',
url: '/vue-element-admin/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
@@ -72,7 +72,7 @@ export default [
// user logout
{
url: '/user/logout',
url: '/vue-element-admin/user/logout',
type: 'post',
response: _ => {
return {

View File

@@ -49,7 +49,7 @@
"driver.js": "0.9.5",
"dropzone": "5.5.1",
"echarts": "4.2.1",
"element-ui": "2.7.0",
"element-ui": "2.13.0",
"file-saver": "2.0.1",
"fuse.js": "3.4.4",
"js-cookie": "2.2.0",
@@ -59,6 +59,7 @@
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"screenfull": "4.2.0",
"script-loader": "0.7.2",
"showdown": "1.9.0",
"sortablejs": "1.8.4",
"tui-editor": "1.3.3",
@@ -96,7 +97,6 @@
"runjs": "^4.3.2",
"sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "2.1.3",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.0",

View File

@@ -0,0 +1,16 @@
{{#if state}}
const state = {}
{{/if}}
{{#if mutations}}
const mutations = {}
{{/if}}
{{#if actions}}
const actions = {}
{{/if}}
export default {
namespaced: true,
{{options}}
}

View File

@@ -0,0 +1,62 @@
const { notEmpty } = require('../utils.js')
module.exports = {
description: 'generate store',
prompts: [{
type: 'input',
name: 'name',
message: 'store name please',
validate: notEmpty('name')
},
{
type: 'checkbox',
name: 'blocks',
message: 'Blocks:',
choices: [{
name: 'state',
value: 'state',
checked: true
},
{
name: 'mutations',
value: 'mutations',
checked: true
},
{
name: 'actions',
value: 'actions',
checked: true
}
],
validate(value) {
if (!value.includes('state') || !value.includes('mutations')) {
return 'store require at least state and mutations'
}
return true
}
}
],
actions(data) {
const name = '{{name}}'
const { blocks } = data
const options = ['state', 'mutations']
const joinFlag = `,
`
if (blocks.length === 3) {
options.push('actions')
}
const actions = [{
type: 'add',
path: `src/store/modules/${name}.js`,
templateFile: 'plop-templates/store/index.hbs',
data: {
options: options.join(joinFlag),
state: blocks.includes('state'),
mutations: blocks.includes('mutations'),
actions: blocks.includes('actions')
}
}]
return actions
}
}

View File

@@ -1,7 +1,9 @@
const viewGenerator = require('./plop-templates/view/prompt')
const componentGenerator = require('./plop-templates/component/prompt')
const storeGenerator = require('./plop-templates/store/prompt.js')
module.exports = function(plop) {
plop.setGenerator('view', viewGenerator)
plop.setGenerator('component', componentGenerator)
plop.setGenerator('store', storeGenerator)
}

6
sandbox.config.json Normal file
View File

@@ -0,0 +1,6 @@
{
"infiniteLoopProtection": true,
"hardReloadOnChange": false,
"view": "browser",
"template": "node"
}

View File

@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function fetchList(query) {
return request({
url: '/article/list',
url: '/vue-element-admin/article/list',
method: 'get',
params: query
})
@@ -10,7 +10,7 @@ export function fetchList(query) {
export function fetchArticle(id) {
return request({
url: '/article/detail',
url: '/vue-element-admin/article/detail',
method: 'get',
params: { id }
})
@@ -18,7 +18,7 @@ export function fetchArticle(id) {
export function fetchPv(pv) {
return request({
url: '/article/pv',
url: '/vue-element-admin/article/pv',
method: 'get',
params: { pv }
})
@@ -26,7 +26,7 @@ export function fetchPv(pv) {
export function createArticle(data) {
return request({
url: '/article/create',
url: '/vue-element-admin/article/create',
method: 'post',
data
})
@@ -34,7 +34,7 @@ export function createArticle(data) {
export function updateArticle(data) {
return request({
url: '/article/update',
url: '/vue-element-admin/article/update',
method: 'post',
data
})

View File

@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function searchUser(name) {
return request({
url: '/search/user',
url: '/vue-element-admin/search/user',
method: 'get',
params: { name }
})
@@ -10,7 +10,7 @@ export function searchUser(name) {
export function transactionList(query) {
return request({
url: '/transaction/list',
url: '/vue-element-admin/transaction/list',
method: 'get',
params: query
})

View File

@@ -2,21 +2,21 @@ import request from '@/utils/request'
export function getRoutes() {
return request({
url: '/routes',
url: '/vue-element-admin/routes',
method: 'get'
})
}
export function getRoles() {
return request({
url: '/roles',
url: '/vue-element-admin/roles',
method: 'get'
})
}
export function addRole(data) {
return request({
url: '/role',
url: '/vue-element-admin/role',
method: 'post',
data
})
@@ -24,7 +24,7 @@ export function addRole(data) {
export function updateRole(id, data) {
return request({
url: `/role/${id}`,
url: `/vue-element-admin/role/${id}`,
method: 'put',
data
})
@@ -32,7 +32,7 @@ export function updateRole(id, data) {
export function deleteRole(id) {
return request({
url: `/role/${id}`,
url: `/vue-element-admin/role/${id}`,
method: 'delete'
})
}

View File

@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function login(data) {
return request({
url: '/user/login',
url: '/vue-element-admin/user/login',
method: 'post',
data
})
@@ -10,7 +10,7 @@ export function login(data) {
export function getInfo(token) {
return request({
url: '/user/info',
url: '/vue-element-admin/user/info',
method: 'get',
params: { token }
})
@@ -18,7 +18,7 @@ export function getInfo(token) {
export function logout() {
return request({
url: '/user/logout',
url: '/vue-element-admin/user/logout',
method: 'post'
})
}

View File

@@ -3,32 +3,54 @@ import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHandler)
this.initListener()
},
activated() {
if (!this.$_resizeHandler) {
// avoid duplication init
this.initListener()
}
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
// when keep-alive chart activated, auto resize
this.resize()
},
beforeDestroy() {
window.removeEventListener('resize', this.__resizeHandler)
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
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()
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()
}
}
}

View File

@@ -12,7 +12,7 @@ import Editor from 'tui-editor'
import defaultOptions from './default-options'
export default {
name: 'MarddownEditor',
name: 'MarkdownEditor',
props: {
value: {
type: String,

View File

@@ -44,6 +44,7 @@ $t: .1s;
width: 250px;
position: relative;
z-index: 1;
height: auto!important;
&-title {
width: 100%;
display: block;
@@ -65,10 +66,12 @@ $t: .1s;
position: absolute;
width: 100%;
background: #e0e0e0;
color: #000;
line-height: 60px;
height: 60px;
cursor: pointer;
font-size: 20px;
font-size: 18px;
overflow: hidden;
opacity: 1;
transition: transform 0.28s ease;
&:hover {
@@ -90,7 +93,7 @@ $t: .1s;
.share-dropdown-menu-item {
@for $i from 1 through $n {
&:nth-of-type(#{$i}) {
transition-delay: ($n - $i)*$t;
transition-delay: ($n - $i)*$t;
transform: translate3d(0, ($i - 1)*60px, 0);
}
}

View File

@@ -1,7 +1,7 @@
<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 :href="iconName" />
<use :xlink:href="iconName" />
</svg>
</template>

View File

@@ -147,7 +147,11 @@ export default {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
}
},
// it will try to keep these URLs intact
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
convert_urls: false
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {

View File

@@ -36,8 +36,8 @@
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
<el-dropdown-item>Docs</el-dropdown-item>
</a>
<el-dropdown-item divided>
<span style="display:block;" @click="logout">Log Out</span>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">Log Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>

View File

@@ -1,7 +1,5 @@
<template>
<!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<component :is="type" v-bind="linkProps(to)">
<slot />
</component>
</template>
@@ -16,19 +14,28 @@ export default {
required: true
}
},
computed: {
isExternal() {
return isExternal(this.to)
},
type() {
if (this.isExternal) {
return 'a'
}
return 'router-link'
}
},
methods: {
linkProps(url) {
if (isExternal(url)) {
linkProps(to) {
if (this.isExternal) {
return {
is: 'a',
href: url,
href: to,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'router-link',
to: url
to: to
}
}
}

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="!item.hidden" class="menu-wrapper">
<div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">

View File

@@ -6,6 +6,7 @@ import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './styles/element-variables.scss'
import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
import '@/styles/index.scss' // global css
@@ -25,15 +26,16 @@ import * as filters from './filters' // global filters
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online! ! !
* please remove it before going online ! ! !
*/
import { mockXHR } from '../mock'
if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
size: Cookies.get('size') || 'medium', // set element-ui default size
locale: enLang // 如果使用中文,无需设置,请删除
})
// register global utility filters

View File

@@ -45,7 +45,7 @@ export const constantRoutes = [
hidden: true,
children: [
{
path: '/redirect/:path*',
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index')
}
]

View File

@@ -77,3 +77,8 @@
.el-range-editor.el-input__inner {
display: inline-flex !important;
}
// to fix el-date-picker css style
.el-range-separator {
box-sizing: content-box;
}

View File

@@ -6,7 +6,7 @@
/* theme color */
$--color-primary: #1890ff;
$--color-success: #13ce66;
$--color-warning: #FFBA00;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
// $--color-info: #1E1E1E;
@@ -17,10 +17,10 @@ $--button-font-weight: 400;
$--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
$--table-border:1px solid#dfe6ec;
$--table-border: 1px solid #dfe6ec;
/* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
$--font-path: "~element-ui/lib/theme-chalk/fonts";
@import "~element-ui/packages/theme-chalk/src/index";

View File

@@ -17,9 +17,17 @@ export function parseTime(time, cFormat) {
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}

View File

@@ -70,7 +70,7 @@ export default {
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Techology', max: 20000 },
{ name: 'Information Technology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }

View File

@@ -1,26 +1,10 @@
<template>
<div class="app-container documentation-container">
<a
class="document-btn"
target="_blank"
href="https://panjiachen.github.io/vue-element-admin-site/"
>Documentation</a>
<a
class="document-btn"
target="_blank"
href="https://github.com/PanJiaChen/vue-element-admin/"
>Github Repository</a>
<a
class="document-btn"
target="_blank"
href="https://panjiachen.gitee.io/vue-element-admin-site/zh/"
>国内文档</a>
<dropdown-menu :items="articleList" style="float:left;margin-left:50px;" title="系列文章" />
<a
class="document-btn"
target="_blank"
href="https://panjiachen.github.io/vue-element-admin-site/zh/job/"
>内推招聘</a>
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a>
<a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a>
<a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a>
<dropdown-menu class="document-btn" :items="articleList" title="系列文章" />
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/zh/job/">内推招聘</a>
</div>
</template>
@@ -53,8 +37,10 @@ export default {
margin: 50px;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
.document-btn {
margin-left: 50px;
flex-shrink: 0;
display: block;
cursor: pointer;
background: black;

View File

@@ -13,7 +13,7 @@
</a>
</div>
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
<el-table v-loading="listLoading" :data="list" element-loading-text="Loading..." border fit highlight-current-row>
<el-table-column align="center" label="Id" width="95">
<template slot-scope="scope">
{{ scope.$index }}

View File

@@ -1,74 +1,3 @@
const elementIcons = [
'info',
'error',
'success',
'warning',
'question',
'back',
'arrow-left',
'arrow-down',
'arrow-right',
'arrow-up',
'caret-left',
'caret-bottom',
'caret-top',
'caret-right',
'd-arrow-left',
'd-arrow-right',
'minus',
'plus',
'remove',
'circle-plus',
'remove-outline',
'circle-plus-outline',
'close',
'check',
'circle-close',
'circle-check',
'circle-close-outline',
'circle-check-outline',
'zoom-out',
'zoom-in',
'd-caret',
'sort',
'sort-down',
'sort-up',
'tickets',
'document',
'goods',
'sold-out',
'news',
'message',
'date',
'printer',
'time',
'bell',
'mobile-phone',
'service',
'view',
'menu',
'more',
'more-outline',
'star-on',
'star-off',
'location',
'location-outline',
'phone',
'phone-outline',
'picture',
'picture-outline',
'delete',
'search',
'edit',
'edit-outline',
'rank',
'refresh',
'share',
'setting',
'upload',
'upload2',
'download',
'loading'
]
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
export default elementIcons

View File

@@ -6,29 +6,33 @@
</aside>
<el-tabs type="border-card">
<el-tab-pane label="Icons">
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateIconCode(item) }}
</div>
<div class="icon-item">
<svg-icon :icon-class="item" class-name="disabled" />
<span>{{ item }}</span>
</div>
</el-tooltip>
<div class="grid">
<div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateIconCode(item) }}
</div>
<div class="icon-item">
<svg-icon :icon-class="item" class-name="disabled" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="Element-UI Icons">
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateElementIconCode(item) }}
</div>
<div class="icon-item">
<i :class="'el-icon-' + item" />
<span>{{ item }}</span>
</div>
</el-tooltip>
<div class="grid">
<div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)">
<el-tooltip placement="top">
<div slot="content">
{{ generateElementIconCode(item) }}
</div>
<div class="icon-item">
<i :class="'el-icon-' + item" />
<span>{{ item }}</span>
</div>
</el-tooltip>
</div>
</div>
</el-tab-pane>
</el-tabs>
@@ -67,6 +71,12 @@ export default {
margin: 10px 20px 0;
overflow: hidden;
.grid {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.icon-item {
margin: 20px;
height: 85px;

View File

@@ -138,17 +138,9 @@ export default {
// window.removeEventListener('storage', this.afterQRScan)
},
methods: {
checkCapslock({ shiftKey, key } = {}) {
if (key && key.length === 1) {
if (shiftKey && (key >= 'a' && key <= 'z') || !shiftKey && (key >= 'A' && key <= 'Z')) {
this.capsTooltip = true
} else {
this.capsTooltip = false
}
}
if (key === 'CapsLock' && this.capsTooltip === true) {
this.capsTooltip = false
}
checkCapslock(e) {
const { key } = e
this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
},
showPwd() {
if (this.passwordType === 'password') {

View File

@@ -26,17 +26,17 @@ export default {
},
methods: {
fetchData() {
import('./content.js').then(data => {
const { title } = data.default
document.title = title
this.article = data.default
setTimeout(() => {
this.fullscreenLoading = false
this.$nextTick(() => {
window.print()
})
}, 3000)
})
import('./content.js').then(data => {
const { title } = data.default
document.title = title
this.article = data.default
setTimeout(() => {
this.fullscreenLoading = false
this.$nextTick(() => {
window.print()
})
}, 3000)
})
}
}
}

View File

@@ -65,7 +65,7 @@ export default {
name: '',
email: '',
avatar: '',
roles: ''
role: ''
}
}
}
@@ -74,61 +74,61 @@ export default {
</script>
<style lang="scss" scoped>
.box-center {
margin: 0 auto;
display: table;
}
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
.text-muted {
color: #777;
}
.user-profile {
.user-name {
font-weight: bold;
}
.user-profile {
.user-name {
font-weight: bold;
}
.box-center {
padding-top: 10px;
}
.box-center {
padding-top: 10px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.box-social {
padding-top: 30px;
.box-social {
padding-top: 30px;
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-bio {
margin-top: 20px;
color: #606266;
.user-bio {
margin-top: 20px;
color: #606266;
span {
padding-left: 4px;
}
span {
padding-left: 4px;
}
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
</style>

View File

@@ -13,11 +13,11 @@
</template>
<script>
import tabPane from './components/TabPane'
import TabPane from './components/TabPane'
export default {
name: 'Tab',
components: { tabPane },
components: { TabPane },
data() {
return {
tabMapOptions: [

View File

@@ -36,13 +36,13 @@
@sort-change="sortChange"
>
<el-table-column label="ID" prop="id" sortable="custom" align="center" width="80" :class-name="getSortClass('id')">
<template slot-scope="scope">
<span>{{ scope.row.id }}</span>
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column label="Date" width="150px" align="center">
<template slot-scope="scope">
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
<template slot-scope="{row}">
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column label="Title" min-width="150px">
@@ -52,18 +52,18 @@
</template>
</el-table-column>
<el-table-column label="Author" width="110px" align="center">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
<template slot-scope="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column v-if="showReviewer" label="Reviewer" width="110px" align="center">
<template slot-scope="scope">
<span style="color:red;">{{ scope.row.reviewer }}</span>
<template slot-scope="{row}">
<span style="color:red;">{{ row.reviewer }}</span>
</template>
</el-table-column>
<el-table-column label="Imp" width="80px">
<template slot-scope="scope">
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" />
<template slot-scope="{row}">
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
</template>
</el-table-column>
<el-table-column label="Readings" align="center" width="95">
@@ -80,7 +80,7 @@
</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="230" class-name="small-padding fixed-width">
<template slot-scope="{row}">
<template slot-scope="{row,$index}">
<el-button type="primary" size="mini" @click="handleUpdate(row)">
Edit
</el-button>
@@ -90,7 +90,7 @@
<el-button v-if="row.status!='draft'" size="mini" @click="handleModifyStatus(row,'draft')">
Draft
</el-button>
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleModifyStatus(row,'deleted')">
<el-button v-if="row.status!='deleted'" size="mini" type="danger" @click="handleDelete(row,$index)">
Delete
</el-button>
</template>
@@ -319,13 +319,8 @@ export default {
const tempData = Object.assign({}, this.temp)
tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
updateArticle(tempData).then(() => {
for (const v of this.list) {
if (v.id === this.temp.id) {
const index = this.list.indexOf(v)
this.list.splice(index, 1, this.temp)
break
}
}
const index = this.list.findIndex(v => v.id === this.temp.id)
this.list.splice(index, 1, this.temp)
this.dialogFormVisible = false
this.$notify({
title: 'Success',
@@ -337,14 +332,13 @@ export default {
}
})
},
handleDelete(row) {
handleDelete(row, index) {
this.$notify({
title: 'Success',
message: 'Delete Successfully',
type: 'success',
duration: 2000
})
const index = this.list.indexOf(row)
this.list.splice(index, 1)
},
handleFetchPv(pv) {
@@ -358,7 +352,7 @@ export default {
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
const data = this.formatJson(filterVal, this.list)
const data = this.formatJson(filterVal)
excel.export_json_to_excel({
header: tHeader,
data,
@@ -367,8 +361,8 @@ export default {
this.downloadLoading = false
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
formatJson(filterVal) {
return this.list.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
@@ -378,11 +372,7 @@ export default {
},
getSortClass: function(key) {
const sort = this.listQuery.sort
return sort === `+${key}`
? 'ascending'
: sort === `-${key}`
? 'descending'
: ''
return sort === `+${key}` ? 'ascending' : 'descending'
}
}
}

View File

@@ -3,38 +3,38 @@
<!-- Note that row-key is necessary to get a correct row order. -->
<el-table ref="dragTable" v-loading="listLoading" :data="list" row-key="id" border fit highlight-current-row style="width: 100%">
<el-table-column align="center" label="ID" width="65">
<template slot-scope="scope">
<span>{{ scope.row.id }}</span>
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<template slot-scope="scope">
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
<template slot-scope="{row}">
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<template slot-scope="scope">
<span>{{ scope.row.title }}</span>
<template slot-scope="{row}">
<span>{{ row.title }}</span>
</template>
</el-table-column>
<el-table-column width="110px" align="center" label="Author">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
<template slot-scope="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column width="100px" label="Importance">
<template slot-scope="scope">
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="icon-star" />
<template slot-scope="{row}">
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="icon-star" />
</template>
</el-table-column>
<el-table-column align="center" label="Readings" width="95">
<template slot-scope="scope">
<span>{{ scope.row.pageviews }}</span>
<template slot-scope="{row}">
<span>{{ row.pageviews }}</span>
</template>
</el-table-column>

View File

@@ -2,26 +2,26 @@
<div class="app-container">
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
<el-table-column align="center" label="ID" width="80">
<template slot-scope="scope">
<span>{{ scope.row.id }}</span>
<template slot-scope="{row}">
<span>{{ row.id }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<template slot-scope="scope">
<span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
<template slot-scope="{row}">
<span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column width="120px" align="center" label="Author">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
<template slot-scope="{row}">
<span>{{ row.author }}</span>
</template>
</el-table-column>
<el-table-column width="100px" label="Importance">
<template slot-scope="scope">
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" class="meta-item__icon" />
<template slot-scope="{row}">
<svg-icon v-for="n in + row.importance" :key="n" icon-class="star" class="meta-item__icon" />
</template>
</el-table-column>

View File

@@ -4,6 +4,11 @@ describe('Utils:parseTime', () => {
it('timestamp', () => {
expect(parseTime(d)).toBe('2018-07-13 17:54:01')
})
it('timestamp string', () => {
expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01')
})
it('ten digits timestamp', () => {
expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
})

View File

@@ -36,18 +36,7 @@ module.exports = {
warnings: false,
errors: true
},
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://127.0.0.1:${port}/mock`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
after: require('./mock/mock-server.js')
before: require('./mock/mock-server.js')
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
@@ -91,12 +80,6 @@ module.exports = {
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config
.when(process.env.NODE_ENV !== 'development',
config => {