소스 검색

perf(消费服务): 设备验证处理

1.设备数据默认从缓存获取,如果缓存不存在则从数据库获取并初始人化缓存
autumnal_wind 11 달 전
부모
커밋
323c626946

+ 8 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java

@@ -162,8 +162,16 @@ public interface CacheNames {
      */
     String PT_TERM_LIST = "pt_term_list";
 
+    /**
+     * 根据设备mac地址缓存设备
+     */
     String PT_TERM_MAC_MAP = "pt_term_mac_map";
 
+    /**
+     * 根据设备机号缓存设备
+     */
+    String PT_TERM_NO = "pt_term_no";
+
     String T_XF_LIMITEDTERM = "t_xf_limitedTerm";
 
     String T_XF_LIMITED = "t_xf_limited";

+ 10 - 0
ruoyi-server/ruoyi-server-common/src/main/java/org/dromara/server/common/constant/ConsumeConstants.java

@@ -39,4 +39,14 @@ public interface ConsumeConstants {
      * 根据物理卡号获取卡片
      */
     int CARD_FACTORY = 2;
+
+    /**
+     * 根据设备机号获取设备
+     */
+    int TERM_NO = 0;
+
+    /**
+     * 根据设备mac地址获取设备
+     */
+    int TERM_MAC = 1;
 }

+ 15 - 3
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/InitBusiness.java

@@ -285,9 +285,21 @@ public class InitBusiness {
      */
     public void initTermInfo() {
         List<XfTermVo> list = xfTermService.queryList();
-        RedisUtils.deleteKeys(CacheNames.PT_TERM_LIST);
-        RedisUtils.setCacheList(CacheNames.PT_TERM_LIST, list);
-        RedisUtils.expire(CacheNames.PT_TERM_LIST, Duration.ofDays(1));
+        if (CollUtil.isNotEmpty(list)) {
+            RedisUtils.deleteKeys(CacheNames.PT_TERM_NO);
+            RedisUtils.deleteKeys(CacheNames.PT_TERM_MAC_MAP);
+
+            list.parallelStream().forEach(p->{
+                String no = String.valueOf(p.getTermNo());
+                String mac = p.getTermMac();
+
+                RedisUtils.setCacheMapValue(CacheNames.PT_TERM_NO, no, p);
+                RedisUtils.setCacheMapValue(CacheNames.PT_TERM_MAC_MAP, mac, p);
+            });
+
+            RedisUtils.expire(CacheNames.PT_TERM_NO, Duration.ofDays(1));
+            RedisUtils.expire(CacheNames.PT_TERM_MAC_MAP, Duration.ofDays(1));
+        }
 
         log.info("初始化消费设备参数完成");
     }

+ 19 - 7
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/TermBusiness.java

@@ -5,18 +5,23 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.backstage.api.domain.vo.RemoteCardVo;
 import org.dromara.common.core.config.DefaultConfig;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.constant.DefaultConstants;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.enums.SystemUseTypeEnum;
+import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.server.common.constant.ConsumeConstants;
+import org.dromara.server.consume.cache.CardCacheManager;
 import org.dromara.server.consume.cache.TokenManager;
 import org.dromara.server.consume.domain.vo.XfTermVo;
 import org.dromara.server.consume.domain.vo.yc.RoomInfo;
 import org.dromara.server.consume.domain.vo.yc.SettlementAccount;
 import org.dromara.server.consume.domain.vo.yc.TermInfo;
 import org.dromara.server.consume.domain.vo.yc.TermToken;
+import org.dromara.server.consume.service.IXfTermService;
 import org.springframework.stereotype.Service;
 
 import java.text.MessageFormat;
@@ -60,6 +65,8 @@ public class TermBusiness {
 
     private final TokenManager tokenManager;
     private final DefaultConfig defaultConfig;
+    private final IXfTermService termService;
+
 
     /**
      * 获取终端令牌(TermToken)。
@@ -163,13 +170,7 @@ public class TermBusiness {
      *         如果操作成功,则 TermInfo 将包含在返回值中;如果失败,则可能包含错误信息。
      */
     public R<TermInfo> getTermInfoByTermNo(Long termNo, String tenantId) {
-        List<XfTermVo> list = RedisUtils.getCacheList(CacheNames.PT_TERM_LIST);
-        if (CollectionUtil.isEmpty(list)) {
-            return R.fail("无设备清单,请重新加载数据");
-        }
-        XfTermVo termVo = list.stream().filter(x -> ObjectUtil.equals(x.getTermNo(), termNo)
-                                                        && ObjectUtil.equals(x.getTenantId(), tenantId)).findFirst().orElse(null);
-
+        XfTermVo termVo = getTermFromCache(String.valueOf(termNo), ConsumeConstants.TERM_NO);
         if(termVo == null) {
             return R.fail(MessageFormat.format("机号为[{0}]的设备不存在", termNo), null);
         } else {
@@ -195,6 +196,17 @@ public class TermBusiness {
         return R.ok(resultMap);
     }
 
+    public XfTermVo getTermFromCache(String checkParam, Integer checkMode) {
+        switch (checkMode) {
+            case ConsumeConstants.TERM_NO -> {
+                return termService.queryVoOneByNo(Long.valueOf(checkParam));
+            }
+            case ConsumeConstants.TERM_MAC -> {
+                return termService.queryVoOneByMac(checkParam);
+            }
+        }
+        return null;
+    }
     /**
      * 将系统中的设备信息转换成消费机可接收的类型
      * @param termVo 系统消费机信息

+ 5 - 17
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/CommonCheck.java

@@ -26,6 +26,7 @@ import org.dromara.server.common.util.CardDateUtils;
 import org.dromara.server.consume.business.BaseBusiness;
 import org.dromara.server.consume.business.CardBusiness;
 import org.dromara.server.consume.business.InitBusiness;
+import org.dromara.server.consume.business.TermBusiness;
 import org.dromara.server.consume.cache.CardCacheManager;
 import org.dromara.server.consume.domain.vo.XfCardLimitedVo;
 import org.dromara.server.consume.domain.vo.XfTermVo;
@@ -71,6 +72,7 @@ public class CommonCheck {
     private final InitBusiness initBusiness;
     private final CardBusiness cardBusiness;
     private final ThreadPoolTaskExecutor taskExecutor;
+    private final TermBusiness termBusiness;
 
     //region 账户、卡片与设备验证
 
@@ -269,27 +271,13 @@ public class CommonCheck {
      */
     public R<ErrorInfo> checkTerm(AllowConsumeValidationContext ctx) {
         String msgInfo = ObjectUtil.isEmpty(ctx.getTermMac()) ? ctx.getTermNo().toString() : ctx.getTermMac();
-        // 先从缓存获取数据
-        List<XfTermVo> list = RedisUtils.getCacheList(CacheNames.PT_TERM_LIST);
-        if (CollectionUtil.isEmpty(list)) {
-            // 如果第一次没有从缓存中取到,则使用数据库初始化下
-            initBusiness.initTermInfo();
-            list = RedisUtils.getCacheList(CacheNames.PT_TERM_LIST);
-            if (CollectionUtil.isEmpty(list)) {
-                // 如果执行了初始化还没有数据,则返回错误
-                return createErrorResponse(1, ApiErrorTypeConstants.OBJECT_NOT_EXISTS,
-                    "未获取到设备数据",
-                    "获取消费设备失败");
-            }
-        }
-
         XfTermVo termVo;
         String mac = ctx.getTermMac();
-        Long termNo = ctx.getTermNo();
+        String termNo = String.valueOf(ctx.getTermNo());
         if (ObjectUtil.isNotEmpty(mac)) {
-            termVo = list.stream().filter(x -> ObjectUtil.equals(x.getTermMac(), mac)).findFirst().orElse(null);
+            termVo = termBusiness.getTermFromCache(mac,ConsumeConstants.TERM_MAC);
         } else {
-            termVo = list.stream().filter(x -> ObjectUtil.equals(x.getTermNo(), termNo)).findFirst().orElse(null);
+            termVo = termBusiness.getTermFromCache(termNo,ConsumeConstants.TERM_NO);;
         }
         if (ObjectUtil.isEmpty(termVo)) {
             return createErrorResponse(400, ApiErrorTypeConstants.OBJECT_NOT_EXISTS,

+ 22 - 5
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/controller/v1/CardController.java

@@ -1,8 +1,13 @@
 package org.dromara.server.consume.controller.v1;
 
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.api.ReturnResult;
+import org.dromara.common.core.constant.ApiErrorTypeConstants;
 import org.dromara.common.core.constant.HttpStatus;
+import org.dromara.common.core.domain.model.ErrorInfo;
+import org.dromara.common.core.domain.model.ErrorResult;
+import org.dromara.common.core.enums.ResultCodeEnum;
 import org.dromara.server.consume.business.CardBusiness;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -18,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @Version 1.0
  * @since jdk17
  */
+@Slf4j
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/v1/Cards")
@@ -31,11 +37,22 @@ public class CardController {
      */
     @GetMapping("/{cardNo}/bags")
     public Object getCardBags(@PathVariable("cardNo") Long cardNo) {
-        ReturnResult result = cardBusiness.getCardBagsByCardNo(cardNo);
-        if(result.isSuccess()){
-            return result.getData();
-        } else{
-            return new ResponseEntity<>(result.getData(), null, HttpStatus.NOT_FOUND);
+        try {
+            ReturnResult result = cardBusiness.getCardBagsByCardNo(cardNo);
+            if (result.isSuccess()) {
+                return result.getData();
+            } else {
+                return new ResponseEntity<>(result.getData(), null, HttpStatus.NOT_FOUND);
+            }
+        } catch (Exception e) {
+            log.error("[获取卡钱包数据异常]-[{}]",e.getMessage(),e);
+            ErrorResult result = new ErrorResult();
+            result.setStatusCode(org.springframework.http.HttpStatus.NOT_FOUND.value());
+            result.setMessage("获取卡片信息失败");
+            result.getErrors()
+                .add(new ErrorInfo(1, "获取卡片信息失败", ApiErrorTypeConstants.NOT_FOUND, "流水号为[" + cardNo + "]的卡片不存在!"));
+
+            return new ResponseEntity<>(result, null, HttpStatus.NOT_FOUND);
         }
     }
 }

+ 2 - 0
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/IXfTermService.java

@@ -41,4 +41,6 @@ public interface IXfTermService {
      * @return 消费设备视图
      */
     XfTermVo queryVoOneByNo(Long termNo);
+
+    XfTermVo queryVoOneByMac(String mac);
 }

+ 14 - 16
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/service/impl/XfTermServiceImpl.java

@@ -19,6 +19,7 @@ import org.dromara.server.consume.domain.bo.XfTermBo;
 import org.dromara.server.consume.domain.vo.XfTermVo;
 import org.dromara.server.consume.mapper.XfTermMapper;
 import org.dromara.server.consume.service.IXfTermService;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -96,17 +97,14 @@ public class XfTermServiceImpl implements IXfTermService {
             RemotePtAccountVo accountVo = remotePtAccountService.selectVoById(vo.getAccountId());
             if (ObjUtil.isNotEmpty(accountVo)) {
                 vo.setAccountName(accountVo.getAccountName());
+            } else{
+                vo.setAccountName("未知结算账户");
             }
             RemotePtRoomVo roomVo = remotePtRoomService.selectVoById(vo.getRoomId());
             if (ObjUtil.isNotEmpty(roomVo)) {
                 vo.setRoomName(roomVo.getRoomName());
-            }
-            List<XfTermVo> redisList = RedisUtils.getCacheList(CacheNames.PT_TERM_LIST);
-            if (CollectionUtil.isNotEmpty(redisList)) {
-                RedisUtils.addCacheList(CacheNames.PT_TERM_LIST, vo);
             } else {
-                redisList.add(vo);
-                RedisUtils.setCacheList(CacheNames.PT_TERM_LIST, redisList);
+                vo.setRoomName("未知房间");
             }
         }
         return vo;
@@ -119,19 +117,20 @@ public class XfTermServiceImpl implements IXfTermService {
      * @return 消费设备设备
      */
     @Override
+    @Cacheable(cacheNames = CacheNames.PT_TERM_NO, key = "#termNo", unless = "#result == null")
     public XfTermVo queryVoOneByNo(Long termNo) {
-        XfTermVo vo;
-        List<XfTermVo> redisList = RedisUtils.getCacheList(CacheNames.PT_TERM_LIST);
-        if (CollectionUtil.isNotEmpty(redisList)) {
-            vo = redisList.stream().filter(p -> Objects.equals(p.getTermNo(), termNo)).findFirst().orElse(null);
-            if (ObjUtil.isNotNull(vo)) {
-                return vo;
-            }
-        }
         XfTermBo bo = new XfTermBo();
         bo.setTermNo(termNo);
         bo.setTenantId(defaultConfig.getTenantId());
-        return this.queryVoOneByBo(bo);
+        return queryVoOneByBo(bo);
+    }
+
+    @Override
+    @Cacheable(cacheNames = CacheNames.PT_TERM_MAC_MAP, key = "#mac", unless = "#result == null")
+    public XfTermVo queryVoOneByMac(String mac) {
+        XfTermBo bo = new XfTermBo();
+        bo.setTermMac(mac);
+        return queryVoOneByBo(bo);
     }
 
     /**
@@ -146,7 +145,6 @@ public class XfTermServiceImpl implements IXfTermService {
         lqw.eq(StringUtils.isNotBlank(bo.getTenantId()), XfTerm::getTenantId, bo.getTenantId());
         lqw.eq(StringUtils.isNotBlank(bo.getTermIp()), XfTerm::getTermIp, bo.getTermIp());
         lqw.eq(StringUtils.isNotBlank(bo.getTermMac()), XfTerm::getTermMac, bo.getTermMac());
-
         lqw.like(StringUtils.isNotBlank(bo.getTermName()), XfTerm::getTermName, bo.getTermName());
 
         lqw.orderByAsc(XfTerm::getTermNo);