Browse Source

feat: 结算包适配批量结算

shc 3 years ago
parent
commit
c1f14dcf92

+ 6 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmScorePackageSettleNoteService.java

@@ -69,6 +69,12 @@ public interface WmScorePackageSettleNoteService extends IService<WmScorePackage
 	 */
 	R singletSettle(WmScorePackageSettleNote note);
 
+	/**
+	 * 提交结算申请
+	 *
+	 * @param note
+	 * @return R
+	 */
 	R batchSettle(WmScorePackageSettleNote note);
 
 	/**

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

@@ -74,6 +74,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -559,6 +560,7 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 
 		String[] ids = input.getIdStr().split(",");
 		List<WmScorePackageSettleNote> noteList = new ArrayList<>(ids.length);
+		List<WmScorePackageSettleNote> oladingNoteList = new ArrayList<>(ids.length);
 		for (int i = 0; i < ids.length; i++) {
 			String id = ids[i];
 			WmScorePackageSettleNote note = this.baseMapper.selectById(id);
@@ -581,22 +583,39 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 			}
 
 			SysUser sysUser = sysUserService.getById(note.getUserId());
+
+			// 获取结算零工
+			GigTypeEnum gigTypeEnum = GigTypeEnum.resolve(Integer.parseInt(note.getSubType()));
+
+			if (gigTypeEnum == null){
+				return R.failed(sysUser.getRealname() + "人员结算渠道不存在,不能结算");
+			}
+
+			SysUserSub userSub = sysUserSubMapper.selectOne(Wrappers.<SysUserSub>lambdaQuery().eq(SysUserSub::getGigType, gigTypeEnum)
+					.eq(SysUserSub::getUserId, sysUser.getUserId())
+			);
+
+			if (userSub == null){
+				return R.failed(sysUser.getRealname() + "人员认证信息不存在,不能结算");
+			}
+
 			if (redisTemplate.hasKey(CacheConstants.SETTLE_PACKAGE_KEY + note.getId())) {
 				return R.failed("结算对象-" + sysUser.getRealname() + ":正在结算,请勿重复结算");
 			}
-			if (SubjectTypeEnum.TYPE_RENLIJIA.getCode().equals(note.getSubType())) {
-				log.info("结算渠道 {}", SubjectTypeEnum.TYPE_RENLIJIA.getDesc());
-				if (!DingEnum.CER_STATUS_1.getType().equals(sysUser.getRljCertStatus())) {
-					//认证中
-					log.info("结算对象- {} :未认证成功,不能结算", sysUser.getRealname());
-					return R.failed("结算对象-" + sysUser.getRealname() + ":未认证成功,不能结算");
-				}
-			} else {
-				log.info("结算渠道 {}", SubjectTypeEnum.TYPE_SHUIBANGYUN.getDesc());
-				if (!Objects.equals(sysUser.getCertStatus(), TaxHelperCertStatus.CERT.getCode())) {
-					log.info("结算对象- {} :人员未认证或未绑卡,不能结算", sysUser.getRealname());
-					return R.failed("人员未认证或未绑卡,不能结算");
-				}
+
+			switch (gigTypeEnum) {
+				case REN_LI_JIA:
+				case OLADING:
+					if (!Objects.equals(userSub.getCertStatus(), DingEnum.CER_STATUS_1.getType())) {
+						return R.failed(sysUser.getRealname() + "未认证,不能发起结算");
+					}
+					break;
+				case TAX_HELPOR:
+					if (!Objects.equals(userSub.getCertStatus(), TaxHelperCertStatus.CERT.getCode())) {
+						return R.failed(sysUser.getRealname() + "人员未认证或未绑卡,不能结算");
+					}
+				default:
+					return R.failed(sysUser.getRealname() + "人员结算渠道不存在,不能结算");
 			}
 
 			/**
@@ -613,14 +632,20 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 				String subjectName = sysDeptSub.getSubjectName();
 				settleByRenLiJia(note, config, wmScorePackage, subjectName);
 
-			} else {
+			}
+			// 自由职家
+			else if (SubjectTypeEnum.TYPE_OLADING.getCode().equals(note.getSubType())){
+				oladingNoteList.add(note);
+			}
+			// 税邦云
+			else {
 				noteList.add(note);
 			}
 		}
 
 		// 税邦云结算
+		String taxCode = sysDept.getTaxCode();
 		if (CollectionUtils.isNotEmpty(noteList)) {
-			String taxCode = sysDept.getTaxCode();
 			if (StringUtils.isNotEmpty(taxCode)) {
 				log.info("税邦云结算开始-获取会员所属企业的统一社会信用代码:{} ", taxCode);
 			} else {
@@ -634,6 +659,18 @@ 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 batchSettleByOlading(oladingNoteList,taxCode);
+			// return settleByTaxHelper();
+		}
+
 		return R.ok();
 	}
 
@@ -642,6 +679,183 @@ public class WmScorePackageSettleNoteServiceImpl extends ServiceImpl<WmScorePack
 		return R.failed("因系统维护,暂时不能提起支付,有问题请联系客服");
 	}
 
+	/**
+	 * 税帮云结算
+	 *
+	 * @param noteList 结算记录
+	 * @param taxCode  企业三合一码
+	 * @return 结果
+	 */
+	private R batchSettleByOlading(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("requestId", RandomStringUtils.randomAlphabetic(12));
+				params.put("taskName", String.format("%s(%s)_%s", sysUser.getRealname(), sysUser.getUsername(), System.currentTimeMillis()));
+				params.put("amount", String.valueOf(note.getSettleAmount().doubleValue()));
+				params.put("taskStartTime", wmScorePackage.getCreateTime().toLocalDate());
+				params.put("taskEndTime", wmScorePackage.getUpdateTime().toLocalDate());
+				params.put("taskLocation", "要易云");
+				params.put("username", sysUser.getUsername());
+				params.put("idCard", note.getIdCardNumber());
+				params.put("realName", sysUser.getRealname());
+				params.put("bankCard", sysUser.getBankCardNumber());
+				params.put("tagId", note.getInvoiceType());
+				params.put("endType", "CSO");
+				params.put("enterpriseCode", taxCode);
+				params.put("subjectType", "OLADING");
+				params.put("channel", "DEFAULT");
+				params.put("taskDescription", "根据要求,执行、并完成学术推广活动,并以在线平台工具采集、记录活动内容");
+				params.put("acceptanceStandard", "完成不同任务获得不同任务积分,根据不同任务给与0~30000积分,每个积分兑换0.8~1.2元,按次数结算");
+
+				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("提交结算成功");
+	}
+
 	/**
 	 * 税帮云结算
 	 *