概述
用户(user)是能够登录平台的账号集合,即登录用户。其最基本的属性为用户名、密码、手机号和邮箱等等(主表),另外还有很多附加属性如:
- 内部员工(employee):归属部门、归属公司、入职时间、岗位、在职状态、学历等等。
- 会员用户(member):注册时间、姓名、等级、积分、地址等等。
- 往来单位(btype):单位名称、单位电话、负责人、类型等等。
- 专家用户(expert):专业、擅长领域、技术专长、熟悉程度等等。
从上可以看出,各种用户类型的附加属性都是不同的,所以需要建立不同的表(附表)来存储。
下面咱们来看下,主表和附表之间的关系是什么:
用户主表 | 用户表/sys_user | 用户类型/user_type | 引用编码/ref_code | 引用名称/ref_name |
---|---|---|---|---|
员工附表 | 员工表/sys_employee | 员工/employee | 员工编码/emp_code | 员工姓名/emp_name |
会员附表 | 会员表/sys_member | 会员/member | 会员编码/member_code | 会员姓名/member_name |
单位附表 | 单位表/sys_btype | 往来单位/btype | 单位编码/btype_code | 单位姓名/btype_name |
专家附表 | 专家表/sys_expert | 往来单位/expert | 单位编码/expert_code | 单位姓名/expert_name |
解释: 1)用户类型:区分用户表中的数据,归属用户类型是什么。 2)引用编码和名称: 如果用户类型是员工,则存储的是员工编码和员工名称;如果引用类型是会员,则是会员编码、会员名称;
自定义用户类型
菜单中的员工管理,其实就是 JeeSite 已经默认实现一种数据类型:员工类型,表名:sys_employee,剩下的类型还需要你根据业务需要,模仿员工,进行扩充实现。
举例新建会员类型
新建配置
配置 member 的用户类型参数
# 用户相关
user:
# 用户类型配置信息(employee员工,member会员,btype往来单位,persion个人,expert专家,...)
userTypeMap: >
{
"employee":{
"beanName":"employeeService",
"loginView":"modules/sys/sysLogin",
"indexView":"modules/sys/sysIndex"
},
"member":{
"beanName":"memberService",
"loginView":"modules/sys/sysLogin",
"indexView":"modules/sys/sysIndex"
},
"btype":{
"beanName":"btypeInfoService",
"loginView":"modules/sys/sysLogin",
"indexView":"modules/sys/sysIndex"
},
"expert":{"beanName":"expertService",
"loginView":"modules/sys/sysLogin",
"indexView":"modules/sys/sysIndex"
}
}
上述配置 JSON 格式说明如下:
{
"用户类型":{
"beanName":"Service或Dao的Bean名称",
"loginView":"登录页面视图",
"indexView":"主框架页面视图,支持 redirect: 前缀"
}
}
4.2 版本将 dao 修改为 beanName,主要目的是对 Cloud 微服务更友好,Service 可通过 API 远程调用。
若登录页面视图和主框架视图不一致的话可通过上述配置自定义视图路径。
代码生成
通过代码生成 sys_member 表的,增删改查代码:
-- 会员用户表
CREATE TABLE js_sys_member
(
mem_id varchar(64) NOT NULL COMMENT '会员编号',
mem_name varchar(50) COMMENT '会员姓名',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态(0正常 1删除 2停用)',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
update_by varchar(64) NOT NULL COMMENT '更新者',
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
PRIMARY KEY (menber_id)
) COMMENT = '会员用户表';
- 实体类:Member
- 持久类:MemberDao
- 服务类:MemberService
通过上述代码生成 Member 功能后,接着创建如下会员和用户相关的代码文件:
Entity
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.entity;
import javax.validation.Valid;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.JoinTable;
import com.jeesite.common.mybatis.annotation.JoinTable.Type;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.modules.sys.entity.User;
/**
* 会员用户Entity
* @author ThinkGem
* @version 2020-9-19
*/
@Table(name="${_prefix}sys_user", alias="a", columns={
@Column(includeEntity=User.class),
}, joinTable={
@JoinTable(type=Type.JOIN, entity=Member.class, alias="e",
on="e.mem_code=a.ref_code AND a.user_type=#{USER_TYPE_MEMBER}", columns = {
@Column(includeEntity=Member.class),
}),
},
orderBy="a.user_weight DESC, a.update_date DESC"
)
public class MemUser extends User {
private static final long serialVersionUID = 1L;
public MemUser() {
this(null);
}
public MemUser(String id){
super(id);
}
@Valid
public Member getMember(){
Member member = (Member)super.getRefObj();
if (member == null){
member = new Member(getRefCode());
super.setRefObj(member);
}
return member;
}
public void setMember(Member Member){
super.setRefObj(Member);
}
@Override
@JsonIgnore
public <E> E getRefObj() {
return super.getRefObj();
}
}
Dao
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.MemUser;
/**
* 会员用户DAO接口
* @author ThinkGem
* @version 2020-9-19
*/
@MyBatisDao
public interface MemUserDao extends CrudDao<MemUser> {
}
Service
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.entity.Page;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.sys.dao.MemUserDao;
import com.jeesite.modules.sys.entity.MemUser;
import com.jeesite.modules.sys.entity.Member;
import com.jeesite.modules.sys.service.UserService;
/**
* 会员用户Service
* @author ThinkGem
* @version 2020-9-19
*/
@Service
@Transactional(readOnly=true)
public class MemUserService extends CrudService<MemUserDao, MemUser> {
@Autowired
private UserService userService;
@Autowired
private MemberService memberService;
/**
* 获取单条数据
*/
@Override
public MemUser get(MemUser memUser) {
return super.get(memUser);
}
/**
* 分页查询数据
*/
@Override
public Page<MemUser> findPage(MemUser memUser) {
return super.findPage(memUser);
}
/**
* 保存用户会员
*/
@Override
@Transactional(readOnly=false)
public void save(MemUser user) {
// 1、初始化用户信息
if (user.getIsNewRecord()){
userService.genId(user, user.getLoginCode());
user.setUserCode(user.getUserCode()+"_"+IdGen.randomBase62(4).toLowerCase());
user.setUserType(MemUser.USER_TYPE_MEMBER);
user.setMgrType(MemUser.MGR_TYPE_NOT_ADMIN);
}
Member member = user.getMember();
// 生成会员编号
if (user.getIsNewRecord()) {
member.setMemId(user.getUserCode());
}
// 如果会员姓名为空,则使用昵称名
if (StringUtils.isBlank(member.getMemName())){
member.setMemName(user.getUserName());
}
// 2、保存用户
user.setRefCode(member.getMemId());
user.setRefName(member.getMemName());
userService.save(user);
// 3、保存员工
member.setIsNewRecord(user.getIsNewRecord());
memberService.save(member);
}
/**
* 更新状态
*/
@Override
@Transactional(readOnly=false)
public void updateStatus(MemUser memUser) {
userService.updateStatus(memUser);
memberService.updateStatus(memUser.getMember());
}
/**
* 删除用户
*/
@Override
@Transactional(readOnly=false)
public void delete(MemUser memUser) {
userService.delete(memUser);
memberService.delete(memUser.getMember());
}
}
Utils
package com.jeesite.modules.sys.utils;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.Member;
import com.jeesite.modules.sys.service.MemberService;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.UserUtils;
/**
* 会员工具类
* @author ThinkGem
* @version 2020-9-19
*/
public class MemUtils {
/**
* 静态内部类,延迟加载,懒汉式,线程安全的单例模式
*/
private static final class Static {
private static MemberService memberService = SpringUtils.getBean(MemberService.class);
}
/**
* 根据会员编码获取员工
* @author ThinkGem
*/
public static Member get(String memId){
return Static.memberService.get(memId);
}
/**
* 根据用户对象获取会员,不是会员返回null
* @author ThinkGem
*/
public static Member get(User user){
if (user != null && User.USER_TYPE_MEMBER.equals(user.getUserType())){
return user.getRefObj();
}
return null;
}
/**
* 根据用户编码获取会员,找不到或不是会员返回null
* @author ThinkGem
*/
public static Member getByUserCode(String userCode){
User user = UserUtils.get(userCode);
Member entity = get(user);
return entity;
}
/**
* 根据登录账号获取员工,找不到或不是员工返回null
* @author ThinkGem
*/
public static Member getByLoginCode(String loginCode){
User user = UserUtils.getByLoginCode(loginCode);
Member entity = get(user);
return entity;
}
/**
* 获取当前登录的员工
* @author ThinkGem
*/
public static Member getMember(){
User user = UserUtils.getUser();
Member entity = get(user);
if (entity == null){
entity = new Member();
}
return entity;
}
}
Countroller
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.shiro.realm.AuthorizingRealm;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.sys.entity.MemUser;
import com.jeesite.modules.sys.service.MemUserService;
import com.jeesite.modules.sys.entity.Role;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.RoleService;
import com.jeesite.modules.sys.service.UserService;
import com.jeesite.modules.sys.utils.UserUtils;
/**
* 会员用户Controller
* @author ThinkGem
* @version 2020-9-19
*/
@Controller
@RequestMapping(value = "${adminPath}/sys/memUser")
@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true)
public class MemUserController extends BaseController {
@Autowired
private MemUserService memUserService;
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@ModelAttribute
public MemUser get(String userCode, boolean isNewRecord) {
return memUserService.get(userCode, isNewRecord);
}
@RequiresPermissions("sys:memUser:view")
@RequestMapping(value = "list")
public String list(MemUser memUser, Model model) {
model.addAttribute("memUser", memUser);
return "modules/sys/memUserList";
}
@RequiresPermissions("sys:memUser:view")
@RequestMapping(value = "listData")
@ResponseBody
public Page<MemUser> listData(MemUser memUser, HttpServletRequest request, HttpServletResponse response) {
memUser.setPage(new Page<>(request, response));
Page<MemUser> page = memUserService.findPage(memUser);
return page;
}
@RequiresPermissions("sys:memUser:view")
@RequestMapping(value = "form")
public String form(MemUser memUser, String op, Model model) {
// 获取当前编辑用户的角色和权限
if (StringUtils.inString(op, Global.OP_AUTH)) {
// 获取当前用户所拥有的角色
Role role = new Role();
role.setUserCode(memUser.getUserCode());
model.addAttribute("roleList", roleService.findListByUserCode(role));
}
// 操作类型:add: 全部; edit: 编辑; auth: 授权
model.addAttribute("op", op);
model.addAttribute("memUser", memUser);
return "modules/sys/memUserForm";
}
@RequiresPermissions(value={"sys:memUser:edit","sys:memUser:authRole"}, logical=Logical.OR)
@PostMapping(value = "save")
@ResponseBody
public String save(@Validated MemUser memUser, String op, HttpServletRequest request) {
if (User.isSuperAdmin(memUser.getUserCode())) {
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (!MemUser.USER_TYPE_MEMBER.equals(memUser.getUserType())){
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
MemUser old = super.getWebDataBinderSource(request);
if (!Global.TRUE.equals(userService.checkLoginCode(old != null ? old.getLoginCode() : "", memUser.getLoginCode()))) {
return renderResult(Global.FALSE, text("保存用户失败,登录账号''{0}''已存在", memUser.getLoginCode()));
}
Subject subject = UserUtils.getSubject();
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_EDIT) && subject.isPermitted("sys:memUser:edit")){
memUserService.save(memUser);
}
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_AUTH) && subject.isPermitted("sys:memUser:authRole")){
userService.saveAuth(memUser);
}
return renderResult(Global.TRUE, text("保存用户''{0}''成功", memUser.getUserName()));
}
/**
* 停用用户
* @param memUser
* @return
*/
@RequiresPermissions("sys:memUser:updateStatus")
@ResponseBody
@RequestMapping(value = "disable")
public String disable(MemUser memUser) {
if (User.isSuperAdmin(memUser.getUserCode())) {
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (!MemUser.USER_TYPE_MEMBER.equals(memUser.getUserType())){
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (memUser.getCurrentUser().getUserCode().equals(memUser.getUserCode())) {
return renderResult(Global.FALSE, text("停用用户失败,不允许停用当前用户"));
}
memUser.setStatus(User.STATUS_DISABLE);
memUserService.updateStatus(memUser);
return renderResult(Global.TRUE, text("停用用户''{0}''成功", memUser.getUserName()));
}
/**
* 启用用户
* @param memUser
* @return
*/
@RequiresPermissions("sys:memUser:updateStatus")
@ResponseBody
@RequestMapping(value = "enable")
public String enable(MemUser memUser) {
if (User.isSuperAdmin(memUser.getUserCode())) {
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (!MemUser.USER_TYPE_MEMBER.equals(memUser.getUserType())){
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
memUser.setStatus(User.STATUS_NORMAL);
memUserService.updateStatus(memUser);
AuthorizingRealm.isValidCodeLogin(memUser.getLoginCode(), memUser.getCorpCode_(), null, "success");
return renderResult(Global.TRUE, text("启用用户''{0}''成功", memUser.getUserName()));
}
/**
* 密码重置
* @param memUser
* @return
*/
@RequiresPermissions("sys:memUser:resetpwd")
@RequestMapping(value = "resetpwd")
@ResponseBody
public String resetpwd(MemUser memUser) {
if (User.isSuperAdmin(memUser.getUserCode())) {
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (!MemUser.USER_TYPE_MEMBER.equals(memUser.getUserType())){
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
userService.updatePassword(memUser.getUserCode(), null);
AuthorizingRealm.isValidCodeLogin(memUser.getLoginCode(), memUser.getCorpCode_(), null, "success");
return renderResult(Global.TRUE, text("重置用户''{0}''密码成功", memUser.getUserName()));
}
/**
* 删除用户
* @param memUser
* @return
*/
@RequiresPermissions("sys:memUser:edit")
@RequestMapping(value = "delete")
@ResponseBody
public String delete(MemUser memUser) {
if (User.isSuperAdmin(memUser.getUserCode())) {
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (!MemUser.USER_TYPE_MEMBER.equals(memUser.getUserType())){
return renderResult(Global.FALSE, "非法操作,不能够操作此用户!");
}
if (memUser.getCurrentUser().getUserCode().equals(memUser.getUserCode())) {
return renderResult(Global.FALSE, text("删除用户失败,不允许删除当前用户"));
}
memUserService.delete(memUser);
return renderResult(Global.TRUE, text("删除用户'{0}'成功", memUser.getUserName()));
}
/**
* 选择会员对话框
*/
@RequiresPermissions("srv:memUser:view")
@RequestMapping(value = "memUserSelect")
public String memSelect(Member member, String selectData, Model model) {
String selectDataJson = EncodeUtils.decodeUrl(selectData);
if (selectDataJson != null && JSONValidator.from(selectDataJson).validate()){
model.addAttribute("selectData", selectDataJson);
}
model.addAttribute("member", member);
return "modules/srv/memUserSelect";
}
}
List View
memUserList.html
<% layout('/layouts/default.html', {title: '会员管理', libs: ['dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header">
<div class="box-title">
<i class="fa icon-user"></i> ${text('会员管理')}
</div>
<div class="box-tools pull-right">
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
<% if(hasPermi('sys:memUser:edit')){ %>
<a href="${ctx}/sys/memUser/form?op=add" class="btn btn-default btnTool" title="${text('新增会员')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
<% } %>
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
</div>
</div>
<div class="box-body">
<#form:form id="searchForm" model="${memUser}" action="${ctx}/sys/memUser/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<#form:hidden name="ctrlPermi" value="${@Global.getConfig('user.adminCtrlPermi', '2')}"/>
<div class="form-group">
<label class="control-label">${text('账号')}:</label>
<div class="control-inline">
<#form:input path="loginCode" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('昵称')}:</label>
<div class="control-inline">
<#form:input path="userName" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('姓名')}:</label>
<div class="control-inline">
<#form:input path="refName" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('手机')}:</label>
<div class="control-inline">
<#form:input path="mobile" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('状态')}:</label>
<div class="control-inline width-90">
<#form:select path="status" dictType="sys_user_status" blankOption="true" class="form-control isQuick"/>
</div>
</div>
<!-- <div class="form-row"></div> -->
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
<button type="button" class="btn btn-default btn-sm btnFormMore">${text('更多')}<i class="fa fa-angle-double-down"></i></button>
</div>
<div class="form-more">
<div class="form-group">
<label class="control-label">${text('邮箱')}:</label>
<div class="control-inline">
<#form:input path="email" maxlength="300" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('电话')}:</label>
<div class="control-inline">
<#form:input path="phone" maxlength="100" class="form-control width-90"/>
</div>
</div>
</div>
</#form:form>
<table id="dataGrid"></table>
<div id="dataGridPage"></div>
</div>
</div>
</div>
<% } %>
<script>
// 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
{header:'${text("登录账号")}', name:'loginCode', index:'a.login_code', width:200, align:"center", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/sys/memUser/form?userCode='+row.userCode+'&op=edit" class="btnList" data-title="${text("编辑会员")}">'+(val||row.id)+'</a>';
}},
{header:'${text("会员昵称")}', name:'userName', index:'a.user_name', width:200, align:"center"},
{header:'${text("员工姓名")}', name:'refName', index:'a.ref_name', width:200, align:"center"},
{header:'${text("电子邮箱")}', name:'email', index:'a.email', width:200, align:"center"},
{header:'${text("手机号码")}', name:'mobile', index:'a.mobile', width:200, align:"center"},
{header:'${text("办公电话")}', name:'phone', index:'a.phone', width:200, align:"center"},
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:200, align:"center"},
{header:'${text("状态")}', name:'status', index:'a.status', width:140, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_status')}, val, '未知', true);
}},
{header:'${text("操作")}', name:'actions', width:270, sortable:false, title:false, formatter: function(val, obj, row, act){
var actions = [];
<% if(hasPermi('sys:memUser:edit')){ %>
actions.push('<a href="${ctx}/sys/memUser/form?userCode='+row.userCode+'&op=edit" class="btnList" title="${text("编辑会员")}"><i class="fa fa-pencil"></i></a> ');
<% } %>
<% if(hasPermi('sys:memUser:updateStatus')){ %>
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/sys/memUser/disable?userCode='+row.userCode+'" class="btnList" title="${text("停用会员")}" data-confirm="${text("确认要停用该会员吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
}else if (row.status == Global.STATUS_DISABLE || row.status == Global.STATUS_FREEZE || row.status == Global.STATUS_AUDIT){
actions.push('<a href="${ctx}/sys/memUser/enable?userCode='+row.userCode+'" class="btnList" title="${text("启用会员")}" data-confirm="${text("确认要启用该会员吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
}
<% } %>
<% if(hasPermi('sys:memUser:edit')){ %>
actions.push('<a href="${ctx}/sys/memUser/delete?userCode='+row.userCode+'" class="btnList" title="${text("删除会员")}" data-confirm="${text("确认要删除该会员吗?")}"><i class="fa fa-trash-o"></i></a> ');
<% } %>
<% if(hasPermi('sys:memUser:authRole,sys:memUser:authDataScope,sys:memUser:resetpwd', 'or')){ %>
actions.push('<a href="javascript:" class="btnMore" title="${text("更多操作")}"><i class="fa fa-chevron-circle-right"></i></a> ');
actions.push('<div class="moreItems">');
<% if(hasPermi('sys:memUser:authRole')){ %>
actions.push('<a href="${ctx}/sys/memUser/form?userCode='+row.userCode+'&op=auth" class="btn btn-default btn-xs btnList" title="${text("会员分配角色")}"><i class="fa fa-check-square-o"></i> ${text("分配角色")}</a> ');
<% } %>
<% if(hasPermi('sys:memUser:resetpwd')){ %>
actions.push('<a href="${ctx}/sys/memUser/resetpwd?userCode='+row.userCode+'" class="btn btn-default btn-xs btnList" title="${text("会员密码重置")}" data-confirm="${text("确认要将该会员密码重置到初始状态吗?")}"><i class="fa fa-reply-all"></i> ${text("重置密码")}</a> ');
<% } %>
actions.push('</div>');
<% } %>
return actions.join('');
}}
],
// 加载成功后执行事件
ajaxSuccess: function(data){
}
});
</script>
Form View
memUserForm.html
<% layout('/layouts/default.html', {title: '会员管理', libs: ['validate','dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa icon-people"></i> ${text(memUser.isNewRecord ? '新增会员' : op == 'auth' ? '会员分配角色' : '编辑会员')}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${memUser}" action="${ctx}/sys/memUser/save" method="post" class="form-horizontal">
<#form:hidden name="op" value="${op}"/>
<#form:hidden name="userType" value="member"/>
<#form:hidden path="userCode"/>
<div class="box-body">
<% if(op=='auth'){ %><br/><% } %>
<% if(op == 'add' || op == 'edit') { %>
<div class="form-unit">${text('基本信息')}</div>
<% } %>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> ${text('登录账号')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:hidden name="oldLoginCode" value="${memUser.loginCode}"/>
<#form:input path="loginCode" minlength="4" maxlength="20" readonly="${op=='auth'}"
class="form-control required userName"
remote="${ctx}/sys/user/checkLoginCode?oldLoginCode=${memUser.loginCode}"
data-msg-remote="${text('登录账号已存在')}"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> ${text('会员昵称')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="userName" maxlength="32" readonly="${op=='auth'}" class="form-control required "/>
</div>
</div>
</div>
</div>
<% if(op == 'add' || op == 'edit') { %>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('电子邮箱')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<div class="input-group">
<#form:input path="email" maxlength="300" class="form-control email"/>
<span class="input-group-addon"><i class="fa fa-fw fa-envelope"></i></span>
</div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('手机号码')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<div class="input-group">
<#form:input path="mobile" maxlength="100" class="form-control mobile"/>
<span class="input-group-addon"><i class="fa fa-fw fa-mobile"></i></span>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('办公电话')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<div class="input-group">
<#form:input path="phone" maxlength="100" class="form-control phone"/>
<span class="input-group-addon"><i class="fa fa-fw fa-phone"></i></span>
</div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('权重(排序)')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="userWeight" maxlength="8" class="form-control digits" placeholder="${text('权重越大排名越靠前,请填写数字。')}"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('详细信息')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('会员姓名')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="member.memName" maxlength="50" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}:<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/>
</div>
</div>
</div>
</div>
<% } %>
<% if(hasPermi('sys:memUser:authRole') && (op == 'add' || op == 'auth')) { %>
<div class="form-unit">${text('分配角色')}</div>
<div class="pl10 pb20">
<table id="roleGrid"></table>
<#form:hidden name="userRoleString"/>
</div>
<% } %>
<% if(op == 'add' || op == 'edit') { %>
<#form:extend collapsed="true" />
<% } %>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('sys:memUser:edit,sys:memUser:authRole', 'or')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
<% if(hasPermi('sys:memUser:authRole') && (op == 'add' || op == 'auth')) { %>
// 加载角色列表
var roleGrid = $("#roleGrid").dataGrid({
url: '${ctx}/sys/role/treeData',
postData: [
{name:'userType',value:'member'},
{name:'ctrlPermi',value:'${@Global.getConfig("user.adminCtrlPermi", "2")}'}
],
columnModel: [
{header:'${text("角色名称")}', name:'name', sortable:false, width:100, align:"center"},
{header:'${text("角色编码")}', name:'id', sortable:false, width:100, align:"center"}
],
showCheckbox: true,
autoGridHeight: function(){
return 'auto';
},
autoGridWidth: function(){
return $('#inputForm .box-body').width()-20;
},
ajaxSuccess: function(){
<% for (role in roleList!){ %>
roleGrid.dataGrid('setSelectRow', '${role.roleCode}');
<% } %>
}
});
<% } %>
$("#inputForm").validate({
submitHandler: function(form){
<% if(hasPermi('sys:memUser:authRole') && (op == 'add' || op == 'auth')) { %>
$("#userRoleString").val(roleGrid.dataGrid('getSelectRows').join(','));
<% } %>
var memName = $('#member_memName').val();
if (memName == ''){
$('#member_memName').val($('#loginName').val());
}
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</script>
Select View
memUserSelect.html
<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. */ %>
<% layout('/layouts/default.html', {title: '用户选择', libs: ['dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-body">
<#form:form id="searchForm" model="${memUser}" action="${ctx}/srv/memUser/listData" method="post" class="form-inline "
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('账号')}:</label>
<div class="control-inline">
<#form:input path="loginCode" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('昵称')}:</label>
<div class="control-inline">
<#form:input path="userName" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('邮箱')}:</label>
<div class="control-inline">
<#form:input path="email" maxlength="300" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('手机')}:</label>
<div class="control-inline">
<#form:input path="mobile" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('电话')}:</label>
<div class="control-inline">
<#form:input path="phone" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('会员名称')}:</label>
<div class="control-inline">
<#form:input path="member.memName" maxlength="100" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
</div>
</#form:form>
<div class="row">
<div class="col-xs-10 pr10">
<table id="dataGrid"></table>
<div id="dataGridPage"></div>
</div>
<div class="col-xs-2 pl0">
<div id="selectData" class="tags-input"></div>
</div>
</div>
</div>
</div>
</div>
<% } %>
<script>
var selectData = ${isNotBlank(selectData!) ? selectData! : "{\}"},
selectNum = 0, dataGrid = $('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
{header:'${text("登录账号")}', name:'loginCode', index:'a.login_code', width:200, align:"center"},
{header:'${text("用户昵称")}', name:'userName', index:'a.user_name', width:200, align:"center"},
{header:'${text("电子邮箱")}', name:'email', index:'a.email', width:200, align:"center"},
{header:'${text("手机号码")}', name:'mobile', index:'a.mobile', width:200, align:"center"},
{header:'${text("办公电话")}', name:'phone', index:'a.phone', width:200, align:"center"},
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:200, align:"center"},
{header:'${text("名称")}', name:'member.memName', index:'m.mem_name', width:200, align:"center"},
{header:'${text("状态")}', name:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_status')}, val, '未知', true);
}},
{header:'行数据', name:'rowData', hidden:true, formatter: function(val, obj, row, act){
return JSON.stringify(row);
}}
],
autoGridHeight: function(){
var height = $(window).height() - $('#searchForm').height() - $('#dataGridPage').height() - 74;
$('.tags-input').height($('.ui-jqgrid').height() - 10);
return height;
},
showCheckbox: '${parameter.checkbox}' == 'true',
multiboxonly: false, // 单击复选框时再多选
ajaxSuccess: function(data){
$.each(selectData, function(key, value){
dataGrid.dataGrid('setSelectRow', key);
});
initSelectTag();
},
onSelectRow: function(id, isSelect, event){
if ('${parameter.checkbox}' == 'true'){
if(isSelect){
selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
}else{
delete selectData[id];
}
}else{
selectData = {};
selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
}
initSelectTag();
},
onSelectAll: function(ids, isSelect){
if ('${parameter.checkbox}' == 'true'){
for (var i=0; i<ids.length; i++){
if(isSelect){
selectData[ids[i]] = JSON.parse(dataGrid.dataGrid('getRowData', ids[i]).rowData);
}else{
delete selectData[ids[i]];
}
}
}
initSelectTag();
},
ondblClickRow: function(id, rownum, colnum, event){
if ('${parameter.checkbox}' != 'true'){
js.layer.$('#' + window.name).closest('.layui-layer')
.find(".layui-layer-btn0").trigger("click");
}
initSelectTag();
}
});
function initSelectTag(){
selectNum = 0;
var html = [];
$.each(selectData, function(key, value){
selectNum ++;
html.push('<span class="tag" id="'+key+'_tags-input"><span>'+value.userName+' </span>'
+ '<a href="#" onclick="removeSelectTag(\''+key+'\');" title="${text("取消选择")}">x</a></span>');
});
html.unshift('<div class="title">${text("当前已选择 {0\} 项", "<span id=\"selectNum\">'+selectNum+'</span>")}:</div>');
$('#selectData').empty().append(html.join(''));
}
function removeSelectTag(key){
delete selectData[key];
dataGrid.dataGrid('resetSelection', key);
$('#selectNum').html(--selectNum);
$('#'+key+'_tags-input').remove();
}
function getSelectData(){
return selectData;
}
</script>