Browse Source

feat:业务指令接口

tags/freeze
白凤吉 3 months ago
parent
commit
896e669f73
  1. 12
      src/main/java/com/iflytop/gd/app/common/annotation/CommandMapping.java
  2. 55
      src/main/java/com/iflytop/gd/app/controller/CmdController.java
  3. 9
      src/main/java/com/iflytop/gd/app/core/cmd/CommandHandler.java
  4. 42
      src/main/java/com/iflytop/gd/app/core/cmd/CommandHandlerRegistry.java
  5. 55
      src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java

12
src/main/java/com/iflytop/gd/app/common/annotation/CommandMapping.java

@ -0,0 +1,12 @@
package com.iflytop.gd.app.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CommandMapping {
String value();
}

55
src/main/java/com/iflytop/gd/app/controller/CmdController.java

@ -0,0 +1,55 @@
package com.iflytop.gd.app.controller;
import com.iflytop.gd.app.core.cmd.CommandHandler;
import com.iflytop.gd.app.core.cmd.CommandHandlerRegistry;
import com.iflytop.gd.app.model.dto.CmdDTO;
import com.iflytop.gd.system.common.result.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
@Tag(name = "前端业务指令")
@RestController
@RequestMapping("/api/cmd")
@RequiredArgsConstructor
@Slf4j
public class CmdController {
private final CommandHandlerRegistry registry;
@Operation(summary = "前端统一调用一个接口")
@PostMapping
public Result<?> controlMethod(@RequestBody CmdDTO cmdDTO) {
String cmdId = cmdDTO.getCmdId();
String cmdCode = cmdDTO.getCmdCode();
try {
CommandHandler commandHandler = registry.getHandler(cmdCode);
if (commandHandler == null) {
log.error("未找到对应的业务指令");
return Result.failed();
}
log.info("业务指令开始执行");
CompletableFuture<Void> future = commandHandler.handle(cmdDTO);
future.whenComplete((v, ex) -> {
if (ex != null) {
log.error("执行业务指令发生异常: {}", cmdDTO, ex);
} else {
log.info("业务指令执行成功");
}
log.info("业务指令执行结束");
});
} catch (Exception e) {
log.error("执行业务指令发生异常: {}", cmdDTO, e);
return Result.failed(e.getMessage());
}
return Result.success();
}
}

9
src/main/java/com/iflytop/gd/app/core/cmd/CommandHandler.java

@ -0,0 +1,9 @@
package com.iflytop.gd.app.core.cmd;
import com.iflytop.gd.app.model.dto.CmdDTO;
import java.util.concurrent.CompletableFuture;
public interface CommandHandler {
CompletableFuture<Void> handle(CmdDTO cmdDTO);
}

42
src/main/java/com/iflytop/gd/app/core/cmd/CommandHandlerRegistry.java

@ -0,0 +1,42 @@
package com.iflytop.gd.app.core.cmd;
import com.iflytop.gd.app.common.annotation.CommandMapping;
import io.micrometer.common.lang.NonNull;
import jakarta.annotation.PostConstruct;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class CommandHandlerRegistry implements ApplicationContextAware {
private final Map<String, CommandHandler> handlerMap = new HashMap<>();
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@PostConstruct
public void init() {
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(CommandMapping.class);
for (Object bean : beans.values()) {
// 获取实际目标类而不是代理类
Class<?> targetClass = AopUtils.getTargetClass(bean);
CommandMapping mapping = targetClass.getAnnotation(CommandMapping.class);
if (mapping != null && bean instanceof CommandHandler) {
handlerMap.put(mapping.value(), (CommandHandler) bean);
}
}
}
public CommandHandler getHandler(String command) {
return handlerMap.get(command);
}
}

55
src/main/java/com/iflytop/gd/app/model/dto/CmdDTO.java

@ -0,0 +1,55 @@
package com.iflytop.gd.app.model.dto;
import cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.Map;
import java.util.Optional;
@Schema(description = "指令")
@Data
public class CmdDTO {
@NotBlank()
@Schema(description = "指令id,前端生成唯一ID")
private String cmdId;
@NotBlank()
@Schema(description = "指令")
private String cmdCode;
@Schema(description = "参数")
private Map<String, Object> params;
public Double getDoubleParam(String key) {
return Optional.ofNullable(params.get(key))
.map(Object::toString)
.map(Double::parseDouble)
.orElse(null);
}
public String getStringParam(String key) {
return (String) params.get(key);
}
public Integer getIntegerParam(String key) {
return Optional.ofNullable(params.get(key))
.map(Object::toString)
.map(Integer::parseInt)
.orElse(null);
}
public Boolean getBooleanParam(String key) {
return Optional.ofNullable(params.get(key))
.map(Object::toString)
.map(Boolean::parseBoolean)
.orElse(null);
}
@Override
public String toString() {
return JSONUtil.toJsonStr(this);
}
}
Loading…
Cancel
Save