package com.xuqm.tenant.controller; import com.xuqm.tenant.config.PrivateDeploymentProperties; import com.xuqm.tenant.service.SystemUpdateService; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; 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 org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import java.util.Map; @RestController @RequestMapping("/api/system") public class SystemUpdateController { private final PrivateDeploymentProperties deployProps; private final SystemUpdateService updateService; public SystemUpdateController(PrivateDeploymentProperties deployProps, SystemUpdateService updateService) { this.deployProps = deployProps; this.updateService = updateService; } /** 返回当前部署版本号。仅 PRIVATE 模式可用。 */ @GetMapping("/version") public ResponseEntity version() { if (!deployProps.isPrivate()) { return ResponseEntity.status(403).body(Map.of("message", "此接口仅在私有化部署可用")); } String currentVersion = updateService.readCurrentVersion(); return ResponseEntity.ok(Map.of("data", Map.of("currentVersion", currentVersion))); } /** * 拉取最新镜像并重建所有容器。耗时较长(需 docker pull)。 * 仅 PRIVATE 模式可用。 */ @PostMapping(value = "/update", produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity update() { if (!deployProps.isPrivate()) { return ResponseEntity.status(403) .contentType(MediaType.TEXT_PLAIN) .body(out -> out.write("此接口仅在私有化部署可用\n".getBytes())); } return stream(emit -> updateService.runUpdate(emit)); } /** * 不拉取新镜像,直接用当前本地镜像重建所有容器。速度快,适合修复异常服务。 * 仅 PRIVATE 模式可用。 */ @PostMapping(value = "/reset", produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity reset() { if (!deployProps.isPrivate()) { return ResponseEntity.status(403) .contentType(MediaType.TEXT_PLAIN) .body(out -> out.write("此接口仅在私有化部署可用\n".getBytes())); } return stream(emit -> updateService.runReset(emit)); } private ResponseEntity stream(java.util.function.Consumer> action) { StreamingResponseBody body = outputStream -> action.accept(line -> { try { outputStream.write((line + "\n").getBytes()); outputStream.flush(); } catch (Exception ignored) {} }); return ResponseEntity.ok() .contentType(MediaType.TEXT_PLAIN) .body(body); } }