From 1379855230ff20ad6790deec284c101ff6244679 Mon Sep 17 00:00:00 2001 From: OpenCode Date: Sat, 11 Jul 2026 12:11:51 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=9D=92=E9=BE=99API?= =?UTF-8?q?=20JSONNull=E5=BA=8F=E5=88=97=E5=8C=96=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=92=8C=E8=84=9A=E6=9C=AC=E5=90=8D=E7=A7=B0=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AdminQinglongController: 用Jackson ObjectMapper替代hutool JSONObject序列化,解决JSONNull问题 - qlResult方法:提取青龙API的data字段直接返回,避免前端多层嵌套 - QinglongService: sanitize方法处理JSONNull转null --- .../admin/AdminQinglongController.java | 63 ++++++++++++------- .../modules/task/service/QinglongService.java | 18 ++++-- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/cool/modules/task/controller/admin/AdminQinglongController.java b/src/main/java/com/cool/modules/task/controller/admin/AdminQinglongController.java index 994f5e6..f40e0da 100644 --- a/src/main/java/com/cool/modules/task/controller/admin/AdminQinglongController.java +++ b/src/main/java/com/cool/modules/task/controller/admin/AdminQinglongController.java @@ -2,12 +2,12 @@ package com.cool.modules.task.controller.admin; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.cool.core.request.R; import com.cool.core.util.CoolSecurityUtil; import com.cool.modules.base.entity.sys.BaseSysUserEntity; import com.cool.modules.base.mapper.sys.BaseSysUserMapper; import com.cool.modules.task.service.QinglongService; -import com.mybatisflex.core.query.QueryWrapper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.Collections; @@ -33,6 +33,23 @@ public class AdminQinglongController { return Collections.emptyList(); } + private final com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper(); + + private Object qlResult(JSONObject json) { + if (json == null) return null; + try { + String str = json.toString(); + java.util.Map map = objectMapper.readValue(str, java.util.Map.class); + Object code = map.get("code"); + if (code instanceof Number && ((Number) code).intValue() == 200 && map.containsKey("data")) { + return map.get("data"); + } + return map; + } catch (Exception e) { + return null; + } + } + @Operation(summary = "检查连接") @GetMapping("/check") public R check() { @@ -44,43 +61,43 @@ public class AdminQinglongController { public R scripts(@RequestParam(required = false) String searchValue, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) { - return R.ok(qinglongService.getScripts(currentUserDeptIds(), searchValue, page, size)); + return R.ok(qlResult(qinglongService.getScripts(currentUserDeptIds(), searchValue, page, size))); } @Operation(summary = "获取脚本详情") @GetMapping("/scripts/{fileName}") public R scriptDetail(@PathVariable String fileName) { - return R.ok(qinglongService.getScript(currentUserDeptIds(), fileName)); + return R.ok(qlResult(qinglongService.getScript(currentUserDeptIds(), fileName))); } @Operation(summary = "添加脚本") @PostMapping("/scripts") public R addScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.addScript(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.addScript(currentUserDeptIds(), body))); } @Operation(summary = "更新脚本") @PutMapping("/scripts/{fileName}") public R updateScript(@PathVariable String fileName, @RequestBody JSONObject body) { - return R.ok(qinglongService.updateScript(currentUserDeptIds(), fileName, body)); + return R.ok(qlResult(qinglongService.updateScript(currentUserDeptIds(), fileName, body))); } @Operation(summary = "删除脚本") @DeleteMapping("/scripts") public R deleteScript(@RequestBody JSONArray fileNames) { - return R.ok(qinglongService.deleteScript(currentUserDeptIds(), fileNames.toList(String.class))); + return R.ok(qlResult(qinglongService.deleteScript(currentUserDeptIds(), fileNames.toList(String.class)))); } @Operation(summary = "运行脚本") @PostMapping("/scripts/run") public R runScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.runScript(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.runScript(currentUserDeptIds(), body))); } @Operation(summary = "停止脚本") @PostMapping("/scripts/stop") public R stopScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.stopScript(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.stopScript(currentUserDeptIds(), body))); } @Operation(summary = "获取环境变量列表") @@ -88,37 +105,37 @@ public class AdminQinglongController { public R envs(@RequestParam(required = false) String searchValue, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) { - return R.ok(qinglongService.getEnvs(currentUserDeptIds(), searchValue, page, size)); + return R.ok(qlResult(qinglongService.getEnvs(currentUserDeptIds(), searchValue, page, size))); } @Operation(summary = "添加环境变量") @PostMapping("/envs") public R addEnv(@RequestBody JSONArray envs) { - return R.ok(qinglongService.addEnv(currentUserDeptIds(), envs)); + return R.ok(qlResult(qinglongService.addEnv(currentUserDeptIds(), envs))); } @Operation(summary = "更新环境变量") @PutMapping("/envs") public R updateEnv(@RequestBody JSONObject body) { - return R.ok(qinglongService.updateEnv(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.updateEnv(currentUserDeptIds(), body))); } @Operation(summary = "删除环境变量") @DeleteMapping("/envs") public R deleteEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.deleteEnv(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.deleteEnv(currentUserDeptIds(), ids))); } @Operation(summary = "启用环境变量") @PutMapping("/envs/enable") public R enableEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.enableEnv(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.enableEnv(currentUserDeptIds(), ids))); } @Operation(summary = "禁用环境变量") @PutMapping("/envs/disable") public R disableEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.disableEnv(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.disableEnv(currentUserDeptIds(), ids))); } @Operation(summary = "获取青龙定时任务列表") @@ -126,54 +143,54 @@ public class AdminQinglongController { public R crons(@RequestParam(required = false) String searchValue, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size) { - return R.ok(qinglongService.getCrons(currentUserDeptIds(), searchValue, page, size)); + return R.ok(qlResult(qinglongService.getCrons(currentUserDeptIds(), searchValue, page, size))); } @Operation(summary = "添加青龙定时任务") @PostMapping("/crons") public R addCron(@RequestBody JSONObject body) { - return R.ok(qinglongService.addCron(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.addCron(currentUserDeptIds(), body))); } @Operation(summary = "更新青龙定时任务") @PutMapping("/crons") public R updateCron(@RequestBody JSONObject body) { - return R.ok(qinglongService.updateCron(currentUserDeptIds(), body)); + return R.ok(qlResult(qinglongService.updateCron(currentUserDeptIds(), body))); } @Operation(summary = "删除青龙定时任务") @DeleteMapping("/crons") public R deleteCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.deleteCron(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.deleteCron(currentUserDeptIds(), ids))); } @Operation(summary = "运行青龙定时任务") @PutMapping("/crons/run") public R runCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.runCron(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.runCron(currentUserDeptIds(), ids))); } @Operation(summary = "停止青龙定时任务") @PutMapping("/crons/stop") public R stopCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.stopCron(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.stopCron(currentUserDeptIds(), ids))); } @Operation(summary = "启用青龙定时任务") @PutMapping("/crons/enable") public R enableCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.enableCron(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.enableCron(currentUserDeptIds(), ids))); } @Operation(summary = "禁用青龙定时任务") @PutMapping("/crons/disable") public R disableCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.disableCron(currentUserDeptIds(), ids)); + return R.ok(qlResult(qinglongService.disableCron(currentUserDeptIds(), ids))); } @Operation(summary = "获取青龙任务日志") @GetMapping("/crons/{cronId}/log") public R cronLog(@PathVariable String cronId) { - return R.ok(qinglongService.getCronLog(currentUserDeptIds(), cronId)); + return R.ok(qlResult(qinglongService.getCronLog(currentUserDeptIds(), cronId))); } } diff --git a/src/main/java/com/cool/modules/task/service/QinglongService.java b/src/main/java/com/cool/modules/task/service/QinglongService.java index 8a460fb..221ad02 100644 --- a/src/main/java/com/cool/modules/task/service/QinglongService.java +++ b/src/main/java/com/cool/modules/task/service/QinglongService.java @@ -6,12 +6,16 @@ import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONNull; import cn.hutool.json.JSONUtil; import com.cool.modules.task.entity.QlDeptConfigEntity; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -205,7 +209,7 @@ public class QinglongService { HttpResponse resp = HttpRequest.get(sUrl) .header("Authorization", authHeader(token)) .timeout(10000).execute(); - return JSONUtil.parseObj(resp.body()); + return sanitize(JSONUtil.parseObj(resp.body())); } catch (Exception e) { log.error("青龙API请求失败: {}", e.getMessage()); return new JSONObject().set("code", 500).set("message", e.getMessage()); @@ -221,7 +225,7 @@ public class QinglongService { .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); - return JSONUtil.parseObj(resp.body()); + return sanitize(JSONUtil.parseObj(resp.body())); } catch (Exception e) { log.error("青龙API请求失败: {}", e.getMessage()); return new JSONObject().set("code", 500).set("message", e.getMessage()); @@ -237,7 +241,7 @@ public class QinglongService { .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); - return JSONUtil.parseObj(resp.body()); + return sanitize(JSONUtil.parseObj(resp.body())); } catch (Exception e) { log.error("青龙API请求失败: {}", e.getMessage()); return new JSONObject().set("code", 500).set("message", e.getMessage()); @@ -253,7 +257,7 @@ public class QinglongService { .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); - return JSONUtil.parseObj(resp.body()); + return sanitize(JSONUtil.parseObj(resp.body())); } catch (Exception e) { log.error("青龙API请求失败: {}", e.getMessage()); return new JSONObject().set("code", 500).set("message", e.getMessage()); @@ -442,4 +446,10 @@ public class QinglongService { String token = getDeptAccessToken(configs.get(0)); return qlGet(token, "/open/crons/" + cronId + "/log"); } + + private JSONObject sanitize(JSONObject json) { + if (json == null) return null; + String jsonStr = json.toString(); + return JSONUtil.parseObj(jsonStr, false); + } }