Forráskód Böngészése

fix: 自助服务
1.增加了根据校园码的字符串解析用户流水号和根据用户流水号生成校园码字符串的接口

luoyb 1 éve
szülő
commit
dce3538651

+ 98 - 7
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/controller/self/SelfController.java

@@ -1,5 +1,6 @@
 package org.dromara.backstage.controller.self;
 
+import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.backstage.business.accouunt.UserFaceBusiness;
@@ -10,8 +11,12 @@ import org.dromara.common.core.api.ResponseResult;
 import org.dromara.common.core.api.ReturnResult;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.enums.ResultCodeEnum;
+import org.dromara.common.core.utils.StringUtilsByYC;
+import org.dromara.common.encrypt.utils.EncryptUtils;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
@@ -47,44 +52,45 @@ public class SelfController {
     }
 
     @PostMapping(value = "/api/v1/sms/no")
-    public void sendNoRoomSms(@RequestBody Map<String, String> mapSendInfo){
+    public void sendNoRoomSms(@RequestBody Map<String, String> mapSendInfo) {
         String phone = mapSendInfo.get("mobile");
         String realName = mapSendInfo.get("realName");
         String className = mapSendInfo.get("className");
-        selfBusiness.sendSmsNoRoom(phone,realName,className);
+        selfBusiness.sendSmsNoRoom(phone, realName, className);
     }
 
     /**
      * 短信系统登录
      */
     @GetMapping(value = "/api/v1/sms/login")
-    public void loginSms(){
+    public void loginSms() {
         selfBusiness.loginSms();
     }
 
     @GetMapping("/api/v1/wechat/result/{deptId}/{userId}")
     public ReturnResult queryWxPayResult(@PathVariable("deptId") String deptId, @PathVariable("userId") String userId) {
         ReturnResult result = selfBusiness.queryPayResultByUserAndDept(Long.parseLong(deptId), Long.parseLong(userId));
-        return result.isSuccess() ? ReturnResult.success(true) : ReturnResult.failure(ResultCodeEnum.DATA_NOT_FOUND,false);
+        return result.isSuccess() ? ReturnResult.success(true) : ReturnResult.failure(ResultCodeEnum.DATA_NOT_FOUND, false);
 
     }
 
     @GetMapping("/api/v1/wechat/result/{orderSn}")
-    public ReturnResult queryPayResultByOrderSn(@PathVariable("orderSn") String orderSn){
+    public ReturnResult queryPayResultByOrderSn(@PathVariable("orderSn") String orderSn) {
         R<Void> result = thirdPayBusiness.queryOrderPayResult(orderSn);
         if (R.isSuccess(result)) {
             return ReturnResult.success();
         }
-        return ReturnResult.failure(ResultCodeEnum.SYSTEM_INNER_ERROR.code(),result.getMsg());
+        return ReturnResult.failure(ResultCodeEnum.SYSTEM_INNER_ERROR.code(), result.getMsg());
     }
 
     @RequestMapping(value = "api/v1/lock/card/{cardId}/{cardData}/{userId}", method = RequestMethod.GET)
-    public boolean setLockCardDataId(@PathVariable("cardId") String cardId,@PathVariable("cardData") String cardData,@PathVariable("userId") String userId) {
+    public boolean setLockCardDataId(@PathVariable("cardId") String cardId, @PathVariable("cardData") String cardData, @PathVariable("userId") String userId) {
         return traineeBusiness.updateCardIdToCardData(cardData, userId, cardId);
     }
 
     /**
      * 自助工具查询卡片信息(餐卡、房卡)
+     *
      * @param mapInfo 查询条件
      * @return 卡片信息
      */
@@ -135,4 +141,89 @@ public class SelfController {
 
         return userFaceBusiness.extractUserFaces(userId, imageData);
     }
+
+    /**
+     * 根据用户流水号生成校园码字符串
+     *
+     * @param userNo 用户流水号
+     * @return 二维码串
+     */
+    @RequestMapping(value = "api/v1/test/code/en/{userNo}", method = RequestMethod.GET)
+    public R<Void> getQrCodeByUserNo(@PathVariable("userNo") String userNo) {
+        long currentTime = new Date().getTime();
+        long secondTime = currentTime / 1000 % 60;
+        long minuteTime = currentTime / 1000 - secondTime;
+        String head = "1";
+        String clientNo = "20200813044411";
+        Map<String, Object> m = new LinkedHashMap<>();
+        m.put("head", head);
+        m.put("userNo", Integer.valueOf(userNo));
+        m.put("clientNo", clientNo);
+        m.put("minuteTime", minuteTime);
+        m.put("secondTime", secondTime);
+
+        String jsonStr = JSONUtil.toJsonStr(m);
+        String keyStr = StringUtilsByYC.addString("YC" + userNo, "X", 16, "R");
+        String base64Mac = EncryptUtils.encryptByAes(jsonStr, keyStr);
+
+        String code = String.format("Q1|%s|%s|%s", userNo, clientNo, base64Mac);
+        String codeStr = StringUtilsByYC.addString(String.valueOf(code.length()), "0", 4, "L");
+        String data = String.format("YC|%s|%s|ZN", codeStr, code);
+
+        long hashCode = data.hashCode();
+        if (hashCode < 0) {
+            hashCode = 2147483648L + hashCode;
+        }
+
+        // 截取到前6位字符串
+        String currentHashCodeStr = String.valueOf(hashCode);
+        if (currentHashCodeStr.length() > 6) {
+            // 当值大于6位数时,就用前六位值 加 后N位值,以提高验证时的准确性
+            currentHashCodeStr = String.valueOf(Integer.parseInt(currentHashCodeStr.substring(0, 6))
+                + Integer.parseInt(currentHashCodeStr.substring(6)));
+        } else {
+            currentHashCodeStr = StringUtilsByYC.addString(currentHashCodeStr, "0", 6, "L");
+        }
+        String userNoStr = StringUtilsByYC.addString(userNo, "0", 10, "R");// 10位字符串,后面补0
+        int padValue = 10 - userNo.length(); // 用于代表用户编号补了几个0
+        // 整型数据加起来,得到10位字符串(确保在解析时,能够解除userNo 和 时间戳的分钟值)
+        String value = String.valueOf(minuteTime / 10 + Long.parseLong(userNoStr) + Long.parseLong(currentHashCodeStr));
+        String qrCode = head + currentHashCodeStr + padValue + value + secondTime;
+
+        return R.ok(qrCode);
+    }
+
+    /**
+     * 根据二维码字符串解析出用户流水号
+     *
+     * @param userCode 二维码字符串
+     * @return 用户流水号
+     */
+    @RequestMapping(value = "api/v1/test/code/de/{userCode}", method = RequestMethod.GET)
+    public R<Void> getUserNoFromQrCode(@PathVariable("userCode") String userCode) {
+        if (userCode.length() != 20)
+            return null;
+        long currentTime = new Date().getTime();
+        // 取出值
+        String head = userCode.substring(0, 1);
+        String hashCodeStr = userCode.substring(1, 7);
+        int padValue = Integer.parseInt(userCode.substring(7, 8));
+        String valueStr = userCode.substring(8, 18);
+        long secondTime = Long.parseLong(userCode.substring(18, 20));
+
+        // 取出包含时间戳分钟和用户编号的值
+        long value = (Long.parseLong(valueStr) - Long.parseLong(hashCodeStr)) * 10;
+        // 取出时间戳分钟值(当前时间戳 + 编号中的时间戳的分钟值 )(此值在服务器与二维码的时间在1000秒内使用才可能正确)
+        long codeMinuteTime = currentTime / 1000 - currentTime / 1000 % 1000 + value % 1000;
+
+        //计算两者差值,小于0或者大于90都认为二维码失效
+        long diffTime = currentTime / 1000 - codeMinuteTime;
+        if (diffTime < -180 || diffTime > 180) {
+            return R.fail("二维码失效");
+        }
+
+        // 计算出用户编号(若codeMinuteTime是不准确的,那么userNo也不正确)
+        String userNo = String.valueOf(value - codeMinuteTime).substring(0, 10 - padValue);
+        return R.ok(userNo);
+    }
 }