全局lint优化

This commit is contained in:
Pan 2017-08-22 15:43:34 +08:00 committed by 花裤衩
parent b8ecda19d8
commit 551e911eb4
104 changed files with 3487 additions and 3672 deletions

View File

@ -6,7 +6,8 @@ module.exports = {
}, },
env: { env: {
browser: true, browser: true,
node: true node: true,
es6: true,
}, },
extends: 'eslint:recommended', extends: 'eslint:recommended',
// required to lint *.vue files // required to lint *.vue files
@ -22,297 +23,122 @@ module.exports = {
} }
}, },
// add your custom rules here // add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
'rules': { 'rules': {
// don't require .vue extension when importing 'accessor-pairs': 2,
// 'import/extensions': ['error', 'always', { 'arrow-spacing': [2, { 'before': true, 'after': true }],
// 'js': 'never', 'block-spacing': [2, 'always'],
// 'vue': 'never' 'brace-style': [2, '1tbs', { 'allowSingleLine': true }],
// }], 'camelcase': [0, { 'properties': 'always' }],
// allow debugger during development 'comma-dangle': [2, 'never'],
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 'comma-spacing': [2, { 'before': false, 'after': true }],
/* 'comma-style': [2, 'last'],
* Possible Errors 'constructor-super': 2,
*/ 'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
// disallow unnecessary parentheses 'eol-last': 2,
'no-extra-parens': ['error', 'all', {'nestedBinaryExpressions': false}], 'eqeqeq': [2, 'allow-null'],
'generator-star-spacing': [2, { 'before': true, 'after': true }],
// disallow negating the left operand of relational operators 'handle-callback-err': [2, '^(err|error)$' ],
'no-unsafe-negation': 'error', 'indent': [2, 2, { 'SwitchCase': 1 }],
'jsx-quotes': [2, 'prefer-single'],
// enforce valid JSDoc comments 'key-spacing': [2, { 'beforeColon': false, 'afterColon': true }],
'valid-jsdoc': 'off', 'keyword-spacing': [2, { 'before': true, 'after': true }],
'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
/* 'new-parens': 2,
* Best Practices 'no-array-constructor': 2,
*/ 'no-caller': 2,
// enforce return statements in callbacks of array methods
'array-callback-return': 'error',
// enforce consistent brace style for all control statements
curly: ['error', 'multi-line'],
// enforce consistent newlines before and after dots
'dot-location': ['error', 'property'],
// enforce dot notation whenever possible
'dot-notation': 'error',
// require the use of === and !==
'eqeqeq': ['error', 'smart'],
// disallow the use of arguments.caller or arguments.callee
'no-caller': 'error',
// disallow empty functions
'no-empty-function': 'error',
// disallow unnecessary calls to .bind()
'no-extra-bind': 'error',
// disallow unnecessary labels
'no-extra-label': 'error',
// disallow leading or trailing decimal points in numeric literals
'no-floating-decimal': 'error',
// disallow assignments to native objects or read-only global variables
'no-global-assign': 'error',
// disallow the use of eval()-like methods
'no-implied-eval': 'error',
// disallow the use of the __iterator__ property
'no-iterator': 'error',
// disallow unnecessary nested blocks
'no-lone-blocks': 'error',
// disallow multiple spaces
'no-multi-spaces': 'error',
// disallow new operators with the String, Number, and Boolean objects
'no-new-wrappers': 'error',
// disallow octal escape sequences in string literals
'no-octal-escape': 'error',
// disallow the use of the __proto__ property
'no-proto': 'error',
// disallow comparisons where both sides are exactly the same
'no-self-compare': 'error',
// disallow throwing literals as exceptions
'no-throw-literal': 'error',
// disallow unused expressions
'no-unused-expressions': 'error',
// disallow unnecessary calls to .call() and .apply()
'no-useless-call': 'error',
// disallow unnecessary concatenation of literals or template literals
'no-useless-concat': 'error',
// disallow unnecessary escape characters
'no-useless-escape': 'error',
// disallow void operators
'no-void': 'error',
// require parentheses around immediate function invocations
'wrap-iife': 'error',
// require or disallow “Yoda” conditions
yoda: 'error',
/*
* Variables
*/
// disallow labels that share a name with a variable
'no-label-var': 'error',
// disallow initializing variables to undefined
'no-undef-init': 'error',
'no-undef': 'off',
// disallow the use of variables before they are defined
'no-use-before-define': 'error',
/*
* Node.js and CommonJS
*/
// disallow new operators with calls to require
'no-new-require': 'error',
/*
* Stylistic Issues
*/
// enforce consistent spacing inside array brackets
'array-bracket-spacing': 'error',
// enforce consistent spacing inside single-line blocks
'block-spacing': 'error',
// enforce consistent brace style for blocks
'brace-style': ['error', '1tbs', {'allowSingleLine': true}],
// require or disallow trailing commas
'comma-dangle': 'error',
// enforce consistent spacing before and after commas
'comma-spacing': 'error',
// enforce consistent comma style
'comma-style': 'error',
// enforce consistent spacing inside computed property brackets
'computed-property-spacing': 'error',
// require or disallow spacing between function identifiers and their invocations
'func-call-spacing': 'error',
// enforce consistent indentation
indent: ['error', 2, {SwitchCase: 1}],
// enforce the consistent use of either double or single quotes in JSX attributes
'jsx-quotes': 'error',
// enforce consistent spacing between keys and values in object literal properties
'key-spacing': 'error',
// enforce consistent spacing before and after keywords
'keyword-spacing': 'error',
// enforce consistent linebreak style
'linebreak-style': 'error',
// require or disallow newlines around directives
'lines-around-directive': 'error',
// require constructor names to begin with a capital letter
'new-cap': 'off',
// require parentheses when invoking a constructor with no arguments
'new-parens': 'error',
// disallow Array constructors
'no-array-constructor': 'error',
// disallow Object constructors
'no-new-object': 'error',
// disallow trailing whitespace at the end of lines
'no-trailing-spaces': 'error',
// disallow ternary operators when simpler alternatives exist
'no-unneeded-ternary': 'error',
// disallow whitespace before properties
'no-whitespace-before-property': 'error',
// enforce consistent spacing inside braces
'object-curly-spacing': ['error', 'always'],
// require or disallow padding within blocks
'padded-blocks': ['error', 'never'],
// require quotes around object literal property names
'quote-props': ['error', 'as-needed'],
// enforce the consistent use of either backticks, double, or single quotes
quotes: ['error', 'single'],
// enforce consistent spacing before and after semicolons
'semi-spacing': 'error',
// require or disallow semicolons instead of ASI
// semi: ['error', 'never'],
// enforce consistent spacing before blocks
'space-before-blocks': 'error',
'no-console': 'off', 'no-console': 'off',
'no-class-assign': 2,
// enforce consistent spacing before function definition opening parenthesis 'no-cond-assign': 2,
'space-before-function-paren': ['error', 'never'], 'no-const-assign': 2,
'no-control-regex': 2,
// enforce consistent spacing inside parentheses 'no-delete-var': 2,
'space-in-parens': 'error', 'no-dupe-args': 2,
'no-dupe-class-members': 2,
// require spacing around infix operators 'no-dupe-keys': 2,
'space-infix-ops': 'error', 'no-duplicate-case': 2,
'no-empty-character-class': 2,
// enforce consistent spacing before or after unary operators 'no-empty-pattern': 2,
'space-unary-ops': 'error', 'no-eval': 2,
'no-ex-assign': 2,
// enforce consistent spacing after the // or /* in a comment 'no-extend-native': 2,
'spaced-comment': 'error', 'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
// require or disallow Unicode byte order mark (BOM) 'no-extra-parens': [2, 'functions'],
'unicode-bom': 'error', 'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
/* 'no-implied-eval': 2,
* ECMAScript 6 'no-inner-declarations': [2, 'functions'],
*/ 'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
// require braces around arrow function bodies 'no-iterator': 2,
'arrow-body-style': 'error', 'no-label-var': 2,
'no-labels': [2, { 'allowLoop': false, 'allowSwitch': false }],
// require parentheses around arrow function arguments 'no-lone-blocks': 2,
'arrow-parens': ['error', 'as-needed'], 'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
// enforce consistent spacing before and after the arrow in arrow functions 'no-multi-str': 2,
'arrow-spacing': 'error', 'no-multiple-empty-lines': [2, { 'max': 1 }],
'no-native-reassign': 2,
// enforce consistent spacing around * operators in generator functions 'no-negated-in-lhs': 2,
'generator-star-spacing': ['error', 'after'], 'no-new-object': 2,
'no-new-require': 2,
// disallow duplicate module imports 'no-new-symbol': 2,
'no-duplicate-imports': 'error', 'no-new-wrappers': 2,
'no-obj-calls': 2,
// disallow unnecessary computed property keys in object literals 'no-octal': 2,
'no-useless-computed-key': 'error', 'no-octal-escape': 2,
'no-path-concat': 2,
// disallow unnecessary constructors 'no-proto': 2,
'no-useless-constructor': 'error', 'no-redeclare': 2,
'no-regex-spaces': 2,
// disallow renaming import, export, and destructured assignments to the same name 'no-return-assign': [2, 'except-parens'],
'no-useless-rename': 'error', 'no-self-assign': 2,
'no-self-compare': 2,
// require let or const instead of var 'no-sequences': 2,
'no-var': 'error', 'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
// require or disallow method and property shorthand syntax for object literals 'no-sparse-arrays': 2,
'object-shorthand': 'error', 'no-this-before-super': 2,
'no-throw-literal': 2,
// require arrow functions as callbacks 'no-trailing-spaces': 2,
'prefer-arrow-callback': 'error', 'no-undef': 2,
'no-undef-init': 2,
// require const declarations for variables that are never reassigned after declared 'no-unexpected-multiline': 2,
'prefer-const': 'error', 'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, { 'defaultAssignment': false }],
// disallow parseInt() in favor of binary, octal, and hexadecimal literals 'no-unreachable': 2,
'prefer-numeric-literals': 'error', 'no-unsafe-finally': 2,
'no-unused-vars': [2, { 'vars': 'all', 'args': 'none' }],
// require rest parameters instead of arguments 'no-useless-call': 2,
'prefer-rest-params': 'error', 'no-useless-computed-key': 2,
'no-useless-constructor': 2,
// require spread operators instead of .apply() 'no-useless-escape': 0,
'prefer-spread': 'error', 'no-whitespace-before-property': 2,
'no-with': 2,
// enforce spacing between rest and spread operators and their expressions 'one-var': [2, { 'initialized': 'never' }],
'rest-spread-spacing': 'error', 'operator-linebreak': [2, 'after', { 'overrides': { '?': 'before', ':': 'before' } }],
'padded-blocks': [2, 'never'],
// require or disallow spacing around embedded expressions of template strings 'quotes': [2, 'single', { 'avoidEscape': true, 'allowTemplateLiterals': true }],
'template-curly-spacing': 'error', 'semi': [2, 'never'],
'semi-spacing': [2, { 'before': false, 'after': true }],
// require or disallow spacing around the * in yield* expressions 'space-before-blocks': [2, 'always'],
'yield-star-spacing': 'error' 'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, { 'words': true, 'nonwords': false }],
'spaced-comment': [2, 'always', { 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] }],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', { objectsInObjects: false }],
'array-bracket-spacing': [2, 'never']
} }
} }

View File

@ -37,15 +37,15 @@ module.exports = {
}, },
module: { module: {
rules: [ rules: [
// { {
// test: /\.(js|vue)$/, test: /\.(js|vue)$/,
// loader: 'eslint-loader', loader: 'eslint-loader',
// enforce: "pre", enforce: "pre",
// include: [resolve('src'), resolve('test')], include: [resolve('src'), resolve('test')],
// options: { options: {
// formatter: require('eslint-friendly-formatter') formatter: require('eslint-friendly-formatter')
// } }
// }, },
{ {
test: /\.vue$/, test: /\.vue$/,
loader: 'vue-loader', loader: 'vue-loader',

View File

@ -11,6 +11,6 @@
</script> </script>
<style lang="scss"> <style lang="scss">
@import '~normalize.css/normalize.css';// normalize.css @import '~normalize.css/normalize.css';// normalize.css
@import './styles/index.scss'; // css @import './styles/index.scss'; // css
</style> </style>

View File

@ -1,16 +1,16 @@
import fetch from 'utils/fetch'; import fetch from 'utils/fetch'
export function getList() { export function getList () {
return fetch({ return fetch({
url: '/article/list', url: '/article/list',
method: 'get' method: 'get'
}); })
} }
export function getArticle() { export function getArticle () {
return fetch({ return fetch({
url: '/article/detail', url: '/article/detail',
method: 'get' method: 'get'
}); })
} }

View File

@ -1,17 +1,17 @@
import fetch from 'utils/fetch'; import fetch from 'utils/fetch'
export function fetchList(query) { export function fetchList (query) {
return fetch({ return fetch({
url: '/article_table/list', url: '/article_table/list',
method: 'get', method: 'get',
params: query params: query
}); })
} }
export function fetchPv(pv) { export function fetchPv (pv) {
return fetch({ return fetch({
url: '/article_table/pv', url: '/article_table/pv',
method: 'get', method: 'get',
params: { pv } params: { pv }
}); })
} }

View File

@ -1,6 +1,6 @@
import fetch from 'utils/fetch' import fetch from 'utils/fetch'
export function loginByUsername(username, password) { export function loginByUsername (username, password) {
const data = { const data = {
username, username,
password password
@ -12,14 +12,14 @@ export function loginByUsername(username, password) {
}) })
} }
export function logout() { export function logout () {
return fetch({ return fetch({
url: '/login/logout', url: '/login/logout',
method: 'post' method: 'post'
}) })
} }
export function getInfo(token) { export function getInfo (token) {
return fetch({ return fetch({
url: '/user/info', url: '/user/info',
method: 'get', method: 'get',

View File

@ -1,8 +1,8 @@
import fetch from 'utils/fetch'; import fetch from 'utils/fetch'
export function getToken() { export function getToken () {
return fetch({ return fetch({
url: '/qiniu/upload/token', // 假地址 自行替换 url: '/qiniu/upload/token', // 假地址 自行替换
method: 'get' method: 'get'
}); })
} }

View File

@ -1,9 +1,9 @@
import fetch from 'utils/fetch'; import fetch from 'utils/fetch'
export function userSearch(name) { export function userSearch (name) {
return fetch({ return fetch({
url: '/search/user', url: '/search/user',
method: 'get', method: 'get',
params: { name } params: { name }
}); })
} }

View File

@ -12,73 +12,73 @@
</template> </template>
<script> <script>
export default { export default {
name: 'BackToTop', name: 'BackToTop',
props: { props: {
visibilityHeight: { visibilityHeight: {
type: Number, type: Number,
default: 400 default: 400
}, },
backPosition: { backPosition: {
type: Number, type: Number,
default: 0 default: 0
}, },
customStyle: { customStyle: {
type: Object, type: Object,
default: { default: {
right: '50px', right: '50px',
bottom: '50px', bottom: '50px',
width: '40px', width: '40px',
height: '40px', height: '40px',
'border-radius': '4px', 'border-radius': '4px',
'line-height': '45px', 'line-height': '45px',
background: '#e7eaf1' background: '#e7eaf1'
}
},
transitionName: {
type: String,
default: 'fade'
}
},
data() {
return {
visible: false,
interval: null
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll)
if (this.interval) {
clearInterval(this.interval)
}
},
methods: {
handleScroll() {
this.visible = window.pageYOffset > this.visibilityHeight
},
backToTop() {
const start = window.pageYOffset
let i = 0
this.interval = setInterval(() => {
const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500))
if (next <= this.backPosition) {
window.scrollTo(0, this.backPosition)
clearInterval(this.interval)
} else {
window.scrollTo(0, next)
} }
}, i++
transitionName: { }, 16.7)
type: String,
default: 'fade'
}
}, },
data() { easeInOutQuad(t, b, c, d) {
return { if ((t /= d / 2) < 1) return c / 2 * t * t + b
visible: false, return -c / 2 * (--t * (t - 2) - 1) + b
interval: null
}
},
mounted() {
window.addEventListener('scroll', this.handleScroll);
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll);
if (this.interval) {
clearInterval(this.interval);
}
},
methods: {
handleScroll() {
this.visible = window.pageYOffset > this.visibilityHeight;
},
backToTop() {
const start = window.pageYOffset;
let i = 0;
this.interval = setInterval(() => {
const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500));
if (next <= this.backPosition) {
window.scrollTo(0, this.backPosition);
clearInterval(this.interval)
} else {
window.scrollTo(0, next);
}
i++;
}, 16.7)
},
easeInOutQuad(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * (--t * (t - 2) - 1) + b;
}
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -3,111 +3,111 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
}, },
id: { id: {
type: String, type: String,
default: 'chart' default: 'chart'
}, },
width: { width: {
type: String, type: String,
default: '200px' default: '200px'
}, },
height: { height: {
type: String, type: String,
default: '200px' default: '200px'
} }
}, },
data() { data() {
return { return {
chart: null chart: null
}; }
}, },
mounted() { mounted() {
this.initChart(); this.initChart()
}, },
beforeDestroy() { beforeDestroy() {
if (!this.chart) { if (!this.chart) {
return return
} }
this.chart.dispose(); this.chart.dispose()
this.chart = null; this.chart = null
}, },
methods: { methods: {
initChart() { initChart() {
this.chart = echarts.init(document.getElementById(this.id)); this.chart = echarts.init(document.getElementById(this.id))
const xAxisData = []; const xAxisData = []
const data = []; const data = []
for (let i = 0; i < 30; i++) { for (let i = 0; i < 30; i++) {
xAxisData.push(i + '号'); xAxisData.push(i + '号')
data.push(Math.round(Math.random() * 2 + 3)) data.push(Math.round(Math.random() * 2 + 3))
} }
this.chart.setOption( this.chart.setOption(
{ {
backgroundColor: '#08263a', backgroundColor: '#08263a',
tooltip: { tooltip: {
trigger: 'axis' trigger: 'axis'
}, },
xAxis: { xAxis: {
show: false, show: false,
data: xAxisData data: xAxisData
}, },
visualMap: { visualMap: {
show: false, show: false,
min: 0, min: 0,
max: 50, max: 50,
dimension: 0, dimension: 0,
inRange: { inRange: {
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055'] color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
} }
}, },
yAxis: { yAxis: {
axisLine: { axisLine: {
show: false show: false
}, },
axisLabel: { axisLabel: {
textStyle: { textStyle: {
color: '#4a657a' color: '#4a657a'
} }
}, },
splitLine: { splitLine: {
show: true, show: true,
lineStyle: { lineStyle: {
color: '#08263f' color: '#08263f'
} }
}, },
axisTick: {} axisTick: {}
}, },
series: [{ series: [{
type: 'bar', type: 'bar',
data, data,
name: '撸文数', name: '撸文数',
itemStyle: { itemStyle: {
normal: { normal: {
barBorderRadius: 5, barBorderRadius: 5,
shadowBlur: 10, shadowBlur: 10,
shadowColor: '#111' shadowColor: '#111'
} }
}, },
animationEasing: 'elasticOut', animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut', animationEasingUpdate: 'elasticOut',
animationDelay(idx) { animationDelay(idx) {
return idx * 20; return idx * 20
}, },
animationDelayUpdate(idx) { animationDelayUpdate(idx) {
return idx * 20; return idx * 20
} }
}] }]
}) })
} }
} }
} }
</script> </script>

View File

@ -3,148 +3,148 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
}, },
data() { id: {
return { type: String,
chart: null default: 'chart'
};
}, },
mounted() { width: {
this.initChart(); type: String,
default: '200px'
}, },
beforeDestroy() { height: {
if (!this.chart) { type: String,
return default: '200px'
} }
this.chart.dispose(); },
this.chart = null; data() {
}, return {
methods: { chart: null
initChart() { }
this.chart = echarts.init(document.getElementById(this.id)); },
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 xAxisData = []
const data = []; const data = []
const data2 = []; const data2 = []
for (let i = 0; i < 50; i++) { for (let i = 0; i < 50; i++) {
xAxisData.push(i); xAxisData.push(i)
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5); data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3); data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
} }
this.chart.setOption( this.chart.setOption(
{ {
backgroundColor: '#08263a', backgroundColor: '#08263a',
xAxis: [{ xAxis: [{
show: false, show: false,
data: xAxisData data: xAxisData
}, { }, {
show: false, show: false,
data: xAxisData data: xAxisData
}], }],
visualMap: { visualMap: {
show: false, show: false,
min: 0, min: 0,
max: 50, max: 50,
dimension: 0, dimension: 0,
inRange: { inRange: {
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055'] 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;
} }
}) },
} 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> </script>

View File

@ -3,220 +3,220 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
}, },
data() { id: {
return { type: String,
chart: null default: 'chart'
};
}, },
mounted() { width: {
this.initChart(); type: String,
default: '200px'
}, },
beforeDestroy() { height: {
if (!this.chart) { type: String,
return default: '200px'
}
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id));
this.chart.setOption({
backgroundColor: '#394056',
title: {
text: '请求数',
textStyle: {
fontWeight: 'normal',
fontSize: 16,
color: '#F1F1F3'
},
left: '6%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#57617B'
}
}
},
legend: {
icon: 'rect',
itemWidth: 14,
itemHeight: 5,
itemGap: 13,
data: ['移动', '电信', '联通'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#F1F1F3'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
}],
yAxis: [{
type: 'value',
name: '单位(%',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: '#57617B'
}
}
}],
series: [{
name: '移动',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(137, 189, 27, 0.3)'
}, {
offset: 0.8,
color: 'rgba(137, 189, 27, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(137,189,27)',
borderColor: 'rgba(137,189,2,0.27)',
borderWidth: 12
}
},
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
}, {
name: '电信',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 136, 212, 0.3)'
}, {
offset: 0.8,
color: 'rgba(0, 136, 212, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(0,136,212)',
borderColor: 'rgba(0,136,212,0.2)',
borderWidth: 12
}
},
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
}, {
name: '联通',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(219, 50, 51, 0.3)'
}, {
offset: 0.8,
color: 'rgba(219, 50, 51, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(219,50,51)',
borderColor: 'rgba(219,50,51,0.2)',
borderWidth: 12
}
},
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
}]
})
}
} }
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
this.chart.setOption({
backgroundColor: '#394056',
title: {
text: '请求数',
textStyle: {
fontWeight: 'normal',
fontSize: 16,
color: '#F1F1F3'
},
left: '6%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#57617B'
}
}
},
legend: {
icon: 'rect',
itemWidth: 14,
itemHeight: 5,
itemGap: 13,
data: ['移动', '电信', '联通'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#F1F1F3'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
}],
yAxis: [{
type: 'value',
name: '单位(%',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: '#57617B'
}
}
}],
series: [{
name: '移动',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(137, 189, 27, 0.3)'
}, {
offset: 0.8,
color: 'rgba(137, 189, 27, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(137,189,27)',
borderColor: 'rgba(137,189,2,0.27)',
borderWidth: 12
}
},
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
}, {
name: '电信',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 136, 212, 0.3)'
}, {
offset: 0.8,
color: 'rgba(0, 136, 212, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(0,136,212)',
borderColor: 'rgba(0,136,212,0.2)',
borderWidth: 12
}
},
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
}, {
name: '联通',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(219, 50, 51, 0.3)'
}, {
offset: 0.8,
color: 'rgba(219, 50, 51, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(219,50,51)',
borderColor: 'rgba(219,50,51,0.2)',
borderWidth: 12
}
},
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
}]
})
}
}
} }
</script> </script>

View File

@ -3,266 +3,265 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
}, },
data() { id: {
return { type: String,
chart: null default: 'chart'
};
}, },
mounted() { width: {
this.initChart(); type: String,
this.chart = null; default: '200px'
}, },
beforeDestroy() { height: {
if (!this.chart) { type: String,
return default: '200px'
} }
this.chart.dispose(); },
this.chart = null; data() {
}, return {
methods: { chart: null
initChart() { }
this.chart = echarts.init(document.getElementById(this.id)); },
const xData = (function() { mounted() {
const data = []; this.initChart()
for (let i = 1; i < 13; i++) { this.chart = null
data.push(i + '月份'); },
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
const xData = (function() {
const data = []
for (let i = 1; i < 13; i++) {
data.push(i + '月份')
}
return data
}())
this.chart.setOption({
backgroundColor: '#344b58',
title: {
text: '统计',
x: '4%',
textStyle: {
color: '#fff',
fontSize: '22'
},
subtextStyle: {
color: '#90979c',
fontSize: '16'
} }
return data; },
}()); tooltip: {
this.chart.setOption({ trigger: 'axis',
backgroundColor: '#344b58', axisPointer: {
title: {
text: '统计',
x: '4%',
textStyle: {
color: '#fff',
fontSize: '22'
},
subtextStyle: {
color: '#90979c',
fontSize: '16'
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
textStyle: {
color: '#fff'
}
}
},
grid: {
borderWidth: 0,
top: 110,
bottom: 95,
textStyle: { textStyle: {
color: '#fff' color: '#fff'
} }
},
legend: {
x: '15%',
top: '10%',
textStyle: {
color: '#90979c'
},
data: ['女', '男', '平均']
},
calculable: true,
xAxis: [{
type: 'category',
axisLine: {
lineStyle: {
color: '#90979c'
}
},
splitLine: {
show: false
},
axisTick: {
show: false
},
splitArea: {
show: false
},
axisLabel: {
interval: 0
},
data: xData
}],
yAxis: [{
type: 'value',
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: '#90979c'
}
},
axisTick: {
show: false
},
axisLabel: {
interval: 0
},
splitArea: {
show: false
}
}],
dataZoom: [{
show: true,
height: 30,
xAxisIndex: [
0
],
bottom: 30,
start: 10,
end: 80,
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
handleSize: '110%',
handleStyle: {
color: '#d3dee5'
},
textStyle: {
color: '#fff' },
borderColor: '#90979c'
}, {
type: 'inside',
show: true,
height: 15,
start: 1,
end: 35
}],
series: [{
name: '女',
type: 'bar',
stack: '总量',
barMaxWidth: 35,
barGap: '10%',
itemStyle: {
normal: {
color: 'rgba(255,144,128,1)',
label: {
show: true,
textStyle: {
color: '#fff'
},
position: 'insideTop',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
709,
1917,
2455,
2610,
1719,
1433,
1544,
3285,
5208,
3372,
2484,
4078
]
},
{
name: '男',
type: 'bar',
stack: '总量',
itemStyle: {
normal: {
color: 'rgba(0,191,183,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
327,
1776,
507,
1200,
800,
482,
204,
1390,
1001,
951,
381,
220
]
}, {
name: '平均',
type: 'line',
stack: '总量',
symbolSize: 10,
symbol: 'circle',
itemStyle: {
normal: {
color: 'rgba(252,230,48,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : '';
}
}
}
},
data: [
1036,
3693,
2962,
3810,
2519,
1915,
1748,
4675,
6209,
4323,
2865,
4298
]
} }
},
grid: {
borderWidth: 0,
top: 110,
bottom: 95,
textStyle: {
color: '#fff'
}
},
legend: {
x: '15%',
top: '10%',
textStyle: {
color: '#90979c'
},
data: ['女', '男', '平均']
},
calculable: true,
xAxis: [{
type: 'category',
axisLine: {
lineStyle: {
color: '#90979c'
}
},
splitLine: {
show: false
},
axisTick: {
show: false
},
splitArea: {
show: false
},
axisLabel: {
interval: 0
},
data: xData
}],
yAxis: [{
type: 'value',
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: '#90979c'
}
},
axisTick: {
show: false
},
axisLabel: {
interval: 0
},
splitArea: {
show: false
}
}],
dataZoom: [{
show: true,
height: 30,
xAxisIndex: [
0
],
bottom: 30,
start: 10,
end: 80,
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
handleSize: '110%',
handleStyle: {
color: '#d3dee5'
},
textStyle: {
color: '#fff' },
borderColor: '#90979c'
}, {
type: 'inside',
show: true,
height: 15,
start: 1,
end: 35
}],
series: [{
name: '女',
type: 'bar',
stack: '总量',
barMaxWidth: 35,
barGap: '10%',
itemStyle: {
normal: {
color: 'rgba(255,144,128,1)',
label: {
show: true,
textStyle: {
color: '#fff'
},
position: 'insideTop',
formatter(p) {
return p.value > 0 ? p.value : ''
}
}
}
},
data: [
709,
1917,
2455,
2610,
1719,
1433,
1544,
3285,
5208,
3372,
2484,
4078
] ]
}) },
}
{
name: '男',
type: 'bar',
stack: '总量',
itemStyle: {
normal: {
color: 'rgba(0,191,183,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : ''
}
}
}
},
data: [
327,
1776,
507,
1200,
800,
482,
204,
1390,
1001,
951,
381,
220
]
}, {
name: '平均',
type: 'line',
stack: '总量',
symbolSize: 10,
symbol: 'circle',
itemStyle: {
normal: {
color: 'rgba(252,230,48,1)',
barBorderRadius: 0,
label: {
show: true,
position: 'top',
formatter(p) {
return p.value > 0 ? p.value : ''
}
}
}
},
data: [
1036,
3693,
2962,
3810,
2519,
1915,
1748,
4675,
6209,
4323,
2865,
4298
]
}
]
})
} }
} }
}
</script> </script>

View File

@ -5,59 +5,59 @@
</template> </template>
<script> <script>
import Dropzone from 'dropzone'; import Dropzone from 'dropzone'
import 'dropzone/dist/dropzone.css'; import 'dropzone/dist/dropzone.css'
// import { getToken } from 'api/qiniu'; // import { getToken } from 'api/qiniu';
Dropzone.autoDiscover = false; Dropzone.autoDiscover = false
export default { export default {
data() { data() {
return { return {
dropzone: '', dropzone: '',
initOnce: true initOnce: true
} }
}, },
mounted() { mounted() {
const element = document.getElementById(this.id); const element = document.getElementById(this.id)
const vm = this; const vm = this
this.dropzone = new Dropzone(element, { this.dropzone = new Dropzone(element, {
clickable: this.clickable, clickable: this.clickable,
thumbnailWidth: this.thumbnailWidth, thumbnailWidth: this.thumbnailWidth,
thumbnailHeight: this.thumbnailHeight, thumbnailHeight: this.thumbnailHeight,
maxFiles: this.maxFiles, maxFiles: this.maxFiles,
maxFilesize: this.maxFilesize, maxFilesize: this.maxFilesize,
dictRemoveFile: 'Remove', dictRemoveFile: 'Remove',
addRemoveLinks: this.showRemoveLink, addRemoveLinks: this.showRemoveLink,
acceptedFiles: this.acceptedFiles, acceptedFiles: this.acceptedFiles,
autoProcessQueue: this.autoProcessQueue, autoProcessQueue: this.autoProcessQueue,
dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload', dictDefaultMessage: '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload',
dictMaxFilesExceeded: '只能一个图', dictMaxFilesExceeded: '只能一个图',
previewTemplate: '<div class="dz-preview dz-file-preview"> <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div> <div class="dz-details"><div class="dz-size"><span data-dz-size></span></div> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> <div class="dz-error-message"><span data-dz-errormessage></span></div> <div class="dz-success-mark"> <i class="material-icons">done</i> </div> <div class="dz-error-mark"><i class="material-icons">error</i></div></div>', previewTemplate: '<div class="dz-preview dz-file-preview"> <div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" ><img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail /></div> <div class="dz-details"><div class="dz-size"><span data-dz-size></span></div> <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div> <div class="dz-error-message"><span data-dz-errormessage></span></div> <div class="dz-success-mark"> <i class="material-icons">done</i> </div> <div class="dz-error-mark"><i class="material-icons">error</i></div></div>',
init() { init() {
const val = vm.defaultImg; const val = vm.defaultImg
if (!val) return; if (!val) return
if (Array.isArray(val)) { if (Array.isArray(val)) {
if (val.length === 0) return; if (val.length === 0) return
val.map((v, i) => { val.map((v, i) => {
const mockFile = { name: 'name' + i, size: 12345, url: v }; const mockFile = { name: 'name' + i, size: 12345, url: v }
this.options.addedfile.call(this, mockFile); this.options.addedfile.call(this, mockFile)
this.options.thumbnail.call(this, mockFile, v); this.options.thumbnail.call(this, mockFile, v)
mockFile.previewElement.classList.add('dz-success'); mockFile.previewElement.classList.add('dz-success')
mockFile.previewElement.classList.add('dz-complete'); mockFile.previewElement.classList.add('dz-complete')
vm.initOnce = false; vm.initOnce = false
return true; return true
}) })
} else { } else {
const mockFile = { name: 'name', size: 12345, url: val }; const mockFile = { name: 'name', size: 12345, url: val }
this.options.addedfile.call(this, mockFile); this.options.addedfile.call(this, mockFile)
this.options.thumbnail.call(this, mockFile, val); this.options.thumbnail.call(this, mockFile, val)
mockFile.previewElement.classList.add('dz-success'); mockFile.previewElement.classList.add('dz-success')
mockFile.previewElement.classList.add('dz-complete'); mockFile.previewElement.classList.add('dz-complete')
vm.initOnce = false; vm.initOnce = false
} }
}, },
accept: (file, done) => { accept: (file, done) => {
/* 七牛*/ /* 七牛*/
// const token = this.$store.getters.token; // const token = this.$store.getters.token;
// getToken(token).then(response => { // getToken(token).then(response => {
@ -66,142 +66,140 @@
// file.url = response.data.qiniu_url; // file.url = response.data.qiniu_url;
// done(); // done();
// }) // })
done(); done()
}, },
sending: (file, xhr, formData) => { sending: (file, xhr, formData) => {
/* 七牛*/
console.log(file, xhr, formData)
// formData.append('token', file.token); // formData.append('token', file.token);
// formData.append('key', file.key); // formData.append('key', file.key);
vm.initOnce = false; vm.initOnce = false
}
});
if (this.couldPaste) {
document.addEventListener('paste', this.pasteImg)
} }
})
this.dropzone.on('success', file => { if (this.couldPaste) {
vm.$emit('dropzone-success', file, vm.dropzone.element) document.addEventListener('paste', this.pasteImg)
}); }
this.dropzone.on('addedfile', file => {
vm.$emit('dropzone-fileAdded', file)
});
this.dropzone.on('removedfile', file => {
vm.$emit('dropzone-removedFile', file)
});
this.dropzone.on('error', (file, error, xhr) => {
vm.$emit('dropzone-error', file, error, xhr)
});
this.dropzone.on('successmultiple', (file, error, xhr) => {
vm.$emit('dropzone-successmultiple', file, error, xhr)
});
},
methods: {
removeAllFiles() {
this.dropzone.removeAllFiles(true)
},
processQueue() {
this.dropzone.processQueue()
},
pasteImg(event) {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
if (items[0].kind === 'file') {
this.dropzone.addFile(items[0].getAsFile())
}
},
initImages(val) {
if (!val) return;
if (Array.isArray(val)) {
val.map((v, i) => {
const mockFile = { name: 'name' + i, size: 12345, url: v };
this.dropzone.options.addedfile.call(this.dropzone, mockFile);
this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v);
mockFile.previewElement.classList.add('dz-success');
mockFile.previewElement.classList.add('dz-complete');
return true
})
} else {
const mockFile = { name: 'name', size: 12345, url: val };
this.dropzone.options.addedfile.call(this.dropzone, mockFile);
this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val);
mockFile.previewElement.classList.add('dz-success');
mockFile.previewElement.classList.add('dz-complete');
}
}
this.dropzone.on('success', file => {
vm.$emit('dropzone-success', file, vm.dropzone.element)
})
this.dropzone.on('addedfile', file => {
vm.$emit('dropzone-fileAdded', file)
})
this.dropzone.on('removedfile', file => {
vm.$emit('dropzone-removedFile', file)
})
this.dropzone.on('error', (file, error, xhr) => {
vm.$emit('dropzone-error', file, error, xhr)
})
this.dropzone.on('successmultiple', (file, error, xhr) => {
vm.$emit('dropzone-successmultiple', file, error, xhr)
})
},
methods: {
removeAllFiles() {
this.dropzone.removeAllFiles(true)
}, },
destroyed() { processQueue() {
document.removeEventListener('paste', this.pasteImg); this.dropzone.processQueue()
this.dropzone.destroy();
}, },
watch: { pasteImg(event) {
defaultImg(val) { const items = (event.clipboardData || event.originalEvent.clipboardData).items
if (val.length === 0) { if (items[0].kind === 'file') {
this.initOnce = false; this.dropzone.addFile(items[0].getAsFile())
return;
}
if (!this.initOnce) return;
this.initImages(val);
this.initOnce = false;
} }
}, },
props: { initImages(val) {
id: { if (!val) return
type: String, if (Array.isArray(val)) {
required: true val.map((v, i) => {
}, const mockFile = { name: 'name' + i, size: 12345, url: v }
url: { this.dropzone.options.addedfile.call(this.dropzone, mockFile)
type: String, this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v)
required: true mockFile.previewElement.classList.add('dz-success')
}, mockFile.previewElement.classList.add('dz-complete')
clickable: { return true
type: Boolean, })
default: true } else {
}, const mockFile = { name: 'name', size: 12345, url: val }
defaultMsg: { this.dropzone.options.addedfile.call(this.dropzone, mockFile)
type: String, this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val)
default: '上传图片' mockFile.previewElement.classList.add('dz-success')
}, mockFile.previewElement.classList.add('dz-complete')
acceptedFiles: {
type: String
},
thumbnailHeight: {
type: Number,
default: 200
},
thumbnailWidth: {
type: Number,
default: 200
},
showRemoveLink: {
type: Boolean,
default: true
},
maxFilesize: {
type: Number,
default: 2
},
maxFiles: {
type: Number,
default: 3
},
autoProcessQueue: {
type: Boolean,
default: true
},
useCustomDropzoneOptions: {
type: Boolean,
default: false
},
defaultImg: {
default: false
},
couldPaste: {
default: false
} }
} }
},
destroyed() {
document.removeEventListener('paste', this.pasteImg)
this.dropzone.destroy()
},
watch: {
defaultImg(val) {
if (val.length === 0) {
this.initOnce = false
return
}
if (!this.initOnce) return
this.initImages(val)
this.initOnce = false
}
},
props: {
id: {
type: String,
required: true
},
url: {
type: String,
required: true
},
clickable: {
type: Boolean,
default: true
},
defaultMsg: {
type: String,
default: '上传图片'
},
acceptedFiles: {
type: String
},
thumbnailHeight: {
type: Number,
default: 200
},
thumbnailWidth: {
type: Number,
default: 200
},
showRemoveLink: {
type: Boolean,
default: true
},
maxFilesize: {
type: Number,
default: 2
},
maxFiles: {
type: Number,
default: 3
},
autoProcessQueue: {
type: Boolean,
default: true
},
useCustomDropzoneOptions: {
type: Boolean,
default: false
},
defaultImg: {
default: false
},
couldPaste: {
default: false
}
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -30,19 +30,19 @@
</template> </template>
<script> <script>
export default { export default {
name: 'errLog', name: 'errLog',
props: { props: {
logsList: { logsList: {
type: Array type: Array
} }
}, },
data() { data() {
return { return {
dialogTableVisible: false dialogTableVisible: false
}
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -13,19 +13,19 @@
</template> </template>
<script> <script>
export default { export default {
name: 'hamburger', name: 'hamburger',
props: { props: {
isActive: { isActive: {
type: Boolean, type: Boolean,
default: false default: false
}, },
toggleClick: { toggleClick: {
type: Function, type: Function,
default: null default: null
}
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -5,18 +5,18 @@
</template> </template>
<script> <script>
export default { export default {
name: 'icon-svg', name: 'icon-svg',
props: { props: {
iconClass: { iconClass: {
type: String, type: String,
required: true required: true
} }
}, },
computed: { computed: {
iconName() { iconName() {
return `#icon-${this.iconClass}` return `#icon-${this.iconClass}`
}
} }
} }
}
</script> </script>

View File

@ -37,5 +37,5 @@ const langBag = {
lowestPx: 'The lowest pixel in the image: ' lowestPx: 'The lowest pixel in the image: '
} }
} }
}; }
export default langBag; export default langBag

View File

@ -1,40 +1,40 @@
<template> <template>
<div class="material-input__component" :class="computedClasses"> <div class="material-input__component" :class="computedClasses">
<input v-if="type === 'email'" type="email" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy" <input v-if="type === 'email'" type="email" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput"> @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'url'" type="url" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy" <input v-if="type === 'url'" type="url" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput"> @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'number'" type="number" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy" <input v-if="type === 'number'" type="number" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :minlength="minlength" :maxlength="maxlength" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :minlength="minlength" :maxlength="maxlength"
:required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput"> :required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'password'" type="password" class="material-input" :name="name" :id="id" :placeholder="placeholder" <input v-if="type === 'password'" type="password" class="material-input" :name="name" :id="id" :placeholder="placeholder"
v-model="valueCopy" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :required="required" v-model="valueCopy" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :required="required"
@focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput"> @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy" <input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
@blur="handleFocus(false)" @input="handleModelInput"> @blur="handleFocus(false)" @input="handleModelInput">
<input v-if="type === 'text'" type="text" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy" <input v-if="type === 'text'" type="text" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :minlength="minlength" :maxlength="maxlength" :required="required" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :minlength="minlength" :maxlength="maxlength"
@focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput"> :required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
<span class="material-input-bar"></span> <span class="material-input-bar"></span>
<label class="material-label"> <label class="material-label">
<slot></slot> <slot></slot>
</label> </label>
<div v-if="errorMessages" class="material-errors"> <div v-if="errorMessages" class="material-errors">
<div v-for="error in computedErrors" class="material-error" :key='error'> <div v-for="error in computedErrors" class="material-error" :key='error'>
{{ error }} {{ error }}
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
// source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue // source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue
export default { export default {
name: 'material-input', name: 'material-input',
computed: { computed: {
computedErrors() { computedErrors() {

View File

@ -6,75 +6,75 @@
</template> </template>
<script> <script>
import 'simplemde/dist/simplemde.min.css'; import 'simplemde/dist/simplemde.min.css'
import SimpleMDE from 'simplemde'; import SimpleMDE from 'simplemde'
export default { export default {
name: 'simplemde-md', name: 'simplemde-md',
props: { props: {
value: String, value: String,
id: { id: {
type: String, type: String,
default: 'markdown-editor' default: 'markdown-editor'
},
autofocus: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: ''
},
height: {
type: Number,
default: 150
},
zIndex: {
type: Number,
default: 10
},
toolbar: {
type: Array
}
}, },
data() { autofocus: {
return { type: Boolean,
simplemde: null, default: false
hasChange: false
};
}, },
watch: { placeholder: {
value(val) { type: String,
if (val === this.simplemde.value() && !this.hasChange) return; default: ''
this.simplemde.value(val);
}
}, },
mounted() { height: {
this.simplemde = new SimpleMDE({ type: Number,
element: document.getElementById(this.id), default: 150
autofocus: this.autofocus,
toolbar: this.toolbar,
spellChecker: false,
insertTexts: {
link: ['[', ']( )']
},
// hideIcons: ['guide', 'heading', 'quote', 'image', 'preview', 'side-by-side', 'fullscreen'],
placeholder: this.placeholder
});
if (this.value) {
this.simplemde.value(this.value);
}
this.simplemde.codemirror.on('change', () => {
if (this.hasChange) {
this.hasChange = true
}
this.$emit('input', this.simplemde.value());
});
}, },
destroyed() { zIndex: {
this.simplemde = null; type: Number,
default: 10
},
toolbar: {
type: Array
} }
}; },
data() {
return {
simplemde: null,
hasChange: false
}
},
watch: {
value(val) {
if (val === this.simplemde.value() && !this.hasChange) return
this.simplemde.value(val)
}
},
mounted() {
this.simplemde = new SimpleMDE({
element: document.getElementById(this.id),
autofocus: this.autofocus,
toolbar: this.toolbar,
spellChecker: false,
insertTexts: {
link: ['[', ']( )']
},
// hideIcons: ['guide', 'heading', 'quote', 'image', 'preview', 'side-by-side', 'fullscreen'],
placeholder: this.placeholder
})
if (this.value) {
this.simplemde.value(this.value)
}
this.simplemde.codemirror.on('change', () => {
if (this.hasChange) {
this.hasChange = true
}
this.$emit('input', this.simplemde.value())
})
},
destroyed() {
this.simplemde = null
}
}
</script> </script>
<style> <style>

View File

@ -10,27 +10,27 @@
</template> </template>
<script> <script>
export default { export default {
name: 'PanThumb', name: 'PanThumb',
props: { props: {
image: { image: {
type: String, type: String,
required: true required: true
}, },
zIndex: { zIndex: {
type: Number, type: Number,
default: 100 default: 100
}, },
width: { width: {
type: String, type: String,
default: '150px' default: '150px'
}, },
height: { height: {
type: String, type: String,
default: '150px' default: '150px'
}
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -7,41 +7,41 @@
</template> </template>
<script> <script>
import screenfull from 'screenfull'; import screenfull from 'screenfull'
export default { export default {
name: 'hamburger', name: 'hamburger',
props: { props: {
width: { width: {
type: Number, type: Number,
default: 22 default: 22
},
height: {
type: Number,
default: 22
},
fill: {
type: String,
default: '#48576a'
}
}, },
data() { height: {
return { type: Number,
isFullscreen: false default: 22
}
}, },
methods: { fill: {
click() { type: String,
if (!screenfull.enabled) { default: '#48576a'
this.$message({ }
message: 'you browser can not work', },
type: 'warning' data() {
}); return {
return false; isFullscreen: false
} }
screenfull.toggle(); },
methods: {
click() {
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
} }
screenfull.toggle()
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -5,16 +5,16 @@
</template> </template>
<script> <script>
export default { export default {
name: 'Pane', name: 'Pane',
data() { data() {
const classes = ['Pane', this.$parent.split, 'className']; const classes = ['Pane', this.$parent.split, 'className']
return { return {
classes: classes.join(' '), classes: classes.join(' '),
percent: 50 percent: 50
} }
} }
} }
</script> </script>
<style scoped> <style scoped>

View File

@ -3,26 +3,26 @@
</template> </template>
<script> <script>
export default { export default {
props: { props: {
split: { split: {
validator(value) { validator(value) {
return ['vertical', 'horizontal'].indexOf(value) >= 0 return ['vertical', 'horizontal'].indexOf(value) >= 0
},
required: true
}, },
onMouseDown: { required: true
type: Function,
required: true
}
}, },
data() { onMouseDown: {
const classes = ['Resizer', this.split, 'className']; type: Function,
return { required: true
classes: classes.join(' ') }
} },
data() {
const classes = ['Resizer', this.split, 'className']
return {
classes: classes.join(' ')
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -11,86 +11,86 @@
</template> </template>
<script> <script>
import Resizer from './Resizer'; import Resizer from './Resizer'
import Pane from './Pane'; import Pane from './Pane'
export default { export default {
name: 'splitPane', name: 'splitPane',
components: { Resizer, Pane }, components: { Resizer, Pane },
props: { props: {
margin: { margin: {
type: Number, type: Number,
default: 10 default: 10
},
split: {
validator(value) {
return ['vertical', 'horizontal'].indexOf(value) >= 0
}, },
split: { required: true
validator(value) { }
return ['vertical', 'horizontal'].indexOf(value) >= 0 },
}, data() {
required: true return {
active: false,
hasMoved: false,
height: null,
percent: 50,
type: this.split === 'vertical' ? 'width' : 'height',
resizeType: this.split === 'vertical' ? 'left' : 'top'
}
},
computed: {
userSelect() {
return this.active ? 'none' : ''
},
cursor() {
return this.active ? 'col-resize' : ''
}
},
methods: {
onClick() {
if (!this.hasMoved) {
this.percent = 50
this.$emit('resize')
} }
}, },
data() { onMouseDown() {
return { this.active = true
active: false, this.hasMoved = false
hasMoved: false,
height: null,
percent: 50,
type: this.split === 'vertical' ? 'width' : 'height',
resizeType: this.split === 'vertical' ? 'left' : 'top'
}
}, },
computed: { onMouseUp() {
userSelect() { this.active = false
return this.active ? 'none' : ''
},
cursor() {
return this.active ? 'col-resize' : ''
}
}, },
methods: { onMouseMove(e) {
onClick() { if (e.buttons === 0 || e.which === 0) {
if (!this.hasMoved) { this.active = false
this.percent = 50; }
this.$emit('resize'); if (this.active) {
} let offset = 0
}, let target = e.currentTarget
onMouseDown() { if (this.split === 'vertical') {
this.active = true; while (target) {
this.hasMoved = false; offset += target.offsetLeft
}, target = target.offsetParent
onMouseUp() {
this.active = false;
},
onMouseMove(e) {
if (e.buttons === 0 || e.which === 0) {
this.active = false;
}
if (this.active) {
let offset = 0;
let target = e.currentTarget;
if (this.split === 'vertical') {
while (target) {
offset += target.offsetLeft;
target = target.offsetParent;
}
} else {
while (target) {
offset += target.offsetTop;
target = target.offsetParent;
}
} }
} else {
while (target) {
offset += target.offsetTop
target = target.offsetParent
}
}
const currentPage = this.split === 'vertical' ? e.pageX : e.pageY; const currentPage = this.split === 'vertical' ? e.pageX : e.pageY
const targetOffset = this.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight; const targetOffset = this.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight
const percent = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100; const percent = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100
if (percent > this.margin && percent < 100 - this.margin) { if (percent > this.margin && percent < 100 - this.margin) {
this.percent = percent; this.percent = percent
}
this.$emit('resize');
this.hasMoved = true;
} }
this.$emit('resize')
this.hasMoved = true
} }
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -9,66 +9,66 @@
</template> </template>
<script> <script>
export default { export default {
name: 'Sticky', name: 'Sticky',
props: { props: {
stickyTop: { stickyTop: {
type: Number, type: Number,
default: 0 default: 0
},
zIndex: {
type: Number,
default: 1
},
className: {
type: String
}
}, },
data() { zIndex: {
return { type: Number,
active: false, default: 1
position: '',
currentTop: '',
width: undefined,
height: undefined,
child: null,
stickyHeight: 0
};
}, },
methods: { className: {
sticky() { type: String
if (this.active) {
return
}
this.position = 'fixed';
this.active = true;
this.width = this.width + 'px';
},
reset() {
if (!this.active) {
return
}
this.position = '';
this.width = 'auto'
this.active = false
},
handleScroll() {
this.width = this.$el.getBoundingClientRect().width;
const offsetTop = this.$el.getBoundingClientRect().top;
if (offsetTop <= this.stickyTop) {
this.sticky();
return
}
this.reset()
}
},
mounted() {
this.height = this.$el.getBoundingClientRect().height;
window.addEventListener('scroll', this.handleScroll);
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll);
} }
}; },
data() {
return {
active: false,
position: '',
currentTop: '',
width: undefined,
height: undefined,
child: null,
stickyHeight: 0
}
},
methods: {
sticky() {
if (this.active) {
return
}
this.position = 'fixed'
this.active = true
this.width = this.width + 'px'
},
reset() {
if (!this.active) {
return
}
this.position = ''
this.width = 'auto'
this.active = false
},
handleScroll() {
this.width = this.$el.getBoundingClientRect().width
const offsetTop = this.$el.getBoundingClientRect().top
if (offsetTop <= this.stickyTop) {
this.sticky()
return
}
this.reset()
}
},
mounted() {
this.height = this.$el.getBoundingClientRect().height
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
}
}
</script> </script>

View File

@ -5,80 +5,79 @@
</template> </template>
<script> <script>
// import { getToken, upload } from 'api/qiniu'; // export default {
export default { name: 'tinymce',
name: 'tinymce', props: {
props: { id: {
id: { type: String,
type: String, default: 'tinymceEditor'
default: 'tinymceEditor' },
}, value: {
value: { type: String,
type: String, default: ''
default: '' },
}, toolbar: {
toolbar: { type: Array,
type: Array, required: false,
required: false, default() {
default() { return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright']
return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright'] }
} },
}, data() {
data() { return {
return { hasChange: false,
hasChange: false, hasInit: false
hasInit: false }
} },
}, menubar: {
menubar: { default: ''
default: '' },
}, height: {
height: { type: Number,
type: Number, required: false,
required: false, default: 360
default: 360 }
} },
}, watch: {
watch: { value(val) {
value(val) { if (!this.hasChange && this.hasInit) {
if (!this.hasChange && this.hasInit) { this.$nextTick(() => window.tinymce.get(this.id).setContent(val))
this.$nextTick(() => tinymce.get(this.id).setContent(val)) }
} }
} },
}, mounted() {
mounted() { const _this = this
const _this = this; window.tinymce.init({
tinymce.init({ selector: `#${this.id}`,
selector: `#${this.id}`, height: this.height,
height: this.height, body_class: 'panel-body ',
body_class: 'panel-body ', object_resizing: false,
object_resizing: false,
// language: 'zh_CN', // language: 'zh_CN',
// language_url: '/static/tinymce/langs/zh_CN.js', // language_url: '/static/tinymce/langs/zh_CN.js',
toolbar: this.toolbar, toolbar: this.toolbar,
menubar: this.menubar, menubar: this.menubar,
plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools,watermark', plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools,watermark',
end_container_on_empty_block: true, end_container_on_empty_block: true,
powerpaste_word_import: 'clean', powerpaste_word_import: 'clean',
code_dialog_height: 450, code_dialog_height: 450,
code_dialog_width: 1000, code_dialog_width: 1000,
advlist_bullet_styles: 'square', advlist_bullet_styles: 'square',
advlist_number_styles: 'default', advlist_number_styles: 'default',
block_formats: '普通标签=p;小标题=h2;', block_formats: '普通标签=p;小标题=h2;',
imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'], imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
imagetools_toolbar: 'watermark', imagetools_toolbar: 'watermark',
default_link_target: '_blank', default_link_target: '_blank',
link_title: false, link_title: false,
init_instance_callback: editor => { init_instance_callback: editor => {
if (_this.value) { if (_this.value) {
editor.setContent(_this.value) editor.setContent(_this.value)
} }
_this.hasInit = true; _this.hasInit = true
editor.on('NodeChange Change KeyUp', () => { editor.on('NodeChange Change KeyUp', () => {
this.hasChange = true; this.hasChange = true
this.$emit('input', editor.getContent({ format: 'raw' })); this.$emit('input', editor.getContent({ format: 'raw' }))
}); })
}, },
// //
// images_dataimg_filter(img) { // images_dataimg_filter(img) {
// setTimeout(() => { // setTimeout(() => {
@ -112,44 +111,44 @@
// console.log(err); // console.log(err);
// }); // });
// }, // },
setup(editor) { setup(editor) {
editor.addButton('h2', { editor.addButton('h2', {
title: '小标题', // tooltip text seen on mouseover title: '小标题', // tooltip text seen on mouseover
text: '小标题', text: '小标题',
onclick() { onclick() {
editor.execCommand('mceToggleFormat', false, 'h2'); editor.execCommand('mceToggleFormat', false, 'h2')
}, },
onPostRender() { onPostRender() {
const btn = this; const btn = this
editor.on('init', () => { editor.on('init', () => {
editor.formatter.formatChanged('h2', state => { editor.formatter.formatChanged('h2', state => {
btn.active(state); btn.active(state)
}); })
}); })
} }
}); })
editor.addButton('p', { editor.addButton('p', {
title: '正文', title: '正文',
text: '正文', text: '正文',
onclick() { onclick() {
editor.execCommand('mceToggleFormat', false, 'p'); editor.execCommand('mceToggleFormat', false, 'p')
}, },
onPostRender() { onPostRender() {
const btn = this; const btn = this
editor.on('init', () => { editor.on('init', () => {
editor.formatter.formatChanged('p', state => { editor.formatter.formatChanged('p', state => {
btn.active(state); btn.active(state)
}); })
}); })
} }
}); })
} }
}); })
}, },
destroyed() { destroyed() {
tinymce.get(this.id).destroy(); window.tinymce.get(this.id).destroy()
}
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -84,12 +84,10 @@ export default {
this.setLocalStorgae() this.setLocalStorgae()
}, },
deleteTodo(todo) { deleteTodo(todo) {
console.log(todo)
this.todos.splice(this.todos.indexOf(todo), 1) this.todos.splice(this.todos.indexOf(todo), 1)
this.setLocalStorgae() this.setLocalStorgae()
}, },
editTodo({ todo, value }) { editTodo({ todo, value }) {
console.log(todo, value)
todo.text = value todo.text = value
this.setLocalStorgae() this.setLocalStorgae()
}, },

View File

@ -17,52 +17,53 @@
</template> </template>
<script> <script>
// //
import { getToken } from 'api/qiniu'; import { getToken } from 'api/qiniu'
export default {
name: 'singleImageUpload', export default {
props: { name: 'singleImageUpload',
value: String props: {
value: String
}, },
computed: { computed: {
imageUrl() { imageUrl() {
return this.value return this.value
} }
}, },
data() { data() {
return { return {
tempUrl: '', tempUrl: '',
dataObj: { token: '', key: '' } dataObj: { token: '', key: '' }
}; }
}, },
methods: { methods: {
rmImage() { rmImage() {
this.emitInput(''); this.emitInput('')
}, },
emitInput(val) { emitInput(val) {
this.$emit('input', val); this.$emit('input', val)
}, },
handleImageScucess() { handleImageScucess() {
this.emitInput(this.tempUrl) this.emitInput(this.tempUrl)
}, },
beforeUpload() { beforeUpload() {
const _self = this; const _self = this
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getToken().then(response => { getToken().then(response => {
const key = response.data.qiniu_key; const key = response.data.qiniu_key
const token = response.data.qiniu_token; const token = response.data.qiniu_token
_self._data.dataObj.token = token; _self._data.dataObj.token = token
_self._data.dataObj.key = key; _self._data.dataObj.key = key
this.tempUrl = response.data.qiniu_url; this.tempUrl = response.data.qiniu_url
resolve(true); resolve(true)
}).catch(err => { }).catch(err => {
console.log(err); console.log(err)
reject(false) reject(false)
}); })
}); })
} }
} }
}; }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -18,8 +18,8 @@
<script> <script>
// //
import { getToken } from 'api/qiniu'; import { getToken } from 'api/qiniu'
export default { export default {
name: 'singleImageUpload2', name: 'singleImageUpload2',
props: { props: {
value: String value: String
@ -33,36 +33,35 @@
return { return {
tempUrl: '', tempUrl: '',
dataObj: { token: '', key: '' } dataObj: { token: '', key: '' }
}; }
}, },
methods: { methods: {
rmImage() { rmImage() {
this.emitInput(''); this.emitInput('')
}, },
emitInput(val) { emitInput(val) {
this.$emit('input', val); this.$emit('input', val)
}, },
handleImageScucess() { handleImageScucess() {
this.emitInput(this.tempUrl) this.emitInput(this.tempUrl)
}, },
beforeUpload() { beforeUpload() {
const _self = this; const _self = this
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getToken().then(response => { getToken().then(response => {
const key = response.data.qiniu_key; const key = response.data.qiniu_key
const token = response.data.qiniu_token; const token = response.data.qiniu_token
_self._data.dataObj.token = token; _self._data.dataObj.token = token
_self._data.dataObj.key = key; _self._data.dataObj.key = key
this.tempUrl = response.data.qiniu_url; this.tempUrl = response.data.qiniu_url
resolve(true); resolve(true)
}).catch(err => { }).catch(() => {
console.log(err); reject(false)
reject(false) })
}); })
});
} }
} }
}; }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -27,8 +27,8 @@
<script> <script>
// //
import { getToken } from 'api/qiniu'; import { getToken } from 'api/qiniu'
export default { export default {
name: 'singleImageUpload', name: 'singleImageUpload',
props: { props: {
value: String value: String
@ -42,36 +42,36 @@
return { return {
tempUrl: '', tempUrl: '',
dataObj: { token: '', key: '' } dataObj: { token: '', key: '' }
}; }
}, },
methods: { methods: {
rmImage() { rmImage() {
this.emitInput(''); this.emitInput('')
}, },
emitInput(val) { emitInput(val) {
this.$emit('input', val); this.$emit('input', val)
}, },
handleImageScucess(file) { handleImageScucess(file) {
this.emitInput(file.files.file) this.emitInput(file.files.file)
}, },
beforeUpload() { beforeUpload() {
const _self = this; const _self = this
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getToken().then(response => { getToken().then(response => {
const key = response.data.qiniu_key; const key = response.data.qiniu_key
const token = response.data.qiniu_token; const token = response.data.qiniu_token
_self._data.dataObj.token = token; _self._data.dataObj.token = token
_self._data.dataObj.key = key; _self._data.dataObj.key = key
this.tempUrl = response.data.qiniu_url; this.tempUrl = response.data.qiniu_url
resolve(true); resolve(true)
}).catch(err => { }).catch(err => {
console.log(err); console.log(err)
reject(false) reject(false)
}); })
}); })
} }
} }
}; }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -5,52 +5,52 @@
</template> </template>
<script> <script>
import CodeMirror from 'codemirror'; import CodeMirror from 'codemirror'
import 'codemirror/addon/lint/lint.css'; import 'codemirror/addon/lint/lint.css'
import 'codemirror/lib/codemirror.css'; import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/rubyblue.css'; import 'codemirror/theme/rubyblue.css'
require('script-loader!jsonlint'); require('script-loader!jsonlint')
import 'codemirror/mode/javascript/javascript' import 'codemirror/mode/javascript/javascript'
import 'codemirror/addon/lint/lint' import 'codemirror/addon/lint/lint'
import 'codemirror/addon/lint/json-lint'; import 'codemirror/addon/lint/json-lint'
export default { export default {
name: 'jsonEditor', name: 'jsonEditor',
data() { data() {
return { return {
jsonEditor: false jsonEditor: false
} }
}, },
props: ['value'], props: ['value'],
watch: { watch: {
value(value) { value(value) {
const editor_value = this.jsonEditor.getValue(); const editor_value = this.jsonEditor.getValue()
if (value !== editor_value) { if (value !== editor_value) {
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)); this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
}
}
},
mounted() {
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
lineNumbers: true,
mode: 'application/json',
gutters: ['CodeMirror-lint-markers'],
theme: 'rubyblue',
lint: true
});
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2));
this.jsonEditor.on('change', cm => {
this.$emit('changed', cm.getValue())
this.$emit('input', cm.getValue())
})
},
methods: {
getValue() {
return this.jsonEditor.getValue()
} }
} }
},
mounted() {
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea, {
lineNumbers: true,
mode: 'application/json',
gutters: ['CodeMirror-lint-markers'],
theme: 'rubyblue',
lint: true
})
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
this.jsonEditor.on('change', cm => {
this.$emit('changed', cm.getValue())
this.$emit('input', cm.getValue())
})
},
methods: {
getValue() {
return this.jsonEditor.getValue()
}
} }
}
</script> </script>
<style> <style>

View File

@ -26,74 +26,74 @@
</template> </template>
<script> <script>
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
export default { export default {
name: 'twoDndList', name: 'twoDndList',
components: { draggable }, components: { draggable },
computed: { computed: {
filterList2() { filterList2() {
return this.list2.filter(v => { return this.list2.filter(v => {
if (this.isNotInList1(v)) { if (this.isNotInList1(v)) {
return v return v
} }
return false; return false
}) })
}
},
props: {
list1: {
type: Array,
default() {
return []
} }
}, },
props: { list2: {
list1: { type: Array,
type: Array, default() {
default() { return []
return []
}
},
list2: {
type: Array,
default() {
return []
}
},
list1Title: {
type: String,
default: 'list1'
},
list2Title: {
type: String,
default: 'list2'
},
width1: {
type: String,
default: '48%'
},
width2: {
type: String,
default: '48%'
} }
}, },
methods: { list1Title: {
isNotInList1(v) { type: String,
return this.list1.every(k => v.id !== k.id) default: 'list1'
}, },
isNotInList2(v) { list2Title: {
return this.list2.every(k => v.id !== k.id) type: String,
}, default: 'list2'
deleteEle(ele) { },
for (const item of this.list1) { width1: {
if (item.id === ele.id) { type: String,
const index = this.list1.indexOf(item); default: '48%'
this.list1.splice(index, 1) },
break width2: {
} type: String,
default: '48%'
}
},
methods: {
isNotInList1(v) {
return this.list1.every(k => v.id !== k.id)
},
isNotInList2(v) {
return this.list2.every(k => v.id !== k.id)
},
deleteEle(ele) {
for (const item of this.list1) {
if (item.id === ele.id) {
const index = this.list1.indexOf(item)
this.list1.splice(index, 1)
break
} }
if (this.isNotInList2(ele)) {
this.list2.unshift(ele)
}
},
pushEle(ele) {
this.list1.push(ele)
} }
if (this.isNotInList2(ele)) {
this.list2.unshift(ele)
}
},
pushEle(ele) {
this.list1.push(ele)
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -1,43 +1,43 @@
const vueSticky = {}; const vueSticky = {}
let listenAction; let listenAction
vueSticky.install = Vue => { vueSticky.install = Vue => {
Vue.directive('sticky', { Vue.directive('sticky', {
inserted(el, binding) { inserted(el, binding) {
const params = binding.value || {}, const params = binding.value || {}
stickyTop = params.stickyTop || 0, const stickyTop = params.stickyTop || 0
zIndex = params.zIndex || 1000, const zIndex = params.zIndex || 1000
elStyle = el.style; const elStyle = el.style
elStyle.position = '-webkit-sticky'; elStyle.position = '-webkit-sticky'
elStyle.position = 'sticky'; elStyle.position = 'sticky'
// if the browser support css stickyCurrently Safari, Firefox and Chrome Canary // if the browser support css stickyCurrently Safari, Firefox and Chrome Canary
// if (~elStyle.position.indexOf('sticky')) { // if (~elStyle.position.indexOf('sticky')) {
// elStyle.top = `${stickyTop}px`; // elStyle.top = `${stickyTop}px`;
// elStyle.zIndex = zIndex; // elStyle.zIndex = zIndex;
// return // return
// } // }
const elHeight = el.getBoundingClientRect().height; const elHeight = el.getBoundingClientRect().height
const elWidth = el.getBoundingClientRect().width; const elWidth = el.getBoundingClientRect().width
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`; elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
const parentElm = el.parentNode || document.documentElement; const parentElm = el.parentNode || document.documentElement
const placeholder = document.createElement('div'); const placeholder = document.createElement('div')
placeholder.style.display = 'none'; placeholder.style.display = 'none'
placeholder.style.width = `${elWidth}px`; placeholder.style.width = `${elWidth}px`
placeholder.style.height = `${elHeight}px`; placeholder.style.height = `${elHeight}px`
parentElm.insertBefore(placeholder, el) parentElm.insertBefore(placeholder, el)
let active = false; let active = false
const getScroll = (target, top) => { const getScroll = (target, top) => {
const prop = top ? 'pageYOffset' : 'pageXOffset'; const prop = top ? 'pageYOffset' : 'pageXOffset'
const method = top ? 'scrollTop' : 'scrollLeft'; const method = top ? 'scrollTop' : 'scrollLeft'
let ret = target[prop]; let ret = target[prop]
if (typeof ret !== 'number') { if (typeof ret !== 'number') {
ret = window.document.documentElement[method]; ret = window.document.documentElement[method]
} }
return ret; return ret
}; }
const sticky = () => { const sticky = () => {
if (active) { if (active) {
@ -47,36 +47,36 @@ vueSticky.install = Vue => {
elStyle.height = `${el.offsetHeight}px` elStyle.height = `${el.offsetHeight}px`
} }
elStyle.position = 'fixed'; elStyle.position = 'fixed'
elStyle.width = `${elWidth}px`; elStyle.width = `${elWidth}px`
placeholder.style.display = 'inline-block'; placeholder.style.display = 'inline-block'
active = true active = true
}; }
const reset = () => { const reset = () => {
if (!active) { if (!active) {
return return
} }
elStyle.position = ''; elStyle.position = ''
placeholder.style.display = 'none'; placeholder.style.display = 'none'
active = false; active = false
}; }
const check = () => { const check = () => {
const scrollTop = getScroll(window, true); const scrollTop = getScroll(window, true)
const offsetTop = el.getBoundingClientRect().top; const offsetTop = el.getBoundingClientRect().top
if (offsetTop < stickyTop) { if (offsetTop < stickyTop) {
sticky(); sticky()
} else { } else {
if (scrollTop < elHeight + stickyTop) { if (scrollTop < elHeight + stickyTop) {
reset() reset()
} }
} }
}; }
listenAction = () => { listenAction = () => {
check() check()
}; }
window.addEventListener('scroll', listenAction) window.addEventListener('scroll', listenAction)
}, },
@ -85,7 +85,7 @@ vueSticky.install = Vue => {
window.removeEventListener('scroll', listenAction) window.removeEventListener('scroll', listenAction)
} }
}) })
}; }
export default vueSticky export default vueSticky

View File

@ -1,44 +1,42 @@
import './waves.css'; import './waves.css'
export default{ export default{
bind(el, binding) { bind(el, binding) {
el.addEventListener('click', e => { el.addEventListener('click', e => {
const customOpts = Object.assign({}, binding.value); const customOpts = Object.assign({}, binding.value)
const opts = Object.assign({ const opts = Object.assign({
ele: el, // 波纹作用元素 ele: el, // 波纹作用元素
type: 'hit', // hit点击位置扩散center中心点扩展 type: 'hit', // hit点击位置扩散center中心点扩展
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色 color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
}, customOpts), }, customOpts)
target = opts.ele; const target = opts.ele
if (target) { if (target) {
target.style.position = 'relative'; target.style.position = 'relative'
target.style.overflow = 'hidden'; target.style.overflow = 'hidden'
const rect = target.getBoundingClientRect(); const rect = target.getBoundingClientRect()
let ripple = target.querySelector('.waves-ripple'); let ripple = target.querySelector('.waves-ripple')
if (!ripple) { if (!ripple) {
ripple = document.createElement('span'); ripple = document.createElement('span')
ripple.className = 'waves-ripple'; ripple.className = 'waves-ripple'
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'; ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px'
target.appendChild(ripple); target.appendChild(ripple)
} else { } else {
ripple.className = 'waves-ripple'; ripple.className = 'waves-ripple'
} }
switch (opts.type) { switch (opts.type) {
case 'center': case 'center':
ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'; ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px'
ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'; ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px'
break; break
default: default:
ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'; ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px'
ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'; ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px'
} }
ripple.style.backgroundColor = opts.color; ripple.style.backgroundColor = opts.color
ripple.className = 'waves-ripple z-active'; ripple.className = 'waves-ripple z-active'
return false; return false
} }
}, false); }, false)
} }
} }

View File

@ -4,11 +4,11 @@ import errLog from '@/store/errLog'
// 生产环境错误日志 // 生产环境错误日志
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
Vue.config.errorHandler = function(err, vm) { Vue.config.errorHandler = function(err, vm) {
console.log(err, window.location.href); console.log(err, window.location.href)
errLog.pushLog({ errLog.pushLog({
err, err,
url: window.location.href, url: window.location.href,
vm vm
}) })
}; }
} }

View File

@ -5,7 +5,7 @@ function pluralize(time, label) {
return time + label + 's' return time + label + 's'
} }
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) {
return pluralize(~~(between / 60), ' minute') return pluralize(~~(between / 60), ' minute')
} else if (between < 86400) { } else if (between < 86400) {
@ -17,19 +17,19 @@ export function timeAgo(time) {
export function parseTime(time, cFormat) { export function parseTime(time, cFormat) {
if (arguments.length === 0) { if (arguments.length === 0) {
return null; return null
} }
if ((time + '').length === 10) { if ((time + '').length === 10) {
time = +time * 1000 time = +time * 1000
} }
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'; const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date; let date
if (typeof time == 'object') { if (typeof time === 'object') {
date = time; date = time
} else { } else {
date = new Date(parseInt(time)); date = new Date(parseInt(time))
} }
const formatObj = { const formatObj = {
y: date.getFullYear(), y: date.getFullYear(),
@ -39,24 +39,24 @@ export function parseTime(time, cFormat) {
i: date.getMinutes(), i: date.getMinutes(),
s: date.getSeconds(), s: date.getSeconds(),
a: date.getDay() a: date.getDay()
}; }
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]; let value = formatObj[key]
if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]; if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
if (result.length > 0 && value < 10) { if (result.length > 0 && value < 10) {
value = '0' + value; value = '0' + value
} }
return value || 0; return value || 0
}); })
return time_str; return time_str
} }
export function formatTime(time, option) { export function formatTime(time, option) {
time = +time * 1000; time = +time * 1000
const d = new Date(time); const d = new Date(time)
const now = Date.now(); const now = Date.now()
const diff = (now - d) / 1000; const diff = (now - d) / 1000
if (diff < 30) { if (diff < 30) {
return '刚刚' return '刚刚'
@ -83,21 +83,21 @@ export function nFormatter(num, digits) {
{ value: 1E9, symbol: 'G' }, { value: 1E9, symbol: 'G' },
{ value: 1E6, symbol: 'M' }, { value: 1E6, symbol: 'M' },
{ value: 1E3, symbol: 'k' } { value: 1E3, symbol: 'k' }
]; ]
for (let i = 0; i < si.length; i++) { for (let i = 0; i < si.length; i++) {
if (num >= si[i].value) { if (num >= si[i].value) {
return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol; return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
} }
} }
return num.toString(); return num.toString()
} }
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
} }
export function toThousandslsFilter(num) { export function toThousandslsFilter(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, ','))
} }

View File

@ -29,5 +29,3 @@ new Vue({
template: '<App/>', template: '<App/>',
components: { App } components: { App }
}) })

View File

@ -1,9 +1,7 @@
import Mock from 'mockjs'; import Mock from 'mockjs'
const List = [];
const count = 20;
const List = []
const count = 20
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
List.push(Mock.mock({ List.push(Mock.mock({
@ -13,7 +11,7 @@ for (let i = 0; i < count; i++) {
author: '@cname', author: '@cname',
display_time: '@datetime', display_time: '@datetime',
pageviews: '@integer(300, 5000)' pageviews: '@integer(300, 5000)'
})); }))
} }
export default { export default {
@ -34,4 +32,4 @@ export default {
tags: [], tags: [],
title: '' title: ''
}) })
}; }

View File

@ -1,8 +1,8 @@
import Mock from 'mockjs'; import Mock from 'mockjs'
import { param2Obj } from 'utils'; import { param2Obj } from 'utils'
const List = []; const List = []
const count = 100; const count = 100
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
List.push(Mock.mock({ List.push(Mock.mock({
@ -16,23 +16,23 @@ for (let i = 0; i < count; i++) {
'type|1': ['CN', 'US', 'JP', 'EU'], 'type|1': ['CN', 'US', 'JP', 'EU'],
'status|1': ['published', 'draft', 'deleted'], 'status|1': ['published', 'draft', 'deleted'],
pageviews: '@integer(300, 5000)' pageviews: '@integer(300, 5000)'
})); }))
} }
export default { export default {
getList: config => { getList: config => {
const { importance, type, title, page, limit, sort } = param2Obj(config.url); const { importance, type, title, page, limit, sort } = param2Obj(config.url)
let mockList = List.filter(item => { let mockList = List.filter(item => {
if (importance && item.importance !== +importance) return false; if (importance && item.importance !== +importance) return false
if (type && item.type !== type) return false; if (type && item.type !== type) return false
if (title && item.title.indexOf(title) < 0) return false; if (title && item.title.indexOf(title) < 0) return false
return true; return true
}); })
if (sort === '-id') { if (sort === '-id') {
mockList = mockList.reverse() mockList = mockList.reverse()
} }
const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)); const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
return { return {
total: mockList.length, total: mockList.length,
items: pageList items: pageList
@ -41,4 +41,4 @@ export default {
getPv: () => ({ getPv: () => ({
pvData: [{ key: 'PC网站', pv: 1024 }, { key: 'mobile网站', pv: 1024 }, { key: 'ios', pv: 1024 }, { key: 'android', pv: 1024 }] pvData: [{ key: 'PC网站', pv: 1024 }, { key: 'mobile网站', pv: 1024 }, { key: 'ios', pv: 1024 }, { key: 'android', pv: 1024 }]
}) })
}; }

View File

@ -1,4 +1,4 @@
import { param2Obj } from 'utils'; import { param2Obj } from 'utils'
const userMap = { const userMap = {
admin: { admin: {
@ -26,16 +26,16 @@ const userMap = {
export default { export default {
loginByUsername: config => { loginByUsername: config => {
const { username } = JSON.parse(config.body); const { username } = JSON.parse(config.body)
return userMap[username]; return userMap[username]
}, },
getInfo: config => { getInfo: config => {
const { token } = param2Obj(config.url); const { token } = param2Obj(config.url)
if (userMap[token]) { if (userMap[token]) {
return userMap[token]; return userMap[token]
} else { } else {
return Promise.reject('error'); return Promise.reject('error')
} }
}, },
logout: () => 'success' logout: () => 'success'
}; }

View File

@ -1,24 +1,24 @@
import Mock from 'mockjs'; import Mock from 'mockjs'
import { param2Obj } from 'utils'; import { param2Obj } from 'utils'
const NameList = []; const NameList = []
const count = 100; const count = 100
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
NameList.push(Mock.mock({ NameList.push(Mock.mock({
name: '@first' name: '@first'
})); }))
} }
NameList.push({ name: 'mockPan' }) NameList.push({ name: 'mockPan' })
export default { export default {
searchUser: config => { searchUser: config => {
const { name } = param2Obj(config.url); const { name } = param2Obj(config.url)
const mockNameList = NameList.filter(item => { const mockNameList = NameList.filter(item => {
const lowerCaseName = item.name.toLowerCase() const lowerCaseName = item.name.toLowerCase()
if (name && lowerCaseName.indexOf(name.toLowerCase()) < 0) return false; if (name && lowerCaseName.indexOf(name.toLowerCase()) < 0) return false
return true; return true
}); })
return { items: mockNameList } return { items: mockNameList }
} }
}; }

View File

@ -36,7 +36,7 @@ router.beforeEach((to, from, next) => {
if (hasPermission(store.getters.roles, to.meta.role)) { if (hasPermission(store.getters.roles, to.meta.role)) {
next()// next()//
} else { } else {
next({ path: '/401', query: { noGoBack: true } }) next({ path: '/401', query: { noGoBack: true }})
} }
// 可删 ↑ // 可删 ↑
} }

View File

@ -1,12 +1,12 @@
import Vue from 'vue'; import Vue from 'vue'
import Router from 'vue-router'; import Router from 'vue-router'
const _import = require('./_import_' + process.env.NODE_ENV); const _import = require('./_import_' + process.env.NODE_ENV)
// in development env not use Lazy Loading,because Lazy Loading large page will cause webpack hot update too slow.so only in production use Lazy Loading // in development env not use Lazy Loading,because Lazy Loading large page will cause webpack hot update too slow.so only in production use Lazy Loading
Vue.use(Router); Vue.use(Router)
/* layout */ /* layout */
import Layout from '../views/layout/Layout'; import Layout from '../views/layout/Layout'
/** /**
* icon : the icon show in the sidebar * icon : the icon show in the sidebar
@ -42,7 +42,7 @@ export default new Router({
// mode: 'history', //后端支持可开 // mode: 'history', //后端支持可开
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap routes: constantRouterMap
}); })
export const asyncRouterMap = [ export const asyncRouterMap = [
{ {
@ -53,7 +53,7 @@ export const asyncRouterMap = [
icon: 'quanxian', icon: 'quanxian',
meta: { role: ['admin'] }, meta: { role: ['admin'] },
noDropdown: true, noDropdown: true,
children: [{ path: 'index', component: _import('permission/index'), name: '权限测试页', meta: { role: ['admin'] } }] children: [{ path: 'index', component: _import('permission/index'), name: '权限测试页', meta: { role: ['admin'] }}]
}, },
{ {
path: '/components', path: '/components',
@ -110,7 +110,7 @@ export const asyncRouterMap = [
{ path: 'table', component: _import('example/table/table'), name: '综合table' } { path: 'table', component: _import('example/table/table'), name: '综合table' }
] ]
}, },
{ path: 'form/edit', icon: 'ziliaoshouce', component: _import('example/form'), name: '编辑Form', meta: { isEdit: true } }, { path: 'form/edit', icon: 'ziliaoshouce', component: _import('example/form'), name: '编辑Form', meta: { isEdit: true }},
{ path: 'form/create', icon: 'yinhangqia', component: _import('example/form'), name: '创建Form' }, { path: 'form/create', icon: 'yinhangqia', component: _import('example/form'), name: '创建Form' },
{ path: 'tab/index', icon: 'mobankuangjia', component: _import('example/tab/index'), name: 'Tab' } { path: 'tab/index', icon: 'mobankuangjia', component: _import('example/tab/index'), name: 'Tab' }
@ -158,4 +158,4 @@ export const asyncRouterMap = [
}, },
{ path: '*', redirect: '/404', hidden: true } { path: '*', redirect: '/404', hidden: true }
]; ]

View File

@ -6,8 +6,8 @@ const errLog = {
this.state.errLog.unshift(log) this.state.errLog.unshift(log)
}, },
clearLog() { clearLog() {
this.state.errLog = []; this.state.errLog = []
} }
}; }
export default errLog; export default errLog

View File

@ -10,5 +10,5 @@ const getters = {
setting: state => state.user.setting, setting: state => state.user.setting,
permission_routers: state => state.permission.routers, permission_routers: state => state.permission.routers,
addRouters: state => state.permission.addRouters addRouters: state => state.permission.addRouters
}; }
export default getters export default getters

View File

@ -1,11 +1,11 @@
import Vue from 'vue'; import Vue from 'vue'
import Vuex from 'vuex'; import Vuex from 'vuex'
import app from './modules/app'; import app from './modules/app'
import user from './modules/user'; import user from './modules/user'
import permission from './modules/permission'; import permission from './modules/permission'
import getters from './getters'; import getters from './getters'
Vue.use(Vuex); Vue.use(Vuex)
const store = new Vuex.Store({ const store = new Vuex.Store({
modules: { modules: {
@ -14,6 +14,6 @@ const store = new Vuex.Store({
permission permission
}, },
getters getters
}); })
export default store export default store

View File

@ -1,4 +1,4 @@
import Cookies from 'js-cookie'; import Cookies from 'js-cookie'
const app = { const app = {
state: { state: {
@ -12,11 +12,11 @@ const app = {
mutations: { mutations: {
TOGGLE_SIDEBAR: state => { TOGGLE_SIDEBAR: state => {
if (state.sidebar.opened) { if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1); Cookies.set('sidebarStatus', 1)
} else { } else {
Cookies.set('sidebarStatus', 0); Cookies.set('sidebarStatus', 0)
} }
state.sidebar.opened = !state.sidebar.opened; state.sidebar.opened = !state.sidebar.opened
}, },
ADD_VISITED_VIEWS: (state, view) => { ADD_VISITED_VIEWS: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return if (state.visitedViews.some(v => v.path === view.path)) return
@ -44,6 +44,6 @@ const app = {
commit('DEL_VISITED_VIEWS', view) commit('DEL_VISITED_VIEWS', view)
} }
} }
}; }
export default app; export default app

View File

@ -52,11 +52,11 @@ const permission = {
} else { } else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles) accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
} }
commit('SET_ROUTERS', accessedRouters); commit('SET_ROUTERS', accessedRouters)
resolve(); resolve()
}) })
} }
} }
}; }
export default permission; export default permission

View File

@ -1,5 +1,5 @@
import { loginByUsername, logout, getInfo } from 'api/login'; import { loginByUsername, logout, getInfo } from 'api/login'
import { getToken, setToken, removeToken } from 'utils/auth'; import { getToken, setToken, removeToken } from 'utils/auth'
const user = { const user = {
state: { state: {
@ -18,110 +18,110 @@ const user = {
mutations: { mutations: {
SET_CODE: (state, code) => { SET_CODE: (state, code) => {
state.code = code; state.code = code
}, },
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = token; state.token = token
}, },
SET_INTRODUCTION: (state, introduction) => { SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction; state.introduction = introduction
}, },
SET_SETTING: (state, setting) => { SET_SETTING: (state, setting) => {
state.setting = setting; state.setting = setting
}, },
SET_STATUS: (state, status) => { SET_STATUS: (state, status) => {
state.status = status; state.status = status
}, },
SET_NAME: (state, name) => { SET_NAME: (state, name) => {
state.name = name; state.name = name
}, },
SET_AVATAR: (state, avatar) => { SET_AVATAR: (state, avatar) => {
state.avatar = avatar; state.avatar = avatar
}, },
SET_ROLES: (state, roles) => { SET_ROLES: (state, roles) => {
state.roles = roles; state.roles = roles
} }
}, },
actions: { actions: {
// 用户名登录 // 用户名登录
LoginByUsername({ commit }, userInfo) { LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim(); const username = userInfo.username.trim()
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => { loginByUsername(username, userInfo.password).then(response => {
const data = response.data; const data = response.data
setToken(response.data.token); setToken(response.data.token)
commit('SET_TOKEN', data.token); commit('SET_TOKEN', data.token)
resolve(); resolve()
}).catch(error => { }).catch(error => {
reject(error); reject(error)
}); })
}); })
}, },
// 获取用户信息 // 获取用户信息
GetInfo({ commit, state }) { GetInfo({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo(state.token).then(response => { getInfo(state.token).then(response => {
const data = response.data; const data = response.data
commit('SET_ROLES', data.role); commit('SET_ROLES', data.role)
commit('SET_NAME', data.name); commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar); commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction); commit('SET_INTRODUCTION', data.introduction)
resolve(response); resolve(response)
}).catch(error => { }).catch(error => {
reject(error); reject(error)
}); })
}); })
}, },
// 第三方验证登录 // 第三方验证登录
LoginByThirdparty({ commit, state }, code) { // LoginByThirdparty({ commit, state }, code) {
return new Promise((resolve, reject) => { // return new Promise((resolve, reject) => {
commit('SET_CODE', code); // commit('SET_CODE', code)
loginByThirdparty(state.status, state.email, state.code).then(response => { // loginByThirdparty(state.status, state.email, state.code).then(response => {
commit('SET_TOKEN', response.data.token); // commit('SET_TOKEN', response.data.token)
setToken(response.data.token); // setToken(response.data.token)
resolve(); // resolve()
}).catch(error => { // }).catch(error => {
reject(error); // reject(error)
}); // })
}); // })
}, // },
// 登出 // 登出
LogOut({ commit, state }) { LogOut({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { logout(state.token).then(() => {
commit('SET_TOKEN', ''); commit('SET_TOKEN', '')
commit('SET_ROLES', []); commit('SET_ROLES', [])
removeToken(); removeToken()
resolve(); resolve()
}).catch(error => { }).catch(error => {
reject(error); reject(error)
}); })
}); })
}, },
// 前端 登出 // 前端 登出
FedLogOut({ commit }) { FedLogOut({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', ''); commit('SET_TOKEN', '')
removeToken(); removeToken()
resolve(); resolve()
}); })
}, },
// 动态修改权限 // 动态修改权限
ChangeRole({ commit }, role) { ChangeRole({ commit }, role) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_ROLES', [role]); commit('SET_ROLES', [role])
commit('SET_TOKEN', role); commit('SET_TOKEN', role)
setToken(role); setToken(role)
resolve(); resolve()
}) })
} }
} }
}; }
export default user; export default user

View File

@ -2,7 +2,7 @@
* Created by jiachenpan on 17/3/8. * Created by jiachenpan on 17/3/8.
*/ */
export default function createUniqueString() { export default 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)
} }

View File

@ -1,25 +1,25 @@
import axios from 'axios'; import axios from 'axios'
import { Message } from 'element-ui'; import { Message } from 'element-ui'
import store from '../store'; import store from '../store'
import { getToken } from 'utils/auth'; import { getToken } from 'utils/auth'
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url baseURL: process.env.BASE_API, // api的base_url
timeout: 5000 // 请求超时时间 timeout: 5000 // 请求超时时间
}); })
// request拦截器 // request拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(config => {
// Do something before request is sent // Do something before request is sent
if (store.getters.token) { if (store.getters.token) {
config.headers['X-Token'] = getToken(); // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改 config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
} }
return config; return config
}, error => { }, error => {
// Do something with request error // Do something with request error
console.log(error); // for debug console.log(error) // for debug
Promise.reject(error); Promise.reject(error)
}) })
// respone拦截器 // respone拦截器
@ -53,14 +53,14 @@ service.interceptors.response.use(
// return response.data; // return response.data;
// } // }
error => { error => {
console.log('err' + error);// for debug console.log('err' + error)// for debug
Message({ Message({
message: error.message, message: error.message,
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
}); })
return Promise.reject(error); return Promise.reject(error)
} }
) )
export default service; export default service

View File

@ -4,15 +4,15 @@
export function parseTime(time, cFormat) { export function parseTime(time, cFormat) {
if (arguments.length === 0) { if (arguments.length === 0) {
return null; return null
} }
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'; const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date; let date
if (typeof time == 'object') { if (typeof time === 'object') {
date = time; date = time
} else { } else {
if (('' + time).length === 10) time = parseInt(time) * 1000; if (('' + time).length === 10) time = parseInt(time) * 1000
date = new Date(time); date = new Date(time)
} }
const formatObj = { const formatObj = {
y: date.getFullYear(), y: date.getFullYear(),
@ -22,24 +22,24 @@
i: date.getMinutes(), i: date.getMinutes(),
s: date.getSeconds(), s: date.getSeconds(),
a: date.getDay() a: date.getDay()
}; }
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]; let value = formatObj[key]
if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]; if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
if (result.length > 0 && value < 10) { if (result.length > 0 && value < 10) {
value = '0' + value; value = '0' + value
} }
return value || 0; return value || 0
}); })
return time_str; return time_str
} }
export function formatTime(time, option) { export function formatTime(time, option) {
time = +time * 1000; time = +time * 1000
const d = new Date(time); const d = new Date(time)
const now = Date.now(); const now = Date.now()
const diff = (now - d) / 1000; const diff = (now - d) / 1000
if (diff < 30) { if (diff < 30) {
return '刚刚' return '刚刚'
@ -59,67 +59,66 @@
// 格式化时间 // 格式化时间
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)
const obj = {}; const obj = {}
const reg = /([^?&=]+)=([^?&=]*)/g; const reg = /([^?&=]+)=([^?&=]*)/g
search.replace(reg, (rs, $1, $2) => { search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1); const name = decodeURIComponent($1)
let val = decodeURIComponent($2); let val = decodeURIComponent($2)
val = String(val); val = String(val)
obj[name] = val; obj[name] = val
return rs; return rs
}); })
return obj; return obj
} }
/** /**
*get getByteLen *get getByteLen
* @param {Sting} val input value * @param {Sting} val input value
* @returns {number} output value * @returns {number} output value
*/ */
export function getByteLen(val) { export function getByteLen(val) {
let len = 0; let len = 0
for (let i = 0; i < val.length; i++) { for (let i = 0; i < val.length; i++) {
if (val[i].match(/[^\x00-\xff]/ig) != null) { if (val[i].match(/[^\x00-\xff]/ig) != null) {
len += 1; len += 1
} else { len += 0.5; } } else { len += 0.5 }
} }
return Math.floor(len); return Math.floor(len)
} }
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++) {
if (actual[i]) { if (actual[i]) {
newArray.push(actual[i]); newArray.push(actual[i])
} }
} }
return newArray; return newArray
} }
export function param(json) { export function param(json) {
if (!json) return ''; if (!json) return ''
return cleanArray(Object.keys(json).map(key => { return cleanArray(Object.keys(json).map(key => {
if (json[key] === undefined) return ''; if (json[key] === undefined) return ''
return encodeURIComponent(key) + '=' + return encodeURIComponent(key) + '=' +
encodeURIComponent(json[key]); encodeURIComponent(json[key])
})).join('&'); })).join('&')
} }
export function param2Obj(url) { export function param2Obj(url) {
const search = url.split('?')[1]; const search = url.split('?')[1]
if (!search) { if (!search) {
return {} return {}
} }
return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}'); return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
} }
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
} }
export function objectMerge(target, source) { export function objectMerge(target, source) {
@ -127,83 +126,82 @@
giving the last one precedence */ giving the last one precedence */
if (typeof target !== 'object') { if (typeof target !== 'object') {
target = {}; target = {}
} }
if (Array.isArray(source)) { if (Array.isArray(source)) {
return source.slice(); return source.slice()
} }
for (const property in source) { for (const property in source) {
if (source.hasOwnProperty(property)) { if (source.hasOwnProperty(property)) {
const sourceProperty = source[property]; const sourceProperty = source[property]
if (typeof sourceProperty === 'object') { if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty); target[property] = objectMerge(target[property], sourceProperty)
continue; continue
} }
target[property] = sourceProperty; target[property] = sourceProperty
} }
} }
return target; return target
} }
export function scrollTo(element, to, duration) { export function scrollTo(element, to, duration) {
if (duration <= 0) return; if (duration <= 0) return
const difference = to - element.scrollTop; const difference = to - element.scrollTop
const perTick = difference / duration * 10; const perTick = difference / duration * 10
setTimeout(() => { setTimeout(() => {
console.log(new Date()) console.log(new Date())
element.scrollTop = element.scrollTop + perTick; element.scrollTop = element.scrollTop + perTick
if (element.scrollTop === to) return; if (element.scrollTop === to) return
scrollTo(element, to, duration - 10); scrollTo(element, to, duration - 10)
}, 10); }, 10)
} }
export function toggleClass(element, className) { export function toggleClass(element, className) {
if (!element || !className) { if (!element || !className) {
return; return
} }
let classString = element.className; let classString = element.className
const nameIndex = classString.indexOf(className); const nameIndex = classString.indexOf(className)
if (nameIndex === -1) { if (nameIndex === -1) {
classString += '' + className; classString += '' + className
} else { } else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length); classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length)
} }
element.className = classString; element.className = classString
} }
export const pickerOptions = [ export const pickerOptions = [
{ {
text: '今天', text: '今天',
onClick(picker) { onClick(picker) {
const end = new Date(); const end = new Date()
const start = new Date(new Date().toDateString()); const start = new Date(new Date().toDateString())
end.setTime(start.getTime()); end.setTime(start.getTime())
picker.$emit('pick', [start, end]); picker.$emit('pick', [start, end])
} }
}, { }, {
text: '最近一周', text: '最近一周',
onClick(picker) { onClick(picker) {
const end = new Date(new Date().toDateString()); const end = new Date(new Date().toDateString())
const start = new Date(); const start = new Date()
start.setTime(end.getTime() - 3600 * 1000 * 24 * 7); start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end]); picker.$emit('pick', [start, end])
} }
}, { }, {
text: '最近一个月', text: '最近一个月',
onClick(picker) { onClick(picker) {
const end = new Date(new Date().toDateString()); const end = new Date(new Date().toDateString())
const start = new Date(); const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end]); picker.$emit('pick', [start, end])
} }
}, { }, {
text: '最近三个月', text: '最近三个月',
onClick(picker) { onClick(picker) {
const end = new Date(new Date().toDateString()); const end = new Date(new Date().toDateString())
const start = new Date(); const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end]); picker.$emit('pick', [start, end])
} }
}] }]
@ -216,55 +214,54 @@
} }
export function debounce(func, wait, immediate) { export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result; let timeout, args, context, timestamp, result
const later = function() { const later = function() {
// 据上一次触发时间间隔 // 据上一次触发时间间隔
const last = +new Date() - timestamp; const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if (last < wait && last > 0) { if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last); timeout = setTimeout(later, wait - last)
} else { } else {
timeout = null; timeout = null
// 如果设定为immediate===true因为开始边界已经调用过了此处无需调用 // 如果设定为immediate===true因为开始边界已经调用过了此处无需调用
if (!immediate) { if (!immediate) {
result = func.apply(context, args); result = func.apply(context, args)
if (!timeout) context = args = null; if (!timeout) context = args = null
} }
} }
}; }
return function(...args) { return function(...args) {
context = this; context = this
timestamp = +new Date(); timestamp = +new Date()
const callNow = immediate && !timeout; const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时 // 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait); if (!timeout) timeout = setTimeout(later, wait)
if (callNow) { if (callNow) {
result = func.apply(context, args); result = func.apply(context, args)
context = args = null; context = args = null
} }
return result; return result
}; }
} }
export function deepClone(source) { export function deepClone(source) {
if (!source && typeof source !== 'object') { if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'shallowClone'); throw new Error('error arguments', 'shallowClone')
} }
const targetObj = source.constructor === Array ? [] : {}; const targetObj = source.constructor === Array ? [] : {}
for (const keys in source) { for (const keys in source) {
if (source.hasOwnProperty(keys)) { if (source.hasOwnProperty(keys)) {
if (source[keys] && typeof source[keys] === 'object') { if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = source[keys].constructor === Array ? [] : {}
targetObj[keys] = deepClone(source[keys]); targetObj[keys] = deepClone(source[keys])
} else { } else {
targetObj[keys] = source[keys]; targetObj[keys] = source[keys]
} }
} }
} }
return targetObj; return targetObj
} }

View File

@ -8,20 +8,19 @@
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
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width
const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height
const left = ((width / 2) - (w / 2)) + dualScreenLeft; const left = ((width / 2) - (w / 2)) + dualScreenLeft
const top = ((height / 2) - (h / 2)) + dualScreenTop; const top = ((height / 2) - (h / 2)) + dualScreenTop
const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left); const newWindow = window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left)
// Puts focus on the newWindow // Puts focus on the newWindow
if (window.focus) { if (window.focus) {
newWindow.focus(); newWindow.focus()
} }
} }

View File

@ -5,19 +5,19 @@
/* 是否是公司邮箱*/ /* 是否是公司邮箱*/
export function isvalidUsername(str) { export function isvalidUsername(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
} }
/* 合法uri*/ /* 合法uri*/
export function validateURL(textval) { export function validateURL(textval) {
const urlregex = /^(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 urlregex = /^(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 urlregex.test(textval); return urlregex.test(textval)
} }
/* 小写字母*/ /* 小写字母*/
export function validateLowerCase(str) { export function validateLowerCase(str) {
const reg = /^[a-z]+$/; const reg = /^[a-z]+$/
return reg.test(str); return reg.test(str)
} }
/* 验证key*/ /* 验证key*/
@ -28,14 +28,13 @@ export function validateLowerCase(str) {
/* 大写字母*/ /* 大写字母*/
export function validateUpperCase(str) { export function validateUpperCase(str) {
const reg = /^[A-Z]+$/; const reg = /^[A-Z]+$/
return reg.test(str); return reg.test(str)
} }
/* 大小写字母*/ /* 大小写字母*/
export function validatAlphabets(str) { export function validatAlphabets(str) {
const reg = /^[A-Za-z]+$/; const reg = /^[A-Za-z]+$/
return reg.test(str); return reg.test(str)
} }

View File

@ -7,11 +7,11 @@
</template> </template>
<script> <script>
import keyboardChart from 'components/Charts/keyboard'; import keyboardChart from 'components/Charts/keyboard'
export default { export default {
components: { keyboardChart } components: { keyboardChart }
}; }
</script> </script>
<style scoped> <style scoped>

View File

@ -7,11 +7,11 @@
</template> </template>
<script> <script>
import keyboardChart2 from 'components/Charts/keyboard2'; import keyboardChart2 from 'components/Charts/keyboard2'
export default { export default {
components: { keyboardChart2 } components: { keyboardChart2 }
}; }
</script> </script>
<style scoped> <style scoped>

View File

@ -7,11 +7,11 @@
</template> </template>
<script> <script>
import lineMarker from 'components/Charts/lineMarker'; import lineMarker from 'components/Charts/lineMarker'
export default { export default {
components: { lineMarker } components: { lineMarker }
}; }
</script> </script>
<style scoped> <style scoped>

View File

@ -7,11 +7,11 @@
</template> </template>
<script> <script>
import mixChart from 'components/Charts/mixChart'; import mixChart from 'components/Charts/mixChart'
export default { export default {
components: { mixChart } components: { mixChart }
}; }
</script> </script>
<style scoped> <style scoped>

View File

@ -14,29 +14,29 @@
</template> </template>
<script> <script>
import ImageCropper from 'components/ImageCropper'; import ImageCropper from 'components/ImageCropper'
import PanThumb from 'components/PanThumb'; import PanThumb from 'components/PanThumb'
export default { export default {
components: { ImageCropper, PanThumb }, components: { ImageCropper, PanThumb },
data() { data() {
return { return {
imagecropperShow: false, imagecropperShow: false,
imagecropperKey: 0, imagecropperKey: 0,
image: 'https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191' image: 'https://wpimg.wallstcn.com/577965b9-bb9e-4e02-9f0c-095b41417191'
}
},
methods: {
cropSuccess(resData) {
this.imagecropperShow = false;
this.imagecropperKey = this.imagecropperKey + 1;
this.image = resData.files.avatar;
},
close() {
this.imagecropperShow = false;
}
} }
}; },
methods: {
cropSuccess(resData) {
this.imagecropperShow = false
this.imagecropperKey = this.imagecropperKey + 1
this.image = resData.files.avatar
},
close() {
this.imagecropperShow = false
}
}
}
</script> </script>
<style scoped> <style scoped>

View File

@ -135,21 +135,22 @@
</template> </template>
<script> <script>
import BackToTop from 'components/BackToTop'; import BackToTop from 'components/BackToTop'
export default {
components: { BackToTop }, export default {
data() { components: { BackToTop },
return { data() {
myBackToTopStyle: { return {
right: '50px', myBackToTopStyle: {
bottom: '50px', right: '50px',
width: '40px', bottom: '50px',
height: '40px', width: '40px',
'border-radius': '4px', height: '40px',
'line-height': '45px', // 'border-radius': '4px',
background: '#e7eaf1'// 'line-height': '45px', //
} background: '#e7eaf1'//
} }
} }
} }
}
</script> </script>

View File

@ -22,72 +22,73 @@
</template> </template>
<script> <script>
import countTo from 'vue-count-to'; import countTo from 'vue-count-to'
export default {
components: { countTo }, export default {
data() { components: { countTo },
return { data() {
setStartVal: 0, return {
setEndVal: 2017, setStartVal: 0,
setDuration: 4000, setEndVal: 2017,
setDecimals: 0, setDuration: 4000,
setSeparator: ',', setDecimals: 0,
setSuffix: ' rmb', setSeparator: ',',
setPrefix: '¥ ' setSuffix: ' rmb',
} setPrefix: '¥ '
},
computed: {
_startVal() {
if (this.setStartVal) {
return this.setStartVal
} else {
return 0
}
},
_endVal() {
if (this.setEndVal) {
return this.setEndVal
} else {
return 0
}
},
_duration() {
if (this.setDuration) {
return this.setDuration
} else {
return 100
}
},
_decimals() {
if (this.setDecimals) {
if (this.setDecimals < 0 || this.setDecimals > 20) {
alert('digits argument must be between 0 and 20')
return 0
}
return this.setDecimals
} else {
return 0
}
},
_separator() {
return this.setSeparator
},
_suffix() {
return this.setSuffix
},
_prefix() {
return this.setPrefix
}
},
methods: {
start() {
this.$refs.example.start();
},
pauseResume() {
this.$refs.example.pauseResume();
}
} }
}; },
computed: {
_startVal() {
if (this.setStartVal) {
return this.setStartVal
} else {
return 0
}
},
_endVal() {
if (this.setEndVal) {
return this.setEndVal
} else {
return 0
}
},
_duration() {
if (this.setDuration) {
return this.setDuration
} else {
return 100
}
},
_decimals() {
if (this.setDecimals) {
if (this.setDecimals < 0 || this.setDecimals > 20) {
alert('digits argument must be between 0 and 20')
return 0
}
return this.setDecimals
} else {
return 0
}
},
_separator() {
return this.setSeparator
},
_suffix() {
return this.setSuffix
},
_prefix() {
return this.setPrefix
}
},
methods: {
start() {
this.$refs.example.start()
},
pauseResume() {
this.$refs.example.pauseResume()
}
}
}
</script> </script>
<style scoped> <style scoped>

View File

@ -8,31 +8,31 @@
</template> </template>
<script> <script>
import DndList from 'components/twoDndList' import DndList from 'components/twoDndList'
import { getList } from 'api/article'; import { getList } from 'api/article'
export default { export default {
components: { DndList }, components: { DndList },
data() { data() {
return { return {
list1: [], list1: [],
list2: [] list2: []
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.listLoading = true;
getList(this.listQuery).then(response => {
this.list1 = response.data.splice(0, 5);
this.list2 = response.data;
console.log(this.list1, this.list2)
})
}
} }
}; },
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getList(this.listQuery).then(response => {
this.list1 = response.data.splice(0, 5)
this.list2 = response.data
console.log(this.list1, this.list2)
})
}
}
}
</script> </script>

View File

@ -10,21 +10,21 @@
</template> </template>
<script> <script>
import Dropzone from 'components/Dropzone'; import Dropzone from 'components/Dropzone'
export default { export default {
components: { Dropzone }, components: { Dropzone },
methods: { methods: {
dropzoneS(file) { dropzoneS(file) {
console.log(file) console.log(file)
this.$message({ message: '上传成功', type: 'success' }); this.$message({ message: '上传成功', type: 'success' })
}, },
dropzoneR(file) { dropzoneR(file) {
console.log(file) console.log(file)
this.$message({ message: '删除成功', type: 'success' }); this.$message({ message: '删除成功', type: 'success' })
}
} }
}; }
}
</script> </script>

View File

@ -8,17 +8,17 @@
</template> </template>
<script> <script>
import jsonEditor from 'components/jsonEditor'; import jsonEditor from 'components/jsonEditor'
const jsonData = '[{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"CORN"}],"name":""},{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"XAGUSD"},{"market_type":"forexdata","symbol":"AUTD"},{"market_type":"forexdata","symbol":"AGTD"}],"name":"贵金属"},{"items":[{"market_type":"forexdata","symbol":"CORN"},{"market_type":"forexdata","symbol":"WHEAT"},{"market_type":"forexdata","symbol":"SOYBEAN"},{"market_type":"forexdata","symbol":"SUGAR"}],"name":"农产品"},{"items":[{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"USOIL"},{"market_type":"forexdata","symbol":"NGAS"}],"name":"能源化工"}]'; const jsonData = '[{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"CORN"}],"name":""},{"items":[{"market_type":"forexdata","symbol":"XAUUSD"},{"market_type":"forexdata","symbol":"XAGUSD"},{"market_type":"forexdata","symbol":"AUTD"},{"market_type":"forexdata","symbol":"AGTD"}],"name":"贵金属"},{"items":[{"market_type":"forexdata","symbol":"CORN"},{"market_type":"forexdata","symbol":"WHEAT"},{"market_type":"forexdata","symbol":"SOYBEAN"},{"market_type":"forexdata","symbol":"SUGAR"}],"name":"农产品"},{"items":[{"market_type":"forexdata","symbol":"UKOIL"},{"market_type":"forexdata","symbol":"USOIL"},{"market_type":"forexdata","symbol":"NGAS"}],"name":"能源化工"}]'
export default { export default {
components: { jsonEditor }, components: { jsonEditor },
data() { data() {
return { return {
value: JSON.parse(jsonData) value: JSON.parse(jsonData)
}
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -10,24 +10,24 @@
</template> </template>
<script> <script>
import MdEditor from 'components/MdEditor'; import MdEditor from 'components/MdEditor'
export default { export default {
components: { MdEditor }, components: { MdEditor },
data() { data() {
return { return {
content: '## Simplemde', content: '## Simplemde',
html: '' html: ''
}
},
methods: {
markdown2Html() {
import('showdown').then(showdown => {
const converter = new showdown.Converter();
this.html = converter.makeHtml(this.content)
})
}
} }
}; },
methods: {
markdown2Html() {
import('showdown').then(showdown => {
const converter = new showdown.Converter()
this.html = converter.makeHtml(this.content)
})
}
}
}
</script> </script>

View File

@ -22,21 +22,21 @@
</template> </template>
<script> <script>
import MdInput from 'components/MDinput'; import MdInput from 'components/MDinput'
import PanThumb from 'components/PanThumb'; import PanThumb from 'components/PanThumb'
import waves from '@/directive/waves.js';// import waves from '@/directive/waves.js'//
export default { export default {
components: { MdInput, PanThumb }, components: { MdInput, PanThumb },
directives: { directives: {
waves waves
}, },
data() { data() {
return { return {
title: '' title: ''
}
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -23,16 +23,16 @@
</template> </template>
<script> <script>
import splitPane from 'components/SplitPane' import splitPane from 'components/SplitPane'
export default { export default {
components: { splitPane }, components: { splitPane },
methods: { methods: {
resize() { resize() {
console.log('resize') console.log('resize')
}
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -94,28 +94,28 @@
<script> <script>
import Sticky from 'components/Sticky'; import Sticky from 'components/Sticky'
export default { export default {
components: { Sticky }, components: { Sticky },
data() { data() {
return { return {
time: '', time: '',
url: '', url: '',
platforms: ['a-platform'], platforms: ['a-platform'],
platformsOptions: [ platformsOptions: [
{ key: 'a-platform', name: '平台A' }, { key: 'a-platform', name: '平台A' },
{ key: 'b-platform', name: '平台B' }, { key: 'b-platform', name: '平台B' },
{ key: 'c-platform', name: '平台C' } { key: 'c-platform', name: '平台C' }
], ],
pickerOptions: { pickerOptions: {
disabledDate(time) { disabledDate(time) {
return time.getTime() > Date.now(); return time.getTime() > Date.now()
}
} }
} }
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -9,16 +9,16 @@
</template> </template>
<script> <script>
import Tinymce from 'components/Tinymce'; import Tinymce from 'components/Tinymce'
export default { export default {
components: { Tinymce }, components: { Tinymce },
data() { data() {
return { return {
content: 'Tinymce' content: 'Tinymce'
}
} }
}; }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -26,25 +26,25 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex'
import PanThumb from 'components/PanThumb'; import PanThumb from 'components/PanThumb'
export default { export default {
name: 'dashboard-default', name: 'dashboard-default',
components: { PanThumb }, components: { PanThumb },
data() { data() {
return { return {
emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3'
}
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
} }
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -3,90 +3,91 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
require('echarts/theme/macarons'); // echarts require('echarts/theme/macarons') // echarts
const animationDuration = 3000;
export default {
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
};
},
mounted() {
this.initChart();
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons');
this.chart.setOption({ const animationDuration = 3000
tooltip: { export default {
trigger: 'axis', props: {
axisPointer: { // className: {
type: 'shadow' // 线'line' | 'shadow' type: String,
} default: 'chart'
}, },
grid: { width: {
left: '3%', type: String,
right: '4%', default: '100%'
bottom: '3%', },
containLabel: true height: {
}, type: String,
xAxis: [{ default: '300px'
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value'
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
} }
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value'
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
}
} }
</script> </script>

View File

@ -75,35 +75,36 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex'
import panThumb from 'components/PanThumb'; import panThumb from 'components/PanThumb'
import pieChart from './pieChart'; import pieChart from './pieChart'
import barChart from './barChart'; import barChart from './barChart'
import lineChart from './lineChart'; import lineChart from './lineChart'
import countTo from 'vue-count-to'; import countTo from 'vue-count-to'
import todoList from 'components/TodoList'; import todoList from 'components/TodoList'
export default {
name: 'dashboard-editor', export default {
components: { panThumb, countTo, pieChart, lineChart, barChart, todoList }, name: 'dashboard-editor',
data() { components: { panThumb, countTo, pieChart, lineChart, barChart, todoList },
data() {
return { return {
statisticsData: { statisticsData: {
article_count: 1024, article_count: 1024,
comment_count: 102400, comment_count: 102400,
latest_article: [], latest_article: [],
month_article_count: 28, month_article_count: 28,
pageviews_count: 1024 pageviews_count: 1024
} }
} }
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'name', 'name',
'avatar', 'avatar',
'roles' 'roles'
]) ])
} }
} }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -3,120 +3,120 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
require('echarts/theme/macarons'); // echarts require('echarts/theme/macarons') // echarts
import { debounce } from 'utils'; import { debounce } from 'utils'
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
}
}, },
data() { width: {
return { type: String,
chart: null default: '100%'
};
}, },
mounted() { height: {
this.initChart(); type: String,
if (this.autoResize) { default: '350px'
this.__resizeHanlder = debounce(() => { },
if (this.chart) { autoResize: {
this.chart.resize() type: Boolean,
} default: true
}, 100) }
window.addEventListener('resize', this.__resizeHanlder) },
} data() {
return {
chart: null
}
},
mounted() {
this.initChart()
if (this.autoResize) {
this.__resizeHanlder = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener('resize', this.__resizeHanlder)
}
// //
const sidebarElm = document.getElementsByClassName('sidebar-container')[0] const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
sidebarElm.addEventListener('transitionend', this.__resizeHanlder) sidebarElm.addEventListener('transitionend', this.__resizeHanlder)
}, },
beforeDestroy() { beforeDestroy() {
if (!this.chart) { if (!this.chart) {
return return
} }
if (this.autoResize) { if (this.autoResize) {
window.removeEventListener('resize', this.__resizeHanlder) window.removeEventListener('resize', this.__resizeHanlder)
} }
const sidebarElm = document.getElementsByClassName('sidebar-container')[0] const sidebarElm = document.getElementsByClassName('sidebar-container')[0]
sidebarElm.removeEventListener('transitionend', this.__resizeHanlder) sidebarElm.removeEventListener('transitionend', this.__resizeHanlder)
this.chart.dispose() this.chart.dispose()
this.chart = null this.chart = null
}, },
methods: { methods: {
initChart() { initChart() {
this.chart = echarts.init(this.$el, 'macarons'); this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({ this.chart.setOption({
xAxis: { xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
boundaryGap: false boundaryGap: false
}, },
grid: { grid: {
left: 10, left: 10,
right: 10, right: 10,
bottom: 20, bottom: 20,
containLabel: true containLabel: true
}, },
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
type: 'cross' type: 'cross'
}
},
yAxis: {},
series: [{
name: 'visitors',
itemStyle: {
normal: {
areaStyle: {}
} }
}, },
yAxis: {}, smooth: true,
series: [{ type: 'line',
name: 'visitors', data: [100, 120, 161, 134, 105, 160, 165],
itemStyle: { animationDuration: 2600,
normal: { animationEasing: 'cubicInOut'
areaStyle: {} },
{
name: 'buyers',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: 'rgba(2, 197, 233, 0.2)',
lineStyle: {
color: 'rgba(2, 197, 233, 0.2)'
},
areaStyle: {
color: 'rgba(99,194,255, 0.6)'
} }
}, }
smooth: true,
type: 'line',
data: [100, 120, 161, 134, 105, 160, 165],
animationDuration: 2600,
animationEasing: 'cubicInOut'
}, },
{ data: [120, 82, 91, 154, 162, 140, 130],
name: 'buyers', animationDuration: 2000,
smooth: true, animationEasing: 'quadraticOut'
type: 'line', }]
itemStyle: { })
normal: {
color: 'rgba(2, 197, 233, 0.2)',
lineStyle: {
color: 'rgba(2, 197, 233, 0.2)'
},
areaStyle: {
color: 'rgba(99,194,255, 0.6)'
}
}
},
data: [120, 82, 91, 154, 162, 140, 130],
animationDuration: 2000,
animationEasing: 'quadraticOut'
}]
})
}
} }
}
} }
</script> </script>

View File

@ -3,77 +3,77 @@
</template> </template>
<script> <script>
import echarts from 'echarts'; import echarts from 'echarts'
require('echarts/theme/macarons'); // echarts require('echarts/theme/macarons') // echarts
export default { export default {
props: { props: {
className: { className: {
type: String, type: String,
default: 'chart' default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
}, },
data() { width: {
return { type: String,
chart: null default: '100%'
};
}, },
mounted() { height: {
this.initChart(); type: String,
}, default: '300px'
beforeDestroy() { }
if (!this.chart) { },
return data() {
} return {
this.chart.dispose(); chart: null
this.chart = null; }
}, },
methods: { mounted() {
initChart() { this.initChart()
this.chart = echarts.init(this.$el, 'macarons'); },
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({ this.chart.setOption({
title: { title: {
text: 'WEEKLY WRITE ARTICLES', text: 'WEEKLY WRITE ARTICLES',
x: 'center' x: 'center'
}, },
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)' formatter: '{a} <br/>{b} : {c} ({d}%)'
}, },
legend: { legend: {
x: 'center', x: 'center',
y: 'bottom', y: 'bottom',
data: ['industries', 'technology', 'forex', 'gold', 'forecasts', 'markets'] data: ['industries', 'technology', 'forex', 'gold', 'forecasts', 'markets']
}, },
calculable: true, calculable: true,
series: [ series: [
{ {
name: 'WEEKLY WRITE ARTICLES', name: 'WEEKLY WRITE ARTICLES',
type: 'pie', type: 'pie',
roseType: 'radius', roseType: 'radius',
data: [ data: [
{ value: 320, name: 'industries' }, { value: 320, name: 'industries' },
{ value: 240, name: 'technology' }, { value: 240, name: 'technology' },
{ value: 149, name: 'forex' }, { value: 149, name: 'forex' },
{ value: 100, name: 'gold' }, { value: 100, name: 'gold' },
{ value: 59, name: 'forecasts' }, { value: 59, name: 'forecasts' },
{ value: 49, name: 'markets' } { value: 49, name: 'markets' }
], ],
animationEasing: 'cubicInOut', animationEasing: 'cubicInOut',
animationDuration: 2600 animationDuration: 2600
} }
] ]
}) })
}
} }
}
} }
</script> </script>

View File

@ -5,31 +5,31 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex'
import EditorDashboard from './editor/index'; import EditorDashboard from './editor/index'
import DefaultDashboard from './default/index'; import DefaultDashboard from './default/index'
export default { export default {
name: 'dashboard', name: 'dashboard',
components: { EditorDashboard, DefaultDashboard }, components: { EditorDashboard, DefaultDashboard },
data() { data() {
return { return {
currentRole: 'EditorDashboard' currentRole: 'EditorDashboard'
}
},
computed: {
...mapGetters([
'name',
'avatar',
'introduction',
'roles'
])
},
created() {
if (this.roles.indexOf('admin') >= 0) {
return;
}
this.currentRole = 'DefaultDashboard';
} }
},
computed: {
...mapGetters([
'name',
'avatar',
'introduction',
'roles'
])
},
created() {
if (this.roles.indexOf('admin') >= 0) {
return
}
this.currentRole = 'DefaultDashboard'
} }
}
</script> </script>

View File

@ -11,11 +11,11 @@
</template> </template>
<script> <script>
import errCode from './errcode'; import errCode from './errcode'
export default { export default {
components: { errCode } components: { errCode }
}; }
</script> </script>
<style scoped> <style scoped>

View File

@ -28,25 +28,26 @@
</template> </template>
<script> <script>
import errGif from 'assets/401_images/401.gif'; import errGif from 'assets/401_images/401.gif'
export default {
data() { export default {
return { data() {
errGif: errGif + '?' + +new Date(), return {
ewizardClap: 'https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646', errGif: errGif + '?' + +new Date(),
dialogVisible: false ewizardClap: 'https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646',
} dialogVisible: false
}, }
methods: { },
back() { methods: {
if (this.$route.query.noGoBack) { back() {
this.$router.push({ path: '/dashboard' }); if (this.$route.query.noGoBack) {
} else { this.$router.push({ path: '/dashboard' })
this.$router.go(-1); } else {
} this.$router.go(-1)
} }
} }
}; }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -19,22 +19,22 @@
</template> </template>
<script> <script>
import img_404 from '@/assets/404_images/404.png' import img_404 from '@/assets/404_images/404.png'
import img_404_cloud from '@/assets/404_images/404_cloud.png' import img_404_cloud from '@/assets/404_images/404_cloud.png'
export default { export default {
data() { data() {
return { return {
img_404, img_404,
img_404_cloud img_404_cloud
} }
}, },
computed: { computed: {
message() { message() {
return '特朗普说这个页面你不能进......' return '特朗普说这个页面你不能进......'
}
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -120,144 +120,144 @@
</template> </template>
<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 Multiselect from 'vue-multiselect'// 使element-uiselect import Multiselect from 'vue-multiselect'// 使element-uiselect
import 'vue-multiselect/dist/vue-multiselect.min.css'// css import 'vue-multiselect/dist/vue-multiselect.min.css'// css
import Sticky from 'components/Sticky' // header import Sticky from 'components/Sticky' // header
import { validateURL } from 'utils/validate' import { validateURL } from 'utils/validate'
import { getArticle } from 'api/article' import { getArticle } from 'api/article'
import { userSearch } from 'api/remoteSearch' import { userSearch } from 'api/remoteSearch'
export default { export default {
name: 'articleDetail', name: 'articleDetail',
components: { Tinymce, MDinput, Upload, Multiselect, Sticky }, components: { Tinymce, MDinput, Upload, Multiselect, Sticky },
data() { data() {
const validateRequire = (rule, value, callback) => { const validateRequire = (rule, value, callback) => {
if (value === '') { if (value === '') {
this.$message({
message: rule.field + '为必传项',
type: 'error'
})
callback(null)
} else {
callback()
}
}
const validateSourceUri = (rule, value, callback) => {
if (value) {
if (validateURL(value)) {
callback()
} else {
this.$message({ this.$message({
message: rule.field + '为必传项', message: '外链url填写不正确',
type: 'error' type: 'error'
}); })
callback(null) callback(null)
} else {
callback()
} }
}; } else {
const validateSourceUri = (rule, value, callback) => { callback()
if (value) { }
if (validateURL(value)) { }
callback() return {
} else { postForm: {
this.$message({ title: '', //
message: '外链url填写不正确', content: '', //
type: 'error' content_short: '', //
}); source_uri: '', //
callback(null) image_uri: '', //
} source_name: '', //
} else { display_time: undefined, //
callback() id: undefined,
} platforms: ['a-platform']
}; },
return { fetchSuccess: true,
postForm: { loading: false,
title: '', // userLIstOptions: [],
content: '', // platformsOptions: [
content_short: '', //
source_uri: '', //
image_uri: '', //
source_name: '', //
display_time: undefined, //
id: undefined,
platforms: ['a-platform']
},
fetchSuccess: true,
loading: false,
userLIstOptions: [],
platformsOptions: [
{ key: 'a-platform', name: 'a-platform' }, { key: 'a-platform', name: 'a-platform' },
{ key: 'b-platform', name: 'b-platform' }, { key: 'b-platform', name: 'b-platform' },
{ key: 'c-platform', name: 'c-platform' } { key: 'c-platform', name: 'c-platform' }
], ],
rules: { rules: {
image_uri: [{ validator: validateRequire }], image_uri: [{ validator: validateRequire }],
title: [{ validator: validateRequire }], title: [{ validator: validateRequire }],
content: [{ validator: validateRequire }], content: [{ validator: validateRequire }],
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }] source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
}
}
},
computed: {
contentShortLength() {
return this.postForm.content_short.length
},
isEdit() {
return this.$route.meta.isEdit // meta
// return this.$route.path.indexOf('edit') !== -1 //
}
},
created() {
if (this.isEdit) {
this.fetchData();
}
},
methods: {
fetchData() {
getArticle().then(response => {
this.postForm = response.data;
}).catch(err => {
this.fetchSuccess = false;
console.log(err);
});
},
submitForm() {
this.postForm.display_time = parseInt(this.display_time / 1000);
console.log(this.postForm)
this.$refs.postForm.validate(valid => {
if (valid) {
this.loading = true;
this.$notify({
title: '成功',
message: '发布文章成功',
type: 'success',
duration: 2000
});
this.postForm.status = 'published';
this.loading = false;
} else {
console.log('error submit!!');
return false;
}
});
},
draftForm() {
if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
this.$message({
message: '请填写必要的标题和内容',
type: 'warning'
});
return;
}
this.$message({
message: '保存成功',
type: 'success',
showClose: true,
duration: 1000
});
this.postForm.status = 'draft';
},
getRemoteUserList(query) {
userSearch(query).then(response => {
if (!response.data.items) return;
console.log(response)
this.userLIstOptions = response.data.items.map(v => ({
key: v.name
}));
})
} }
} }
},
computed: {
contentShortLength() {
return this.postForm.content_short.length
},
isEdit() {
return this.$route.meta.isEdit // meta
// return this.$route.path.indexOf('edit') !== -1 //
}
},
created() {
if (this.isEdit) {
this.fetchData()
}
},
methods: {
fetchData() {
getArticle().then(response => {
this.postForm = response.data
}).catch(err => {
this.fetchSuccess = false
console.log(err)
})
},
submitForm() {
this.postForm.display_time = parseInt(this.display_time / 1000)
console.log(this.postForm)
this.$refs.postForm.validate(valid => {
if (valid) {
this.loading = true
this.$notify({
title: '成功',
message: '发布文章成功',
type: 'success',
duration: 2000
})
this.postForm.status = 'published'
this.loading = false
} else {
console.log('error submit!!')
return false
}
})
},
draftForm() {
if (this.postForm.content.length === 0 || this.postForm.title.length === 0) {
this.$message({
message: '请填写必要的标题和内容',
type: 'warning'
})
return
}
this.$message({
message: '保存成功',
type: 'success',
showClose: true,
duration: 1000
})
this.postForm.status = 'draft'
},
getRemoteUserList(query) {
userSearch(query).then(response => {
if (!response.data.items) return
console.log(response)
this.userLIstOptions = response.data.items.map(v => ({
key: v.name
}))
})
}
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss"; @import "src/styles/mixin.scss";

View File

@ -48,51 +48,51 @@
</template> </template>
<script> <script>
import { fetchList } from 'api/article_table'; import { fetchList } from 'api/article_table'
export default { export default {
name: 'articleDetail', name: 'articleDetail',
props: { props: {
type: { type: {
type: String, type: String,
default: 'CN' default: 'CN'
} }
}, },
data() { data() {
return { return {
list: null, list: null,
total: null, total: null,
listQuery: { listQuery: {
page: 1, page: 1,
limit: 5, limit: 5,
type: this.type, type: this.type,
sort: '+id' sort: '+id'
}
}
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
};
return statusMap[status]
}
},
created() {
this.getList();
},
methods: {
getList() {
this.$emit('create'); // for test
fetchList(this.listQuery).then(response => {
this.list = response.data.items;
this.total = response.data.total;
})
} }
} }
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
created() {
this.getList()
},
methods: {
getList() {
this.$emit('create') // for test
fetchList(this.listQuery).then(response => {
this.list = response.data.items
this.total = response.data.total
})
}
} }
}
</script> </script>

View File

@ -12,29 +12,29 @@
</template> </template>
<script> <script>
import tabPane from './components/tabPane' import tabPane from './components/tabPane'
export default { export default {
name: 'tabDemo', name: 'tabDemo',
components: { tabPane }, components: { tabPane },
data() { data() {
return { return {
tabMapOptions: [ tabMapOptions: [
{ label: '中国', key: 'CN' }, { label: '中国', key: 'CN' },
{ label: '美国', key: 'US' }, { label: '美国', key: 'US' },
{ label: '日本', key: 'JP' }, { label: '日本', key: 'JP' },
{ label: '欧元区', key: 'EU' } { label: '欧元区', key: 'EU' }
], ],
activeName: 'CN', activeName: 'CN',
createdTimes: 0 createdTimes: 0
} }
}, },
methods: { methods: {
showCreatedTimes() { showCreatedTimes() {
this.createdTimes = this.createdTimes + 1; this.createdTimes = this.createdTimes + 1
}
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -60,64 +60,64 @@
</template> </template>
<script> <script>
import { fetchList } from 'api/article_table'; import { fetchList } from 'api/article_table'
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
export default { export default {
name: 'drag-table_demo', name: 'drag-table_demo',
data() { data() {
return { return {
list: null, list: null,
total: null, total: null,
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page: 1, page: 1,
limit: 10 limit: 10
},
sortable: null,
olderList: [],
newList: []
}
},
created() {
this.getList();
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
};
return statusMap[status]
}
},
methods: {
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.list = response.data.items;
this.total = response.data.total;
this.listLoading = false;
this.olderList = this.list.map(v => v.id);
this.newList = this.olderList.slice();
this.$nextTick(() => {
this.setSort()
})
})
}, },
setSort() { sortable: null,
const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]; olderList: [],
this.sortable = Sortable.create(el, { newList: []
// handle: '.drag-handler', }
onEnd: evt => { },
const tempIndex = this.newList.splice(evt.oldIndex, 1)[0]; created() {
this.newList.splice(evt.newIndex, 0, tempIndex); this.getList()
} },
}); filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
} }
return statusMap[status]
}
},
methods: {
getList() {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = response.data.items
this.total = response.data.total
this.listLoading = false
this.olderList = this.list.map(v => v.id)
this.newList = this.olderList.slice()
this.$nextTick(() => {
this.setSort()
})
})
},
setSort() {
const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
this.sortable = Sortable.create(el, {
// handle: '.drag-handler',
onEnd: evt => {
const tempIndex = this.newList.splice(evt.oldIndex, 1)[0]
this.newList.splice(evt.newIndex, 0, tempIndex)
}
})
} }
} }
}
</script> </script>
<style > <style >

View File

@ -9,11 +9,11 @@
</template> </template>
<script> <script>
import fixedThead from './dynamictable/fixedThead' import fixedThead from './dynamictable/fixedThead'
import unfixedThead from './dynamictable/unfixedThead' import unfixedThead from './dynamictable/unfixedThead'
export default { export default {
components: { fixedThead, unfixedThead } components: { fixedThead, unfixedThead }
}; }
</script> </script>

View File

@ -22,36 +22,37 @@
</template> </template>
<script> <script>
const defaultFormThead = ['apple', 'banana']; // const defaultFormThead = ['apple', 'banana'] //
export default {
data() { export default {
return { data() {
tableData: [ return {
{ tableData: [
name: 'fruit-1', {
apple: 'apple-10', name: 'fruit-1',
banana: 'banana-10', apple: 'apple-10',
orange: 'orange-10' banana: 'banana-10',
}, orange: 'orange-10'
{ },
name: 'fruit-2', {
apple: 'apple-20', name: 'fruit-2',
banana: 'banana-20', apple: 'apple-20',
orange: 'orange-20' banana: 'banana-20',
} orange: 'orange-20'
], }
key: 1, // table key ],
formTheadOptions: ['apple', 'banana', 'orange'], // key: 1, // table key
checkboxVal: defaultFormThead, // checkboxVal formTheadOptions: ['apple', 'banana', 'orange'], //
formThead: defaultFormThead // checkboxVal: defaultFormThead, // checkboxVal
} formThead: defaultFormThead //
},
watch: {
checkboxVal(valArr) {
this.formThead = this.formTheadOptions.filter(i => valArr.indexOf(i) >= 0);
this.key = this.key + 1;// table
}
} }
}; },
watch: {
checkboxVal(valArr) {
this.formThead = this.formTheadOptions.filter(i => valArr.indexOf(i) >= 0)
this.key = this.key + 1// table
}
}
}
</script> </script>

View File

@ -23,25 +23,25 @@
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
tableData: [ tableData: [
{ {
name: 'fruit-1', name: 'fruit-1',
apple: 'apple-10', apple: 'apple-10',
banana: 'banana-10', banana: 'banana-10',
orange: 'orange-10' orange: 'orange-10'
}, },
{ {
name: 'fruit-2', name: 'fruit-2',
apple: 'apple-20', apple: 'apple-20',
banana: 'banana-20', banana: 'banana-20',
orange: 'orange-20' orange: 'orange-20'
} }
], ],
formThead: ['apple', 'banana'] formThead: ['apple', 'banana']
}
} }
}; }
}
</script> </script>

View File

@ -52,44 +52,44 @@
</template> </template>
<script> <script>
import { fetchList } from 'api/article_table'; import { fetchList } from 'api/article_table'
export default { export default {
name: 'inline_edit-table_demo', name: 'inline_edit-table_demo',
data() { data() {
return { return {
list: null, list: null,
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page: 1, page: 1,
limit: 10 limit: 10
}
}
},
created() {
this.getList();
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
};
return statusMap[status]
}
},
methods: {
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.list = response.data.items.map(v => {
v.edit = false;
return v
});
this.listLoading = false;
})
} }
} }
},
created() {
this.getList()
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
methods: {
getList() {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = response.data.items.map(v => {
v.edit = false
return v
})
this.listLoading = false
})
}
} }
}
</script> </script>

View File

@ -150,203 +150,203 @@
</template> </template>
<script> <script>
import { fetchList, fetchPv } from 'api/article_table'; import { fetchList, fetchPv } from 'api/article_table'
import waves from '@/directive/waves.js';// import waves from '@/directive/waves.js'//
import { parseTime } from 'utils'; import { parseTime } from 'utils'
const calendarTypeOptions = [ const calendarTypeOptions = [
{ key: 'CN', display_name: '中国' }, { key: 'CN', display_name: '中国' },
{ key: 'US', display_name: '美国' }, { key: 'US', display_name: '美国' },
{ key: 'JP', display_name: '日本' }, { key: 'JP', display_name: '日本' },
{ key: 'EU', display_name: '欧元区' } { key: 'EU', display_name: '欧元区' }
]; ]
// arr to obj // arr to obj
const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => { const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
acc[cur.key] = cur.display_name; acc[cur.key] = cur.display_name
return acc return acc
}, {}); }, {})
export default { export default {
name: 'table_demo', name: 'table_demo',
directives: { directives: {
waves waves
}, },
data() { data() {
return { return {
list: null, list: null,
total: null, total: null,
listLoading: true, listLoading: true,
listQuery: { listQuery: {
page: 1, page: 1,
limit: 20, limit: 20,
importance: undefined, importance: undefined,
title: undefined, title: undefined,
type: undefined, type: undefined,
sort: '+id' sort: '+id'
}, },
temp: { temp: {
id: undefined, id: undefined,
importance: 0, importance: 0,
remark: '', remark: '',
timestamp: 0, timestamp: 0,
title: '', title: '',
type: '', type: '',
status: 'published' status: 'published'
}, },
importanceOptions: [1, 2, 3], importanceOptions: [1, 2, 3],
calendarTypeOptions, calendarTypeOptions,
sortOptions: [{ label: '按ID升序列', key: '+id' }, { label: '按ID降序', key: '-id' }], sortOptions: [{ label: '按ID升序列', key: '+id' }, { label: '按ID降序', key: '-id' }],
statusOptions: ['published', 'draft', 'deleted'], statusOptions: ['published', 'draft', 'deleted'],
dialogFormVisible: false, dialogFormVisible: false,
dialogStatus: '', dialogStatus: '',
textMap: { textMap: {
update: '编辑', update: '编辑',
create: '创建' create: '创建'
}, },
dialogPvVisible: false, dialogPvVisible: false,
pvData: [], pvData: [],
showAuditor: false, showAuditor: false,
tableKey: 0 tableKey: 0
}
},
created() {
this.getList()
},
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
} }
return statusMap[status]
}, },
created() { typeFilter(type) {
this.getList(); return calendarTypeKeyValue[type]
}
},
methods: {
getList() {
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.list = response.data.items
this.total = response.data.total
this.listLoading = false
})
}, },
filters: { handleFilter() {
statusFilter(status) { this.getList()
const statusMap = { },
published: 'success', handleSizeChange(val) {
draft: 'gray', this.listQuery.limit = val
deleted: 'danger' this.getList()
}; },
return statusMap[status] handleCurrentChange(val) {
}, this.listQuery.page = val
typeFilter(type) { this.getList()
return calendarTypeKeyValue[type] },
timeFilter(time) {
if (!time[0]) {
this.listQuery.start = undefined
this.listQuery.end = undefined
return
} }
this.listQuery.start = parseInt(+time[0] / 1000)
this.listQuery.end = parseInt((+time[1] + 3600 * 1000 * 24) / 1000)
}, },
methods: { handleModifyStatus(row, status) {
getList() { this.$message({
this.listLoading = true; message: '操作成功',
fetchList(this.listQuery).then(response => { type: 'success'
this.list = response.data.items; })
this.total = response.data.total; row.status = status
this.listLoading = false; },
}) handleCreate() {
}, this.resetTemp()
handleFilter() { this.dialogStatus = 'create'
this.getList(); this.dialogFormVisible = true
}, },
handleSizeChange(val) { handleUpdate(row) {
this.listQuery.limit = val; this.temp = Object.assign({}, row)
this.getList(); this.dialogStatus = 'update'
}, this.dialogFormVisible = true
handleCurrentChange(val) { },
this.listQuery.page = val; handleDelete(row) {
this.getList(); this.$notify({
}, title: '成功',
timeFilter(time) { message: '删除成功',
if (!time[0]) { type: 'success',
this.listQuery.start = undefined; duration: 2000
this.listQuery.end = undefined; })
return; const index = this.list.indexOf(row)
this.list.splice(index, 1)
},
create() {
this.temp.id = parseInt(Math.random() * 100) + 1024
this.temp.timestamp = +new Date()
this.temp.author = '原创作者'
this.list.unshift(this.temp)
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
})
},
update() {
this.temp.timestamp = +this.temp.timestamp
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
} }
this.listQuery.start = parseInt(+time[0] / 1000);
this.listQuery.end = parseInt((+time[1] + 3600 * 1000 * 24) / 1000);
},
handleModifyStatus(row, status) {
this.$message({
message: '操作成功',
type: 'success'
});
row.status = status;
},
handleCreate() {
this.resetTemp();
this.dialogStatus = 'create';
this.dialogFormVisible = true;
},
handleUpdate(row) {
this.temp = Object.assign({}, row);
this.dialogStatus = 'update';
this.dialogFormVisible = true;
},
handleDelete(row) {
this.$notify({
title: '成功',
message: '删除成功',
type: 'success',
duration: 2000
});
const index = this.list.indexOf(row);
this.list.splice(index, 1);
},
create() {
this.temp.id = parseInt(Math.random() * 100) + 1024;
this.temp.timestamp = +new Date();
this.temp.author = '原创作者';
this.list.unshift(this.temp);
this.dialogFormVisible = false;
this.$notify({
title: '成功',
message: '创建成功',
type: 'success',
duration: 2000
});
},
update() {
this.temp.timestamp = +this.temp.timestamp;
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;
}
}
this.dialogFormVisible = false;
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
});
},
resetTemp() {
this.temp = {
id: undefined,
importance: 0,
remark: '',
timestamp: 0,
title: '',
status: 'published',
type: ''
};
},
handleFetchPv(pv) {
fetchPv(pv).then(response => {
this.pvData = response.data.pvData;
this.dialogPvVisible = true;
})
},
handleDownload() {
require.ensure([], () => {
const { export_json_to_excel } = require('vendor/Export2Excel');
const tHeader = ['时间', '地区', '类型', '标题', '重要性'];
const filterVal = ['timestamp', 'province', 'type', 'title', 'importance'];
const data = this.formatJson(filterVal, this.list);
export_json_to_excel(tHeader, data, 'table数据');
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
} }
this.dialogFormVisible = false
this.$notify({
title: '成功',
message: '更新成功',
type: 'success',
duration: 2000
})
},
resetTemp() {
this.temp = {
id: undefined,
importance: 0,
remark: '',
timestamp: 0,
title: '',
status: 'published',
type: ''
}
},
handleFetchPv(pv) {
fetchPv(pv).then(response => {
this.pvData = response.data.pvData
this.dialogPvVisible = true
})
},
handleDownload() {
require.ensure([], () => {
const { export_json_to_excel } = require('vendor/Export2Excel')
const tHeader = ['时间', '地区', '类型', '标题', '重要性']
const filterVal = ['timestamp', 'province', 'type', 'title', 'importance']
const data = this.formatJson(filterVal, this.list)
export_json_to_excel(tHeader, data, 'table数据')
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
return v[j]
}
}))
} }
} }
}
</script> </script>

View File

@ -34,41 +34,41 @@
</template> </template>
<script> <script>
import { getList } from 'api/article'; import { getList } from 'api/article'
export default { export default {
data() { data() {
return { return {
list: null, list: null,
listLoading: true listLoading: true
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.listLoading = true;
getList(this.listQuery).then(response => {
this.list = response.data;
this.listLoading = false;
})
},
handleDownload() {
require.ensure([], () => {
const {
export_json_to_excel
} = require('vendor/Export2Excel');
const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间'];
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'];
const list = this.list;
const data = this.formatJson(filterVal, list);
export_json_to_excel(tHeader, data, '列表excel');
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
}
} }
}; },
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getList(this.listQuery).then(response => {
this.list = response.data
this.listLoading = false
})
},
handleDownload() {
require.ensure([], () => {
const {
export_json_to_excel
} = require('vendor/Export2Excel')
const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间']
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.list
const data = this.formatJson(filterVal, list)
export_json_to_excel(tHeader, data, '列表excel')
})
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
}
}
}
</script> </script>

View File

@ -41,51 +41,51 @@
<script> <script>
import { getList } from 'api/article'; import { getList } from 'api/article'
export default { export default {
data() { data() {
return { return {
list: null, list: null,
listLoading: true, listLoading: true,
multipleSelection: [] multipleSelection: []
}
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.listLoading = true;
getList(this.listQuery).then(response => {
this.list = response.data;
this.listLoading = false;
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleDownload() {
if (this.multipleSelection.length) {
require.ensure([], () => {
const { export_json_to_excel } = require('vendor/Export2Excel');
const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间'];
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'];
const list = this.multipleSelection;
const data = this.formatJson(filterVal, list);
export_json_to_excel(tHeader, data, '列表excel');
this.$refs.multipleTable.clearSelection();
})
} else {
this.$message({
message: '请选择一条或多条记录导出',
type: 'warning'
});
}
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
}
} }
}; },
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getList(this.listQuery).then(response => {
this.list = response.data
this.listLoading = false
})
},
handleSelectionChange(val) {
this.multipleSelection = val
},
handleDownload() {
if (this.multipleSelection.length) {
require.ensure([], () => {
const { export_json_to_excel } = require('vendor/Export2Excel')
const tHeader = ['序号', '文章标题', '作者', '阅读数', '发布时间']
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.multipleSelection
const data = this.formatJson(filterVal, list)
export_json_to_excel(tHeader, data, '列表excel')
this.$refs.multipleTable.clearSelection()
})
} else {
this.$message({
message: '请选择一条或多条记录导出',
type: 'warning'
})
}
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
}
}
}
</script> </script>

View File

@ -7,7 +7,7 @@
</template> </template>
<script> <script>
export default { export default {
name: 'AppMain', name: 'AppMain',
computed: { computed: {
key() { key() {

View File

@ -9,21 +9,21 @@
</template> </template>
<script> <script>
import { Navbar, Sidebar, AppMain } from 'views/layout'; import { Navbar, Sidebar, AppMain } from 'views/layout'
export default { export default {
name: 'layout', name: 'layout',
components: { components: {
Navbar, Navbar,
Sidebar, Sidebar,
AppMain AppMain
}, },
computed: { computed: {
sidebar() { sidebar() {
return this.$store.state.app.sidebar; return this.$store.state.app.sidebar
}
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -8,31 +8,31 @@
</template> </template>
<script> <script>
export default { export default {
created() { created() {
this.getBreadcrumb()
},
data() {
return {
levelList: null
}
},
methods: {
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name)
const first = matched[0]
if (first && (first.name !== '首页' || first.path !== '')) {
matched = [{ name: '首页', path: '/' }].concat(matched)
}
this.levelList = matched
}
},
watch: {
$route() {
this.getBreadcrumb() this.getBreadcrumb()
},
data() {
return {
levelList: null
}
},
methods: {
getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name);
const first = matched[0];
if (first && (first.name !== '首页' || first.path !== '')) {
matched = [{ name: '首页', path: '/' }].concat(matched)
}
this.levelList = matched;
}
},
watch: {
$route() {
this.getBreadcrumb();
}
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -28,45 +28,45 @@
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex'
import Levelbar from './Levelbar'; import Levelbar from './Levelbar'
import TabsView from './TabsView'; import TabsView from './TabsView'
import Hamburger from 'components/Hamburger'; import Hamburger from 'components/Hamburger'
import Screenfull from 'components/Screenfull'; import Screenfull from 'components/Screenfull'
import ErrorLog from 'components/ErrLog'; import ErrorLog from 'components/ErrLog'
import errLogStore from 'store/errLog'; import errLogStore from 'store/errLog'
export default { export default {
components: { components: {
Levelbar, Levelbar,
TabsView, TabsView,
Hamburger, Hamburger,
ErrorLog, ErrorLog,
Screenfull Screenfull
},
data() {
return {
log: errLogStore.state.errLog
}
},
computed: {
...mapGetters([
'sidebar',
'name',
'avatar'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('ToggleSideBar')
}, },
data() { logout() {
return { this.$store.dispatch('LogOut').then(() => {
log: errLogStore.state.errLog location.reload()// vue-router bug
} })
},
computed: {
...mapGetters([
'sidebar',
'name',
'avatar'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('ToggleSideBar')
},
logout() {
this.$store.dispatch('LogOut').then(() => {
location.reload();// vue-router bug
});
}
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -6,18 +6,18 @@
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'; import SidebarItem from './SidebarItem'
export default { export default {
components: { SidebarItem }, components: { SidebarItem },
computed: { computed: {
...mapGetters([ ...mapGetters([
'permission_routers', 'permission_routers',
'sidebar' 'sidebar'
]), ]),
isCollapse() { isCollapse() {
return !this.sidebar.opened return !this.sidebar.opened
}
} }
} }
}
</script> </script>

View File

@ -31,13 +31,13 @@
</template> </template>
<script> <script>
export default { export default {
name: 'SidebarItem', name: 'SidebarItem',
props: { props: {
routes: { routes: {
type: Array type: Array
}
} }
} }
}
</script> </script>

View File

@ -9,37 +9,37 @@
</template> </template>
<script> <script>
export default { export default {
computed: { computed: {
visitedViews() { visitedViews() {
return this.$store.state.app.visitedViews.slice(-6) return this.$store.state.app.visitedViews.slice(-6)
} }
},
methods: {
closeViewTabs(view, $event) {
this.$store.dispatch('delVisitedViews', view)
$event.preventDefault()
}, },
methods: { generateRoute() {
closeViewTabs(view, $event) { if (this.$route.matched[this.$route.matched.length - 1].name) {
this.$store.dispatch('delVisitedViews', view) return this.$route.matched[this.$route.matched.length - 1]
$event.preventDefault()
},
generateRoute() {
if (this.$route.matched[this.$route.matched.length - 1].name) {
return this.$route.matched[this.$route.matched.length - 1]
}
this.$route.matched[0].path = '/'
return this.$route.matched[0]
},
addViewTabs() {
this.$store.dispatch('addVisitedViews', this.generateRoute())
},
isActive(path) {
return path === this.$route.path
} }
this.$route.matched[0].path = '/'
return this.$route.matched[0]
}, },
watch: { addViewTabs() {
$route() { this.$store.dispatch('addVisitedViews', this.generateRoute())
this.addViewTabs() },
} isActive(path) {
return path === this.$route.path
}
},
watch: {
$route() {
this.addViewTabs()
} }
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>

View File

@ -1,7 +1,7 @@
export { default as Navbar } from './Navbar'; export { default as Navbar } from './Navbar'
export { default as Sidebar } from './Sidebar'; export { default as Sidebar } from './Sidebar'
export { default as Levelbar } from './Levelbar'; export { default as Levelbar } from './Levelbar'
export { default as AppMain } from './AppMain'; export { default as AppMain } from './AppMain'

View File

@ -2,9 +2,9 @@
export default { export default {
name: 'authredirect', name: 'authredirect',
created() { created() {
const hash = window.location.search.slice(1); const hash = window.location.search.slice(1)
window.opener.location.href = window.location.origin + '/login#' + hash; window.opener.location.href = window.location.origin + '/login#' + hash
window.close(); window.close()
} }
} }
</script> </script>

View File

@ -37,67 +37,67 @@
</template> </template>
<script> <script>
import { isvalidUsername } from 'utils/validate' import { isvalidUsername } from 'utils/validate'
import socialSign from './socialsignin' import socialSign from './socialsignin'
export default { export default {
components: { socialSign }, components: { socialSign },
name: 'login', name: 'login',
data() { data() {
const validateUsername = (rule, value, callback) => { const validateUsername = (rule, value, callback) => {
if (!isvalidUsername(value)) { if (!isvalidUsername(value)) {
callback(new Error('请输入正确的用户名')) callback(new Error('请输入正确的用户名'))
} else { } else {
callback() callback()
}
} }
const validatePassword = (rule, value, callback) => { }
if (value.length < 6) { const validatePassword = (rule, value, callback) => {
callback(new Error('密码不能小于6位')) if (value.length < 6) {
} else { callback(new Error('密码不能小于6位'))
callback() } else {
} callback()
} }
return { }
loginForm: { return {
username: 'admin', loginForm: {
password: '1111111' username: 'admin',
}, password: '1111111'
loginRules: { },
username: [{ required: true, trigger: 'blur', validator: validateUsername }], loginRules: {
password: [{ required: true, trigger: 'blur', validator: validatePassword }] username: [{ required: true, trigger: 'blur', validator: validateUsername }],
}, password: [{ required: true, trigger: 'blur', validator: validatePassword }]
pwdType: 'password', },
loading: false, pwdType: 'password',
showDialog: false loading: false,
showDialog: false
}
},
methods: {
showPwd() {
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = 'password'
} }
}, },
methods: { handleLogin() {
showPwd() { this.$refs.loginForm.validate(valid => {
if (this.pwdType === 'password') { if (valid) {
this.pwdType = '' this.loading = true
} else { this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
this.pwdType = 'password' this.loading = false
} this.$router.push({ path: '/' })
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
this.loading = false
this.$router.push({ path: '/' })
// this.showDialog = true // this.showDialog = true
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
}) })
} else { } else {
console.log('error submit!!') console.log('error submit!!')
return false return false
} }
}) })
}, },
afterQRScan() { afterQRScan() {
// const hash = window.location.hash.slice(1) // const hash = window.location.hash.slice(1)
// const hashObj = getQueryObject(hash) // const hashObj = getQueryObject(hash)
// const originUrl = window.location.origin // const originUrl = window.location.origin
@ -114,15 +114,15 @@
// this.$router.push({ path: '/' }) // this.$router.push({ path: '/' })
// }) // })
// } // }
}
},
created() {
// window.addEventListener('hashchange', this.afterQRScan)
},
destroyed() {
// window.removeEventListener('hashchange', this.afterQRScan)
} }
},
created() {
// window.addEventListener('hashchange', this.afterQRScan)
},
destroyed() {
// window.removeEventListener('hashchange', this.afterQRScan)
} }
}
</script> </script>
<style rel="stylesheet/scss" lang="scss"> <style rel="stylesheet/scss" lang="scss">

Some files were not shown because too many files have changed in this diff Show More