feat: 右上角功能菜单调整

This commit is contained in:
fit2cloud-chenyw 2021-05-13 16:00:15 +08:00
parent 2f4842d410
commit fe29511e38
8 changed files with 486 additions and 14 deletions

View File

@ -3,6 +3,8 @@ package io.dataease.controller.sys;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.sys.base.BaseGridRequest;
@ -73,4 +75,18 @@ public class SysUserController {
public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){
sysUserService.adminUpdatePwd(request);
}
@ApiOperation("个人信息")
@PostMapping("/personInfo")
public CurrentUserDto personInfo() {
CurrentUserDto user = AuthUtils.getUser();
return user;
}
@ApiOperation("更新个人信息")
@PostMapping("/updatePersonInfo")
public void updatePersonInfo(@RequestBody SysUserCreateRequest request){
sysUserService.updatePersonInfo(request);
}
}

View File

@ -1,5 +1,6 @@
package io.dataease.service.sys;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.base.domain.SysUser;
import io.dataease.base.domain.SysUserExample;
import io.dataease.base.domain.SysUsersRolesExample;
@ -9,6 +10,7 @@ import io.dataease.base.mapper.SysUsersRolesMapper;
import io.dataease.base.mapper.ext.ExtSysUserMapper;
import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CodingUtil;
import io.dataease.controller.sys.base.BaseGridRequest;
@ -89,6 +91,22 @@ public class SysUserService {
deleteUserRoles(user.getUserId());//先删除用户角色关联
saveUserRoles(user.getUserId(), request.getRoleIds());//再插入角色关联
return sysUserMapper.updateByPrimaryKey(user);
}
/**
* 用户修改个人信息
* @param request
* @return
*/
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
@Transactional
public int updatePersonInfo(SysUserCreateRequest request){
SysUser user = BeanUtils.copyBean(new SysUser(), request);
long now = System.currentTimeMillis();
user.setUpdateTime(now);
return sysUserMapper.updateByPrimaryKeySelective(user);
}
@ -107,20 +125,16 @@ public class SysUserService {
*/
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
public int updatePwd(SysUserPwdRequest request) {
if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){
throw new RuntimeException("两次密码不一致");
}
SysUser temp = new SysUser();
temp.setUserId(request.getUserId());
SysUser user = findOne(temp);
CurrentUserDto user = AuthUtils.getUser();
if (ObjectUtils.isEmpty(user)) {
throw new RuntimeException("用户不存在");
}
if (!StringUtils.equals(request.getPassword(), user.getPassword())){
if (!StringUtils.equals(CodingUtil.md5(request.getPassword()), user.getPassword())){
throw new RuntimeException("密码错误");
}
SysUser sysUser = new SysUser();
sysUser.setUserId(request.getUserId());
sysUser.setUserId(user.getUserId());
sysUser.setPassword(CodingUtil.md5(request.getNewPassword()));
return sysUserMapper.updateByPrimaryKeySelective(sysUser);
}

View File

@ -1,5 +1,8 @@
import request from '@/utils/request'
const pathMap = {
userUpdatePwdPath: '/api/user/updatePwd/',
personInfoPath: '/api/user/personInfo/',
piupdatePath: '/api/user/updatePersonInfo/',
queryPath: '/api/user/userGrid/',
deletePath: '/api/user/delete/',
createPath: '/api/user/create',
@ -55,4 +58,27 @@ export const editStatus = (data) => {
})
}
export default { editPassword, delUser, editUser, addUser, userLists, editStatus }
export const persionInfo = () => {
return request({
url: pathMap.personInfoPath,
method: 'post'
})
}
export const updatePerson = (data) => {
return request({
url: pathMap.piupdatePath,
method: 'post',
data
})
}
export const updatePersonPwd = (data) => {
return request({
url: pathMap.userUpdatePwdPath,
method: 'post',
data
})
}
export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd }

View File

@ -406,7 +406,7 @@ export default {
special_characters_are_not_supported: '不支持特殊字符',
mobile_number_format_is_incorrect: '手机号码格式不正确',
email_format_is_incorrect: '邮箱格式不正确',
password_format_is_incorrect: '有效密码:8-30位英文大小写字母+数字+特殊字符(可选)',
password_format_is_incorrect: '有效密码:6-30位英文大小写字母+数字+特殊字符(可选)',
old_password: '旧密码',
new_password: '新密码',
repeat_password: '确认密码',

View File

@ -37,9 +37,46 @@
<lang-select class="right-menu-item hover-effect" />
</template>
<el-dropdown class="avatar-container" trigger="click">
<el-dropdown class="top-dropdown">
<span class="el-dropdown-link">
{{ name }}<i class="el-icon-arrow-down el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<router-link to="/person-info/index">
<el-dropdown-item>个人信息</el-dropdown-item>
</router-link>
<router-link to="/person-pwd/index">
<el-dropdown-item>重置密码</el-dropdown-item>
</router-link>
<a href="https://panjiachen.github.io/vue-element-admin-site/#/" target="_blank">
<el-dropdown-item>Docs</el-dropdown-item>
</a>
<a href="https://fit2cloud.com/" target="_blank">
<el-dropdown-item>关于</el-dropdown-item>
</a>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">退出</span>
</el-dropdown-item>
<!-- <el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item disabled>双皮奶</el-dropdown-item>
<el-dropdown-item divided>蚵仔煎</el-dropdown-item> -->
</el-dropdown-menu>
</el-dropdown>
<!-- <el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<img src="@/assets/avatar.jpeg" class="user-avatar">
<div class="de-user-avatar">
<span>
{{ name }}
</span>
</div>
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<router-link to="/">
@ -55,7 +92,7 @@
<span style="display:block;">Log Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-dropdown> -->
</div>
</div>
</template>
@ -113,7 +150,8 @@ export default {
},
...mapGetters([
'avatar',
'permission_routes'
'permission_routes',
'name'
])
},
@ -222,5 +260,21 @@ export default {
}
</script>
<style lang="scss" scoped>
.el-dropdown-link {
cursor: pointer;
color: #ffffff;
}
.el-icon-arrow-down {
font-size: 12px;
}
.top-dropdown {
display: inline-block;
padding: 10px 8px;
height: 100%;
font-size: 16px;
color: rgba(255,255,255,.87);
vertical-align: text-bottom;
margin-right: 30px;
}
</style>

View File

@ -87,6 +87,14 @@
height: 40px;
border-radius: 10px;
}
.de-user-avatar {
cursor: pointer;
height: 40px;
border-radius: 10px;
span {
color: #ffffff;
}
}
.el-icon-caret-bottom {
cursor: pointer;

View File

@ -0,0 +1,88 @@
<template>
<layout-content header="修改密码">
<el-form ref="createUserForm" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
<el-form-item label="原始密码" prop="oldPwd">
<el-input v-model="form.oldPwd" type="password" />
</el-form-item>
<el-form-item label="新密码" prop="newPwd">
<el-input v-model="form.newPwd" type="password" />
</el-form-item>
<el-form-item label="确认密码" prop="repeatPwd">
<el-input v-model="form.repeatPwd" type="password" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">保存</el-button>
</el-form-item>
</el-form>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import { updatePersonPwd } from '@/api/system/user'
export default {
components: { LayoutContent },
data() {
return {
form: {
},
rule: {
oldPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' }
// {
// required: true,
// pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{6,30}$/,
// message: this.$t('member.password_format_is_incorrect'),
// trigger: 'blur'
// }
],
newPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' }
],
repeatPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
{ required: true, trigger: 'blur', validator: this.repeatValidator }
]
}
}
},
created() {
},
methods: {
repeatValidator(rule, value, callback) {
if (value !== this.form.newPwd) {
callback(new Error(this.$t('member.inconsistent_passwords')))
} else {
callback()
}
},
save() {
this.$refs.createUserForm.validate(valid => {
if (valid) {
const param = {
password: this.form.oldPwd,
newPassword: this.form.newPwd
}
updatePersonPwd(param).then(res => {
this.$success(this.$t('commons.save_success'))
this.$router.push('/panel/index')
})
} else {
return false
}
})
}
}
}
</script>

View File

@ -0,0 +1,266 @@
<template>
<layout-content header="个人信息">
<div>
<el-form ref="createUserForm" :disabled="formType !== 'modify'" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" disabled />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" />
</el-form-item>
<!-- <el-form-item label="性别">
<el-radio-group v-model="form.gender" style="width: 178px">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="状态">
<el-radio-group v-model="form.enabled" disabled style="width: 140px">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item disabled label="部门" prop="dept">
<treeselect
v-model="form.deptId"
disabled
:options="depts"
:load-options="loadDepts"
:auto-load-root-options="false"
placeholder="选择部门"
/>
</el-form-item>
<el-form-item label="角色" prop="roleIds">
<el-select
v-model="form.roleIds"
disabled
style="width: 100%"
multiple
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeRole"
>
<el-option
v-for="item in roles"
:key="item.name"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- <el-form-item>
<el-button v-if="formType==='modify'" type="primary" @click="save">保存</el-button>
<el-button v-if="formType==='modify'" @click="reset">重置</el-button>
</el-form-item> -->
</el-form>
<div slot="footer" style="margin-left: 30px;" class="dialog-footer">
<el-button v-if="formType==='modify'" type="text" @click="reset">{{ $t('commons.cancel') }}</el-button>
<el-button v-if="formType==='modify'" type="primary" @click="save">确认</el-button>
<el-button v-if="formType!=='modify'" type="primary" @click="edit">编辑</el-button>
</div>
</div>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { PHONE_REGEX } from '@/utils/validate'
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
import { getDeptTree, treeByDeptId } from '@/api/system/dept'
import { allRoles } from '@/api/system/role'
import { updatePerson, persionInfo } from '@/api/system/user'
export default {
components: { LayoutContent, Treeselect },
data() {
return {
form: {
roles: [{
id: ''
}]
},
rule: {
username: [
{ required: true, message: this.$t('user.input_id'), trigger: 'blur' },
{ min: 1, max: 50, message: this.$t('commons.input_limit', [1, 50]), trigger: 'blur' },
{
required: true,
pattern: '^[^\u4e00-\u9fa5]+$',
message: this.$t('user.special_characters_are_not_supported'),
trigger: 'blur'
}
],
nickName: [
{ required: true, message: this.$t('user.input_name'), trigger: 'blur' },
{ min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur' },
{
required: true,
message: this.$t('user.special_characters_are_not_supported'),
trigger: 'blur'
}
],
phone: [
{
pattern: PHONE_REGEX,
message: this.$t('user.mobile_number_format_is_incorrect'),
trigger: 'blur'
}
],
email: [
{ required: true, message: this.$t('user.input_email'), trigger: 'blur' },
{
required: true,
pattern: /^[a-zA-Z0-9_._-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
message: this.$t('user.email_format_is_incorrect'),
trigger: 'blur'
}
],
password: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
{
required: true,
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
message: this.$t('member.password_format_is_incorrect'),
trigger: 'blur'
}
],
newPassword: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
{
required: true,
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
message: this.$t('member.password_format_is_incorrect'),
trigger: 'blur'
}
],
roleIds: [{ required: true, message: this.$t('user.input_roles'), trigger: 'change' }]
},
defaultForm: { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 1, deptId: null, phone: null, roleIds: [] },
depts: null,
roles: [],
roleDatas: [],
userRoles: [],
formType: 'add'
}
},
created() {
this.queryPerson()
this.initRoles()
},
methods: {
queryPerson() {
persionInfo().then(res => {
const info = res.data
this.form = info
const roles = info.roles
this.form['roleIds'] = roles.map(role => role.id)
if (this.form.deptId === 0) {
this.form.deptId = null
}
this.initDeptTree()
})
},
edit() {
this.formType = 'modify'
},
initRoles() {
allRoles().then(res => {
this.roles = res.data
})
},
initDeptTree() {
treeByDeptId(this.form.deptId || 0).then(res => {
const results = res.data.map(node => {
if (node.hasChildren && !node.children) {
node.children = null
// delete node.children
}
return node
})
this.depts = results
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_ROOT_OPTIONS && !this.form.deptId) {
const _self = this
treeByDeptId(0).then(res => {
const results = res.data.map(node => {
if (node.hasChildren && !node.children) {
node.children = null
}
return node
})
_self.depts = results
callback()
})
}
if (action === LOAD_CHILDREN_OPTIONS) {
const _self = this
getDeptTree(parentNode.id).then(res => {
parentNode.children = res.data.map(function(obj) {
return _self.normalizer(obj)
})
callback()
})
}
},
normalizer(node) {
if (node.hasChildren) {
node.children = null
}
return {
id: node.deptId,
label: node.name,
children: node.children
}
},
deleteTag(value) {
this.userRoles.forEach(function(data, index) {
if (data.id === value) {
this.userRoles.splice(index, value)
}
}.bind(this))
},
changeRole(value) {
this.userRoles = []
value.forEach(function(data, index) {
const role = { id: data }
this.userRoles.push(role)
}.bind(this))
},
reset() {
this.formType = 'add'
this.queryPerson()
},
save() {
this.$refs.createUserForm.validate(valid => {
if (valid) {
updatePerson(this.form).then(res => {
this.$success(this.$t('commons.save_success'))
this.reset()
})
} else {
return false
}
})
}
}
}
</script>