Browse Source

fix(order): 优化场地订单门禁权限设置逻辑

- 添加详细日志记录,跟踪订单和用户信息
- 查询所有待使用场地订单,解析useDateStr字段
- 计算场地订单中的最早和最晚使用日期范围
- 将日期转换为Date类型,避免时区问题影响
- 使用日期范围调用addUser方法更新门禁权限,传入每日时间段frameTimeStr
- 调用addFace方法同步录入用户面部信息
- 增加异常处理,确保设备录入失败时抛出异常通知管理员
- 优化代码结构,提升场地订单门禁设置的准确性和可维护性
SheepHy 9 giờ trước cách đây
mục cha
commit
670aa19324

+ 76 - 34
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -1299,46 +1299,88 @@ public class OrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> impl
                 appIsinMapper.insert(appIsin);
             }
             if (Objects.equals(appOrderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_0)) {
+                log.info("========== 场地订单门禁设置开始 ==========");
+                log.info("订单ID: {}, 用户: {}, useDateStr: {}, frameTimeStr: {}", 
+                        appOrderProInfo.getId(), appOrderProInfo.getUserName(), 
+                        appOrderProInfo.getUseDateStr(), appOrderProInfo.getFrameTimeStr());
+                
                 FamilyMembers familyMembers = familyMembersMapper.selectById(appOrderProInfo.getFamilyUserId());
-                AppOrderProInfo proInfo1 = appOrderProInfoMapper.selectOne(Wrappers.<AppOrderProInfo>lambdaQuery()
+                // 查询该用户所有待使用的场地订单,找出最早和最晚的使用日期
+                List<AppOrderProInfo> allFieldOrders = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery()
                         .eq(AppOrderProInfo::getFamilyUserId, appOrderProInfo.getFamilyUserId())
                         .eq(AppOrderProInfo::getOrderStatus, 1)
                         .eq(AppOrderProInfo::getType, 0)
-                        .orderByDesc(AppOrderProInfo::getExpireTime)
-                        .last("limit 1"));
-                AppOrderProInfo proInfo2 = appOrderProInfoMapper.selectOne(Wrappers.<AppOrderProInfo>lambdaQuery()
-                        .eq(AppOrderProInfo::getFamilyUserId, appOrderProInfo.getFamilyUserId())
-                        .eq(AppOrderProInfo::getOrderStatus, 1)
-                        .eq(AppOrderProInfo::getType, 0)
-                        .orderByAsc(AppOrderProInfo::getExpireTime)
-                        .last("limit 1"));
-                for (AppDevice appDevice : appDeviceMapper.selectList(Wrappers.<AppDevice>lambdaQuery().eq(AppDevice::getOrgCode, appOrder.getOrgCode()))) {
-                    if(proInfo1 != null && proInfo2 != null){
-                        // 场地预约订单:使用最早和最晚的过期时间,并传入frameTimeStr指定每日时间段
-                        String addUser = addUser(new DateTime(proInfo2.getExpireTime()),
-                                appDevice.getDeviceSerial(),
-                                appOrderProInfo.getUserName(),
-                                familyMembers.getId(), new DateTime(proInfo1.getExpireTime()), appOrderProInfo.getFrameTimeStr());
-                        String addFace = addFace(appDevice.getDeviceSerial(), familyMembers.getId(),
-                                familyMembers.getRealNameImg());
-                        JsonObject addUserJson = JsonParser.parseString(addUser).getAsJsonObject();
-                        JsonObject addFaceJson = JsonParser.parseString(addFace).getAsJsonObject();
-                        if (addUserJson.get("code").getAsInt() != 0 && addFaceJson.get("code").getAsInt() != 0)
-                            throw new JeecgBootException("设备录入用户信息失败!请联系管理员");
-                    }else {
-                        // 只有单个订单:使用开始销售日期,并传入frameTimeStr
-                        String addUser = addUser(appSitePriceRulesMapper.selectById(appOrderProInfo.getProductId()).getDateOfSale(),
-                                appDevice.getDeviceSerial(),
-                                appOrderProInfo.getUserName(),
-                                familyMembers.getId(), null, appOrderProInfo.getFrameTimeStr());
-                        String addFace = addFace(appDevice.getDeviceSerial(), familyMembers.getId(),
-                                familyMembers.getRealNameImg());
-                        JsonObject addUserJson = JsonParser.parseString(addUser).getAsJsonObject();
-                        JsonObject addFaceJson = JsonParser.parseString(addFace).getAsJsonObject();
-                        if (addUserJson.get("code").getAsInt() != 0 && addFaceJson.get("code").getAsInt() != 0)
-                            throw new JeecgBootException("设备录入用户信息失败!请联系管理员");
+                        .isNotNull(AppOrderProInfo::getUseDateStr));
+                
+                log.info("查询到用户 {} 的场地订单数量: {}", familyMembers.getFullName(), allFieldOrders.size());
+                
+                if (CollUtil.isNotEmpty(allFieldOrders)) {
+                    // 解析所有订单的useDateStr,找出最早和最晚的日期
+                    LocalDate earliestDate = null;
+                    LocalDate latestDate = null;
+                    
+                    for (AppOrderProInfo fieldOrder : allFieldOrders) {
+                        String useDateStr = fieldOrder.getUseDateStr();
+                        if (useDateStr != null && !useDateStr.isEmpty()) {
+                            try {
+                                // 解析日期 "yyyy-MM-dd"
+                                LocalDate useDate = LocalDate.parse(useDateStr);
+                                log.info("  订单 {} 的useDateStr: {} -> 解析为: {}", 
+                                        fieldOrder.getId(), useDateStr, useDate);
+                                
+                                // 找出最早的日期
+                                if (earliestDate == null || useDate.isBefore(earliestDate)) {
+                                    earliestDate = useDate;
+                                }
+                                // 找出最晚的日期
+                                if (latestDate == null || useDate.isAfter(latestDate)) {
+                                    latestDate = useDate;
+                                }
+                            } catch (Exception e) {
+                                // 解析失败,跳过该订单
+                                log.error("解析场地订单useDateStr失败: {}", useDateStr, e);
+                            }
+                        }
+                    }
+                    
+                    log.info("日期范围统计 - 最早: {}, 最晚: {}", earliestDate, latestDate);
+                    
+                    // 使用解析到的日期范围更新门禁权限
+                    if (earliestDate != null && latestDate != null) {
+                        for (AppDevice appDevice : appDeviceMapper.selectList(Wrappers.<AppDevice>lambdaQuery().eq(AppDevice::getOrgCode, appOrder.getOrgCode()))) {
+                            if (null != appDevice) {
+                                // 将LocalDate转换为Date类型,使用正午12:00避免时区问题
+                                Date startDate = Date.from(earliestDate.atTime(12, 0).atZone(ZoneId.systemDefault()).toInstant());
+                                Date endDate = Date.from(latestDate.atTime(12, 0).atZone(ZoneId.systemDefault()).toInstant());
+                                
+                                log.info("转换为Date - startDate: {}, endDate: {}", startDate, endDate);
+                                log.info("准备调用addUser - deviceSerial: {}, employeeNo: {}, frameTimeStr: {}",
+                                        appDevice.getDeviceSerial(), familyMembers.getId(), appOrderProInfo.getFrameTimeStr());
+                                
+                                String addUser = addUser(
+                                        startDate,  // 使用最早的使用日期
+                                        appDevice.getDeviceSerial(),
+                                        appOrderProInfo.getUserName(),
+                                        familyMembers.getId(),
+                                        endDate,  // 使用最晚的使用日期
+                                        appOrderProInfo.getFrameTimeStr());  // 传入时间段
+                                
+                                log.info("addUser返回结果: {}", addUser);
+                                
+                                String addFace = addFace(appDevice.getDeviceSerial(), familyMembers.getId(),
+                                        familyMembers.getRealNameImg());
+                                
+                                log.info("addFace返回结果: {}", addFace);
+                                
+                                JsonObject addUserJson = JsonParser.parseString(addUser).getAsJsonObject();
+                                JsonObject addFaceJson = JsonParser.parseString(addFace).getAsJsonObject();
+                                if (addUserJson.get("code").getAsInt() != 0 && addFaceJson.get("code").getAsInt() != 0)
+                                    throw new JeecgBootException("设备录入用户信息失败!请联系管理员");
+                            }
+                        }
                     }
                 }
+                log.info("========== 场地订单门禁设置结束 ==========");
             }
         }
 

+ 71 - 15
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/hikiot/HikiotTool.java

@@ -212,9 +212,17 @@ public class HikiotTool {
      * @return 海康接口返回结果
      **/
     public static String addUser(Date inputDate,String deviceSerial,String name,String employeeNo,Date endDate, String frameTimeStr){
+        // 将Date转换为LocalDateTime,使用系统默认时区
         LocalDateTime now = inputDate.toInstant()
                 .atZone(ZoneId.systemDefault())
                 .toLocalDateTime();
+        
+        // 打印调试信息
+        System.out.println("[HikiotTool.addUser] inputDate: " + inputDate);
+        System.out.println("[HikiotTool.addUser] 转换后的LocalDateTime: " + now);
+        System.out.println("[HikiotTool.addUser] endDate: " + endDate);
+        System.out.println("[HikiotTool.addUser] frameTimeStr: " + frameTimeStr);
+        
         // 默认开始时间为当天00:00:00
         LocalDateTime startOfDay = now.with(LocalTime.MIN); // 00:00:00
         // 默认结束时间为当天23:59:59
@@ -247,8 +255,12 @@ public class HikiotTool {
                     // 开始时间和结束时间都应用到同一天(inputDate)
                     startOfDay = now.with(customStartTime);  // 2025-11-05T18:00:00
                     endOfDay = now.with(customEndTime);      // 2025-11-05T22:00:00
+                    
+                    System.out.println("[HikiotTool.addUser] 格式1-应用时间段后 startOfDay: " + startOfDay);
+                    System.out.println("[HikiotTool.addUser] 格式1-应用时间段后 endOfDay: " + endOfDay);
                 } catch (Exception e) {
                     // 时间格式解析失败,使用默认全天时间
+                    System.err.println("[HikiotTool.addUser] 时间段解析失败: " + frameTimeStr + ", " + e.getMessage());
                 }
             } else if(parts.length == 5) {
                 // 格式2: 场地预约type=5课程的日期范围 "yyyy-MM-dd-MM-dd"
@@ -264,11 +276,19 @@ public class HikiotTool {
                     
                     startOfDay = parsedStartDate.atTime(LocalTime.MIN);  // 2025-11-02T00:00:00
                     endOfDay = parsedEndDate.atTime(LocalTime.MAX);      // 2025-11-05T23:59:59
+                    
+                    System.out.println("[HikiotTool.addUser] 格式2-应用日期范围后 startOfDay: " + startOfDay);
+                    System.out.println("[HikiotTool.addUser] 格式2-应用日期范围后 endOfDay: " + endOfDay);
                 } catch (Exception e) {
                     // 日期格式解析失败,使用默认全天时间
+                    System.err.println("[HikiotTool.addUser] 日期范围解析失败: " + frameTimeStr + ", " + e.getMessage());
                 }
             }
         }
+        
+        System.out.println("[HikiotTool.addUser] 最终 beginTime: " + LocalDateTimeUtil.format(startOfDay, "yyyy-MM-dd'T'HH:mm:ss"));
+        System.out.println("[HikiotTool.addUser] 最终 endTime: " + LocalDateTimeUtil.format(endOfDay, "yyyy-MM-dd'T'HH:mm:ss"));
+        
         AddUserRequestDTO addUserRequestDTO = new AddUserRequestDTO();
         List<AddUserRequestDTO.DoorRightPlan> doorRightPlans = new ArrayList<>();
         AddUserRequestDTO.DoorRightPlan doorRightPlan = new AddUserRequestDTO.DoorRightPlan();
@@ -625,22 +645,58 @@ public class HikiotTool {
     }
 
     public static void main(String[] args) throws IOException, InterruptedException {
-        String[] deviceSerials = {
-                "FY1932308", "FY1932375", "FX0889977", "FW9664115", "FY2389303",
-                "FY2389306", "FX0890040", "FW9664183", "FY1932320", "FW9664124",
-                "FY2389346", "FY2389320", "FZ0080611", "FW9664116", "FY2389367",
-                "FY1929855", "FX0890043", "FW9664192", "FZ0080523", "FN1697293",
-                "FW9664142", "FW9664200", "FZ0080597", "FZ0080608", "FY2389353",
-                "FY2389338", "FY2389361", "FY1929864", "FX0889961"
-        };
-
-        for (String deviceSerial : deviceSerials) {
-            try {
-                String result = deleteExpiredVisitors(deviceSerial);
-                System.out.println("设备 " + deviceSerial + " 处理结果: " + result);
-            } catch (Exception e) {
-                System.err.println("处理设备 " + deviceSerial + " 时发生错误: " + e.getMessage());
+        System.out.println("========== 场地订单门禁权限测试 ==========");
+        System.out.println("订单信息:");
+        System.out.println("  订单ID: 1998692909877137409");
+        System.out.println("  用户名: 黎建均");
+        System.out.println("  使用日期: 2025-12-10");
+        System.out.println("  时间段: 17:00:00-18:00:00");
+        System.out.println("  过期时间: 2025-12-10 18:00:00");
+        System.out.println("  设备序列号: EZAHSYEHGM05477");
+        System.out.println("  员工编号: 1997909843353112577");
+        System.out.println();
+        
+        // 模拟从 useDateStr 解析日期
+        String useDateStr = "2025-12-10";
+        LocalDate useDate = LocalDate.parse(useDateStr);
+        System.out.println("1. 解析useDateStr: " + useDateStr + " -> " + useDate);
+        
+        // 将LocalDate转换为Date,使用正午12:00避免时区问题
+        Date inputDate = Date.from(useDate.atTime(12, 0).atZone(ZoneId.systemDefault()).toInstant());
+        System.out.println("2. 转换为Date(使用12:00): " + inputDate);
+        System.out.println("   时区: " + ZoneId.systemDefault());
+        System.out.println();
+        
+        // 调用addUser方法
+        String deviceSerial = "FY2389310";
+        String name = "黎建均";
+        String employeeNo = "1997909843353112577";
+        String frameTimeStr = "18:00:00-22:00:00";
+        
+        System.out.println("3. 调用addUser方法");
+        System.out.println("   inputDate: " + inputDate);
+        System.out.println("   endDate: " + inputDate + " (同一天)");
+        System.out.println("   frameTimeStr: " + frameTimeStr);
+        System.out.println();
+        
+        try {
+            String result = addUser(inputDate, deviceSerial, name, employeeNo, inputDate, frameTimeStr);
+            System.out.println("4. addUser返回结果:");
+            System.out.println(result);
+            System.out.println();
+            
+            // 解析返回结果
+            JsonObject resultJson = JsonParser.parseString(result).getAsJsonObject();
+            if (resultJson.get("code").getAsInt() == 0) {
+                System.out.println("✅ 测试成功!门禁权限设置成功");
+            } else {
+                System.out.println("❌ 测试失败: " + resultJson.get("msg").getAsString());
             }
+        } catch (Exception e) {
+            System.err.println("❌ 测试异常: " + e.getMessage());
+            e.printStackTrace();
         }
+        
+        System.out.println("\n========== 测试结束 ==========");
     }
 }