Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/master' into master

# Conflicts:
#	blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java
yangyj 2 rokov pred
rodič
commit
9a6ff45cd1
35 zmenil súbory, kde vykonal 945 pridanie a 677 odobranie
  1. 38 2
      blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
  2. 142 140
      blade-auth/src/main/java/org/springblade/auth/utils/TokenUtil.java
  3. 4 0
      blade-common/src/main/java/org/springblade/common/constant/CommonConstant.java
  4. 28 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/sms/SmsBuilder.java
  5. 8 2
      blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewISmsClientImpl.java
  6. 2 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java
  7. 5 0
      blade-service-api/blade-system-api/pom.xml
  8. 5 4
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java
  9. 16 0
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/RoleAndMenusVO.java
  10. 4 4
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/enums/UserEnum.java
  11. 118 0
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/TreeNodeVO.java
  12. 2 0
      blade-service/blade-business/src/main/java/org/springblade/BusinessApplication.java
  13. 24 21
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  14. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  15. 18 12
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  16. 1 4
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java
  17. 24 8
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/LinkdataInfoController.java
  18. 8 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java
  19. 71 38
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  20. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsFormElementController.java
  21. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java
  22. 22 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  23. 0 162
      blade-service/blade-manager/src/main/java/org/springblade/manager/excel/WbsExcelUtil.java
  24. 23 16
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  25. 7 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  26. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  27. 28 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  28. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  29. 40 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  30. 6 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  31. 25 10
      blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java
  32. 16 8
      blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.java
  33. 12 3
      blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml
  34. 9 4
      blade-service/blade-system/src/main/java/org/springblade/system/service/IMenuService.java
  35. 230 207
      blade-service/blade-system/src/main/java/org/springblade/system/service/impl/MenuServiceImpl.java

+ 38 - 2
blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java

@@ -114,7 +114,7 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
         } else if (userType.equals(UserEnum.APP.getName())) {
             result = userClient.userInfo(tenantId, username, UserEnum.APP.getName());
         } else {
-            result = userClient.userInfo(tenantId, username, UserEnum.OTHER.getName());
+            result = userClient.userInfo(tenantId, username, UserEnum.ALL.getName());
         }
 
         // 判断返回信息
@@ -141,6 +141,16 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
             if (Func.isEmpty(userInfo.getRoles())) {
                 throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_ROLE);
             }
+
+            /*校验登陆账号权限,客户端登陆userType=1,app端登陆userType=2,全部端均可登陆userType=3*/
+            if (user.getUserType().equals(1) || user.getUserType().equals(2) || user.getUserType().equals(3)) {
+                if (!user.getUserType().equals(3)) {
+                    this.judgeLoginPermission(user);
+                }
+            } else {
+                throw new UserDeniedAuthorizationException(TokenUtil.USER_ACCOUNT_NO_TYPE);
+            }
+
             // 多部门情况下指定单部门
             if (Func.isNotEmpty(headerDept) && user.getDeptId().contains(headerDept)) {
                 user.setDeptId(headerDept);
@@ -155,7 +165,7 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
             }
             // 成功则清除登录错误次数
             delFailCount(tenantId, username);
-            return new BladeUserDetails(user.getId(),user.getPhone(),
+            return new BladeUserDetails(user.getId(), user.getPhone(),
                     user.getTenantId(), StringPool.EMPTY, user.getName(), user.getRealName(), user.getDeptId(), user.getPostId(), user.getRoleId(), Func.join(userInfo.getRoles()), Func.toStr(user.getAvatar(), TokenUtil.DEFAULT_AVATAR),
                     username, AuthConstant.ENCRYPT + user.getPassword(), userInfo.getDetail(), true, true, true, true,
                     AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result.getData().getRoles())));
@@ -214,5 +224,31 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
         return true;
     }
 
+    /**
+     * 校验登陆账号权限
+     *
+     * @param user user信息
+     */
+    private void judgeLoginPermission(User user) {
+        String clientId = TokenUtil.getClientIdFromHeader();
+        Integer result = 0;
+        if (clientId != null) {
+            switch (clientId) {
+                case "client":
+                    result = 1; //WEB=客户端
+                    break;
+                case "app":
+                    result = 2; //APP=APP端
+                    break;
+                case "saber":
+                    result = 3; //OTHER=后管
+                    break;
+            }
+        }
+        if (!result.equals(user.getUserType())) {
+            throw new UserDeniedAuthorizationException(TokenUtil.USER_ACCOUNT_NO_PERMISSION);
+        }
+    }
+
 
 }

+ 142 - 140
blade-auth/src/main/java/org/springblade/auth/utils/TokenUtil.java

@@ -39,145 +39,147 @@ import java.util.Date;
  */
 public class TokenUtil {
 
-	public final static String AVATAR = TokenConstant.AVATAR;
-	public final static String ACCOUNT = TokenConstant.ACCOUNT;
-	public final static String USER_NAME = TokenConstant.USER_NAME;
-	public final static String NICK_NAME = TokenConstant.NICK_NAME;
-	public final static String REAL_NAME = TokenConstant.REAL_NAME;
-	public final static String USER_ID = TokenConstant.USER_ID;
-	public final static String DEPT_ID = TokenConstant.DEPT_ID;
-	public final static String POST_ID = TokenConstant.POST_ID;
-	public final static String ROLE_ID = TokenConstant.ROLE_ID;
-	public final static String ROLE_NAME = TokenConstant.ROLE_NAME;
-	public final static String TENANT_ID = TokenConstant.TENANT_ID;
-	public final static String OAUTH_ID = TokenConstant.OAUTH_ID;
-	public final static String CLIENT_ID = TokenConstant.CLIENT_ID;
-	public final static String DETAIL = TokenConstant.DETAIL;
-	public final static String LICENSE = TokenConstant.LICENSE;
-	public final static String LICENSE_NAME = TokenConstant.LICENSE_NAME;
-
-	public final static String DEPT_HEADER_KEY = "Dept-Id";
-	public final static String ROLE_HEADER_KEY = "Role-Id";
-	public final static String CAPTCHA_HEADER_KEY = "Captcha-Key";
-	public final static String CAPTCHA_HEADER_CODE = "Captcha-Code";
-	public final static String CAPTCHA_NOT_CORRECT = "验证码不正确";
-	public final static String TENANT_HEADER_KEY = "Tenant-Id";
-	public final static String TENANT_PARAM_KEY = "tenant_id";
-	public final static String DEFAULT_TENANT_ID = "000000";
-	public final static String TENANT_NOT_FOUND = "租户ID未找到";
-	public final static String USER_TYPE_HEADER_KEY = "User-Type";
-	public final static String DEFAULT_USER_TYPE = "web";
-	public final static String TOKEN_NOT_PERMISSION = "令牌授权已过期";
-	public final static String USER_NOT_FOUND = "用户名或密码错误";
-	public final static String USER_HAS_NO_ROLE = "未获得用户的角色信息";
-	public final static String USER_HAS_NO_TENANT = "未获得用户的租户信息";
-	public final static String USER_HAS_NO_TENANT_PERMISSION = "租户授权已过期,请联系管理员";
-	public final static String USER_HAS_TOO_MANY_FAILS = "登录错误次数过多,请稍后再试";
-	public final static String HEADER_KEY = "Authorization";
-	public final static String HEADER_PREFIX = "Basic ";
-	public final static String DEFAULT_AVATAR = "";
-	public final static String PASSWORD_KEY = "password";
-	public final static String GRANT_TYPE_KEY = "grant_type";
-	public final static String REFRESH_TOKEN_KEY = "refresh_token";
-	public final static String USER_STATUS_BAN = "该用户被封禁,请联系管理员";
-
-	private static BladeTenantProperties tenantProperties;
-
-	/**
-	 * 获取租户配置
-	 *
-	 * @return tenantProperties
-	 */
-	private static BladeTenantProperties getTenantProperties() {
-		if (tenantProperties == null) {
-			tenantProperties = SpringUtil.getBean(BladeTenantProperties.class);
-		}
-		return tenantProperties;
-	}
-
-	/**
-	 * 解码
-	 */
-	@SneakyThrows
-	public static String[] extractAndDecodeHeader() {
-		String header = WebUtil.getRequest().getHeader(TokenUtil.HEADER_KEY);
-		if (header == null || !header.startsWith(TokenUtil.HEADER_PREFIX)) {
-			throw new UnapprovedClientAuthenticationException("请求头中无client信息");
-		}
-
-		byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
-
-		byte[] decoded;
-		try {
-			decoded = Base64.getDecoder().decode(base64Token);
-		} catch (IllegalArgumentException var7) {
-			throw new BadCredentialsException("Failed to decode basic authentication token");
-		}
-
-		String token = new String(decoded, Charsets.UTF_8_NAME);
-		int index = token.indexOf(StringPool.COLON);
-		if (index == -1) {
-			throw new BadCredentialsException("Invalid basic authentication token");
-		} else {
-			return new String[]{token.substring(0, index), token.substring(index + 1)};
-		}
-	}
-
-	/**
-	 * 获取请求头中的客户端id
-	 */
-	public static String getClientIdFromHeader() {
-		String[] tokens = extractAndDecodeHeader();
-		return tokens[0];
-	}
-
-	/**
-	 * 获取token过期时间(次日凌晨3点)
-	 *
-	 * @return expire
-	 */
-	public static int getTokenValiditySecond() {
-		Calendar cal = Calendar.getInstance();
-		cal.add(Calendar.DAY_OF_YEAR, 1);
-		cal.set(Calendar.HOUR_OF_DAY, 3);
-		cal.set(Calendar.SECOND, 0);
-		cal.set(Calendar.MINUTE, 0);
-		cal.set(Calendar.MILLISECOND, 0);
-		return (int) (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
-	}
-
-	/**
-	 * 获取refreshToken过期时间
-	 *
-	 * @return expire
-	 */
-	public static int getRefreshTokenValiditySeconds() {
-		return 60 * 60 * 24 * 15;
-	}
-
-	/**
-	 * 判断租户权限
-	 *
-	 * @param tenant 租户信息
-	 * @return boolean
-	 */
-	public static boolean judgeTenant(Tenant tenant) {
-		if (tenant == null || tenant.getId() == null) {
-			throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_TENANT);
-		}
-		if (StringUtil.equalsIgnoreCase(tenant.getTenantId(), BladeConstant.ADMIN_TENANT_ID)) {
-			return false;
-		}
-		Date expireTime = tenant.getExpireTime();
-		if (getTenantProperties().getLicense()) {
-			String licenseKey = tenant.getLicenseKey();
-			String decrypt = DesUtil.decryptFormHex(licenseKey, TenantConstant.DES_KEY);
-			expireTime = JsonUtil.parse(decrypt, Tenant.class).getExpireTime();
-		}
-		if (expireTime != null && expireTime.before(DateUtil.now())) {
-			throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);
-		}
-		return false;
-	}
+    public final static String AVATAR = TokenConstant.AVATAR;
+    public final static String ACCOUNT = TokenConstant.ACCOUNT;
+    public final static String USER_NAME = TokenConstant.USER_NAME;
+    public final static String NICK_NAME = TokenConstant.NICK_NAME;
+    public final static String REAL_NAME = TokenConstant.REAL_NAME;
+    public final static String USER_ID = TokenConstant.USER_ID;
+    public final static String DEPT_ID = TokenConstant.DEPT_ID;
+    public final static String POST_ID = TokenConstant.POST_ID;
+    public final static String ROLE_ID = TokenConstant.ROLE_ID;
+    public final static String ROLE_NAME = TokenConstant.ROLE_NAME;
+    public final static String TENANT_ID = TokenConstant.TENANT_ID;
+    public final static String OAUTH_ID = TokenConstant.OAUTH_ID;
+    public final static String CLIENT_ID = TokenConstant.CLIENT_ID;
+    public final static String DETAIL = TokenConstant.DETAIL;
+    public final static String LICENSE = TokenConstant.LICENSE;
+    public final static String LICENSE_NAME = TokenConstant.LICENSE_NAME;
+
+    public final static String DEPT_HEADER_KEY = "Dept-Id";
+    public final static String ROLE_HEADER_KEY = "Role-Id";
+    public final static String CAPTCHA_HEADER_KEY = "Captcha-Key";
+    public final static String CAPTCHA_HEADER_CODE = "Captcha-Code";
+    public final static String CAPTCHA_NOT_CORRECT = "验证码不正确";
+    public final static String TENANT_HEADER_KEY = "Tenant-Id";
+    public final static String TENANT_PARAM_KEY = "tenant_id";
+    public final static String DEFAULT_TENANT_ID = "000000";
+    public final static String TENANT_NOT_FOUND = "租户ID未找到";
+    public final static String USER_TYPE_HEADER_KEY = "User-Type";
+    public final static String DEFAULT_USER_TYPE = "web";
+    public final static String TOKEN_NOT_PERMISSION = "令牌授权已过期";
+    public final static String USER_NOT_FOUND = "用户名或密码错误";
+    public final static String USER_HAS_NO_ROLE = "未获得用户的角色信息";
+    public final static String USER_HAS_NO_TENANT = "未获得用户的租户信息";
+    public final static String USER_HAS_NO_TENANT_PERMISSION = "租户授权已过期,请联系管理员";
+    public final static String USER_HAS_TOO_MANY_FAILS = "登录错误次数过多,请稍后再试";
+    public final static String HEADER_KEY = "Authorization";
+    public final static String HEADER_PREFIX = "Basic ";
+    public final static String DEFAULT_AVATAR = "";
+    public final static String PASSWORD_KEY = "password";
+    public final static String GRANT_TYPE_KEY = "grant_type";
+    public final static String REFRESH_TOKEN_KEY = "refresh_token";
+    public final static String USER_STATUS_BAN = "该用户账号被封禁,请联系管理员";
+    public final static String USER_ACCOUNT_NO_PERMISSION = "该用户账号没有对应权限,请联系管理员";
+    public final static String USER_ACCOUNT_NO_TYPE = "该账号的用户类型分配异常,请联系管理员";
+
+    private static BladeTenantProperties tenantProperties;
+
+    /**
+     * 获取租户配置
+     *
+     * @return tenantProperties
+     */
+    private static BladeTenantProperties getTenantProperties() {
+        if (tenantProperties == null) {
+            tenantProperties = SpringUtil.getBean(BladeTenantProperties.class);
+        }
+        return tenantProperties;
+    }
+
+    /**
+     * 解码
+     */
+    @SneakyThrows
+    public static String[] extractAndDecodeHeader() {
+        String header = WebUtil.getRequest().getHeader(TokenUtil.HEADER_KEY);
+        if (header == null || !header.startsWith(TokenUtil.HEADER_PREFIX)) {
+            throw new UnapprovedClientAuthenticationException("请求头中无client信息");
+        }
+
+        byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
+
+        byte[] decoded;
+        try {
+            decoded = Base64.getDecoder().decode(base64Token);
+        } catch (IllegalArgumentException var7) {
+            throw new BadCredentialsException("Failed to decode basic authentication token");
+        }
+
+        String token = new String(decoded, Charsets.UTF_8_NAME);
+        int index = token.indexOf(StringPool.COLON);
+        if (index == -1) {
+            throw new BadCredentialsException("Invalid basic authentication token");
+        } else {
+            return new String[]{token.substring(0, index), token.substring(index + 1)};
+        }
+    }
+
+    /**
+     * 获取请求头中的客户端id
+     */
+    public static String getClientIdFromHeader() {
+        String[] tokens = extractAndDecodeHeader();
+        return tokens[0];
+    }
+
+    /**
+     * 获取token过期时间(次日凌晨3点)
+     *
+     * @return expire
+     */
+    public static int getTokenValiditySecond() {
+        Calendar cal = Calendar.getInstance();
+        cal.add(Calendar.DAY_OF_YEAR, 1);
+        cal.set(Calendar.HOUR_OF_DAY, 3);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return (int) (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
+    }
+
+    /**
+     * 获取refreshToken过期时间
+     *
+     * @return expire
+     */
+    public static int getRefreshTokenValiditySeconds() {
+        return 60 * 60 * 24 * 15;
+    }
+
+    /**
+     * 判断租户权限
+     *
+     * @param tenant 租户信息
+     * @return boolean
+     */
+    public static boolean judgeTenant(Tenant tenant) {
+        if (tenant == null || tenant.getId() == null) {
+            throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_TENANT);
+        }
+        if (StringUtil.equalsIgnoreCase(tenant.getTenantId(), BladeConstant.ADMIN_TENANT_ID)) {
+            return false;
+        }
+        Date expireTime = tenant.getExpireTime();
+        if (getTenantProperties().getLicense()) {
+            String licenseKey = tenant.getLicenseKey();
+            String decrypt = DesUtil.decryptFormHex(licenseKey, TenantConstant.DES_KEY);
+            expireTime = JsonUtil.parse(decrypt, Tenant.class).getExpireTime();
+        }
+        if (expireTime != null && expireTime.before(DateUtil.now())) {
+            throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION);
+        }
+        return false;
+    }
 
 }

+ 4 - 0
blade-common/src/main/java/org/springblade/common/constant/CommonConstant.java

@@ -62,6 +62,10 @@ public interface CommonConstant {
 
 	String SYS_USER_TASK_BATCH = "sys.user.task.batch";
 
+	String JL_THE_LOG = "JL.theLog";
+
+	String SG_THE_LOG = "SG.theLog";
+
 	/**
 	 * 默认排序字段
 	 */

+ 28 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/sms/SmsBuilder.java

@@ -112,6 +112,34 @@ public class SmsBuilder {
 		return template;
 	}
 
+	public SmsTemplate template(Sms sms) {
+		String tenantId = AuthUtil.getTenantId();
+		Sms smsCached = smsPool.get(tenantId);
+		SmsTemplate template = templatePool.get(tenantId);
+		// 若为空或者不一致,则重新加载
+		if (Func.hasEmpty(template, smsCached) ||
+				!sms.getTemplateId().equals(smsCached.getTemplateId()) ||
+				!sms.getAccessKey().equals(smsCached.getAccessKey()) ||
+				!sms.getSignName().equals(smsCached.getSignName())) {
+			synchronized (SmsBuilder.class) {
+				template = templatePool.get(tenantId);
+
+				if (sms.getCategory() == SmsEnum.YUNPIAN.getCategory()) {
+					template = YunpianSmsBuilder.template(sms, bladeRedis);
+				} else if (sms.getCategory() == SmsEnum.QINIU.getCategory()) {
+					template = QiniuSmsBuilder.template(sms, bladeRedis);
+				} else if (sms.getCategory() == SmsEnum.TENCENT.getCategory()) {
+					template = TencentSmsBuilder.template(sms, bladeRedis);
+				} else if (sms.getCategory() == SmsEnum.ALI.getCategory()) {
+					//阿里云
+					template = AliSmsBuilder.template(sms, bladeRedis);
+				}
+				templatePool.put(tenantId, template);
+				smsPool.put(tenantId, sms);
+			}
+		}
+		return template;
+	}
 
 	/**
 	 * 获取短信实体

+ 8 - 2
blade-ops/blade-resource/src/main/java/org/springblade/resource/feign/NewISmsClientImpl.java

@@ -1,6 +1,8 @@
 package org.springblade.resource.feign;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import org.springblade.core.sms.SmsTemplate;
 import org.springblade.core.sms.model.SmsData;
 import org.springblade.core.sms.model.SmsResponse;
 import org.springblade.core.tenant.annotation.NonDS;
@@ -8,6 +10,8 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.jackson.JsonUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.resource.builder.sms.SmsBuilder;
+import org.springblade.resource.entity.Sms;
+import org.springblade.resource.service.ISmsService;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -18,11 +22,13 @@ public class NewISmsClientImpl implements NewISmsClient {
 
     private final SmsBuilder smsBuilder;
 
+    private final ISmsService smsService;
+
     @Override
     @PostMapping(SEND_MESSAGE)
     public R<SmsResponse> sendMessage(String code, String params, String phones) {
         SmsData smsData = new SmsData(JsonUtil.readMap(params, String.class, String.class));
-        SmsResponse response = smsBuilder.template(code).sendMessage(smsData, Func.toStrList(phones));
-        return R.data(response);
+        return R.data(this.smsBuilder.template(this.smsService.getOne(Wrappers.<Sms>lambdaQuery().eq(Sms::getSmsCode, code))).sendMessage(smsData, Func.toStrList(phones)));
     }
+
 }

+ 2 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContract.java

@@ -189,7 +189,8 @@ public class WbsTreeContract extends BaseEntity {
     /**
      * 用户端是否隐藏
      */
-    @ApiModelProperty(value = "用户端是否隐藏")
+
+    @ApiModelProperty(name = "is_buss_show", value = "is_buss_show")
     private Integer isBussShow;
 
 

+ 5 - 0
blade-service-api/blade-system-api/pom.xml

@@ -24,6 +24,11 @@
             <artifactId>blade-dict-api</artifactId>
             <version>2.9.1.RELEASE</version>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-user-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 5 - 4
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java

@@ -2,6 +2,7 @@ package org.springblade.system.vo;
 
 import lombok.Data;
 import org.springblade.core.tool.node.TreeNode;
+import org.springblade.system.user.vo.TreeNodeVO;
 
 import java.io.Serializable;
 import java.util.List;
@@ -16,16 +17,16 @@ public class GrantTreeVO implements Serializable {
 	private static final long serialVersionUID = 1L;
 
 	//后管
-	private List<TreeNode> menu;
+	private List<TreeNodeVO> menu;
 
 	//客户端
-	private List<TreeNode> usermenu;
+	private List<TreeNodeVO> usermenu;
 
 	//数据
-	private List<TreeNode> dataScope;
+	private List<TreeNodeVO> dataScope;
 
 	//api
-	private List<TreeNode> apiScope;
+	private List<TreeNodeVO> apiScope;
 
 	//表单
 	private List<DictVO02> tableOwners;

+ 16 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/RoleAndMenusVO.java

@@ -0,0 +1,16 @@
+package org.springblade.system.vo;
+
+import lombok.Data;
+import java.io.Serializable;
+
+@Data
+public class RoleAndMenusVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private Long menuId;
+
+    private Long roleId;
+
+}

+ 4 - 4
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/enums/UserEnum.java

@@ -29,19 +29,19 @@ import lombok.Getter;
 public enum UserEnum {
 
 	/**
-	 * web
+	 * web客户端
 	 */
 	WEB("web", 1),
 
 	/**
-	 * app
+	 * app
 	 */
 	APP("app", 2),
 
 	/**
-	 * other
+	 * all全部端
 	 */
-	OTHER("other", 3),
+	ALL("all", 3),
 	;
 
 	final String name;

+ 118 - 0
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/TreeNodeVO.java

@@ -0,0 +1,118 @@
+package org.springblade.system.user.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+import org.springblade.core.tool.node.BaseNode;
+
+@Data
+public class TreeNodeVO extends BaseNode<TreeNodeVO> {
+    private static final long serialVersionUID = 1L;
+    private String title;
+    @JsonSerialize(
+        using = ToStringSerializer.class
+    )
+    private Long key;
+    @JsonSerialize(
+        using = ToStringSerializer.class
+    )
+    private Long value;
+
+    private Long sysId;
+
+    public TreeNodeVO() {
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    public Long getKey() {
+        return this.key;
+    }
+
+    public Long getValue() {
+        return this.value;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public void setKey(final Long key) {
+        this.key = key;
+    }
+
+    public void setValue(final Long value) {
+        this.value = value;
+    }
+
+    public String toString() {
+        return "TreeNode(title=" + this.getTitle() + ", key=" + this.getKey() + ", value=" + this.getValue() + ")";
+    }
+
+    public boolean equals(final Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof TreeNodeVO)) {
+            return false;
+        } else {
+            TreeNodeVO other = (TreeNodeVO)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                label47: {
+                    Object this$key = this.getKey();
+                    Object other$key = other.getKey();
+                    if (this$key == null) {
+                        if (other$key == null) {
+                            break label47;
+                        }
+                    } else if (this$key.equals(other$key)) {
+                        break label47;
+                    }
+
+                    return false;
+                }
+
+                Object this$value = this.getValue();
+                Object other$value = other.getValue();
+                if (this$value == null) {
+                    if (other$value != null) {
+                        return false;
+                    }
+                } else if (!this$value.equals(other$value)) {
+                    return false;
+                }
+
+                Object this$title = this.getTitle();
+                Object other$title = other.getTitle();
+                if (this$title == null) {
+                    if (other$title != null) {
+                        return false;
+                    }
+                } else if (!this$title.equals(other$title)) {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    protected boolean canEqual(final Object other) {
+        return other instanceof TreeNodeVO;
+    }
+
+    public int hashCode() {
+        boolean PRIME = true;
+        int result = 1;
+        Object $key = this.getKey();
+        result = result * 59 + ($key == null ? 43 : $key.hashCode());
+        Object $value = this.getValue();
+        result = result * 59 + ($value == null ? 43 : $value.hashCode());
+        Object $title = this.getTitle();
+        result = result * 59 + ($title == null ? 43 : $title.hashCode());
+        return result;
+    }
+}

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/BusinessApplication.java

@@ -4,10 +4,12 @@ import org.springblade.common.constant.BusinessConstant;
 import org.springblade.core.cloud.feign.EnableBladeFeign;
 import org.springblade.core.launch.BladeApplication;
 import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
 
 /**
  * 客户端启动类
  */
+@EnableAsync
 @EnableBladeFeign
 @SpringCloudApplication
 public class BusinessApplication {

+ 24 - 21
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -252,8 +252,8 @@ public class TaskController extends BladeController {
 
 				taskApprovalVOS.add(approvalVO);
 			}
-
-			return R.data(this.taskService.batchCompleteApprovalTask(taskApprovalVOS));
+			this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
+			return R.data(true);
 		}
 		return R.data(false);
 	}
@@ -301,7 +301,7 @@ public class TaskController extends BladeController {
 		//获取已办(基于原生已办)
 		R<Object> rObject = this.newFlowClient.selectDonePage(queryVO.getCurrent(), queryVO.getSize(), String.join(",", parallelProcessInstanceIds));
 		//处理参数
-		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap);
+		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, false);
 	}
 
 	/**
@@ -335,7 +335,7 @@ public class TaskController extends BladeController {
 		//获取待办(基于原生待办)
 		R<Object> rObject = this.newFlowClient.selectTodoPage(queryVO.getCurrent(), queryVO.getSize(), String.join(",", parallelProcessInstanceIds));
 		//处理参数
-		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap);
+		return this.integrationMethod(queryVO, rObject, masterTaskMap, parallelMap, true);
 	}
 
 	/**
@@ -390,7 +390,7 @@ public class TaskController extends BladeController {
 	/**
 	 * 统合处理方法
 	 */
-	private R<IPage<TaskVO>> integrationMethod(TaskQueryVO queryVO, R<Object> rObject, Map<String,Task> masterTaskMap, Map<String,TaskParallel> parallelMap){
+	private R<IPage<TaskVO>> integrationMethod(TaskQueryVO queryVO, R<Object> rObject, Map<String,Task> masterTaskMap, Map<String,TaskParallel> parallelMap, boolean isToDo){
 		Query query = new Query();
 		query.setCurrent(queryVO.getCurrent());
 		query.setSize(queryVO.getSize());
@@ -434,18 +434,23 @@ public class TaskController extends BladeController {
 					}
 				});
 
-				//result是一个总的集合,需要手动进行分组分页
-				List<List<TaskVO>> groupResult = CommonUtil.getBatchSize(finalResult, query.getSize());
-				//获取当前页数据
-				List<TaskVO> finalFlowList;
-				if(groupResult.size() > 0){
-					finalFlowList = groupResult.get(query.getCurrent() - 1);
-				} else {
-					finalFlowList = new ArrayList<>();
-				}
-
-				//最终分页数据
-				return this.getIPageR(query, flowIPage, finalFlowList);
+//				//待办的原生方法并没有对数据做分页,所以需要在这里进行手动分页,而已办的原生方法已经做了分页处理
+//				if(!isToDo){
+//					//result是一个总的集合,需要手动进行分组分页
+//					List<List<TaskVO>> groupResult = CommonUtil.getBatchSize(finalResult, query.getSize());
+//					//获取当前页数据
+//					List<TaskVO> finalFlowList;
+//					if(groupResult.size() > 0){
+//						finalFlowList = groupResult.get(query.getCurrent() - 1);
+//					} else {
+//						finalFlowList = new ArrayList<>();
+//					}
+//					//最终分页数据
+//					return this.getIPageR(query, flowIPage, finalFlowList);
+//				} else {
+					//最终分页数据
+					return this.getIPageR(query, flowIPage, finalResult);
+//				}
 			}
 		}
 		return R.data(null);
@@ -489,10 +494,8 @@ public class TaskController extends BladeController {
 			//生成等待批次,任务完成后删除
 			List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
 			taskApprovalVOS.add(taskApprovalVO);
-
-			this.taskBatchService.save(new TaskBatch(taskApprovalVO.getParallelProcessInstanceId(), JSONObject.toJSONString(taskApprovalVOS)));
-
-			return R.data(this.taskService.batchCompleteApprovalTask(taskApprovalVOS));
+			this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
+			return R.data(true, "提交成功");
 		}
 	}
 

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java

@@ -48,7 +48,7 @@ public interface ITaskService extends BaseService<Task> {
     /**
      * 批量审批
      */
-    Boolean batchCompleteApprovalTask(List<TaskApprovalVO> taskApprovalVOS);
+    void batchCompleteApprovalTask(List<TaskApprovalVO> taskApprovalVOS);
 
     /**
      * 启动流程

+ 18 - 12
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -42,6 +42,7 @@ import org.springblade.manager.feign.ProjectClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -153,7 +154,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
          return taskApprovalVO;
      }
 
-     @Override
+    @Override
     public TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO) {
         switch (taskApprovalVO.getApprovalType()){
             case 1:
@@ -282,33 +283,35 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return this.baseMapper.queryBatchList(projectId, contract);
     }
 
+    @Async
     @Override
-    public Boolean batchCompleteApprovalTask(List<TaskApprovalVO> taskApprovalVOS) {
+    public void batchCompleteApprovalTask(List<TaskApprovalVO> taskApprovalVOS) {
+        List<String> taskIds = taskApprovalVOS.stream().map(TaskApprovalVO::getParallelProcessInstanceId).distinct().collect(Collectors.toList());
+
         long batch = this.taskBatchService.count(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getCreateUser, AuthUtil.getUserId()));
         if(batch > 0){
-            List<String> taskIds = taskApprovalVOS.stream().map(TaskApprovalVO::getParallelProcessInstanceId).distinct().collect(Collectors.toList());
-
             //修改电签状态
             this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
                     .set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
                     .in(TaskParallel::getParallelProcessInstanceId, taskIds));
             //保存批次
             this.taskBatchService.save(new TaskBatch(null, JSONObject.toJSONString(taskApprovalVOS)));
-
-            return true;
         } else {
+            //修改电签状态
+            this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                    .set(TaskParallel::getEVisaContent, "正在电签,请稍后查看........")
+                    .in(TaskParallel::getParallelProcessInstanceId, taskIds));
+
             //保存批次
             TaskBatch taskBatch = new TaskBatch(null, JSONObject.toJSONString(taskApprovalVOS));
             this.taskBatchService.save(taskBatch);
 
             //执行电签,结束后检查在执行是否有新的等待批次
             this.checkIsExsitTaskBatch(taskApprovalVOS, taskBatch.getId().toString());
-            return true;
         }
     }
 
-    @Async
-    public void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId){
+    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId){
         boolean isContinue = true;
         while (isContinue){
             logger.info("【任务审核】当前批次开始电签。批次ID:" + batchId);
@@ -748,7 +751,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 施工日志等
      */
-    private void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    @Transactional
+    public void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
         this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status)
                 .set(ContractLog::getEVisaPdfUrl, newFileUrl)
                 .set(ContractLog::getAuditUserIdAndName, null)
@@ -761,7 +765,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 资料填报
      */
-    private void updateWriteBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    @Transactional
+    public void updateWriteBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
         this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, status)
                 .set(InformationQuery::getEVisaPdfUrl, newFileUrl)
                 .set(InformationQuery::getReportNumber, null)
@@ -774,7 +779,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 工程文件
      */
-    private void updateArchiveFileBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    @Transactional
+    public void updateArchiveFileBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
         LambdaUpdateWrapper<ArchiveFile> wrapper = Wrappers.lambdaUpdate();
         //更改状态,更改电签文件信息
         wrapper.set(ArchiveFile::getStatus, status)

+ 1 - 4
blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java

@@ -1469,6 +1469,7 @@ public class StringUtils {
 		return max;
 	}
 
+
 	/**
 	 * @Description 公式脚本转义
 	 * @Param [f]
@@ -1488,9 +1489,5 @@ public class StringUtils {
 		return f;
 	}
 
-	public static void main(String[] args) {
-		String f= "FC.join(E['m_20220922155211_1572856268366807040:key_3'],\"\")";
-		System.out.println(escapeFormula(f));
-	}
 
 }

+ 24 - 8
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/LinkdataInfoController.java

@@ -188,15 +188,31 @@ public class LinkdataInfoController extends BladeController {
 		}else{
 			// 获取元素基本信息
 			WbsFormElement wbsFormElement = wbsFormElementService.getById(linkdataInfo.getHtmlType());
-			String enName = wbsFormElement.getEName().replaceAll("[^\u4E00-\u9FA5_]", "");
+			String enName = wbsFormElement.getEName();
 			String dataInfo2 =wbsFormElement.getEKey()+"__"+linkdataInfo.getTrIndex()+"_"+linkdataInfo.getTdIndex() ;
-			element.children().get(0)
-					.removeAttr("placeholder").removeAttr("keyName").removeAttr("weighing").removeAttr("v-model").removeAttr("@focus").
-					attr("placeholder",enName)
-					.attr("keyName",dataInfo2)
-					.attr("weighing","100")
-					.attr("v-model","formData."+dataInfo2)
-					.attr("@focus","getInformation('"+enName+"',"+linkdataInfo.getTrIndex()+","+linkdataInfo.getTdIndex()+")");
+			Element element1=element1 = element.children().get(0);
+
+
+
+			if(element.html().indexOf("el-tooltip")>=0){
+				element1.removeAttr("placeholder");
+				element1.removeAttr("keyName");
+				element1.removeAttr("weighing");
+				element1.removeAttr("v-model");
+				element1.removeAttr("@focus");
+				element1 = element.children().get(0).children().get(0);
+			}
+			element1.removeAttr("placeholder");
+			element1.removeAttr("keyName");
+			element1.removeAttr("weighing");
+			element1.removeAttr("v-model");
+			element1.removeAttr("@focus");
+
+			element1.attr("placeholder",enName).attr("keyName",dataInfo2);
+			element1.attr("weighing","100");
+			element1.attr("v-model","formData."+dataInfo2);
+			element1.attr("@focus","getInformation('"+enName+"',"+linkdataInfo.getTrIndex()+","+linkdataInfo.getTdIndex()+")");
+			System.out.println(element1);
 		}
 
 		File writefile = new File(wbsTreePrivate.getHtmlUrl());

+ 8 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java

@@ -87,8 +87,14 @@ public class TableFileController extends BladeController {
 				.eq(WbsTreeContract::getProjectId, wbsTreeContract.getProjectId())
 				.eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
 		);
-
-		excelTabService.getBussPdfs(wbsTreeContractP.getPKeyId()+"",wbsTreeContract.getTableOwner(),wbsTreeContract.getContractId(),wbsTreeContract.getProjectId());
+		String classfy ="1";
+		String dataInfo = wbsTreeContract.getTableOwner();
+		if (dataInfo.equals("1")||dataInfo.equals("2")||dataInfo.equals("3")) {
+			classfy = "1";
+		} else if (dataInfo.equals("4")||dataInfo.equals("5")||dataInfo.equals("6")) {
+			classfy = "2";
+		}
+		excelTabService.getBussPdfs(wbsTreeContractP.getPKeyId()+"",classfy,wbsTreeContract.getContractId(),wbsTreeContract.getProjectId());
 		return R.status(true);
 	}
 

+ 71 - 38
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -27,6 +27,7 @@ import lombok.AllArgsConstructor;
 
 import javax.validation.Valid;
 
+import org.apache.commons.lang.StringUtils;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -57,6 +58,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -147,8 +149,32 @@ public class TextdictInfoController extends BladeController {
 	@PostMapping("/remove")
 	@ApiOperationSupport(order = 7)
 	@ApiOperation(value = "逻辑删除", notes = "传入ids")
-	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String id) {
-        textdictInfoService.deleDataInfoById(id);
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) throws FileNotFoundException {
+
+         TextdictInfo textdictInfo = textdictInfoService.getById(ids);
+        if(textdictInfo.getType()==5){
+            // 获取 节点信息
+            WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(Long.parseLong(textdictInfo.getTabId()));
+
+            // 读取html页面信息
+            File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+            String htmlString = IoUtil.readToString(new FileInputStream(file1));
+            // 样式集合
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Element table = doc.select("table").first();
+            Elements trs = table.select("tr");
+            String trtd[] = textdictInfo.getColKey().split("__");
+            Element element = trs.get(Integer.parseInt(trtd[1].split("_")[0])).select("td").get(Integer.parseInt(trtd[1].split("_")[1]));
+            if(element.html().indexOf("el-tooltip")>=0){
+                Element newele = element.children().get(0).children().get(0);
+                element.empty().append(newele+"");
+                File writefile = new File(wbsTreePrivate.getHtmlUrl());
+                FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+            }
+        }
+
+        textdictInfoService.deleDataInfoById(ids);
 		return R.success("成功");
 	}
 
@@ -184,29 +210,25 @@ public class TextdictInfoController extends BladeController {
         String placeholder = element.children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
         String keyname = element.children().get(0).attr("keyname");
         String weighing = element.children().get(0).attr("weighing");
-
+        System.out.println(y2);
         String parm = trindex + "," + tdindex + "," + x1 + "," + x2 + "," + y1 + "," + y2 + ",$event";
         String oncklickText = "'" + placeholder + "'," + trindex + "," + tdindex;
 
         String vmode = "formData." + keyname;
         if (textdictInfo.getTextId().equals("input")) { // 单选框
             element.empty().append("<el-input type='text' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </el-input>");
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
         } else if (textdictInfo.getTextId().equals("textarea")) { // 文本域
             int rowspan = element.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(element.attr("ROWSPAN"));
-            //@focus='getInformation("+oncklickText+")'
             element.empty().append("<el-input :rows=" + rowspan * 2 + "  type='textarea' placeholder=" + placeholder + " v-model=" + vmode + "    keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'  > </el-input>");
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
         } else if (textdictInfo.getTextId().equals("select")) { // 下拉框
             String selectText = " <el-select v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">"; //v-model="+keyname+"
             List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
             if (optionList != null && optionList.size() >= 1) {
                 for (int i = 0; i < optionList.size(); i++)
-                    selectText += "<el-option  :key='" + i + "' :label='" + optionList.get(i).getDictValue() + "'   :value='" + i + "' > </el-option>";
+                    selectText += "<el-option  key='" + i + "' label='" + optionList.get(i).getDictValue() + "'   value='" + i + "' > </el-option>";
             }
             selectText += "</el-select>";
             element.empty().append(selectText);
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
         } else if (textdictInfo.getTextId().equals("radio")) { // 单选按钮
 
             String radioText = "<template v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
@@ -217,40 +239,33 @@ public class TextdictInfoController extends BladeController {
             }
             radioText += "</template>";
             element.empty().append(radioText);
-            element.children().get(0).attr("v-on:click", "getInformation(" + oncklickText + ")");
-            element.attr("tabindex", "-1");
         } else if (textdictInfo.getTextId().equals("checkbox")) { // 多选框
-
-            String checkbox = "<template v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
             List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
             if (optionList != null && optionList.size() >= 1) {
-                for (int i = 0; i < optionList.size(); i++)
-                    checkbox += "<el-checkbox>" + optionList.get(i).getDictValue() + "</el-checkbox>";
+                Integer[] data = new Integer[optionList.size()];
+                JSONArray objs = new JSONArray();
+
+                for (int i = 0; i < optionList.size(); i++){
+                    data[i]=i+1;
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("key",i+1);
+                    jsonObject.put("name",optionList.get(i).getDictValue());
+                    objs.add(jsonObject);
+                }
+                String checkbox = "<hc-form-checkbox-group :objs="+objs+"  @change='checkboxGroupChange' :val=" + vmode + " v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "> </hc-form-checkbox-group>";
+                element.empty().append(checkbox);
             }
-            checkbox += "</template>";
-            element.empty().append(checkbox);
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
-            element.attr("tabindex", "-1");
         } else if (textdictInfo.getTextId().equals("date")) { // 日期
-
             element.empty().append("<el-date-picker v-model=" + vmode + " type='date' format='YYYY年MM月DD日' placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'   placeholder='" + placeholder + "'> </el-date-picker>");
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
-
         } else if (textdictInfo.getTextId().equals("daterange")) { // 时间段
             element.empty().append("<el-date-picker  v-model=" + vmode + " type='datetimerange' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
-            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
             element.children().get(0).attr("@change", "datePickerChange($event,'" + keyname + "')");
         } else if (textdictInfo.getTextId().equals("img")) {
-			/*element.empty().append("<el-upload :disabled='formUploadLoading' v-loading='formUploadLoading' element-loading-text='上传中...' :on-progress='uploadprogress' @exceed='formUploadExceed' :on-error='formUploadError' placeholder="+placeholder+" v-model="+vmode+" keyname="+keyname+" weighing="+weighing+"  class='hc-upload-table-form' action='/api/blade-resource/oss/endpoint/put-file' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+"  accept='image/png,image/jpg,image/jpeg' :headers='getTokenHeader' :show-file-list='false' > <img v-if='"+vmode+"' :src="+vmode+" class='hc-table-form-img' /> <div class='hc-table-form-icon' v-else> 点此选择文件并上传 </div> <div v-if="+vmode+" class='hc-table-form-del' >" +
-					"        <el-button type='danger'"+ " plain @click.stop=delTableFormFile('"+keyname+"')>删除当前文件</el-button> " +
-					"    </div></el-upload>");*/
-
-            element.empty().append("<hc-table-form-upload :src='" + vmode + "' placeholder=" + placeholder + " v-model=" + vmode + "  keyName=" + keyname + " weighing=" + weighing + "  @success='formUploadSuccess' @del='delTableFormFile' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "/> ");
-
-            //element.children().get(0);
-            element.attr("@focus", "getInformation(" + oncklickText + ")");
-            element.attr("tabindex", "-1");
+            element.empty().append("<hc-table-form-upload :src='" + vmode + "' placeholder=" + placeholder + " v-model=" + vmode + "  keyName=" + keyname + " weighing=" + weighing + "  @success='formUploadSuccess' @del='delTableFormFile' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" +y2+"></hc-table-form-upload> ");
+        }else if (textdictInfo.getTextId().equals("searchSelect")) { //搜索框
+            element.empty().append("<hc-form-select-search type='dap_site_data' :val=" + vmode + " contractId=''  pkeyId='' @change='formRemoteChange' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </hc-form-select-search>");
         }
+        element.attr("@click", "getInformation(" + oncklickText + ")");
         File writefile = new File(wbsTreePrivate.getHtmlUrl());
         FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
         Thread.sleep(300);
@@ -263,6 +278,9 @@ public class TextdictInfoController extends BladeController {
             String clarSql = "update  " + tabName + " set " + keyname.split("__")[0] + "=null where p_key_id in(SELECT p_key_id FROM m_wbs_tree_contract WHERE id ='" + wbsTreePrivate.getId() + "' and project_id='" + wbsTreePrivate.getProjectId() + "' )";
             jdbcTemplate.execute(clarSql);
         }
+
+        //
+
         return R.success("操作成功");
     }
 
@@ -275,25 +293,40 @@ public class TextdictInfoController extends BladeController {
     public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws IOException {
 
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
-        if(jsonArray==null || jsonArray.size()==0){
-            return R.fail("保存列表无任何数据");
-        }
-        Long tableId = jsonArray.getJSONObject(0).getLong("tabId");
-
+        Long tableId = dataInfo.getLong("tabId");
         // 删除
         textdictInfoService.getBaseMapper().delete(Wrappers.<TextdictInfo>query().lambda()
                 .eq(TextdictInfo::getTabId, tableId));
+        if(jsonArray==null || jsonArray.size()==0 ){
+            return R.fail("保存列表无任何数据");
+        }
 
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
         // 读取html页面信息
         File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
         String htmlString = IoUtil.readToString(new FileInputStream(file1));
+
         // 样式集合
         Document doc = Jsoup.parse(htmlString);
+
         //解析
         Element table = doc.select("table").first();
         Elements trs = table.select("tr");
 
+        Elements onlyInfo = doc.select("el-input[readonly]");
+        if(onlyInfo!=null && onlyInfo.size()>=1){
+            for(Element element :onlyInfo ){
+                 element.removeAttr("readonly");
+             }
+        }
+
+        Elements tryInfo = doc.select("td[dqid]");
+        if(tryInfo!=null && tryInfo.size()>=1){
+            for(Element element :tryInfo ){
+                element.removeAttr("dqid");
+            }
+        }
+
         List<TextdictInfo> textdictInfos = new ArrayList<>();
 
         for (int i = 0; i < jsonArray.size(); i++) {
@@ -304,7 +337,7 @@ public class TextdictInfoController extends BladeController {
 
             String id = element.children().get(0).attr("keyname");
             textdictInfo.setName("电签位置配置");
-            textdictInfo.setType(2);
+            textdictInfo.setType(jsonObject.getInteger("type"));
             textdictInfo.setColKey(id);
             textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
             textdictInfo.setTabId(jsonObject.getString("tabId"));
@@ -316,7 +349,7 @@ public class TextdictInfoController extends BladeController {
             textdictInfoService.saveOrUpdate(textdictInfo);
             element.removeAttr("dqId");
             element.attr("dqId", textdictInfo.getId() + "");
-            element.children().get(0).attr("readonly", true);
+            element.children().get(0).attr("readonly","true");
         }
 
         // 写入 excel

+ 1 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsFormElementController.java

@@ -114,6 +114,7 @@ public class WbsFormElementController extends BladeController {
     public void exportWbsTree(HttpServletResponse response) {
         List<WbsFormElementExcel> list = new ArrayList<>();
         ExcelUtil.export(response, "WBS元素模板", "WBS元素模板", list, WbsFormElementExcel.class);
+
     }
 
     /**

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java

@@ -172,10 +172,10 @@ public class WbsTreeController extends BladeController {
     @ApiImplicitParam(name = "id", value = "表单id", required = true)
     public R removeTableById(@RequestParam("id") String id) {
         if (StringUtils.isNotEmpty(id)) {
-            List<WbsFormElementVO> wbsFormElements = wbsTreeService.selectFormElements(id);
+            /*List<WbsFormElementVO> wbsFormElements = wbsTreeService.selectFormElements(id);
             if (wbsFormElements.size() > 0) {
                 throw new ServiceException("该表单中存在元素,删除失败");
-            }
+            }*/
             /*Long wbsTreePrivates = wbsTreePrivateMapper.selectCount(Wrappers.<WbsTreePrivate>query().lambda()
                     .eq(WbsTreePrivate::getStatus, 1)
                     .eq(WbsTreePrivate::getId, id));

+ 22 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java

@@ -256,14 +256,14 @@ public class WbsTreePrivateController extends BladeController {
     public R removeTableByCondition(@RequestParam("id") String id,
                                     @RequestParam("wbsId") String wbsId,
                                     @RequestParam("projectId") String projectId) {
-        Long wbsTreeContracts = wbsTreeContractMapper.selectCount(Wrappers.<WbsTreeContract>query().lambda()
+        /*Long wbsTreeContracts = wbsTreeContractMapper.selectCount(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getProjectId, projectId)
                 .eq(WbsTreeContract::getWbsId, wbsId)
                 .eq(WbsTreeContract::getId, id)
         );
         if (wbsTreeContracts > 0L) {
             throw new ServiceException("当前表单被合同段引用中,删除失败");
-        }
+        }*/
         boolean result = wbsTreePrivateService.removeTableByCondition(id, wbsId, projectId);
         if (result) {
             return R.success("删除成功");
@@ -291,6 +291,7 @@ public class WbsTreePrivateController extends BladeController {
         return R.fail(200, "未查询到信息");
     }
 
+
     /**
      * 获取当前节点详情
      */
@@ -409,4 +410,23 @@ public class WbsTreePrivateController extends BladeController {
         return R.status(wbsTreePrivateService.syncNodeTable(primaryKeyId));
     }
 
+
+    /**
+     * wbs私有树懒加载获取项目私有节点树形结构--(表单类型划分树)
+     */
+    @GetMapping("/tab_Type_lazy-tree")
+    @ApiOperationSupport(order = 16)
+    @ApiOperation(value = "项目级懒加载节点树形结构-表单类型划分树", notes = "传入项目Id和父Id")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "parentId", value = "父级id", required = true),
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+    })
+    public R<List<WbsTreePrivateVO>> tabTypeLazyTree(Long parentId, String projectId, BladeUser bladeUser, String tenantId) {
+        List<WbsTreePrivateVO> tree = wbsTreePrivateService.tabTypeLazyTree(parentId, projectId);
+        if (tree != null && tree.size() > 0) {
+            return R.data(tree);
+        }
+        return R.fail(200, "未查询到信息");
+    }
+
 }

+ 0 - 162
blade-service/blade-manager/src/main/java/org/springblade/manager/excel/WbsExcelUtil.java

@@ -17,168 +17,6 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 public class WbsExcelUtil {
-    /*public static void main(String[] args) throws IOException {
-        WbsExcelUtil excelUtil = new WbsExcelUtil();
-        //读取excel数据
-        ArrayList<Map<String, String>> result = excelUtil.readExcelToObjContract("C:\\Users\\泓创开发\\Desktop\\合同段工程节点导入.xlsx");
-        ArrayList<Map<String, String>> resultNow = excelUtil.getDataListByType(result, 1);
-        List<Map<Integer, String>> resultList = new ArrayList<>();
-
-        int isSplicingNumber = 1;
-
-        //构造map
-        String str = "\\s*|\r|\n|\t";
-        for (Map<String, String> map : resultNow) {
-            Map<Integer, String> maps = new HashMap<>();
-            map.forEach((k1, value1) -> {
-                String v1 = value1.replaceAll(str, "");
-                map.forEach((k2, value2) -> {
-                    String v2 = value2.replaceAll(str, "");
-                    *//*if ("1".equals(k1) && "2".equals(k2)) {
-                        maps.put(1, v1 + ":::" + v2);
-                    } else if ("3".equals(k1) && "4".equals(k2)) {
-                        String s1 = "";
-                        if (number == 1) {
-                            if (StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(1);
-                                if (StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s1 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(2, v1 + ":::" + s1 + v2);
-
-                    } else if ("5".equals(k1) && "6".equals(k2)) {
-                        String s2 = "";
-                        if (number == 1) {
-                            if (StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(2);
-                                if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(1);
-                                }
-                                if (StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s2 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(3, v1 + ":::" + s2 + v2);
-
-                    } else if ("7".equals(k1) && "8".equals(k2)) {
-                        String s3 = "";
-                        if (number == 1) {
-                            if (StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(3);
-                                if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(2);
-                                    if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(1);
-                                    }
-                                }
-                                if (StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s3 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(4, v1 + ":::" + s3 + v2);
-
-                    } else if ("9".equals(k1) && "10".equals(k2)) {
-                        String s4 = "";
-                        if (StringUtils.isNotEmpty(v2)) {
-                            String s = maps.get(4);
-                            if (number == 1) {
-                                if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(3);
-                                    if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(2);
-                                    }
-                                    if (StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(1);
-                                    }
-                                }
-                                if (StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s4 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(5, v1 + ":::" + s4 + v2);
-                    }*//*
-
-                    if ("1".equals(k1) && "2".equals(k2)) {
-                        maps.put(1, v1 + ":::" + v2);
-                    } else if ("3".equals(k1) && "4".equals(k2)) {
-                        String s1 = "";
-                        if (isSplicingNumber == 1) {
-                            if (org.apache.commons.lang.StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(1);
-                                if (org.apache.commons.lang.StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s1 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(2, v1 + ":::" + s1 + v2);
-
-                    } else if ("5".equals(k1) && "6".equals(k2)) {
-                        String s2 = "";
-                        if (isSplicingNumber == 1) {
-                            if (org.apache.commons.lang.StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(2);
-                                if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(1);
-                                }
-                                if (org.apache.commons.lang.StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s2 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(3, v1 + ":::" + s2 + v2);
-
-                    } else if ("7".equals(k1) && "8".equals(k2)) {
-                        String s3 = "";
-                        if (isSplicingNumber == 1) {
-                            if (org.apache.commons.lang.StringUtils.isNotEmpty(v2)) {
-                                String s = maps.get(3);
-                                if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(2);
-                                    if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(1);
-                                    }
-                                }
-                                if (org.apache.commons.lang.StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s3 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(4, v1 + ":::" + s3 + v2);
-
-                    } else if ("9".equals(k1) && "10".equals(k2)) {
-                        String s4 = "";
-                        if (org.apache.commons.lang.StringUtils.isNotEmpty(v2)) {
-                            String s = maps.get(4);
-                            if (isSplicingNumber == 1) {
-                                if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                    s = maps.get(3);
-                                    if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(2);
-                                    }
-                                    if (org.apache.commons.lang.StringUtils.isEmpty(s.replaceAll(":::", ""))) {
-                                        s = maps.get(1);
-                                    }
-                                }
-                                if (org.apache.commons.lang.StringUtils.isNotEmpty(s.replaceAll(":::", ""))) {
-                                    s4 = s.split(":::")[1] + "-";
-                                }
-                            }
-                        }
-                        maps.put(5, v1 + ":::" + s4 + v2);
-                    }
-                });
-
-            });
-            resultList.add(maps);
-        }
-        resultList.forEach(System.out::println);
-    }*/
-
 
     /**
      * 读取excel数据

+ 23 - 16
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ContractInfo;
@@ -18,6 +19,7 @@ import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.vo.WbsTreeContractTreeVO;
 import org.springblade.manager.vo.WbsTreeContractTreeVO3;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
+import org.springblade.system.cache.ParamCache;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springframework.web.bind.annotation.RestController;
@@ -193,25 +195,19 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         List<WbsTreeContract> result = this.wbsTreeContractService.queryCurrentContractLogList(contract.getPId());
         if (result != null && result.size() != 0) {
             List<WbsTreeContractTreeVOS> vosResult = new ArrayList<>();
+
+            //获取施工配置,如果未找到配置则使用默认判断
+            String sgTheLog = StringUtils.isNotEmpty(ParamCache.getValue(CommonConstant.SG_THE_LOG)) ? ParamCache.getValue(CommonConstant.SG_THE_LOG) : "7,9,13";
+            //获取监理配置,如果未找到配置则使用默认判断
+            String jlTheLOg = StringUtils.isNotEmpty(ParamCache.getValue(CommonConstant.JL_THE_LOG)) ? ParamCache.getValue(CommonConstant.JL_THE_LOG) : "8,10,11,12";
+
             result.forEach(node -> {
-               if(new Integer("2").equals(contract.getContractType()) && Arrays.asList("8,10,11,12".split(",")).contains(node.getNodeType().toString())){
+               if(new Integer("2").equals(contract.getContractType()) && Arrays.asList(jlTheLOg.split(",")).contains(node.getNodeType().toString())){
                    //转换
-                   WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
-                   vos.setNodeType(node.getNodeType());
-                   vos.setPrimaryKeyId(String.valueOf(node.getPKeyId()));
-                   vos.setTitle(StringUtils.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
-                   vos.setExcelId(node.getExcelId());
-                   //最终返回集合
-                   vosResult.add(vos);
-               } else if(new Integer("1").equals(contract.getContractType()) && Arrays.asList("7,9,13".split(",")).contains(node.getNodeType().toString())){
+                   this.setWbsTreeContractTreeVOS(node, vosResult);
+               } else if(new Integer("1").equals(contract.getContractType()) && Arrays.asList(sgTheLog.split(",")).contains(node.getNodeType().toString())){
                    //转换
-                   WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
-                   vos.setNodeType(node.getNodeType());
-                   vos.setPrimaryKeyId(String.valueOf(node.getPKeyId()));
-                   vos.setTitle(StringUtils.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
-                   vos.setExcelId(node.getExcelId());
-                   //最终返回集合
-                   vosResult.add(vos);
+                   this.setWbsTreeContractTreeVOS(node, vosResult);
                }
             });
 
@@ -273,4 +269,15 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         }
         return null;
     }
+
+    private void setWbsTreeContractTreeVOS(WbsTreeContract node, List<WbsTreeContractTreeVOS> vosResult){
+        WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();
+        vos.setNodeType(node.getNodeType());
+        vos.setPrimaryKeyId(String.valueOf(node.getPKeyId()));
+        vos.setTitle(StringUtils.isNotEmpty(node.getFullName()) ? node.getFullName() : node.getNodeName());
+        vos.setExcelId(node.getExcelId());
+        //最终返回集合
+        vosResult.add(vos);
+    }
+
 }

+ 7 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml

@@ -19,7 +19,13 @@
     </resultMap>
 
     <select id="selectTextdictInfoPage" resultMap="textdictInfoResultMap">
-        select * from m_textdict_info where is_deleted = 0 and type =#{param2.type} and tab_id=#{param2.tabId}
+        select * from m_textdict_info where is_deleted = 0 and tab_id=#{param2.tabId}
+        <if test="param2.type== 2 ">
+          and type in('2','6')
+        </if>
+        <if test="param2.type!= 2 ">
+         and type =#{param2.type}
+        </if>
     </select>
 
 </mapper>

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java

@@ -40,6 +40,8 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     List<WbsTreePrivateVO> lazyTree(String wbsId, String tenantId, Long parentId, String projectId);
 
+    List<WbsTreePrivateVO> tabTypeLazyTree(Long parentId, String projectId);
+
     int updateByPKeyId(@Param("pKeyId") Long pKeyId, @Param("wbsTP") WbsTreePrivate wbsTP);
 
     WbsTreePrivate getByCondition(Long parentId, String projectId, String wbsId);

+ 28 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -513,4 +513,32 @@
         ORDER BY wt.sort, wt.node_name, wt.create_time
     </select>
 
+    <!-- 项目级 表单类型分类 wbs树 -->
+    <select id="tabTypeLazyTree" resultMap="treeNodeResultMap">
+        SELECT *,
+               (
+                   SELECT
+                       CASE WHEN count(1) > 0 THEN 1 ELSE 0 END
+                   FROM
+                       (
+                           SELECT  '12345678910' as p_key_id , '表单类型' as node_name, 0 as parent_id
+                           union all
+                           SELECT dict_key as p_key_id ,dict_value as node_name,'12345678910' as parent_id from blade_dict where code='table_type' and dict_key not in(-1,0)
+                           union all
+                           SELECT p_key_id,node_name,table_type as  parent_id from m_wbs_tree_private WHERE project_id=#{projectId} and is_deleted=0 and type=2 and table_type is not NULL GROUP BY node_name
+                       ) b
+                   WHERE
+                       b.parent_id = a.id
+               ) AS "has_children"
+
+               from (
+            SELECT  '12345678910' as p_key_id , '表单类型' as node_name, 0 as parent_id
+                 union all
+            SELECT dict_key as p_key_id ,dict_value as node_name,'12345678910' as parent_id from blade_dict where code='table_type' and dict_key not in(-1,0)
+                 union all
+            SELECT p_key_id,node_name,table_type as  parent_id from m_wbs_tree_private WHERE project_id=#{projectId} and is_deleted=0 and type=2 and table_type is not NULL GROUP BY node_name
+           ) a where a.parent_id = #{parentId}
+    </select>
+
+
 </mapper>

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java

@@ -23,6 +23,9 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     List<WbsTreePrivateVO> lazyTree(String wbsId, String tenantId, Long parentId, String projectId);
 
+    // 项目级 表单类型划分
+    List<WbsTreePrivateVO> tabTypeLazyTree(Long parentId, String projectId);
+
     List<WbsTreePrivateDTO2> findWbsTreePrivateSameLevel(String projectId, String parentId, String wbsId);
 
     boolean wbsTreePrivateSort(List<WbsTreePrivateDTO2> wbsTreeDTO);

+ 40 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -419,21 +419,6 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return true;
     }
 
-    private WbsTreeContract buildFailData(Integer nodeType, String nodeName, String partitionCode) {
-        WbsTreeContract wbsTreeContract = new WbsTreeContract();
-        Long id = SnowFlakeUtil.getId();
-        wbsTreeContract.setPKeyId(id);
-        wbsTreeContract.setId(id);
-        wbsTreeContract.setNodeName(nodeName);
-        wbsTreeContract.setFullName(nodeName);
-        wbsTreeContract.setImportMatchingInfo(nodeName);
-        wbsTreeContract.setPartitionCode(partitionCode);
-        wbsTreeContract.setType(1);
-        wbsTreeContract.setNodeType(nodeType);
-        wbsTreeContract.setIsImportIdentificationNode(0);  //识别失败
-        return wbsTreeContract;
-    }
-
     private List<WbsTreeContract> findAllNodeList(String wbsTreeIds, String projectId, String contractId, String wbsId) {
         String[] ids = wbsTreeIds.split(",");
         List<WbsTreeContract> list = new ArrayList<>();
@@ -610,7 +595,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                     updateWrapper.set(WbsTreeContract::getImportMatchingInfo, wbsTreeContractVO2.getImportMatchingInfo());
                                     baseMapper.update(null, updateWrapper);
                                     successData.add(wbsTreeContractVO2);
-                                    //nodeOld.getFullName()重新赋值用于下方条件判断
+                                    //重新赋值用于下方条件判断
                                     nodeOld.setFullName(wbsTreeContractVO2.getFullName());
                                     count = 1;
                                     break;
@@ -666,21 +651,38 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
         }
 
+        Set<WbsTreeContractVO> listSet = new HashSet<>();
+        //把successData的节点的上级节点都添加进去
+        if (successData.size() > 0) {
+            //通过ancestors获取所有上级节点
+            for (WbsTreeContractVO successDatum : successData) {
+                String ancestorsIds = successDatum.getAncestors();
+                List<Long> parentIds = Func.toLongList(ancestorsIds);
+                for (Long parentId : parentIds) {
+                    for (WbsTreeContractVO wbsTreeContractVO : wbsTreeContractVOS) {
+                        if (parentId.equals(wbsTreeContractVO.getId())) {
+                            listSet.add(wbsTreeContractVO);
+                        }
+                    }
+                }
+            }
+        }
+
         WbsTreeContractVO4 res = new WbsTreeContractVO4();
         try {
             //重复导入时删除多余节点信息
             List<WbsTreeContract> wbsTreeContractDel = baseMapper.selectList(Wrappers.<WbsTreeContract>query().lambda().eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()));
-            List<WbsTreeContract> collect = wbsTreeContractDel.stream().filter(f -> f.getNodeName().contains(("_copy_copy")) && f.getId().equals(f.getPKeyId())).collect(Collectors.toList());
-            List<Long> delIds = collect.stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-            baseMapper.deleteByIds(delIds);
+            List<Long> delIds = wbsTreeContractDel.stream().filter(f -> f.getNodeName().contains(("_copy_copy")) && f.getId().equals(f.getPKeyId())).collect(Collectors.toList())
+                    .stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+            if (delIds.size() > 0) {
+                baseMapper.deleteByIds(delIds);
+            }
 
             //构建成功树
-            List<WbsTreeContractVO> collect1 = successData.stream().collect(
+            List<WbsTreeContractVO> collect1 = listSet.stream().collect(
                     Collectors.collectingAndThen(
                             Collectors.toCollection(() -> new TreeSet<>(
-                                    Comparator.comparing(o -> o.getId() + ";" + o.getFullName()))), ArrayList::new))
-                    .stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime, Comparator.reverseOrder())).collect(Collectors.toList());
-
+                                    Comparator.comparing(o -> o.getId() + ";" + o.getFullName()))), ArrayList::new));
             List<WbsTreeContractVO> successWbsTreeContractVOS = this.buildWbsTreeByStream(collect1, wbsTreeContractRoot.getParentId());
             List<WbsTreeContractVO> collect2 = successWbsTreeContractVOS.stream().sorted(Comparator.comparing(WbsTreeContract::getCreateTime, Comparator.reverseOrder())).collect(Collectors.toList());
             res.setMatchedData(collect2);
@@ -831,6 +833,21 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return resultData;
     }
 
+    private WbsTreeContract buildFailData(Integer nodeType, String nodeName, String partitionCode) {
+        WbsTreeContract wbsTreeContract = new WbsTreeContract();
+        Long id = SnowFlakeUtil.getId();
+        wbsTreeContract.setPKeyId(id);
+        wbsTreeContract.setId(id);
+        wbsTreeContract.setNodeName(nodeName);
+        wbsTreeContract.setFullName(nodeName);
+        wbsTreeContract.setImportMatchingInfo(nodeName);
+        wbsTreeContract.setPartitionCode(partitionCode);
+        wbsTreeContract.setType(1);
+        wbsTreeContract.setNodeType(nodeType);
+        wbsTreeContract.setIsImportIdentificationNode(0);  //识别失败
+        return wbsTreeContract;
+    }
+
     private List<WbsTreeContractVO> buildWbsTreeByStream(List<WbsTreeContractVO> wbsTreeVO2s, Long id) {
         List<WbsTreeContractVO> list = wbsTreeVO2s.stream().filter(f -> f.getParentId().equals(id)).collect(Collectors.toList());
         Map<Long, List<WbsTreeContractVO>> map = wbsTreeVO2s.stream().collect(Collectors.groupingBy(WbsTreeContractVO::getParentId));

+ 6 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java

@@ -148,6 +148,12 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         return ForestNodeMerger.merge(baseMapper.lazyTree(wbsId, tenantId, parentId, projectId));
     }
 
+    @Override
+    public List<WbsTreePrivateVO> tabTypeLazyTree( Long parentId, String projectId) {
+        return ForestNodeMerger.merge(baseMapper.tabTypeLazyTree(parentId, projectId));
+    }
+
+
     @Override
     public List<WbsTreePrivateDTO2> findWbsTreePrivateSameLevel(String projectId, String parentId, String wbsId) {
         return baseMapper.selectNodeListByCondition(projectId, parentId, wbsId);

+ 25 - 10
blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java

@@ -32,6 +32,7 @@ import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.WbsTableOwnerRole;
+import org.springblade.system.entity.AuthClient;
 import org.springblade.system.entity.Dict;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.entity.TopMenu;
@@ -40,6 +41,7 @@ import org.springblade.system.service.IDictService;
 import org.springblade.system.service.IMenuService;
 import org.springblade.system.service.IRoleService;
 import org.springblade.system.service.ITopMenuService;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.vo.CheckedTreeVO;
 import org.springblade.system.vo.DictVO02;
 import org.springblade.system.vo.GrantTreeVO;
@@ -217,22 +219,36 @@ public class MenuController extends BladeController {
 
     /**
      * 获取权限分配树形结构
-     *
      */
     @GetMapping("/grant-tree")
     @ApiOperationSupport(order = 12)
     @ApiOperation(value = "权限分配树形结构", notes = "权限分配树形结构")
     public R<GrantTreeVO> grantTree(BladeUser user) {
         GrantTreeVO vo = new GrantTreeVO();
-        List<TreeNode> treeUserMenu = new ArrayList<>();
-        List<TreeNode> treeMenu = new ArrayList<>();
+        List<TreeNodeVO> treeUserMenu = new ArrayList<>();
+        List<TreeNodeVO> treeMenu = new ArrayList<>();
         //获取所有菜单
-        List<TreeNode> treeNodesAll = menuService.grantTree(user);
-        for (TreeNode treeNode : treeNodesAll) {
-            if (treeNode.getTitle().equals("质量管理") || treeNode.getTitle().equals("任务管理")) {
-                treeUserMenu.add(treeNode);
-            } else {
-                treeMenu.add(treeNode);
+        List<TreeNodeVO> treeNodesAll = menuService.grantTree(user);
+        //获取AuthClient
+        List<AuthClient> authClients = menuService.getSysId();
+
+        for (TreeNodeVO treeNode : treeNodesAll) {
+            if (treeNode.getSysId() != null) {
+                for (AuthClient authClient : authClients) {
+                    if (("client").equals(authClient.getClientId())) {
+                        //客户端
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeUserMenu.add(treeNode);
+                        }
+                    }
+                    if (("saber").equals(authClient.getClientId())) {
+                        //后管
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenu.add(treeNode);
+                        }
+                    }
+                    //TODO 其他菜单权限
+                }
             }
         }
 
@@ -253,7 +269,6 @@ public class MenuController extends BladeController {
 
     /**
      * 获取权限分配树形结构
-     *
      */
     @GetMapping("/role-tree-keys")
     @ApiOperationSupport(order = 13)

+ 16 - 8
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.java

@@ -18,9 +18,12 @@ package org.springblade.system.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springblade.core.tool.node.TreeNode;
+import org.springblade.system.entity.AuthClient;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.dto.MenuDTO;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.vo.MenuVO;
+import org.springblade.system.vo.RoleAndMenusVO;
 
 import java.util.List;
 import java.util.Map;
@@ -63,7 +66,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantTree();
+	List<TreeNodeVO> grantTree();
 
 	/**
 	 * 授权树形结构
@@ -71,14 +74,14 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantTreeByRole(List<Long> roleId);
 
 	/**
 	 * 顶部菜单树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantTopTree();
+	List<TreeNodeVO> grantTopTree();
 
 	/**
 	 * 顶部菜单树形结构
@@ -86,21 +89,21 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantTopTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantTopTreeByRole(List<Long> roleId);
 
 	/**
 	 * 数据权限授权树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTree();
+	List<TreeNodeVO> grantDataScopeTree();
 
 	/**
 	 * 接口权限授权树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTree();
+	List<TreeNodeVO> grantApiScopeTree();
 
 	/**
 	 * 数据权限授权树形结构
@@ -108,7 +111,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantDataScopeTreeByRole(List<Long> roleId);
 
 	/**
 	 * 接口权限授权树形结构
@@ -116,7 +119,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantApiScopeTreeByRole(List<Long> roleId);
 
 	/**
 	 * 所有菜单
@@ -190,4 +193,9 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @return
 	 */
 	List<MenuDTO> authRoutes(List<Long> roleIds);
+
+    List<AuthClient> selectBySysId();
+
+    List<RoleAndMenusVO> allRoleAndMenu(String roleId);
+
 }

+ 12 - 3
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml

@@ -40,12 +40,13 @@
         <result column="text_info" property="textInfo"/>
     </resultMap>
 
-    <resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
+    <resultMap id="treeNodeResultMap" type="org.springblade.system.user.vo.TreeNodeVO">
         <id column="id" property="id"/>
         <result column="parent_id" property="parentId"/>
         <result column="title" property="title"/>
         <result column="value" property="value"/>
         <result column="key" property="key"/>
+        <result column="sysId" property="sysId"/>
     </resultMap>
 
     <select id="lazyList"  resultMap="menuVOResultMap">
@@ -284,11 +285,11 @@
 
 
     <select id="grantTree" resultMap="treeNodeResultMap">
-        select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0 order by sort
+        select id, parent_id, name as title, id as "value", id as "key", sys_id AS "sysId" from blade_menu where is_deleted = 0 order by sort
     </select>
 
     <select id="grantTreeByRole" resultMap="treeNodeResultMap">
-        select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0
+        select id, parent_id, name as title, id as "value", id as "key", sys_id AS "sysId" from blade_menu where is_deleted = 0
         and id in ( select menu_id from blade_role_menu where role_id in
         <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
             #{item}
@@ -538,4 +539,12 @@
         GROUP BY m.path
     </select>
 
+    <select id="selectBySysId" resultType="org.springblade.system.entity.AuthClient">
+        select * from blade_client
+    </select>
+
+    <select id="allRoleAndMenu" resultType="org.springblade.system.vo.RoleAndMenusVO">
+        select * from blade_role_menu where role_id = #{roleId}
+    </select>
+
 </mapper>

+ 9 - 4
blade-service/blade-system/src/main/java/org/springblade/system/service/IMenuService.java

@@ -20,6 +20,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
+import org.springblade.system.entity.AuthClient;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.vo.MenuVO;
 
@@ -82,7 +84,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantTree(BladeUser user);
+	List<TreeNodeVO> grantTree(BladeUser user);
 
 	/**
 	 * 顶部菜单树形结构
@@ -90,7 +92,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantTopTree(BladeUser user);
+	List<TreeNodeVO> grantTopTree(BladeUser user);
 
 	/**
 	 * 数据权限授权树形结构
@@ -98,7 +100,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTree(BladeUser user);
+	List<TreeNodeVO> grantDataScopeTree(BladeUser user);
 
 	/**
 	 * 接口权限授权树形结构
@@ -106,7 +108,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTree(BladeUser user);
+	List<TreeNodeVO> grantApiScopeTree(BladeUser user);
 
 	/**
 	 * 默认选中节点
@@ -164,4 +166,7 @@ public interface IMenuService extends IService<Menu> {
 	 */
 	boolean submit(Menu menu);
 
+	List<AuthClient> getSysId();
+
+
 }

+ 230 - 207
blade-service/blade-system/src/main/java/org/springblade/system/service/impl/MenuServiceImpl.java

@@ -29,6 +29,7 @@ import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.cache.SysCache;
 import org.springblade.system.dto.MenuDTO;
 import org.springblade.system.entity.*;
@@ -38,6 +39,7 @@ import org.springblade.system.service.IRoleMenuService;
 import org.springblade.system.service.IRoleScopeService;
 import org.springblade.system.service.ITopMenuSettingService;
 import org.springblade.system.vo.MenuVO;
+import org.springblade.system.vo.RoleAndMenusVO;
 import org.springblade.system.wrapper.MenuWrapper;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
@@ -58,212 +60,233 @@ import static org.springblade.core.cache.constant.CacheConstant.MENU_CACHE;
 @AllArgsConstructor
 public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
 
-	private final IRoleMenuService roleMenuService;
-	private final IRoleScopeService roleScopeService;
-	private final ITopMenuSettingService topMenuSettingService;
-	private final static String PARENT_ID = "parentId";
-	private final static Integer MENU_CATEGORY = 1;
-
-	@Override
-	public List<MenuVO> lazyList(Long parentId, Map<String, Object> param) {
-		if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
-			parentId = null;
-		}
-		List<MenuVO> lazyList = baseMapper.lazyList(parentId, param);
-		return lazyList;
-
-	}
-
-	@Override
-	public List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param) {
-		if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
-			parentId = null;
-		}
-		return baseMapper.lazyMenuList(parentId, param);
-	}
-
-
-	@Override
-	public List<MenuVO> routes(String roleId, Long topMenuId,String sysType) {
-		if (StringUtil.isBlank(roleId)) {
-			return null;
-		}
-
-		List<Menu> allMenus = baseMapper.allMenuBySysType(sysType);
-
-		List<Menu> roleMenus;
-		// 超级管理员并且不是顶部菜单请求则返回全部菜单
-		if (AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
-			roleMenus = allMenus;
-		}
-		// 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单
-		else if (!AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
-			roleMenus = tenantPackageMenu(baseMapper.roleMenuByRoleId(Func.toLongList(roleId)));
-		}
-		// 顶部菜单请求返回对应角色权限菜单
-		else {
-			// 角色配置对应菜单
-			List<Menu> roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
-			// 反向递归角色菜单所有父级
-			List<Menu> routes = new LinkedList<>(roleIdMenus);
-			roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
-			// 顶部配置对应菜单
-			List<Menu> topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId);
-			// 筛选匹配角色对应的权限菜单
-			roleMenus = topIdMenus.stream().filter(x ->
-				routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
-			).collect(Collectors.toList());
-		}
-		return buildRoutes(allMenus, roleMenus);
-	}
-
-	private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
-		List<Menu> routes = new LinkedList<>(roleMenus);
-		roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
-		routes.sort(Comparator.comparing(Menu::getSort));
-		MenuWrapper menuWrapper = new MenuWrapper();
-		List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
-		return menuWrapper.listNodeVO(collect);
-	}
-
-	private void recursion(List<Menu> allMenus, List<Menu> routes, Menu roleMenu) {
-		Optional<Menu> menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst();
-		if (menu.isPresent() && !routes.contains(menu.get())) {
-			routes.add(menu.get());
-			recursion(allMenus, routes, menu.get());
-		}
-	}
-
-
-	@Override
-	public List<MenuVO> buttons(String roleId,String clientId) {
-		List<Menu> buttons = (AuthUtil.isAdministrator()) ? baseMapper.allButtons(clientId) : baseMapper.buttonsByClientId(Func.toLongList(roleId),clientId);
-		MenuWrapper menuWrapper = new MenuWrapper();
-		return menuWrapper.listNodeVO(buttons);
-	}
-
-	@Override
-	public List<TreeNode> tree() {
-		return ForestNodeMerger.merge(baseMapper.tree());
-	}
-
-	@Override
-	public List<TreeNode> grantTree(BladeUser user) {
-		List<TreeNode> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTree() : baseMapper.grantTreeByRole(Func.toLongList(user.getRoleId()));
-		return ForestNodeMerger.merge(tenantPackageTree(menuTree, user.getTenantId()));
-	}
-
-	@Override
-	public List<TreeNode> grantTopTree(BladeUser user) {
-		List<TreeNode> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTopTree() : baseMapper.grantTopTreeByRole(Func.toLongList(user.getRoleId()));
-		return ForestNodeMerger.merge(tenantPackageTree(menuTree, user.getTenantId()));
-	}
-
-	/**
-	 * 租户菜单权限自定义筛选
-	 */
-	private List<TreeNode> tenantPackageTree(List<TreeNode> menuTree, String tenantId) {
-		TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
-		if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
-			List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
-			menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
-		}
-		return menuTree;
-	}
-
-	/**
-	 * 租户菜单权限自定义筛选
-	 */
-	private List<Menu> tenantPackageMenu(List<Menu> menu) {
-		TenantPackage tenantPackage = SysCache.getTenantPackage(AuthUtil.getTenantId());
-		if (Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
-			List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
-			menu = menu.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
-		}
-		return menu;
-	}
-
-	@Override
-	public List<TreeNode> grantDataScopeTree(BladeUser user) {
-		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId())));
-	}
-
-	@Override
-	public List<TreeNode> grantApiScopeTree(BladeUser user) {
-		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId())));
-	}
-
-	@Override
-	public List<String> roleTreeKeys(String roleIds) {
-		List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds)));
-		return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> topTreeKeys(String topMenuIds) {
-		List<TopMenuSetting> settings = topMenuSettingService.list(Wrappers.<TopMenuSetting>query().lambda().in(TopMenuSetting::getTopMenuId, Func.toLongList(topMenuIds)));
-		return settings.stream().map(setting -> Func.toStr(setting.getMenuId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> dataScopeTreeKeys(String roleIds) {
-		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
-		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> apiScopeTreeKeys(String roleIds) {
-		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
-		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
-	}
-
-	@Override
-	@Cacheable(cacheNames = MENU_CACHE, key = "'auth:routes:' + #user.roleId")
-	public List<Kv> authRoutes(BladeUser user) {
-		List<MenuDTO> routes = baseMapper.authRoutes(Func.toLongList(user.getRoleId()));
-		List<Kv> list = new ArrayList<>();
-		routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias())))));
-		return list;
-	}
-
-	@Override
-	public boolean removeMenu(String ids) {
-		Long cnt = baseMapper.selectCount(Wrappers.<Menu>query().lambda().in(Menu::getParentId, Func.toLongList(ids)));
-		if (cnt > 0L) {
-			throw new ServiceException("请先删除子节点!");
-		}
-		return removeByIds(Func.toLongList(ids));
-	}
-
-	@Override
-	public boolean submit(Menu menu) {
-		LambdaQueryWrapper<Menu> menuQueryWrapper = Wrappers.lambdaQuery();
-		if (menu.getId() == null) {
-			menuQueryWrapper.eq(Menu::getCode, menu.getCode()).or(
-				wrapper -> wrapper.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
-			);
-		} else {
-			menuQueryWrapper.ne(Menu::getId, menu.getId()).and(
-				wrapper -> wrapper.eq(Menu::getCode, menu.getCode()).or(
-					o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
-				)
-			);
-		}
-		Long cnt = baseMapper.selectCount(menuQueryWrapper);
-		if (cnt > 0L) {
-			throw new ServiceException("菜单名或编号已存在!");
-		}
-		if (menu.getParentId() == null && menu.getId() == null) {
-			menu.setParentId(BladeConstant.TOP_PARENT_ID);
-		}
-		if (menu.getParentId() != null && menu.getId() == null) {
-			Menu parentMenu = baseMapper.selectById(menu.getParentId());
-			if (parentMenu != null && parentMenu.getCategory() != 1) {
-				throw new ServiceException("父节点只可选择菜单类型!");
-			}
-		}
-		menu.setIsDeleted(BladeConstant.DB_NOT_DELETED);
-		return saveOrUpdate(menu);
-	}
+    private final IRoleMenuService roleMenuService;
+    private final IRoleScopeService roleScopeService;
+    private final ITopMenuSettingService topMenuSettingService;
+    private final static String PARENT_ID = "parentId";
+    private final static Integer MENU_CATEGORY = 1;
+
+    @Override
+    public List<MenuVO> lazyList(Long parentId, Map<String, Object> param) {
+        if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
+            parentId = null;
+        }
+        List<MenuVO> lazyList = baseMapper.lazyList(parentId, param);
+        return lazyList;
+
+    }
+
+    @Override
+    public List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param) {
+        if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
+            parentId = null;
+        }
+        return baseMapper.lazyMenuList(parentId, param);
+    }
+
+
+    @Override
+    public List<MenuVO> routes(String roleId, Long topMenuId, String sysType) {
+        if (StringUtil.isBlank(roleId)) {
+            return null;
+        }
+
+        //根据类型获取对应菜单
+        List<Menu> allMenusList = baseMapper.allMenuBySysType(sysType);
+
+        //获取该角色与菜单关系信息
+        List<RoleAndMenusVO> resultList = baseMapper.allRoleAndMenu(roleId);
+
+        //获取对应权限的菜单List
+        List<Menu> allMenus = allMenusList.stream().filter(f -> resultList.stream().map(RoleAndMenusVO::getMenuId).collect(Collectors.toList()).contains(f.getId())).collect(Collectors.toList());
+
+        List<Menu> roleMenus;
+        // 超级管理员并且不是顶部菜单请求则返回全部菜单
+        if (AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
+            roleMenus = allMenus;
+        }
+        // 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单
+        else if (!AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
+            roleMenus = tenantPackageMenu(baseMapper.roleMenuByRoleId(Func.toLongList(roleId)));
+        }
+        // 顶部菜单请求返回对应角色权限菜单
+        else {
+            // 角色配置对应菜单
+            List<Menu> roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
+            // 反向递归角色菜单所有父级
+            List<Menu> routes = new LinkedList<>(roleIdMenus);
+            roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
+            // 顶部配置对应菜单
+            List<Menu> topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId);
+            // 筛选匹配角色对应的权限菜单
+            roleMenus = topIdMenus.stream().filter(x ->
+                    routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
+            ).collect(Collectors.toList());
+        }
+        return buildRoutes(allMenus, roleMenus);
+    }
+
+    private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
+        List<Menu> routes = new LinkedList<>(roleMenus);
+        roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
+        routes.sort(Comparator.comparing(Menu::getSort));
+        MenuWrapper menuWrapper = new MenuWrapper();
+        List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
+        return menuWrapper.listNodeVO(collect);
+    }
+
+    private void recursion(List<Menu> allMenus, List<Menu> routes, Menu roleMenu) {
+        Optional<Menu> menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst();
+        if (menu.isPresent() && !routes.contains(menu.get())) {
+            routes.add(menu.get());
+            recursion(allMenus, routes, menu.get());
+        }
+    }
+
+
+    @Override
+    public List<MenuVO> buttons(String roleId, String clientId) {
+        List<Menu> buttons = (AuthUtil.isAdministrator()) ? baseMapper.allButtons(clientId) : baseMapper.buttonsByClientId(Func.toLongList(roleId), clientId);
+        MenuWrapper menuWrapper = new MenuWrapper();
+        return menuWrapper.listNodeVO(buttons);
+    }
+
+    @Override
+    public List<TreeNode> tree() {
+        return ForestNodeMerger.merge(baseMapper.tree());
+    }
+
+    @Override
+    public List<TreeNodeVO> grantTree(BladeUser user) {
+        List<TreeNodeVO> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTree() : baseMapper.grantTreeByRole(Func.toLongList(user.getRoleId()));
+        return ForestNodeMerger.merge(tenantPackageTree2(menuTree, user.getTenantId()));
+    }
+
+    @Override
+    public List<TreeNodeVO> grantTopTree(BladeUser user) {
+        List<TreeNodeVO> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTopTree() : baseMapper.grantTopTreeByRole(Func.toLongList(user.getRoleId()));
+        return ForestNodeMerger.merge(tenantPackageTree2(menuTree, user.getTenantId()));
+    }
+
+    /**
+     * 租户菜单权限自定义筛选
+     */
+    private List<TreeNode> tenantPackageTree(List<TreeNode> menuTree, String tenantId) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
+        if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menuTree;
+    }
+
+    private List<TreeNodeVO> tenantPackageTree2(List<TreeNodeVO> menuTree, String tenantId) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
+        if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menuTree;
+    }
+
+    /**
+     * 租户菜单权限自定义筛选
+     */
+    private List<Menu> tenantPackageMenu(List<Menu> menu) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(AuthUtil.getTenantId());
+        if (Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menu = menu.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menu;
+    }
+
+    @Override
+    public List<TreeNodeVO> grantDataScopeTree(BladeUser user) {
+        return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId())));
+    }
+
+    @Override
+    public List<TreeNodeVO> grantApiScopeTree(BladeUser user) {
+        return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId())));
+    }
+
+    @Override
+    public List<String> roleTreeKeys(String roleIds) {
+        List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds)));
+        return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> topTreeKeys(String topMenuIds) {
+        List<TopMenuSetting> settings = topMenuSettingService.list(Wrappers.<TopMenuSetting>query().lambda().in(TopMenuSetting::getTopMenuId, Func.toLongList(topMenuIds)));
+        return settings.stream().map(setting -> Func.toStr(setting.getMenuId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> dataScopeTreeKeys(String roleIds) {
+        List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
+        return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> apiScopeTreeKeys(String roleIds) {
+        List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
+        return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
+    }
+
+    @Override
+    @Cacheable(cacheNames = MENU_CACHE, key = "'auth:routes:' + #user.roleId")
+    public List<Kv> authRoutes(BladeUser user) {
+        List<MenuDTO> routes = baseMapper.authRoutes(Func.toLongList(user.getRoleId()));
+        List<Kv> list = new ArrayList<>();
+        routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias())))));
+        return list;
+    }
+
+    @Override
+    public boolean removeMenu(String ids) {
+        Long cnt = baseMapper.selectCount(Wrappers.<Menu>query().lambda().in(Menu::getParentId, Func.toLongList(ids)));
+        if (cnt > 0L) {
+            throw new ServiceException("请先删除子节点!");
+        }
+        return removeByIds(Func.toLongList(ids));
+    }
+
+    @Override
+    public boolean submit(Menu menu) {
+        LambdaQueryWrapper<Menu> menuQueryWrapper = Wrappers.lambdaQuery();
+        if (menu.getId() == null) {
+            menuQueryWrapper.eq(Menu::getCode, menu.getCode()).or(
+                    wrapper -> wrapper.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
+            );
+        } else {
+            menuQueryWrapper.ne(Menu::getId, menu.getId()).and(
+                    wrapper -> wrapper.eq(Menu::getCode, menu.getCode()).or(
+                            o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
+                    )
+            );
+        }
+        Long cnt = baseMapper.selectCount(menuQueryWrapper);
+        if (cnt > 0L) {
+            throw new ServiceException("菜单名或编号已存在!");
+        }
+        if (menu.getParentId() == null && menu.getId() == null) {
+            menu.setParentId(BladeConstant.TOP_PARENT_ID);
+        }
+        if (menu.getParentId() != null && menu.getId() == null) {
+            Menu parentMenu = baseMapper.selectById(menu.getParentId());
+            if (parentMenu != null && parentMenu.getCategory() != 1) {
+                throw new ServiceException("父节点只可选择菜单类型!");
+            }
+        }
+        menu.setIsDeleted(BladeConstant.DB_NOT_DELETED);
+        return saveOrUpdate(menu);
+    }
+
+    @Override
+    public List<AuthClient> getSysId() {
+        return baseMapper.selectBySysId();
+    }
 
 }