From ce13e25ed685ba5c961832d023ceafecf4f30d47 Mon Sep 17 00:00:00 2001
From: Junjie <DELL@qq.com>
Date: 星期六, 10 一月 2026 15:27:33 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/asrs/controller/DeviceLogController.java | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 218 insertions(+), 1 deletions(-)
diff --git a/src/main/java/com/zy/asrs/controller/DeviceLogController.java b/src/main/java/com/zy/asrs/controller/DeviceLogController.java
index d5537e9..6640886 100644
--- a/src/main/java/com/zy/asrs/controller/DeviceLogController.java
+++ b/src/main/java/com/zy/asrs/controller/DeviceLogController.java
@@ -1,24 +1,29 @@
package com.zy.asrs.controller;
+import com.alibaba.fastjson.JSON;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
+import com.zy.asrs.entity.DeviceDataLog;
import com.zy.common.web.BaseController;
import com.zy.core.enums.SlaveType;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-
import javax.servlet.http.HttpServletResponse;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
+@Slf4j
@RestController
public class DeviceLogController extends BaseController {
@@ -130,6 +135,186 @@
return R.ok(res);
} catch (Exception e) {
return R.error("璇诲彇璁惧鍒楄〃澶辫触");
+ }
+ }
+
+ @RequestMapping(value = "/deviceLog/day/{day}/preview/auth")
+ @ManagerAuth
+ public R preview(@PathVariable("day") String day,
+ @RequestParam("type") String type,
+ @RequestParam("deviceNo") String deviceNo,
+ @RequestParam(value = "offset", required = false) Integer offset,
+ @RequestParam(value = "limit", required = false) Integer limit) {
+ try {
+ String dayClean = day == null ? null : day.replaceAll("\\D", "");
+ if (dayClean == null || dayClean.length() != 8 || !dayClean.chars().allMatch(Character::isDigit)) {
+ return R.error("鏃ユ湡鏍煎紡閿欒");
+ }
+ if (type == null || SlaveType.findInstance(type) == null) {
+ return R.error("璁惧绫诲瀷閿欒");
+ }
+ if (deviceNo == null || !deviceNo.chars().allMatch(Character::isDigit)) {
+ return R.error("璁惧缂栧彿閿欒");
+ }
+ Path dayDir = Paths.get(loggingPath, dayClean);
+ if (!Files.exists(dayDir) || !Files.isDirectory(dayDir)) {
+ return R.ok(new ArrayList<>());
+ }
+ String prefix = type + "_" + deviceNo + "_" + dayClean + "_";
+ List<Path> files = Files.list(dayDir)
+ .filter(p -> {
+ String name = p.getFileName().toString();
+ return name.endsWith(".log") && name.startsWith(prefix);
+ }).collect(Collectors.toList());
+
+ files.sort(Comparator.comparingInt(p -> {
+ String n = p.getFileName().toString();
+ try {
+ String suf = n.substring(prefix.length(), n.length() - 4);
+ return Integer.parseInt(suf);
+ } catch (Exception e) {
+ return Integer.MAX_VALUE;
+ }
+ }));
+
+ int from = offset == null || offset < 0 ? 0 : offset;
+ int max = limit == null || limit <= 0 ? 5 : limit; // 榛樿璇诲彇5涓枃浠�
+ if (max > 10) max = 10; // 闄愬埗鏈�澶ф枃浠舵暟锛岄槻姝㈣秴鏃�
+ int to = Math.min(files.size(), from + max);
+
+ if (from >= files.size()) {
+ return R.ok(new ArrayList<>());
+ }
+
+ List<Path> targetFiles = files.subList(from, to);
+ List<DeviceDataLog> resultLogs = new ArrayList<>();
+
+ for (Path f : targetFiles) {
+ try (Stream<String> lines = Files.lines(f, StandardCharsets.UTF_8)) {
+ lines.forEach(line -> {
+ if (line != null && !line.trim().isEmpty()) {
+ try {
+ DeviceDataLog logItem = JSON.parseObject(line, DeviceDataLog.class);
+ resultLogs.add(logItem);
+ } catch (Exception e) {
+ // 蹇界暐瑙f瀽閿欒
+ }
+ }
+ });
+ } catch (Exception e) {
+ log.error("璇诲彇鏃ュ織鏂囦欢澶辫触: " + f, e);
+ }
+ }
+ // 鎸夋椂闂存帓搴�
+ resultLogs.sort(Comparator.comparing(DeviceDataLog::getCreateTime, Comparator.nullsLast(Date::compareTo)));
+
+ return R.ok(resultLogs);
+ } catch (Exception e) {
+ log.error("棰勮鏃ュ織澶辫触", e);
+ return R.error("棰勮鏃ュ織澶辫触");
+ }
+ }
+
+ @RequestMapping(value = "/deviceLog/day/{day}/seek/auth")
+ @ManagerAuth
+ public R seek(@PathVariable("day") String day,
+ @RequestParam("type") String type,
+ @RequestParam("deviceNo") String deviceNo,
+ @RequestParam("timestamp") Long timestamp) {
+ try {
+ String dayClean = day == null ? null : day.replaceAll("\\D", "");
+ if (dayClean == null || dayClean.length() != 8 || !dayClean.chars().allMatch(Character::isDigit)) {
+ return R.error("鏃ユ湡鏍煎紡閿欒");
+ }
+ if (type == null || SlaveType.findInstance(type) == null) {
+ return R.error("璁惧绫诲瀷閿欒");
+ }
+ if (deviceNo == null || !deviceNo.chars().allMatch(Character::isDigit)) {
+ return R.error("璁惧缂栧彿閿欒");
+ }
+ Path dayDir = Paths.get(loggingPath, dayClean);
+ if (!Files.exists(dayDir) || !Files.isDirectory(dayDir)) {
+ return R.error("鏈壘鍒版棩蹇楁枃浠�");
+ }
+
+ String prefix = type + "_" + deviceNo + "_" + dayClean + "_";
+ List<Path> files = Files.list(dayDir)
+ .filter(p -> {
+ String name = p.getFileName().toString();
+ return name.endsWith(".log") && name.startsWith(prefix);
+ }).collect(Collectors.toList());
+
+ files.sort(Comparator.comparingInt(p -> {
+ String n = p.getFileName().toString();
+ try {
+ String suf = n.substring(prefix.length(), n.length() - 4);
+ return Integer.parseInt(suf);
+ } catch (Exception e) {
+ return Integer.MAX_VALUE;
+ }
+ }));
+
+ if (files.isEmpty()) {
+ return R.error("鏈壘鍒版棩蹇楁枃浠�");
+ }
+
+ // Binary search for the file containing the timestamp
+ // We want to find the LAST file that has startTime <= targetTime.
+ // Because files are sequential: [t0, t1), [t1, t2), ...
+ // If we find file[i].startTime <= target < file[i+1].startTime, then target is in file[i].
+
+ int low = 0;
+ int high = files.size() - 1;
+ int foundIndex = -1;
+
+ while (low <= high) {
+ int mid = (low + high) >>> 1;
+ Path midFile = files.get(mid);
+
+ // Read start time of this file
+ Long midStart = getFileStartTime(midFile);
+ if (midStart == null) {
+ low = mid + 1;
+ continue;
+ }
+
+ if (midStart <= timestamp) {
+ // This file starts before or at target. It COULD be the one.
+ // But maybe a later file also starts before target?
+ foundIndex = mid;
+ low = mid + 1; // Try to find a later start time
+ } else {
+ // This file starts AFTER target. So target must be in an earlier file.
+ high = mid - 1;
+ }
+ }
+
+ if (foundIndex == -1) {
+ foundIndex = 0;
+ }
+
+ // Return the file index (offset)
+ Map<String, Object> result = new HashMap<>();
+ result.put("offset", foundIndex);
+ return R.ok(result);
+
+ } catch (Exception e) {
+ log.error("瀵诲潃澶辫触", e);
+ return R.error("瀵诲潃澶辫触");
+ }
+ }
+
+ private Long getFileStartTime(Path file) {
+ try {
+ String firstLine = null;
+ try (Stream<String> lines = Files.lines(file, StandardCharsets.UTF_8)) {
+ firstLine = lines.findFirst().orElse(null);
+ }
+ if (firstLine == null) return null;
+ DeviceDataLog firstLog = JSON.parseObject(firstLine, DeviceDataLog.class);
+ return firstLog.getCreateTime().getTime();
+ } catch (Exception e) {
+ return null;
}
}
@@ -335,4 +520,36 @@
res.put("finished", info.finished);
return R.ok(res);
}
+
+ @RequestMapping(value = "/deviceLog/enums/auth")
+ @ManagerAuth
+ public R getEnums() {
+ Map<String, Map<String, String>> enums = new HashMap<>();
+
+ enums.put("CrnModeType", Arrays.stream(com.zy.core.enums.CrnModeType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("CrnStatusType", Arrays.stream(com.zy.core.enums.CrnStatusType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("CrnForkPosType", Arrays.stream(com.zy.core.enums.CrnForkPosType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("CrnLiftPosType", Arrays.stream(com.zy.core.enums.CrnLiftPosType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("DualCrnForkPosType", Arrays.stream(com.zy.core.enums.DualCrnForkPosType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("DualCrnLiftPosType", Arrays.stream(com.zy.core.enums.DualCrnLiftPosType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("RgvModeType", Arrays.stream(com.zy.core.enums.RgvModeType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ enums.put("RgvStatusType", Arrays.stream(com.zy.core.enums.RgvStatusType.values())
+ .collect(Collectors.toMap(e -> String.valueOf(e.id), e -> e.desc)));
+
+ return R.ok(enums);
+ }
}
--
Gitblit v1.9.1