Commit 26ca100a authored by 朱招明's avatar 朱招明

update

parent fff74c5a
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
class="header-search-select" class="header-search-select"
@change="change" @change="change"
> >
<el-option v-for="item in options" :key="item.path" :value="item" :label="item.title.join(' > ')" /> <el-option v-for="item in options" :key="item.item.path" :value="item.item" :label="item.item.title.join(' > ')" />
</el-select> </el-select>
</div> </div>
</template> </template>
...@@ -36,7 +36,7 @@ export default { ...@@ -36,7 +36,7 @@ export default {
}, },
computed: { computed: {
routes() { routes() {
return this.$store.getters.addRouters return this.$store.getters.addRouters.find(item => item.path === '/').children
} }
}, },
watch: { watch: {
...@@ -131,6 +131,7 @@ export default { ...@@ -131,6 +131,7 @@ export default {
querySearch(query) { querySearch(query) {
if (query !== '') { if (query !== '') {
this.options = this.fuse.search(query) this.options = this.fuse.search(query)
console.log(this.options)
} else { } else {
this.options = [] this.options = []
} }
......
...@@ -59,6 +59,7 @@ export default { ...@@ -59,6 +59,7 @@ export default {
created() { created() {
const routes = this.addRouters.find(item => item.path === '/') const routes = this.addRouters.find(item => item.path === '/')
this.menus = (routes && routes.children) || [] this.menus = (routes && routes.children) || []
console.log(this.menus)
} }
} }
......
import Vue from 'vue' import Vue from 'vue'
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui' import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n // import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css import '@/styles/index.scss' // global css
...@@ -14,6 +15,7 @@ import router from './router' ...@@ -14,6 +15,7 @@ import router from './router'
import '@/icons' // icon import '@/icons' // icon
import '@/permission' // permission control import '@/permission' // permission control
import './utils/error-log' // error log
/** /**
* If you don't want to use mock-server * If you don't want to use mock-server
...@@ -29,9 +31,11 @@ if (process.env.NODE_ENV === 'production') { ...@@ -29,9 +31,11 @@ if (process.env.NODE_ENV === 'production') {
} }
// set ElementUI lang to EN // set ElementUI lang to EN
Vue.use(ElementUI, { locale }) // Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明 // 如果想要中文版 element-ui,按如下方式声明
// Vue.use(ElementUI) Vue.use(ElementUI, {
size: Cookies.get('size') || 'medium'
})
Vue.config.productionTip = false Vue.config.productionTip = false
......
// 路由标识对应页面 // 路由标识对应页面
export const constantRouterComponents = { export const constantRouterComponents = {
// 权限管理 // 权限管理
// SystemPowerRoleList: () => import('@/views/system/power/role/List'), 'role': () => import('@/views/system/power/role/index'),
// UserList: () => import('@/views/power/user/list'), 'user': () => import('@/views/system/power/user/index.vue'),
'Dashboard': () => import('@/views/dashboard/index'), 'menu': () => import('@/views/system/power/menu/index')
'SystemPowerRoleList': () => import('@/views/system/power/role/List'),
'SystemPowerUserList': () => import('@/views/system/power/user/List'),
'SystemPowerMenuList': () => import('@/views/system/power/menu/List')
} }
...@@ -12,16 +12,18 @@ const notFoundRouter = { ...@@ -12,16 +12,18 @@ const notFoundRouter = {
// 根级菜单 // 根级菜单
const rootRouter = { const rootRouter = {
router: '/', path: '/',
key: 'Root', name: '/',
component: Layout, component: Layout,
redirect: '/dashboard', redirect: '/dashboard',
children: [{ children: [{
router: '/dashboard', path: '/dashboard',
key: 'Dashboard', name: 'dashboard',
title: '首页', component: () => import('@/views/dashboard/index'),
icon: 'dashboard', meta: {
component: () => import('@/views/dashboard/index') title: '首页',
icon: 'dashboard'
}
}] }]
} }
...@@ -40,13 +42,12 @@ export const generatorDynamicRouter = () => { ...@@ -40,13 +42,12 @@ export const generatorDynamicRouter = () => {
const childrenNav = [] const childrenNav = []
// 后端数据, 根级树数组, 根级 PID // 后端数据, 根级树数组, 根级 PID
listToTree(menus, childrenNav, 0) listToTree(menus, childrenNav, 0)
rootRouter.children = [...rootRouter.children, ...childrenNav] const routers = generator(childrenNav)
rootRouter.children = [...rootRouter.children, ...routers]
menuNav.push(rootRouter) menuNav.push(rootRouter)
const routers = generator(menuNav) console.log(menuNav)
console.log(routers) menuNav.push(notFoundRouter)
// const routers = [] resolve(menuNav)
routers.push(notFoundRouter)
resolve(routers)
}) })
.catch(err => { .catch(err => {
reject(err) reject(err)
...@@ -63,73 +64,29 @@ export const generatorDynamicRouter = () => { ...@@ -63,73 +64,29 @@ export const generatorDynamicRouter = () => {
*/ */
export const generator = (routerMap, parent) => { export const generator = (routerMap, parent) => {
return routerMap.map(item => { return routerMap.map(item => {
// const { show, hideChildren, hiddenHeaderContent, target, icon } = item.meta || {}
// const path = item.path || item.key + (item.id || '')
const component = item.component || constantRouterComponents[item.key]
const currentRouter = { const currentRouter = {
// 如果路由设置了 path,则作为默认 path,否则 路由地址 动态拼接生成如 /dashboard/workplace // 上级key + 自己key
path: item.router || (item.key + '_' + (item.id || '')), path: ((parent && parent.path) || '') + '/' + item.key,
// 路由名称,建议唯一 // 路由名称,建议唯一
name: item.key + (item.id || ''), name: item.key,
// 该路由对应页面的 组件 :方案1 // 该路由对应页面的 组件 || 404
// component: constantRouterComponents[item.component || item.key], component: constantRouterComponents[item.key] || (() => import('@/views/404')),
// 该路由对应页面的 组件 :方案2 (动态加载) // meta: 页面标题, 菜单图标
component: component,
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
meta: { meta: {
title: item.title, title: item.title,
icon: item.icon icon: item.icon
} }
} }
// // 是否设置了隐藏菜单
// if (show === false) {
// currentRouter.hidden = true
// }
// // 是否设置了隐藏子菜单
// if (hideChildren) {
// currentRouter.hideChildrenInMenu = true
// }
// // 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
// if (!currentRouter.path.startsWith('http')) {
// currentRouter.path = currentRouter.path.replace('//', '/')
// }
// 重定向
item.redirect && (currentRouter.redirect = item.redirect)
// 是否有子菜单,并递归处理 // 是否有子菜单,并递归处理
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
// Recursion // Recursion
currentRouter.children = generator(item.children, currentRouter) currentRouter.children = generator(item.children, currentRouter)
if (item.key !== 'Root') {
currentRouter.component = RouteView
}
}
// 是否有功能页菜单 currentRouter.component = RouteView
// const actions = constantActionRouterComponents[item.key] currentRouter.redirect = 'noRedirect'
// if (actions) {
// const children_action = generatorAction(actions, currentRouter)
// const children_menu = currentRouter.children || []
// console.log(children_action, children_menu)
// currentRouter.children = [...children_menu, ...children_action]
// }
return currentRouter
})
}
export const generatorAction = (routerMap, parent) => {
return routerMap.map(item => {
return {
path: item.path,
name: parent.name + '.' + item.name,
component: item.component,
hidden: true,
meta: {
title: item.title,
icon: item.icon,
activeMenu: parent.path
}
} }
return currentRouter
}) })
} }
......
import Vue from 'vue' import Vue from 'vue'
import Router from 'vue-router' import Router from 'vue-router'
import Layout from '@/layout'
Vue.use(Router) Vue.use(Router)
...@@ -39,6 +40,17 @@ export const constantRouterMap = [ ...@@ -39,6 +40,17 @@ export const constantRouterMap = [
path: '/404', path: '/404',
component: () => import('@/views/404'), component: () => import('@/views/404'),
hidden: true hidden: true
},
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index')
}
]
} }
] ]
......
...@@ -26,6 +26,10 @@ const mutations = { ...@@ -26,6 +26,10 @@ const mutations = {
}, },
TOGGLE_DEVICE: (state, device) => { TOGGLE_DEVICE: (state, device) => {
state.device = device state.device = device
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
} }
} }
...@@ -38,6 +42,9 @@ const actions = { ...@@ -38,6 +42,9 @@ const actions = {
}, },
toggleDevice({ commit }, device) { toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device) commit('TOGGLE_DEVICE', device)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
} }
} }
......
import Vue from 'vue'
import store from '@/store'
import { isString, isArray } from '@/utils/validate'
import settings from '@/settings'
// you can set in settings.js
// errorLog:'production' | ['production', 'development']
const { errorLog: needErrorLog } = settings
function checkNeed() {
const env = process.env.NODE_ENV
if (isString(needErrorLog)) {
return env === needErrorLog
}
if (isArray(needErrorLog)) {
return needErrorLog.includes(env)
}
return false
}
if (checkNeed()) {
Vue.config.errorHandler = function(err, vm, info, a) {
// Don't ask me why I use Vue.nextTick, it just a hack.
// detail see https://forum.vuejs.org/t/dispatch-in-vue-config-errorhandler-has-some-problem/23500
Vue.nextTick(() => {
store.dispatch('errorLog/addErrorLog', {
err,
vm,
info,
url: window.location.href
})
console.error(err, info)
})
}
}
...@@ -46,9 +46,17 @@ service.interceptors.response.use( ...@@ -46,9 +46,17 @@ service.interceptors.response.use(
console.log('err' + error) // for debug console.log('err' + error) // for debug
const data = error.response.data const data = error.response.data
const token = getToken() const token = getToken()
const params_errors = data.errors
switch (error.response.status) { switch (error.response.status) {
case 422: case 422:
Message.error('参数错误') if (params_errors) {
for (const item in params_errors) {
Message.error(params_errors[item][0])
break
}
} else {
Message.error('参数错误')
}
break break
case 403: case 403:
Message.error('无权操作') Message.error('无权操作')
......
...@@ -18,3 +18,70 @@ export function validUsername(str) { ...@@ -18,3 +18,70 @@ export function validUsername(str) {
const valid_map = ['admin', 'editor'] const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0 return valid_map.indexOf(str.trim()) >= 0
} }
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return reg.test(email)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) {
if (typeof str === 'string' || str instanceof String) {
return true
}
return false
}
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) {
if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]'
}
return Array.isArray(arg)
}
<script>
export default {
created() {
const { params, query } = this.$route
const { path } = params
this.$router.replace({ path: '/' + path, query })
},
render: function(h) {
return h() // avoid warning message
}
}
</script>
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
<el-tree <el-tree
:data="treeData" :data="treeData"
node-key="id" node-key="id"
default-expand-all
:expand-on-click-node="false" :expand-on-click-node="false"
> >
<span slot-scope="{ node, data }" class="custom-tree-node"> <span slot-scope="{ node, data }" class="custom-tree-node">
...@@ -18,6 +17,7 @@ ...@@ -18,6 +17,7 @@
新增 新增
</el-button> </el-button>
<el-button <el-button
v-if="data.id !== 0"
type="text" type="text"
size="mini" size="mini"
@click="() => edit(node, data)" @click="() => edit(node, data)"
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
编辑 编辑
</el-button> </el-button>
<el-button <el-button
v-if="data.id !== 0"
type="text" type="text"
size="mini" size="mini"
@click="() => remove(node, data)" @click="() => remove(node, data)"
...@@ -51,18 +52,20 @@ ...@@ -51,18 +52,20 @@
<el-form-item label="标题" prop="title"> <el-form-item label="标题" prop="title">
<el-input v-model="form.title" placeholder="输入标题" /> <el-input v-model="form.title" placeholder="输入标题" />
</el-form-item> </el-form-item>
<el-form-item label="前端页面" prop="key"> <el-form-item label="路由标识" prop="key">
<el-select v-model="form.key" placeholder="请选择前端页面"> <el-input v-model="form.key" placeholder="输入路由标识" />
<el-option
v-for="item in routePath" <!-- <el-select v-model="form.key" placeholder="请选择前端页面">-->
:key="item.key" <!-- <el-option-->
:label="item.path" <!-- v-for="item in routePath"-->
:value="item.key" <!-- :key="item.key"-->
/> <!-- :label="item.path"-->
</el-select> <!-- :value="item.key"-->
<!-- />-->
<!-- </el-select>-->
</el-form-item> </el-form-item>
<el-form-item label="后端接口地址" prop="path"> <el-form-item label="后端接口地址" prop="path">
<el-input v-model="form.path" placeholder="输入接口地址" /> <el-input v-model="form.api" placeholder="输入接口地址" />
</el-form-item> </el-form-item>
<el-form-item label="图标" prop="icon"> <el-form-item label="图标" prop="icon">
<el-input v-model="form.icon" placeholder="输入图标" /> <el-input v-model="form.icon" placeholder="输入图标" />
...@@ -103,10 +106,10 @@ export default { ...@@ -103,10 +106,10 @@ export default {
treeData: [], treeData: [],
treeSelectData: [], treeSelectData: [],
form: { form: {
parent_id: '', parent_id: 0,
title: '', title: '',
key: 'Dashboard', key: 'Dashboard',
path: '', api: '',
icon: '', icon: '',
is_menu: 1 is_menu: 1
} }
...@@ -130,27 +133,37 @@ export default { ...@@ -130,27 +133,37 @@ export default {
methods: { methods: {
resetForm() { resetForm() {
this.form = { this.form = {
parent_id: '', parent_id: 0,
title: '', title: '',
key: 'Dashboard', key: '',
path: '', path: '',
icon: '', icon: '',
is_menu: 1 is_menu: 1
} }
}, },
init() { init() {
// 注册功能页路由 this.dialogFormVisible = false
menuList().then(res => { menuList().then(res => {
const menus = res.data const menus = res.data
const rootRouter = {
id: 0,
label: 'ROOT',
children: []
}
const childrenNav = [] const childrenNav = []
this.listToTree(menus, childrenNav, 0) this.listToTree(menus, childrenNav, 0)
this.treeData = childrenNav rootRouter.children = childrenNav
this.treeData = [rootRouter]
const rootRouterSelect = {
value: 0,
label: 'ROOT',
children: []
}
const treeChildSelectData = [] const treeChildSelectData = []
this.listToSelectTree(menus, treeChildSelectData, 0) this.listToSelectTree(menus, treeChildSelectData, 0)
this.treeSelectData = treeChildSelectData rootRouterSelect.children = treeChildSelectData
this.treeSelectData = [rootRouterSelect]
this.dialogFormVisible = false
}) })
}, },
...@@ -201,8 +214,8 @@ export default { ...@@ -201,8 +214,8 @@ export default {
this.form = { this.form = {
parent_id: this.form_parent_menu_id, parent_id: this.form_parent_menu_id,
title: '', title: '',
key: 'Dashboard', key: '',
path: '', api: '',
icon: '', icon: '',
is_menu: 1 is_menu: 1
} }
...@@ -226,7 +239,7 @@ export default { ...@@ -226,7 +239,7 @@ export default {
parent_id: menu_data.parent_id, parent_id: menu_data.parent_id,
title: menu_data.title, title: menu_data.title,
key: menu_data.key, key: menu_data.key,
path: menu_data.path, api: menu_data.api,
icon: menu_data.icon, icon: menu_data.icon,
is_menu: menu_data.is_menu is_menu: menu_data.is_menu
} }
......
...@@ -83,6 +83,7 @@ import { roleList } from '@/api/role' ...@@ -83,6 +83,7 @@ import { roleList } from '@/api/role'
export default { export default {
data() { data() {
return { return {
imageUrl: '',
user: { user: {
username: '', username: '',
password: '', password: '',
...@@ -202,4 +203,27 @@ export default { ...@@ -202,4 +203,27 @@ export default {
margin-bottom: 30px; margin-bottom: 30px;
} }
} }
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment