Commit 7b267a8d authored by 朱招明's avatar 朱招明

update

parent f263c06d
......@@ -2,5 +2,5 @@
ENV = 'production'
# base api
VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API = 'http://www.oa.com/api'
......@@ -4,5 +4,5 @@ NODE_ENV = production
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'
VUE_APP_BASE_API = 'http://www.oa.com/api'
# vue-admin-template
> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。
[线上地址](http://panjiachen.github.io/vue-admin-template)
[国内访问](https://panjiachen.gitee.io/vue-admin-template)
目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`
<p align="center">
<b>SPONSORED BY</b>
</p>
<p align="center">
<a href="https://finclip.com?from=vue_element" title="FinClip" target="_blank">
<img height="200px" src="https://gitee.com/panjiachen/gitee-cdn/raw/master/vue%E8%B5%9E%E5%8A%A9.png" title="FinClip">
</a>
</p>
## Extra
如果你想要根据用户角色来动态生成侧边栏和 router,你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
## 相关项目
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
## Build Setup
```bash
# 克隆项目
git clone https://github.com/PanJiaChen/vue-admin-template.git
# 进入项目目录
cd vue-admin-template
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
# 启动服务
npm run dev
```
浏览器访问 [http://localhost:9528](http://localhost:9528)
## 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
```
## 其它
```bash
# 预览发布环境效果
npm run preview
# 预览发布环境效果 + 静态资源分析
npm run preview -- --report
# 代码格式检查
npm run lint
# 代码格式检查并自动修复
npm run lint -- --fix
```
更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
## 购买贴纸
你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen
# vue-admin-template
English | [简体中文](./README-zh.md)
> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
**Live demo:** http://panjiachen.github.io/vue-admin-template
**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
<p align="center">
<b>SPONSORED BY</b>
</p>
<p align="center">
<a href="https://finclip.com?from=vue_element" title="FinClip" target="_blank">
<img height="200px" src="https://gitee.com/panjiachen/gitee-cdn/raw/master/vue%E8%B5%9E%E5%8A%A9.png" title="FinClip">
</a>
</p>
## Build Setup
```bash
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git
# enter the project directory
cd vue-admin-template
# install dependency
npm install
# develop
npm run dev
```
This will automatically open http://localhost:9528
## Build
```bash
# build for test environment
npm run build:stage
# build for production environment
npm run build:prod
```
## Advanced
```bash
# preview the release environment effect
npm run preview
# preview the release environment effect + static resource analysis
npm run preview -- --report
# code format check
npm run lint
# code format check and auto fix
npm run lint -- --fix
```
Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Extra
If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
## Related Project
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen
{
"name": "vue-admin-template",
"version": "4.4.0",
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
"author": "Pan <panfree23@gmail.com>",
"name": "oa",
"version": "1.0.0",
"description": "SMG OA",
"author": "Zzm <316346092@qq.com>",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
......
......@@ -25,19 +25,13 @@
</div>
<el-dropdown-menu slot="dropdown">
<router-link to="/profile/index">
<el-dropdown-item>Profile</el-dropdown-item>
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<router-link to="/">
<el-dropdown-item>Dashboard</el-dropdown-item>
<el-dropdown-item>首页</el-dropdown-item>
</router-link>
<a target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">
<el-dropdown-item>Github</el-dropdown-item>
</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 @click.native="logout">
<span style="display:block;">Log Out</span>
<span style="display:block;">退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
......
......@@ -59,7 +59,6 @@ export default {
created() {
const routes = this.addRouters.find(item => item.path === '/')
this.menus = (routes && routes.children) || []
console.log(this.menus)
}
}
......
......@@ -25,10 +25,10 @@ import './utils/error-log' // error log
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
// set ElementUI lang to EN
// Vue.use(ElementUI, { locale })
......
import router, { resetRouter } from './router'
import store from './store'
// import { Message } from 'element-ui'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
......@@ -28,15 +28,18 @@ router.beforeEach(async(to, from, next) => {
} else {
if (!store.getters.menuSet) {
try {
await store.dispatch('user/getInfo')
// await store.dispatch('user/getInfo')
store.dispatch('GenerateRoutes', {}).then(() => {
resetRouter() // 重置路由 防止退出重新登录或者 token 过期后页面未刷新,导致的路由重复添加
router.addRoutes(store.getters.addRouters)
// 请求带有 redirect 重定向时,登录自动重定向到该地址
next({ ...to, replace: true })
})
const configs = await store.dispatch('user/getConfigs')
const { menus } = configs
await store.dispatch('GenerateRoutes', menus)
resetRouter() // 重置路由 防止退出重新登录或者 token 过期后页面未刷新,导致的路由重复添加
router.addRoutes(store.getters.addRouters)
next({ ...to, replace: true })
} catch (error) {
Message.error('获取配置失败,请重新登录')
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
next(`/login?redirect=${to.path}`)
......
import * as userService from '@/api/user'
import { constantRouterComponents } from '@/router/config'
import Layout from '@/layout'
import RouteView from '@/layout/RouteView'
......@@ -29,29 +28,20 @@ const rootRouter = {
/**
* 动态生成菜单
* @param token
* @param menus
* @returns {Promise<Router>}
*/
export const generatorDynamicRouter = () => {
export const generatorDynamicRouter = (menus) => {
return new Promise((resolve, reject) => {
userService
.getConfigs()
.then(res => {
const menus = res.data.menus
const menuNav = []
const childrenNav = []
// 后端数据, 根级树数组, 根级 PID
listToTree(menus, childrenNav, 0)
const routers = generator(childrenNav)
rootRouter.children = [...rootRouter.children, ...routers]
menuNav.push(rootRouter)
console.log(menuNav)
menuNav.push(notFoundRouter)
resolve(menuNav)
})
.catch(err => {
reject(err)
})
const menuNav = []
const childrenNav = []
// 后端数据, 根级树数组, 根级 PID
listToTree(menus, childrenNav, 0)
const routers = generator(childrenNav)
rootRouter.children = [...rootRouter.children, ...routers]
menuNav.push(rootRouter)
menuNav.push(notFoundRouter)
resolve(menuNav)
})
}
......
......@@ -51,6 +51,20 @@ export const constantRouterMap = [
component: () => import('@/views/redirect/index')
}
]
},
{
path: '/profile',
component: Layout,
redirect: '/profile/index',
hidden: true,
children: [
{
path: 'index',
component: () => import('@/views/profile/index'),
name: '个人中心',
meta: { title: '个人中心', icon: 'user', noCache: true }
}
]
}
]
......
......@@ -20,9 +20,9 @@ const permission = {
}
},
actions: {
GenerateRoutes({ commit }) {
GenerateRoutes({ commit }, menus) {
return new Promise((resolve, reject) => {
generatorDynamicRouter().then(routers => {
generatorDynamicRouter(menus).then(routers => {
commit('SET_ROUTERS', routers)
commit('SET_MENU_SET', true)
resolve()
......
import { login, logout, getInfo } from '@/api/user'
import { login, logout, getInfo, getConfigs } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
......@@ -19,6 +19,9 @@ const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_USER_INFO: (state, user_info) => {
state.user_info = user_info
},
SET_NAME: (state, name) => {
state.name = name
},
......@@ -64,6 +67,28 @@ const actions = {
})
},
getConfigs({ commit, state }) {
return new Promise((resolve, reject) => {
getConfigs().then(response => {
const { data } = response
if (!data) {
return reject('获取配置失败,请重新登录')
}
const { user_info } = data
commit('SET_USER_INFO', user_info)
commit('SET_NAME', user_info.name)
commit('SET_AVATAR', user_info.avatar_full_url)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
......
<template>
<div class="dashboard-container">
<div class="dashboard-text">name: {{ name }}</div>
</div>
<div class="dashboard-container" />
</template>
<script>
......
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" />
</el-col>
<el-col :span="2" class="line">-</el-col>
<el-col :span="11">
<el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" />
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery" />
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type" />
<el-checkbox label="Promotion activities" name="type" />
<el-checkbox label="Offline activities" name="type" />
<el-checkbox label="Simple brand exposure" name="type" />
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor" />
<el-radio label="Venue" />
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input v-model="form.desc" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button @click="onCancel">Cancel</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit() {
this.$message('submit!')
},
onCancel() {
this.$message({
message: 'cancel!',
type: 'warning'
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>
......@@ -3,7 +3,7 @@
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
<div class="title-container">
<h3 class="title">Login Form</h3>
<h3 class="title">登录</h3>
</div>
<el-form-item prop="username">
......@@ -44,8 +44,8 @@
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>
<div class="tips">
<span style="margin-right:20px;">username: admin</span>
<span> password: any</span>
<!-- <span style="margin-right:20px;">username: admin</span>-->
<!-- <span> password: any</span>-->
</div>
</el-form>
......@@ -62,11 +62,7 @@ export default {
callback()
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('The password can not be less than 6 digits'))
} else {
callback()
}
callback()
}
return {
loginForm: {
......
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1">
<router-view />
</el-alert>
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-1" type="success">
<router-view />
</el-alert>
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2" type="success">
<router-view />
</el-alert>
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-1" type="warning" />
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-2-2" type="warning" />
</div>
</template>
<template functional>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 1-3" type="success" />
</div>
</template>
<template>
<div style="padding:30px;">
<el-alert :closable="false" title="menu 2" />
</div>
</template>
<template>
<el-form>
<el-form-item label="名称">
<el-input v-model.trim="user.name" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">更新</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: ''
}
}
}
},
methods: {
submit() {
this.$message({
message: 'User information has been updated successfully',
type: 'success',
duration: 5 * 1000
})
}
}
}
</script>
<template>
<el-card style="margin-bottom:20px;">
<div slot="header" class="clearfix">
<span>个人信息</span>
</div>
<div class="user-profile">
<div class="box-center">
<el-avatar :size="60" :src="user.avatar">
<img :src="user.avatar" alt="">
</el-avatar>
</div>
<div class="box-center">
<div class="user-name text-center">{{ user.name }}</div>
</div>
</div>
</el-card>
</template>
<script>
export default {
components: { },
props: {
user: {
type: Object,
default: () => {
return {
name: '',
email: '',
avatar: '',
role: ''
}
}
}
}
}
</script>
<style lang="scss" scoped>
.box-center {
margin: 0 auto;
display: table;
}
.text-muted {
color: #777;
}
.user-profile {
.user-name {
font-weight: bold;
}
.box-center {
padding-top: 10px;
}
.user-role {
padding-top: 10px;
font-weight: 400;
font-size: 14px;
}
.box-social {
padding-top: 30px;
.el-table {
border-top: 1px solid #dfe6ec;
}
}
.user-follow {
padding-top: 20px;
}
}
.user-bio {
margin-top: 20px;
color: #606266;
span {
padding-left: 4px;
}
.user-bio-section {
font-size: 14px;
padding: 15px 0;
.user-bio-section-header {
border-bottom: 1px solid #dfe6ec;
padding-bottom: 10px;
margin-bottom: 10px;
font-weight: bold;
}
}
}
</style>
<template>
<div class="app-container">
<div v-if="user">
<el-row :gutter="20">
<el-col :span="6" :xs="24">
<user-card :user="user" />
</el-col>
<el-col :span="18" :xs="24">
<el-card>
<el-tabs v-model="activeTab">
<el-tab-pane label="资料" name="account">
<account :user="user" />
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import UserCard from './components/UserCard'
import Account from './components/Account'
export default {
name: 'Profile',
components: { UserCard, Account },
data() {
return {
user: {},
activeTab: 'account'
}
},
computed: {
...mapGetters([
'name',
'avatar'
])
},
created() {
this.getUser()
},
methods: {
getUser() {
this.user = {
name: this.name,
avatar: this.avatar
}
}
}
}
</script>
......@@ -4,8 +4,8 @@
<el-tree
:data="treeData"
node-key="id"
:props="{label:'title'}"
default-expand-all
:expand-on-click-node="false"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>{{ node.label }} </span>
......@@ -13,7 +13,7 @@
<el-button
type="text"
size="mini"
@click="() => add(node, data)"
@click="add(node, data)"
>
新增
</el-button>
......@@ -21,7 +21,7 @@
v-if="data.id !== 0"
type="text"
size="mini"
@click="() => edit(node, data)"
@click="edit(node, data)"
>
编辑
</el-button>
......@@ -44,9 +44,8 @@
ref="parent_select"
v-model="form.parent_id"
:options="treeSelectData"
:props="{ expandTrigger: 'hover' ,checkStrictly: true ,emitPath:false}"
:props="{ value:'id', label:'title', expandTrigger: 'hover' ,checkStrictly: true ,emitPath:false}"
:show-all-levels="false"
clearable
/>
</el-form-item>
......@@ -55,15 +54,6 @@
</el-form-item>
<el-form-item label="路由标识" prop="key">
<el-input v-model="form.key" placeholder="输入路由标识" />
<!-- <el-select v-model="form.key" placeholder="请选择前端页面">-->
<!-- <el-option-->
<!-- v-for="item in routePath"-->
<!-- :key="item.key"-->
<!-- :label="item.path"-->
<!-- :value="item.key"-->
<!-- />-->
<!-- </el-select>-->
</el-form-item>
<el-form-item label="后端接口地址" prop="path">
<el-input v-model="form.api" placeholder="输入接口地址" />
......@@ -80,7 +70,7 @@
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button :loading="loading" type="primary" @click="onSubmit">提交</el-button>
</div>
</el-dialog>
......@@ -88,14 +78,14 @@
</template>
<script>
import { menuList, menuAdd, menuDel, menuEdit, menuDetail } from '@/api/menu'
import { constantRouterComponents } from '@/router/config'
import { menuList, menuAdd, menuDel, menuEdit } from '@/api/menu'
import { Message } from 'element-ui'
export default {
name: 'List',
data() {
return {
loading: false,
form_menu_id: 0,
form_parent_menu_id: 0,
dialogFormVisible: false,
......@@ -109,7 +99,7 @@ export default {
form: {
parent_id: 0,
title: '',
key: 'Dashboard',
key: '',
api: '',
icon: '',
is_menu: 1
......@@ -117,16 +107,6 @@ export default {
}
},
computed: {
routePath() {
const map = []
for (const key in constantRouterComponents) {
map.push({
key: key,
path: key
})
}
return map
}
},
created() {
this.init()
......@@ -148,7 +128,7 @@ export default {
const menus = res.data
const rootRouter = {
id: 0,
label: 'ROOT',
title: 'ROOT',
children: []
}
const childrenNav = []
......@@ -158,11 +138,11 @@ export default {
const rootRouterSelect = {
value: 0,
label: 'ROOT',
title: 'ROOT',
children: []
}
const treeChildSelectData = []
this.listToSelectTree(menus, treeChildSelectData, 0)
this.listToTree(menus, treeChildSelectData, 0)
rootRouterSelect.children = treeChildSelectData
this.treeSelectData = [rootRouterSelect]
})
......@@ -173,8 +153,7 @@ export default {
// 判断是否为父级菜单
if (item.parent_id === parentId) {
const child = {
id: item.id,
label: item.title,
...item,
// key: item.key || item.name,
children: []
}
......@@ -189,62 +168,19 @@ export default {
}
})
},
listToSelectTree(list, tree, parentId) {
list.forEach(item => {
// 判断是否为父级菜单
if (item.parent_id === parentId) {
const child = {
value: item.id,
label: item.title,
children: []
}
// 迭代 list, 找到当前菜单相符合的所有子菜单
this.listToSelectTree(list, child.children, item.id)
// 删掉不存在 children 值的属性
if (child.children.length <= 0) {
delete child.children
}
// 加入到树中
tree.push(child)
}
})
},
add(node, data) {
this.resetForm()
this.form = Object.assign({ is_menu: 1 })
this.form_parent_menu_id = data.id
this.form = {
parent_id: this.form_parent_menu_id,
title: '',
key: '',
api: '',
icon: '',
is_menu: 1
}
this.form.parent_id = data.id
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['menuForm'].clearValidate()
})
},
edit(node, data) {
this.resetForm()
this.form_menu_id = data.id
this.dialogStatus = 'edit'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['menuForm'].clearValidate()
})
menuDetail(this.form_menu_id).then(res => {
const menu_data = res.data
this.form = {
parent_id: menu_data.parent_id,
title: menu_data.title,
key: menu_data.key,
api: menu_data.api,
icon: menu_data.icon,
is_menu: menu_data.is_menu
}
})
this.form = data
},
remove(node, data) {
this.$confirm('确定要删除嘛?', '删除', {
......@@ -263,19 +199,17 @@ export default {
})
}).catch(_ => {})
},
onSubmit() {
async onSubmit() {
this.loading = true
if (this.dialogStatus === 'create') {
menuAdd(this.form).then(res => {
this.$refs['menuForm'].resetFields()
Message.success('已添加')
this.init()
})
await menuAdd(this.form)
Message.success('已添加')
} else {
menuEdit(this.form_menu_id, this.form).then(res => {
Message.success('已修改')
this.init()
})
await menuEdit(this.form.id, this.form)
Message.success('已修改')
}
this.loading = false
this.init()
}
}
}
......
......@@ -55,7 +55,7 @@
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirmRole">提交</el-button>
<el-button :loading="loading" type="primary" @click="confirmRole">提交</el-button>
</div>
</el-dialog>
</div>
......@@ -70,6 +70,7 @@ import { Message } from 'element-ui'
export default {
data() {
return {
loading: false,
role: {
name: '',
slug: '',
......@@ -169,11 +170,11 @@ export default {
.catch(err => { console.error(err) })
},
async confirmRole() {
this.loading = true
const isEdit = this.dialogType === 'edit'
const CheckedKeys = this.$refs.tree.getCheckedKeys()
const HalfCheckedKeys = this.$refs.tree.getHalfCheckedKeys()
this.role.menus = [...CheckedKeys, ...HalfCheckedKeys]
console.log(this.role.menus)
if (isEdit) {
await roleEdit(this.role.id, this.role)
for (let index = 0; index < this.data.length; index++) {
......@@ -189,6 +190,7 @@ export default {
this.data.push(this.role)
Message.success('已添加')
}
this.loading = false
this.dialogVisible = false
}
}
......
......@@ -84,7 +84,7 @@
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirmRole">提交</el-button>
<el-button :loading="loading" type="primary" @click="confirmRole">提交</el-button>
</div>
</el-dialog>
</div>
......@@ -99,6 +99,7 @@ import { roleList } from '@/api/role'
export default {
data() {
return {
loading: false,
imageUrl: '',
user: {
username: '',
......@@ -181,6 +182,7 @@ export default {
},
async confirmRole() {
const isEdit = this.dialogType === 'edit'
this.loading = true
if (isEdit) {
await userEdit(this.user.id, this.user)
const newData = this.user
......@@ -211,6 +213,7 @@ export default {
this.data.push(newData)
Message.success('已添加')
}
this.loading = false
this.dialogVisible = false
},
async upload(file) {
......
......@@ -51,7 +51,7 @@
</el-form-item>
<el-form-item v-if="dialogType==='edit'" label="密码">
<el-input v-model="user.password" placeholder="为空不修改" />
</el-form-item>
</el-form-item>
<el-form-item label="头像">
<el-upload
class="avatar-uploader"
......
<template>
<div class="app-container">
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column align="center" label="ID" width="95">
<template slot-scope="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Title">
<template slot-scope="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template slot-scope="scope">
<span>{{ scope.row.author }}</span>
</template>
</el-table-column>
<el-table-column label="Pageviews" width="110" align="center">
<template slot-scope="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="Display_time" width="200">
<template slot-scope="scope">
<i class="el-icon-time" />
<span>{{ scope.row.display_time }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getList } from '@/api/table'
export default {
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getList().then(response => {
this.list = response.data.items
this.listLoading = false
})
}
}
}
</script>
<template>
<div class="app-container">
<el-input v-model="filterText" placeholder="Filter keyword" style="margin-bottom:30px;" />
<el-tree
ref="tree2"
:data="data2"
:props="defaultProps"
:filter-node-method="filterNode"
class="filter-tree"
default-expand-all
/>
</div>
</template>
<script>
export default {
data() {
return {
filterText: '',
data2: [{
id: 1,
label: 'Level one 1',
children: [{
id: 4,
label: 'Level two 1-1',
children: [{
id: 9,
label: 'Level three 1-1-1'
}, {
id: 10,
label: 'Level three 1-1-2'
}]
}]
}, {
id: 2,
label: 'Level one 2',
children: [{
id: 5,
label: 'Level two 2-1'
}, {
id: 6,
label: 'Level two 2-2'
}]
}, {
id: 3,
label: 'Level one 3',
children: [{
id: 7,
label: 'Level two 3-1'
}, {
id: 8,
label: 'Level two 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText(val) {
this.$refs.tree2.filter(val)
}
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>
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