فهرست منبع

组织机构权限修改,易耗品记录修改

hfy 3 ماه پیش
والد
کامیت
4563148b7e

+ 129 - 11
src/main/java/com/jeesite/modules/mes/web/EmpUserCustomController.java

@@ -2,8 +2,10 @@ package com.jeesite.modules.mes.web;
 
 import com.jeesite.common.config.Global;
 import com.jeesite.common.collect.ListUtils;
+import com.jeesite.common.entity.Page;
 import com.jeesite.common.lang.DateUtils;
 import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
 import com.jeesite.common.service.ServiceException;
 import com.jeesite.common.utils.excel.ExcelExport;
 import com.jeesite.common.utils.excel.ExcelImport;
@@ -17,8 +19,11 @@ import com.jeesite.modules.sys.entity.*;
 import com.jeesite.modules.sys.service.EmployeeService;
 import com.jeesite.modules.sys.service.EmpUserService;
 import com.jeesite.modules.sys.service.UserService;
+import com.jeesite.modules.sys.utils.UserUtils;
 import com.jeesite.modules.sys.web.user.EmpUserController;
+import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.ModelAttribute;
@@ -51,6 +56,9 @@ public class EmpUserCustomController extends BaseController {
     @Autowired
     private EmployeeService employeeService;
 
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
     @ModelAttribute
     public EmpUser get(String userCode, boolean isNewRecord) {
         return empUserService.get(userCode, isNewRecord);
@@ -181,23 +189,133 @@ public class EmpUserCustomController extends BaseController {
         return empUserController.save(empUser, oldLoginCode, request);
     }
 
+    @RequestMapping(value = "listData")
+    @ResponseBody
+    public Page<EmpUser> listData(EmpUser empUser, Boolean isAll, String ctrlPermi, String ctrlPermiFilter,
+                                  HttpServletRequest request, HttpServletResponse response) {
+        applyOfficeTreeFilter(empUser, Boolean.TRUE.equals(isAll));
+        empUser.setPage(new Page<>(request, response));
+        return empUserService.findPage(empUser);
+    }
+
+    private void applyOfficeTreeFilter(EmpUser empUser, boolean isAll) {
+        if (isAll) {
+            return;
+        }
+        User currentUser = UserUtils.getUser();
+        if (currentUser == null || currentUser.isSuperAdmin()) {
+            return;
+        }
+        if (empUser.getEmployee() != null && empUser.getEmployee().getCompany() != null) {
+            empUser.getEmployee().getCompany().setIsQueryChildren(true);
+        }
+        Office office = empUser.getEmployee() == null ? null : empUser.getEmployee().getOffice();
+        String officeCode = office == null ? null : office.getOfficeCode();
+        if (office != null) {
+            office.setIsQueryChildren(true);
+        }
+
+        if (StringUtils.isNotBlank(officeCode) && !isTopOffice(officeCode)) {
+            List<String> officeCodes = findPermittedOfficeCodes(currentUser.getUserCode(), officeCode);
+            if (officeCodes.isEmpty()) {
+                officeCodes.add("__NO_AUTH_OFFICE__");
+            }
+            empUser.getSqlMap().getWhere().and("o.office_code", QueryType.IN, officeCodes.toArray(new String[0]));
+            return;
+        }
+
+        List<String> officeCodes = findPermittedOfficeCodes(currentUser.getUserCode(), officeCode);
+        if (officeCodes.isEmpty()) {
+            officeCodes.add("__NO_AUTH_OFFICE__");
+        }
+        empUser.getSqlMap().getWhere().and("o.office_code", QueryType.IN, officeCodes.toArray(new String[0]));
+        if (office != null) {
+            office.setOfficeCode(null);
+        }
+    }
+
+    private boolean isTopOffice(String officeCode) {
+        try {
+            String parentCode = jdbcTemplate.queryForObject(
+                    "select parent_code from js_sys_office where office_code = ?",
+                    String.class, officeCode);
+            return StringUtils.isBlank(parentCode) || "0".equals(parentCode);
+        } catch (EmptyResultDataAccessException ex) {
+            return false;
+        }
+    }
+
+    private List<String> findPermittedOfficeCodes(String userCode, String rootOfficeCode) {
+        if (StringUtils.isBlank(userCode)) {
+            return ListUtils.newArrayList();
+        }
+        boolean selectedTopOffice = StringUtils.isNotBlank(rootOfficeCode) && isTopOffice(rootOfficeCode);
+        if (StringUtils.isBlank(rootOfficeCode) || selectedTopOffice) {
+            List<String> officeCodes = queryPermittedOfficeCodes(userCode, rootOfficeCode, true);
+            if (!officeCodes.isEmpty()) {
+                return officeCodes;
+            }
+        } else if (!queryPermittedOfficeCodes(userCode, null, true).isEmpty()) {
+            return queryPermittedOfficeCodes(userCode, rootOfficeCode, true);
+        }
+        return queryPermittedOfficeCodes(userCode, rootOfficeCode, false);
+    }
+
+    private List<String> queryPermittedOfficeCodes(String userCode, String rootOfficeCode, boolean onlySpecificScopes) {
+        List<Object> params = ListUtils.newArrayList();
+        StringBuilder sql = new StringBuilder();
+        sql.append("select distinct o.office_code ");
+        sql.append("from js_sys_office o ");
+        sql.append("where 1 = 1 ");
+        if (StringUtils.isNotBlank(rootOfficeCode)) {
+            sql.append("and (o.office_code = ? or o.parent_codes like concat('%,', ?, ',%')) ");
+            params.add(rootOfficeCode);
+            params.add(rootOfficeCode);
+        }
+        sql.append("and exists (");
+        sql.append("  select 1 from (");
+        sql.append("    select rds.ctrl_data from js_sys_role_data_scope rds ");
+        sql.append("    join js_sys_user_role ur on ur.role_code = rds.role_code ");
+        sql.append("    where ur.user_code = ? and rds.ctrl_type = 'Office' and rds.ctrl_permi = '1' ");
+        sql.append("    union ");
+        sql.append("    select uds.ctrl_data from js_sys_user_data_scope uds ");
+        sql.append("    where uds.user_code = ? and uds.ctrl_type = 'Office' and uds.ctrl_permi = '1' ");
+        sql.append("  ) ds ");
+        sql.append("  join js_sys_office so on so.office_code = ds.ctrl_data ");
+        sql.append("  where (o.office_code = ds.ctrl_data or o.parent_codes like concat('%,', ds.ctrl_data, ',%')) ");
+        params.add(userCode);
+        params.add(userCode);
+        if (onlySpecificScopes) {
+            if (StringUtils.isBlank(rootOfficeCode)) {
+                sql.append("  and so.parent_code is not null and so.parent_code <> '0' ");
+            } else if (!isTopOffice(rootOfficeCode)) {
+                sql.append("  and so.parent_code is not null and so.parent_code <> '0' ");
+            } else {
+                sql.append("  and ds.ctrl_data <> ? and so.parent_codes like concat('%,', ?, ',%') ");
+                params.add(rootOfficeCode);
+                params.add(rootOfficeCode);
+            }
+        } else if (StringUtils.isNotBlank(rootOfficeCode)) {
+            sql.append("  and exists (");
+            sql.append("    select 1 from js_sys_office selected ");
+            sql.append("    where selected.office_code = ? ");
+            sql.append("    and (so.office_code = selected.office_code ");
+            sql.append("      or so.parent_codes like concat('%,', selected.office_code, ',%') ");
+            sql.append("      or selected.parent_codes like concat('%,', so.office_code, ',%'))");
+            sql.append("  ) ");
+            params.add(rootOfficeCode);
+        }
+        sql.append(")");
+        return jdbcTemplate.queryForList(sql.toString(), String.class, params.toArray());
+    }
+
     private boolean shouldSaveAuth(HttpServletRequest request) {
         return "auth".equals(request.getParameter("op")) || request.getParameterMap().containsKey("userRoleString");
     }
 
     @RequestMapping(value = "exportData")
     public void exportData(EmpUser empUser, String ctrlPermi, String ctrlPermiFilter, HttpServletResponse response) {
-        if (empUser.getEmployee() != null) {
-            if (empUser.getEmployee().getOffice() != null) {
-                empUser.getEmployee().getOffice().setIsQueryChildren(true);
-            }
-            if (empUser.getEmployee().getCompany() != null) {
-                empUser.getEmployee().getCompany().setIsQueryChildren(true);
-            }
-        }
-        if (StringUtils.isBlank(ctrlPermi) || !"0".equals(ctrlPermi) || Global.isStrictMode()) {
-            empUserService.addDataScopeFilter(empUser, ctrlPermiFilter);
-        }
+        applyOfficeTreeFilter(empUser, false);
         List<ExcelEmpUserEmployee> list = ListUtils.newArrayList();
         for (EmpUser user : empUserService.findList(empUser)) {
             list.add(toExcel(user));

+ 30 - 0
src/main/java/com/jeesite/modules/mes/web/RoleCustomController.java

@@ -0,0 +1,30 @@
+package com.jeesite.modules.mes.web;
+
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.sys.entity.Role;
+import com.jeesite.modules.sys.service.RoleService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Controller
+@RequestMapping(value = "${adminPath}/mes/roleCustom")
+public class RoleCustomController extends BaseController {
+
+    @Autowired
+    private RoleService roleService;
+
+    @RequiresPermissions("sys:role:view")
+    @RequestMapping(value = "listData")
+    @ResponseBody
+    public Page<Role> listData(Role role, HttpServletRequest request, HttpServletResponse response) {
+        role.setPage(new Page<>(request, response));
+        return roleService.findPage(role);
+    }
+}

+ 3 - 2
src/main/resources/config/application.yml

@@ -439,8 +439,9 @@ user:
   #  # 系统管理员角色编号(客户方管理员使用的角色)
   #  corpAdminRoleCode: corpAdmin
   #
-  #  # 二级管理员的控制权限类型(1拥有的权限 2管理的权限,管理功能包括:用户管理、组织机构、公司管理等)(v4.1.5+)
-  #  adminCtrlPermi: 2
+  # 二级管理员的控制权限类型(1拥有的权限 2管理的权限,管理功能包括:用户管理、组织机构、公司管理等)(v4.1.5+)
+  # 用户管理、组织机构页面本项目按全部数据查询,避免角色分配自定义数据权限后反向过滤用户列表。
+  adminCtrlPermi: 0
 
   # 多租户模式(SAAS模式)(专业版)
   useCorpModel: false

+ 3 - 3
src/main/resources/views/modules/mes/mesDeviceConsumableRecordList.html

@@ -53,12 +53,12 @@ $('#dataGrid').dataGrid({
 	columnModel: [
 
 		{header:'${text("易耗品")}', name:'consumableId', index:'a.consumable_id', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
-			return row.consumable.title;
+			return js.val(row, 'consumable.title') || val || '';
 		}},
 		{header:'${text("类型")}', name:'busType', index:'a.bus_type', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
 			return js.getDictLabel(${@DictUtils.getDictListJson('mes_consumable_bus_type')}, val, '${text("未知")}', true);
 		}},
-		{header:'${text("维修设备")}', name:'deviceRecordId', index:'a.device_record_id', width:150, align:"center", frozen:true},
+		{header:'${text("维修设备")}', name:'device.treeName', index:'d.tree_name', width:150, align:"center", frozen:true},
 
 		{header:'${text("数量")}', name:'num', index:'a.num', width:150, align:"center"},
 		{header:'${text("创建人")}', name:'createBy', index:'a.create_by', width:120, align:"center"},
@@ -127,4 +127,4 @@ $('#btnImport').click(function(){
 		</div>
 	</div>
 </form>
-//--></script>
+//--></script>

+ 3 - 3
src/main/resources/views/modules/mes/skillUserSelect.html

@@ -27,10 +27,10 @@
     <div class="main-content">
         <div class="box box-main">
             <div class="box-body pb0">
-                <#form:form id="searchForm" model="${empUser}" action="${ctx}/sys/empUser/listData" method="post" class="form-inline "
+                <#form:form id="searchForm" model="${empUser}" action="${ctx}/mes/empUserCustom/listData" method="post" class="form-inline "
                 data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
                 <#form:hidden name="status" value="${isNotBlank(empUser.status) ? empUser.status : '0'}" class="isReset"/>
-                <#form:hidden name="isAll" value="${parameter.isAll}" class=""/>
+                <#form:hidden name="isAll" value="${isNotBlank(parameter.isAll) ? parameter.isAll : 'true'}" class=""/>
                 <#form:hidden id="roleCode" name="roleCode" class="isReset"/>
                 <#form:hidden id="userType" name="userType" class="isReset"/>
                 <div class="form-group">
@@ -99,7 +99,7 @@
                 if (queryType == 'userType'){
                     $('#userType').val(treeNode.id);
                     if (treeNode.id == 'employee'){
-                        $('#searchForm').attr('action', '${ctx}/sys/empUser/listData');
+                        $('#searchForm').attr('action', '${ctx}/mes/empUserCustom/listData');
                     }else{
                         $('#searchForm').attr('action', '${ctx}/sys/user/listData');
                     }

+ 230 - 0
src/main/resources/views/modules/sys/roleFormAuthDataScope.html

@@ -0,0 +1,230 @@
+<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+   * No deletion without permission, or be held responsible to law. */ %>
+<% layout('/layouts/default.html', {title: '角色管理', libs: ['validate', 'zTree']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-people"></i> ${text('角色分配数据权限')}
+			</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="${role}" action="${ctx}/sys/role/saveAuthDataScope" method="post" class="form-horizontal">
+			<div class="box-body"><br/>
+				<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="oldRoleName" value="${role.roleName}"/>
+								<#form:input path="roleName" maxlength="100" readonly="true" class="form-control required "/>
+							</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:hidden path="isNewRecord"/>
+								<#form:hidden path="roleCode"/>
+								<#form:input path="viewCode" maxlength="64" readonly="true" class="form-control required abc"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="row">
+					<div class="col-xs-12">
+						<div class="form-group">
+							<label class="control-label col-sm-2" title="${text('指定数据权限范围类型,多个角色同时指定,之间为或者关系')}">
+								<span class="required ">*</span> ${text('数据范围')}:<i class="fa icon-question "></i></label>
+							<div class="col-sm-10">
+								<#form:radio path="dataScope" dictType="sys_role_data_scope" class="form-control required " />
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="row hide">
+					<div class="col-xs-12">
+						<div class="form-group">
+							<label class="control-label col-sm-2" title="${text('在 addFilter 权限过滤的时候指定适应的业务范围,不指定代表所有生效,如:有的功能看本部门,有的功能看本公司;新的业务范围从字典 sys_role_biz_scope 类型添加。')}">
+								<span class="required hide">*</span> ${text('控制业务范围')}:<i class="fa icon-question "></i></label>
+							<div class="col-sm-10">
+								<#form:select path="bizScope" dictType="sys_role_biz_scope" class="form-control " multiple="true"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="form-unit">${text('授权数据权限')}</div>
+				<div id="dataScopeTrees"></div>
+				<script id="dataScopeTpl" type="text/template">
+					<div class="pull-left" style="padding:0 15px;min-width:300px;">
+						<div class="box box-solid box-trees">
+							<div class="box-header">
+								<div class="box-title icheck">
+									<label><input type="checkbox" id="checkall_{{d.key}}"
+										class="checkall"/> {{d.label}}</label>
+								</div>
+								<div class="box-tools pull-right" style="top:8px;">
+									<a class="btn btn-box-tool" id="expand_{{d.key}}"
+										value="dataScopeTree_{{d.key}}" >${text('展开')}</a>/<a
+										class="btn btn-box-tool" id="collapse_{{d.key}}"
+										value="dataScopeTree_{{d.key}}" >${text('折叠')}</a>
+								</div>
+							</div>
+							<div class="box-body">
+								<div id="dataScopeTree_{{d.key}}" class="ztree"></div>
+							</div>
+						</div>
+					</div>
+				</script>
+			    <#form:hidden name="roleDataScopeListJson"/>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('sys:role:edit')){ %>
+							<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
+						<% } %>
+						<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>
+function initDataScopeRadio(){
+	var $dataScopeInputs = $('#dataScope input');
+	$dataScopeInputs.each(function(){
+		var $input = $(this), $label = $input.closest('label');
+		if ($input.val() == '2'){
+			$label.contents().filter(function(){
+				return this.nodeType == 3;
+			}).last().replaceWith(' ${text("数据授权")}');
+			$input.prop('checked', true);
+			if ($.fn.iCheck){
+				$input.iCheck('check');
+			}
+		}else{
+			($label.length ? $label : $input.parent()).hide();
+		}
+	});
+}
+initDataScopeRadio();
+$('#dataScope input').on('ifCreated ifChecked', function(){
+	if ($(this).is(':checked')){
+		if ($(this).val() == '2'){ // 2 自定义数据
+			$('#dataScopeTrees').show().prev().show();
+		}else{
+			$('#dataScopeTrees').hide().prev().hide();
+		}
+	}
+}).change();
+$("#inputForm").validate({
+	submitHandler: function(form){
+		// 获取数据权限数据
+		var dataScopeData = [];
+		$.each(dataScopeTrees, function(key, dataScopeTree){
+			var treeNodes = dataScopeTree.getCheckedNodes(true);
+			for(var i=0; i<treeNodes.length; i++) {
+				dataScopeData.push({
+					ctrlType: key, ctrlData: treeNodes[i].id
+				});
+			}
+		});
+		$("#roleDataScopeListJson").val(JSON.stringify(dataScopeData));
+		// 提交表单数据
+		js.ajaxSubmitForm($(form), function(data){
+			js.showMessage(data.message);
+			if(data.result == Global.TRUE){
+				js.closeCurrentTabPage(function(contentWindow){
+					contentWindow.page();
+				});
+			}
+		}, "json");
+    }
+});
+//加载数据权限树结构
+var setting = {
+	check:{enable:true,nocheckInherit:true},
+	view:{selectedMulti:false,nameIsHTML: true},
+	data:{simpleData:{enable:true},key:{title:"title"}},
+	callback:{
+		beforeClick: function (treeId, treeNode, clickFlag) {
+			var tree = $.fn.zTree.getZTreeObj(treeId);
+			tree.checkNode(treeNode, !treeNode.checked, true, true);
+			return false;
+		},
+		onCheck: function (event, treeId, treeNode){
+			$('#dataScope3').parent().click(); // 选中“自定义权限”单选按钮
+		}
+	}
+},
+moduleCodes = '${toJson(moduleCodes)}';
+dataScopes = ${toJson(dataScopes)},
+dataScopeTrees = {}; // 用sysCode分类存储所有菜单树
+for (var i=0; i<dataScopes.length; i++){
+	var dataScope = dataScopes[i];
+	// 验证模块是否开启,如果未开启,则跳过
+	if (moduleCodes.indexOf("\""+dataScope.moduleCode+"\"") == -1){
+		continue;
+	}
+	// 控制权限 ctrlPermi: 0全部  1拥有权限  2管理权限
+	if (!(dataScope.ctrlPermi == '0'
+			|| dataScope.ctrlPermi == '1')){
+		continue;
+	}
+ 	$('#dataScopeTrees').append(js.template('dataScopeTpl', {
+ 		key: dataScope.ctrlType, label: dataScope.ctrlName_${lang()} || dataScope.ctrlName}));
+ 	var ctrlDataUrl = dataScope.ctrlDataUrl || '';
+	$.ajax({
+		type: 'POST',
+		url: "${ctx}" + ctrlDataUrl + (ctrlDataUrl.indexOf("?")!=-1?'&':'?') + "___t=" + new Date().getTime(),
+		data: {ctrlPermi: dataScope.ctrlPermi || '0'},
+		dataType: 'json',
+		async: false,
+		error: function(data){
+			js.showErrorMessage(data.responseText);
+		},
+		success: function(data, status, xhr){
+			// 初始化树结构
+			var tree = $.fn.zTree.init($("#dataScopeTree_"+dataScope.ctrlType), setting, data);
+			tree.setting.check.chkboxType = dataScope.chkboxType;
+			// 默认展开节点(如果级别设置为-1,则:如果有1个根节点,则展开一级节点,否则不展开)
+			$.fn.zTree.expandNodeByLevel(tree, dataScope.expandLevel);
+			// 树结构:全选、取消全选
+			$('#checkall_'+dataScope.ctrlType).iCheck({
+		 		checkboxClass:'icheckbox_minimal-grey'
+		 	}).on('ifChecked ifUnchecked', function(){
+	        	var ctrlType = $(this).attr('ctrlType');
+				if(this.checked){
+					dataScopeTrees[ctrlType].checkAllNodes(true);
+				}else{
+					dataScopeTrees[ctrlType].checkAllNodes(false);
+				}
+			}).attr("ctrlType", dataScope.ctrlType);
+			// 展开和折叠按钮绑定
+			$('#expand_'+dataScope.ctrlType).click(function(){
+				var ctrlType = $(this).attr('ctrlType');
+				dataScopeTrees[ctrlType].expandAll(true);
+			}).attr("ctrlType", dataScope.ctrlType);
+			$('#collapse_'+dataScope.ctrlType).click(function(){
+				var ctrlType = $(this).attr('ctrlType');
+				dataScopeTrees[ctrlType].expandAll(false);
+			}).attr("ctrlType", dataScope.ctrlType);
+			// 将树对象存储到全局数组里
+			dataScopeTrees[dataScope.ctrlType] = tree;
+		}
+	});
+}
+// 默认选择节点
+<% for(dataScope in roleDataScopeList){ %> 
+try{dataScopeTrees['${dataScope.ctrlType}'].checkNode(dataScopeTrees['${dataScope.ctrlType}']
+	.getNodeByParam("id","${dataScope.ctrlData}"), true, false);}catch(e){}
+<% } %>
+</script>

+ 133 - 0
src/main/resources/views/modules/sys/roleFormAuthUser.html

@@ -0,0 +1,133 @@
+<% layout('/layouts/default.html', {title: '角色管理', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header" style="display:block;">
+			<div class="box-title">
+				<i class="fa icon-people"></i> ${text('角色分配用户')}(${role.roleName}-${role.viewCode}-${@DictUtils.getDictLabel('sys_user_type',role.userType,'未设置')})
+			</div>
+			<div class="box-tools pull-right">
+				<a href="#" class="btn btn-default" id="btnAddUser" title="${text('添加用户')}"><i class="fa fa-plus"></i> ${text('添加用户')}</a>
+				<a href="#" class="btn btn-default" id="btnDelUser" title="${text('删除用户')}"><i class="fa fa-remove"></i> ${text('批量取消')}</a>
+				<a href="javascript:" class="btn btn-default" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" action="${ctx}/sys/user/listData" method="post" class="form-inline "
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<#form:hidden name="roleCode" value="${role.roleCode}"/>
+				<#form:hidden name="userType" value="${role.userType}"/>
+				<div class="form-group">
+					<label class="control-label">${text('账号')}:</label>
+					<div class="control-inline">
+						<#form:input name="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 name="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 name="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 name="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 name="phone" 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-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>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<div class="hide"><#form:listselect id="userSelect" title="${text('用户选择')}"
+	url="${ctx}/sys/user/userSelect?userType=${role.userType}" allowClear="false"
+	checkbox="true" itemCode="userCode" itemName="userName"/></div>
+<% } %>
+<script>
+$('#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:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_status')}, val, '未知', true);
+		}},
+		{header:'${text("操作")}', name:'actions', width:100, formatter: function(val, obj, row, act){
+			var actions = [];
+			actions.push('<a href="${ctx}/sys/role/deleteAuthUser?roleCode=${role.roleCode}&userRoleString='+row.userCode+'" class="btnList" title="${text("取消授权")}" data-confirm="${text("确认要取消该用户角色吗?")}"><i class="fa fa-remove"></i></a>&nbsp;');
+			return actions.join('');
+		}}
+	],
+	showCheckbox: true,
+	ajaxSuccess: function(data){
+	}
+});
+$('#btnDelUser').click(function(){
+	var userCodes = $('#dataGrid').dataGrid('getSelectRows');
+	if (userCodes != null && userCodes.length > 0){
+		js.confirm('${text("确认要取消选中的用户角色权限吗?")}', function(){
+			js.ajaxSubmit('${ctx}/sys/role/deleteAuthUser', {
+				roleCode: '${role.roleCode}',
+				userRoleString: userCodes.join(',')
+			}, function(data){
+				js.showMessage(data.message);
+				page();
+			});
+		});
+	}else{
+		js.showMessage('${text("请在列表选中要取消角色的用户")}');
+	}
+	return false;
+});
+$('#btnAddUser').click(function(){
+	if ('${role.userType}' == 'employee'){
+		$('#userSelectDiv').attr('data-url', '${ctx}/sys/empUser/empUserSelect?isAll=true&ctrlPermi=0');
+	}else{
+		$('#userSelectDiv').attr('data-url', '${ctx}/sys/user/userSelect?userType=${role.userType}');
+	}
+	$('#userSelectCode').val('');
+	$('#userSelectName').val('').click();
+});
+function listselectCallback(id, action, index, layero){
+	if (id == 'userSelect' && action == 'ok'){
+		if ($('#userSelectCode').val() != ''){
+			js.ajaxSubmit('${ctx}/sys/role/saveAuthUser', {
+				roleCode: '${role.roleCode}',
+				userRoleString: $('#userSelectCode').val()
+			}, function(data){
+				js.showMessage(data.message);
+				page();
+			});
+		}else{
+			js.showMessage('${text("没有选择要授权的用户")}');
+		}
+	}
+}
+</script>

+ 110 - 0
src/main/resources/views/modules/sys/roleList.html

@@ -0,0 +1,110 @@
+<% 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-people"></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:role:edit')){ %>
+					<a href="${ctx}/sys/role/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="${role}" action="${ctx}/mes/roleCustom/listData" method="post" class="form-inline hide"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<#form:hidden name="ctrlPermi" value="0"/>
+				<div class="form-group">
+					<label class="control-label">${text('角色名称')}:</label>
+					<div class="control-inline">
+						<#form:input path="roleName_like" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('角色编码')}:</label>
+					<div class="control-inline">
+						<#form:input path="roleCode_like" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('用户类型')}:</label>
+					<div class="control-inline width-90">
+						<#form:select path="userType" dictType="sys_user_type" blankOption="true" class="form-control"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('系统角色')}:</label>
+					<div class="control-inline width-60">
+						<#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('状态')}:</label>
+					<div class="control-inline width-60">
+						<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
+					</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>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("角色名称")}', name:'roleName', index:'a.role_name', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/sys/role/form?roleCode='+row.roleCode+'&op=edit" class="btnList" data-title="${text("编辑角色")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("角色编码")}', name:'roleCode', index:'a.role_code', width:150, align:"center"},
+		{header:'${text("排序号")}', name:'roleSort', index:'a.role_sort', width:80, align:"center"},
+		{header:'${text("用户类型")}', name:'userType', index:'a.user_type', width:100, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_user_type')}, val, '<font color=#aaa>${text("未设置")}</font>', true);
+		}},
+		{header:'${text("系统角色")}', name:'isSys', index:'a.is_sys', width:80, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_yes_no')}, val, '未知', true);
+		}},
+		{header:'${text("数据范围")}', name:'dataScope', index:'a.data_scope', width:100, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_role_data_scope')}, val, '${text("未设置")}', true);
+		}},
+		{header:'${text("业务范围")}', name:'bizScope', index:'a.biz_scope', width:100, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_role_biz_scope')}, val, '${text("未设置")}', true);
+		}},
+		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:130, align:"center"},
+		{header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:160, align:"left"},
+		{header:'${text("状态")}', name:'status', index:'a.status', width:80, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('sys_status')}, val, '未知', true);
+		}},
+		{header:'${text("操作")}', name:'actions', width:130, formatter: function(val, obj, row, act){
+			var actions = [];
+			<% if(hasPermi('sys:role:edit')){ %>
+				actions.push('<a href="${ctx}/sys/role/form?roleCode='+row.roleCode+'&op=edit" class="btnList" title="${text("编辑角色")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				if (row.status == Global.STATUS_NORMAL){
+					actions.push('<a href="${ctx}/sys/role/disable?roleCode='+row.roleCode+'" class="btnList" title="${text("停用角色")}" data-confirm="${text("确认要停用该角色吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
+				}else if (row.status == Global.STATUS_DISABLE){
+					actions.push('<a href="${ctx}/sys/role/enable?roleCode='+row.roleCode+'" class="btnList" title="${text("启用角色")}" data-confirm="${text("确认要启用该角色吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
+				}
+				actions.push('<a href="${ctx}/sys/role/delete?roleCode='+row.roleCode+'" class="btnList" title="${text("删除角色")}" data-confirm="${text("确认要删除该角色吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+				actions.push('<a href="javascript:" class="btnMore" title="${text("更多操作")}"><i class="fa fa-chevron-circle-right"></i></a>&nbsp;');
+				actions.push('<div class="moreItems">');
+				actions.push('<a href="${ctx}/sys/role/form?roleCode='+row.id+'&op=auth" class="btn btn-default btn-xs btnList" title="${text("角色分配功能权限")}"><i class="fa fa-check-square-o"></i> ${text("授权菜单")}</a>&nbsp;');
+				actions.push('<a href="${ctx}/sys/role/formAuthDataScope?roleCode='+row.id+'" class="btn btn-default btn-xs btnList" title="${text("角色分配数据权限")}"><i class="fa fa-check-circle-o"></i> ${text("数据权限")}</a>&nbsp;');
+				actions.push('<a href="${ctx}/sys/role/formAuthUser?roleCode='+row.id+'" class="btn btn-default btn-xs btnList" title="${text("角色分配用户")}"><i class="fa fa-user"></i> ${text("分配用户")}</a>&nbsp;');
+				actions.push('</div>');
+			<% } %>
+			return actions.join('');
+		}}
+	],
+	ajaxSuccess: function(data){
+	}
+});
+</script>

+ 1 - 1
src/main/resources/views/modules/sys/user/empUserList.html

@@ -26,7 +26,7 @@
 			</div>
 		</div>
 		<div class="box-body">
-			<#form:form id="searchForm" model="${empUser}" action="${ctx}/sys/empUser/listData" method="post" class="form-inline "
+			<#form:form id="searchForm" model="${empUser}" action="${ctx}/mes/empUserCustom/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="0"/>
 			<div class="form-group">