diff --git a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java index bdf85a3..e4fff01 100644 --- a/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java +++ b/src/main/java/com/cool/modules/base/service/sys/impl/BaseSysLoginServiceImpl.java @@ -46,8 +46,6 @@ public class BaseSysLoginServiceImpl implements BaseSysLoginService { private final BaseSysPermsService baseSysPermsService; - private final com.cool.modules.task.service.QinglongService qinglongService; - @org.springframework.beans.factory.annotation.Value("${cool.captcha.enable:true}") private boolean captchaEnable; @@ -106,7 +104,6 @@ public class BaseSysLoginServiceImpl implements BaseSysLoginService { if (captchaEnable) { coolCache.del("verify:img:" + baseSysLoginDto.getCaptchaId()); } - qinglongService.ensureUserApp(baseSysUserEntity.getId()); return generateToken(roleIds, baseSysUserEntity, null); } 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 624f144..994f5e6 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 @@ -4,9 +4,14 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; 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; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -17,15 +22,21 @@ import org.springframework.web.bind.annotation.*; public class AdminQinglongController { final private QinglongService qinglongService; + final private BaseSysUserMapper baseSysUserMapper; - private Long currentUserId() { - return CoolSecurityUtil.getCurrentUserId(); + private List currentUserDeptIds() { + Long userId = CoolSecurityUtil.getCurrentUserId(); + BaseSysUserEntity user = baseSysUserMapper.selectOneById(userId); + if (user != null && user.getDepartmentId() != null) { + return Collections.singletonList(user.getDepartmentId()); + } + return Collections.emptyList(); } @Operation(summary = "检查连接") @GetMapping("/check") public R check() { - return R.ok(qinglongService.checkConnection(currentUserId())); + return R.ok(qinglongService.checkConnection(currentUserDeptIds())); } @Operation(summary = "获取脚本列表") @@ -33,43 +44,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(currentUserId(), searchValue, page, size)); + return R.ok(qinglongService.getScripts(currentUserDeptIds(), searchValue, page, size)); } @Operation(summary = "获取脚本详情") @GetMapping("/scripts/{fileName}") public R scriptDetail(@PathVariable String fileName) { - return R.ok(qinglongService.getScript(currentUserId(), fileName)); + return R.ok(qinglongService.getScript(currentUserDeptIds(), fileName)); } @Operation(summary = "添加脚本") @PostMapping("/scripts") public R addScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.addScript(currentUserId(), body)); + return R.ok(qinglongService.addScript(currentUserDeptIds(), body)); } @Operation(summary = "更新脚本") @PutMapping("/scripts/{fileName}") public R updateScript(@PathVariable String fileName, @RequestBody JSONObject body) { - return R.ok(qinglongService.updateScript(currentUserId(), fileName, body)); + return R.ok(qinglongService.updateScript(currentUserDeptIds(), fileName, body)); } @Operation(summary = "删除脚本") @DeleteMapping("/scripts") public R deleteScript(@RequestBody JSONArray fileNames) { - return R.ok(qinglongService.deleteScript(currentUserId(), fileNames.toList(String.class))); + return R.ok(qinglongService.deleteScript(currentUserDeptIds(), fileNames.toList(String.class))); } @Operation(summary = "运行脚本") @PostMapping("/scripts/run") public R runScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.runScript(currentUserId(), body)); + return R.ok(qinglongService.runScript(currentUserDeptIds(), body)); } @Operation(summary = "停止脚本") @PostMapping("/scripts/stop") public R stopScript(@RequestBody JSONObject body) { - return R.ok(qinglongService.stopScript(currentUserId(), body)); + return R.ok(qinglongService.stopScript(currentUserDeptIds(), body)); } @Operation(summary = "获取环境变量列表") @@ -77,37 +88,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(currentUserId(), searchValue, page, size)); + return R.ok(qinglongService.getEnvs(currentUserDeptIds(), searchValue, page, size)); } @Operation(summary = "添加环境变量") @PostMapping("/envs") public R addEnv(@RequestBody JSONArray envs) { - return R.ok(qinglongService.addEnv(currentUserId(), envs)); + return R.ok(qinglongService.addEnv(currentUserDeptIds(), envs)); } @Operation(summary = "更新环境变量") @PutMapping("/envs") public R updateEnv(@RequestBody JSONObject body) { - return R.ok(qinglongService.updateEnv(currentUserId(), body)); + return R.ok(qinglongService.updateEnv(currentUserDeptIds(), body)); } @Operation(summary = "删除环境变量") @DeleteMapping("/envs") public R deleteEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.deleteEnv(currentUserId(), ids)); + return R.ok(qinglongService.deleteEnv(currentUserDeptIds(), ids)); } @Operation(summary = "启用环境变量") @PutMapping("/envs/enable") public R enableEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.enableEnv(currentUserId(), ids)); + return R.ok(qinglongService.enableEnv(currentUserDeptIds(), ids)); } @Operation(summary = "禁用环境变量") @PutMapping("/envs/disable") public R disableEnv(@RequestBody JSONArray ids) { - return R.ok(qinglongService.disableEnv(currentUserId(), ids)); + return R.ok(qinglongService.disableEnv(currentUserDeptIds(), ids)); } @Operation(summary = "获取青龙定时任务列表") @@ -115,54 +126,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(currentUserId(), searchValue, page, size)); + return R.ok(qinglongService.getCrons(currentUserDeptIds(), searchValue, page, size)); } @Operation(summary = "添加青龙定时任务") @PostMapping("/crons") public R addCron(@RequestBody JSONObject body) { - return R.ok(qinglongService.addCron(currentUserId(), body)); + return R.ok(qinglongService.addCron(currentUserDeptIds(), body)); } @Operation(summary = "更新青龙定时任务") @PutMapping("/crons") public R updateCron(@RequestBody JSONObject body) { - return R.ok(qinglongService.updateCron(currentUserId(), body)); + return R.ok(qinglongService.updateCron(currentUserDeptIds(), body)); } @Operation(summary = "删除青龙定时任务") @DeleteMapping("/crons") public R deleteCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.deleteCron(currentUserId(), ids)); + return R.ok(qinglongService.deleteCron(currentUserDeptIds(), ids)); } @Operation(summary = "运行青龙定时任务") @PutMapping("/crons/run") public R runCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.runCron(currentUserId(), ids)); + return R.ok(qinglongService.runCron(currentUserDeptIds(), ids)); } @Operation(summary = "停止青龙定时任务") @PutMapping("/crons/stop") public R stopCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.stopCron(currentUserId(), ids)); + return R.ok(qinglongService.stopCron(currentUserDeptIds(), ids)); } @Operation(summary = "启用青龙定时任务") @PutMapping("/crons/enable") public R enableCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.enableCron(currentUserId(), ids)); + return R.ok(qinglongService.enableCron(currentUserDeptIds(), ids)); } @Operation(summary = "禁用青龙定时任务") @PutMapping("/crons/disable") public R disableCron(@RequestBody JSONArray ids) { - return R.ok(qinglongService.disableCron(currentUserId(), ids)); + return R.ok(qinglongService.disableCron(currentUserDeptIds(), ids)); } @Operation(summary = "获取青龙任务日志") @GetMapping("/crons/{cronId}/log") public R cronLog(@PathVariable String cronId) { - return R.ok(qinglongService.getCronLog(currentUserId(), cronId)); + return R.ok(qinglongService.getCronLog(currentUserDeptIds(), cronId)); } } diff --git a/src/main/java/com/cool/modules/task/controller/admin/AdminQlDeptConfigController.java b/src/main/java/com/cool/modules/task/controller/admin/AdminQlDeptConfigController.java new file mode 100644 index 0000000..512dd65 --- /dev/null +++ b/src/main/java/com/cool/modules/task/controller/admin/AdminQlDeptConfigController.java @@ -0,0 +1,143 @@ +package com.cool.modules.task.controller.admin; + +import cn.hutool.json.JSONObject; +import com.cool.core.request.R; +import com.cool.modules.base.entity.sys.BaseSysDepartmentEntity; +import com.cool.modules.base.service.sys.BaseSysDepartmentService; +import com.cool.modules.task.entity.QlDeptConfigEntity; +import com.cool.modules.task.service.QlDeptConfigService; +import com.cool.modules.task.service.QinglongService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "青龙部门配置", description = "部门青龙App绑定管理") +@RestController +@RequestMapping("/admin/task/qlDeptConfig") +@RequiredArgsConstructor +public class AdminQlDeptConfigController { + + final private QlDeptConfigService service; + final private QinglongService qinglongService; + final private BaseSysDepartmentService baseSysDepartmentService; + + @Operation(summary = "分页查询") + @PostMapping("/page") + public R page(@RequestBody JSONObject body) { + int page = body.getInt("page", 1); + int size = body.getInt("size", 20); + String keyWord = body.getStr("keyWord"); + com.mybatisflex.core.query.QueryWrapper qw = com.mybatisflex.core.query.QueryWrapper.create(); + if (keyWord != null && !keyWord.isEmpty()) { + qw.like(QlDeptConfigEntity::getDeptName, keyWord); + } + com.mybatisflex.core.paginate.Page result = service.page( + new com.mybatisflex.core.paginate.Page<>(page, size), qw); + return R.ok(result); + } + + @Operation(summary = "列表查询") + @PostMapping("/list") + public R list(@RequestBody JSONObject body) { + return R.ok(service.list()); + } + + @Operation(summary = "详情") + @GetMapping("/info") + public R info(@RequestParam Long id) { + return R.ok(service.getById(id)); + } + + @Operation(summary = "新增") + @PostMapping("/add") + public R add(@RequestBody JSONObject body) { + QlDeptConfigEntity entity = new QlDeptConfigEntity(); + entity.setDeptId(body.getLong("deptId")); + entity.setDeptName(body.getStr("deptName")); + entity.setClientId(body.getStr("clientId")); + entity.setClientSecret(body.getStr("clientSecret")); + service.save(entity); + return R.ok(entity); + } + + @Operation(summary = "更新") + @PostMapping("/update") + public R update(@RequestBody JSONObject body) { + Long id = body.getLong("id"); + QlDeptConfigEntity entity = service.getById(id); + if (entity == null) { + return R.error("记录不存在"); + } + if (body.containsKey("accessToken")) { + entity.setAccessToken(body.getStr("accessToken")); + } + if (body.containsKey("tokenExpire")) { + entity.setTokenExpire(body.getLong("tokenExpire")); + } + service.updateById(entity); + return R.ok(entity); + } + + @Operation(summary = "删除") + @PostMapping("/delete") + public R delete(@RequestBody JSONObject body) { + Object ids = body.get("ids"); + if (ids instanceof List) { + service.removeByIds((List) ids); + } + return R.ok(); + } + + @Operation(summary = "为部门绑定青龙App") + @PostMapping("/bind") + public R bind(@RequestBody JSONObject body) { + Long deptId = body.getLong("deptId"); + if (deptId == null) { + return R.error("部门ID不能为空"); + } + BaseSysDepartmentEntity dept = baseSysDepartmentService.getById(deptId); + if (dept == null) { + return R.error("部门不存在"); + } + QlDeptConfigEntity config = qinglongService.ensureDeptApp(deptId, dept.getName()); + if (config == null) { + return R.error("创建青龙应用失败,请检查青龙面板连接"); + } + return R.ok(config); + } + + @Operation(summary = "解绑部门青龙App") + @PostMapping("/unbind") + public R unbind(@RequestBody JSONObject body) { + Long deptId = body.getLong("deptId"); + if (deptId == null) { + return R.error("部门ID不能为空"); + } + qinglongService.deleteDeptApp(deptId); + return R.ok(); + } + + @Operation(summary = "获取未绑定青龙的部门列表") + @GetMapping("/unbound-departments") + public R unboundDepartments() { + List boundConfigs = service.list(); + List boundDeptIds = new ArrayList<>(); + for (QlDeptConfigEntity c : boundConfigs) { + boundDeptIds.add(c.getDeptId()); + } + List allDepts = baseSysDepartmentService.list(); + List unbound = new ArrayList<>(); + for (BaseSysDepartmentEntity dept : allDepts) { + if (!boundDeptIds.contains(dept.getId()) && dept.getStatus() == 1) { + JSONObject item = new JSONObject(); + item.set("id", dept.getId()); + item.set("name", dept.getName()); + unbound.add(item); + } + } + return R.ok(unbound); + } +} diff --git a/src/main/java/com/cool/modules/task/entity/QlUserConfigEntity.java b/src/main/java/com/cool/modules/task/entity/QlDeptConfigEntity.java similarity index 68% rename from src/main/java/com/cool/modules/task/entity/QlUserConfigEntity.java rename to src/main/java/com/cool/modules/task/entity/QlDeptConfigEntity.java index bb2238c..83b96bd 100644 --- a/src/main/java/com/cool/modules/task/entity/QlUserConfigEntity.java +++ b/src/main/java/com/cool/modules/task/entity/QlDeptConfigEntity.java @@ -9,15 +9,15 @@ import org.dromara.autotable.annotation.Index; @Getter @Setter -@Table(value = "ql_user_config", comment = "青龙用户配置") -public class QlUserConfigEntity extends BaseEntity { +@Table(value = "ql_dept_config", comment = "青龙部门配置") +public class QlDeptConfigEntity extends BaseEntity { @Index - @ColumnDefine(comment = "系统用户ID", notNull = true, type = "bigint") - private Long userId; + @ColumnDefine(comment = "部门ID", notNull = true, type = "bigint") + private Long deptId; - @ColumnDefine(comment = "系统用户名", notNull = true) - private String username; + @ColumnDefine(comment = "部门名称", notNull = true) + private String deptName; @ColumnDefine(comment = "青龙应用ID") private Long qlAppId; diff --git a/src/main/java/com/cool/modules/task/mapper/QlDeptConfigMapper.java b/src/main/java/com/cool/modules/task/mapper/QlDeptConfigMapper.java new file mode 100644 index 0000000..a715ccf --- /dev/null +++ b/src/main/java/com/cool/modules/task/mapper/QlDeptConfigMapper.java @@ -0,0 +1,7 @@ +package com.cool.modules.task.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.cool.modules.task.entity.QlDeptConfigEntity; + +public interface QlDeptConfigMapper extends BaseMapper { +} diff --git a/src/main/java/com/cool/modules/task/mapper/QlUserConfigMapper.java b/src/main/java/com/cool/modules/task/mapper/QlUserConfigMapper.java deleted file mode 100644 index dad664c..0000000 --- a/src/main/java/com/cool/modules/task/mapper/QlUserConfigMapper.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.cool.modules.task.mapper; - -import com.mybatisflex.core.BaseMapper; -import com.cool.modules.task.entity.QlUserConfigEntity; - -public interface QlUserConfigMapper extends BaseMapper { -} 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 7393803..8a460fb 100644 --- a/src/main/java/com/cool/modules/task/service/QinglongService.java +++ b/src/main/java/com/cool/modules/task/service/QinglongService.java @@ -1,13 +1,17 @@ package com.cool.modules.task.service; -import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; -import com.cool.modules.task.entity.QlUserConfigEntity; +import com.cool.modules.task.entity.QlDeptConfigEntity; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -29,7 +33,7 @@ public class QinglongService { private String adminToken; private boolean enabled; - private final QlUserConfigService qlUserConfigService; + private final QlDeptConfigService qlDeptConfigService; private String getAdminInternalToken() { if (!enabled) return null; @@ -53,14 +57,6 @@ public class QinglongService { return null; } - private String getAdminAccessToken() { - if (!enabled) return null; - if (StrUtil.isNotBlank(adminToken)) { - return adminToken; - } - return doTokenRequest(clientId, clientSecret); - } - private String doTokenRequest(String cId, String cSecret) { try { String authUrl = url + "/open/auth/token?client_id=" + cId @@ -77,18 +73,7 @@ public class QinglongService { return null; } - private String authHeader(Long userId) { - String token = getUserAccessToken(userId); - return token != null ? "Bearer " + token : ""; - } - - public String getUserAccessToken(Long userId) { - if (!enabled || userId == null) return null; - QlUserConfigEntity config = qlUserConfigService.getByUserId(userId); - if (config == null) { - config = ensureUserApp(userId); - if (config == null) return null; - } + private String getDeptAccessToken(QlDeptConfigEntity config) { if (StrUtil.isNotBlank(config.getAccessToken()) && config.getTokenExpire() != null && System.currentTimeMillis() < config.getTokenExpire()) { @@ -98,27 +83,40 @@ public class QinglongService { if (token != null) { config.setAccessToken(token); config.setTokenExpire(System.currentTimeMillis() + 86400_000L); - qlUserConfigService.updateById(config); + qlDeptConfigService.updateById(config); } return token; } - public QlUserConfigEntity ensureUserApp(Long userId) { + private String authHeader(String token) { + return StrUtil.isNotBlank(token) ? "Bearer " + token : ""; + } + + public List getUserDeptConfigs(List deptIds) { + if (!enabled || CollUtil.isEmpty(deptIds)) return new ArrayList<>(); + return qlDeptConfigService.listByDeptIds(deptIds); + } + + public QlDeptConfigEntity ensureDeptApp(Long deptId, String deptName) { if (!enabled) return null; - QlUserConfigEntity existing = qlUserConfigService.getByUserId(userId); + QlDeptConfigEntity existing = qlDeptConfigService.getByDeptId(deptId); if (existing != null && StrUtil.isNotBlank(existing.getClientId())) { + if (!deptName.equals(existing.getDeptName())) { + existing.setDeptName(deptName); + qlDeptConfigService.updateById(existing); + } return existing; } String adminToken = getAdminInternalToken(); if (adminToken == null) { - log.error("无法获取管理员token来创建用户青龙应用"); + log.error("无法获取管理员token来创建部门青龙应用"); return null; } try { - String username = "user_" + userId; + String appName = "dept_" + deptId; String appsUrl = url + "/api/apps?t=" + System.currentTimeMillis(); JSONObject body = new JSONObject(); - body.set("name", username); + body.set("name", appName); body.set("scopes", new JSONArray().put("crons").put("envs").put("scripts").put("logs")); HttpResponse resp = HttpRequest.post(appsUrl) .header("Authorization", "Bearer " + adminToken) @@ -128,52 +126,84 @@ public class QinglongService { JSONObject result = JSONUtil.parseObj(resp.body()); if (result.getInt("code") == 200 && result.get("data") != null) { JSONObject data = result.getJSONObject("data"); - QlUserConfigEntity config = existing != null ? existing : new QlUserConfigEntity(); - config.setUserId(userId); - config.setUsername(username); + QlDeptConfigEntity config = existing != null ? existing : new QlDeptConfigEntity(); + config.setDeptId(deptId); + config.setDeptName(deptName); config.setQlAppId(data.getLong("id")); config.setClientId(data.getStr("client_id")); config.setClientSecret(data.getStr("client_secret")); if (config.getId() != null) { - qlUserConfigService.updateById(config); + qlDeptConfigService.updateById(config); } else { - qlUserConfigService.save(config); + qlDeptConfigService.save(config); } - log.info("为用户{}创建青龙应用成功: clientId={}", userId, config.getClientId()); + log.info("为部门{}({})创建青龙应用成功: clientId={}", deptId, deptName, config.getClientId()); return config; } - log.error("创建青龙应用失败: {}", result.getStr("message")); + log.error("创建部门青龙应用失败: {}", result.getStr("message")); } catch (Exception e) { - log.error("创建青龙应用异常: {}", e.getMessage()); + log.error("创建部门青龙应用异常: {}", e.getMessage()); } return existing; } - public JSONObject checkConnection(Long userId) { + public boolean deleteDeptApp(Long deptId) { + if (!enabled) return false; + QlDeptConfigEntity config = qlDeptConfigService.getByDeptId(deptId); + if (config == null) return true; + if (config.getQlAppId() != null) { + String adminToken = getAdminInternalToken(); + if (adminToken != null) { + try { + String appsUrl = url + "/api/apps?t=" + System.currentTimeMillis(); + JSONArray ids = new JSONArray().put(config.getQlAppId()); + HttpRequest.delete(appsUrl) + .header("Authorization", "Bearer " + adminToken) + .header("Content-Type", "application/json") + .body(ids.toString()) + .timeout(10000).execute(); + log.info("删除部门{}青龙应用成功", deptId); + } catch (Exception e) { + log.error("删除部门青龙应用异常: {}", e.getMessage()); + } + } + } + qlDeptConfigService.removeById(config.getId()); + return true; + } + + public JSONObject checkConnection(List deptIds) { JSONObject result = new JSONObject(); if (!enabled) { result.set("connected", false).set("message", "青龙未启用"); return result; } + List configs = getUserDeptConfigs(deptIds); + if (CollUtil.isEmpty(configs)) { + result.set("connected", false).set("message", "当前部门未配置青龙面板"); + return result; + } try { - String t = getUserAccessToken(userId); - if (t != null) { - result.set("connected", true).set("message", "连接成功"); - } else { - result.set("connected", false).set("message", "Token获取失败"); + for (QlDeptConfigEntity config : configs) { + String t = getDeptAccessToken(config); + if (t == null) { + result.set("connected", false).set("message", "部门[" + config.getDeptName() + "]Token获取失败"); + return result; + } } + result.set("connected", true).set("message", "连接成功"); } catch (Exception e) { result.set("connected", false).set("message", e.getMessage()); } return result; } - private JSONObject qlGet(Long userId, String path) { + private JSONObject qlGet(String token, String path) { if (!enabled) return new JSONObject().set("code", 500).set("message", "青龙未启用"); try { String sUrl = url + path + (path.contains("?") ? "&" : "?") + "t=" + System.currentTimeMillis(); HttpResponse resp = HttpRequest.get(sUrl) - .header("Authorization", authHeader(userId)) + .header("Authorization", authHeader(token)) .timeout(10000).execute(); return JSONUtil.parseObj(resp.body()); } catch (Exception e) { @@ -182,12 +212,12 @@ public class QinglongService { } } - private JSONObject qlPost(Long userId, String path, Object body) { + private JSONObject qlPost(String token, String path, Object body) { if (!enabled) return new JSONObject().set("code", 500).set("message", "青龙未启用"); try { String sUrl = url + path + (path.contains("?") ? "&" : "?") + "t=" + System.currentTimeMillis(); HttpResponse resp = HttpRequest.post(sUrl) - .header("Authorization", authHeader(userId)) + .header("Authorization", authHeader(token)) .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); @@ -198,12 +228,12 @@ public class QinglongService { } } - private JSONObject qlPut(Long userId, String path, Object body) { + private JSONObject qlPut(String token, String path, Object body) { if (!enabled) return new JSONObject().set("code", 500).set("message", "青龙未启用"); try { String sUrl = url + path + (path.contains("?") ? "&" : "?") + "t=" + System.currentTimeMillis(); HttpResponse resp = HttpRequest.put(sUrl) - .header("Authorization", authHeader(userId)) + .header("Authorization", authHeader(token)) .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); @@ -214,12 +244,12 @@ public class QinglongService { } } - private JSONObject qlDelete(Long userId, String path, Object body) { + private JSONObject qlDelete(String token, String path, Object body) { if (!enabled) return new JSONObject().set("code", 500).set("message", "青龙未启用"); try { String sUrl = url + path + (path.contains("?") ? "&" : "?") + "t=" + System.currentTimeMillis(); HttpResponse resp = HttpRequest.delete(sUrl) - .header("Authorization", authHeader(userId)) + .header("Authorization", authHeader(token)) .header("Content-Type", "application/json") .body(body instanceof String ? (String) body : body.toString()) .timeout(10000).execute(); @@ -230,98 +260,186 @@ public class QinglongService { } } - public JSONObject getScripts(Long userId, String searchValue, int page, int size) { - String path = "/open/scripts"; - if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; - return qlGet(userId, path); + private List resolveDeptConfigs(List deptIds) { + List configs = getUserDeptConfigs(deptIds); + if (CollUtil.isEmpty(configs)) { + throw new RuntimeException("当前部门未配置青龙面板,请联系管理员"); + } + return configs; } - public JSONObject getScript(Long userId, String fileName) { - return qlGet(userId, "/open/scripts/" + fileName); + private JSONArray mergeDataFromDepts(List configs, String apiPath, String dataKey, String searchValue) { + JSONArray merged = new JSONArray(); + for (QlDeptConfigEntity config : configs) { + String token = getDeptAccessToken(config); + if (token == null) continue; + String path = apiPath; + if (StrUtil.isNotBlank(searchValue)) { + path += (path.contains("?") ? "&" : "?") + "searchValue=" + searchValue; + } + JSONObject resp = qlGet(token, path); + if (resp.getInt("code") == 200 && resp.get("data") != null) { + Object data = resp.get("data"); + JSONArray items = data instanceof JSONArray ? (JSONArray) data : new JSONArray().put(data); + for (int i = 0; i < items.size(); i++) { + JSONObject item = items.getJSONObject(i); + item.set("_deptId", config.getDeptId()); + item.set("_deptName", config.getDeptName()); + merged.add(item); + } + } + } + return merged; } - public JSONObject addScript(Long userId, JSONObject body) { - return qlPost(userId, "/open/scripts", body); + public JSONObject getScripts(List deptIds, String searchValue, int page, int size) { + List configs = resolveDeptConfigs(deptIds); + if (configs.size() == 1) { + String token = getDeptAccessToken(configs.get(0)); + String path = "/open/scripts"; + if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; + return qlGet(token, path); + } + JSONArray merged = mergeDataFromDepts(configs, "/open/scripts", "data", searchValue); + return new JSONObject().set("code", 200).set("data", merged); } - public JSONObject updateScript(Long userId, String fileName, JSONObject body) { + public JSONObject getScript(List deptIds, String fileName) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlGet(token, "/open/scripts/" + fileName); + } + + public JSONObject addScript(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPost(token, "/open/scripts", body); + } + + public JSONObject updateScript(List deptIds, String fileName, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); body.set("name", fileName); - return qlPut(userId, "/open/scripts", body); + return qlPut(token, "/open/scripts", body); } - public JSONObject deleteScript(Long userId, java.util.List fileNames) { - return qlDelete(userId, "/open/scripts", JSONUtil.createArray().put(fileNames)); + public JSONObject deleteScript(List deptIds, java.util.List fileNames) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlDelete(token, "/open/scripts", JSONUtil.createArray().put(fileNames)); } - public JSONObject runScript(Long userId, JSONObject body) { - return qlPost(userId, "/open/scripts/run", body); + public JSONObject runScript(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPost(token, "/open/scripts/run", body); } - public JSONObject stopScript(Long userId, JSONObject body) { - return qlPost(userId, "/open/scripts/stop", body); + public JSONObject stopScript(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPost(token, "/open/scripts/stop", body); } - public JSONObject getEnvs(Long userId, String searchValue, int page, int size) { - String path = "/open/envs"; - if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; - return qlGet(userId, path); + public JSONObject getEnvs(List deptIds, String searchValue, int page, int size) { + List configs = resolveDeptConfigs(deptIds); + if (configs.size() == 1) { + String token = getDeptAccessToken(configs.get(0)); + String path = "/open/envs"; + if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; + return qlGet(token, path); + } + JSONArray merged = mergeDataFromDepts(configs, "/open/envs", "data", searchValue); + return new JSONObject().set("code", 200).set("data", merged); } - public JSONObject addEnv(Long userId, JSONArray envs) { - return qlPost(userId, "/open/envs", envs); + public JSONObject addEnv(List deptIds, JSONArray envs) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPost(token, "/open/envs", envs); } - public JSONObject updateEnv(Long userId, JSONObject body) { - return qlPut(userId, "/open/envs", body); + public JSONObject updateEnv(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/envs", body); } - public JSONObject deleteEnv(Long userId, JSONArray ids) { - return qlDelete(userId, "/open/envs", ids); + public JSONObject deleteEnv(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlDelete(token, "/open/envs", ids); } - public JSONObject enableEnv(Long userId, JSONArray ids) { - return qlPut(userId, "/open/envs/enable", ids); + public JSONObject enableEnv(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/envs/enable", ids); } - public JSONObject disableEnv(Long userId, JSONArray ids) { - return qlPut(userId, "/open/envs/disable", ids); + public JSONObject disableEnv(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/envs/disable", ids); } - public JSONObject getCrons(Long userId, String searchValue, int page, int size) { - String path = "/open/crons"; - if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; - return qlGet(userId, path); + public JSONObject getCrons(List deptIds, String searchValue, int page, int size) { + List configs = resolveDeptConfigs(deptIds); + if (configs.size() == 1) { + String token = getDeptAccessToken(configs.get(0)); + String path = "/open/crons"; + if (StrUtil.isNotBlank(searchValue)) path += "?searchValue=" + searchValue; + return qlGet(token, path); + } + JSONArray merged = mergeDataFromDepts(configs, "/open/crons", "data", searchValue); + return new JSONObject().set("code", 200).set("data", merged); } - public JSONObject addCron(Long userId, JSONObject body) { - return qlPost(userId, "/open/crons", body); + public JSONObject addCron(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPost(token, "/open/crons", body); } - public JSONObject updateCron(Long userId, JSONObject body) { - return qlPut(userId, "/open/crons", body); + public JSONObject updateCron(List deptIds, JSONObject body) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/crons", body); } - public JSONObject deleteCron(Long userId, JSONArray ids) { - return qlDelete(userId, "/open/crons", ids); + public JSONObject deleteCron(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlDelete(token, "/open/crons", ids); } - public JSONObject runCron(Long userId, JSONArray ids) { - return qlPut(userId, "/open/crons/run", ids); + public JSONObject runCron(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/crons/run", ids); } - public JSONObject stopCron(Long userId, JSONArray ids) { - return qlPut(userId, "/open/crons/stop", ids); + public JSONObject stopCron(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/crons/stop", ids); } - public JSONObject enableCron(Long userId, JSONArray ids) { - return qlPut(userId, "/open/crons/enable", ids); + public JSONObject enableCron(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/crons/enable", ids); } - public JSONObject disableCron(Long userId, JSONArray ids) { - return qlPut(userId, "/open/crons/disable", ids); + public JSONObject disableCron(List deptIds, JSONArray ids) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlPut(token, "/open/crons/disable", ids); } - public JSONObject getCronLog(Long userId, String cronId) { - return qlGet(userId, "/open/crons/" + cronId + "/log"); + public JSONObject getCronLog(List deptIds, String cronId) { + List configs = resolveDeptConfigs(deptIds); + String token = getDeptAccessToken(configs.get(0)); + return qlGet(token, "/open/crons/" + cronId + "/log"); } } diff --git a/src/main/java/com/cool/modules/task/service/QlDeptConfigService.java b/src/main/java/com/cool/modules/task/service/QlDeptConfigService.java new file mode 100644 index 0000000..deeb560 --- /dev/null +++ b/src/main/java/com/cool/modules/task/service/QlDeptConfigService.java @@ -0,0 +1,10 @@ +package com.cool.modules.task.service; + +import com.cool.core.base.BaseService; +import com.cool.modules.task.entity.QlDeptConfigEntity; +import java.util.List; + +public interface QlDeptConfigService extends BaseService { + QlDeptConfigEntity getByDeptId(Long deptId); + List listByDeptIds(List deptIds); +} diff --git a/src/main/java/com/cool/modules/task/service/QlUserConfigService.java b/src/main/java/com/cool/modules/task/service/QlUserConfigService.java deleted file mode 100644 index 5ed2eb1..0000000 --- a/src/main/java/com/cool/modules/task/service/QlUserConfigService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.cool.modules.task.service; - -import com.cool.core.base.BaseService; -import com.cool.modules.task.entity.QlUserConfigEntity; - -public interface QlUserConfigService extends BaseService { - QlUserConfigEntity getByUserId(Long userId); -} diff --git a/src/main/java/com/cool/modules/task/service/impl/QlDeptConfigServiceImpl.java b/src/main/java/com/cool/modules/task/service/impl/QlDeptConfigServiceImpl.java new file mode 100644 index 0000000..c7c2dd7 --- /dev/null +++ b/src/main/java/com/cool/modules/task/service/impl/QlDeptConfigServiceImpl.java @@ -0,0 +1,24 @@ +package com.cool.modules.task.service.impl; + +import com.cool.core.base.BaseServiceImpl; +import com.cool.modules.task.entity.QlDeptConfigEntity; +import com.cool.modules.task.mapper.QlDeptConfigMapper; +import com.cool.modules.task.service.QlDeptConfigService; +import com.mybatisflex.core.query.QueryWrapper; +import java.util.List; +import org.springframework.stereotype.Service; + +@Service +public class QlDeptConfigServiceImpl extends BaseServiceImpl + implements QlDeptConfigService { + + @Override + public QlDeptConfigEntity getByDeptId(Long deptId) { + return getOne(QueryWrapper.create().eq(QlDeptConfigEntity::getDeptId, deptId)); + } + + @Override + public List listByDeptIds(List deptIds) { + return list(QueryWrapper.create().in(QlDeptConfigEntity::getDeptId, deptIds)); + } +} diff --git a/src/main/java/com/cool/modules/task/service/impl/QlUserConfigServiceImpl.java b/src/main/java/com/cool/modules/task/service/impl/QlUserConfigServiceImpl.java deleted file mode 100644 index 9beb889..0000000 --- a/src/main/java/com/cool/modules/task/service/impl/QlUserConfigServiceImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.cool.modules.task.service.impl; - -import com.cool.core.base.BaseServiceImpl; -import com.cool.modules.task.entity.QlUserConfigEntity; -import com.cool.modules.task.mapper.QlUserConfigMapper; -import com.cool.modules.task.service.QlUserConfigService; -import com.mybatisflex.core.query.QueryWrapper; -import org.springframework.stereotype.Service; - -@Service -public class QlUserConfigServiceImpl extends BaseServiceImpl - implements QlUserConfigService { - - @Override - public QlUserConfigEntity getByUserId(Long userId) { - return getOne(QueryWrapper.create().eq(QlUserConfigEntity::getUserId, userId)); - } -}