chore: 调整项目结构
diff --git a/admin-bff/bff/.gitignore b/admin-bff/bff/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/admin-bff/bff/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/admin-bff/bff/Dockerfile b/admin-bff/bff/Dockerfile
new file mode 100644
index 0000000..b91c9f4
--- /dev/null
+++ b/admin-bff/bff/Dockerfile
@@ -0,0 +1,21 @@
+FROM harbor.supwisdom.com/institute/openjdk:8-jre-alpine
+
+ENV ENABLE_JMX_SSL=false
+ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker
+ENV SPRING_PROFILES_ACTIVE=docker
+
+ARG NAME
+ARG VERSION
+ARG JAR_FILE
+
+LABEL name=$NAME \
+ version=$VERSION
+
+EXPOSE 8080
+
+EXPOSE 8443
+
+COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar
+
+# COPY --chown=java-app:java-app target/doc /home/java-app/doc
+# COPY --chown=java-app:java-app target/api-docs /home/java-app/api-docs
diff --git a/admin-bff/bff/pom.xml b/admin-bff/bff/pom.xml
new file mode 100644
index 0000000..81e4eb9
--- /dev/null
+++ b/admin-bff/bff/pom.xml
@@ -0,0 +1,216 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-bff-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-bff</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Admin Backend for Frontend</name>
+ <description>Supwisdom Backend Framework Admin Backend for Frontend project</description>
+
+ <properties>
+ <start-class>com.supwisdom.institute.backend.admin.bff.Application</start-class>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <!-- 微服务 健康监控 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-openfeign</artifactId>
+ </dependency>
+ <!-- openfeign's dependency -->
+ <dependency>
+ <groupId>com.netflix.feign</groupId>
+ <artifactId>feign-httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-online-doc</artifactId>
+ </dependency>
+
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-mvc</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-object-mapper</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-i18n</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-lang</artifactId>
+ </dependency> -->
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ </dependency>
+
+
+ <!-- 热部署,无需重启项目 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-devtools</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+
+
+ <!-- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4.3</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <id>copy-doc-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/doc</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../doc</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>copy-api-docs-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/api-docs</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../api-docs</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
new file mode 100644
index 0000000..64ea622
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/Application.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.admin.bff;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc;
+import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
+import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
+
+@SpringBootApplication
+@EnableFeignClients
+
+@EnableScheduling
+
+@EnableSimpleUserTransmit
+
+@EnableCustomExceptionHandler
+
+@EnableInfrasOnlineDoc
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/autorefesh/base/InMemeryPermissionRoleSetAutoRefresh.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/autorefesh/base/InMemeryPermissionRoleSetAutoRefresh.java
new file mode 100644
index 0000000..d149eee
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/autorefesh/base/InMemeryPermissionRoleSetAutoRefresh.java
@@ -0,0 +1,26 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.autorefesh.base;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.service.base.AuthnService;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class InMemeryPermissionRoleSetAutoRefresh {
+
+ @Autowired
+ private AuthnService authnService;
+
+ @Scheduled(initialDelayString = "${inMemeryPermissionRoleSetAutoRefresh.schedule.startDelay:500}",
+ fixedDelayString = "${inMemeryPermissionRoleSetAutoRefresh.schedule.repeatInterval:20000}")
+ public void refresh() {
+ log.info("InMemeryPermissionRoleSetAutoRefresh, refresh permissionRoleSets");
+
+ authnService.loadPermissionRoleSets();
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/.gitkeep b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/.gitkeep
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/base/AdminBaseController.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/base/AdminBaseController.java
new file mode 100644
index 0000000..6224970
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/base/AdminBaseController.java
@@ -0,0 +1,19 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.controller.base;
+
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.common.core.transmit.user.UserContext;
+
+@RestController
+@RequestMapping(value = "/v1/admin/base")
+public class AdminBaseController {
+
+ @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public String hello() {
+ return "hello, " + UserContext.getUsername();
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/biz/AdminBizController.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/biz/AdminBizController.java
new file mode 100644
index 0000000..8c46261
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/biz/AdminBizController.java
@@ -0,0 +1,26 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.controller.biz;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.service.biz.BizService;
+
+@RestController
+@RequestMapping(value = "/v1/admin/biz")
+public class AdminBizController {
+
+ @Autowired
+ BizService bizService;
+
+ @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public String biz() {
+
+ bizService.query(true, -1, -1);
+
+ return "biz";
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/me/MeController.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/me/MeController.java
new file mode 100644
index 0000000..c88e7c5
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/me/MeController.java
@@ -0,0 +1,79 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.controller.me;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Permission;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.me.CurrentUser;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.me.GrantedMenu;
+import com.supwisdom.institute.backend.admin.bff.api.v1.service.base.AuthnService;
+import com.supwisdom.institute.backend.admin.bff.api.v1.vo.me.response.data.CurrentUserResponseData;
+import com.supwisdom.institute.backend.admin.bff.api.v1.vo.me.response.data.GrantedMenusResponseData;
+import com.supwisdom.institute.backend.admin.bff.utils.CurrentUserUtil;
+import com.supwisdom.institute.backend.common.core.transmit.user.User;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+
+@Api(value = "BFFMe", tags = { "me" }, description = "登录用户相关信息的接口")
+@RestController
+@RequestMapping(value = "/v1/me")
+public class MeController {
+
+ @Autowired
+ private AuthnService authnService;
+
+ @ApiOperation(
+ tags = { "me" },
+ value = "获取登录用户的基本信息", notes = "获取登录用户的基本信息", nickname = "user"
+ )
+ @RequestMapping(method = RequestMethod.GET, path = "/user", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public DefaultApiResponse<CurrentUserResponseData> user() {
+
+ User user = CurrentUserUtil.currentUser();
+
+ CurrentUser cu = new CurrentUser();
+ cu.setUsername(user.getUsername());
+ cu.setRoles(user.getRoles());
+ cu.setAttributes(user.getAttributes());
+
+ // XXX: 如果需要放入其他信息,可以扩展CurrentUser,并从服务接口中获取后写入数据
+
+ CurrentUserResponseData data = CurrentUserResponseData.of(cu);
+ return new DefaultApiResponse<CurrentUserResponseData>(data);
+ }
+
+ @ApiOperation(
+ tags = { "me" },
+ value = "获取登录用户的访问菜单", notes = "获取登录用户的访问菜单", nickname = "accountMenus"
+ )
+ @RequestMapping(method = RequestMethod.GET, path = "/menus", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public DefaultApiResponse<GrantedMenusResponseData> accountMenus() {
+
+ String username = CurrentUserUtil.currentUsername();
+
+ List<Permission> menus = authnService.menus(username, "1"); // XXX: applicationId
+
+ List<GrantedMenu> grantedMenus = new ArrayList<>();
+
+ menus.forEach(m -> {
+ GrantedMenu grantedMenu = new GrantedMenu();
+ grantedMenu = EntityUtils.copy(m, grantedMenu);
+ grantedMenus.add(grantedMenu);
+ });
+
+ GrantedMenusResponseData data = GrantedMenusResponseData.of(grantedMenus);
+ return new DefaultApiResponse<GrantedMenusResponseData>(data);
+
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenController.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenController.java
new file mode 100644
index 0000000..1b04e65
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenController.java
@@ -0,0 +1,53 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.controller.open;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.PermissionRoleSet;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.open.Menu;
+import com.supwisdom.institute.backend.admin.bff.api.v1.service.base.AuthnService;
+import com.supwisdom.institute.backend.admin.bff.api.v1.vo.open.response.data.MenusResponseData;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value = "BFFOpen", tags = { "open" }, description = "公开接口")
+@RestController
+@RequestMapping(value = "/v1/open")
+public class OpenController {
+
+ @Autowired
+ private AuthnService authnService;
+
+ @ApiOperation(
+ tags = { "open" },
+ value = "获取菜单", notes = "获取菜单", nickname = "openMenus"
+ )
+ @RequestMapping(method = RequestMethod.GET, path = "/menus", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public DefaultApiResponse<MenusResponseData> menus() {
+
+ List<Menu> menus = new ArrayList<>();
+
+ List<PermissionRoleSet> permissionRoleSets = authnService.getPermissionRoleSets("1"); // XXX: applicationId
+ if (permissionRoleSets != null) {
+ for (PermissionRoleSet permissionRoleSet : permissionRoleSets) {
+ Menu menu = new Menu();
+ BeanUtils.copyProperties(permissionRoleSet, menu);
+ menus.add(menu);
+ }
+ }
+
+ MenusResponseData data = MenusResponseData.of(menus);
+ return new DefaultApiResponse<MenusResponseData>(data);
+ }
+
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenSyncController.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenSyncController.java
new file mode 100644
index 0000000..ab6da53
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/controller/open/OpenSyncController.java
@@ -0,0 +1,55 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.controller.open;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Role;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.open.SyncRoleModel;
+import com.supwisdom.institute.backend.admin.bff.api.v1.service.base.AuthnService;
+import com.supwisdom.institute.backend.admin.bff.api.v1.vo.open.response.data.OpenSyncRolesResponseData;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(value = "BFFOpen", tags = { "open" }, description = "公开接口")
+@RestController
+@RequestMapping(value = "/v1/open/sync")
+public class OpenSyncController {
+
+ @Autowired
+ private AuthnService authnService;
+
+ @ApiOperation(
+ tags = { "open" },
+ value = "获取角色", notes = "获取角色", nickname = "openRoles"
+ )
+ @RequestMapping(method = RequestMethod.GET, path = "/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public DefaultApiResponse<OpenSyncRolesResponseData> roles(
+ @RequestParam(name = "applicationId", required = true) String applicationId) {
+
+ List<SyncRoleModel> syncRoleModels = new ArrayList<>();
+
+ List<Role> systemRoles = authnService.roles();
+ for (Role systemRole : systemRoles) {
+ SyncRoleModel syncRoleModel = new SyncRoleModel(
+ systemRole.getId(),
+ systemRole.getCode(),
+ systemRole.getName(),
+ systemRole.getMemo());
+ syncRoleModels.add(syncRoleModel);
+ }
+
+ OpenSyncRolesResponseData data = OpenSyncRolesResponseData.of(applicationId, syncRoleModels);
+ return new DefaultApiResponse<OpenSyncRolesResponseData>(data);
+ }
+
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/.gitkeep b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/.gitkeep
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Account.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Account.java
new file mode 100644
index 0000000..ebb0513
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Account.java
@@ -0,0 +1,70 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+@Getter
+@Setter
+public class Account extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4889952442290543101L;
+
+ private String id;
+
+ /**
+ * 用户名
+ */
+ private String username;
+
+ /**
+ * 密码
+ */
+ private String password;
+
+ /**
+ * 是否可用,1 可用,0 不可用,默认:1
+ */
+ private Boolean enabled;
+ /**
+ * 账号未过期,1 未过期,0 过期,默认:1
+ */
+ private Boolean accountNonExpired;
+ /**
+ * 账号未锁定,1 未锁定,0 锁定,默认:1
+ */
+ private Boolean accountNonLocked;
+ /**
+ * 密码未过期,1 未过期,0 过期,默认:1
+ */
+ private Boolean credentialsNonExpired;
+
+ /**
+ * 姓名
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+ /**
+ * 登录手机
+ */
+ private String mobile;
+ /**
+ * 登录邮箱
+ */
+ private String email;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Application.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Application.java
new file mode 100644
index 0000000..b0f6c48
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Application.java
@@ -0,0 +1,39 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class Application extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7687658763529677076L;
+
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Permission.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Permission.java
new file mode 100644
index 0000000..5877bf9
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Permission.java
@@ -0,0 +1,69 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+@Getter
+@Setter
+public class Permission extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3042842657207449148L;
+
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+ /**
+ * 菜单图标
+ */
+ private String icon;
+
+ /**
+ * 类型(1 应用,2 菜单,3 操作)
+ */
+ private String type;
+
+ /**
+ * URL地址
+ */
+ private String url;
+
+ /**
+ * 系统ID
+ */
+ private String applicationId;
+
+ /**
+ * 父级ID
+ */
+ private String parentId;
+
+ /**
+ * 排序
+ */
+ private Integer order;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/PermissionRoleSet.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/PermissionRoleSet.java
new file mode 100644
index 0000000..6080107
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/PermissionRoleSet.java
@@ -0,0 +1,114 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class PermissionRoleSet extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1482739465611090145L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ /**
+ * 代码
+ */
+ @Getter
+ @Setter
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Getter
+ @Setter
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Getter
+ @Setter
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Getter
+ @Setter
+ private String status;
+
+ /**
+ * 类型(1 应用,2 菜单,3 操作)
+ */
+ @Getter
+ @Setter
+ private String type;
+
+ /**
+ * 菜单图标
+ */
+ @Getter
+ @Setter
+ private String icon;
+
+ /**
+ * URL地址
+ */
+ @Getter
+ @Setter
+ private String url;
+
+ /**
+ * 系统ID
+ */
+ @Getter
+ @Setter
+ private String applicationId;
+
+ /**
+ * 父级ID
+ */
+ @Getter
+ @Setter
+ private String parentId;
+
+ /**
+ * 排序
+ */
+ @Getter
+ @Setter
+ private Integer order;
+
+ @Getter
+ @Setter
+ private Collection<Role> roles;
+
+ private Collection<String> permissionRoles = null;
+ public boolean matches(Collection<String> userRoles) {
+ if (permissionRoles == null) {
+ permissionRoles = new ArrayList<String>();
+ Iterator<Role> it = roles.iterator();
+ while (it.hasNext()) {
+ Role r = it.next();
+ permissionRoles.add(r.getCode());
+ }
+ }
+
+ userRoles.retainAll(permissionRoles);
+
+ return !userRoles.isEmpty();
+ }
+
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/ResourceRoleSet.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/ResourceRoleSet.java
new file mode 100644
index 0000000..665154d
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/ResourceRoleSet.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import java.util.Collection;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class ResourceRoleSet extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -683204173918706673L;
+
+ public static final String ACCESS_ANONYMOUS = "anonymous"; // 匿名访问anonymous
+ public static final String ACCESS_AUTHENTICATE = "authenticate"; // 认证访问authenticate
+ public static final String ACCESS_AUTHORIZE = "authorize"; // 授权访问authorize
+ public static final String ACCESS_PERMIT_ALL = "permitAll"; // 允许所有permitAll
+ public static final String ACCESS_DENY_ALL = "denyAll"; // 拒绝所有denyAll
+
+ @Getter
+ @Setter
+ private String id;
+
+ /**
+ * 代码
+ */
+ @Getter
+ @Setter
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Getter
+ @Setter
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Getter
+ @Setter
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Getter
+ @Setter
+ private String status;
+
+ /**
+ * 请求方式(GET、POST、PUT、DELETE 等)
+ */
+ @Getter
+ @Setter
+ private String method;
+
+ /**
+ * 请求路径
+ */
+ @Getter
+ @Setter
+ private String path;
+
+ /**
+ * 访问规则(匿名访问anonymous、认证访问authenticate、授权访问authorize、允许所有permitAll、拒绝所有denyAll)
+ */
+ @Getter
+ @Setter
+ private String access;
+
+ @Getter
+ @Setter
+ Collection<Role> roles;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Role.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Role.java
new file mode 100644
index 0000000..d8c5144
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/base/Role.java
@@ -0,0 +1,39 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.base;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+@Getter
+@Setter
+public class Role extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8551951601186240995L;
+
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/biz/Biz.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/biz/Biz.java
new file mode 100644
index 0000000..a290125
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/biz/Biz.java
@@ -0,0 +1,37 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.biz;
+
+import java.util.Date;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+public class Biz extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8755876583168251137L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private String name;
+
+ @Getter
+ @Setter
+ private Boolean bool;
+
+ @Getter
+ @Setter
+ private Date date;
+
+ @Getter
+ @Setter
+ private Integer num;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/CurrentUser.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/CurrentUser.java
new file mode 100644
index 0000000..3563b30
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/CurrentUser.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.me;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+public class CurrentUser extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2049212615500816301L;
+
+ @Getter
+ @Setter
+ private String username;
+
+ @Getter
+ @Setter
+ private List<String> roles;
+
+ @Getter
+ @Setter
+ private Map<String, Object> attributes;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/GrantedMenu.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/GrantedMenu.java
new file mode 100644
index 0000000..5d8cd70
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/me/GrantedMenu.java
@@ -0,0 +1,64 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.me;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class GrantedMenu extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1261755008133562980L;
+
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+ /**
+ * 菜单图标
+ */
+ private String icon;
+
+ /**
+ * URL地址
+ */
+ private String url;
+
+ /**
+ * 系统ID
+ */
+ private String applicationId;
+
+ /**
+ * 父级ID
+ */
+ private String parentId;
+
+ /**
+ * 排序
+ */
+ private Integer order;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/Menu.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/Menu.java
new file mode 100644
index 0000000..b3bdc99
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/Menu.java
@@ -0,0 +1,64 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.open;
+
+import com.supwisdom.institute.backend.common.framework.model.ABaseModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class Menu extends ABaseModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4206010261706882919L;
+
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 备注
+ */
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ private String status;
+
+ /**
+ * 菜单图标
+ */
+ private String icon;
+
+ /**
+ * URL地址
+ */
+ private String url;
+
+ /**
+ * 系统ID
+ */
+ private String applicationId;
+
+ /**
+ * 父级ID
+ */
+ private String parentId;
+
+ /**
+ * 排序
+ */
+ private Integer order;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/SyncRoleModel.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/SyncRoleModel.java
new file mode 100644
index 0000000..72986bc
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/model/open/SyncRoleModel.java
@@ -0,0 +1,39 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.model.open;
+
+import java.io.Serializable;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class SyncRoleModel implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1916611618482825238L;
+
+ /**
+ * ID
+ */
+ private String id;
+
+ /**
+ * 代码
+ */
+ private String code;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 描述
+ */
+ private String memo;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/.gitkeep b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/.gitkeep
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/configuration/BaseFeignClientConfiguration.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/configuration/BaseFeignClientConfiguration.java
new file mode 100644
index 0000000..da7040b
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/configuration/BaseFeignClientConfiguration.java
@@ -0,0 +1,36 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.base.configuration;
+
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
+import org.springframework.context.annotation.Bean;
+
+import com.supwisdom.institute.backend.common.core.feign.FeignClientBuilder;
+
+import feign.Client;
+
+public class BaseFeignClientConfiguration {
+
+ @Bean
+ public Client feignClient(
+ @Value("${sw-backend-base-api.client-auth.enabled:false}") boolean enabled,
+ @Value("${sw-backend-base-api.client-auth.key-password:}") String keyPassword,
+ @Value("${sw-backend-base-api.client-auth.key-store:}") String keyStore,
+ @Value("${sw-backend-base-api.client-auth.key-store-password:}") String keyStorePassword,
+ @Value("${sw-backend-base-api.client-auth.trust-store:}") String trustStore,
+ @Value("${sw-backend-base-api.client-auth.trust-store-password:}") String trustStorePassword,
+ ApacheHttpClientFactory httpClientFactory,
+ HttpClientConnectionManager httpClientConnectionManager) {
+
+ return FeignClientBuilder.builder()
+ .enabled(enabled)
+ .keyPassword(keyPassword)
+ .keyStore(keyStore)
+ .keyStorePassword(keyStorePassword)
+ .trustStore(trustStore)
+ .trustStorePassword(trustStorePassword)
+ .build()
+ .apacheHttpClient(httpClientFactory, httpClientConnectionManager);
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFallbackFactory.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFallbackFactory.java
new file mode 100644
index 0000000..e965dab
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFallbackFactory.java
@@ -0,0 +1,101 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.base.v1.authn;
+
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.exception.FallbackError;
+
+import feign.hystrix.FallbackFactory;
+
+@Component
+public class AuthnRemoteFallbackFactory implements FallbackFactory<AuthnRemoteFeignClient> {
+
+ @Override
+ public AuthnRemoteFeignClient create(Throwable cause) {
+ return new AuthnRemoteFeignClient() {
+
+ @Override
+ public JSONObject account(String username) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject roles(String username) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject applications(String username, String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject menus(String username, String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject operations(String username, String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject resources(String username, String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+
+ @Override
+ public JSONObject applications() {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject roles() {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject permissionRoleSets(String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject resourceRoleSets(String applicationId) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ };
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFeignClient.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFeignClient.java
new file mode 100644
index 0000000..0486ffd
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/base/v1/authn/AuthnRemoteFeignClient.java
@@ -0,0 +1,64 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.base.v1.authn;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.base.configuration.BaseFeignClientConfiguration;
+
+@FeignClient(
+ configuration = {BaseFeignClientConfiguration.class},
+ name = "base-admin-account-remote-feign-client",
+ url = "${sw-backend-base-api.uri}/v1/authn",
+ fallbackFactory = AuthnRemoteFallbackFactory.class
+)
+public interface AuthnRemoteFeignClient {
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/account")
+ JSONObject account(
+ @PathVariable(name = "username") String username);
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/roles")
+ JSONObject roles(
+ @PathVariable(name = "username") String username);
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/applications")
+ JSONObject applications(
+ @PathVariable(name = "username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/menus")
+ JSONObject menus(
+ @PathVariable(name = "username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/operations")
+ JSONObject operations(
+ @PathVariable(name = "username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{username}/resources")
+ JSONObject resources(
+ @PathVariable(name = "username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/applications")
+ JSONObject applications();
+
+ @RequestMapping(method = RequestMethod.GET, path = "/roles")
+ JSONObject roles();
+
+ @RequestMapping(method = RequestMethod.GET, path = "/permissionRoleSets")
+ JSONObject permissionRoleSets(
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+ @RequestMapping(method = RequestMethod.GET, path = "/resourceRoleSets")
+ JSONObject resourceRoleSets(
+ @RequestParam(name = "applicationId", required = false) String applicationId);
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/configuration/BizFeignClientConfiguration.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/configuration/BizFeignClientConfiguration.java
new file mode 100644
index 0000000..1e031d0
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/configuration/BizFeignClientConfiguration.java
@@ -0,0 +1,36 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.biz.configuration;
+
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
+import org.springframework.context.annotation.Bean;
+
+import com.supwisdom.institute.backend.common.core.feign.FeignClientBuilder;
+
+import feign.Client;
+
+public class BizFeignClientConfiguration {
+
+ @Bean
+ public Client feignClient(
+ @Value("${sw-backend-biz-api.client-auth.enabled:false}") boolean enabled,
+ @Value("${sw-backend-biz-api.client-auth.key-password:}") String keyPassword,
+ @Value("${sw-backend-biz-api.client-auth.key-store:}") String keyStore,
+ @Value("${sw-backend-biz-api.client-auth.key-store-password:}") String keyStorePassword,
+ @Value("${sw-backend-biz-api.client-auth.trust-store:}") String trustStore,
+ @Value("${sw-backend-biz-api.client-auth.trust-store-password:}") String trustStorePassword,
+ ApacheHttpClientFactory httpClientFactory,
+ HttpClientConnectionManager httpClientConnectionManager) {
+
+ return FeignClientBuilder.builder()
+ .enabled(enabled)
+ .keyPassword(keyPassword)
+ .keyStore(keyStore)
+ .keyStorePassword(keyStorePassword)
+ .trustStore(trustStore)
+ .trustStorePassword(trustStorePassword)
+ .build()
+ .apacheHttpClient(httpClientFactory, httpClientConnectionManager);
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFallbackFactory.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFallbackFactory.java
new file mode 100644
index 0000000..c73d3ee
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFallbackFactory.java
@@ -0,0 +1,61 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.biz.v1.admin;
+
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.biz.Biz;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.exception.FallbackError;
+
+import feign.hystrix.FallbackFactory;
+
+@Component
+public class AdminBizRemoteFallbackFactory implements FallbackFactory<AdminBizRemoteFeignClient> {
+
+ @Override
+ public AdminBizRemoteFeignClient create(Throwable cause) {
+ return new AdminBizRemoteFeignClient() {
+
+ @Override
+ public JSONObject query(boolean loadAll, int pageIndex, int pageSize) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject load(String id) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject create(Biz biz) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject update(String id, Biz biz) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ @Override
+ public JSONObject delete(String id) {
+ if (cause != null) {
+ cause.printStackTrace();
+ }
+ return FallbackError.defaultErrorJson(cause);
+ }
+
+ };
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFeignClient.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFeignClient.java
new file mode 100644
index 0000000..7c25a01
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/biz/v1/admin/AdminBizRemoteFeignClient.java
@@ -0,0 +1,51 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.biz.v1.admin;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.biz.Biz;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.biz.configuration.BizFeignClientConfiguration;
+
+@FeignClient(
+ configuration = {BizFeignClientConfiguration.class},
+ name = "biz-admin-biz-remote-feign-client",
+ url = "${sw-backend-biz-api.uri}/v1/admin/biz",
+ fallbackFactory = AdminBizRemoteFallbackFactory.class
+)
+public interface AdminBizRemoteFeignClient {
+
+ @RequestMapping(method = RequestMethod.GET)
+ JSONObject query(
+ @RequestParam(name = "loadAll") boolean loadAll,
+ @RequestParam(name = "pageIndex") int pageIndex,
+ @RequestParam(name = "pageSize") int pageSize
+
+ );
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}")
+ JSONObject load(
+ @PathVariable(name = "id") String id
+ );
+
+ @RequestMapping(method = RequestMethod.POST)
+ JSONObject create(
+ @RequestBody Biz biz
+ );
+
+ @RequestMapping(method = RequestMethod.PUT, path = "/{id}")
+ JSONObject update(
+ @PathVariable(name = "id") String id,
+ @RequestBody Biz biz
+ );
+
+ @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
+ JSONObject delete(
+ @PathVariable(name = "id") String id
+ );
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/exception/FallbackError.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/exception/FallbackError.java
new file mode 100644
index 0000000..14f8326
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/remote/exception/FallbackError.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.remote.exception;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class FallbackError {
+
+ private FallbackError() {
+
+ }
+
+ public static JSONObject defaultErrorJson(Throwable cause) {
+ JSONObject error = new JSONObject();
+
+ error.put("code", -1);
+ error.put("message", cause.getMessage());
+ error.put("error", cause.getMessage());
+
+ return error;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/.gitkeep b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/.gitkeep
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/base/AuthnService.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/base/AuthnService.java
new file mode 100644
index 0000000..8f6d9df
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/base/AuthnService.java
@@ -0,0 +1,202 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.service.base;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Account;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Application;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Permission;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.PermissionRoleSet;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.ResourceRoleSet;
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.base.Role;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.base.v1.authn.AuthnRemoteFeignClient;
+
+@Slf4j
+@Service
+public class AuthnService {
+
+ @Autowired
+ private AuthnRemoteFeignClient authnRemote;
+
+ public Account account(String username) {
+
+ JSONObject jsonObject = authnRemote.account(username);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ if (jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.toJavaObject(Account.class);
+ }
+
+ return null;
+ }
+
+ public List<Role> roles(String username) {
+
+ JSONObject jsonObject = authnRemote.roles(username);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ if (jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("roles").toJavaList(Role.class);
+ }
+
+ return null;
+ }
+
+ public List<Permission> menus(String username, String applicationId) {
+
+ JSONObject jsonObject = authnRemote.menus(username, applicationId);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ if (jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("permissions").toJavaList(Permission.class);
+ }
+
+ return null;
+ }
+
+
+ public List<Application> applications() {
+
+ try {
+ JSONObject jsonObject = authnRemote.applications();
+ if (jsonObject == null) {
+ return null;
+ }
+ log.debug("{}", jsonObject.toJSONString());
+
+ if (jsonObject.containsKey("code") && jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("applications").toJavaList(Application.class);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public List<Role> roles() {
+
+ try {
+ JSONObject jsonObject = authnRemote.roles();
+ if (jsonObject == null) {
+ return null;
+ }
+ log.debug("{}", jsonObject.toJSONString());
+
+ if (jsonObject.containsKey("code") && jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("roles").toJavaList(Role.class);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+
+
+
+
+ public static volatile Map<String, List<PermissionRoleSet>> mapPermissionRoleSets =
+ new HashMap<String, List<PermissionRoleSet>>();
+
+ public void putPermissionRoleSets(String applicationId, List<PermissionRoleSet> permissionRoleSets) {
+ AuthnService.mapPermissionRoleSets.put(applicationId, permissionRoleSets);
+ }
+
+ public List<PermissionRoleSet> getPermissionRoleSets(String applicationId) {
+ if (StringUtils.isNotEmpty(applicationId)) {
+ return AuthnService.mapPermissionRoleSets.get(applicationId);
+ }
+
+ List<PermissionRoleSet> allPermissionRoleSets = new ArrayList<>();
+ for (List<PermissionRoleSet> permissionRoleSets : AuthnService.mapPermissionRoleSets.values()) {
+ allPermissionRoleSets.addAll(permissionRoleSets);
+ }
+
+ return allPermissionRoleSets;
+ }
+
+ public void loadPermissionRoleSets() {
+
+ List<Application> applications = applications();
+ if (applications != null) {
+ for (Application application : applications) {
+ String applicationId = application.getId();
+ List<PermissionRoleSet> permissionRoleSets = this.permissionRoleSets(applicationId);
+ if (permissionRoleSets != null) {
+ this.putPermissionRoleSets(applicationId, permissionRoleSets);
+ }
+ }
+ }
+ }
+
+
+ public List<PermissionRoleSet> permissionRoleSets(String applicationId) {
+
+ try {
+ JSONObject jsonObject = authnRemote.permissionRoleSets(applicationId);
+ if (jsonObject == null) {
+ return null;
+ }
+ log.debug("{}", jsonObject.toJSONString());
+
+ if (jsonObject.containsKey("code") && jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("permissionRoleSets").toJavaList(PermissionRoleSet.class);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public List<ResourceRoleSet> resourceRoleSets() {
+
+ try {
+ JSONObject jsonObject = authnRemote.resourceRoleSets(null);
+ if (jsonObject == null) {
+ return null;
+ }
+ log.debug("{}", jsonObject.toJSONString());
+
+ if (jsonObject.containsKey("code") && jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.getJSONArray("resourceRoleSets").toJavaList(ResourceRoleSet.class);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/biz/BizService.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/biz/BizService.java
new file mode 100644
index 0000000..0fa9bdf
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/service/biz/BizService.java
@@ -0,0 +1,32 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.service.biz;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.admin.bff.api.v1.remote.biz.v1.admin.AdminBizRemoteFeignClient;
+import com.supwisdom.institute.backend.admin.bff.api.v1.vo.biz.response.data.BizQueryResponseData;
+
+@Service
+public class BizService {
+
+ @Autowired
+ private AdminBizRemoteFeignClient bizRemote;
+
+ public BizQueryResponseData query(boolean loadAll, int pageIndex, int pageSize) {
+
+ JSONObject jsonObject = bizRemote.query(loadAll, pageIndex, pageSize);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ if (jsonObject.getIntValue("code") == 0) {
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ return data.toJavaObject(BizQueryResponseData.class);
+ }
+
+ return null;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/.gitkeep b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/.gitkeep
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/biz/response/data/BizQueryResponseData.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/biz/response/data/BizQueryResponseData.java
new file mode 100644
index 0000000..8b3891b
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/biz/response/data/BizQueryResponseData.java
@@ -0,0 +1,45 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.vo.biz.response.data;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.biz.Biz;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+public class BizQueryResponseData implements IApiQueryResponseData<Biz> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -380945463584664943L;
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Biz> items;
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/CurrentUserResponseData.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/CurrentUserResponseData.java
new file mode 100644
index 0000000..97443d3
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/CurrentUserResponseData.java
@@ -0,0 +1,23 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.vo.me.response.data;
+
+import org.springframework.beans.BeanUtils;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.me.CurrentUser;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class CurrentUserResponseData extends CurrentUser implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2296310299015658064L;
+
+ public static CurrentUserResponseData of(CurrentUser currentUser) {
+ CurrentUserResponseData data = new CurrentUserResponseData();
+
+ BeanUtils.copyProperties(currentUser, data);
+
+ return data;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/GrantedMenusResponseData.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/GrantedMenusResponseData.java
new file mode 100644
index 0000000..2aacc52
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/me/response/data/GrantedMenusResponseData.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.vo.me.response.data;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.me.GrantedMenu;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class GrantedMenusResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7495122676647463043L;
+
+ @Getter
+ @Setter
+ private List<GrantedMenu> menus;
+
+ public static GrantedMenusResponseData of(List<GrantedMenu> grantedMenus) {
+ GrantedMenusResponseData data = new GrantedMenusResponseData();
+
+ data.setMenus(grantedMenus);
+
+ return data;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/MenusResponseData.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/MenusResponseData.java
new file mode 100644
index 0000000..6beabd2
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/MenusResponseData.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.vo.open.response.data;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.open.Menu;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class MenusResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3516729316884770800L;
+
+ @Getter
+ @Setter
+ private List<Menu> menus;
+
+ public static MenusResponseData of(List<Menu> menus) {
+ MenusResponseData data = new MenusResponseData();
+
+ data.setMenus(menus);
+
+ return data;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/OpenSyncRolesResponseData.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/OpenSyncRolesResponseData.java
new file mode 100644
index 0000000..69453b6
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/api/v1/vo/open/response/data/OpenSyncRolesResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.admin.bff.api.v1.vo.open.response.data;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.admin.bff.api.v1.model.open.SyncRoleModel;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class OpenSyncRolesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2739730369123803327L;
+
+ @Getter
+ @Setter
+ private String applicationId;
+
+ @Getter
+ @Setter
+ private List<SyncRoleModel> roles;
+
+ public static OpenSyncRolesResponseData of(String applicationId, List<SyncRoleModel> roles) {
+ OpenSyncRolesResponseData data = new OpenSyncRolesResponseData();
+
+ data.setApplicationId(applicationId);
+ data.setRoles(roles);
+
+ return data;
+ }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java
new file mode 100644
index 0000000..191e1e8
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/FeignBasicAuthRequestInterceptor.java
@@ -0,0 +1,77 @@
+package com.supwisdom.institute.backend.admin.bff.configuration;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * feign请求参数转化
+ * @author fengpy
+ */
+//@Configuration
+public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ public FeignBasicAuthRequestInterceptor() {}
+
+ @Override
+ public void apply(RequestTemplate template) {
+ ///**get-pojo贯穿*/
+ if (template.method().equals("GET") && template.request().body() != null) {
+ try {
+ JsonNode jsonNode = objectMapper.readTree(template.request().body());
+ //template.body(null);
+ Map<String, Collection<String>> queries = new HashMap<>();
+ //feign 不支持 GET 方法传 POJO, json body转query
+ buildQuery(jsonNode, "", queries);
+ template.queries(queries);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ //处理 get-pojo贯穿
+ private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
+ if (!jsonNode.isContainerNode()) { //叶子节点
+ if (jsonNode.isNull()) {
+ return;
+ }
+ Collection<String> values = queries.get(path);
+ if (null == values) {
+ values = new ArrayList<>();
+ queries.put(path, values);
+ }
+ values.add(jsonNode.asText());
+ return;
+ }
+ if (jsonNode.isArray()) { //数组节点
+ Iterator<JsonNode> it = jsonNode.elements();
+ while (it.hasNext()) {
+ buildQuery(it.next(), path, queries);
+ }
+ } else {
+ Iterator<Map.Entry<String, JsonNode>> it = jsonNode.fields();
+ while (it.hasNext()) {
+ Map.Entry<String, JsonNode> entry = it.next();
+ if (StringUtils.hasText(path)) {
+ if ("mapBean".equals(path)||"orderBy".equals(path)||"sequence".equals(path)) {
+ buildQuery(entry.getValue(), path + "[" + entry.getKey() + "]", queries);
+ } else {
+ buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
+ }
+ } else { //根节点
+ buildQuery(entry.getValue(), entry.getKey(), queries);
+ }
+ }
+ }
+ }
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java
new file mode 100644
index 0000000..5a1022a
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/configuration/Swagger2Config.java
@@ -0,0 +1,132 @@
+package com.supwisdom.institute.backend.admin.bff.configuration;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.AuthorizationScopeBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.BasicAuth;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+import static com.google.common.collect.Lists.*;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+
+ @Value("${swagger2.apis.basePackage:com.supwisdom.institute}")
+ private String basePackage;
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .securitySchemes(securitySchemes())
+ .securityContexts(securityContexts())
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage(basePackage))
+ .paths(PathSelectors.any())
+ .build()
+ ;
+ }
+
+ private ApiInfo apiInfo() {
+ Contact contact = new Contact("Backend Admin BFF", "https://sw-backend-api.supwisdom.com/swagger-ui.html", ""); // name, url, email
+ return new ApiInfoBuilder()
+ .title("Backend Admin BFF APIs")
+ .description("管理后台 - 后端接口<br /><br />"
+ + "X-FORWARD-USER(测试用):<br /><br />"
+ + "明文:{\"attributes\":{\"accountId\":\"1\"},\"roles\":[\"ROLE_ADMIN\",\"administrator\",\"user\"],\"username\":\"swadmin\"}<br /><br />"
+ + "Base64:eyJhdHRyaWJ1dGVzIjp7ImFjY291bnRJZCI6IjEifSwicm9sZXMiOlsiUk9MRV9BRE1JTiIsImFkbWluaXN0cmF0b3IiLCJ1c2VyIl0sInVzZXJuYW1lIjoic3dhZG1pbiJ9<br /><br />"
+ + "使用 Base64字符串 进行 Authorize,然后进行接口测试<br /><br />"
+ + "若需要其他帐号,请自行拼接明文,再进行 Base64 编码<br /><br />"
+ + ""
+ )
+ .termsOfServiceUrl("http://www.supwisdom.com/")
+ .contact(contact)
+ .version("1.0")
+ .build();
+ }
+
+ private List<SecurityScheme> securitySchemes() {
+ //return newArrayList(new BasicAuth("sample"));
+ return newArrayList(
+ //new BasicAuth("Basic"),
+ //new ApiKey("JWTToken", "Authorization", "header"),
+ new ApiKey("SimpleUserTransmit", "X-FORWARD-USER", "header"));
+ }
+
+ private List<SecurityContext> securityContexts() {
+
+ List<SecurityReference> globalSecurityReference = newArrayList(
+ new SecurityReference("SimpleUserTransmit", new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}));
+
+// AuthorizationScope[] authScopes = new AuthorizationScope[1];
+// authScopes[0] = new AuthorizationScopeBuilder()
+// .scope("read")
+// .description("read access")
+// .build();
+// SecurityReference securityReference = SecurityReference.builder()
+// .reference("sample")
+// .scopes(authScopes)
+// .build();
+
+ return newArrayList(
+ SecurityContext.builder()
+ .securityReferences(newArrayList(globalSecurityReference))
+ .build());
+ }
+
+ @Bean
+ public UiConfiguration uiConfig() {
+
+ return UiConfigurationBuilder.builder().build();
+
+// return new UiConfiguration(null, // url
+// "none", // docExpansion => none | list
+// "alpha", // apiSorter => alpha
+// "schema", // defaultModelRendering => schema
+// UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
+// false, // enableJsonEditor => true || false
+// true, // showRequestHeaders => true | false
+// 60000L); // requestTimeout => in milliseconds, defaults to null
+// // (uses jquery xh timeout)
+ }
+
+
+// @Bean
+// public SecurityConfiguration oauth2() {
+// return SecurityConfigurationBuilder.builder()
+// .clientId("common")
+// .clientSecret("secret")
+// .scopeSeparator(" ")
+// .useBasicAuthenticationWithAccessCodeGrant(true)
+// .build();
+// }
+//
+// @Bean
+// public SecurityConfiguration basic() {
+// return SecurityConfigurationBuilder.builder()
+// .clientId("common")
+// .clientSecret("secret")
+// .scopeSeparator(" ")
+// .useBasicAuthenticationWithAccessCodeGrant(true)
+// .build();
+// }
+
+}
diff --git a/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/CurrentUserUtil.java b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/CurrentUserUtil.java
new file mode 100644
index 0000000..b97e5ae
--- /dev/null
+++ b/admin-bff/bff/src/main/java/com/supwisdom/institute/backend/admin/bff/utils/CurrentUserUtil.java
@@ -0,0 +1,26 @@
+package com.supwisdom.institute.backend.admin.bff.utils;
+
+import com.supwisdom.institute.backend.common.core.transmit.user.User;
+import com.supwisdom.institute.backend.common.core.transmit.user.UserContext;
+
+public class CurrentUserUtil {
+
+ public static User currentUser() {
+ User user = UserContext.getUser();
+
+ if (user == null) {
+ throw new RuntimeException("current user is null");
+ }
+
+ return user;
+ }
+
+ public static String currentUsername() {
+ return currentUser().getUsername();
+ }
+
+ public static String currentUserAccountId() {
+ return String.valueOf(currentUser().getAttributes().get("accountId"));
+ }
+
+}
diff --git a/admin-bff/bff/src/main/resources/application-docker.yml b/admin-bff/bff/src/main/resources/application-docker.yml
new file mode 100644
index 0000000..81e78c9
--- /dev/null
+++ b/admin-bff/bff/src/main/resources/application-docker.yml
@@ -0,0 +1,74 @@
+server:
+ port: ${SERVER_PORT:8443}
+ ssl:
+ enabled: ${SSL_ENABLED:true}
+ clientAuth: NEED
+ key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore}
+ key-store-password: ${SSL_KEYSTORE_PASSWORD:}
+ trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore}
+ trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:}
+ tomcat:
+ accesslog:
+ enabled: ${TOMCAT_ACCESSLOG_ENABLED:false}
+ buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true}
+ directory: ${TOMCAT_ACCESSLOG_DIR:log}
+ prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog}
+ suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log}
+ file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd}
+ rotate: ${TOMCAT_ACCESSLOG_ROTATE:true}
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: INFO
+
+
+spring:
+ jackson:
+ time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false}
+infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/}
+infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/}
+
+
+##
+# server url for feign
+#
+sw-backend-base-api:
+ uri: ${SW_BACKEND_BASE_API_URI:https://sw-backend-admin-sa}
+ client-auth:
+ enabled: ${SW_BACKEND_BASE_API_CLIENT_AUTH_ENABLED:true}
+ key-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEY_PASSWORD:}
+ key-store: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+ key-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+ trust-store: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+ trust-store-password: ${SW_BACKEND_BASE_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
+
+sw-backend-system-api:
+ uri: ${SW_BACKEND_SYSTEM_API_URI:https://sw-backend-admin-sa}
+ client-auth:
+ enabled: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_ENABLED:true}
+ key-password: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_KEY_PASSWORD:}
+ key-store: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+ key-store-password: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+ trust-store: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+ trust-store-password: ${SW_BACKEND_SYSTEM_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
+
+sw-backend-biz-api:
+ uri: ${SW_BACKEND_BIZ_API_URI:https://sw-backend-biz-sa}
+ client-auth:
+ enabled: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_ENABLED:true}
+ key-password: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_KEY_PASSWORD:}
+ key-store: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_KEYSTORE_FILE:file:/certs/common/common.keystore}
+ key-store-password: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_KEYSTORE_PASSWORD:}
+ trust-store: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_TRUSTSTORE_FILE:file:/certs/common/common.truststore}
+ trust-store-password: ${SW_BACKEND_BIZ_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD:}
diff --git a/admin-bff/bff/src/main/resources/application.yml b/admin-bff/bff/src/main/resources/application.yml
new file mode 100644
index 0000000..8ad7215
--- /dev/null
+++ b/admin-bff/bff/src/main/resources/application.yml
@@ -0,0 +1,68 @@
+server:
+ port: 8081
+ ssl:
+ enabled: false
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: DEBUG
+# org.springframework.web: INFO
+# org.springframework.cloud.openfeign: INFO
+
+
+swagger2.apis.basePackage: com.supwisdom.institute
+
+
+spring:
+ jackson:
+ time-zone: Asia/Shanghai
+
+
+feign:
+ client:
+ config:
+ default:
+ #errorDecoder: com.supwisdom.leaveschool.common.config.BaseExceptionErrorDecoder
+ connectTimeout: 12000
+ readTimeout: 12000
+ loggerLevel: full
+ hystrix:
+ enabled: true
+ httpclient:
+ enabled: true
+
+hystrix:
+ command:
+ default:
+ execution:
+ timeout:
+ enabled: true
+ isolation:
+ thread:
+ timeoutInMilliseconds: 12000
+
+
+##
+# infras.online-doc
+#
+infras.online-doc.enabled: true
+infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/
+infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/
+
+
+##
+# server url for feign
+#
+sw-backend-base-api:
+ uri: http://localhost:8082
+
+sw-backend-system-api:
+ uri: http://localhost:8082
+
+sw-backend-biz-api:
+ uri: http://localhost:8082
diff --git a/admin-bff/bff/src/main/resources/bootstrap.yml b/admin-bff/bff/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..2df1be7
--- /dev/null
+++ b/admin-bff/bff/src/main/resources/bootstrap.yml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: sw-backend-admin-bff
diff --git a/admin-bff/pom.xml b/admin-bff/pom.xml
new file mode 100644
index 0000000..a863ec8
--- /dev/null
+++ b/admin-bff/pom.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-bff-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework Admin Backend for Frontend Parent</name>
+ <description>Supwisdom Backend Framework Admin Backend for Frontend Parent project</description>
+
+ <modules>
+ <module>bff</module>
+ </modules>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ </properties>
+
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-bom</artifactId>
+ <version>${infras.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <!-- 使用Apache HttpClient替换Feign原生httpclient -->
+ <dependency>
+ <groupId>com.netflix.feign</groupId>
+ <artifactId>feign-httpclient</artifactId>
+ <version>8.17.0</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <version>${dockerfile-maven-plugin.version}</version>
+ <configuration>
+ <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
+ <tag>${project.version}</tag>
+ <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+ <buildArgs>
+ <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
+ <VERSION>${project.version}</VERSION>
+ <NAME>${project.artifactId}</NAME>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/admin-sa/base/api/.gitignore b/admin-sa/base/api/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/admin-sa/base/api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/admin-sa/base/api/pom.xml b/admin-sa/base/api/pom.xml
new file mode 100644
index 0000000..0947d3c
--- /dev/null
+++ b/admin-sa/base/api/pom.xml
@@ -0,0 +1,110 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-api</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Admin Base API</name>
+ <description>Supwisdom Backend Framework Admin Base API project</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-domain</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminAccountController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminAccountController.java
new file mode 100644
index 0000000..2b2efb3
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminAccountController.java
@@ -0,0 +1,583 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.HashMap;
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountDeleteBatchRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountRelateGroupsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountRelateRolesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountRelatedGroupsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountRelatedRolesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.AccountUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountDeleteBatchResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountRelateGroupsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountRelateRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountRelatedGroupsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountRelatedRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.AccountUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.base.domain.service.AccountService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminAccount", tags = { "BaseAdminAccount" }, description = "帐号的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/accounts")
+public class AdminAccountController {
+
+ @Autowired
+ private AccountService accountService;
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts?pageIndex=2&pageSize=50'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts?pageIndex=0&pageSize=20&mapBean[username]=username&mapBean[name]=name&mapBean[status]=1'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts?pageIndex=0&pageSize=20&mapBean[username]=username&mapBean[name]=name&mapBean[status]=0'
+ *
+ * response success:
+ *
+ * <pre>
+ * {
+ * "pageIndex":0,
+ * "pageSize":20,
+ * "mapBean":null,
+ * "pageCount":1,
+ * "recordCount":1,
+ * "items":[
+ * {
+ * "id":"ff80808164feb8990164feba0de50000",
+ * "companyId":"1",
+ * "deleted":false,
+ * "addAccount":"account","addTime":"2018-08-03T07:39:23.000+0000",
+ * "editAccount":null,"editTime":null,
+ * "deleteAccount":null,"deleteTime":null,
+ * "accountname":"test001",
+ * "password":"test001",
+ * "enabled":true,
+ * "accountNonExpired":true,
+ * "accountNonLocked":true,
+ * "credentialsNonExpired":true,
+ * "name":"测试001",
+ * "status":"1",
+ * "mobile":null,
+ * "email":null
+ * }
+ * ]
+ * }
+ * </pre>
+ *
+ * response error 401:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * @param pagerRequestModel
+ * @return
+ */
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountQueryResponseData> query(AccountQueryRequest queryRequest) {
+
+ Page<Account> page = accountService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ AccountQueryResponseData data = AccountQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<AccountQueryResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1'
+ *
+ * response success:
+ *
+ * <pre>
+ * {
+ * "id":"ff80808164feb8990164feba0de50000",
+ * "companyId":"1",
+ * "deleted":false,
+ * "addAccount":"account","addTime":"2018-08-03T07:39:23.000+0000",
+ * "editAccount":null,"editTime":null,
+ * "deleteAccount":null,"deleteTime":null,
+ * "username":"test001",
+ * "password":"test001",
+ * "enabled":true,
+ * "accountNonExpired":true,
+ * "accountNonLocked":true,
+ * "credentialsNonExpired":true,
+ * "name":"测试001",
+ * "status":"1",
+ * "mobile":null,
+ * "email":null
+ * }
+ * </pre>
+ *
+ * response error 401:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:43:26.080+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/api/v1/admin/accounts/ff80808164fecf640164fed269480000"
+ * }
+ * </pre>
+ *
+ * response error 500:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T07:44:07.963+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.get.domain.not.exist",
+ * "path":"/api/v1/admin/accounts/1"
+ * }
+ * </pre>
+ *
+ * @param id
+ * @return
+ */
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account account = accountService.selectById(id);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ AccountLoadResponseData data = AccountLoadResponseData.of(account);
+
+ return new DefaultApiResponse<AccountLoadResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts' \
+ * -d '{"accountname":"test001","password":"test001","enabled":true,"accountNonExpired":true,"accountNonLocked":true,"credentialsNonExpired":true,"name":"测试001","status":"1"}'
+ *
+ * response success:
+ *
+ * <pre>
+ * {
+ * "success":"info.create.success"
+ * }
+ * </pre>
+ *
+ * response error 401:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * response error: // FIXME: save error
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T07:45:43.436+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"org.springframework.dao.DataIntegrityViolationException",
+ * "message":"could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * @param account
+ * @return
+ */
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountCreateResponseData> create(
+ @RequestBody AccountCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Account account = createRequest.getEntity();
+
+ if (account.getPassword() !=null && account.getPassword().length() > 0 && !account.getPassword().startsWith("{")) {
+ //account.setPassword(passwordEncoder.encode(account.getPassword()));
+ }
+
+ Account ret = accountService.insert(account);
+
+ AccountCreateResponseData data = AccountCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<AccountCreateResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts' \
+ * -d '{"id":"1","status":"0"}'
+ *
+ * response success:
+ *
+ * <pre>
+ * {
+ * "success":"info.update.success"
+ * }
+ * </pre>
+ *
+ * response error 401:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts' \
+ * -d '{"status":"0"}'
+ *
+ * response error:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T07:50:52.327+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.update.id.must.not.empty",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * curl -i -s -X PUT -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts' \
+ * -d '{"id":"1","status":"0"}'
+ *
+ * response error:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T07:48:24.774+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.update.domain.not.exist",
+ * "path":"/api/v1/admin/accounts"
+ * }
+ * </pre>
+ *
+ * @param account
+ * @return
+ */
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody AccountUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Account tmp = accountService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Account account = updateRequest.getEntity();
+ account.setId(id);
+
+ if (account.getPassword() !=null && account.getPassword().length() > 0 && !account.getPassword().startsWith("{")) {
+ //account.setPassword(passwordEncoder.encode(account.getPassword()));
+ }
+
+ account = EntityUtils.merge(tmp, account);
+
+ Account ret = accountService.update(account);
+
+ AccountUpdateResponseData data = AccountUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<AccountUpdateResponseData>(data);
+ }
+
+
+ /**
+ *
+ * curl -i -s -X DELETE -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1'
+ *
+ * response success:
+ *
+ * <pre>
+ * {
+ * "success":"info.delete.success"
+ * }
+ * </pre>
+ *
+ * response error 401:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:48:25.777+0000",
+ * "status":401,
+ * "error":"Http Status 401",
+ * "message":"Unauthorized",
+ * "path":"/api/v1/admin/accounts/1"
+ * }
+ * </pre>
+ *
+ * response error 500:
+ *
+ * <pre>
+ * {
+ * "timestamp":"2018-08-03T08:03:16.364+0000",
+ * "status":500,
+ * "error":"Internal Server Error",
+ * "exception":"java.lang.RuntimeException",
+ * "message":"exception.delete.domain.not.exist",
+ * "path":"/api/v1/admin/accounts/1"
+ * }
+ * </pre>
+ *
+ * @param id
+ * @return
+ */
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account tmp = accountService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ accountService.deleteById(id);
+
+ AccountRemoveResponseData data = AccountRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<AccountRemoveResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/batch", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AccountDeleteBatchResponseData> deleteBatch(
+ @RequestBody AccountDeleteBatchRequest deleteBatchRequest) {
+
+ List<String> ids = deleteBatchRequest.getIds();
+
+ accountService.deleteBatch(ids);
+
+ AccountDeleteBatchResponseData data = AccountDeleteBatchResponseData.build(ids);
+ return new DefaultApiResponse<AccountDeleteBatchResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/groups'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/groups?pageIndex=2&pageSize=50'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/groups?pageIndex=0&pageSize=20&mapBean[groupCode]=groupCode&mapBean[groupName]=groupName'
+ *
+ *
+ *
+ * @param id
+ * @param pagerRequestModel
+ * @return
+ */
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/groups", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<AccountRelatedGroupsResponseData> accountGroups(
+ @PathVariable("id") String id,
+ AccountRelatedGroupsRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account account = accountService.selectById(id);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("accountId", account.getId());
+
+ Page<AccountGroup> page = accountService.selectAccountGroups(request.getPageIndex(),
+ request.getPageSize(), request.getMapBean());
+
+ AccountRelatedGroupsResponseData data = AccountRelatedGroupsResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<AccountRelatedGroupsResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/groups' \
+ * -d '{"groupAccounts":[{"groupId":"1"},{"groupId":"2"}]}'
+ *
+ *
+ * @param id
+ * @param groupAccounts
+ * @return
+ */
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/groups", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<AccountRelateGroupsResponseData> relateGroups(
+ @PathVariable("id") String id,
+ @RequestBody AccountRelateGroupsRequest accountGroups) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account tmp = accountService.selectById(id);
+
+ if (tmp == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ accountService.relateAccountGroups(tmp, accountGroups.getAccountGroups());
+
+ AccountRelateGroupsResponseData data = AccountRelateGroupsResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<AccountRelateGroupsResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/roles'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/roles?pageIndex=2&pageSize=50'
+ * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/roles?pageIndex=0&pageSize=20&mapBean[roleCode]=roleCode&mapBean[roleName]=roleName'
+ *
+ *
+ *
+ * @param id
+ * @param pagerRequestModel
+ * @return
+ */
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<AccountRelatedRolesResponseData> accountRoles(
+ @PathVariable("id") String id,
+ AccountRelatedRolesRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account account = accountService.selectById(id);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("accountId", account.getId());
+
+ Page<AccountRole> page = accountService.selectAccountRoles(request.getPageIndex(),
+ request.getPageSize(), request.getMapBean());
+
+ AccountRelatedRolesResponseData data = AccountRelatedRolesResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<AccountRelatedRolesResponseData>(data);
+ }
+
+ /**
+ *
+ * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:8081/api/v1/admin/accounts/1/roles' \
+ * -d '{"accountRoles":[{"roleId":"1"},{"roleId":"2"}]}'
+ *
+ *
+ * @param id
+ * @param accountRoles
+ * @return
+ */
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/roles", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<AccountRelateRolesResponseData> relateRoles(
+ @PathVariable("id") String id,
+ @RequestBody AccountRelateRolesRequest accountRoles) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Account account = accountService.selectById(id);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ accountService.relateAccountRoles(account, accountRoles.getAccountRoles());
+
+ AccountRelateRolesResponseData data = AccountRelateRolesResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<AccountRelateRolesResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminApplicationController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminApplicationController.java
new file mode 100644
index 0000000..02fb24b
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminApplicationController.java
@@ -0,0 +1,165 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ApplicationCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ApplicationDeleteBatchRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ApplicationQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ApplicationUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationDeleteBatchResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ApplicationUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.base.domain.service.ApplicationService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminApplication", tags = { "BaseAdminApplication" }, description = "应用的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/applications")
+public class AdminApplicationController {
+
+ @Autowired
+ private ApplicationService applicationService;
+
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationQueryResponseData> query(ApplicationQueryRequest queryRequest) {
+
+ Page<Application> page = applicationService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ ApplicationQueryResponseData data = ApplicationQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<ApplicationQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Application application = applicationService.selectById(id);
+
+ if (application == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ ApplicationLoadResponseData data = ApplicationLoadResponseData.of(application);
+
+ return new DefaultApiResponse<ApplicationLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationCreateResponseData> create(
+ @RequestBody ApplicationCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Application application = createRequest.getEntity();
+
+ Application ret = applicationService.insert(application);
+
+ ApplicationCreateResponseData data = ApplicationCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<ApplicationCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody ApplicationUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Application tmp = applicationService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Application application = updateRequest.getEntity();
+ application.setId(id);
+
+ application = EntityUtils.merge(tmp, application);
+
+ Application ret = applicationService.update(application);
+
+ ApplicationUpdateResponseData data = ApplicationUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<ApplicationUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Application tmp = applicationService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ applicationService.deleteById(id);
+
+ ApplicationRemoveResponseData data = ApplicationRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<ApplicationRemoveResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/batch", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ApplicationDeleteBatchResponseData> deleteBatch(
+ @RequestBody ApplicationDeleteBatchRequest deleteBatchRequest) {
+
+ List<String> ids = deleteBatchRequest.getIds();
+
+ applicationService.deleteBatch(ids);
+
+ ApplicationDeleteBatchResponseData data = ApplicationDeleteBatchResponseData.build(ids);
+ return new DefaultApiResponse<ApplicationDeleteBatchResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminConfigController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminConfigController.java
new file mode 100644
index 0000000..4b38209
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminConfigController.java
@@ -0,0 +1,198 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ConfigCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ConfigQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ConfigUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ConfigCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ConfigLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ConfigQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ConfigUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.base.domain.exception.ConfigException;
+import com.supwisdom.institute.backend.base.domain.service.ConfigService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminConfig", tags = { "BaseAdminConfig" }, description = "配置项的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/configs")
+public class AdminConfigController {
+
+ @Autowired
+ private ConfigService configService;
+
+
+ /**
+ * @param configQueryRequest
+ * @return
+ */
+ @ApiOperation(value = "查询配置列表", notes = "查询配置列表", nickname = "systemAdminConfigQuery")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "loadAll", value = "是否加载全部", required = true, dataType = "boolean", paramType = "query", defaultValue = "false"),
+ @ApiImplicitParam(name = "pageIndex", value = "分页 - 页码", required = true, dataType = "int", paramType = "query", defaultValue = "0", example = "0"),
+ @ApiImplicitParam(name = "pageSize", value = "分页 - 每页记录数", required = true, dataType = "int", paramType = "query", defaultValue = "20", example = "20"),
+ @ApiImplicitParam(name = "mapBean[deleted]", value = "查询条件 - 删除状态 (精确)", required = false, dataType = "boolean", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[categoryCode]", value = "查询条件 - 分类代码 (精确)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[categoryName]", value = "查询条件 - 分类名称 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[name]", value = "查询条件 - 名称 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[description]", value = "查询条件 - 描述 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[configKey]", value = "查询条件 - 配置Key (精确)", required = false, dataType = "string", paramType = "query"),
+ })
+ @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ConfigQueryResponseData> query(ConfigQueryRequest configQueryRequest) {
+
+ Page<Config> page = configService.selectPageList(
+ configQueryRequest.isLoadAll(),
+ configQueryRequest.getPageIndex(),
+ configQueryRequest.getPageSize(),
+ configQueryRequest.getMapBean(),
+ configQueryRequest.getOrderBy());
+
+ ConfigQueryResponseData resp = ConfigQueryResponseData.of(configQueryRequest).build(page);
+
+ return new DefaultApiResponse<ConfigQueryResponseData>(resp);
+ }
+
+ /**
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "根据ID获取配置项", notes = "根据ID获取配置项", nickname="systemAdminConfigLoad")
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ConfigLoadResponseData> load(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new ConfigException().newInstance("exception.get.id.must.not.empty");
+ }
+
+ Config config = configService.selectById(id);
+
+ if (config == null) {
+ throw new ConfigException().newInstance("exception.get.domain.not.exist");
+ }
+
+ ConfigLoadResponseData resp = ConfigLoadResponseData.build(config);
+
+ return new DefaultApiResponse<ConfigLoadResponseData>(resp);
+ }
+
+ /**
+ * @param configCreateRequest
+ * @return
+ */
+ @ApiOperation(value = "创建配置项", notes = "创建配置项", nickname = "systemAdminConfigCreate")
+ @RequestMapping(method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.CREATED)
+ @ResponseBody
+ public DefaultApiResponse<ConfigCreateResponseData> create(
+ @RequestBody ConfigCreateRequest configCreateRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Config entity = configCreateRequest.getEntity();
+
+ Config ret = configService.insert(entity);
+
+ ConfigCreateResponseData resp = ConfigCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<ConfigCreateResponseData>(resp);
+ }
+
+ @ApiOperation(value = "更新配置项", notes = "更新配置项", nickname = "systemAdminConfigUpdate")
+ @RequestMapping(method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ConfigUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody ConfigUpdateRequest configUpdateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new ConfigException().newInstance("exception.update.id.must.not.empty");
+ }
+
+ Config tmp = configService.selectById(id);
+ if (tmp == null) {
+ throw new ConfigException().newInstance("exception.update.domain.not.exist");
+ }
+
+ if (!tmp.getEditable().booleanValue()) {
+ throw new ConfigException().newInstance("exception.editable.can.not.update");
+ }
+
+ Config entity = configUpdateRequest.getEntity();
+ entity.setId(id);
+
+ entity = EntityUtils.merge(tmp, entity);
+
+// if (tmp.getEditable().booleanValue() != entity.getEditable().booleanValue()) {
+// throw new ConfigException().newInstance("exception.editable.can.not.update");
+// }
+
+ entity.setEditable(true); // 防止 可修改记录的 editable 被置为false
+
+ Config ret = configService.update(entity);
+
+ ConfigUpdateResponseData resp = ConfigUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<ConfigUpdateResponseData>(resp);
+ }
+
+
+ /**
+ * @param categoryCode
+ * @param configKey
+ * @return
+ */
+ @ApiOperation(value = "根据 categoryCode、configKey 获取配置项", notes = "根据 categoryCode、configKey 获取配置项", nickname = "systemAdminConfigLoadByCategoryKey")
+ @RequestMapping(method = RequestMethod.GET, path = "/loadByCategoryKey", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ConfigLoadResponseData> loadByCategoryKey(
+ @RequestParam("categoryCode") String categoryCode,
+ @RequestParam("configKey") String configKey
+ ) {
+
+ if (categoryCode == null || categoryCode.length() == 0) {
+ throw new ConfigException().newInstance("exception.load.params.must.not.empty");
+ }
+ if (configKey == null || configKey.length() == 0) {
+ throw new ConfigException().newInstance("exception.load.params.must.not.empty");
+ }
+
+ Config config = configService.selectByCategoryKey(categoryCode, configKey);
+
+ if (config == null) {
+ throw new ConfigException().newInstance("exception.load.domain.not.exist");
+ }
+
+ ConfigLoadResponseData resp = ConfigLoadResponseData.build(config);
+
+ return new DefaultApiResponse<ConfigLoadResponseData>(resp);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminGroupController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminGroupController.java
new file mode 100644
index 0000000..c9a28d7
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminGroupController.java
@@ -0,0 +1,270 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.HashMap;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupRelateAccountsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupRelateRolesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupRelatedAccountsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupRelatedRolesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.GroupUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupRelateAccountsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupRelateRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupRelatedAccountsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupRelatedRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.GroupUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.base.domain.service.GroupService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminGroup", tags = { "BaseAdminGroup" }, description = "用户组的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/groups")
+public class AdminGroupController {
+
+ @Autowired
+ private GroupService groupService;
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<GroupQueryResponseData> query(GroupQueryRequest queryRequest) {
+
+ Page<Group> page = groupService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ GroupQueryResponseData data = GroupQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<GroupQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<GroupLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group group = groupService.selectById(id);
+
+ if (group == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ GroupLoadResponseData data = GroupLoadResponseData.of(group);
+
+ return new DefaultApiResponse<GroupLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<GroupCreateResponseData> create(
+ @RequestBody GroupCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Group group = createRequest.getEntity();
+
+ Group ret = groupService.insert(group);
+
+ GroupCreateResponseData data = GroupCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<GroupCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<GroupUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody GroupUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Group tmp = groupService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Group group = updateRequest.getEntity();
+ group.setId(id);
+
+ group = EntityUtils.merge(tmp, group);
+
+ Group ret = groupService.update(group);
+
+ GroupUpdateResponseData data = GroupUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<GroupUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<GroupRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group tmp = groupService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ groupService.deleteById(id);
+
+ GroupRemoveResponseData data = GroupRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<GroupRemoveResponseData>(data);
+ }
+
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/accounts", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<GroupRelatedAccountsResponseData> groupAccounts(
+ @PathVariable("id") String id,
+ GroupRelatedAccountsRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group group = groupService.selectById(id);
+
+ if (group == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("groupId", group.getId());
+
+ Page<AccountGroup> page = groupService.selectGroupAccounts(
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ GroupRelatedAccountsResponseData data = GroupRelatedAccountsResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<GroupRelatedAccountsResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/accounts", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<GroupRelateAccountsResponseData> relateAccounts(
+ @PathVariable("id") String id,
+ @RequestBody GroupRelateAccountsRequest groupAccounts) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group group = groupService.selectById(id);
+
+ if (group == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ groupService.relateGroupAccounts(group, groupAccounts.getGroupAccounts());
+
+ GroupRelateAccountsResponseData data = GroupRelateAccountsResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<GroupRelateAccountsResponseData>(data);
+ }
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<GroupRelatedRolesResponseData> groupRoles(
+ @PathVariable("id") String id,
+ GroupRelatedRolesRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group group = groupService.selectById(id);
+
+ if (group == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("groupId", group.getId());
+
+ Page<GroupRole> page = groupService.selectGroupRoles(
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ GroupRelatedRolesResponseData data = GroupRelatedRolesResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<GroupRelatedRolesResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/roles", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<GroupRelateRolesResponseData> relateRoles(
+ @PathVariable("id") String id,
+ @RequestBody GroupRelateRolesRequest groupRoles) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Group group = groupService.selectById(id);
+
+ if (group == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ groupService.relateGroupRoles(group, groupRoles.getGroupRoles());
+
+ GroupRelateRolesResponseData data = GroupRelateRolesResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<GroupRelateRolesResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminMenuController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminMenuController.java
new file mode 100644
index 0000000..d4ebef0
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminMenuController.java
@@ -0,0 +1,209 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionDeleteBatchRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionDeleteBatchResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionTreeResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.base.domain.model.PermissionTreeNode;
+import com.supwisdom.institute.backend.base.domain.service.PermissionService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminMenu", tags = { "BaseAdminMenu" }, description = "菜单的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/menus")
+public class AdminMenuController {
+
+ @Autowired
+ private PermissionService permissionService;
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionQueryResponseData> query(PermissionQueryRequest queryRequest) {
+
+ if (queryRequest.getMapBean() == null) {
+ queryRequest.setMapBean(new HashMap<String, Object>());
+ }
+ queryRequest.getMapBean().put("type", Permission.TYPE_MENU);
+
+ Page<Permission> page = permissionService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ PermissionQueryResponseData data = PermissionQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<PermissionQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission permission = permissionService.selectById(id);
+
+ if (permission == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+ if (!Permission.TYPE_MENU.equals(permission.getType())) {
+ throw new RuntimeException("exception.get.domain.type.error");
+ }
+
+ List<String> resourceIds = new ArrayList<>();
+
+ Map<String, Object> mapBean = new HashMap<>();
+ mapBean.put("permissionId", id);
+ Page<PermissionResource> permissionResources = permissionService.selectPermissionResources(true, 0, 0, mapBean);
+ for (PermissionResource permissionResource : permissionResources) {
+ resourceIds.add(permissionResource.getResourceId());
+ }
+
+ PermissionLoadResponseData data = PermissionLoadResponseData.of(permission, resourceIds);
+
+ return new DefaultApiResponse<PermissionLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionCreateResponseData> create(
+ @RequestBody PermissionCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Permission permission = createRequest.getEntity();
+ permission.setType(Permission.TYPE_MENU);
+
+ Permission ret = permissionService.insert(permission);
+
+ PermissionCreateResponseData data = PermissionCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<PermissionCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody PermissionUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Permission tmp = permissionService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+ if (!Permission.TYPE_MENU.equals(tmp.getType())) {
+ throw new RuntimeException("exception.update.domain.type.error");
+ }
+
+ Permission permission = updateRequest.getEntity();
+ permission.setId(id);
+
+ permission = EntityUtils.merge(tmp, permission);
+
+ Permission ret = permissionService.update(permission);
+
+ PermissionUpdateResponseData data = PermissionUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<PermissionUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission tmp = permissionService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+ if (!Permission.TYPE_MENU.equals(tmp.getType())) {
+ throw new RuntimeException("exception.delete.domain.type.error");
+ }
+
+ permissionService.deleteById(id);
+
+ PermissionRemoveResponseData data = PermissionRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<PermissionRemoveResponseData>(data);
+ }
+
+
+ @DeleteMapping(path = "/batch", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionDeleteBatchResponseData> deleteBatch(
+ @RequestBody PermissionDeleteBatchRequest deleteBatchRequest) {
+
+ List<String> ids = deleteBatchRequest.getIds();
+
+ permissionService.deleteBatch(ids);
+
+ PermissionDeleteBatchResponseData data = PermissionDeleteBatchResponseData.build(ids);
+ return new DefaultApiResponse<PermissionDeleteBatchResponseData>(data);
+ }
+
+ @GetMapping(path = "/tree", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionTreeResponseData> tree(
+ @RequestParam(name = "applicationId", required = false, defaultValue = Permission.APPLICATION_ID) String applicationId) {
+
+ PermissionTreeNode tree = permissionService.selectPermissionTree(applicationId, Permission.TYPE_MENU);
+
+ PermissionTreeResponseData data = PermissionTreeResponseData.of(tree);
+
+ return new DefaultApiResponse<PermissionTreeResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminOperationController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminOperationController.java
new file mode 100644
index 0000000..e84e2e0
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminOperationController.java
@@ -0,0 +1,177 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import io.swagger.annotations.Api;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.base.domain.service.PermissionService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminOperation", tags = { "BaseAdminOperation" }, description = "操作的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/operations")
+public class AdminOperationController {
+
+ @Autowired
+ private PermissionService permissionService;
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionQueryResponseData> query(PermissionQueryRequest queryRequest) {
+
+ if (queryRequest.getMapBean() == null) {
+ queryRequest.setMapBean(new HashMap<String, Object>());
+ }
+ queryRequest.getMapBean().put("type", Permission.TYPE_OPERATION);
+
+ Page<Permission> page = permissionService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ PermissionQueryResponseData data = PermissionQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<PermissionQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission permission = permissionService.selectById(id);
+
+ if (permission == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+ if (!Permission.TYPE_OPERATION.equals(permission.getType())) {
+ throw new RuntimeException("exception.get.domain.type.error");
+ }
+
+ List<String> resourceIds = new ArrayList<>();
+
+ Map<String, Object> mapBean = new HashMap<>();
+ mapBean.put("permissionId", id);
+ Page<PermissionResource> permissionResources = permissionService.selectPermissionResources(true, 0, 0, mapBean);
+ for (PermissionResource permissionResource : permissionResources) {
+ resourceIds.add(permissionResource.getResourceId());
+ }
+
+ PermissionLoadResponseData data = PermissionLoadResponseData.of(permission, resourceIds);
+
+ return new DefaultApiResponse<PermissionLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionCreateResponseData> create(
+ @RequestBody PermissionCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Permission permission = createRequest.getEntity();
+ permission.setType(Permission.TYPE_OPERATION);
+
+ Permission ret = permissionService.insert(permission);
+
+ PermissionCreateResponseData data = PermissionCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<PermissionCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody PermissionUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Permission tmp = permissionService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+ if (!Permission.TYPE_OPERATION.equals(tmp.getType())) {
+ throw new RuntimeException("exception.update.domain.type.error");
+ }
+
+ Permission permission = updateRequest.getEntity();
+ permission.setId(id);
+
+ permission = EntityUtils.merge(tmp, permission);
+
+ Permission ret = permissionService.update(permission);
+
+ PermissionUpdateResponseData data = PermissionUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<PermissionUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission tmp = permissionService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+ if (!Permission.TYPE_OPERATION.equals(tmp.getType())) {
+ throw new RuntimeException("exception.delete.domain.type.error");
+ }
+
+ permissionService.deleteById(id);
+
+ PermissionRemoveResponseData data = PermissionRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<PermissionRemoveResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminPermissionController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminPermissionController.java
new file mode 100644
index 0000000..a415095
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminPermissionController.java
@@ -0,0 +1,108 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.HashMap;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionRelateResourcesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.PermissionRelatedResourcesRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionRelateResourcesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionRelatedResourcesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.PermissionTreeResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.base.domain.model.PermissionTreeNode;
+import com.supwisdom.institute.backend.base.domain.service.PermissionService;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminPermission", tags = { "BaseAdminPermission" }, description = "权限的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/permissions")
+public class AdminPermissionController {
+
+ @Autowired
+ private PermissionService permissionService;
+
+ @GetMapping(path = "/tree", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<PermissionTreeResponseData> tree() {
+
+ PermissionTreeNode tree = permissionService.selectPermissionTree(Permission.APPLICATION_ID, null);
+
+ PermissionTreeResponseData data = PermissionTreeResponseData.of(tree);
+
+ return new DefaultApiResponse<PermissionTreeResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/resources", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<PermissionRelatedResourcesResponseData> permissionResources(
+ @PathVariable("id") String id,
+ PermissionRelatedResourcesRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission permission = permissionService.selectById(id);
+
+ if (permission == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("permissionId", permission.getId());
+
+ Page<PermissionResource> page = permissionService.selectPermissionResources(
+ request.isLoadAll(),
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ PermissionRelatedResourcesResponseData data = PermissionRelatedResourcesResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<PermissionRelatedResourcesResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/resources", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<PermissionRelateResourcesResponseData> relateResources(
+ @PathVariable("id") String id,
+ @RequestBody PermissionRelateResourcesRequest permissionResources) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Permission permission = permissionService.selectById(id);
+
+ if (permission == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ permissionService.relatePermissionResources(permission, permissionResources.getPermissionResources());
+
+ PermissionRelateResourcesResponseData data = PermissionRelateResourcesResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<PermissionRelateResourcesResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminResourceController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminResourceController.java
new file mode 100644
index 0000000..5594269
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminResourceController.java
@@ -0,0 +1,146 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ResourceCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ResourceQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ResourceUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ResourceCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ResourceLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ResourceQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ResourceRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.ResourceUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.base.domain.service.ResourceService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminResource", tags = { "BaseAdminResource" }, description = "资源(API)的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/resources")
+public class AdminResourceController {
+
+ @Autowired
+ private ResourceService resourceService;
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ResourceQueryResponseData> query(ResourceQueryRequest queryRequest) {
+
+ Page<Resource> page = resourceService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ ResourceQueryResponseData data = ResourceQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<ResourceQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ResourceLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Resource resource = resourceService.selectById(id);
+
+ if (resource == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ ResourceLoadResponseData data = ResourceLoadResponseData.of(resource);
+
+ return new DefaultApiResponse<ResourceLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ResourceCreateResponseData> create(
+ @RequestBody ResourceCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Resource resource = createRequest.getEntity();
+
+ Resource ret = resourceService.insert(resource);
+
+ ResourceCreateResponseData data = ResourceCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<ResourceCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ResourceUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody ResourceUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Resource tmp = resourceService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Resource resource = updateRequest.getEntity();
+ resource.setId(id);
+
+ resource = EntityUtils.merge(tmp, resource);
+
+ Resource ret = resourceService.update(resource);
+
+ ResourceUpdateResponseData data = ResourceUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<ResourceUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<ResourceRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Resource tmp = resourceService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ resourceService.deleteById(id);
+
+ ResourceRemoveResponseData data = ResourceRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<ResourceRemoveResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRoleController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRoleController.java
new file mode 100644
index 0000000..b45bc25
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRoleController.java
@@ -0,0 +1,346 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.HashMap;
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleDeleteBatchRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelateAccountsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelateGroupsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelatePermissionsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelatedAccountsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelatedGroupsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleRelatedPermissionsRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RoleUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleDeleteBatchResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelateAccountsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelateGroupsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelatePermissionsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelatedAccountsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelatedGroupsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRelatedPermissionsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RoleUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.entity.RolePermission;
+import com.supwisdom.institute.backend.base.domain.service.RoleService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminRole", tags = { "BaseAdminRole" }, description = "角色的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/roles")
+public class AdminRoleController {
+
+ @Autowired
+ private RoleService roleService;
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleQueryResponseData> query(RoleQueryRequest queryRequest) {
+
+ Page<Role> page = roleService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ RoleQueryResponseData data = RoleQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<RoleQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ RoleLoadResponseData data = RoleLoadResponseData.of(role);
+
+ return new DefaultApiResponse<RoleLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleCreateResponseData> create(
+ @RequestBody RoleCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Role role = createRequest.getEntity();
+
+ Role ret = roleService.insert(role);
+
+ RoleCreateResponseData data = RoleCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<RoleCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody RoleUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Role tmp = roleService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Role role = updateRequest.getEntity();
+ role.setId(id);
+
+ role = EntityUtils.merge(tmp, role);
+
+ Role ret = roleService.update(role);
+
+ RoleUpdateResponseData data = RoleUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<RoleUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role tmp = roleService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ roleService.deleteById(id);
+
+ RoleRemoveResponseData data = RoleRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<RoleRemoveResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/batch", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleDeleteBatchResponseData> deleteBatch(
+ @RequestBody RoleDeleteBatchRequest deleteBatchRequest) {
+
+ List<String> ids = deleteBatchRequest.getIds();
+
+ roleService.deleteBatch(ids);
+
+ RoleDeleteBatchResponseData data = RoleDeleteBatchResponseData.build(ids);
+ return new DefaultApiResponse<RoleDeleteBatchResponseData>(data);
+ }
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/accounts", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelatedAccountsResponseData> roleAccounts(
+ @PathVariable("id") String id,
+ RoleRelatedAccountsRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("roleId", role.getId());
+
+ Page<AccountRole> page = roleService.selectRoleAccounts(
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ RoleRelatedAccountsResponseData data = RoleRelatedAccountsResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<RoleRelatedAccountsResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/accounts", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelateAccountsResponseData> relateAccounts(
+ @PathVariable("id") String id,
+ @RequestBody RoleRelateAccountsRequest roleAccounts) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ roleService.relateRoleAccounts(role, roleAccounts.getRoleAccounts());
+
+ RoleRelateAccountsResponseData data = RoleRelateAccountsResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<RoleRelateAccountsResponseData>(data);
+ }
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/groups", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelatedGroupsResponseData> roleGroups(
+ @PathVariable("id") String id,
+ RoleRelatedGroupsRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("roleId", role.getId());
+
+ Page<GroupRole> page = roleService.selectRoleGroups(
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ RoleRelatedGroupsResponseData data = RoleRelatedGroupsResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<RoleRelatedGroupsResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/groups", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelateGroupsResponseData> relateGroups(
+ @PathVariable("id") String id,
+ @RequestBody RoleRelateGroupsRequest roleGroups) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ roleService.relateRoleGroups(role, roleGroups.getRoleGroups());
+
+ RoleRelateGroupsResponseData data = RoleRelateGroupsResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<RoleRelateGroupsResponseData>(data);
+ }
+
+
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}/permissions", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelatedPermissionsResponseData> rolePermissions(
+ @PathVariable("id") String id,
+ RoleRelatedPermissionsRequest request) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ if (request.getMapBean() == null) {
+ request.setMapBean(new HashMap<String, Object>());
+ }
+ request.getMapBean().put("roleId", role.getId());
+
+ Page<RolePermission> page = roleService.selectRolePermissions(
+ request.getPageIndex(),
+ request.getPageSize(),
+ request.getMapBean());
+
+ RoleRelatedPermissionsResponseData data = RoleRelatedPermissionsResponseData.of(request).build(page);
+
+ return new DefaultApiResponse<RoleRelatedPermissionsResponseData>(data);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, path = "/{id}/permissions", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseBody
+ public DefaultApiResponse<RoleRelatePermissionsResponseData> relatePermissions(
+ @PathVariable("id") String id,
+ @RequestBody RoleRelatePermissionsRequest rolePermissions) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Role role = roleService.selectById(id);
+
+ if (role == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ roleService.relateRolePermissions(role, rolePermissions.getRolePermissions());
+
+ RoleRelatePermissionsResponseData data = RoleRelatePermissionsResponseData.of("info.relate.success");
+
+ return new DefaultApiResponse<RoleRelatePermissionsResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRouteController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRouteController.java
new file mode 100644
index 0000000..a52334d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/admin/AdminRouteController.java
@@ -0,0 +1,165 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.admin;
+
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RouteCreateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RouteDeleteBatchRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RouteQueryRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.RouteUpdateRequest;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteCreateResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteDeleteBatchResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteLoadResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteQueryResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteRemoveResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.response.RouteUpdateResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.base.domain.service.RouteService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAdminRoute", tags = { "BaseAdminRoute" }, description = "路由信息的操作接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/routes")
+public class AdminRouteController {
+
+ @Autowired
+ private RouteService routeService;
+
+
+ @GetMapping(produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteQueryResponseData> query(RouteQueryRequest queryRequest) {
+
+ Page<Route> page = routeService.selectPageList(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy());
+
+ RouteQueryResponseData data = RouteQueryResponseData.of(queryRequest).build(page);
+
+ return new DefaultApiResponse<RouteQueryResponseData>(data);
+ }
+
+ @GetMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteLoadResponseData> load(@PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Route route = routeService.selectById(id);
+
+ if (route == null) {
+ throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+ }
+
+ RouteLoadResponseData data = RouteLoadResponseData.of(route);
+
+ return new DefaultApiResponse<RouteLoadResponseData>(data);
+ }
+
+ @PostMapping(consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteCreateResponseData> create(
+ @RequestBody RouteCreateRequest createRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Route route = createRequest.getEntity();
+
+ Route ret = routeService.insert(route);
+
+ RouteCreateResponseData data = RouteCreateResponseData.build(ret);
+
+ return new DefaultApiResponse<RouteCreateResponseData>(data);
+ }
+
+ @PutMapping(path = "/{id}", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody RouteUpdateRequest updateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.update.id.must.not.empty");
+ }
+
+ Route tmp = routeService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.update.domain.not.exist");
+ }
+
+ Route route = updateRequest.getEntity();
+ route.setId(id);
+
+ route = EntityUtils.merge(tmp, route);
+
+ Route ret = routeService.update(route);
+
+ RouteUpdateResponseData data = RouteUpdateResponseData.build(ret);
+
+ return new DefaultApiResponse<RouteUpdateResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteRemoveResponseData> delete(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw new RuntimeException("exception.delete.id.must.not.empty"); // FIXME: RestException
+ }
+
+ Route tmp = routeService.selectById(id);
+ if (tmp == null) {
+ throw new RuntimeException("exception.delete.domain.not.exist"); // FIXME: RestException
+ }
+
+ routeService.deleteById(id);
+
+ RouteRemoveResponseData data = RouteRemoveResponseData.build(tmp);
+ return new DefaultApiResponse<RouteRemoveResponseData>(data);
+ }
+
+ @DeleteMapping(path = "/batch", consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RouteDeleteBatchResponseData> deleteBatch(
+ @RequestBody RouteDeleteBatchRequest deleteBatchRequest) {
+
+ List<String> ids = deleteBatchRequest.getIds();
+
+ routeService.deleteBatch(ids);
+
+ RouteDeleteBatchResponseData data = RouteDeleteBatchResponseData.build(ids);
+ return new DefaultApiResponse<RouteDeleteBatchResponseData>(data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/authn/AuthnController.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/authn/AuthnController.java
new file mode 100644
index 0000000..d79f298
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/controller/authn/AuthnController.java
@@ -0,0 +1,320 @@
+package com.supwisdom.institute.backend.base.api.v1.controller.authn;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnAccountPermissionsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnAccountResourcesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnAccountResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnAccountRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnApplicationsResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnPermissionRoleListResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnResourceRoleListResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnRolesResponseData;
+import com.supwisdom.institute.backend.base.api.v1.vo.authn.response.AuthnRoutesResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.base.domain.model.PermissionRoleSet;
+import com.supwisdom.institute.backend.base.domain.model.ResourceRoleSet;
+import com.supwisdom.institute.backend.base.domain.service.AccountService;
+import com.supwisdom.institute.backend.base.domain.service.ApplicationService;
+import com.supwisdom.institute.backend.base.domain.service.PermissionService;
+import com.supwisdom.institute.backend.base.domain.service.ResourceService;
+import com.supwisdom.institute.backend.base.domain.service.RoleService;
+import com.supwisdom.institute.backend.base.domain.service.RouteService;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAuthn", tags = { "BaseAuthn" }, description = "认证授权接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/authn")
+public class AuthnController {
+
+ @Autowired
+ private AccountService accountService;
+
+ @Autowired
+ private RoleService roleService;
+
+ @Autowired
+ private ApplicationService applicationService;
+
+ @Autowired
+ private PermissionService permissionService;
+
+ @Autowired
+ private ResourceService resourceService;
+
+ @Autowired
+ private RouteService routeService;
+
+ @GetMapping(path = "/{username}/account", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountResponseData> account(
+ @PathVariable("username") String username) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ AuthnAccountResponseData data = AuthnAccountResponseData.of(account);
+
+ return new DefaultApiResponse<AuthnAccountResponseData>(data);
+ }
+
+ @GetMapping(path = "/{username}/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountRolesResponseData> accountRoles(
+ @PathVariable("username") String username) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ List<Role> roles = roleService.selectByUsername(username);
+
+ AuthnAccountRolesResponseData data = AuthnAccountRolesResponseData.of(roles);
+
+ return new DefaultApiResponse<AuthnAccountRolesResponseData>(data);
+ }
+
+ @GetMapping(path = "/{username}/applications", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountPermissionsResponseData> accountApplications(
+ @PathVariable("username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ List<Permission> applications = permissionService.selectByUsername(username, null, Permission.TYPE_APPLICATION);
+
+ AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(applications);
+
+ return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+ }
+
+ @GetMapping(path = "/{username}/menus", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountPermissionsResponseData> accountMenus(
+ @PathVariable("username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ List<Permission> menus = permissionService.selectByUsername(username, applicationId, Permission.TYPE_MENU);
+
+ AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(menus);
+
+ return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+ }
+
+ @GetMapping(path = "/{username}/operations", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountPermissionsResponseData> accountOperations(
+ @PathVariable("username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ List<Permission> operations = permissionService.selectByUsername(username, applicationId, Permission.TYPE_OPERATION);
+
+ AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(operations);
+
+ return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+ }
+
+ @GetMapping(path = "/{username}/resources", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnAccountResourcesResponseData> accountResources(
+ @PathVariable("username") String username,
+ @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ Account account = accountService.selectByUsername(username);
+
+ if (account == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ List<Resource> resources = null;// FIXME: resourceService.selectByUsername(username, applicationId);
+
+ AuthnAccountResourcesResponseData data = AuthnAccountResourcesResponseData.of(resources);
+
+ return new DefaultApiResponse<AuthnAccountResourcesResponseData>(data);
+ }
+
+// @GetMapping(path = "/resources", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+// @ResponseStatus(value = HttpStatus.OK)
+// @ResponseBody
+// public DefaultApiResponse<AuthnResourceRoleListResponseData> applicationResources(
+// @RequestParam(name = "applicationId", required = false) String applicationId) {
+//
+// List<ResourceRoleSet> resourceRoleSets = resourceService.selectByApplication(applicationId);
+//
+// AuthnResourceRoleListResponseData data = AuthnResourceRoleListResponseData.of(resourceRoleSets);
+//
+// return new DefaultApiResponse<AuthnResourceRoleListResponseData>(data);
+// }
+
+
+ @GetMapping(path = "/applications", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnApplicationsResponseData> applications() {
+
+ Map<String, Object> mapBean = new HashMap<>();
+ Map<String, String> orderBy = null;
+
+ mapBean.put("status", "1");
+
+ List<Application> applications = applicationService.selectList(mapBean, orderBy);
+
+ AuthnApplicationsResponseData data = AuthnApplicationsResponseData.of(applications);
+
+ return new DefaultApiResponse<AuthnApplicationsResponseData>(data);
+ }
+
+ @GetMapping(path = "/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnRolesResponseData> roles() {
+
+ Map<String, Object> mapBean = new HashMap<>();
+ Map<String, String> orderBy = null;
+
+ mapBean.put("status", "1");
+
+ List<Role> roles = roleService.selectList(mapBean, orderBy);
+
+ AuthnRolesResponseData data = AuthnRolesResponseData.of(roles);
+
+ return new DefaultApiResponse<AuthnRolesResponseData>(data);
+ }
+
+
+ @GetMapping(path = "/permissionRoleSets", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnPermissionRoleListResponseData> permissionRoleSets(
+ @RequestParam(name = "applicationId", required = false, defaultValue = Permission.APPLICATION_ID) String applicationId) {
+
+ Map<String, Object> mapBean = new HashMap<>();
+
+ mapBean.put("status", "1");
+ if (applicationId != null && !applicationId.isEmpty()) {
+ mapBean.put("applicationId", applicationId);
+ }
+
+ List<PermissionRoleSet> permissionRoleSets = permissionService.selectPermissionRoleSet(mapBean);
+
+ AuthnPermissionRoleListResponseData data = AuthnPermissionRoleListResponseData.of(permissionRoleSets);
+
+ return new DefaultApiResponse<AuthnPermissionRoleListResponseData>(data);
+ }
+
+
+ @GetMapping(path = "/resourceRoleSets", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnResourceRoleListResponseData> resourceRoleSets(
+ @RequestParam(name = "applicationId", required = false, defaultValue = Permission.APPLICATION_ID) String applicationId) {
+
+ Map<String, Object> mapBean = new HashMap<>();
+
+ mapBean.put("status", "1");
+ if (applicationId != null && !applicationId.isEmpty()) {
+ mapBean.put("applicationId", applicationId);
+ }
+
+ List<ResourceRoleSet> resourceRoleSets = resourceService.selectResourceRoleSet(mapBean);
+
+ AuthnResourceRoleListResponseData data = AuthnResourceRoleListResponseData.of(resourceRoleSets);
+
+ return new DefaultApiResponse<AuthnResourceRoleListResponseData>(data);
+ }
+
+
+
+ @GetMapping(path = "/routes", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<AuthnRoutesResponseData> routes() {
+
+ Map<String, Object> mapBean = new HashMap<>();
+ Map<String, String> orderBy = null;
+
+ mapBean.put("status", "1");
+
+ List<Route> routes = routeService.selectList(mapBean, orderBy);
+
+ AuthnRoutesResponseData data = AuthnRoutesResponseData.of(routes);
+
+ return new DefaultApiResponse<AuthnRoutesResponseData>(data);
+ }
+
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/.gitkeep b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/.gitkeep
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountCreateRequest.java
new file mode 100644
index 0000000..bf8cfc7
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class AccountCreateRequest extends Account implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3708476811446308442L;
+
+ public Account getEntity() {
+ return EntityUtils.copy(this, new Account());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountDeleteBatchRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountDeleteBatchRequest.java
new file mode 100644
index 0000000..d936658
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountDeleteBatchRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class AccountDeleteBatchRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5886243153431313069L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountQueryRequest.java
new file mode 100644
index 0000000..f31652f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class AccountQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8594346811904818135L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateGroupsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateGroupsRequest.java
new file mode 100644
index 0000000..acb37d9
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateGroupsRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class AccountRelateGroupsRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5685421340396797488L;
+
+ @Getter
+ @Setter
+ private List<AccountGroup> accountGroups;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateRolesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateRolesRequest.java
new file mode 100644
index 0000000..dc59b3f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelateRolesRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class AccountRelateRolesRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6612833201128786481L;
+
+ @Getter
+ @Setter
+ private List<AccountRole> accountRoles;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedGroupsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedGroupsRequest.java
new file mode 100644
index 0000000..d63a859
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedGroupsRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class AccountRelatedGroupsRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1998794079137356318L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedRolesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedRolesRequest.java
new file mode 100644
index 0000000..d484452
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountRelatedRolesRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class AccountRelatedRolesRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2118300523470868823L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountUpdateRequest.java
new file mode 100644
index 0000000..795c687
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/AccountUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class AccountUpdateRequest extends Account implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7297542338912221083L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Account getEntity() {
+ return EntityUtils.copy(this, new Account());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationCreateRequest.java
new file mode 100644
index 0000000..f950918
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class ApplicationCreateRequest extends Application implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7619506409619195684L;
+
+ public Application getEntity() {
+ return EntityUtils.copy(this, new Application());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationDeleteBatchRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationDeleteBatchRequest.java
new file mode 100644
index 0000000..62e69ed
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationDeleteBatchRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class ApplicationDeleteBatchRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8296636817441994821L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationQueryRequest.java
new file mode 100644
index 0000000..b4b6ea1
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class ApplicationQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4728297863070197861L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationUpdateRequest.java
new file mode 100644
index 0000000..12f8a49
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ApplicationUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ApplicationUpdateRequest extends Application implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2370390240675594737L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Application getEntity() {
+ return EntityUtils.copy(this, new Application());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigCreateRequest.java
new file mode 100644
index 0000000..6506f3b
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class ConfigCreateRequest extends Config implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8380208871984763567L;
+
+ public Config getEntity() {
+ return EntityUtils.copy(this, new Config());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigQueryRequest.java
new file mode 100644
index 0000000..53f2b29
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class ConfigQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1033044092932525382L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigUpdateRequest.java
new file mode 100644
index 0000000..6fd4fc9
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ConfigUpdateRequest.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ConfigUpdateRequest extends Config implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6002556449210326472L;
+
+ @Getter
+ @Setter
+ private String id;
+
+
+ public Config getEntity() {
+ return EntityUtils.copy(this, new Config());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupCreateRequest.java
new file mode 100644
index 0000000..8f60f9c
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class GroupCreateRequest extends Group implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5922604207821365121L;
+
+ public Group getEntity() {
+ return EntityUtils.copy(this, new Group());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupQueryRequest.java
new file mode 100644
index 0000000..ea610b3
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class GroupQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4023230222050081483L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateAccountsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateAccountsRequest.java
new file mode 100644
index 0000000..8b81132
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateAccountsRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class GroupRelateAccountsRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 440910731161851824L;
+
+ @Getter
+ @Setter
+ private List<AccountGroup> groupAccounts;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateRolesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateRolesRequest.java
new file mode 100644
index 0000000..52b4486
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelateRolesRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class GroupRelateRolesRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 795337416058792163L;
+
+ @Getter
+ @Setter
+ private List<GroupRole> groupRoles;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedAccountsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedAccountsRequest.java
new file mode 100644
index 0000000..6a1b13d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedAccountsRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class GroupRelatedAccountsRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3102006206798574212L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedRolesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedRolesRequest.java
new file mode 100644
index 0000000..6000d6a
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupRelatedRolesRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class GroupRelatedRolesRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6642264903131667637L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupUpdateRequest.java
new file mode 100644
index 0000000..63e82fd
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/GroupUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class GroupUpdateRequest extends Group implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6406242462582902819L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Group getEntity() {
+ return EntityUtils.copy(this, new Group());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionCreateRequest.java
new file mode 100644
index 0000000..e287f65
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionCreateRequest.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class PermissionCreateRequest extends Permission implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8247861768124918116L;
+
+ @Getter
+ @Setter
+ private List<String> resourceIds;
+
+ public Permission getEntity() {
+ return EntityUtils.copy(this, new Permission());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionDeleteBatchRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionDeleteBatchRequest.java
new file mode 100644
index 0000000..9777b30
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionDeleteBatchRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class PermissionDeleteBatchRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9180558051324597595L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionQueryRequest.java
new file mode 100644
index 0000000..d32f363
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class PermissionQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3944162671254599673L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelateResourcesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelateResourcesRequest.java
new file mode 100644
index 0000000..ae09876
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelateResourcesRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class PermissionRelateResourcesRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7016517754275684031L;
+
+ @Getter
+ @Setter
+ private List<PermissionResource> permissionResources;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelatedResourcesRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelatedResourcesRequest.java
new file mode 100644
index 0000000..4419071
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionRelatedResourcesRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class PermissionRelatedResourcesRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7634304817036292579L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionUpdateRequest.java
new file mode 100644
index 0000000..00d28c4
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/PermissionUpdateRequest.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class PermissionUpdateRequest extends Permission implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5923008482749557479L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private List<String> resourceIds;
+
+ public Permission getEntity() {
+ return EntityUtils.copy(this, new Permission());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceCreateRequest.java
new file mode 100644
index 0000000..3c17cac
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class ResourceCreateRequest extends Resource implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7999657157256566904L;
+
+ public Resource getEntity() {
+ return EntityUtils.copy(this, new Resource());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceQueryRequest.java
new file mode 100644
index 0000000..7171557
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class ResourceQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -911488989591489730L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceUpdateRequest.java
new file mode 100644
index 0000000..596cbd7
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/ResourceUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ResourceUpdateRequest extends Resource implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8922380312193462613L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Resource getEntity() {
+ return EntityUtils.copy(this, new Resource());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleCreateRequest.java
new file mode 100644
index 0000000..e91cfba
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class RoleCreateRequest extends Role implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5891171833738647843L;
+
+ public Role getEntity() {
+ return EntityUtils.copy(this, new Role());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleDeleteBatchRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleDeleteBatchRequest.java
new file mode 100644
index 0000000..94a23a5
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleDeleteBatchRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class RoleDeleteBatchRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3121491905067659896L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleQueryRequest.java
new file mode 100644
index 0000000..db54ea4
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class RoleQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8717113985995182773L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateAccountsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateAccountsRequest.java
new file mode 100644
index 0000000..1fc5848
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateAccountsRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class RoleRelateAccountsRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7935779803020137819L;
+
+ @Getter
+ @Setter
+ private List<AccountRole> roleAccounts;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateGroupsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateGroupsRequest.java
new file mode 100644
index 0000000..e400df4
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelateGroupsRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class RoleRelateGroupsRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9206282464451171269L;
+
+ @Getter
+ @Setter
+ private List<GroupRole> roleGroups;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatePermissionsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatePermissionsRequest.java
new file mode 100644
index 0000000..dc31c16
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatePermissionsRequest.java
@@ -0,0 +1,22 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.RolePermission;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class RoleRelatePermissionsRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7524940232102183145L;
+
+ @Getter
+ @Setter
+ private List<RolePermission> rolePermissions;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedAccountsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedAccountsRequest.java
new file mode 100644
index 0000000..2d8b77e
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedAccountsRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedAccountsRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1798385113493396290L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedGroupsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedGroupsRequest.java
new file mode 100644
index 0000000..b69aef5
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedGroupsRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedGroupsRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7253046382409370442L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedPermissionsRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedPermissionsRequest.java
new file mode 100644
index 0000000..7ff22a2
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleRelatedPermissionsRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedPermissionsRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5695303573516182415L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleUpdateRequest.java
new file mode 100644
index 0000000..b1137db
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RoleUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RoleUpdateRequest extends Role implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7272388577177587142L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Role getEntity() {
+ return EntityUtils.copy(this, new Role());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteCreateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteCreateRequest.java
new file mode 100644
index 0000000..f1af807
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteCreateRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class RouteCreateRequest extends Route implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1610189545107922L;
+
+ public Route getEntity() {
+ return EntityUtils.copy(this, new Route());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteDeleteBatchRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteDeleteBatchRequest.java
new file mode 100644
index 0000000..af2657c
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteDeleteBatchRequest.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiRequest;
+
+public class RouteDeleteBatchRequest implements IApiRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6325676083300813571L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteQueryRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteQueryRequest.java
new file mode 100644
index 0000000..b077d34
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteQueryRequest.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class RouteQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5501929058767629345L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+ @Getter
+ @Setter
+ private int pageSize = 20;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteUpdateRequest.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteUpdateRequest.java
new file mode 100644
index 0000000..e96eb28
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/request/RouteUpdateRequest.java
@@ -0,0 +1,28 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.request;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RouteUpdateRequest extends Route implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1999295284394866961L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ public Route getEntity() {
+ return EntityUtils.copy(this, new Route());
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountCreateResponseData.java
new file mode 100644
index 0000000..d4b91d8
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class AccountCreateResponseData extends Account implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8882701323050726169L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private AccountCreateResponseData() {
+
+ }
+
+ public static AccountCreateResponseData build(Account entity) {
+ AccountCreateResponseData data = new AccountCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountDeleteBatchResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountDeleteBatchResponseData.java
new file mode 100644
index 0000000..6c471ee
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountDeleteBatchResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+/**
+ * @author loie
+ */
+public class AccountDeleteBatchResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8625399816385346436L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+ private AccountDeleteBatchResponseData() {
+
+ }
+
+ public static AccountDeleteBatchResponseData build(List<String> ids) {
+ AccountDeleteBatchResponseData data = new AccountDeleteBatchResponseData();
+ data.setIds(ids);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountLoadResponseData.java
new file mode 100644
index 0000000..a9f250d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class AccountLoadResponseData extends Account implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8236721435440256832L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private AccountLoadResponseData() {
+
+ }
+
+ public static AccountLoadResponseData of(Account entity) {
+ AccountLoadResponseData data = new AccountLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountQueryResponseData.java
new file mode 100644
index 0000000..a36d033
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class AccountQueryResponseData implements IApiQueryResponseData<Account> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3949426339318397970L;
+
+ private AccountQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static AccountQueryResponseData of(IApiQueryRequest queryRequest) {
+ AccountQueryResponseData configQueryResponse = new AccountQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public AccountQueryResponseData build(Page<Account> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Account> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateGroupsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateGroupsResponseData.java
new file mode 100644
index 0000000..a269841
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateGroupsResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AccountRelateGroupsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -720047649055920794L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public AccountRelateGroupsResponseData(String message) {
+ this.message = message;
+ }
+
+ public static AccountRelateGroupsResponseData of(String message) {
+ AccountRelateGroupsResponseData data = new AccountRelateGroupsResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateRolesResponseData.java
new file mode 100644
index 0000000..93895ff
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelateRolesResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AccountRelateRolesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5011147266134585651L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public AccountRelateRolesResponseData(String message) {
+ this.message = message;
+ }
+
+ public static AccountRelateRolesResponseData of(String message) {
+ AccountRelateRolesResponseData data = new AccountRelateRolesResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedGroupsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedGroupsResponseData.java
new file mode 100644
index 0000000..802437d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedGroupsResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class AccountRelatedGroupsResponseData implements IApiQueryResponseData<AccountGroup> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3949426339318397970L;
+
+ private AccountRelatedGroupsResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static AccountRelatedGroupsResponseData of(IApiQueryRequest queryRequest) {
+ AccountRelatedGroupsResponseData configQueryResponse = new AccountRelatedGroupsResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public AccountRelatedGroupsResponseData build(Page<AccountGroup> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<AccountGroup> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedRolesResponseData.java
new file mode 100644
index 0000000..5289a30
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRelatedRolesResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class AccountRelatedRolesResponseData implements IApiQueryResponseData<AccountRole> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4933467585328478547L;
+
+ private AccountRelatedRolesResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static AccountRelatedRolesResponseData of(IApiQueryRequest queryRequest) {
+ AccountRelatedRolesResponseData configQueryResponse = new AccountRelatedRolesResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public AccountRelatedRolesResponseData build(Page<AccountRole> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<AccountRole> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRemoveResponseData.java
new file mode 100644
index 0000000..40d0b87
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class AccountRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8510464738198696332L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private AccountRemoveResponseData() {
+
+ }
+
+ public static AccountRemoveResponseData build(Account entity) {
+ AccountRemoveResponseData data = new AccountRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountUpdateResponseData.java
new file mode 100644
index 0000000..59cba51
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/AccountUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class AccountUpdateResponseData extends Account implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7885193620877829529L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private AccountUpdateResponseData() {
+
+ }
+
+ public static AccountUpdateResponseData build(Account entity) {
+ AccountUpdateResponseData data = new AccountUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationCreateResponseData.java
new file mode 100644
index 0000000..b4a7c94
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ApplicationCreateResponseData extends Application implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5986639173730939508L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ApplicationCreateResponseData() {
+
+ }
+
+ public static ApplicationCreateResponseData build(Application entity) {
+ ApplicationCreateResponseData data = new ApplicationCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationDeleteBatchResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationDeleteBatchResponseData.java
new file mode 100644
index 0000000..9e22692
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationDeleteBatchResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+/**
+ * @author loie
+ */
+public class ApplicationDeleteBatchResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1441419457044931039L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+ private ApplicationDeleteBatchResponseData() {
+
+ }
+
+ public static ApplicationDeleteBatchResponseData build(List<String> ids) {
+ ApplicationDeleteBatchResponseData data = new ApplicationDeleteBatchResponseData();
+ data.setIds(ids);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationLoadResponseData.java
new file mode 100644
index 0000000..27acd2f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ApplicationLoadResponseData extends Application implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4866881763278414027L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ApplicationLoadResponseData() {
+
+ }
+
+ public static ApplicationLoadResponseData of(Application entity) {
+ ApplicationLoadResponseData data = new ApplicationLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationQueryResponseData.java
new file mode 100644
index 0000000..c0fb9bd
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class ApplicationQueryResponseData implements IApiQueryResponseData<Application> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1355060716641084862L;
+
+ private ApplicationQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static ApplicationQueryResponseData of(IApiQueryRequest queryRequest) {
+ ApplicationQueryResponseData configQueryResponse = new ApplicationQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public ApplicationQueryResponseData build(Page<Application> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Application> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationRemoveResponseData.java
new file mode 100644
index 0000000..97f1a87
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class ApplicationRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8179059520857121842L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ApplicationRemoveResponseData() {
+
+ }
+
+ public static ApplicationRemoveResponseData build(Application entity) {
+ ApplicationRemoveResponseData data = new ApplicationRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationUpdateResponseData.java
new file mode 100644
index 0000000..1a72e5c
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ApplicationUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ApplicationUpdateResponseData extends Application implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2690439553701722798L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ApplicationUpdateResponseData() {
+
+ }
+
+ public static ApplicationUpdateResponseData build(Application entity) {
+ ApplicationUpdateResponseData data = new ApplicationUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigCreateResponseData.java
new file mode 100644
index 0000000..663f179
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigCreateResponseData.java
@@ -0,0 +1,32 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ConfigCreateResponseData extends Config implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2300091307366254182L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ConfigCreateResponseData() {
+
+ }
+
+ public static ConfigCreateResponseData build(Config entity) {
+ ConfigCreateResponseData configCreateResponse = new ConfigCreateResponseData();
+ return EntityUtils.copy(entity, configCreateResponse);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigLoadResponseData.java
new file mode 100644
index 0000000..c8ddafa
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigLoadResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ConfigLoadResponseData extends Config implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -579946566129915779L;
+
+ @Getter
+ @Setter
+ private String id;
+
+
+ private ConfigLoadResponseData() {
+
+ }
+
+ public static ConfigLoadResponseData build(Config entity) {
+ ConfigLoadResponseData configCreateResponse = new ConfigLoadResponseData();
+ return EntityUtils.copy(entity, configCreateResponse);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigQueryResponseData.java
new file mode 100644
index 0000000..6255a4b
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigQueryResponseData.java
@@ -0,0 +1,83 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.api.v1.vo.admin.request.ConfigQueryRequest;
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class ConfigQueryResponseData implements IApiQueryResponseData<Config> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3188467441502226095L;
+
+// private ConfigQueryResponseData() {
+// }
+
+ public ConfigQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static ConfigQueryResponseData of(ConfigQueryRequest configQueryRequest) {
+ ConfigQueryResponseData configQueryResponse = new ConfigQueryResponseData(
+ configQueryRequest.isLoadAll(),
+ configQueryRequest.getPageIndex(),
+ configQueryRequest.getPageSize(),
+ configQueryRequest.getMapBean(),
+ configQueryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public ConfigQueryResponseData build(Page<Config> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Config> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigRemoveResponseData.java
new file mode 100644
index 0000000..e656a1f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigRemoveResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class ConfigRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8510464738198696332L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ConfigRemoveResponseData() {
+
+ }
+
+ public static ConfigRemoveResponseData build(Config entity) {
+ ConfigRemoveResponseData configRemoveResponse = new ConfigRemoveResponseData();
+ return EntityUtils.copy(entity, configRemoveResponse);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigUpdateResponseData.java
new file mode 100644
index 0000000..df4de29
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ConfigUpdateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ConfigUpdateResponseData extends Config implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2798387429543859170L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ConfigUpdateResponseData() {
+
+ }
+
+ public static ConfigUpdateResponseData build(Config entity) {
+ ConfigUpdateResponseData configUpdateResponse = new ConfigUpdateResponseData();
+ return EntityUtils.copy(entity, configUpdateResponse);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupCreateResponseData.java
new file mode 100644
index 0000000..4c3f545
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class GroupCreateResponseData extends Group implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3720317246428656184L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private GroupCreateResponseData() {
+
+ }
+
+ public static GroupCreateResponseData build(Group entity) {
+ GroupCreateResponseData data = new GroupCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupLoadResponseData.java
new file mode 100644
index 0000000..a3b83b0
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class GroupLoadResponseData extends Group implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8064680472492241116L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private GroupLoadResponseData() {
+
+ }
+
+ public static GroupLoadResponseData of(Group entity) {
+ GroupLoadResponseData data = new GroupLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupQueryResponseData.java
new file mode 100644
index 0000000..20e6fac
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class GroupQueryResponseData implements IApiQueryResponseData<Group> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1512126460241874099L;
+
+ private GroupQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static GroupQueryResponseData of(IApiQueryRequest queryRequest) {
+ GroupQueryResponseData configQueryResponse = new GroupQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public GroupQueryResponseData build(Page<Group> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Group> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateAccountsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateAccountsResponseData.java
new file mode 100644
index 0000000..fbc6b08
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateAccountsResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class GroupRelateAccountsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6510043291221068404L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public GroupRelateAccountsResponseData(String message) {
+ this.message = message;
+ }
+
+ public static GroupRelateAccountsResponseData of(String message) {
+ GroupRelateAccountsResponseData data = new GroupRelateAccountsResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateRolesResponseData.java
new file mode 100644
index 0000000..104041c
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelateRolesResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class GroupRelateRolesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1758005341902663320L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public GroupRelateRolesResponseData(String message) {
+ this.message = message;
+ }
+
+ public static GroupRelateRolesResponseData of(String message) {
+ GroupRelateRolesResponseData data = new GroupRelateRolesResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedAccountsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedAccountsResponseData.java
new file mode 100644
index 0000000..1e9e819
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedAccountsResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class GroupRelatedAccountsResponseData implements IApiQueryResponseData<AccountGroup> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6697630069320874813L;
+
+ private GroupRelatedAccountsResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static GroupRelatedAccountsResponseData of(IApiQueryRequest queryRequest) {
+ GroupRelatedAccountsResponseData configQueryResponse = new GroupRelatedAccountsResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public GroupRelatedAccountsResponseData build(Page<AccountGroup> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<AccountGroup> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedRolesResponseData.java
new file mode 100644
index 0000000..4ae2d5f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRelatedRolesResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class GroupRelatedRolesResponseData implements IApiQueryResponseData<GroupRole> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1574248919628509262L;
+
+ private GroupRelatedRolesResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static GroupRelatedRolesResponseData of(IApiQueryRequest queryRequest) {
+ GroupRelatedRolesResponseData configQueryResponse = new GroupRelatedRolesResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public GroupRelatedRolesResponseData build(Page<GroupRole> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<GroupRole> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRemoveResponseData.java
new file mode 100644
index 0000000..08e7440
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class GroupRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8704397808353314340L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private GroupRemoveResponseData() {
+
+ }
+
+ public static GroupRemoveResponseData build(Group entity) {
+ GroupRemoveResponseData data = new GroupRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupUpdateResponseData.java
new file mode 100644
index 0000000..3ae507d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/GroupUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class GroupUpdateResponseData extends Group implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1248124641996970651L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private GroupUpdateResponseData() {
+
+ }
+
+ public static GroupUpdateResponseData build(Group entity) {
+ GroupUpdateResponseData data = new GroupUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionCreateResponseData.java
new file mode 100644
index 0000000..cec1042
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class PermissionCreateResponseData extends Permission implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4619013116994825066L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private PermissionCreateResponseData() {
+
+ }
+
+ public static PermissionCreateResponseData build(Permission entity) {
+ PermissionCreateResponseData data = new PermissionCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionDeleteBatchResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionDeleteBatchResponseData.java
new file mode 100644
index 0000000..f1626bf
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionDeleteBatchResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+/**
+ * @author loie
+ */
+public class PermissionDeleteBatchResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7406287471651267066L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+ private PermissionDeleteBatchResponseData() {
+
+ }
+
+ public static PermissionDeleteBatchResponseData build(List<String> ids) {
+ PermissionDeleteBatchResponseData data = new PermissionDeleteBatchResponseData();
+ data.setIds(ids);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionLoadResponseData.java
new file mode 100644
index 0000000..3815743
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionLoadResponseData.java
@@ -0,0 +1,44 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class PermissionLoadResponseData extends Permission implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2692036336252091453L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private List<String> resourceIds;
+
+
+ private PermissionLoadResponseData() {
+
+ }
+
+ public static PermissionLoadResponseData of(Permission entity, List<String> resourceIds) {
+ PermissionLoadResponseData data = new PermissionLoadResponseData();
+
+ EntityUtils.copy(entity, data);
+ data.setResourceIds(resourceIds);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionQueryResponseData.java
new file mode 100644
index 0000000..436a7ee
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class PermissionQueryResponseData implements IApiQueryResponseData<Permission> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8586983968415937644L;
+
+ private PermissionQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static PermissionQueryResponseData of(IApiQueryRequest queryRequest) {
+ PermissionQueryResponseData configQueryResponse = new PermissionQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public PermissionQueryResponseData build(Page<Permission> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Permission> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelateResourcesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelateResourcesResponseData.java
new file mode 100644
index 0000000..e895aac
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelateResourcesResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class PermissionRelateResourcesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5576856617389758687L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public PermissionRelateResourcesResponseData(String message) {
+ this.message = message;
+ }
+
+ public static PermissionRelateResourcesResponseData of(String message) {
+ PermissionRelateResourcesResponseData data = new PermissionRelateResourcesResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelatedResourcesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelatedResourcesResponseData.java
new file mode 100644
index 0000000..969d3c6
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRelatedResourcesResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class PermissionRelatedResourcesResponseData implements IApiQueryResponseData<PermissionResource> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2095633445866557991L;
+
+ private PermissionRelatedResourcesResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static PermissionRelatedResourcesResponseData of(IApiQueryRequest queryRequest) {
+ PermissionRelatedResourcesResponseData configQueryResponse = new PermissionRelatedResourcesResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public PermissionRelatedResourcesResponseData build(Page<PermissionResource> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<PermissionResource> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRemoveResponseData.java
new file mode 100644
index 0000000..d54d0a1
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class PermissionRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 216116075050505802L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private PermissionRemoveResponseData() {
+
+ }
+
+ public static PermissionRemoveResponseData build(Permission entity) {
+ PermissionRemoveResponseData data = new PermissionRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionTreeResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionTreeResponseData.java
new file mode 100644
index 0000000..1735549
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionTreeResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.model.PermissionTreeNode;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class PermissionTreeResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6659447453323545811L;
+
+ public PermissionTreeResponseData(PermissionTreeNode tree) {
+ this.tree = tree;
+ }
+
+ @Getter
+ @Setter
+ private PermissionTreeNode tree;
+
+ public static PermissionTreeResponseData of(PermissionTreeNode tree) {
+ PermissionTreeResponseData data = new PermissionTreeResponseData(tree);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionUpdateResponseData.java
new file mode 100644
index 0000000..806c2c6
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/PermissionUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class PermissionUpdateResponseData extends Permission implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7627522286872083527L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private PermissionUpdateResponseData() {
+
+ }
+
+ public static PermissionUpdateResponseData build(Permission entity) {
+ PermissionUpdateResponseData data = new PermissionUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceCreateResponseData.java
new file mode 100644
index 0000000..1a07eb1
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ResourceCreateResponseData extends Resource implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1679712204106541555L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ResourceCreateResponseData() {
+
+ }
+
+ public static ResourceCreateResponseData build(Resource entity) {
+ ResourceCreateResponseData data = new ResourceCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceLoadResponseData.java
new file mode 100644
index 0000000..289e776
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ResourceLoadResponseData extends Resource implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8194462780086471511L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ResourceLoadResponseData() {
+
+ }
+
+ public static ResourceLoadResponseData of(Resource entity) {
+ ResourceLoadResponseData data = new ResourceLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceQueryResponseData.java
new file mode 100644
index 0000000..b591899
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class ResourceQueryResponseData implements IApiQueryResponseData<Resource> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 241098548786558434L;
+
+ private ResourceQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static ResourceQueryResponseData of(IApiQueryRequest queryRequest) {
+ ResourceQueryResponseData configQueryResponse = new ResourceQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public ResourceQueryResponseData build(Page<Resource> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Resource> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceRemoveResponseData.java
new file mode 100644
index 0000000..ecc9988
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class ResourceRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2847742767960670522L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ResourceRemoveResponseData() {
+
+ }
+
+ public static ResourceRemoveResponseData build(Resource entity) {
+ ResourceRemoveResponseData data = new ResourceRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceUpdateResponseData.java
new file mode 100644
index 0000000..f6c4292
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/ResourceUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class ResourceUpdateResponseData extends Resource implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 893314081061207360L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private ResourceUpdateResponseData() {
+
+ }
+
+ public static ResourceUpdateResponseData build(Resource entity) {
+ ResourceUpdateResponseData data = new ResourceUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleCreateResponseData.java
new file mode 100644
index 0000000..bae356d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RoleCreateResponseData extends Role implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6548339240060091209L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RoleCreateResponseData() {
+
+ }
+
+ public static RoleCreateResponseData build(Role entity) {
+ RoleCreateResponseData data = new RoleCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleDeleteBatchResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleDeleteBatchResponseData.java
new file mode 100644
index 0000000..61776d3
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleDeleteBatchResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleDeleteBatchResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7775951512990321469L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+ private RoleDeleteBatchResponseData() {
+
+ }
+
+ public static RoleDeleteBatchResponseData build(List<String> ids) {
+ RoleDeleteBatchResponseData data = new RoleDeleteBatchResponseData();
+ data.setIds(ids);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleLoadResponseData.java
new file mode 100644
index 0000000..bbbc439
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RoleLoadResponseData extends Role implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 57708002489387653L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RoleLoadResponseData() {
+
+ }
+
+ public static RoleLoadResponseData of(Role entity) {
+ RoleLoadResponseData data = new RoleLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleQueryResponseData.java
new file mode 100644
index 0000000..24d6a09
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleQueryResponseData implements IApiQueryResponseData<Role> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2542992897241822185L;
+
+ private RoleQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static RoleQueryResponseData of(IApiQueryRequest queryRequest) {
+ RoleQueryResponseData configQueryResponse = new RoleQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public RoleQueryResponseData build(Page<Role> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Role> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateAccountsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateAccountsResponseData.java
new file mode 100644
index 0000000..f137972
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateAccountsResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class RoleRelateAccountsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1732402839300368775L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public RoleRelateAccountsResponseData(String message) {
+ this.message = message;
+ }
+
+ public static RoleRelateAccountsResponseData of(String message) {
+ RoleRelateAccountsResponseData data = new RoleRelateAccountsResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateGroupsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateGroupsResponseData.java
new file mode 100644
index 0000000..5c752ae
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelateGroupsResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class RoleRelateGroupsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -248658847598115689L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public RoleRelateGroupsResponseData(String message) {
+ this.message = message;
+ }
+
+ public static RoleRelateGroupsResponseData of(String message) {
+ RoleRelateGroupsResponseData data = new RoleRelateGroupsResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatePermissionsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatePermissionsResponseData.java
new file mode 100644
index 0000000..da7c9c2
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatePermissionsResponseData.java
@@ -0,0 +1,29 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class RoleRelatePermissionsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5398594379968952750L;
+
+ @Getter
+ @Setter
+ private String message;
+
+ public RoleRelatePermissionsResponseData(String message) {
+ this.message = message;
+ }
+
+ public static RoleRelatePermissionsResponseData of(String message) {
+ RoleRelatePermissionsResponseData data = new RoleRelatePermissionsResponseData(message);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedAccountsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedAccountsResponseData.java
new file mode 100644
index 0000000..a906d6e
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedAccountsResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedAccountsResponseData implements IApiQueryResponseData<AccountRole> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5272966183728979505L;
+
+ private RoleRelatedAccountsResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static RoleRelatedAccountsResponseData of(IApiQueryRequest queryRequest) {
+ RoleRelatedAccountsResponseData configQueryResponse = new RoleRelatedAccountsResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public RoleRelatedAccountsResponseData build(Page<AccountRole> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<AccountRole> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedGroupsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedGroupsResponseData.java
new file mode 100644
index 0000000..cf5dc80
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedGroupsResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedGroupsResponseData implements IApiQueryResponseData<GroupRole> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1327331843770679868L;
+
+ private RoleRelatedGroupsResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static RoleRelatedGroupsResponseData of(IApiQueryRequest queryRequest) {
+ RoleRelatedGroupsResponseData configQueryResponse = new RoleRelatedGroupsResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public RoleRelatedGroupsResponseData build(Page<GroupRole> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<GroupRole> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedPermissionsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedPermissionsResponseData.java
new file mode 100644
index 0000000..05ab0c5
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRelatedPermissionsResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.RolePermission;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleRelatedPermissionsResponseData implements IApiQueryResponseData<RolePermission> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7556328257191962088L;
+
+ private RoleRelatedPermissionsResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static RoleRelatedPermissionsResponseData of(IApiQueryRequest queryRequest) {
+ RoleRelatedPermissionsResponseData configQueryResponse = new RoleRelatedPermissionsResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public RoleRelatedPermissionsResponseData build(Page<RolePermission> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<RolePermission> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRemoveResponseData.java
new file mode 100644
index 0000000..3f97566
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class RoleRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2556956704425975795L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RoleRemoveResponseData() {
+
+ }
+
+ public static RoleRemoveResponseData build(Role entity) {
+ RoleRemoveResponseData data = new RoleRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleUpdateResponseData.java
new file mode 100644
index 0000000..3f5e93f
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RoleUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RoleUpdateResponseData extends Role implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7822437040348157286L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RoleUpdateResponseData() {
+
+ }
+
+ public static RoleUpdateResponseData build(Role entity) {
+ RoleUpdateResponseData data = new RoleUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteCreateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteCreateResponseData.java
new file mode 100644
index 0000000..ea50cd4
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteCreateResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RouteCreateResponseData extends Route implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3115757571075013907L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RouteCreateResponseData() {
+
+ }
+
+ public static RouteCreateResponseData build(Route entity) {
+ RouteCreateResponseData data = new RouteCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteDeleteBatchResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteDeleteBatchResponseData.java
new file mode 100644
index 0000000..da236b1
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteDeleteBatchResponseData.java
@@ -0,0 +1,35 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+/**
+ * @author loie
+ */
+public class RouteDeleteBatchResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2204591486919573195L;
+
+ @Getter
+ @Setter
+ private List<String> ids;
+
+ private RouteDeleteBatchResponseData() {
+
+ }
+
+ public static RouteDeleteBatchResponseData build(List<String> ids) {
+ RouteDeleteBatchResponseData data = new RouteDeleteBatchResponseData();
+ data.setIds(ids);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteLoadResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteLoadResponseData.java
new file mode 100644
index 0000000..5fd52d1
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteLoadResponseData.java
@@ -0,0 +1,33 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RouteLoadResponseData extends Route implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3295217395256011396L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RouteLoadResponseData() {
+
+ }
+
+ public static RouteLoadResponseData of(Route entity) {
+ RouteLoadResponseData data = new RouteLoadResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteQueryResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteQueryResponseData.java
new file mode 100644
index 0000000..99d3fb7
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class RouteQueryResponseData implements IApiQueryResponseData<Route> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2632433248197514787L;
+
+ private RouteQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static RouteQueryResponseData of(IApiQueryRequest queryRequest) {
+ RouteQueryResponseData configQueryResponse = new RouteQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return configQueryResponse;
+ }
+
+ public RouteQueryResponseData build(Page<Route> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Route> items;
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteRemoveResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteRemoveResponseData.java
new file mode 100644
index 0000000..4735d20
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class RouteRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -143516413115089421L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RouteRemoveResponseData() {
+
+ }
+
+ public static RouteRemoveResponseData build(Route entity) {
+ RouteRemoveResponseData data = new RouteRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteUpdateResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteUpdateResponseData.java
new file mode 100644
index 0000000..89ace30
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/admin/response/RouteUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.admin.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class RouteUpdateResponseData extends Route implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 364945014290674973L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private RouteUpdateResponseData() {
+
+ }
+
+ public static RouteUpdateResponseData build(Route entity) {
+ RouteUpdateResponseData data = new RouteUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountPermissionsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountPermissionsResponseData.java
new file mode 100644
index 0000000..3d3aa4c
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountPermissionsResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountPermissionsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8276878427539012799L;
+
+ @Getter
+ @Setter
+ public List<Permission> permissions;
+
+
+ public static AuthnAccountPermissionsResponseData of(List<Permission> permissions) {
+ AuthnAccountPermissionsResponseData data = new AuthnAccountPermissionsResponseData();
+
+ data.setPermissions(permissions);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResourcesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResourcesResponseData.java
new file mode 100644
index 0000000..617be41
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResourcesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountResourcesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4924064418294890589L;
+
+ @Getter
+ @Setter
+ public List<Resource> resources;
+
+
+ public static AuthnAccountResourcesResponseData of(List<Resource> resources) {
+ AuthnAccountResourcesResponseData data = new AuthnAccountResourcesResponseData();
+
+ data.setResources(resources);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResponseData.java
new file mode 100644
index 0000000..a84f199
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountResponseData.java
@@ -0,0 +1,19 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountResponseData extends Account implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -289285783805128927L;
+
+ public static AuthnAccountResponseData of(Account entity) {
+ AuthnAccountResponseData data = new AuthnAccountResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountRolesResponseData.java
new file mode 100644
index 0000000..2241c15
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnAccountRolesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountRolesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6588284546370817275L;
+
+ @Getter
+ @Setter
+ public List<Role> roles;
+
+
+ public static AuthnAccountRolesResponseData of(List<Role> roles) {
+ AuthnAccountRolesResponseData data = new AuthnAccountRolesResponseData();
+
+ data.setRoles(roles);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnApplicationsResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnApplicationsResponseData.java
new file mode 100644
index 0000000..79dae74
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnApplicationsResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class AuthnApplicationsResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 277008963651011910L;
+
+ @Getter
+ @Setter
+ public List<Application> applications;
+
+
+ public static AuthnApplicationsResponseData of(List<Application> applications) {
+ AuthnApplicationsResponseData data = new AuthnApplicationsResponseData();
+
+ data.setApplications(applications);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnPermissionRoleListResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnPermissionRoleListResponseData.java
new file mode 100644
index 0000000..bca4b9d
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnPermissionRoleListResponseData.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.model.PermissionRoleSet;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class AuthnPermissionRoleListResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1484993874632504947L;
+
+ @Getter
+ @Setter
+ public List<PermissionRoleSet> permissionRoleSets;
+
+ public static AuthnPermissionRoleListResponseData of(List<PermissionRoleSet> permissionRoleSets) {
+ AuthnPermissionRoleListResponseData data = new AuthnPermissionRoleListResponseData();
+
+ data.setPermissionRoleSets(permissionRoleSets);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnResourceRoleListResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnResourceRoleListResponseData.java
new file mode 100644
index 0000000..da6df80
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnResourceRoleListResponseData.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.model.ResourceRoleSet;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnResourceRoleListResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9178840503146742900L;
+
+ @Getter
+ @Setter
+ public List<ResourceRoleSet> resourceRoleSets;
+
+ public static AuthnResourceRoleListResponseData of(List<ResourceRoleSet> resourceRoleSets) {
+ AuthnResourceRoleListResponseData data = new AuthnResourceRoleListResponseData();
+
+ data.setResourceRoleSets(resourceRoleSets);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRolesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRolesResponseData.java
new file mode 100644
index 0000000..4f503ed
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRolesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class AuthnRolesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3695033930841370744L;
+
+ @Getter
+ @Setter
+ public List<Role> roles;
+
+
+ public static AuthnRolesResponseData of(List<Role> roles) {
+ AuthnRolesResponseData data = new AuthnRolesResponseData();
+
+ data.setRoles(roles);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRoutesResponseData.java b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRoutesResponseData.java
new file mode 100644
index 0000000..3c46ae4
--- /dev/null
+++ b/admin-sa/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/vo/authn/response/AuthnRoutesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.v1.vo.authn.response;
+
+import java.util.List;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class AuthnRoutesResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7221340609572046915L;
+
+ @Getter
+ @Setter
+ public List<Route> routes;
+
+
+ public static AuthnRoutesResponseData of(List<Route> routes) {
+ AuthnRoutesResponseData data = new AuthnRoutesResponseData();
+
+ data.setRoutes(routes);
+
+ return data;
+ }
+
+}
diff --git a/admin-sa/base/domain/.gitignore b/admin-sa/base/domain/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/admin-sa/base/domain/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/admin-sa/base/domain/pom.xml b/admin-sa/base/domain/pom.xml
new file mode 100644
index 0000000..a3e258b
--- /dev/null
+++ b/admin-sa/base/domain/pom.xml
@@ -0,0 +1,99 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-domain</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Admin Base Domain</name>
+ <description>Supwisdom Backend Framework Admin Base Domain project</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-data-jpa</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/.gitkeep b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/.gitkeep
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Account.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Account.java
new file mode 100644
index 0000000..6cca9f9
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Account.java
@@ -0,0 +1,164 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ACCOUNT")
+public class Account extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7955624268022038897L;
+
+ public static final String STATUS_ENABLED = "1";
+ public static final String STATUS_DISABLED = "0";
+
+
+ /**
+ * 用户名
+ */
+ @Column(name = "USERNAME", unique = true)
+ private String username;
+
+ /**
+ * 密码
+ */
+ @Column(name = "PASSWORD")
+ private String password;
+
+ /**
+ * 是否可用,1 可用,0 不可用,默认:1
+ */
+ @Column(name = "ENABLED")
+ private Boolean enabled;
+ /**
+ * 账号未过期,1 未过期,0 过期,默认:1
+ */
+ @Column(name = "ACCOUNT_NON_EXPIRED")
+ private Boolean accountNonExpired;
+ /**
+ * 账号未锁定,1 未锁定,0 锁定,默认:1
+ */
+ @Column(name = "ACCOUNT_NON_LOCKED")
+ private Boolean accountNonLocked;
+ /**
+ * 密码未过期,1 未过期,0 过期,默认:1
+ */
+ @Column(name = "CREDENTIALS_NON_EXPIRED")
+ private Boolean credentialsNonExpired;
+
+ /**
+ * 姓名
+ */
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO")
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ private String status;
+
+ /**
+ * 登录手机
+ */
+ @Column(name = "MOBILE", nullable = true)
+ private String mobile;
+ /**
+ * 登录邮箱
+ */
+ @Column(name = "EMAIL", nullable = true)
+ private String email;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public Boolean getAccountNonExpired() {
+ return accountNonExpired;
+ }
+
+ public void setAccountNonExpired(Boolean accountNonExpired) {
+ this.accountNonExpired = accountNonExpired;
+ }
+
+ public Boolean getAccountNonLocked() {
+ return accountNonLocked;
+ }
+
+ public void setAccountNonLocked(Boolean accountNonLocked) {
+ this.accountNonLocked = accountNonLocked;
+ }
+
+ public Boolean getCredentialsNonExpired() {
+ return credentialsNonExpired;
+ }
+
+ public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
+ this.credentialsNonExpired = credentialsNonExpired;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountGroup.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountGroup.java
new file mode 100644
index 0000000..f46767b
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountGroup.java
@@ -0,0 +1,46 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ACCOUNT_GROUP")
+public class AccountGroup extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4239845385965871983L;
+
+ /**
+ * 帐号ID
+ */
+ @Column(name = "ACCOUNT_ID")
+ private String accountId;
+
+ /**
+ * 用户组ID
+ */
+ @Column(name = "GROUP_ID")
+ private String groupId;
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountRole.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountRole.java
new file mode 100644
index 0000000..b08506a
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/AccountRole.java
@@ -0,0 +1,46 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ACCOUNT_ROLE")
+public class AccountRole extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6158470486381850942L;
+
+ /**
+ * 帐号ID
+ */
+ @Column(name = "ACCOUNT_ID")
+ private String accountId;
+
+ /**
+ * 角色ID
+ */
+ @Column(name = "ROLE_ID")
+ private String roleId;
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+ public String getRoleId() {
+ return roleId;
+ }
+
+ public void setRoleId(String roleId) {
+ this.roleId = roleId;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Application.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Application.java
new file mode 100644
index 0000000..b68fd38
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Application.java
@@ -0,0 +1,69 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_APPLICATION")
+public class Application extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1874484930838884168L;
+
+ /**
+ * 代码
+ */
+ @Column(name = "CODE")
+ @Getter
+ @Setter
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Column(name = "NAME")
+ @Getter
+ @Setter
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO")
+ @Getter
+ @Setter
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ @Getter
+ @Setter
+ private String status;
+
+ /**
+ * 系统访问地址
+ */
+ @Column(name = "URL", nullable = true)
+ @Getter
+ @Setter
+ private String url;
+
+ /**
+ * SPI接口地址前缀
+ */
+ @Column(name = "SPI_URL_PREFIX", nullable = true)
+ @Getter
+ @Setter
+ private String spiUrlPrefix;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Config.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Config.java
new file mode 100644
index 0000000..ee78348
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Config.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+/**
+ * @author loie
+ */
+@Entity
+@Table(name = "TB_CONFIG")
+public class Config extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2721844710909809785L;
+
+ /**
+ * 分类代码
+ */
+ @Getter
+ @Setter
+ @Column(name = "CATEGORY_CODE")
+ private String categoryCode;
+
+ /**
+ * 分类名称
+ */
+ @Getter
+ @Setter
+ @Column(name = "CATEGORY_NAME")
+ private String categoryName;
+
+ /**
+ * 名称
+ */
+ @Getter
+ @Setter
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 描述
+ */
+ @Getter
+ @Setter
+ @Column(name = "DESCRIPTION")
+ private String description;
+
+ /**
+ * 配置键
+ */
+ @Getter
+ @Setter
+ @Column(name = "CONFIG_KEY")
+ private String configKey;
+
+ /**
+ * 配置值
+ */
+ @Getter
+ @Setter
+ @Column(name = "CONFIG_VALUE")
+ private String configValue;
+
+ /**
+ * 是否可修改
+ */
+ @Getter
+ @Setter
+ @Column(name = "EDITABLE")
+ private Boolean editable;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Group.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Group.java
new file mode 100644
index 0000000..5e1de9a
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Group.java
@@ -0,0 +1,74 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity(name = "Group_")
+@Table(name = "TB_BASE_GROUP")
+public class Group extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4260326816456622523L;
+
+ /**
+ * 代码
+ */
+ @Column(name = "CODE")
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO")
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ private String status;
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public void setMemo(String memo) {
+ this.memo = memo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/GroupRole.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/GroupRole.java
new file mode 100644
index 0000000..dafbcb5
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/GroupRole.java
@@ -0,0 +1,46 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_GROUP_ROLE")
+public class GroupRole extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3141266845902556712L;
+
+ /**
+ * 用户组ID
+ */
+ @Column(name = "GROUP_ID")
+ private String groupId;
+
+ /**
+ * 角色ID
+ */
+ @Column(name = "ROLE_ID")
+ private String roleId;
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getRoleId() {
+ return roleId;
+ }
+
+ public void setRoleId(String roleId) {
+ this.roleId = roleId;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java
new file mode 100644
index 0000000..df33e6e
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java
@@ -0,0 +1,210 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_PERMISSION")
+public class Permission extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8834200833972243635L;
+
+ public static final String ROOT_PARENT_ID = "0";
+
+ public static final String APPLICATION_ID = "1";
+
+ public static final String TYPE_APPLICATION = "1";
+ public static final String TYPE_MENU = "2";
+ public static final String TYPE_OPERATION = "3";
+
+ public static final Integer DEFAULT_ORDER = 0;
+
+ /**
+ * 代码
+ */
+ @Column(name = "CODE")
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO", nullable = true)
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ private String status;
+
+ /**
+ * 系统ID
+ */
+ @Column(name = "APPLICATION_ID", nullable = true)
+ private String applicationId;
+
+ /**
+ * 父级ID
+ */
+ @Column(name = "PARENT_ID")
+ private String parentId;
+
+ /**
+ * 类型(1 应用,2 菜单,3 操作)
+ */
+ @Column(name = "TYPE_")
+ private String type;
+
+ /**
+ * 菜单图标
+ */
+ @Column(name = "ICON", nullable = true)
+ private String icon;
+
+ /**
+ * URL地址
+ */
+ @Column(name = "URL", nullable = true)
+ private String url;
+
+ /**
+ * 排序
+ */
+ @Column(name = "ORDER_")
+ private Integer order;
+
+ /**
+ * 层次
+ */
+ @Column(name = "LEVEL_")
+ private Integer level;
+
+ /**
+ * 左序
+ */
+ @Column(name = "LFT")
+ private Integer lft;
+
+ /**
+ * 右序
+ */
+ @Column(name = "RGT")
+ private Integer rgt;
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public void setMemo(String memo) {
+ this.memo = memo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getIcon() {
+ return icon;
+ }
+
+ public void setIcon(String icon) {
+ this.icon = icon;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public void setApplicationId(String applicationId) {
+ this.applicationId = applicationId;
+ }
+
+ public String getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(String parentId) {
+ this.parentId = parentId;
+ }
+
+ public Integer getOrder() {
+ return order;
+ }
+
+ public void setOrder(Integer order) {
+ this.order = order;
+ }
+
+ public Integer getLevel() {
+ return level;
+ }
+
+ public void setLevel(Integer level) {
+ this.level = level;
+ }
+
+ public Integer getLft() {
+ return lft;
+ }
+
+ public void setLft(Integer lft) {
+ this.lft = lft;
+ }
+
+ public Integer getRgt() {
+ return rgt;
+ }
+
+ public void setRgt(Integer rgt) {
+ this.rgt = rgt;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/PermissionResource.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/PermissionResource.java
new file mode 100644
index 0000000..7ec0413
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/PermissionResource.java
@@ -0,0 +1,46 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_PERMISSION_RESOURCE")
+public class PermissionResource extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4224037561100974979L;
+
+ /**
+ * 权限ID
+ */
+ @Column(name = "PERMISSION_ID")
+ private String permissionId;
+
+ /**
+ * 资源ID
+ */
+ @Column(name = "RESOURCE_ID")
+ private String resourceId;
+
+ public String getPermissionId() {
+ return permissionId;
+ }
+
+ public void setPermissionId(String permissionId) {
+ this.permissionId = permissionId;
+ }
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Resource.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Resource.java
new file mode 100644
index 0000000..8f8f8a4
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Resource.java
@@ -0,0 +1,83 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_RESOURCE")
+public class Resource extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4288268877209267453L;
+
+ public static final String ACCESS_ANONYMOUS = "anonymous"; // 匿名访问anonymous
+ public static final String ACCESS_AUTHENTICATE = "authenticate"; // 认证访问authenticate
+ public static final String ACCESS_AUTHORIZE = "authorize"; // 授权访问authorize
+ public static final String ACCESS_PERMIT_ALL = "permitAll"; // 允许所有permitAll
+ public static final String ACCESS_DENY_ALL = "denyAll"; // 拒绝所有denyAll
+
+ /**
+ * 代码
+ */
+ @Getter
+ @Setter
+ @Column(name = "CODE")
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Getter
+ @Setter
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Getter
+ @Setter
+ @Column(name = "MEMO", nullable = true)
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Getter
+ @Setter
+ @Column(name = "STATUS")
+ private String status;
+
+ /**
+ * 请求方式
+ */
+ @Getter
+ @Setter
+ @Column(name = "METHOD")
+ private String method;
+
+ /**
+ * 请求路径
+ */
+ @Getter
+ @Setter
+ @Column(name = "PATH")
+ private String path;
+
+ /**
+ * 访问规则(匿名访问anonymous、认证访问authenticate、授权访问authorize、允许所有permitAll、拒绝所有denyAll)
+ */
+ @Getter
+ @Setter
+ @Column(name = "ACCESS")
+ private String access;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Role.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Role.java
new file mode 100644
index 0000000..c75cbe9
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Role.java
@@ -0,0 +1,74 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ROLE")
+public class Role extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5470129732727732514L;
+
+ /**
+ * 代码
+ */
+ @Column(name = "CODE")
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Column(name = "NAME")
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO")
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ private String status;
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public void setMemo(String memo) {
+ this.memo = memo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/RolePermission.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/RolePermission.java
new file mode 100644
index 0000000..19ba5b4
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/RolePermission.java
@@ -0,0 +1,46 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ROLE_PERMISSION")
+public class RolePermission extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5293251541687343949L;
+
+ /**
+ * 角色ID
+ */
+ @Column(name = "ROLE_ID")
+ private String roleId;
+
+ /**
+ * 权限ID
+ */
+ @Column(name = "PERMISSION_ID")
+ private String permissionId;
+
+ public String getRoleId() {
+ return roleId;
+ }
+
+ public void setRoleId(String roleId) {
+ this.roleId = roleId;
+ }
+
+ public String getPermissionId() {
+ return permissionId;
+ }
+
+ public void setPermissionId(String permissionId) {
+ this.permissionId = permissionId;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Route.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Route.java
new file mode 100644
index 0000000..6a58e92
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Route.java
@@ -0,0 +1,77 @@
+package com.supwisdom.institute.backend.base.domain.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BASE_ROUTE")
+public class Route extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7435404154376360786L;
+
+ /**
+ * 代码
+ */
+ @Column(name = "CODE")
+ @Getter
+ @Setter
+ private String code;
+
+ /**
+ * 名称
+ */
+ @Column(name = "NAME")
+ @Getter
+ @Setter
+ private String name;
+
+ /**
+ * 备注
+ */
+ @Column(name = "MEMO")
+ @Getter
+ @Setter
+ private String memo;
+
+ /**
+ * 状态(1 启用,0 停用)
+ */
+ @Column(name = "STATUS")
+ @Getter
+ @Setter
+ private String status;
+
+ /**
+ * 路径前缀
+ */
+ @Column(name = "PATH_PREFIX")
+ @Getter
+ @Setter
+ private String pathPrefix;
+
+ /**
+ * 路由地址
+ */
+ @Column(name = "URL")
+ @Getter
+ @Setter
+ private String url;
+
+ /**
+ * 是否排除前缀
+ */
+ @Column(name = "STRIP_PREFIX")
+ @Getter
+ @Setter
+ private Boolean stripPrefix;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/.gitkeep b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/.gitkeep
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/ConfigException.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/ConfigException.java
new file mode 100644
index 0000000..77fee05
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/exception/ConfigException.java
@@ -0,0 +1,12 @@
+package com.supwisdom.institute.backend.base.domain.exception;
+
+import com.supwisdom.institute.backend.common.framework.exception.BaseException;
+
+public class ConfigException extends BaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8112079911386045865L;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/.gitkeep b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/.gitkeep
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionRoleSet.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionRoleSet.java
new file mode 100644
index 0000000..a95a0f7
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionRoleSet.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.domain.model;
+
+import java.util.Collection;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.model.IModel;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class PermissionRoleSet extends Permission implements IModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1823157193945264156L;
+
+ @Getter
+ @Setter
+ Collection<Role> roles;
+
+ public PermissionRoleSet(Permission permission, Collection<Role> roles) {
+
+ EntityUtils.copy(permission, this);
+
+ this.roles = roles;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionTreeNode.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionTreeNode.java
new file mode 100644
index 0000000..233de5f
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/PermissionTreeNode.java
@@ -0,0 +1,24 @@
+package com.supwisdom.institute.backend.base.domain.model;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.model.IModel;
+
+@ToString
+public class PermissionTreeNode extends Permission implements IModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6984458902464386215L;
+
+ @Getter
+ @Setter
+ List<PermissionTreeNode> children;
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/ResourceRoleSet.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/ResourceRoleSet.java
new file mode 100644
index 0000000..598b30d
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/model/ResourceRoleSet.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.domain.model;
+
+import java.util.Collection;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.model.IModel;
+
+public class ResourceRoleSet extends Resource implements IModel {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2220390504237330816L;
+
+ @Getter
+ @Setter
+ Collection<Role> roles;
+
+ public ResourceRoleSet(Resource resource, Collection<Role> roles) {
+
+ EntityUtils.copy(resource, this);
+
+ this.roles = roles;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/.gitkeep b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/.gitkeep
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountGroupRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountGroupRepository.java
new file mode 100644
index 0000000..be61930
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountGroupRepository.java
@@ -0,0 +1,191 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface AccountGroupRepository extends BaseJpaRepository<AccountGroup> {
+
+ public default Page<AccountGroup> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+ AccountGroup probe = new AccountGroup();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountGroup> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Page<AccountGroup> selectAccountGroups(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountGroup probe = new AccountGroup();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountGroup> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public default void relateAccountGroups(Account account, List<AccountGroup> accountGroups) {
+
+ List<AccountGroup> existAccountGroups = this.selectListByAccountId(account.getId());
+
+ Map<String, AccountGroup> existMapAccountGroups = new LinkedHashMap<String, AccountGroup>();
+ for (AccountGroup accountGroup : existAccountGroups) {
+ String k = String.format("%s", accountGroup.getGroupId());
+ existMapAccountGroups.put(k, accountGroup);
+ }
+
+ for (AccountGroup accountGroup : accountGroups) {
+ String k = String.format("%s", accountGroup.getGroupId());
+
+ if (existMapAccountGroups.containsKey(k)) {
+ existMapAccountGroups.remove(k);
+ } else {
+ accountGroup.setCompanyId(account.getCompanyId());
+ accountGroup.setAccountId(account.getId());
+
+ this.insert(accountGroup);
+ }
+ }
+
+ for (AccountGroup accountGroup : existMapAccountGroups.values()) {
+ this.deleteById(accountGroup.getId());
+ }
+ }
+
+ public default List<AccountGroup> selectListByAccountId(String accountId) {
+
+ AccountGroup probe = new AccountGroup();
+ probe.setAccountId(accountId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ List<AccountGroup> accountGroups = this.findAll(example);
+
+ return accountGroups;
+ }
+
+ public default void relateGroupAccounts(Group group, List<AccountGroup> accountGroups) {
+
+ List<AccountGroup> existGroupAccounts = this.selectListByGroupId(group.getId());
+
+ Map<String, AccountGroup> existMapGroupAccounts = new LinkedHashMap<String, AccountGroup>();
+ for (AccountGroup accountGroup : existGroupAccounts) {
+ String k = String.format("%s", accountGroup.getAccountId());
+ existMapGroupAccounts.put(k, accountGroup);
+ }
+
+ for (AccountGroup accountGroup : accountGroups) {
+ String k = String.format("%s", accountGroup.getAccountId());
+
+ if (existMapGroupAccounts.containsKey(k)) {
+ existMapGroupAccounts.remove(k);
+ } else {
+ accountGroup.setCompanyId(group.getCompanyId());
+ accountGroup.setGroupId(group.getId());
+
+ this.insert(accountGroup);
+ }
+ }
+
+ for (AccountGroup accountGroup : existMapGroupAccounts.values()) {
+ this.deleteById(accountGroup.getId());
+ }
+ }
+
+ public default List<AccountGroup> selectListByGroupId(String groupId) {
+
+ AccountGroup probe = new AccountGroup();
+ probe.setGroupId(groupId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ List<AccountGroup> accountGroups = this.findAll(example);
+
+ return accountGroups;
+ }
+
+ public default AccountGroup selectOneByAccountGroup(String accountId, String groupId) {
+
+ AccountGroup probe = new AccountGroup();
+ probe.setAccountId(accountId);
+ probe.setGroupId(groupId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ Optional<AccountGroup> o = this.findOne(example);
+
+ return o.isPresent() ? o.get() : null;
+ }
+
+ public default void addAccountGroup(String accountId, String groupId) {
+
+ AccountGroup accountGroup = this.selectOneByAccountGroup(accountId, groupId);
+
+ if (accountGroup == null) {
+ accountGroup = new AccountGroup();
+ //accountGroup.setCompanyId(companyId);
+ accountGroup.setAccountId(accountId);
+ accountGroup.setGroupId(groupId);
+
+ this.insert(accountGroup);
+ }
+ }
+
+ public default void removeAccountGroup(String accountId, String groupId) {
+
+ AccountGroup accountGroup = this.selectOneByAccountGroup(accountId, groupId);
+
+ if (accountGroup != null) {
+ this.deleteById(accountGroup.getId());
+ }
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRepository.java
new file mode 100644
index 0000000..e4d9e07
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRepository.java
@@ -0,0 +1,199 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface AccountRepository extends BaseJpaRepository<Account> {
+
+// public default Page<Account> selectPageList(int pageIndex, int pageSize, Account probe) {
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("username", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+// Example<Account> example = Example.of(probe, matcher);
+//
+// Page<Account> page = this.findAll(example, pageRequest);
+//
+// return page;
+// }
+
+
+ @Override
+ public default Specification<Account> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Account> spec = new Specification<Account>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9071470982419099273L;
+
+ @Override
+ public Predicate toPredicate(Root<Account> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "username"))) {
+ predicates.add(criteriaBuilder.like(root.get("username"), "%" + MapBeanUtils.getString(mapBean, "username") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+// if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "grantTimeBegin"))) {
+// String grantTimeBegin = MapBeanUtils.getString(mapBean, "grantTimeBegin");
+// Date d = DateUtil.parseDate(grantTimeBegin+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
+//
+// if (d != null) {
+// predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("grantTime"), d));
+// }
+// }
+//
+// if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "grantTimeEnd"))) {
+// String grantTimeEnd = MapBeanUtils.getString(mapBean, "grantTimeEnd");
+// Date d = DateUtil.parseDate(grantTimeEnd+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
+//
+// if (d != null) {
+// predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("grantTime"), d));
+// }
+// }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("username"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+
+// @Override
+// public default Page<Account> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+// if (loadAll) {
+// pageIndex = 0;
+// pageSize = Integer.MAX_VALUE;
+// }
+//
+// Account probe = new Account();
+// if (mapBean != null) {
+// probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+// probe.setUsername(MapBeanUtils.getString(mapBean, "username"));
+// probe.setName(MapBeanUtils.getString(mapBean, "name"));
+// probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+// }
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+// .withMatcher("username", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+// Example<Account> example = Example.of(probe, matcher);
+//
+// Page<Account> page = this.findAll(example, pageRequest);
+//
+// return page;
+// }
+
+ /*
+ public default User selectById(String id) {
+
+ try {
+ Optional<User> entity = this.findById(id);
+
+ return entity.get();
+ } catch(RuntimeException e) {
+ System.out.println("RuntimeException:"+e.getMessage());
+ } catch(Exception e) {
+ System.out.println("Exception:"+e.getMessage());
+ }
+
+ return null;
+ }
+
+ public default User insert(User entity) {
+
+ if (entity.getCompanyId() == null || entity.getCompanyId().isEmpty()) {
+ entity.setCompanyId("1");
+ }
+
+ entity.setDeleted(false);
+ //entity.setAddAccount(AuthUtil.getRemoteUser());
+ entity.setAddTime(Calendar.getInstance().getTime());
+
+ User e = this.save(entity);
+
+ return e;
+ }
+
+ public default User update(User entity) {
+
+ //entity.setEditAccount(AuthUtil.getRemoteUser());
+ entity.setEditTime(Calendar.getInstance().getTime());
+
+ User e = this.save(entity);
+
+ return e;
+ }
+ */
+
+ public default Account selectByUsername(String username) {
+ Account probe = new Account();
+ probe.setUsername(username);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("username", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<Account> example = Example.of(probe, matcher);
+
+ Optional<Account> u = this.findOne(example);
+
+ if (u.isPresent()) {
+ return u.get();
+ }
+
+ return null;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRoleRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRoleRepository.java
new file mode 100644
index 0000000..503f3b5
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/AccountRoleRepository.java
@@ -0,0 +1,191 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface AccountRoleRepository extends BaseJpaRepository<AccountRole> {
+
+ public default Page<AccountRole> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountRole probe = new AccountRole();
+ if (mapBean != null) {
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ Page<AccountRole> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Page<AccountRole> selectAccountRoles(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountRole probe = new AccountRole();
+ if (mapBean != null) {
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountRole> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public default void relateAccountRoles(Account account, List<AccountRole> accountRoles) {
+
+ List<AccountRole> existAccountRoles = this.selectListByAccountId(account.getId());
+
+ Map<String, AccountRole> existMapAccountRoles = new LinkedHashMap<String, AccountRole>();
+ for (AccountRole accountRole : existAccountRoles) {
+ String k = String.format("%s", accountRole.getRoleId());
+ existMapAccountRoles.put(k, accountRole);
+ }
+
+ for (AccountRole accountRole : accountRoles) {
+ String k = String.format("%s", accountRole.getRoleId());
+
+ if (existMapAccountRoles.containsKey(k)) {
+ existMapAccountRoles.remove(k);
+ } else {
+ accountRole.setCompanyId(account.getCompanyId());
+ accountRole.setAccountId(account.getId());
+
+ this.insert(accountRole);
+ }
+ }
+
+ for (AccountRole accountRole : existMapAccountRoles.values()) {
+ this.deleteById(accountRole.getId());
+ }
+ }
+
+ public default List<AccountRole> selectListByAccountId(String accountId) {
+
+ AccountRole probe = new AccountRole();
+ probe.setAccountId(accountId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("accountId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ List<AccountRole> accountRoles = this.findAll(example);
+
+ return accountRoles;
+ }
+
+ public default void relateRoleAccounts(Role role, List<AccountRole> accountRoles) {
+
+ List<AccountRole> existRoleAccounts = this.selectListByRoleId(role.getId());
+
+ Map<String, AccountRole> existMapRoleAccounts = new LinkedHashMap<String, AccountRole>();
+ for (AccountRole accountRole : existRoleAccounts) {
+ String k = String.format("%s", accountRole.getAccountId());
+ existMapRoleAccounts.put(k, accountRole);
+ }
+
+ for (AccountRole accountRole : accountRoles) {
+ String k = String.format("%s", accountRole.getAccountId());
+
+ if (existMapRoleAccounts.containsKey(k)) {
+ existMapRoleAccounts.remove(k);
+ } else {
+ accountRole.setCompanyId(role.getCompanyId());
+ accountRole.setRoleId(role.getId());
+
+ this.insert(accountRole);
+ }
+ }
+
+ for (AccountRole accountRole : existMapRoleAccounts.values()) {
+ this.deleteById(accountRole.getId());
+ }
+ }
+
+ public default List<AccountRole> selectListByRoleId(String roleId) {
+
+ AccountRole probe = new AccountRole();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("roleId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ List<AccountRole> accountRoles = this.findAll(example);
+
+ return accountRoles;
+ }
+
+ public default AccountRole selectOneByAccountRole(String accountId, String roleId) {
+
+ AccountRole probe = new AccountRole();
+ probe.setAccountId(accountId);
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ Optional<AccountRole> o = this.findOne(example);
+
+ return o.isPresent() ? o.get() : null;
+ }
+
+ public default void addAccountRole(String accountId, String roleId) {
+
+ AccountRole accountRole = this.selectOneByAccountRole(accountId, roleId);
+
+ if (accountRole == null) {
+ accountRole = new AccountRole();
+ //accountRole.setCompanyId(companyId);
+ accountRole.setAccountId(accountId);
+ accountRole.setRoleId(roleId);
+
+ this.insert(accountRole);
+ }
+ }
+
+ public default void removeAccountRole(String accountId, String roleId) {
+
+ AccountRole accountRole = this.selectOneByAccountRole(accountId, roleId);
+
+ if (accountRole != null) {
+ this.deleteById(accountRole.getId());
+ }
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ApplicationRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ApplicationRepository.java
new file mode 100644
index 0000000..3e1b6ea
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ApplicationRepository.java
@@ -0,0 +1,76 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface ApplicationRepository extends BaseJpaRepository<Application> {
+
+ @Override
+ public default Specification<Application> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Application> spec = new Specification<Application>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -263282246904382286L;
+
+ @Override
+ public Predicate toPredicate(Root<Application> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "url"))) {
+ predicates.add(criteriaBuilder.like(root.get("url"), "%" + MapBeanUtils.getString(mapBean, "url") + "%"));
+ }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ConfigRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ConfigRepository.java
new file mode 100644
index 0000000..052115e
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ConfigRepository.java
@@ -0,0 +1,77 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * @author loie
+ */
+@Repository
+public interface ConfigRepository extends BaseJpaRepository<Config> {
+
+ public default Page<Config> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ Config probe = new Config();
+ if (mapBean != null) {
+ probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+ probe.setCategoryCode(MapBeanUtils.getString(mapBean, "categoryCode"));
+ probe.setCategoryName(MapBeanUtils.getString(mapBean, "categoryName"));
+ probe.setName(MapBeanUtils.getString(mapBean, "name"));
+ probe.setDescription(MapBeanUtils.getString(mapBean, "description"));
+ probe.setConfigKey(MapBeanUtils.getString(mapBean, "configKey"));
+ probe.setEditable(MapBeanUtils.getBoolean(mapBean, "editable"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("categoryCode", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("categoryName", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("description", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("configKey", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("editable", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ if (loadAll) {
+ pageIndex = 0;
+ pageSize = Integer.MAX_VALUE;
+ }
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<Config> example = Example.of(probe, matcher);
+
+ Page<Config> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Config selectByCategoryKey(String categoryCode, String configKey) {
+ Config probe = new Config();
+
+ probe.setDeleted(false);
+ probe.setCategoryCode(categoryCode);
+ probe.setConfigKey(configKey);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("categoryCode", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("configKey", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<Config> example = Example.of(probe, matcher);
+
+ Optional<Config> config = this.findOne(example);
+
+ return config.isPresent() ? config.get() : null;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRepository.java
new file mode 100644
index 0000000..75ad2b4
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRepository.java
@@ -0,0 +1,107 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface GroupRepository extends BaseJpaRepository<Group> {
+
+
+ @Override
+ public default Specification<Group> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Group> spec = new Specification<Group>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5467747850605022253L;
+
+ @Override
+ public Predicate toPredicate(Root<Group> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "memo"))) {
+ predicates.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "memo") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+// @Override
+// public default Page<Group> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+// if (loadAll) {
+// pageIndex = 0;
+// pageSize = Integer.MAX_VALUE;
+// }
+//
+// Group probe = new Group();
+// if (mapBean != null) {
+// probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+// probe.setCode(MapBeanUtils.getString(mapBean, "code"));
+// probe.setName(MapBeanUtils.getString(mapBean, "name"));
+// probe.setMemo(MapBeanUtils.getString(mapBean, "memo"));
+// probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+// }
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+// .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("memo", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+// Example<Group> example = Example.of(probe, matcher);
+//
+// Page<Group> page = this.findAll(example, pageRequest);
+//
+// return page;
+// }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRoleRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRoleRepository.java
new file mode 100644
index 0000000..35bd4d5
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/GroupRoleRepository.java
@@ -0,0 +1,191 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface GroupRoleRepository extends BaseJpaRepository<GroupRole> {
+
+ public default Page<GroupRole> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+ GroupRole probe = new GroupRole();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ Page<GroupRole> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Page<GroupRole> selectGroupRoles(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ GroupRole probe = new GroupRole();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<GroupRole> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public default void relateGroupRoles(Group group, List<GroupRole> groupRoles) {
+
+ List<GroupRole> existGroupRoles = this.selectListByGroupId(group.getId());
+
+ Map<String, GroupRole> existMapGroupRoles = new LinkedHashMap<String, GroupRole>();
+ for (GroupRole groupRole : existGroupRoles) {
+ String k = String.format("%s", groupRole.getRoleId());
+ existMapGroupRoles.put(k, groupRole);
+ }
+
+ for (GroupRole groupRole : groupRoles) {
+ String k = String.format("%s", groupRole.getRoleId());
+
+ if (existMapGroupRoles.containsKey(k)) {
+ existMapGroupRoles.remove(k);
+ } else {
+ groupRole.setCompanyId(group.getCompanyId());
+ groupRole.setGroupId(group.getId());
+
+ this.insert(groupRole);
+ }
+ }
+
+ for (GroupRole groupRole : existMapGroupRoles.values()) {
+ this.deleteById(groupRole.getId());
+ }
+ }
+
+ public default List<GroupRole> selectListByGroupId(String groupId) {
+
+ GroupRole probe = new GroupRole();
+ probe.setGroupId(groupId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("groupId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ List<GroupRole> groupRoles = this.findAll(example);
+
+ return groupRoles;
+ }
+
+
+ public default void relateRoleGroups(Role role, List<GroupRole> groupRoles) {
+
+ List<GroupRole> existRoleGroups = this.selectListByRoleId(role.getCode());
+
+ Map<String, GroupRole> existMapRoleGroups = new LinkedHashMap<String, GroupRole>();
+ for (GroupRole groupRole : existRoleGroups) {
+ String k = String.format("%s", groupRole.getGroupId());
+ existMapRoleGroups.put(k, groupRole);
+ }
+
+ for (GroupRole groupRole : groupRoles) {
+ String k = String.format("%s", groupRole.getGroupId());
+
+ if (existMapRoleGroups.containsKey(k)) {
+ existMapRoleGroups.remove(k);
+ } else {
+ groupRole.setCompanyId(role.getCompanyId());
+ groupRole.setRoleId(role.getId());
+
+ this.insert(groupRole);
+ }
+ }
+
+ for (GroupRole groupRole : existMapRoleGroups.values()) {
+ this.deleteById(groupRole.getId());
+ }
+ }
+
+ public default List<GroupRole> selectListByRoleId(String roleId) {
+
+ GroupRole probe = new GroupRole();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ List<GroupRole> groupRoles = this.findAll(example);
+
+ return groupRoles;
+ }
+
+ public default GroupRole selectOneByGroupRole(String groupId, String roleId) {
+
+ GroupRole probe = new GroupRole();
+ probe.setGroupId(groupId);
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ Optional<GroupRole> o = this.findOne(example);
+
+ return o.isPresent() ? o.get() : null;
+ }
+
+ public default void addGroupRole(String groupId, String roleId) {
+
+ GroupRole groupRole = this.selectOneByGroupRole(groupId, roleId);
+
+ if (groupRole == null) {
+ groupRole = new GroupRole();
+ //groupRole.setCompanyId(companyId);
+ groupRole.setGroupId(groupId);
+ groupRole.setRoleId(roleId);
+
+ this.insert(groupRole);
+ }
+ }
+
+ public default void removeGroupRole(String groupId, String roleId) {
+
+ GroupRole groupRole = this.selectOneByGroupRole(groupId, roleId);
+
+ if (groupRole != null) {
+ this.deleteById(groupRole.getId());
+ }
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java
new file mode 100644
index 0000000..aaa0214
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java
@@ -0,0 +1,419 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.transaction.Transactional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+@Transactional
+public interface PermissionRepository extends BaseJpaRepository<Permission> {
+
+
+ @Override
+ public default Specification<Permission> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Permission> spec = new Specification<Permission>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6195601104797641573L;
+
+ @Override
+ public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "type"))) {
+ predicates.add(criteriaBuilder.equal(root.get("type"), MapBeanUtils.getString(mapBean, "type")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "url"))) {
+ predicates.add(criteriaBuilder.like(root.get("url"), "%" + MapBeanUtils.getString(mapBean, "url") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "applicationId"))) {
+ predicates.add(criteriaBuilder.equal(root.get("applicationId"), MapBeanUtils.getString(mapBean, "applicationId")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "parentId"))) {
+ predicates.add(criteriaBuilder.equal(root.get("parentId"), MapBeanUtils.getString(mapBean, "parentId")));
+ }
+
+// if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "grantTimeBegin"))) {
+// String grantTimeBegin = MapBeanUtils.getString(mapBean, "grantTimeBegin");
+// Date d = DateUtil.parseDate(grantTimeBegin+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
+//
+// if (d != null) {
+// predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("grantTime"), d));
+// }
+// }
+//
+// if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "grantTimeEnd"))) {
+// String grantTimeEnd = MapBeanUtils.getString(mapBean, "grantTimeEnd");
+// Date d = DateUtil.parseDate(grantTimeEnd+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
+//
+// if (d != null) {
+// predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("grantTime"), d));
+// }
+// }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+ @Override
+ public default Page<Permission> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ if (loadAll) {
+ pageIndex = 0;
+ pageSize = Integer.MAX_VALUE;
+ }
+
+ Permission probe = new Permission();
+ if (mapBean != null) {
+ probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+ probe.setCode(MapBeanUtils.getString(mapBean, "code"));
+ probe.setName(MapBeanUtils.getString(mapBean, "name"));
+ probe.setMemo(MapBeanUtils.getString(mapBean, "memo"));
+ probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+ probe.setType(MapBeanUtils.getString(mapBean, "type"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("memo", ExampleMatcher.GenericPropertyMatchers.contains())
+ .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("type", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<Permission> example = Example.of(probe, matcher);
+
+ Page<Permission> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+
+
+ @Query(value = "select max(p.rgt) from Permission p")
+ public int selectMaxRgt();
+
+ @Query(value = "select p from Permission p where p.lft>:lft and p.rgt<:rgt order by p.lft")
+ public List<Permission> selectBetweenLftRgt(@Param("lft") int lft, @Param("rgt") int rgt);
+
+ @Modifying
+ @Query(value = "update TB_BASE_PERMISSION "
+ + "set "
+ + " LFT = (case when LFT >= :rgt then LFT + :offset else LFT end), "
+ + " RGT = RGT + :offset "
+ + "where RGT >= :rgt", nativeQuery = true)
+ public int updateLftRgtWhenInsert(@Param("rgt") int rgt, @Param("offset") int offset);
+
+ @Modifying
+ @Query(value = "update TB_BASE_PERMISSION "
+ + "set "
+ + " LFT = (case when LFT >= :rgt then LFT - :offset else LFT end), "
+ + " RGT = RGT - :offset "
+ + "where RGT >= :rgt", nativeQuery = true)
+ public int updateLftRgtWhenDelete(@Param("rgt") int rgt, @Param("offset") int offset);
+
+
+ @Override
+ public default Permission insert(Permission entity) {
+
+ if (entity.getParentId() == null) {
+ entity.setParentId(Permission.ROOT_PARENT_ID);
+ }
+
+ if (entity.getParentId() == null || entity.getParentId().isEmpty() || Permission.ROOT_PARENT_ID.equals(entity.getParentId())) {
+ int maxRgt = selectMaxRgt();
+ entity.setLft((maxRgt+1));
+ entity.setRgt((maxRgt+1) + 1);
+
+ entity.setLevel(1);
+ } else {
+ Permission parentEntity = this.selectById(entity.getParentId());
+ if (parentEntity == null) {
+ throw new RuntimeException(String.format("父级对象不存在!"));
+ } else {
+ // 将 lft或rgt 大于等于父级对象 rgt 的记录的 lft、rgt +offset
+ int rgt = parentEntity.getRgt();
+ int offset = 2;
+ updateLftRgtWhenInsert(rgt, offset);
+
+ entity.setLft(rgt);
+ entity.setRgt(rgt + 1);
+
+ entity.setLevel(parentEntity.getLevel() + 1);
+ }
+ }
+
+ return BaseJpaRepository.super.insert(entity);
+ }
+
+ @Override
+ public default Permission update(Permission entity) {
+
+ Permission originEntity = this.selectById(entity.getId());
+ if (originEntity == null) {
+ return null;
+ }
+
+ //if (!this.checkFieldExists("code", entity.getCode(), entity.getId())) {
+ // throw new RuntimeException(String.format("代码重复!"));
+ //}
+
+ if (originEntity.getParentId() == null) {
+ originEntity.setParentId(Permission.ROOT_PARENT_ID);
+ }
+
+ if (entity.getParentId() == null) {
+ entity.setParentId(Permission.ROOT_PARENT_ID);
+ }
+
+ if (!originEntity.getParentId().equals(entity.getParentId()) ) {
+
+ int lft = originEntity.getLft();
+ int rgt = originEntity.getRgt();
+ int level = originEntity.getLevel();
+ int offset = rgt - lft +1;
+
+ List<Permission> childEntities = this.selectBetweenLftRgt(lft, rgt);
+
+ if (entity.getParentId() == null || entity.getParentId().isEmpty() || Permission.ROOT_PARENT_ID.equals(entity.getParentId())) {
+ // 将 lft或rgt 大于等于该对象 rgt 的记录的 lft、rgt -offset
+ updateLftRgtWhenDelete(rgt, offset);
+
+ int maxRgt = selectMaxRgt();
+ entity.setLft((maxRgt+1));
+ entity.setRgt((maxRgt+1) + 1 +offset-2);
+
+ entity.setLevel(1);
+ } else {
+ // 将 lft或rgt 大于等于该对象 rgt 的记录的 lft、rgt -offset
+ updateLftRgtWhenDelete(rgt, offset);
+
+ Permission parentEntity = this.selectById(entity.getParentId());
+ if (parentEntity == null) {
+ throw new RuntimeException(String.format("父级对象不存在!"));
+ }
+ //System.out.println(String.format("pLft %s, pRgt %s", parentEntity.getLft(), parentEntity.getRgt()));
+ if (parentEntity.getLft() >= originEntity.getLft() && parentEntity.getRgt() <= originEntity.getRgt()) {
+ throw new RuntimeException(String.format("不能设置自身或自身的子节点作为父级!"));
+ }
+
+ //parentEntity = this.selectById(entity.getParentId()); System.out.println(String.format("pLft %s, pRgt %s", parentEntity.getLft(), parentEntity.getRgt()));
+ // 将 lft或rgt 大于等于父级对象 rgt 的记录的 lft、rgt +offset
+ //int pLft = parentEntity.getLft();
+ int pRgt = parentEntity.getRgt();
+ updateLftRgtWhenInsert(pRgt, offset);
+
+ entity.setLft(pRgt);
+ entity.setRgt(pRgt + 1 + offset-2);
+
+ entity.setLevel(parentEntity.getLevel() + 1);
+ }
+
+ int newLft = entity.getLft();
+ int newRgt = entity.getRgt();
+ int newLevel = entity.getLevel();
+ //System.out.println(String.format("newLft %s, newRgt %s, newLevel %s", newLft, newRgt, newLevel));
+ //System.out.println(String.format("lft %s, rgt %s, level %s", lft, rgt, level));
+ for (Permission childEntity : childEntities) {
+ //Permission pEntity = this.selectById(childEntity.getParentId());
+
+ int cLft = childEntity.getLft();
+ int cRgt = childEntity.getRgt();
+ int cLevel = childEntity.getLevel();
+
+ childEntity.setLft(cLft + (newLft - lft));
+ childEntity.setRgt(cRgt + (newRgt - rgt));
+
+ childEntity.setLevel(cLevel + (newLevel - level));
+
+ BaseJpaRepository.super.update(childEntity);
+ }
+
+ }
+
+ return BaseJpaRepository.super.update(entity);
+ }
+
+ @Override
+ public default void delete(String id) {
+
+ Permission originEntity = this.selectById(id);
+ if (originEntity == null) {
+ return;
+ }
+
+ int lft = originEntity.getLft();
+ int rgt = originEntity.getRgt();
+ int offset = rgt - lft +1;
+
+ // FIXME: 判断是否有子节点
+ //if (lft + 1 != rgt) {
+ // return;
+ //}
+
+ List<Permission> childEntities = this.selectBetweenLftRgt(lft, rgt);
+ for (Permission childEntity : childEntities) {
+ BaseJpaRepository.super.delete(childEntity.getId());
+ }
+
+ // 将 lft或rgt 大于等于该对象 rgt 的记录的 lft、rgt -offset
+ updateLftRgtWhenDelete(rgt, offset);
+
+ BaseJpaRepository.super.delete(id);
+ }
+
+
+
+
+ public default List<Permission> selectList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+
+ Specification<Permission> spec = convertToSpec(mapBean);
+
+ if (loadAll) {
+ pageIndex = 0;
+ pageSize = Integer.MAX_VALUE;
+ }
+
+ Sort sort = convertToSort(orderBy);
+
+ if (sort == null) {
+ return this.findAll(spec);
+ } else {
+ return this.findAll(spec, sort);
+ }
+ }
+
+
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join AccountRole ar on r.id=ar.roleId "
+ + "inner join Account a on ar.accountId=a.id "
+ + "where a.username=:username "
+ + "and p.lft >= :lft and p.rgt <= :rgt "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountRolePermissionByUsername(@Param("username") String username, @Param("lft") int lft, @Param("rgt") int rgt, @Param("type") String type);
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join GroupRole gr on r.id=gr.roleId "
+ + "inner join Group_ g on gr.groupId=g.id "
+ + "inner join AccountGroup ag on g.id=ag.groupId "
+ + "inner join Account a on ag.accountId=a.id "
+ + "where a.username=:username "
+ + "and p.lft >= :lft and p.rgt <= :rgt "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("lft") int lft, @Param("rgt") int rgt, @Param("type") String type);
+
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join AccountRole ar on r.id=ar.roleId "
+ + "inner join Account a on ar.accountId=a.id "
+ + "where a.username=:username "
+ + "and p.applicationId = :applicationId "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountRolePermissionByUsername(@Param("username") String username, @Param("applicationId") String applicationId, @Param("type") String type);
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join GroupRole gr on r.id=gr.roleId "
+ + "inner join Group_ g on gr.groupId=g.id "
+ + "inner join AccountGroup ag on g.id=ag.groupId "
+ + "inner join Account a on ag.accountId=a.id "
+ + "where a.username=:username "
+ + "and p.applicationId = :applicationId "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("applicationId") String applicationId, @Param("type") String type);
+
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join AccountRole ar on r.id=ar.roleId "
+ + "inner join Account a on ar.accountId=a.id "
+ + "where a.username=:username "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountRolePermissionByUsername(@Param("username") String username, @Param("type") String type);
+
+ @Query(value = "select p from Permission p "
+ + "inner join RolePermission rp on p.id=rp.permissionId "
+ + "inner join Role r on rp.roleId=r.id "
+ + "inner join GroupRole gr on r.id=gr.roleId "
+ + "inner join Group_ g on gr.groupId=g.id "
+ + "inner join AccountGroup ag on g.id=ag.groupId "
+ + "inner join Account a on ag.accountId=a.id "
+ + "where a.username=:username "
+ + "and (:type is null or p.type=:type) "
+ + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("type") String type);
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionResourceRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionResourceRepository.java
new file mode 100644
index 0000000..c40aef7
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionResourceRepository.java
@@ -0,0 +1,194 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface PermissionResourceRepository extends BaseJpaRepository<PermissionResource> {
+
+ public default Page<PermissionResource> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+ PermissionResource probe = new PermissionResource();
+ if (mapBean != null) {
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ probe.setResourceId(MapBeanUtils.getString(mapBean, "resourceId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("resourceId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ Page<PermissionResource> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Page<PermissionResource> selectPermissionResources(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ PermissionResource probe = new PermissionResource();
+ if (mapBean != null) {
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ probe.setResourceId(MapBeanUtils.getString(mapBean, "resourceId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("resourceId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<PermissionResource> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public default void relatePermissionResources(Permission permission, List<PermissionResource> relateResources) {
+
+ List<PermissionResource> existPermissionResources = this.selectListByPermissionId(permission.getId());
+
+ Map<String, PermissionResource> existMapPermissionResources = new LinkedHashMap<String, PermissionResource>();
+ for (PermissionResource permissionResource : existPermissionResources) {
+ String k = String.format("%s", permissionResource.getResourceId());
+ existMapPermissionResources.put(k, permissionResource);
+ }
+
+ for (PermissionResource permissionResource : relateResources) {
+ String k = String.format("%s", permissionResource.getResourceId());
+
+ if (existMapPermissionResources.containsKey(k)) {
+ existMapPermissionResources.remove(k);
+ } else {
+ permissionResource.setCompanyId(permission.getCompanyId());
+ permissionResource.setPermissionId(permission.getId());
+
+ this.insert(permissionResource);
+ }
+ }
+
+ for (PermissionResource rolePermission : existMapPermissionResources.values()) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+
+ public default List<PermissionResource> selectListByPermissionId(String permissionId) {
+
+ PermissionResource probe = new PermissionResource();
+ probe.setPermissionId(permissionId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("permissionId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ List<PermissionResource> rolePermissions = this.findAll(example);
+
+ return rolePermissions;
+ }
+
+
+ public default void relateResourcePermissions(Resource resource, List<PermissionResource> relatePermissions) {
+
+ // 获取权限已关联的角色
+ List<PermissionResource> existResourcePermissions = this.selectListByResourceId(resource.getId());
+
+ Map<String, PermissionResource> existMapResourcePermissions = new LinkedHashMap<String, PermissionResource>();
+ for (PermissionResource permissionResource : existResourcePermissions) {
+ String k = String.format("%s", permissionResource.getPermissionId());
+ existMapResourcePermissions.put(k, permissionResource);
+ }
+
+ // 保存未关联的角色
+ for (PermissionResource permissionResource : relatePermissions) {
+ String k = String.format("%s", permissionResource.getPermissionId());
+
+ if (existMapResourcePermissions.containsKey(k)) {
+ existMapResourcePermissions.remove(k);
+ } else {
+ permissionResource.setCompanyId(resource.getCompanyId());
+ permissionResource.setResourceId(resource.getId());
+
+ this.insert(permissionResource);
+ }
+ }
+
+ // 删除移除关联的角色
+ for (PermissionResource rolePermission : existMapResourcePermissions.values()) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+ public default List<PermissionResource> selectListByResourceId(String resourceId) {
+
+ PermissionResource probe = new PermissionResource();
+ probe.setResourceId(resourceId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("resourceId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ List<PermissionResource> rolePermissions = this.findAll(example);
+
+ return rolePermissions;
+ }
+
+
+ public default PermissionResource selectOneByPermissionResource(String permissionId, String resourceId) {
+
+ PermissionResource probe = new PermissionResource();
+ probe.setPermissionId(permissionId);
+ probe.setResourceId(resourceId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("resourceId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ Optional<PermissionResource> o = this.findOne(example);
+
+ return o.isPresent() ? o.get() : null;
+ }
+
+ public default void addPermissionResource(String permissionId, String resourceId) {
+
+ PermissionResource rolePermission = this.selectOneByPermissionResource(permissionId, resourceId);
+
+ if (rolePermission == null) {
+ rolePermission = new PermissionResource();
+ //rolePermission.setCompanyId(companyId);
+ rolePermission.setPermissionId(permissionId);
+ rolePermission.setResourceId(resourceId);
+
+ this.insert(rolePermission);
+ }
+ }
+
+ public default void removePermissionResource(String permissionId, String resourceId) {
+
+ PermissionResource rolePermission = this.selectOneByPermissionResource(permissionId, resourceId);
+
+ if (rolePermission != null) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ResourceRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ResourceRepository.java
new file mode 100644
index 0000000..a037866
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/ResourceRepository.java
@@ -0,0 +1,127 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface ResourceRepository extends BaseJpaRepository<Resource> {
+
+ @Override
+ public default Specification<Resource> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Resource> spec = new Specification<Resource>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7690039558726467041L;
+
+ @Override
+ public Predicate toPredicate(Root<Resource> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "memo"))) {
+ predicates.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "memo") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+// @Override
+// public default Page<Resource> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+// if (loadAll) {
+// pageIndex = 0;
+// pageSize = Integer.MAX_VALUE;
+// }
+//
+// Resource probe = new Resource();
+// if (mapBean != null) {
+// probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+// probe.setCode(MapBeanUtils.getString(mapBean, "code"));
+// probe.setName(MapBeanUtils.getString(mapBean, "name"));
+// probe.setMemo(MapBeanUtils.getString(mapBean, "memo"));
+// probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+// }
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+// .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("memo", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+// Example<Resource> example = Example.of(probe, matcher);
+//
+// Page<Resource> page = this.findAll(example, pageRequest);
+//
+// return page;
+// }
+
+ public default Resource selectByCode(String code) {
+ Resource probe = new Resource();
+ probe.setCode(code);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<Resource> example = Example.of(probe, matcher);
+
+ Optional<Resource> o = this.findOne(example);
+
+ if (o.isPresent()) {
+ return o.get();
+ }
+
+ return null;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RolePermissionRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RolePermissionRepository.java
new file mode 100644
index 0000000..95f2814
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RolePermissionRepository.java
@@ -0,0 +1,193 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.entity.RolePermission;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface RolePermissionRepository extends BaseJpaRepository<RolePermission> {
+
+ public default Page<RolePermission> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+ RolePermission probe = new RolePermission();
+ if (mapBean != null) {
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ Page<RolePermission> page = this.findAll(example, pageRequest);
+
+ return page;
+ }
+
+ public default Page<RolePermission> selectRolePermissions(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ RolePermission probe = new RolePermission();
+ if (mapBean != null) {
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<RolePermission> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public default void relateRolePermissions(Role role, List<RolePermission> rolePermissions) {
+
+ List<RolePermission> existRolePermissions = this.selectListByRoleId(role.getId());
+
+ Map<String, RolePermission> existMapRolePermissions = new LinkedHashMap<String, RolePermission>();
+ for (RolePermission rolePermission : existRolePermissions) {
+ String k = String.format("%s", rolePermission.getPermissionId());
+ existMapRolePermissions.put(k, rolePermission);
+ }
+
+ for (RolePermission rolePermission : rolePermissions) {
+ String k = String.format("%s", rolePermission.getPermissionId());
+
+ if (existMapRolePermissions.containsKey(k)) {
+ existMapRolePermissions.remove(k);
+ } else {
+ rolePermission.setCompanyId(role.getCompanyId());
+ rolePermission.setRoleId(role.getId());
+
+ this.insert(rolePermission);
+ }
+ }
+
+ for (RolePermission rolePermission : existMapRolePermissions.values()) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+
+ public default List<RolePermission> selectListByRoleId(String roleId) {
+
+ RolePermission probe = new RolePermission();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("roleId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ List<RolePermission> rolePermissions = this.findAll(example);
+
+ return rolePermissions;
+ }
+
+ public default void relatePermissionRoles(Permission permission, List<RolePermission> rolePermissions) {
+
+ // 获取权限已关联的角色
+ List<RolePermission> existPermissionRoles = this.selectListByPermissionId(permission.getId());
+
+ Map<String, RolePermission> existMapPermissionRoles = new LinkedHashMap<String, RolePermission>();
+ for (RolePermission rolePermission : existPermissionRoles) {
+ String k = String.format("%s", rolePermission.getRoleId());
+ existMapPermissionRoles.put(k, rolePermission);
+ }
+
+ // 保存未关联的角色
+ for (RolePermission rolePermission : rolePermissions) {
+ String k = String.format("%s", rolePermission.getRoleId());
+
+ if (existMapPermissionRoles.containsKey(k)) {
+ existMapPermissionRoles.remove(k);
+ } else {
+ rolePermission.setCompanyId(permission.getCompanyId());
+ rolePermission.setPermissionId(permission.getId());
+
+ this.insert(rolePermission);
+ }
+ }
+
+ // 删除移除关联的角色
+ for (RolePermission rolePermission : existMapPermissionRoles.values()) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+
+ public default List<RolePermission> selectListByPermissionId(String permissionId) {
+
+ RolePermission probe = new RolePermission();
+ probe.setPermissionId(permissionId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("permissionId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ List<RolePermission> rolePermissions = this.findAll(example);
+
+ return rolePermissions;
+ }
+
+ public default RolePermission selectOneByRolePermission(String roleId, String permissionId) {
+
+ RolePermission probe = new RolePermission();
+ probe.setRoleId(roleId);
+ probe.setPermissionId(permissionId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ Optional<RolePermission> o = this.findOne(example);
+
+ return o.isPresent() ? o.get() : null;
+ }
+
+ public default void addRolePermission(String roleId, String permissionId) {
+
+ RolePermission rolePermission = this.selectOneByRolePermission(roleId, permissionId);
+
+ if (rolePermission == null) {
+ rolePermission = new RolePermission();
+ //rolePermission.setCompanyId(companyId);
+ rolePermission.setRoleId(roleId);
+ rolePermission.setPermissionId(permissionId);
+
+ this.insert(rolePermission);
+ }
+ }
+
+ public default void removeRolePermission(String roleId, String permissionId) {
+
+ RolePermission rolePermission = this.selectOneByRolePermission(roleId, permissionId);
+
+ if (rolePermission != null) {
+ this.deleteById(rolePermission.getId());
+ }
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java
new file mode 100644
index 0000000..00c3ee6
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java
@@ -0,0 +1,164 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface RoleRepository extends BaseJpaRepository<Role> {
+
+ @Override
+ public default Specification<Role> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Role> spec = new Specification<Role>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -263282246904382286L;
+
+ @Override
+ public Predicate toPredicate(Root<Role> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "memo"))) {
+ predicates.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "memo") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+// @Override
+// public default Page<Role> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+// if (loadAll) {
+// pageIndex = 0;
+// pageSize = Integer.MAX_VALUE;
+// }
+//
+// Role probe = new Role();
+// if (mapBean != null) {
+// probe.setDeleted(MapBeanUtils.getBoolean(mapBean, "deleted"));
+// probe.setCode(MapBeanUtils.getString(mapBean, "code"));
+// probe.setName(MapBeanUtils.getString(mapBean, "name"));
+// probe.setMemo(MapBeanUtils.getString(mapBean, "memo"));
+// probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+// }
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("deleted", ExampleMatcher.GenericPropertyMatchers.exact())
+// .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("memo", ExampleMatcher.GenericPropertyMatchers.contains())
+// .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+// Example<Role> example = Example.of(probe, matcher);
+//
+// Page<Role> page = this.findAll(example, pageRequest);
+//
+// return page;
+// }
+
+
+ public default Role selectByCode(String code) {
+ Role probe = new Role();
+ probe.setCode(code);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<Role> example = Example.of(probe, matcher);
+
+ Optional<Role> o = this.findOne(example);
+
+ if (o.isPresent()) {
+ return o.get();
+ }
+
+ return null;
+ }
+
+ @Query(value = "select r from Role r "
+ + "inner join AccountRole ar on r.id=ar.roleId "
+ + "inner join Account a on ar.accountId=a.id "
+ + "where a.username=:username "
+ + "and r.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Role> selectAccountRoleByUsername(@Param("username") String username);
+
+ @Query(value = "select r from Role r "
+ + "inner join GroupRole gr on r.id=gr.roleId "
+ + "inner join Group_ g on gr.groupId=g.id "
+ + "inner join AccountGroup ag on g.id=ag.groupId "
+ + "inner join Account a on ag.accountId=a.id "
+ + "where a.username=:username "
+ + "and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+ public List<Role> selectAccountGroupRoleByUsername(@Param("username") String username);
+
+
+ @Query(value = "select r from Role r "
+ + "inner join RolePermission rp on r.id=rp.roleId "
+ + "inner join Permission p on rp.permissionId=p.id "
+ + "where p.id=:permissionId "
+ + "and r.status='1' and p.status='1' ")
+ public List<Role> selectPermissionRolesByPermission(@Param("permissionId") String permissionId);
+
+
+ @Query(value = "select r from Role r "
+ + "inner join RolePermission rp on r.id=rp.roleId "
+ + "inner join Permission p on rp.permissionId=p.id "
+ + "inner join PermissionResource pres on p.id=pres.permissionId "
+ + "inner join Resource res on pres.resourceId=res.id "
+ + "where res.id=:resourceId "
+ + "and r.status='1' and p.status='1' and res.status='1' ")
+ public List<Role> selectResourceRolesByResource(@Param("resourceId") String resourceId);
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RouteRepository.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RouteRepository.java
new file mode 100644
index 0000000..425138b
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RouteRepository.java
@@ -0,0 +1,76 @@
+package com.supwisdom.institute.backend.base.domain.repo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface RouteRepository extends BaseJpaRepository<Route> {
+
+ @Override
+ public default Specification<Route> convertToSpec(Map<String, Object> mapBean) {
+
+ Specification<Route> spec = new Specification<Route>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 9131799274128286026L;
+
+ @Override
+ public Predicate toPredicate(Root<Route> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+
+ if (MapBeanUtils.getBoolean(mapBean, "deleted") != null) {
+ predicates.add(criteriaBuilder.equal(root.get("deleted"), MapBeanUtils.getBoolean(mapBean, "deleted")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "code"))) {
+ predicates.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "code") + "%"));
+ }
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "name") + "%"));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "status"))) {
+ predicates.add(criteriaBuilder.equal(root.get("status"), MapBeanUtils.getString(mapBean, "status")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "url"))) {
+ predicates.add(criteriaBuilder.like(root.get("url"), "%" + MapBeanUtils.getString(mapBean, "url") + "%"));
+ }
+
+ List<Predicate> predicatesKeyword = new ArrayList<>();
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "keyword"))) {
+ predicatesKeyword.add(criteriaBuilder.like(root.get("code"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("name"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+ predicatesKeyword.add(criteriaBuilder.like(root.get("memo"), "%" + MapBeanUtils.getString(mapBean, "keyword") + "%"));
+
+ predicates.add(criteriaBuilder.or(predicatesKeyword.toArray(new Predicate[predicatesKeyword.size()])));
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/.gitkeep b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/.gitkeep
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java
new file mode 100644
index 0000000..b0cad6c
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java
@@ -0,0 +1,203 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.base.domain.repo.AccountGroupRepository;
+import com.supwisdom.institute.backend.base.domain.repo.AccountRepository;
+import com.supwisdom.institute.backend.base.domain.repo.AccountRoleRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Service
+public class AccountService extends ABaseService<Account, AccountRepository> {
+
+ @Override
+ public AccountRepository getRepo() {
+ return accountRepository;
+ }
+
+ @Autowired
+ private AccountRepository accountRepository;
+
+ @Autowired
+ private AccountGroupRepository accountGroupRepository;
+
+ @Autowired
+ private AccountRoleRepository accountRoleRepository;
+
+
+ @Override
+ public Account insert(Account entity) {
+
+ entity.setEnabled(Account.STATUS_ENABLED.equals(entity.getStatus()));
+ entity.setAccountNonExpired(true);
+ entity.setAccountNonLocked(true);
+ entity.setCredentialsNonExpired(true);
+
+ return super.insert(entity);
+ }
+
+ @Override
+ public Account update(Account entity) {
+
+ entity.setEnabled(Account.STATUS_ENABLED.equals(entity.getStatus()));
+
+ return super.update(entity);
+ }
+
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+ public Page<AccountGroup> selectAccountGroups(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountGroup probe = new AccountGroup();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountGroup> page = accountGroupRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateAccountGroups(Account account, List<AccountGroup> accountGroups) {
+
+ List<AccountGroup> existAccountGroups = this.selectAccountGroupsByAccountId(account.getId());
+
+ Map<String, AccountGroup> existMapAccountGroups = new LinkedHashMap<String, AccountGroup>();
+ for (AccountGroup accountGroup : existAccountGroups) {
+ String k = String.format("%s", accountGroup.getGroupId());
+ existMapAccountGroups.put(k, accountGroup);
+ }
+
+ for (AccountGroup accountGroup : accountGroups) {
+ String k = String.format("%s", accountGroup.getGroupId());
+
+ if (existMapAccountGroups.containsKey(k)) {
+ existMapAccountGroups.remove(k);
+ } else {
+ accountGroup.setCompanyId(account.getCompanyId());
+ accountGroup.setAccountId(account.getId());
+
+ accountGroupRepository.insert(accountGroup);
+ }
+ }
+
+ for (AccountGroup accountGroup : existMapAccountGroups.values()) {
+ accountGroupRepository.deleteById(accountGroup.getId());
+ }
+ }
+
+ public List<AccountGroup> selectAccountGroupsByAccountId(String accountId) {
+
+ AccountGroup probe = new AccountGroup();
+ probe.setAccountId(accountId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ List<AccountGroup> accountGroups = accountGroupRepository.findAll(example);
+
+ return accountGroups;
+ }
+
+
+
+ public Page<AccountRole> selectAccountRoles(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountRole probe = new AccountRole();
+ if (mapBean != null) {
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountRole> page = accountRoleRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateAccountRoles(Account account, List<AccountRole> accountRoles) {
+
+ List<AccountRole> existAccountRoles = this.selectAccountRolesByAccountId(account.getId());
+
+ Map<String, AccountRole> existMapAccountRoles = new LinkedHashMap<String, AccountRole>();
+ for (AccountRole accountRole : existAccountRoles) {
+ String k = String.format("%s", accountRole.getRoleId());
+ existMapAccountRoles.put(k, accountRole);
+ }
+
+ for (AccountRole accountRole : accountRoles) {
+ String k = String.format("%s", accountRole.getRoleId());
+
+ if (existMapAccountRoles.containsKey(k)) {
+ existMapAccountRoles.remove(k);
+ } else {
+ accountRole.setCompanyId(account.getCompanyId());
+ accountRole.setAccountId(account.getId());
+
+ accountRoleRepository.insert(accountRole);
+ }
+ }
+
+ for (AccountRole accountRole : existMapAccountRoles.values()) {
+ accountRoleRepository.deleteById(accountRole.getId());
+ }
+ }
+
+ public List<AccountRole> selectAccountRolesByAccountId(String accountId) {
+
+ AccountRole probe = new AccountRole();
+ probe.setAccountId(accountId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ List<AccountRole> accountRoles = accountRoleRepository.findAll(example);
+
+ return accountRoles;
+ }
+
+
+ public Account selectByUsername(String username) {
+ return accountRepository.selectByUsername(username);
+ }
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ApplicationService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ApplicationService.java
new file mode 100644
index 0000000..17e7503
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ApplicationService.java
@@ -0,0 +1,91 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Application;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.repo.ApplicationRepository;
+import com.supwisdom.institute.backend.base.domain.repo.PermissionRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+
+@Service
+public class ApplicationService extends ABaseService<Application, ApplicationRepository> {
+
+ @Override
+ public ApplicationRepository getRepo() {
+ return applicationRepository;
+ }
+
+ @Autowired
+ private ApplicationRepository applicationRepository;
+
+ @Autowired
+ private PermissionRepository permissionRepository;
+
+ @Override
+ public Application insert(Application entity) {
+ entity = super.insert(entity);
+
+ Permission p = new Permission();
+ p.setId(entity.getId());
+ p.setCode(entity.getCode());
+ p.setName(entity.getName());
+ p.setMemo(entity.getMemo());
+ p.setStatus(entity.getStatus());
+ p.setType(Permission.TYPE_APPLICATION);
+ p.setApplicationId(entity.getId());
+ p.setParentId(Permission.ROOT_PARENT_ID);
+ p.setOrder(Permission.DEFAULT_ORDER);
+
+ permissionRepository.insert(p);
+
+ return entity;
+ }
+
+ @Override
+ public Application update(Application entity) {
+ entity = super.update(entity);
+
+ Permission p = permissionRepository.selectById(entity.getId());
+ if (p != null) {
+ p = new Permission();
+ p.setCode(entity.getCode());
+ p.setName(entity.getName());
+ p.setMemo(entity.getMemo());
+ p.setStatus(entity.getStatus());
+ p.setType(Permission.TYPE_APPLICATION);
+ p.setApplicationId(entity.getId());
+ p.setParentId(Permission.ROOT_PARENT_ID);
+ p.setOrder(Permission.DEFAULT_ORDER);
+
+ permissionRepository.update(p);
+ } else {
+ p = new Permission();
+ p.setId(entity.getId());
+ p.setCode(entity.getCode());
+ p.setName(entity.getName());
+ p.setMemo(entity.getMemo());
+ p.setStatus(entity.getStatus());
+ p.setType(Permission.TYPE_APPLICATION);
+ p.setApplicationId(entity.getId());
+ p.setParentId(Permission.ROOT_PARENT_ID);
+ p.setOrder(Permission.DEFAULT_ORDER);
+
+ permissionRepository.insert(p);
+ }
+
+ return entity;
+ }
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ConfigService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ConfigService.java
new file mode 100644
index 0000000..d41e362
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ConfigService.java
@@ -0,0 +1,26 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Config;
+import com.supwisdom.institute.backend.base.domain.repo.ConfigRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+
+@Service
+public class ConfigService extends ABaseService<Config, ConfigRepository> {
+
+ @Override
+ public ConfigRepository getRepo() {
+ return configRepository;
+ }
+
+ @Autowired
+ private ConfigRepository configRepository;
+
+ public Config selectByCategoryKey(String categoryCode, String configKey) {
+
+ return configRepository.selectByCategoryKey(categoryCode, configKey);
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/GroupService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/GroupService.java
new file mode 100644
index 0000000..9951b3a
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/GroupService.java
@@ -0,0 +1,182 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountGroup;
+import com.supwisdom.institute.backend.base.domain.entity.Group;
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.base.domain.repo.AccountGroupRepository;
+import com.supwisdom.institute.backend.base.domain.repo.GroupRepository;
+import com.supwisdom.institute.backend.base.domain.repo.GroupRoleRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Service
+public class GroupService extends ABaseService<Group, GroupRepository> {
+
+ @Override
+ public GroupRepository getRepo() {
+ return groupRepository;
+ }
+
+ @Autowired
+ private GroupRepository groupRepository;
+
+ @Autowired
+ private AccountGroupRepository accountGroupRepository;
+
+ @Autowired
+ private GroupRoleRepository groupRoleRepository;
+
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+ public Page<AccountGroup> selectGroupAccounts(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountGroup probe = new AccountGroup();
+ if (mapBean != null) {
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ ;
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountGroup> page = accountGroupRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateGroupAccounts(Group group, List<AccountGroup> accountGroups) {
+
+ List<AccountGroup> existGroupAccounts = this.selectGroupAccountsByGroupId(group.getId());
+
+ Map<String, AccountGroup> existMapGroupAccounts = new LinkedHashMap<String, AccountGroup>();
+ for (AccountGroup accountGroup : existGroupAccounts) {
+ String k = String.format("%s", accountGroup.getAccountId());
+ existMapGroupAccounts.put(k, accountGroup);
+ }
+
+ for (AccountGroup accountGroup : accountGroups) {
+ String k = String.format("%s", accountGroup.getAccountId());
+
+ if (existMapGroupAccounts.containsKey(k)) {
+ existMapGroupAccounts.remove(k);
+ } else {
+ accountGroup.setCompanyId(group.getCompanyId());
+ accountGroup.setGroupId(group.getId());
+
+ accountGroupRepository.insert(accountGroup);
+ }
+ }
+
+ for (AccountGroup accountGroup : existMapGroupAccounts.values()) {
+ accountGroupRepository.deleteById(accountGroup.getId());
+ }
+ }
+
+ public List<AccountGroup> selectGroupAccountsByGroupId(String groupId) {
+
+ AccountGroup probe = new AccountGroup();
+ probe.setGroupId(groupId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountGroup> example = Example.of(probe, matcher);
+
+ List<AccountGroup> accountGroups = accountGroupRepository.findAll(example);
+
+ return accountGroups;
+ }
+
+
+
+
+ public Page<GroupRole> selectGroupRoles(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ GroupRole probe = new GroupRole();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<GroupRole> page = groupRoleRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateGroupRoles(Group group, List<GroupRole> groupRoles) {
+
+ List<GroupRole> existGroupRoles = this.selectGroupRolesByGroupId(group.getId());
+
+ Map<String, GroupRole> existMapGroupRoles = new LinkedHashMap<String, GroupRole>();
+ for (GroupRole groupRole : existGroupRoles) {
+ String k = String.format("%s", groupRole.getRoleId());
+ existMapGroupRoles.put(k, groupRole);
+ }
+
+ for (GroupRole groupRole : groupRoles) {
+ String k = String.format("%s", groupRole.getRoleId());
+
+ if (existMapGroupRoles.containsKey(k)) {
+ existMapGroupRoles.remove(k);
+ } else {
+ groupRole.setCompanyId(group.getCompanyId());
+ groupRole.setGroupId(group.getId());
+
+ groupRoleRepository.insert(groupRole);
+ }
+ }
+
+ for (GroupRole groupRole : existMapGroupRoles.values()) {
+ groupRoleRepository.deleteById(groupRole.getId());
+ }
+ }
+
+ public List<GroupRole> selectGroupRolesByGroupId(String groupId) {
+
+ GroupRole probe = new GroupRole();
+ probe.setGroupId(groupId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("groupId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ List<GroupRole> groupRoles = groupRoleRepository.findAll(example);
+
+ return groupRoles;
+ }
+
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java
new file mode 100644
index 0000000..c546400
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java
@@ -0,0 +1,319 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.PermissionResource;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.model.PermissionRoleSet;
+import com.supwisdom.institute.backend.base.domain.model.PermissionTreeNode;
+import com.supwisdom.institute.backend.base.domain.repo.PermissionRepository;
+import com.supwisdom.institute.backend.base.domain.repo.PermissionResourceRepository;
+import com.supwisdom.institute.backend.base.domain.repo.RoleRepository;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Slf4j
+@Service
+public class PermissionService extends ABaseService<Permission, PermissionRepository> {
+
+ @Override
+ public PermissionRepository getRepo() {
+ return permissionRepository;
+ }
+
+ @Autowired
+ private PermissionRepository permissionRepository;
+
+ @Autowired
+ private PermissionResourceRepository permissionResourceRepository;
+
+ @Autowired
+ private RoleRepository roleRepository;
+
+ @Override
+ public Permission insert(Permission entity) {
+ Permission parentPermission = permissionRepository.selectById(entity.getParentId());
+ if (parentPermission != null) {
+ entity.setApplicationId(parentPermission.getApplicationId());
+ }
+
+ return super.insert(entity);
+ }
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+
+ public Page<PermissionResource> selectPermissionResources(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ if (loadAll) {
+ pageIndex = 0;
+ pageSize = Integer.MAX_VALUE;
+ }
+
+ PermissionResource probe = new PermissionResource();
+ if (mapBean != null) {
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ probe.setResourceId(MapBeanUtils.getString(mapBean, "resourceId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("resourceId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<PermissionResource> page = permissionResourceRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relatePermissionResources(Permission permission, List<PermissionResource> permissionResources) {
+
+ List<PermissionResource> existPermissionResources = this.selectPermissionResourcesByPermissionId(permission.getId());
+
+ Map<String, PermissionResource> existMapPermissionResources = new LinkedHashMap<String, PermissionResource>();
+ for (PermissionResource permissionResource : existPermissionResources) {
+ String k = String.format("%s", permissionResource.getPermissionId());
+ existMapPermissionResources.put(k, permissionResource);
+ }
+
+ for (PermissionResource permissionResource : permissionResources) {
+ String k = String.format("%s", permissionResource.getPermissionId());
+
+ if (existMapPermissionResources.containsKey(k)) {
+ existMapPermissionResources.remove(k);
+ } else {
+ permissionResource.setCompanyId(permission.getCompanyId());
+ permissionResource.setPermissionId(permission.getId());
+
+ permissionResourceRepository.insert(permissionResource);
+ }
+ }
+
+ for (PermissionResource permissionResource : existMapPermissionResources.values()) {
+ permissionResourceRepository.deleteById(permissionResource.getId());
+ }
+ }
+
+ public List<PermissionResource> selectPermissionResourcesByPermissionId(String permissionId) {
+
+ PermissionResource probe = new PermissionResource();
+ probe.setPermissionId(permissionId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("permissionId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<PermissionResource> example = Example.of(probe, matcher);
+
+ List<PermissionResource> permissionResources = permissionResourceRepository.findAll(example);
+
+ return permissionResources;
+ }
+
+
+ private Permission selectApplicationPermission() {
+ Permission permission = permissionRepository.selectById(Permission.APPLICATION_ID);
+
+ return permission;
+ }
+
+ private List<Permission> selectApplicationPermissionList() {
+ Map<String, Object> mapBean = new HashMap<String, Object>();
+ mapBean.put("type", Permission.TYPE_APPLICATION);
+
+ return permissionRepository.selectList(true, -1, -1, mapBean, null);
+ }
+
+ public PermissionTreeNode selectPermissionTree(String applicationId, String type) {
+
+ Map<String, Object> mapBean = new HashMap<String, Object>();
+ if (StringUtils.isNotBlank(type)) {
+ mapBean.put("type", type);
+ }
+
+ String rootTreeNodeId = "0";
+
+ List<Permission> permissions = new ArrayList<Permission>();
+
+ if (StringUtils.isBlank(applicationId)) {
+ Permission rootPermission = new Permission();
+ rootPermission.setId(Permission.ROOT_PARENT_ID);
+ rootPermission.setCode("root");
+ rootPermission.setName("根");
+
+ permissions.add(rootPermission);
+ rootTreeNodeId = rootPermission.getId();
+
+ List<Permission> applicationPermissions = this.selectApplicationPermissionList();
+ permissions.addAll(applicationPermissions);
+ } else {
+ Permission applicationPermission = permissionRepository.selectById(applicationId); // this.selectApplicationPermissionByCode(applicationCode);
+ if (applicationPermission == null) {
+ return null;
+ }
+
+ permissions.add(applicationPermission);
+ rootTreeNodeId = applicationPermission.getId();
+ }
+
+ List<Permission> menuPermissions = permissionRepository.selectList(true, -1, -1, mapBean, null);
+ permissions.addAll(menuPermissions);
+
+ return convertPermissionTree(permissions, rootTreeNodeId);
+ }
+
+ private PermissionTreeNode convertPermissionTree(List<Permission> permissions, String rootTreeNodeId) {
+ if (permissions == null || permissions.size() == 0) {
+ return null;
+ }
+
+ Map<String, PermissionTreeNode> parentTreeNode = new LinkedHashMap<String, PermissionTreeNode>();
+
+ for (Permission permission : permissions) {
+ PermissionTreeNode treeNode = EntityUtils.copy(permission, new PermissionTreeNode());
+ treeNode.setChildren(new ArrayList<PermissionTreeNode>());
+
+ if (parentTreeNode.containsKey(treeNode.getId())) {
+ continue;
+ }
+ parentTreeNode.put(treeNode.getId(), treeNode);
+ }
+
+ for (PermissionTreeNode treeNode : parentTreeNode.values()) {
+ if (!parentTreeNode.containsKey(treeNode.getParentId())) {
+ continue;
+ }
+
+ parentTreeNode.get(treeNode.getParentId()).getChildren().add(treeNode);
+ }
+
+ return parentTreeNode.get(rootTreeNodeId);
+ }
+
+
+
+// public Permission selectApplicationPermissionByCode(String code) {
+// Permission probe = new Permission();
+// probe.setCode(code);
+// probe.setType("1");
+//
+// ExampleMatcher matcher = ExampleMatcher.matching()
+// .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact())
+// .withMatcher("type", ExampleMatcher.GenericPropertyMatchers.exact());
+//
+// Example<Permission> example = Example.of(probe, matcher);
+//
+// Optional<Permission> o = permissionRepository.findOne(example);
+//
+// if (o.isPresent()) {
+// return o.get();
+// }
+//
+// return null;
+// }
+
+
+ public List<Permission> selectByUsername(String username, String applicationId, String type) {
+ List<Permission> permissions = new ArrayList<Permission>();
+
+// Permission applicationPermission = permissionRepository.selectById(applicationId);
+// if (applicationPermission == null) {
+// return permissions;
+// }
+//
+// int lft = applicationPermission.getLft();
+// int rgt = applicationPermission.getRgt();
+
+ if (StringUtils.isBlank(applicationId)) {
+ List<Permission> accountRolePermissions = permissionRepository.selectAccountRolePermissionByUsername(username, type);
+ permissions.addAll(accountRolePermissions);
+
+ List<Permission> accountGroupRolePermissions = permissionRepository.selectAccountGroupRolePermissionByUsername(username, type);
+ permissions.addAll(accountGroupRolePermissions);
+ } else {
+ List<Permission> accountRolePermissions = permissionRepository.selectAccountRolePermissionByUsername(username, applicationId, type);
+ permissions.addAll(accountRolePermissions);
+
+ List<Permission> accountGroupRolePermissions = permissionRepository.selectAccountGroupRolePermissionByUsername(username, applicationId, type);
+ permissions.addAll(accountGroupRolePermissions);
+ }
+
+ return EntityUtils.distinctList(permissions);
+ }
+
+ @Deprecated
+ public PermissionTreeNode selectPermissionTreeByUsername(String username, String applicationId, String type) {
+ String rootTreeNodeId = "0";
+
+ List<Permission> permissions = new ArrayList<Permission>();
+
+ if (StringUtils.isBlank(applicationId)) {
+ Permission rootPermission = new Permission();
+ rootPermission.setId(Permission.ROOT_PARENT_ID);
+ rootPermission.setCode("root");
+ rootPermission.setName("根");
+
+ permissions.add(rootPermission);
+ rootTreeNodeId = rootPermission.getId();
+
+ List<Permission> applicationPermissions = this.selectApplicationPermissionList();
+ permissions.addAll(applicationPermissions);
+ } else {
+ Permission applicationPermission = permissionRepository.selectById(applicationId); // this.selectApplicationPermissionByCode(applicationCode);
+ if (applicationPermission == null) {
+ return null;
+ }
+
+ permissions.add(applicationPermission);
+ rootTreeNodeId = applicationPermission.getId();
+ }
+
+ List<Permission> menuPermissions = this.selectByUsername(username, applicationId, type);
+ permissions.addAll(menuPermissions);
+
+ return convertPermissionTree(permissions, rootTreeNodeId);
+ }
+
+ public List<PermissionRoleSet> selectPermissionRoleSet(Map<String, Object> mapBean) {
+
+ List<PermissionRoleSet> prsList = new ArrayList<>();
+
+ List<Permission> resourceList = permissionRepository.selectList(mapBean, null);
+
+ for (Permission permission : resourceList) {
+
+ List<Role> roleList = roleRepository.selectPermissionRolesByPermission(permission.getId());
+
+ PermissionRoleSet prs = new PermissionRoleSet(permission, roleList);
+
+ prsList.add(prs);
+ }
+
+ return prsList;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ResourceService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ResourceService.java
new file mode 100644
index 0000000..eea0422
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/ResourceService.java
@@ -0,0 +1,58 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.model.ResourceRoleSet;
+import com.supwisdom.institute.backend.base.domain.repo.ResourceRepository;
+import com.supwisdom.institute.backend.base.domain.repo.RoleRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+
+@Service
+public class ResourceService extends ABaseService<Resource, ResourceRepository> {
+
+ @Override
+ public ResourceRepository getRepo() {
+ return resourceRepository;
+ }
+
+ @Autowired
+ private ResourceRepository resourceRepository;
+
+ @Autowired
+ private RoleRepository roleRepository;
+
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+ public List<ResourceRoleSet> selectResourceRoleSet(Map<String, Object> mapBean) {
+
+ List<ResourceRoleSet> rrsList = new ArrayList<>();
+
+ List<Resource> resourceList = resourceRepository.selectList(mapBean, null);
+
+ for (Resource resource : resourceList) {
+
+ List<Role> roleList = roleRepository.selectResourceRolesByResource(resource.getId());
+
+ ResourceRoleSet rrs = new ResourceRoleSet(resource, roleList);
+
+ rrsList.add(rrs);
+ }
+
+ return rrsList;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java
new file mode 100644
index 0000000..c66e3ff
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java
@@ -0,0 +1,268 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.AccountRole;
+import com.supwisdom.institute.backend.base.domain.entity.GroupRole;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.entity.RolePermission;
+import com.supwisdom.institute.backend.base.domain.repo.AccountRoleRepository;
+import com.supwisdom.institute.backend.base.domain.repo.GroupRoleRepository;
+import com.supwisdom.institute.backend.base.domain.repo.RolePermissionRepository;
+import com.supwisdom.institute.backend.base.domain.repo.RoleRepository;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Service
+public class RoleService extends ABaseService<Role, RoleRepository> {
+
+ @Override
+ public RoleRepository getRepo() {
+ return roleRepository;
+ }
+
+ @Autowired
+ private RoleRepository roleRepository;
+
+ @Autowired
+ private AccountRoleRepository accountRoleRepository;
+
+ @Autowired
+ private GroupRoleRepository groupRoleRepository;
+
+ @Autowired
+ private RolePermissionRepository rolePermissionRepository;
+
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+ public Page<AccountRole> selectRoleAccounts(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ AccountRole probe = new AccountRole();
+ if (mapBean != null) {
+ probe.setAccountId(MapBeanUtils.getString(mapBean, "accountId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("accountId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<AccountRole> page = accountRoleRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateRoleAccounts(Role role, List<AccountRole> roleAccounts) {
+
+ List<AccountRole> existRoleAccounts = this.selectRoleAccountsByRoleId(role.getId());
+
+ Map<String, AccountRole> existMapRoleAccounts = new LinkedHashMap<String, AccountRole>();
+ for (AccountRole accountRole : existRoleAccounts) {
+ String k = String.format("%s", accountRole.getAccountId());
+ existMapRoleAccounts.put(k, accountRole);
+ }
+
+ for (AccountRole accountRole : roleAccounts) {
+ String k = String.format("%s", accountRole.getAccountId());
+
+ if (existMapRoleAccounts.containsKey(k)) {
+ existMapRoleAccounts.remove(k);
+ } else {
+ accountRole.setCompanyId(role.getCompanyId());
+ accountRole.setRoleId(role.getId());
+
+ accountRoleRepository.insert(accountRole);
+ }
+ }
+
+ for (AccountRole accountRole : existMapRoleAccounts.values()) {
+ accountRoleRepository.deleteById(accountRole.getId());
+ }
+ }
+
+ public List<AccountRole> selectRoleAccountsByRoleId(String roleId) {
+
+ AccountRole probe = new AccountRole();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<AccountRole> example = Example.of(probe, matcher);
+
+ List<AccountRole> accountRoles = accountRoleRepository.findAll(example);
+
+ return accountRoles;
+ }
+
+
+
+ public Page<GroupRole> selectRoleGroups(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ GroupRole probe = new GroupRole();
+ if (mapBean != null) {
+ probe.setGroupId(MapBeanUtils.getString(mapBean, "groupId"));
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("groupId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<GroupRole> page = groupRoleRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateRoleGroups(Role role, List<GroupRole> groupRoles) {
+
+ List<GroupRole> existRoleGroups = this.selectRoleGroupsByRoleId(role.getCode());
+
+ Map<String, GroupRole> existMapRoleGroups = new LinkedHashMap<String, GroupRole>();
+ for (GroupRole groupRole : existRoleGroups) {
+ String k = String.format("%s", groupRole.getGroupId());
+ existMapRoleGroups.put(k, groupRole);
+ }
+
+ for (GroupRole groupRole : groupRoles) {
+ String k = String.format("%s", groupRole.getGroupId());
+
+ if (existMapRoleGroups.containsKey(k)) {
+ existMapRoleGroups.remove(k);
+ } else {
+ groupRole.setCompanyId(role.getCompanyId());
+ groupRole.setRoleId(role.getId());
+
+ groupRoleRepository.insert(groupRole);
+ }
+ }
+
+ for (GroupRole groupRole : existMapRoleGroups.values()) {
+ groupRoleRepository.deleteById(groupRole.getId());
+ }
+ }
+
+ public List<GroupRole> selectRoleGroupsByRoleId(String roleId) {
+
+ GroupRole probe = new GroupRole();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<GroupRole> example = Example.of(probe, matcher);
+
+ List<GroupRole> groupRoles = groupRoleRepository.findAll(example);
+
+ return groupRoles;
+ }
+
+
+ public Page<RolePermission> selectRolePermissions(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+ RolePermission probe = new RolePermission();
+ if (mapBean != null) {
+ probe.setRoleId(MapBeanUtils.getString(mapBean, "roleId"));
+ probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+ }
+
+ ExampleMatcher matcher = ExampleMatcher.matching()
+ .withMatcher("roleId", ExampleMatcher.GenericPropertyMatchers.exact())
+ .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+ Page<RolePermission> page = rolePermissionRepository.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+ return page;
+ }
+
+ public void relateRolePermissions(Role role, List<RolePermission> rolePermissions) {
+
+ List<RolePermission> existRolePermissions = this.selectRolePermissionsByRoleId(role.getId());
+
+ Map<String, RolePermission> existMapRolePermissions = new LinkedHashMap<String, RolePermission>();
+ for (RolePermission rolePermission : existRolePermissions) {
+ String k = String.format("%s", rolePermission.getPermissionId());
+ existMapRolePermissions.put(k, rolePermission);
+ }
+
+ for (RolePermission rolePermission : rolePermissions) {
+ String k = String.format("%s", rolePermission.getPermissionId());
+
+ if (existMapRolePermissions.containsKey(k)) {
+ existMapRolePermissions.remove(k);
+ } else {
+ rolePermission.setCompanyId(role.getCompanyId());
+ rolePermission.setRoleId(role.getId());
+
+ rolePermissionRepository.insert(rolePermission);
+ }
+ }
+
+ for (RolePermission rolePermission : existMapRolePermissions.values()) {
+ rolePermissionRepository.deleteById(rolePermission.getId());
+ }
+ }
+
+ public List<RolePermission> selectRolePermissionsByRoleId(String roleId) {
+
+ RolePermission probe = new RolePermission();
+ probe.setRoleId(roleId);
+
+ ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("roleId",
+ ExampleMatcher.GenericPropertyMatchers.exact());
+
+ Example<RolePermission> example = Example.of(probe, matcher);
+
+ List<RolePermission> rolePermissions = rolePermissionRepository.findAll(example);
+
+ return rolePermissions;
+ }
+
+
+
+
+ public List<Role> selectByUsername(String username) {
+ List<Role> roles = new ArrayList<Role>();
+
+ List<Role> userRoles = roleRepository.selectAccountRoleByUsername(username);
+ roles.addAll(userRoles);
+
+ List<Role> userGroupRoles = roleRepository.selectAccountGroupRoleByUsername(username);
+ roles.addAll(userGroupRoles);
+
+ roles = EntityUtils.distinctList(roles);
+
+ return roles;
+ }
+
+}
diff --git a/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RouteService.java b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RouteService.java
new file mode 100644
index 0000000..f93595f
--- /dev/null
+++ b/admin-sa/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RouteService.java
@@ -0,0 +1,32 @@
+package com.supwisdom.institute.backend.base.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.base.domain.entity.Route;
+import com.supwisdom.institute.backend.base.domain.repo.RouteRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+
+@Service
+public class RouteService extends ABaseService<Route, RouteRepository> {
+
+ @Override
+ public RouteRepository getRepo() {
+ return routeRepository;
+ }
+
+ @Autowired
+ private RouteRepository routeRepository;
+
+
+ public void deleteBatch(List<String> ids) {
+
+ ids.stream().forEach(id -> {
+ this.deleteById(id);
+ });
+ }
+
+
+}
diff --git a/admin-sa/base/pom.xml b/admin-sa/base/pom.xml
new file mode 100644
index 0000000..9cfaad2
--- /dev/null
+++ b/admin-sa/base/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-aggregator</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework Admin Base Aggregator</name>
+ <description>Supwisdom Backend Framework Admin Base Aggregator project</description>
+
+ <modules>
+ <module>domain</module>
+ <module>api</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/admin-sa/pom.xml b/admin-sa/pom.xml
new file mode 100644
index 0000000..8e04113
--- /dev/null
+++ b/admin-sa/pom.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework Admin SuperAdmin API Parent</name>
+ <description>Supwisdom Backend Framework Admin SuperAdmin API Parent project</description>
+
+ <modules>
+ <module>base</module>
+ <module>sa</module>
+ </modules>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ </properties>
+
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-bom</artifactId>
+ <version>${infras.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-domain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>8.0.12</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <version>${dockerfile-maven-plugin.version}</version>
+ <configuration>
+ <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
+ <tag>${project.version}</tag>
+ <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+ <buildArgs>
+ <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
+ <VERSION>${project.version}</VERSION>
+ <NAME>${project.artifactId}</NAME>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/admin-sa/sa/.gitignore b/admin-sa/sa/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/admin-sa/sa/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/admin-sa/sa/Dockerfile b/admin-sa/sa/Dockerfile
new file mode 100644
index 0000000..f7bf86e
--- /dev/null
+++ b/admin-sa/sa/Dockerfile
@@ -0,0 +1,18 @@
+FROM harbor.supwisdom.com/institute/openjdk:8-jre-alpine
+
+ENV ENABLE_JMX_SSL=false
+ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker
+ENV SPRING_PROFILES_ACTIVE=docker
+
+ARG NAME
+ARG VERSION
+ARG JAR_FILE
+
+LABEL name=$NAME \
+ version=$VERSION
+
+EXPOSE 8080
+
+EXPOSE 8443
+
+COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar
diff --git a/admin-sa/sa/pom.xml b/admin-sa/sa/pom.xml
new file mode 100644
index 0000000..54c3077
--- /dev/null
+++ b/admin-sa/sa/pom.xml
@@ -0,0 +1,203 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-sa</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Admin SuperAdmin API</name>
+ <description>Supwisdom Backend Framework Admin SuperAdmin API project</description>
+
+ <properties>
+ <start-class>com.supwisdom.institute.backend.admin.sa.Application</start-class>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <!-- 微服务 健康监控 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-openfeign</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-online-doc</artifactId>
+ </dependency>
+
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-mvc</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-object-mapper</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-i18n</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-lang</artifactId>
+ </dependency> -->
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-admin-base-api</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- 热部署,无需重启项目 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-devtools</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+
+
+ <!-- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4.3</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <id>copy-doc-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/doc</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../doc</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>copy-api-docs-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/api-docs</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../api-docs</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java b/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java
new file mode 100644
index 0000000..058fee7
--- /dev/null
+++ b/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/Application.java
@@ -0,0 +1,47 @@
+package com.supwisdom.institute.backend.admin.sa;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc;
+import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
+import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
+
+@SpringBootApplication
+
+@EnableSimpleUserTransmit
+@EnableCustomExceptionHandler
+
+@EnableInfrasOnlineDoc
+
+@EntityScan(basePackages = {"com.supwisdom.**.domain.entity"}) // 扫描子项目下的实体
+@EnableJpaRepositories(basePackages = {"com.supwisdom.**.domain.repo"}) // 扫描子项目下的持久类
+@ComponentScan(basePackages = {"com.supwisdom"}) // FIXME: ComponentScan
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ final CorsConfiguration config = new CorsConfiguration();
+ // config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.addAllowedMethod("*");
+
+ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/v2/api-docs", config);
+
+ return new CorsFilter(source);
+ }
+
+}
diff --git a/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java b/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java
new file mode 100644
index 0000000..287cea5
--- /dev/null
+++ b/admin-sa/sa/src/main/java/com/supwisdom/institute/backend/admin/sa/configuration/Swagger2Config.java
@@ -0,0 +1,110 @@
+package com.supwisdom.institute.backend.admin.sa.configuration;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+
+ @Value("${swagger2.apis.basePackage:com.supwisdom.institute}")
+ private String basePackage;
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .securitySchemes(securitySchemes())
+ .securityContexts(securityContexts())
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage(basePackage))
+ .paths(PathSelectors.any())
+ .build()
+ ;
+ }
+
+ private ApiInfo apiInfo() {
+ Contact contact = new Contact("Backend Admin Super Admin", "https://sw-backend-sa.supwisdom.com/swagger-ui.html", ""); // name, url, email
+ return new ApiInfoBuilder()
+ .title("Backend Admin Super Admin APIs")
+ .description("管理后台 - 服务接口<br /><br />"
+ + "X-FORWARD-USER(测试用):<br /><br />"
+ + "明文:{\"attributes\":{\"accountId\":\"1\"},\"roles\":[\"ROLE_ADMIN\",\"administrator\",\"user\"],\"username\":\"swadmin\"}<br /><br />"
+ + "Base64:eyJhdHRyaWJ1dGVzIjp7ImFjY291bnRJZCI6IjEifSwicm9sZXMiOlsiUk9MRV9BRE1JTiIsImFkbWluaXN0cmF0b3IiLCJ1c2VyIl0sInVzZXJuYW1lIjoic3dhZG1pbiJ9<br /><br />"
+ + "使用 Base64字符串 进行 Authorize,然后进行接口测试<br /><br />"
+ + "若需要其他帐号,请自行拼接明文,再进行 Base64 编码<br /><br />"
+ + ""
+ )
+ .termsOfServiceUrl("http://www.supwisdom.com/")
+ .contact(contact)
+ .version("1.0")
+ .build();
+ }
+
+ private List<SecurityScheme> securitySchemes() {
+ //return newArrayList(new BasicAuth("sample"));
+ return newArrayList(
+ //new BasicAuth("Basic"),
+ //new ApiKey("JWTToken", "Authorization", "header"),
+ new ApiKey("SimpleUserTransmit", "X-FORWARD-USER", "header"));
+ }
+
+ private List<SecurityContext> securityContexts() {
+
+ List<SecurityReference> globalSecurityReference = newArrayList(
+ new SecurityReference("SimpleUserTransmit", new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}));
+
+// AuthorizationScope[] authScopes = new AuthorizationScope[1];
+// authScopes[0] = new AuthorizationScopeBuilder()
+// .scope("read")
+// .description("read access")
+// .build();
+// SecurityReference securityReference = SecurityReference.builder()
+// .reference("sample")
+// .scopes(authScopes)
+// .build();
+
+ return newArrayList(
+ SecurityContext.builder()
+ .securityReferences(newArrayList(globalSecurityReference))
+ .build());
+ }
+
+ @Bean
+ UiConfiguration uiConfig() {
+
+ return UiConfigurationBuilder.builder().build();
+
+// return new UiConfiguration(null, // url
+// "none", // docExpansion => none | list
+// "alpha", // apiSorter => alpha
+// "schema", // defaultModelRendering => schema
+// UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
+// false, // enableJsonEditor => true || false
+// true, // showRequestHeaders => true | false
+// 60000L); // requestTimeout => in milliseconds, defaults to null
+// // (uses jquery xh timeout)
+ }
+
+}
diff --git a/admin-sa/sa/src/main/resources/application-docker.yml b/admin-sa/sa/src/main/resources/application-docker.yml
new file mode 100644
index 0000000..d72a475
--- /dev/null
+++ b/admin-sa/sa/src/main/resources/application-docker.yml
@@ -0,0 +1,46 @@
+server:
+ port: ${SERVER_PORT:8443}
+ ssl:
+ enabled: ${SSL_ENABLED:true}
+ clientAuth: NEED
+ key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore}
+ key-store-password: ${SSL_KEYSTORE_PASSWORD:}
+ trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore}
+ trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:}
+ tomcat:
+ accesslog:
+ enabled: ${TOMCAT_ACCESSLOG_ENABLED:false}
+ buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true}
+ directory: ${TOMCAT_ACCESSLOG_DIR:log}
+ prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog}
+ suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log}
+ file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd}
+ rotate: ${TOMCAT_ACCESSLOG_ROTATE:true}
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: INFO
+
+
+spring:
+ jackson:
+ time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
+
+ datasource:
+ driver-class-name: ${JDBC_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver}
+ url: ${JDBC_URL:jdbc:mysql://mysql-server:3306/sw-admin}
+ username: ${JDBC_USERNAME:sw-admin}
+ password: ${JDBC_PASSWORD:}
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false}
+infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/}
+infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/}
diff --git a/admin-sa/sa/src/main/resources/application.yml b/admin-sa/sa/src/main/resources/application.yml
new file mode 100644
index 0000000..93558d2
--- /dev/null
+++ b/admin-sa/sa/src/main/resources/application.yml
@@ -0,0 +1,48 @@
+server:
+ port: 8082
+ ssl:
+ enabled: false
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: DEBUG
+# org.springframework.web: INFO
+# org.springframework.cloud.openfeign: INFO
+
+
+swagger2.apis.basePackage: com.supwisdom.institute
+
+
+spring:
+ jackson:
+ time-zone: Asia/Shanghai
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/sw-admin
+ username: root
+ password: root
+ hikari:
+ data-source-properties:
+ useSSL: false
+ characterEncoding: utf8
+ characterSetResults: utf8
+ jpa:
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
+ database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+ show-sql: false
+
+
+##
+# infras.online-doc
+#
+infras.online-doc.enabled: true
+infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/
+infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/
diff --git a/admin-sa/sa/src/main/resources/bootstrap.yml b/admin-sa/sa/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..5e82cca
--- /dev/null
+++ b/admin-sa/sa/src/main/resources/bootstrap.yml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: sw-backend-admin-sa
diff --git a/biz-sa/biz/api/.gitignore b/biz-sa/biz/api/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/biz-sa/biz/api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/biz-sa/biz/api/pom.xml b/biz-sa/biz/api/pom.xml
new file mode 100644
index 0000000..a5ff844
--- /dev/null
+++ b/biz-sa/biz/api/pom.xml
@@ -0,0 +1,110 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-api</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework BIZ API</name>
+ <description>Supwisdom Backend Framework BIZ API project</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-domain</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminBizController.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminBizController.java
new file mode 100644
index 0000000..aa324c6
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminBizController.java
@@ -0,0 +1,175 @@
+package com.supwisdom.institute.backend.biz.api.v1.admin;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.biz.api.vo.request.BizCreateRequest;
+import com.supwisdom.institute.backend.biz.api.vo.request.BizQueryRequest;
+import com.supwisdom.institute.backend.biz.api.vo.request.BizUpdateRequest;
+import com.supwisdom.institute.backend.biz.api.vo.response.BizCreateResponseData;
+import com.supwisdom.institute.backend.biz.api.vo.response.BizLoadResponseData;
+import com.supwisdom.institute.backend.biz.api.vo.response.BizQueryResponseData;
+import com.supwisdom.institute.backend.biz.api.vo.response.BizRemoveResponseData;
+import com.supwisdom.institute.backend.biz.api.vo.response.BizUpdateResponseData;
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.biz.domain.exception.BizException;
+import com.supwisdom.institute.backend.biz.domain.service.BizService;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BizAdminBiz", tags = { "BizAdminBiz" }, description = "Biz示例接口")
+@RestController
+@RequestMapping("/v1/admin/biz")
+public class AdminBizController {
+
+ @Autowired
+ private BizService bizService;
+
+ /**
+ * @param bizQueryRequest
+ * @return
+ */
+ @ApiOperation(value = "查询配置列表", notes = "查询配置列表", nickname = "systemAdminBizQuery")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "loadAll", value = "是否加载全部", required = true, dataType = "boolean", paramType = "query", defaultValue = "false"),
+ @ApiImplicitParam(name = "pageIndex", value = "分页 - 页码", required = true, dataType = "int", paramType = "query", defaultValue = "0", example = "0"),
+ @ApiImplicitParam(name = "pageSize", value = "分页 - 每页记录数", required = true, dataType = "int", paramType = "query", defaultValue = "20", example = "20"),
+ @ApiImplicitParam(name = "mapBean[deleted]", value = "查询条件 - 删除状态 (精确)", required = false, dataType = "boolean", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[categoryCode]", value = "查询条件 - 分类代码 (精确)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[categoryName]", value = "查询条件 - 分类名称 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[name]", value = "查询条件 - 名称 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[description]", value = "查询条件 - 描述 (模糊)", required = false, dataType = "string", paramType = "query"),
+ @ApiImplicitParam(name = "mapBean[bizKey]", value = "查询条件 - 配置Key (精确)", required = false, dataType = "string", paramType = "query"),
+ })
+ @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<BizQueryResponseData> query(BizQueryRequest bizQueryRequest) {
+
+ Page<Biz> page = bizService.selectPageList(
+ bizQueryRequest.isLoadAll(),
+ bizQueryRequest.getPageIndex(),
+ bizQueryRequest.getPageSize(),
+ bizQueryRequest.getMapBean(),
+ bizQueryRequest.getOrderBy());
+
+ BizQueryResponseData resp = BizQueryResponseData.of(bizQueryRequest).build(page);
+
+ return new DefaultApiResponse<BizQueryResponseData>(resp);
+ }
+
+ /**
+ * @param id
+ * @return
+ */
+ @ApiOperation(value = "根据ID获取配置项", notes = "根据ID获取配置项", nickname="systemAdminBizLoad")
+ @RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<BizLoadResponseData> load(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw BizException.newInstance("exception.get.id.must.not.empty");
+ }
+
+ Biz biz = bizService.selectById(id);
+
+ if (biz == null) {
+ throw BizException.newInstance("exception.get.domain.not.exist");
+ }
+
+ BizLoadResponseData resp = BizLoadResponseData.of(biz);
+
+ return new DefaultApiResponse<BizLoadResponseData>(resp);
+ }
+
+ /**
+ * @param bizCreateRequest
+ * @return
+ */
+ @ApiOperation(value = "创建配置项", notes = "创建配置项", nickname = "systemAdminBizCreate")
+ @RequestMapping(method = RequestMethod.POST, produces = MimeTypeUtils.APPLICATION_JSON_VALUE, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.CREATED)
+ @ResponseBody
+ public DefaultApiResponse<BizCreateResponseData> create(
+ @RequestBody BizCreateRequest bizCreateRequest) {
+
+ // FIXME: 验证数据有效性
+
+ Biz entity = EntityUtils.copy(bizCreateRequest, new Biz());
+
+ Biz ret = bizService.insert(entity);
+
+ BizCreateResponseData resp = BizCreateResponseData.of(ret);
+
+ return new DefaultApiResponse<BizCreateResponseData>(resp);
+ }
+
+ @ApiOperation(value = "更新", notes = "更新", nickname = "systemAdminBizUpdate")
+ @RequestMapping(method = RequestMethod.PUT, path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<BizUpdateResponseData> update(
+ @PathVariable("id") String id,
+ @RequestBody BizUpdateRequest bizUpdateRequest) {
+
+ if (id == null || id.length() == 0) {
+ throw BizException.newInstance("exception.update.id.must.not.empty");
+ }
+
+ Biz tmp = bizService.selectById(id);
+ if (tmp == null) {
+ throw BizException.newInstance("exception.update.domain.not.exist");
+ }
+
+ Biz entity = EntityUtils.copy(bizUpdateRequest, new Biz());
+ entity.setId(id);
+
+ entity = EntityUtils.merge(tmp, entity);
+
+ Biz ret = bizService.update(entity);
+
+ BizUpdateResponseData resp = BizUpdateResponseData.of(ret);
+
+ return new DefaultApiResponse<BizUpdateResponseData>(resp);
+ }
+
+ @ApiOperation(value = "删除", notes = "删除", nickname = "systemAdminBizRemove")
+ @RequestMapping(method = RequestMethod.DELETE, path = "/{id}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<BizRemoveResponseData> remove(
+ @PathVariable("id") String id) {
+
+ if (id == null || id.length() == 0) {
+ throw BizException.newInstance("exception.remove.id.must.not.empty");
+ }
+
+ Biz tmp = bizService.selectById(id);
+ if (tmp == null) {
+ throw BizException.newInstance("exception.remove.domain.not.exist");
+ }
+
+ bizService.deleteById(id);
+
+ BizRemoveResponseData resp = BizRemoveResponseData.of(tmp);
+
+ return new DefaultApiResponse<BizRemoveResponseData>(resp);
+ }
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java
new file mode 100644
index 0000000..a46c806
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/v1/admin/AdminHelloController.java
@@ -0,0 +1,26 @@
+package com.supwisdom.institute.backend.biz.api.v1.admin;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.common.core.transmit.user.User;
+import com.supwisdom.institute.backend.common.core.transmit.user.UserContext;
+
+@Api(value = "BizAdminHello", tags = { "BizAdminHello" }, description = "示例接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/admin/hello")
+public class AdminHelloController {
+
+ @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ public User biz() {
+ User user = UserContext.getUser(); log.debug("{}", user);
+ return user;
+ }
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizCreateRequest.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizCreateRequest.java
new file mode 100644
index 0000000..e6b6f0e
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizCreateRequest.java
@@ -0,0 +1,16 @@
+package com.supwisdom.institute.backend.biz.api.vo.request;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiCreateRequest;
+
+/**
+ * @author loie
+ */
+public class BizCreateRequest extends Biz implements IApiCreateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3512866840130579457L;
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizQueryRequest.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizQueryRequest.java
new file mode 100644
index 0000000..7f60870
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizQueryRequest.java
@@ -0,0 +1,44 @@
+package com.supwisdom.institute.backend.biz.api.vo.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiQueryRequest;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author loie
+ */
+public class BizQueryRequest implements IApiQueryRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4345168235529389375L;
+
+ @Getter
+ @Setter
+ private boolean loadAll = false;
+
+ @Getter
+ @Setter
+ private int pageIndex = 0;
+
+ @Getter
+ @Setter
+ private int pageSize = 20;
+
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, Object> mapBean;
+
+ @Getter
+ @Setter
+ @ApiModelProperty(hidden = true)
+ private Map<String, String> orderBy;
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizUpdateRequest.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizUpdateRequest.java
new file mode 100644
index 0000000..74973ce
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/request/BizUpdateRequest.java
@@ -0,0 +1,23 @@
+package com.supwisdom.institute.backend.biz.api.vo.request;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.vo.request.IApiUpdateRequest;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class BizUpdateRequest extends Biz implements IApiUpdateRequest {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6002556449210326472L;
+
+ @Getter
+ @Setter
+ private String id;
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizCreateResponseData.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizCreateResponseData.java
new file mode 100644
index 0000000..9a91fce
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizCreateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.biz.api.vo.response;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiCreateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class BizCreateResponseData extends Biz implements IApiCreateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7081539211184618366L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private BizCreateResponseData() {
+
+ }
+
+ public static BizCreateResponseData of(Biz entity) {
+ BizCreateResponseData data = new BizCreateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizLoadResponseData.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizLoadResponseData.java
new file mode 100644
index 0000000..84c2864
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizLoadResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.biz.api.vo.response;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiLoadResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class BizLoadResponseData extends Biz implements IApiLoadResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -921871332091924834L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private BizLoadResponseData() {
+
+ }
+
+ public static BizLoadResponseData of(Biz entity) {
+ BizLoadResponseData data = new BizLoadResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizQueryResponseData.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizQueryResponseData.java
new file mode 100644
index 0000000..3c19ad1
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizQueryResponseData.java
@@ -0,0 +1,80 @@
+package com.supwisdom.institute.backend.biz.api.vo.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.biz.api.vo.request.BizQueryRequest;
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiQueryResponseData;
+
+/**
+ * @author loie
+ */
+public class BizQueryResponseData implements IApiQueryResponseData<Biz> {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5706417972093485886L;
+
+ private BizQueryResponseData(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+ this.loadAll = loadAll;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ this.mapBean = mapBean;
+ this.orderBy = orderBy;
+ }
+
+ public static BizQueryResponseData of(BizQueryRequest queryRequest) {
+ BizQueryResponseData data = new BizQueryResponseData(
+ queryRequest.isLoadAll(),
+ queryRequest.getPageIndex(),
+ queryRequest.getPageSize(),
+ queryRequest.getMapBean(),
+ queryRequest.getOrderBy()
+ );
+
+ return data;
+ }
+
+ public BizQueryResponseData build(Page<Biz> page) {
+ this.currentItemCount = page.getNumberOfElements();
+ this.pageCount = page.getTotalPages();
+ this.recordCount = page.getTotalElements();
+ this.items = page.getContent();
+
+ return this;
+ }
+
+ @Getter
+ private boolean loadAll;
+ @Getter
+ private int pageIndex;
+ @Getter
+ private int pageSize;
+ @Getter
+ private Map<String, Object> mapBean;
+ @Getter
+ private Map<String, String> orderBy;
+
+ @Getter
+ @Setter
+ private int pageCount;
+ @Getter
+ @Setter
+ private long recordCount;
+
+ @Getter
+ @Setter
+ private int currentItemCount;
+
+ @Getter
+ @Setter
+ private List<Biz> items;
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizRemoveResponseData.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizRemoveResponseData.java
new file mode 100644
index 0000000..0d3f019
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizRemoveResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.biz.api.vo.response;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiRemoveResponseData;
+
+/**
+ * @author loie
+ */
+public class BizRemoveResponseData implements IApiRemoveResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7920962172100289008L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private BizRemoveResponseData() {
+
+ }
+
+ public static BizRemoveResponseData of(Biz entity) {
+ BizRemoveResponseData data = new BizRemoveResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizUpdateResponseData.java b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizUpdateResponseData.java
new file mode 100644
index 0000000..19bef62
--- /dev/null
+++ b/biz-sa/biz/api/src/main/java/com/supwisdom/institute/backend/biz/api/vo/response/BizUpdateResponseData.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.biz.api.vo.response;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiUpdateResponseData;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author loie
+ */
+public class BizUpdateResponseData extends Biz implements IApiUpdateResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4502820318022107903L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ private BizUpdateResponseData() {
+
+ }
+
+ public static BizUpdateResponseData of(Biz entity) {
+ BizUpdateResponseData data = new BizUpdateResponseData();
+
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/biz-sa/biz/domain/.gitignore b/biz-sa/biz/domain/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/biz-sa/biz/domain/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/biz-sa/biz/domain/pom.xml b/biz-sa/biz/domain/pom.xml
new file mode 100644
index 0000000..b511ecc
--- /dev/null
+++ b/biz-sa/biz/domain/pom.xml
@@ -0,0 +1,99 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-domain</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework BIZ Domain</name>
+ <description>Supwisdom Backend Framework BIZ Domain project</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-data-jpa</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/entity/Biz.java b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/entity/Biz.java
new file mode 100644
index 0000000..553cc05
--- /dev/null
+++ b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/entity/Biz.java
@@ -0,0 +1,43 @@
+package com.supwisdom.institute.backend.biz.domain.entity;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Entity
+@Table(name = "TB_BIZ")
+public class Biz extends ABaseEntity {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5503233707196628811L;
+
+ @Getter
+ @Setter
+ @Column(name = "NAME")
+ private String name;
+
+ @Getter
+ @Setter
+ @Column(name = "BOOL")
+ private Boolean bool;
+
+ @Getter
+ @Setter
+ @Column(name = "DATE")
+ private Date date;
+
+ @Getter
+ @Setter
+ @Column(name = "NUM")
+ private Integer num;
+
+}
diff --git a/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/exception/BizException.java b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/exception/BizException.java
new file mode 100644
index 0000000..2ae5778
--- /dev/null
+++ b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/exception/BizException.java
@@ -0,0 +1,12 @@
+package com.supwisdom.institute.backend.biz.domain.exception;
+
+import com.supwisdom.institute.backend.common.framework.exception.BaseException;
+
+public class BizException extends BaseException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8112079911386045865L;
+
+}
diff --git a/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/repo/BizRepository.java b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/repo/BizRepository.java
new file mode 100644
index 0000000..cfeae8f
--- /dev/null
+++ b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/repo/BizRepository.java
@@ -0,0 +1,114 @@
+package com.supwisdom.institute.backend.biz.domain.repo;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Order;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+import com.supwisdom.institute.backend.common.util.DateUtil;
+import com.supwisdom.institute.backend.common.util.MapBeanUtils;
+
+@Repository
+public interface BizRepository extends BaseJpaRepository<Biz> {
+
+ default Specification<Biz> convertSpecification(Map<String, Object> mapBean) {
+
+ Specification<Biz> spec = new Specification<Biz>() {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1820403213133310124L;
+
+ @Override
+ public Predicate toPredicate(Root<Biz> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
+ List<Predicate> predicates = new ArrayList<>();
+
+ if (mapBean != null) {
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "name"))) {
+ predicates.add(criteriaBuilder.like(root.get("name"), MapBeanUtils.getString(mapBean, "name")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getBoolean(mapBean, "bool"))) {
+ predicates.add(criteriaBuilder.equal(root.get("bool"), MapBeanUtils.getBoolean(mapBean, "bool")));
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "dateBegin"))) {
+ String grantTimeBegin = MapBeanUtils.getString(mapBean, "dateBegin");
+ Date d = DateUtil.parseDate(grantTimeBegin+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
+
+ if (d != null) {
+ predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("date"), d));
+ }
+ }
+
+ if (!StringUtils.isEmpty(MapBeanUtils.getString(mapBean, "dateEnd"))) {
+ String grantTimeEnd = MapBeanUtils.getString(mapBean, "dateEnd");
+ Date d = DateUtil.parseDate(grantTimeEnd+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
+
+ if (d != null) {
+ predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("date"), d));
+ }
+ }
+ }
+
+ return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
+ }
+
+ };
+
+ return spec;
+ }
+
+ @Override
+ public default Page<Biz> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+
+ Specification<Biz> spec = this.convertSpecification(mapBean);
+
+ if (loadAll) {
+ pageIndex = 0;
+ pageSize = Integer.MAX_VALUE;
+ }
+
+ Sort sort = new Sort(Sort.Direction.DESC, "date"); // Sort.unsorted
+
+ if (orderBy != null) {
+ List<Order> orders = new ArrayList<>();
+
+ orderBy.forEach((k, v) -> {
+ if ("asc".equalsIgnoreCase(v)) {
+ Order order = Order.asc(k);
+ orders.add(order);
+ } else if ("desc".equalsIgnoreCase(v)) {
+ Order order = Order.desc(k);
+ orders.add(order);
+ } else {
+ Order order = Order.by(k);
+ orders.add(order);
+ }
+ });
+
+ sort = Sort.by(orders);
+ }
+
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sort);
+
+ return this.findAll(spec, pageRequest);
+ }
+
+}
diff --git a/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/service/BizService.java b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/service/BizService.java
new file mode 100644
index 0000000..43f1dd7
--- /dev/null
+++ b/biz-sa/biz/domain/src/main/java/com/supwisdom/institute/backend/biz/domain/service/BizService.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.biz.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.supwisdom.institute.backend.biz.domain.entity.Biz;
+import com.supwisdom.institute.backend.biz.domain.repo.BizRepository;
+import com.supwisdom.institute.backend.common.framework.service.ABaseService;
+
+@Service
+public class BizService extends ABaseService<Biz, BizRepository> {
+
+ @Autowired
+ private BizRepository bizRepository;
+
+ @Override
+ public BizRepository getRepo() {
+ return bizRepository;
+ }
+
+}
diff --git a/biz-sa/biz/pom.xml b/biz-sa/biz/pom.xml
new file mode 100644
index 0000000..ee22d80
--- /dev/null
+++ b/biz-sa/biz/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-aggregator</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework BIZ Aggregator</name>
+ <description>Supwisdom Backend Framework BIZ Aggregator project</description>
+
+ <modules>
+ <module>domain</module>
+ <module>api</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/biz-sa/pom.xml b/biz-sa/pom.xml
new file mode 100644
index 0000000..77f3962
--- /dev/null
+++ b/biz-sa/pom.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework Biz SuperAdmin API Parent</name>
+ <description>Supwisdom Backend Framework Biz SuperAdmin API Parent project</description>
+
+ <modules>
+ <module>biz</module>
+ <module>sa</module>
+ </modules>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ </properties>
+
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-bom</artifactId>
+ <version>${infras.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-domain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>8.0.12</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <version>${dockerfile-maven-plugin.version}</version>
+ <configuration>
+ <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
+ <tag>${project.version}</tag>
+ <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+ <buildArgs>
+ <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
+ <VERSION>${project.version}</VERSION>
+ <NAME>${project.artifactId}</NAME>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/biz-sa/sa/.gitignore b/biz-sa/sa/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/biz-sa/sa/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/biz-sa/sa/Dockerfile b/biz-sa/sa/Dockerfile
new file mode 100644
index 0000000..f7bf86e
--- /dev/null
+++ b/biz-sa/sa/Dockerfile
@@ -0,0 +1,18 @@
+FROM harbor.supwisdom.com/institute/openjdk:8-jre-alpine
+
+ENV ENABLE_JMX_SSL=false
+ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker
+ENV SPRING_PROFILES_ACTIVE=docker
+
+ARG NAME
+ARG VERSION
+ARG JAR_FILE
+
+LABEL name=$NAME \
+ version=$VERSION
+
+EXPOSE 8080
+
+EXPOSE 8443
+
+COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar
diff --git a/biz-sa/sa/pom.xml b/biz-sa/sa/pom.xml
new file mode 100644
index 0000000..0c4fbd1
--- /dev/null
+++ b/biz-sa/sa/pom.xml
@@ -0,0 +1,203 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-sa</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Biz SuperAdmin API</name>
+ <description>Supwisdom Backend Framework Biz SuperAdmin API project</description>
+
+ <properties>
+ <start-class>com.supwisdom.institute.backend.biz.sa.Application</start-class>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <!-- 微服务 健康监控 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-openfeign</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-online-doc</artifactId>
+ </dependency>
+
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-mvc</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-object-mapper</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-i18n</artifactId>
+ </dependency> -->
+
+ <!-- <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-lang</artifactId>
+ </dependency> -->
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-biz-api</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- 热部署,无需重启项目 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-devtools</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+
+
+ <!-- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4.3</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <id>copy-doc-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/doc</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../doc</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ <execution>
+ <id>copy-api-docs-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <encoding>utf-8</encoding>
+ <outputDirectory>${basedir}/target/api-docs</outputDirectory>
+ <overwrite>true</overwrite>
+ <resources>
+ <resource>
+ <directory>${basedir}/../api-docs</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin> -->
+
+
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/Application.java b/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/Application.java
new file mode 100644
index 0000000..e0f0af4
--- /dev/null
+++ b/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/Application.java
@@ -0,0 +1,47 @@
+package com.supwisdom.institute.backend.biz.sa;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import com.supwisdom.infras.online.doc.configuration.EnableInfrasOnlineDoc;
+import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
+import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
+
+@SpringBootApplication
+
+@EnableSimpleUserTransmit
+@EnableCustomExceptionHandler
+
+@EnableInfrasOnlineDoc
+
+@EntityScan(basePackages = {"com.supwisdom.**.domain.entity"}) // 扫描子项目下的实体
+@EnableJpaRepositories(basePackages = {"com.supwisdom.**.domain.repo"}) // 扫描子项目下的持久类
+@ComponentScan(basePackages = {"com.supwisdom"}) // FIXME: ComponentScan
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ final CorsConfiguration config = new CorsConfiguration();
+ // config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.addAllowedMethod("*");
+
+ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/v2/api-docs", config);
+
+ return new CorsFilter(source);
+ }
+
+}
diff --git a/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/configuration/Swagger2Config.java b/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/configuration/Swagger2Config.java
new file mode 100644
index 0000000..f2ffe33
--- /dev/null
+++ b/biz-sa/sa/src/main/java/com/supwisdom/institute/backend/biz/sa/configuration/Swagger2Config.java
@@ -0,0 +1,110 @@
+package com.supwisdom.institute.backend.biz.sa.configuration;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+
+ @Value("${swagger2.apis.basePackage:com.supwisdom.institute}")
+ private String basePackage;
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .securitySchemes(securitySchemes())
+ .securityContexts(securityContexts())
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage(basePackage))
+ .paths(PathSelectors.any())
+ .build()
+ ;
+ }
+
+ private ApiInfo apiInfo() {
+ Contact contact = new Contact("Backend Biz Super Admin", "https://sw-backend-biz-sa.supwisdom.com/swagger-ui.html", ""); // name, url, email
+ return new ApiInfoBuilder()
+ .title("Backend Biz Super Admin APIs")
+ .description("管理后台 - 服务接口<br /><br />"
+ + "X-FORWARD-USER(测试用):<br /><br />"
+ + "明文:{\"attributes\":{\"accountId\":\"1\"},\"roles\":[\"ROLE_ADMIN\",\"administrator\",\"user\"],\"username\":\"swadmin\"}<br /><br />"
+ + "Base64:eyJhdHRyaWJ1dGVzIjp7ImFjY291bnRJZCI6IjEifSwicm9sZXMiOlsiUk9MRV9BRE1JTiIsImFkbWluaXN0cmF0b3IiLCJ1c2VyIl0sInVzZXJuYW1lIjoic3dhZG1pbiJ9<br /><br />"
+ + "使用 Base64字符串 进行 Authorize,然后进行接口测试<br /><br />"
+ + "若需要其他帐号,请自行拼接明文,再进行 Base64 编码<br /><br />"
+ + ""
+ )
+ .termsOfServiceUrl("http://www.supwisdom.com/")
+ .contact(contact)
+ .version("1.0")
+ .build();
+ }
+
+ private List<SecurityScheme> securitySchemes() {
+ //return newArrayList(new BasicAuth("sample"));
+ return newArrayList(
+ //new BasicAuth("Basic"),
+ //new ApiKey("JWTToken", "Authorization", "header"),
+ new ApiKey("SimpleUserTransmit", "X-FORWARD-USER", "header"));
+ }
+
+ private List<SecurityContext> securityContexts() {
+
+ List<SecurityReference> globalSecurityReference = newArrayList(
+ new SecurityReference("SimpleUserTransmit", new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}));
+
+// AuthorizationScope[] authScopes = new AuthorizationScope[1];
+// authScopes[0] = new AuthorizationScopeBuilder()
+// .scope("read")
+// .description("read access")
+// .build();
+// SecurityReference securityReference = SecurityReference.builder()
+// .reference("sample")
+// .scopes(authScopes)
+// .build();
+
+ return newArrayList(
+ SecurityContext.builder()
+ .securityReferences(newArrayList(globalSecurityReference))
+ .build());
+ }
+
+ @Bean
+ UiConfiguration uiConfig() {
+
+ return UiConfigurationBuilder.builder().build();
+
+// return new UiConfiguration(null, // url
+// "none", // docExpansion => none | list
+// "alpha", // apiSorter => alpha
+// "schema", // defaultModelRendering => schema
+// UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
+// false, // enableJsonEditor => true || false
+// true, // showRequestHeaders => true | false
+// 60000L); // requestTimeout => in milliseconds, defaults to null
+// // (uses jquery xh timeout)
+ }
+
+}
diff --git a/biz-sa/sa/src/main/resources/application-docker.yml b/biz-sa/sa/src/main/resources/application-docker.yml
new file mode 100644
index 0000000..cbf3924
--- /dev/null
+++ b/biz-sa/sa/src/main/resources/application-docker.yml
@@ -0,0 +1,46 @@
+server:
+ port: ${SERVER_PORT:8443}
+ ssl:
+ enabled: ${SSL_ENABLED:true}
+ clientAuth: NEED
+ key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore}
+ key-store-password: ${SSL_KEYSTORE_PASSWORD:}
+ trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore}
+ trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:}
+ tomcat:
+ accesslog:
+ enabled: ${TOMCAT_ACCESSLOG_ENABLED:false}
+ buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true}
+ directory: ${TOMCAT_ACCESSLOG_DIR:log}
+ prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog}
+ suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log}
+ file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd}
+ rotate: ${TOMCAT_ACCESSLOG_ROTATE:true}
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: INFO
+
+
+spring:
+ jackson:
+ time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
+
+ datasource:
+ driver-class-name: ${JDBC_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver}
+ url: ${JDBC_URL:jdbc:mysql://mysql-server:3306/sw-biz}
+ username: ${JDBC_USERNAME:sw-biz}
+ password: ${JDBC_PASSWORD:}
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false}
+infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/}
+infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/}
diff --git a/biz-sa/sa/src/main/resources/application.yml b/biz-sa/sa/src/main/resources/application.yml
new file mode 100644
index 0000000..531f8bd
--- /dev/null
+++ b/biz-sa/sa/src/main/resources/application.yml
@@ -0,0 +1,48 @@
+server:
+ port: 8083
+ ssl:
+ enabled: false
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: DEBUG
+# org.springframework.web: INFO
+# org.springframework.cloud.openfeign: INFO
+
+
+swagger2.apis.basePackage: com.supwisdom.institute
+
+
+spring:
+ jackson:
+ time-zone: Asia/Shanghai
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/sw-biz
+ username: root
+ password: root
+ hikari:
+ data-source-properties:
+ useSSL: false
+ characterEncoding: utf8
+ characterSetResults: utf8
+ jpa:
+ hibernate:
+ ddl-auto: none
+ naming:
+ physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
+ database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
+ show-sql: false
+
+
+##
+# infras.online-doc
+#
+infras.online-doc.enabled: true
+infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/
+infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/
diff --git a/biz-sa/sa/src/main/resources/bootstrap.yml b/biz-sa/sa/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..8c1026a
--- /dev/null
+++ b/biz-sa/sa/src/main/resources/bootstrap.yml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: sw-backend-biz-sa
diff --git a/common/core/.gitignore b/common/core/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/common/core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/common/core/pom.xml b/common/core/pom.xml
index 4b69173..ef4a706 100644
--- a/common/core/pom.xml
+++ b/common/core/pom.xml
@@ -5,9 +5,8 @@
<parent>
<groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-parent</artifactId>
+ <artifactId>sw-backend-common-parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
- <relativePath>../../</relativePath>
</parent>
<groupId>com.supwisdom.institute</groupId>
diff --git a/common/framework/.gitignore b/common/framework/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/common/framework/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/common/framework/pom.xml b/common/framework/pom.xml
index 092d616..68e9c10 100644
--- a/common/framework/pom.xml
+++ b/common/framework/pom.xml
@@ -5,9 +5,8 @@
<parent>
<groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-parent</artifactId>
+ <artifactId>sw-backend-common-parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
- <relativePath>../../</relativePath>
</parent>
<groupId>com.supwisdom.institute</groupId>
diff --git a/common/pom.xml b/common/pom.xml
index a324f66..cec612e 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
-
+
<parent>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-parent</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
</parent>
-
+
<groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-common</artifactId>
+ <artifactId>sw-backend-common-parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>pom</packaging>
- <name>Supwisdom Backend Framework Common</name>
- <description>Supwisdom Backend Framework Common project</description>
+ <name>Supwisdom Backend Framework Common Parent</name>
+ <description>Supwisdom Backend Framework Common Parent project</description>
<modules>
<module>core</module>
@@ -23,15 +23,122 @@
<module>framework</module>
</modules>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-deploy-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ </properties>
+
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-bom</artifactId>
+ <version>${infras.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <!-- 使用Apache HttpClient替换Feign原生httpclient -->
+ <dependency>
+ <groupId>com.netflix.feign</groupId>
+ <artifactId>feign-httpclient</artifactId>
+ <version>8.17.0</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ <version>1.2.61</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>28.0-jre</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
</project>
diff --git a/common/utils/.gitignore b/common/utils/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/common/utils/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/common/utils/pom.xml b/common/utils/pom.xml
index 99fa621..59367e7 100644
--- a/common/utils/pom.xml
+++ b/common/utils/pom.xml
@@ -5,9 +5,8 @@
<parent>
<groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-parent</artifactId>
+ <artifactId>sw-backend-common-parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
- <relativePath>../../</relativePath>
</parent>
<groupId>com.supwisdom.institute</groupId>
diff --git a/gateway/pom.xml b/gateway/pom.xml
index d9600f6..0772813 100644
--- a/gateway/pom.xml
+++ b/gateway/pom.xml
@@ -4,9 +4,9 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-parent</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
</parent>
<groupId>com.supwisdom.institute</groupId>
@@ -18,9 +18,100 @@
<description>Supwisdom Backend Framework Gateway project</description>
<properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ <mybatis.spring.boot.version>1.3.1</mybatis.spring.boot.version>
+
<start-class>com.supwisdom.institute.backend.gateway.Application</start-class>
</properties>
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.infras</groupId>
+ <artifactId>infras-bom</artifactId>
+ <version>${infras.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ <version>1.2.56</version>
+ </dependency>
+
+
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
@@ -100,6 +191,15 @@
<groupId>com.supwisdom.institute</groupId>
<artifactId>sw-backend-common-framework</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-redis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>redis.clients</groupId>
+ <artifactId>jedis</artifactId>
+ </dependency>
<dependency>
<groupId>commons-codec</groupId>
@@ -112,14 +212,14 @@
</dependency>
- <dependency>
+ <!-- <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
- </dependency>
+ </dependency> -->
<!-- 热部署,无需重启项目 -->
@@ -140,6 +240,26 @@
<build>
<finalName>${project.artifactId}</finalName>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <version>${dockerfile-maven-plugin.version}</version>
+ <configuration>
+ <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
+ <tag>${project.version}</tag>
+ <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+ <buildArgs>
+ <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
+ <VERSION>${project.version}</VERSION>
+ <NAME>${project.artifactId}</NAME>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -162,52 +282,6 @@
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
-
- <!-- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <configuration>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- <executions>
- <execution>
- <id>copy-doc-resources</id>
- <phase>package</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <encoding>utf-8</encoding>
- <outputDirectory>${basedir}/target/doc</outputDirectory>
- <overwrite>true</overwrite>
- <resources>
- <resource>
- <directory>${basedir}/../../doc</directory>
- </resource>
- </resources>
- </configuration>
- </execution>
- <execution>
- <id>copy-certs-jwt-resources</id>
- <phase>package</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <encoding>utf-8</encoding>
- <outputDirectory>${basedir}/target/certs/jwt</outputDirectory>
- <overwrite>true</overwrite>
- <resources>
- <resource>
- <directory>${basedir}/../../certs/jwt</directory>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin> -->
-
-
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/configuration/AuthnRestTemplateConfig.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/configuration/AuthnRestTemplateConfig.java
index 789f930..9041e1a 100644
--- a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/configuration/AuthnRestTemplateConfig.java
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/configuration/AuthnRestTemplateConfig.java
@@ -92,8 +92,8 @@
return factory;
}
- @Bean(name = "authnAccountRestTemplate")
- public RestTemplate authnAccountRestTemplate(ClientHttpRequestFactory requestFactory) {
+ @Bean(name = "authnRestTemplate")
+ public RestTemplate authnRestTemplate(ClientHttpRequestFactory requestFactory) {
return new RestTemplate(requestFactory);
}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteRestTemplate.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteClient.java
similarity index 98%
rename from gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteRestTemplate.java
rename to gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteClient.java
index b0fe53d..78d8c3f 100644
--- a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteRestTemplate.java
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/remote/web/client/AuthnRemoteClient.java
@@ -12,7 +12,7 @@
@Slf4j
@Component
-public class AuthnRemoteRestTemplate {
+public class AuthnRemoteClient {
@Autowired
private RestTemplate authnRestTemplate;
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/service/AuthnService.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/service/AuthnService.java
index 13434ec..160c5d8 100644
--- a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/service/AuthnService.java
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/authn/service/AuthnService.java
@@ -12,18 +12,18 @@
import com.supwisdom.institute.backend.gateway.authn.model.ResourceRoleSet;
import com.supwisdom.institute.backend.gateway.authn.model.Role;
import com.supwisdom.institute.backend.gateway.authn.model.Route;
-import com.supwisdom.institute.backend.gateway.authn.remote.web.client.AuthnRemoteRestTemplate;
+import com.supwisdom.institute.backend.gateway.authn.remote.web.client.AuthnRemoteClient;
@Slf4j
@Service
public class AuthnService {
@Autowired
- private AuthnRemoteRestTemplate authnRemote;
+ private AuthnRemoteClient authnRemoteClient;
public Account account(String username) {
- JSONObject jsonObject = authnRemote.account(username);
+ JSONObject jsonObject = authnRemoteClient.account(username);
if (jsonObject == null) {
return null;
}
@@ -40,7 +40,7 @@
public List<Role> accountRoles(String username) {
- JSONObject jsonObject = authnRemote.accountRoles(username);
+ JSONObject jsonObject = authnRemoteClient.accountRoles(username);
if (jsonObject == null) {
return null;
}
@@ -57,7 +57,7 @@
public List<ResourceRoleSet> resourceRoleSets() {
- JSONObject jsonObject = authnRemote.resourceRoleSets();
+ JSONObject jsonObject = authnRemoteClient.resourceRoleSets();
if (jsonObject == null) {
return null;
}
@@ -74,7 +74,7 @@
public List<Route> routes() {
- JSONObject jsonObject = authnRemote.routes();
+ JSONObject jsonObject = authnRemoteClient.routes();
if (jsonObject == null) {
return null;
}
diff --git a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/InMemeryUserDetailsService.java b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/InMemeryUserDetailsService.java
index 4e761a5..5dea61c 100644
--- a/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/InMemeryUserDetailsService.java
+++ b/gateway/src/main/java/com/supwisdom/institute/backend/gateway/security/core/userdetails/InMemeryUserDetailsService.java
@@ -59,13 +59,6 @@
MyUser myUser = new MyUser(username, passwordEncoder.encode(username), authorities, attributes);
log.debug("myUser is {}", myUser);
- List<String> roles = new ArrayList<>();
- roles.add("ROLE_ADMIN");
- roles.add("administrator");
- roles.add("user");
- User user = new User(username, roles, attributes);
- UserContext.setUser(user);
-
return Mono.just(myUser);
}
diff --git a/pom.xml b/pom.xml
index 446c3f8..7b0234b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,12 +3,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>com.supwisdom.buildcommons</groupId>
- <artifactId>spring-cloud-parent</artifactId>
- <version>Finchley.RELEASE-1.1</version>
- </parent>
-
<groupId>com.supwisdom.institute</groupId>
<artifactId>sw-backend-parent</artifactId>
<version>0.0.2-SNAPSHOT</version>
@@ -17,196 +11,22 @@
<name>Supwisdom Backend Framework Parent</name>
<description>Supwisdom Backend Framework Parent project</description>
- <modules>
- <module>common</module>
-
- <module>base</module>
- <module>biz</module>
-
- <module>sa</module>
- <module>bff</module>
-
- <module>gateway</module>
-
- </modules>
-
<properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <java.version>1.8</java.version>
-
- <argLine>-Dfile.encoding=UTF-8</argLine>
-
- <downloadSources>true</downloadSources>
- <downloadJavadocs>true</downloadJavadocs>
-
- <maven.compiler.source>${java.version}</maven.compiler.source>
- <maven.compiler.target>${java.version}</maven.compiler.target>
-
- <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
- <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
- <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
-
- <infras.version>0.1.1-SNAPSHOT</infras.version>
-
- <io.springfox.version>2.9.2</io.springfox.version>
-
- <mybatis.spring.boot.version>1.3.1</mybatis.spring.boot.version>
-
+ <maven.deploy.skip>true</maven.deploy.skip>
</properties>
- <distributionManagement>
- <repository>
- <id>supwisdom-releases</id>
- <name>internal release</name>
- <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
- </repository>
- <snapshotRepository>
- <id>supwisdom-snapshots</id>
- <name>internal snapshots</name>
- <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
- </snapshotRepository>
- </distributionManagement>
+ <modules>
+ <module>common</module>
- <repositories>
- <repository>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <id>supwisdom</id>
- <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
- </repository>
- <repository>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- <id>central</id>
- <url>http://repo.maven.apache.org/maven2</url>
- </repository>
- </repositories>
+ <module>thirdparty-agent</module>
- <dependencyManagement>
- <dependencies>
+ <module>admin-sa</module>
+ <module>biz-sa</module>
- <dependency>
- <groupId>com.supwisdom.infras</groupId>
- <artifactId>infras-bom</artifactId>
- <version>${infras.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
+ <module>admin-bff</module>
+ <module>gateway</module>
+ </modules>
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-common-core</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-common-utils</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-common-framework</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-base-domain</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-base-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-biz-domain</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.supwisdom.institute</groupId>
- <artifactId>sw-backend-biz-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- 使用Apache HttpClient替换Feign原生httpclient -->
- <dependency>
- <groupId>com.netflix.feign</groupId>
- <artifactId>feign-httpclient</artifactId>
- <version>8.17.0</version>
- </dependency>
-
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.12</version>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.56</version>
- </dependency>
-
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>28.0-jre</version>
- </dependency>
-
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger2</artifactId>
- <version>${io.springfox.version}</version>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger-ui</artifactId>
- <version>${io.springfox.version}</version>
- </dependency>
-
- </dependencies>
- </dependencyManagement>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- <version>${dockerfile-maven-plugin.version}</version>
- <configuration>
- <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
- <tag>${project.version}</tag>
- <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
- <buildArgs>
- <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
- <VERSION>${project.version}</VERSION>
- <NAME>${project.artifactId}</NAME>
- </buildArgs>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
-
- <plugins>
- <plugin>
- <groupId>com.spotify</groupId>
- <artifactId>dockerfile-maven-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
-
- </build>
</project>
diff --git a/thirdparty-agent/agent/.gitignore b/thirdparty-agent/agent/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/thirdparty-agent/agent/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/thirdparty-agent/agent/Dockerfile b/thirdparty-agent/agent/Dockerfile
new file mode 100644
index 0000000..f7bf86e
--- /dev/null
+++ b/thirdparty-agent/agent/Dockerfile
@@ -0,0 +1,18 @@
+FROM harbor.supwisdom.com/institute/openjdk:8-jre-alpine
+
+ENV ENABLE_JMX_SSL=false
+ENV JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker
+ENV SPRING_PROFILES_ACTIVE=docker
+
+ARG NAME
+ARG VERSION
+ARG JAR_FILE
+
+LABEL name=$NAME \
+ version=$VERSION
+
+EXPOSE 8080
+
+EXPOSE 8443
+
+COPY --chown=java-app:java-app target/${JAR_FILE} /home/java-app/lib/app.jar
diff --git a/thirdparty-agent/agent/pom.xml b/thirdparty-agent/agent/pom.xml
new file mode 100644
index 0000000..eecf40b
--- /dev/null
+++ b/thirdparty-agent/agent/pom.xml
@@ -0,0 +1,117 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-agent-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-agent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Third Party Agent</name>
+ <description>Supwisdom Backend Framework Third Party Agent project</description>
+
+ <properties>
+ <start-class>com.supwisdom.institute.backend.thirdparty.agent.Application</start-class>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <!-- 微服务 健康监控 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-poa</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ </dependency>
+
+
+ <!-- 热部署,无需重启项目 -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-devtools</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>${project.artifactId}</finalName>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/Application.java b/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/Application.java
new file mode 100644
index 0000000..089732a
--- /dev/null
+++ b/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/Application.java
@@ -0,0 +1,40 @@
+package com.supwisdom.institute.backend.thirdparty.agent;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+import com.supwisdom.institute.backend.common.core.transmit.annotation.EnableSimpleUserTransmit;
+import com.supwisdom.institute.backend.common.framework.exception.EnableCustomExceptionHandler;
+
+@SpringBootApplication
+
+@EnableScheduling
+
+@EnableSimpleUserTransmit
+@EnableCustomExceptionHandler
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ final CorsConfiguration config = new CorsConfiguration();
+ // config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.addAllowedMethod("*");
+
+ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/v2/api-docs", config);
+
+ return new CorsFilter(source);
+ }
+
+}
diff --git a/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/configuration/Swagger2Config.java b/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/configuration/Swagger2Config.java
new file mode 100644
index 0000000..a0a511c
--- /dev/null
+++ b/thirdparty-agent/agent/src/main/java/com/supwisdom/institute/backend/thirdparty/agent/configuration/Swagger2Config.java
@@ -0,0 +1,110 @@
+package com.supwisdom.institute.backend.thirdparty.agent.configuration;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+
+ @Value("${swagger2.apis.basePackage:com.supwisdom.institute}")
+ private String basePackage;
+
+ @Bean
+ public Docket createRestApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .securitySchemes(securitySchemes())
+ .securityContexts(securityContexts())
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage(basePackage))
+ .paths(PathSelectors.any())
+ .build()
+ ;
+ }
+
+ private ApiInfo apiInfo() {
+ Contact contact = new Contact("Backend Third Party Agent", "https://sw-backend-agent.supwisdom.com/swagger-ui.html", ""); // name, url, email
+ return new ApiInfoBuilder()
+ .title("Backend Third Party Agent APIs")
+ .description("管理后台 - 代理接口<br /><br />"
+ + "X-FORWARD-USER(测试用):<br /><br />"
+ + "明文:{\"attributes\":{\"accountId\":\"1\"},\"roles\":[\"ROLE_ADMIN\",\"administrator\",\"user\"],\"username\":\"swadmin\"}<br /><br />"
+ + "Base64:eyJhdHRyaWJ1dGVzIjp7ImFjY291bnRJZCI6IjEifSwicm9sZXMiOlsiUk9MRV9BRE1JTiIsImFkbWluaXN0cmF0b3IiLCJ1c2VyIl0sInVzZXJuYW1lIjoic3dhZG1pbiJ9<br /><br />"
+ + "使用 Base64字符串 进行 Authorize,然后进行接口测试<br /><br />"
+ + "若需要其他帐号,请自行拼接明文,再进行 Base64 编码<br /><br />"
+ + ""
+ )
+ .termsOfServiceUrl("http://www.supwisdom.com/")
+ .contact(contact)
+ .version("1.0")
+ .build();
+ }
+
+ private List<SecurityScheme> securitySchemes() {
+ //return newArrayList(new BasicAuth("sample"));
+ return newArrayList(
+ //new BasicAuth("Basic"),
+ //new ApiKey("JWTToken", "Authorization", "header"),
+ new ApiKey("SimpleUserTransmit", "X-FORWARD-USER", "header"));
+ }
+
+ private List<SecurityContext> securityContexts() {
+
+ List<SecurityReference> globalSecurityReference = newArrayList(
+ new SecurityReference("SimpleUserTransmit", new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}));
+
+// AuthorizationScope[] authScopes = new AuthorizationScope[1];
+// authScopes[0] = new AuthorizationScopeBuilder()
+// .scope("read")
+// .description("read access")
+// .build();
+// SecurityReference securityReference = SecurityReference.builder()
+// .reference("sample")
+// .scopes(authScopes)
+// .build();
+
+ return newArrayList(
+ SecurityContext.builder()
+ .securityReferences(newArrayList(globalSecurityReference))
+ .build());
+ }
+
+ @Bean
+ UiConfiguration uiConfig() {
+
+ return UiConfigurationBuilder.builder().build();
+
+// return new UiConfiguration(null, // url
+// "none", // docExpansion => none | list
+// "alpha", // apiSorter => alpha
+// "schema", // defaultModelRendering => schema
+// UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
+// false, // enableJsonEditor => true || false
+// true, // showRequestHeaders => true | false
+// 60000L); // requestTimeout => in milliseconds, defaults to null
+// // (uses jquery xh timeout)
+ }
+
+}
diff --git a/thirdparty-agent/agent/src/main/resources/application-docker.yml b/thirdparty-agent/agent/src/main/resources/application-docker.yml
new file mode 100644
index 0000000..c48d4b2
--- /dev/null
+++ b/thirdparty-agent/agent/src/main/resources/application-docker.yml
@@ -0,0 +1,63 @@
+server:
+ port: ${SERVER_PORT:8443}
+ ssl:
+ enabled: ${SSL_ENABLED:true}
+ clientAuth: NEED
+ key-store: ${SSL_KEYSTORE_FILE:file:/certs/server/server.keystore}
+ key-store-password: ${SSL_KEYSTORE_PASSWORD:}
+ trust-store: ${SSL_TRUSTSTORE_FILE:file:/certs/server/server.truststore}
+ trust-store-password: ${SSL_TRUSTSTORE_PASSWORD:}
+ tomcat:
+ accesslog:
+ enabled: ${TOMCAT_ACCESSLOG_ENABLED:false}
+ buffered: ${TOMCAT_ACCESSLOG_BUFFERED:true}
+ directory: ${TOMCAT_ACCESSLOG_DIR:log}
+ prefix: ${TOMCAT_ACCESSLOG_PREFIX:sa-api-accesslog}
+ suffix: ${TOMCAT_ACCESSLOG_SUFFIX:.log}
+ file-date-format: ${TOMCAT_ACCESSLOG_FILE_DATE_FORMAT:.yyyy-MM-dd}
+ rotate: ${TOMCAT_ACCESSLOG_ROTATE:true}
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: INFO
+
+
+spring:
+ jackson:
+ time-zone: ${JACKSON_TIME_ZONE:Asia/Shanghai}
+
+##
+# spring.redis
+#
+ redis:
+ host: ${SPRING_REDIS_HOST:redis-server}
+ port: ${SPRING_REDIS_PORT:6379}
+ password: ${SPRING_REDIS_PASSWORD:}
+
+
+##
+# online-doc
+#
+infras.online-doc.enabled: ${INFRAS_ONLINE_DOC_ENABLED:false}
+infras.online-doc.md-docs.staitc.path: ${INFRAS_ONLINE_DOC_MD_DOCS_STATIC_PATH:/doc/}
+infras.online-doc.api-docs.staitc.path: ${INFRAS_ONLINE_DOC_API_DOCS_STATIC_PATH:/api-docs/}
+
+
+## 平台OpenAPI
+poa.server.url: ${POA_SERVER_URL:https://poa.supwisdom.com}
+
+poa.client.id: ${POA_CLIENT_ID:id}
+poa.client.secret: ${POA_CLIENT_SECRET:secret}
+poa.scopes: ${POA_SCOPES:read,write,trust}
+
+## 开放接口地址
+user-data-service.server.url: ${USER_DATA_SERVICE_SERVER_URL:${poa.server.url}/apis/user/v1}
+user-authorization-service.server.url: ${USER_AUTHORIZATION_SERVICE_SERVER_URL:${poa.server.url}/apis/authz/v1}
+
+## 用户授权服务
+user-authorization-service.applicationId: ${USER_AUTHORIZATION_SERVICE_APPLICATION_ID:}
diff --git a/thirdparty-agent/agent/src/main/resources/application.yml b/thirdparty-agent/agent/src/main/resources/application.yml
new file mode 100644
index 0000000..001a0bd
--- /dev/null
+++ b/thirdparty-agent/agent/src/main/resources/application.yml
@@ -0,0 +1,63 @@
+server:
+ port: 8090
+ ssl:
+ enabled: false
+
+
+##
+# logging
+#
+logging:
+ level:
+ root: INFO
+ com.supwisdom: DEBUG
+# org.springframework.web: INFO
+# org.springframework.cloud.openfeign: INFO
+
+
+swagger2.apis.basePackage: com.supwisdom.institute
+
+
+spring:
+ jackson:
+ time-zone: Asia/Shanghai
+
+##
+# spring.redis
+#
+ redis:
+ database: 0
+ host: localhost
+ port: 6379
+ password:
+ timeout: 10000
+
+ jedis:
+ pool:
+ maxIdle: 8
+ minIdle: 0
+ maxActive: 8
+ maxWait: -1
+
+
+##
+# infras.online-doc
+#
+infras.online-doc.enabled: true
+infras.online-doc.md-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/doc/
+infras.online-doc.api-docs.staitc.path: /Users/loie/c/work/git/institute/sw-backend/api-docs/
+
+
+## 平台OpenAPI
+poa.server.url: https://poa.supwisdom.com
+
+poa.client.id: nV8US9uAdFQ0ovuYpFOloXtFkME=
+poa.client.secret: dDgZAzuNnOjfsbm8iDohyVCXBU1GwImeMsmkJzjyGh8=
+poa.scopes: user:v1:readUser,user:v1:readOrganization,user:v1:readGroup,user:v1:readLabel,authz:v1:readRole
+
+## 开放接口地址
+user-data-service.server.url: ${poa.server.url}/apis/user/v1
+user-authorization-service.server.url: ${poa.server.url}/apis/authz/v1
+
+## 用户授权服务
+user-authorization-service.applicationId: 2
diff --git a/thirdparty-agent/agent/src/main/resources/bootstrap.yml b/thirdparty-agent/agent/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..92df83b
--- /dev/null
+++ b/thirdparty-agent/agent/src/main/resources/bootstrap.yml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: sw-backend-thirdparty-agent
diff --git a/thirdparty-agent/pom.xml b/thirdparty-agent/pom.xml
new file mode 100644
index 0000000..ba5b8bb
--- /dev/null
+++ b/thirdparty-agent/pom.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.buildcommons</groupId>
+ <artifactId>spring-cloud-parent</artifactId>
+ <version>Finchley.RELEASE-1.1</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-agent-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Supwisdom Backend Framework Third Party Agent Parent</name>
+ <description>Supwisdom Backend Framework Third Party Agent Parent project</description>
+
+ <modules>
+ <module>thirdparty-poa</module>
+ <module>agent</module>
+ </modules>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java.version>1.8</java.version>
+
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+
+ <downloadSources>true</downloadSources>
+ <downloadJavadocs>true</downloadJavadocs>
+
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+
+ <dockerfile-maven-plugin.version>1.4.8</dockerfile-maven-plugin.version>
+ <dockerfile.image.server>harbor.supwisdom.com</dockerfile.image.server>
+ <dockerfile.image.prefix>sw-admin-framework</dockerfile.image.prefix>
+
+ <infras.version>0.1.1-SNAPSHOT</infras.version>
+
+ <io.springfox.version>2.9.2</io.springfox.version>
+
+ </properties>
+
+ <distributionManagement>
+ <repository>
+ <id>supwisdom-releases</id>
+ <name>internal release</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>supwisdom-snapshots</id>
+ <name>internal snapshots</name>
+ <url>https://app.supwisdom.com/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <id>supwisdom</id>
+ <url>https://app.supwisdom.com/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <id>central</id>
+ <url>http://repo.maven.apache.org/maven2</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-poa</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ <version>1.2.61</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${io.springfox.version}</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <version>${dockerfile-maven-plugin.version}</version>
+ <configuration>
+ <repository>${dockerfile.image.server}/${dockerfile.image.prefix}/${project.artifactId}</repository>
+ <tag>${project.version}</tag>
+ <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
+ <buildArgs>
+ <JAR_FILE>${project.build.finalName}.${project.packaging}</JAR_FILE>
+ <VERSION>${project.version}</VERSION>
+ <NAME>${project.artifactId}</NAME>
+ </buildArgs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+</project>
diff --git a/thirdparty-agent/thirdparty-poa/.gitignore b/thirdparty-agent/thirdparty-poa/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/thirdparty-agent/thirdparty-poa/pom.xml b/thirdparty-agent/thirdparty-poa/pom.xml
new file mode 100644
index 0000000..c252ac9
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/pom.xml
@@ -0,0 +1,132 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-agent-parent</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-thirdparty-poa</artifactId>
+ <version>0.0.2-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Supwisdom Backend Framework Third Party POA</name>
+ <description>Supwisdom Backend Framework Third Party POA project</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-utils</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.supwisdom.institute</groupId>
+ <artifactId>sw-backend-common-framework</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-redis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>redis.clients</groupId>
+ <artifactId>jedis</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/HttpUtils.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/HttpUtils.java
new file mode 100644
index 0000000..d6e18d6
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/HttpUtils.java
@@ -0,0 +1,384 @@
+package com.supwisdom.institute.backend.thirdparty.poa;
+
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * This is {@link HttpUtils}.
+ *
+ * @author Misagh Moayyed
+ * @since 5.2.0
+ */
+@Slf4j
+@UtilityClass
+public class HttpUtils {
+
+ private static final int MAX_CONNECTIONS = 200;
+ private static final int MAX_CONNECTIONS_PER_ROUTE = 20;
+
+ private static final HttpClient HTTP_CLIENT = HttpClientBuilder.create().setMaxConnTotal(MAX_CONNECTIONS)
+ .setMaxConnPerRoute(MAX_CONNECTIONS_PER_ROUTE).build();
+
+ /**
+ * Execute http response.
+ *
+ * @param url the url
+ * @param method the method
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method,
+ final String basicAuthUsername,
+ final String basicAuthPassword) {
+ return execute(url, method, basicAuthUsername, basicAuthPassword, new HashMap<>(), new HashMap<>());
+ }
+
+ /**
+ * Execute http response.
+ *
+ * @param url the url
+ * @param method the method
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param headers the headers
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method,
+ final String basicAuthUsername, final String basicAuthPassword,
+ final Map<String, Object> headers) {
+ return execute(url, method, basicAuthUsername, basicAuthPassword, new HashMap<>(), headers);
+ }
+
+ /**
+ * Execute http response.
+ *
+ * @param url the url
+ * @param method the method
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method) {
+ return execute(url, method, null, null, new HashMap<>(), new HashMap<>());
+ }
+
+ /**
+ * Execute http response.
+ *
+ * @param url the url
+ * @param method the method
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method, final Map<String, Object> parameters, final Map<String, Object> headers) {
+ return execute(url, method, null, null, parameters, headers);
+ }
+
+ /**
+ * Execute http response.
+ *
+ * @param url the url
+ * @param method the method
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param parameters the parameters
+ * @param headers the headers
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final Map<String, Object> parameters,
+ final Map<String, Object> headers) {
+ return execute(url, method, basicAuthUsername, basicAuthPassword, parameters, headers, null);
+ }
+
+ /**
+ * Execute http request and produce a response.
+ *
+ * @param url the url
+ * @param method the method
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param parameters the parameters
+ * @param headers the headers
+ * @param entity the entity
+ * @return the http response
+ */
+ public static HttpResponse execute(final String url, final String method,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final Map<String, Object> parameters,
+ final Map<String, Object> headers,
+ final String entity) {
+ try {
+ final URI uri = buildHttpUri(url, parameters);
+ final HttpUriRequest request;
+ switch (method.toLowerCase()) {
+ case "post":
+ case "put":
+ request = new HttpPost(uri);
+ if (StringUtils.isNotBlank(entity)) {
+ final StringEntity stringEntity = new StringEntity(entity);
+ ((HttpPost) request).setEntity(stringEntity);
+ }
+ break;
+ case "delete":
+ request = new HttpDelete(uri);
+ break;
+ case "get":
+ default:
+ request = new HttpGet(uri);
+ break;
+ }
+ headers.forEach((k, v) -> request.addHeader(k, v.toString()));
+ prepareHttpRequest(request, basicAuthUsername, basicAuthPassword);
+ return HTTP_CLIENT.execute(request);
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Close the response.
+ *
+ * @param response the response to close
+ */
+ public static void close(final HttpResponse response) {
+ if (response != null) {
+ final CloseableHttpResponse closeableHttpResponse = (CloseableHttpResponse) response;
+ try {
+ closeableHttpResponse.close();
+ } catch (final IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Execute get http response.
+ *
+ * @param url the url
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param parameters the parameters
+ * @return the http response
+ */
+ public static HttpResponse executeGet(final String url,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final Map<String, Object> parameters) {
+ try {
+ return executeGet(url, basicAuthUsername, basicAuthPassword, parameters, new HashMap<>());
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Execute get http response.
+ *
+ * @param url the url
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param parameters the parameters
+ * @param headers the headers
+ * @return the http response
+ */
+ public static HttpResponse executeGet(final String url,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final Map<String, Object> parameters,
+ final Map<String, Object> headers) {
+ try {
+ return execute(url, "GET", basicAuthUsername, basicAuthPassword, parameters, headers);
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Execute get http response.
+ *
+ * @param url the url
+ * @param parameters the parameters
+ * @return the http response
+ */
+ public static HttpResponse executeGet(final String url,
+ final Map<String, Object> parameters) {
+ try {
+ return executeGet(url, null, null, parameters);
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Execute get http response.
+ *
+ * @param url the url
+ * @return the http response
+ */
+ public static HttpResponse executeGet(final String url) {
+ try {
+ return executeGet(url, null, null, new LinkedHashMap<>());
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Execute get http response.
+ *
+ * @param url the url
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @return the http response
+ */
+ public static HttpResponse executeGet(final String url,
+ final String basicAuthUsername,
+ final String basicAuthPassword) {
+ try {
+ return executeGet(url, basicAuthUsername, basicAuthPassword, new HashMap<>());
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Execute post http response.
+ *
+ * @param url the url
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param jsonEntity the json entity
+ * @return the http response
+ */
+ public static HttpResponse executePost(final String url,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final String jsonEntity) {
+ return executePost(url, basicAuthUsername, basicAuthPassword, jsonEntity, new HashMap<>());
+ }
+
+ /**
+ * Execute post http response.
+ *
+ * @param url the url
+ * @param parameters the parameters
+ * @return the http response
+ */
+ public static HttpResponse executePost(final String url,
+ final Map<String, Object> parameters) {
+ return executePost(url, null, null, null, parameters);
+ }
+
+ /**
+ * Execute post http response.
+ *
+ * @param url the url
+ * @param jsonEntity the json entity
+ * @param parameters the parameters
+ * @return the http response
+ */
+ public static HttpResponse executePost(final String url,
+ final String jsonEntity,
+ final Map<String, Object> parameters) {
+ return executePost(url, null, null, jsonEntity, parameters);
+ }
+
+ /**
+ * Execute post http response.
+ *
+ * @param url the url
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ * @param jsonEntity the json entity
+ * @param parameters the parameters
+ * @return the http response
+ */
+ public static HttpResponse executePost(final String url,
+ final String basicAuthUsername,
+ final String basicAuthPassword,
+ final String jsonEntity,
+ final Map<String, Object> parameters) {
+ try {
+ return execute(url, "POST", basicAuthUsername, basicAuthPassword, parameters, new HashMap<>(), jsonEntity);
+ } catch (final Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Prepare http request. Tries to set the authorization header
+ * in cases where the URL endpoint does not actually produce the header
+ * on its own.
+ *
+ * @param request the request
+ * @param basicAuthUsername the basic auth username
+ * @param basicAuthPassword the basic auth password
+ */
+ private static void prepareHttpRequest(final HttpUriRequest request, final String basicAuthUsername,
+ final String basicAuthPassword) {
+ if (StringUtils.isNotBlank(basicAuthUsername) && StringUtils.isNotBlank(basicAuthPassword)) {
+ final String auth = encodeBase64(basicAuthUsername + ":" + basicAuthPassword);
+ request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + auth);
+ }
+ }
+
+ private static URI buildHttpUri(final String url, final Map<String, Object> parameters) throws URISyntaxException {
+ final URIBuilder uriBuilder = new URIBuilder(url);
+ parameters.forEach((k, v) -> uriBuilder.addParameter(k, v.toString()));
+ return uriBuilder.build();
+ }
+
+ /**
+ * Create headers org . springframework . http . http headers.
+ *
+ * @param basicAuthUser the basic auth user
+ * @param basicAuthPassword the basic auth password
+ * @return the org . springframework . http . http headers
+ */
+// public static org.springframework.http.HttpHeaders createBasicAuthHeaders(final String basicAuthUser, final String basicAuthPassword) {
+// final org.springframework.http.HttpHeaders acceptHeaders = new org.springframework.http.HttpHeaders();
+// acceptHeaders.setAccept(CollectionUtils.wrap(MediaType.APPLICATION_JSON));
+// if (StringUtils.isNotBlank(basicAuthUser) && StringUtils.isNotBlank(basicAuthPassword)) {
+// final String authorization = basicAuthUser + ':' + basicAuthPassword;
+// final String basic = encodeBase64(authorization.getBytes(Charset.forName("US-ASCII")));
+// acceptHeaders.set("Authorization", "Basic " + basic);
+// }
+// return acceptHeaders;
+// }
+
+
+ private static String encodeBase64(final String data) {
+ return Base64.encodeBase64String(data.getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/PoaUtil.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/PoaUtil.java
new file mode 100644
index 0000000..41f44d6
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/PoaUtil.java
@@ -0,0 +1,321 @@
+package com.supwisdom.institute.backend.thirdparty.poa;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.common.core.distributedlock.DistributedLockHandler;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class PoaUtil {
+
+ public static void main(String[] args) {
+
+ PoaUtil.poaServerUrl = "https://poa.supwisdom.com";
+ PoaUtil.clientId = "nV8US9uAdFQ0ovuYpFOloXtFkME=";
+ PoaUtil.clientSecret = "dDgZAzuNnOjfsbm8iDohyVCXBU1GwImeMsmkJzjyGh8=";
+ PoaUtil.scope = "user:v1:readUser,user:v1:readOrganization,user:v1:readGroup,user:v1:readLabel,authz:v1:readRole";
+
+ //JSONObject accessTokenObject = PoaUtil.getAccessToken("https://poa.supwisdom.com", "tikgr8E6vfcGDXVSG5Vs-00XJoQ=", "wZugRIydkt9lQqJyi7lco-x8wZyyreb41WC_ioj8g-I=", "personalSecurityCenterSa:v1:admin");
+ JSONObject accessTokenObject = PoaUtil.getAccessTokenObject();
+ System.out.println(accessTokenObject.toJSONString());
+
+ String accessToken = accessTokenObject.getString("access_token");
+ PoaUtil.accessToken = accessToken;
+
+ JSONObject jsonObject = PoaUtil.loadUserInfoByAccountName("https://poa.supwisdom.com/apis/user/v1", "smartadmin");
+ System.out.println(jsonObject.toJSONString());
+ }
+
+
+
+ @Autowired(required = false)
+ private DistributedLockHandler distributedLockHandler;
+
+ //每隔 3000 秒执行一次
+ @Scheduled(fixedRate = 3000000)
+ public void refresh() {
+ if (distributedLockHandler == null) {
+ PoaUtil.clearAccessToken();
+
+ try {
+ JSONObject accessTokenObject = PoaUtil.getAccessTokenObject();
+ if (PoaUtil.saveAccessToken(accessTokenObject)) {
+ return;
+ }
+
+ try {
+ Thread.sleep(500L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ log.debug("AccessTokenRefresh.refresh retry");
+
+ refresh();
+ } finally {
+
+ }
+ }
+
+ final String LOCK_KEY = "poa:ACCESS_TOKEN_REFRESH:LOCK";
+
+ boolean lock = distributedLockHandler.lock(LOCK_KEY, 5000L); log.debug("AccessTokenRefresh.refresh lock: {}", lock);
+ if(!lock) {
+ return;
+ }
+
+ PoaUtil.clearAccessToken();
+
+ try {
+ JSONObject accessTokenObject = PoaUtil.getAccessTokenObject();
+
+ if (PoaUtil.saveAccessToken(accessTokenObject)) {
+ return;
+ }
+
+ // 如果 token 获取失败,则 先释放锁,随后再次尝试获取
+ boolean releaseLock = distributedLockHandler.releaseLock(LOCK_KEY); log.debug("AccessTokenRefresh.refresh releaseLock: {}", releaseLock);
+
+ try {
+ Thread.sleep(500L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ log.debug("AccessTokenRefresh.refresh retry");
+
+ refresh();
+
+ } finally {
+ boolean releaseLock = distributedLockHandler.releaseLock(LOCK_KEY); log.debug("AccessTokenRefresh.refresh finally releaseLock: {}", releaseLock);
+ }
+
+ }
+
+
+ private static String accessToken = null;
+
+
+ private static String poaServerUrl;
+
+ private static String clientId;
+
+ private static String clientSecret;
+
+ private static String scope;
+
+ private static StringRedisTemplate stringRedisTemplate;
+
+ @Value("${poa.server.url}")
+ public void setPoaServerUrl(String poaServerUrl) {
+ PoaUtil.poaServerUrl = poaServerUrl;
+ }
+ @Value("${poa.client.id}")
+ public void setClientId(String clientId) {
+ PoaUtil.clientId = clientId;
+ }
+ @Value("${poa.client.secret}")
+ public void setClientSecret(String clientSecret) {
+ PoaUtil.clientSecret = clientSecret;
+ }
+ @Value("${poa.scopes}")
+ public void setScopes(String[] scopes) {
+ PoaUtil.scope = StringUtils.join(scopes, ","); log.debug("{}", PoaUtil.scope);
+ }
+
+ @Autowired(required = false)
+ public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
+ PoaUtil.stringRedisTemplate = stringRedisTemplate;
+ }
+
+ public static boolean saveAccessToken(JSONObject accessTokenObject) {
+
+ if (accessTokenObject != null) {
+ String accessToken = accessTokenObject.getString("access_token");
+ Long expiresIn = accessTokenObject.getLong("expires_in");
+
+ PoaUtil.accessToken = accessToken;
+
+ if (stringRedisTemplate != null) {
+ final String ACCESS_TOKEN_KEY = "poa:"+clientId+":ACCESS_TOKEN";
+ RedisUtils.redisTemplate(stringRedisTemplate).setValue(ACCESS_TOKEN_KEY, expiresIn, accessToken);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void clearAccessToken() {
+ PoaUtil.accessToken = null;
+
+ if (stringRedisTemplate != null) {
+ final String ACCESS_TOKEN_KEY = "poa:"+clientId+":ACCESS_TOKEN";
+ RedisUtils.redisTemplate(stringRedisTemplate).expireValue(ACCESS_TOKEN_KEY);
+ }
+ }
+
+ public static String getAccessToken() {
+ if (PoaUtil.accessToken != null) {
+ return PoaUtil.accessToken;
+ }
+
+ if (stringRedisTemplate != null) {
+ final String ACCESS_TOKEN_KEY = "poa:"+clientId+":ACCESS_TOKEN";
+ PoaUtil.accessToken = RedisUtils.redisTemplate(stringRedisTemplate).getValue(ACCESS_TOKEN_KEY);
+ }
+
+ return PoaUtil.accessToken;
+ }
+
+ public static JSONObject getAccessTokenObject() {
+
+ String tokenUrl = poaServerUrl + "/oauth2/token";
+
+ String grantType = "client_credentials";
+
+ Map<String, Object> headers = new HashMap<String, Object>();
+ headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+ String formData = String.format("grant_type=%s&client_id=%s&client_secret=%s&scope=%s", grantType, clientId, clientSecret, scope);
+ //log.debug("Post formData [{}]", formData);
+
+ int retry = 0;
+ while(retry < 3) {
+ try{
+ HttpResponse httpResponse = HttpUtils.execute(tokenUrl, "POST", null, null, new HashMap<String, Object>(), headers, formData);
+ /**
+ * {
+ * "access_token": "0loVdVN4AqPIbStZmkvtkw==",
+ * "token_type": "bearer",
+ * "expires_in": 3600
+ * }
+ */
+
+ /**
+ * {
+ * "error": "invalid_client",
+ * "error_description": ""
+ * }
+ */
+
+ JSONObject resultJsonObject = parseJSONObject(httpResponse);
+ if (resultJsonObject != null) {
+ if (!resultJsonObject.containsKey("error")) {
+ return resultJsonObject;
+ }
+
+ log.error("Get access_token by [{}] from poa error: {}", clientId, resultJsonObject.getString("error"));
+ break;
+ }
+
+ retry ++;
+ Thread.sleep(retry * retry * 500L);
+ log.debug("Retry {}", retry);
+ } catch (Exception e) {
+ // 未知异常时,重试
+ log.error("Get access_token by [{}] from poa excption: ", clientId, e);
+ }
+
+ }
+
+ return null;
+ }
+
+
+
+ private static JSONObject parseJSONObject(HttpResponse httpResponse) {
+ try {
+ if (httpResponse != null) {
+ StringBuilder entityStringBuilder = new StringBuilder();
+
+ BufferedReader b = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "UTF-8"), 8*1024);
+
+ String line=null;
+ while ((line=b.readLine())!=null) {
+ entityStringBuilder.append(line);
+ }
+ log.debug("Fetch response [{}]", entityStringBuilder.toString());
+
+ JSONObject resultJsonObject = JSONObject.parseObject(entityStringBuilder.toString());
+
+ return resultJsonObject;
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (UnsupportedOperationException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+
+ public static JSONObject loadUserInfoByAccountName(String baseUrl, String accountName) {
+
+ String url = baseUrl + "/users/accountName/" + accountName;
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+
+ Map<String, Object> headers = new HashMap<String, Object>();
+ headers.put(HttpHeaders.AUTHORIZATION, "Bearer "+PoaUtil.getAccessToken());
+ log.debug("{}", headers);
+
+ HttpResponse httpResponse = HttpUtils.execute(url, "GET", parameters, headers);
+
+ JSONObject resultJsonObject = parseJSONObject(httpResponse);
+ if (resultJsonObject != null) {
+ if (!resultJsonObject.containsKey("error")) {
+ // XXX: 根据API响应数据,须修改为 只返回实际的 data 数据
+ return resultJsonObject;
+ }
+ }
+
+ return null;
+ }
+
+
+ public static JSONObject loadAccountApplicationRoles(String baseUrl, String applicationId, String username) {
+
+ String url = baseUrl + "/application/"+applicationId+"/account/"+username+"/roles";
+ log.debug(url);
+
+ Map<String, Object> parameters = new HashMap<String, Object>();
+ log.debug("{}", parameters);
+
+ Map<String, Object> headers = new HashMap<String, Object>();
+ headers.put(HttpHeaders.AUTHORIZATION, "Bearer "+PoaUtil.getAccessToken());
+ log.debug("{}", headers);
+
+ HttpResponse httpResponse = HttpUtils.execute(url, "GET", parameters, headers);
+
+ JSONObject resultJsonObject = parseJSONObject(httpResponse);
+ if (resultJsonObject != null) {
+ if (!resultJsonObject.containsKey("error")) {
+ // XXX: 根据API响应数据,须修改为 只返回实际的 data 数据
+ return resultJsonObject;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/RedisUtils.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/RedisUtils.java
new file mode 100644
index 0000000..26b7dee
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/RedisUtils.java
@@ -0,0 +1,205 @@
+package com.supwisdom.institute.backend.thirdparty.poa;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.springframework.data.redis.core.BoundHashOperations;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.BoundValueOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+
+public class RedisUtils<T> {
+
+ private RedisUtils() {
+ this.redisTemplate = null;
+ }
+
+ private RedisUtils(RedisTemplate<String, T> redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }
+
+ private final RedisTemplate<String, T> redisTemplate;
+
+ public static <T> RedisUtils<T> redisTemplate(RedisTemplate<String, T> redisTemplate) {
+ RedisUtils<T> redisUtils = new RedisUtils<T>(redisTemplate);
+
+ return redisUtils;
+ }
+
+
+
+ /**
+ * Set the value of a key
+ * @param redisKey
+ * @param expireTime, time in seconds
+ * @param t
+ */
+ public void setValue(String redisKey, Long expireTime, T t) {
+ BoundValueOperations<String, T> boundValue = this.redisTemplate.boundValueOps(redisKey);
+ boundValue.set(t);
+
+ if (expireTime != null) {
+ boundValue.expire(expireTime, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * Get the value of a key
+ * @param redisKey
+ * @return
+ */
+ public T getValue(String redisKey) {
+ BoundValueOperations<String, T> boundValue = this.redisTemplate.boundValueOps(redisKey);
+ if (boundValue == null) {
+ return null;
+ }
+
+ return boundValue.get();
+ }
+
+ /**
+ * Expire the value of a key
+ * @param redisKey
+ */
+ public void expireValue(String redisKey) {
+ BoundValueOperations<String, T> boundValue = this.redisTemplate.boundValueOps(redisKey);
+ if (boundValue == null) {
+ return;
+ }
+
+ boundValue.expire(-1L, TimeUnit.SECONDS);
+ }
+
+ public List<T> getAllValue(String patternRedisKey) {
+ return this.redisTemplate.keys(patternRedisKey)
+ .stream()
+ .map(redisKey -> this.redisTemplate.boundValueOps(redisKey).get())
+ .filter(Objects::nonNull).collect(Collectors.toList());
+ }
+
+
+ /**
+ * SADD key member
+ * Add a member ({@link T}) to a set
+ * @param redisKey
+ * @param expireTime
+ * @param member
+ */
+ public void addToSet(String redisKey, Long expireTime, T member) {
+ BoundSetOperations<String, T> boundSet = this.redisTemplate.boundSetOps(redisKey);
+ boundSet.add(member);
+
+ if (expireTime != null) {
+ boundSet.expire(expireTime, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * SREM key member
+ * Remove a member ({@link T}) from a set
+ * @param redisKey
+ * @param member
+ */
+ public void remFromSet(String redisKey, T member) {
+ BoundSetOperations<String, T> boundSet = this.redisTemplate.boundSetOps(redisKey);
+ if (boundSet == null) {
+ return;
+ }
+
+ boundSet.remove(member);
+
+ if (boundSet.size() == 0) {
+ boundSet.expire(-1L, TimeUnit.SECONDS);
+ }
+ }
+
+ public void expireSet(String redisKey) {
+ BoundSetOperations<String, T> boundSet = this.redisTemplate.boundSetOps(redisKey);
+ if (boundSet == null) {
+ return;
+ }
+
+ boundSet.expire(-1L, TimeUnit.SECONDS);
+ }
+
+
+ /**
+ * HSET key field value
+ * Set the string value of a hash field
+ * @param redisKey
+ * @param expireTime
+ * @param field
+ * @param value
+ */
+ public void setToHash(String redisKey, Long expireTime, String field, T value) {
+ BoundHashOperations<String, String, T> boundHash = this.redisTemplate.boundHashOps(redisKey);
+ boundHash.put(field, value);
+
+ if (expireTime != null) {
+ boundHash.expire(expireTime, TimeUnit.SECONDS);
+ }
+ }
+
+ /**
+ * HGETALL key
+ * Get all the fields and values in a hash
+ * @param redisKey
+ * @return
+ */
+ public Map<String, T> getAllFromHash(String redisKey) {
+ BoundHashOperations<String, String, T> boundHash = this.redisTemplate.boundHashOps(redisKey);
+ if (boundHash == null) {
+ return null;
+ }
+
+ return boundHash.entries();
+ }
+
+ /**
+ * HGET key field
+ * summary: Get the value of a hash field
+ * @param redisKey
+ * @param field
+ * @return
+ */
+ public T getFromHash(String redisKey, String field) {
+ BoundHashOperations<String, String, T> boundHash = this.redisTemplate.boundHashOps(redisKey);
+ if (boundHash == null) {
+ return null;
+ }
+
+ return boundHash.get(field);
+ }
+
+ /**
+ * HDEL key field
+ * summary: Delete a hash field
+ * @param redisKey
+ * @param field
+ */
+ public void delFromHash(String redisKey, String field) {
+ BoundHashOperations<String, String, T> boundHash = this.redisTemplate.boundHashOps(redisKey);
+ if (boundHash == null) {
+ return;
+ }
+
+ boundHash.delete(field);
+
+ if (boundHash.size() == 0) {
+ boundHash.expire(-1L, TimeUnit.SECONDS);
+ }
+ }
+
+ public void expireHash(String redisKey) {
+ BoundHashOperations<String, String, T> boundHash = this.redisTemplate.boundHashOps(redisKey);
+ if (boundHash == null) {
+ return;
+ }
+
+ boundHash.expire(-1L, TimeUnit.SECONDS);
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/AuthzController.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/AuthzController.java
new file mode 100644
index 0000000..b98f10a
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/AuthzController.java
@@ -0,0 +1,53 @@
+package com.supwisdom.institute.backend.thirdparty.poa.api.v1.controller;
+
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+import com.supwisdom.institute.backend.thirdparty.poa.api.v1.vo.response.RoleListResponseData;
+import com.supwisdom.institute.backend.thirdparty.poa.model.Role;
+import com.supwisdom.institute.backend.thirdparty.poa.service.AuthzService;
+
+@Api(value = "AgentPoaAuthz", tags = { "AgentPoaAuthz" }, description = "POA授权服务代理接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/poa/authz")
+public class AuthzController {
+
+ @Autowired
+ private AuthzService authzService;
+
+ @GetMapping(path = "roles/account/{username}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<RoleListResponseData> loadAccountApplicationRoles(
+ @PathVariable("username") String username) {
+
+ if (username == null || username.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ List<Role> roles = authzService.loadAccountRoles(username);
+
+ if (roles == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ RoleListResponseData data = RoleListResponseData.of(roles);
+
+ return new DefaultApiResponse<RoleListResponseData>(data);
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/UserController.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/UserController.java
new file mode 100644
index 0000000..b82b77b
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/controller/UserController.java
@@ -0,0 +1,51 @@
+package com.supwisdom.institute.backend.thirdparty.poa.api.v1.controller;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+import com.supwisdom.institute.backend.thirdparty.poa.api.v1.vo.response.UserInfoResponseData;
+import com.supwisdom.institute.backend.thirdparty.poa.model.UserInfoModel;
+import com.supwisdom.institute.backend.thirdparty.poa.service.UserService;
+
+@Api(value = "AgentPoaUser", tags = { "AgentPoaUser" }, description = "POA用户服务代理接口")
+@Slf4j
+@RestController
+@RequestMapping("/v1/poa/user")
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ @GetMapping(path = "/users/accountName/{accountName}", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+ @ResponseStatus(value = HttpStatus.OK)
+ @ResponseBody
+ public DefaultApiResponse<UserInfoResponseData> loadUserInfoByAccountName(
+ @PathVariable("accountName") String accountName) {
+
+ if (accountName == null || accountName.length() == 0) {
+ throw new RuntimeException("exception.get.username.must.not.empty");
+ }
+
+ UserInfoModel userInfoModel = userService.loadUserInfoByAccountName(accountName);
+
+ if (userInfoModel == null) {
+ throw new RuntimeException("exception.get.account.not.exist");
+ }
+
+ UserInfoResponseData data = UserInfoResponseData.of(userInfoModel);
+
+ return new DefaultApiResponse<UserInfoResponseData>(data);
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/RoleListResponseData.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/RoleListResponseData.java
new file mode 100644
index 0000000..eb5002b
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/RoleListResponseData.java
@@ -0,0 +1,30 @@
+package com.supwisdom.institute.backend.thirdparty.poa.api.v1.vo.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+import com.supwisdom.institute.backend.thirdparty.poa.model.Role;
+
+public class RoleListResponseData implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4227215295471065273L;
+
+ @Getter
+ @Setter
+ public List<Role> roles;
+
+ public static RoleListResponseData of(List<Role> roles) {
+ RoleListResponseData data = new RoleListResponseData();
+
+ data.setRoles(roles);
+
+ return data;
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/UserInfoResponseData.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/UserInfoResponseData.java
new file mode 100644
index 0000000..73ad872
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/api/v1/vo/response/UserInfoResponseData.java
@@ -0,0 +1,19 @@
+package com.supwisdom.institute.backend.thirdparty.poa.api.v1.vo.response;
+
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+import com.supwisdom.institute.backend.thirdparty.poa.model.UserInfoModel;
+
+public class UserInfoResponseData extends UserInfoModel implements IApiResponseData {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6563198124742058531L;
+
+ public static UserInfoResponseData of(UserInfoModel entity) {
+ UserInfoResponseData data = new UserInfoResponseData();
+ return EntityUtils.copy(entity, data);
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/autoconfigure/PoaAutoConfiguration.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/autoconfigure/PoaAutoConfiguration.java
new file mode 100644
index 0000000..a480ee3
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/autoconfigure/PoaAutoConfiguration.java
@@ -0,0 +1,10 @@
+package com.supwisdom.institute.backend.thirdparty.poa.autoconfigure;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages = {"com.supwisdom.institute.backend.thirdparty.poa"})
+public class PoaAutoConfiguration {
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/Role.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/Role.java
new file mode 100644
index 0000000..cdcc151
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/Role.java
@@ -0,0 +1,41 @@
+package com.supwisdom.institute.backend.thirdparty.poa.model;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@ToString
+public class Role implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -273297347381636597L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private String code;
+
+ @Getter
+ @Setter
+ private String name;
+
+ @Getter
+ @Setter
+ private String description;
+
+ @Getter
+ @Setter
+ private Boolean enabled;
+
+ @Getter
+ @Setter
+ private String externalId;
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/UserInfoModel.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/UserInfoModel.java
new file mode 100644
index 0000000..9b16312
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/model/UserInfoModel.java
@@ -0,0 +1,124 @@
+package com.supwisdom.institute.backend.thirdparty.poa.model;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@ToString
+public class UserInfoModel implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -822608981040243176L;
+
+ @Getter
+ @Setter
+ private String id;
+
+ @Getter
+ @Setter
+ private String accountName;
+
+ @Getter
+ @Setter
+ private String identityTypeId;
+ @Getter
+ @Setter
+ private String identityTypeCode;
+ @Getter
+ @Setter
+ private String identityTypeName;
+
+ @Getter
+ @Setter
+ private String organizationId;
+ @Getter
+ @Setter
+ private String organizationCode;
+ @Getter
+ @Setter
+ private String organizationName;
+
+ @Getter
+ @Setter
+ private String uid;
+
+ @Getter
+ @Setter
+ private String name;
+
+ @Getter
+ @Setter
+ private String fullNameSpelling;
+ @Getter
+ @Setter
+ private String nameSpelling;
+
+ @Getter
+ @Setter
+ private String certificateTypeId;
+ @Getter
+ @Setter
+ private String certificateTypeCode;
+ @Getter
+ @Setter
+ private String certificateTypeName;
+ @Getter
+ @Setter
+ private String certificateNumber;
+
+ @Getter
+ @Setter
+ private String genderId;
+ @Getter
+ @Setter
+ private String genderCode;
+ @Getter
+ @Setter
+ private String genderName;
+
+ @Getter
+ @Setter
+ private String nationId;
+ @Getter
+ @Setter
+ private String nationCode;
+ @Getter
+ @Setter
+ private String nationName;
+
+ @Getter
+ @Setter
+ private String countryId;
+ @Getter
+ @Setter
+ private String countryCode;
+ @Getter
+ @Setter
+ private String countryName;
+
+ @Getter
+ @Setter
+ private String addressId;
+ @Getter
+ @Setter
+ private String addressCode;
+ @Getter
+ @Setter
+ private String addressName;
+
+ @Getter
+ @Setter
+ private String phoneNumber;
+ @Getter
+ @Setter
+ private String email;
+
+ @Getter
+ @Setter
+ private String imageUrl;
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/AuthzService.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/AuthzService.java
new file mode 100644
index 0000000..9780b20
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/AuthzService.java
@@ -0,0 +1,41 @@
+package com.supwisdom.institute.backend.thirdparty.poa.service;
+
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.thirdparty.poa.PoaUtil;
+import com.supwisdom.institute.backend.thirdparty.poa.model.Role;
+
+@Slf4j
+@Service
+public class AuthzService {
+
+ @Value("${user-authorization-service.applicationId}")
+ private String applicationId;
+
+ @Value("${user-authorization-service.server.url}")
+ private String userAuthorizationServiceServerUrl;
+
+ public List<Role> loadAccountRoles(String username) {
+
+ JSONObject jsonObject = PoaUtil.loadAccountApplicationRoles(userAuthorizationServiceServerUrl, applicationId, username);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ JSONArray roleArray = data.getJSONArray("roles");
+
+ List<Role> roles = roleArray.toJavaList(Role.class);
+ log.debug("{}", roles);
+
+ return roles;
+ }
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/UserService.java b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/UserService.java
new file mode 100644
index 0000000..ba2527f
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/java/com/supwisdom/institute/backend/thirdparty/poa/service/UserService.java
@@ -0,0 +1,34 @@
+package com.supwisdom.institute.backend.thirdparty.poa.service;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.thirdparty.poa.PoaUtil;
+import com.supwisdom.institute.backend.thirdparty.poa.model.UserInfoModel;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class UserService {
+
+ @Value("${user-data-service.server.url}")
+ private String userDataServiceServerUrl;
+
+ public UserInfoModel loadUserInfoByAccountName(String accountName) {
+
+ JSONObject jsonObject = PoaUtil.loadUserInfoByAccountName(userDataServiceServerUrl, accountName);
+ if (jsonObject == null) {
+ return null;
+ }
+
+ JSONObject data = jsonObject.getJSONObject("data");
+
+ UserInfoModel userInfoModel = data.toJavaObject(UserInfoModel.class);
+ log.debug("userInfoModel: [{}]", userInfoModel);
+
+ return userInfoModel;
+ }
+
+}
diff --git a/thirdparty-agent/thirdparty-poa/src/main/resources/META-INF/spring.factories b/thirdparty-agent/thirdparty-poa/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..b4f81c0
--- /dev/null
+++ b/thirdparty-agent/thirdparty-poa/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.supwisdom.institute.backend.thirdparty.poa.autoconfigure.PoaAutoConfiguration