5 changed files with 145 additions and 2 deletions
-
44src/main/java/com/iflytop/colortitration/app/controller/SystemController.java
-
16src/main/java/com/iflytop/colortitration/app/model/dto/TimeSetDTO.java
-
27src/main/java/com/iflytop/colortitration/app/service/SystemService.java
-
4src/main/java/com/iflytop/colortitration/common/service/SystemConfigService.java
-
56src/main/java/com/iflytop/colortitration/common/utils/CommandUtil.java
@ -0,0 +1,44 @@ |
|||
package com.iflytop.colortitration.app.controller; |
|||
|
|||
import com.iflytop.colortitration.app.core.state.DeviceState; |
|||
import com.iflytop.colortitration.app.model.dto.TimeSetDTO; |
|||
import com.iflytop.colortitration.app.service.SystemService; |
|||
import com.iflytop.colortitration.common.result.Result; |
|||
import io.swagger.v3.oas.annotations.Operation; |
|||
import io.swagger.v3.oas.annotations.tags.Tag; |
|||
import jakarta.validation.Valid; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.time.Instant; |
|||
|
|||
@Tag(name = "系统") |
|||
@RestController |
|||
@RequestMapping("/api/sys") |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class SystemController { |
|||
private final SystemService systemService; |
|||
private final DeviceState deviceState; |
|||
|
|||
@Operation(summary = "获取当前系统状态") |
|||
@GetMapping("/device-status") |
|||
public Result<?> getDeviceStatus() { |
|||
return Result.success(deviceState.toJSON()); |
|||
} |
|||
|
|||
@Operation(summary = "设置系统时间") |
|||
@PostMapping("/set-datetime") |
|||
public Result<?> setDatetime(@Valid @RequestBody TimeSetDTO timeSetDTO) { |
|||
systemService.setSystemTime(timeSetDTO.getEpochMilli()); |
|||
return Result.success(); |
|||
} |
|||
|
|||
@Operation(summary = "获取当前系统时间") |
|||
@GetMapping("/datetime") |
|||
public Result<?> getDatetime() { |
|||
return Result.success(Instant.now().toEpochMilli()); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,16 @@ |
|||
package com.iflytop.colortitration.app.model.dto; |
|||
|
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import jakarta.validation.constraints.NotNull; |
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class TimeSetDTO { |
|||
/** |
|||
* 要设置的时间戳(毫秒),UTC 纪元毫秒数 |
|||
*/ |
|||
@NotNull |
|||
@Schema(description = "要设置的时间戳(毫秒),UTC 纪元毫秒数") |
|||
private Long epochMilli; |
|||
|
|||
} |
@ -0,0 +1,27 @@ |
|||
package com.iflytop.colortitration.app.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.iflytop.colortitration.common.mapper.SystemConfigMapper; |
|||
import com.iflytop.colortitration.common.model.entity.SystemConfig; |
|||
import com.iflytop.colortitration.common.utils.CommandUtil; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
/** |
|||
* 系统配置接口服务 |
|||
*/ |
|||
@Service |
|||
@RequiredArgsConstructor |
|||
public class SystemService extends ServiceImpl<SystemConfigMapper, SystemConfig> { |
|||
/** |
|||
* 将系统时区(可选)和系统时间(必选)一起设定 |
|||
* |
|||
* @param epochMilli UTC 毫秒时间戳 |
|||
*/ |
|||
public void setSystemTime(long epochMilli) { |
|||
long epochSecond = epochMilli / 1_000; |
|||
CommandUtil.runCommand("timedatectl", "set-ntp", "false"); |
|||
CommandUtil.runCommand("date", "-s", "@" + epochSecond); |
|||
CommandUtil.runCommand("hwclock", "--systohc"); |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
package com.iflytop.colortitration.common.utils; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.io.BufferedReader; |
|||
import java.io.IOException; |
|||
import java.io.InputStreamReader; |
|||
import java.nio.charset.StandardCharsets; |
|||
|
|||
/** |
|||
* 系统命令执行工具类 |
|||
*/ |
|||
@Slf4j |
|||
public class CommandUtil { |
|||
|
|||
private static final String DEFAULT_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; |
|||
|
|||
/** |
|||
* 执行系统命令并返回输出内容 |
|||
* |
|||
* @param cmd 命令及其参数,如 runCommand("ls", "-l") |
|||
* @return 命令输出 |
|||
* @throws RuntimeException 命令执行失败或中断 |
|||
*/ |
|||
public static String runCommand(String... cmd) { |
|||
try { |
|||
log.info("CMD: {}", String.join(" ", cmd)); |
|||
ProcessBuilder pb = new ProcessBuilder(cmd); |
|||
pb.environment().put("PATH", DEFAULT_PATH); // 设置 PATH 变量,防止找不到命令 |
|||
pb.redirectErrorStream(true); // 合并错误输出 |
|||
|
|||
Process process = pb.start(); |
|||
StringBuilder output = new StringBuilder(); |
|||
|
|||
try (BufferedReader reader = new BufferedReader( |
|||
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { |
|||
String line; |
|||
while ((line = reader.readLine()) != null) { |
|||
output.append(line).append('\n'); |
|||
} |
|||
} |
|||
|
|||
int exitCode = process.waitFor(); |
|||
if (exitCode != 0) { |
|||
throw new IllegalStateException(String.format( |
|||
"命令执行失败: [%s], 退出码=%d, 输出=\n%s", |
|||
String.join(" ", cmd), exitCode, output)); |
|||
} |
|||
|
|||
return output.toString().trim(); // 去掉最后一个换行 |
|||
} catch (IOException | InterruptedException e) { |
|||
Thread.currentThread().interrupt(); // 恢复中断状态 |
|||
throw new RuntimeException("执行系统命令失败: " + String.join(" ", cmd), e); |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue