This commit is contained in:
van
2026-04-11 22:35:39 +08:00
parent 5205d8c155
commit 94f319514e
14 changed files with 296 additions and 30 deletions

View File

@@ -55,6 +55,9 @@ public class TencentDocController extends BaseController {
@Autowired
private com.ruoyi.jarvis.service.ITencentDocDelayedPushService delayedPushService;
@Autowired
private com.ruoyi.jarvis.wecom.WxSendGoofishNotifyClient wxSendGoofishNotifyClient;
/** 单次请求最大行数(腾讯文档 API行数≤1000 */
private static final int API_MAX_ROWS_PER_REQUEST = 200;
/** 用 rowTotal 时接口实际单次只能读 200 行 */
@@ -938,6 +941,7 @@ public class TencentDocController extends BaseController {
@Anonymous
@PostMapping("/fillLogisticsByOrderNo")
public AjaxResult fillLogisticsByOrderNo(@RequestBody Map<String, Object> params) {
String batchId = null;
try {
// 直接尝试刷新token如果失败说明需要首次授权
String accessToken;
@@ -955,7 +959,7 @@ public class TencentDocController extends BaseController {
}
// 从参数获取批次ID如果是批量调用会传入
String batchId = params.get("batchId") != null ? String.valueOf(params.get("batchId")) : null;
batchId = params.get("batchId") != null ? String.valueOf(params.get("batchId")) : null;
// 从参数或配置中获取文档信息
String fileId = (String) params.get("fileId");
@@ -1920,7 +1924,7 @@ public class TencentDocController extends BaseController {
if (errorCount > 0 && successUpdates == 0) {
status = "FAILED";
} else if (errorCount > 0) {
status = "PARTIAL_SUCCESS";
status = "PARTIAL";
}
batchPushService.updateBatchPushRecord(batchId, status, successUpdates, skippedCount, errorCount,
message, null);
@@ -1948,7 +1952,21 @@ public class TencentDocController extends BaseController {
return AjaxResult.success("填充物流链接完成", result);
} catch (Exception e) {
log.error("填充物流链接失败", e);
return AjaxResult.error("填充物流链接失败: " + e.getMessage());
String errMsg = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName();
if (batchId != null && !batchId.trim().isEmpty()) {
try {
batchPushService.updateBatchPushRecord(batchId, "FAILED", 0, 0, 0, null, errMsg);
} catch (Exception ex) {
log.error("异常后更新批量推送记录失败 batchId={}", batchId, ex);
}
try {
wxSendGoofishNotifyClient.pushGoofishAgentText(null,
"【腾讯文档推送】批量同步异常\n批次: " + batchId + "\n" + errMsg);
} catch (Exception ex) {
log.warn("腾讯文档推送异常企微通知失败: {}", ex.toString());
}
}
return AjaxResult.error("填充物流链接失败: " + errMsg);
}
}
@@ -2093,6 +2111,10 @@ public class TencentDocController extends BaseController {
String fileId = tencentDocConfig.getFileId();
String sheetId = tencentDocConfig.getSheetId();
if (fileId != null && !fileId.trim().isEmpty()) {
batchPushService.reconcileStaleRunningRecords(fileId);
}
if (fileId != null && sheetId != null) {
com.ruoyi.jarvis.domain.TencentDocBatchPushRecord lastSuccess =
batchPushService.getLastSuccessRecord(fileId, sheetId);

View File

@@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -12,6 +13,7 @@ import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.framework.web.domain.Server;
import com.ruoyi.jarvis.service.ILogisticsService;
import com.ruoyi.jarvis.service.IWxSendService;
import com.ruoyi.jarvis.wecom.WxSendGoofishNotifyClient;
import javax.annotation.Resource;
import java.util.HashMap;
@@ -32,6 +34,9 @@ public class ServerController
@Resource
private IWxSendService wxSendService;
@Resource
private WxSendGoofishNotifyClient wxSendGoofishNotifyClient;
/** Ollama 服务地址,用于健康检查 */
@Value("${jarvis.ollama.base-url:http://192.168.8.34:11434}")
private String ollamaBaseUrl;
@@ -72,23 +77,23 @@ public class ServerController
healthMap.put("logistics", logisticsMap);
}
// 微信推送服务健康检测
try {
IWxSendService.HealthCheckResult wxSendHealth = wxSendService.checkHealth();
Map<String, Object> wxSendMap = new HashMap<>();
wxSendMap.put("healthy", wxSendHealth.isHealthy());
wxSendMap.put("status", wxSendHealth.getStatus());
wxSendMap.put("message", wxSendHealth.getMessage());
wxSendMap.put("serviceUrl", wxSendHealth.getServiceUrl());
healthMap.put("wxSend", wxSendMap);
} catch (Exception e) {
Map<String, Object> wxSendMap = new HashMap<>();
wxSendMap.put("healthy", false);
wxSendMap.put("status", "异常");
wxSendMap.put("message", "健康检测异常: " + e.getMessage());
wxSendMap.put("serviceUrl", "");
healthMap.put("wxSend", wxSendMap);
}
// 微信推送:不在此自动下发消息,仅展示配置地址;真实检测见 POST /monitor/server/health/wx-send-test
Map<String, Object> wxSendMap = new HashMap<>();
wxSendMap.put("manualOnly", true);
wxSendMap.put("healthy", null);
wxSendMap.put("status", "未检测");
wxSendMap.put("message", "点击「测试」将发送一条健康检查消息(会真实推送到微信)");
wxSendMap.put("serviceUrl", wxSendService.getHealthCheckServiceUrl());
healthMap.put("wxSend", wxSendMap);
// 企微闲鱼通知:仅展示接口地址;真实检测见 POST /monitor/server/health/goofish-notify-test
Map<String, Object> goofishMap = new HashMap<>();
goofishMap.put("manualOnly", true);
goofishMap.put("healthy", null);
goofishMap.put("status", "未检测");
goofishMap.put("message", "点击「测试」将经 wxSend 向企微闲鱼应用发送一条测试文本");
goofishMap.put("serviceUrl", wxSendGoofishNotifyClient.getGoofishPushEndpointDisplay());
healthMap.put("goofishNotify", goofishMap);
// Ollama 服务健康检测(调试用)
try {
@@ -115,6 +120,54 @@ public class ServerController
return AjaxResult.success(healthMap);
}
/**
* 手动测试微信推送(会真实下发一条消息)
*/
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@PostMapping("/health/wx-send-test")
public AjaxResult testWxSendHealth() {
try {
IWxSendService.HealthCheckResult r = wxSendService.checkHealth();
Map<String, Object> m = new HashMap<>();
m.put("manualOnly", true);
m.put("healthy", r.isHealthy());
m.put("status", r.getStatus());
m.put("message", r.getMessage());
m.put("serviceUrl", r.getServiceUrl());
return AjaxResult.success(m);
} catch (Exception e) {
Map<String, Object> m = new HashMap<>();
m.put("manualOnly", true);
m.put("healthy", false);
m.put("status", "异常");
m.put("message", "检测异常: " + e.getMessage());
m.put("serviceUrl", wxSendService.getHealthCheckServiceUrl());
return AjaxResult.success(m);
}
}
/**
* 手动测试企微闲鱼通知(经 wxSend goofish-active-push
*/
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@PostMapping("/health/goofish-notify-test")
public AjaxResult testGoofishNotify() {
String err = wxSendGoofishNotifyClient.testGoofishNotify();
Map<String, Object> m = new HashMap<>();
m.put("manualOnly", true);
m.put("serviceUrl", wxSendGoofishNotifyClient.getGoofishPushEndpointDisplay());
if (err == null) {
m.put("healthy", true);
m.put("status", "正常");
m.put("message", "闲鱼通知测试消息已发送");
} else {
m.put("healthy", false);
m.put("status", "异常");
m.put("message", err);
}
return AjaxResult.success(m);
}
private void putOllamaUnhealthy(Map<String, Object> healthMap, String url, String message) {
Map<String, Object> ollamaMap = new HashMap<>();