Bladeren bron

feature: 增加了上传消费记录成功后更新其它消费信息的逻辑
1.更新卡片的日、餐消费信息(t_pt_card表)
2.更新卡片限制信息中的限次、限额与折扣信息(t_xf_card_limited表,新加)

luo.yibo@datuai.com 1 jaar geleden
bovenliggende
commit
a5b392d528
31 gewijzigde bestanden met toevoegingen van 884 en 169 verwijderingen
  1. 13 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteCardService.java
  2. 14 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfDiscountService.java
  3. 17 1
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfLimitedService.java
  4. 15 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfQuotaService.java
  5. 78 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteDiscountVo.java
  6. 71 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteLimitedVo.java
  7. 71 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteQuotaVo.java
  8. 16 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/dubbo/RemoteCardServiceImpl.java
  9. 14 4
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/IPtCardService.java
  10. 45 8
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/impl/PtCardServiceImpl.java
  11. 11 11
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/controller/XfLimitedtermController.java
  12. 1 1
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/XfLimitedTerm.java
  13. 3 4
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/bo/XfLimitedTermBo.java
  14. 18 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/convert/RemoteLimitedVoConvert.java
  15. 3 5
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/vo/XfLimitedTermVo.java
  16. 12 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfDiscountServiceImpl.java
  17. 31 2
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfLimitedServiceImpl.java
  18. 11 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfQuotaServiceImpl.java
  19. 15 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/mapper/XfLimitedTermMapper.java
  20. 0 15
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/mapper/XfLimitedtermMapper.java
  21. 10 3
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfLimitedService.java
  22. 15 9
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfLimitedTermService.java
  23. 26 9
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfLimitedServiceImpl.java
  24. 50 37
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfLimitedTermServiceImpl.java
  25. 2 2
      ruoyi-modules/ruoyi-backstage/src/main/resources/mapper/consumption/XfLimitedTermMapper.xml
  26. 1 1
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/CardBusiness.java
  27. 198 33
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/CheckBusiness.java
  28. 1 1
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/ConsumeBusiness.java
  29. 6 0
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/controller/v1/CardController.java
  30. 23 0
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/IXfCardLimitedService.java
  31. 93 23
      ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/impl/XfCardLimitedServiceImpl.java

+ 13 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteCardService.java

@@ -2,6 +2,9 @@ package org.dromara.backstage.api;
 
 import org.dromara.backstage.api.domain.vo.RemoteCardVo;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * name: RemoteBagService
  * package: org.dromara.backstage.api
@@ -59,4 +62,14 @@ public interface RemoteCardService {
      * @return
      */
     Boolean initCardDayData(Long cardNo);
+
+    /**
+     * 更新当天的消费信息
+     * @param cardNo 卡流水号
+     * @param mealType 餐类
+     * @param consumeValue 消费金额
+     * @param consumeDate 消费日期
+     * @return 更新结果
+     */
+    Boolean updateCardDayData(Long cardNo, Long mealType, BigDecimal consumeValue, Date consumeDate);
 }

+ 14 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfDiscountService.java

@@ -1,6 +1,7 @@
 package org.dromara.backstage.api;
 
 import org.dromara.backstage.api.domain.bo.RemoteXfDiscountBo;
+import org.dromara.backstage.api.domain.vo.RemoteDiscountVo;
 
 import java.util.Collection;
 import java.util.List;
@@ -36,4 +37,17 @@ public interface RemoteXfDiscountService {
      * 删除折扣设备
      */
     Boolean deleteDiscountTerm(List<Long> ids);
+    /**
+     * 根据设备Id查询折扣设备Id
+     * @param termId 设备Id
+     * @return 限制设备Id
+     */
+    Long queryDisCountTermIdByTermId(Long termId);
+
+    /**
+     * 根据卡类型查询折扣信息
+     * @param cardType 卡类
+     * @return 卡类折扣信息
+     */
+    RemoteDiscountVo queryDisCountByCardType(Integer cardType);
 }

+ 17 - 1
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfLimitedService.java

@@ -1,12 +1,13 @@
 package org.dromara.backstage.api;
 
 import org.dromara.backstage.api.domain.bo.RemoteXfLimitedBo;
+import org.dromara.backstage.api.domain.vo.RemoteLimitedVo;
 
 import java.util.Collection;
 import java.util.List;
 
 /**
- * 消费限服务
+ * 消费限服务
  *
  * @author Lion Li
  */
@@ -36,4 +37,19 @@ public interface RemoteXfLimitedService {
      * 删除限额设备
      */
     Boolean deleteLimitedTerm(List<Long> ids);
+
+    /**
+     * 根据设备Id查询限次设备Id
+     * @param termId 设备Id
+     * @return 限制设备Id
+     */
+    Long queryLimitedTermIdByTermId(Long termId);
+
+    /**
+     * 根据卡类型查询限次信息
+     * @param cardType 卡类
+     * @return 卡类限次信息
+     */
+    RemoteLimitedVo queryLimitedByCardType(Integer cardType);
+
 }

+ 15 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteXfQuotaService.java

@@ -1,6 +1,7 @@
 package org.dromara.backstage.api;
 
 import org.dromara.backstage.api.domain.bo.RemoteXfQuotaBo;
+import org.dromara.backstage.api.domain.vo.RemoteQuotaVo;
 
 import java.util.Collection;
 import java.util.List;
@@ -36,4 +37,18 @@ public interface RemoteXfQuotaService {
      * 删除限额设备
      */
     Boolean deleteQuotaTerm(List<Long> ids);
+
+    /**
+     * 根据设备Id查询限额设备Id
+     * @param termId 设备Id
+     * @return 限制设备Id
+     */
+    Long queryQuotaTermIdByTermId(Long termId);
+
+    /**
+     * 根据卡类型查询限额信息
+     * @param cardType 卡类
+     * @return 卡类限额信息
+     */
+    RemoteQuotaVo queryQuotaByCardType(Integer cardType);
 }

+ 78 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteDiscountVo.java

@@ -0,0 +1,78 @@
+package org.dromara.backstage.api.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 折扣管理视图对象 t_xf_discount
+ *
+ * @author bing
+ * @date 2024-08-13
+ */
+@Data
+public class RemoteDiscountVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 折扣Id,主键
+     */
+    private Long discountId;
+
+    /**
+     * 卡类Id
+     */
+    private String cardType;
+
+    private String cardTypeName;
+
+    /**
+     * 餐类Id
+     */
+    private Long mealType;
+
+    private String mealTypeName;
+
+    /**
+     * 折扣类型,默认为0
+     */
+    private String rateType;
+
+    /**
+     * 折扣率1
+     */
+    private Long oneRate;
+
+    /**
+     * 折扣率2
+     */
+    private Long twoRate;
+
+    /**
+     * 折扣率3
+     */
+    private Long threeRate;
+
+    /**
+     * 折扣率4
+     */
+    private Long fourRate;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 启用状态,0-未启用 1-启用
+     */
+    private String status;
+
+
+
+
+}

+ 71 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteLimitedVo.java

@@ -0,0 +1,71 @@
+package org.dromara.backstage.api.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 限次管理视图对象 t_xf_limited
+ *
+ * @author bing
+ * @date 2024-08-15
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class RemoteLimitedVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 限次Id,主键
+     */
+    private Long limitedId;
+
+    /**
+     * 卡类Id
+     */
+    private Long cardType;
+
+    private String cardTypeName;
+
+    /**
+     * 每日次数
+     */
+    private Long dailyCount;
+
+    /**
+     * 早餐次数
+     */
+    private Long oneCount;
+
+    /**
+     * 午餐次数
+     */
+    private Long twoCount;
+
+    /**
+     * 晚餐次数
+     */
+    private Long threeCount;
+
+    /**
+     * 宵夜次数
+     */
+    private Long fourCount;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 启用状态,0-未启用 1-启用
+     */
+    private String status;
+
+
+}

+ 71 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/vo/RemoteQuotaVo.java

@@ -0,0 +1,71 @@
+package org.dromara.backstage.api.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 限额管理视图对象 t_xf_quota
+ *
+ * @author bing
+ * @date 2024-08-14
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class RemoteQuotaVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 限额Id,主键
+     */
+    private Long quotaId;
+
+    /**
+     * 卡类Id
+     */
+    private Long cardType;
+
+    private String cardTypeName;
+
+    /**
+     * 每日金额
+     */
+    private Long dailyMoney;
+
+    /**
+     * 早餐金额
+     */
+    private Long oneMoney;
+
+    /**
+     * 午餐金额
+     */
+    private Long twoMoney;
+
+    /**
+     * 晚餐金额
+     */
+    private Long threeMoney;
+
+    /**
+     * 宵夜金额
+     */
+    private Long fourMoney;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 启用状态,0-未启用 1-启用
+     */
+    private String status;
+
+
+}

+ 16 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/dubbo/RemoteCardServiceImpl.java

@@ -9,6 +9,9 @@ import org.dromara.backstage.cardCenter.service.IPtCardService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * name: RemoteBagServiceImpl
  * package: org.dromara.backstage.dubbo
@@ -82,5 +85,18 @@ public class RemoteCardServiceImpl implements RemoteCardService {
     public Boolean initCardDayData(Long cardNo) {
         return cardService.initCardDayData(cardNo);
     }
+    /**
+     * 更新当天的消费信息
+     * @param cardNo 卡流水号
+     * @param mealType 餐类
+     * @param consumeValue 消费金额
+     * @param consumeDate 消费日期
+     * @return 更新结果
+     */
+    @Override
+    public Boolean updateCardDayData(Long cardNo, Long mealType, BigDecimal consumeValue, Date consumeDate) {
+        return cardService.updateCardDayData(cardNo, mealType, consumeValue, consumeDate);
+    }
+
 }
 

+ 14 - 4
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/IPtCardService.java

@@ -1,13 +1,14 @@
 package org.dromara.backstage.cardCenter.service;
 
-import org.dromara.backstage.domain.vo.card.PtCardVo;
 import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
+import org.dromara.backstage.domain.vo.card.PtCardVo;
 import org.dromara.backstage.payment.domain.bo.PtBagBo;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -179,7 +180,7 @@ public interface IPtCardService {
      *
      * @param cardNo   卡流水号
      * @param mealType 餐类
-     * @return
+     * @return 初始化结果
      */
     Boolean initCardMealData(Long cardNo, String mealType);
 
@@ -187,7 +188,16 @@ public interface IPtCardService {
      * 初始化卡片日消费数据
      *
      * @param cardNo 卡流水号
-     * @return
+     * @return 初始化结果
      */
     Boolean initCardDayData(Long cardNo);
+    /**
+     * 更新当天的消费信息
+     * @param cardNo 卡流水号
+     * @param mealType 餐类
+     * @param consumeValue 消费金额
+     * @param consumeDate 消费日期
+     * @return 更新结果
+     */
+    Boolean updateCardDayData(Long cardNo, Long mealType, BigDecimal consumeValue, Date consumeDate);
 }

+ 45 - 8
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/impl/PtCardServiceImpl.java

@@ -21,6 +21,7 @@ import org.dromara.backstage.domain.vo.card.PtCardVo;
 import org.dromara.backstage.payment.domain.bo.PtBagBo;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.DefaultConstants;
 import org.dromara.common.core.enums.CardOpenEnum;
 import org.dromara.common.core.enums.CardStatusEnum;
 import org.dromara.common.core.utils.MapstructUtils;
@@ -329,14 +330,14 @@ public class PtCardServiceImpl implements IPtCardService {
      */
     @Override
     public PtCardVo queryCardByCardNo(Long cardNo) {
-        PtCardVo vo;
-        List<PtCardVo> redisList = RedisUtils.getCacheList(CacheNames.PT_USER_CARD);
-        if (ObjUtil.isNotNull(redisList) && !redisList.isEmpty()) {
-            vo = redisList.stream().filter(p -> Objects.equals(p.getCardNo(), cardNo)).findFirst().orElse(null);
-            if (ObjUtil.isNotNull(vo)) {
-                return vo;
-            }
-        }
+        // PtCardVo vo;
+        // List<PtCardVo> redisList = RedisUtils.getCacheList(CacheNames.PT_USER_CARD);
+        // if (ObjUtil.isNotNull(redisList) && !redisList.isEmpty()) {
+        //     vo = redisList.stream().filter(p -> Objects.equals(p.getCardNo(), cardNo)).findFirst().orElse(null);
+        //     if (ObjUtil.isNotNull(vo)) {
+        //         return vo;
+        //     }
+        // }
         PtCardBo bo = new PtCardBo();
         bo.setCardNo(cardNo);
         return this.selectOneByBo(bo);
@@ -493,4 +494,40 @@ public class PtCardServiceImpl implements IPtCardService {
 
         return baseMapper.update(null, lpw) > 0;
     }
+    /**
+     * 更新当天的消费信息
+     * @param cardNo 卡流水号
+     * @param mealType 餐类
+     * @param consumeValue 消费金额
+     * @param consumeDate 消费日期
+     * @return 更新结果
+     */
+    @Override
+    public Boolean updateCardDayData(Long cardNo, Long mealType, BigDecimal consumeValue, Date consumeDate) {
+        PtCardBo bo = new PtCardBo();
+        bo.setCardNo(cardNo);
+        bo.setLastMeal(mealType);
+        List<PtCardVo> list = this.queryList(bo);
+        if (CollectionUtil.isNotEmpty(list)) {
+            PtCardVo vo = list.get(0);
+            String date1 = DateUtil.format(consumeDate, DefaultConstants.DATE_FORMAT);
+            String date2 = DateUtil.format(vo.getLastPay(), DefaultConstants.DATE_FORMAT);
+            if (ObjUtil.equals(date1, date2)) {
+                LambdaUpdateWrapper<PtCard> luw = new LambdaUpdateWrapper<>();
+                luw.set(PtCard::getDayCount, vo.getDayCount() + 1);
+                luw.set(PtCard::getDayTotal, consumeValue.add(vo.getDayTotal()));
+                luw.set(PtCard::getMealCount, vo.getMealCount() + 1);
+                luw.set(PtCard::getMealTotal, consumeValue.add(vo.getMealTotal()));
+                luw.set(PtCard::getLastPay, DateUtil.date());
+                luw.set(PtCard::getLastMeal, mealType);
+
+                luw.eq(PtCard::getCardNo, cardNo);
+                luw.eq(PtCard::getLastMeal, mealType);
+
+                return baseMapper.update(null, luw) > 0;
+            }
+        }
+
+        return true;
+    }
 }

+ 11 - 11
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/controller/XfLimitedtermController.java

@@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.backstage.consumption.domain.bo.XfLimitedTermBo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedTermVo;
 import org.dromara.common.message.kafka.aop.annotation.SyncDataToLocal;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
@@ -18,9 +20,7 @@ import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.excel.utils.ExcelUtil;
-import org.dromara.backstage.consumption.domain.vo.XfLimitedtermVo;
-import org.dromara.backstage.consumption.domain.bo.XfLimitedtermBo;
-import org.dromara.backstage.consumption.service.IXfLimitedtermService;
+import org.dromara.backstage.consumption.service.IXfLimitedTermService;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 import static org.dromara.common.message.kafka.constant.MessageEventTypeConstants.*;
@@ -38,14 +38,14 @@ import static org.dromara.common.message.kafka.constant.MessageEventTypeConstant
 @RequestMapping("/consumption/xfLimitedterm")
 public class XfLimitedtermController extends BaseController {
 
-    private final IXfLimitedtermService xfLimitedtermService;
+    private final IXfLimitedTermService xfLimitedtermService;
 
     /**
      * 查询限次设备绑定列表
      */
     @SaCheckPermission("consumption:xfLimitedterm:list")
     @GetMapping("/list")
-    public TableDataInfo<XfLimitedtermVo> list(XfLimitedtermBo bo, PageQuery pageQuery) {
+    public TableDataInfo<XfLimitedTermVo> list(XfLimitedTermBo bo, PageQuery pageQuery) {
         return xfLimitedtermService.queryPageList(bo, pageQuery);
     }
 
@@ -55,9 +55,9 @@ public class XfLimitedtermController extends BaseController {
     @SaCheckPermission("consumption:xfLimitedterm:export")
     @Log(title = "限次设备绑定", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(XfLimitedtermBo bo, HttpServletResponse response) {
-        List<XfLimitedtermVo> list = xfLimitedtermService.queryList(bo);
-        ExcelUtil.exportExcel(list, "限次设备绑定", XfLimitedtermVo.class, response);
+    public void export(XfLimitedTermBo bo, HttpServletResponse response) {
+        List<XfLimitedTermVo> list = xfLimitedtermService.queryList(bo);
+        ExcelUtil.exportExcel(list, "限次设备绑定", XfLimitedTermVo.class, response);
     }
 
     /**
@@ -67,7 +67,7 @@ public class XfLimitedtermController extends BaseController {
      */
     @SaCheckPermission("consumption:xfLimitedterm:query")
     @GetMapping("/{limitedTermId}")
-    public R<XfLimitedtermVo> getInfo(@NotNull(message = "主键不能为空")
+    public R<XfLimitedTermVo> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable Long limitedTermId) {
         return R.ok(xfLimitedtermService.queryById(limitedTermId));
     }
@@ -80,7 +80,7 @@ public class XfLimitedtermController extends BaseController {
     @RepeatSubmit()
 //    @SyncDataToLocal(eventType = LIMITED_TERM_ADD, sender = XF_LIMITED_SENDER)
     @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody XfLimitedtermBo bo) {
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody XfLimitedTermBo bo) {
         return toAjax(xfLimitedtermService.insertByBo(bo));
     }
 
@@ -103,7 +103,7 @@ public class XfLimitedtermController extends BaseController {
     @Log(title = "限次设备绑定", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody XfLimitedtermBo bo) {
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody XfLimitedTermBo bo) {
         return toAjax(xfLimitedtermService.updateByBo(bo));
     }
 

+ 1 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/XfLimitedterm.java → ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/XfLimitedTerm.java

@@ -16,7 +16,7 @@ import java.io.Serial;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("t_xf_limitedTerm")
-public class XfLimitedterm extends TenantEntity {
+public class XfLimitedTerm extends TenantEntity {
 
     @Serial
     private static final long serialVersionUID = 1L;

+ 3 - 4
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/bo/XfLimitedtermBo.java → ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/bo/XfLimitedTermBo.java

@@ -1,7 +1,6 @@
 package org.dromara.backstage.consumption.domain.bo;
 
-import org.dromara.backstage.consumption.domain.XfLimitedterm;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.backstage.consumption.domain.XfLimitedTerm;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import io.github.linpeilie.annotations.AutoMapper;
@@ -20,8 +19,8 @@ import java.io.Serial;
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = XfLimitedterm.class, reverseConvertGenerate = false)
-public class XfLimitedtermBo extends TenantEntity {
+@AutoMapper(target = XfLimitedTerm.class, reverseConvertGenerate = false)
+public class XfLimitedTermBo extends TenantEntity {
 
     @Serial
     private static final long serialVersionUID = -3270258400346750990L;

+ 18 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/convert/RemoteLimitedVoConvert.java

@@ -0,0 +1,18 @@
+package org.dromara.backstage.consumption.domain.convert;
+
+import io.github.linpeilie.BaseMapper;
+import org.dromara.backstage.api.domain.vo.RemoteLimitedVo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedVo;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ReportingPolicy;
+
+/**
+ * 卡片视图对象转换器
+ *
+ * @author bing
+ */
+@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface RemoteLimitedVoConvert extends BaseMapper<XfLimitedVo, RemoteLimitedVo> {
+
+}

+ 3 - 5
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/vo/XfLimitedtermVo.java → ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/vo/XfLimitedTermVo.java

@@ -1,10 +1,8 @@
 package org.dromara.backstage.consumption.domain.vo;
 
-import org.dromara.backstage.consumption.domain.XfLimitedterm;
+import org.dromara.backstage.consumption.domain.XfLimitedTerm;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
-import org.dromara.common.excel.annotation.ExcelDictFormat;
-import org.dromara.common.excel.convert.ExcelDictConvert;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 
@@ -22,8 +20,8 @@ import java.util.Date;
  */
 @Data
 @ExcelIgnoreUnannotated
-@AutoMapper(target = XfLimitedterm.class)
-public class XfLimitedtermVo implements Serializable {
+@AutoMapper(target = XfLimitedTerm.class)
+public class XfLimitedTermVo implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;

+ 12 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfDiscountServiceImpl.java

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.backstage.api.RemoteXfDiscountService;
 import org.dromara.backstage.api.domain.bo.RemoteXfDiscountBo;
+import org.dromara.backstage.api.domain.vo.RemoteDiscountVo;
 import org.dromara.backstage.consumption.domain.bo.XfDiscountBo;
 import org.dromara.backstage.consumption.service.IXfDiscountService;
 import org.dromara.backstage.consumption.service.IXfDiscounttermService;
@@ -50,4 +51,15 @@ public class RemoteXfDiscountServiceImpl implements RemoteXfDiscountService {
     public Boolean deleteDiscountTerm(List<Long> ids) {
         return discountTermService.deleteWithValidByIds(ids, true);
     }
+
+
+    @Override
+    public Long queryDisCountTermIdByTermId(Long termId) {
+        return 0L;
+    }
+
+    @Override
+    public RemoteDiscountVo queryDisCountByCardType(Integer cardType) {
+        return null;
+    }
 }

+ 31 - 2
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfLimitedServiceImpl.java

@@ -1,13 +1,18 @@
 package org.dromara.backstage.consumption.dubbo;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.backstage.api.RemoteXfLimitedService;
 import org.dromara.backstage.api.domain.bo.RemoteXfLimitedBo;
+import org.dromara.backstage.api.domain.vo.RemoteLimitedVo;
 import org.dromara.backstage.consumption.domain.bo.XfLimitedBo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedTermVo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedVo;
 import org.dromara.backstage.consumption.service.IXfLimitedService;
-import org.dromara.backstage.consumption.service.IXfLimitedtermService;
+import org.dromara.backstage.consumption.service.IXfLimitedTermService;
+import org.dromara.common.core.utils.MapstructUtils;
 import org.springframework.stereotype.Service;
 
 import java.util.Collection;
@@ -25,7 +30,7 @@ import java.util.List;
 public class RemoteXfLimitedServiceImpl implements RemoteXfLimitedService {
 
     private final IXfLimitedService limitedService;
-    private final IXfLimitedtermService limitedTermService;
+    private final IXfLimitedTermService limitedTermService;
 
     @Override
     public Boolean insertByBo(RemoteXfLimitedBo bo) throws Exception {
@@ -51,4 +56,28 @@ public class RemoteXfLimitedServiceImpl implements RemoteXfLimitedService {
     public Boolean deleteLimitedTerm(List<Long> ids) {
         return limitedTermService.deleteWithValidByIds(ids,true);
     }
+    /**
+     * 根据设备Id查询限次设备Id
+     * @param termId 设备Id
+     * @return 限制设备Id
+     */
+    @Override
+    public Long queryLimitedTermIdByTermId(Long termId) {
+        XfLimitedTermVo vo = limitedTermService.queryByTermId(termId);
+        if (ObjectUtil.isNotEmpty(vo)) {
+            return vo.getLimitedTermId();
+        }
+        return 0L;
+    }
+    /**
+     * 根据卡类型查询限次信息
+     * @param cardType 卡类
+     * @return 卡类限次信息
+     */
+    @Override
+    public RemoteLimitedVo queryLimitedByCardType(Integer cardType) {
+        XfLimitedVo vo = limitedService.queryByCardType(cardType);
+        return MapstructUtils.convert(vo, RemoteLimitedVo.class);
+    }
+
 }

+ 11 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/dubbo/RemoteXfQuotaServiceImpl.java

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.backstage.api.RemoteXfQuotaService;
 import org.dromara.backstage.api.domain.bo.RemoteXfQuotaBo;
+import org.dromara.backstage.api.domain.vo.RemoteQuotaVo;
 import org.dromara.backstage.consumption.domain.bo.XfQuotaBo;
 import org.dromara.backstage.consumption.service.IXfQuotaService;
 import org.dromara.backstage.consumption.service.IXfQuotatermService;
@@ -49,4 +50,14 @@ public class RemoteXfQuotaServiceImpl implements RemoteXfQuotaService {
     public Boolean deleteQuotaTerm(List<Long> ids) {
         return xfQuotatermService.deleteWithValidByIds(ids,true);
     }
+
+    @Override
+    public Long queryQuotaTermIdByTermId(Long termId) {
+        return 0L;
+    }
+
+    @Override
+    public RemoteQuotaVo queryQuotaByCardType(Integer cardType) {
+        return null;
+    }
 }

+ 15 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/mapper/XfLimitedTermMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.backstage.consumption.mapper;
+
+import org.dromara.backstage.consumption.domain.XfLimitedTerm;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedTermVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 限次设备绑定Mapper接口
+ *
+ * @author bing
+ * @date 2024-08-15
+ */
+public interface XfLimitedTermMapper extends BaseMapperPlus<XfLimitedTerm, XfLimitedTermVo> {
+
+}

+ 0 - 15
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/mapper/XfLimitedtermMapper.java

@@ -1,15 +0,0 @@
-package org.dromara.backstage.consumption.mapper;
-
-import org.dromara.backstage.consumption.domain.XfLimitedterm;
-import org.dromara.backstage.consumption.domain.vo.XfLimitedtermVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 限次设备绑定Mapper接口
- *
- * @author bing
- * @date 2024-08-15
- */
-public interface XfLimitedtermMapper extends BaseMapperPlus<XfLimitedterm, XfLimitedtermVo> {
-
-}

+ 10 - 3
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfLimitedService.java

@@ -1,10 +1,9 @@
 package org.dromara.backstage.consumption.service;
 
-import org.dromara.backstage.consumption.domain.XfLimited;
-import org.dromara.backstage.consumption.domain.vo.XfLimitedVo;
 import org.dromara.backstage.consumption.domain.bo.XfLimitedBo;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedVo;
 import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 import java.util.Collection;
 import java.util.List;
@@ -66,4 +65,12 @@ public interface IXfLimitedService {
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 根据卡类型查询限次信息
+     * @param cardType 卡类
+     * @return 卡类限次信息
+     */
+
+    XfLimitedVo queryByCardType(Integer cardType);
 }

+ 15 - 9
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfLimitedtermService.java → ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfLimitedTermService.java

@@ -1,8 +1,7 @@
 package org.dromara.backstage.consumption.service;
 
-import org.dromara.backstage.consumption.domain.XfLimitedterm;
-import org.dromara.backstage.consumption.domain.vo.XfLimitedtermVo;
-import org.dromara.backstage.consumption.domain.bo.XfLimitedtermBo;
+import org.dromara.backstage.consumption.domain.bo.XfLimitedTermBo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedTermVo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 
@@ -15,7 +14,7 @@ import java.util.List;
  * @author bing
  * @date 2024-08-15
  */
-public interface IXfLimitedtermService {
+public interface IXfLimitedTermService {
 
     /**
      * 根据设备id批量新增折扣设备
@@ -30,7 +29,7 @@ public interface IXfLimitedtermService {
      * @param limitedTermId 主键
      * @return 限次设备绑定
      */
-    XfLimitedtermVo queryById(Long limitedTermId);
+    XfLimitedTermVo queryById(Long limitedTermId);
 
     /**
      * 分页查询限次设备绑定列表
@@ -39,7 +38,7 @@ public interface IXfLimitedtermService {
      * @param pageQuery 分页参数
      * @return 限次设备绑定分页列表
      */
-    TableDataInfo<XfLimitedtermVo> queryPageList(XfLimitedtermBo bo, PageQuery pageQuery);
+    TableDataInfo<XfLimitedTermVo> queryPageList(XfLimitedTermBo bo, PageQuery pageQuery);
 
     /**
      * 查询符合条件的限次设备绑定列表
@@ -47,7 +46,7 @@ public interface IXfLimitedtermService {
      * @param bo 查询条件
      * @return 限次设备绑定列表
      */
-    List<XfLimitedtermVo> queryList(XfLimitedtermBo bo);
+    List<XfLimitedTermVo> queryList(XfLimitedTermBo bo);
 
     /**
      * 新增限次设备绑定
@@ -55,7 +54,7 @@ public interface IXfLimitedtermService {
      * @param bo 限次设备绑定
      * @return 是否新增成功
      */
-    Boolean insertByBo(XfLimitedtermBo bo);
+    Boolean insertByBo(XfLimitedTermBo bo);
 
     /**
      * 修改限次设备绑定
@@ -63,7 +62,7 @@ public interface IXfLimitedtermService {
      * @param bo 限次设备绑定
      * @return 是否修改成功
      */
-    Boolean updateByBo(XfLimitedtermBo bo);
+    Boolean updateByBo(XfLimitedTermBo bo);
 
     /**
      * 校验并批量删除限次设备绑定信息
@@ -73,4 +72,11 @@ public interface IXfLimitedtermService {
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 根据设备Id查询限次设备信息
+     * @param termId 设备Id
+     * @return 限次设备信息
+     */
+    XfLimitedTermVo queryByTermId(Long termId);
 }

+ 26 - 9
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfLimitedServiceImpl.java

@@ -1,24 +1,25 @@
 package org.dromara.backstage.consumption.service.impl;
 
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
+import org.dromara.backstage.consumption.domain.XfLimited;
 import org.dromara.backstage.consumption.domain.bo.XfLimitedBo;
 import org.dromara.backstage.consumption.domain.vo.XfLimitedVo;
-import org.dromara.backstage.consumption.domain.XfLimited;
 import org.dromara.backstage.consumption.mapper.XfLimitedMapper;
 import org.dromara.backstage.consumption.service.IXfLimitedService;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.stereotype.Service;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.Collection;
 
 /**
  * 限次管理Service业务层处理
@@ -73,6 +74,7 @@ public class XfLimitedServiceImpl implements IXfLimitedService {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<XfLimited> lqw = Wrappers.lambdaQuery();
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XfLimited::getStatus, bo.getStatus());
+        lqw.eq(bo.getCardType()!=null, XfLimited::getCardType, bo.getCardType());
         return lqw;
     }
 
@@ -132,4 +134,19 @@ public class XfLimitedServiceImpl implements IXfLimitedService {
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+    /**
+     * 根据卡类型查询限次信息
+     * @param cardType 卡类
+     * @return 卡类限次信息
+     */
+    @Override
+    public XfLimitedVo queryByCardType(Integer cardType) {
+        XfLimitedBo bo = new XfLimitedBo();
+        bo.setCardType(cardType.longValue());
+        List<XfLimitedVo> list = this.queryList(bo);
+        if (CollectionUtil.isNotEmpty(list)) {
+            return list.get(0);
+        }
+        return null;
+    }
 }

+ 50 - 37
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfLimitedtermServiceImpl.java → ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfLimitedTermServiceImpl.java

@@ -1,12 +1,12 @@
 package org.dromara.backstage.consumption.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
-import org.dromara.backstage.consumption.domain.XfDiscountterm;
-import org.dromara.backstage.consumption.domain.vo.XfQuotatermVo;
+import org.dromara.backstage.consumption.domain.XfLimitedTerm;
+import org.dromara.backstage.consumption.domain.bo.XfLimitedTermBo;
+import org.dromara.backstage.consumption.domain.vo.XfLimitedTermVo;
 import org.dromara.backstage.consumption.domain.vo.XfTermVo;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -14,11 +14,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
-import org.dromara.backstage.consumption.domain.bo.XfLimitedtermBo;
-import org.dromara.backstage.consumption.domain.vo.XfLimitedtermVo;
-import org.dromara.backstage.consumption.domain.XfLimitedterm;
-import org.dromara.backstage.consumption.mapper.XfLimitedtermMapper;
-import org.dromara.backstage.consumption.service.IXfLimitedtermService;
+import org.dromara.backstage.consumption.mapper.XfLimitedTermMapper;
+import org.dromara.backstage.consumption.service.IXfLimitedTermService;
 
 import java.util.List;
 import java.util.Map;
@@ -33,24 +30,24 @@ import java.util.stream.Collectors;
  */
 @RequiredArgsConstructor
 @Service
-public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
+public class XfLimitedTermServiceImpl implements IXfLimitedTermService {
 
-    private final XfLimitedtermMapper baseMapper;
+    private final XfLimitedTermMapper baseMapper;
 
     private final XfTermServiceImpl termService;
 
     @Override
     public Boolean insertByTermIds(List<Long> ids) {
         if(CollectionUtil.isEmpty(ids)) return true;
-        LambdaQueryWrapper<XfLimitedterm> w = Wrappers.lambdaQuery();
-        w.in(XfLimitedterm::getTermId, ids);
-        List<XfLimitedterm> exists = baseMapper.selectList(w);
-        List<Long> existIds = exists.stream().map(XfLimitedterm::getTermId).toList();
+        LambdaQueryWrapper<XfLimitedTerm> w = Wrappers.lambdaQuery();
+        w.in(XfLimitedTerm::getTermId, ids);
+        List<XfLimitedTerm> exists = baseMapper.selectList(w);
+        List<Long> existIds = exists.stream().map(XfLimitedTerm::getTermId).toList();
         if(CollectionUtil.isNotEmpty(existIds)){
             List<Long> adds = ids.stream().filter(id -> !existIds.contains(id)).toList();
             if(CollectionUtil.isNotEmpty(adds)){
                 return baseMapper.insertBatch(adds.stream().map(id -> {
-                    XfLimitedterm limitedterm = new XfLimitedterm();
+                    XfLimitedTerm limitedterm = new XfLimitedTerm();
                     limitedterm.setTermId(id);
                     return limitedterm;
                 }).collect(Collectors.toList()));
@@ -58,7 +55,7 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
             return true;
         }
         return baseMapper.insertBatch(ids.stream().map(id -> {
-            XfLimitedterm limitedterm = new XfLimitedterm();
+            XfLimitedTerm limitedterm = new XfLimitedTerm();
             limitedterm.setTermId(id);
             return limitedterm;
         }).collect(Collectors.toList()));
@@ -71,7 +68,7 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
      * @return 限次设备绑定
      */
     @Override
-    public XfLimitedtermVo queryById(Long limitedTermId){
+    public XfLimitedTermVo queryById(Long limitedTermId){
         return baseMapper.selectVoById(limitedTermId);
     }
 
@@ -83,12 +80,12 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
      * @return 限次设备绑定分页列表
      */
     @Override
-    public TableDataInfo<XfLimitedtermVo> queryPageList(XfLimitedtermBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<XfLimitedterm> lqw = buildQueryWrapper(bo);
-        Page<XfLimitedtermVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        List<XfLimitedtermVo> records = result.getRecords();
+    public TableDataInfo<XfLimitedTermVo> queryPageList(XfLimitedTermBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<XfLimitedTerm> lqw = buildQueryWrapper(bo);
+        Page<XfLimitedTermVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<XfLimitedTermVo> records = result.getRecords();
         if(CollectionUtil.isNotEmpty(records)){
-            Map<Long, XfTermVo> xfTermVoMap = termService.queryMapByIds(records.stream().map(XfLimitedtermVo::getTermId).collect(Collectors.toList()));
+            Map<Long, XfTermVo> xfTermVoMap = termService.queryMapByIds(records.stream().map(XfLimitedTermVo::getTermId).collect(Collectors.toList()));
             records.forEach(x -> {
                 XfTermVo xfTermVo = xfTermVoMap.get(x.getTermId());
                 if(xfTermVo != null){
@@ -107,15 +104,15 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
      * @return 限次设备绑定列表
      */
     @Override
-    public List<XfLimitedtermVo> queryList(XfLimitedtermBo bo) {
-        LambdaQueryWrapper<XfLimitedterm> lqw = buildQueryWrapper(bo);
+    public List<XfLimitedTermVo> queryList(XfLimitedTermBo bo) {
+        LambdaQueryWrapper<XfLimitedTerm> lqw = buildQueryWrapper(bo);
         return baseMapper.selectVoList(lqw);
     }
 
-    private LambdaQueryWrapper<XfLimitedterm> buildQueryWrapper(XfLimitedtermBo bo) {
+    private LambdaQueryWrapper<XfLimitedTerm> buildQueryWrapper(XfLimitedTermBo bo) {
         Map<String, Object> params = bo.getParams();
-        LambdaQueryWrapper<XfLimitedterm> lqw = Wrappers.lambdaQuery();
-        lqw.eq(bo.getTermId() != null, XfLimitedterm::getTermId, bo.getTermId());
+        LambdaQueryWrapper<XfLimitedTerm> lqw = Wrappers.lambdaQuery();
+        lqw.eq(bo.getTermId() != null, XfLimitedTerm::getTermId, bo.getTermId());
         return lqw;
     }
 
@@ -126,8 +123,8 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
      * @return 是否新增成功
      */
     @Override
-    public Boolean insertByBo(XfLimitedtermBo bo) {
-        XfLimitedterm add = MapstructUtils.convert(bo, XfLimitedterm.class);
+    public Boolean insertByBo(XfLimitedTermBo bo) {
+        XfLimitedTerm add = MapstructUtils.convert(bo, XfLimitedTerm.class);
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
@@ -143,8 +140,8 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
      * @return 是否修改成功
      */
     @Override
-    public Boolean updateByBo(XfLimitedtermBo bo) {
-        XfLimitedterm update = MapstructUtils.convert(bo, XfLimitedterm.class);
+    public Boolean updateByBo(XfLimitedTermBo bo) {
+        XfLimitedTerm update = MapstructUtils.convert(bo, XfLimitedTerm.class);
         validEntityBeforeSave(update);
         return baseMapper.updateById(update) > 0;
     }
@@ -152,10 +149,10 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(XfLimitedterm entity){
-        LambdaQueryWrapper<XfLimitedterm> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.eq(XfLimitedterm::getTermId,entity.getTermId())
-            .ne(entity.getLimitedTermId()!=null,XfLimitedterm::getLimitedTermId, entity.getLimitedTermId());
+    private void validEntityBeforeSave(XfLimitedTerm entity){
+        LambdaQueryWrapper<XfLimitedTerm> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(XfLimitedTerm::getTermId, entity.getTermId())
+            .ne(entity.getLimitedTermId()!=null, XfLimitedTerm::getLimitedTermId, entity.getLimitedTermId());
         if (baseMapper.selectCount(queryWrapper) > 0) {
             throw new ServiceException("设备已绑定");
         }
@@ -173,8 +170,24 @@ public class XfLimitedtermServiceImpl implements IXfLimitedtermService {
         if(isValid){
             //可以删除
         }
-        LambdaQueryWrapper<XfLimitedterm> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.in(XfLimitedterm::getTermId, ids);
+        LambdaQueryWrapper<XfLimitedTerm> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.in(XfLimitedTerm::getTermId, ids);
         return baseMapper.delete(queryWrapper) > 0;
     }
+
+    /**
+     * 根据设备Id查询限次设备信息
+     * @param termId 设备Id
+     * @return 限次设备信息
+     */
+    @Override
+    public XfLimitedTermVo queryByTermId(Long termId) {
+        XfLimitedTermBo bo = new XfLimitedTermBo();
+        bo.setTermId(termId);
+        List<XfLimitedTermVo> list = this.queryList(bo);
+        if (CollectionUtil.isNotEmpty(list)) {
+            return list.get(0);
+        }
+        return null;
+    }
 }

+ 2 - 2
ruoyi-modules/ruoyi-backstage/src/main/resources/mapper/consumption/XfLimitedtermMapper.xml → ruoyi-modules/ruoyi-backstage/src/main/resources/mapper/consumption/XfLimitedTermMapper.xml

@@ -2,9 +2,9 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.backstage.consumption.mapper.XfLimitedtermMapper">
+<mapper namespace="org.dromara.backstage.consumption.mapper.XfLimitedTermMapper">
 
-    <resultMap type="org.dromara.backstage.consumption.domain.XfLimitedterm" id="XfLimitedtermResult">
+    <resultMap type="org.dromara.backstage.consumption.domain.XfLimitedTerm" id="XfLimitedTermResult">
             <result property="limitedTermId"    column="limited_term_id"    />
             <result property="tenantId"    column="tenant_id"    />
             <result property="termId"    column="term_id"    />

+ 1 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/CardBusiness.java

@@ -80,7 +80,7 @@ public class CardBusiness {
             bagInfo.setEmployeeid(userAccountVo.getUserNo());
             // 获取解密后的卡余
             if (ObjectUtil.isNotEmpty(vo.getEncryptBalance())) {
-                String decryptValue = YcEncryptUtil.decryptByRsaPublicKeySection(vo.getEncryptBalance(), vo.getUserId().toString());
+                String decryptValue = YcEncryptUtil.decryptBagBalanceByPublicKey(vo.getEncryptBalance(), vo.getUserId().toString());
                 bagInfo.setCardvalue(new BigDecimal(decryptValue));
             } else {
                 bagInfo.setCardvalue(vo.getBalance());

+ 198 - 33
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/CheckBusiness.java

@@ -6,15 +6,10 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
-import org.dromara.backstage.api.RemoteCardService;
-import org.dromara.backstage.api.RemoteMealTypeService;
-import org.dromara.backstage.api.RemoteOperatorService;
-import org.dromara.backstage.api.RemoteUserAccountService;
-import org.dromara.backstage.api.domain.vo.RemoteCardVo;
-import org.dromara.backstage.api.domain.vo.RemoteMealTypeVo;
-import org.dromara.backstage.api.domain.vo.RemoteOperatorVo;
-import org.dromara.backstage.api.domain.vo.RemoteUserAccountVo;
+import org.dromara.backstage.api.*;
+import org.dromara.backstage.api.domain.vo.*;
 import org.dromara.common.core.constant.ApiErrorTypeConstants;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.domain.model.ErrorInfo;
@@ -32,6 +27,7 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.text.MessageFormat;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.ArrayList;
@@ -61,6 +57,14 @@ public class CheckBusiness {
     private final RemoteMealTypeService remoteMealTypeService;
     @DubboReference
     private final RemoteOperatorService remoteOperatorService;
+    @DubboReference
+    private final RemotePtParameterService remotePtParameterService;
+    @DubboReference
+    private final RemoteXfLimitedService remoteLimitedService;
+    @DubboReference
+    private final RemoteXfDiscountService remoteDisCountService;
+    @DubboReference
+    private final RemoteXfQuotaService remoteQuotaService;
 
     private final IXfTermService termService;
     private final IConsumeDetailOriginalService consumeDetailOriginalService;
@@ -87,7 +91,7 @@ public class CheckBusiness {
         // 检查交易人员标识
         if (bo.getCardNo() <= 0 && bo.getFactoryId() == 0 && bo.getUserNo() <= 0 && StrUtil.isEmpty(bo.getUserNumb())) {
             errorInfo = new ErrorInfo(1, ApiErrorTypeConstants.PARAM_ERROR, "交易人员标识不满足",
-                "必须提供 [CardNo | FactoryId | userNo | userNumb] 中至少1项来标识交易用户");
+                                      "必须提供 [CardNo | FactoryId | userNo | userNumb] 中至少1项来标识交易用户");
             return R.fail(errorInfo);
         }
         return R.ok();
@@ -106,7 +110,7 @@ public class CheckBusiness {
         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));
+                                      MessageFormat.format("没有找到机号为[{0}]的设备的Token!", termNo));
             return R.fail(errorInfo);
         }
         if (ObjectUtil.isNotEmpty(mac)) {
@@ -160,7 +164,7 @@ public class CheckBusiness {
         XfTermVo termVo = termService.queryVoOneByNo(termNo);
         if (ObjectUtil.isEmpty(termVo)) {
             ErrorInfo errorInfo = new ErrorInfo(400, "", "设备不存在",
-                MessageFormat.format("机号为[{0}]的设备不存在,不允许交易", termNo));
+                                                MessageFormat.format("机号为[{0}]的设备不存在,不允许交易", termNo));
 
             return R.fail(errorInfo);
         }
@@ -239,6 +243,9 @@ public class CheckBusiness {
         // 获取营业员信息
         BeanUtil.copyProperties(getOperatorVo(bo), operatorVo);
 
+        // 更新卡片的折扣、限额与限次信息
+        updateOtherConsumeInfo(bo, userCardVo, mealTypeVo, useTermVo);
+
         return R.ok();
     }
 
@@ -255,13 +262,13 @@ public class CheckBusiness {
         RemoteCardVo cardVo = remoteCardService.queryCardByCardNo(cardNo);
         if (ObjectUtil.isEmpty(cardVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片不存在",
-                MessageFormat.format("流水号为[{0}]的卡片不存在,不允许交易", cardNo));
+                                      MessageFormat.format("流水号为[{0}]的卡片不存在,不允许交易", cardNo));
 
             return R.fail(errorInfo);
         }
         if (!"1".equals(cardVo.getStatus())) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片状态不正确",
-                MessageFormat.format("流水号为[{0}]的卡片状态不正确,不允许交易", cardNo));
+                                      MessageFormat.format("流水号为[{0}]的卡片状态不正确,不允许交易", cardNo));
 
             return R.fail(errorInfo);
         }
@@ -287,14 +294,14 @@ public class CheckBusiness {
         RemoteCardVo cardVo = remoteCardService.queryCardByFactoryId(factoryId);
         if (ObjectUtil.isEmpty(cardVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片不存在",
-                MessageFormat.format("物理卡号为[{0}]的卡片不存在,不允许交易", factoryId));
+                                      MessageFormat.format("物理卡号为[{0}]的卡片不存在,不允许交易", factoryId));
 
             return R.fail(errorInfo);
         }
         if (!"1".equals(cardVo.getStatus())) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片状态不正确",
-                MessageFormat.format("物理卡号为[{0}]的卡片卡片状态不正确,不允许交易",
-                    factoryId));
+                                      MessageFormat.format("物理卡号为[{0}]的卡片卡片状态不正确,不允许交易",
+                                                           factoryId));
 
             return R.fail(errorInfo);
         }
@@ -313,20 +320,20 @@ public class CheckBusiness {
         RemoteUserAccountVo accountVo = remoteUserAccountService.getUserAccountVoByUserNo(userNo);
         if (ObjectUtil.isEmpty(accountVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "人员不存在",
-                MessageFormat.format("流水号为[{0}]的人员不存在,不允许交易", userNo));
+                                      MessageFormat.format("流水号为[{0}]的人员不存在,不允许交易", userNo));
 
             return R.fail(errorInfo);
         }
         RemoteCardVo cardVo = remoteCardService.queryMainCardByUserId(accountVo.getUserId());
         if (ObjectUtil.isEmpty(cardVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片不存在",
-                MessageFormat.format("流水号为[{0}]的人员卡片不存在,不允许交易", userNo));
+                                      MessageFormat.format("流水号为[{0}]的人员卡片不存在,不允许交易", userNo));
 
             return R.fail(errorInfo);
         }
         if (!"1".equals(cardVo.getStatus())) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片状态不正确",
-                MessageFormat.format("流水号为[{0}]的人员卡片状态不正确,不允许交易", userNo));
+                                      MessageFormat.format("流水号为[{0}]的人员卡片状态不正确,不允许交易", userNo));
 
             return R.fail(errorInfo);
         }
@@ -346,20 +353,20 @@ public class CheckBusiness {
 
         if (ObjectUtil.isEmpty(accountVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "人员不存在",
-                MessageFormat.format("编号为[{0}]的人员不存在,不允许交易", userNumb));
+                                      MessageFormat.format("编号为[{0}]的人员不存在,不允许交易", userNumb));
 
             return R.fail(errorInfo);
         }
         RemoteCardVo cardVo = remoteCardService.queryMainCardByUserId(accountVo.getUserId());
         if (ObjectUtil.isEmpty(cardVo)) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片不存在",
-                MessageFormat.format("编号为[{0}]的人员卡片不存在,不允许交易", userNumb));
+                                      MessageFormat.format("编号为[{0}]的人员卡片不存在,不允许交易", userNumb));
 
             return R.fail(errorInfo);
         }
         if (!"1".equals(cardVo.getStatus())) {
             errorInfo = new ErrorInfo(400, ApiErrorTypeConstants.PARAM_ERROR, "卡片状态不正确",
-                MessageFormat.format("编号为[{0}]的人员卡片状态不正确,不允许交易", userNumb));
+                                      MessageFormat.format("编号为[{0}]的人员卡片状态不正确,不允许交易", userNumb));
 
             return R.fail(errorInfo);
         }
@@ -375,18 +382,18 @@ public class CheckBusiness {
 
     private R<ErrorInfo> checkOriginalRecord(ConsumptionBo bo) {
         String originalId = RecordIdUtils.getRecordId(bo.getConsumeDate(), bo.getTermNo().shortValue(),
-            bo.getTermRecordId().shortValue(), bo.getUserNo().intValue(), 0);
+                                                      bo.getTermRecordId().shortValue(), bo.getUserNo().intValue(), 0);
         XfConsumeDetailOriginalVo consumeDetailOriginalVo = consumeDetailOriginalService.queryById(originalId);
         if (ObjectUtil.isEmpty(consumeDetailOriginalVo)) {
             // TODO 正常应该是进行记录类型和脱机消费的检查,此处先按错误处理
             return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.NOT_FOUND, "原始消费记录不存在",
-                MessageFormat.format("标识为[{0}]的原始消费记录不存在", bo.getRecordId())));
+                                        MessageFormat.format("标识为[{0}]的原始消费记录不存在", bo.getRecordId())));
         }
         XfConsumeDetailVo consumeDetailVo = consumeDetailService.queryVoByOriginalId(originalId);
         if (ObjectUtil.isNotEmpty(consumeDetailVo)) {
             // 认为是重复上传,不再入账
             return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.RECORD_IS_EXISTS, "原始消费记录已处理",
-                MessageFormat.format("标识为[{0}]的原始消费记录已处理", bo.getRecordId())));
+                                        MessageFormat.format("标识为[{0}]的原始消费记录已处理", bo.getRecordId())));
         }
         bo.setOriginalId(originalId);
         return R.ok();
@@ -434,15 +441,16 @@ public class CheckBusiness {
         if (doMoney.compareTo(BigDecimal.ZERO) > 0) {
             // 循环扣费后,如果还有未扣的金额,表示钱包余额不足,不允许交易
             return R.fail(new ErrorInfo(400, ApiErrorTypeConstants.CONSUME_CHECK_FAIL, "钱包余额不足",
-                MessageFormat.format("余额不足,余额[{0}],消费金额[{1}]", totalBalance,
-                    consumeMoney)));
+                                        MessageFormat.format("余额不足,余额[{0}],消费金额[{1}]", totalBalance,
+                                                             consumeMoney)));
         }
         bo.setBalance(totalBalance.subtract(consumeMoney));
         bagVos.addAll(doBagVos);
         return R.ok();
     }
 
-    public R<ErrorInfo> checkTermLimitDeal(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();
         BigDecimal consumeValue = bo.getConsumeMoney();
         Long factoryFixId = userCardVo.getFactoryId();
@@ -477,7 +485,7 @@ public class CheckBusiness {
 
         // 设备消费间隔验证
         if ((currentLocalDt.toEpochSecond(ZoneOffset.of("+8"))
-            - lastPayLocalDt.toEpochSecond(ZoneOffset.of("+8"))) / 60 < termSwipeInterval && termSwipeInterval > 0) {// 消费间隔
+                 - lastPayLocalDt.toEpochSecond(ZoneOffset.of("+8"))) / 60 < termSwipeInterval && termSwipeInterval > 0) {// 消费间隔
             return R.fail(new ErrorInfo(400, TradeStatusEnum.TimeInterval.toString(), "超过设备单次限额", TradeStatusEnum.TimeInterval.getName()));
         }
         // 设备单次限额验证
@@ -486,7 +494,8 @@ public class CheckBusiness {
         }
         // 设备启用了卡有效时进行卡有效期验证
         if (factoryFixId != 0 && termUseValidity && currentLocalDt.isAfter(expiryLocalDt)) {
-            return R.fail(new ErrorInfo(400, TradeStatusEnum.CardValidDate.toString(), "卡片已超过失效日期", TradeStatusEnum.CardValidDate.getName()));
+            return R.fail(
+                new ErrorInfo(400, TradeStatusEnum.CardValidDate.toString(), "卡片已超过失效日期", TradeStatusEnum.CardValidDate.getName()));
         }
         // 消费卡类限制验证
         int offsetTypeId = (int) Math.pow(2, (cardTypeId - 1));
@@ -494,12 +503,12 @@ public class CheckBusiness {
         if (temp != offsetTypeId) {
             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())) {
+                || !currentLocalDt.toLocalDate().isEqual(lastPayLocalDt.toLocalDate())) {
             remoteCardService.initCardMealData(userCardVo.getCardNo(), mealTypeId);
             lastMeal = mealTypeId;
             mealCount = 0;
@@ -513,6 +522,8 @@ public class CheckBusiness {
         int dayCount = userCardVo.getDayCount().intValue();
         BigDecimal dayValue = userCardVo.getDayTotal();
 
+        LocalDate t1 = currentLocalDt.toLocalDate();
+        LocalDate t2 = lastPayLocalDt.toLocalDate();
         if (!currentLocalDt.toLocalDate().isEqual(lastPayLocalDt.toLocalDate())) {
             remoteCardService.initCardDayData(userCardVo.getCardNo());
             dayCount = 0;
@@ -525,6 +536,10 @@ public class CheckBusiness {
                 return R.fail(new ErrorInfo(400, TradeStatusEnum.DayLimitMoney.toString(), "日限额", TradeStatusEnum.DayLimitMoney.getName()));
             }
         }
+        R<ErrorInfo> result = checkCardLimitDeal(bo, termVo, userCardVo, mealTypeVo);
+        if (R.isError(result)) {
+            return R.fail(result.getData());
+        }
         return R.ok();
     }
 
@@ -550,7 +565,7 @@ public class CheckBusiness {
         Long zkMealCount = cardLimitedVo.getMealDiscountCount();
         // 最后交易时间
         LocalDateTime lastPayLimitLocalDt = LocalDateTime.ofInstant(cardLimitedVo.getLastPay().toInstant(),
-            ZoneOffset.of("+8"));
+                                                                    ZoneOffset.of("+8"));
         // 最后交易餐类
         Long lastPayLimitMealType = cardLimitedVo.getLastMeal();
         // 判断交易是否为新的一天(重置各项数据)
@@ -575,10 +590,160 @@ public class CheckBusiness {
                 zkMealCount = 0L;
             }
         }
+        // 卡类限次检查
+        R<ErrorInfo> result = checkCardLimited(termVo, userCardVo, cardLimitedVo, mealTypeVo);
+        if (R.isError(result)) {
+            return R.fail(result.getData());
+        }
+        return R.ok();
+    }
 
+    private R<ErrorInfo> checkCardLimited(XfTermVo termVo, RemoteCardVo userCardVo, XfCardLimitedVo cardLimitedVo, RemoteMealTypeVo mealTypeVo) {
+        String useLimited = remotePtParameterService.getPtParameterByKey("XC_CONSUME");
+        String mealType = mealTypeVo.getTypeId();
+        if (StrUtil.isEmpty(useLimited) || ObjectUtil.notEqual(useLimited, "1")) {
+            // 如果没有启用限次,直接返回
+            return R.ok();
+        }
+        Long limitedTermId = remoteLimitedService.queryLimitedTermIdByTermId(termVo.getTermId());
+        if (ObjectUtil.equals(limitedTermId, 0L)) {
+            // 当前设备没有设置限次
+            return R.ok();
+        }
+        RemoteLimitedVo remoteLimitedVo = remoteLimitedService.queryLimitedByCardType(userCardVo.getCardType().intValue());
+        if (ObjectUtil.isEmpty(remoteLimitedVo)) {
+            // 当前卡类没有限次信息
+            return R.ok();
+        }
+        String limitedStatus = remoteLimitedVo.getStatus();
+        if (ObjectUtil.isEmpty(limitedStatus) || ObjectUtil.equals(limitedStatus, "0")) {
+            // 卡类限次未启用
+            return R.ok();
+        }
+        // 每日次数
+        Long dayCount = remoteLimitedVo.getDailyCount();
+        // 早餐次数
+        Long oneCount = remoteLimitedVo.getOneCount();
+        // 午餐次数
+        Long twoCount = remoteLimitedVo.getTwoCount();
+        // 晚餐次数
+        Long threeCount = remoteLimitedVo.getThreeCount();
+        // 宵夜次数
+        Long fourCount = remoteLimitedVo.getFourCount();
+
+        if (dayCount.compareTo(0L) > 0 || oneCount.compareTo(0L) > 0 || twoCount.compareTo(0L) > 0 || threeCount.compareTo(
+            0L) > 0 || fourCount.compareTo(0L) > 0) {
+            if (dayCount.compareTo(0L) > 0) {
+                // 日限次
+                if (cardLimitedVo.getDayCount().compareTo(dayCount) > 0) {
+                    return R.fail(
+                        new ErrorInfo(400, TradeStatusEnum.DayLimitTimes.toString(), "卡类日限制次数", TradeStatusEnum.DayLimitTimes.getName()));
+                }
+                // 早餐限次
+                if (ObjectUtil.equals(mealType, "1")) {
+                    if (cardLimitedVo.getMealCount().compareTo(oneCount) > 0) {
+                        return R.fail(new ErrorInfo(400, TradeStatusEnum.MealLimitTimes.toString(), "卡类早餐限制次数",
+                                                    TradeStatusEnum.MealLimitTimes.getName()));
+                    }
+                }
+                // 午餐限次
+                if (ObjectUtil.equals(mealType, "2")) {
+                    if (cardLimitedVo.getMealCount().compareTo(twoCount) > 0) {
+                        return R.fail(new ErrorInfo(400, TradeStatusEnum.MealLimitTimes.toString(), "卡类午餐限制次数",
+                                                    TradeStatusEnum.MealLimitTimes.getName()));
+                    }
+                }
+                // 晚餐限次
+                if (ObjectUtil.equals(mealType, "3")) {
+                    if (cardLimitedVo.getMealCount().compareTo(threeCount) > 0) {
+                        return R.fail(new ErrorInfo(400, TradeStatusEnum.MealLimitTimes.toString(), "卡类晚餐限制次数",
+                                                    TradeStatusEnum.MealLimitTimes.getName()));
+                    }
+                }
+                // 宵夜限次
+                if (ObjectUtil.equals(mealType, "4")) {
+                    if (cardLimitedVo.getMealCount().compareTo(fourCount) > 0) {
+                        return R.fail(new ErrorInfo(400, TradeStatusEnum.MealLimitTimes.toString(), "卡类夜宵限制次数",
+                                                    TradeStatusEnum.MealLimitTimes.getName()));
+                    }
+                }
+
+            }
+        }
         return R.ok();
     }
 
+    /**
+     * 更新其它消费信息
+     * 1.更新卡片交易信息
+     * @param bo 交易业务对象
+     * @param userCardVo 卡片视图对象
+     * @param mealTypeVo 餐类视图对象
+     * @param termVo 设备视图对象
+     */
+    private void updateOtherConsumeInfo(ConsumptionBo bo, RemoteCardVo userCardVo, RemoteMealTypeVo mealTypeVo,XfTermVo termVo) {
+        Long mealType = Long.parseLong(mealTypeVo.getTypeId());
+        Date consumeDate = bo.getConsumeDate();
+        String currentDateStr = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
+        String consumeDateStr = DateFormatUtils.format(consumeDate, "yyyy-MM-dd");
+        if (ObjectUtil.equals(currentDateStr, consumeDateStr)) {
+            // 更新卡片交易信息
+            Boolean result = remoteCardService.updateCardDayData(userCardVo.getCardNo(), mealType, bo.getConsumeMoney(), consumeDate);
+
+            // 限次消费处理
+            String useLimited = remotePtParameterService.getPtParameterByKey("XC_CONSUME");
+            // 启用了限次
+            if (ObjectUtil.isNotEmpty(useLimited) && ObjectUtil.equals(useLimited, "1")) {
+                Long limitedTermId = remoteLimitedService.queryLimitedTermIdByTermId(termVo.getTermId());
+                // 当前设备也有限次
+                if (ObjectUtil.isNotEmpty(limitedTermId) && limitedTermId > 0) {
+                    // 查询卡类的限次信息
+                    RemoteLimitedVo remoteLimitedVo = remoteLimitedService.queryLimitedByCardType(userCardVo.getCardType().intValue());
+                    // 有卡类的限次信息并已启用
+                    if (ObjectUtil.isNotEmpty(remoteLimitedVo) && ObjectUtil.equals(remoteLimitedVo.getStatus(), "1")) {
+                        // 更新卡类的限次信息
+                        result = cardLimitedService.updateLimitedData(userCardVo.getCardNo());
+                    }
+                }
+            }
+            // 限额消费处理
+            String useQuota = remotePtParameterService.getPtParameterByKey("XE_CONSUME");
+            // 启用了限额
+            if (ObjectUtil.isNotEmpty(useQuota) && ObjectUtil.equals(useQuota, "1")) {
+                Long quotaId = remoteQuotaService.queryQuotaTermIdByTermId(termVo.getTermId());
+                // 当前设备也有限额
+                if (ObjectUtil.isNotEmpty(quotaId) && quotaId > 0) {
+                    // 查询卡类的限额信息
+                    RemoteQuotaVo remoteQuotaVo = remoteQuotaService.queryQuotaByCardType(userCardVo.getCardType().intValue());
+                    // 有卡类的限额信息并已启用
+                    if (ObjectUtil.isNotEmpty(remoteQuotaVo) && ObjectUtil.equals(remoteQuotaVo.getStatus(), "1")) {
+                        // 更新卡类的限额信息
+                        result = cardLimitedService.updateQuotaData(userCardVo.getCardNo(),bo.getConsumeMoney());
+                    }
+                }
+            }
+            // 折扣消费处理
+            String useDisCount = remotePtParameterService.getPtParameterByKey("RATE_CONSUME");
+            // 启用了折扣
+            if (ObjectUtil.isNotEmpty(useDisCount) && ObjectUtil.equals(useDisCount, "1")) {
+                Long disCountTermId = remoteDisCountService.queryDisCountTermIdByTermId(termVo.getTermId());
+                // 当前设备也有折扣
+                if (ObjectUtil.isNotEmpty(disCountTermId) && disCountTermId > 0) {
+                    // 查询卡类的折扣信息
+                    RemoteDiscountVo remoteDisCountVo = remoteDisCountService.queryDisCountByCardType(userCardVo.getCardType().intValue());
+                    // 有卡类的折扣信息并已启用
+                    if (ObjectUtil.isNotEmpty(remoteDisCountVo) && ObjectUtil.equals(remoteDisCountVo.getStatus(), "1")) {
+                        // 更新卡类的折扣信息
+                        result = cardLimitedService.updateDisCountData(userCardVo.getCardNo());
+                    }
+                }
+            }
+
+
+        }
+
+    }
+
     private XfCardLimitedVo initXfCardLimited(Long cardNo, Long mealType, RemoteCardVo userCardVo) {
         LocalDateTime lastPayLocalDt = LocalDateTime.ofInstant(userCardVo.getLastPay().toInstant(), ZoneOffset.of("+8"));
         ;

+ 1 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/ConsumeBusiness.java

@@ -64,7 +64,7 @@ public class ConsumeBusiness {
             return result;
         }
         XfTermVo termVo = new XfTermVo();
-        result = checkBusiness.checkTerm(bo, termVo);
+         result = checkBusiness.checkTerm(bo, termVo);
         if (R.isError(result)) {
             log.error("[请求交易]-[设备验证失败]-[{}]", result.getData());
             return result;

+ 6 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/controller/v1/CardController.java

@@ -23,6 +23,12 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/v1/Cards")
 public class CardController {
     private final CardBusiness cardBusiness;
+
+    /**
+     * 获取卡片钱包
+     * @param cardNo 卡流水号
+     * @return 卡片钱包列表
+     */
     @GetMapping("/{cardNo}/bags")
     public Object getCardBags(@PathVariable("cardNo") Long cardNo) {
         ReturnResult result = cardBusiness.getCardBagsByCardNo(cardNo);

+ 23 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/IXfCardLimitedService.java

@@ -5,6 +5,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.server.consume.domain.bo.XfCardLimitedBo;
 import org.dromara.server.consume.domain.vo.XfCardLimitedVo;
 
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
 
@@ -96,4 +97,26 @@ public interface IXfCardLimitedService {
      * @return 消费数据
      */
     XfCardLimitedVo resetMealCardLimitedData(Long cardNo, String mealTypeId);
+
+    /**
+     * 更新限次信息
+     * @param cardNo 卡流水号
+     * @return 更新结果
+     */
+    Boolean updateLimitedData(Long cardNo);
+
+    /**
+     * 更新限额信息
+     * @param cardNo 卡流水号
+     * @param consumeValue 消费金额
+     * @return 更新结果
+     */
+    Boolean updateQuotaData(Long cardNo, BigDecimal consumeValue);
+
+    /**
+     * 更新折扣信息
+     * @param cardNo 卡流水号
+     * @return 更新结果
+     */
+    Boolean updateDisCountData(Long cardNo);
 }

+ 93 - 23
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/impl/XfCardLimitedServiceImpl.java

@@ -2,13 +2,13 @@ package org.dromara.server.consume.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
-import org.apache.ibatis.annotations.Update;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -20,6 +20,7 @@ import org.dromara.server.consume.mapper.XfCardLimitedMapper;
 import org.dromara.server.consume.service.IXfCardLimitedService;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -45,7 +46,7 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
      * @return 卡片限制
      */
     @Override
-    public XfCardLimitedVo queryById(Long limitedId){
+    public XfCardLimitedVo queryById(Long limitedId) {
         return baseMapper.selectVoById(limitedId);
     }
 
@@ -90,21 +91,21 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
         return lqw;
     }
 
-    private QueryWrapper<XfCardLimited> buildQueryWrapper(XfCardLimitedBo bo,String tableAlias) {
+    private QueryWrapper<XfCardLimited> buildQueryWrapper(XfCardLimitedBo bo, String tableAlias) {
         QueryWrapper<XfCardLimited> lqw = new QueryWrapper<>();
         String columnPrefix = "";
-        if(StringUtils.isNotBlank(tableAlias)){
+        if (StringUtils.isNotBlank(tableAlias)) {
             columnPrefix = tableAlias + ".";
         }
-        lqw.eq(bo.getCardNo() != null, columnPrefix+"card_no", bo.getCardNo());
-        lqw.eq(bo.getDayCount() != null, columnPrefix+"day_count", bo.getDayCount());
-        lqw.eq(bo.getDayMoney() != null, columnPrefix+"day_Money", bo.getDayMoney());
-        lqw.eq(bo.getMealCount() != null, columnPrefix+"meal_count", bo.getMealCount());
-        lqw.eq(bo.getMealMoney() != null, columnPrefix+"meal_money", bo.getMealMoney());
-        lqw.eq(bo.getDayDiscountCount() != null, columnPrefix+"day_discount_count", bo.getDayDiscountCount());
-        lqw.eq(bo.getMealDiscountCount() != null, columnPrefix+"meal_discount_count", bo.getMealDiscountCount());
-        lqw.eq(bo.getLastPay() != null, columnPrefix+"last_pay", bo.getLastPay());
-        lqw.eq(bo.getLastMeal() != null, columnPrefix+"last_meal", bo.getLastMeal());
+        lqw.eq(bo.getCardNo() != null, columnPrefix + "card_no", bo.getCardNo());
+        lqw.eq(bo.getDayCount() != null, columnPrefix + "day_count", bo.getDayCount());
+        lqw.eq(bo.getDayMoney() != null, columnPrefix + "day_Money", bo.getDayMoney());
+        lqw.eq(bo.getMealCount() != null, columnPrefix + "meal_count", bo.getMealCount());
+        lqw.eq(bo.getMealMoney() != null, columnPrefix + "meal_money", bo.getMealMoney());
+        lqw.eq(bo.getDayDiscountCount() != null, columnPrefix + "day_discount_count", bo.getDayDiscountCount());
+        lqw.eq(bo.getMealDiscountCount() != null, columnPrefix + "meal_discount_count", bo.getMealDiscountCount());
+        lqw.eq(bo.getLastPay() != null, columnPrefix + "last_pay", bo.getLastPay());
+        lqw.eq(bo.getLastMeal() != null, columnPrefix + "last_meal", bo.getLastMeal());
         return lqw;
     }
 
@@ -143,8 +144,8 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(XfCardLimited entity){
-        //TODO 做一些数据校验,如唯一约束
+    private void validEntityBeforeSave(XfCardLimited entity) {
+        // TODO 做一些数据校验,如唯一约束
     }
 
     /**
@@ -156,13 +157,15 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
-            //TODO 做一些业务上的校验,判断是否需要校验
+        if (isValid) {
+            // TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
     /**
      * 根据卡流水号查询卡片的限制数据
+     *
      * @param cardNo 卡流水号
      * @return 卡片限制信息
      */
@@ -171,26 +174,30 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
         XfCardLimitedBo bo = new XfCardLimitedBo();
         bo.setCardNo(cardNo);
         List<XfCardLimitedVo> list = this.queryList(bo);
-        if(CollectionUtil.isNotEmpty(list)){
+        if (CollectionUtil.isNotEmpty(list)) {
             return list.get(0);
         }
         return null;
     }
+
     /**
      * 新增卡片限制并返回新增数据
+     *
      * @param bo 卡片限制
      * @return 新增信息
      */
     @Override
     public XfCardLimitedVo insertReturnByBo(XfCardLimitedBo bo) {
-        if(this.insertByBo(bo)){
+        if (this.insertByBo(bo)) {
             return this.queryById(bo.getLimitedId());
         }
         return null;
     }
+
     /**
      * 重置当天的卡消费数据
-     * @param cardNo 卡流水号
+     *
+     * @param cardNo   卡流水号
      * @param mealType 餐类
      * @return 卡消费数据
      */
@@ -206,14 +213,16 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
         luw.set(XfCardLimited::getLastMeal, Long.parseLong(mealType));
 
         luw.eq(XfCardLimited::getCardNo, cardNo);
-        if(baseMapper.update(null,luw)>0){
+        if (baseMapper.update(null, luw) > 0) {
             return this.queryByCardNo(cardNo);
         }
         return null;
     }
+
     /**
      * 重置当餐的卡消费数据
-     * @param cardNo 卡流水号
+     *
+     * @param cardNo     卡流水号
      * @param mealTypeId 餐类
      * @return 消费数据
      */
@@ -227,9 +236,70 @@ public class XfCardLimitedServiceImpl implements IXfCardLimitedService {
         luw.set(XfCardLimited::getLastPay, DateUtil.date());
 
         luw.eq(XfCardLimited::getCardNo, cardNo);
-        if(baseMapper.update(null,luw)>0){
+        if (baseMapper.update(null, luw) > 0) {
             return this.queryByCardNo(cardNo);
         }
         return null;
     }
+
+    /**
+     * 更新限次信息
+     *
+     * @param cardNo 卡流水号
+     * @return 更新结果
+     */
+    @Override
+    public Boolean updateLimitedData(Long cardNo) {
+        XfCardLimitedVo vo = this.queryByCardNo(cardNo);
+        if (ObjUtil.isNotEmpty(vo)) {
+            LambdaUpdateWrapper<XfCardLimited> luw = new LambdaUpdateWrapper<>();
+            luw.set(XfCardLimited::getMealCount, vo.getMealCount() + 1);
+            luw.set(XfCardLimited::getDayCount, vo.getDayCount() + 1);
+
+            luw.eq(XfCardLimited::getCardNo, cardNo);
+            return baseMapper.update(null, luw) > 0;
+        }
+        return true;
+    }
+
+    /**
+     * 更新限额信息
+     *
+     * @param cardNo       卡流水号
+     * @param consumeValue 消费金额
+     * @return 更新结果
+     */
+    @Override
+    public Boolean updateQuotaData(Long cardNo, BigDecimal consumeValue) {
+        XfCardLimitedVo vo = this.queryByCardNo(cardNo);
+        if (ObjUtil.isNotEmpty(vo)) {
+            LambdaUpdateWrapper<XfCardLimited> luw = new LambdaUpdateWrapper<>();
+            luw.set(XfCardLimited::getDayMoney, consumeValue.add(vo.getDayMoney()));
+            luw.set(XfCardLimited::getMealMoney, consumeValue.add(vo.getMealMoney()));
+
+            luw.eq(XfCardLimited::getCardNo, cardNo);
+            return baseMapper.update(null, luw) > 0;
+        }
+        return true;
+    }
+
+    /**
+     * 更新折扣信息
+     *
+     * @param cardNo 卡流水号
+     * @return 更新结果
+     */
+    @Override
+    public Boolean updateDisCountData(Long cardNo) {
+        XfCardLimitedVo vo = this.queryByCardNo(cardNo);
+        if (ObjUtil.isNotEmpty(vo)) {
+            LambdaUpdateWrapper<XfCardLimited> luw = new LambdaUpdateWrapper<>();
+            luw.set(XfCardLimited::getDayDiscountCount, vo.getDayDiscountCount()+1);
+            luw.set(XfCardLimited::getMealDiscountCount, vo.getMealDiscountCount()+1);
+
+            luw.eq(XfCardLimited::getCardNo, cardNo);
+            return baseMapper.update(null, luw) > 0;
+        }
+        return true;
+    }
 }