feat: 应用开发后端基础框架,初始提交
diff --git a/common/core/pom.xml b/common/core/pom.xml
new file mode 100644
index 0000000..d535132
--- /dev/null
+++ b/common/core/pom.xml
@@ -0,0 +1,74 @@
+<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-parent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>../../</relativePath>
+  </parent>
+
+  <groupId>com.supwisdom.institute</groupId>
+  <artifactId>sw-backend-common-core</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>Supwisdom Backend Framework Common Core</name>
+  <description>Supwisdom Backend Framework Common Core 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.cloud</groupId>
+      <artifactId>spring-cloud-starter-openfeign</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </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>
+    </plugins>
+  </build>
+
+</project>
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java
new file mode 100644
index 0000000..5a094e9
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/annotation/EnableSimpleUserTransmit.java
@@ -0,0 +1,19 @@
+package com.supwisdom.institute.backend.common.core.transmit.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Import;
+
+import com.supwisdom.institute.backend.common.core.transmit.config.SimpleUserTransmitAutoConfiguration;
+
+@Documented
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Import({SimpleUserTransmitAutoConfiguration.class})
+public @interface EnableSimpleUserTransmit {
+
+}
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java
new file mode 100644
index 0000000..a3e11ce
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/config/SimpleUserTransmitAutoConfiguration.java
@@ -0,0 +1,27 @@
+package com.supwisdom.institute.backend.common.core.transmit.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.supwisdom.institute.backend.common.core.transmit.feign.SimpleUserTransmitRequestInterceptor;
+import com.supwisdom.institute.backend.common.core.transmit.filter.SimpleUserTransmitFilter;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Configuration
+public class SimpleUserTransmitAutoConfiguration {
+  
+  @Bean
+  public SimpleUserTransmitRequestInterceptor simpleUserTransmitRequestInterceptor() {
+    log.debug("-----SimpleUserTransmitRequestInterceptor");
+    return new SimpleUserTransmitRequestInterceptor();
+  }
+
+  @Bean
+  public SimpleUserTransmitFilter simpleUserTransmitFilter() {
+    log.debug("-----SimpleUserTransmitFilter");
+    return new SimpleUserTransmitFilter();
+  }
+  
+}
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java
new file mode 100644
index 0000000..be002db
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/feign/SimpleUserTransmitRequestInterceptor.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.common.core.transmit.feign;
+
+import java.net.URLDecoder;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.common.core.transmit.user.User;
+import com.supwisdom.institute.backend.common.core.transmit.user.UserContext;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+
+@Slf4j
+public class SimpleUserTransmitRequestInterceptor implements RequestInterceptor {
+
+  @Override
+  public void apply(RequestTemplate template) {
+    User user = UserContext.getUser();
+    if (user != null) {
+      try {
+        String jsonUser = JSONObject.toJSONString(user);
+        String headerValue = new String(URLDecoder.decode(jsonUser,"UTF-8"));
+        template.header(UserContext.KEY_USER_IN_HTTP_HEADER, headerValue);
+      } catch (Exception e) {
+        log.warn("User set error", e);
+      }
+    }
+  }
+
+}
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java
new file mode 100644
index 0000000..4d8a2dc
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/filter/SimpleUserTransmitFilter.java
@@ -0,0 +1,55 @@
+package com.supwisdom.institute.backend.common.core.transmit.filter;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.supwisdom.institute.backend.common.core.transmit.user.User;
+import com.supwisdom.institute.backend.common.core.transmit.user.UserContext;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SimpleUserTransmitFilter implements Filter {
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    
+  }
+
+  @Override
+  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+    HttpServletRequest request = (HttpServletRequest) servletRequest;
+    
+    String headerValue = request.getHeader(UserContext.KEY_USER_IN_HTTP_HEADER);
+    if (StringUtils.isNotBlank(headerValue)) {
+      try {
+        String jsonUser = URLDecoder.decode(headerValue,"UTF-8");
+        
+        User user = JSONObject.parseObject(jsonUser, User.class);
+        
+        UserContext.setUser(user);
+      } catch (Exception e) {
+        log.warn("User get error", e);
+      }
+    }
+    
+    filterChain.doFilter(servletRequest, servletResponse);
+  }
+
+  @Override
+  public void destroy() {
+    
+  }
+
+}
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java
new file mode 100644
index 0000000..3d34bc4
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/User.java
@@ -0,0 +1,17 @@
+package com.supwisdom.institute.backend.common.core.transmit.user;
+
+import java.util.List;
+import java.util.Map;
+
+import lombok.Value;
+
+@Value
+public class User {
+  
+  private String username;
+  
+  private List<String> roles;
+  
+  private Map<String, Object> attributes;
+
+}
diff --git a/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java
new file mode 100644
index 0000000..00f2e43
--- /dev/null
+++ b/common/core/src/main/java/com/supwisdom/institute/backend/common/core/transmit/user/UserContext.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.common.core.transmit.user;
+
+public class UserContext {
+  
+  private static ThreadLocal<User> user = new ThreadLocal<User>();
+  
+  public static String KEY_USER_IN_HTTP_HEADER = "X-FORWARD-USER";
+  
+  private UserContext() {
+    
+  }
+  
+  public static User getUser() {
+    return user.get();
+  }
+  
+  public static void setUser(User value) {
+    user.set(value);
+  }
+
+}
diff --git a/common/framework/pom.xml b/common/framework/pom.xml
new file mode 100644
index 0000000..328b83c
--- /dev/null
+++ b/common/framework/pom.xml
@@ -0,0 +1,80 @@
+<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-parent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>../../</relativePath>
+  </parent>
+
+  <groupId>com.supwisdom.institute</groupId>
+  <artifactId>sw-backend-common-framework</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>Supwisdom Backend Framework Common Framework</name>
+  <description>Supwisdom Backend Framework Common Framework project</description>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <scope>provided</scope>
+    </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>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-jpa</artifactId>
+      <optional>true</optional>
+    </dependency>
+
+
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger2</artifactId>
+    </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>
+    </plugins>
+  </build>
+
+</project>
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java
new file mode 100644
index 0000000..3c14c25
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/ABaseEntity.java
@@ -0,0 +1,79 @@
+package com.supwisdom.institute.backend.common.framework.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@MappedSuperclass
+public abstract class ABaseEntity implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 2613136930230449335L;
+
+  @Id
+  @Column(name = "ID")
+  private String id;
+
+  /**
+   * 获取主键
+   */
+  public String getId() {
+    return id;
+  }
+
+  /**
+   * 设置ID属性,主要用于人工指定键值
+   */
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  @Getter
+  @Setter
+  @Column(name = "COMPANY_ID", nullable = true)
+  private String companyId = null;
+
+  @Getter
+  @Setter
+  @Column(name = "DELETED")
+  private Boolean deleted = false;
+
+  @Getter
+  @Setter
+  @Column(name = "ADD_ACCOUNT", nullable = true)
+  private String addAccount = null;
+
+  @Getter
+  @Setter
+  @Column(name = "ADD_TIME", nullable = true)
+  private Date addTime = null;
+
+  @Getter
+  @Setter
+  @Column(name = "EDIT_ACCOUNT", nullable = true)
+  private String editAccount = null;
+
+  @Getter
+  @Setter
+  @Column(name = "EDIT_TIME", nullable = true)
+  private Date editTime = null;
+
+  @Getter
+  @Setter
+  @Column(name = "DELETE_ACCOUNT", nullable = true)
+  private String deleteAccount = null;
+
+  @Getter
+  @Setter
+  @Column(name = "DELETE_TIME", nullable = true)
+  private Date deleteTime = null;
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java
new file mode 100644
index 0000000..662b24a
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/entity/EntityUtils.java
@@ -0,0 +1,199 @@
+package com.supwisdom.institute.backend.common.framework.entity;
+
+import java.lang.reflect.Field;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+import com.supwisdom.institute.backend.common.util.ReflectUtils;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 对 entity 的操作 如:复制、合并、转换等
+ * 
+ * @author loie
+ *
+ */
+public class EntityUtils {
+
+  /**
+   * 合并 domain 中带有{@link Column}注解的字段值, 将 newEntity 中值为null的字段,使用 oldEntity 中的值
+   * 进行覆盖
+   * 
+   * @param oldEntity
+   *          ,覆盖的实体
+   * @param newEntity
+   *          ,待覆盖的实体
+   * @return 合并后的newEntity
+   */
+  public static <T> T merge(T oldEntity, T newEntity) {
+
+    for (Class<?> clazz = oldEntity.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
+      for (Field field : clazz.getDeclaredFields()) {
+        Column[] annotations = field.getAnnotationsByType(Column.class);
+        if (annotations == null || annotations.length == 0) {
+          Id[] idAnnotations = field.getAnnotationsByType(Id.class);
+          if (idAnnotations == null || idAnnotations.length == 0) {
+            continue;
+          }
+        }
+
+        String fieldName = field.getName();
+        Object newFieldValue = ReflectUtils.getFieldValue(newEntity, fieldName);
+
+        if (newFieldValue == null) {
+          Object oldFieldValue = ReflectUtils.getFieldValue(oldEntity, fieldName);
+          ReflectUtils.setFieldValue(newEntity, fieldName, oldFieldValue,field.getType());
+        }
+      }
+    }
+
+    return newEntity;
+  }
+
+  public static <S, T> T copy(S sourceEntity, T targetEntity) {
+    
+    for (Class<?> clazz = targetEntity.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
+      for (Field field : clazz.getDeclaredFields()) {
+        Column[] annotations = field.getAnnotationsByType(Column.class);
+        if (annotations == null || annotations.length == 0) {
+          Id[] idAnnotations = field.getAnnotationsByType(Id.class);
+          if (idAnnotations == null || idAnnotations.length == 0) {
+            continue;
+          }
+        }
+
+        String fieldName = field.getName();
+        Object sFieldValue = ReflectUtils.getFieldValue(sourceEntity, fieldName);
+
+        if (sFieldValue != null) {
+          ReflectUtils.setFieldValue(targetEntity, fieldName, sFieldValue,field.getType());
+        }
+      }
+    }
+
+    return targetEntity;
+  }
+
+  public static <S, T> T fatherToChild (S father, T child){
+    for (Class<?> clazz = child.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
+      for (Field field : clazz.getDeclaredFields()) {
+        String fieldName = field.getName();
+        if(fieldName.equals("serialVersionUID")){continue;}
+        Object sFieldValue = ReflectUtils.getFieldValue(father, fieldName);
+
+        if (sFieldValue != null) {
+          ReflectUtils.setFieldValue(child, fieldName, sFieldValue,field.getType());
+        }
+      }
+    }
+
+    return child;
+  }
+
+    public static void main(String[] args) {
+
+    Test target0 = new Test();
+    target0.setId("id0");
+    target0.setCode("code");
+    target0.setName("name");
+    target0.setDate(new Date());
+    target0.setEnabled(false);
+    target0.setStatus(1);
+
+    System.out.println("target0 == " + target0.toString());
+    System.out.println();
+
+    Test source1 = new Test();
+    // source1.setId("id1");
+    source1.setCode("code1");
+    // source1.setName("name");
+    // source1.setDate(new Date());
+    source1.setEnabled(true);
+    // source1.setStatus(1);
+    System.out.println("source1 == " + source1.toString());
+
+    Test target1 = EntityUtils.merge(source1, target0);
+    System.out.println("target0 == " + target0.toString());
+    System.out.println("target1 == " + target1.toString());
+    System.out.println();
+
+    Test source2 = new Test();
+    // source2.setId("id2");
+    source2.setCode("code2");
+    source2.setName("name2");
+    // source2.setDate(new Date());
+    // source2.setEnabled(true);
+    source2.setStatus(2);
+    System.out.println("source2 == " + source2.toString());
+
+    Test target2 = EntityUtils.merge(source2, target0);
+    System.out.println("target0 == " + target0.toString());
+    System.out.println("target2 == " + target2.toString());
+    System.out.println();
+
+
+    Test test = new Test();
+    test.setId("id0");
+    test.setCode("code");
+    test.setName("name");
+    test.setDate(new Date());
+    test.setEnabled(false);
+    test.setStatus(1);
+
+    Test2 test2 = new Test2();
+    test2 = EntityUtils.copy(test, test2);
+    System.out.println("test    == " + test.toString());
+    System.out.println("test2   == " + test2.toString());
+    System.out.println();
+
+  }
+  
+  @Getter
+  @Setter
+  @ToString
+  public static class Test extends ABaseEntity {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -8348781653151879484L;
+    
+    @Column
+    private String code = null;
+    @Column
+    private String name = null;
+    @Column
+    private Date date = null;
+    @Column
+    private Boolean enabled = null;
+    @Column
+    private Integer status = null;
+    
+  }
+  
+  public static class Test2 extends ABaseEntity {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5565959639168005384L;
+    
+    @Column
+    private String name = null;
+    @Column
+    private String memo = null;
+    @Column
+    private Date date = null;
+    @Column
+    private Boolean enabled = null;
+    @Column
+    private Integer status = null;
+
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java
new file mode 100644
index 0000000..ee21f7a
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/exception/BaseException.java
@@ -0,0 +1,66 @@
+package com.supwisdom.institute.backend.common.framework.exception;
+
+public class BaseException extends RuntimeException {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 2278568118369300446L;
+
+  /**
+   * 异常信息
+   */
+  protected String msg;
+
+  /**
+   * 具体异常码
+   */
+  protected int code = -1;
+
+  public BaseException(int code, String msgFormat, Object... args) {
+      super(String.format(msgFormat, args));
+      this.code = code;
+      this.msg = String.format(msgFormat, args);
+  }
+
+  public BaseException() {
+      super();
+  }
+
+  public BaseException(String message, Throwable cause) {
+      super(message, cause);
+  }
+
+  public BaseException(Throwable cause) {
+      super(cause);
+  }
+
+  public BaseException(String message) {
+      super(message);
+  }
+
+  public String getMsg() {
+      return msg;
+  }
+
+  public int getCode() {
+      return code;
+  }
+
+  /**
+   * 实例化异常
+   * 
+   * @param msgFormat
+   * @param args
+   * @return
+   */
+  @Deprecated
+  public BaseException newInstance(String msgFormat, Object... args) {
+      return new BaseException(this.code, msgFormat, args);
+  }
+  
+  public BaseException newInstance(int code, String msgFormat, Object... args) {
+    return new BaseException(code, msgFormat, args);
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java
new file mode 100644
index 0000000..3b8d6d3
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/ABaseModal.java
@@ -0,0 +1,10 @@
+package com.supwisdom.institute.backend.common.framework.modal;
+
+public abstract class ABaseModal implements IModal {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 8717041105592152819L;
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java
new file mode 100644
index 0000000..cb6f72b
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/modal/IModal.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.modal;
+
+import java.io.Serializable;
+
+public interface IModal extends Serializable {
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java
new file mode 100644
index 0000000..1266710
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/ExchangeNames.java
@@ -0,0 +1,13 @@
+package com.supwisdom.institute.backend.common.framework.rabbitmq.constants;
+
+public class ExchangeNames {
+
+  public static final String EXCHANGE_NAME_FANOUT = "fanout-exchange";
+
+  public static final String EXCHANGE_NAME_DIRECT = "direct-exchange";
+
+  public static final String EXCHANGE_NAME_TOPIC = "topic-exchange";
+
+  public static final String EXCHANGE_NAME_HEADERS = "headers-exchange";
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java
new file mode 100644
index 0000000..e2ed900
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/QueueNames.java
@@ -0,0 +1,21 @@
+package com.supwisdom.institute.backend.common.framework.rabbitmq.constants;
+
+public class QueueNames {
+
+  /**
+   * 授权添加事件
+   */
+  public static final String QUEUE_NAME_GRANTED_ADDED = "granted-added";
+
+  /**
+   * 授权移除事件
+   */
+  public static final String QUEUE_NAME_GRANTED_REMOVED = "granted-removed";
+
+  
+  /**
+   * 授权操作日志记录事件
+   */
+  public static final String QUEUE_NAME_GRANT_OPERATE_LOGGING = "granted-operate-logging";
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java
new file mode 100644
index 0000000..dad0e02
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/rabbitmq/constants/RoutingKeys.java
@@ -0,0 +1,20 @@
+package com.supwisdom.institute.backend.common.framework.rabbitmq.constants;
+
+public class RoutingKeys {
+
+  /**
+   * 授权添加事件
+   */
+  public static final String ROUTING_KEY_GRANTED_ADDED = "granted.added";
+
+  /**
+   * 授权移除事件
+   */
+  public static final String ROUTING_KEY_GRANTED_REMOVED = "granted.removed";
+
+  
+  /**
+   * 授权操作日志记录事件
+   */
+  public static final String ROUTING_KEY_GRANT_OPERATE_LOGGING = "grant.operate.logging";
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java
new file mode 100644
index 0000000..32e0e33
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/ABaseJpaRepositoryImpl.java
@@ -0,0 +1,92 @@
+package com.supwisdom.institute.backend.common.framework.repo;
+
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Transactional;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.jpa.repository.support.JpaEntityInformation;
+import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+@Transactional
+@NoRepositoryBean
+public class ABaseJpaRepositoryImpl<E extends ABaseEntity> extends SimpleJpaRepository<E, String> implements BaseJpaRepository<E> {
+
+  @SuppressWarnings("unused")
+  private final EntityManager em;
+
+  public ABaseJpaRepositoryImpl(Class<E> domainClass, EntityManager em) {
+    super(domainClass, em);
+    this.em = em;
+  }
+
+  public ABaseJpaRepositoryImpl(JpaEntityInformation<E, String> information, EntityManager em) {
+    super(information, em);
+    this.em = em;
+  }
+  
+  public Page<E> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+    PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+    Page<E> page = this.findAll(pageRequest);
+
+    return page;
+  }
+
+  public E selectById(String id) {
+
+    try {
+      Optional<E> entity = this.findById(id);
+
+      if (entity.isPresent()) {
+        return entity.get();
+      }
+    } catch (RuntimeException e) {
+      System.out.println("RuntimeException:" + e.getMessage());
+    } catch (Exception e) {
+      System.out.println("Exception:" + e.getMessage());
+    }
+
+    return null;
+  }
+
+  public E insert(E entity) {
+
+    if (entity.getCompanyId() == null || entity.getCompanyId().isEmpty()) {
+      entity.setCompanyId("1");
+    }
+
+    if (entity.getDeleted() == null) {
+      entity.setDeleted(false);
+    }
+    //entity.setAddAccount(AuthUtil.getRemoteUser()); // FIXME: setAddAccount
+    if (entity.getAddTime() == null) {
+      entity.setAddTime(Calendar.getInstance().getTime());
+    }
+
+    E e = this.save(entity);
+
+    return e;
+  }
+
+  public E update(E entity) {
+
+    //entity.setEditAccount(AuthUtil.getRemoteUser()); // FIXME: setEditAccount
+    if (entity.getEditTime() == null) {
+      entity.setEditTime(Calendar.getInstance().getTime());
+    }
+    
+    E e = this.save(entity);
+
+    return e;
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java
new file mode 100644
index 0000000..3451705
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/BaseJpaRepository.java
@@ -0,0 +1,123 @@
+package com.supwisdom.institute.backend.common.framework.repo;
+
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+import com.supwisdom.institute.backend.common.util.UUIDUtils;
+
+@NoRepositoryBean
+public interface BaseJpaRepository<E extends ABaseEntity> extends JpaRepository<E, String>, JpaSpecificationExecutor<E> {
+  
+
+  /**
+   * 生成主键值。 默认使用方法
+   * 如果需要生成主键,需要由子类重写此方法根据需要的方式生成主键值。 
+   * @param entity 要持久化的对象 
+   */
+  public default String generateId() {
+    return UUIDUtils.create();
+  }
+
+  public default Page<E> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+    
+    if (loadAll) {
+      pageIndex = 0;
+      pageSize = Integer.MAX_VALUE;
+    }
+
+    PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+    Page<E> page = this.findAll(pageRequest);
+
+    return page;
+  }
+  
+  public default E selectById(String id) {
+
+    try {
+      Optional<E> entity = this.findById(id);
+
+      if (entity.isPresent()) {
+        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 E insert(E entity) {
+    
+    if (entity.getId() == null || entity.getId().isEmpty()) {
+      entity.setId(generateId());
+    }
+
+    if (entity.getCompanyId() == null || entity.getCompanyId().isEmpty()) {
+      entity.setCompanyId("1");
+    }
+
+    if (entity.getDeleted() == null) {
+      entity.setDeleted(false);
+    }
+    if (entity.getAddAccount() == null) {
+      //entity.setAddAccount(AuthUtil.getRemoteUser()); // FIXME: setAddAccount
+    }
+    if (entity.getAddTime() == null) {
+      entity.setAddTime(Calendar.getInstance().getTime());
+    }
+    
+    E e = this.save(entity);
+
+    return e;
+  }
+  
+  public default E update(E entity) {
+
+    if (entity.getEditAccount() == null) {
+      //entity.setEditAccount(AuthUtil.getRemoteUser()); // FIXME: setEditAccount
+    }
+    if (entity.getEditTime() == null) {
+      entity.setEditTime(Calendar.getInstance().getTime());
+    }
+    
+    E e = this.save(entity);
+
+    return e;
+  }
+  
+  
+  public default E remove(E entity) {
+    
+    if (entity.getDeleted() == null) {
+      entity.setDeleted(true);
+    }
+    if (entity.getDeleteAccount() == null) {
+      //entity.setDeleteAccount(AuthUtil.getRemoteUser()); // FIXME: setDeleteAccount
+    }
+    if (entity.getDeleteTime() == null) {
+      entity.setDeleteTime(Calendar.getInstance().getTime());
+    }
+    
+    E e = this.save(entity);
+    
+    return e;
+  }
+  
+  
+  public default void delete(String id) {
+    
+    this.deleteById(id);
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java
new file mode 100644
index 0000000..ee622bc
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/repo/resultTransformer/IgnoreCaseResultTransformer.java
@@ -0,0 +1,72 @@
+package com.supwisdom.institute.backend.common.framework.repo.resultTransformer;
+
+import com.google.common.collect.Lists;
+import com.supwisdom.institute.backend.common.util.ReflectUtils;
+
+import org.hibernate.HibernateException;
+import org.hibernate.transform.ResultTransformer;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ * 
+ * 修正hibernate返回自定义pojo类型时找不到属性的BUG
+ * 主要发生在使用oracle或高版本的mysql时,查询返回的字段默认是大写的(除非SQL中指定了别名),这导致返回自定义pojo类型时会报找不到属性的错误,该类用于修正此BUG。
+ * 使用该类时SQL返回的字段名大小写或者带"_"都会被忽略,如数据库字段为 USER_NAME,自定义pojo的属性名为username就可以使用
+ * 
+ * @author feng*/
+public class IgnoreCaseResultTransformer implements ResultTransformer {
+        private static final long serialVersionUID = -3779317531110592988L;
+        private final Class<?> resultClass;
+        private Field[] fields;
+        private List<Class> types = Lists.newArrayList();
+        public IgnoreCaseResultTransformer(final Class<?> resultClass) {
+            this.resultClass = resultClass;
+            List<Field> list = Lists.newArrayList();
+            for (Class<?> superClass = resultClass; superClass != Object.class; superClass = superClass.getSuperclass()) {
+                Field[] fs = superClass.getDeclaredFields();
+                List<Field> newFs = Lists.newArrayList();
+                for(int i=0;i<fs.length;i++){
+                    if(fs[i].getName().equals("serialVersionUID")){
+                        continue;
+                    }
+                    types.add(fs[i].getType());
+                    ReflectUtils.makeAccessible(fs[i]);
+                    newFs.add(fs[i]);
+                }
+                list.addAll(newFs);
+            }
+            this.fields = list.toArray(new Field[list.size()]);
+        }
+         /**
+      * aliases为每条记录的数据库字段名,ORACLE字段名默认为大写
+      * tupe为与aliases对应的字段的值
+      */
+         @Override
+         public Object transformTuple(final Object[] tuple, final String[] aliases) {
+           Object result;
+             try {
+                result = this.resultClass.newInstance();
+                    for (int i = 0; i < aliases.length; i++) {
+                        for (int j=0;j<this.fields.length;j++) {
+                          String fieldName = this.fields[j].getName();
+                           //数据库字段带下划线的时候也能保证使用,如数据库字段为 USER_NAME,自定义pojo的属性名为username就可以使用
+                           if (fieldName.equalsIgnoreCase(aliases[i].replaceAll("_", ""))) {
+                               ReflectUtils.invokeSetter(result,fieldName,tuple[i],this.types.get(j));
+//                               beanUtilsBean.setProperty(result, fieldName, tuple[i]);
+                               break;
+                                   }
+                          }
+                  }
+           } catch (Exception e) {
+               throw new HibernateException("Could not instantiate resultclass: " + this.resultClass.getName(), e);
+           }
+          return result;
+      }
+      @Override
+      @SuppressWarnings("rawtypes")
+      public List transformList(final List collection) {
+           return collection;
+      }
+}
\ No newline at end of file
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/service/ABaseService.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/service/ABaseService.java
new file mode 100644
index 0000000..dccfc17
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/service/ABaseService.java
@@ -0,0 +1,42 @@
+package com.supwisdom.institute.backend.common.framework.service;
+
+import java.util.Map;
+
+import org.springframework.data.domain.Page;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+import com.supwisdom.institute.backend.common.framework.repo.BaseJpaRepository;
+
+public abstract class ABaseService<E extends ABaseEntity, REPO extends BaseJpaRepository<E>> {
+  
+  public abstract REPO getRepo();
+  
+  public Page<E> selectPageList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
+    
+    return getRepo().selectPageList(loadAll, pageIndex, pageSize, mapBean, orderBy);
+  }
+  
+  public E selectById(String id) {
+    
+    return getRepo().selectById(id);
+  }
+  
+  public E insert(E entity) {
+    
+    return getRepo().insert(entity);
+  }
+  
+  public E update(E entity) {
+    
+    E ret = getRepo().update(entity);
+    getRepo().flush();
+    
+    return ret;
+  }
+  
+  public void deleteById(String id) {
+    
+    getRepo().deleteById(id);
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java
new file mode 100644
index 0000000..f118c4d
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiCreateRequest.java
@@ -0,0 +1,5 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+public interface IApiCreateRequest extends IApiRequest {
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java
new file mode 100644
index 0000000..3cf62c4
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiLoadRequest.java
@@ -0,0 +1,9 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+public interface IApiLoadRequest extends IApiRequest {
+  
+  String getId();
+
+  void setId(String id);
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java
new file mode 100644
index 0000000..da3b638
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiQueryRequest.java
@@ -0,0 +1,27 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+import java.util.Map;
+
+public interface IApiQueryRequest extends IApiRequest {
+
+  boolean isLoadAll();
+  
+  void setLoadAll(boolean loadAll);
+
+  int getPageIndex();
+  
+  void setPageIndex(int pageIndex);
+
+  int getPageSize();
+  
+  void setPageSize(int pageSize);
+  
+  Map<String, Object> getMapBean();
+  
+  void setMapBean(Map<String, Object> mapBean);
+
+  Map<String, String> getOrderBy();
+  
+  void setOrderBy(Map<String, String> orderBy);
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java
new file mode 100644
index 0000000..bda1e59
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRemoveRequest.java
@@ -0,0 +1,10 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+public interface IApiRemoveRequest extends IApiRequest {
+
+  String getId();
+
+
+  void setId(String id);
+  
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java
new file mode 100644
index 0000000..71a4abd
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiRequest.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+import java.io.Serializable;
+
+public interface IApiRequest extends Serializable {
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java
new file mode 100644
index 0000000..9c491c4
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/request/IApiUpdateRequest.java
@@ -0,0 +1,9 @@
+package com.supwisdom.institute.backend.common.framework.vo.request;
+
+public interface IApiUpdateRequest extends IApiRequest {
+
+  String getId();
+
+  void setId(String id);
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java
new file mode 100644
index 0000000..8e979e3
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/AbstractApiResponse.java
@@ -0,0 +1,37 @@
+package com.supwisdom.institute.backend.common.framework.vo.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public abstract class AbstractApiResponse<T extends IApiResponseData> implements IApiResponse<T> {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 846108786006850165L;
+  
+  @JsonIgnore
+  @Deprecated
+  protected boolean acknowleged = true;
+
+  @Override
+  @JsonIgnore
+  @Deprecated
+  public boolean isAcknowleged() {
+    return acknowleged;
+  }
+  
+  protected int code = 0;
+  protected String message = null;
+  
+  @Override
+  public int getCode() {
+    return code;
+  }
+  
+  @Override
+  public String getMessage() {
+    return message;
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java
new file mode 100644
index 0000000..72ac7e2
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/DefaultApiResponse.java
@@ -0,0 +1,59 @@
+package com.supwisdom.institute.backend.common.framework.vo.response;
+
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class DefaultApiResponse<T extends IApiResponseData> extends AbstractApiResponse<T> {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 4380576799912565681L;
+
+  protected T data;
+
+  @Override
+  public T getData() {
+    return data;
+  }
+
+//  public void setData(T data) {
+//    this.data = data;
+//  }
+//
+//  public DefaultApiResponse() {
+//
+//  }
+
+  public DefaultApiResponse(T data) {
+    this(0, null, data);
+  }
+
+  @Deprecated
+  public DefaultApiResponse(boolean acknowleged, T data) {
+    super.acknowleged = acknowleged;
+    if (super.acknowleged == false) {
+      super.code = -1;
+      super.message = "未知错误";
+    }
+    
+    this.data = data;
+  }
+  
+  public DefaultApiResponse(int code, String message, T data) {
+    super.code = code;
+    super.message = message;
+    
+    if (code != 0) {
+      super.acknowleged = false;
+    }
+    
+    this.data = data;
+  }
+
+  public static <T extends IApiResponseData> DefaultApiResponse<T> build(T data) {
+    DefaultApiResponse<T> defaultApiResponse = new DefaultApiResponse<T>(data);
+
+    return defaultApiResponse;
+  }
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java
new file mode 100644
index 0000000..487183a
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/IApiResponse.java
@@ -0,0 +1,20 @@
+package com.supwisdom.institute.backend.common.framework.vo.response;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public interface IApiResponse<T extends IApiResponseData> extends Serializable {
+  
+  @JsonIgnore
+  @Deprecated
+  boolean isAcknowleged();
+  
+  int getCode();
+  
+  String getMessage();
+  
+  T getData();
+  
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java
new file mode 100644
index 0000000..05ab9d2
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiCreateResponseData.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+public interface IApiCreateResponseData extends IApiResponseData {
+
+  String getId();
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java
new file mode 100644
index 0000000..8741959
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiLoadResponseData.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+public interface IApiLoadResponseData extends IApiResponseData {
+
+  String getId();
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java
new file mode 100644
index 0000000..4e78c10
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiQueryResponseData.java
@@ -0,0 +1,58 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+import java.util.List;
+import java.util.Map;
+
+import com.supwisdom.institute.backend.common.framework.entity.ABaseEntity;
+
+public interface IApiQueryResponseData<E extends ABaseEntity> extends IApiResponseData {
+  
+  /**
+   * 当前页码
+   * @return
+   */
+  int getPageIndex();
+  
+  /**
+   * 每页记录数
+   * @return
+   */
+  int getPageSize();
+  
+  /**
+   * 查询条件
+   * @return
+   */
+  Map<String, Object> getMapBean();
+  
+  /**
+   * 排序字段
+   * @return
+   */
+  Map<String, String> getOrderBy();
+  
+  /**
+   * 总页数
+   * @return
+   */
+  int getPageCount();
+  
+  /**
+   * 总记录数
+   * @return
+   */
+  long getRecordCount();
+  
+  /**
+   * 返回记录数
+   * @return
+   */
+  int getCurrentItemCount();
+  
+  /**
+   * 返回记录
+   * @return
+   */
+  List<E> getItems();
+  
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java
new file mode 100644
index 0000000..820c62d
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiRemoveResponseData.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+public interface IApiRemoveResponseData extends IApiResponseData {
+
+  String getId();
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java
new file mode 100644
index 0000000..56b9163
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiResponseData.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+import java.io.Serializable;
+
+public interface IApiResponseData extends Serializable {
+
+}
diff --git a/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java
new file mode 100644
index 0000000..211c437
--- /dev/null
+++ b/common/framework/src/main/java/com/supwisdom/institute/backend/common/framework/vo/response/data/IApiUpdateResponseData.java
@@ -0,0 +1,7 @@
+package com.supwisdom.institute.backend.common.framework.vo.response.data;
+
+public interface IApiUpdateResponseData extends IApiResponseData {
+
+  String getId();
+
+}
diff --git a/common/pom.xml b/common/pom.xml
new file mode 100644
index 0000000..22eb667
--- /dev/null
+++ b/common/pom.xml
@@ -0,0 +1,37 @@
+<?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-parent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+  </parent>
+  
+  <groupId>com.supwisdom.institute</groupId>
+  <artifactId>sw-backend-common</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <name>Supwisdom Backend Framework Common</name>
+  <description>Supwisdom Backend Framework Common project</description>
+
+  <modules>
+    <module>core</module>
+    <module>utils</module>
+    <module>framework</module>
+  </modules>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/common/utils/pom.xml b/common/utils/pom.xml
new file mode 100644
index 0000000..36fec72
--- /dev/null
+++ b/common/utils/pom.xml
@@ -0,0 +1,68 @@
+<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-parent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>../../</relativePath>
+  </parent>
+
+  <groupId>com.supwisdom.institute</groupId>
+  <artifactId>sw-backend-common-utils</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>Supwisdom Backend Framework Common Utils</name>
+  <description>Supwisdom Backend Framework Common Utils 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>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </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>
+    </plugins>
+  </build>
+
+</project>
diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java
new file mode 100644
index 0000000..0f08910
--- /dev/null
+++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/DateUtil.java
@@ -0,0 +1,45 @@
+package com.supwisdom.institute.backend.common.util;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DateUtils;
+
+public class DateUtil {
+  
+  public static void main(String[] args) {
+    Date d0 = DateUtil.parseDate("2019-07-23 00:00:00", "yyyy-MM-dd HH:mm:ss");
+
+    Date d1 = DateUtil.parseDate("2019-07-23 23:59:59", "yyyy-MM-dd HH:mm:ss");
+
+    System.out.println(d0);
+    System.out.println(d1);
+    
+    String s0 = DateUtil.formatDate(DateUtil.now(), "yyyyMMddHHmmss");
+    System.out.println(s0);
+  }
+  
+  public static Date parseDate(String source, String pattern) {
+    
+    try {
+      Date d = DateUtils.parseDate(source, pattern);
+      
+      return d;
+    } catch (ParseException e) {
+      e.printStackTrace();
+    }
+    
+    return null;
+  }
+
+  public static Date now() {
+    return new Date();
+  }
+  
+  
+  public static String formatDate(Date date, String pattern) {
+    return DateFormatUtils.format(date, pattern);
+  }
+
+}
diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java
new file mode 100644
index 0000000..0a5f50f
--- /dev/null
+++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/MapBeanUtils.java
@@ -0,0 +1,226 @@
+package com.supwisdom.institute.backend.common.util;
+
+import com.google.common.collect.Lists;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Map;
+
+public class MapBeanUtils {
+
+  /**
+   * 判断 mapBean 中的 key 是否存在;若存在,则判断是否有值
+   * 
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static boolean containsValue(Map<String, Object> mapBean, String key) {
+
+    if (!mapBean.containsKey(key)) {
+      return false;
+    }
+
+    if (mapBean.get(key) == null) {
+      return false;
+    }
+
+    if (String.valueOf(mapBean.get(key)).isEmpty()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 null
+   * 
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static String getString(Map<String, Object> mapBean, String key) {
+
+    return getString(mapBean, key, null);
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+   * 
+   * @param mapBean
+   * @param key
+   * @param defaultValue
+   * @return
+   */
+  public static String getString(Map<String, Object> mapBean, String key, String defaultValue) {
+
+    if (containsValue(mapBean, key)) {
+      return String.valueOf(mapBean.get(key));
+    }
+
+    return defaultValue;
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 false
+   * 
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static Boolean getBoolean(Map<String, Object> mapBean, String key) {
+
+    return getBoolean(mapBean, key, null);
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+   * 
+   * @param mapBean
+   * @param key
+   * @param defaultValue
+   * @return
+   */
+  public static Boolean getBoolean(Map<String, Object> mapBean, String key, Boolean defaultValue) {
+
+    if (containsValue(mapBean, key)) {
+      Boolean b = Boolean.valueOf(String.valueOf(mapBean.get(key)));
+      return b == null ? defaultValue : b;
+    }
+
+    return defaultValue;
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 -1
+   * 
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static Integer getInteger(Map<String, Object> mapBean, String key) {
+
+    return getInteger(mapBean, key, null);
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+   * 
+   * @param mapBean
+   * @param key
+   * @param defaultValue
+   * @return
+   */
+  public static Integer getInteger(Map<String, Object> mapBean, String key, Integer defaultValue) {
+
+    if (containsValue(mapBean, key)) {
+      Integer i = Integer.valueOf(String.valueOf(mapBean.get(key)));
+      return i == null ? defaultValue : i;
+    }
+
+    return defaultValue;
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 -1L
+   * 
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static Long getLong(Map<String, Object> mapBean, String key) {
+
+    return getLong(mapBean, key, null);
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+   * 
+   * @param mapBean
+   * @param key
+   * @param defaultValue
+   * @return
+   */
+  public static Long getLong(Map<String, Object> mapBean, String key, Long defaultValue) {
+
+    if (containsValue(mapBean, key)) {
+      Long l = Long.valueOf(String.valueOf(mapBean.get(key)));
+      return l == null ? defaultValue : l;
+    }
+
+    return defaultValue;
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 -1L
+   *
+   * @param mapBean
+   * @param key
+   * @return
+   */
+  public static List getList(Map<String, Object> mapBean, String key) {
+
+    return getList(mapBean, key, Lists.newArrayList());
+  }
+
+  /**
+   * 获取 mapBean 中 key 的 value,若不存在,则返回 defaultValue
+   *
+   * @param mapBean
+   * @param key
+   * @param defaultValue
+   * @return
+   */
+  public static List getList(Map<String, Object> mapBean, String key, List defaultValue) {
+
+    if (containsValue(mapBean, key)) {
+      List l = (List)mapBean.get(key);
+      return l == null ? defaultValue : l;
+    }
+
+    return defaultValue;
+  }
+
+  /**
+   * 将一个 Map 对象转化为一个 JavaBean
+   * @param obj 要转化的对象
+   * @param map 包含属性值的 map
+   * @return 转化出来的 JavaBean 对象
+   * @throws IntrospectionException
+   *             如果分析类属性失败
+   * @throws IllegalAccessException
+   *             如果实例化 JavaBean 失败
+   * @throws InstantiationException
+   *             如果实例化 JavaBean 失败
+   * @throws InvocationTargetException
+   *             如果调用属性的 setter 方法失败
+   */
+  public static Object convert2Bean(Object obj, Map map)
+          throws IntrospectionException, IllegalAccessException,
+          InstantiationException, InvocationTargetException {
+    BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性
+
+    // 给 JavaBean 对象的属性赋值
+    PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
+    for (int i = 0; i< propertyDescriptors.length; i++) {
+      PropertyDescriptor descriptor = propertyDescriptors[i];
+      String propertyName = descriptor.getName();
+
+      if (map.containsKey(propertyName)) {
+        // 下面一句可以 try 起来,这样当一个属性赋值失败的时候就不会影响其他属性赋值。
+        Object value = map.get(propertyName);
+
+        Object[] args = new Object[1];
+        args[0] = value;
+
+        descriptor.getWriteMethod().invoke(obj, args);
+      }
+    }
+    return obj;
+  }
+
+}
diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java
new file mode 100644
index 0000000..1b9313e
--- /dev/null
+++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/ReflectUtils.java
@@ -0,0 +1,386 @@
+package com.supwisdom.institute.backend.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+import org.springframework.util.Assert;
+
+import java.lang.reflect.*;
+import java.util.Date;
+
+/**
+ * 利用反射进行操作的一个工具类
+ *
+ * @author fengpy
+ */
+@SuppressWarnings("rawtypes")
+@Slf4j
+public class ReflectUtils {
+
+  private static final String SETTER_PREFIX = "set";
+
+  private static final String GETTER_PREFIX = "get";
+
+  private static final String CGLIB_CLASS_SEPARATOR = "$$";
+
+  /**
+   * 利用反射获取指定对象里面的指定属性
+   *
+   * @param obj
+   *          目标对象
+   * @param fieldName
+   *          目标属性
+   * @return 目标字段
+   */
+  private static Field getField(Object obj, String fieldName) {
+    Field field = null;
+    for (Class<?> clazz = obj.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
+      try {
+        field = clazz.getDeclaredField(fieldName);
+        break;
+      } catch (NoSuchFieldException e) {
+        // 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。
+      }
+    }
+    return field;
+  }
+
+  /**
+   * 调用Getter方法.
+   * 支持多级,如:对象名.对象名.方法
+   */
+  public static Object invokeGetter(Object obj, String propertyName) {
+    Object object = obj;
+    for (String name : StringUtils.split(propertyName, ".")){
+      String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
+      object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
+    }
+    return object;
+  }
+
+  /**
+   * 调用Setter方法, 仅匹配方法名。
+   * 支持多级,如:对象名.对象名.方法
+   */
+  public static void invokeSetter(Object obj, String propertyName, Object value, Class valueCla) throws IllegalAccessException, InstantiationException {
+    Object object = obj;
+    String[] names = StringUtils.split(propertyName, ".");
+    for (int i=0; i<names.length; i++){
+      if(i<names.length-1){
+        String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
+        object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
+      }else{
+        String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
+        value = doSpecial(value,valueCla);
+        invokeMethodByName(object, setterMethodName, new Object[] { value });
+      }
+    }
+  }
+
+  /**
+   * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
+   */
+  public static Object getFieldValue(final Object obj, final String fieldName) {
+    Field field = getAccessibleField(obj, fieldName);
+
+    if (field == null) {
+      throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
+    }
+
+    Object result = null;
+    try {
+      result = field.get(obj);
+    } catch (IllegalAccessException e) {
+      log.error("不可能抛出的异常{}", e.getMessage());
+    }
+    return result;
+  }
+
+  /**
+   * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
+   */
+  public static void setFieldValue(final Object obj, final String fieldName, final Object value, Class valueCla) {
+    Field field = getAccessibleField(obj, fieldName);
+
+    if (field == null) {
+      throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
+    }
+
+    try {
+      doSpecial(value,valueCla);
+      field.set(obj, value);
+    } catch (IllegalAccessException e) {
+      log.error("不可能抛出的异常:{}", e.getMessage());
+    }
+  }
+
+  /**
+   * 直接调用对象方法, 无视private/protected修饰符.
+   * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
+   * 同时匹配方法名+参数类型,
+   */
+  public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
+                                    final Object[] args) {
+    Method method = getAccessibleMethod(obj, methodName, parameterTypes);
+    if (method == null) {
+      throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
+    }
+
+    try {
+      return method.invoke(obj, args);
+    } catch (Exception e) {
+      throw convertReflectionExceptionToUnchecked(e);
+    }
+  }
+
+  /**
+   * 直接调用对象方法, 无视private/protected修饰符,
+   * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
+   * 只匹配函数名,如果有多个同名函数调用第一个。
+   */
+  public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
+    Method method = getAccessibleMethodByName(obj, methodName);
+    if (method == null) {
+      throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
+    }
+
+    try {
+      return method.invoke(obj, args);
+    } catch (Exception e) {
+      throw convertReflectionExceptionToUnchecked(e);
+    }
+  }
+
+  /**
+   * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
+   *
+   * 如向上转型到Object仍无法找到, 返回null.
+   */
+  public static Field getAccessibleField(final Object obj, final String fieldName) {
+    Validate.notNull(obj, "object can't be null");
+    Validate.notBlank(fieldName, "fieldName can't be blank");
+    for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
+      try {
+        Field field = superClass.getDeclaredField(fieldName);
+        makeAccessible(field);
+        return field;
+      } catch (NoSuchFieldException e) {//NOSONAR
+        // Field不在当前类定义,继续向上转型
+        continue;// new add
+      }
+    }
+    return null;
+  }
+
+  /**
+   * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
+   * 如向上转型到Object仍无法找到, 返回null.
+   * 匹配函数名+参数类型。
+   *
+   * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
+   */
+  public static Method getAccessibleMethod(final Object obj, final String methodName,
+                                           final Class<?>... parameterTypes) {
+    Validate.notNull(obj, "object can't be null");
+    Validate.notBlank(methodName, "methodName can't be blank");
+
+    for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
+      try {
+        Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
+        makeAccessible(method);
+        return method;
+      } catch (NoSuchMethodException e) {
+        // Method不在当前类定义,继续向上转型
+        continue;// new add
+      }
+    }
+    return null;
+  }
+
+  /**
+   * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
+   * 如向上转型到Object仍无法找到, 返回null.
+   * 只匹配函数名。
+   *
+   * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
+   */
+  public static Method getAccessibleMethodByName(final Object obj, final String methodName) {
+    Validate.notNull(obj, "object can't be null");
+    Validate.notBlank(methodName, "methodName can't be blank");
+
+    for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
+      Method[] methods = searchType.getDeclaredMethods();
+      for (Method method : methods) {
+        if (method.getName().equals(methodName)) {
+          makeAccessible(method);
+          return method;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
+   */
+  public static void makeAccessible(Method method) {
+    if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
+            && !method.isAccessible()) {
+      method.setAccessible(true);
+    }
+  }
+
+  /**
+   * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
+   */
+  public static void makeAccessible(Field field) {
+    if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
+            .isFinal(field.getModifiers())) && !field.isAccessible()) {
+      field.setAccessible(true);
+    }
+  }
+
+  /**
+   * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
+   * 如无法找到, 返回Object.class.
+   * eg.
+   * public UserDao extends HibernateDao<User>
+   *
+   * @param clazz The class to introspect
+   * @return the first generic declaration, or Object.class if cannot be determined
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> Class<T> getClassGenricType(final Class clazz) {
+    return getClassGenricType(clazz, 0);
+  }
+
+  /**
+   * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
+   * 如无法找到, 返回Object.class.
+   *
+   * 如public UserDao extends HibernateDao<User,Long>
+   *
+   * @param clazz clazz The class to introspect
+   * @param index the Index of the generic ddeclaration,start from 0.
+   * @return the index generic declaration, or Object.class if cannot be determined
+   */
+  public static Class getClassGenricType(final Class clazz, final int index) {
+
+    Type genType = clazz.getGenericSuperclass();
+
+    if (!(genType instanceof ParameterizedType)) {
+      log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
+      return Object.class;
+    }
+
+    Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+
+    if (index >= params.length || index < 0) {
+      log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+              + params.length);
+      return Object.class;
+    }
+    if (!(params[index] instanceof Class)) {
+      log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
+      return Object.class;
+    }
+
+    return (Class) params[index];
+  }
+
+  public static Class<?> getUserClass(Object instance) {
+    Assert.notNull(instance, "Instance must not be null");
+    Class clazz = instance.getClass();
+    if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
+      Class<?> superClass = clazz.getSuperclass();
+      if (superClass != null && !Object.class.equals(superClass)) {
+        return superClass;
+      }
+    }
+    return clazz;
+
+  }
+
+  /**
+   * 将反射时的checked exception转换为unchecked exception.
+   */
+  public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
+    if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
+            || e instanceof NoSuchMethodException) {
+      return new IllegalArgumentException(e);
+    } else if (e instanceof InvocationTargetException) {
+      return new RuntimeException(((InvocationTargetException) e).getTargetException());
+    } else if (e instanceof RuntimeException) {
+      return (RuntimeException) e;
+    }
+    return new RuntimeException("Unexpected Checked Exception.", e);
+  }
+
+  /**
+   * 类型转换
+   *
+   * @param clazz
+   *          :目标类型
+   * @param source
+   *          :待转换对象
+   * @return :目标对象
+   */
+  public static Object typeConversion(Class<?> clazz, String source) {
+
+    if (clazz == null) {
+      throw new IllegalArgumentException("clazz should not be null");
+    }
+
+    Object targetObj = null;
+    String nameType = clazz.getName();
+
+    if ("java.lang.Integer".equals(nameType) || "int".equals(nameType)) {
+      targetObj = Integer.valueOf(source);
+    } else if ("java.lang.String".equals(nameType) || "string".equals(nameType)) {
+      targetObj = source;
+    } else if ("java.lang.Float".equals(nameType) || "float".equals(nameType)) {
+      targetObj = Float.valueOf(source);
+    } else if ("java.lang.Double".equals(nameType) || "double".equals(nameType)) {
+      targetObj = Double.valueOf(source);
+    } else if ("java.lang.Boolean".equals(nameType) || "boolean".equals(nameType)) {
+      targetObj = Boolean.valueOf(source);
+    } else if ("java.lang.Long".equals(nameType) || "long".equals(nameType)) {
+      targetObj = Long.valueOf(source);
+    } else if ("java.lang.Short".equals(nameType) || "short".equals(nameType)) {
+      targetObj = Short.valueOf(source);
+    } else if ("java.lang.Character".equals(nameType) || "char".equals(nameType)) {
+      targetObj = source.charAt(1);
+    }else if ("java.util.Date".equals(nameType)) {
+      targetObj = new Date(source);
+    }
+
+    return targetObj;
+  }
+
+
+  /**
+   * 根据类的全路径获取class
+   * @param fullPath
+   *          :类的全路径
+   * @return :class
+   */
+  public static Class fullPath2Class(String fullPath) {
+    Class cl = null;
+    try {
+      ClassLoader loader = ClassLoader.getSystemClassLoader();
+      cl = loader.loadClass(fullPath);
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+    }
+    return cl;
+  }
+
+    private static Object doSpecial(Object value, Class valueCla){
+        //TODO 针对sql脚本的类型和实体entity的类型不一致做的特殊处理(有待优化)
+        if(valueCla.equals(Boolean.class)&&value.getClass().equals(Integer.class)){
+            value = typeConversion(Boolean.class,value.toString());
+        }
+        return value;
+    }
+}
diff --git a/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java
new file mode 100644
index 0000000..d348d91
--- /dev/null
+++ b/common/utils/src/main/java/com/supwisdom/institute/backend/common/util/UUIDUtils.java
@@ -0,0 +1,87 @@
+package com.supwisdom.institute.backend.common.util;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class UUIDUtils {
+
+  private static boolean IS_THREADLOCALRANDOM_AVAILABLE = false;
+  private static Random random;
+  private static final long leastSigBits;
+  private static final ReentrantLock lock = new ReentrantLock();
+  private static long lastTime;
+
+  static {
+    try {
+      IS_THREADLOCALRANDOM_AVAILABLE = null != UUIDUtils.class.getClassLoader().loadClass(
+          "java.util.concurrent.ThreadLocalRandom");
+    } catch (ClassNotFoundException e) {
+    }
+
+    byte[] seed = new SecureRandom().generateSeed(8);
+    leastSigBits = new BigInteger(seed).longValue();
+    if (!IS_THREADLOCALRANDOM_AVAILABLE) {
+      random = new Random(leastSigBits);
+    }
+  }
+
+  private UUIDUtils() {}
+
+  /**
+   * 生成32位随机码
+   * @return
+   */
+  public static String random() {
+    byte[] randomBytes = new byte[16];
+    if (IS_THREADLOCALRANDOM_AVAILABLE) {
+      java.util.concurrent.ThreadLocalRandom.current().nextBytes(randomBytes);
+    } else {
+      random.nextBytes(randomBytes);
+    }
+
+    long mostSigBits = 0;
+    for (int i = 0; i < 8; i++) {
+      mostSigBits = (mostSigBits << 8) | (randomBytes[i] & 0xff);
+    }
+    long leastSigBits = 0;
+    for (int i = 8; i < 16; i++) {
+      leastSigBits = (leastSigBits << 8) | (randomBytes[i] & 0xff);
+    }
+
+    return new UUID(mostSigBits, leastSigBits).toString().replaceAll("-", "");
+  }
+
+  /**
+   * 生成32位随机码
+   * @return
+   */
+  public static String create() {
+    long timeMillis = (System.currentTimeMillis() * 10000) + 0x01B21DD213814000L;
+
+    lock.lock();
+    try {
+      if (timeMillis > lastTime) {
+        lastTime = timeMillis;
+      } else {
+        timeMillis = ++lastTime;
+      }
+    } finally {
+      lock.unlock();
+    }
+
+    long mostSigBits = timeMillis << 32;
+    mostSigBits |= (timeMillis & 0xFFFF00000000L) >> 16;
+    mostSigBits |= 0x1000 | ((timeMillis >> 48) & 0x0FFF); 
+    return new UUID(mostSigBits, leastSigBits).toString().replaceAll("-", "");
+    
+  }
+  
+  public static void main(String[] args){
+    System.out.println(random());
+    System.out.println(create());
+  }
+
+}