|
@@ -22,12 +22,14 @@ import org.dromara.common.core.enums.TradeStatusEnum;
|
|
|
import org.dromara.common.core.enums.UserAccountStatusEnum;
|
|
import org.dromara.common.core.enums.UserAccountStatusEnum;
|
|
|
import org.dromara.common.core.utils.RecordIdUtils;
|
|
import org.dromara.common.core.utils.RecordIdUtils;
|
|
|
import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
|
|
import org.dromara.server.common.domain.consume.bo.ConsumptionBo;
|
|
|
|
|
+import org.dromara.server.consume.cache.TokenManager;
|
|
|
import org.dromara.server.consume.domain.vo.PtBagVo;
|
|
import org.dromara.server.consume.domain.vo.PtBagVo;
|
|
|
import org.dromara.server.consume.domain.vo.XfConsumeDetailOriginalVo;
|
|
import org.dromara.server.consume.domain.vo.XfConsumeDetailOriginalVo;
|
|
|
import org.dromara.server.consume.domain.vo.XfConsumeDetailVo;
|
|
import org.dromara.server.consume.domain.vo.XfConsumeDetailVo;
|
|
|
import org.dromara.server.consume.domain.vo.XfTermVo;
|
|
import org.dromara.server.consume.domain.vo.XfTermVo;
|
|
|
-import org.dromara.server.consume.service.IPtBagService;
|
|
|
|
|
|
|
+import org.dromara.server.consume.domain.vo.yc.TermToken;
|
|
|
import org.dromara.server.consume.service.IConsumeDetailOriginalService;
|
|
import org.dromara.server.consume.service.IConsumeDetailOriginalService;
|
|
|
|
|
+import org.dromara.server.consume.service.IPtBagService;
|
|
|
import org.dromara.server.consume.service.IXfConsumeDetailService;
|
|
import org.dromara.server.consume.service.IXfConsumeDetailService;
|
|
|
import org.dromara.server.consume.service.IXfTermService;
|
|
import org.dromara.server.consume.service.IXfTermService;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.NotNull;
|
|
@@ -35,6 +37,8 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
import java.text.MessageFormat;
|
|
import java.text.MessageFormat;
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.ZoneOffset;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Objects;
|
|
import java.util.Objects;
|
|
@@ -66,6 +70,7 @@ public class CheckBusiness {
|
|
|
private final IConsumeDetailOriginalService consumeDetailOriginalService;
|
|
private final IConsumeDetailOriginalService consumeDetailOriginalService;
|
|
|
private final IXfConsumeDetailService consumeDetailService;
|
|
private final IXfConsumeDetailService consumeDetailService;
|
|
|
private final IPtBagService bagService;
|
|
private final IPtBagService bagService;
|
|
|
|
|
+ private final TokenManager tokenManager;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 消费记录参数检检查
|
|
* 消费记录参数检检查
|
|
@@ -79,41 +84,52 @@ public class CheckBusiness {
|
|
|
ErrorInfo errorInfo;
|
|
ErrorInfo errorInfo;
|
|
|
// 检查设备机号
|
|
// 检查设备机号
|
|
|
if (ObjectUtil.isEmpty(bo.getTermNo()) || bo.getTermNo() == 0) {
|
|
if (ObjectUtil.isEmpty(bo.getTermNo()) || bo.getTermNo() == 0) {
|
|
|
- errorInfo = new ErrorInfo(1, "", "设备机号不正确", "设备机号必须大于零!");
|
|
|
|
|
|
|
+ errorInfo = new ErrorInfo(1, ApiErrorTypeConstants.PARAM_ERROR, "设备机号不正确", "设备机号必须大于零!");
|
|
|
return R.fail(errorInfo);
|
|
return R.fail(errorInfo);
|
|
|
}
|
|
}
|
|
|
// 检查交易人员标识
|
|
// 检查交易人员标识
|
|
|
if (bo.getCardNo() <= 0 && bo.getFactoryId() == 0 && bo.getUserNo() <= 0 && StrUtil.isEmpty(bo.getUserNumb())) {
|
|
if (bo.getCardNo() <= 0 && bo.getFactoryId() == 0 && bo.getUserNo() <= 0 && StrUtil.isEmpty(bo.getUserNumb())) {
|
|
|
- errorInfo = new ErrorInfo(1, "", "交易人员标识不满足",
|
|
|
|
|
|
|
+ errorInfo = new ErrorInfo(1, ApiErrorTypeConstants.PARAM_ERROR, "交易人员标识不满足",
|
|
|
"必须提供 [CardNo | FactoryId | userNo | userNumb] 中至少1项来标识交易用户");
|
|
"必须提供 [CardNo | FactoryId | userNo | userNumb] 中至少1项来标识交易用户");
|
|
|
return R.fail(errorInfo);
|
|
return R.fail(errorInfo);
|
|
|
}
|
|
}
|
|
|
return R.ok();
|
|
return R.ok();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查校验码
|
|
|
|
|
+ * @param bo 消费信息
|
|
|
|
|
+ * @param mac 校验码
|
|
|
|
|
+ * @return 检查结果
|
|
|
|
|
+ */
|
|
|
|
|
+ public R<ErrorInfo> checkMac(ConsumptionBo bo, String mac) {
|
|
|
|
|
+ ErrorInfo errorInfo;
|
|
|
|
|
+ Long termNo = bo.getTermNo();
|
|
|
|
|
+ TermToken token = tokenManager.getTermToken().get(String.valueOf(termNo));
|
|
|
|
|
+ if (ObjectUtil.isEmpty(token)) {
|
|
|
|
|
+ errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.INVALID_TOKEN, "Token不存在",
|
|
|
|
|
+ MessageFormat.format("没有找到机号为[{0}]的设备的Token!",termNo));
|
|
|
|
|
+ return R.fail(errorInfo);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjectUtil.isNotEmpty(mac)) {
|
|
|
|
|
+ // TODO 2024-12-25 luoyibo 如果mac不为空,需要校验
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok();
|
|
|
|
|
+ }
|
|
|
/**
|
|
/**
|
|
|
* 消费记录人员、卡片检查,全部通过后获取到消费账户、卡片及设备的视图信息
|
|
* 消费记录人员、卡片检查,全部通过后获取到消费账户、卡片及设备的视图信息
|
|
|
*
|
|
*
|
|
|
* @param bo 消费记录
|
|
* @param bo 消费记录
|
|
|
* @param userAccountVo 消费账户
|
|
* @param userAccountVo 消费账户
|
|
|
* @param userCardVo 消费卡片
|
|
* @param userCardVo 消费卡片
|
|
|
- * @param useTermVo 消费设备
|
|
|
|
|
* @return 验证结果
|
|
* @return 验证结果
|
|
|
*/
|
|
*/
|
|
|
- public R<ErrorInfo> checkUser(ConsumptionBo bo, RemoteUserAccountVo userAccountVo, RemoteCardVo userCardVo,
|
|
|
|
|
- XfTermVo useTermVo) {
|
|
|
|
|
- long termNo = ObjectUtil.isEmpty(bo.getTermNo()) ? 0 : bo.getTermNo();
|
|
|
|
|
|
|
+ public R<ErrorInfo> checkUser(ConsumptionBo bo, RemoteUserAccountVo userAccountVo, RemoteCardVo userCardVo) {
|
|
|
long cardNo = ObjectUtil.isEmpty(bo.getCardNo()) ? 0 : bo.getCardNo();
|
|
long cardNo = ObjectUtil.isEmpty(bo.getCardNo()) ? 0 : bo.getCardNo();
|
|
|
long factoryId = ObjectUtil.isEmpty(bo.getFactoryId()) ? 0 : bo.getFactoryId();
|
|
long factoryId = ObjectUtil.isEmpty(bo.getFactoryId()) ? 0 : bo.getFactoryId();
|
|
|
long userNo = ObjectUtil.isEmpty(bo.getUserNo()) ? 0 : bo.getUserNo();
|
|
long userNo = ObjectUtil.isEmpty(bo.getUserNo()) ? 0 : bo.getUserNo();
|
|
|
String userNumb = bo.getUserNumb() == null ? null : bo.getUserNumb();
|
|
String userNumb = bo.getUserNumb() == null ? null : bo.getUserNumb();
|
|
|
- // 获取设备信息
|
|
|
|
|
- if (termNo > 0) {
|
|
|
|
|
- R<ErrorInfo> result = checkTerm(bo, useTermVo);
|
|
|
|
|
- if (R.isError(result)) {
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
// 卡流水号检查
|
|
// 卡流水号检查
|
|
|
if (cardNo > 0) {
|
|
if (cardNo > 0) {
|
|
|
return checkCardNo(bo, userAccountVo, userCardVo);
|
|
return checkCardNo(bo, userAccountVo, userCardVo);
|
|
@@ -182,8 +198,8 @@ public class CheckBusiness {
|
|
|
if (ObjectUtil.isEmpty(mealType)) {
|
|
if (ObjectUtil.isEmpty(mealType)) {
|
|
|
return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "不在交易时段", "不在交易时段"));
|
|
return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "不在交易时段", "不在交易时段"));
|
|
|
}
|
|
}
|
|
|
- // 3.折扣\限额\限次验证
|
|
|
|
|
- result = checkLimitDeal(bo, userAccountVo, useTermVo, userCardVo, mealType);
|
|
|
|
|
|
|
+ // 3.设备限制验证
|
|
|
|
|
+ result = checkTermLimitDeal(bo, userAccountVo, useTermVo, userCardVo, mealType);
|
|
|
if (R.isError(result)) {
|
|
if (R.isError(result)) {
|
|
|
return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "消费限制判断存在问题", JSONUtil.toJsonStr(result.getData())));
|
|
return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "消费限制判断存在问题", JSONUtil.toJsonStr(result.getData())));
|
|
|
}
|
|
}
|
|
@@ -427,8 +443,10 @@ public class CheckBusiness {
|
|
|
return R.ok();
|
|
return R.ok();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public R<ErrorInfo> checkLimitDeal(ConsumptionBo bo, RemoteUserAccountVo userAccountVo, XfTermVo termVo, RemoteCardVo userCardVo,RemoteMealTypeVo mealTypeVo) {
|
|
|
|
|
|
|
+ public R<ErrorInfo> checkTermLimitDeal(ConsumptionBo bo, RemoteUserAccountVo userAccountVo, XfTermVo termVo, RemoteCardVo userCardVo,RemoteMealTypeVo mealTypeVo) {
|
|
|
Long termNo = termVo.getTermNo();
|
|
Long termNo = termVo.getTermNo();
|
|
|
|
|
+ BigDecimal consumeValue = bo.getConsumeMoney();
|
|
|
|
|
+ Long factoryFixId = userCardVo.getFactoryId();
|
|
|
String mealTypeId = mealTypeVo.getTypeId();
|
|
String mealTypeId = mealTypeVo.getTypeId();
|
|
|
if (termNo == 0 && ObjectUtil.equal("0", mealTypeId)) {
|
|
if (termNo == 0 && ObjectUtil.equal("0", mealTypeId)) {
|
|
|
return R.ok();
|
|
return R.ok();
|
|
@@ -442,20 +460,56 @@ public class CheckBusiness {
|
|
|
// 每天最大消费金额
|
|
// 每天最大消费金额
|
|
|
BigDecimal termDayMoney = termVo.getDayMoney() == null ? BigDecimal.ZERO : termVo.getDayMoney();
|
|
BigDecimal termDayMoney = termVo.getDayMoney() == null ? BigDecimal.ZERO : termVo.getDayMoney();
|
|
|
// 每餐最大消费次数
|
|
// 每餐最大消费次数
|
|
|
- Integer termMealCount = termVo.getMealCount() == null ? 0 : termVo.getMealCount();
|
|
|
|
|
|
|
+ int termMealCount = termVo.getMealCount() == null ? 0 : termVo.getMealCount();
|
|
|
// 单次最大消费金额
|
|
// 单次最大消费金额
|
|
|
BigDecimal termSingleMoney = termVo.getSingleMoney() == null ? BigDecimal.ZERO : termVo.getSingleMoney();
|
|
BigDecimal termSingleMoney = termVo.getSingleMoney() == null ? BigDecimal.ZERO : termVo.getSingleMoney();
|
|
|
// 二次可用最大时间间隔
|
|
// 二次可用最大时间间隔
|
|
|
- Integer termSwipeInterval = termVo.getSwipeInterval() == null ? 0 : termVo.getSwipeInterval();
|
|
|
|
|
|
|
+ int termSwipeInterval = termVo.getSwipeInterval() == null ? 0 : termVo.getSwipeInterval();
|
|
|
// 设备是否启用了卡有效
|
|
// 设备是否启用了卡有效
|
|
|
- Boolean termUseValidity = Objects.equals(termVo.getTermValidity(), "0") ? Boolean.FALSE : Boolean.TRUE;
|
|
|
|
|
|
|
+ boolean termUseValidity = Objects.equals(termVo.getTermValidity(), "0") ? Boolean.FALSE : Boolean.TRUE;
|
|
|
|
|
+
|
|
|
|
|
+ LocalDateTime currentLocalDt = LocalDateTime.now();
|
|
|
|
|
+ LocalDateTime expiryLocalDt = LocalDateTime.now();
|
|
|
|
|
+
|
|
|
|
|
+ // 最后消费时间
|
|
|
|
|
+ LocalDateTime lastPayLocalDt = LocalDateTime.ofInstant(userCardVo.getLastPay().toInstant(), ZoneOffset.of("+8"));
|
|
|
|
|
+ // 有效期时间
|
|
|
|
|
+ expiryLocalDt = LocalDateTime.ofInstant(userCardVo.getLifespan().toInstant(), ZoneOffset.of("+8"));
|
|
|
|
|
|
|
|
|
|
+ // 设备消费间隔验证
|
|
|
|
|
+ if ((currentLocalDt.toEpochSecond(ZoneOffset.of("+8"))
|
|
|
|
|
+ - lastPayLocalDt.toEpochSecond(ZoneOffset.of("+8"))) / 60 < termSwipeInterval && termSwipeInterval > 0) {// 消费间隔
|
|
|
|
|
+ return R.fail(new ErrorInfo(400, TradeStatusEnum.TimeInterval.toString(), "超过设备单次限额", TradeStatusEnum.TimeInterval.getName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设备单次限额验证
|
|
|
|
|
+ if (termSingleMoney.compareTo(consumeValue) < 0 && termSingleMoney.compareTo(BigDecimal.ZERO) > 0) {// 限制金额
|
|
|
|
|
+ return R.fail(new ErrorInfo(400, TradeStatusEnum.OnceBigMoney.toString(), "超过设备单次限额", TradeStatusEnum.OnceBigMoney.getName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设备启用了卡有效时进行卡有效期验证
|
|
|
|
|
+ if (factoryFixId != 0 && termUseValidity && currentLocalDt.isAfter(expiryLocalDt)) {
|
|
|
|
|
+ return R.fail(new ErrorInfo(400, TradeStatusEnum.CardValidDate.toString(), "卡片已超过失效日期", TradeStatusEnum.CardValidDate.getName()));
|
|
|
|
|
+ }
|
|
|
// 消费卡类限制验证
|
|
// 消费卡类限制验证
|
|
|
int offsetTypeId = (int) Math.pow(2, (cardTypeId - 1));
|
|
int offsetTypeId = (int) Math.pow(2, (cardTypeId - 1));
|
|
|
int temp = offsetTypeId & termCardTypeId;
|
|
int temp = offsetTypeId & termCardTypeId;
|
|
|
if (temp != offsetTypeId) {
|
|
if (temp != offsetTypeId) {
|
|
|
- return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "卡类限制", TradeStatusEnum.CardTypeLimit.getName()));
|
|
|
|
|
|
|
+ return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "设备卡类限制", TradeStatusEnum.CardTypeLimit.getName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ String lastMeal = userCardVo.getLastMeal().toString();
|
|
|
|
|
+ int mealCount = userCardVo.getMealCount().intValue();
|
|
|
|
|
+ BigDecimal mealValue = userCardVo.getMealTotal();
|
|
|
|
|
+ if (!ObjectUtil.equals(lastMeal,mealTypeId)
|
|
|
|
|
+ || !currentLocalDt.toLocalDate().isEqual(lastPayLocalDt.toLocalDate())) {
|
|
|
|
|
+ remoteCardService.initCardMealData(userCardVo.getCardNo(), mealTypeId);
|
|
|
|
|
+ lastMeal = mealTypeId;
|
|
|
|
|
+ mealCount = 0;
|
|
|
|
|
+ mealValue = BigDecimal.ZERO;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (termMealCount != 0 && mealCount >= termMealCount) {
|
|
|
|
|
+ return R.fail(new ErrorInfo(400, TradeStatusEnum.MealLimitTimes.toString(), "餐限次", TradeStatusEnum.MealLimitTimes.getName()));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return R.ok();
|
|
return R.ok();
|
|
|
}
|
|
}
|
|
|
|
|
|