Procházet zdrojové kódy

Merge remote-tracking branch 'origin/zhuanxie2' into prod-test

lwhhszx před 10 měsíci
rodič
revize
97508d0cb4
68 změnil soubory, kde provedl 2984 přidání a 58 odebrání
  1. 16 5
      PCS/pom.xml
  2. 8 5
      PCS/src/main/java/cn/cslg/permission/common/GlobalException.java
  3. 59 0
      PCS/src/main/java/cn/cslg/permission/common/core/business/BaseProperties.java
  4. 35 0
      PCS/src/main/java/cn/cslg/permission/common/core/business/LoginCacheKeyUtil.java
  5. 75 0
      PCS/src/main/java/cn/cslg/permission/common/core/business/SmsService.java
  6. 21 0
      PCS/src/main/java/cn/cslg/permission/common/core/exception/GlobalExceptionHandler.java
  7. 28 0
      PCS/src/main/java/cn/cslg/permission/common/model/dto/EncryptionFunctionDTO.java
  8. 39 0
      PCS/src/main/java/cn/cslg/permission/common/model/dto/EncryptionLoginDTO.java
  9. 28 0
      PCS/src/main/java/cn/cslg/permission/common/model/dto/LoginCommonDTO.java
  10. 38 0
      PCS/src/main/java/cn/cslg/permission/common/model/dto/PhoneLoginDTO.java
  11. 12 0
      PCS/src/main/java/cn/cslg/permission/common/model/dto/SendCodeDTO.java
  12. 42 0
      PCS/src/main/java/cn/cslg/permission/common/model/personnel/PersonSignUpDTO.java
  13. 21 0
      PCS/src/main/java/cn/cslg/permission/common/model/personnel/UploadPersonnelConfigDTO.java
  14. 13 0
      PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/PersonVipMessVO.java
  15. 16 0
      PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiPersonSignUpDTO.java
  16. 9 0
      PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiVIPTypeVO.java
  17. 13 0
      PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiVipTypeDTO.java
  18. 13 0
      PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionFunctionFinalVO.java
  19. 14 0
      PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionFunctionVO.java
  20. 29 0
      PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionLoginVO.java
  21. 1 1
      PCS/src/main/java/cn/cslg/permission/common/model/vo/LoginVO.java
  22. 23 0
      PCS/src/main/java/cn/cslg/permission/common/model/vo/PhoneLoginVO.java
  23. 39 0
      PCS/src/main/java/cn/cslg/permission/common/utils/AESUtils.java
  24. 3 1
      PCS/src/main/java/cn/cslg/permission/common/utils/CacheUtils.java
  25. 19 0
      PCS/src/main/java/cn/cslg/permission/common/utils/DateUtils.java
  26. 317 0
      PCS/src/main/java/cn/cslg/permission/common/utils/RSAUtils.java
  27. 58 0
      PCS/src/main/java/cn/cslg/permission/common/utils/RandomUtil.java
  28. 80 0
      PCS/src/main/java/cn/cslg/permission/common/utils/RegexUtil.java
  29. 8 0
      PCS/src/main/java/cn/cslg/permission/common/utils/Response.java
  30. 14 1
      PCS/src/main/java/cn/cslg/permission/common/utils/ResponseEnum.java
  31. 38 0
      PCS/src/main/java/cn/cslg/permission/controller/LoginController.java
  32. 8 1
      PCS/src/main/java/cn/cslg/permission/controller/PersonnelController.java
  33. 39 0
      PCS/src/main/java/cn/cslg/permission/controller/qiaobi/QiaoBiPersonController.java
  34. 36 0
      PCS/src/main/java/cn/cslg/permission/controller/qiaobi/VipTypeController.java
  35. 1 1
      PCS/src/main/java/cn/cslg/permission/domain/Client.java
  36. 27 0
      PCS/src/main/java/cn/cslg/permission/domain/PersonInvitationCode.java
  37. 21 0
      PCS/src/main/java/cn/cslg/permission/domain/Personnel.java
  38. 45 0
      PCS/src/main/java/cn/cslg/permission/domain/associate/AssoFunctionModule.java
  39. 40 0
      PCS/src/main/java/cn/cslg/permission/domain/associate/AssoPersonnelMachine.java
  40. 21 0
      PCS/src/main/java/cn/cslg/permission/domain/qiaobi/AppVipType.java
  41. 30 0
      PCS/src/main/java/cn/cslg/permission/domain/qiaobi/AssoPersonVipType.java
  42. 100 0
      PCS/src/main/java/cn/cslg/permission/exception/ExceptionEnum.java
  43. 30 0
      PCS/src/main/java/cn/cslg/permission/exception/XiaoShiException.java
  44. 1 1
      PCS/src/main/java/cn/cslg/permission/mapper/DepartmentMapper.java
  45. 9 0
      PCS/src/main/java/cn/cslg/permission/mapper/PersonInvitationCodeMapper.java
  46. 15 0
      PCS/src/main/java/cn/cslg/permission/mapper/associate/AssoFunctionModuleMapper.java
  47. 15 0
      PCS/src/main/java/cn/cslg/permission/mapper/associate/AssoPersonnelMachineMapper.java
  48. 22 0
      PCS/src/main/java/cn/cslg/permission/mapper/qiaobi/AppVipTypeMapper.java
  49. 20 0
      PCS/src/main/java/cn/cslg/permission/mapper/qiaobi/AssoPersonVipTypeMapper.java
  50. 427 9
      PCS/src/main/java/cn/cslg/permission/service/LoginService.java
  51. 28 0
      PCS/src/main/java/cn/cslg/permission/service/PersonInvitationCodeService.java
  52. 77 11
      PCS/src/main/java/cn/cslg/permission/service/PersonnelService.java
  53. 37 0
      PCS/src/main/java/cn/cslg/permission/service/qiaobi/AppVipTypeService.java
  54. 143 0
      PCS/src/main/java/cn/cslg/permission/service/qiaobi/AssoPersonVipTypeService.java
  55. 134 0
      PCS/src/main/java/cn/cslg/permission/service/qiaobi/QiaoBiPersonService.java
  56. 23 16
      PCS/src/main/resources/application-dev.yml
  57. 8 1
      PCS/src/main/resources/application-prodNetIn.yml
  58. 8 1
      PCS/src/main/resources/application-prodNetOut.yml
  59. 8 1
      PCS/src/main/resources/application-testNetIn.yml
  60. 9 2
      PCS/src/main/resources/application-testNetOut.yml
  61. 18 0
      PCS/src/main/resources/mapper/AppVipTypeMapper.xml
  62. 19 0
      PCS/src/main/resources/mapper/AssoPersonVipTypeMapper.xml
  63. 2 1
      PCS/src/main/resources/mapper/TenantVipTypeMapper.xml
  64. 42 0
      PCS/src/test/java/cn/cslg/permission/AppVipTypeTest.java
  65. 130 0
      PCS/src/test/java/cn/cslg/permission/EncryptionPersonTest.java
  66. 74 0
      PCS/src/test/java/cn/cslg/permission/PersonTest.java
  67. 19 0
      PCS/src/test/java/cn/cslg/permission/SmsServiceTest.java
  68. 169 0
      PCS/src/test/java/cn/cslg/permission/WritingAidTest.java

+ 16 - 5
PCS/pom.xml

@@ -155,6 +155,17 @@
 <!--            <version>4.10.0</version>-->
 <!--        </dependency>-->
         <!--rabbitmq-->
+        <!-- 短信接口 -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.5.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
+            <version>1.1.0</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-amqp</artifactId>
@@ -164,11 +175,11 @@
             <artifactId>pagehelper-spring-boot-starter</artifactId>
             <version>1.4.6</version>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>org.springframework.boot</groupId>-->
-<!--            <artifactId>spring-boot-starter-test</artifactId>-->
-<!--            <scope>test</scope>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>

+ 8 - 5
PCS/src/main/java/cn/cslg/permission/common/GlobalException.java

@@ -6,6 +6,7 @@ import cn.cslg.permission.common.utils.ResponseEnum;
 import cn.cslg.permission.exception.XiaoShiException;
 import cn.dev33.satoken.exception.NotLoginException;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
@@ -35,10 +36,12 @@ public class GlobalException {
 
     //小世异常
     @ExceptionHandler
-    public Response handlerXiaoShiException(XiaoShiException e) {
-        log.info("全局异常处理机制捕获到XiaoShiException,异常信息提示为:{}", e.getMessage());
-        return Response.fail(e.getMessage());
-
+    public String handlerXiaoShiException(XiaoShiException e) {
+        log.info("全局异常处理机制捕获到XiaoShiException,异常信息提示为:{}", e.getErrorCode() + "--" + e.getMessage());
+        if (StringUtils.isNotEmpty(e.getErrorCode())) {
+            return Response.error(Integer.parseInt(e.getErrorCode()), e.getErrorMessage());
+        } else {
+            return Response.error(e.getMessage());
+        }
     }
-
 }

+ 59 - 0
PCS/src/main/java/cn/cslg/permission/common/core/business/BaseProperties.java

@@ -0,0 +1,59 @@
+package cn.cslg.permission.common.core.business;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+@ConfigurationProperties(prefix = "base")
+public class BaseProperties {
+
+	public String project;
+	public String distributedCacheTopic;
+	public String distributedCachePrefix;
+	public List<String> noAuthPath = new ArrayList<>();
+	public String sharedDistributedCacheTopic;
+	public String filePath;
+	
+	public String getProject() {
+		return project;
+	}
+	public void setProject(String project) {
+		this.project = project;
+	}
+	public String getDistributedCacheTopic() {
+		return distributedCacheTopic;
+	}
+	public void setDistributedCacheTopic(String distributedCacheTopic) {
+		this.distributedCacheTopic = distributedCacheTopic;
+	}
+	public List<String> getNoAuthPath() {
+		return noAuthPath;
+	}
+	public void setNoAuthPath(List<String> noAuthPath) {
+		this.noAuthPath = noAuthPath;
+	}
+	public String getDistributedCachePrefix() {
+		return distributedCachePrefix;
+	}
+	public void setDistributedCachePrefix(String distributedCachePrefix) {
+		this.distributedCachePrefix = distributedCachePrefix;
+	}
+	public String getSharedDistributedCacheTopic() {
+		return sharedDistributedCacheTopic;
+	}
+
+	public void setSharedDistributedCacheTopic(String sharedDistributedCacheTopic) {
+		this.sharedDistributedCacheTopic = sharedDistributedCacheTopic;
+	}
+
+	public String getFilePath() {
+		return filePath;
+	}
+
+	public void setFilePath(String filePath) {
+		this.filePath = filePath;
+	}
+}

+ 35 - 0
PCS/src/main/java/cn/cslg/permission/common/core/business/LoginCacheKeyUtil.java

@@ -0,0 +1,35 @@
+package cn.cslg.permission.common.core.business;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class LoginCacheKeyUtil {
+
+    //分隔符
+    public final static String SEPARATOR = ":";
+    //统一前缀
+    private final static String prefix = "XIAOSHI";
+
+//    @Autowired
+//    public LoginCacheKeyUtil(BaseProperties baseProperties) {
+//        prefix = baseProperties.getProject();
+//    }
+
+    public final static String PHONE_LOGIN = "PHONELOGIN";
+
+    public final static String LOGIN_CAPTCHA  = "LOGIN_CAPTCHA";
+
+    /*
+     * 获取用户手机号缓存key
+     * key:手机号
+     * value:验证码 类型:String
+     * */
+    public static String getLoginCaptcha(String phoneNo) {
+        StringBuilder builder = new StringBuilder(prefix + SEPARATOR + PHONE_LOGIN + SEPARATOR);
+        builder.append(LOGIN_CAPTCHA + SEPARATOR)
+                .append(phoneNo);
+        return builder.toString();
+    }
+
+}

+ 75 - 0
PCS/src/main/java/cn/cslg/permission/common/core/business/SmsService.java

@@ -0,0 +1,75 @@
+package cn.cslg.permission.common.core.business;
+
+import cn.cslg.permission.exception.ExceptionEnum;
+import cn.cslg.permission.exception.XiaoShiException;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.profile.DefaultProfile;
+import com.google.gson.Gson;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SmsService {
+
+    @Value("${SMS.regionId}")
+    private String regionId;
+
+    @Value("${SMS.accessKeyId}")
+    private String accessKeyId;
+
+    @Value("${SMS.secret}")
+    private String secret;
+
+    public void sendMessage(String phoneNum,String random){
+
+        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
+        IAcsClient client = new DefaultAcsClient(profile);
+        SendSmsRequest request = new SendSmsRequest();
+//        String templateParam = "{\"code\":\"" + random + "\",\"message\":\"" + "为您的登陆验证码" + "\",\"validTime\":\"" + "5分钟" + "\"}";
+        String templateParam = "{\"code\":\"" + random + "\"}";
+        request.setPhoneNumbers(phoneNum);//接收短信的手机号码
+        request.setSignName("小世数字科技");//短信签名名称
+        request.setTemplateCode("SMS_296725687");//短信模板CODE
+        request.setTemplateParam(templateParam);//短信模板变量对应的实际值
+        try {
+            SendSmsResponse response = client.getAcsResponse(request);
+            if (!StringUtils.equals(response.getCode(), "OK")) {
+                throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "短信发送过于频繁,请一小时后重试");
+            }
+            System.out.println(new Gson().toJson(response));
+        } catch (ClientException e) {
+            System.out.println("ErrCode:" + e.getErrCode());
+            System.out.println("ErrMsg:" + e.getErrMsg());
+            System.out.println("RequestId:" + e.getRequestId());
+        }
+    }
+
+    public void sendQiaoBiMessage(String phoneNum,String password){
+
+        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
+        IAcsClient client = new DefaultAcsClient(profile);
+        SendSmsRequest request = new SendSmsRequest();
+//        String templateParam = "{\"code\":\"" + random + "\",\"message\":\"" + "为您的登陆验证码" + "\",\"validTime\":\"" + "5分钟" + "\"}";
+        String templateParam = "{\"password\":\"" + password + "\"}";
+        request.setPhoneNumbers(phoneNum);//接收短信的手机号码
+        request.setSignName("小世数字科技");//短信签名名称
+        request.setTemplateCode("SMS_474865949");//短信模板CODE
+        request.setTemplateParam(templateParam);//短信模板变量对应的实际值
+        try {
+            SendSmsResponse response = client.getAcsResponse(request);
+            if (!StringUtils.equals(response.getCode(), "OK")) {
+                throw new XiaoShiException(ExceptionEnum.BUSINESS_ERROR, "短信发送过于频繁,请一小时后重试");
+            }
+            System.out.println(new Gson().toJson(response));
+        } catch (ClientException e) {
+            System.out.println("ErrCode:" + e.getErrCode());
+            System.out.println("ErrMsg:" + e.getErrMsg());
+            System.out.println("RequestId:" + e.getRequestId());
+        }
+    }
+}

+ 21 - 0
PCS/src/main/java/cn/cslg/permission/common/core/exception/GlobalExceptionHandler.java

@@ -0,0 +1,21 @@
+package cn.cslg.permission.common.core.exception;
+
+import cn.cslg.permission.common.utils.Response;
+import cn.cslg.permission.exception.XiaoShiException;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(value = {XiaoShiException.class})
+    @ResponseBody
+    public String  handleAllExceptions(XiaoShiException ex) {
+        // 返回一个包含错误信息的 HTTP 响应
+        return Response.error(Integer.parseInt(ex.getErrorCode()), ex.getErrorMessage());
+    }
+
+}

+ 28 - 0
PCS/src/main/java/cn/cslg/permission/common/model/dto/EncryptionFunctionDTO.java

@@ -0,0 +1,28 @@
+package cn.cslg.permission.common.model.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class EncryptionFunctionDTO {
+
+    /**
+     * 请求的secret
+     */
+    private String sign;
+
+    /**
+     * 应用key
+     */
+    private String appKey;
+
+    /**
+     * 发起请求时的时间戳
+     */
+    private Long currentTimeMillis;
+
+    private String version;
+
+    private List<String> permissions;
+}

+ 39 - 0
PCS/src/main/java/cn/cslg/permission/common/model/dto/EncryptionLoginDTO.java

@@ -0,0 +1,39 @@
+package cn.cslg.permission.common.model.dto;
+
+import lombok.Data;
+
+@Data
+public class EncryptionLoginDTO {
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 机器码
+     */
+    private String machineCode;
+
+    /**
+     * 请求的secret
+     */
+    private String sign;
+
+    /**
+     * 应用key
+     */
+    private String appKey;
+
+    /**
+     * 发起请求时的时间戳
+     */
+    private Long currentTimeMillis;
+
+
+}

+ 28 - 0
PCS/src/main/java/cn/cslg/permission/common/model/dto/LoginCommonDTO.java

@@ -0,0 +1,28 @@
+package cn.cslg.permission.common.model.dto;
+
+
+import lombok.Data;
+
+@Data
+public class LoginCommonDTO {
+
+    /**
+     * 机器码
+     */
+    private String machineCode;
+
+    /**
+     * 请求的secret
+     */
+    private String sign;
+
+    /**
+     * 应用key
+     */
+    private String appKey;
+
+    /**
+     * 发起请求时的时间戳
+     */
+    private Long currentTimeMillis;
+}

+ 38 - 0
PCS/src/main/java/cn/cslg/permission/common/model/dto/PhoneLoginDTO.java

@@ -0,0 +1,38 @@
+package cn.cslg.permission.common.model.dto;
+
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class PhoneLoginDTO {
+
+    //手机号
+    @NotBlank
+    private String phoneNum;
+
+    //验证码
+    @NotBlank
+    private String phoneCode;
+
+    /**
+     * 机器码
+     */
+    private String machineCode;
+
+    /**
+     * 请求的secret
+     */
+    private String sign;
+
+    /**
+     * 应用key
+     */
+    private String appKey;
+
+    /**
+     * 发起请求时的时间戳
+     */
+    private Long currentTimeMillis;
+}

+ 12 - 0
PCS/src/main/java/cn/cslg/permission/common/model/dto/SendCodeDTO.java

@@ -0,0 +1,12 @@
+package cn.cslg.permission.common.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class SendCodeDTO {
+    //手机号
+    @NotBlank
+    private String phoneNum;
+}

+ 42 - 0
PCS/src/main/java/cn/cslg/permission/common/model/personnel/PersonSignUpDTO.java

@@ -0,0 +1,42 @@
+package cn.cslg.permission.common.model.personnel;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-3
+ * @description 应用类 前台对应实体
+ */
+
+@Data
+@Accessors(chain = true)
+public class PersonSignUpDTO {
+    /**
+     * 手机号
+     */
+    private String phoneNum;
+    /**
+     * 验证码
+     */
+    private String phoneCode;
+    /**
+     * 姓名
+     */
+    private String name;
+    /**
+     * 邮件
+     */
+    private String email;
+
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 密码
+     */
+   private String password;
+
+
+}

+ 21 - 0
PCS/src/main/java/cn/cslg/permission/common/model/personnel/UploadPersonnelConfigDTO.java

@@ -0,0 +1,21 @@
+package cn.cslg.permission.common.model.personnel;
+
+import cn.cslg.permission.common.model.BaseVO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-3
+ * @description 应用类 前台对应实体
+ */
+
+@Data
+@Accessors(chain = true)
+public class UploadPersonnelConfigDTO {
+
+    private String personnelConfig;
+
+
+}

+ 13 - 0
PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/PersonVipMessVO.java

@@ -0,0 +1,13 @@
+package cn.cslg.permission.common.model.qiaobi;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class PersonVipMessVO {
+    private Integer id;
+    private String vipTypeName;
+    private Date expitrTime;
+    private Boolean ifInVip;
+}

+ 16 - 0
PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiPersonSignUpDTO.java

@@ -0,0 +1,16 @@
+package cn.cslg.permission.common.model.qiaobi;
+
+import lombok.Data;
+
+@Data
+public class QiaoBiPersonSignUpDTO {
+    private String phoneNum;
+    private String phoneCode;
+    private Integer vipType;
+    private String name;
+    private String email;
+    private String username;
+    private String password;
+    private String inviteCode;
+    private Integer id;
+}

+ 9 - 0
PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiVIPTypeVO.java

@@ -0,0 +1,9 @@
+package cn.cslg.permission.common.model.qiaobi;
+
+import lombok.Data;
+
+@Data
+public class QiaoBiVIPTypeVO {
+    private Integer vipTypeId;
+    private String vipTypeName;
+}

+ 13 - 0
PCS/src/main/java/cn/cslg/permission/common/model/qiaobi/QiaoBiVipTypeDTO.java

@@ -0,0 +1,13 @@
+package cn.cslg.permission.common.model.qiaobi;
+
+
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+
+@Data
+public class QiaoBiVipTypeDTO {
+private String vipTypeName;
+private String appCode;
+}

+ 13 - 0
PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionFunctionFinalVO.java

@@ -0,0 +1,13 @@
+package cn.cslg.permission.common.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class EncryptionFunctionFinalVO {
+
+    private String key;
+
+    private List<EncryptionFunctionVO> functionVOS;
+}

+ 14 - 0
PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionFunctionVO.java

@@ -0,0 +1,14 @@
+package cn.cslg.permission.common.model.vo;
+
+import lombok.Data;
+
+@Data
+public class EncryptionFunctionVO {
+
+    //权限
+    private String permission;
+
+    //加密后的权限对应的模块化代码
+    private String encryptionModuleCode;
+
+}

+ 29 - 0
PCS/src/main/java/cn/cslg/permission/common/model/vo/EncryptionLoginVO.java

@@ -0,0 +1,29 @@
+package cn.cslg.permission.common.model.vo;
+
+import cn.cslg.permission.common.model.qiaobi.PersonVipMessVO;
+import lombok.Data;
+
+@Data
+public class EncryptionLoginVO {
+    private Integer personId;
+
+    private String personnelName;
+
+    private String personnelUserName;
+
+    private String personnelPhone;
+
+    //机器码
+    private String machineCode;
+
+    //私钥
+    private String privateKey;
+
+    /**
+     * 登陆成功后生成的Token
+     */
+    private String token;
+    //个人配置
+    private String personnelConfig;
+    private PersonVipMessVO personVipMessVO;
+}

+ 1 - 1
PCS/src/main/java/cn/cslg/permission/common/model/vo/LoginVO.java

@@ -34,7 +34,7 @@ public class LoginVO {
     private String password;
 
     /**
-     * 登录系统(0权限系统1分析系统2报告系统)
+     * 登录系统(0权限系统1分析系统2报告系统3窍笔系统)
      */
     private Integer loginSystem;
 

+ 23 - 0
PCS/src/main/java/cn/cslg/permission/common/model/vo/PhoneLoginVO.java

@@ -0,0 +1,23 @@
+package cn.cslg.permission.common.model.vo;
+
+import lombok.Data;
+
+@Data
+public class PhoneLoginVO {
+
+    private String personnelUserName;
+
+    private Integer personId;
+
+    private String personnelName;
+
+    private String personnelPhone;
+
+    private String machineCode;
+
+    private String privateKey;
+
+    private String personnelConfig;
+
+    private String token;
+}

+ 39 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/AESUtils.java

@@ -0,0 +1,39 @@
+package cn.cslg.permission.common.utils;
+
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.SecureRandom;
+import java.util.Base64;
+
+@Component
+public class AESUtils {
+
+    private static final String ALGORITHM = "AES";
+    private static final int KEY_SIZE = 128;
+
+    public static String generateKey() throws Exception {
+        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
+        keyGenerator.init(KEY_SIZE, new SecureRandom());
+        SecretKey secretKey = keyGenerator.generateKey();
+        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
+    }
+
+    public static String encrypt(String data, String key) throws Exception {
+        Cipher cipher = Cipher.getInstance(ALGORITHM);
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM));
+        byte[] encryptedData = cipher.doFinal(data.getBytes());
+        return Base64.getEncoder().encodeToString(encryptedData);
+    }
+
+    public static String decrypt(String encryptedData, String key) throws Exception {
+        Cipher cipher = Cipher.getInstance(ALGORITHM);
+        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Base64.getDecoder().decode(key), ALGORITHM));
+        byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
+        return new String(decryptedData);
+    }
+
+}

+ 3 - 1
PCS/src/main/java/cn/cslg/permission/common/utils/CacheUtils.java

@@ -2,6 +2,8 @@ package cn.cslg.permission.common.utils;
 
 import cn.cslg.permission.common.core.base.RedisConf;
 import cn.cslg.permission.common.model.vo.PersonnelVO;
+import cn.cslg.permission.exception.ExceptionEnum;
+import cn.cslg.permission.exception.XiaoShiException;
 import cn.dev33.satoken.exception.NotLoginException;
 import com.alibaba.fastjson2.JSONObject;
 import org.springframework.stereotype.Component;
@@ -20,7 +22,7 @@ public class CacheUtils {
     public PersonnelVO getLoginUser(Object userId) {
         String json = redisUtil.get(RedisConf.LOGIN_USER + RedisConf.SYMBOL_COLON + userId);
         if (StringUtils.isEmpty(json)) {
-            throw new NotLoginException("无数据", "user", "");
+            throw new XiaoShiException(ExceptionEnum.LOGIN_NO_LOGIN,ExceptionEnum.LOGIN_NO_LOGIN.getMessage());
         } else {
             return JSONObject.parseObject(json, PersonnelVO.class);
         }

+ 19 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/DateUtils.java

@@ -766,4 +766,23 @@ public class DateUtils {
         calendar.set(Calendar.SECOND, 0);
         return calendar.getTime();
     }
+
+    /**
+     * 获取增加月份后的时间
+     *
+     * @param date  yyyy-MM-dd HH:mm:ss
+     * @param
+     */
+    public static Date getPlusMonthDate(Date date, int month) {
+        Calendar cal = Calendar.getInstance();
+        try {
+            cal.setTime(date);
+            cal.add(Calendar.MONTH, month);
+            return cal.getTime();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
 }

+ 317 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/RSAUtils.java

@@ -0,0 +1,317 @@
+package cn.cslg.permission.common.utils;
+
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayOutputStream;
+import java.security.*;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class RSAUtils {
+
+    //签名算法名称
+    private static final String RSA_KEY_ALGORITHM = "RSA";
+
+    //标准签名算法名称
+    private static final String RSA_SIGNATURE_ALGORITHM = "SHA1withRSA";
+    private static final String RSA2_SIGNATURE_ALGORITHM = "SHA256withRSA";
+
+    //RSA密钥长度,默认密钥长度是1024,密钥长度必须是64的倍数,在512到65536位之间,不管是RSA还是RSA2长度推荐使用2048
+    private static final int KEY_SIZE = 2048;
+    //RSA最大加密明文大小
+    private static final int MAX_ENCRYPT_BLOCK = 245;
+    //RSA最大解密密文大小
+    private static final int MAX_DECRYPT_BLOCK = 256;
+
+    /**
+     * 生成密钥对
+     *
+     * @return 返回包含公私钥的map
+     */
+    public static Map<String, String> generateKey() {
+        KeyPairGenerator keygen;
+        try {
+            keygen = KeyPairGenerator.getInstance(RSA_KEY_ALGORITHM);
+        } catch (Exception e) {
+            throw new RuntimeException("RSA初始化密钥出现错误,算法异常");
+        }
+        SecureRandom secrand = new SecureRandom();
+        //初始化随机产生器
+        secrand.setSeed("China".getBytes());
+        //初始化密钥生成器
+        keygen.initialize(KEY_SIZE, secrand);
+        KeyPair keyPair = keygen.genKeyPair();
+        //获取公钥并转成base64编码
+        byte[] publicKey = keyPair.getPublic().getEncoded();
+        String publicKeyStr = Base64.getEncoder().encodeToString(publicKey);
+        //获取私钥并转成base64编码
+        byte[] privateKey = keyPair.getPrivate().getEncoded();
+        String privateKeyStr = Base64.getEncoder().encodeToString(privateKey);
+        //创建一个Map返回结果
+        Map<String, String> keyPairMap = new HashMap<>();
+        keyPairMap.put("publicKeyStr", publicKeyStr);
+        keyPairMap.put("privateKeyStr", privateKeyStr);
+        return keyPairMap;
+    }
+
+    /**
+     * 公钥加密(用于数据加密) 分段加密
+     *
+     * @param data         加密前的字符串
+     * @param publicKeyStr base64编码后的公钥
+     * @return base64编码后的字符串
+     * @throws Exception
+     */
+    public static String encryptByPublicKey(String data, String publicKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
+        //创建X509编码密钥规范
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据X509编码密钥规范产生公钥对象
+        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用公钥初始化此Cipher对象(加密模式)
+        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+        //对数据加密
+        int inputLen = data.getBytes().length;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int offset = 0;
+        byte[] cache;
+        int i = 0;
+        // 对数据分段加密
+        while (inputLen - offset > 0) {
+            if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
+                cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
+            } else {
+                cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
+            }
+            out.write(cache, 0, cache.length);
+            i++;
+            offset = i * MAX_ENCRYPT_BLOCK;
+        }
+        byte[] encryptedData = out.toByteArray();
+        out.close();
+        //返回base64编码后的字符串
+        return Base64.getEncoder().encodeToString(encryptedData);
+    }
+
+    /**
+     * 私钥解密(用于数据解密)    分段解密
+     *
+     * @param data          解密前的字符串
+     * @param privateKeyStr 私钥
+     * @return 解密后的字符串
+     * @throws Exception
+     */
+    public static String decryptByPrivateKey(String data, String privateKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
+        //创建PKCS8编码密钥规范
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据PKCS8编码密钥规范产生私钥对象
+        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用私钥初始化此Cipher对象(解密模式)
+        cipher.init(Cipher.DECRYPT_MODE, privateKey);
+        byte[] decodeBytes = Base64.getDecoder().decode(data);
+        //对数据分段解密
+        int inputLen = decodeBytes.length;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int offset = 0;
+        byte[] cache;
+        int i = 0;
+        // 对数据分段解密
+        while (inputLen - offset > 0) {
+            if (inputLen - offset > MAX_DECRYPT_BLOCK) {
+                cache = cipher.doFinal(decodeBytes, offset, MAX_DECRYPT_BLOCK);
+            } else {
+                cache = cipher.doFinal(decodeBytes, offset, inputLen - offset);
+            }
+            out.write(cache, 0, cache.length);
+            i++;
+            offset = i * MAX_DECRYPT_BLOCK;
+        }
+        byte[] decryptedData = out.toByteArray();
+        out.close();
+        //返回字符串
+        return new String(decryptedData, "UTF-8");
+    }
+
+    /**
+     * 公钥加密(用于数据加密)
+     *
+     * @param data         加密前的字符串
+     * @param publicKeyStr base64编码后的公钥
+     * @return base64编码后的字符串
+     * @throws Exception
+     */
+    public static String encryptByPublicKey1(String data, String publicKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
+        //创建X509编码密钥规范
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据X509编码密钥规范产生公钥对象
+        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用公钥初始化此Cipher对象(加密模式)
+        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+        //对数据加密
+        byte[] encrypt = cipher.doFinal(data.getBytes());
+        //返回base64编码后的字符串
+        return Base64.getEncoder().encodeToString(encrypt);
+    }
+
+    /**
+     * 私钥解密(用于数据解密)
+     *
+     * @param data          解密前的字符串
+     * @param privateKeyStr 私钥
+     * @return 解密后的字符串
+     * @throws Exception
+     */
+    public static String decryptByPrivateKey1(String data, String privateKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
+        //创建PKCS8编码密钥规范
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据PKCS8编码密钥规范产生私钥对象
+        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用私钥初始化此Cipher对象(解密模式)
+        cipher.init(Cipher.DECRYPT_MODE, privateKey);
+        //对数据解密
+        byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
+        //返回字符串
+        return new String(decrypt);
+    }
+
+    /**
+     * 私钥加密(用于数据签名)
+     *
+     * @param data          加密前的字符串
+     * @param privateKeyStr base64编码后的私钥
+     * @return base64编码后后的字符串
+     * @throws Exception
+     */
+    public static String encryptByPrivateKey(String data, String privateKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
+        //创建PKCS8编码密钥规范
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据PKCS8编码密钥规范产生私钥对象
+        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用私钥初始化此Cipher对象(加密模式)
+        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+        //对数据加密
+        byte[] encrypt = cipher.doFinal(data.getBytes());
+        //返回base64编码后的字符串
+        return Base64.getEncoder().encodeToString(encrypt);
+    }
+
+    /**
+     * 公钥解密(用于数据验签)
+     *
+     * @param data         解密前的字符串
+     * @param publicKeyStr base64编码后的公钥
+     * @return 解密后的字符串
+     * @throws Exception
+     */
+    public static String decryptByPublicKey(String data, String publicKeyStr) throws Exception {
+        //Java原生base64解码
+        byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
+        //创建X509编码密钥规范
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据X509编码密钥规范产生公钥对象
+        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
+        //根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
+        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+        //用公钥初始化此Cipher对象(解密模式)
+        cipher.init(Cipher.DECRYPT_MODE, publicKey);
+        //对数据解密
+        byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
+        //返回字符串
+        return new String(decrypt);
+    }
+
+    /**
+     * RSA签名
+     *
+     * @param data     待签名数据
+     * @param priKey   私钥
+     * @param signType RSA或RSA2
+     * @return 签名
+     * @throws Exception
+     */
+    public static String sign(byte[] data, byte[] priKey, String signType) throws Exception {
+        //创建PKCS8编码密钥规范
+        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //根据PKCS8编码密钥规范产生私钥对象
+        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
+        //标准签名算法名称(RSA还是RSA2)
+        String algorithm = RSA_KEY_ALGORITHM.equals(signType) ? RSA_SIGNATURE_ALGORITHM : RSA2_SIGNATURE_ALGORITHM;
+        //用指定算法产生签名对象Signature
+        Signature signature = Signature.getInstance(algorithm);
+        //用私钥初始化签名对象Signature
+        signature.initSign(privateKey);
+        //将待签名的数据传送给签名对象(须在初始化之后)
+        signature.update(data);
+        //返回签名结果字节数组
+        byte[] sign = signature.sign();
+        //返回Base64编码后的字符串
+        return Base64.getEncoder().encodeToString(sign);
+    }
+
+    /**
+     * RSA校验数字签名
+     *
+     * @param data     待校验数据
+     * @param sign     数字签名
+     * @param pubKey   公钥
+     * @param signType RSA或RSA2
+     * @return boolean 校验成功返回true,失败返回false
+     */
+    public static boolean verify(byte[] data, byte[] sign, byte[] pubKey, String signType) throws Exception {
+        //返回转换指定算法的KeyFactory对象
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
+        //创建X509编码密钥规范
+        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
+        //根据X509编码密钥规范产生公钥对象
+        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
+        //标准签名算法名称(RSA还是RSA2)
+        String algorithm = RSA_KEY_ALGORITHM.equals(signType) ? RSA_SIGNATURE_ALGORITHM : RSA2_SIGNATURE_ALGORITHM;
+        //用指定算法产生签名对象Signature
+        Signature signature = Signature.getInstance(algorithm);
+        //用公钥初始化签名对象,用于验证签名
+        signature.initVerify(publicKey);
+        //更新签名内容
+        signature.update(data);
+        //得到验证结果
+        return signature.verify(sign);
+    }
+
+}

+ 58 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/RandomUtil.java

@@ -0,0 +1,58 @@
+package cn.cslg.permission.common.utils;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+public class RandomUtil {
+
+    // 定义可用来生成邀请码的字符集
+    private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    // 定义邀请码的长度
+    private static final int CODE_LENGTH = 8;
+
+    private static String[] STR_ARR = new String[] { "a", "b", "c", "d", "e",
+            "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
+            "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E",
+            "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
+            "S", "T", "U", "V", "W", "X", "Y", "Z", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "0"};
+
+    /**
+     * 随机验证码
+     * @return
+     */
+    public static String getSixRandom(){
+        return String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5)));
+    }
+
+    /**
+     * 随机生成code码的方法
+     * @param length
+     * @return
+     */
+    public static String generateRandomString(int length) {
+        StringBuilder sb = new StringBuilder();
+        Random rand = new Random();
+        for (int i = 0; i < length; i++) {
+            sb.append(STR_ARR[rand.nextInt(STR_ARR.length)]);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 生成随机邀请码的方法
+     *
+     * @return 生成的邀请码
+     */
+    public static String generateInvitationCode() {
+        SecureRandom random = new SecureRandom();
+        StringBuilder codeBuilder = new StringBuilder(CODE_LENGTH);
+
+        for (int i = 0; i < CODE_LENGTH; i++) {
+            int index = random.nextInt(CHARACTERS.length());
+            codeBuilder.append(CHARACTERS.charAt(index));
+        }
+
+        return codeBuilder.toString();
+    }
+}

+ 80 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/RegexUtil.java

@@ -0,0 +1,80 @@
+package cn.cslg.permission.common.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+  * 正则工具类
+ */
+public class RegexUtil {
+
+    /**
+     * 大陆号码或香港号码均可
+     */
+    public static boolean isPhoneLegal(String str) throws PatternSyntaxException {
+        return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
+    }
+
+    /**
+     * 手机号验证,1开头,后面10位随机0-9数字
+     */
+    public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
+        if (str == null) {
+            return false;
+        }
+        String regExp = "^[1][0-9]{10}$";
+        Pattern p = Pattern.compile(regExp);
+        Matcher m = p.matcher(str);
+        return m.matches();
+    }
+
+    /**
+     * 香港手机号码8位数,5|6|8|9开头+7位任意数
+     */
+    public static boolean isHKPhoneLegal(String str) throws PatternSyntaxException {
+        if (str == null) {
+            return false;
+        }
+        String regExp = "^(5|6|8|9)\\d{7}$";
+        Pattern p = Pattern.compile(regExp);
+        Matcher m = p.matcher(str);
+        return m.matches();
+    }
+
+    public static boolean isRegExpReplace(String str) throws PatternSyntaxException {
+        if (str == null) {
+            return false;
+        }
+        String regExp = "[,。、;,./;]";
+        Pattern p = Pattern.compile(regExp);
+        Matcher m = p.matcher(str);
+        return m.matches();
+    }
+
+    //split By分隔符忽略引号
+    public static List<String> splitByDelimiters(String input) {
+        List<String> result = new ArrayList<>();
+        // 正则表达式匹配分隔符,但忽略引号内的内容
+        // 注意:这里使用了Unicode转义序列来表示中文引号
+        Pattern pattern = Pattern.compile("\"([^\"]*)\"|’([^’]*)’|‘([^’]*)’|“([^\"]*)”|([^,。、;,./;\\s+]+)");
+        Matcher matcher = pattern.matcher(input);
+
+        while (matcher.find()) {
+            if (matcher.group(1) != null) { // 英文双引号
+                result.add(matcher.group(1));
+            } else if (matcher.group(2) != null) { // 中文单引号
+                result.add(matcher.group(2));
+            } else if (matcher.group(3) != null) { // 中文单引号(另一种可能的形式)
+                result.add(matcher.group(3));
+            } else if (matcher.group(4) != null) { // 中文双引号
+                result.add(matcher.group(4));
+            } else { // 其他内容(即分隔符外的部分)
+                result.add(matcher.group(5));
+            }
+        }
+        return result;
+    }
+}

+ 8 - 0
PCS/src/main/java/cn/cslg/permission/common/utils/Response.java

@@ -74,6 +74,14 @@ public class Response {
         return JsonUtils.objectToJson(response);
     }
 
+    public static String error(Integer code, String message) {
+        Response response = new Response();
+        response.setCode(code);
+        response.setData(Boolean.FALSE);
+        response.setMessage(message);
+        return JsonUtils.objectToJson(response);
+    }
+
     public Response(Integer code, String message) {
         this.code = code;
         this.message = message;

+ 14 - 1
PCS/src/main/java/cn/cslg/permission/common/utils/ResponseEnum.java

@@ -24,7 +24,20 @@ public enum ResponseEnum {
     ERROR(0, "请求失败"),
     TENANT_STATUS_ERROR(805, "该用户的租户未启用"),
     PERSONNEL_STATUS_ERROR(806, "该用户未启用"),
-    TENANT_DEADLINE_ERROR(0, "该用户的租户已过期");
+    TENANT_DEADLINE_ERROR(0, "该用户的租户已过期"),
+    THE_TOKEN_IS_INVALID(500, "token失效"),
+    THE_REQUEST_TIME_OVERTIME(500, "请求时间超时"),
+    THE_SIGN_IS_NOT_SAME(500, "请求SIGN不一致,重新检查"),
+    THE_MACHINE_CODE_IS_NULL(500, "机器码不可为空"),
+    DO_NOT_LOG_IN_TO_MORE_THAN_TWO_NEW_MACHINES_WITH_THE_SAME_ACCOUNT(500, "同一账号新机登录不可超过两个"),
+    THE_PHONE_FORMAT_ERROR(500,"手机号格式错误"),
+    THE_PHONE_IS_NOT_EMPTY(500,"手机号不可为空"),
+    THE_PHONE_CODE_IS_INVALID(500,"手机验证码失效"),
+    THE_PHONE_CODE_IS_NOT_NULL(500,"手机验证码不可为空"),
+    THE_PHONE_CODE_IS_INCONFORMITY(500,"验证码不一致"),
+    THE_PERSONNEL_IS_NOT_EXIST(500,"用户不存在"),
+    THE_PERSONNEL_IS_FORBIDDEN(500,"该用户已停用"),
+    THE_VERSION_IS_NULL(500, "版本号不可为空");
 
 
     private Integer code;

+ 38 - 0
PCS/src/main/java/cn/cslg/permission/controller/LoginController.java

@@ -1,10 +1,16 @@
 package cn.cslg.permission.controller;
 
 import cn.cslg.permission.common.core.base.Constants;
+import cn.cslg.permission.common.model.dto.EncryptionFunctionDTO;
+import cn.cslg.permission.common.model.dto.EncryptionLoginDTO;
+import cn.cslg.permission.common.model.dto.PhoneLoginDTO;
+import cn.cslg.permission.common.model.dto.SendCodeDTO;
 import cn.cslg.permission.common.model.vo.LoginVO;
+import cn.cslg.permission.common.model.vo.PhoneLoginVO;
 import cn.cslg.permission.common.utils.Response;
 import cn.cslg.permission.common.utils.auth.checkAuth;
 import cn.cslg.permission.domain.ReSetPasswordDTO;
+import cn.cslg.permission.exception.ExceptionEnum;
 import cn.cslg.permission.service.LoginService;
 import cn.dev33.satoken.stp.StpUtil;
 import io.swagger.v3.oas.annotations.Operation;
@@ -14,6 +20,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.web.bind.annotation.*;
 
+import javax.validation.Valid;
+
 /**
  * @author 沈永艺
  * @date 2022-8-5
@@ -69,4 +77,34 @@ public class LoginController {
         return Response.success();
     }
 
+    @Operation(summary = "登录加密")
+    @PostMapping("/loginByEncryption")
+    public String loginByEncryption(@RequestBody EncryptionLoginDTO vo) throws Exception {
+        return loginService.loginByEncryption(vo);
+    }
+
+    @Operation(summary = "功能模块化代码加密")
+    @PostMapping("/functionByEncryption")
+    public String functionByEncryption(@RequestBody EncryptionFunctionDTO vo) throws Exception {
+        return loginService.functionByEncryption(vo);
+    }
+
+    @Operation(summary = "获取手机验证码")
+    @PostMapping("/getPhoneCode")
+    public String getPhoneCode(@RequestBody @Valid SendCodeDTO vo) {
+        String result = loginService.getPhoneCode(vo);
+        return Response.success(result);
+    }
+
+    @Operation(summary = "手机号登录")
+    @PostMapping(value = "/loginByPhone")
+    public String loginByPhone(@Valid @RequestBody PhoneLoginDTO vo) throws Exception {
+        return loginService.loginByPhone(vo);
+    }
+
+    @Operation(summary = "生成邀请链接")
+    @PostMapping(value = "/generateInvitationCode")
+    public String generateInvitationCode() {
+        return loginService.generateInvitationCode();
+    }
 }

+ 8 - 1
PCS/src/main/java/cn/cslg/permission/controller/PersonnelController.java

@@ -1,6 +1,7 @@
 package cn.cslg.permission.controller;
 
 import cn.cslg.permission.common.core.base.Constants;
+import cn.cslg.permission.common.model.personnel.UploadPersonnelConfigDTO;
 import cn.cslg.permission.common.model.vo.PersonnelVO;
 import cn.cslg.permission.common.utils.Response;
 import cn.cslg.permission.common.utils.auth.checkAuth;
@@ -8,7 +9,6 @@ import cn.cslg.permission.domain.Personnel;
 import cn.cslg.permission.service.PersonnelService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.models.security.SecurityScheme;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.web.bind.annotation.*;
@@ -130,5 +130,12 @@ public class PersonnelController {
     public String changePwd(String oldPassword, String newPassword) {
         return personnelService.changePwd(oldPassword, newPassword);
     }
+    @PostMapping("/uploadPersonnelConfig")
+    @Operation(summary = "上传用户配置")
+    public String uploadPersonnelConfig(@RequestBody UploadPersonnelConfigDTO uploadPersonnelConfigVO) {
+        personnelService.setPersonConfig(uploadPersonnelConfigVO);
+        return Response.success();
+    }
+
 
 }

+ 39 - 0
PCS/src/main/java/cn/cslg/permission/controller/qiaobi/QiaoBiPersonController.java

@@ -0,0 +1,39 @@
+package cn.cslg.permission.controller.qiaobi;
+
+import cn.cslg.permission.common.core.base.Constants;
+import cn.cslg.permission.common.model.personnel.UploadPersonnelConfigDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiPersonSignUpDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.common.utils.Response;
+import cn.cslg.permission.service.qiaobi.AppVipTypeService;
+import cn.cslg.permission.service.qiaobi.QiaoBiPersonService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-3
+ * @description 应用类 Controller 层
+ */
+@Tag(name = "会员类型管理")
+@RestController
+@RequestMapping(Constants.PERMISSION_API + "/qiaoBiPerson")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+public class QiaoBiPersonController {
+    private final QiaoBiPersonService qiaoBiPersonService;
+    @PostMapping("/personnelSignUp")
+    @Operation(summary = "用户注册")
+    public String personnelSignUp(@RequestBody QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO) {
+        qiaoBiPersonService.personSignUp(qiaoBiPersonSignUpDTO);
+        return Response.success();
+    }
+}

+ 36 - 0
PCS/src/main/java/cn/cslg/permission/controller/qiaobi/VipTypeController.java

@@ -0,0 +1,36 @@
+package cn.cslg.permission.controller.qiaobi;
+
+import cn.cslg.permission.common.core.base.Constants;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.common.utils.Response;
+import cn.cslg.permission.domain.qiaobi.AppVipType;
+import cn.cslg.permission.service.ApplicationService;
+import cn.cslg.permission.service.qiaobi.AppVipTypeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-3
+ * @description 应用类 Controller 层
+ */
+@Tag(name = "会员类型管理")
+@RestController
+@RequestMapping(Constants.PERMISSION_API + "/vipType")
+@RequiredArgsConstructor(onConstructor_ = {@Lazy})
+public class VipTypeController {
+    private final AppVipTypeService appVipTypeService;
+
+    @PostMapping("/queryQiaoBiVipType")
+    public String queryQiaoBiVipType(@RequestBody QiaoBiVipTypeDTO qiaoBiVipTypeDTO){
+      List<QiaoBiVIPTypeVO> qiaoBiVIPTypeVOList=  appVipTypeService.qiaoBiVIPTypeVOList(qiaoBiVipTypeDTO);
+      return Response.success(qiaoBiVIPTypeVOList);
+    }
+
+}

+ 1 - 1
PCS/src/main/java/cn/cslg/permission/domain/Client.java

@@ -18,7 +18,7 @@ import lombok.Data;
  */
 @Data
 @TableName("CLIENT")
-public class Client extends BaseEntity<Client> {
+public class  Client extends BaseEntity<Client> {
 
     /**
      * 客户名称

+ 27 - 0
PCS/src/main/java/cn/cslg/permission/domain/PersonInvitationCode.java

@@ -0,0 +1,27 @@
+package cn.cslg.permission.domain;
+
+import cn.cslg.permission.common.model.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "PERSON_INVITATION_CODE")
+public class PersonInvitationCode extends BaseEntity<PersonInvitationCode> {
+
+    /**
+     * 人员id
+     */
+    @TableField(value = "PERSON_ID")
+    private Integer personId;
+
+    /**
+     * 人员账号
+     */
+    @TableField(value = "INVITATION_CODE")
+    private String invitationCode;
+}

+ 21 - 0
PCS/src/main/java/cn/cslg/permission/domain/Personnel.java

@@ -92,4 +92,25 @@ public class Personnel extends BaseEntity<Personnel> {
      */
     @TableField(value = "TENANT_ID")
     private Integer tenantId;
+
+    /**
+     * 私钥
+     */
+    @TableField(value = "PRIVATE_KEY")
+    private String privateKey;
+
+    /**
+     * 公钥
+     */
+    @TableField(value = "PUBLIC_KEY")
+    private String publicKey;
+
+    /**
+     * 对称密钥
+     */
+    @TableField(value = "SYMMETRY_KEY")
+    private String symmetryKey;
+
+    @TableField(value = "PERSON_CONFIG")
+    private String personConfig;
 }

+ 45 - 0
PCS/src/main/java/cn/cslg/permission/domain/associate/AssoFunctionModule.java

@@ -0,0 +1,45 @@
+package cn.cslg.permission.domain.associate;
+
+import cn.cslg.permission.common.model.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-2
+ * @description 功能模块代码关联表
+ */
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "ASSO_FUNCTION_MODULE")
+public class AssoFunctionModule extends BaseEntity<AssoFunctionModule> {
+
+    /**
+     * 关联功能id
+     */
+    @TableField(value = "FUNCTION_ID")
+    private Integer functionId;
+
+    /**
+     * 功能模块代码
+     */
+    @TableField(value = "CODE")
+    private String code;
+
+    /**
+     * 代码授权类型  1未授权2授权
+     */
+    @TableField(value = "AUTH_TYPE")
+    private Integer authType;
+
+    /**
+     * 版本号
+     */
+    @TableField(value = "VERSION")
+    private String version;
+}

+ 40 - 0
PCS/src/main/java/cn/cslg/permission/domain/associate/AssoPersonnelMachine.java

@@ -0,0 +1,40 @@
+package cn.cslg.permission.domain.associate;
+
+import cn.cslg.permission.common.model.BaseEntity;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-2
+ * @description 人员机器码关联表
+ */
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "ASSO_PERSONNEL_MACHINE")
+public class AssoPersonnelMachine extends BaseEntity<AssoPersonnelMachine> {
+
+    /**
+     * 人员id
+     */
+    @TableField(value = "PERSONNEL_ID")
+    private Integer personnelId;
+
+    /**
+     * 机器码
+     */
+    @TableField(value = "MACHINE_CODE")
+    private String machineCode;
+
+
+    /**
+     * 是否首次激活(1是0否)
+     */
+    @TableField(value = "IF_FIRST_ACTIVATION")
+    private Boolean ifFirstActivation;
+}

+ 21 - 0
PCS/src/main/java/cn/cslg/permission/domain/qiaobi/AppVipType.java

@@ -0,0 +1,21 @@
+package cn.cslg.permission.domain.qiaobi;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @TableName APP_VIP_TYPE
+ */
+@TableName(value ="APP_VIP_TYPE")
+@Data
+public class AppVipType extends Model {
+    private Integer id;
+
+    private String applicationCode;
+
+    private Integer tenantVipTypeId;
+    private Integer lastTime;
+}

+ 30 - 0
PCS/src/main/java/cn/cslg/permission/domain/qiaobi/AssoPersonVipType.java

@@ -0,0 +1,30 @@
+package cn.cslg.permission.domain.qiaobi;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+
+/**
+ * @TableName ASSO_PERSON_VIP_TYPE
+ */
+@TableName(value ="ASSO_PERSON_VIP_TYPE")
+@Data
+public class AssoPersonVipType extends Model {
+    private Integer id;
+
+    private Integer personId;
+
+    private Integer vipTypeId;
+
+    private Date createTime;
+
+    private Date expitrTime;
+
+    private static final long serialVersionUID = 1L;
+}

+ 100 - 0
PCS/src/main/java/cn/cslg/permission/exception/ExceptionEnum.java

@@ -0,0 +1,100 @@
+package cn.cslg.permission.exception;
+
+import lombok.Getter;
+
+@Getter
+public enum ExceptionEnum {
+    //400~500  登录相关异常提示
+    LOGIN_NO_LOGIN("401","未登录"),
+    LOGIN_ACCOUNT_MISTAKE("402","账号错误"),
+    LOGIN_PASSWORD_MISTAKE("403","密码错误"),
+    LOGIN_ERROR("405","登录错误"),
+    LOGIN_INVITE_ERROR("406","邀请码错误"),
+    THE_TOKEN_IS_INVALID("407", "token失效"),
+    THE_REQUEST_TIME_OVERTIME("408", "请求时间超时"),
+    THE_SIGN_IS_NOT_SAME("408", "请求SIGN不一致,重新检查"),
+    THE_MACHINE_CODE_IS_NULL("409", "机器码不可为空"),
+    DO_NOT_LOG_IN_TO_MORE_THAN_TWO_NEW_MACHINES_WITH_THE_SAME_ACCOUNT("410", "同一账号新机登录不可超过两个"),
+    THE_PHONE_FORMAT_ERROR("411","手机号格式错误"),
+    THE_PHONE_IS_NOT_EMPTY("412","手机号不可为空"),
+    THE_PHONE_CODE_IS_INVALID("413","手机验证码失效"),
+    THE_PHONE_CODE_IS_NOT_NULL("414","手机验证码不可为空"),
+    THE_PHONE_CODE_IS_INCONFORMITY("415","验证码不一致"),
+    THE_PERSONNEL_IS_NOT_EXIST("416","用户不存在"),
+    THE_PERSONNEL_IS_FORBIDDEN("417","该用户不可用"),
+    THE_VERSION_IS_NULL("418", "版本号不可为空"),
+    THE_PERSONNEL_IS_EXIST("419","用户已存在"),
+    //500~600   业务异常相关
+    THE_SYSTEM_ERROR("500", "系统异常"),
+
+    //600~700  权限相关异常提示
+    PERMISSION_ERROR("601","无权限"),
+    PERMISSION_NO_VIP("606","未开会员"),
+    PERMISSION_BEYOND_USETIME("607","超过使用次数"),
+
+    //700~800  参数相关异常提示
+    BUSINESS_ERROR("708","业务错误"),
+    BUSINESS_CHECK("709","参数校验错误"),
+
+
+    NO_NEED_PAY("901","支付成功"),
+
+
+
+
+
+    /*APP端 100000-300000*/
+    SUCCESS("000000", "调用成功"),
+    PARAMETER_VERIFICATION_ERROR("000001", "数据参数校验异常"),
+    PHONE_FORMAT_ERROR("000002","手机号格式错误"),
+
+    VERIFY_CODE("10001", "校验码失效"),
+    CODE_WRONG("10002","验证码错误"),
+    INIT_GENERICITY_BEAN_ERROR("10003","泛型实例化异常"),
+    THE_PHONE_CANNOT_BE_EXIST("10004","手机号已存在"),
+    THE_LOG_OUT("10004","未登录"),
+    THE_CODE_IS_NOT_NULL("10006","验证码不能为空"),
+
+    //异常20000
+    THE_PARAMETER_EXCEPTION("20001", "参数异常,请传入数据"),
+    THE_GET_INFORMATION_TOKEN_INVALID("20002", "获取用户信息token失效"),
+    THE_FAIL_TO_DELETE("20003", "删除失败"),
+
+    //业务异常
+    THE_PRODUCT_CATEGORY_NAME_IS_EXIST("607", "产品类别名称已存在"),
+    THE_LOG_INVALID_NEED_LOGIN_AGAIN("606","登录失效,请重新登录"),
+
+
+
+
+
+
+
+
+
+    SYSTEM_ERROR("999999", "系统异常");
+
+    private String code;// 异常代码
+    private String message;// 异常信息
+
+    ExceptionEnum(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 30 - 0
PCS/src/main/java/cn/cslg/permission/exception/XiaoShiException.java

@@ -8,8 +8,38 @@ package cn.cslg.permission.exception;
  */
 public class XiaoShiException extends RuntimeException {
 
+    private String errorCode;// 异常代码
+    private String errorMessage;// 异常信息
     public XiaoShiException(String message) {
         super(message);
     }
 
+    public XiaoShiException(ExceptionEnum e, String errorMessage) {
+        super(errorMessage);
+        this.errorCode = e.getCode();
+        this.errorMessage = errorMessage;
+    }
+
+    public XiaoShiException(ExceptionEnum e) {
+        super(e.getMessage());
+        this.errorMessage = e.getMessage();
+        this.errorCode = e.getCode();
+    }
+
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
 }

+ 1 - 1
PCS/src/main/java/cn/cslg/permission/mapper/DepartmentMapper.java

@@ -16,7 +16,7 @@ import java.util.List;
  * @description 部门类 Mapper 层
  */
 
-@Mapper
+
 public interface DepartmentMapper extends BaseMapper<Department> {
     @Select("SELECT * FROM DEPARTMENT WHERE IS_DELETE = 0 AND FIND_IN_SET(#{param},PATH)")
     List<Department> getDepartInPathById(@Param("param") Object param);

+ 9 - 0
PCS/src/main/java/cn/cslg/permission/mapper/PersonInvitationCodeMapper.java

@@ -0,0 +1,9 @@
+package cn.cslg.permission.mapper;
+
+import cn.cslg.permission.domain.PersonInvitationCode;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface PersonInvitationCodeMapper extends BaseMapper<PersonInvitationCode> {
+}

+ 15 - 0
PCS/src/main/java/cn/cslg/permission/mapper/associate/AssoFunctionModuleMapper.java

@@ -0,0 +1,15 @@
+package cn.cslg.permission.mapper.associate;
+
+import cn.cslg.permission.domain.associate.AssoFunctionModule;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-2
+ * @description 关联类 功能模块代码 Mapper 层
+ */
+
+@Repository
+public interface AssoFunctionModuleMapper extends BaseMapper<AssoFunctionModule> {
+}

+ 15 - 0
PCS/src/main/java/cn/cslg/permission/mapper/associate/AssoPersonnelMachineMapper.java

@@ -0,0 +1,15 @@
+package cn.cslg.permission.mapper.associate;
+
+import cn.cslg.permission.domain.associate.AssoPersonnelMachine;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author 沈永艺
+ * @date 2022-8-2
+ * @description 关联类 人员机器码 Mapper 层
+ */
+
+@Repository
+public interface AssoPersonnelMachineMapper extends BaseMapper<AssoPersonnelMachine> {
+}

+ 22 - 0
PCS/src/main/java/cn/cslg/permission/mapper/qiaobi/AppVipTypeMapper.java

@@ -0,0 +1,22 @@
+package cn.cslg.permission.mapper.qiaobi;
+
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.domain.qiaobi.AppVipType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+* @author admin
+* @description 针对表【APP_VIP_TYPE(应用会员类型)】的数据库操作Mapper
+* @createDate 2024-10-31 14:42:32
+* @Entity generator.domain.AppVipType
+*/
+public interface AppVipTypeMapper extends BaseMapper<AppVipType> {
+    public List<QiaoBiVIPTypeVO> queryQiaobiVipTypeVOs(QiaoBiVipTypeDTO qiaoBiVipTypeDTO);
+}
+
+
+
+

+ 20 - 0
PCS/src/main/java/cn/cslg/permission/mapper/qiaobi/AssoPersonVipTypeMapper.java

@@ -0,0 +1,20 @@
+package cn.cslg.permission.mapper.qiaobi;
+
+import cn.cslg.permission.domain.qiaobi.AssoPersonVipType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @author admin
+* @description 针对表【ASSO_PERSON_VIP_TYPE(人员的会员)】的数据库操作Mapper
+* @createDate 2024-11-01 11:06:57
+* @Entity generator.domain.AssoPersonVipType
+*/
+@Mapper
+public interface AssoPersonVipTypeMapper extends BaseMapper<AssoPersonVipType> {
+
+}
+
+
+
+

+ 427 - 9
PCS/src/main/java/cn/cslg/permission/service/LoginService.java

@@ -1,18 +1,27 @@
 package cn.cslg.permission.service;
 
 import cn.cslg.permission.common.core.base.RedisConf;
-import cn.cslg.permission.common.model.vo.LoginRecordVO;
-import cn.cslg.permission.common.model.vo.LoginVO;
-import cn.cslg.permission.common.model.vo.PersonnelVO;
-import cn.cslg.permission.common.model.vo.RoleVO;
+import cn.cslg.permission.common.core.business.LoginCacheKeyUtil;
+import cn.cslg.permission.common.core.business.SmsService;
+import cn.cslg.permission.common.model.dto.*;
+import cn.cslg.permission.common.model.qiaobi.PersonVipMessVO;
+import cn.cslg.permission.common.model.vo.*;
 import cn.cslg.permission.common.utils.*;
 import cn.cslg.permission.common.utils.message.MessageUtils;
-import cn.cslg.permission.domain.Personnel;
-import cn.cslg.permission.domain.ReSetPasswordDTO;
-import cn.cslg.permission.domain.Tenant;
-import cn.cslg.permission.mapper.PersonnelMapper;
+import cn.cslg.permission.domain.*;
+import cn.cslg.permission.domain.associate.AssoFunctionModule;
+import cn.cslg.permission.domain.associate.AssoPersonnelMachine;
+import cn.cslg.permission.domain.qiaobi.AssoPersonVipType;
+import cn.cslg.permission.exception.ExceptionEnum;
+import cn.cslg.permission.exception.XiaoShiException;
+import cn.cslg.permission.mapper.*;
+import cn.cslg.permission.mapper.associate.AssoFunctionModuleMapper;
+import cn.cslg.permission.mapper.associate.AssoPersonnelMachineMapper;
+import cn.cslg.permission.mapper.qiaobi.AssoPersonVipTypeMapper;
 import cn.cslg.permission.service.associate.PerDpService;
 import cn.cslg.permission.service.associate.PersonRoleService;
+import cn.cslg.permission.service.associate.RoleFunctionDataService;
+import cn.cslg.permission.service.qiaobi.AssoPersonVipTypeService;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.captcha.CaptchaUtil;
 import cn.hutool.captcha.CircleCaptcha;
@@ -22,18 +31,25 @@ import cn.hutool.crypto.SecureUtil;
 
 import javax.servlet.http.HttpServletRequest;
 
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import eu.bitwalker.useragentutils.UserAgent;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
-import javax.servlet.ServletRequest;
+import java.lang.System;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * @author 沈永艺
@@ -45,6 +61,8 @@ import java.util.concurrent.TimeUnit;
 @Service
 @RequiredArgsConstructor(onConstructor_ = {@Lazy})
 public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
+    @Value("${inviteSignInLink}")
+    private String inviteSignInLink;
     private final RedisUtil redisUtil;
     private final CacheUtils cacheUtils;
     private final TenantService tenantService;
@@ -54,6 +72,24 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
     private final SystemService systemService;
     private final LoginRecordService loginRecordService;
     private final HttpServletRequest request;
+    private final RoleFunctionDataService roleFunctionDataService;
+    private final FunctionService functionService;
+    private final AssoPersonVipTypeService assoPersonVipTypeService;
+    private final AssoTenantVipTypeFunctionMapper assoTenantVipTypeFunctionMapper;
+    private final SmsService smsService;
+    private final ApplicationService applicationService;
+    @Autowired
+    private PersonnelMapper personnelMapper;
+    @Autowired
+    private FunctionMapper functionMapper;
+    @Autowired
+    private AssoPersonnelMachineMapper assoPersonnelMachineMapper;
+    @Autowired
+    private AssoFunctionModuleMapper assoFunctionModuleMapper;
+    @Autowired
+    private PersonInvitationCodeMapper personInvitationCodeMapper;
+    @Autowired
+    private AssoPersonVipTypeMapper assoPersonVipTypeMapper;
 
     /**
      * @param loginVO 登录参数类
@@ -314,8 +350,390 @@ public class LoginService extends ServiceImpl<PersonnelMapper, Personnel> {
             map.put("value2", personnel.getPersonnelName());
             mailUtils.sendEmailMessage(map);
         }
+    }
 
+    //校验登录时参数
+    public EncryptionLoginVO loginCommonMethod(LoginCommonDTO vo, Personnel personnel,LoginRecordVO loginRecordVO) throws Exception {
+        Integer personnelId = personnel.getId();
+        List<AssoPersonVipType> personVipTypes = assoPersonVipTypeMapper.selectList(new LambdaQueryWrapper<AssoPersonVipType>()
+                .eq(AssoPersonVipType::getPersonId, personnelId));
+        if (org.springframework.util.CollectionUtils.isEmpty(personVipTypes)) {
+            loginRecordVO.setLoginResult("无权限");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.PERMISSION_ERROR);
+        }
+        Long timeMillis = vo.getCurrentTimeMillis();
+        String appKey = vo.getAppKey();
+        String sign = vo.getSign();
+        String machineCode = vo.getMachineCode();
+        long currentTimeMillis = timeMillis / 1000;
+        long currentTimeSecond = System.currentTimeMillis() / 1000;
+        final long second = currentTimeSecond - currentTimeMillis;
+        if (second > 30) {
+            loginRecordVO.setLoginResult("请求时间超时");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.THE_REQUEST_TIME_OVERTIME);
+        }
+        String appSecret = appKey + currentTimeMillis;
+        String md5Sign = SecureUtil.md5(appSecret);
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
+            loginRecordVO.setLoginResult("请求SIGN不一致,重新检查");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.THE_SIGN_IS_NOT_SAME);
+        }
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(machineCode))) {
+            loginRecordVO.setLoginResult("机器码不可为空");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.THE_MACHINE_CODE_IS_NULL);
+        }
+
+        List<AssoPersonnelMachine> machineList = assoPersonnelMachineMapper.selectList(new LambdaQueryWrapper<AssoPersonnelMachine>()
+                .eq(AssoPersonnelMachine::getPersonnelId, personnelId)
+                .ne(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode)));
+        if (machineList.size() > 1) {
+            loginRecordVO.setLoginResult("同一账号新机登录不可超过两个");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.DO_NOT_LOG_IN_TO_MORE_THAN_TWO_NEW_MACHINES_WITH_THE_SAME_ACCOUNT);
+        }
+        //人员信息中私钥或公钥为空则添加进去
+        this.updatePersonnel(personnel.getPrivateKey(), personnel.getPublicKey(), personnel.getSymmetryKey(), personnelId);
+        personnel = personnelMapper.selectById(personnel.getId());
+        //添加人员和机器关联
+        this.addOrUpdatePersonnelMachine(machineCode, personnel);
 
+        EncryptionLoginVO loginVO = new EncryptionLoginVO();
+        loginVO.setPrivateKey(personnel.getPrivateKey());
+        loginVO.setPersonId(personnelId);
+        loginVO.setPersonnelName(personnel.getPersonnelName());
+        loginVO.setPersonnelUserName(personnel.getPersonnelUserName());
+        loginVO.setPersonnelPhone(personnel.getPersonnelPhone());
+        loginVO.setMachineCode(vo.getMachineCode());
+        loginVO.setPersonnelConfig(personnel.getPersonConfig());
+        //Sa-token 登录方法 登录后 生成Token 如果集成了Redis的话 会自动存入Redis
+        StpUtil.login(personnel.getId());
+        loginVO.setToken(StpUtil.getTokenValue());
+        PersonVipMessVO personVipMessVO = assoPersonVipTypeService.getPersonVipMessage(personnelId);
+        loginVO.setPersonVipMessVO(personVipMessVO);
+        loginRecordVO.setLoginResult("成功");
+        loginRecordService.addLoginRecord(loginRecordVO);
+        return loginVO;
     }
 
+    public void addLoginRecord(Personnel personnel,LoginRecordVO loginRecordVO) {
+        loginRecordVO.setLoginSystem(3);
+        loginRecordVO.setPersonnelId(personnel.getId());
+        loginRecordVO.setTenantId(personnel.getTenantId());
+        //登录日志记录ip地址
+        loginRecordVO.setLoginIp(request.getRemoteAddr());
+        String ua = request.getHeader("User-Agent");
+        UserAgent userAgent = UserAgent.parseUserAgentString(ua);
+        //获取客户端操作系统
+        String os = userAgent.getOperatingSystem().getName();
+        //获取客户端浏览器
+        String browser = userAgent.getBrowser().getName();
+        //登录日志记录操作系统
+        loginRecordVO.setLoginOs(os);
+        //解析浏览器
+        loginRecordVO.setBrowser(browser);
+    }
+
+    /**
+     * 登录加密
+     *
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
+    public String loginByEncryption(EncryptionLoginDTO vo) throws Exception {
+        final String username = vo.getUsername();
+        final String password = vo.getPassword();
+        //用用户名查询人员信息
+        LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Personnel::getPersonnelPhone, username)
+                .or()
+                .eq(Personnel::getPersonnelEmail, username)
+                .or()
+                .eq(Personnel::getPersonnelUserName, username);
+        //获取一条
+        Personnel personnel = this.getOne(queryWrapper, false);
+        //如果查不到 报错 用户名不存在
+        if (ObjectUtils.isEmpty(personnel)) {
+            throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_NOT_EXIST);
+        }
+        LoginRecordVO loginRecordVO = new LoginRecordVO();
+        this.addLoginRecord(personnel, loginRecordVO);
+        if (personnel.getPersonnelStatus().equals(0)) {
+            loginRecordVO.setLoginResult("该用户不可用");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_FORBIDDEN);
+        }
+        //校验密码是否正确
+        boolean isPassword = personnel.getPersonnelPassword().equals(SecureUtil.md5(password));
+        if (!isPassword) {
+            loginRecordVO.setLoginResult("密码错误");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            //登录日志记录登录是否成功
+            throw new XiaoShiException(ExceptionEnum.LOGIN_PASSWORD_MISTAKE);
+        }
+        LoginCommonDTO commonDTO = new LoginCommonDTO();
+        commonDTO.setAppKey(vo.getAppKey());
+        commonDTO.setSign(vo.getSign());
+        commonDTO.setCurrentTimeMillis(vo.getCurrentTimeMillis());
+        commonDTO.setMachineCode(vo.getMachineCode());
+        EncryptionLoginVO loginVO = this.loginCommonMethod(commonDTO, personnel,loginRecordVO);
+        return Response.success(loginVO);
+    }
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
+    public void updatePersonnel(String privateKey, String publicKey, String symmetryKey, Integer personId) throws Exception {
+        if (StringUtils.isEmpty(privateKey) || StringUtils.isEmpty(publicKey) || Boolean.TRUE.equals(StringUtils.isEmpty(symmetryKey))) {
+            Map<String, String> map = RSAUtils.generateKey();
+            String publicKeyStr = map.get("publicKeyStr");
+            String privateKeyStr = map.get("privateKeyStr");
+            String generateKey = AESUtils.generateKey();
+            Personnel newPersonnel = personnelMapper.selectById(personId);
+            newPersonnel.setPrivateKey(privateKeyStr);
+            newPersonnel.setPublicKey(publicKeyStr);
+            newPersonnel.setSymmetryKey(generateKey);
+            newPersonnel.updateById();
+        }
+    }
+
+    /**
+     * 新增或修改人员机器码关联表
+     *
+     * @param machineCode
+     * @param personnel
+     */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
+    public void addOrUpdatePersonnelMachine(String machineCode, Personnel personnel) {
+        AssoPersonnelMachine machine = assoPersonnelMachineMapper.selectOne(new LambdaQueryWrapper<AssoPersonnelMachine>()
+                .eq(AssoPersonnelMachine::getMachineCode, SecureUtil.md5(machineCode))
+                .eq(AssoPersonnelMachine::getPersonnelId, personnel.getId()));
+        if (ObjectUtils.isEmpty(machine)) {
+            AssoPersonnelMachine assoPersonnelMachine = new AssoPersonnelMachine();
+            assoPersonnelMachine.setPersonnelId(personnel.getId());
+            assoPersonnelMachine.setMachineCode(SecureUtil.md5(machineCode));
+            assoPersonnelMachine.setIfFirstActivation(true);
+            assoPersonnelMachine.setCreateUser(personnel.getCreateUser());
+            assoPersonnelMachine.setCreateTime(new Date());
+            assoPersonnelMachine.insert();
+        } else {
+            machine.setId(machine.getId());
+            machine.setIfFirstActivation(false);
+            machine.updateById();
+        }
+    }
+
+    public void checkedRational(String sign, String appKey, long timeMillis) {
+        long currentTimeMillis = timeMillis / 1000;
+        long currentTimeSecond = System.currentTimeMillis() / 1000;
+        final long second = currentTimeSecond - currentTimeMillis;
+        if (second > 30) {
+            throw new XiaoShiException(ExceptionEnum.THE_REQUEST_TIME_OVERTIME);
+        }
+        String appSecret = appKey + currentTimeMillis;
+        String md5Sign = SecureUtil.md5(appSecret);
+
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(sign)) || !sign.equals(md5Sign)) {
+            throw new XiaoShiException(ExceptionEnum.THE_SIGN_IS_NOT_SAME);
+        }
+    }
+
+    /**
+     * 功能模块化代码加密
+     *
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    public String functionByEncryption(EncryptionFunctionDTO vo) throws Exception {
+        String sign = vo.getSign();
+        String appKey = vo.getAppKey();
+        String version = vo.getVersion();
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(version))) {
+            version = "1.0.0.0";
+        }
+        this.checkedRational(sign, appKey, vo.getCurrentTimeMillis());
+        Integer userId = StpUtil.getLoginIdAsInt();
+//        Integer userId = 3;
+        Personnel personnel = this.getById(userId);
+        if (ObjectUtils.isEmpty(personnel)) {
+            return Response.error(ResponseEnum.THE_TOKEN_IS_INVALID);
+        }
+        String publicKey = personnel.getPublicKey();
+        String symmetryKey = personnel.getSymmetryKey();
+        EncryptionFunctionFinalVO finalVO = new EncryptionFunctionFinalVO();
+        List<EncryptionFunctionVO> functionVOS = new ArrayList<>();
+
+        List<String> permissions = new ArrayList<>();
+        //1.获取该人员的权限id
+        List<Integer> functionIds = new ArrayList<>();
+        Integer vipId = assoPersonVipTypeService.getPersonVipId(personnel.getId());
+        if (vipId != null) {
+            List<AssoTenantVipTypeAndFunctionVO> vos = assoTenantVipTypeFunctionMapper.selectByTenantVipTypeId(vipId);
+            if (vos != null && vos.size() > 0) {
+                functionIds = vos.stream().map(AssoTenantVipTypeAndFunctionVO::getFunctionId).collect(Collectors.toList());
+            }
+        }
+        if (!CollectionUtils.isEmpty(functionIds)) {
+            //2.用IDList在功能表中查出对应功能信息
+            List<Function> functionList = functionService.listByIds(functionIds);
+            //3.获取该人员角色所有权限
+            functionList.forEach(i -> {
+                permissions.add(i.getFunctionPath());
+            });
+        }
+        List<EncryptionFunctionVO> list = this.loadFunctionVOS(permissions, 2, symmetryKey, version);
+        functionVOS.addAll(list);
+
+        List<String> permissions1 = new ArrayList<>();
+        //获取所有权限
+        LambdaQueryWrapper<Application> queryWrapper =new LambdaQueryWrapper<>();
+        queryWrapper.eq(Application::getApplicationCode,appKey);
+        Application application =applicationService.getOne(queryWrapper,false);
+        List<Function> functionList1 = functionService.list(new LambdaQueryWrapper<Function>().eq(Function::getApplicationId,application.getId()));
+
+        functionList1.forEach(i -> {
+            permissions1.add(i.getFunctionPath());
+        });
+        permissions1.removeAll(permissions);
+        List<EncryptionFunctionVO> list1 = this.loadFunctionVOS(permissions1, 1, symmetryKey, version);
+        functionVOS.addAll(list1);
+        finalVO.setFunctionVOS(functionVOS);
+        String key = RSAUtils.encryptByPublicKey(symmetryKey, publicKey);
+        finalVO.setKey(key);
+        return Response.success(finalVO);
+    }
+
+    private List<EncryptionFunctionVO> loadFunctionVOS(List<String> permissions, Integer type, String symmetryKey, String version) throws Exception {
+        List<EncryptionFunctionVO> functionVOS = new ArrayList<>();
+        if (permissions == null || permissions.size() <= 0) {
+            return functionVOS;
+        }
+        List<Function> functions = functionMapper.selectList(new LambdaQueryWrapper<Function>()
+                .in(Function::getFunctionPath, permissions));
+        for (Function function : functions) {
+            Integer functionId = function.getId();
+            String functionPath = function.getFunctionPath();
+            AssoFunctionModule functionModule = assoFunctionModuleMapper.selectOne(new LambdaQueryWrapper<AssoFunctionModule>()
+                    .eq(AssoFunctionModule::getFunctionId, functionId)
+                    .eq(AssoFunctionModule::getAuthType, type)
+                    .eq(AssoFunctionModule::getVersion, version));
+            if (ObjectUtils.isNotEmpty(functionModule) && StringUtils.isNotEmpty(functionModule.getCode())) {
+                String moduleCode = functionModule.getCode();
+                String encryptInfo = AESUtils.encrypt(moduleCode, symmetryKey);
+                EncryptionFunctionVO functionVO = new EncryptionFunctionVO();
+                functionVO.setPermission(functionPath);
+                functionVO.setEncryptionModuleCode(encryptInfo);
+                functionVOS.add(functionVO);
+            }
+        }
+        return functionVOS;
+    }
+
+    //---------------------------------------二期开发--------------------------
+
+    /**
+     * 发送验证码
+     *
+     * @param vo
+     * @return
+     */
+    public String getPhoneCode(SendCodeDTO vo) {
+        String res = "发送验证码失败";
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(vo.getPhoneNum()))) {
+            throw new XiaoShiException(ExceptionEnum.THE_PHONE_IS_NOT_EMPTY);
+        }
+        if (!RegexUtil.isPhoneLegal(vo.getPhoneNum())) {
+            throw new XiaoShiException(ExceptionEnum.THE_PHONE_FORMAT_ERROR);
+        }
+        if (StringUtils.isNotEmpty(vo.getPhoneNum())) {
+            String code = redisUtil.get(LoginCacheKeyUtil.getLoginCaptcha(vo.getPhoneNum()));
+            if (org.apache.commons.lang3.StringUtils.isNotEmpty(code)) {
+                redisUtil.delete(LoginCacheKeyUtil.getLoginCaptcha(vo.getPhoneNum()));
+            }
+            //生成验证码
+            String random = RandomUtil.getSixRandom();
+            //手机号和验证码放进缓存 设置过期时间60s
+            redisUtil.set(LoginCacheKeyUtil.getLoginCaptcha(vo.getPhoneNum()), random);
+            redisUtil.expire(LoginCacheKeyUtil.getLoginCaptcha(vo.getPhoneNum()), 300L, TimeUnit.SECONDS);
+            //发送短信
+            smsService.sendMessage(vo.getPhoneNum(), random);
+            res = "发送验证码成功";
+        }
+        return res;
+    }
+
+    /**
+     * 手机号登录
+     *
+     * @param dto
+     * @return
+     */
+//    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
+    public String loginByPhone(PhoneLoginDTO dto) throws Exception {
+        //获取缓存中验证码
+        String code = redisUtil.get(LoginCacheKeyUtil.getLoginCaptcha(dto.getPhoneNum()));
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(code))) {
+            throw new XiaoShiException(ExceptionEnum.THE_PHONE_CODE_IS_INVALID);
+        }
+        //校验验证码
+        if (Boolean.TRUE.equals(StringUtils.isEmpty(dto.getPhoneCode()))) {
+            throw new XiaoShiException(ExceptionEnum.THE_PHONE_CODE_IS_NOT_NULL);
+        }
+
+        if (!org.apache.commons.lang3.StringUtils.equals(code, dto.getPhoneCode())) {
+            throw new XiaoShiException(ExceptionEnum.THE_PHONE_CODE_IS_INCONFORMITY);
+        }
+        //校验验证码成功后使其失效
+        redisUtil.delete(LoginCacheKeyUtil.getLoginCaptcha(dto.getPhoneNum()));
+        //查询用户
+        LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
+        if (org.apache.commons.lang3.StringUtils.isNotEmpty(dto.getPhoneNum())) {
+            queryWrapper.eq(Personnel::getPersonnelPhone, dto.getPhoneNum());
+        }
+        Personnel person = this.getOne(queryWrapper, false);
+        if (org.apache.commons.lang3.ObjectUtils.isEmpty(person)) {
+            throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_NOT_EXIST);
+        }
+        LoginRecordVO loginRecordVO = new LoginRecordVO();
+        this.addLoginRecord(person, loginRecordVO);
+        if (person.getPersonnelStatus().equals(0)) {
+            loginRecordVO.setLoginResult("该用户不可用");
+            loginRecordService.addLoginRecord(loginRecordVO);
+            throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_FORBIDDEN);
+        }
+        LoginCommonDTO commonDTO = new LoginCommonDTO();
+        commonDTO.setAppKey(dto.getAppKey());
+        commonDTO.setSign(dto.getSign());
+        commonDTO.setCurrentTimeMillis(dto.getCurrentTimeMillis());
+        commonDTO.setMachineCode(dto.getMachineCode());
+        EncryptionLoginVO loginVO = this.loginCommonMethod(commonDTO, person, loginRecordVO);
+        return Response.success(loginVO);
+    }
+
+    public String generateInvitationCode() {
+        Integer userId = null;
+        try {
+            userId = StpUtil.getLoginIdAsInt();
+            PersonInvitationCode assoPersoninvitationCode = personInvitationCodeMapper.selectOne(new LambdaQueryWrapper<PersonInvitationCode>()
+                    .eq(PersonInvitationCode::getPersonId, userId));
+            String invitationCode = "";
+            if (ObjectUtils.isEmpty(assoPersoninvitationCode)) {
+                PersonInvitationCode personInvitationCode = new PersonInvitationCode();
+                personInvitationCode.setPersonId(userId);
+                personInvitationCode.setInvitationCode(RandomUtil.generateInvitationCode());
+                personInvitationCode.setCreateUser(userId);
+                personInvitationCode.insert();
+                invitationCode = personInvitationCode.getInvitationCode();
+            } else {
+                invitationCode = assoPersoninvitationCode.getInvitationCode();
+            }
+            return Response.success(inviteSignInLink + "?invitationCode=" + invitationCode);
+        } catch (Exception e) {
+            return Response.success(inviteSignInLink);
+        }
+    }
 }

+ 28 - 0
PCS/src/main/java/cn/cslg/permission/service/PersonInvitationCodeService.java

@@ -0,0 +1,28 @@
+package cn.cslg.permission.service;
+
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.domain.PersonInvitationCode;
+import cn.cslg.permission.domain.qiaobi.AppVipType;
+import cn.cslg.permission.mapper.PersonInvitationCodeMapper;
+import cn.cslg.permission.mapper.qiaobi.AppVipTypeMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author admin
+ * @description 针对表【APP_VIP_TYPE(应用会员类型)】的数据库操作Service实现
+ * @createDate 2024-10-31 14:42:32
+ */
+@Service
+public class PersonInvitationCodeService extends ServiceImpl<PersonInvitationCodeMapper, PersonInvitationCode> {
+
+
+
+}
+
+
+
+

+ 77 - 11
PCS/src/main/java/cn/cslg/permission/service/PersonnelService.java

@@ -1,16 +1,21 @@
 package cn.cslg.permission.service;
 
 import cn.cslg.permission.common.core.base.RedisConf;
+import cn.cslg.permission.common.model.personnel.UploadPersonnelConfigDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiPersonSignUpDTO;
 import cn.cslg.permission.common.model.vo.PersonnelVO;
 import cn.cslg.permission.common.model.vo.RoleVO;
 import cn.cslg.permission.common.utils.*;
 import cn.cslg.permission.common.utils.SecurityUtils.SecurityUtils;
+import cn.cslg.permission.common.utils.message.MessageUtils;
 import cn.cslg.permission.domain.Personnel;
 import cn.cslg.permission.domain.Tenant;
 import cn.cslg.permission.domain.associate.AssoDepartPos;
 import cn.cslg.permission.domain.associate.AssoPerDp;
 import cn.cslg.permission.domain.associate.AssoPersonRole;
+import cn.cslg.permission.domain.sys.SysDictItem;
 import cn.cslg.permission.mapper.PersonnelMapper;
+import cn.cslg.permission.mapper.SysDictItemMapper;
 import cn.cslg.permission.service.associate.DepartPosiService;
 import cn.cslg.permission.service.associate.PerDpService;
 import cn.cslg.permission.service.associate.PersonGroupService;
@@ -18,6 +23,7 @@ import cn.cslg.permission.service.associate.PersonRoleService;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.crypto.SecureUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
@@ -27,10 +33,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -50,6 +53,8 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
     private final TenantService tenantService;
     private final CacheUtils cacheUtils;
     private final RedisUtil redisUtil;
+    private final SysDictItemMapper sysDictItemMapper;
+    private final MessageUtils messageUtils;
 
     @Transactional(rollbackFor = Exception.class)
     public Personnel addPersonnel(PersonnelVO personnelVO) {
@@ -148,6 +153,9 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
                     personRoleService.addAssociatePerRole(personnelVO.getRole(), personnel.getId());
                 }
             }
+
+            this.sendAddPersonEmail(personnelVO);
+
         } catch (Exception e) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             e.printStackTrace();
@@ -328,7 +336,7 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
                 );
 
         //根据人员id查询
-        if(personnelVO.getId()!=null){
+        if (personnelVO.getId() != null) {
             queryWrapper.in(Personnel::getId, Integer.parseInt(personnelVO.getId()));
         }
 
@@ -344,6 +352,10 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
             queryWrapper.in(Personnel::getId, perIds);
         }
 
+        if (personnelVO.getTenant() != null) {
+            queryWrapper.eq(Personnel::getTenantId, personnelVO.getTenant());
+        }
+
         //若前台有传职位ids,则根据职位ids查询人员列表
         if (personnelVO.getPositionIds() != null && personnelVO.getPositionIds().size() != 0) {
             LambdaQueryWrapper<AssoDepartPos> qw = new LambdaQueryWrapper<>();
@@ -373,10 +385,9 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
 
         LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
         //若前台有传租户id,则根据租户id查询人员列表
-        if(personnelVO.getTenantId()!=null) {
+        if (personnelVO.getTenantId() != null) {
             queryWrapper.eq(Personnel::getTenantId, personnelVO.getTenantId());
-        }
-        else {
+        } else {
             //TODO 代码控制若不是超级管理员则只能查看本租户的人员列表
             if (personnelVO1.getRoleType() == null || personnelVO1.getRoleType() != 1) {
                 queryWrapper.eq(Personnel::getTenantId, personnelVO1.getTenantId());
@@ -393,7 +404,7 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
                 );
 
         //根据人员id查询
-        if(personnelVO.getId()!=null){
+        if (personnelVO.getId() != null) {
             queryWrapper.in(Personnel::getId, Integer.parseInt(personnelVO.getId()));
         }
 
@@ -430,8 +441,6 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
     }
 
 
-
-
     public List<Integer> getByTenantId(Integer tenantId) {
         //根据租户id查询人员列表
         LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
@@ -513,4 +522,61 @@ public class PersonnelService extends ServiceImpl<PersonnelMapper, Personnel> {
         }
         return personnel;
     }
+
+    public void sendAddPersonEmail(PersonnelVO personnel) {
+        //从字典表里获得配置联系人数
+        LambdaQueryWrapper<SysDictItem> wrapper1 = new LambdaQueryWrapper<>();
+        wrapper1.eq(SysDictItem::getDictParentKey, "ADD_CC_PERSON");
+        List<SysDictItem> sysDictItems = sysDictItemMapper.selectList(wrapper1);
+        Map<String, Object> map = new LinkedHashMap<>();
+        map.put("title", "人员添加通知");
+        map.put("template", "mail/addPersonEmail.html");
+
+        map.put("img", "/logo.png");
+        map.put("value0", personnel.getName());
+        map.put("value1", personnel.getUsername());
+        map.put("value2", personnel.getPassword());
+        map.put("email", personnel.getEmail());
+        if (sysDictItems != null && sysDictItems.size() > 0) {
+            String[] cc = new String[sysDictItems.size()];
+            for (int i = 0; i < sysDictItems.size(); i++) {
+                cc[i] = sysDictItems.get(i).getDictChildValue();
+            }
+            map.put("cc", cc);
+        }
+        messageUtils.sendEmailMessage(map);
+    }
+
+    public void setPersonConfig(UploadPersonnelConfigDTO uploadPersonnelConfigVO) {
+        String personConfig = uploadPersonnelConfigVO.getPersonnelConfig();
+        PersonnelVO localPer = cacheUtils.getLoginUser(StpUtil.getLoginIdAsInt());
+        String id = localPer.getId();
+        LambdaUpdateWrapper<Personnel> personnelLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        personnelLambdaUpdateWrapper.set(Personnel::getPersonConfig, personConfig)
+                .eq(Personnel::getId, Integer.parseInt(id));
+        this.update(personnelLambdaUpdateWrapper);
+    }
+
+    public QiaoBiPersonSignUpDTO addPhoneSignUpPerson(QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO) {
+        String phone = qiaoBiPersonSignUpDTO.getPhoneNum();
+        String email = qiaoBiPersonSignUpDTO.getEmail();
+        String name = qiaoBiPersonSignUpDTO.getName();
+        String userName = qiaoBiPersonSignUpDTO.getUsername();
+        String passWord = qiaoBiPersonSignUpDTO.getPassword();
+        if (passWord == null || passWord.trim().equals("")) {
+            passWord = RandomUtil.generateRandomString(8);
+        }
+        qiaoBiPersonSignUpDTO.setPassword(passWord);
+
+        passWord = SecureUtil.md5(passWord);
+        Personnel personnel = new Personnel();
+        personnel.setPersonnelPhone(phone);
+        personnel.setPersonnelEmail(email);
+        personnel.setPersonnelName(name);
+        personnel.setPersonnelUserName(userName);
+        personnel.setPersonnelPassword(passWord);
+        personnel.insert();
+        qiaoBiPersonSignUpDTO.setId(personnel.getId());
+        return qiaoBiPersonSignUpDTO;
+    }
 }

+ 37 - 0
PCS/src/main/java/cn/cslg/permission/service/qiaobi/AppVipTypeService.java

@@ -0,0 +1,37 @@
+package cn.cslg.permission.service.qiaobi;
+
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.domain.qiaobi.AppVipType;
+import cn.cslg.permission.mapper.qiaobi.AppVipTypeMapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author admin
+ * @description 针对表【APP_VIP_TYPE(应用会员类型)】的数据库操作Service实现
+ * @createDate 2024-10-31 14:42:32
+ */
+@Service
+public class AppVipTypeService extends ServiceImpl<AppVipTypeMapper, AppVipType> {
+
+    public List<QiaoBiVIPTypeVO> qiaoBiVIPTypeVOList(QiaoBiVipTypeDTO qiaoBiVipTypeDTO) {
+        qiaoBiVipTypeDTO.setAppCode("4e95e3d926a2a4befa5d913acc0aa9f5");
+        List<QiaoBiVIPTypeVO> qiaoBiVIPTypeVOList = this.getBaseMapper().queryQiaobiVipTypeVOs(qiaoBiVipTypeDTO);
+        return qiaoBiVIPTypeVOList;
+    }
+    public AppVipType queryById(Integer id) {
+        LambdaQueryWrapper<AppVipType> queryWrapper =new LambdaQueryWrapper<>();
+        queryWrapper.eq(AppVipType::getTenantVipTypeId,id);
+        AppVipType appVipType =this.getOne(queryWrapper);
+        return appVipType;
+    }
+}
+
+
+
+

+ 143 - 0
PCS/src/main/java/cn/cslg/permission/service/qiaobi/AssoPersonVipTypeService.java

@@ -0,0 +1,143 @@
+package cn.cslg.permission.service.qiaobi;
+
+import cn.cslg.permission.common.model.qiaobi.PersonVipMessVO;
+import cn.cslg.permission.common.utils.DateUtils;
+import cn.cslg.permission.domain.TenantVipType;
+import cn.cslg.permission.domain.qiaobi.AppVipType;
+import cn.cslg.permission.service.impl.TenantVipTypeService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import cn.cslg.permission.domain.qiaobi.AssoPersonVipType;
+import cn.cslg.permission.mapper.qiaobi.AssoPersonVipTypeMapper;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+/**
+ * @author admin
+ * @description 针对表【ASSO_PERSON_VIP_TYPE(人员的会员)】的数据库操作Service实现
+ * @createDate 2024-11-01 11:06:57
+ */
+@Service
+public class AssoPersonVipTypeService extends ServiceImpl<AssoPersonVipTypeMapper, AssoPersonVipType> {
+    @Autowired
+    private AppVipTypeService appVipTypeService;
+    @Autowired
+    private TenantVipTypeService tenantVipTypeService;
+
+    public AssoPersonVipType addVip(Integer personId, Integer vipTypeId, Integer lastTime) {
+        AssoPersonVipType assoPersonVip = new AssoPersonVipType();
+        LambdaQueryWrapper<AssoPersonVipType> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AssoPersonVipType::getPersonId, personId)
+                .eq(AssoPersonVipType::getVipTypeId, vipTypeId)
+                .orderByDesc(AssoPersonVipType::getExpitrTime);
+        assoPersonVip = this.getOne(queryWrapper, false);
+
+        if (lastTime == null) {
+            AppVipType appVipType = appVipTypeService.queryById(vipTypeId);
+
+            lastTime = appVipType.getLastTime();
+        }
+        if (assoPersonVip != null) {
+            this.updateAssoPersonVip(assoPersonVip, lastTime);
+        } else {
+            assoPersonVip = this.addAssoPersonVip(personId, vipTypeId, lastTime);
+        }
+        return assoPersonVip;
+    }
+
+    public AssoPersonVipType addAssoPersonVip(Integer personUuid, Integer vipTypeId, Integer lastTime) {
+        Date date = new Date();
+        AssoPersonVipType assoPersonVip = new AssoPersonVipType();
+        assoPersonVip.setCreateTime(date);
+
+        Date expiryDate = DateUtils.getPlusMonthDate(date, lastTime);
+        assoPersonVip.setExpitrTime(expiryDate);
+        assoPersonVip.setPersonId(personUuid);
+        assoPersonVip.setVipTypeId(vipTypeId);
+        assoPersonVip.insert();
+        return assoPersonVip;
+    }
+
+    public AssoPersonVipType updateAssoPersonVip(AssoPersonVipType assoPersonVipType, Integer lastTime) {
+        Date expitrTime = assoPersonVipType.getExpitrTime();
+        Date date = new Date();
+        if (expitrTime.compareTo(date) < 0) {
+            expitrTime = date;
+        }
+        expitrTime = DateUtils.getPlusMonthDate(expitrTime, lastTime);
+        assoPersonVipType.setExpitrTime(expitrTime);
+
+        this.updateById(assoPersonVipType);
+        return assoPersonVipType;
+    }
+
+
+    public void lastPersonVip(Integer personId) {
+        Integer vipTypeId;
+        //查询登录人是否有vip
+        LambdaQueryWrapper<AssoPersonVipType> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AssoPersonVipType::getPersonId, personId)
+                .orderByDesc(AssoPersonVipType::getCreateTime);
+        AssoPersonVipType assoPersonVipType = this.getOne(queryWrapper, false);
+        if (assoPersonVipType == null) {
+            AppVipType appVipType = appVipTypeService.getOne(new LambdaQueryWrapper<>(), false);
+            vipTypeId = appVipType.getTenantVipTypeId();
+        } else {
+            vipTypeId = assoPersonVipType.getVipTypeId();
+        }
+        this.addVip(personId, vipTypeId, 1);
+    }
+
+    public Integer getPersonVipId(Integer personId) {
+        Integer vipId = null;
+        LambdaQueryWrapper<AssoPersonVipType> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AssoPersonVipType::getPersonId, personId)
+                .gt(AssoPersonVipType::getExpitrTime, new Date())
+                .orderByDesc(AssoPersonVipType::getCreateTime);
+        AssoPersonVipType assoPersonVipType = this.getOne(queryWrapper, false);
+        if (assoPersonVipType != null) {
+            vipId = assoPersonVipType.getVipTypeId();
+        }
+        return vipId;
+    }
+
+    public PersonVipMessVO getPersonVipMessage(Integer personId) {
+        PersonVipMessVO personVipMessVO = new PersonVipMessVO();
+        personVipMessVO.setIfInVip(true);
+        Integer vipId = this.getPersonVipId(personId);
+        if(vipId==null){
+            personVipMessVO.setIfInVip(false);
+        }
+        Date expitrTime = null;
+        if (vipId == null) {
+            LambdaQueryWrapper<AssoPersonVipType> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AssoPersonVipType::getPersonId, personId)
+                    .orderByDesc(AssoPersonVipType::getExpitrTime);
+            AssoPersonVipType assoPersonVipType = this.getOne(queryWrapper, false);
+            if (assoPersonVipType != null) {
+                vipId = assoPersonVipType.getVipTypeId();
+                expitrTime = assoPersonVipType.getExpitrTime();
+            }
+
+        }
+        if(vipId!=null){
+            LambdaQueryWrapper<AssoPersonVipType> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(AssoPersonVipType::getVipTypeId, vipId);
+             AssoPersonVipType assoPersonVipType =this.getOne(queryWrapper,false);
+            expitrTime=assoPersonVipType.getExpitrTime();
+          TenantVipType tenantVipType =  tenantVipTypeService.getById(vipId);
+
+        personVipMessVO.setVipTypeName(tenantVipType.getTenantVipName());
+         personVipMessVO.setId(vipId);
+         personVipMessVO.setExpitrTime(expitrTime);
+        }
+        return  personVipMessVO;
+    }
+}
+
+
+
+

+ 134 - 0
PCS/src/main/java/cn/cslg/permission/service/qiaobi/QiaoBiPersonService.java

@@ -0,0 +1,134 @@
+package cn.cslg.permission.service.qiaobi;
+
+import cn.cslg.permission.common.core.business.LoginCacheKeyUtil;
+import cn.cslg.permission.common.core.business.SmsService;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiPersonSignUpDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.common.utils.RedisUtil;
+import cn.cslg.permission.common.utils.RegexUtil;
+import cn.cslg.permission.common.utils.StringUtils;
+import cn.cslg.permission.domain.PersonInvitationCode;
+import cn.cslg.permission.domain.Personnel;
+import cn.cslg.permission.exception.ExceptionEnum;
+import cn.cslg.permission.exception.XiaoShiException;
+import cn.cslg.permission.service.PersonInvitationCodeService;
+import cn.cslg.permission.service.PersonnelService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.Data;
+import org.apache.commons.lang3.RegExUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class QiaoBiPersonService {
+    @Autowired
+    private PersonnelService personnelService;
+    @Autowired
+    private PersonInvitationCodeService personInvitationCodeService;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private AssoPersonVipTypeService assoPersonVipTypeService;
+    @Autowired
+    private SmsService smsService;
+
+    @Transactional(rollbackFor = Exception.class)
+    public QiaoBiPersonSignUpDTO personSignUp(QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO) {
+        String phoneNum = qiaoBiPersonSignUpDTO.getPhoneNum();
+        String inviteCode = qiaoBiPersonSignUpDTO.getInviteCode();
+        Integer vipTypeId = qiaoBiPersonSignUpDTO.getVipType();
+        //验证参数是否正确
+        this.checkMessage(qiaoBiPersonSignUpDTO);
+        this.checkPersonInvalid(qiaoBiPersonSignUpDTO);
+        //添加人员
+        qiaoBiPersonSignUpDTO = personnelService.addPhoneSignUpPerson(qiaoBiPersonSignUpDTO);
+        //绑定版本
+        assoPersonVipTypeService.addVip(qiaoBiPersonSignUpDTO.getId(), vipTypeId, null);
+        //执行邀请逻辑
+        if (inviteCode != null && !inviteCode.trim().equals("")) {
+            LambdaQueryWrapper<PersonInvitationCode> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(PersonInvitationCode::getInvitationCode, inviteCode);
+            PersonInvitationCode personInvitationCode = personInvitationCodeService.getOne(queryWrapper, false);
+            //根据邀请码查找人员
+            Integer personId = personInvitationCode.getPersonId();
+            assoPersonVipTypeService.lastPersonVip(personId);
+        }
+        redisUtil.delete(LoginCacheKeyUtil.getLoginCaptcha(phoneNum));
+        smsService.sendQiaoBiMessage(qiaoBiPersonSignUpDTO.getPhoneNum(), qiaoBiPersonSignUpDTO.getPassword());
+        return qiaoBiPersonSignUpDTO;
+    }
+
+    /**
+     * 校验参数
+     *
+     * @param qiaoBiPersonSignUpDTO
+     */
+    private void checkMessage(QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO) {
+        String phoneNum = qiaoBiPersonSignUpDTO.getPhoneNum();
+        Integer vipType = qiaoBiPersonSignUpDTO.getVipType();
+        String phoneCode = qiaoBiPersonSignUpDTO.getPhoneCode();
+        String inviteCode = qiaoBiPersonSignUpDTO.getInviteCode();
+        if (phoneCode == null || phoneCode.trim().equals("")) {
+            throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "验证码不可为空");
+        }
+        if (phoneNum == null || phoneNum.trim().equals("")) {
+            throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "手机号不可为空");
+        }
+        if (!RegexUtil.isPhoneLegal(phoneNum)) {
+            throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "手机号格式错误");
+        }
+        if (vipType == null) {
+            throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "请选择版本");
+        }
+
+        String code = redisUtil.get(LoginCacheKeyUtil.getLoginCaptcha(phoneNum));
+        if (!phoneCode.equals(code)) {
+            throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "验证码错误");
+        }
+        if (inviteCode != null && !inviteCode.trim().equals("")) {
+            LambdaQueryWrapper<PersonInvitationCode> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(PersonInvitationCode::getInvitationCode, inviteCode);
+            PersonInvitationCode personInvitationCode = personInvitationCodeService.getOne(queryWrapper, false);
+            if (personInvitationCode == null) {
+                throw new XiaoShiException(ExceptionEnum.BUSINESS_CHECK, "邀请码不存在");
+            }
+            qiaoBiPersonSignUpDTO.setInviteCode(personInvitationCode.getPersonId().toString());
+        }
+
+    }
+
+    /**
+     * 校验用户是否已注册
+     *
+     * @param qiaoBiPersonSignUpDTO
+     */
+    private void checkPersonInvalid(QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO) {
+        String phoneNum = qiaoBiPersonSignUpDTO.getPhoneNum();
+        String username = qiaoBiPersonSignUpDTO.getUsername();
+        String email = qiaoBiPersonSignUpDTO.getEmail();
+        //根据手机号查询用户
+        LambdaQueryWrapper<Personnel> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(Personnel::getPersonnelPhone, phoneNum);
+        if (username != null && !username.trim().equals("")) {
+            queryWrapper.or().eq(Personnel::getPersonnelUserName, username);
+        }
+        if (email != null && !email.trim().equals("")) {
+            queryWrapper.or().eq(Personnel::getPersonnelEmail, email);
+        }
+        Personnel personnel = personnelService.getOne(queryWrapper, false);
+        if (personnel != null) {
+            if (phoneNum.equals(personnel.getPersonnelPhone())) {
+                throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_EXIST, "手机号码已存在");
+            } else if (email != null && email.equals(personnel.getPersonnelEmail())) {
+                throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_EXIST, "邮箱已存在");
+            } else if (username != null && username.equals(personnel.getPersonnelUserName())) {
+                throw new XiaoShiException(ExceptionEnum.THE_PERSONNEL_IS_EXIST, "账号已存在");
+
+            }
+        }
+
+
+    }
+
+}

+ 23 - 16
PCS/src/main/resources/application-dev.yml

@@ -1,23 +1,23 @@
 spring:
   #    # 使用 smtp 协议
-  #  mail.protocol: smtps
-  #  mail.host: smtp.exmail.qq.com
-  #  mail.port: 465
-  #  mail.username: shenyongyi@china-wispro.com
-  #    # 授权码
-  #  mail.password: c3hY5cgAexhhr9HL
-  #  mail.test-connection: false
-  #  mail.properties.mail.smtp.auth: true
-  #  mail.properties.mail.debug: false
-  #  mail.properties.mail.mime.splitlongparameters: false
-  #  mail.default-encoding: UTF-8
-  # rabbitmq
-  rabbitmq.host: 192.168.1.24
+  #  #  mail.protocol: smtps
+  #  #  mail.host: smtp.exmail.qq.com
+  #  #  mail.port: 465
+  #  #  mail.username: shenyongyi@china-wispro.com
+  #  #    # 授权码
+  #  #  mail.password: c3hY5cgAexhhr9HL
+  #  #  mail.test-connection: false
+  #  #  mail.properties.mail.smtp.auth: true
+  #  #  mail.properties.mail.debug: false
+  #  #  mail.properties.mail.mime.splitlongparameters: false
+  #  #  mail.default-encoding: UTF-8
+  #  # rabbitmq
+  rabbitmq.host: 192.168.2.24
   rabbitmq.port: 5672
   rabbitmq.username: admin
   rabbitmq.password: 123456
   redis:
-    host: 192.168.1.24
+    host: 192.168.2.24
     port: 6379
     database: 3
     password: Xx0GWxdWQJxx6Swe
@@ -29,7 +29,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://192.168.1.24:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://192.168.2.24:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: rrzTwWAYX8Gxh5JH
     driver-class-name: com.mysql.cj.jdbc.Driver
@@ -40,4 +40,11 @@ spring:
         login-password: 123456
       web-stat-filter:
         exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
-queueName: emailProd.queue
+queueName: emailProd.queue
+##################  邀请注册页面 ####################
+inviteSignInLink: http://47.116.194.135:8078/register
+##################  短信 ####################
+SMS:
+  regionId: cn-shanghai
+  accessKeyId: LTAI5tGyG1Q7fKprgg1nWhXj
+  secret: Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN

+ 8 - 1
PCS/src/main/resources/application-prodNetIn.yml

@@ -43,4 +43,11 @@ spring:
 springdoc:
   api-docs:
     enabled: false
-queueName: emailProd.queue
+queueName: emailProd.queue
+##################  邀请注册页面 ####################
+inviteSignInLink: http://47.116.194.135:8078/register
+##################  短信 ####################
+SMS:
+  regionId: cn-shanghai
+  accessKeyId: LTAI5tGyG1Q7fKprgg1nWhXj
+  secret: Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN

+ 8 - 1
PCS/src/main/resources/application-prodNetOut.yml

@@ -40,4 +40,11 @@ spring:
         login-password: Cslg2022+
       web-stat-filter:
         exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
-queueName: emailProd.queue
+queueName: emailProd.queue
+##################  邀请注册页面 ####################
+inviteSignInLink: http://47.116.194.135:8078/register
+##################  短信 ####################
+SMS:
+  regionId: cn-shanghai
+  accessKeyId: LTAI5tGyG1Q7fKprgg1nWhXj
+  secret: Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN

+ 8 - 1
PCS/src/main/resources/application-testNetIn.yml

@@ -40,4 +40,11 @@ spring:
         login-password: 123456
       web-stat-filter:
         exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
-queueName: emailTest.queue
+queueName: emailTest.queue
+##################  邀请注册页面 ####################
+inviteSignInLink: http://47.116.194.135:8078/register
+##################  短信 ####################
+SMS:
+  regionId: cn-shanghai
+  accessKeyId: LTAI5tGyG1Q7fKprgg1nWhXj
+  secret: Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN

+ 9 - 2
PCS/src/main/resources/application-testNetOut.yml

@@ -29,7 +29,7 @@ spring:
         max-wait: -1ms
     timeout: 2000ms
   datasource:
-    url: jdbc:mysql://47.101.137.223:3306/PCS_TEST?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
+    url: jdbc:mysql://47.101.137.223:3306/PCS_TEST3?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=GMT%2B8
     username: root
     password: TU5x6IeBi7rl
     driver-class-name: com.mysql.cj.jdbc.Driver
@@ -40,4 +40,11 @@ spring:
         login-password: 123456
       web-stat-filter:
         exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
-queueName: emailTest.queue
+queueName: emailTest.queue
+##################  邀请注册页面 ####################
+inviteSignInLink: http://47.116.194.135:8078/register
+##################  短信 ####################
+SMS:
+  regionId: cn-shanghai
+  accessKeyId: LTAI5tGyG1Q7fKprgg1nWhXj
+  secret: Y6Erboh5lEFiRPR4XK8oCPMvUzYGLN

+ 18 - 0
PCS/src/main/resources/mapper/AppVipTypeMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.cslg.permission.mapper.qiaobi.AppVipTypeMapper">
+
+
+    <select id="queryQiaobiVipTypeVOs" resultType="cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO">
+        select vip.ID as vipTypeId,vip.TENANT_VIP_NAME as vipTypeName from APP_VIP_TYPE as app left join TENANT_VIP_TYPE as vip on
+        app.TENANT_VIP_TYPE_ID = vip.ID
+        <where>
+            app.APPLICATION_CODE =#{appCode}
+            <if test="vipTypeName!=null">
+              and  vip.TENANT_VIP_NAME like concat('%', #{vipTypeName}, '%')
+            </if>
+        </where>
+    </select>
+</mapper>

+ 19 - 0
PCS/src/main/resources/mapper/AssoPersonVipTypeMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.cslg.permission.mapper.qiaobi.AssoPersonVipTypeMapper">
+
+    <resultMap id="BaseResultMap" type="cn.cslg.permission.domain.qiaobi.AssoPersonVipType">
+            <result property="id" column="ID" jdbcType="INTEGER"/>
+            <result property="personId" column="PERSON_ID" jdbcType="INTEGER"/>
+            <result property="vipTypeId" column="VIP_TYPE_ID" jdbcType="INTEGER"/>
+            <result property="createTime" column="CREATE_TIME" jdbcType="TIMESTAMP"/>
+            <result property="expitrTime" column="EXPITR_TIME" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        ID,PERSON_ID,VIP_TYPE_ID,
+        CREATE_TIME,EXPITR_TIME
+    </sql>
+</mapper>

+ 2 - 1
PCS/src/main/resources/mapper/TenantVipTypeMapper.xml

@@ -30,8 +30,9 @@
         CREATE_TIME
         from TENANT_VIP_TYPE
         <where>
+            USE_TYPE is null
             <if test="likeName != null">
-                TENANT_VIP_NAME like #{likeName} or CREATE_PERSON_NAME like #{likeName}
+             and   (TENANT_VIP_NAME like #{likeName} or CREATE_PERSON_NAME like #{likeName})
             </if>
         </where>
         order by

+ 42 - 0
PCS/src/test/java/cn/cslg/permission/AppVipTypeTest.java

@@ -0,0 +1,42 @@
+package cn.cslg.permission;
+
+import cn.cslg.permission.common.model.dto.EncryptionLoginDTO;
+import cn.cslg.permission.common.model.dto.PhoneLoginDTO;
+import cn.cslg.permission.common.model.dto.SendCodeDTO;
+import cn.cslg.permission.common.model.personnel.UploadPersonnelConfigDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.service.LoginService;
+import cn.cslg.permission.service.qiaobi.AppVipTypeService;
+import cn.hutool.crypto.SecureUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class AppVipTypeTest {
+    @Autowired
+    private AppVipTypeService appVipTypeService;
+@Test
+    public void uploadPersonnelConfigPCSTest2() throws IOException {
+    QiaoBiVipTypeDTO qiaoBiVipTypeDTO =new QiaoBiVipTypeDTO();
+    qiaoBiVipTypeDTO.setVipTypeName("个人");
+         List<QiaoBiVIPTypeVO> qiaoBiVIPTypeVOList= appVipTypeService.qiaoBiVIPTypeVOList(qiaoBiVipTypeDTO);
+    System.out.println(qiaoBiVIPTypeVOList);
+}
+
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 130 - 0
PCS/src/test/java/cn/cslg/permission/EncryptionPersonTest.java


+ 74 - 0
PCS/src/test/java/cn/cslg/permission/PersonTest.java

@@ -0,0 +1,74 @@
+package cn.cslg.permission;
+
+import cn.cslg.permission.common.core.business.LoginCacheKeyUtil;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiPersonSignUpDTO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVIPTypeVO;
+import cn.cslg.permission.common.model.qiaobi.QiaoBiVipTypeDTO;
+import cn.cslg.permission.common.utils.RandomUtil;
+import cn.cslg.permission.common.utils.RedisUtil;
+import cn.cslg.permission.domain.Personnel;
+import cn.cslg.permission.service.PersonnelService;
+import cn.cslg.permission.service.qiaobi.AppVipTypeService;
+import cn.cslg.permission.service.qiaobi.QiaoBiPersonService;
+import cn.hutool.crypto.SecureUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.util.List;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class PersonTest {
+    @Autowired
+    private AppVipTypeService appVipTypeService;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private QiaoBiPersonService qiaoBiPersonService;
+    @Autowired
+    private PersonnelService personnelService;
+
+    @Test
+    public void uploadPersonnelConfigPCSTest2() throws IOException {
+        String phoneNum = "17625547167";
+        String random = RandomUtil.getSixRandom();
+        Integer vipTypeId = 19;
+        String email="2232141@qq.com";
+        String userName="zhangsansan";
+        String passWord ="12343545";
+        String name ="张赛男";
+        String intiteCode ="lDyp91RQ";
+        //手机号和验证码放进缓存 设置过期时间60s
+        redisUtil.set(LoginCacheKeyUtil.getLoginCaptcha(phoneNum), random);
+        QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO = new QiaoBiPersonSignUpDTO();
+        qiaoBiPersonSignUpDTO.setPhoneNum(phoneNum);
+        qiaoBiPersonSignUpDTO.setVipType(vipTypeId);
+        qiaoBiPersonSignUpDTO.setPhoneCode(random);
+        qiaoBiPersonSignUpDTO.setEmail(email);
+        qiaoBiPersonSignUpDTO.setName(name);
+        qiaoBiPersonSignUpDTO.setUsername(userName);
+        qiaoBiPersonSignUpDTO.setPassword(passWord);
+        qiaoBiPersonSignUpDTO.setInviteCode(intiteCode);
+        QiaoBiPersonSignUpDTO qiaoBiPersonSignUpDTO1 = qiaoBiPersonService.personSignUp(qiaoBiPersonSignUpDTO);
+        Integer personId = qiaoBiPersonSignUpDTO1.getId();
+
+       Personnel personnel= personnelService.getById(personId);
+//        personnelService.removeById(qiaoBiPersonSignUpDTO1.getId());
+
+           Assert.assertEquals(personnel.getPersonnelUserName(),userName);
+        Assert.assertEquals(personnel.getPersonnelName(),name);
+     Assert.assertEquals(personnel.getPersonnelPhone(),phoneNum);
+Assert.assertEquals(personnel.getPersonnelEmail(),email);
+Assert.assertEquals(personnel.getPersonnelPassword(),SecureUtil.md5(passWord));
+    }
+
+    private void deletePerson(Integer personId) {
+
+
+    }
+}

+ 19 - 0
PCS/src/test/java/cn/cslg/permission/SmsServiceTest.java

@@ -0,0 +1,19 @@
+package cn.cslg.permission;
+
+import cn.cslg.permission.common.core.business.SmsService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class SmsServiceTest {
+    @Autowired
+    private SmsService smsService;
+    @Test
+    public void sendQiaoBiMessage( ) {
+        smsService.sendQiaoBiMessage("17625547167","123456");
+    }
+}

+ 169 - 0
PCS/src/test/java/cn/cslg/permission/WritingAidTest.java

@@ -0,0 +1,169 @@
+package cn.cslg.permission;
+
+import cn.cslg.permission.common.model.dto.EncryptionLoginDTO;
+import cn.cslg.permission.common.model.dto.PhoneLoginDTO;
+import cn.cslg.permission.common.model.dto.SendCodeDTO;
+import cn.cslg.permission.common.model.personnel.UploadPersonnelConfigDTO;
+import cn.cslg.permission.common.model.vo.PhoneLoginVO;
+import cn.hutool.crypto.SecureUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class WritingAidTest {
+
+//    public String uploadPersonnelConfigPCSTest2(UploadPersonnelConfigDTO vo) throws IOException {
+//        String param = new Gson().toJson(vo);
+//        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+//        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+//                .connectTimeout(60, TimeUnit.SECONDS)
+//                .writeTimeout(60, TimeUnit.SECONDS)
+//                .readTimeout(60, TimeUnit.SECONDS)
+//                .build();
+//        Request request = new Request.Builder()
+//                .url("http://47.116.194.135:8085" + "/api/permission/api/personnel/uploadPersonnelConfig")
+//                .post(requestBody)
+//                .build();
+//        return Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+//    }
+
+    @Test
+    public void AccountLoginPCSTest2() throws Exception {
+        String appKey = "4e95e3d926a2a4befa5d913acc0aa9f5";
+        EncryptionLoginDTO encryptionLoginDTO = new EncryptionLoginDTO();
+        encryptionLoginDTO.setAppKey(appKey);
+        //登录账号
+        encryptionLoginDTO.setUsername("admin");
+//        encryptionLoginDTO.setUsername("zhuhao");
+        //登录密码
+        encryptionLoginDTO.setPassword("xiaoshi221101");
+//        encryptionLoginDTO.setPassword("xiaoshi221101");
+        //本机器的机器码,此处为伪造
+        encryptionLoginDTO.setMachineCode("BFEBFBFF000A0654");
+        long currentTimeMillis = System.currentTimeMillis();
+        encryptionLoginDTO.setCurrentTimeMillis(currentTimeMillis);
+        String appSecret = appKey + currentTimeMillis / 1000;
+        //md5加密标识
+        String md5Sign = SecureUtil.md5(appSecret);
+        encryptionLoginDTO.setSign(md5Sign);
+        String param = new Gson().toJson(encryptionLoginDTO);
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .build();
+        Request request = new Request.Builder()
+                .url("http://47.116.194.135:8085" + "/api/permission/api/admin/loginByEncryption")
+                .post(requestBody)
+                .build();
+        String res = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+        System.out.println(res);
+        JSONObject jsonObject = JSONObject.parseObject(res);
+        JSONObject jsonObject1 = jsonObject.getJSONObject("data");
+
+        String token = jsonObject1.getObject("token", String.class);
+        System.out.println(token);
+    }
+
+    @Test
+    public void uploadPersonnelConfigPCSTest2() throws IOException {
+        String token = "89_9iJkukncP5zspe_8EuigjI7tPxllFKk__";
+        UploadPersonnelConfigDTO vo = new UploadPersonnelConfigDTO();
+        vo.setPersonnelConfig("{\"124544845641532132\"}");
+        String param = new Gson().toJson(vo);
+
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .build();
+        Request request = new Request.Builder()
+                .url("http://47.116.194.135:8085" + "/api/permission/api/personnel/uploadPersonnelConfig")
+                .addHeader("Cookie", "token=" + token)
+                .post(requestBody)
+                .build();
+        String res = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+        System.out.println(res);
+    }
+
+    @Test
+    public void getPhoneCodePCSTest2() throws IOException {
+        SendCodeDTO vo = new SendCodeDTO();
+        vo.setPhoneNum("15705220533");
+        String param = new Gson().toJson(vo);
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .build();
+        Request request = new Request.Builder()
+                .url("http://47.116.194.135:8085" + "/api/permission/api/admin/getPhoneCode")
+                .post(requestBody)
+                .build();
+        String res = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+        System.out.println(res);
+    }
+
+    @Test
+    public void loginByPhonePCSTest2() throws IOException {
+        String appKey = "4e95e3d926a2a4befa5d913acc0aa9f5";
+        PhoneLoginDTO vo = new PhoneLoginDTO();
+        vo.setAppKey(appKey);
+        vo.setPhoneNum("15705220533");
+        vo.setPhoneCode("702235");
+        vo.setMachineCode("BFEBFBFF000A0654");
+        long currentTimeMillis = System.currentTimeMillis();
+        vo.setCurrentTimeMillis(currentTimeMillis);
+        String appSecret = appKey + currentTimeMillis / 1000;
+        //md5加密标识
+        String md5Sign = SecureUtil.md5(appSecret);
+        vo.setSign(md5Sign);
+        String param = new Gson().toJson(vo);
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
+        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .build();
+        Request request = new Request.Builder()
+                .url("http://47.116.194.135:8085" + "/api/permission/api/admin/loginByPhone")
+                .post(requestBody)
+                .build();
+        String res = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+        System.out.println(res);
+    }
+
+    @Test
+    public void generateInvitationCodePCSTest2() throws IOException {
+        String token = "89_9iJkukncP5zspe_8EuigjI7tPxllFKk__";
+        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), "");
+        OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                .connectTimeout(60, TimeUnit.SECONDS)
+                .writeTimeout(60, TimeUnit.SECONDS)
+                .readTimeout(60, TimeUnit.SECONDS)
+                .build();
+        Request request = new Request.Builder()
+                .url("http://47.116.194.135:8085" + "/api/permission/api/admin/generateInvitationCode")
+                .addHeader("Cookie", "token=" + token)
+                .post(requestBody)
+                .build();
+        String res = Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
+        System.out.println(res);
+    }
+}