zhangqiankun hace 3 años
padre
commit
ca96e861e2

+ 4 - 4
saas-account/src/main/java/com/persagy/person/controller/SaasAccountController.java

@@ -42,9 +42,9 @@ import io.swagger.annotations.ApiOperation;
  * @author zhangqiankun
  * @date 2021-03-13 15:29:50
  */
-
-@Api(tags = "账号信息")
 @RestController
+@Api(tags = "账号信息")
+@SuppressWarnings("unchecked")
 @RequestMapping(value = "/account", method = RequestMethod.POST)
 public class SaasAccountController {
 	
@@ -77,7 +77,7 @@ public class SaasAccountController {
 		if (BooleanUtil.isTrue(queryVO.getGroupIsNull())) {
 			queryWrapper.apply("(GROUP_CODE IS NULL OR TRIM(GROUP_CODE) = '')");
 		}
-		queryWrapper.orderByDesc(SaasAccount::getUpdateTime);		//更新时间降序
+		queryWrapper.orderByDesc(SaasAccount::getUpdateTime, SaasAccount::getId);		// 默认更新时间降序
     	List<SaasAccount> list = this.saasAccountService.list(queryWrapper);
     	if (CollectionUtil.isEmpty(list)) {
 			return ResponseResultUtil.successResult(Lists.newArrayList(), 0L);
@@ -101,7 +101,7 @@ public class SaasAccountController {
 		} else {
 			Page<SaasAccount> page = new Page<SaasAccount>(pageVO.getPage(), pageVO.getSize());
 			LambdaQueryWrapper<SaasAccount> queryWrapper = this.saasAccountService.getQueryWrapper(saasAccount);
-			queryWrapper.orderByDesc(SaasAccount::getUpdateTime);		//更新时间降序
+			queryWrapper.orderByDesc(SaasAccount::getUpdateTime, SaasAccount::getId);		// 默认更新时间降序
 	    	pageList = this.saasAccountService.page(page, queryWrapper);
 		}
     	if (pageList == null || CollectionUtil.isEmpty(pageList.getRecords())) {

+ 12 - 10
saas-account/src/main/java/com/persagy/person/controller/SaasLoginController.java

@@ -84,6 +84,9 @@ public class SaasLoginController {
     	if (SaasCommonConstant.STATUS_1 != account.getValid()) {
     		return ResponseResultUtil.errorResult(ResponseCode.A0220.getCode(), "此账号已停用");
 		}
+    	if (!account.getAppId().contains(loginVO.getAppId())) {
+    		return ResponseResultUtil.errorResult(ResponseCode.A0220.getCode(), "此账号不允许在此端登录");
+		}
     	// 验证是否在有效期内
     	if (SaasCommonConstant.STR_STATUS_0.equals(account.getValidLast())) {
     		Date date = new Date();
@@ -108,7 +111,7 @@ public class SaasLoginController {
     		return ResponseResultUtil.errorResult("登录信息更新失败");
 		}
     	account.setPassword(null);
-    	String token = this.setRedisToken(account, loginVO.isRemember(), false);
+    	String token = this.setRedisToken(account, loginVO.getAppId(), loginVO.isRemember(), false);
     	response.setHeader(CipherConstans.TOKEN_HEADER_TOKEN, token);
     	return ResponseResultUtil.successResult(account);
     }
@@ -131,7 +134,7 @@ public class SaasLoginController {
     	if (account == null) {
     		return ResponseResultUtil.errorResult(ResponseCode.A0402.getCode(), "账号信息不存在");
 		}
-    	String token = this.setRedisToken(account, true, true);
+    	String token = this.setRedisToken(account, queryVO.getAppId(), true, true);
     	response.setHeader(CipherConstans.TOKEN_HEADER_TOKEN, token);
     	return ResponseResultUtil.successResult(account);
     }
@@ -158,12 +161,13 @@ public class SaasLoginController {
     /**
      * 设置此账号的token,存入redis,如果redis中已存在,只追加有效期
      * @param account
+     * @param loginApp
      * @param remember
      * @param isEqual 是否验证一致
      * @return
      * @throws UnsupportedEncodingException
      */
-    private String setRedisToken(SaasAccount account, boolean remember, boolean isEqual) throws UnsupportedEncodingException {
+    private String setRedisToken(SaasAccount account, String loginApp, boolean remember, boolean isEqual) throws UnsupportedEncodingException {
     	// 生成token,并验证之前登录是否为记住登录
     	SecureAES aes = new SecureAES(properties.getAesKey(), properties.getAesIv());
     	// 对称性加密用户信息
@@ -175,13 +179,13 @@ public class SaasLoginController {
 	    		// 判断是否与redis中一致,不一致,返回错误信息
 	        	boolean result = this.bouncycastleCipher.isEqual(sign, account.getId());
 	        	if (!result) {
-	        		throw new BusinessException("该账户未登录,请先登录");
+	        		throw new BusinessException(ResponseCode.A0301.getCode(), ResponseCode.A0301.getDesc());
 	    		}
 			}
 			this.redisTemplate.expire(account.getId(), Long.parseLong(this.properties.getTokenExpire()), TimeUnit.MINUTES);
 		} else {
 			// 加密串MD5加密转为sign,redis:key-账号ID,value-sign(data-MD5加密后)
-	    	sign = this.bouncycastleCipher.encrypt(this.tokenInfo(data), account.getId(), DigestAlgorithm.MD5, Long.parseLong(this.properties.getTokenExpire()), TimeUnit.MINUTES);
+	    	sign = this.bouncycastleCipher.encrypt(this.tokenInfo(data, loginApp), account.getId(), DigestAlgorithm.MD5, Long.parseLong(this.properties.getTokenExpire()), TimeUnit.MINUTES);
 		}
         // token=data.sign
     	String token = data + SaasCommonConstant.POINT_JOIN_SYMBOL + sign;
@@ -201,7 +205,6 @@ public class SaasLoginController {
 		JSONObject object = new JSONObject();
 		object.put(SaasCommonConstant.REMEMBER, remember);
 		object.put(SaasCommonConstant.GROUP_CODE, saasAccount.getGroupCode());
-		object.put(SaasCommonConstant.APP_ID, saasAccount.getAppId());
 		object.put(SaasCommonConstant.ACCOUNT_ID, saasAccount.getId());
 		return object;
 	}
@@ -210,13 +213,12 @@ public class SaasLoginController {
      * 账号信息
      * 
      * @param groupCode
-     * @param appId
-     * @param accountId
-     * @param accountBelong
+     * @param loginApp
      * @return
      */
-    private String tokenInfo(String content) {
+    private String tokenInfo(String content, String loginApp) {
 		JSONObject object = new JSONObject();
+		object.put(SaasCommonConstant.APP_ID, loginApp);
 		object.put("date", System.currentTimeMillis());
 		object.put("content", content);
 		return object.toJSONString();

+ 2 - 2
saas-account/src/main/java/com/persagy/person/controller/SaasMenuController.java

@@ -77,9 +77,9 @@ public class SaasMenuController {
     	List<SaasMenu> menuTree = null;
     	if (SaasCommonConstant.STR_STATUS_0.equals(accountType) && SaasCommonConstant.STR_STATUS_0.equals(accountBelong)) {
     		// 如果是运维系统的账号,accountType为0的情况下查询所有菜单权限,其余情况走表关联查询,为1时,后续可添加
-    		menuTree = this.saasRoleMenuHandler.querySaasMenuTree(null, null, true, queryVO.isMenu());
+    		menuTree = this.saasRoleMenuHandler.querySaasMenuTree(null, null, queryVO.getAppId(), true, queryVO.isMenu());
     	} else {
-    		menuTree = this.saasRoleMenuHandler.querySaasMenuTree(queryVO.getAccountId(), queryVO.getGroupCode(), false, queryVO.isMenu());
+    		menuTree = this.saasRoleMenuHandler.querySaasMenuTree(queryVO.getAccountId(), queryVO.getGroupCode(), queryVO.getAppId(), false, queryVO.isMenu());
 		}
     	return ResponseResultUtil.successResult(menuTree);
     }

+ 21 - 7
saas-account/src/main/java/com/persagy/person/controller/SaasRoleController.java

@@ -1,5 +1,6 @@
 package com.persagy.person.controller;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import com.persagy.person.pojo.vo.role.*;
@@ -39,9 +40,9 @@ import io.swagger.annotations.ApiOperation;
  * @author zhangqiankun
  * @date 2021-03-13 15:29:50
  */
-
-@Api(tags = "角色信息")
 @RestController
+@Api(tags = "角色信息")
+@SuppressWarnings("unchecked")
 @RequestMapping(value = "/role", method = RequestMethod.POST)
 public class SaasRoleController {
 	
@@ -63,14 +64,14 @@ public class SaasRoleController {
     /**
      * 查询角色信息
      */
-    @ApiOperation(value = "查询角色信息")
+	@ApiOperation(value = "查询角色信息")
     @RequestMapping(value = "querySaasRoleList")
     public ResponseResult querySaasRoleList(@RequestBody @Validated SaasRoleQueryVO queryVO) {
     	LambdaQueryWrapper<SaasRole> queryWrapper = new SaasRole.Builder().createQueryWrapper().idEq(queryVO.getId())
     			.idIn(queryVO.getRoleIds()).roleCodeEq(queryVO.getRoleCode()).roleNameLike(queryVO.getRoleName())
     			.groupCodeEq(queryVO.getGroupCode()).roleTypeEq(queryVO.getRoleType()).roleTypeIn(queryVO.getRoleTypes())
     			.updateUserEq(queryVO.getUpdateUser()).validEq(queryVO.getValid()).builderQueryWrapper();
-    	queryWrapper.orderByDesc(SaasRole::getUpdateTime);		// 默认更新时间降序
+    	queryWrapper.orderByDesc(SaasRole::getUpdateTime, SaasRole::getId);		// 默认更新时间降序
     	List<SaasRole> list = this.saasRoleService.list(queryWrapper);
     	if (CollectionUtil.isEmpty(list)) {
 			return ResponseResultUtil.successResult(Lists.newArrayList(), 0L);
@@ -100,7 +101,7 @@ public class SaasRoleController {
     			.roleCodeEq(pageVO.getRoleCode()).roleNameLike(pageVO.getRoleName()).roleTypeEq(pageVO.getRoleType())
     			.roleTypeIn(pageVO.getRoleTypes()).groupCodeEq(pageVO.getGroupCode()).updateUserEq(pageVO.getUpdateUser())
     			.validEq(pageVO.getValid()).builderQueryWrapper();
-    	queryWrapper.orderByDesc(SaasRole::getUpdateTime);							// 默认更新时间降序
+		queryWrapper.orderByDesc(SaasRole::getUpdateTime, SaasRole::getId);		// 默认更新时间降序
     	Page<SaasRole> pageList = this.saasRoleService.page(page, queryWrapper);
     	if (pageList == null || CollectionUtil.isEmpty(pageList.getRecords())) {
     		return ResponseResultUtil.successResult(Lists.newArrayList(), 0L);
@@ -108,16 +109,29 @@ public class SaasRoleController {
     	// 额外信息补充
     	List<SaasRole> records = pageList.getRecords();
     	// 额外信息补充
-    	if (pageVO.isCountMenu() || pageVO.isCountFunction()) {
-			for (SaasRole saasRole : records) {
+    	List<SaasRole> temp = new ArrayList<SaasRole>(pageVO.getSize());
+    	if (pageVO.isCountMenu() || pageVO.isCountFunction() || (pageVO.isAdminOrder() && pageVO.getPage() == 1)) {
+    		for (int i = records.size() - 1; i >= 0; i--) {
+    			SaasRole saasRole = records.get(i);
 				if (pageVO.isCountFunction()) {
 					saasRole.setCountFunction(this.saasRoleMenuService.countFunction(saasRole.getId(), null));
 				}
 				if (pageVO.isCountMenu()) {
 					saasRole.setCountMenu(this.saasRoleMenuService.countMenu(saasRole.getId()));
 				}
+				// 判断是否要进行业务超管放在第一位
+		    	if (pageVO.isAdminOrder() && pageVO.getPage() == 1) {
+		    		temp.add(saasRole);
+		    		records.remove(i);
+				}
 			}
 		}
+    	if (pageVO.isAdminOrder() && pageVO.getPage() == 1) {
+    		for (SaasRole saasRole : records) {
+    			temp.add(saasRole);
+			}
+    		return ResponseResultUtil.successResult(temp, pageList.getTotal()); 
+    	}
     	return ResponseResultUtil.successResult(records, pageList.getTotal());
     }
 

+ 4 - 3
saas-account/src/main/java/com/persagy/person/manage/SaasRoleMenuHandler.java

@@ -61,18 +61,19 @@ public class SaasRoleMenuHandler {
 	 * 
 	 * @param accountId
 	 * @param groupCode
+	 * @param appId
 	 * @param isAdmin 是否为超管 true-是
 	 * @param isMenu 是否仅查询出菜单树,true-是
 	 * @return 空集合或数据菜单树
 	 */
-	public List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, boolean isAdmin, boolean isMenu) {
+	public List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, String appId, boolean isAdmin, boolean isMenu) {
 		// 1.获取此账号对应菜单集合
 		List<SaasMenu> menuTree = null;
 		if (isAdmin) {
-			LambdaQueryWrapper<SaasMenu> queryWrapper = new SaasMenu.Builder().createQueryWrapper().menuTypeEq(SaasCommonConstant.STR_STATUS_0).builderQueryWrapper();
+			LambdaQueryWrapper<SaasMenu> queryWrapper = new SaasMenu.Builder().createQueryWrapper().appIdEq(appId).menuTypeEq(SaasCommonConstant.STR_STATUS_0).builderQueryWrapper();
 			menuTree = this.saasMenuService.list(queryWrapper);
 		} else {
-			menuTree = this.saasMenuService.querySaasMenuTree(accountId, groupCode, SaasCommonConstant.STATUS_1);
+			menuTree = this.saasMenuService.querySaasMenuTree(accountId, groupCode, appId, SaasCommonConstant.STATUS_1);
 		}
 		if (CollectionUtil.isEmpty(menuTree)) {
 			return Lists.newArrayList();

+ 3 - 1
saas-account/src/main/java/com/persagy/person/mapper/SaasMenuMapper.java

@@ -23,10 +23,12 @@ public interface SaasMenuMapper extends BaseMapper<SaasMenu> {
 	 * 获取菜单树
 	 * @param accountId
 	 * @param groupCode
+	 * @param appId
 	 * @param valid
 	 * @return
 	 */
-	List<SaasMenu> querySaasMenuTree(@Param("accountId") String accountId, @Param("groupCode") String groupCode, @Param("valid") Integer valid);
+	List<SaasMenu> querySaasMenuTree(@Param("accountId") String accountId, @Param("groupCode") String groupCode, 
+			@Param("appId") String appId, @Param("valid") Integer valid);
 	
 	/**
 	 * 查询出此角色下,所有不存在功能点的菜单集合

+ 11 - 7
saas-account/src/main/java/com/persagy/person/pojo/dto/SaasAccount.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
 import com.persagy.common.annotation.IdGeneratorPrefix;
 import com.persagy.common.constant.SaasCommonConstant;
 import com.persagy.common.model.BaseEntity;
@@ -33,7 +34,7 @@ import lombok.ToString;
 @Setter
 @ToString
 @EqualsAndHashCode(callSuper = false)
-@TableName("saas_account")
+@TableName(value = "saas_account", autoResultMap = true)
 @IdGeneratorPrefix(SaasCommonConstant.SAAS_ACCOUNT_ID_PREFIX)
 public class SaasAccount extends BaseEntity<SaasAccount> {
 	private static final long serialVersionUID = 3222916987593249671L;
@@ -41,8 +42,8 @@ public class SaasAccount extends BaseEntity<SaasAccount> {
 	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
 	private String groupCode; // 集团编码
 
-	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
-	private String appId; // 应用ID, PC-电脑端,APP-手机端
+	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY, typeHandler = FastjsonTypeHandler.class)
+	private Set<String> appId; // 应用ID, PC-电脑端,APP-手机端
 
 	@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
 	private String username; // 登录用户名
@@ -113,6 +114,9 @@ public class SaasAccount extends BaseEntity<SaasAccount> {
 	@TableField(exist = false)
 	private List<SaasRole> roles;	//角色集合
 	
+	@TableField(exist = false)
+	private List<SaasMenu> auths;	//菜单权限树集合
+	
 	public static class Builder {
 
 		private LambdaQueryWrapper<SaasAccount> queryWrapper = null;
@@ -162,17 +166,17 @@ public class SaasAccount extends BaseEntity<SaasAccount> {
 			return this;
 		}
 
-		public Builder appIdEq(String appId) {
+		public Builder appIdLike(String appId) {
 			if (StringUtil.isNotBlank(appId)) {
 				if (updateWrapper != null) {
-					updateWrapper.eq(SaasAccount::getAppId, appId);
+					updateWrapper.apply("APP_ID LIKE CONCAT('%', " + appId + ",'%')");
 				} else {
-					queryWrapper.eq(SaasAccount::getAppId, appId);
+					queryWrapper.apply("APP_ID LIKE CONCAT('%', " + appId + ",'%')");
 				}
 			}
 			return this;
 		}
-
+		
 		public Builder usernameEq(String username) {
 			if (StringUtil.isNotBlank(username)) {
 				if (updateWrapper != null) {

+ 3 - 0
saas-account/src/main/java/com/persagy/person/pojo/vo/role/SaasRoleQueryVO.java

@@ -55,6 +55,9 @@ public class SaasRoleQueryVO extends BaseUserModel {
 	@ApiModelProperty(value = "是否统计功能点数量,true-统计,默认false", example = "false")
 	private boolean countFunction = false; // 是否统计功能点数量,true-统计,默认false
 
+	@ApiModelProperty(value = "是否按照超级管理员第一位,其余账号顺延的规则排序,true-是,默认false", example = "false")
+	private boolean adminOrder = false; // 是否按照超级管理员第一位,其余账号顺延的规则排序
+	
 	private Integer valid = SaasCommonConstant.STATUS_1; // 0-不可用,1-可用
 
 }

+ 3 - 1
saas-account/src/main/java/com/persagy/person/service/ISaasMenuService.java

@@ -19,9 +19,11 @@ public interface ISaasMenuService extends ISuperService<SaasMenu> {
 	 * 获取账号菜单集合
 	 * @param accountId
 	 * @param groupCode
+	 * @param appId
+	 * @param valid
 	 * @return
 	 */
-	List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, Integer valid);
+	List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, String appId, Integer valid);
 
 	/**
 	 * 查询出此角色下,所有不存在功能点的菜单集合

+ 2 - 2
saas-account/src/main/java/com/persagy/person/service/impl/SaasAccountServiceImpl.java

@@ -54,7 +54,7 @@ public class SaasAccountServiceImpl extends SuperServiceImpl<SaasAccountMapper,
 		}
 		// 查询出总记录数大小
 		LambdaQueryWrapper<SaasAccount> queryWrapper = new SaasAccount.Builder().createQueryWrapper()
-    			.idEq(saasAccount.getId()).appIdEq(saasAccount.getAppId()).updateUserEq(saasAccount.getUpdateUser())
+    			.idEq(saasAccount.getId()).updateUserEq(saasAccount.getUpdateUser())
     			.groupCodeEq(saasAccount.getGroupCode()).usernameLike(saasAccount.getUsername()).accountTypeEq(saasAccount.getAccountType())
     			.accountSourceEq(saasAccount.getAccountSource()).phoneNumEq(saasAccount.getPhoneNum()).mailEq(saasAccount.getMail())
     			.accountBelongEq(saasAccount.getAccountBelong()).validEq(saasAccount.getValid()).builderQueryWrapper();
@@ -68,7 +68,7 @@ public class SaasAccountServiceImpl extends SuperServiceImpl<SaasAccountMapper,
 	@Override
 	public LambdaQueryWrapper<SaasAccount> getQueryWrapper(SaasAccount saasAccount) {
 		LambdaQueryWrapper<SaasAccount> queryWrapper = new SaasAccount.Builder().createQueryWrapper()
-    			.idEq(saasAccount.getId()).appIdEq(saasAccount.getAppId()).updateUserEq(saasAccount.getUpdateUser())
+    			.idEq(saasAccount.getId()).updateUserEq(saasAccount.getUpdateUser())
     			.groupCodeEq(saasAccount.getGroupCode()).usernameLike(saasAccount.getUsername()).accountTypeEq(saasAccount.getAccountType())
     			.accountSourceEq(saasAccount.getAccountSource()).phoneNumEq(saasAccount.getPhoneNum()).mailEq(saasAccount.getMail())
     			.accountBelongEq(saasAccount.getAccountBelong()).validEq(saasAccount.getValid()).builderQueryWrapper();

+ 2 - 2
saas-account/src/main/java/com/persagy/person/service/impl/SaasMenuServiceImpl.java

@@ -21,8 +21,8 @@ import com.persagy.person.service.ISaasMenuService;
 public class SaasMenuServiceImpl extends SuperServiceImpl<SaasMenuMapper, SaasMenu> implements ISaasMenuService {
 	
 	@Override
-	public List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, Integer valid) {
-		return this.baseMapper.querySaasMenuTree(accountId, groupCode, valid);
+	public List<SaasMenu> querySaasMenuTree(String accountId, String groupCode, String appId, Integer valid) {
+		return this.baseMapper.querySaasMenuTree(accountId, groupCode, appId, valid);
 	}
 
 	@Override

+ 3 - 2
saas-account/src/main/resources/mapper/SaasAccountMapper.xml

@@ -6,7 +6,8 @@
 	<resultMap id="BaseResultMap" type="com.persagy.person.pojo.dto.SaasAccount">
 		<result column="ID" property="id" jdbcType="VARCHAR" />
 		<result column="GROUP_CODE" property="groupCode" jdbcType="VARCHAR" />
-		<result column="APP_ID" property="appId" jdbcType="VARCHAR" />
+		<result column="APP_ID" property="appId" 
+			typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler" />
 		<result column="USERNAME" property="username" jdbcType="VARCHAR" />
 		<result column="PASSWORD" property="password" jdbcType="VARCHAR" />
 		<result column="PHONE_NUM" property="phoneNum" jdbcType="VARCHAR" />
@@ -52,7 +53,7 @@
 		</where>) M LEFT JOIN (SELECT GROUP_CODE, GROUP_NAME FROM saas_group
 		<where>
 			<if test="account.groupCode != null and account.groupCode.trim().length() != 0">AND GROUP_CODE = #{account.groupCode}</if>
-		</where>) N ON M.GROUP_CODE = N.GROUP_CODE ORDER BY M.UPDATE_TIME DESC 
+		</where>) N ON M.GROUP_CODE = N.GROUP_CODE ORDER BY M.UPDATE_TIME DESC, M.ID DESC 
 		<if test="startRow != null and size != null">LIMIT #{startRow}, #{size} </if>
 	</select>
 	

+ 4 - 1
saas-account/src/main/resources/mapper/SaasMenuMapper.xml

@@ -44,7 +44,10 @@
 			<if test="groupCode != null and groupCode.trim().length() != 0">AND GROUP_CODE = #{groupCode}</if>
 		</where>) S ON M.ROLE_ID = S.ROLE_ID) P
 		JOIN (SELECT ID AS MENU_ID, PARENT_ID, APP_ID, MENU_CODE, MENU_NAME, MENU_URL, URL_TYPE, MENU_ICON, MENU_SORT, MENU_TYPE, REMARK 
-			FROM saas_menu) Q ON P.MENU_ID = Q.MENU_ID ORDER BY Q.MENU_SORT
+			FROM saas_menu
+		<where>
+			<if test="appId != null and appId.trim().length() != 0">AND APP_ID = #{appId}</if>
+		</where>) Q ON P.MENU_ID = Q.MENU_ID ORDER BY Q.MENU_SORT
 	</select>
 	
 	<!-- 查询出此角色下,所有不存在功能点的菜单集合 -->