移除RoleUser实体设计,用户角色关系简化为使用User.roles维护

This commit is contained in:
interestinglife41 2021-08-20 13:04:56 +08:00
parent d895357de3
commit cddd34093f
11 changed files with 230 additions and 33 deletions

View File

@ -178,6 +178,9 @@ public abstract class AbstractMybatisEntityService<ID, T extends Entity<ID>> ext
@SuppressWarnings("unchecked")
protected T getById(ID id, Map<String, Object> params)
{
if (id == null)
return null;
T entity = null;
ValueWrapper entityWrapper = cacheGet(id);

View File

@ -164,25 +164,19 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
protected void saveUserRoles(User user)
{
// TODO 完成用户编辑页面的角色编辑功能后再开启
boolean save = false;
deleteUserRoles(user.getId());
if (save)
Set<Role> roles = user.getRoles();
if (roles != null && !roles.isEmpty())
{
deleteUserRoles(user.getId());
Map<String, Object> params = buildParamMap();
Set<Role> roles = user.getRoles();
if (roles != null && !roles.isEmpty())
for (Role role : roles)
{
Map<String, Object> params = buildParamMap();
RoleUser ru = new RoleUser(IDUtil.randomIdOnTime20(), role.getId(), user.getId());
params.put("entity", ru);
for (Role role : roles)
{
RoleUser ru = new RoleUser(IDUtil.randomIdOnTime20(), role.getId(), user.getId());
params.put("entity", ru);
insertMybatis("insertUserRole", params);
}
insertMybatis("insertUserRole", params);
}
}
}
@ -239,7 +233,7 @@ public class UserServiceImpl extends AbstractMybatisEntityService<String, User>
rolesNew.add(role);
}
obj.setRoles(roles);
obj.setRoles(rolesNew);
}
return super.postProcessGet(obj);

View File

@ -11,9 +11,7 @@ import static org.junit.Assert.assertEquals;
import org.datagear.management.domain.User;
import org.datagear.management.service.RoleService;
import org.datagear.management.service.RoleUserService;
import org.datagear.management.service.impl.RoleServiceImpl;
import org.datagear.management.service.impl.RoleUserServiceImpl;
import org.datagear.management.service.impl.UserServiceImpl;
import org.junit.Test;
@ -30,9 +28,8 @@ public class UserServiceImplTest extends ServiceImplTestSupport
public UserServiceImplTest()
{
super();
RoleUserService roleUserService = new RoleUserServiceImpl(getSqlSessionFactory(), getDialect());
RoleService roleService = new RoleServiceImpl(getSqlSessionFactory(), getDialect());
this.userServiceImpl = new UserServiceImpl(getSqlSessionFactory(), getDialect(), roleUserService, roleService);
this.userServiceImpl = new UserServiceImpl(getSqlSessionFactory(), getDialect(), roleService);
}
@Test

View File

@ -147,6 +147,7 @@ public class RoleController extends AbstractController
{
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "role.selectRole");
model.addAttribute(KEY_SELECT_OPERATION, true);
setIsMultipleSelectAttribute(request, model);
return "/role/role_grid";
}

View File

@ -7,9 +7,17 @@
package org.datagear.web.controller;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.datagear.management.domain.Role;
import org.datagear.management.domain.User;
import org.datagear.management.service.SchemaService;
import org.datagear.management.service.UserService;
@ -89,6 +97,7 @@ public class UserController extends AbstractController
User user = new User();
model.addAttribute("user", user);
model.addAttribute("userRoles", toWriteJsonTemplateModel(toUserRolesList(user)));
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "user.addUser");
model.addAttribute(KEY_FORM_ACTION, "saveAdd");
@ -97,9 +106,12 @@ public class UserController extends AbstractController
@RequestMapping(value = "/saveAdd", produces = CONTENT_TYPE_JSON)
@ResponseBody
public ResponseEntity<OperationMessage> saveAdd(HttpServletRequest request, HttpServletResponse response, User user,
@RequestParam("confirmPassword") String confirmPassword)
public ResponseEntity<OperationMessage> saveAdd(HttpServletRequest request, HttpServletResponse response,
@RequestBody UserForm userForm)
{
User user = userForm.getUser();
String confirmPassword = userForm.getConfirmPassword();
if (isBlank(user.getName()) || isBlank(user.getPassword()))
throw new IllegalInputException();
@ -126,9 +138,13 @@ public class UserController extends AbstractController
public String edit(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
User user = this.userService.getById(id);
User user = this.userService.getByIdNoPassword(id);
if (user == null)
throw new RecordNotFoundException();
model.addAttribute("user", user);
model.addAttribute("userRoles", toWriteJsonTemplateModel(toUserRolesList(user)));
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "user.editUser");
model.addAttribute(KEY_FORM_ACTION, "saveEdit");
@ -138,8 +154,11 @@ public class UserController extends AbstractController
@RequestMapping(value = "/saveEdit", produces = CONTENT_TYPE_JSON)
@ResponseBody
public ResponseEntity<OperationMessage> saveEdit(HttpServletRequest request, HttpServletResponse response,
User user, @RequestParam("confirmPassword") String confirmPassword)
@RequestBody UserForm userForm)
{
User user = userForm.getUser();
String confirmPassword = userForm.getConfirmPassword();
if (isBlank(user.getName()))
throw new IllegalInputException();
@ -164,12 +183,13 @@ public class UserController extends AbstractController
public String view(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id)
{
User user = this.userService.getById(id);
User user = this.userService.getByIdNoPassword(id);
if (user == null)
throw new RecordNotFoundException();
model.addAttribute("user", user);
model.addAttribute("userRoles", toWriteJsonTemplateModel(toUserRolesList(user)));
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "user.viewUser");
model.addAttribute(KEY_READONLY, true);
@ -239,8 +259,11 @@ public class UserController extends AbstractController
@RequestMapping(value = "/savePersonalSet", produces = CONTENT_TYPE_JSON)
@ResponseBody
public ResponseEntity<OperationMessage> savePersonalSet(HttpServletRequest request, HttpServletResponse response,
User user, @RequestParam("confirmPassword") String confirmPassword)
@RequestBody UserForm userForm)
{
User user = userForm.getUser();
String confirmPassword = userForm.getConfirmPassword();
if (isBlank(user.getName()) || !confirmPassword.equals(user.getPassword()))
throw new IllegalInputException();
@ -267,4 +290,58 @@ public class UserController extends AbstractController
{
return buildMessageCode("user", code);
}
protected List<Role> toUserRolesList(User user)
{
List<Role> list = new ArrayList<Role>();
Set<Role> roles = (user == null ? null : user.getRoles());
if (roles != null)
list.addAll(roles);
Collections.sort(list, new Comparator<Role>()
{
@Override
public int compare(Role o1, Role o2)
{
return o1.getName().compareTo(o2.getName());
}
});
return list;
}
public static class UserForm implements Serializable
{
private static final long serialVersionUID = 1L;
private User user;
private String confirmPassword;
public UserForm()
{
super();
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public String getConfirmPassword()
{
return confirmPassword;
}
public void setConfirmPassword(String confirmPassword)
{
this.confirmPassword = confirmPassword;
}
}
}

View File

@ -383,6 +383,7 @@ user.realName=昵称
user.email=邮箱
user.admin=管理员
user.createTime=创建日期
user.roles=角色
user.confirmPassword=确认密码
user.validation.confirmPasswordError=与[密码]项不一致
user.confirmDelete=确定删除选中的用户吗?用户创建的数据源也会被删除

View File

@ -383,6 +383,7 @@ user.realName=Nickname
user.email=Email
user.admin=Administrator
user.createTime=Create time
user.roles=Roles
user.confirmPassword=Confirm password
user.validation.confirmPasswordError=Must be the same with [Password]
user.confirmDelete=Confirm delete selected user? All data related will be deleted also

View File

@ -355,6 +355,30 @@ form.display-block .form-content .form-item .form-item-value label.error,
padding-bottom: 0.3em;
}
/*轻型列表*/
.minor-list{
height: 10em;
overflow: auto;
padding: 0.41em 0.41em;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.minor-list .minor-list-item{
margin-bottom: 0.3em;
padding: 0.3em 0.3em;
}
.minor-list .minor-list-item .item-content{
margin-left: 0.41em;
}
.minor-list.deletable-list .minor-list-item .item-content{
display: inline-block;
}
.minor-list.deletable-list .minor-list-item .delete-icon{
cursor: pointer;
}
/*首选操作按钮*/
.ui-button.recommended{
border: 1px solid #0066ff;
@ -1379,6 +1403,15 @@ table.dataTable tbody tr td select{
padding-top: 2em;
}
/*用户*/
.page-form-user{}
.page-form-user .user-roles{
display: inline-block;
}
.page-form-user .selectUserRoleBtn{
vertical-align: top;
}
/*驱动信息管理表单页*/
.page-form-driverEntity{
}

View File

@ -32,7 +32,7 @@
<label><@spring.message code='register.name' /></label>
</div>
<div class="form-item-value">
<input type="text" name="name" value="" class="ui-widget ui-widget-content" />
<input type="text" name="name" value="" class="ui-widget ui-widget-content" autocomplete="off" />
</div>
</div>
<div class="form-item">
@ -40,7 +40,7 @@
<label><@spring.message code='register.password' /></label>
</div>
<div class="form-item-value">
<input type="password" name="password" value="" class="ui-widget ui-widget-content" />
<input type="password" name="password" value="" class="ui-widget ui-widget-content" autocomplete="new-password" />
</div>
</div>
<div class="form-item">
@ -48,7 +48,7 @@
<label><@spring.message code='register.confirmPassword' /></label>
</div>
<div class="form-item-value">
<input type="password" name="confirmPassword" value="" class="ui-widget ui-widget-content" />
<input type="password" name="confirmPassword" value="" class="ui-widget ui-widget-content" autocomplete="new-password" />
</div>
</div>
<div class="form-item">

View File

@ -13,6 +13,7 @@ titleMessageKey 标题标签I18N关键字不允许null
selectOperation 是否选择操作允许为null
-->
<#assign selectOperation=(selectOperation!false)>
<#assign isMultipleSelect=(isMultipleSelect!false)>
<html>
<head>
<#include "../include/html_head.ftl">
@ -117,10 +118,17 @@ selectOperation 是否选择操作允许为null
po.element("input[name=confirmButton]").click(function()
{
<#if isMultipleSelect>
po.executeOnSelects(function(rows)
{
po.pageParamCallSelect(true, rows);
});
<#else>
po.executeOnSelect(function(row)
{
po.pageParamCallSelect(true, row);
});
</#if>
});
po.initPagination();

View File

@ -42,7 +42,7 @@ readonly 是否只读操作允许为null
<label><@spring.message code='user.password' /></label>
</div>
<div class="form-item-value">
<input type="password" name="password" value="" class="ui-widget ui-widget-content" />
<input type="password" name="password" value="" class="ui-widget ui-widget-content" autocomplete="new-password" />
</div>
</div>
<div class="form-item">
@ -50,7 +50,7 @@ readonly 是否只读操作允许为null
<label><@spring.message code='user.confirmPassword' /></label>
</div>
<div class="form-item-value">
<input type="password" name="confirmPassword" value="" class="ui-widget ui-widget-content" />
<input type="password" name="confirmPassword" value="" class="ui-widget ui-widget-content" autocomplete="new-password" />
</div>
</div>
</#if>
@ -62,6 +62,18 @@ readonly 是否只读操作允许为null
<input type="text" name="realName" value="${(user.realName)!''}" class="ui-widget ui-widget-content" />
</div>
</div>
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='user.roles' /></label>
</div>
<div class="form-item-value">
<div class="user-roles ui-widget ui-widget-content input minor-list deletable-list">
</div>
<#if !readonly>
<button class="selectUserRoleBtn" type="button"><@spring.message code='select' /></button>
</#if>
</div>
</div>
<#--
禁用新建管理员账号功能
<div class="form-item">
@ -90,6 +102,8 @@ readonly 是否只读操作允许为null
<script type="text/javascript">
(function(po)
{
po.userRoles = <@writeJson var=userRoles />;
$.initButtons(po.element());
<#--
@ -103,6 +117,57 @@ readonly 是否只读操作允许为null
return "${contextPath}/user/" + action;
};
po.element(".user-roles").on("click", ".delete-icon", function()
{
$(this).closest(".minor-list-item").remove();
});
po.renderRoles = function(roles)
{
roles = (roles || []);
var $parent = po.element(".user-roles");
for(var i=0; i<roles.length; i++)
po.renderRole($parent, roles[i]);
}
po.renderRole = function($parent, role)
{
var exists = po.element("input[name='roleIds[]']", $parent);
for(var i=0; i<exists.length; i++)
{
if($(exists[i]).val() == role.id)
return;
}
var $item = $("<div class='minor-list-item ui-widget ui-widget-content ui-corner-all' />").appendTo($parent);
$("<input type='hidden' name='roleIds[]' />").attr("value", role.id).appendTo($item);
<#if !readonly>
$("<span class='delete-icon ui-icon ui-icon-close' title='<@spring.message code='delete' />' />").appendTo($item);
</#if>
$("<div class='item-content' />").text(role.name).appendTo($item);
};
po.element(".selectUserRoleBtn").click(function()
{
var options =
{
pageParam :
{
select : function(roles)
{
po.renderRoles(roles);
}
}
};
$.setGridPageHeightOption(options);
po.open("${contextPath}/role/select?multiple", options);
});
<#if !readonly>
po.form().validate(
{
@ -136,11 +201,26 @@ readonly 是否只读操作允许为null
},
submitHandler : function(form)
{
$(form).ajaxSubmit(
var data = $.formToJson(form);
var confirmPassword = data.confirmPassword;
data.confirmPassword = undefined;
var roleIds = (data.roleIds || []);
var roles = [];
for(var i=0; i<roleIds.length; i++)
{
success : function(operationMessage)
roles[i] = { "id": roleIds[i] };
}
data.roles = roles;
data.roleIds = undefined;
$.ajaxJson($(form).attr("action"),
{
data: { "user": data, "confirmPassword": confirmPassword },
success : function(response)
{
po.pageParamCallAfterSave(true, operationMessage.data);
po.pageParamCallAfterSave(true, response.data);
}
});
},
@ -150,6 +230,8 @@ readonly 是否只读操作允许为null
}
});
</#if>
po.renderRoles(po.userRoles);
})
(${pageId});
</script>