فهرست منبع

Merge branch 'feat-20220907-zhengqizhixing' into temp-pre

lixuesong 2 سال پیش
والد
کامیت
7943a702e5
13فایلهای تغییر یافته به همراه777 افزوده شده و 3 حذف شده
  1. 18 0
      db/v2.0/220909.sql
  2. 5 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java
  3. 85 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/GigThirdApiController.java
  4. 83 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/XinbadaInputRecord.java
  5. 1 2
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/SubjectTypeEnum.java
  6. 17 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/XinbadaInputRecordMapper.java
  7. 13 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/XinbadaInputRecordService.java
  8. 9 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/gig/GigThirdApiService.java
  9. 61 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/gig/impl/GigThirdApiServiceImpl.java
  10. 1 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/SysUserServiceImpl.java
  11. 172 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmPayOffServiceImpl.java
  12. 294 1
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmScorePackageSettleNoteServiceImpl.java
  13. 18 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/XinbadaInputRecordServiceImpl.java

+ 18 - 0
db/v2.0/220909.sql

@@ -0,0 +1,18 @@
+-- 正启之星请求记录表
+create table xinbada_input_record
+(
+    id                 int auto_increment comment '主键id'
+        primary key,
+    signature          varchar(128)                        not null comment '签名',
+    action_name        varchar(32)                         not null comment '通知类型',
+    req_body           text                                not null comment '请求body内容',
+    order_uuid         varchar(64)                         null comment '订单编号唯一',
+    order_status       int                                 null comment '订单状态',
+    order_no           varchar(32)                         null comment '',
+    customer_user_uuid varchar(64)                         null comment '',
+    server_user_uuid   varchar(64)                         null comment '',
+    public_key         varchar(2048)                       null comment '请求公钥',
+    private_key        varchar(2048)                       null comment '请求时私钥',
+    create_time        timestamp default CURRENT_TIMESTAMP not null comment '创建时间'
+)
+    comment '正启之星请求记录';

+ 5 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/constant/CacheConstants.java

@@ -115,6 +115,11 @@ public interface CacheConstants {
 	 */
 	String OLADING_NOTIFY_KEY = "OLADING:NOTIFY:KEY:";
 
+	/**
+	 * 正启之星异步结果回调key
+	 */
+	String ZHEGN_QI_ZHI_XING_NOTIFY_KEY = "ZHEGN:QI:ZHI:XING:NOTIFY:KEY:";
+
 	/**
 	 * 发起阿拉丁认证渠道记录key
 	 */

+ 85 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/GigThirdApiController.java

@@ -1,10 +1,13 @@
 package com.qunzhixinxi.hnqz.admin.controller;
 
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
 import com.qunzhixinxi.hnqz.admin.api.dto.OladingCommonRequest;
 import com.qunzhixinxi.hnqz.admin.entity.OladingInputRecord;
+import com.qunzhixinxi.hnqz.admin.entity.XinbadaInputRecord;
+import com.qunzhixinxi.hnqz.admin.service.XinbadaInputRecordService;
 import com.qunzhixinxi.hnqz.admin.service.gig.GigThirdApiService;
 import com.qunzhixinxi.hnqz.admin.service.gig.OladingInputRecordService;
 import com.qunzhixinxi.hnqz.admin.util.HMACSignProvider;
@@ -13,13 +16,21 @@ import com.qunzhixinxi.hnqz.common.security.annotation.Inner;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpHeaders;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -38,6 +49,8 @@ public class GigThirdApiController {
 
 	private final OladingInputRecordService oladingInputRecordService;
 
+	private final XinbadaInputRecordService xinbadaInputRecordService;
+
 	private final RedisTemplate redisTemplate;
 
 	private static final HMACSignProvider hMACSignProvide = new HMACSignProvider();
@@ -52,6 +65,78 @@ public class GigThirdApiController {
 	 */
 	private static final String ALGORITHM_TYPE = "HmacSHA256";
 
+	/**
+	 * 正启之星异步通知回调
+	 *
+	 * 接口用于接收批量订单创建结果通知和下发结果通知。
+	 * 请注意回调请求头默认的”Content-Type”: “application/octet-stream”
+	 * 企业需要给我方响应。通知超时时间10秒,如果没有收到正确响应视为通知失败,失败后重试3次,每次间隔10分钟。
+	 *
+	 * @param body 请求body
+	 * @param headers 请求头
+	 */
+	@Inner(value = false)
+	@SysLog("正启之星异步通知回调")
+	@PostMapping("/xinbada")
+	public Map<String, Object> xinbadaRequest(@RequestBody String body, @RequestHeader HttpHeaders headers) {
+
+		log.info("正启之星请求方法参数:body={}, headers={}", body, headers);
+
+		// 	签名
+		String signature = Objects.requireNonNull(headers.get("signature")).get(0);
+		// 通知类型(order_check_result_notify:订单校验结果通知,order_call_back_notification:订单下发回调通知,task_redispatch_notification:单笔重试回调通知)
+		String actionName = Objects.requireNonNull(headers.get("action_name")).get(0);
+
+		// 请求body json
+		JSONObject bodyJson = JSONUtil.parseObj(body);
+		Integer orderStatus = bodyJson.getInt("order_status");
+		String orderUuid = bodyJson.getStr("order_uuid");
+		String orderNo = bodyJson.getStr("order_no");
+		String customerUserUuid = bodyJson.getStr("customer_user_uuid");
+		String serverUserUuid = bodyJson.getStr("server_user_uuid");
+
+		Map<String, Object> successResult = new HashMap<>();
+		if (!StrUtil.isAllNotBlank(signature, actionName, orderNo) || orderStatus == null) {
+			log.warn("必传参数为空");
+			successResult.put("resp_code", 400);
+			successResult.put("resp_message", "必传参数为空");
+			successResult.put("success", "false");
+			return successResult;
+		}
+
+		String redisKey = String.format("%s_%s_%s", CacheConstants.ZHEGN_QI_ZHI_XING_NOTIFY_KEY, actionName, orderNo);
+		Boolean absent = redisTemplate.opsForValue().setIfAbsent(redisKey, orderNo, 30, TimeUnit.MINUTES);
+		if (!absent) {
+			log.warn("存在在途操作orderNo={}", orderNo);
+			successResult.put("resp_code", 400);
+			successResult.put("resp_message", "存在在途操作");
+			successResult.put("success", "false");
+			return successResult;
+		}
+
+		// 请求记录到数据库
+		XinbadaInputRecord xinbadaInputRecord = new XinbadaInputRecord();
+		xinbadaInputRecord.setActionName(actionName);
+		xinbadaInputRecord.setSignature(signature);
+		xinbadaInputRecord.setReqBody(body);
+		xinbadaInputRecord.setCreateTime(LocalDateTime.now());
+		// body中的部分字段
+		xinbadaInputRecord.setOrderStatus(orderStatus);
+		xinbadaInputRecord.setOrderUuid(orderUuid);
+		xinbadaInputRecord.setOrderNo(orderNo);
+		xinbadaInputRecord.setCustomerUserUuid(customerUserUuid);
+		xinbadaInputRecord.setServerUserUuid(serverUserUuid);
+		xinbadaInputRecordService.save(xinbadaInputRecord);
+
+		gigThirdApiService.xinbadaNotify(actionName, orderNo, orderStatus);
+
+		successResult.put("resp_code", 200);
+		successResult.put("resp_message", "SUCCESS");
+		successResult.put("success", "true");
+
+		return successResult;
+	}
+
 	/**
 	 * 自由职家统一请求地址
 	 *

+ 83 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/XinbadaInputRecord.java

@@ -0,0 +1,83 @@
+package com.qunzhixinxi.hnqz.admin.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 正启之星请求记录
+ *
+ * @TableName xinbada_input_record
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName(value = "xinbada_input_record")
+public class XinbadaInputRecord extends Model<XinbadaInputRecord> {
+
+	/**
+	 * 主键id
+	 */
+	@TableId(type = IdType.AUTO)
+	private Integer id;
+
+	/**
+	 * 签名
+	 */
+	private String signature;
+
+	/**
+	 * 通知类型
+	 */
+	private String actionName;
+
+	/**
+	 * 请求body内容
+	 */
+	private String reqBody;
+
+	/**
+	 * 订单编号唯一
+	 */
+	private String orderUuid;
+
+	/**
+	 * 订单状态
+	 */
+	private Integer orderStatus;
+
+	/**
+	 *
+	 */
+	private String orderNo;
+
+	/**
+	 *
+	 */
+	private String customerUserUuid;
+
+	/**
+	 *
+	 */
+	private String serverUserUuid;
+
+	/**
+	 * 请求公钥
+	 */
+	private String publicKey;
+
+	/**
+	 * 请求时私钥
+	 */
+	private String privateKey;
+
+	/**
+	 * 创建时间
+	 */
+	private LocalDateTime createTime;
+
+}

+ 1 - 2
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/enums/SubjectTypeEnum.java

@@ -14,8 +14,7 @@ public enum SubjectTypeEnum {
 	TYPE_SHUIBANGYUN("1", "税邦云"),
 	TYPE_OLADING("2", "自由职家"),
 	TYPE_YEE("3", "易联数科"),
-//	TYPE_JIN_YUAN("4", "金园数科"),
-//	TYPE_XIN_TAI_ZI("5", "薪泰梓"),
+	TYPE_ZHENG_QI_ZHI_XING("4", "政企之星"),
 
 
 	ENABLE_FLAG_FALSE("0", "无效"),

+ 17 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/XinbadaInputRecordMapper.java

@@ -0,0 +1,17 @@
+package com.qunzhixinxi.hnqz.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.entity.XinbadaInputRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author lixuesong
+ * @description 针对表【xinbada_input_record(正启之星请求记录)】的数据库操作Mapper
+ * @createDate 2022-09-09 14:09:31
+ * @Entity com.qunzhixinxi.hnqz.admin.entity.XinbadaInputRecord
+ */
+@Mapper
+public interface XinbadaInputRecordMapper extends BaseMapper<XinbadaInputRecord> {
+
+
+}

+ 13 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/XinbadaInputRecordService.java

@@ -0,0 +1,13 @@
+package com.qunzhixinxi.hnqz.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.entity.XinbadaInputRecord;
+
+/**
+ * @author lixuesong
+ * @description 针对表【xinbada_input_record(正启之星请求记录)】的数据库操作Service
+ * @createDate 2022-09-09 14:09:31
+ */
+public interface XinbadaInputRecordService extends IService<XinbadaInputRecord> {
+
+}

+ 9 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/gig/GigThirdApiService.java

@@ -10,6 +10,15 @@ import com.qunzhixinxi.hnqz.admin.api.dto.OladingCommonRequest;
  */
 public interface GigThirdApiService {
 
+	/**
+	 * 正启之星回调业务处理
+	 *
+	 * @param actionName
+	 * @param orderNo
+	 * @param orderStatus
+	 */
+	void xinbadaNotify(String actionName, String orderNo, Integer orderStatus);
+
 	/**
 	 * 自由职家回调业务处理
 	 *

+ 61 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/gig/impl/GigThirdApiServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qunzhixinxi.hnqz.admin.service.gig.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
@@ -36,6 +37,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author lixuesong
@@ -52,6 +54,65 @@ public class GigThirdApiServiceImpl implements GigThirdApiService {
 	private final WmScorePackageSettleNoteService scorePackageSettleNoteService;
 	private final WmScorePackageService scorePackageService;
 
+	/**
+	 * 正启之星回调业务处理
+	 *
+	 * @param actionName 通知类型 order_check_result_notify:订单校验结果通知,order_call_back_notification:订单下发回调通知,task_redispatch_notification:单笔重试回调通知
+	 * @param orderNo 订单no
+	 * @param orderStatus
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void xinbadaNotify(String actionName, String orderNo, Integer orderStatus) {
+
+		switch (actionName) {
+			// 订单下发回调通知
+			case "order_call_back_notification":
+
+				// 订单状态转换为
+				int yaoyiStatus;
+				switch (orderStatus){
+					case 50:
+						yaoyiStatus = 1;
+						break;
+					default:
+						yaoyiStatus = 2;
+						break;
+				}
+
+				// 根据orderNo查询结算单
+				List<WmScorePackageSettleNote> settleNoteList = scorePackageSettleNoteService.list(Wrappers.<WmScorePackageSettleNote>lambdaQuery()
+						.eq(WmScorePackageSettleNote::getSettleNo, orderNo));
+				if (CollUtil.isEmpty(settleNoteList)) {
+					log.warn("订单号orderNo={}对应结算单不存在", orderNo);
+					return;
+				}
+
+				// 修改结算状态
+				List<WmScorePackageSettleNote> updateList = settleNoteList.stream().map(note -> {
+					WmScorePackageSettleNote updateEntity = new WmScorePackageSettleNote();
+					updateEntity.setId(note.getId());
+					updateEntity.setSettleNoteStatus(yaoyiStatus);
+					if (yaoyiStatus == 1){
+						updateEntity.setNotifyTime(LocalDateTime.now());
+					}
+					updateEntity.setUpdateTime(LocalDateTime.now());
+					return updateEntity;
+				}).collect(Collectors.toList());
+
+				scorePackageSettleNoteService.updateBatchById(updateList);
+
+				WmScorePackageSettleNote tmp = settleNoteList.get(0);
+				redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + tmp.getId());
+
+				break;
+			default:
+				log.warn("通知类型暂不处理actionName={}", actionName);
+				break;
+		}
+
+	}
+
 	/**
 	 * 自由职家回调业务处理
 	 *

+ 1 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/SysUserServiceImpl.java

@@ -213,6 +213,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 			switch (subjectLocation.getGigType()) {
 				case REN_LI_JIA:
 				case OLADING:
+				case ZHENG_QI_ZHI_XING:
 					if (!Objects.equals(userSub.getCertStatus(), DingEnum.CER_STATUS_1.getType())) {
 						throw new RuntimeException(user.getRealname() + "未认证,不能发起结算");
 					}

+ 172 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmPayOffServiceImpl.java

@@ -380,6 +380,10 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 		else if (SubjectTypeEnum.TYPE_OLADING.getCode().equals(subType)) {
 			return settleByOlading(input, wmScorePackage, taxCode, operator);
 		}
+		// 正启之星
+		else if (SubjectTypeEnum.TYPE_ZHENG_QI_ZHI_XING.getCode().equals(subType)){
+			return settleBySinbaad(input, wmScorePackage, taxCode, operator);
+		}
 		// 税邦云
 		else {
 			log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码:{} ", taxCode);
@@ -423,6 +427,10 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 		else if (SubjectTypeEnum.TYPE_OLADING.getCode().equals(subType)) {
 			return settleByOlading(input, wmScorePackage, taxCode, operator);
 		}
+		// 正启之星
+		else if (SubjectTypeEnum.TYPE_ZHENG_QI_ZHI_XING.getCode().equals(subType)){
+			return settleBySinbaad(input, wmScorePackage, taxCode, operator);
+		}
 		// 税邦云
 		else {
 			log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码:{} ", taxCode);
@@ -431,6 +439,170 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 
 	}
 
+	/**
+	 * 阿拉丁结算操作
+	 *
+	 * @param input          结算数据
+	 * @param wmScorePackage 积分包
+	 * @param taxCode        税号
+	 * @param operator       操作员
+	 * @return 结果
+	 */
+	private R<?> settleBySinbaad(WmScorePackageSettleInput input,
+								 WmScorePackage wmScorePackage,
+								 String taxCode,
+								 HnqzUser operator) {
+
+		List<WmScorePackageSettleNote> notes = input.getNotes();
+		StringBuilder noticeInfo = new StringBuilder();
+
+		// WmScorePackageSettleNote
+		for (WmScorePackageSettleNote note : notes) {
+			note.setInvoiceType(input.getInvoiceCategory());
+			note.setCategoryName(StrUtil.isNotBlank(input.getCategoryName()) ? input.getCategoryName() : note.getCategoryName());
+			note.setSubToGigTime(LocalDateTime.now());
+		}
+		noteService.updateBatchById(notes);
+
+
+		for (WmScorePackageSettleNote note : notes) {
+			SysUser sysUser = sysUserMapper.selectById(note.getUserId());
+
+			SysUserSub userSub = sysUserSubMapper.selectOne(Wrappers.<SysUserSub>lambdaQuery()
+					.eq(SysUserSub::getUserId, sysUser.getUserId())
+					.eq(SysUserSub::getSubjectLocation, input.getSubjectLocation())
+					.eq(SysUserSub::getDeptId, operator.getDeptId())
+			);
+
+			if (userSub == null) {
+				log.info("结算对象-" + sysUser.getRealname() + ":认证信息不存在,不能结算");
+				return R.failed("结算对象-" + sysUser.getRealname() + ":认证信息不存在,不能结算");
+			}
+
+			if (!Objects.equals(userSub.getCertStatus(), DingEnum.CER_STATUS_1.getType())) {
+				return R.failed(sysUser.getRealname() + "人员未认证或未绑卡,不能结算");
+			}
+
+			if (Boolean.TRUE.equals(redisTemplate.hasKey(CacheConstants.SETTLE_PACKAGE_KEY + note.getId()))) {
+				return R.failed("结算对象-" + sysUser.getRealname() + ":正在结算,请勿重复结算");
+			}
+
+			if (DingEnum.NOTE_STATUS_SUCCESS.getType().equals(note.getSettleNoteStatus())) {
+				log.info("结算对象-" + sysUser.getRealname() + ":已结算,请勿重复结算");
+				return R.failed("结算对象-" + sysUser.getRealname() + ":已结算,请勿重复结算");
+			}
+			if (DingEnum.NOTE_STATUS_SUBMIT.getType().equals(note.getSettleNoteStatus())) {
+				log.info("结算对象-" + sysUser.getRealname() + ":已提交,请等待耐心结算结果");
+				return R.failed("结算对象-" + sysUser.getRealname() + ":已提交,请等待耐心结算结果");
+			}
+		}
+
+		for (WmScorePackageSettleNote note : notes) {
+			// 加锁
+			redisTemplate.opsForValue().set(CacheConstants.SETTLE_PACKAGE_KEY + note.getId(),
+					note.getId(), CacheConstants.SETTLE_TIME, TimeUnit.DAYS);
+
+			SysUser sysUser = sysUserMapper.selectById(note.getUserId());
+
+			try {
+
+				// 获取请求token
+				String url = String.format(GIG_TOKEN_URL, upmsConfig.getGigServiceUrl());
+				log.info("远端请求gig-token:{}", url);
+				ResponseEntity<String> tokenResult = new RestTemplate().getForEntity(url, String.class,
+						String.valueOf(operator.getDeptId()), "settle", String.valueOf(operator.getId()));
+				log.warn("获取结算token:{}", tokenResult.getBody());
+				if (!JSONUtil.isJson(tokenResult.getBody())) {
+					return R.failed("获取结算token失败");
+				}
+
+				JSONObject jsonObject = JSONUtil.parseObj(tokenResult.getBody());
+
+				if (jsonObject.getInt("code") != 0 || StrUtil.isBlank(jsonObject.getStr("data"))) {
+					return R.failed("获取结算token失败");
+				}
+
+				String token = jsonObject.getStr("data");
+
+				// 间隔100毫秒
+				Thread.sleep(100);
+
+				// 封装结算参数
+				Map<String, Object> params = new HashMap<>();
+				params.put("token", token);
+				params.put("tenantId", operator.getDeptId());
+				params.put("operatorId", operator.getId());
+				params.put("amount", String.valueOf(note.getSettleAmount().doubleValue()));
+				params.put("username", sysUser.getUsername());
+				params.put("idCard", sysUser.getIdCardNumber());
+				params.put("realName", sysUser.getRealname());
+				params.put("bankCard", sysUser.getBankCardNumber());
+				params.put("endType", "CSO");
+				params.put("enterpriseCode", taxCode);
+				params.put("idCardType","ID_CARD");
+				params.put("subjectType", "ZHENG_QI_ZHI_XING");
+				params.put("channel", "DEFAULT");
+				params.put("subjectLocation", input.getSubjectLocation().getType());
+
+				// 发起结算
+				String url1 = String.format(GIG_SETTLE_URL, upmsConfig.getGigServiceUrl());
+				log.info("远端请求gig-settle:{}", url);
+				HttpHeaders headers = new HttpHeaders();
+				headers.setContentType(MediaType.APPLICATION_JSON);
+				HttpEntity<String> result = new RestTemplate().exchange(url1, HttpMethod.POST, new HttpEntity<>(params, headers), String.class);
+				log.warn("政企之星结算: {}", result.getBody());
+				if (!JSONUtil.isJson(result.getBody())) {
+					return R.failed("结算失败");
+				}
+
+				JSONObject settleObj = JSONUtil.parseObj(result.getBody());
+
+
+				if (Objects.equals(settleObj.getInt("code"), CommonConstants.SUCCESS)) {
+					log.info("政企之星结算提交成功: {}", settleObj.getStr("data"));
+					//streamId 获取不到
+					if (StringUtils.isEmpty(settleObj.getStr("data"))) {
+						log.warn("政企之星结算提交成功 orderNo 获取不到: {}", settleObj.getStr("data"));
+						noticeInfo.append(sysUser.getRealname()).append(":提交结算成功,业务流水号获取不到,请联系管理员;");
+					}
+					note.setUpdateTime(LocalDateTime.now());
+					note.setSettleNoteStatus(DingEnum.NOTE_STATUS_SUBMIT.getType());
+					// 新增字段streamId
+					note.setStreamId(settleObj.getStr("data"));
+					noticeInfo.append(sysUser.getRealname()).append(":提交结算成功;");
+				} else {
+					log.warn("政企之星结算失败: {}", note.getSettleNo());
+					note.setUpdateTime(LocalDateTime.now());
+					note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+					noticeInfo.append(sysUser.getRealname()).append(":结算提交失败-").append(settleObj.getStr("msg")).append(";");
+
+					log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+					redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + note.getId());
+
+				}
+			} catch (Exception e) {
+				log.warn("政企之星结算提交失败: {}", note.getSettleNo());
+				note.setUpdateTime(LocalDateTime.now());
+				note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+				noticeInfo.append(sysUser.getRealname()).append(":结算提交失败;");
+
+				log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+				redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + note.getId());
+			}
+		}
+
+		noteService.updateBatchById(notes);
+
+		// 更新结算结果
+		SettleNoteStatusOutput output = noteService.selectSettleNoteStatus(input.getId());
+		WmScorePackage updateEntity = new WmScorePackage();
+		updateEntity.setId(input.getId());
+		updateEntity.setSettleStatus(output.toSettleStatus());
+		wmScorePackageService.updateById(updateEntity);
+
+		return R.ok(null, noticeInfo.toString());
+	}
+
 
 	/**
 	 * 阿拉丁结算操作

+ 294 - 1
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmScorePackageSettleNoteServiceImpl.java

@@ -543,6 +543,7 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 		switch (gigTypeEnum) {
 			case REN_LI_JIA:
 			case OLADING:
+			case ZHENG_QI_ZHI_XING:
 				if (!Objects.equals(userSub.getCertStatus(), DingEnum.CER_STATUS_1.getType())) {
 					return R.failed(sysUser.getRealname() + "未认证,不能发起结算");
 				}
@@ -577,6 +578,11 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 			String taxCode = sysDept.getTaxCode();
 			return settleByOlading(note, wmScorePackage, sysUser, taxCode);
 		}
+		//政企之星
+		else if (SubjectTypeEnum.TYPE_ZHENG_QI_ZHI_XING.getCode().equals(subType)){
+			String taxCode = sysDept.getTaxCode();
+			return settleBySinbaad(note, wmScorePackage, sysUser, taxCode);
+		}
 		// 税邦云
 		else {
 			String taxCode = sysDept.getTaxCode();
@@ -660,6 +666,7 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 			switch (gigTypeEnum) {
 				case REN_LI_JIA:
 				case OLADING:
+				case ZHENG_QI_ZHI_XING:
 					if (!Objects.equals(userSub.getCertStatus(), DingEnum.CER_STATUS_1.getType())) {
 						return R.failed(sysUser.getRealname() + "未认证,不能发起结算");
 					}
@@ -689,7 +696,7 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 
 			}
 			// 自由职家
-			else if (SubjectTypeEnum.TYPE_OLADING.getCode().equals(subType)) {
+			else if (SubjectTypeEnum.TYPE_OLADING.getCode().equals(subType) || SubjectTypeEnum.TYPE_ZHENG_QI_ZHI_XING.getCode().equals(subType)) {
 				oladingNoteList.add(note);
 			}
 			// 税邦云
@@ -714,6 +721,16 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 			return settleByTaxHelper(noteList, config, taxCode);
 			// return settleByTaxHelper();
 		}
+		// 政企之星结算
+		if (CollectionUtils.isNotEmpty(oladingNoteList)) {
+			if (StringUtils.isNotEmpty(taxCode)) {
+				log.info("政企之星结算结算开始-获取会员所属企业的统一社会信用代码:{} ", taxCode);
+			} else {
+				return R.failed("未配置企业的统一社会信用代码");
+			}
+			return batchSettleBySinbaad(oladingNoteList, taxCode);
+			// return settleByTaxHelper();
+		}
 
 		// 自由职家结算
 		if (CollectionUtils.isNotEmpty(oladingNoteList)) {
@@ -734,6 +751,178 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 		return R.failed("因系统维护,暂时不能提起支付,有问题请联系客服");
 	}
 
+	/**
+	 * 政企之星结算
+	 *
+	 * @param noteList 结算记录
+	 * @param taxCode  企业三合一码
+	 * @return 结果
+	 */
+	private R batchSettleBySinbaad(List<WmScorePackageSettleNote> noteList, String taxCode) {
+
+		// 加锁
+		List<Integer> noteIdList = noteList.stream().filter(note ->
+						redisTemplate.opsForValue().setIfAbsent(
+								CacheConstants.SETTLE_PACKAGE_KEY + ":note_id_" + note.getId(),
+								noteList, CacheConstants.SETTLE_TIME, TimeUnit.DAYS))
+				.mapToInt(WmScorePackageSettleNote::getId).boxed().collect(Collectors.toList());
+
+		// 加锁记录数不等于提交记录数,说明存在在途交易
+		if (CollectionUtils.isEmpty(noteIdList)) {
+			log.error("当前用户存在其他结算请求");
+			return R.failed("当前用户存在其他结算请求");
+		} else {
+			if (!Objects.equals(noteList.size(), noteIdList.size())) {
+				// 删除锁
+				noteIdList.forEach(id -> redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + ":note_id_" + id));
+				log.error("当前用户存在其他结算请求");
+				return R.failed("当前用户存在其他结算请求");
+			}
+		}
+
+		HnqzUser operator = SecurityUtils.getUser();
+		String gigTokenUrl = upmsConfig.getGigServiceUrl() + "/gig/operation/token?tenantId={tenantId}&action={action}&userId={userId}";
+		String gigSettleUrl = upmsConfig.getGigServiceUrl() + "/gig/operation/settlement";
+
+		List<Map<String, Object>> settleParamsMapper = new ArrayList<>();
+		Map<String, Map<String, Object>> detailMap = new HashMap<>();
+		noteList.forEach(note -> {
+			WmScorePackage wmScorePackage = wmScorePackageMapper.selectById(note.getPackageId());
+			// 封装结算参数
+			Map<String, Object> params;
+			if (detailMap.containsKey(note.getIdCardNumber())) {
+				params = detailMap.get(note.getIdCardNumber());
+				params.put("amount", String.valueOf(new BigDecimal((String) params.get("amount")).add(note.getSettleAmount()).doubleValue()));
+
+
+				LocalDate startTime = (LocalDate) params.get("taskStartTime");
+				LocalDate endTime = (LocalDate) params.get("taskEndTime");
+				LocalDate noteCreateTime = wmScorePackage.getCreateTime().toLocalDate();
+				LocalDate noteUpdateTime = wmScorePackage.getUpdateTime().toLocalDate();
+
+				if (noteCreateTime.isBefore(startTime)) {
+					params.put("taskStartTime", wmScorePackage.getCreateTime().toLocalDate());
+				}
+				if (noteUpdateTime.isAfter(endTime)) {
+					params.put("taskEndTime", wmScorePackage.getUpdateTime().toLocalDate());
+				}
+
+				Set<Integer> ids = (Set<Integer>) params.get("noteIds");
+				ids.add(note.getId());
+				params.put("noteIds", ids);
+			} else {
+				SysUser sysUser = sysUserService.getById(note.getUserId());
+				params = new HashMap<>(19);
+				params.put("tenantId", operator.getDeptId());
+				params.put("operatorId", operator.getId());
+				params.put("amount", String.valueOf(note.getSettleAmount().doubleValue()));
+				params.put("username", sysUser.getUsername());
+				params.put("idCard", sysUser.getIdCardNumber());
+				params.put("realName", sysUser.getRealname());
+				params.put("bankCard", sysUser.getBankCardNumber());
+				params.put("endType", "CSO");
+				params.put("enterpriseCode", taxCode);
+				params.put("idCardType","ID_CARD");
+				params.put("subjectType", "ZHENG_QI_ZHI_XING");
+				params.put("channel", "DEFAULT");
+				params.put("subjectLocation", note.getSubjectLocation());
+
+
+				Set<Integer> noteIds = new HashSet<>();
+				noteIds.add(note.getId());
+				params.put("noteIds", noteIds);
+				detailMap.put(note.getIdCardNumber(), params);
+			}
+		});
+
+		detailMap.forEach((key, value) -> settleParamsMapper.add(value));
+
+
+		// 开始结算
+		for (Map<String, Object> params : settleParamsMapper) {
+
+			Set<Integer> noteIds = (Set<Integer>) params.get("noteIds");
+			try {
+				// 获取请求token
+				ResponseEntity<String> tokenResult = new RestTemplate().getForEntity(gigTokenUrl, String.class,
+						String.valueOf(operator.getDeptId()), "settle", String.valueOf(operator.getId()));
+				log.warn("获取结算token:{}", tokenResult.getBody());
+				if (!JSONUtil.isJson(tokenResult.getBody())) {
+					return R.failed("获取结算token失败");
+				}
+
+				JSONObject jsonObject = JSONUtil.parseObj(tokenResult.getBody());
+
+				if (jsonObject.getInt("code") != 0 || StrUtil.isBlank(jsonObject.getStr("data"))) {
+					return R.failed("获取结算token失败");
+				}
+
+				String token = jsonObject.getStr("data");
+
+				// 间隔100毫秒
+				Thread.sleep(100);
+
+				params.put("token", token);
+
+				// 发起结算
+				HttpHeaders headers = new HttpHeaders();
+				headers.setContentType(MediaType.APPLICATION_JSON);
+				HttpEntity<String> result = new RestTemplate().exchange(gigSettleUrl, HttpMethod.POST, new HttpEntity<>(params, headers), String.class);
+				log.warn("政企之星结算: {}", result.getBody());
+				if (!JSONUtil.isJson(result.getBody())) {
+					return R.failed("结算失败");
+				}
+				JSONObject settelObj = JSONUtil.parseObj(result.getBody());
+
+				if (Objects.equals(settelObj.getInt("code"), CommonConstants.SUCCESS)) {
+					noteIds.forEach(id -> {
+						log.info("政企之星结算结算提交成功");
+						//streamId 获取不到
+						if (StringUtils.isEmpty(settelObj.getStr("data"))) {
+							log.info("政企之星结算提交成功 streamId 获取不到");
+						}
+						WmScorePackageSettleNote note = new WmScorePackageSettleNote();
+						note.setId(id);
+						note.setUpdateTime(LocalDateTime.now());
+						note.setSettleNoteStatus(DingEnum.NOTE_STATUS_SUBMIT.getType());
+						// 新增字段streamId
+						note.setStreamId(settelObj.getStr("data"));
+						this.baseMapper.updateById(note);
+					});
+
+				} else {
+					noteIds.forEach(id -> {
+						WmScorePackageSettleNote note = new WmScorePackageSettleNote();
+						note.setId(id);
+						log.info("政企之星结算提交失败: {}", note.getSettleNo());
+						note.setUpdateTime(LocalDateTime.now());
+						note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+						this.baseMapper.updateById(note);
+						log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+						redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + ":note_id_" + note.getId());
+					});
+
+					return R.ok("结算失败");
+				}
+
+			} catch (Exception e) {
+				noteIds.forEach(id -> {
+					WmScorePackageSettleNote note = new WmScorePackageSettleNote();
+					note.setId(id);
+					log.info("政企之星结算提交失败: {}", note.getSettleNo());
+					note.setUpdateTime(LocalDateTime.now());
+					note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+					this.baseMapper.updateById(note);
+					log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+					redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + ":note_id_" + note.getId());
+				});
+				return R.ok("结算失败");
+			}
+		}
+
+		return R.ok("提交结算成功");
+	}
+
 	/**
 	 * 哦拉丁结算
 	 *
@@ -1019,6 +1208,110 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 		}
 	}
 
+	private R settleBySinbaad(WmScorePackageSettleNote note,
+							  WmScorePackage wmScorePackage,
+							  SysUser sysUser,
+							  String taxCode) {
+
+		/**
+		 * 加锁
+		 */
+		redisTemplate.opsForValue().set(CacheConstants.SETTLE_PACKAGE_KEY + note.getId(),
+				note.getId(), CacheConstants.SETTLE_TIME, TimeUnit.DAYS);
+
+		/**
+		 * 开始结算
+		 */
+
+		HnqzUser operator = SecurityUtils.getUser();
+		String gigTokenUrl = upmsConfig.getGigServiceUrl() + "/gig/operation/token?tenantId={tenantId}&action={action}&userId={userId}";
+		String gigSettleUrl = upmsConfig.getGigServiceUrl() + "/gig/operation/settlement";
+
+		try {
+			// 获取请求token
+			ResponseEntity<String> tokenResult = new RestTemplate().getForEntity(gigTokenUrl, String.class,
+					String.valueOf(operator.getDeptId()), "settle", String.valueOf(operator.getId()));
+			log.warn("获取结算token:{}", tokenResult.getBody());
+			if (!JSONUtil.isJson(tokenResult.getBody())) {
+				return R.failed("获取结算token失败");
+			}
+
+			JSONObject jsonObject = JSONUtil.parseObj(tokenResult.getBody());
+
+			if (jsonObject.getInt("code") != 0 || StrUtil.isBlank(jsonObject.getStr("data"))) {
+				return R.failed("获取结算token失败");
+			}
+
+			String token = jsonObject.getStr("data");
+
+			// 间隔100毫秒
+			Thread.sleep(100);
+
+
+			// 封装结算参数
+
+			// 封装结算参数
+			Map<String, Object> params = new HashMap<>();
+			params.put("token", token);
+			params.put("tenantId", operator.getDeptId());
+			params.put("operatorId", operator.getId());
+			params.put("amount", String.valueOf(note.getSettleAmount().doubleValue()));
+			params.put("username", sysUser.getUsername());
+			params.put("idCard", sysUser.getIdCardNumber());
+			params.put("realName", sysUser.getRealname());
+			params.put("bankCard", sysUser.getBankCardNumber());
+			params.put("endType", "CSO");
+			params.put("enterpriseCode", taxCode);
+			params.put("idCardType","ID_CARD");
+			params.put("subjectType", "ZHENG_QI_ZHI_XING");
+			params.put("channel", "DEFAULT");
+			params.put("subjectLocation", note.getSubjectLocation());
+
+
+			// 发起结算
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_JSON);
+			HttpEntity<String> result = new RestTemplate().exchange(gigSettleUrl, HttpMethod.POST, new HttpEntity<>(params, headers), String.class);
+			log.warn("政企之星结算: {}", result.getBody());
+			if (!JSONUtil.isJson(result.getBody())) {
+				return R.failed("结算失败");
+			}
+			JSONObject settelObj = JSONUtil.parseObj(result.getBody());
+
+
+			if (Objects.equals(settelObj.getInt("code"), CommonConstants.SUCCESS)) {
+				log.info("政企之星结算提交成功: {}", note.getSettleNo());
+				//streamId 获取不到
+				if (StringUtils.isEmpty(settelObj.getStr("data"))) {
+					log.warn("政企之星结算提交成功 requestId 获取不到: {}", note.getSettleNo());
+				}
+				note.setUpdateTime(LocalDateTime.now());
+				note.setSettleNoteStatus(DingEnum.NOTE_STATUS_SUBMIT.getType());
+				// 新增字段streamId
+				note.setStreamId(settelObj.getStr("data"));
+			} else {
+				log.warn("政企之星结算提交失败: {}", note.getSettleNo());
+				note.setUpdateTime(LocalDateTime.now());
+				note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+
+				log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+				redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + note.getId());
+
+			}
+		} catch (Exception e) {
+			log.warn("政企之星结算提交失败: {}", note.getSettleNo());
+			note.setUpdateTime(LocalDateTime.now());
+			note.setSettleNoteStatus(DingEnum.NOTE_STATUS_FAIL.getType());
+
+			log.info("认证状态异常,结算解锁settleNoteId:{}", note.getId());
+			redisTemplate.delete(CacheConstants.SETTLE_PACKAGE_KEY + note.getId());
+		}
+
+		this.baseMapper.updateById(note);
+
+		return R.ok();
+	}
+
 	private R settleByOlading(WmScorePackageSettleNote note,
 							  WmScorePackage wmScorePackage,
 							  SysUser sysUser,

+ 18 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/XinbadaInputRecordServiceImpl.java

@@ -0,0 +1,18 @@
+package com.qunzhixinxi.hnqz.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qunzhixinxi.hnqz.admin.entity.XinbadaInputRecord;
+import com.qunzhixinxi.hnqz.admin.mapper.XinbadaInputRecordMapper;
+import com.qunzhixinxi.hnqz.admin.service.XinbadaInputRecordService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author lixuesong
+ * @description 针对表【xinbada_input_record(正启之星请求记录)】的数据库操作Service实现
+ * @createDate 2022-09-09 14:09:31
+ */
+@Service
+public class XinbadaInputRecordServiceImpl extends ServiceImpl<XinbadaInputRecordMapper, XinbadaInputRecord>
+		implements XinbadaInputRecordService {
+
+}