Browse Source

登录/忘记密码page

dev
xuhuajiao 3 years ago
parent
commit
e7f4458c51
  1. 8
      .env.development
  2. 12
      README.md
  3. 5
      src/api/login.js
  4. 5
      src/router/index.js
  5. 79
      src/router/routers.js
  6. 2
      src/store/modules/user.js
  7. 223
      src/views/forgetPassword.vue
  8. 74
      src/views/login.vue
  9. 448
      src/views/system/role/index.vue
  10. 265
      src/views/system/role/role.json
  11. 481
      src/views/system/user/index.vue

8
.env.development

@ -1,12 +1,16 @@
ENV = 'development' ENV = 'development'
# 本地接口地址 # 本地接口地址
VUE_APP_BASE_API = '/dev-api'
#VUE_APP_BASE_API = 'http://192.168.99.103:7000' #VUE_APP_BASE_API = 'http://192.168.99.103:7000'
#VUE_APP_WS_API = 'ws://192.168.99.103:7000' #VUE_APP_WS_API = 'ws://192.168.99.103:7000'
#VUE_APP_BASE_API = 'http://192.168.99.207:7000'
#VUE_APP_WS_API = 'ws://192.168.99.207:7000'
# 外网接口地址 # 外网接口地址
VUE_APP_BASE_API = 'https://yxkadmin.aiyxlib.com'
VUE_APP_WS_API = 'wss://yxkadmin.aiyxlib.com'
#VUE_APP_BASE_API = 'https://yxkadmin.aiyxlib.com'
#VUE_APP_WS_API = 'wss://yxkadmin.aiyxlib.com'
# 是否启用 babel-plugin-dynamic-import-node插件 # 是否启用 babel-plugin-dynamic-import-node插件
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

12
README.md

@ -1 +1,11 @@
多媒体信息发布平台
多媒体信息发布平台
## Getting started
```bash
# install dependency
yarn install
# develop
yarn run dev
```

5
src/api/login.js

@ -1,18 +1,17 @@
import request from '@/utils/request' import request from '@/utils/request'
export function login(username, password, code, uuid) {
export function login(phone, password, code, uuid) {
return request({ return request({
url: 'auth/login', url: 'auth/login',
method: 'post', method: 'post',
data: { data: {
username,
phone,
password, password,
code, code,
uuid uuid
} }
}) })
} }
export function getInfo() { export function getInfo() {
return request({ return request({
url: 'auth/info', url: 'auth/info',

5
src/router/index.js

@ -9,13 +9,16 @@ import { filterAsyncRouter } from '@/store/modules/permission'
NProgress.configure({ showSpinner: false }) // NProgress Configuration NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
const whiteList = ['/login', '/forgetPassword'] // no redirect whitelist
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
if (to.meta.title) { if (to.meta.title) {
document.title = to.meta.title + ' - ' + Config.title document.title = to.meta.title + ' - ' + Config.title
} }
// 加载效果
NProgress.start() NProgress.start()
// next()
// NProgress.done()
if (getToken()) { if (getToken()) {
// 已登录且要跳转的页面是登录页 // 已登录且要跳转的页面是登录页
if (to.path === '/login') { if (to.path === '/login') {

79
src/router/routers.js

@ -7,10 +7,22 @@ Vue.use(Router)
export const constantRouterMap = [ export const constantRouterMap = [
{ {
path: '/login', path: '/login',
meta: { title: '登录', noCache: true },
meta: {
title: '登录',
noCache: true
},
component: resolve => require(['@/views/login'], resolve), component: resolve => require(['@/views/login'], resolve),
hidden: true hidden: true
}, },
{
path: '/forgetPassword',
meta: {
title: '忘记密码',
noCache: true
},
component: resolve => require(['@/views/forgetPassword'], resolve),
hidden: true
},
{ {
path: '/404', path: '/404',
component: resolve => require(['@/views/features/404'], resolve), component: resolve => require(['@/views/features/404'], resolve),
@ -25,26 +37,61 @@ export const constantRouterMap = [
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,
hidden: true, hidden: true,
children: [
{
path: '/redirect/:path*',
component: resolve => require(['@/views/features/redirect'], resolve)
}
]
children: [{
path: '/redirect/:path*',
component: resolve => require(['@/views/features/redirect'], resolve)
}]
}, },
{ {
path: '/', path: '/',
component: Layout, component: Layout,
redirect: '/dashboard', redirect: '/dashboard',
children: [
{
path: 'dashboard',
component: resolve => require(['@/views/home'], resolve),
name: 'Dashboard',
meta: { title: '首页', icon: 'index', affix: true, noCache: true }
children: [{
path: 'dashboard',
component: resolve => require(['@/views/home'], resolve),
name: 'Dashboard',
meta: {
title: '首页',
icon: 'index',
affix: true,
noCache: true
} }
]
}]
}, },
// {
// path: '/user',
// component: Layout,
// redirect: '/system/user',
// meta: {
// title: '用户管理',
// icon: 'documentation'
// },
// children: [{
// path: '/system/user',
// component: () => import('@/views/system/user/index'),
// meta: {
// title: '用户管理',
// icon: 'edit'
// }
// }]
// },
// {
// path: '/role',
// component: Layout,
// redirect: '/system/role',
// meta: {
// title: '角色管理',
// icon: 'documentation'
// },
// children: [{
// path: '/system/role',
// component: () => import('@/views/system/role/index'),
// meta: {
// title: '角色管理',
// icon: 'edit'
// }
// }]
// }
{ {
path: '/user', path: '/user',
component: Layout, component: Layout,
@ -65,6 +112,8 @@ export default new Router({
// 修改路由,取消hash的注释改变部署模式 // 修改路由,取消hash的注释改变部署模式
// mode: 'hash', // mode: 'hash',
mode: 'history', mode: 'history',
scrollBehavior: () => ({ y: 0 }),
scrollBehavior: () => ({
y: 0
}),
routes: constantRouterMap routes: constantRouterMap
}) })

2
src/store/modules/user.js

@ -30,7 +30,7 @@ const user = {
Login({ commit }, userInfo) { Login({ commit }, userInfo) {
const rememberMe = userInfo.rememberMe const rememberMe = userInfo.rememberMe
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
login(userInfo.username, userInfo.password, userInfo.code, userInfo.uuid).then(res => {
login(userInfo.phone, userInfo.password, userInfo.code, userInfo.uuid).then(res => {
setToken(res.token, rememberMe) setToken(res.token, rememberMe)
commit('SET_TOKEN', res.token) commit('SET_TOKEN', res.token)
setUserInfo(res.user, commit) setUserInfo(res.user, commit)

223
src/views/forgetPassword.vue

@ -0,0 +1,223 @@
<template>
<div class="login" :style="'background-image:url('+ Background +');'">
<el-form ref="modifyForm" :model="modifyForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
<h3 class="title">
多媒体信息发布平台-忘记密码
</h3>
<el-form-item prop="phone">
<el-input v-model="modifyForm.phone" type="text" auto-complete="off" placeholder="手机号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="modifyForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleModify">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<el-button :disable="disabledSendCode" :type="disabledSendCode==false?'primary':'info'" size="medium" style="width:100%;" @click="countdown()">
{{ verification }}
</el-button>
</div>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="modifyForm.password" type="password" auto-complete="off" placeholder="新密码" @keyup.enter.native="handleModify">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input v-model="modifyForm.confirmPassword" type="password" auto-complete="off" placeholder="确认密码" @keyup.enter.native="handleModify">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleModify">
<span v-if="!loading">确定修改</span>
<span v-else>修改密码中...</span>
</el-button>
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" style="width:100%;">
<span @click="toLogin()"> </span>
</el-button>
</el-form-item>
</el-form>
<!-- 底部 -->
<div v-if="$store.state.settings.showFooter" id="el-login-footer">
<span v-html="$store.state.settings.footerTxt" />
<span> </span>
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">{{ $store.state.settings.caseNumber }}</a>
</div>
</div>
</template>
<script>
// import { encrypt } from '@/utils/rsaEncrypt'
import { isvalidPhone } from '@/utils/validate'
// import { getCodeImg } from '@/api/login'
import Background from '@/assets/images/background.jpg'
export default {
name: 'ForgetPassword',
data() {
//
const validPhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入手机号码'))
} else if (!isvalidPhone(value)) {
callback(new Error('请输入正确的11位手机号码'))
} else {
callback()
}
}
const validatePass = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入新密码'))
} else if (value.toString().length < 6 || value.toString().length > 18) {
callback(new Error('密码长度为6-18位'))
} else {
callback()
}
}
const validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.modifyForm.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return {
Background: Background,
disabledSendCode: false,
verification: '获取验证码',
countNum: 60,
modifyForm: {
phone: '',
password: '',
confirmPassword: '',
code: '',
uuid: ''
},
loginRules: {
phone: [{ required: true, trigger: 'blur', validator: validPhone }],
password: [{ required: true, trigger: 'blur', validator: validatePass }],
confirmPassword: [{ required: true, trigger: 'blur', validator: validatePass2 }],
code: [{ required: true, trigger: 'change', message: '验证码不能为空' }]
},
loading: false,
redirect: undefined
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
},
methods: {
getAuthCode() {
},
countdown() {
if (this.disabledSendCode) {
return
}
if (!/^1\d{10}$/.test(this.modifyForm.phone)) {
this.$message.error('手机号错误,请重新输入')
return
}
this.getAuthCode()
this.disabledSendCode = true
this.countNum = 60
const timer = setInterval(() => {
this.verification = this.countNum + 's后重新获取'
this.countNum -= 1
if (this.countNum < 1) {
clearInterval(timer)
this.verification = '重新获取'
this.disabledSendCode = false
console.log('倒计时结束')
}
}, 1000)
},
toLogin() {
this.$router.push(`/login`)
},
handleModify() {
this.$refs.modifyForm.validate(valid => {
const params = {
phone: this.modifyForm.phone,
password: this.modifyForm.password,
confirmPassword: this.modifyForm.confirmPassword,
code: this.modifyForm.code,
uuid: this.modifyForm.uuid
}
// if (user.password !== this.cookiePass) {
// user.password = encrypt(user.password)
// }
if (valid) {
this.loading = true
this.$store.dispatch('Login', params).then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/' })
}).catch(() => {
this.loading = false
this.getCode()
})
} else {
console.log('error submit!!')
return false
}
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-size: cover;
}
.title {
margin: 0 auto 30px auto;
text-align: center;
color: #707070;
}
.login-form {
border-radius: 6px;
background: #ffffff;
width: 385px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon{
height: 39px;width: 14px;margin-left: 2px;
}
}
.login-code {
width: 33%;
display: inline-block;
height: 38px;
float: right;
.el-button--medium{
font-size: 12px;
padding: 10px;
}
img{
cursor: pointer;
vertical-align:middle
}
}
</style>

74
src/views/login.vue

@ -4,8 +4,8 @@
<h3 class="title"> <h3 class="title">
多媒体信息发布平台 多媒体信息发布平台
</h3> </h3>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<el-form-item prop="phone">
<el-input v-model="loginForm.phone" type="text" auto-complete="off" placeholder="手机号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -22,15 +22,23 @@
<img :src="codeUrl" @click="getCode"> <img :src="codeUrl" @click="getCode">
</div> </div>
</el-form-item> </el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">
记住我
</el-checkbox>
<el-form-item prop="agree" class="login_checked" style="line-height: 0;">
<el-checkbox v-model="loginForm.agree">
我已阅读并同意用户隐私政策
</el-checkbox>
</el-form-item>
<el-form-item style="width:100%;"> <el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin"> <el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
<span v-if="!loading"> </span> <span v-if="!loading"> </span>
<span v-else> 中...</span> <span v-else> 中...</span>
</el-button> </el-button>
</el-form-item> </el-form-item>
<div class="login_bottom">
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;" class="login_checked">
记住密码
</el-checkbox>
<span @click="toForgetPassword()">忘记密码</span>
</div>
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div v-if="$store.state.settings.showFooter" id="el-login-footer"> <div v-if="$store.state.settings.showFooter" id="el-login-footer">
@ -43,6 +51,7 @@
<script> <script>
import { encrypt } from '@/utils/rsaEncrypt' import { encrypt } from '@/utils/rsaEncrypt'
import { isvalidPhone } from '@/utils/validate'
import Config from '@/settings' import Config from '@/settings'
import { getCodeImg } from '@/api/login' import { getCodeImg } from '@/api/login'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
@ -50,21 +59,33 @@ import Background from '@/assets/images/background.jpg'
export default { export default {
name: 'Login', name: 'Login',
data() { data() {
//
const validPhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入手机号码'))
} else if (!isvalidPhone(value)) {
callback(new Error('请输入正确的11位手机号码'))
} else {
callback()
}
}
return { return {
Background: Background, Background: Background,
codeUrl: '', codeUrl: '',
cookiePass: '', cookiePass: '',
loginForm: { loginForm: {
username: 'admin',
phone: '15902734788',
password: '123456', password: '123456',
rememberMe: false, rememberMe: false,
code: '', code: '',
uuid: ''
uuid: '',
agree: false
}, },
loginRules: { loginRules: {
username: [{ required: true, trigger: 'blur', message: '用户名不能为空' }],
phone: [{ required: true, trigger: 'blur', validator: validPhone }],
password: [{ required: true, trigger: 'blur', message: '密码不能为空' }], password: [{ required: true, trigger: 'blur', message: '密码不能为空' }],
code: [{ required: true, trigger: 'change', message: '验证码不能为空' }]
code: [{ required: true, trigger: 'change', message: '验证码不能为空' }],
agree: [{ required: true, trigger: 'change', message: '请阅读并勾选用户隐私政策' }]
}, },
loading: false, loading: false,
redirect: undefined redirect: undefined
@ -94,28 +115,31 @@ export default {
}) })
}, },
getCookie() { getCookie() {
const username = Cookies.get('username')
const phone = Cookies.get('phone')
let password = Cookies.get('password') let password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe') const rememberMe = Cookies.get('rememberMe')
// cookie // cookie
this.cookiePass = password === undefined ? '' : password this.cookiePass = password === undefined ? '' : password
password = password === undefined ? this.loginForm.password : password password = password === undefined ? this.loginForm.password : password
this.loginForm = { this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
phone: phone === undefined ? this.loginForm.phone : phone,
password: password, password: password,
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
code: '' code: ''
} }
}, },
toForgetPassword() {
this.$router.push(`/forgetPassword`)
},
handleLogin() { handleLogin() {
// this.$router.push('/')
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate(valid => {
const user = { const user = {
username: this.loginForm.username,
phone: this.loginForm.phone,
password: this.loginForm.password, password: this.loginForm.password,
rememberMe: this.loginForm.rememberMe, rememberMe: this.loginForm.rememberMe,
code: this.loginForm.code, code: this.loginForm.code,
uuid: this.loginForm.uuid
uuid: this.loginForm.uuid,
agree: this.loginForm.agree
} }
if (user.password !== this.cookiePass) { if (user.password !== this.cookiePass) {
user.password = encrypt(user.password) user.password = encrypt(user.password)
@ -123,11 +147,11 @@ export default {
if (valid) { if (valid) {
this.loading = true this.loading = true
if (user.rememberMe) { if (user.rememberMe) {
Cookies.set('username', user.username, { expires: Config.passCookieExpires })
Cookies.set('phone', user.phone, { expires: Config.passCookieExpires })
Cookies.set('password', user.password, { expires: Config.passCookieExpires }) Cookies.set('password', user.password, { expires: Config.passCookieExpires })
Cookies.set('rememberMe', user.rememberMe, { expires: Config.passCookieExpires }) Cookies.set('rememberMe', user.rememberMe, { expires: Config.passCookieExpires })
} else { } else {
Cookies.remove('username')
Cookies.remove('phone')
Cookies.remove('password') Cookies.remove('password')
Cookies.remove('rememberMe') Cookies.remove('rememberMe')
} }
@ -204,4 +228,22 @@ export default {
vertical-align:middle vertical-align:middle
} }
} }
.login_checked{
.el-checkbox__label{
font-size: 12px;
}
.el-form-item__content{
line-height: 0;
}
}
.login_bottom{
display: flex;
justify-content: space-between;
font-size: 12px;
color: #606266;
span{
cursor: pointer;
}
}
</style> </style>

448
src/views/system/role/index.vue

@ -2,73 +2,76 @@
<div class="app-container"> <div class="app-container">
<!--工具栏--> <!--工具栏-->
<div class="head-container"> <div class="head-container">
<div v-if="crud.props.searchToggle">
<el-col :span="20">
<!-- 搜索 --> <!-- 搜索 -->
<el-input v-model="query.blurry" size="small" clearable placeholder="输入名称或者描述搜索" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<date-range-picker v-model="query.createTime" class="date-item" />
<el-input v-model="query.blurry" clearable size="small" placeholder="角色名称" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<rrOperation /> <rrOperation />
</div>
<crudOperation :permission="permission" />
</el-col>
<el-col class="page_add" :span="4"><el-button class="table_add" type="primary" icon="el-icon-plus" @click="roleFormVisible = true">新增</el-button></el-col>
</div> </div>
<!-- 表单渲染 --> <!-- 表单渲染 -->
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="520px">
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="roleFormVisible" :title="crud.status.title" width="600px" top="20px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="角色名称" prop="name">
<el-input v-model="form.name" style="width: 380px;" />
</el-form-item>
<el-form-item label="角色级别" prop="level">
<el-input-number v-model.number="form.level" :min="1" controls-position="right" style="width: 145px;" />
</el-form-item>
<el-form-item label="数据范围" prop="dataScope">
<el-select v-model="form.dataScope" style="width: 140px" placeholder="请选择数据范围" @change="changeScope">
<el-option
v-for="item in dateScopes"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item v-if="form.dataScope === '自定义'" label="数据权限" prop="depts">
<treeselect
v-model="deptDatas"
:load-options="loadDepts"
:options="depts"
multiple
style="width: 380px"
placeholder="请选择"
/>
</el-form-item>
<el-form-item label="描述信息" prop="description">
<el-input v-model="form.description" style="width: 380px;" rows="5" type="textarea" />
<el-form-item label="角色名称" prop="roleName"><el-input v-model="form.roleName" style="width: 380px;" /></el-form-item>
<el-form-item label="描述" prop="description"><el-input v-model="form.description" style="width: 380px;" /></el-form-item>
<el-form-item v-for="item in roleTree" :key="item.key" class="press_form" :label="item.Title" :prop="item.Title">
<el-checkbox-group v-for="checkItem in item.children" :key="checkItem.key" v-model="selectCheckboxForm[item.Title]" class="press_list">
<el-checkbox :v-model="checkItem.IsCheck" :label="checkItem.Title" name="permissionAll" />
</el-checkbox-group>
</el-form-item> </el-form-item>
<!-- <el-tree
ref="menu"
:data="roleTree"
:props="defaultProps"
check-strictly
show-checkbox
node-key="Key"
:default-checked-keys="Key"
default-expand-all
/> -->
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button> <el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button> <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="recordVisible" :title="crud.status.title">
<el-table :data="recordData">
<el-table-column property="name" label="操作人" />
<el-table-column property="permissionType" label="角色权限" />
<el-table-column property="account" label="登录账号" />
<el-table-column property="type" label="操作类型" />
<el-table-column property="date" label="操作时间" />
</el-table>
</el-dialog>
<el-row :gutter="15"> <el-row :gutter="15">
<!--角色管理--> <!--角色管理-->
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
<el-col>
<el-card class="box-card" shadow="never"> <el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<!-- <div slot="header" class="clearfix">
<span class="role-span">角色列表</span> <span class="role-span">角色列表</span>
</div>
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
<el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column prop="name" label="名称" />
<el-table-column prop="dataScope" label="数据权限" />
<el-table-column prop="level" label="角色级别" />
<el-table-column :show-overflow-tooltip="true" prop="description" label="描述" />
<el-table-column :show-overflow-tooltip="true" width="135px" prop="createTime" label="创建日期" />
<el-table-column v-if="checkPer(['admin','roles:edit','roles:del'])" label="操作" width="130px" align="center" fixed="right">
</div> -->
<el-table
ref="table"
v-loading="crud.loading"
highlight-current-row
style="width: 100%;"
:data="roleData"
@selection-change="crud.selectionChangeHandler"
@current-change="handleCurrentChange"
>
<el-table-column :selectable="checkboxT" align="center" type="selection" width="55" />
<el-table-column align="center" prop="roleName" label="角色名称" />
<el-table-column align="center" prop="description" label="描述" />
<el-table-column header-align="center" width="600" prop="permissionList" label="相关权限">
<template slot-scope="scope"> <template slot-scope="scope">
<udOperation
v-if="scope.row.level >= level"
:data="scope.row"
:permission="permission"
/>
<el-tag v-for="tag in scope.row.permissionList" :key="tag.name" type="primary">{{ tag.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="140" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" @click="editFormData(scope.$index, scope.row)" />
<el-button type="info" icon="el-icon-info" @click="handleRecord(scope.$index, scope.row)" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -76,76 +79,83 @@
<pagination /> <pagination />
</el-card> </el-card>
</el-col> </el-col>
<!-- 菜单授权 -->
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
<span class="role-span">菜单分配</span>
</el-tooltip>
<el-button
v-permission="['admin','roles:edit']"
:disabled="!showButton"
:loading="menuLoading"
icon="el-icon-check"
size="mini"
style="float: right; padding: 6px 9px"
type="primary"
@click="saveMenu"
>保存</el-button>
</div>
<el-tree
ref="menu"
lazy
:data="menus"
:default-checked-keys="menuIds"
:load="getMenuDatas"
:props="defaultProps"
check-strictly
accordion
show-checkbox
node-key="id"
@check="menuChange"
/>
</el-card>
</el-col>
</el-row> </el-row>
</div> </div>
</template> </template>
<script> <script>
import crudRoles from '@/api/system/role' import crudRoles from '@/api/system/role'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getMenusTree, getChild } from '@/api/system/menu'
import CRUD, { presenter, header, form, crud } from '@crud/crud' import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination' import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import DateRangePicker from '@/components/DateRangePicker'
import roleTree from './role.json'
const defaultForm = { id: null, name: null, depts: [], description: null, dataScope: '全部', level: 3 }
const defaultForm = {
id: null,
roleName: null,
permissionAll: [],
library: [],
publish: [],
description: null
}
export default { export default {
name: 'Role', name: 'Role',
components: { Treeselect, pagination, crudOperation, rrOperation, udOperation, DateRangePicker },
components: { pagination, rrOperation },
cruds() { cruds() {
return CRUD({ title: '角色', url: 'api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }}) return CRUD({ title: '角色', url: 'api/roles', sort: 'level,asc', crudMethod: { ...crudRoles }})
}, },
mixins: [presenter(), header(), form(defaultForm), crud()], mixins: [presenter(), header(), form(defaultForm), crud()],
data() { data() {
return { return {
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
dateScopes: ['全部', '本级', '自定义'], level: 3,
currentId: 0, menuLoading: false, showButton: false,
menus: [], menuIds: [], depts: [], deptDatas: [], // 使
roleFormVisible: false,
recordVisible: false,
permission: { permission: {
add: ['admin', 'roles:add'], add: ['admin', 'roles:add'],
edit: ['admin', 'roles:edit'], edit: ['admin', 'roles:edit'],
del: ['admin', 'roles:del'] del: ['admin', 'roles:del']
}, },
roleData: [
{
id: 1,
roleName: '机构超级管理员',
description: '系统内置',
permissionList: [
{ name: '紧急通知' },
{ name: '内容发布服务' },
{ name: '播放列表服务' },
{ name: '主题模版' },
{ name: '设备列表' },
{ name: '开关机配置' },
{ name: '素材库' },
{ name: '权限管理' },
{ name: '用户管理' }
]
}
],
recordData: [
{
id: 1,
name: 'xxx',
account: '15100701025',
permissionType: '平台技术人员',
type: 'editor',
date: '2021-1-1 14:00'
}
],
roleTree: null,
defaultProps: { children: 'children', label: 'Title', isLeaf: 'leaf' },
selectCheckboxForm: {
'权限': [],
'素材库': [],
'内容发布': [],
'紧急通知': [],
'播放列表': [],
'主题模板': [],
'设备列表': [],
'开关机': [],
'权限管理': [],
'角色管理': []
},
rules: { rules: {
name: [ name: [
{ required: true, message: '请输入名称', trigger: 'blur' } { required: true, message: '请输入名称', trigger: 'blur' }
@ -157,201 +167,67 @@ export default {
} }
}, },
created() { created() {
crudRoles.getLevel().then(data => {
this.level = data.level
})
this.roleTree = roleTree
console.log(roleTree)
}, },
methods: { methods: {
getMenuDatas(node, resolve) {
setTimeout(() => {
getMenusTree(node.data.id ? node.data.id : 0).then(res => {
resolve(res)
})
}, 100)
},
[CRUD.HOOK.afterRefresh]() {
this.$refs.menu.setCheckedKeys([])
},
//
[CRUD.HOOK.beforeToAdd]() {
this.deptDatas = []
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
this.deptDatas = []
if (form.dataScope === '自定义') {
this.getSupDepts(form.depts)
}
const _this = this
form.depts.forEach(function(dept) {
_this.deptDatas.push(dept.id)
})
},
//
[CRUD.HOOK.afterValidateCU](crud) {
if (crud.form.dataScope === '自定义' && this.deptDatas.length === 0) {
this.$message({
message: '自定义数据权限不能为空',
type: 'warning'
})
return false
} else if (crud.form.dataScope === '自定义') {
const depts = []
this.deptDatas.forEach(function(data) {
const dept = { id: data }
depts.push(dept)
})
crud.form.depts = depts
} else {
crud.form.depts = []
}
return true
},
//
handleCurrentChange(val) {
if (val) {
const _this = this
//
this.$refs.menu.setCheckedKeys([])
// id
this.currentId = val.id
// key
this.menuIds = []
val.menus.forEach(function(data) {
_this.menuIds.push(data.id)
})
this.showButton = true
}
},
menuChange(menu) {
// id
getChild(menu.id).then(childIds => {
// menuIds
if (this.menuIds.indexOf(menu.id) !== -1) {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index !== -1) {
this.menuIds.splice(index, 1)
}
}
} else {
for (let i = 0; i < childIds.length; i++) {
const index = this.menuIds.indexOf(childIds[i])
if (index === -1) {
this.menuIds.push(childIds[i])
}
}
}
this.$refs.menu.setCheckedKeys(this.menuIds)
})
},
//
saveMenu() {
this.menuLoading = true
const role = { id: this.currentId, menus: [] }
// key
this.menuIds.forEach(function(id) {
const menu = { id: id }
role.menus.push(menu)
})
crudRoles.editMenu(role).then(() => {
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.menuLoading = false
this.update()
}).catch(err => {
this.menuLoading = false
console.log(err.response.data.message)
})
},
//
update() {
//
crudRoles.get(this.currentId).then(res => {
for (let i = 0; i < this.crud.data.length; i++) {
if (res.id === this.crud.data[i].id) {
this.crud.data[i] = res
break
}
}
})
},
//
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(depts) {
const ids = []
depts.forEach(dept => {
ids.push(dept.id)
})
getDeptSuperior(ids).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
}
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
//
changeScope() {
if (this.form.dataScope === '自定义') {
this.getDepts()
}
},
checkboxT(row) { checkboxT(row) {
return row.level >= this.level return row.level >= this.level
},
editFormData(index, row) {
this.roleFormVisible = true
this.form.roleName = row.roleName
this.form.description = row.description
},
handleRecord(index, row) {
this.recordVisible = true
// switch (that.recordData[i].operateType) {
// case 'Edit':
// that.recordData[i].operateType = ''
// break
// case 'Add':
// that.recordData[i].operateType = ''
// break
// case 'Del':
// that.recordData[i].operateType = ''
// break
// case 'Recover':
// that.recordData[i].operateType = ''
// break
// }
} }
} }
} }
</script> </script>
<style rel="stylesheet/scss" lang="scss">
.role-span {
font-weight: bold;color: #303133;
font-size: 15px;
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value{
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item{
border: 0;
padding: 0;
}
<style lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
::v-deep .vue-treeselect__multi-value {
margin-bottom: 0;
}
::v-deep .vue-treeselect__multi-value-item {
border: 0;
padding: 0;
}
.head-container{
height: 44px;
}
// start
.page_add {
text-align: right;
}
// end
.el-tag {
margin: 5px 10px 5px 0;
}
.press_form {
display: flex;
}
.press_form ::v-deep .el-form-item__content {
display: flex;
}
.press_list {
margin-right: 10px;
}
</style> </style>

265
src/views/system/role/role.json

@ -0,0 +1,265 @@
[{
"IsCheck": "False",
"Key": "1",
"Title": "权限",
"children": [{
"IsCheck": "False",
"Key": "1-1",
"Title": "全部"
}]
},
{
"IsCheck": "False",
"Key": "2",
"Title": "素材库",
"children": [{
"IsCheck": "true",
"Key": "2-1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2-2",
"Title": "编辑"
},
{
"IsCheck": "true",
"Key": "2-3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "2-4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "2-5",
"Title": "上传"
},
{
"IsCheck": "False",
"Key": "2-6",
"Title": "下载"
}
]
},
{
"IsCheck": "False",
"Key": "3",
"Title": "内容发布",
"children": [{
"IsCheck": "False",
"Key": "3-1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "3-2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3-3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "3-4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "3-5",
"Title": "添加"
}
]
},
{
"IsCheck": "False",
"Key": "4",
"Title": "紧急通知",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "5",
"Title": "添加"
}
]
},
{
"IsCheck": "False",
"Key": "5",
"Title": "播放列表",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "查看"
}
]
},
{
"IsCheck": "False",
"Key": "6",
"Title": "主题模板",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "查看"
}
]
},
{
"IsCheck": "False",
"Key": "7",
"Title": "设备列表",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "5",
"Title": "添加"
}
]
},
{
"IsCheck": "False",
"Key": "8",
"Title": "开关机",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "5",
"Title": "添加"
}
]
},
{
"IsCheck": "False",
"Key": "9",
"Title": "权限管理",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "5",
"Title": "添加"
}
]
},
{
"IsCheck": "False",
"Key": "10",
"Title": "角色管理",
"children": [{
"IsCheck": "False",
"Key": "1",
"Title": "全部"
},
{
"IsCheck": "False",
"Key": "2",
"Title": "编辑"
},
{
"IsCheck": "False",
"Key": "3",
"Title": "查看"
},
{
"IsCheck": "False",
"Key": "4",
"Title": "删除"
},
{
"IsCheck": "False",
"Key": "5",
"Title": "添加"
}
]
}
]

481
src/views/system/user/index.vue

@ -1,33 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-row :gutter="20"> <el-row :gutter="20">
<!--侧边部门数据-->
<!-- <el-col :xs="9" :sm="6" :md="5" :lg="4" :xl="4">
<div class="head-container">
<el-input
v-model="deptName"
clearable
size="small"
placeholder="输入部门名称搜索"
prefix-icon="el-icon-search"
class="filter-item"
@input="getDeptDatas"
/>
</div>
<el-tree
:data="deptDatas"
:load="getDeptDatas"
:props="defaultProps"
:expand-on-click-node="false"
lazy
@node-click="handleNodeClick"
/>
</el-col> -->
<!--用户数据--> <!--用户数据-->
<el-col :xs="15" :sm="18" :md="19" :lg="20" :xl="20">
<el-col>
<!--工具栏--> <!--工具栏-->
<div class="head-container"> <div class="head-container">
<div v-if="crud.props.searchToggle">
<el-col :span="20">
<!-- 搜索 --> <!-- 搜索 -->
<el-input <el-input
v-model="query.blurry" v-model="query.blurry"
@ -48,52 +26,100 @@
@keyup.enter.native="crud.toQuery" @keyup.enter.native="crud.toQuery"
/> />
<rrOperation /> <rrOperation />
</div>
<crudOperation show="" :permission="permission" />
</el-col>
<el-col class="page_add" :span="4">
<el-button class="table_add" type="primary" icon="el-icon-plus" @click="addDialogVisible = true">新增</el-button>
</el-col>
</div> </div>
<!--表单渲染-->
<!-- <el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="570px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="66px">
<el-form-item label="登录账号" prop="username">
<el-input v-model="form.username" />
<!--新增用户-->
<el-dialog append-to-body :close-on-click-modal="false" :show-close="false" :before-close="crud.cancelCU" :visible.sync="addDialogVisible" title="新增" width="400px">
<el-form ref="form" :inline="true" :model="form" size="small" label-width="100px">
<el-form-item
label="登录账号"
prop="account"
:rules="[
{ required: true, message: '请输入登录账号', trigger: 'blur' }
]"
>
<el-input v-model="form.account" style="width: 200px" />
</el-form-item> </el-form-item>
<el-form-item label="管理员名称" prop="phone">
<el-input v-model.number="form.phone" />
<el-form-item
label="管理员名称"
prop="nickName"
:rules="[
{ required: true, message: '请输入管理员名称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
]"
>
<el-input v-model="form.nickName" style="width: 200px" />
</el-form-item> </el-form-item>
<el-form-item label="管理角色" prop="nickName">
<el-input v-model="form.nickName" />
<el-form-item
label="管理员角色"
prop="roles"
:rules="[
{ required: true, message: '请选择管理员角色', trigger: 'change' }
]"
>
<el-select v-model="form.roles" placeholder="请选择管理员角色">
<el-option label="机构超级管理员" value="1" />
<el-option label="普通用户" value="2" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="机构名称" prop="email">
<el-input v-model="form.email" />
<el-form-item
label="管理员状态"
prop="enabled"
:rules="[
{ required: true, trigger: 'change', message: '请选择管理员状态' }
]"
>
<el-select v-model="form.enabled" placeholder="请选择管理员状态">
<el-option label="启用" value="1" />
<el-option label="关闭" value="0" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="email">
<el-input v-model="form.email" />
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">关闭</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div>
</el-dialog>
<!-- 编辑用户 -->
<el-dialog append-to-body :close-on-click-modal="false" :show-close="false" :before-close="crud.cancelCU" :visible.sync="editDialogVisible" title="编辑" width="480px">
<el-form ref="form" :inline="true" :model="editForm" :rules="rules" size="small" label-width="100px">
<el-form-item label="管理员名称" prop="nickName">
<el-input v-model="editForm.nickName" style="width: 200px" />
</el-form-item> </el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.enabled" :disabled="form.id === user.id">
<el-radio
v-for="item in dict.user_status"
:key="item.id"
:label="item.value"
>{{ item.label }}</el-radio>
</el-radio-group>
<el-form-item label="管理员角色" prop="roles">
<el-input v-model="editForm.roles" disabled style="width: 200px" />
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="email">
<el-input v-model="form.email" />
<el-form-item label="机构名称" prop="orgName">
<el-input v-model="editForm.orgName" disabled style="width: 200px" />
</el-form-item>
<el-form-item label="更改手机号" prop="phone">
<el-input v-model.number="editForm.phone" style="width: 200px" />
</el-form-item>
<el-form-item label="获取验证码" prop="code">
<el-input v-model.number="editForm.code" style="width: 200px" />
<el-button class="edit_code" type="primary" :disabled="disabledSendCode" @click="countdown()">{{ verification }}</el-button>
</el-form-item>
<el-form-item label="登录密码" prop="password">
<el-input v-model="editForm.password" style="width: 200px" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
<el-button type="text" @click="crud.cancelCU">关闭</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
</div> </div>
</el-dialog> -->
</el-dialog>
<!--表格渲染--> <!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<!-- :data="crud.data" -->
<el-table ref="table" v-loading="crud.loading" :data="userData" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column :selectable="checkboxT" type="selection" width="55" /> <el-table-column :selectable="checkboxT" type="selection" width="55" />
<el-table-column :show-overflow-tooltip="true" prop="account" label="登录账号" />
<el-table-column :show-overflow-tooltip="true" prop="roles" label="管理角色" />
<el-table-column prop="name" label="机构名称" />
<el-table-column :show-overflow-tooltip="true" prop="phone" width="100" label="手机号码" />
<el-table-column prop="account" width="135" align="center" label="登录账号" />
<el-table-column prop="nickName" align="center" label="管理员名称" />
<el-table-column prop="roles" align="center" label="管理角色" />
<el-table-column prop="orgName" align="center" label="机构名称" />
<el-table-column prop="phone" align="center" label="手机号码" />
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" prop="enabled"> <el-table-column label="状态" align="center" prop="enabled">
<template slot-scope="scope"> <template slot-scope="scope">
@ -106,26 +132,32 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="createTime" width="135" label="创建日期" />
<el-table-column prop="createTime" width="135" label="创建日期" />
<!-- v-if="checkPer(['admin','user:edit','user:del'])" -->
<el-table-column <el-table-column
v-if="checkPer(['admin','user:edit','user:del'])"
label="操作" label="操作"
width="115"
width="140"
align="center" align="center"
fixed="right" fixed="right"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<udOperation
<!-- <udOperation
:data="scope.row" :data="scope.row"
:permission="permission" :permission="permission"
:disabled-dle="scope.row.id === user.id" :disabled-dle="scope.row.id === user.id"
/> -->
<el-button
type="primary"
icon="el-icon-edit"
@click="editFormData(scope.$index, scope.row)"
/> />
<el-button type="danger" icon="el-icon-delete" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!--分页组件--> <!--分页组件-->
<pagination /> <pagination />
</el-col>
</el-dialog></el-col>
</el-row> </el-row>
</div> </div>
</template> </template>
@ -133,29 +165,27 @@
<script> <script>
import crudUser from '@/api/system/user' import crudUser from '@/api/system/user'
import { isvalidPhone } from '@/utils/validate' import { isvalidPhone } from '@/utils/validate'
import { getDepts, getDeptSuperior } from '@/api/system/dept'
import { getAll, getLevel } from '@/api/system/role'
import { getAllJob } from '@/api/system/job'
import CRUD, { presenter, header, form, crud } from '@crud/crud' import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation' import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
// import crudOperation from '@crud/CRUD.operation'
// import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination' import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
let userRoles = []
let userJobs = []
const defaultForm = { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 'false', roles: [], jobs: [], dept: { id: null }, phone: null }
const defaultForm = {
id: null,
account: null,
nickName: '',
roles: null,
enabled: ''
}
export default { export default {
name: 'User', name: 'User',
components: { crudOperation, rrOperation, udOperation, pagination },
components: { rrOperation, pagination },
cruds() { cruds() {
return CRUD({ title: '用户', url: 'api/users', crudMethod: { ...crudUser }}) return CRUD({ title: '用户', url: 'api/users', crudMethod: { ...crudUser }})
}, },
mixins: [presenter(), header(), form(defaultForm), crud()], mixins: [presenter(), header(), form(defaultForm), crud()],
// //
dicts: ['user_status'],
data() { data() {
// //
const validPhone = (rule, value, callback) => { const validPhone = (rule, value, callback) => {
@ -168,34 +198,50 @@ export default {
} }
} }
return { return {
addDialogVisible: false,
editDialogVisible: false,
editForm: {
nickName: '',
roles: '',
orgName: '',
phone: '',
code: '',
password: ''
},
disabledSendCode: false,
verification: '获取验证码',
countNum: 60,
height: document.documentElement.clientHeight - 180 + 'px;', height: document.documentElement.clientHeight - 180 + 'px;',
deptName: '', depts: [], deptDatas: [], jobs: [], level: 3, roles: [],
jobDatas: [], roleDatas: [], // 使
defaultProps: { children: 'children', label: 'name', isLeaf: 'leaf' },
permission: { permission: {
add: ['admin', 'user:add'], add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'], edit: ['admin', 'user:edit'],
del: ['admin', 'user:del'] del: ['admin', 'user:del']
}, },
enabledTypeOptions: [
{ key: 'true', display_name: '激活' },
{ key: 'false', display_name: '锁定' }
userData: [
{
id: 1,
account: '15100701025',
nickName: '王XX',
roles: '机构超级管理员',
orgName: 'XX机构',
phone: '15100701025',
enabled: '0',
createTime: '2021-11-10'
}
], ],
rules: { rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
nickName: [ nickName: [
{ required: true, message: '请输入用户昵称', trigger: 'blur' },
{ required: true, message: '请输入管理员名称', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' } { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
], ],
email: [
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
],
phone: [ phone: [
{ required: true, trigger: 'blur', validator: validPhone } { required: true, trigger: 'blur', validator: validPhone }
],
code: [
{ required: true, trigger: 'blur', message: '请输入验证码' }
],
password: [
{ required: true, trigger: 'blur', message: '请输入密码' }
] ]
} }
} }
@ -215,195 +261,75 @@ export default {
} }
}, },
methods: { methods: {
changeRole(value) {
userRoles = []
value.forEach(function(data, index) {
const role = { id: data }
userRoles.push(role)
})
},
changeJob(value) {
userJobs = []
value.forEach(function(data, index) {
const job = { id: data }
userJobs.push(job)
})
//
editFormData(index, row) {
this.editDialogVisible = true
this.editForm.nickName = row.nickName
this.editForm.roles = row.roles
this.editForm.orgName = row.orgName
this.editForm.phone = row.phone
this.editForm.enabled = row.enabled
}, },
deleteTag(value) {
userRoles.forEach(function(data, index) {
if (data.id === value) {
userRoles.splice(index, value)
}
})
//
getAuthCode() {
// const param = {
// phone: this.editForm.phone
// }
// proxy.$http
// .post(proxy.$API.SENDMSGCODE,
// param
// )
// .then(res => {
// if (res.type == 200) {
// this.countdown()
// } else {
// console.log(res.content)
// }
// })
// .catch(res => {
// console.log(res)
// })
}, },
//
[CRUD.HOOK.afterToCU](crud, form) {
this.getRoles()
if (form.id == null) {
this.getDepts()
} else {
this.getSupDepts(form.dept.id)
countdown() {
if (this.disabledSendCode) {
return
} }
this.getRoleLevel()
this.getJobs()
form.enabled = form.enabled.toString()
},
//
[CRUD.HOOK.beforeToAdd]() {
this.jobDatas = []
this.roleDatas = []
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
this.getJobs(this.form.dept.id)
this.jobDatas = []
this.roleDatas = []
userRoles = []
userJobs = []
const _this = this
form.roles.forEach(function(role, index) {
_this.roleDatas.push(role.id)
const rol = { id: role.id }
userRoles.push(rol)
})
form.jobs.forEach(function(job, index) {
_this.jobDatas.push(job.id)
const data = { id: job.id }
userJobs.push(data)
})
},
//
[CRUD.HOOK.afterValidateCU](crud) {
if (!crud.form.dept.id) {
this.$message({
message: '部门不能为空',
type: 'warning'
})
return false
} else if (this.jobDatas.length === 0) {
this.$message({
message: '岗位不能为空',
type: 'warning'
})
return false
} else if (this.roleDatas.length === 0) {
this.$message({
message: '角色不能为空',
type: 'warning'
})
return false
}
crud.form.roles = userRoles
crud.form.jobs = userJobs
return true
},
//
getDeptDatas(node, resolve) {
const sort = 'id,desc'
const params = { sort: sort }
if (typeof node !== 'object') {
if (node) {
params['name'] = node
}
} else if (node.level !== 0) {
params['pid'] = node.data.id
if (!/^1\d{10}$/.test(this.editForm.phone)) {
this.$message.error('手机号错误,请重新输入')
return
} }
setTimeout(() => {
getDepts(params).then(res => {
if (resolve) {
resolve(res.content)
} else {
this.deptDatas = res.content
}
})
}, 100)
},
getDepts() {
getDepts({ enabled: true }).then(res => {
this.depts = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
})
},
getSupDepts(deptId) {
getDeptSuperior(deptId).then(res => {
const date = res.content
this.buildDepts(date)
this.depts = date
})
},
buildDepts(depts) {
depts.forEach(data => {
if (data.children) {
this.buildDepts(data.children)
this.getAuthCode()
this.disabledSendCode = true
// this.isSendAuth = true
this.countNum = 60
const timer = setInterval(() => {
this.verification = this.countNum + '重新获取'
this.countNum -= 1
if (this.countNum < 1) {
clearInterval(timer)
this.verification = '重新获取'
this.disabledSendCode = false
// this.isSendAuth = false
console.log('倒计时结束')
} }
if (data.hasChildren && !data.children) {
data.children = null
}
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
getDepts({ enabled: true, pid: parentNode.id }).then(res => {
parentNode.children = res.content.map(function(obj) {
if (obj.hasChildren) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 200)
})
}
},
//
handleNodeClick(data) {
if (data.pid === 0) {
this.query.deptId = null
} else {
this.query.deptId = data.id
}
this.crud.toQuery()
}, 1000)
}, },
// //
changeEnabled(data, val) {
this.$confirm('此操作将 "' + this.dict.label.user_status[val] + '" ' + data.username + ', 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
crudUser.edit(data).then(res => {
this.crud.notify(this.dict.label.user_status[val] + '成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
data.enabled = !data.enabled
})
}).catch(() => {
data.enabled = !data.enabled
})
},
//
getRoles() {
getAll().then(res => {
this.roles = res
}).catch(() => { })
},
//
getJobs() {
getAllJob().then(res => {
this.jobs = res.content
}).catch(() => { })
},
//
getRoleLevel() {
getLevel().then(res => {
this.level = res.level
}).catch(() => { })
},
// changeEnabled(data, val) {
// this.$confirm(' "' + this.dict.label.user_status[val] + '" ' + data.username + ', ', '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning'
// }).then(() => {
// crudUser.edit(data).then(res => {
// this.crud.notify(this.dict.label.user_status[val] + '', CRUD.NOTIFICATION_TYPE.SUCCESS)
// }).catch(() => {
// data.enabled = !data.enabled
// })
// }).catch(() => {
// data.enabled = !data.enabled
// })
// },
checkboxT(row, rowIndex) { checkboxT(row, rowIndex) {
return row.id !== this.user.id return row.id !== this.user.id
} }
@ -412,8 +338,15 @@ export default {
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .vue-treeselect__control,::v-deep .vue-treeselect__placeholder,::v-deep .vue-treeselect__single-value {
height: 30px;
line-height: 30px;
// start
.page_add{
text-align: right;
}
// end
.el-dialog__header{
background-color: #f1f1f1;
}
.edit_code{
margin-left: 20px;
} }
</style> </style>
Loading…
Cancel
Save