Merge branch 'master' into deploy

This commit is contained in:
Pan 2019-04-23 13:06:46 +08:00
commit 965c2eca65
22 changed files with 130 additions and 49 deletions

View File

@ -161,7 +161,7 @@ cd vue-element-admin
# 安装依赖 # 安装依赖
npm install npm install
# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题 # 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org npm install --registry=https://registry.npm.taobao.org
# 启动服务 # 启动服务

View File

@ -1,12 +1,9 @@
module.exports = { module.exports = {
verbose: true,
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transformIgnorePatterns: [
'node_modules/(?!(babel-jest|jest-vue-preprocessor)/)'
],
transform: { transform: {
'^.+\\.vue$': 'vue-jest', '^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest' '^.+\\.jsx?$': 'babel-jest'
}, },
moduleNameMapper: { moduleNameMapper: {

View File

@ -1,6 +1,9 @@
const chokidar = require('chokidar') const chokidar = require('chokidar')
const bodyParser = require('body-parser') const bodyParser = require('body-parser')
const chalk = require('chalk') const chalk = require('chalk')
const path = require('path')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) { function registerRoutes(app) {
let mockLastIndex let mockLastIndex
@ -18,7 +21,7 @@ function registerRoutes(app) {
function unregisterRoutes() { function unregisterRoutes() {
Object.keys(require.cache).forEach(i => { Object.keys(require.cache).forEach(i => {
if (i.includes('/mock')) { if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)] delete require.cache[require.resolve(i)]
} }
}) })
@ -40,9 +43,8 @@ module.exports = app => {
var mockStartIndex = mockRoutes.mockStartIndex var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server // watch files, hot reload mock server
chokidar.watch(('./mock'), { chokidar.watch(mockDir, {
ignored: 'mock/mock-server.js', ignored: /mock-server/,
persistent: true,
ignoreInitial: true ignoreInitial: true
}).on('all', (event, path) => { }).on('all', (event, path) => {
if (event === 'change' || event === 'add') { if (event === 'change' || event === 'add') {

View File

@ -119,7 +119,7 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: 'index', path: 'index',
component: 'views/svg-icons/index', component: 'views/icons/index',
name: 'Icons', name: 'Icons',
meta: { title: 'icons', icon: 'icon', noCache: true } meta: { title: 'icons', icon: 'icon', noCache: true }
} }

View File

@ -10,7 +10,7 @@
"build:stage": "vue-cli-service build --mode staging", "build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview", "preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src", "lint": "eslint --ext .js,.vue src",
"test:unit": "vue-cli-service test:unit", "test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit", "test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml", "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"new": "plop", "new": "plop",

View File

@ -22,4 +22,3 @@ export function logout() {
method: 'post' method: 'post'
}) })
} }

View File

@ -40,14 +40,14 @@ export default {
mounted() { mounted() {
this.height = this.$el.getBoundingClientRect().height this.height = this.$el.getBoundingClientRect().height
window.addEventListener('scroll', this.handleScroll) window.addEventListener('scroll', this.handleScroll)
window.addEventListener('resize', this.handleReize) window.addEventListener('resize', this.handleResize)
}, },
activated() { activated() {
this.handleScroll() this.handleScroll()
}, },
destroyed() { destroyed() {
window.removeEventListener('scroll', this.handleScroll) window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleReize) window.removeEventListener('resize', this.handleResize)
}, },
methods: { methods: {
sticky() { sticky() {
@ -81,7 +81,7 @@ export default {
} }
this.handleReset() this.handleReset()
}, },
handleReize() { handleResize() {
if (this.isSticky) { if (this.isSticky) {
this.width = this.$el.getBoundingClientRect().width + 'px' this.width = this.$el.getBoundingClientRect().width + 'px'
} }

View File

@ -1,5 +1,5 @@
<template> <template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container editor-container"> <div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
<textarea :id="tinymceId" class="tinymce-textarea" /> <textarea :id="tinymceId" class="tinymce-textarea" />
<div class="editor-custom-btn-container"> <div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" /> <editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
@ -38,9 +38,14 @@ export default {
default: 'file edit insert view format table' default: 'file edit insert view format table'
}, },
height: { height: {
type: Number, type: [Number, String],
required: false, required: false,
default: 360 default: 360
},
width: {
type: [Number, String],
required: false,
default: 'auto'
} }
}, },
data() { data() {
@ -58,6 +63,13 @@ export default {
computed: { computed: {
language() { language() {
return this.languageTypeList[this.$store.getters.language] return this.languageTypeList[this.$store.getters.language]
},
containerWidth() {
const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
return `${width}px`
}
return width
} }
}, },
watch: { watch: {

View File

@ -36,6 +36,9 @@
{{ $t('navbar.github') }} {{ $t('navbar.github') }}
</el-dropdown-item> </el-dropdown-item>
</a> </a>
<a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/">
<el-dropdown-item>Docs</el-dropdown-item>
</a>
<el-dropdown-item divided> <el-dropdown-item divided>
<span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span> <span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span>
</el-dropdown-item> </el-dropdown-item>
@ -68,7 +71,6 @@ export default {
computed: { computed: {
...mapGetters([ ...mapGetters([
'sidebar', 'sidebar',
'name',
'avatar', 'avatar',
'device' 'device'
]) ])

View File

@ -7,6 +7,7 @@
:collapse="isCollapse" :collapse="isCollapse"
:background-color="variables.menuBg" :background-color="variables.menuBg"
:text-color="variables.menuText" :text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText" :active-text-color="variables.menuActiveText"
:collapse-transition="false" :collapse-transition="false"
mode="vertical" mode="vertical"

View File

@ -163,7 +163,7 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: 'index', path: 'index',
component: () => import('@/views/svg-icons/index'), component: () => import('@/views/icons/index'),
name: 'Icons', name: 'Icons',
meta: { title: 'icons', icon: 'icon', noCache: true } meta: { title: 'icons', icon: 'icon', noCache: true }
} }

View File

@ -11,7 +11,6 @@ const getters = {
introduction: state => state.user.introduction, introduction: state => state.user.introduction,
roles: state => state.user.roles, roles: state => state.user.roles,
permission_routes: state => state.permission.routes, permission_routes: state => state.permission.routes,
addRoutes: state => state.permission.addRoutes,
errorLogs: state => state.errorLog.logs errorLogs: state => state.errorLog.logs
} }
export default getters export default getters

View File

@ -51,7 +51,7 @@ const actions = {
return new Promise(resolve => { return new Promise(resolve => {
let accessedRoutes let accessedRoutes
if (roles.includes('admin')) { if (roles.includes('admin')) {
accessedRoutes = asyncRoutes accessedRoutes = asyncRoutes || []
} else { } else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
} }

View File

@ -1,6 +1,7 @@
/** /**
* Created by jiachenpan on 16/11/18. * Created by jiachenpan on 16/11/18.
*/ */
/** /**
* @param {string} path * @param {string} path
* @returns {Boolean} * @returns {Boolean}

View File

@ -8,22 +8,13 @@
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div> </div>
<div class="bullshit"> <div class="bullshit">
<div class="bullshit__oops"> <div class="bullshit__oops">OOPS!</div>
OOPS! <div class="bullshit__info">All rights reserved
<a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
</div> </div>
<div class="bullshit__info"> <div class="bullshit__headline">{{ message }}</div>
版权所有 <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
<a class="link-type" href="https://wallstreetcn.com" target="_blank">华尔街见闻</a> <a href="" class="bullshit__return-home">Back to home</a>
</div>
<div class="bullshit__headline">
{{ message }}
</div>
<div class="bullshit__info">
请检查您输入的网址是否正确请点击以下按钮返回主页或者发送错误报告
</div>
<router-link to="/" class="bullshit__return-home">
返回首页
</router-link>
</div> </div>
</div> </div>
</div> </div>
@ -35,7 +26,7 @@ export default {
name: 'Page404', name: 'Page404',
computed: { computed: {
message() { message() {
return '网管说这个页面你不能进......' return 'The webmaster said that you can not enter this page...'
} }
} }
} }

View File

@ -0,0 +1,74 @@
const elementIcons = [
'info',
'error',
'success',
'warning',
'question',
'back',
'arrow-left',
'arrow-down',
'arrow-right',
'arrow-up',
'caret-left',
'caret-bottom',
'caret-top',
'caret-right',
'd-arrow-left',
'd-arrow-right',
'minus',
'plus',
'remove',
'circle-plus',
'remove-outline',
'circle-plus-outline',
'close',
'check',
'circle-close',
'circle-check',
'circle-close-outline',
'circle-check-outline',
'zoom-out',
'zoom-in',
'd-caret',
'sort',
'sort-down',
'sort-up',
'tickets',
'document',
'goods',
'sold-out',
'news',
'message',
'date',
'printer',
'time',
'bell',
'mobile-phone',
'service',
'view',
'menu',
'more',
'more-outline',
'star-on',
'star-off',
'location',
'location-outline',
'phone',
'phone-outline',
'picture',
'picture-outline',
'delete',
'search',
'edit',
'edit-outline',
'rank',
'refresh',
'share',
'setting',
'upload',
'upload2',
'download',
'loading'
]
export default elementIcons

View File

@ -6,7 +6,7 @@
</aside> </aside>
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="Icons"> <el-tab-pane label="Icons">
<div v-for="item of iconsMap" :key="item" @click="handleClipboard(generateIconCode(item),$event)"> <div v-for="item of svgIcons" :key="item" @click="handleClipboard(generateIconCode(item),$event)">
<el-tooltip placement="top"> <el-tooltip placement="top">
<div slot="content"> <div slot="content">
{{ generateIconCode(item) }} {{ generateIconCode(item) }}
@ -37,15 +37,15 @@
<script> <script>
import clipboard from '@/utils/clipboard' import clipboard from '@/utils/clipboard'
import icons from './require-icons' import svgIcons from './svg-icons'
import elementIcons from './element-icon.json' import elementIcons from './element-icons'
export default { export default {
name: 'Icons', name: 'Icons',
data() { data() {
return { return {
iconsMap: icons, svgIcons,
elementIcons: elementIcons elementIcons
} }
}, },
methods: { methods: {

View File

@ -3,8 +3,8 @@ const requireAll = requireContext => requireContext.keys()
const re = /\.\/(.*)\.svg/ const re = /\.\/(.*)\.svg/
const icons = requireAll(req).map(i => { const svgIcons = requireAll(req).map(i => {
return i.match(re)[1] return i.match(re)[1]
}) })
export default icons export default svgIcons

View File

@ -1,10 +1,12 @@
<template> <template>
<div class="social-signup-container"> <div class="social-signup-container">
<div class="sign-btn" @click="wechatHandleClick('wechat')"> <div class="sign-btn" @click="wechatHandleClick('wechat')">
<span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span> 微信 <span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon" /></span>
WeChat
</div> </div>
<div class="sign-btn" @click="tencentHandleClick('tencent')"> <div class="sign-btn" @click="tencentHandleClick('tencent')">
<span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span> QQ <span class="qq-svg-container"><svg-icon icon-class="qq" class="icon" /></span>
QQ
</div> </div>
</div> </div>
</template> </template>

View File

@ -19,6 +19,7 @@
:placeholder="$t('login.username')" :placeholder="$t('login.username')"
name="username" name="username"
type="text" type="text"
tabindex="1"
auto-complete="on" auto-complete="on"
/> />
</el-form-item> </el-form-item>
@ -35,6 +36,7 @@
:type="passwordType" :type="passwordType"
:placeholder="$t('login.password')" :placeholder="$t('login.password')"
name="password" name="password"
tabindex="2"
auto-complete="on" auto-complete="on"
@keyup.native="checkCapslock" @keyup.native="checkCapslock"
@blur="capsTooltip = false" @blur="capsTooltip = false"

View File

@ -1 +0,0 @@
["info","error","success","warning","question","back","arrow-left","arrow-down","arrow-right","arrow-up","caret-left","caret-bottom","caret-top","caret-right","d-arrow-left","d-arrow-right","minus","plus","remove","circle-plus","remove-outline","circle-plus-outline","close","check","circle-close","circle-check","circle-close-outline","circle-check-outline","zoom-out","zoom-in","d-caret","sort","sort-down","sort-up","tickets","document","goods","sold-out","news","message","date","printer","time","bell","mobile-phone","service","view","menu","more","more-outline","star-on","star-off","location","location-outline","phone","phone-outline","picture","picture-outline","delete","search","edit","edit-outline","rank","refresh","share","setting","upload","upload2","download","loading"]