diff --git a/src/main/java/iflytop/app/config/AppConstantConfig.java b/src/main/java/iflytop/app/config/AppConstantConfig.java new file mode 100644 index 0000000..cc1bbc5 --- /dev/null +++ b/src/main/java/iflytop/app/config/AppConstantConfig.java @@ -0,0 +1,10 @@ +package iflytop.config; + +public class AppConstantConfig { + public static final int HEARTBEAT_INTERVAL = 5000; + + public static final double SENSOR_ARM0_LENGTH_MM = 0.5; + public static final double SENSOR_ARM1_LENGTH_MM = 0.5; + + public static final int ENCODER_ACCURACY = 4096; +} diff --git a/src/main/java/iflytop/config/CorsConfig.java b/src/main/java/iflytop/app/config/CorsConfig.java similarity index 100% rename from src/main/java/iflytop/config/CorsConfig.java rename to src/main/java/iflytop/app/config/CorsConfig.java diff --git a/src/main/java/iflytop/config/SpringDocConfig.java b/src/main/java/iflytop/app/config/SpringDocConfig.java similarity index 100% rename from src/main/java/iflytop/config/SpringDocConfig.java rename to src/main/java/iflytop/app/config/SpringDocConfig.java diff --git a/src/main/java/iflytop/config/WebSocketConfiguration.java b/src/main/java/iflytop/app/config/WebSocketConfiguration.java similarity index 100% rename from src/main/java/iflytop/config/WebSocketConfiguration.java rename to src/main/java/iflytop/app/config/WebSocketConfiguration.java diff --git a/src/main/java/iflytop/app/controler/LocalDeviceControler.java b/src/main/java/iflytop/app/controler/LocalDeviceControler.java new file mode 100644 index 0000000..034b9a2 --- /dev/null +++ b/src/main/java/iflytop/app/controler/LocalDeviceControler.java @@ -0,0 +1,34 @@ +package iflytop.app.controler; + + +import iflytop.app.service.data.UserMgrService; +import iflytop.app.type.db.AppUser; +import iflytop.app.type.db.IflytopRet; +import iflytop.app.type.exception.AppException; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Tag(name = "用户", description = "") +@Slf4j +@Controller +@RequestMapping(value = "/user/") +@ResponseBody +public class UserControler { + + @Resource + UserMgrService appUserMgrService; + + @Operation(summary = "用户登录") + @PostMapping("login") + public IflytopRet login(Integer id, String password) throws AppException { + return IflytopRet.success(appUserMgrService.login(id, password)); + } + + +} diff --git a/src/main/java/iflytop/app/controler/ws/AppStateWSEndpoint.java b/src/main/java/iflytop/app/controler/ws/EventWSChannel.java similarity index 57% rename from src/main/java/iflytop/app/controler/ws/AppStateWSEndpoint.java rename to src/main/java/iflytop/app/controler/ws/EventWSChannel.java index a5fbe99..67288ca 100644 --- a/src/main/java/iflytop/app/controler/ws/AppStateWSEndpoint.java +++ b/src/main/java/iflytop/app/controler/ws/EventWSChannel.java @@ -1,19 +1,39 @@ package iflytop.app.controler.ws; -import iflytop.app.service.base.WebSocketEndpointMgr; -import iflytop.app.utils.SpringBootBeanUtil; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -@ServerEndpoint(value = "/ws/state") +@ServerEndpoint(value = "/ws/event") @Slf4j @Component -public class AppStateWSEndpoint { - private Session session; +public class MeasurementTaskReportChannel { + + private Session session; + static List sessions = new ArrayList<>(); + + // + // ON MESSAGE + // + synchronized static public void report(String message) { + for (Session session : sessions) { + try { + session.getBasicRemote().sendText(message); + } catch (IOException ignored) { + + } + } + + } + + // + // CALLBACKS + // // 收到消息 @OnMessage @@ -24,17 +44,17 @@ public class AppStateWSEndpoint { // 连接打开 @OnOpen public void onOpen(Session session, EndpointConfig endpointConfig) { - // 保存 session 到对象 + log.info("[websocket] 新的连接:id={}", session.getId()); this.session = session; - SpringBootBeanUtil.getBean(WebSocketEndpointMgr.class).pushStateWebsocketSession(session); - log.info("{} [websocket] 新的连接:id={}", this,this.session.getId()); + addSession(session); } // 连接关闭 @OnClose public void onClose(CloseReason closeReason) { - SpringBootBeanUtil.getBean(WebSocketEndpointMgr.class).removeStateWebsocketSession(this.session); log.info("[websocket] 连接断开:id={},reason={}", this.session.getId(), closeReason); + removeSession(this.session); + this.session = null; } // 连接异常 @@ -44,4 +64,17 @@ public class AppStateWSEndpoint { // 关闭连接。状态码为 UNEXPECTED_CONDITION(意料之外的异常) this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage())); } + + // + // PRIVATE + // + + synchronized private static void addSession(Session session) { + sessions.add(session); + } + + synchronized private static void removeSession(Session session) { + sessions.remove(session); + } + } diff --git a/src/main/java/iflytop/app/controler/ws/AppEventWSEndpoint.java b/src/main/java/iflytop/app/controler/ws/StateWSChannel.java similarity index 60% rename from src/main/java/iflytop/app/controler/ws/AppEventWSEndpoint.java rename to src/main/java/iflytop/app/controler/ws/StateWSChannel.java index fc1a5ad..501ac3e 100644 --- a/src/main/java/iflytop/app/controler/ws/AppEventWSEndpoint.java +++ b/src/main/java/iflytop/app/controler/ws/StateWSChannel.java @@ -1,20 +1,39 @@ package iflytop.app.controler.ws; -import iflytop.app.service.base.WebSocketEndpointMgr; -import iflytop.app.utils.SpringBootBeanUtil; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; @ServerEndpoint(value = "/ws/event") @Slf4j @Component -public class AppEventWSEndpoint { +public class EventWSChannel { - private Session session; + private Session session; + static List sessions = new ArrayList<>(); + + // + // ON MESSAGE + // + synchronized static public void report(String message) { + for (Session session : sessions) { + try { + session.getBasicRemote().sendText(message); + } catch (IOException ignored) { + + } + } + + } + + // + // CALLBACKS + // // 收到消息 @OnMessage @@ -25,17 +44,17 @@ public class AppEventWSEndpoint { // 连接打开 @OnOpen public void onOpen(Session session, EndpointConfig endpointConfig) { - // 保存 session 到对象 + log.info("[websocket] 新的连接:id={}", session.getId()); this.session = session; - SpringBootBeanUtil.getBean(WebSocketEndpointMgr.class).pushEventWebsocketSession(session); - log.info("[websocket] 新的连接:id={}", this.session.getId()); + addSession(session); } // 连接关闭 @OnClose public void onClose(CloseReason closeReason) { - SpringBootBeanUtil.getBean(WebSocketEndpointMgr.class).removeEventWebsocketSession(this.session); log.info("[websocket] 连接断开:id={},reason={}", this.session.getId(), closeReason); + removeSession(this.session); + this.session = null; } // 连接异常 @@ -45,4 +64,17 @@ public class AppEventWSEndpoint { // 关闭连接。状态码为 UNEXPECTED_CONDITION(意料之外的异常) this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage())); } + + // + // PRIVATE + // + + synchronized private static void addSession(Session session) { + sessions.add(session); + } + + synchronized private static void removeSession(Session session) { + sessions.remove(session); + } + } diff --git a/src/main/java/iflytop/app/service/backgroud/SensorReportPreAnalysis.java b/src/main/java/iflytop/app/service/backgroud/SensorReportPreAnalysis.java new file mode 100644 index 0000000..d510c22 --- /dev/null +++ b/src/main/java/iflytop/app/service/backgroud/SensorReportPreAnalysis.java @@ -0,0 +1,2 @@ +package iflytop.app.service.backgroud;public class SensorReportPreAnalysis { +} diff --git a/src/main/java/iflytop/app/type/XYPoint.java b/src/main/java/iflytop/app/type/XYPoint.java new file mode 100644 index 0000000..6a2cfd7 --- /dev/null +++ b/src/main/java/iflytop/app/type/XYPoint.java @@ -0,0 +1,2 @@ +package iflytop.app.type;public class XYPoint { +} diff --git a/src/main/java/iflytop/app/type/event/MeasurementTaskReportPosEvent.java b/src/main/java/iflytop/app/type/event/MeasurementTaskReportPosEvent.java new file mode 100644 index 0000000..7ad4905 --- /dev/null +++ b/src/main/java/iflytop/app/type/event/MeasurementTaskReportPosEvent.java @@ -0,0 +1,11 @@ +package iflytop.app.type.event; + +public class MeasurementTaskDataReportEvent extends AppEvent { + public Double x; + public Double y; + + public MeasurementTaskDataReportEvent(Double x, Double y) { + this.x = x; + this.y = y; + } +} diff --git a/src/main/java/iflytop/app/type/protocol/TPMISensorValReport.java b/src/main/java/iflytop/app/type/protocol/TPMISensorValReport.java new file mode 100644 index 0000000..0eb3070 --- /dev/null +++ b/src/main/java/iflytop/app/type/protocol/TPMISensorValReport.java @@ -0,0 +1,33 @@ +package iflytop.app.type.protocol; + +public class TPMISensorStateReport extends TPMIPacket { + + public TPMISensorStateReport(TPMIPacket packet) { + super(packet.rawpacket); + } + + //value:ARM0角度 + public Integer getArm0Angle() { + return this.getDataAsInt(0); + } + + //value:ARM1角度 + public Integer getArm1Angle() { + return this.getDataAsInt(1); + } + + //value:绝对值编码单圈最大值 + public Integer getMaxArmAngle() { + return this.getDataAsInt(2); + } + + //陀螺仪X角度 + public Integer getGyroscopeX() { + return this.getDataAsInt(3); + } + + //陀螺仪Y角度 + public Integer getGyroscopeY() { + return this.getDataAsInt(4); + } +} diff --git a/src/main/java/iflytop/app/type/ui/MessageBox.java b/src/main/java/iflytop/app/type/ui/MessageBox.java deleted file mode 100644 index 8b3ca27..0000000 --- a/src/main/java/iflytop/app/type/ui/MessageBox.java +++ /dev/null @@ -1,16 +0,0 @@ -package iflytop.app.type.ui; - -import java.util.Date; - -public class MessageBox { - public Date time; - public MessageLevel messageLevel; - public String message; - - public MessageBox(MessageLevel messageLevel, String message) { - this.time = new Date(); - this.messageLevel = messageLevel; - this.message = message; - } - -} diff --git a/src/main/java/iflytop/app/type/ui/ZAppPromopt.java b/src/main/java/iflytop/app/type/ui/message/ZAppMessage.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/ZAppPromopt.java rename to src/main/java/iflytop/app/type/ui/message/ZAppMessage.java diff --git a/src/main/java/iflytop/app/type/ui/MessageLevel.java b/src/main/java/iflytop/app/type/ui/message/basic/MessageLevel.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/MessageLevel.java rename to src/main/java/iflytop/app/type/ui/message/basic/MessageLevel.java diff --git a/src/main/java/iflytop/app/type/ui/ZAppErrorStackInfo.java b/src/main/java/iflytop/app/type/ui/message/basic/ZAppErrorStackInfo.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/ZAppErrorStackInfo.java rename to src/main/java/iflytop/app/type/ui/message/basic/ZAppErrorStackInfo.java diff --git a/src/main/java/iflytop/app/type/ui/ZAppPromoptDetailInfoType.java b/src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptDetailInfoType.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/ZAppPromoptDetailInfoType.java rename to src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptDetailInfoType.java diff --git a/src/main/java/iflytop/app/type/ui/ZAppPromoptFormsItem.java b/src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptFormsItem.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/ZAppPromoptFormsItem.java rename to src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptFormsItem.java diff --git a/src/main/java/iflytop/app/type/ui/ZAppPromoptTable.java b/src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptTable.java similarity index 100% rename from src/main/java/iflytop/app/type/ui/ZAppPromoptTable.java rename to src/main/java/iflytop/app/type/ui/message/basic/ZAppPromoptTable.java diff --git a/src/main/java/iflytop/app/utils/CoordinateCalculator.java b/src/main/java/iflytop/app/utils/CoordinateCalculator.java new file mode 100644 index 0000000..2337294 --- /dev/null +++ b/src/main/java/iflytop/app/utils/CoordinateCalculator.java @@ -0,0 +1,2 @@ +package iflytop.app.utils;public class CoordinateCalculator { +} diff --git a/src/main/java/iflytop/zamis/type/options/Align.java b/src/main/java/iflytop/zamis/type/options/Align.java deleted file mode 100644 index 9492b52..0000000 --- a/src/main/java/iflytop/zamis/type/options/Align.java +++ /dev/null @@ -1,5 +0,0 @@ -package iflytop.zamis.type.options; - -public enum Align { - left, right -} diff --git a/src/main/java/iflytop/zamis/type/options/Size.java b/src/main/java/iflytop/zamis/type/options/Size.java deleted file mode 100644 index b906ca8..0000000 --- a/src/main/java/iflytop/zamis/type/options/Size.java +++ /dev/null @@ -1,5 +0,0 @@ -package iflytop.zamis.type.options; - -public enum Size { - xs,sm,md,lg -} diff --git a/src/main/java/iflytop/engineer/controler/EngineerRootPageControler.java b/src/main/java/iflytoplib/amiseui/controler/EngineerRootPageControler.java similarity index 100% rename from src/main/java/iflytop/engineer/controler/EngineerRootPageControler.java rename to src/main/java/iflytoplib/amiseui/controler/EngineerRootPageControler.java diff --git a/src/main/java/iflytop/engineer/service/RootMgrService.java b/src/main/java/iflytoplib/amiseui/service/RootMgrService.java similarity index 88% rename from src/main/java/iflytop/engineer/service/RootMgrService.java rename to src/main/java/iflytoplib/amiseui/service/RootMgrService.java index e765068..5df588c 100644 --- a/src/main/java/iflytop/engineer/service/RootMgrService.java +++ b/src/main/java/iflytoplib/amiseui/service/RootMgrService.java @@ -1,8 +1,8 @@ package iflytop.engineer.service; import iflytop.engineer.type.EngineerPage; -import iflytop.zamis.type.features.Nav; -import iflytop.zamis.type.layout.Page; +import iflytop.engineer.type.features.Nav; +import iflytop.engineer.type.layout.Page; import org.springframework.stereotype.Component; import java.util.ArrayList; diff --git a/src/main/java/iflytop/engineer/type/EngineerPage.java b/src/main/java/iflytoplib/amiseui/type/EngineerPage.java similarity index 100% rename from src/main/java/iflytop/engineer/type/EngineerPage.java rename to src/main/java/iflytoplib/amiseui/type/EngineerPage.java diff --git a/src/main/java/iflytop/zamis/type/display/Icon.java b/src/main/java/iflytoplib/amiseui/type/display/Icon.java similarity index 93% rename from src/main/java/iflytop/zamis/type/display/Icon.java rename to src/main/java/iflytoplib/amiseui/type/display/Icon.java index a1d6700..4737ca8 100644 --- a/src/main/java/iflytop/zamis/type/display/Icon.java +++ b/src/main/java/iflytoplib/amiseui/type/display/Icon.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.display; +package iflytop.engineer.type.display; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/display/Remark.java b/src/main/java/iflytoplib/amiseui/type/display/Remark.java similarity index 77% rename from src/main/java/iflytop/zamis/type/display/Remark.java rename to src/main/java/iflytoplib/amiseui/type/display/Remark.java index e717af0..cff24ba 100644 --- a/src/main/java/iflytop/zamis/type/display/Remark.java +++ b/src/main/java/iflytoplib/amiseui/type/display/Remark.java @@ -1,9 +1,9 @@ -package iflytop.zamis.type.display; +package iflytop.engineer.type.display; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.options.Position; -import iflytop.zamis.type.options.Shape; -import iflytop.zamis.type.options.Trigger; +import iflytop.engineer.type.options.Position; +import iflytop.engineer.type.options.Shape; +import iflytop.engineer.type.options.Trigger; @JsonInclude(JsonInclude.Include.NON_NULL) public class Remark { diff --git a/src/main/java/iflytop/zamis/type/features/ActionButton.java b/src/main/java/iflytoplib/amiseui/type/features/ActionButton.java similarity index 98% rename from src/main/java/iflytop/zamis/type/features/ActionButton.java rename to src/main/java/iflytoplib/amiseui/type/features/ActionButton.java index 2f7d395..7251f6e 100644 --- a/src/main/java/iflytop/zamis/type/features/ActionButton.java +++ b/src/main/java/iflytoplib/amiseui/type/features/ActionButton.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.features; +package iflytop.engineer.type.features; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/features/DropDownButton.java b/src/main/java/iflytoplib/amiseui/type/features/DropDownButton.java similarity index 93% rename from src/main/java/iflytop/zamis/type/features/DropDownButton.java rename to src/main/java/iflytoplib/amiseui/type/features/DropDownButton.java index 81abfb7..ba88010 100644 --- a/src/main/java/iflytop/zamis/type/features/DropDownButton.java +++ b/src/main/java/iflytoplib/amiseui/type/features/DropDownButton.java @@ -1,7 +1,7 @@ -package iflytop.zamis.type.features; +package iflytop.engineer.type.features; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.options.Trigger; +import iflytop.engineer.type.options.Trigger; import java.util.List; diff --git a/src/main/java/iflytop/zamis/type/features/Nav.java b/src/main/java/iflytoplib/amiseui/type/features/Nav.java similarity index 98% rename from src/main/java/iflytop/zamis/type/features/Nav.java rename to src/main/java/iflytoplib/amiseui/type/features/Nav.java index 6c6248d..bb10734 100644 --- a/src/main/java/iflytop/zamis/type/features/Nav.java +++ b/src/main/java/iflytoplib/amiseui/type/features/Nav.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.features; +package iflytop.engineer.type.features; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/features/ServiceContainer.java b/src/main/java/iflytoplib/amiseui/type/features/ServiceContainer.java similarity index 97% rename from src/main/java/iflytop/zamis/type/features/ServiceContainer.java rename to src/main/java/iflytoplib/amiseui/type/features/ServiceContainer.java index c763f27..72edaa1 100644 --- a/src/main/java/iflytop/zamis/type/features/ServiceContainer.java +++ b/src/main/java/iflytoplib/amiseui/type/features/ServiceContainer.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.features; +package iflytop.engineer.type.features; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/form/Form.java b/src/main/java/iflytoplib/amiseui/type/form/Form.java similarity index 97% rename from src/main/java/iflytop/zamis/type/form/Form.java rename to src/main/java/iflytoplib/amiseui/type/form/Form.java index 1555509..3897aeb 100644 --- a/src/main/java/iflytop/zamis/type/form/Form.java +++ b/src/main/java/iflytoplib/amiseui/type/form/Form.java @@ -1,8 +1,8 @@ -package iflytop.zamis.type.form; +package iflytop.engineer.type.form; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.features.ServiceContainer; -import iflytop.zamis.type.options.Align; +import iflytop.engineer.type.features.ServiceContainer; +import iflytop.engineer.type.options.Align; @JsonInclude(JsonInclude.Include.NON_NULL) public class Form { diff --git a/src/main/java/iflytop/zamis/type/form/FormItem.java b/src/main/java/iflytoplib/amiseui/type/form/FormItem.java similarity index 97% rename from src/main/java/iflytop/zamis/type/form/FormItem.java rename to src/main/java/iflytoplib/amiseui/type/form/FormItem.java index 349613b..c363b47 100644 --- a/src/main/java/iflytop/zamis/type/form/FormItem.java +++ b/src/main/java/iflytoplib/amiseui/type/form/FormItem.java @@ -1,7 +1,7 @@ -package iflytop.zamis.type.form; +package iflytop.engineer.type.form; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.options.Align; +import iflytop.engineer.type.options.Align; import java.util.List; diff --git a/src/main/java/iflytop/zamis/type/form/InputNumber.java b/src/main/java/iflytoplib/amiseui/type/form/InputNumber.java similarity index 84% rename from src/main/java/iflytop/zamis/type/form/InputNumber.java rename to src/main/java/iflytoplib/amiseui/type/form/InputNumber.java index acf594e..1a41438 100644 --- a/src/main/java/iflytop/zamis/type/form/InputNumber.java +++ b/src/main/java/iflytoplib/amiseui/type/form/InputNumber.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.form; +package iflytop.engineer.type.form; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/form/InputText.java b/src/main/java/iflytoplib/amiseui/type/form/InputText.java similarity index 84% rename from src/main/java/iflytop/zamis/type/form/InputText.java rename to src/main/java/iflytoplib/amiseui/type/form/InputText.java index fe75e58..0f5543c 100644 --- a/src/main/java/iflytop/zamis/type/form/InputText.java +++ b/src/main/java/iflytoplib/amiseui/type/form/InputText.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.form; +package iflytop.engineer.type.form; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/form/Select.java b/src/main/java/iflytoplib/amiseui/type/form/Select.java similarity index 89% rename from src/main/java/iflytop/zamis/type/form/Select.java rename to src/main/java/iflytoplib/amiseui/type/form/Select.java index 8594339..e97d98b 100644 --- a/src/main/java/iflytop/zamis/type/form/Select.java +++ b/src/main/java/iflytoplib/amiseui/type/form/Select.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.form; +package iflytop.engineer.type.form; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/layout/Flex.java b/src/main/java/iflytoplib/amiseui/type/layout/Flex.java similarity index 95% rename from src/main/java/iflytop/zamis/type/layout/Flex.java rename to src/main/java/iflytoplib/amiseui/type/layout/Flex.java index ebd0255..7f8c305 100644 --- a/src/main/java/iflytop/zamis/type/layout/Flex.java +++ b/src/main/java/iflytoplib/amiseui/type/layout/Flex.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.layout; +package iflytop.engineer.type.layout; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/iflytop/zamis/type/layout/Page.java b/src/main/java/iflytoplib/amiseui/type/layout/Page.java similarity index 94% rename from src/main/java/iflytop/zamis/type/layout/Page.java rename to src/main/java/iflytoplib/amiseui/type/layout/Page.java index 7ba0248..e6bfe33 100644 --- a/src/main/java/iflytop/zamis/type/layout/Page.java +++ b/src/main/java/iflytoplib/amiseui/type/layout/Page.java @@ -1,8 +1,8 @@ -package iflytop.zamis.type.layout; +package iflytop.engineer.type.layout; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.display.Remark; -import iflytop.zamis.type.options.Position; +import iflytop.engineer.type.display.Remark; +import iflytop.engineer.type.options.Position; @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/src/main/java/iflytop/zamis/type/layout/Tabs.java b/src/main/java/iflytoplib/amiseui/type/layout/Tabs.java similarity index 96% rename from src/main/java/iflytop/zamis/type/layout/Tabs.java rename to src/main/java/iflytoplib/amiseui/type/layout/Tabs.java index 65711d6..22969af 100644 --- a/src/main/java/iflytop/zamis/type/layout/Tabs.java +++ b/src/main/java/iflytoplib/amiseui/type/layout/Tabs.java @@ -1,8 +1,8 @@ -package iflytop.zamis.type.layout; +package iflytop.engineer.type.layout; import com.fasterxml.jackson.annotation.JsonInclude; -import iflytop.zamis.type.display.Icon; -import iflytop.zamis.type.options.Position; +import iflytop.engineer.type.display.Icon; +import iflytop.engineer.type.options.Position; import java.util.List; diff --git a/src/main/java/iflytoplib/amiseui/type/options/Align.java b/src/main/java/iflytoplib/amiseui/type/options/Align.java new file mode 100644 index 0000000..bd46696 --- /dev/null +++ b/src/main/java/iflytoplib/amiseui/type/options/Align.java @@ -0,0 +1,5 @@ +package iflytop.engineer.type.options; + +public enum Align { + left, right +} diff --git a/src/main/java/iflytop/zamis/type/options/Position.java b/src/main/java/iflytoplib/amiseui/type/options/Position.java similarity index 57% rename from src/main/java/iflytop/zamis/type/options/Position.java rename to src/main/java/iflytoplib/amiseui/type/options/Position.java index 849a85b..61d5aff 100644 --- a/src/main/java/iflytop/zamis/type/options/Position.java +++ b/src/main/java/iflytoplib/amiseui/type/options/Position.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.options; +package iflytop.engineer.type.options; public enum Position { left, right, top, bottom diff --git a/src/main/java/iflytop/zamis/type/options/Shape.java b/src/main/java/iflytoplib/amiseui/type/options/Shape.java similarity index 50% rename from src/main/java/iflytop/zamis/type/options/Shape.java rename to src/main/java/iflytoplib/amiseui/type/options/Shape.java index 61f7f66..4b4d359 100644 --- a/src/main/java/iflytop/zamis/type/options/Shape.java +++ b/src/main/java/iflytoplib/amiseui/type/options/Shape.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.options; +package iflytop.engineer.type.options; public enum Shape { circle, square diff --git a/src/main/java/iflytoplib/amiseui/type/options/Size.java b/src/main/java/iflytoplib/amiseui/type/options/Size.java new file mode 100644 index 0000000..3b83062 --- /dev/null +++ b/src/main/java/iflytoplib/amiseui/type/options/Size.java @@ -0,0 +1,5 @@ +package iflytop.engineer.type.options; + +public enum Size { + xs,sm,md,lg +} diff --git a/src/main/java/iflytop/zamis/type/options/Trigger.java b/src/main/java/iflytoplib/amiseui/type/options/Trigger.java similarity index 50% rename from src/main/java/iflytop/zamis/type/options/Trigger.java rename to src/main/java/iflytoplib/amiseui/type/options/Trigger.java index 5a44442..ac301cf 100644 --- a/src/main/java/iflytop/zamis/type/options/Trigger.java +++ b/src/main/java/iflytoplib/amiseui/type/options/Trigger.java @@ -1,4 +1,4 @@ -package iflytop.zamis.type.options; +package iflytop.engineer.type.options; public enum Trigger { hover, focus diff --git a/src/main/java/iflytoplib/zextui/controler/ExtApiControler.java b/src/main/java/iflytoplib/zextui/controler/ExtApiControler.java new file mode 100644 index 0000000..4e64c14 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/controler/ExtApiControler.java @@ -0,0 +1,305 @@ +package zengineer.controler; + + +import iflytop.app.utils.SpringBootBeanUtil; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.util.Assert; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import zengineer.mgr.ExtApiPageGroupCfgMgr; +import zengineer.mgr.ExtApiPageMgr; +import zengineer.type.ExUIFunction; +import zengineer.type.ExUIParam; +import zengineer.type.ExtApiStatu; +import zengineer.type.ExtUIPageCfg; +import zengineer.type.param.ExtUIFile; +import zengineer.type.ret.AppRetV1; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Controller +public class ExtApiControler { + + @Resource + ExtApiPageGroupCfgMgr extApiPageGroupCfgMgr; + @Resource + ExtApiPageMgr extApiPageMgr; + + /** + * 获取服务列表 + * @return 服务列表 + */ + @PostMapping("/api/service-config/service-list") + @ResponseBody + public AppRetV1 services() { +// List> services = new ArrayList<>(); +// var classes = SpringBootBeanUtil.getBeans(); +// for (var clazz : classes) { +// var cfg = extApiPageGroupCfgMgr.getCfg(clazz); +// if (cfg == null) { +// continue; +// } +// if (!cfg.display) { +// continue; +// } +// Map service = new HashMap<>(); +// service.put("key", clazz.getSimpleName()); +// service.put("name", cfg.getChName()); +// service.put("order", cfg.getIndex()); +// services.add(service); +// } + // log.info("services:{}", services); + return AppRetV1.success(extApiPageGroupCfgMgr.getMenuList()); + } + + + @PostMapping("/api/service-config/service-params-list") + @ResponseBody + public AppRetV1 serviceParams(@RequestBody Map params) { + List> list = new ArrayList<>(); + return AppRetV1.success(list); + + } + + @PostMapping("/api/service-config/service-params-update") + @ResponseBody + public AppRetV1 serviceParamsUpdate(@RequestBody Map params) { + return AppRetV1.success(); + } + + @PostMapping("/api/service-config/service-params-reset") + @ResponseBody + public AppRetV1 serviceParamsReset(@RequestBody Map params) { + return AppRetV1.success(); + } + + + @PostMapping("/api/service-config/service-status-list") + @ResponseBody + public AppRetV1 serviceStatus(@RequestBody Map params) throws InvocationTargetException, IllegalAccessException { + String serviceKey = (String) params.get("serviceKey"); + Class serviceClass = null; + var classes = SpringBootBeanUtil.getBeans(); + for (var clazz : classes) { + if (!clazz.getSimpleName().equals(serviceKey)) { + continue; + } + serviceClass = clazz; + break; + } + + List> statusList = new ArrayList<>(); + if (null == serviceClass) { + return AppRetV1.success(statusList); + } + + var service = SpringBootBeanUtil.getBean(serviceClass); + var methods = serviceClass.getMethods(); + for (var method : methods) { + var statusAnnotation = method.getAnnotation(ExtApiStatu.class); + if (null == statusAnnotation) { + continue; + } + + var status = new HashMap(); + status.put("name", statusAnnotation.name()); + status.put("group", statusAnnotation.group()); + status.put("order", statusAnnotation.order()); + status.put("minWidth", statusAnnotation.minWidth()); + var value = method.invoke(service); + status.put("value", value); + statusList.add(status); + } + return AppRetV1.success(statusList); + } + + + Map buildActionParam(ExUIFunction func, ExUIParam param) { + var actionParam = new HashMap(); + actionParam.put("key", param.keyName); + actionParam.put("type", param.type.getName()); + actionParam.put("name", param.disname); + actionParam.put("value", null); + + if (param.getInitValFn1 != null) { + actionParam.put("value", param.getInitValFn1.getInitVal()); + } else if (param.getInitValFn2 != null) { + actionParam.put("value", param.getInitValFn2.getInitVal(func.keyName, param.keyName)); + } else if (param.initValue != null) { + actionParam.put("value", param.initValue); + } + + if (param.type.isEnum()) { + actionParam.put("type", "java.lang.Enum"); + actionParam.put("typeEnum", param.type.getName()); + var paramOptions = new ArrayList>(); + for (var value : param.type.getEnumConstants()) { + var paramOption = new HashMap(); + paramOption.put("name", value.toString()); + paramOption.put("value", value.toString()); + paramOptions.add(paramOption); + } + actionParam.put("options", paramOptions); + } + return actionParam; + } + + // + @PostMapping("/api/service-config/service-action-list") + @ResponseBody + public AppRetV1 serviceActionList(@RequestBody Map params) throws Exception { + String serviceKey = (String) params.get("serviceKey"); + Object service = SpringBootBeanUtil.getBeanBySimpleName(serviceKey); + Class serviceClass = service != null ? service.getClass() : null; + ExtUIPageCfg exUIpageCfg = extApiPageMgr.getPage(serviceKey); + + if (serviceClass == null) { + log.warn("serviceActionList: service not found:{}", serviceKey); + return AppRetV1.success(new ArrayList<>()); + } + + if (exUIpageCfg == null) { + log.warn("serviceActionList: page not found:{}", serviceKey); + return AppRetV1.success(new ArrayList<>()); + } + + + //获取OBject + List> actions = new ArrayList<>(); + int i = 0; + for (var method : exUIpageCfg.functions) { + + var action = new HashMap(); + + //Action + action.put("key", method.keyName); + action.put("name", method.disName); + action.put("group", method.group); + action.put("groupOrder", i); + action.put("order", i); + action.put("newline", false); + + //Action Params + var actionParams = new ArrayList>(); + method.params.forEach(param -> { + actionParams.add(buildActionParam(method, param)); + }); + action.put("params", actionParams); + actions.add(action); + i++; + } + return AppRetV1.success(actions); + } + + @PostMapping("/api/service-config/service-action-exec") + @ResponseBody + public AppRetV1 serviceActionExecute(@RequestBody Map params) throws Throwable { + String serviceKey = (String) params.get("serviceKey"); + var service = this.getServiceInstanceByServiceKey(serviceKey); + Assert.isTrue(service != null, "service not found"); + + var actionName = (String) params.get("action"); + var actionParams = (List) params.get("params"); + var actionParamTypes = (List) params.get("paramTypes"); + + + Class[] parameterTypes = new Class[actionParams.size()]; + for (int i = 0; i < actionParams.size(); ++i) { + var name = actionParamTypes.get(i); + parameterTypes[i] = Class.forName(name); + } + Method method = service.getClass().getMethod(actionName, parameterTypes); + + var parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + var parameter = parameters[i]; + if (parameter.getType().isEnum()) { + var methodValueOf = parameter.getType().getMethod("valueOf", String.class); + var value = methodValueOf.invoke(null, actionParams.get(i)); + actionParams.set(i, value); + } else if (parameter.getType().equals(ExtUIFile.class)) { + String value = (String) actionParams.get(i); + actionParams.set(i, ExtUIFile.fromBase64(value)); + } else if (parameter.getType().equals(Double.class)) { + Object value = actionParams.get(i); + actionParams.set(i, Double.valueOf(String.format("%s", value))); + } + } + + return this.executeServiceActionAndGetResponse(service, method, actionParams); + } + + + @PostMapping("/api/service-config/class-struct-info-get") + @ResponseBody + public AppRetV1 classStructInfoGet(@RequestBody Map params) throws Exception { + String className = (String) params.get("class"); + Class clazz = Class.forName(className); + List> struct = new ArrayList<>(); + this.classStructInfoFill(clazz, struct); + return AppRetV1.success(struct); + } + + // execute service action and get response + private AppRetV1 executeServiceActionAndGetResponse(Object service, Method method, List actionParams) throws Throwable { + Object actionResult = null; + try { + var actionParamList = actionParams.toArray(); + if (method.getReturnType().equals(Void.TYPE)) { + method.invoke(service, actionParamList); + } else { + actionResult = method.invoke(service, actionParamList); + } + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + + if (actionResult instanceof AppRetV1) { + return (AppRetV1) actionResult; + } + return AppRetV1.success(actionResult); + } + + // get service instance by service key + private Object getServiceInstanceByServiceKey(String serviceKey) { + Class serviceClass = null; + var classes = SpringBootBeanUtil.getBeans(); + for (var clazz : classes) { + if (!clazz.getSimpleName().equals(serviceKey)) { + continue; + } + serviceClass = clazz; + break; + } + if (null == serviceClass) { + return null; + } + return SpringBootBeanUtil.getBean(serviceClass); + } + + + // fill up struct info + private void classStructInfoFill(Class clazz, List> struct) { + var fields = clazz.getFields(); + for (var item : fields) { + if (Modifier.isStatic(item.getModifiers()) || Modifier.isFinal(item.getModifiers())) { + continue; + } + var filed = new HashMap(); + filed.put("name", item.getName()); + filed.put("type", item.getType().getSimpleName()); + filed.put("typeShort", item.getType().getSimpleName()); + struct.add(filed); + } + } +} diff --git a/src/main/java/iflytoplib/zextui/controler/ExtApiControllerAdvice.java b/src/main/java/iflytoplib/zextui/controler/ExtApiControllerAdvice.java new file mode 100644 index 0000000..061b87d --- /dev/null +++ b/src/main/java/iflytoplib/zextui/controler/ExtApiControllerAdvice.java @@ -0,0 +1,21 @@ +package zengineer.controler; + +import a8k.extui.type.ret.AppRetV1; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@ControllerAdvice(value = "a8k.extui.controler") +public class ExtApiControllerAdvice { + + Logger logger = LoggerFactory.getLogger(ExtApiControllerAdvice.class); + + @ResponseBody + @ExceptionHandler(value = Exception.class) + public AppRetV1 controllerExceptionHandler(Exception e) { + logger.info("捕获到异常 : ", e); + return AppRetV1.fail(e); + } +} diff --git a/src/main/java/iflytoplib/zextui/mgr/ExtApiPageGroupCfgMgr.java b/src/main/java/iflytoplib/zextui/mgr/ExtApiPageGroupCfgMgr.java new file mode 100644 index 0000000..fe8a96a --- /dev/null +++ b/src/main/java/iflytoplib/zextui/mgr/ExtApiPageGroupCfgMgr.java @@ -0,0 +1,69 @@ +package zengineer.mgr; + +import jakarta.annotation.PostConstruct; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class ExtApiPageGroupCfgMgr { + + public static class Menu { + public String key; + public String label; + public List children = null; + + + public Menu(Class key, String label) { + this.key = key.getSimpleName(); + this.label = label; + } + + public Menu(String label, List menus) { + this.key = label; + this.label = label; + this.children = menus; + } + + + public Menu pushSubMenu(Class key, String label) { + if (children == null) + children = new ArrayList<>(); + children.add(new Menu(key, label)); + return this; + } + + + public Menu pushSubMenuGroup(String label, List menus) { + if (children == null) + children = new ArrayList<>(); + children.add(new Menu(label, menus)); + return this; + } + + } + + synchronized public List getMenuList() { + return menuList; + } + + List menuList = new ArrayList<>(); + + + void pushMenu(Menu label) { + menuList.add(label); + } + + + @PostConstruct + void init() { + + + + + //////////////////////////////////////////////////////////////////////////////////////////// + + } + +} diff --git a/src/main/java/iflytoplib/zextui/mgr/ExtApiPageMgr.java b/src/main/java/iflytoplib/zextui/mgr/ExtApiPageMgr.java new file mode 100644 index 0000000..813c2bb --- /dev/null +++ b/src/main/java/iflytoplib/zextui/mgr/ExtApiPageMgr.java @@ -0,0 +1,31 @@ +package zengineer.mgr; + +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; +import zengineer.type.ExtUIPageCfg; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +@Component +public class ExtApiPageMgr { + List pages = new ArrayList<>(); + + public void addPage(ExtUIPageCfg page) { + pages.add(page); + } + + public ExtUIPageCfg newPage(Object object) { + return new ExtUIPageCfg(object); + } + + public ExtUIPageCfg getPage(String name) { + for (ExtUIPageCfg page : pages) { + if (page.name.equals(name)) { + return page; + } + } + return null; + } +} diff --git a/src/main/java/iflytoplib/zextui/type/ExApiPage.java b/src/main/java/iflytoplib/zextui/type/ExApiPage.java new file mode 100644 index 0000000..9259dcf --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExApiPage.java @@ -0,0 +1,5 @@ +package zengineer.type; + +public class ExApiPage { + String chName; +} diff --git a/src/main/java/iflytoplib/zextui/type/ExUIFunction.java b/src/main/java/iflytoplib/zextui/type/ExUIFunction.java new file mode 100644 index 0000000..ec05353 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExUIFunction.java @@ -0,0 +1,110 @@ +package zengineer.type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.springframework.util.Assert; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.List; + +public class ExUIFunction { + + + public String keyName; + public String disName; + public String group; + @JsonIgnore + public Method method; + public List params = new ArrayList<>(); + + public Object getDefauleInitVal(Class type) { + if (type.equals(Boolean.class)) { + return false; + } else if (type.equals(Integer.class)) { + return 0; + } else if (type.equals(String.class)) { + return ""; + } + if (type.isEnum()) { + return type.getEnumConstants()[0]; + } + return null; + } + + public ExUIFunction setGroup(String group) { + this.group = group; + return this; + } + + public ExUIParam newParameter(String paraName, Object defaultVal) { + Assert.notNull(method, "method is null"); + Assert.isTrue(params.size() < method.getParameterCount(), "params size is greater than method parameter count"); + + Parameter parameter = method.getParameters()[params.size()]; + ExUIParam param = new ExUIParam(); + param.keyName = parameter.getName(); + param.disname = paraName; + param.type = parameter.getType(); + param.initValue = defaultVal; + return param; + } + + + public void addParam(String paraName) { + params.add(newParameter(paraName, getDefauleInitVal(method.getParameters()[params.size()].getType()))); + } + + ExUIParam getParam(String paraName) { + for (ExUIParam param : params) { + if (param.keyName.equals(paraName)) { + return param; + } + } + return null; + } + + + public ExUIFunction setParamVal(String paraName, Object defaultVal) { + ExUIParam param = getParam(paraName); + Assert.notNull(param, String.format("Can't find param %s in function %s", paraName, keyName)); + param.initValue = defaultVal; + return this; + } + + public ExUIFunction setParamVal(String paraName, ExUIParamGetInitValFnType1 getInitValFn) { + ExUIParam param = getParam(paraName); + Assert.notNull(param, String.format("Can't find param %s in function %s", paraName, keyName)); + param.getInitValFn1 = getInitValFn; + return this; + } + + public ExUIFunction setParamVal(String paraName, ExUIParamGetInitValFnType2 getInitValFn) { + ExUIParam param = getParam(paraName); + Assert.notNull(param, String.format("Can't find param %s in function %s", paraName, keyName)); + param.getInitValFn2 = getInitValFn; + return this; + } + + // public ExUIFunction addParam(String paraName, Object defaultVal) { + // params.add(newParameter(paraName, defaultVal)); + // return this; + // } + // + + // + // + // public ExUIFunction addParam(String paraName, ExUIParamGetInitValFnType1 getInitValFn) { + // ExUIParam param = newParameter(paraName, null); + // param.getInitValFn1 = getInitValFn; + // params.add(param); + // return this; + // } + // + // public ExUIFunction addParam(String paraName, ExUIParamGetInitValFnType2 getInitValFn) { + // ExUIParam param = newParameter(paraName, null); + // param.getInitValFn2 = getInitValFn; + // params.add(param); + // return this; + // } +} diff --git a/src/main/java/iflytoplib/zextui/type/ExUIParam.java b/src/main/java/iflytoplib/zextui/type/ExUIParam.java new file mode 100644 index 0000000..1d0fbc6 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExUIParam.java @@ -0,0 +1,11 @@ +package zengineer.type; + +public class ExUIParam { + public String keyName; + public String disname; + public Class type; + + public Object initValue = null; + public ExUIParamGetInitValFnType1 getInitValFn1 = null; + public ExUIParamGetInitValFnType2 getInitValFn2 = null; +} diff --git a/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType1.java b/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType1.java new file mode 100644 index 0000000..73d9259 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType1.java @@ -0,0 +1,6 @@ +package zengineer.type; + +@FunctionalInterface +public interface ExUIParamGetInitValFnType1 { + public Object getInitVal(); +} diff --git a/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType2.java b/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType2.java new file mode 100644 index 0000000..db62905 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExUIParamGetInitValFnType2.java @@ -0,0 +1,6 @@ +package zengineer.type; + +@FunctionalInterface +public interface ExUIParamGetInitValFnType2 { + public Object getInitVal(String funcNameKey, String paramKey); +} diff --git a/src/main/java/iflytoplib/zextui/type/ExtApiFn.java b/src/main/java/iflytoplib/zextui/type/ExtApiFn.java new file mode 100644 index 0000000..ebede79 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExtApiFn.java @@ -0,0 +1,16 @@ +package zengineer.type; +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.METHOD}) +public @interface ExtApiFn { + String name() default ""; + String group() default ""; + int groupOrder() default 0; + int order() default 0; + boolean newline() default false; + String beforeExecute() default ""; +} diff --git a/src/main/java/iflytoplib/zextui/type/ExtApiStatu.java b/src/main/java/iflytoplib/zextui/type/ExtApiStatu.java new file mode 100644 index 0000000..248da92 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExtApiStatu.java @@ -0,0 +1,14 @@ +package zengineer.type; +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.METHOD}) +public @interface ExtApiStatu { + String name() default ""; + String group() default ""; + String minWidth() default "20%"; + int order() default 0; +} diff --git a/src/main/java/iflytoplib/zextui/type/ExtUIPageCfg.java b/src/main/java/iflytoplib/zextui/type/ExtUIPageCfg.java new file mode 100644 index 0000000..14e018c --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExtUIPageCfg.java @@ -0,0 +1,204 @@ +package zengineer.type; + +import a8k.extui.utils.FieldUtils; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.springframework.util.Assert; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.List; + +public class ExtUIPageCfg { + + public String name; + @JsonIgnore + public Object object; + public List functions = new java.util.ArrayList<>(); + public String groupContext = ""; + + + Method findSimilarMethod(Object obj, String name) { + Class classz = obj.getClass(); + Method[] methods = classz.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(name)) { + return method; + } + } + return null; + } + + + void completeParameter(ExUIFunction function) { + Class clazz = object.getClass(); + Method method = findSimilarMethod(object, function.keyName); + if (function.params.isEmpty()) { + for (var parameter : method.getParameters()) { + function.addParam(parameter.getName()); + } + } + Assert.isTrue(function.params.size() == method.getParameterCount(), "params size is not equal to method parameter count"); + } + + + Method findSimilarMethod(String name) { + Class classz = object.getClass(); + Method[] methods = classz.getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(name)) { + return method; + } + } + return null; + } + + public ExtUIPageCfg(Object object) { + this.object = object; + this.name = object.getClass().getSimpleName(); + } + + public ExUIFunction getFunction(String name) { + for (ExUIFunction func : functions) { + if (func.keyName.equals(name)) { + return func; + } + } + return null; + } + + private ExUIFunction addFunction(String groupName, String keyName, String disName) { + ExUIFunction func = new ExUIFunction(); + Method method = findSimilarMethod(keyName); + Assert.notNull(method, "method not found"); + if (disName == null) { + disName = keyName; + } + func.keyName = keyName; + func.group = groupName; + func.disName = disName; + func.method = method; + functions.add(func); + for (ExUIFunction function : functions) { + completeParameter(function); + } + return func; + } + + public void newGroup(String groupName) { + groupContext = groupName; + } + + // + // UTILS_IMPL + // + + @FunctionalInterface + public interface ExUIFnR1P0 extends Serializable { + public R fn() throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR1P1 extends Serializable { + public R fn(T0 p0) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR1P2 extends Serializable { + public R fn(T0 p0, T1 p1) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR1P3 extends Serializable { + public R fn(T0 p0, T1 p1, T2 p2) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR1P4 extends Serializable { + public R fn(T0 p0, T1 p1, T2 p2, T3 p3) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR1P5 extends Serializable { + public R fn(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P0 extends Serializable { + public void fn() throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P1 extends Serializable { + public void fn(T0 p0) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P2 extends Serializable { + public void fn(T0 p0, T1 p1) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P3 extends Serializable { + public void fn(T0 p0, T1 p1, T2 p2) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P4 extends Serializable { + public void fn(T0 p0, T1 p1, T2 p2, T3 p3) throws Exception; + } + + @FunctionalInterface + public interface ExUIFnR0P5 extends Serializable { + public void fn(T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) throws Exception; + } + + + public ExUIFunction addFunction(String displayName, ExUIFnR0P0 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR0P1 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR0P2 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR0P3 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR0P4 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR0P5 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P0 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P1 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P2 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P3 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P4 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + + public ExUIFunction addFunction(String displayName, ExUIFnR1P5 fn) { + return addFunction(groupContext, FieldUtils.getImplMethodName(fn), displayName); + } + +} \ No newline at end of file diff --git a/src/main/java/iflytoplib/zextui/type/ExtUITab.java b/src/main/java/iflytoplib/zextui/type/ExtUITab.java new file mode 100644 index 0000000..c5acc94 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExtUITab.java @@ -0,0 +1,11 @@ +package zengineer.type; + +import java.util.ArrayList; +import java.util.List; + +public class ExtUITab { + public String tabName; + public List tabCfgList = new ArrayList<>(); + + +} diff --git a/src/main/java/iflytoplib/zextui/type/ExtUiTable.java b/src/main/java/iflytoplib/zextui/type/ExtUiTable.java new file mode 100644 index 0000000..0af8729 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ExtUiTable.java @@ -0,0 +1,110 @@ +package zengineer.type; + + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.text.SimpleDateFormat; +import java.util.*; + +public class ExtUiTable { + + static public class Filter { + public String text; + public String value; + + public Filter(String text, String value) { + this.text = text; + this.value = value; + } + + } + + static public class TableColumn { + public String title; + public String dataIndex; + @JsonIgnore + public List filters; + public Boolean fixed = false; + public Boolean ellipsis = true; + // public Boolean resizable = true; + public Integer width = 120; + // public String onFilter = "$fn:(value, record) => record.name.indexOf(value) === 0"; + + public TableColumn(String title, String dataIndex) { + this.title = title; + this.dataIndex = dataIndex; + } + + public TableColumn(String title, String dataIndex, List filters) { + this.title = title; + this.dataIndex = dataIndex; + this.filters = filters; + } + } + + public List columns; + public List datas = new ArrayList<>(); + + private void priSetFilter(String dataIndex, List filters) { + for (TableColumn column : columns) { + if (column.dataIndex.equals(dataIndex)) { + column.filters = filters; + } + } + } + + public void setFilter(String dataIndex, List vals) { + List filters = new ArrayList<>(); + for (String val : vals) { + filters.add(new Filter(val, val)); + } + priSetFilter(dataIndex, filters); + } + + + public ExtUiTable(Class classType, List datas) { + this.columns = new ArrayList<>(); + + Map title = new HashMap<>(Map.of()); + Map emptyData = new HashMap<>(Map.of()); + for (Field field : classType.getDeclaredFields()) { + if (field.getType().isEnum() || field.getType().isPrimitive() + || field.getType().equals(String.class) + || field.getType().equals(Integer.class) + || field.getType().equals(Long.class) + || field.getType().equals(Double.class) + || field.getType().equals(Float.class) + || field.getType().equals(Boolean.class) + || field.getType().equals(Character.class) + || field.getType().equals(Byte.class) + || field.getType().equals(Date.class) + || field.getType().equals(Short.class)) { + this.columns.add(new TableColumn(field.getName(), field.getName())); + if (this.columns.size() == 1) { + this.columns.get(0).fixed = true; + } + title.put(field.getName(), field.getName()); + emptyData.put(field.getName(), ""); + } + } + // this.datas.add(title); + if (datas == null || datas.isEmpty()) { + this.datas.add(emptyData); + } else { + + ObjectMapper mapper = new ObjectMapper(); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")); + for (Object data : datas) { + var val = mapper.valueToTree(data); + this.datas.add(val); + } + } + + + } +} +; + diff --git a/src/main/java/iflytoplib/zextui/type/TabCfg.java b/src/main/java/iflytoplib/zextui/type/TabCfg.java new file mode 100644 index 0000000..0c59993 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/TabCfg.java @@ -0,0 +1,19 @@ +package zengineer.type; + +import lombok.Data; + +@Data +public class TabCfg { + static int staticIndex; + + public Class service; + public String chName; + public Boolean display; + public int index = staticIndex++; + + public TabCfg(Class service, String chName) { + this.service = service; + this.display = true; + this.chName = chName; + } +} diff --git a/src/main/java/iflytoplib/zextui/type/param/ExtUIFile.java b/src/main/java/iflytoplib/zextui/type/param/ExtUIFile.java new file mode 100644 index 0000000..041f482 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/param/ExtUIFile.java @@ -0,0 +1,12 @@ +package zengineer.type.param; +import java.util.Base64; +public class ExtUIFile { + public byte[] bytes; + + public static ExtUIFile fromBase64( String base64 ) { + Base64.Decoder decoder = Base64.getDecoder(); + var file = new ExtUIFile(); + file.bytes = decoder.decode( base64 ); + return file; + } +} diff --git a/src/main/java/iflytoplib/zextui/type/ret/EngineerUIRet.java b/src/main/java/iflytoplib/zextui/type/ret/EngineerUIRet.java new file mode 100644 index 0000000..ae42403 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ret/EngineerUIRet.java @@ -0,0 +1,39 @@ +package zengineer.type.ret; +import lombok.Getter; +public class AppRetV1 { + // 错误信息 + public Boolean success = null; + public String dataType; + public Object data; + public String message; + + // 接口请求时间 + @Getter + long timestamp; + + public AppRetV1() { + this.timestamp = System.currentTimeMillis(); + } + + public static AppRetV1 success(T data) { + AppRetV1 r = new AppRetV1(); + r.data = data; + r.success = true; + if (data != null) + r.dataType = data.getClass().getSimpleName(); + return r; + } + + + public static AppRetV1 success() { + return new AppRetV1(); + } + + public static AppRetV1 fail(Exception e) { + AppRetV1 r = new AppRetV1(); + r.success = false; + r.message = e.getMessage(); + return r; + } + +} diff --git a/src/main/java/iflytoplib/zextui/type/ret/ExtApiCurve.java b/src/main/java/iflytoplib/zextui/type/ret/ExtApiCurve.java new file mode 100644 index 0000000..69433d4 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ret/ExtApiCurve.java @@ -0,0 +1,16 @@ +package zengineer.type.ret; + +import java.util.List; + +public class ExtApiCurve { + public String name = null; + public String color = null; + public List data = null; + public List markLine = null; + + public Object minY; + public Object maxY; + + public String xtype = "value"; + public String ytype = "value"; +} diff --git a/src/main/java/iflytoplib/zextui/type/ret/ExtUIDownloadTasks.java b/src/main/java/iflytoplib/zextui/type/ret/ExtUIDownloadTasks.java new file mode 100644 index 0000000..951c656 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ret/ExtUIDownloadTasks.java @@ -0,0 +1,8 @@ +package zengineer.type.ret; + +import java.util.ArrayList; +import java.util.List; + +public class ExtUIDownloadTasks { + public List urls = new ArrayList<>(); +} diff --git a/src/main/java/iflytoplib/zextui/type/ret/FileToBeDownload.java b/src/main/java/iflytoplib/zextui/type/ret/FileToBeDownload.java new file mode 100644 index 0000000..2671470 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/type/ret/FileToBeDownload.java @@ -0,0 +1,9 @@ +package zengineer.type.ret; + +public class FileToBeDownload { + public String url; + + public FileToBeDownload(String url) { + this.url = url; + } +} diff --git a/src/main/java/iflytoplib/zextui/utils/FieldUtils.java b/src/main/java/iflytoplib/zextui/utils/FieldUtils.java new file mode 100644 index 0000000..882dca8 --- /dev/null +++ b/src/main/java/iflytoplib/zextui/utils/FieldUtils.java @@ -0,0 +1,69 @@ +package zengineer.utils; + +import java.lang.invoke.SerializedLambda; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * bean属性获取工具类 + */ +public class FieldUtils { + + public static SerializedLambda getSerializedLambda(Object fn) { + // 从function取出序列化方法 + Method writeReplaceMethod; + try { + writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace"); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + + // 从序列化方法取出序列化的lambda信息 + boolean isAccessible = writeReplaceMethod.isAccessible(); + writeReplaceMethod.setAccessible(true); + SerializedLambda serializedLambda; + try { + serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + writeReplaceMethod.setAccessible(isAccessible); + return serializedLambda; + } + + public static String getImplMethodName(Object fn) { + SerializedLambda serializedLambda = getSerializedLambda(fn); + return serializedLambda.getImplMethodName(); + } + + /** + * 将bean的属性的get方法,作为lambda表达式传入时,获取get方法对应的属性Field + * + * @param fn lambda表达式,bean的属性的get方法 + * @return 属性对象 + */ + public static Field getField(Object fn) { + SerializedLambda serializedLambda = getSerializedLambda(fn); + String implMethodName = serializedLambda.getImplMethodName(); + // 确保方法是符合规范的get方法,boolean类型是is开头 + if (!implMethodName.startsWith("is") && !implMethodName.startsWith("get")) { + throw new RuntimeException("get方法名称: " + implMethodName + ", 不符合java bean规范"); + } + + // get方法开头为 is 或者 get,将方法名 去除is或者get,然后首字母小写,就是属性名 + int prefixLen = implMethodName.startsWith("is") ? 2 : 3; + + String fieldName = implMethodName.substring(prefixLen); + String firstChar = fieldName.substring(0, 1); + fieldName = fieldName.replaceFirst(firstChar, firstChar.toLowerCase()); + Field field; + try { + field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName); + } catch (ClassNotFoundException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + + return field; + } +}