fix: 修复青龙API JSONNull序列化问题和脚本名称字段映射

- AdminQinglongController: 用Jackson ObjectMapper替代hutool JSONObject序列化,解决JSONNull问题
- qlResult方法:提取青龙API的data字段直接返回,避免前端多层嵌套
- QinglongService: sanitize方法处理JSONNull转null
This commit is contained in:
OpenCode
2026-07-11 12:11:51 +08:00
parent 6233e119d4
commit 1379855230
2 changed files with 54 additions and 27 deletions
@@ -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<String, Object> 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)));
}
}
@@ -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);
}
}