From ce486708c0c54e147648e96d81f47abb2257f45a Mon Sep 17 00:00:00 2001 From: sige Date: Tue, 30 Jul 2024 14:11:16 +0800 Subject: [PATCH 1/3] update version to 0.0.27 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f30293e..63f786c 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.iflytop a800 - 0.0.26 + 0.0.27 boditech-a800 boditech-a800 From ca87fec5c3b5f730160b2b453bf8d0a8d4f80416 Mon Sep 17 00:00:00 2001 From: sige Date: Tue, 30 Jul 2024 17:03:29 +0800 Subject: [PATCH 2/3] 1 --- src/main/java/a8k/MyApplicationRunner.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/a8k/MyApplicationRunner.java diff --git a/src/main/java/a8k/MyApplicationRunner.java b/src/main/java/a8k/MyApplicationRunner.java new file mode 100644 index 0000000..7446f6c --- /dev/null +++ b/src/main/java/a8k/MyApplicationRunner.java @@ -0,0 +1,18 @@ +package a8k; +import a8k.utils.AppServiceManager; +import jakarta.annotation.Resource; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +@Order(1) +@Component +public class MyApplicationRunner implements ApplicationRunner { + @Resource + private AppServiceManager appServiceManager; + + @Override + public void run(ApplicationArguments args) throws Exception { + this.appServiceManager.loadActions(); + } +} From 89ccbb153343d0f2cc076f4c7c35e869829d9947 Mon Sep 17 00:00:00 2001 From: sige Date: Wed, 31 Jul 2024 10:39:01 +0800 Subject: [PATCH 3/3] 1 --- src/main/java/a8k/controler/AppController.java | 23 ++++++++ .../controler/engineer/EngineerPageControler.java | 69 ++++++++++++++++++---- .../a8k/service/usermgr/AppUserMgrService.java | 20 ++++++- src/main/java/a8k/utils/AppService.java | 10 ++++ src/main/java/a8k/utils/AppServiceAction.java | 9 +++ src/main/java/a8k/utils/AppServiceManager.java | 69 ++++++++++++++++++++++ 6 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 src/main/java/a8k/controler/AppController.java create mode 100644 src/main/java/a8k/utils/AppService.java create mode 100644 src/main/java/a8k/utils/AppServiceAction.java create mode 100644 src/main/java/a8k/utils/AppServiceManager.java diff --git a/src/main/java/a8k/controler/AppController.java b/src/main/java/a8k/controler/AppController.java new file mode 100644 index 0000000..fdd2d15 --- /dev/null +++ b/src/main/java/a8k/controler/AppController.java @@ -0,0 +1,23 @@ +package a8k.controler; +import a8k.appbase.appret.AppRet; +import a8k.utils.AppServiceManager; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import java.util.Map; +@Controller +public class AppController { + @Resource + private AppServiceManager appServiceManager; + + @PostMapping("/api/app/execute-action") + @ResponseBody + public AppRet executeAction( @RequestBody Map params ) throws Exception { + String action = (String) params.get("name"); + Map actionParams = (Map) params.get("params"); + var result = this.appServiceManager.executeAction(action, actionParams); + return result instanceof AppRet ? (AppRet)result : AppRet.success(result); + } +} diff --git a/src/main/java/a8k/controler/engineer/EngineerPageControler.java b/src/main/java/a8k/controler/engineer/EngineerPageControler.java index 7d12421..660aed2 100644 --- a/src/main/java/a8k/controler/engineer/EngineerPageControler.java +++ b/src/main/java/a8k/controler/engineer/EngineerPageControler.java @@ -266,6 +266,65 @@ public class EngineerPageControler { } } + return this.executeServiceActionAndGetResponse(service, method, actionParams); + } + + @PostMapping("/api/service-config/service-action-exec-by-map") + @ResponseBody + public AppRet serviceActionExecuteByMap( @RequestBody Map params ) throws Throwable { + String serviceKey = (String)params.get("serviceKey"); + var service = this.getServiceInstanceByServiceKey(serviceKey); + assert service != null; + + var actionName = (String)params.get("action"); + var actionParams = (Map)params.get("params"); + List actionParamList = new ArrayList<>(); + Method method = null; + for ( var methodItem : service.getClass().getMethods() ) { + if ( !methodItem.getName().equals(actionName) ) { + continue ; + } + if ( methodItem.getParameterTypes().length != actionParams.size() ) { + continue ; + } + if ( !methodItem.isAnnotationPresent(EnginnerPageAction.class)) { + continue; + } + + actionParamList.clear(); + for ( var paramItem : methodItem.getParameters() ) { + var name = paramItem.getName(); + Object value = actionParams.get(name); + if ( paramItem.getType().isEnum() ) { + var methodValueOf = paramItem.getType().getMethod("valueOf", String.class); + value = methodValueOf.invoke(null, (String)value); + } else if ( paramItem.getType().equals(EnginnerParamFile.class) ) { + value = EnginnerParamFile.fromBase64((String)value); + } + if ( !paramItem.getType().isAssignableFrom(value.getClass()) ) { + continue ; + } + actionParamList.add(value); + } + method = methodItem; + break; + } + assert method != null; + return this.executeServiceActionAndGetResponse(service, method, actionParamList); + } + + @PostMapping("/api/service-config/class-struct-info-get") + @ResponseBody + public AppRet 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 AppRet.success(struct); + } + + // execute service action and get response + private AppRet executeServiceActionAndGetResponse( Object service, Method method, List actionParams) throws Throwable { Object actionResult = null; try { var actionParamList = actionParams.toArray(); @@ -292,16 +351,6 @@ public class EngineerPageControler { return AppRet.success(actionResult); } - @PostMapping("/api/service-config/class-struct-info-get") - @ResponseBody - public AppRet 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 AppRet.success(struct); - } - // get service instance by service key private Object getServiceInstanceByServiceKey( String serviceKey ) { Class serviceClass = null; diff --git a/src/main/java/a8k/service/usermgr/AppUserMgrService.java b/src/main/java/a8k/service/usermgr/AppUserMgrService.java index 06d9a1a..ea620da 100644 --- a/src/main/java/a8k/service/usermgr/AppUserMgrService.java +++ b/src/main/java/a8k/service/usermgr/AppUserMgrService.java @@ -1,8 +1,13 @@ package a8k.service.usermgr; import a8k.appbase.appret.AppRet; +import a8k.controler.engineer.utils.EngineerPageTab; +import a8k.controler.engineer.utils.EnginnerPageAction; +import a8k.controler.engineer.utils.EnginnerPageParam; import a8k.db.AppUser; import a8k.service.hardware.canbus.protocol.A8kEcode; +import a8k.utils.AppService; +import a8k.utils.AppServiceAction; import com.iflytop.uf.UfActiveRecord; import jakarta.annotation.PostConstruct; import org.slf4j.Logger; @@ -13,6 +18,7 @@ import java.util.Map; @Component +@EngineerPageTab(name = "用户管理") public class AppUserMgrService { static Logger logger = org.slf4j.LoggerFactory.getLogger(AppUserMgrService.class); @@ -45,6 +51,7 @@ public class AppUserMgrService { // EXT FUNC // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + @EnginnerPageAction(name = "用户登录") public AppRet login(String account, String password) { var user = dbGetUser(account); if (user == null) { @@ -61,11 +68,18 @@ public class AppUserMgrService { return AppRet.success(loginUsr); } + @EnginnerPageAction(name = "用户列表") + public AppRet> list() { + return AppRet.success(dbGetUserList()); + } + + @EnginnerPageAction(name = "登录用户列表") public AppRet> loginList() { return AppRet.success(dbGetUserList()); } - public AppRet addUser(String account, String password, int isAdmin) { + @EnginnerPageAction(name = "用户添加") + public AppRet addUser(String account, String password, Integer isAdmin) { if (dbGetUser(account) != null) { return AppRet.fail(A8kEcode.UsrExistError); } @@ -77,6 +91,7 @@ public class AppUserMgrService { return AppRet.success(user); } + @EnginnerPageAction(name = "用户删除") public AppRet delUser(String account) { var user = dbGetUser(account); if (user == null) { @@ -89,7 +104,8 @@ public class AppUserMgrService { return AppRet.success(user); } - public AppRet modifyUser(String account, String password, int isAdmin) { + @EnginnerPageAction(name = "用户变更") + public AppRet modifyUser(String account, String password, Integer isAdmin) { var user = dbGetUser(account); if (user == null) { return AppRet.fail(A8kEcode.UsrNotExitError); diff --git a/src/main/java/a8k/utils/AppService.java b/src/main/java/a8k/utils/AppService.java new file mode 100644 index 0000000..590f688 --- /dev/null +++ b/src/main/java/a8k/utils/AppService.java @@ -0,0 +1,10 @@ +package a8k.utils; +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 AppService { + String name(); +} diff --git a/src/main/java/a8k/utils/AppServiceAction.java b/src/main/java/a8k/utils/AppServiceAction.java new file mode 100644 index 0000000..d73a93b --- /dev/null +++ b/src/main/java/a8k/utils/AppServiceAction.java @@ -0,0 +1,9 @@ +package a8k.utils; +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 AppServiceAction { +} diff --git a/src/main/java/a8k/utils/AppServiceManager.java b/src/main/java/a8k/utils/AppServiceManager.java new file mode 100644 index 0000000..6345c95 --- /dev/null +++ b/src/main/java/a8k/utils/AppServiceManager.java @@ -0,0 +1,69 @@ +package a8k.utils; +import com.iflytop.uf.UfApplication; +import com.iflytop.uf.util.UfClassHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +@Component +public class AppServiceManager { + public static final Logger LOG = LoggerFactory.getLogger(AppServiceManager.class); + + // actions + public Map actions; + // services + public Map> actionServices; + + // load actions + public void loadActions() throws Exception { + this.actions = new HashMap(); + this.actionServices = new HashMap>(); + var classList = UfClassHelper.getAllClassesInPackage("a8k"); + for (var clazz : classList) { + var serviceAnnotation = clazz.getAnnotation(AppService.class); + if (serviceAnnotation == null) { + continue ; + } + var methods = clazz.getMethods(); + for (var method : methods) { + if (!method.isAnnotationPresent(AppServiceAction.class)) { + continue ; + } + String actionKey = String.format("%s.%s", serviceAnnotation.name(), method.getName()); + if (this.actions.containsKey(actionKey)) { + throw new Exception(String.format("重复action '%s'", actionKey)); + } + this.actions.put(actionKey, method); + this.actionServices.put(method, clazz); + LOG.info("load app action : {}", actionKey); + } + } + } + + // execute action + public Object executeAction(String action, Map params) throws Exception { + var method = actions.get(action); + if (method == null) { + throw new Exception("不存在"); + } + + var actionParamDefs = method.getParameters(); + Object[] args = new Object[actionParamDefs.length]; + for ( var i=0; i