dongxin 1 год назад
Родитель
Сommit
bb47dbcf5c
24 измененных файлов с 1774 добавлено и 10 удалено
  1. 0 1
      authentication/src/main/java/com/jzg/controller/AppAuthController.java
  2. 14 0
      authentication/src/main/java/com/jzg/entity/SysUser.java
  3. 190 0
      commons/src/main/java/com/jzg/commons/entity/account/po/InvAccount.java
  4. 159 0
      commons/src/main/java/com/jzg/commons/entity/account/po/InvAccountCard.java
  5. 47 0
      commons/src/main/java/com/jzg/commons/entity/dto/AuthInfoAddParam.java
  6. 22 0
      commons/src/main/java/com/jzg/commons/entity/dto/BusinessInfoAddParam.java
  7. 20 0
      commons/src/main/java/com/jzg/commons/entity/po/SysUser.java
  8. 6 5
      commons/src/main/java/com/jzg/commons/entity/po/SysUserJzgApp.java
  9. 42 0
      commons/src/main/java/com/jzg/commons/entity/vo/AuthInfoVo.java
  10. 60 0
      commons/src/main/java/com/jzg/commons/util/UnionPayUtils.java
  11. 344 0
      commons/src/main/java/com/jzg/commons/util/sm/SM2.java
  12. 213 0
      commons/src/main/java/com/jzg/commons/util/sm/SM3.java
  13. 34 0
      tenant/organization/src/main/java/com/jzg/organization/component/UnionPayApiConfigurationProperties.java
  14. 309 0
      tenant/organization/src/main/java/com/jzg/organization/component/UnionPayRequestApiComponent.java
  15. 25 0
      tenant/organization/src/main/java/com/jzg/organization/component/request/UnionPayRequest.java
  16. 24 0
      tenant/organization/src/main/java/com/jzg/organization/component/response/UnionPayResponse.java
  17. 64 0
      tenant/organization/src/main/java/com/jzg/organization/controller/AppUserController.java
  18. 13 0
      tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserJzgAppMapper.java
  19. 30 0
      tenant/organization/src/main/java/com/jzg/organization/service/SysUserJzgAppService.java
  20. 110 0
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgAppServiceImpl.java
  21. 4 4
      tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java
  22. 13 0
      tenant/organization/src/main/resources/application-dev.yml
  23. 13 0
      tenant/organization/src/main/resources/application-test.yml
  24. 18 0
      tenant/organization/src/main/resources/mapper/SysUserJzgAppMapper.xml

+ 0 - 1
authentication/src/main/java/com/jzg/controller/AppAuthController.java

@@ -1,6 +1,5 @@
 package com.jzg.controller;
 
-
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.jzg.commons.constants.RedisKeyConstants;

+ 14 - 0
authentication/src/main/java/com/jzg/entity/SysUser.java

@@ -1,5 +1,6 @@
 package com.jzg.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.jzg.commons.core.base.BaseModel;
 import com.jzg.commons.entity.po.SysUserJzgApp;
 import com.jzg.commons.exception.SystemException;
@@ -31,7 +32,20 @@ public class SysUser extends BaseModel {
     @Schema(description = "账号状态")
     private Integer accountStatus;
 
+    @Schema(description = "认证状态 0.未认证 1. 认证成功 2. 认证驳回")
+    private Integer authStatus;
 
+    @TableField(value = "identity")
+    @Schema(description = "身份证号")
+    private String identity;
+
+    @TableField(value = "identity_time_start")
+    @Schema(description = "身份证有效期起期")
+    private String identityTimeStart;
+
+    @TableField(value = "identity_time_end")
+    @Schema(description = "身份证有效期止期")
+    private String identityTimeEnd;
     /**
      * 验证用户
      *

+ 190 - 0
commons/src/main/java/com/jzg/commons/entity/account/po/InvAccount.java

@@ -0,0 +1,190 @@
+package com.jzg.commons.entity.account.po;
+
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 来往企业表
+ * @TableName inv_account
+ */
+@Data
+public class InvAccount implements Serializable {
+    /**
+     * 账户id
+     */
+    private Long accountId;
+
+    /**
+     * 户名
+     */
+    private String accountName;
+
+    /**
+     * 企业类型(0内部企业 1外部企业)
+     */
+    private String outerFlag;
+
+    /**
+     * 营业性质(3一般纳税 2小规模 1个体户)
+     */
+    private String businessQuality;
+
+    /**
+     * 所属地
+     */
+    private String owned;
+
+    /**
+     * 法人
+     */
+    private String juridicalPerson;
+
+    /**
+     * 成立日期
+     */
+    private Date establishTime;
+
+    /**
+     * 开票员
+     */
+    private String biller;
+
+    /**
+     * 开票额度
+     */
+    private String invoicingAmount;
+
+    /**
+     * 剩余开票额度
+     */
+    private String invoicingAmountExcess;
+
+    /**
+     * 季度开票额度
+     */
+    private String quarterInvoicingAmount;
+
+    /**
+     * 总开票额度
+     */
+    private String sumInvoicingAmount;
+
+    /**
+     * 暂估
+     */
+    private String tentativeEstimates;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public boolean equals(Object that) {
+        if (this == that) {
+            return true;
+        }
+        if (that == null) {
+            return false;
+        }
+        if (getClass() != that.getClass()) {
+            return false;
+        }
+        InvAccount other = (InvAccount) that;
+        return (this.getAccountId() == null ? other.getAccountId() == null : this.getAccountId().equals(other.getAccountId()))
+            && (this.getAccountName() == null ? other.getAccountName() == null : this.getAccountName().equals(other.getAccountName()))
+            && (this.getOuterFlag() == null ? other.getOuterFlag() == null : this.getOuterFlag().equals(other.getOuterFlag()))
+            && (this.getBusinessQuality() == null ? other.getBusinessQuality() == null : this.getBusinessQuality().equals(other.getBusinessQuality()))
+            && (this.getOwned() == null ? other.getOwned() == null : this.getOwned().equals(other.getOwned()))
+            && (this.getJuridicalPerson() == null ? other.getJuridicalPerson() == null : this.getJuridicalPerson().equals(other.getJuridicalPerson()))
+            && (this.getEstablishTime() == null ? other.getEstablishTime() == null : this.getEstablishTime().equals(other.getEstablishTime()))
+            && (this.getBiller() == null ? other.getBiller() == null : this.getBiller().equals(other.getBiller()))
+            && (this.getInvoicingAmount() == null ? other.getInvoicingAmount() == null : this.getInvoicingAmount().equals(other.getInvoicingAmount()))
+            && (this.getInvoicingAmountExcess() == null ? other.getInvoicingAmountExcess() == null : this.getInvoicingAmountExcess().equals(other.getInvoicingAmountExcess()))
+            && (this.getQuarterInvoicingAmount() == null ? other.getQuarterInvoicingAmount() == null : this.getQuarterInvoicingAmount().equals(other.getQuarterInvoicingAmount()))
+            && (this.getSumInvoicingAmount() == null ? other.getSumInvoicingAmount() == null : this.getSumInvoicingAmount().equals(other.getSumInvoicingAmount()))
+            && (this.getTentativeEstimates() == null ? other.getTentativeEstimates() == null : this.getTentativeEstimates().equals(other.getTentativeEstimates()))
+            && (this.getCreateBy() == null ? other.getCreateBy() == null : this.getCreateBy().equals(other.getCreateBy()))
+            && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
+            && (this.getUpdateBy() == null ? other.getUpdateBy() == null : this.getUpdateBy().equals(other.getUpdateBy()))
+            && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()))
+            && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((getAccountId() == null) ? 0 : getAccountId().hashCode());
+        result = prime * result + ((getAccountName() == null) ? 0 : getAccountName().hashCode());
+        result = prime * result + ((getOuterFlag() == null) ? 0 : getOuterFlag().hashCode());
+        result = prime * result + ((getBusinessQuality() == null) ? 0 : getBusinessQuality().hashCode());
+        result = prime * result + ((getOwned() == null) ? 0 : getOwned().hashCode());
+        result = prime * result + ((getJuridicalPerson() == null) ? 0 : getJuridicalPerson().hashCode());
+        result = prime * result + ((getEstablishTime() == null) ? 0 : getEstablishTime().hashCode());
+        result = prime * result + ((getBiller() == null) ? 0 : getBiller().hashCode());
+        result = prime * result + ((getInvoicingAmount() == null) ? 0 : getInvoicingAmount().hashCode());
+        result = prime * result + ((getInvoicingAmountExcess() == null) ? 0 : getInvoicingAmountExcess().hashCode());
+        result = prime * result + ((getQuarterInvoicingAmount() == null) ? 0 : getQuarterInvoicingAmount().hashCode());
+        result = prime * result + ((getSumInvoicingAmount() == null) ? 0 : getSumInvoicingAmount().hashCode());
+        result = prime * result + ((getTentativeEstimates() == null) ? 0 : getTentativeEstimates().hashCode());
+        result = prime * result + ((getCreateBy() == null) ? 0 : getCreateBy().hashCode());
+        result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
+        result = prime * result + ((getUpdateBy() == null) ? 0 : getUpdateBy().hashCode());
+        result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
+        result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName());
+        sb.append(" [");
+        sb.append("Hash = ").append(hashCode());
+        sb.append(", accountId=").append(accountId);
+        sb.append(", accountName=").append(accountName);
+        sb.append(", outerFlag=").append(outerFlag);
+        sb.append(", businessQuality=").append(businessQuality);
+        sb.append(", owned=").append(owned);
+        sb.append(", juridicalPerson=").append(juridicalPerson);
+        sb.append(", establishTime=").append(establishTime);
+        sb.append(", biller=").append(biller);
+        sb.append(", invoicingAmount=").append(invoicingAmount);
+        sb.append(", invoicingAmountExcess=").append(invoicingAmountExcess);
+        sb.append(", quarterInvoicingAmount=").append(quarterInvoicingAmount);
+        sb.append(", sumInvoicingAmount=").append(sumInvoicingAmount);
+        sb.append(", tentativeEstimates=").append(tentativeEstimates);
+        sb.append(", createBy=").append(createBy);
+        sb.append(", createTime=").append(createTime);
+        sb.append(", updateBy=").append(updateBy);
+        sb.append(", updateTime=").append(updateTime);
+        sb.append(", isDelete=").append(isDelete);
+        sb.append(", serialVersionUID=").append(serialVersionUID);
+        sb.append("]");
+        return sb.toString();
+    }
+}

+ 159 - 0
commons/src/main/java/com/jzg/commons/entity/account/po/InvAccountCard.java

@@ -0,0 +1,159 @@
+package com.jzg.commons.entity.account.po;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jzg.commons.core.base.BaseModel;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 账户信息表
+ * @TableName inv_account_card
+ */
+@Schema(description = "账户信息表")
+@Data
+public class InvAccountCard extends BaseModel {
+    /**
+     * 账户id
+     */
+    @Schema(description = "主键")
+    private Long id;
+
+    /**
+     * 账户简称
+     */
+    @Schema(description = "账户简称")
+    private String cardName;
+
+    /**
+     * 银行卡号
+     */
+    @Schema(description = "银行卡号")
+    private String bankCardNum;
+
+    /**
+     * 账户id
+     */
+    @Schema(description = "账户id")
+    private Long accountId;
+
+    /**
+     * 账户性质(0公户 1私户)
+     */
+    @Schema(description = "账户性质(0公户 1私户)")
+    private String accountQuality;
+
+    /**
+     * 开户行名称
+     */
+    @Schema(description = "开户行名称")
+    private String bankName;
+
+    /**
+     * 开户行
+     */
+    @Schema(description = "开户行")
+    private String bank;
+
+    @Schema(description = "开户行号")
+    private String bankNum;
+
+    /**
+     * 证书有效期开始
+     */
+    @Schema(description = "证书有效期开始")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime startCertExpirationDate;
+
+    /**
+     * 证书有效期结束
+     */
+    @Schema(description = "证书有效期结束")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime endCertExpirationDate;
+
+    /**
+     * 余额
+     */
+    @Schema(description = "余额")
+    private String balance;
+
+    /**
+     * 支出
+     */
+    @Schema(description = "支出")
+    private String spend;
+
+    /**
+     * 单日转账笔数限制
+     */
+    @Schema(description = "单日转账笔数限制")
+    private String dayStrokeNum;
+
+    /**
+     * 单日转账笔数剩余
+     */
+    @Schema(description = "单日转账笔数剩余")
+    private String dayStrokeNumExcess;
+
+    /**
+     * 对私单日限额
+     */
+    @Schema(description = "对私单日限额")
+    private String priDayLines;
+
+    /**
+     * 对私单笔限额
+     */
+    @Schema(description = "对私单笔限额")
+    private String priSingleLines;
+
+    /**
+     * 对私单日限额剩余
+     */
+    @Schema(description = "对私单日限额剩余")
+    private String priDayLinesExcess;
+
+    /**
+     * 对私年额度
+     */
+    @Schema(description = "对私年额度")
+    private String priYearLines;
+
+    /**
+     * 对私年剩余额度
+     */
+    @Schema(description = "对私年剩余额度")
+    private String priYearExcess;
+
+    /**
+     * 对公单笔限额
+     */
+    @Schema(description = "对公单笔限额")
+    private String pubSingleLines;
+
+    /**
+     * 对公年额度
+     */
+    @Schema(description = "对公年额度")
+    private String pubYearLines;
+
+    /**
+     * 对公单日限额
+     */
+    private String pubDayLines;
+
+    /**
+     * 对公年剩余额度
+     */
+    private String pubYearExcess;
+
+    /**
+     * 对公单日限额剩余
+     */
+    private String pubDayLinesExcess;
+
+}

+ 47 - 0
commons/src/main/java/com/jzg/commons/entity/dto/AuthInfoAddParam.java

@@ -0,0 +1,47 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.entity.po.SysUserJzgInfoFile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "实名信息新增dto")
+@Data
+public class AuthInfoAddParam {
+
+    @Schema(description = "用户id")
+    @NotNull(message = "用户id不能为空")
+    private String userId;
+
+    @Schema(description = "姓名")
+    @NotNull(message = "姓名不能为空")
+    private String name;
+
+    @Schema(description = "手机")
+    @NotNull(message = "手机不能为空")
+    private String mobile;
+
+    @Schema(description = "身份证号")
+    @NotNull(message = "身份证号不能为空")
+    private String identity;
+
+    @Schema(description = "身份证有效期起期")
+    //    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @NotNull(message = "身份证有效期起期不能为空")
+    private LocalDate identityTimeStart;
+
+    @Schema(description = "身份证有效期止期")
+    //    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @NotNull(message = "身份证有效期止期不能为空")
+    private LocalDate identityTimeEnd;
+
+    @NotEmpty(message = "身份证图片不能为空")
+    @Schema(description = "身份证图片数组")
+    private List<SysUserJzgInfoFile> fileList;
+
+}

+ 22 - 0
commons/src/main/java/com/jzg/commons/entity/dto/BusinessInfoAddParam.java

@@ -0,0 +1,22 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.entity.po.SysUserJzgInfoFile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "展业资格证信息保存dto")
+@Data
+public class BusinessInfoAddParam {
+
+    @Schema(description = "用户id")
+    @NotNull(message = "用户id不能为空")
+    private String userId;
+
+    @NotEmpty(message = "展业资格证图片不能为空")
+    @Schema(description = "展业资格证图片数组")
+    private SysUserJzgInfoFile file;
+}

+ 20 - 0
commons/src/main/java/com/jzg/commons/entity/po/SysUser.java

@@ -12,6 +12,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.time.LocalDate;
+
 import static com.jzg.commons.constants.Constants.DEFAULT_PASSWORD;
 
 /**
@@ -45,10 +47,28 @@ public class SysUser extends BaseModel{
     @Schema(description = "手机号")
     private String mobile;
 
+    @Schema(description = "用户头像")
+    private String headSculpture;
+
     /** 用户状态 : 1 正常 0 锁定 */
     @Schema(description = "用户状态 : 1 正常 0 锁定")
     private Integer accountStatus;
 
+    @Schema(description = "认证状态 0.未认证 1. 认证成功 2. 认证驳回")
+    private Integer authStatus;
+
+    @TableField(value = "identity")
+    @Schema(description = "身份证号")
+    private String identity;
+
+    @TableField(value = "identity_time_start")
+    @Schema(description = "身份证有效期起期")
+    private LocalDate identityTimeStart;
+
+    @TableField(value = "identity_time_end")
+    @Schema(description = "身份证有效期止期")
+    private LocalDate identityTimeEnd;
+
     public SysUser(SysSystemAddParam param) {
         this.username = param.getUserName();
         this.mobile = param.getUserAccount();

+ 6 - 5
commons/src/main/java/com/jzg/commons/entity/po/SysUserJzgApp.java

@@ -87,11 +87,6 @@ public class SysUserJzgApp extends BaseModel implements Serializable {
     @Schema(description = "推荐人id")
     private String referrerId;
 
-
-    @TableField(value = "factor_verify")
-    @Schema(description = "是否实名认证 0 未验证 1 已验证")
-    private String factorVerify;
-
     @TableField(value = "address")
     @Schema(description = "地址")
     private String address;
@@ -124,10 +119,16 @@ public class SysUserJzgApp extends BaseModel implements Serializable {
     @Schema(description = "上一次登录时间")
     private LocalDateTime lastLoginTime;
 
+    @TableField(value = "auth_result")
+    @Schema(description = "实名认证结果")
+    private String authResult;
+
     @TableField(value = "is_delete")
     @Schema(description = "是否删除 0未删除 1 删除")
     private Integer isDelete;
 
+
+
     public SysUserJzgApp(String userName, SysUser user, String systemCode, String deptId){
         this.userId = user.getId();
         //默认添加管理员账户

+ 42 - 0
commons/src/main/java/com/jzg/commons/entity/vo/AuthInfoVo.java

@@ -0,0 +1,42 @@
+package com.jzg.commons.entity.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.jzg.commons.entity.po.SysUserJzgInfoFile;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Schema(description = "实名认证信息VO")
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AuthInfoVo {
+
+    @Schema(description = "姓名")
+    private String name;
+
+    @Schema(description = "认证状态 0.未认证 1. 认证成功 2. 认证驳回")
+    private Integer authStatus;
+
+    @Schema(description = "手机")
+    private String mobile;
+
+    @Schema(description = "身份证号")
+    private String identity;
+
+    @Schema(description = "身份证有效期起期")
+    private String identityTimeStart;
+
+    @Schema(description = "身份证有效期止期")
+    private String identityTimeEnd;
+
+    @Schema(description = "用户id")
+    private String userId;
+
+    @Schema(description = "证件明细列表")
+    private List<SysUserJzgInfoFile> fileList;
+
+}

+ 60 - 0
commons/src/main/java/com/jzg/commons/util/UnionPayUtils.java

@@ -0,0 +1,60 @@
+package com.jzg.commons.util;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+
+public class UnionPayUtils {
+
+
+    /**
+     * 生成定长的随机数
+     *
+     * @param length
+     * @return
+     */
+    public static String createData(int length) {
+        StringBuilder sb = new StringBuilder();
+        Random rand = new Random();
+        for (int i = 0; i < length; i++) {
+            sb.append(rand.nextInt(10));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * SHA256算法
+     *
+     * @param value 需要加密的值
+     * @return 加密后的字符
+     */
+    public static String SHA256(String value) {
+        try {
+            // 创建SHA-256哈希算法的MessageDigest对象
+            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
+
+            // 使用SHA-256计算字符串的哈希值
+            byte[] hash = sha256.digest(value.getBytes(StandardCharsets.UTF_8));
+
+            // 将哈希值转换为十六进制字符串
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : hash) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) {
+                    hexString.append('0');
+                }
+                hexString.append(hex);
+            }
+            return hexString.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return "ERROR";
+    }
+
+
+}

+ 344 - 0
commons/src/main/java/com/jzg/commons/util/sm/SM2.java

@@ -0,0 +1,344 @@
+package com.jzg.commons.util.sm;
+
+
+import cn.hutool.core.codec.Base64;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECPoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+
+public class SM2 {
+    private final static Logger LOGGER = LoggerFactory.getLogger(SM2.class);
+
+
+    public static String sm2Encrypt(String plainText, String pubKey) {
+        byte[] data = SM2.encrypt(plainText, pubKey);
+        String enData = Base64.encode(data);
+        return enData;
+    }
+
+    public static String sm2Decrypt(String plainText, String priKey) {
+        byte[] encryptData = Base64.decode(plainText);
+        String rawData = SM2.decrypt(encryptData, priKey);
+        return rawData;
+    }
+
+    //国密办文件中推荐的椭圆曲线相关参数
+
+    private static BigInteger n = new BigInteger(
+            "FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "7203DF6B" + "21C6052B" + "53BBF409" + "39D54123", 16);
+    private static BigInteger p = new BigInteger(
+            "FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF" + "FFFFFFFF", 16);
+    private static BigInteger a = new BigInteger(
+            "FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF" + "FFFFFFFC", 16);
+    private static BigInteger b = new BigInteger(
+            "28E9FA9E" + "9D9F5E34" + "4D5A9E4B" + "CF6509A7" + "F39789F5" + "15AB8F92" + "DDBCBD41" + "4D940E93", 16);
+    private static BigInteger gx = new BigInteger(
+            "32C4AE2C" + "1F198119" + "5F990446" + "6A39C994" + "8FE30BBF" + "F2660BE1" + "715A4589" + "334C74C7", 16);
+    private static BigInteger gy = new BigInteger(
+            "BC3736A2" + "F4F6779C" + "59BDCEE3" + "6B692153" + "D0A9877C" + "C62A4740" + "02DF32E5" + "2139F0A0", 16);
+    private static final int DIGEST_LENGTH = 32;
+    private static SecureRandom random = new SecureRandom();
+    private static ECCurve.Fp curve = new ECCurve.Fp(p, a, b);
+    private static ECPoint G = curve.createPoint(gx, gy);
+    private static ECDomainParameters ecc_bc_spec = new ECDomainParameters(curve, G, n);
+
+    /**
+     * 以16进制打印字节数组
+     *
+     * @param b
+     */
+    public static void printHexString(byte[] b) {
+        for (int i = 0; i < b.length; i++) {
+            String hex = Integer.toHexString(b[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            System.out.print(hex.toUpperCase());
+        }
+        System.out.println();
+    }
+
+    /**
+     * 随机数生成器
+     *
+     * @param max
+     * @return
+     */
+    private static BigInteger random(BigInteger max) {
+
+        BigInteger r = new BigInteger(256, random);
+        while (r.compareTo(max) >= 0) {
+            r = new BigInteger(128, random);
+
+        }
+        return r;
+    }
+
+    /**
+     * 判断字节数组是否全0
+     *
+     * @param buffer
+     * @return
+     */
+    private static boolean allZero(byte[] buffer) {
+        for (int i = 0; i < buffer.length; i++) {
+            if (buffer[i] != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 公钥加密
+     *
+     * @param input     加密原文
+     * @param pubKeyStr 公钥
+     * @return
+     */
+    public static byte[] encrypt(String input, String pubKeyStr) {
+        ECPoint publicKey = curve.decodePoint(hexStr2Bytes(pubKeyStr));
+        byte[] inputBuffer = new byte[0];
+        try {
+            inputBuffer = input.getBytes("UTF8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        byte[] C1Buffer;
+        ECPoint kpb;
+        byte[] t;
+        do {
+            /* 1 产生随机数k,k属于[1, n-1] */
+            BigInteger k = random(n);
+            /* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */
+            ECPoint C1 = G.multiply(k);
+            C1Buffer = C1.getEncoded(false);
+            /*
+             * 3 计算椭圆曲线点 S = [h]Pb
+             */
+            BigInteger h = ecc_bc_spec.getH();
+            if (h != null) {
+                ECPoint S = publicKey.multiply(h);
+                if (S.isInfinity()) {
+                    throw new IllegalStateException();
+                }
+            }
+            /* 4 计算 [k]PB = (x2, y2) */
+            kpb = publicKey.multiply(k).normalize();
+            /* 5 计算 t = KDF(x2||y2, klen) */
+            byte[] kpbBytes = kpb.getEncoded(false);
+            t = KDF(kpbBytes, inputBuffer.length);
+        } while (allZero(t));
+        /* 6 计算C2=M^t */
+        byte[] C2 = new byte[inputBuffer.length];
+        for (int i = 0; i < inputBuffer.length; i++) {
+            C2[i] = (byte) (inputBuffer[i] ^ t[i]);
+        }
+        /* 7 计算C3 = Hash(x2 || M || y2) */
+        byte[] C3 = sm3hash(kpb.getXCoord().toBigInteger().toByteArray(), inputBuffer,
+                kpb.getYCoord().toBigInteger().toByteArray());
+        /* 8 输出密文 C=C1 || C2 || C3 */
+        byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];
+        System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length);
+        System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);
+        System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length, C3.length);
+        return encryptResult;
+    }
+
+    /**
+     * 私钥解密
+     *
+     * @param encryptData 密文数据字节数组
+     * @param priKeyStr   解密私钥
+     * @return
+     */
+    public static String decrypt(byte[] encryptData, String priKeyStr) {
+
+
+        BigInteger privateKey = new BigInteger(priKeyStr, 16);
+
+        byte[] C1Byte = new byte[65];
+        System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);
+
+        ECPoint C1 = curve.decodePoint(C1Byte).normalize();
+
+        /*
+         * 计算椭圆曲线点 S = [h]C1 是否为无穷点
+         */
+        BigInteger h = ecc_bc_spec.getH();
+        if (h != null) {
+            ECPoint S = C1.multiply(h);
+            if (S.isInfinity()) {
+                throw new IllegalStateException();
+            }
+        }
+        /* 计算[dB]C1 = (x2, y2) */
+        ECPoint dBC1 = C1.multiply(privateKey).normalize();
+
+        /* 计算t = KDF(x2 || y2, klen) */
+        byte[] dBC1Bytes = dBC1.getEncoded(false);
+        int klen = encryptData.length - 65 - DIGEST_LENGTH;
+        byte[] t = KDF(dBC1Bytes, klen);
+
+        if (allZero(t)) {
+            System.err.println("all zero");
+            throw new IllegalStateException();
+        }
+
+        /* 计算M'=C2^t */
+        byte[] M = new byte[klen];
+        for (int i = 0; i < M.length; i++) {
+            M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);
+        }
+
+        /*  计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成立 */
+        byte[] C3 = new byte[DIGEST_LENGTH];
+
+
+        System.arraycopy(encryptData, encryptData.length - DIGEST_LENGTH, C3, 0, DIGEST_LENGTH);
+        byte[] u = sm3hash(dBC1.getXCoord().toBigInteger().toByteArray(), M,
+                dBC1.getYCoord().toBigInteger().toByteArray());
+
+        if (Arrays.equals(u, C3)) {
+            try {
+                return new String(M, "UTF8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+            return null;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 判断是否在范围内
+     *
+     * @param param
+     * @param min
+     * @param max
+     * @return
+     */
+    private static boolean between(BigInteger param, BigInteger min, BigInteger max) {
+        if (param.compareTo(min) >= 0 && param.compareTo(max) < 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 判断生成的公钥是否合法
+     *
+     * @param publicKey
+     * @return
+     */
+    private static boolean checkPublicKey(ECPoint publicKey) {
+        if (!publicKey.isInfinity()) {
+            BigInteger x = publicKey.getXCoord().toBigInteger();
+            BigInteger y = publicKey.getYCoord().toBigInteger();
+            if (between(x, new BigInteger("0"), p) && between(y, new BigInteger("0"), p)) {
+                BigInteger xResult = x.pow(3).add(a.multiply(x)).add(b).mod(p);
+                BigInteger yResult = y.pow(2).mod(p);
+                if (yResult.equals(xResult) && publicKey.multiply(n).isInfinity()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 字节数组拼接
+     *
+     * @param params
+     * @return
+     */
+    private static byte[] join(byte[]... params) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] res = null;
+        try {
+            for (int i = 0; i < params.length; i++) {
+                baos.write(params[i]);
+            }
+            res = baos.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return res;
+    }
+
+    /**
+     * sm3摘要
+     * @param params
+     * @return
+     */
+    private static byte[] sm3hash(byte[]... params) {
+        byte[] res = null;
+        try {
+            res = SM3.hash(join(params));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return res;
+    }
+
+    /**
+     * 密钥派生函数
+     * @param Z
+     * @param klen 生成klen字节数长度的密钥
+     * @return
+     */
+    private static byte[] KDF(byte[] Z, int klen) {
+        int ct = 1;
+        int end = (int) Math.ceil(klen * 1.0 / 32);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            for (int i = 1; i < end; i++) {
+                baos.write(sm3hash(Z, SM3.toByteArray(ct)));
+                ct++;
+            }
+            byte[] last = sm3hash(Z, SM3.toByteArray(ct));
+            if (klen % 32 == 0) {
+                baos.write(last);
+            } else {
+                baos.write(last, 0, klen % 32);
+            }
+            return baos.toByteArray();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static byte[] hexStr2Bytes(String src) {
+        int l = src.length() / 2;
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; ++i) {
+            int m = i * 2 + 1;
+            int n = m + 1;
+            ret[i] = uniteBytes(src.substring(i * 2, m), src.substring(m, n));
+        }
+        return ret;
+    }
+
+    private static byte uniteBytes(String src0, String src1) {
+        byte b0 = Byte.decode("0x" + src0);
+        b0 = (byte) (b0 << 4);
+        byte b1 = Byte.decode("0x" + src1);
+        byte ret = (byte) (b0 | b1);
+        return ret;
+    }
+
+
+}

+ 213 - 0
commons/src/main/java/com/jzg/commons/util/sm/SM3.java

@@ -0,0 +1,213 @@
+package com.jzg.commons.util.sm;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Arrays;
+
+/**
+ * SM3杂凑算法实现
+ */
+public class SM3 {
+
+    private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
+            '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+    private static final String ivHexStr = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e";
+    private static final BigInteger IV = new BigInteger(ivHexStr.replaceAll(" ",
+            ""), 16);
+    private static final Integer Tj15 = Integer.valueOf("79cc4519", 16);
+    private static final Integer Tj63 = Integer.valueOf("7a879d8a", 16);
+    private static final byte[] FirstPadding = {(byte) 0x80};
+    private static final byte[] ZeroPadding = {(byte) 0x00};
+
+    private static int T(int j) {
+        if (j >= 0 && j <= 15) {
+            return Tj15.intValue();
+        } else if (j >= 16 && j <= 63) {
+            return Tj63.intValue();
+        } else {
+            throw new RuntimeException("data invalid");
+        }
+    }
+
+    private static Integer FF(Integer x, Integer y, Integer z, int j) {
+        if (j >= 0 && j <= 15) {
+            return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
+        } else if (j >= 16 && j <= 63) {
+            return Integer.valueOf((x.intValue() & y.intValue())
+                    | (x.intValue() & z.intValue())
+                    | (y.intValue() & z.intValue()));
+        } else {
+            throw new RuntimeException("data invalid");
+        }
+    }
+
+    private static Integer GG(Integer x, Integer y, Integer z, int j) {
+        if (j >= 0 && j <= 15) {
+            return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
+        } else if (j >= 16 && j <= 63) {
+            return Integer.valueOf((x.intValue() & y.intValue())
+                    | (~x.intValue() & z.intValue()));
+        } else {
+            throw new RuntimeException("data invalid");
+        }
+    }
+
+    private static Integer P0(Integer x) {
+        return Integer.valueOf(x.intValue()
+                ^ Integer.rotateLeft(x.intValue(), 9)
+                ^ Integer.rotateLeft(x.intValue(), 17));
+    }
+
+    private static Integer P1(Integer x) {
+        return Integer.valueOf(x.intValue()
+                ^ Integer.rotateLeft(x.intValue(), 15)
+                ^ Integer.rotateLeft(x.intValue(), 23));
+    }
+
+    private static byte[] padding(byte[] source) throws IOException {
+        if (source.length >= 0x2000000000000000l) {
+            throw new RuntimeException("src data invalid.");
+        }
+        long l = source.length * 8;
+        long k = 448 - (l + 1) % 512;
+        if (k < 0) {
+            k = k + 512;
+        }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        baos.write(source);
+        baos.write(FirstPadding);
+        long i = k - 7;
+        while (i > 0) {
+            baos.write(ZeroPadding);
+            i -= 8;
+        }
+        baos.write(long2bytes(l));
+        return baos.toByteArray();
+    }
+
+    private static byte[] long2bytes(long l) {
+        byte[] bytes = new byte[8];
+        for (int i = 0; i < 8; i++) {
+            bytes[i] = (byte) (l >>> ((7 - i) * 8));
+        }
+        return bytes;
+    }
+
+    public static byte[] hash(byte[] source) throws IOException {
+        byte[] m1 = padding(source);
+        int n = m1.length / (512 / 8);
+        byte[] b;
+        byte[] vi = IV.toByteArray();
+        byte[] vi1 = null;
+        for (int i = 0; i < n; i++) {
+            b = Arrays.copyOfRange(m1, i * 64, (i + 1) * 64);
+            vi1 = CF(vi, b);
+            vi = vi1;
+        }
+        return vi1;
+    }
+
+    private static byte[] CF(byte[] vi, byte[] bi) throws IOException {
+        int a, b, c, d, e, f, g, h;
+        a = toInteger(vi, 0);
+        b = toInteger(vi, 1);
+        c = toInteger(vi, 2);
+        d = toInteger(vi, 3);
+        e = toInteger(vi, 4);
+        f = toInteger(vi, 5);
+        g = toInteger(vi, 6);
+        h = toInteger(vi, 7);
+
+        int[] w = new int[68];
+        int[] w1 = new int[64];
+        for (int i = 0; i < 16; i++) {
+            w[i] = toInteger(bi, i);
+        }
+        for (int j = 16; j < 68; j++) {
+            w[j] = P1(w[j - 16] ^ w[j - 9] ^ Integer.rotateLeft(w[j - 3], 15))
+                    ^ Integer.rotateLeft(w[j - 13], 7) ^ w[j - 6];
+        }
+        for (int j = 0; j < 64; j++) {
+            w1[j] = w[j] ^ w[j + 4];
+        }
+        int ss1, ss2, tt1, tt2;
+        for (int j = 0; j < 64; j++) {
+            ss1 = Integer
+                    .rotateLeft(
+                            Integer.rotateLeft(a, 12) + e
+                                    + Integer.rotateLeft(T(j), j), 7);
+            ss2 = ss1 ^ Integer.rotateLeft(a, 12);
+            tt1 = FF(a, b, c, j) + d + ss2 + w1[j];
+            tt2 = GG(e, f, g, j) + h + ss1 + w[j];
+            d = c;
+            c = Integer.rotateLeft(b, 9);
+            b = a;
+            a = tt1;
+            h = g;
+            g = Integer.rotateLeft(f, 19);
+            f = e;
+            e = P0(tt2);
+        }
+        byte[] v = toByteArray(a, b, c, d, e, f, g, h);
+        for (int i = 0; i < v.length; i++) {
+            v[i] = (byte) (v[i] ^ vi[i]);
+        }
+        return v;
+    }
+
+    private static int toInteger(byte[] source, int index) {
+        StringBuilder valueStr = new StringBuilder("");
+        for (int i = 0; i < 4; i++) {
+            valueStr.append(hexDigits[(byte) ((source[index * 4 + i] & 0xF0) >> 4)]);
+            valueStr.append(hexDigits[(byte) (source[index * 4 + i] & 0x0F)]);
+        }
+        return Long.valueOf(valueStr.toString(), 16).intValue();
+
+    }
+
+    private static byte[] toByteArray(int a, int b, int c, int d, int e, int f,
+                                      int g, int h) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
+        baos.write(toByteArray(a));
+        baos.write(toByteArray(b));
+        baos.write(toByteArray(c));
+        baos.write(toByteArray(d));
+        baos.write(toByteArray(e));
+        baos.write(toByteArray(f));
+        baos.write(toByteArray(g));
+        baos.write(toByteArray(h));
+        return baos.toByteArray();
+    }
+
+    public static byte[] toByteArray(int i) {
+        byte[] byteArray = new byte[4];
+        byteArray[0] = (byte) (i >>> 24);
+        byteArray[1] = (byte) ((i & 0xFFFFFF) >>> 16);
+        byteArray[2] = (byte) ((i & 0xFFFF) >>> 8);
+        byteArray[3] = (byte) (i & 0xFF);
+        return byteArray;
+    }
+
+    private static String byteToHexString(byte b) {
+        int n = b;
+        if (n < 0) {
+            n = 256 + n;
+        }
+        int d1 = n / 16;
+        int d2 = n % 16;
+        return "" + hexDigits[d1] + hexDigits[d2];
+    }
+
+    public static String byteArrayToHexString(byte[] b) {
+        StringBuffer resultSb = new StringBuffer();
+        for (int i = 0; i < b.length; i++) {
+            resultSb.append(byteToHexString(b[i]));
+        }
+        return resultSb.toString();
+    }
+
+    public static void main(String[] args) throws IOException {
+        System.out.println(SM3.byteArrayToHexString(SM3.hash("sm3算法测试".getBytes())));
+    }
+}

+ 34 - 0
tenant/organization/src/main/java/com/jzg/organization/component/UnionPayApiConfigurationProperties.java

@@ -0,0 +1,34 @@
+package com.jzg.organization.component;
+
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @description: 银联支付 配置文件
+ * @author: wenks
+ * @date: 2024/8/8 16:33
+ **/
+@Data
+@Component
+@ConfigurationProperties(prefix = "unionpay.api")
+public class UnionPayApiConfigurationProperties {
+
+    private String appId;
+
+    private String appKey;
+
+    private String accessTokenUrl;
+
+    private String twoFactorVerifyUrl;
+
+    private String threeFactorVerifyUrl;
+
+    private String bankCardVerifyUrl;
+
+    private String publicKey;
+
+    private String privateKey;
+
+}

+ 309 - 0
tenant/organization/src/main/java/com/jzg/organization/component/UnionPayRequestApiComponent.java

@@ -0,0 +1,309 @@
+package com.jzg.organization.component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jzg.commons.exception.SystemException;
+import com.jzg.commons.util.StringUtils;
+import com.jzg.commons.util.UnionPayUtils;
+import com.jzg.commons.util.idgen.IdGenerate;
+import com.jzg.commons.util.sm.SM2;
+import com.jzg.organization.component.request.UnionPayRequest;
+import com.jzg.organization.component.response.UnionPayResponse;
+import lombok.RequiredArgsConstructor;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidParameterException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @description: 银联Api
+ **/
+@Component
+@RequiredArgsConstructor
+public class UnionPayRequestApiComponent {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(UnionPayRequestApiComponent.class);
+
+    private final UnionPayApiConfigurationProperties unionPayApiConfigurationProperties;
+
+    private final RedissonClient redissonClient;
+
+    private final StringRedisTemplate redisTemplate;
+
+    private final RestTemplate restTemplate;
+
+    private final static String UNION_PAY_MAP = "unionPay";
+
+    private final static String UNION_PAY_ACCESS_TOKEN_KEY = "unionPayAccessToken";
+
+    private final static String UNION_PAY_ACCESS_TOKEN_LOCK = "unionPayAccessTokenLock";
+
+    private final static int UNION_PAY_LOCK_TIME = 10000;
+
+    private final static int UNION_PAY_SLEEP_TIME = 5000;
+
+
+    /**
+     * 运营商二要素验证接口
+     *
+     * @param request
+     */
+    public UnionPayResponse twoFactorVerifyRequest(UnionPayRequest request) {
+        String url = unionPayApiConfigurationProperties.getTwoFactorVerifyUrl();
+        JSONObject params = new JSONObject();
+        if (StringUtils.isBlank(request.getPhoneNo())) {
+            throw new InvalidParameterException("手机号不允许为空!");
+        }
+        params.put("phoneNo", request.getPhoneNo());
+
+        //01:验证姓名+手机号,此时用户姓名必输 02:身份证+手机号,此时证件类型、证件
+        if (StringUtils.isNotBlank(request.getCertNo())) {
+            params.put("verifyType", "02");
+            params.put("certType", "01");//证件类型 01:身份证
+            params.put("certNo", request.getCertNo());
+        } else if (StringUtils.isNotBlank(request.getName())) {
+            params.put("verifyType", "01");
+            params.put("name", request.getName());
+        } else {
+            throw new InvalidParameterException("身份证、用户姓名至少传值一个!");
+        }
+        return commonRequest(url, params);
+    }
+
+    /**
+     * 运营商三要素验证接口
+     *
+     * @param request
+     */
+    public UnionPayResponse threeFactorVerifyRequest(UnionPayRequest request) {
+        String url = unionPayApiConfigurationProperties.getThreeFactorVerifyUrl();
+
+        JSONObject params = new JSONObject();
+        if (StringUtils.isBlank(request.getPhoneNo()) || StringUtils.isBlank(request.getCertNo()) ||
+                StringUtils.isBlank(request.getName())) {
+            throw new InvalidParameterException("手机号、身份证、用户姓名不允许为空!");
+        }
+        params.put("phoneNo", request.getPhoneNo());
+        params.put("certType", "01");//证件类型 01:身份证
+        params.put("certNo", request.getCertNo());
+        params.put("name", request.getName());
+        return commonRequest(url, params);
+    }
+
+    /**
+     * 银行卡验证接口
+     *
+     * @param request
+     */
+    public UnionPayResponse bankCardVerifyRequest(UnionPayRequest request) {
+        String url = unionPayApiConfigurationProperties.getBankCardVerifyUrl();
+
+        JSONObject params = new JSONObject();
+        if (StringUtils.isBlank(request.getCardNo())) {
+            throw new InvalidParameterException("卡号不允许为空!");
+        }
+        if (StringUtils.isBlank(request.getCertNo()) && StringUtils.isBlank(request.getName()) &&
+                StringUtils.isBlank(request.getPhoneNo())) {
+            throw new InvalidParameterException("证件号、用户姓名、手机号至少传值一个!");
+        }
+        params.put("cardNo", request.getCardNo());
+        params.put("personalMandate", "1");//是否取得个人授权,字段取值0或1。1:是 0:否
+        params.put("sceneId", "13"); // 业务场景 13:车险
+        if (StringUtils.isNotBlank(request.getCertNo())) {
+            params.put("certType", "01");//证件类型 01:身份证
+            params.put("certNo", request.getCertNo());
+        }
+        if (StringUtils.isNotBlank(request.getName())) {
+            params.put("name", request.getName());
+        }
+        if (StringUtils.isNotBlank(request.getPhoneNo())) {
+            params.put("phoneNo", request.getPhoneNo());
+        }
+        params.put("appName", "01晋掌柜");// 交易发起应用名称
+        params.put("ipType", "04");//IP版本号 04:IPV4 06:IPV6
+        try {
+            params.put("sourceIp", ipFormat(InetAddress.getLocalHost().getHostAddress())); // ip
+        } catch (UnknownHostException e) {
+            LOGGER.error("获取ipv4地址异常", e);
+            throw new RuntimeException("获取ipv4地址异常:", e);
+        }
+        params.put("protocolVersion", "V1.0"); // 用户授权协议版本号
+        params.put("protocolNo", IdGenerate.nextId());
+        return commonRequest(url, params);
+    }
+
+
+    private String ipFormat(String ip) {
+        String[] ips = ip.split("\\.");
+        StringBuffer br = new StringBuffer();
+        for (int i = 0; i < ips.length; i++) {
+            br.append(StringUtils.leftPad(ips[i], 3, "0"));
+            if (i < ips.length - 1) {
+                br.append(".");
+            }
+        }
+        return br.toString();
+    }
+
+    /**
+     * 调用银联接口
+     *
+     * @param url    地址
+     * @param params 入参
+     * @return 返参
+     */
+    private UnionPayResponse commonRequest(String url, JSONObject params) {
+        try {
+            String publicKey = unionPayApiConfigurationProperties.getPublicKey();
+
+            JSONObject data = new JSONObject();
+            String dataValue = SM2.sm2Encrypt(params.toString(), publicKey);
+            data.put("data", dataValue);
+
+            HttpHeaders httpHeaders = new HttpHeaders();
+            httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
+            httpHeaders.set("Accept", "application/json");
+            httpHeaders.set("Authorization", getAccessToken());
+            // 请求
+            LOGGER.error("银联接口url:" + url);
+            LOGGER.error("银联接口请求报文:" + params);
+            LOGGER.error("银联接口加密请求报文:" + data);
+            HttpEntity<String> httpEntity = new HttpEntity<>(data.toString(), httpHeaders);
+            ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
+            JSONObject resp = JSONObject.parseObject(response.getBody());
+            LOGGER.error("银联接口响应报文:" + resp);
+            if ("20000000".equals(resp.getString("errCode"))) {
+                String privateKey = unionPayApiConfigurationProperties.getPrivateKey();
+                String respData = SM2.sm2Decrypt(resp.getString("data"),
+                        privateKey);
+                LOGGER.error("银联接口解密响应报文:" + respData);
+                return JSONObject.parseObject(respData, UnionPayResponse.class);
+            } else {
+                throw new SystemException("银联信息验证异常[" + resp.getString("errCode") + ":" +
+                        resp.getString("errInfo") + "]");
+            }
+        } catch (SystemException e) {
+            throw new SystemException(e.getMessage());
+        } catch (Exception e) {
+            LOGGER.error("银联接口调用异常", e);
+            throw new RuntimeException("银联接口调用异常:", e);
+        }
+    }
+
+    /**
+     * 获取银联token
+     *
+     * @return
+     */
+    private String getAccessToken() {
+
+        Object token = redisTemplate.opsForHash().get(UNION_PAY_MAP, UNION_PAY_ACCESS_TOKEN_KEY);
+        // 缓存中不存在就去请求token
+        if (!ObjectUtils.isEmpty(token)) {
+            return (String) token;
+        }
+
+        // 使用分布式锁 只有一个人可以访问登录
+        RLock lock = redissonClient.getLock(UNION_PAY_ACCESS_TOKEN_LOCK);
+        try {
+            boolean isLock = lock.tryLock(1, UNION_PAY_LOCK_TIME, TimeUnit.MILLISECONDS);
+            if (isLock) {
+                try {
+                    return this.invokeToken();
+                } finally {
+                    lock.unlock();
+                }
+            }
+
+        } catch (InterruptedException e) {
+            LOGGER.error("getAccessToken InterruptedException", e);
+            lock.unlock();
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("获取银联Token异常,请重试!");
+        }
+
+        // 睡眠一段时间 自调用 重新获取缓存中的 header
+        try {
+            Thread.sleep(UNION_PAY_SLEEP_TIME);
+        } catch (InterruptedException e) {
+            LOGGER.error("getAccessToken InterruptedException", e);
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("获取银联Token异常,请重试!");
+        }
+        return getAccessToken();
+    }
+
+    /**
+     * 调用银联接口获取token
+     *
+     * @return token
+     */
+    public String invokeToken() {
+        String appId = unionPayApiConfigurationProperties.getAppId();
+        String appKey = unionPayApiConfigurationProperties.getAppKey();
+        String accessTokenUrl = unionPayApiConfigurationProperties.getAccessTokenUrl();
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+        String timestamp = sdf.format(new Date());
+        String randNumber = UnionPayUtils.createData(3);
+
+        String signature = UnionPayUtils.SHA256(appId + timestamp + randNumber + appKey);
+
+        JSONObject params = new JSONObject();
+        params.put("appId", appId);
+        params.put("timestamp", timestamp);
+        params.put("nonce", randNumber);
+        params.put("signMethod", "SHA256");
+        params.put("signature", signature);
+
+        try {
+            HttpHeaders httpHeaders = new HttpHeaders();
+            httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
+            httpHeaders.set("Accept", "application/json");
+            // 请求
+            LOGGER.error("银联获取token-url:" + accessTokenUrl);
+            LOGGER.error("银联获取token-入参:" + params);
+            HttpEntity<JSONObject> httpEntity = new HttpEntity<>(params, httpHeaders);
+            ResponseEntity<String> response = restTemplate.postForEntity(accessTokenUrl, httpEntity, String.class);
+            JSONObject resp = JSONObject.parseObject(response.getBody());
+            LOGGER.error("银联获取token-返参:" + resp);
+            if ("0000".equals(resp.getString("errCode"))) {
+                String token = resp.getString("accessToken");
+                int expiresIn = resp.getIntValue("expiresIn"); //失效时间
+                Map<String, String> map = new HashMap<>();
+                String tokenValue = "OPEN-ACCESS-TOKEN AccessToken=" + token + ", AppId=" + appId;
+                map.put(UNION_PAY_ACCESS_TOKEN_KEY, tokenValue);
+                redisTemplate.opsForHash().putAll(UNION_PAY_MAP, map);
+                redisTemplate.expire(UNION_PAY_MAP, expiresIn - 30, TimeUnit.SECONDS);
+                return tokenValue;
+            } else {
+                throw new SystemException("获取银联Token异常[" + resp.getString("errCode") + ":" +
+                        resp.getString("errInfo") + "]");
+            }
+
+        } catch (SystemException e) {
+            throw new SystemException(e.getMessage());
+        } catch (Exception e) {
+            LOGGER.error("获取银联Token异常", e);
+            throw new SystemException("获取银联Token异常,请重试!");
+        }
+
+    }
+
+
+}

+ 25 - 0
tenant/organization/src/main/java/com/jzg/organization/component/request/UnionPayRequest.java

@@ -0,0 +1,25 @@
+package com.jzg.organization.component.request;
+
+
+import lombok.Data;
+
+@Data
+public class UnionPayRequest {
+
+    /**
+     * 姓名
+     */
+    private String name;
+    /**
+     * 证件号
+     */
+    private String certNo;
+    /**
+     * 手机号
+     */
+    private String phoneNo;
+    /**
+     * 银行卡号
+     */
+    private String cardNo;
+}

+ 24 - 0
tenant/organization/src/main/java/com/jzg/organization/component/response/UnionPayResponse.java

@@ -0,0 +1,24 @@
+package com.jzg.organization.component.response;
+
+import lombok.Data;
+
+@Data
+public class UnionPayResponse {
+
+    /**
+     * 应答码
+     */
+    private String respCode;
+    /**
+     * 应答码解释
+     */
+    private String respMsg;
+    /**
+     * 细分应答码
+     */
+    private String detailRespCode;
+    /**
+     * 细分应答码解释
+     */
+    private String detailRespMsg;
+}

+ 64 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/AppUserController.java

@@ -0,0 +1,64 @@
+package com.jzg.organization.controller;
+
+
+import com.jzg.commons.core.base.BaseController;
+import com.jzg.commons.core.page.HttpResult;
+import com.jzg.commons.entity.dto.AuthInfoAddParam;
+import com.jzg.commons.entity.dto.BusinessInfoAddParam;
+import com.jzg.commons.util.AssertionUtils;
+import com.jzg.organization.service.SysUserJzgAppService;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+
+@RestController
+@RequestMapping("/appUser")
+public class AppUserController extends BaseController {
+
+    @Autowired
+    private SysUserJzgAppService userJzgAppService;
+
+    /**
+     * 实名认证信息查询
+     * @param id 用户id
+     * @return
+     */
+    @GetMapping(value = { "/authInfoGet"})
+    @Operation(summary = "实名认证信息查询")
+    public HttpResult authInfoGet(String id) {
+        return HttpResult.ok(userJzgAppService.authInfoGet(id));
+    }
+
+    /**
+     * 实名认证信息保存
+     * @param param
+     * @return
+     */
+    @Operation(summary = "实名认证信息保存")
+    @PostMapping("/authInfoAdd")
+    public HttpResult authInfoAdd(@Validated @RequestBody AuthInfoAddParam param) {
+        LocalDate startDate = param.getIdentityTimeStart();
+        LocalDate endDate = param.getIdentityTimeEnd();
+        if(endDate.isBefore(startDate) || startDate.isEqual(endDate)){
+            AssertionUtils.isFail(false,"身份证起期不能大于止期!");
+        }
+        userJzgAppService.authInfoSave(param);
+        return HttpResult.ok("保存成功");
+    }
+
+    /**
+     * 营业执照信息保存
+     * @param param
+     * @return
+     */
+    @Operation(summary = "营业执照信息保存")
+    @PostMapping("/businessInfoAdd")
+    public HttpResult businessInfoAdd(@Validated @RequestBody BusinessInfoAddParam param) {
+        userJzgAppService.businessInfoAdd(param);
+        return HttpResult.ok("保存成功");
+    }
+
+}

+ 13 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/SysUserJzgAppMapper.java

@@ -0,0 +1,13 @@
+package com.jzg.organization.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jzg.commons.entity.po.SysUserJzgApp;
+import com.jzg.commons.entity.vo.AuthInfoVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface SysUserJzgAppMapper extends BaseMapper<SysUserJzgApp> {
+
+    AuthInfoVo authInfoGet(@Param("id") String id);
+}

+ 30 - 0
tenant/organization/src/main/java/com/jzg/organization/service/SysUserJzgAppService.java

@@ -0,0 +1,30 @@
+package com.jzg.organization.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jzg.commons.entity.dto.AuthInfoAddParam;
+import com.jzg.commons.entity.dto.BusinessInfoAddParam;
+import com.jzg.commons.entity.po.SysUser;
+import com.jzg.commons.entity.po.SysUserJzgApp;
+import com.jzg.commons.entity.vo.AuthInfoVo;
+
+public interface SysUserJzgAppService extends IService<SysUserJzgApp> {
+
+    /**
+     * 用户实名信息查询
+     * @param id
+     * @return
+     */
+    AuthInfoVo authInfoGet(String id);
+
+    /**
+     * 实名信息保存
+     * @param param
+     */
+    void authInfoSave(AuthInfoAddParam param);
+
+    /**
+     * 展业资格证保存
+     * @param param
+     */
+    void businessInfoAdd(BusinessInfoAddParam param);
+}

+ 110 - 0
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserJzgAppServiceImpl.java

@@ -0,0 +1,110 @@
+package com.jzg.organization.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jzg.commons.entity.dto.AuthInfoAddParam;
+import com.jzg.commons.entity.dto.BusinessInfoAddParam;
+import com.jzg.commons.entity.po.SysUser;
+import com.jzg.commons.entity.po.SysUserJzgApp;
+import com.jzg.commons.entity.po.SysUserJzgInfo;
+import com.jzg.commons.entity.po.SysUserJzgInfoFile;
+import com.jzg.commons.entity.vo.AuthInfoVo;
+import com.jzg.organization.component.UnionPayRequestApiComponent;
+import com.jzg.organization.component.request.UnionPayRequest;
+import com.jzg.organization.component.response.UnionPayResponse;
+import com.jzg.organization.mapper.SysUploadFilesMapper;
+import com.jzg.organization.mapper.SysUserJzgAppMapper;
+import com.jzg.organization.mapper.SysUserJzgInfoFileMapper;
+import com.jzg.organization.mapper.SysUserMapper;
+import com.jzg.organization.service.SysUserJzgAppService;
+import com.jzg.organization.service.SysUserJzgInfoFileService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.awt.*;
+import java.util.List;
+import java.util.Objects;
+
+@Service
+public class SysUserJzgAppServiceImpl extends ServiceImpl<SysUserJzgAppMapper, SysUserJzgApp> implements SysUserJzgAppService {
+
+    @Autowired
+    private SysUserJzgAppMapper sysUserJzgAppMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private SysUserJzgInfoFileService userJzgInfoFileService;
+
+
+    @Autowired
+    private UnionPayRequestApiComponent unionPayRequestApiComponent;
+
+    @Override
+    public AuthInfoVo authInfoGet(String id) {
+        AuthInfoVo infoVo = sysUserJzgAppMapper.authInfoGet(id);
+        // 获取身份证和营业执照信息
+        LambdaQueryWrapper<SysUserJzgInfoFile> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysUserJzgInfoFile::getUserId, id);
+        List<SysUserJzgInfoFile> fileList = userJzgInfoFileService.list(queryWrapper);
+        if(CollUtil.isNotEmpty(fileList)){
+            infoVo.setFileList(fileList);
+        }
+        return infoVo;
+    }
+
+    @Override
+    public void authInfoSave(AuthInfoAddParam param) {
+        // 身份证图片进行实名认证
+        UnionPayRequest request = new UnionPayRequest();
+        request.setName(param.getName());
+        request.setPhoneNo(param.getMobile());
+        request.setCertNo(param.getIdentity());
+        UnionPayResponse response = unionPayRequestApiComponent.threeFactorVerifyRequest(request);
+        SysUser user = new SysUser();
+        user.setId(param.getUserId());
+        user.setIdentity(param.getIdentity());
+        user.setIdentityTimeStart(param.getIdentityTimeStart());
+        user.setIdentityTimeEnd(param.getIdentityTimeEnd());
+
+        String msg = null;
+        if (response != null && !"00".equals(response.getRespCode())) {
+            msg = "认证信息不一致:" + response.getDetailRespMsg();
+            user.setAuthStatus(2);
+        } else {
+            msg = "认证成功";
+            user.setAuthStatus(1);
+            // 保存身份证图片 查询之前上传的删除重新上传
+            // 获取身份证和营业执照信息
+            LambdaQueryWrapper<SysUserJzgInfoFile> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(SysUserJzgInfoFile::getUserId, param.getUserId())
+                    .in(SysUserJzgInfoFile::getFileType,"sfz1","sfz2");
+            List<SysUserJzgInfoFile> fileList = userJzgInfoFileService.list(queryWrapper);
+            if(CollUtil.isNotEmpty(fileList)){
+                userJzgInfoFileService.removeByIds(fileList);
+            }
+            userJzgInfoFileService.saveBatch(param.getFileList());
+        }
+        sysUserMapper.updateById(user);
+        UpdateWrapper<SysUserJzgApp> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.set("auth_result", msg);
+        updateWrapper.eq("user_id", user.getId());
+        sysUserJzgAppMapper.update(updateWrapper);
+    }
+
+    @Override
+    public void businessInfoAdd(BusinessInfoAddParam param) {
+        // 获取身份证和营业执照信息
+        LambdaQueryWrapper<SysUserJzgInfoFile> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysUserJzgInfoFile::getUserId, param.getUserId())
+                .eq(SysUserJzgInfoFile::getFileType,"qualification");
+        SysUserJzgInfoFile file = userJzgInfoFileService.getOne(queryWrapper);
+        if(Objects.nonNull(file)){
+            userJzgInfoFileService.removeById(file);
+        }
+        userJzgInfoFileService.save(param.getFile());
+    }
+}

+ 4 - 4
tenant/organization/src/main/java/com/jzg/organization/service/impl/SysUserServiceImpl.java

@@ -299,7 +299,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             if (sysUserVo.getOrganizationId() != null && !sysUserVo.getOrganizationId().equals("")) {
                 saveOrganization(sysUserVo.getOrganizationId(), sysUserJzgInfo.getUserId());
             }
-            saveFile(sysUserVo.getSfz1(), sysUserVo.getSfz2(), sysUserVo.getQualification(), sysUserVo.getContract(), sysUserVo.getApplicant(), sysUserVo.getSalaryTable(), sysUserVo.getLeaveTable(),sysUserJzgInfo.getId());
+            saveFile(sysUserVo.getSfz1(), sysUserVo.getSfz2(), sysUserVo.getQualification(), sysUserVo.getContract(), sysUserVo.getApplicant(), sysUserVo.getSalaryTable(), sysUserVo.getLeaveTable(),sysUserJzgInfo.getUserId());
             //系统中已存在业务员
 //            throw new SystemException("用户信息已存在,无法添加");
         } else {
@@ -570,7 +570,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
 
         List<SysUserJzgInfoFile> sysUserJzgInfoFile = sysUserJzgInfoFileService.list
-                (new LambdaQueryWrapper<SysUserJzgInfoFile>().eq(SysUserJzgInfoFile::getUserId,sysUserJzgInfo.getId()));
+                (new LambdaQueryWrapper<SysUserJzgInfoFile>().eq(SysUserJzgInfoFile::getUserJzgInfoId,sysUserJzgInfo.getId()));
         sysUserJzgInfo.setFileList(sysUserJzgInfoFile);
         List<SysUserJzgInfoBankCardDto> sysUserJzgInfoBankCardDto = sysUserJzgInfoBankCardService.getBankCardByUserId(sysUserJzgInfo.getId());
         sysUserJzgInfo.setBankCardList(sysUserJzgInfoBankCardDto);
@@ -641,7 +641,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     public boolean uploadFile(String fileId,String fileType,String userId){
         List<SysUserJzgInfoFile> sysUserJzgInfoFiles = sysUserJzgInfoFileService.list(
-                (new LambdaQueryWrapper<SysUserJzgInfoFile>().eq(SysUserJzgInfoFile::getUserId, userId)
+                (new LambdaQueryWrapper<SysUserJzgInfoFile>().eq(SysUserJzgInfoFile::getUserJzgInfoId, userId)
                         .eq(SysUserJzgInfoFile::getFileType, fileType)));
         if(sysUserJzgInfoFiles.size()>0) {
             sysUserJzgInfoFileService.removeBatchByIds(sysUserJzgInfoFiles);
@@ -681,7 +681,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     public void verifyFile(SysUserVo sysUserVo,String userId){
         List<SysUserJzgInfoFile> fileList = sysUserJzgInfoFileService.list(new LambdaQueryWrapper<SysUserJzgInfoFile>()
-                .eq(SysUserJzgInfoFile::getUserId, userId));
+                .eq(SysUserJzgInfoFile::getUserJzgInfoId, userId));
         if(checkFileModify(fileList,"sfz1",sysUserVo.getSfz1())){
             uploadFile(sysUserVo.getSfz1(),"sfz1",userId);
         }

+ 13 - 0
tenant/organization/src/main/resources/application-dev.yml

@@ -21,3 +21,16 @@ spring:
 
 config:
   sso: 1
+
+#银联API参数配置
+unionPay:
+  api:
+    appId: 10037e6f8e41423b01912b657e5c116c
+    appKey: 1110043747cb40f4911096480ea93f3e
+    accessTokenUrl: https://test-api-open.chinaums.com/v2/token/access
+    twoFactorVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/2factor/verify
+    threeFactorVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/3factor/verify
+    bankCardVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/bankcard/verify
+    publicKey: 0414bb7e9c3914bb65b85079b1dc6e1ca2a0ee04dd9bb55b2f8d31704a6dec0cca695739e128f9c931330e1c0f493be4d56244236434c9d344c4716ba64a4470ba
+    privateKey: 24ebfde60aecb81214605050763926ec342c487859a8da57d5badcd3c1559336
+

+ 13 - 0
tenant/organization/src/main/resources/application-test.yml

@@ -21,3 +21,16 @@ spring:
 
 config:
   sso: 1
+
+
+#银联API参数配置
+unionPay:
+  api:
+    appId: 8a81c1be8fc4b72501912b65f4bf093a
+    appKey: 43c2fc71b43740539c6c32370e12c7fd
+    accessTokenUrl: https://api-mop.chinaums.com/v2/token/access
+    twoFactorVerifyUrl: https://api-mop.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/2factor/verify
+    threeFactorVerifyUrl: https://api-mop.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/3factor/verify
+    bankCardVerifyUrl: https://api-mop.chinaums.com/v1/datacenter/smartverification/encrypted/bankcard/verify
+    publicKey: 0414bb7e9c3914bb65b85079b1dc6e1ca2a0ee04dd9bb55b2f8d31704a6dec0cca695739e128f9c931330e1c0f493be4d56244236434c9d344c4716ba64a4470ba
+    privateKey: 24ebfde60aecb81214605050763926ec342c487859a8da57d5badcd3c1559336

+ 18 - 0
tenant/organization/src/main/resources/mapper/SysUserJzgAppMapper.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="com.jzg.organization.mapper.SysUserJzgAppMapper">
+
+
+    <select id="authInfoGet" resultType="com.jzg.commons.entity.vo.AuthInfoVo">
+        SELECT sujz.name, su.auth_status as authStatus,su.mobile,
+               su.identity, su.identity_time_start as identityTimeStart,
+               su.identity_time_end as identityTimeEnd,su.id as userId
+        FROM sys_user_jzg_app sujz
+        LEFT JOIN sys_user su ON sujz.user_id = su.id
+        <where>
+            <if test="id != null">
+                and sujz.id = #{id}
+            </if>
+        </where>
+    </select>
+</mapper>