chore: 调整项目结构
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