Browse Source

feat: 提交结算时获取token,并优化校验

shc 3 years ago
parent
commit
1b8fb6bcb1

+ 61 - 11
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmPayOffController.java

@@ -18,22 +18,30 @@ import com.qunzhixinxi.hnqz.admin.service.WmScorePackageService;
 import com.qunzhixinxi.hnqz.common.core.util.R;
 import com.qunzhixinxi.hnqz.common.ding.enums.DingEnum;
 import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
+import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
 import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.validation.Valid;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 结算表
@@ -41,6 +49,7 @@ import java.util.Map;
  * @author Liujh
  * @date 2020-12-1
  */
+@Slf4j
 @RestController
 @AllArgsConstructor
 @RequestMapping("/settle" )
@@ -49,6 +58,7 @@ public class WmPayOffController {
 
 	private final WmPayOffService wmPayOffService;
 	private final WmScorePackageService wmScorePackageService;
+	private final RedisTemplate<String, Object> redisTemplate;
 
 
 	@ApiOperation(value = "结算回退", notes = "提交结算")
@@ -61,19 +71,59 @@ public class WmPayOffController {
 		return wmPayOffService.settleBack(input);
 	}
 
-	@ApiOperation(value = "提交结算", notes = "提交结算")
-	@SysLog("提交结算" )
-	@PostMapping("/settleSubmit")
-	public R settleSubmit(@RequestBody WmScorePackageSettleInput input) {
-		if(CollectionUtils.isEmpty(input.getNotes())){
-			return R.failed("数据异常");
-		}
 
-		if(StringUtils.isEmpty(input.getId())){
-			return R.failed("数据异常");
+	/**
+	 * 获取批量结算token,三分钟有效
+	 * token格式:[租户i]d:order_batch:[用户id]:token:
+	 *
+	 * @return 结算token
+	 */
+	@GetMapping(value = "/token")
+	public String getOrderBatchToken() {
+
+		String randomStr;
+
+		// 获取操作员
+		HnqzUser finaAdmin = SecurityUtils.getUser();
+		final String token = String.format("%d:order_batch:%d:token", finaAdmin.getTenantId(), finaAdmin.getId());
+
+		// 返回缓存生成好的
+		if (Boolean.TRUE.equals(redisTemplate.hasKey(token))){
+			return (String) redisTemplate.opsForValue().get(token);
 		}
-		if(null == input.getInvoiceCategory()){
-			return R.failed("数据异常");
+
+		// 生成缓存key,将token缓存到redis
+		do {
+			randomStr = RandomStringUtils.randomNumeric(6);
+		} while (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(token, randomStr, 3, TimeUnit.MINUTES)));
+
+		return randomStr;
+
+	}
+
+	/**
+	 * 业务提交结算信息到财务
+	 *
+	 * @param input 输入信息
+	 * @return 提交结果
+	 */
+	@ApiOperation(value = "提交结算", notes = "提交结算")
+	@SysLog("提交结算")
+	@PostMapping("/settleSubmit")
+	public R settleSubmit(@RequestBody @Valid WmScorePackageSettleInput input) {
+
+		//1、验证令牌是否合法【令牌的对比和删除必须保证原子性】
+		HnqzUser finaAdmin = SecurityUtils.getUser();
+		final String REDIS_DEL_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
+		Long execute = redisTemplate.execute(new DefaultRedisScript<>(REDIS_DEL_SCRIPT, Long.class),
+				Collections.singletonList(String.format("%d:order_batch:%d:token", finaAdmin.getTenantId(), finaAdmin.getId())), input.getToken());
+		// 通过EVAL脚本原子验证令牌和删除令牌
+		boolean oops = (execute != null && execute == 0);
+
+		// 令牌验证失败
+		if (oops) {
+			log.error(String.format("提交 TOKEN 不正确:%s", input.getToken()));
+			R.failed("提交 TOKEN 不正确,请刷新页面重试");
 		}
 
 		return wmPayOffService.settleSubmit(input);

+ 11 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/entity/input/WmScorePackageSettleInput.java

@@ -5,6 +5,8 @@ import com.qunzhixinxi.hnqz.admin.enums.CategoryEnum;
 import com.qunzhixinxi.hnqz.common.ding.enums.DingEnum;
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -17,10 +19,18 @@ public class WmScorePackageSettleInput {
 	/**
 	 * packageId
 	 */
+	@NotBlank(message = "积分包信息必填")
 	private String id;
 
+	/**
+	 * 发票类目
+	 */
+	@NotBlank(message = "发票类目必填")
 	private Integer invoiceCategory;
 
+	@NotBlank(message = "结算token必填")
+	private String token;
+
 	private String categoryName;
 
 	private String status;
@@ -54,6 +64,7 @@ public class WmScorePackageSettleInput {
 	private Integer ysh;
 	private Integer dsh;
 
+	@NotEmpty(message = "结算信息必填")
 	private List<WmScorePackageSettleNote> notes;
 
 	/**

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

@@ -27,6 +27,12 @@ public interface WmPayOffService extends IService<WmPayOff> {
 
 	R settleReIssue(WmScorePackageSettleInput input);
 
+	/**
+	 * 业务提交结算信息到财务
+	 *
+	 * @param input 输入信息
+	 * @return 提交结果
+	 */
 	R settleSubmit(WmScorePackageSettleInput input);
 
 	R settleBack(WmScorePackageSettleInput input);

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

@@ -240,12 +240,20 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 		return R.ok(resultMap);
 	}
 
+	/**
+	 * 业务提交结算信息到财务
+	 *
+	 * @param input 输入信息
+	 * @return 提交结果
+	 */
 	@Override
 	public R settleSubmit(WmScorePackageSettleInput input) {
 		WmScorePackage wmScorePackage = wmScorePackageService.getById(input.getId());
+
 		if (!"0".equals(wmScorePackage.getSettleFlag())) {
 			return R.failed("结算状态异常,请勿重复结算");
 		}
+
 		List<WmScorePackageSettleNote> notes = input.getNotes();
 
 		for (WmScorePackageSettleNote note : notes) {
@@ -282,6 +290,7 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 		SettleAmountMonitorInput deptMonitorInput = SettleAmountMonitorInput.fromUserId(userIds, ids,input.getSubType());
 		List<SettleAmountMonitorOutput> deptAmountMonitor = sysDeptSubService.getDeptAmountMonitor(deptMonitorInput);
 
+		// 结算渠道
 		SysDeptSub condition = new SysDeptSub();
 		condition.setDeptId(SecurityUtils.getUser().getDeptId());
 		condition.setSubjectType(input.getSubType());
@@ -291,6 +300,7 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 			return R.failed("人员所在机构未配置结算信息");
 		}
 
+		// 限额
 		MonitoringIndicator monitoringIndicator = monitoringIndicatorService.getBySubType(input.getSubType());
 
 		BigDecimal deptLimit = sysDeptSub.getLimitAmount();
@@ -353,6 +363,8 @@ public class WmPayOffServiceImpl extends ServiceImpl<WmPayOffMapper, WmPayOff> i
 		wmScorePackageService.updateById(updateEntity);
 		noteService.saveOrUpdateBatch(notes);
 
+		// todo 构建批量订单信息
+
 		return R.ok();
 	}