Explorar el Código

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

hxl13994548489 hace 2 años
padre
commit
1b8f5109ed
Se han modificado 23 ficheros con 1376 adiciones y 175 borrados
  1. 1 1
      src/main/java/com/ydtech/config/properties/UnionPayApiConfigurationProperties.java
  2. 39 34
      src/main/java/com/ydtech/modules/admin/components/UnionPayRequestApiComponent.java
  3. 33 2
      src/main/java/com/ydtech/modules/admin/controller/personnelStatistics/PersonnelStatisticsController.java
  4. 5 8
      src/main/java/com/ydtech/modules/admin/dao/SysUserMapper.java
  5. 29 0
      src/main/java/com/ydtech/modules/admin/model/dto/EsmUserReferrerDTO.java
  6. 48 0
      src/main/java/com/ydtech/modules/admin/model/dto/QxFrontlineAgentDto.java
  7. 55 0
      src/main/java/com/ydtech/modules/admin/model/vo/QxFrontlineAgentVo.java
  8. 18 0
      src/main/java/com/ydtech/modules/admin/service/UserReportService.java
  9. 219 3
      src/main/java/com/ydtech/modules/admin/service/impl/UserReportServiceImpl.java
  10. 4 0
      src/main/java/com/ydtech/modules/esm/dao/EsmUserReferrerMapper.java
  11. 9 0
      src/main/java/com/ydtech/modules/order/dao/InsAreaCompanyMapper.java
  12. 10 0
      src/main/java/com/ydtech/modules/order/service/InsAreaCompanyService.java
  13. 11 1
      src/main/java/com/ydtech/modules/order/service/impl/InsAreaCompanyServiceImpl.java
  14. 225 0
      src/main/java/com/ydtech/utils/Base64.java
  15. 343 0
      src/main/java/com/ydtech/utils/SM2.java
  16. 0 109
      src/main/java/com/ydtech/utils/SM2Utils.java
  17. 213 0
      src/main/java/com/ydtech/utils/SM3.java
  18. 6 6
      src/main/resources/application-pre.yml
  19. 6 6
      src/main/resources/application-prod.yml
  20. 5 5
      src/main/resources/application-test.yml
  21. 52 0
      src/main/resources/mapper/modules/admin/SysUserMapper.xml
  22. 16 0
      src/main/resources/mapper/modules/esm/EsmUserReferrerMapper.xml
  23. 29 0
      src/main/resources/mapper/modules/order/InsAreaCompanyMapper.xml

+ 1 - 1
src/main/java/com/ydtech/config/properties/UnionPayApiConfigurationProperties.java

@@ -21,7 +21,7 @@ public class UnionPayApiConfigurationProperties {
 
     private String accessTokenUrl;
 
-    private String factorVerifyUrl;
+    private String threeFactorVerifyUrl;
 
     private String bankCardVerifyUrl;
 

+ 39 - 34
src/main/java/com/ydtech/modules/admin/components/UnionPayRequestApiComponent.java

@@ -6,8 +6,9 @@ import com.ydtech.exception.SystemException;
 import com.ydtech.modules.admin.components.request.UnionPayRequest;
 import com.ydtech.modules.admin.components.response.UnionPayResponse;
 import com.ydtech.modules.admin.utils.UnionPayUtils;
-import com.ydtech.utils.SM2Utils;
+import com.ydtech.utils.SM2;
 import com.ydtech.utils.StringUtils;
+import com.ydtech.utils.idgen.IdGenerate;
 import lombok.RequiredArgsConstructor;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
@@ -58,35 +59,24 @@ public class UnionPayRequestApiComponent {
 
     private final static int UNION_PAY_SLEEP_TIME = 5000;
 
-    private final static int RANDOM_MAX = 999999999;
-
-    private final static int RANDOM_MIN = 100000000;
 
     /**
      * 运营商二要素验证接口
      *
      * @param request
      */
-    public UnionPayResponse twoFactorVerifyRequest(UnionPayRequest request) {
-        String url = unionPayApiConfigurationProperties.getFactorVerifyUrl();
+    public UnionPayResponse threeFactorVerifyRequest(UnionPayRequest request) {
+        String url = unionPayApiConfigurationProperties.getThreeFactorVerifyUrl();
 
         JSONObject params = new JSONObject();
-        if (StringUtils.isBlank(request.getPhoneNo())) {
-            throw new InvalidParameterException("手机号不允许为空!");
+        if (StringUtils.isBlank(request.getPhoneNo()) || StringUtils.isBlank(request.getCertNo()) ||
+                StringUtils.isBlank(request.getName())) {
+            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("身份证、用户姓名至少传值一个!");
-        }
+        params.put("certType", "01");//证件类型 01:身份证
+        params.put("certNo", request.getCertNo());
+        params.put("name", request.getName());
         return commonRequest(url, params);
     }
 
@@ -96,7 +86,7 @@ public class UnionPayRequestApiComponent {
      * @param request
      */
     public UnionPayResponse bankCardVerifyRequest(UnionPayRequest request) {
-        String url = unionPayApiConfigurationProperties.getFactorVerifyUrl();
+        String url = unionPayApiConfigurationProperties.getBankCardVerifyUrl();
 
         JSONObject params = new JSONObject();
         if (StringUtils.isBlank(request.getCardNo())) {
@@ -108,7 +98,7 @@ public class UnionPayRequestApiComponent {
         }
         params.put("cardNo", request.getCardNo());
         params.put("personalMandate", "1");//是否取得个人授权,字段取值0或1。1:是 0:否
-        params.put("sceneId", "13"); //TODO 业务场景 13:车险
+        params.put("sceneId", "13"); // 业务场景 13:车险
         if (StringUtils.isNotBlank(request.getCertNo())) {
             params.put("certType", "01");//证件类型 01:身份证
             params.put("certNo", request.getCertNo());
@@ -119,20 +109,32 @@ public class UnionPayRequestApiComponent {
         if (StringUtils.isNotBlank(request.getPhoneNo())) {
             params.put("phoneNo", request.getPhoneNo());
         }
-        params.put("appName", "01晋掌柜");//TODO 交易发起应用名称
+        params.put("appName", "01晋掌柜");// 交易发起应用名称
         params.put("ipType", "04");//IP版本号 04:IPV4 06:IPV6
         try {
-            params.put("sourceIp", InetAddress.getLocalHost().getHostAddress()); // ip
+            params.put("sourceIp", ipFormat(InetAddress.getLocalHost().getHostAddress())); // ip
         } catch (UnknownHostException e) {
             LOGGER.error("获取ipv4地址异常", e);
             throw new RuntimeException("获取ipv4地址异常:", e);
         }
-        params.put("protocolVersion", ""); // 用户授权协议版本号 //TODO
-        params.put("protocolNo", ""); // 用户授权协议流水号
+        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();
+    }
+
     /**
      * 调用银联接口
      *
@@ -145,8 +147,7 @@ public class UnionPayRequestApiComponent {
             String publicKey = unionPayApiConfigurationProperties.getPublicKey();
 
             JSONObject data = new JSONObject();
-            String dataValue = Base64.getEncoder().encodeToString(SM2Utils.encrypt(params.toString(),
-                    publicKey).getBytes());
+            String dataValue = SM2.sm2Encrypt(params.toString(), publicKey);
             data.put("data", dataValue);
 
             HttpHeaders httpHeaders = new HttpHeaders();
@@ -154,15 +155,17 @@ public class UnionPayRequestApiComponent {
             httpHeaders.set("Accept", "application/json");
             httpHeaders.set("Authorization", getAccessToken());
             // 请求
-            HttpEntity<String> httpEntity = new HttpEntity<>(params.toString(), httpHeaders);
+            LOGGER.error("银联接口url:"+url);
+            LOGGER.error("银联接口入参:"+params);
+            HttpEntity<String> httpEntity = new HttpEntity<>(data.toString(), httpHeaders);
             ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
             JSONObject resp = JSONObject.parseObject(response.getBody());
 
             if ("20000000".equals(resp.getString("errCode"))) {
                 String privateKey = unionPayApiConfigurationProperties.getPrivateKey();
-
-                String respData = SM2Utils.decrypt(new String(Base64.getDecoder().decode(resp.getString("data"))),
+                String respData = SM2.sm2Decrypt(resp.getString("data"),
                         privateKey);
+                LOGGER.error("银联接口返参:"+respData);
                 return JSONObject.parseObject(respData, UnionPayResponse.class);
             } else {
                 throw new SystemException("银联信息验证异常[" + resp.getString("errCode") + ":" +
@@ -245,16 +248,18 @@ public class UnionPayRequestApiComponent {
             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<>();
-                map.put(UNION_PAY_MAP, "OPEN-ACCESS-TOKEN AccessToken=\"" + token + "\", appId=\"" + appId + "\"");
-                redisTemplate.opsForHash().putAll(UNION_PAY_ACCESS_TOKEN_KEY, map);
+                map.put(UNION_PAY_ACCESS_TOKEN_KEY, "OPEN-ACCESS-TOKEN AccessToken=" + token + ", AppId=" + appId );
+                redisTemplate.opsForHash().putAll(UNION_PAY_MAP, map);
                 redisTemplate.expire(UNION_PAY_ACCESS_TOKEN_KEY, expiresIn - 30, TimeUnit.SECONDS);
                 return token;
             } else {

+ 33 - 2
src/main/java/com/ydtech/modules/admin/controller/personnelStatistics/PersonnelStatisticsController.java

@@ -1,9 +1,13 @@
 package com.ydtech.modules.admin.controller.personnelStatistics;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.admin.model.vo.HouLinePersonnelReportVo;
+import com.ydtech.modules.admin.model.vo.QxFrontlineAgentVo;
 import com.ydtech.modules.admin.service.SysDeptService;
 import com.ydtech.modules.admin.service.UserReportService;
+import com.ydtech.modules.fnc.entity.SettlementDocumentaryFeesSumEntity;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.HashMap;
+import java.util.List;
 
 /**
  *    人员统计
@@ -39,7 +44,6 @@ public class PersonnelStatisticsController {
     @PostMapping("queryHXReportData")
     @ApiOperation(value = "查询后线人员统计数据")
     public HttpResult<HashMap<String,Object>> queryHXReportDataNew(@RequestBody HouLinePersonnelReportVo houLinePersonnelReportVo) {
-
         try{
             HashMap<String,Object> houLinePersonnelReportDto = userReportService.queryHXReportDataNew(houLinePersonnelReportVo);
             return HttpResult.ok("查询数据成功", houLinePersonnelReportDto);
@@ -48,9 +52,36 @@ public class PersonnelStatisticsController {
         }
     }
 
+    /**
+     * @version
+     * @author: whp
+     * @Date: 2024/8/07
+     * @Description: 人员统计-前线人员-代理人统计
+     */
+    @PostMapping("queryQxFrontlineAgent")
+    @ApiOperation(value = "人员统计-前线人员-代理人统计")
+    public HttpResult<IPage<QxFrontlineAgentDto>> queryQxFrontlineAgent(@RequestBody QxFrontlineAgentVo qxFrontlineAgentVo) {
 
+        HttpResult<IPage<QxFrontlineAgentDto>> result = userReportService.queryQxFrontlineAgent(qxFrontlineAgentVo);
+        return result;
+    }
 
-
+    /**
+     * @version
+     * @author: whp
+     * @Date: 2024/8/07
+     * @Description: 人员统计-前线人员-代理人统计
+     */
+    @PostMapping("queryQxFrontlineAgentRanking")
+    @ApiOperation(value = "人员统计-前线人员-代理人统计-团队排名")
+    public HttpResult<List<QxFrontlineAgentDto>> queryQxFrontlineAgentRanking(@RequestBody QxFrontlineAgentVo qxFrontlineAgentVo) {
+        try{
+            List<QxFrontlineAgentDto> result = userReportService.queryQxFrontlineAgentRanking(qxFrontlineAgentVo);
+            return HttpResult.ok("查询数据成功", result);
+        }catch (Exception e){
+            return HttpResult.error("查询错误"+e.getMessage());
+        }
+    }
 
 
 }

+ 5 - 8
src/main/java/com/ydtech/modules/admin/dao/SysUserMapper.java

@@ -6,16 +6,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ydtech.modules.admin.model.QuTeamNum;
 import com.ydtech.modules.admin.model.QuUserNum;
 import com.ydtech.modules.admin.model.SysUser;
-import com.ydtech.modules.admin.model.dto.QuTeamNumDto;
-import com.ydtech.modules.admin.model.dto.QuUserNumDto;
-import com.ydtech.modules.admin.model.dto.ReportDto;
-import com.ydtech.modules.admin.model.dto.SysUserDto;
+import com.ydtech.modules.admin.model.dto.*;
 import com.ydtech.modules.admin.model.report.user.HouLinePersonnelReportDto;
 import com.ydtech.modules.admin.model.report.user.QianLineQDPersonnelReportDto;
-import com.ydtech.modules.admin.model.vo.HouLinePersonnelReportVo;
-import com.ydtech.modules.admin.model.vo.SysUserBaseVO;
-import com.ydtech.modules.admin.model.vo.SysUserVO;
-import com.ydtech.modules.admin.model.vo.SysUserVOExt;
+import com.ydtech.modules.admin.model.vo.*;
 import com.ydtech.modules.base.model.dto.PageDto;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
@@ -399,6 +393,9 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
     List<String> getUserIds();
 
     HashMap<String,Object> queryHXReportDataNew(HouLinePersonnelReportVo houLinePersonnelReportVo);
+
+     IPage<QxFrontlineAgentDto> queryQxFrontlineAgent(@Param("page") Page page,@Param("vo") QxFrontlineAgentVo qxFrontlineAgentVo);
+
 }
 
 

+ 29 - 0
src/main/java/com/ydtech/modules/admin/model/dto/EsmUserReferrerDTO.java

@@ -0,0 +1,29 @@
+package com.ydtech.modules.admin.model.dto;
+
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel("用户推荐人表")
+public class EsmUserReferrerDTO implements Serializable {
+
+    @ApiModelProperty(value = "id")
+    private String id;
+
+    @ApiModelProperty(value = "推荐人代码")
+    private String referrerId;
+
+    @ApiModelProperty(value = "推荐人姓名")
+    private String referrerName;
+
+    @ApiModelProperty(value = "推荐人级别")
+    private String level;
+
+    @ApiModelProperty(value = "推荐人归属ID")
+    private String affiliation;
+
+}

+ 48 - 0
src/main/java/com/ydtech/modules/admin/model/dto/QxFrontlineAgentDto.java

@@ -0,0 +1,48 @@
+package com.ydtech.modules.admin.model.dto;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@Data
+@ApiModel("人员统计-前线人员-代理人统计实体")
+public class QxFrontlineAgentDto implements Serializable {
+
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
+    @ApiModelProperty(value = "归属机构")
+    private String deptName;
+
+    @ApiModelProperty(value = "总人力")
+    private String totalManpower;
+
+    @ApiModelProperty(value = "出单人力")
+    private String orderManpower;
+
+    @ApiModelProperty(value = "总保费")
+    private String totalPremium;
+
+    @ApiModelProperty(value = "单均保费")
+    private String averagePremium;
+
+    @ApiModelProperty(value = "员工id")
+    private String userId;
+
+    @ApiModelProperty(value = "部门id")
+    private String deptId;
+
+    @ApiModelProperty(value = "头像路径")
+    private String filePath;
+
+}
+

+ 55 - 0
src/main/java/com/ydtech/modules/admin/model/vo/QxFrontlineAgentVo.java

@@ -0,0 +1,55 @@
+package com.ydtech.modules.admin.model.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.Min;
+import java.io.Serializable;
+
+@Data
+@ApiModel("人员统计-前线人员-代理人统计查询实体")
+@NoArgsConstructor
+public class QxFrontlineAgentVo implements Serializable {
+//  员工工号带M是前线
+    @ApiModelProperty(value = "省机构id")
+    private String provinceId;
+
+    @ApiModelProperty(value = "市机构id")
+    private String cityId;
+
+    @ApiModelProperty(value = "县机构id")
+    private String countyId;
+
+    @ApiModelProperty(value = "门店机构id")
+    private String houseId;
+
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
+    @ApiModelProperty(value = "工号")
+    private String userCode;
+
+    @ApiModelProperty(value = "电话号")
+    private String phoneNumber;
+
+    @ApiModelProperty(value = "机构来源(1-渠道、2-个代)")
+    private String managementSource;
+
+    @ApiModelProperty(value = "每页页数")
+    private int pageSize;
+
+    @ApiModelProperty(value = "页数")
+    @Min(value = 1, message = "页数最小为1")
+    private int pageNum;
+
+    @ApiModelProperty(value = "排序  人员 保费")
+    private String orderSort;
+
+    @ApiModelProperty(value = "用户id")
+    private String userId;
+
+
+
+}

+ 18 - 0
src/main/java/com/ydtech/modules/admin/service/UserReportService.java

@@ -1,11 +1,15 @@
 package com.ydtech.modules.admin.service;
 
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.admin.model.report.user.HouLinePersonnelReportDto;
 import com.ydtech.modules.admin.model.report.user.QianLineDDPersonnelReportDto;
 import com.ydtech.modules.admin.model.report.user.QianLineDLPersonnelReportDto;
 import com.ydtech.modules.admin.model.report.user.QianLineQDPersonnelReportDto;
 import com.ydtech.modules.admin.model.vo.HouLinePersonnelReportVo;
+import com.ydtech.modules.admin.model.vo.QxFrontlineAgentVo;
 
 import java.util.HashMap;
 import java.util.List;
@@ -52,6 +56,20 @@ public interface UserReportService {
      *  @Description:  通过后线人员机构查询统计数据
      */
     HashMap<String,Object> queryHXReportDataNew(HouLinePersonnelReportVo houLinePersonnelReportVo);
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/07
+     *  @Description:  人员统计-前线人员-代理人统计
+     */
+    HttpResult<IPage<QxFrontlineAgentDto>> queryQxFrontlineAgent(QxFrontlineAgentVo qxFrontlineAgentVo);
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/07
+     *  @Description:  人员统计-前线人员-代理人统计-团队排名
+     */
+    List<QxFrontlineAgentDto> queryQxFrontlineAgentRanking(QxFrontlineAgentVo qxFrontlineAgentVo);
 
 }
 

+ 219 - 3
src/main/java/com/ydtech/modules/admin/service/impl/UserReportServiceImpl.java

@@ -1,20 +1,38 @@
 package com.ydtech.modules.admin.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ydtech.constants.enums.dict.DictionaryManagement;
+import com.ydtech.core.page.HttpResult;
 import com.ydtech.modules.admin.dao.SysDeptMapper;
 import com.ydtech.modules.admin.dao.SysUserMapper;
 import com.ydtech.modules.admin.model.SysDept;
 import com.ydtech.modules.admin.model.SysUser;
+import com.ydtech.modules.admin.model.dto.EmployeeIncreaseReportDto;
+import com.ydtech.modules.admin.model.dto.EsmUserReferrerDTO;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.admin.model.dto.ReportDto;
 import com.ydtech.modules.admin.model.report.user.*;
 import com.ydtech.modules.admin.model.vo.HouLinePersonnelReportVo;
+import com.ydtech.modules.admin.model.vo.QxFrontlineAgentVo;
 import com.ydtech.modules.admin.service.UserReportService;
+import com.ydtech.modules.base.model.vo.PageVo;
+import com.ydtech.modules.esm.dao.EsmUserReferrerMapper;
+import com.ydtech.modules.esm.model.EsmUserReferrer;
+import com.ydtech.modules.fnc.entity.SettlementDocumentaryFeesSumEntity;
+import com.ydtech.modules.order.dao.InsAreaCompanyMapper;
+import com.ydtech.modules.order.service.InsAreaCompanyService;
+import com.ydtech.utils.StringUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  *  @version
@@ -31,6 +49,12 @@ public class UserReportServiceImpl implements UserReportService {
     @Autowired
     private SysUserMapper sysUserMapper;
 
+    @Autowired
+    private EsmUserReferrerMapper esmUserReferrerMapper;
+
+    @Autowired
+    private InsAreaCompanyService insAreaCompanyService;
+
     /**
      *  @version
      *  @author: hxl
@@ -147,6 +171,198 @@ public class UserReportServiceImpl implements UserReportService {
         SysUser user =sysUserMapper.selectOne(lqw);
         return user;
     }
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/07
+     *  @Description:  人员统计-前线人员-代理人统计
+     */
+    @Override
+    public HttpResult<IPage<QxFrontlineAgentDto>> queryQxFrontlineAgent(QxFrontlineAgentVo qxFrontlineAgentVo) {
+        try {
+            PageVo<SettlementDocumentaryFeesSumEntity> pageVo = new PageVo<>();
+            Page page = new Page(qxFrontlineAgentVo.getPageNum(), qxFrontlineAgentVo.getPageSize());
+
+            pageVo.setPageNum(qxFrontlineAgentVo.getPageNum());
+            pageVo.setPageSize(qxFrontlineAgentVo.getPageSize());
+
+
+            IPage<QxFrontlineAgentDto> sysUserListPage = sysUserMapper.queryQxFrontlineAgent(page, qxFrontlineAgentVo);
+            List<QxFrontlineAgentDto> sysUserList = sysUserListPage.getRecords();
+
+            HashMap<String, Integer> humanResources = new HashMap<>();
+            HashMap<String, List<String>> humanResourcesIdList = new HashMap<>();
+
+//         关系表
+            List<EsmUserReferrerDTO> employeeIncreaseReportDtos = esmUserReferrerMapper.getbyUserNextLevel(null);
+            Map<String, EsmUserReferrerDTO> collect = employeeIncreaseReportDtos.stream().collect(Collectors.toMap(EsmUserReferrerDTO::getId, Function.identity()));
+            Set<String> visited = new HashSet<>();
+            for (EsmUserReferrerDTO item : employeeIncreaseReportDtos) {
+                Integer count = this.nextLevelUser(item.getId(), collect, visited);
+                humanResources.put(item.getId(), count);
+                List<String> ids = new ArrayList<>();
+                humanResourcesIdList.put(item.getId(), this.nextLevelUserList(item.getId(), collect, visited, ids));
+
+            }
+            for (QxFrontlineAgentDto userItem : sysUserList) {
+                String userId = userItem.getUserId();
+//            总人力
+                if (humanResources.containsKey(userId)) {
+                    if (ObjectUtils.isNotEmpty(humanResources.get(userId))) {
+                        userItem.setTotalManpower(humanResources.get(userId).toString());
+                    }
+                }
+                //出单人力 +  总保费  +单均保费
+                if (humanResourcesIdList.containsKey(userId)) {
+                    if (!CollectionUtils.isEmpty(humanResourcesIdList.get(userId))) {
+                        //出单人力
+                        List<String> ids = humanResourcesIdList.get(userId);
+                        QxFrontlineAgentDto orderManpower = insAreaCompanyService.getOrderManpower(ids);
+                        userItem.setOrderManpower(orderManpower.getOrderManpower());
+                        userItem.setTotalPremium(orderManpower.getTotalPremium());
+                        userItem.setAveragePremium(orderManpower.getAveragePremium());
+                    }
+                }
+            }
+            return HttpResult.ok(sysUserListPage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResult.error("查询异常");
+        }
+    }
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/07
+     *  @Description:  人员统计-前线人员-代理人统计-团队排名
+     */
+    @Override
+    public List<QxFrontlineAgentDto> queryQxFrontlineAgentRanking(QxFrontlineAgentVo qxFrontlineAgentVo) {
+
+        PageVo<SettlementDocumentaryFeesSumEntity> pageVo = new PageVo<>();
+        Page page = new Page(1, 50);
+
+        pageVo.setPageNum(1);
+        pageVo.setPageSize(50);
+
+
+        IPage<QxFrontlineAgentDto> sysUserListPage = sysUserMapper.queryQxFrontlineAgent(page, qxFrontlineAgentVo);
+        List<QxFrontlineAgentDto> sysUserList = sysUserListPage.getRecords();
+
+        HashMap<String, Integer> humanResources = new HashMap<>();
+        HashMap<String, List<String>> humanResourcesIdList = new HashMap<>();
+
+//         关系表
+        List<EsmUserReferrerDTO> employeeIncreaseReportDtos = esmUserReferrerMapper.getbyUserNextLevel(null);
+        Map<String, EsmUserReferrerDTO> collect = employeeIncreaseReportDtos.stream().collect(Collectors.toMap(EsmUserReferrerDTO::getId, Function.identity()));
+        Set<String> visited = new HashSet<>();
+        for (EsmUserReferrerDTO item : employeeIncreaseReportDtos) {
+            Integer count = this.nextLevelUser(item.getId(), collect, visited);
+            humanResources.put(item.getId(), count);
+            List<String> ids = new ArrayList<>();
+            humanResourcesIdList.put(item.getId(), this.nextLevelUserList(item.getId(), collect, visited, ids));
+
+        }
+        for (QxFrontlineAgentDto userItem : sysUserList) {
+            String userId = userItem.getUserId();
+//            总人力
+            if (humanResources.containsKey(userId)) {
+                if (ObjectUtils.isNotEmpty(humanResources.get(userId))) {
+                    userItem.setTotalManpower(humanResources.get(userId).toString());
+                }
+            }
+            //出单人力 +  总保费  +单均保费
+            if (humanResourcesIdList.containsKey(userId)) {
+                if (!CollectionUtils.isEmpty(humanResourcesIdList.get(userId))) {
+                    //出单人力
+                    List<String> ids = humanResourcesIdList.get(userId);
+                    QxFrontlineAgentDto orderManpower = insAreaCompanyService.getOrderManpower(ids);
+                    userItem.setOrderManpower(orderManpower.getOrderManpower());
+                    userItem.setTotalPremium(orderManpower.getTotalPremium());
+                    userItem.setAveragePremium(orderManpower.getAveragePremium());
+                }
+            }
+        }
+        //排序
+        if(StringUtils.isNotEmpty(qxFrontlineAgentVo.getOrderSort())){
+//            人员
+                this.sortBy(qxFrontlineAgentVo.getOrderSort(),sysUserList);
+
+        }
+
+        return sysUserList;
+    }
+
+    private void sortBy(String orderSort,List<QxFrontlineAgentDto> sysUserList) {
+            Collections.sort(sysUserList, new Comparator<QxFrontlineAgentDto>() {
+                @Override
+                public int compare(QxFrontlineAgentDto o1, QxFrontlineAgentDto o2) {
+                    // 假设name是String类型,直接使用String的compareTo方法
+                    if("1".equals(orderSort)) { // 人员
+                        return o1.getTotalManpower().compareTo(o2.getTotalManpower());
+
+                    }else {
+                        return o1.getTotalPremium().compareTo(o2.getTotalPremium());
+
+                    }
+                }
+            });
+    }
+
+    /**
+     *
+     * @param id
+     * @param collect
+     * @param visited
+     * @return  获取所有用户人力的统计
+     */
+    private Integer nextLevelUser(String id, Map<String, EsmUserReferrerDTO> collect, Set<String> visited) {
+        if (visited.contains(id)) {
+            return 0; // 如果已经访问过,返回0
+        }
+        visited.add(id); // 标记为已访问
+
+        EsmUserReferrerDTO esmUserReferrerDTO = collect.get(id);
+        if(esmUserReferrerDTO == null ){
+            return 0;
+        }
+        Integer  count=0;
+
+        for (EsmUserReferrerDTO potentialSubordinate : collect.values()) {
+            if (potentialSubordinate.getReferrerId().equals(id)) {
+                count++; // 直接下级加1
+                count += nextLevelUser(potentialSubordinate.getId(),collect,visited); // 递归计算下级的下级
+            }
+        }
+        return count;
+    }
+
+    /**
+     *
+     * @param id
+     * @param collect
+     * @param visited
+     * @param ids  存储用户下级ids
+     * @return  获取用户下级用户idList
+     */
+    private List<String> nextLevelUserList(String id, Map<String, EsmUserReferrerDTO> collect, Set<String> visited, List<String> ids) {
+        if (visited.contains(id)) {
+            return ids; // 如果已经访问过,返回0
+        }
+        visited.add(id); // 标记为已访问
+
+        EsmUserReferrerDTO esmUserReferrerDTO = collect.get(id);
+        if(esmUserReferrerDTO == null ){
+            return ids;
+        }
+        for (EsmUserReferrerDTO potentialSubordinate : collect.values()) {
+            if (potentialSubordinate.getReferrerId().equals(id)) {
+                ids.add(potentialSubordinate.getId());
+                this.nextLevelUserList(potentialSubordinate.getId(),collect,visited,ids); // 递归计算下级的下级
+            }
+        }
+        return ids;
+    }
 
 }
 

+ 4 - 0
src/main/java/com/ydtech/modules/esm/dao/EsmUserReferrerMapper.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ydtech.modules.admin.model.SysUser;
 import com.ydtech.modules.admin.model.dto.EmployeeIncreaseReportDto;
+import com.ydtech.modules.admin.model.dto.EsmUserReferrerDTO;
 import com.ydtech.modules.admin.model.dto.SysUserDto;
 import com.ydtech.modules.admin.model.dto.SysUserTeamDto;
 import com.ydtech.modules.admin.model.vo.AppCustomerManagementQueryVo;
@@ -225,4 +226,7 @@ public interface EsmUserReferrerMapper extends BaseMapper<EsmUserReferrer> {
 
 
     List<EsmUserPolicyForUserVO> queryOrderCountForUser(String userId,String startDate, String endDate);
+
+    List<EsmUserReferrerDTO> getbyUserNextLevel(String userId);
+
 }

+ 9 - 0
src/main/java/com/ydtech/modules/order/dao/InsAreaCompanyMapper.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ydtech.modules.admin.model.dto.AllpremiumDto;
 import com.ydtech.modules.admin.model.dto.PremiumReportDto;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.admin.model.dto.TaskStatisticsDto;
 import com.ydtech.modules.admin.model.report.company.CompanyPremiumDataDto;
 import com.ydtech.modules.admin.model.report.company.CompanyPremiumDataQueryDto;
@@ -24,6 +25,7 @@ import com.ydtech.modules.order.entity.vo.OrderQueryVo;
 import com.ydtech.modules.order.entity.vo.RejectPageQueryVo;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 
@@ -204,6 +206,13 @@ public interface InsAreaCompanyMapper extends BaseMapper<InsAreaCompany> {
      * @date: 2024/7/29
      **/
     IPage<TaskStatisticsDto> costCenter(@Param("page") Page page, @Param("taskStatisticsVo") TaskStatisticsVo taskStatisticsVo);
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/08
+     *  @Description:  控制台出单人力
+     */
+    QxFrontlineAgentDto getOrderManpower(List<String> ids);
 
 }
 

+ 10 - 0
src/main/java/com/ydtech/modules/order/service/InsAreaCompanyService.java

@@ -3,6 +3,7 @@ package com.ydtech.modules.order.service;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ydtech.core.page.HttpResult;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.fnc.entity.vo.ProblemOrderQueryVo;
 import com.ydtech.modules.order.entity.InsAreaCompany;
 import com.ydtech.modules.order.entity.InsAreaCompanyAccidentalDriving;
@@ -11,6 +12,7 @@ import com.ydtech.modules.order.entity.dto.InsAreaCompanyQueryDto;
 import com.ydtech.modules.order.entity.vo.*;
 import com.ydtech.modules.protocols.entity.po.InsFeeOrderNew;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -168,4 +170,12 @@ public interface InsAreaCompanyService extends IService<InsAreaCompany> {
      *  @Description:  获取暂存订单数据
      */
     Page<InsAreaCompany> getStageOrder(Page page, String userId,RejectPageQueryVo rejectPageQueryVo);
+
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/08
+     *  @Description:  控制台出单人力
+     */
+    QxFrontlineAgentDto getOrderManpower(List<String> ids);
 }

+ 11 - 1
src/main/java/com/ydtech/modules/order/service/impl/InsAreaCompanyServiceImpl.java

@@ -9,6 +9,7 @@ import com.ydtech.constants.enums.dict.FeeAuditAuditstatus;
 import com.ydtech.constants.enums.dict.InsOrderStatusEnum;
 import com.ydtech.core.page.HttpResult;
 import com.ydtech.exception.SystemException;
+import com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto;
 import com.ydtech.modules.base.controller.BaseController;
 import com.ydtech.modules.fee.service.FeeRuleSchemeNewService;
 import com.ydtech.modules.fnc.entity.InsFeeAudit;
@@ -948,7 +949,16 @@ public class InsAreaCompanyServiceImpl extends ServiceImpl<InsAreaCompanyMapper,
     public Page<InsAreaCompany> getStageOrder(Page page, String userId,RejectPageQueryVo rejectPageQueryVo) {
         return baseMapper.getStageOrder(page, userId,rejectPageQueryVo);
     }
-
+    /**
+     *  @version
+     *  @author: whp
+     *  @Date: 2024/8/08
+     *  @Description:  控制台出单人力
+     */
+    @Override
+    public QxFrontlineAgentDto getOrderManpower(List<String> ids) {
+        return baseMapper.getOrderManpower(ids);
+    }
 
 }
 

+ 225 - 0
src/main/java/com/ydtech/utils/Base64.java

@@ -0,0 +1,225 @@
+package com.ydtech.utils;
+
+public final class Base64 {
+    static private final int BASELENGTH = 128;
+    static private final int LOOKUPLENGTH = 64;
+    static private final int TWENTYFOURBITGROUP = 24;
+    static private final int EIGHTBIT = 8;
+    static private final int SIXTEENBIT = 16;
+    static private final int FOURBYTE = 4;
+    static private final int SIGN = -128;
+    static private final char PAD = '=';
+    static private final boolean fDebug = false;
+    static final private byte[] base64Alphabet = new byte[BASELENGTH];
+    static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = (char) '+';
+        lookUpBase64Alphabet[63] = (char) '/';
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+        if (binaryData == null) {
+            return null;
+        }
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
+        char encodedData[] = null;
+        encodedData = new char[numberQuartet * 4];
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+        }
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+            if (fDebug) { }
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
+            if (fDebug) { }
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) { }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+        if (encoded == null) {
+            return null;
+        }
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+        if (len % FOURBYTE != 0) {
+            return null;//should be divisible by four
+        }
+        int numberQuadruple = (len / FOURBYTE);
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+        for (; i < numberQuadruple - 1; i++) {
+            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
+                    || !isData((d3 = base64Data[dataIndex++]))
+                    || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }//if found "no data" just return null
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;//if found "no data" just return null
+        }
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)//last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)//last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { //No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data the byte array of base64 data (with WS)
+     * @return the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+}

+ 343 - 0
src/main/java/com/ydtech/utils/SM2.java

@@ -0,0 +1,343 @@
+package com.ydtech.utils;
+
+
+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;
+    }
+
+
+}

+ 0 - 109
src/main/java/com/ydtech/utils/SM2Utils.java

@@ -1,109 +0,0 @@
-package com.ydtech.utils;
-
-
-import com.ydtech.modules.admin.components.UnionPayRequestApiComponent;
-import org.bouncycastle.crypto.engines.SM2Engine;
-import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
-import org.bouncycastle.crypto.params.ECPublicKeyParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.util.PrivateKeyFactory;
-import org.bouncycastle.crypto.util.PublicKeyFactory;
-import org.bouncycastle.jce.ECNamedCurveTable;
-import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
-import org.bouncycastle.jce.spec.ECNamedCurveSpec;
-import org.bouncycastle.jce.spec.ECParameterSpec;
-import org.bouncycastle.jce.spec.ECPublicKeySpec;
-import org.bouncycastle.util.encoders.Hex;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.ECPrivateKeySpec;
-import java.util.Base64;
-
-public class SM2Utils {
-    private final static Logger LOGGER = LoggerFactory.getLogger(SM2Utils.class);
-
-
-    /**
-     * 公钥转换
-     * @param publicKeyString 公钥字符串
-     * @return ECPublicKeyParameters
-     * @throws Exception
-     */
-    public static ECPublicKeyParameters getPublicKeyFromString (String publicKeyString) throws Exception {
-        byte[] keyBytes = Base64.getDecoder().decode(publicKeyString);
-        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
-        ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(ecSpec.getCurve().decodePoint(keyBytes), ecSpec);
-        PublicKey publicKey =  KeyFactory.getInstance("EC","BC").generatePublic(publicKeySpec);
-        return (ECPublicKeyParameters) PublicKeyFactory.createKey(publicKey.getEncoded());
-    }
-
-    /**
-     * 私钥转换
-     * @param privateKeyString 私钥字符串
-     * @return ECPrivateKeyParameters
-     * @throws Exception
-     */
-    public static ECPrivateKeyParameters getPrivateKeyFromString (String privateKeyString) throws Exception{
-        byte[] keyBytes = Base64.getDecoder().decode(privateKeyString);
-        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
-        ECNamedCurveSpec param =  new ECNamedCurveSpec("sm2p256v1", ecSpec.getCurve(), ecSpec.getG(), ecSpec.getN());
-        KeyFactory keyFactory = KeyFactory.getInstance("EC","BC");
-        PrivateKey privateKey = keyFactory.generatePrivate(new ECPrivateKeySpec(new BigInteger(1, keyBytes) , param));
-        return (ECPrivateKeyParameters) PrivateKeyFactory.createKey(privateKey.getEncoded());
-    }
-
-
-    /**
-     * SM2加密算法
-     *
-     * @param publicKeyString 公钥字符串
-     * @param data      明文数据
-     * @return
-     */
-    public static String encrypt(String data, String publicKeyString) throws Exception{
-        try {
-            byte[] bytes = data.getBytes();
-            ECPublicKeyParameters publicKey = getPublicKeyFromString(publicKeyString);
-
-            SM2Engine engine = new SM2Engine();
-            engine.init(true, new ParametersWithRandom(publicKey));
-
-            byte[] arrayOfBytes =engine.processBlock(bytes,0, bytes.length);
-            return Hex.toHexString(arrayOfBytes);
-        } catch (Exception e) {
-            LOGGER.error("SM2加密时出现异常:",e);
-            throw new Exception("SM2加密时出现异常", e);
-        }
-    }
-
-
-
-    /**
-     * SM2解密算法
-     * @param data    hex格式密文
-     * @param privateKeyString    密钥PrivateKey型
-     * @return              明文
-     */
-    public static String decrypt(String data, String privateKeyString)  throws Exception{
-        try {
-            byte[] bytes = data.getBytes();
-            ECPrivateKeyParameters privateKeyParameters = getPrivateKeyFromString(privateKeyString);
-
-            SM2Engine sm2Engine = new SM2Engine();
-            // 设置sm2为解密模式
-            sm2Engine.init(false, privateKeyParameters);
-            byte[] arrayOfBytes = sm2Engine.processBlock(bytes, 0, bytes.length);
-            return new String(arrayOfBytes);
-        } catch (Exception e) {
-            LOGGER.error("SM2解密时出现异常:" ,e);
-            throw new Exception("SM2解密时出现异常", e);
-        }
-    }
-
-
-}

+ 213 - 0
src/main/java/com/ydtech/utils/SM3.java

@@ -0,0 +1,213 @@
+package com.ydtech.utils;
+
+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())));
+    }
+}

+ 6 - 6
src/main/resources/application-pre.yml

@@ -23,13 +23,13 @@ baidu:
 #银联API参数配置
 unionPay:
   api:
-    appId: 111
-    appKey: 1111
-    accessTokenUrl: https://test-api-open.chinaums.com/v2/token/acces
-    factorVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/2factor/verify
-    bankCardVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/bankcard/verify
+    appId: 10037e6f8e41423b01912b657e5c116c
+    appKey: 1110043747cb40f4911096480ea93f3e
+    accessTokenUrl: https://api-mop.chinaums.com/v2/token/access
+    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:
+    privateKey: 24ebfde60aecb81214605050763926ec342c487859a8da57d5badcd3c1559336
 aly:
   cbit:
     url_pre: http://223.70.186.115:80/CBIT/API/insCBIT

+ 6 - 6
src/main/resources/application-prod.yml

@@ -23,13 +23,13 @@ baidu:
 #银联API参数配置
 unionPay:
   api:
-    appId: 111
-    appKey: 1111
-    accessTokenUrl: https://test-api-open.chinaums.com/v2/token/acces
-    factorVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/2factor/verify
-    bankCardVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/bankcard/verify
+    appId: 10037e6f8e41423b01912b657e5c116c
+    appKey: 1110043747cb40f4911096480ea93f3e
+    accessTokenUrl: https://api-mop.chinaums.com/v2/token/access
+    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:
+    privateKey: 24ebfde60aecb81214605050763926ec342c487859a8da57d5badcd3c1559336
 
 aly:
   cbit:

+ 5 - 5
src/main/resources/application-test.yml

@@ -25,13 +25,13 @@ baidu:
 #银联API参数配置
 unionPay:
   api:
-    appId: 111
-    appKey: 1111
-    accessTokenUrl: https://test-api-open.chinaums.com/v2/token/acces
-    factorVerifyUrl: https://test-api-open.chinaums.com/v1/datacenter/smartverification/encrypted/mobile/2factor/verify
+    appId: 10037e6f8e41423b01912b657e5c116c
+    appKey: 1110043747cb40f4911096480ea93f3e
+    accessTokenUrl: https://test-api-open.chinaums.com/v2/token/access
+    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:
+    privateKey: 24ebfde60aecb81214605050763926ec342c487859a8da57d5badcd3c1559336
 
 aly:
   cbit:

+ 52 - 0
src/main/resources/mapper/modules/admin/SysUserMapper.xml

@@ -1298,6 +1298,58 @@
             info.id is not  null
             and su.id  LIKE '%M%'
             and su.status = '1'
+            <if test="vo.provinceId != null and vo.provinceId != ''">
+                and sd.deptid like "$vo.provinceId}%"
+            </if>
+            <if test="vo.cityId != null and vo.cityId != ''">
+                and sd.deptid like "${vo.cityId}%"
+            </if>
+            <if test="vo.countyId != null and vo.countyId != ''">
+                and sd.deptid like "${vo.countyId}%"
+            </if>
+            <if test="vo.houseId != null and vo.houseId != ''">
+                and sd.deptid like "${vo.houseId}%"
+            </if>
+        </where>
+    </select>
+    <select id="queryQxFrontlineAgent" resultType="com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto">
+        SELECT
+            sd.name as "name",
+            su.name as "deptName",
+            su.id  as "userId",
+            su.dept_id  as "deptId",
+            inf.file_path  as "filePath"
+        FROM
+            sys_user su
+                LEFT JOIN sys_dept sd ON sd.id = su.dept_id
+                LEFT JOIN  ins_upload_files   inf on  su.head_sculpture  =inf.id
+        <where>
+            su.id  LIKE '%M%'
+            and su.status = '1'
+            <if test="vo.managementSource != null  and  vo.managementSource!='' ">
+                AND sd.management_source =#{vo.managementSource}
+            </if>
+            <if test="vo.provinceId != null and vo.provinceId != ''">
+                and sd.deptid like "$vo.provinceId}%"
+            </if>
+            <if test="vo.cityId != null and vo.cityId != ''">
+                and sd.deptid like "${vo.cityId}%"
+            </if>
+            <if test="vo.countyId != null and vo.countyId != ''">
+                and sd.deptid like "${vo.countyId}%"
+            </if>
+            <if test="vo.houseId != null and vo.houseId != ''">
+                and sd.deptid like "${vo.houseId}%"
+            </if>
+            <if test="vo.name != null and vo.name != ''">
+                and su.name   =#{vo.name}
+            </if>
+            <if test="vo.userCode != null and vo.userCode != ''">
+                and su.id   =#{vo.userCode}
+            </if>
+            <if test="vo.phoneNumber != null and vo.phoneNumber != ''">
+                and su.mobile   =#{vo.phoneNumber}
+            </if>
         </where>
     </select>
 

+ 16 - 0
src/main/resources/mapper/modules/esm/EsmUserReferrerMapper.xml

@@ -290,4 +290,20 @@
              )c on a.companyId = c.companyId
         where a.companyId is not null
     </select>
+    <select id="getbyUserNextLevel" resultType="com.ydtech.modules.admin.model.dto.EsmUserReferrerDTO">
+        SELECT
+        eur.id as "id",
+        eur.referrer_id as "referrerId"
+        FROM
+            esm_user_referrer eur
+                LEFT JOIN sys_user su ON su.id = eur.id
+        <where>
+            su.id != 'admin'
+            AND su.STATUS = 1
+            AND referrer_id IS NOT NULL
+            <if test="userId !=null and  userId  !=''">
+              AND  eur.referrer_id =#{userId}
+            </if>
+        </where>
+    </select>
 </mapper>

+ 29 - 0
src/main/resources/mapper/modules/order/InsAreaCompanyMapper.xml

@@ -1131,4 +1131,33 @@
             iac.company_id,
             iac.inscompany
     </select>
+
+
+    <select id="getOrderManpower" resultType="com.ydtech.modules.admin.model.dto.QxFrontlineAgentDto">
+        SELECT
+        count( a.numberUserId ) as "orderManpower",
+        sum( a.orderAmount ) as "totalPremium",
+        sum( a.orderAmount )/  count( a.numberUserId ) as "averagePremium"
+        FROM
+        (
+        SELECT
+        count( io.userid ) AS "numberUserId",
+        sum( iac.sumpremium ) AS "orderAmount"
+        FROM
+        `ins_area_company` iac
+        LEFT JOIN ins_orders io ON io.orderno = iac.orderno
+        <where>
+            iac.orderstatus = '3'
+            <if test="ids  != null  and  ids.size()>0 ">
+                AND io.userid IN
+                <foreach item="item"  collection="ids" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+        GROUP BY
+        io.userid
+        ) a
+    </select>
+
 </mapper>