forked from github/dataease
feat: 右上角功能菜单调整
This commit is contained in:
parent
2f4842d410
commit
fe29511e38
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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: '确认密码',
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
88
frontend/src/views/system/user/personPwd.vue
Normal file
88
frontend/src/views/system/user/personPwd.vue
Normal 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>
|
266
frontend/src/views/system/user/privateForm.vue
Normal file
266
frontend/src/views/system/user/privateForm.vue
Normal 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>
|
Loading…
Reference in New Issue
Block a user