diff --git a/config/application-local.yml b/config/application-local.yml
index 8de3de0..621bc04 100644
--- a/config/application-local.yml
+++ b/config/application-local.yml
@@ -66,7 +66,7 @@ mybatis :
mapper-locations : classpath*:mappers/*.xml
type-aliases-package: com.cmhi.gds.pojo.entry
configuration :
- default-enum-type-handler: com.cmhi.cf.common.CommonEnumHandler
+ default-enum-type-handler: com.cf.cs.database.common.DataBaseEnumHandler
mybatis-flex:
global-config:
diff --git a/cs-base/pom.xml b/cs-base/pom.xml
index 0a3bc83..84b7d63 100644
--- a/cs-base/pom.xml
+++ b/cs-base/pom.xml
@@ -27,7 +27,16 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+ 3.1.8
+
com.houkunlin
system-dict-starter
@@ -40,7 +49,6 @@
23.0.0
-
diff --git a/cs-base/src/main/java/com/cf/cs/base/annotation/OperationLogAnnotation.java b/cs-base/src/main/java/com/cf/cs/base/annotation/OperationLogAnnotation.java
new file mode 100644
index 0000000..6a3951e
--- /dev/null
+++ b/cs-base/src/main/java/com/cf/cs/base/annotation/OperationLogAnnotation.java
@@ -0,0 +1,38 @@
+package com.cf.cs.base.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;
+
+/**
+ * The interface Operation log annotation.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD}) // 注解放置的目标位置,PARAMETER: 可用在参数上 METHOD:可用在方法级别上
+@Retention(RetentionPolicy.RUNTIME) // 指明修饰的注解的生存周期 RUNTIME:运行级别保留
+@Documented
+public @interface OperationLogAnnotation {
+ /**
+ * Operation module string.
+ *
+ * @return the string
+ */
+ String OperationModule() default ""; // 操作模块
+
+ /**
+ * Operation type string.
+ *
+ * @return the string
+ */
+ String OperationType() default ""; // 操作类型
+
+ /**
+ * Operation desc string.
+ *
+ * @return the string
+ */
+ String OperationDesc() default ""; // 操作说明
+}
diff --git a/cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java b/cs-base/src/main/java/com/cf/cs/base/config/CacheConfigure.java
similarity index 98%
rename from cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java
rename to cs-base/src/main/java/com/cf/cs/base/config/CacheConfigure.java
index e5ed27d..6f251d1 100644
--- a/cs-web/src/main/java/com/cf/cs/web/configure/CacheConfigure.java
+++ b/cs-base/src/main/java/com/cf/cs/base/config/CacheConfigure.java
@@ -1,4 +1,4 @@
-package com.cf.cs.web.configure;
+package com.cf.cs.base.config;
import com.cf.cs.base.common.CachePool;
import com.github.benmanes.caffeine.cache.Caffeine;
diff --git a/cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java b/cs-base/src/main/java/com/cf/cs/base/config/CommonConfigure.java
similarity index 98%
rename from cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java
rename to cs-base/src/main/java/com/cf/cs/base/config/CommonConfigure.java
index 14f5c2e..319a0e9 100644
--- a/cs-web/src/main/java/com/cf/cs/web/configure/CommonConfigure.java
+++ b/cs-base/src/main/java/com/cf/cs/base/config/CommonConfigure.java
@@ -1,4 +1,4 @@
-package com.cf.cs.web.configure;
+package com.cf.cs.base.config;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
diff --git a/cs-base/src/main/java/com/cf/cs/base/misc/ApiContextUtils.java b/cs-base/src/main/java/com/cf/cs/base/misc/ApiContextUtils.java
new file mode 100644
index 0000000..db16bc4
--- /dev/null
+++ b/cs-base/src/main/java/com/cf/cs/base/misc/ApiContextUtils.java
@@ -0,0 +1,62 @@
+package com.cf.cs.base.misc;
+
+
+import com.cf.cs.base.pojo.po.ApiContext;
+
+/**
+ * The type Api context utils.
+ *
+ * @author xajhuang @163.com
+ */
+public class ApiContextUtils {
+ private static final ThreadLocal API_CONTEXT = new ThreadLocal<>();
+
+ /**
+ * Get api context.
+ *
+ * @return the api context
+ */
+ public static ApiContext get() {
+ ApiContext context = API_CONTEXT.get();
+ if (context == null) {
+ context = new ApiContext();
+ API_CONTEXT.set(context);
+ }
+ return context;
+ }
+
+ /**
+ * Sets request info.
+ *
+ * @param reqBody the req body
+ * @param reqTime the req time
+ */
+ public static void setRequestInfo(String reqBody, Long reqTime) {
+ ApiContext context = get();
+ context.setRequestBody(reqBody);
+ context.setRequestTime(reqTime);
+ }
+
+ /**
+ * Sets jwt user info.
+ *
+ * @param jwt the jwt
+ * @param username the username
+ * @param uid the uid
+ * @param id the id
+ */
+ public static void setJwtUserInfo(String jwt, String username, String uid, Long id) {
+ ApiContext context = get();
+ context.setJwt(jwt);
+ context.setUsername(username);
+ context.setUid(uid);
+ context.setId(id);
+ }
+
+ /**
+ * Clear.
+ */
+ public static void clear() {
+ API_CONTEXT.remove();
+ }
+}
diff --git a/cs-base/src/main/java/com/cf/cs/base/pojo/po/ApiContext.java b/cs-base/src/main/java/com/cf/cs/base/pojo/po/ApiContext.java
new file mode 100644
index 0000000..0b03dca
--- /dev/null
+++ b/cs-base/src/main/java/com/cf/cs/base/pojo/po/ApiContext.java
@@ -0,0 +1,24 @@
+package com.cf.cs.base.pojo.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The type Api context.
+ *
+ * @author xajhuang @163.com
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ApiContext {
+ private String requestBody;
+ private Long requestTime;
+ private String jwt;
+ private String username;
+ private String uid;
+ private Long id;
+}
diff --git a/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/DecryptionProtocol.java b/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/DecryptionProtocol.java
new file mode 100644
index 0000000..7e07df9
--- /dev/null
+++ b/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/DecryptionProtocol.java
@@ -0,0 +1,16 @@
+package com.cf.cs.crypto.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The interface Decryption protocol.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DecryptionProtocol {
+}
diff --git a/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/EncryptionProtocol.java b/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/EncryptionProtocol.java
new file mode 100644
index 0000000..e7e9e2e
--- /dev/null
+++ b/cs-crypto/src/main/java/com/cf/cs/crypto/annotation/EncryptionProtocol.java
@@ -0,0 +1,16 @@
+package com.cf.cs.crypto.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The interface Encryption protocol.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptionProtocol {
+}
diff --git a/cs-database/pom.xml b/cs-database/pom.xml
new file mode 100644
index 0000000..72929d7
--- /dev/null
+++ b/cs-database/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+
+ com.cf.cs
+ IntegrateService
+ 0.0.1-dev
+
+
+ cs-database
+ cs-database
+ cs-database
+ jar
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 3.0.3
+
+
+ org.springframework.security
+ spring-security-core
+ 6.2.2
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.zaxxer
+ HikariCP
+
+
+ com.mybatis-flex
+ mybatis-flex-spring-boot3-starter
+ 1.7.8
+
+
+ com.mybatis-flex
+ mybatis-flex-processor
+ 1.7.8
+ provided
+
+
+ com.jayway.jsonpath
+ json-path
+ 2.9.0
+
+
+
+ com.cf.cs
+ cs-base
+ ${cs-package.version}
+ compile
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/CsDatabaseApplication.java b/cs-database/src/main/java/com/cf/cs/database/CsDatabaseApplication.java
new file mode 100644
index 0000000..09a38e1
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/CsDatabaseApplication.java
@@ -0,0 +1,23 @@
+package com.cf.cs.database;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type Cs database application.
+ *
+ * @author xajhuang @163.com
+ */
+@SpringBootApplication
+public class CsDatabaseApplication {
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(CsDatabaseApplication.class, args);
+ }
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/common/DataBaseEnumHandler.java b/cs-database/src/main/java/com/cf/cs/database/common/DataBaseEnumHandler.java
new file mode 100644
index 0000000..8cf96b8
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/common/DataBaseEnumHandler.java
@@ -0,0 +1,81 @@
+package com.cf.cs.database.common;
+
+import com.cf.cs.base.common.BaseEnum;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The type Data base enum handler.
+ *
+ * @param the type parameter
+ * @author xajhuang @163.com
+ */
+public class DataBaseEnumHandler extends BaseTypeHandler {
+ private final Class enumType;
+ private final List enums;
+
+ /**
+ * Instantiates a new Data base enum handler.
+ *
+ * @param type the type
+ */
+ public DataBaseEnumHandler(Class type) {
+ if (type == null) {
+ throw new IllegalArgumentException("Type argument cannot be null");
+ }
+
+ this.enumType = type;
+ this.enums = Arrays.asList(type.getEnumConstants());
+ }
+
+ @Override
+ public void setNonNullParameter(PreparedStatement preparedStatement, int i, E e, JdbcType jdbcType) throws SQLException {
+ preparedStatement.setInt(i, e.getValue());
+ }
+
+ @Override
+ public E getNullableResult(ResultSet resultSet, String s) throws SQLException {
+ if (resultSet.getObject(s) == null) {
+ return null;
+ }
+
+ int val = resultSet.getInt(s);
+ return locateEnumStatus(val);
+ }
+
+ @Override
+ public E getNullableResult(ResultSet resultSet, int index) throws SQLException {
+ if (resultSet.getObject(index) == null) {
+ return null;
+ }
+
+ int val = resultSet.getInt(index);
+ return locateEnumStatus(val);
+ }
+
+ @Override
+ public E getNullableResult(CallableStatement callableStatement, int index) throws SQLException {
+ if (callableStatement.getObject(index) == null) {
+ return null;
+ }
+
+ int val = callableStatement.getInt(index);
+ return locateEnumStatus(val);
+ }
+
+ private E locateEnumStatus(int index) {
+ for (E e : enums) {
+ if (e.getValue() == index) {
+ return e;
+ }
+ }
+ throw new IllegalArgumentException(enumType.getName() + " unknown enumerated type index:" + index);
+ }
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/config/MybatisFlexConfigure.java b/cs-database/src/main/java/com/cf/cs/database/config/MybatisFlexConfigure.java
new file mode 100644
index 0000000..e3d405d
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/config/MybatisFlexConfigure.java
@@ -0,0 +1,40 @@
+package com.cf.cs.database.config;
+
+import com.cf.cs.base.config.CommonConfigure;
+import com.mybatisflex.core.audit.AuditManager;
+import com.mybatisflex.core.audit.ConsoleMessageCollector;
+import com.mybatisflex.core.audit.MessageCollector;
+import com.mybatisflex.core.keygen.KeyGeneratorFactory;
+import com.mybatisflex.core.logicdelete.LogicDeleteProcessor;
+import com.mybatisflex.core.logicdelete.impl.DateTimeLogicDeleteProcessor;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@MapperScan(value = {"com.cf.cs.database.mapper"})
+public class MybatisFlexConfigure {
+ @Resource
+ private CommonConfigure configure;
+
+ @PostConstruct
+ private void initGlobalValue() {
+ KeyGeneratorFactory.register("UUID", new UuidKeyGenerator());
+
+ if (configure.isShowSqlCommand()) {
+ //开启审计功能
+ AuditManager.setAuditEnable(true);
+
+ //设置 SQL 审计收集器
+ MessageCollector collector = new ConsoleMessageCollector();
+ AuditManager.setMessageCollector(collector);
+ }
+ }
+
+ @Bean
+ public LogicDeleteProcessor logicDeleteProcessor(){
+ return new DateTimeLogicDeleteProcessor();
+ }
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/config/UuidKeyGenerator.java b/cs-database/src/main/java/com/cf/cs/database/config/UuidKeyGenerator.java
new file mode 100644
index 0000000..d221bae
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/config/UuidKeyGenerator.java
@@ -0,0 +1,14 @@
+package com.cf.cs.database.config;
+
+import com.mybatisflex.core.keygen.IKeyGenerator;
+
+import java.util.UUID;
+
+public class UuidKeyGenerator implements IKeyGenerator {
+ public static final String COMMON_UUID = "UUID";
+
+ @Override
+ public Object generate(Object entity, String keyColumn) {
+ return UUID.randomUUID().toString();
+ }
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/DictDataMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/DictDataMapper.java
new file mode 100644
index 0000000..cb0f0f3
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/DictDataMapper.java
@@ -0,0 +1,17 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.DictData;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 字典数据表 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface DictDataMapper extends BaseMapper {
+
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/DictTypeMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/DictTypeMapper.java
new file mode 100644
index 0000000..c1e3ad1
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/DictTypeMapper.java
@@ -0,0 +1,17 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.DictType;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 字典类型表 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface DictTypeMapper extends BaseMapper {
+
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/OperationLogMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/OperationLogMapper.java
new file mode 100644
index 0000000..a531722
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/OperationLogMapper.java
@@ -0,0 +1,17 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.OperationLog;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 系统操作日志 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface OperationLogMapper extends BaseMapper {
+
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceDataMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceDataMapper.java
new file mode 100644
index 0000000..f356540
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceDataMapper.java
@@ -0,0 +1,15 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.ResourceData;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface ResourceDataMapper extends BaseMapper {
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceTypeMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceTypeMapper.java
new file mode 100644
index 0000000..72546f9
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/ResourceTypeMapper.java
@@ -0,0 +1,17 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.ResourceType;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface ResourceTypeMapper extends BaseMapper {
+
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/RoleMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/RoleMapper.java
new file mode 100644
index 0000000..474b899
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/RoleMapper.java
@@ -0,0 +1,16 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.Role;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 权限 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface RoleMapper extends BaseMapper {
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/RoleResourceMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/RoleResourceMapper.java
new file mode 100644
index 0000000..dcd9eb3
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/RoleResourceMapper.java
@@ -0,0 +1,15 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.RoleResource;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 权限资源 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface RoleResourceMapper extends BaseMapper {
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/UserCredentialMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/UserCredentialMapper.java
new file mode 100644
index 0000000..cba1368
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/UserCredentialMapper.java
@@ -0,0 +1,17 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.UserCredential;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户认证 映射层。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Mapper
+public interface UserCredentialMapper extends BaseMapper {
+
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/mapper/UserMapper.java b/cs-database/src/main/java/com/cf/cs/database/mapper/UserMapper.java
new file mode 100644
index 0000000..a75777f
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/mapper/UserMapper.java
@@ -0,0 +1,27 @@
+package com.cf.cs.database.mapper;
+
+import com.cf.cs.database.pojo.entity.User;
+import com.mybatisflex.core.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 用户表(User)表数据库访问层
+ *
+ * @author makejava
+ * @since 2023-12-19 17:35:25
+ */
+public interface UserMapper extends BaseMapper {
+
+ /**
+ * 批量新增或按主键更新数据(MyBatis原生foreach方法)
+ *
+ * @param entities List 实例对象列表
+ * @return 影响行数
+ * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
+ */
+ int insertOrUpdateBatch(@Param("entities") List entities);
+
+}
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictData.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictData.java
new file mode 100644
index 0000000..3260000
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictData.java
@@ -0,0 +1,121 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+
+/**
+ * 字典数据表 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "字典数据表")
+@Table(value = "sys_dict_data")
+@AllArgsConstructor
+@NoArgsConstructor
+public class DictData {
+
+ /**
+ * 字典编码
+ */
+ @Schema(description = "字典编码")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+
+ /**
+ * 字典排序
+ */
+ @Schema(description = "字典排序")
+ @Column(value = "dict_sort")
+ private Integer dictSort;
+
+ /**
+ * 字典标签
+ */
+ @Schema(description = "字典标签")
+ @Column(value = "dict_label")
+ private String dictLabel;
+
+ /**
+ * 字典键值
+ */
+ @Schema(description = "字典键值")
+ @Column(value = "dict_value")
+ private Integer dictValue;
+
+ /**
+ * 字典类型
+ */
+ @Schema(description = "字典类型")
+ @Column(value = "type_id")
+ private Long typeId;
+
+ /**
+ * 样式属性(其他样式扩展)
+ */
+ @Schema(description = "样式属性(其他样式扩展)")
+ @Column(value = "css_class")
+ private String cssClass;
+
+ /**
+ * 表格回显样式
+ */
+ @Schema(description = "表格回显样式")
+ @Column(value = "list_class")
+ private String listClass;
+
+ /**
+ * 是否默认(Y是 N否)
+ */
+ @Schema(description = "是否默认(Y是 N否)")
+ @Column(value = "is_default")
+ private String isDefault;
+
+ /**
+ * 创建者
+ */
+ @Schema(description = "创建者")
+ @Column(value = "create_by")
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Column(value = "create_time")
+ private Timestamp createTime;
+
+ /**
+ * 更新者
+ */
+ @Schema(description = "更新者")
+ @Column(value = "update_by")
+ private String updateBy;
+
+ /**
+ * 更新时间
+ */
+ @Schema(description = "更新时间")
+ @Column(value = "update_time")
+ private Timestamp updateTime;
+
+ /**
+ * 备注
+ */
+ @Schema(description = "备注")
+ @Column(value = "remark")
+ private String remark;
+
+ @Schema(description = "逻辑删除标记")
+ @Column(value = "delete_time", isLogicDelete = true)
+ private Timestamp deleteTime;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictType.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictType.java
new file mode 100644
index 0000000..b36bee7
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/DictType.java
@@ -0,0 +1,88 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.RelationOneToMany;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+/**
+ * 字典类型表 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "字典类型表")
+@Table(value = "sys_dict_type")
+public class DictType {
+
+ /**
+ * 字典主键
+ */
+ @Schema(description = "字典主键")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+
+ /**
+ * 字典名称
+ */
+ @Schema(description = "字典名称")
+ @Column(value = "dict_name")
+ private String dictName;
+
+ /**
+ * 字典类型
+ */
+ @Schema(description = "字典类型")
+ @Column(value = "dict_type")
+ private String dictType;
+
+ /**
+ * 创建者
+ */
+ @Schema(description = "创建者")
+ @Column(value = "create_by")
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Column(value = "create_time")
+ private Timestamp createTime;
+
+ /**
+ * 更新者
+ */
+ @Schema(description = "更新者")
+ @Column(value = "update_by")
+ private String updateBy;
+
+ /**
+ * 更新时间
+ */
+ @Schema(description = "更新时间")
+ @Column(value = "update_time")
+ private Timestamp updateTime;
+
+ /**
+ * 备注
+ */
+ @Schema(description = "备注")
+ @Column(value = "remark")
+ private String remark;
+
+ @Schema(description = "逻辑删除标记")
+ @Column(value = "delete_time", isLogicDelete = true)
+ private Timestamp deleteTime;
+
+ @RelationOneToMany(selfField = "id", targetField = "typeId", targetTable = "sys_dict_data")
+ @Column(ignore = true)
+ private List dictDataList;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/OperationLog.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/OperationLog.java
new file mode 100644
index 0000000..cc15d0c
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/OperationLog.java
@@ -0,0 +1,138 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.cf.cs.database.config.UuidKeyGenerator;
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+/**
+ * 系统操作日志 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "系统操作日志")
+@Table(value = "sys_operation_log")
+public class OperationLog {
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+
+ @Schema(description = "uid")
+ @Id(keyType = KeyType.Generator, value = UuidKeyGenerator.COMMON_UUID)
+ private String uid;
+
+ /**
+ * 操作模块
+ */
+ @Schema(description = "操作模块")
+ @Column(value = "module")
+ private String module;
+
+ /**
+ * 操作类型
+ */
+ @Schema(description = "操作类型")
+ @Column(value = "operation_type")
+ private String operationType;
+
+ /**
+ * 操作状态
+ */
+ @Schema(description = "操作状态")
+ @Column(value = "operation_status")
+ private String operationStatus;
+
+ /**
+ * 操作说明
+ */
+ @Schema(description = "操作说明")
+ @Column(value = "description")
+ private String description;
+
+ /**
+ * 请求来源 IP 地址
+ */
+ @Schema(description = "请求来源 IP 地址")
+ @Column(value = "request_ip")
+ private String requestIp;
+
+ /**
+ * 请求接口
+ */
+ @Schema(description = "请求接口")
+ @Column(value = "call_function")
+ private String callFunction;
+
+ /**
+ * HTTP 请求类型
+ */
+ @Schema(description = "HTTP 请求类型")
+ @Column(value = "http_method")
+ private String httpMethod;
+
+ /**
+ * 请求URI
+ */
+ @Schema(description = "请求URI")
+ @Column(value = "http_path")
+ private String httpPath;
+
+ /**
+ * 响应时间(ms)
+ */
+ @Schema(description = "响应时间(ms)")
+ @Column(value = "expend_time")
+ private Long expendTime;
+
+ /**
+ * 传输延时(ms)
+ */
+ @Schema(description = "传输延时(ms)")
+ @Column(value = "transmit_delay")
+ private Long transmitDelay;
+
+ /**
+ * 操作用户id
+ */
+ @Schema(description = "操作用户id")
+ @Column(value = "user_id")
+ private Long userId;
+
+ /**
+ * HTTP 请求头所有参数
+ */
+ @Schema(description = "HTTP 请求头所有参数")
+ @Column(value = "request_headers")
+ private String requestHeaders;
+
+ /**
+ * 操作请求参数
+ */
+ @Schema(description = "操作请求参数")
+ @Column(value = "request")
+ private String request;
+
+ /**
+ * 操作返回结果
+ */
+ @Schema(description = "操作返回结果")
+ @Column(value = "result")
+ private String result;
+
+ /**
+ * 操作时间
+ */
+ @Schema(description = "操作时间")
+ @Column(value = "operation_time")
+ private Timestamp operationTime;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceData.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceData.java
new file mode 100644
index 0000000..5fc6ad0
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceData.java
@@ -0,0 +1,62 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.cf.cs.database.config.UuidKeyGenerator;
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.RelationOneToOne;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "$table.comment")
+@Table(value = "rbac_resource_data")
+public class ResourceData {
+
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+
+ @Schema(description = "uid")
+ @Id(keyType = KeyType.Generator, value = UuidKeyGenerator.COMMON_UUID)
+ private String uid;
+
+ /**
+ * 资源URL
+ */
+ @Schema(description = "资源URL")
+ @Column(value = "path")
+ private String path;
+
+ /**
+ * 资源名称
+ */
+ @Schema(description = "资源名称")
+ @Column(value = "name")
+ private String name;
+
+ /**
+ * 资源访问 HTTP 方法 GET/POST/DELETE/...
+ */
+ @Schema(description = "资源访问 HTTP 方法 GET/POST/DELETE/...")
+ @Column(value = "http_method")
+ private String httpMethod;
+
+ @Schema(description = "资源类型")
+ @Column(value = "type_id")
+ private Integer typeId;
+
+ @RelationOneToOne(selfField = "typeId", targetField = "typeId", targetTable = "rbac_resource_type")
+ @Column(ignore = true)
+ private ResourceType resType;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceType.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceType.java
new file mode 100644
index 0000000..e426f2a
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/ResourceType.java
@@ -0,0 +1,35 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "$table.comment")
+@Table(value = "rbac_resource_type")
+public class ResourceType {
+
+ /**
+ * 资源类型:0-->路由,1-->菜单,2-->按钮,...
+ */
+ @Schema(description = "资源类型:0-->路由,1-->菜单,2-->按钮,...")
+ @Id(keyType = KeyType.Auto)
+ private Integer typeId;
+
+ /**
+ * 资源名称
+ */
+ @Schema(description = "资源名称")
+ @Column(value = "name")
+ private String name;
+
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/Role.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/Role.java
new file mode 100644
index 0000000..25e3064
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/Role.java
@@ -0,0 +1,49 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 权限(Role)表实体类
+ *
+ * @author makejava @163.com
+ * @since 2023 -12-19 15:14:43
+ */
+@Data
+@Schema(name = "Role", description = "权限")
+@Table("rbac_role")
+@AllArgsConstructor
+@NoArgsConstructor
+public class Role {
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+ /**
+ * 是否有效
+ */
+ @Schema(description = "是否有效")
+ @Column(value = "available")
+ private Boolean available;
+ /**
+ * 权限描述
+ */
+ @Schema(description = "权限描述")
+ @Column(value = "description")
+ private String description;
+ /**
+ * 权限名称
+ */
+ @Schema(description = "权限名称")
+ @Column(value = "name")
+ private String name;
+}
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/RoleResource.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/RoleResource.java
new file mode 100644
index 0000000..89566ec
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/RoleResource.java
@@ -0,0 +1,46 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.RelationOneToOne;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 权限资源 实体类。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+@Data
+@Schema(name = "权限资源")
+@Table(value = "rbac_role_resource")
+public class RoleResource {
+
+ /**
+ * 权限id
+ */
+ @Schema(description = "权限id")
+ @Id(keyType = KeyType.Auto)
+ private Long roleId;
+
+ /**
+ * 权限资源id
+ */
+ @Schema(description = "权限资源id")
+ @Id(keyType = KeyType.Auto)
+ private Long resourceId;
+
+ /**
+ * 0: deny, 1: allow
+ */
+ @Schema(description = "0: deny, 1: allow")
+ @Column(value = "authorize")
+ private Boolean authorize;
+
+ @RelationOneToOne(selfField = "resourceId", targetField = "id")
+ @Column(ignore = true)
+ private ResourceData resources;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/User.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/User.java
new file mode 100644
index 0000000..3f9d0bb
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/User.java
@@ -0,0 +1,66 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.cf.cs.database.config.UuidKeyGenerator;
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.RelationOneToOne;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+/**
+ * 用户表(User)表实体类
+ *
+ * @author makejava @163.com
+ * @since 2023 -12-19 15:14:43
+ */
+@Data
+@Schema(name = "User", description = "用户表")
+@Table("rbac_user")
+public class User {
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+
+ @Schema(description = "uid")
+ @Id(keyType = KeyType.Generator, value = UuidKeyGenerator.COMMON_UUID)
+ private String uid;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间")
+ @Column(value = "created_time")
+ private Timestamp createdTime;
+ /**
+ * 创建用户
+ */
+ @Schema(description = "创建用户")
+ @Column(value = "gender")
+ private Long gender;
+ /**
+ * 用户名
+ */
+ @Schema(description = "用户名")
+ @Column(value = "username")
+ private String username;
+
+ @Schema(description = "用户权限ID")
+ @Column(value = "role_id")
+ private Long roleId;
+
+ @Schema(description = "逻辑删除标记")
+ @Column(value = "delete_time", isLogicDelete = true)
+ private Timestamp deleteTime;
+
+ @RelationOneToOne(selfField = "id", targetField = "userId")
+ @Column(ignore = true)
+ private UserCredential userCredential;
+}
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/entity/UserCredential.java b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/UserCredential.java
new file mode 100644
index 0000000..cd803f7
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/entity/UserCredential.java
@@ -0,0 +1,75 @@
+package com.cf.cs.database.pojo.entity;
+
+import com.mybatisflex.annotation.Column;
+import com.mybatisflex.annotation.Id;
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.annotation.Table;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+/**
+ * 用户认证(UserCredential)表实体类
+ *
+ * @author makejava @163.com
+ * @since 2023 -12-19 15:14:43
+ */
+@Data
+@Schema(name = "UserCredential", description = "用户认证")
+@Table("rbac_user_credential")
+public class UserCredential {
+ /**
+ * id
+ */
+ @Schema(description = "id")
+ @Id(keyType = KeyType.Auto)
+ private Long id;
+ /**
+ * 用户密码
+ */
+ @Schema(description = "用户密码")
+ @Column(value = "credential")
+ private String credential;
+ /**
+ * 用户标识
+ */
+ @Schema(description = "用户标识")
+ @Column(value = "identifier")
+ private String identifier;
+ /**
+ * 登录类型
+ */
+ @Schema(description = "登录类型")
+ @Column(value = "identity_type")
+ private Integer identityType;
+ /**
+ * 用户id
+ */
+ @Schema(description = "用户id")
+ @Column(value = "user_id")
+ private Long userId;
+ /**
+ * 当前状态(CommonStatus):0-->正常,1-->锁定,2-->禁用,3-->删除
+ */
+ @Schema(description = "当前状态(CommonStatus):0-->正常,1-->锁定,2-->禁用,3-->删除")
+ @Column(value = "state")
+ private Integer state;
+ /**
+ * 密码错误次数
+ */
+ @Schema(description = "密码错误次数")
+ @Column(value = "error_cnt")
+ private Integer errorCnt;
+ /**
+ * 账户锁定时间
+ */
+ @Schema(description = "账户锁定时间")
+ @Column(value = "lock_at")
+ private Timestamp lockAt;
+
+ @Schema(description = "逻辑删除标记")
+ @Column(value = "delete_time", isLogicDelete = true)
+ private Timestamp deleteTime;
+}
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogDetails.java b/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogDetails.java
new file mode 100644
index 0000000..b2b5c64
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogDetails.java
@@ -0,0 +1,31 @@
+package com.cf.cs.database.pojo.po;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The type Operation log details.
+ *
+ * @author xajhuang @163.com
+ */
+@Schema(name = "系统操作日志详细信息")
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class OperationLogDetails {
+ @Schema(description = "id")
+ private Long id;
+
+ @Schema(description = "HTTP 请求头所有参数")
+ private String requestHeaders;
+
+ @Schema(description = "操作请求参数")
+ private String request;
+
+ @Schema(description = "操作返回结果")
+ private String result;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogSummary.java b/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogSummary.java
new file mode 100644
index 0000000..176abff
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/po/OperationLogSummary.java
@@ -0,0 +1,54 @@
+package com.cf.cs.database.pojo.po;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+/**
+ * The type Operation log summary.
+ *
+ * @author xajhuang @163.com
+ */
+@Schema(name = "系统操作日志摘要数据")
+@Data
+public class OperationLogSummary {
+ @Schema(description = "id")
+ private Long id;
+
+ @Schema(description = "操作模块")
+ private String module;
+
+ @Schema(description = "操作类型")
+ private String operationType;
+
+ @Schema(description = "操作状态")
+ private String operationStatus;
+
+ @Schema(description = "操作说明")
+ private String description;
+
+ @Schema(description = "请求来源 IP 地址")
+ private String requestIp;
+
+ @Schema(description = "请求接口")
+ private String callFunction;
+
+ @Schema(description = "HTTP 请求类型")
+ private String httpMethod;
+
+ @Schema(description = "请求URI")
+ private String httpPath;
+
+ @Schema(description = "操作用户id")
+ private Long userId;
+
+ @Schema(description = "响应时间(ms)")
+ private Long expendTime;
+
+ @Schema(description = "传输延时(ms)")
+ private Long transmitDelay;
+
+ @Schema(description = "操作时间")
+ private Timestamp operationTime;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/po/PageResults.java b/cs-database/src/main/java/com/cf/cs/database/pojo/po/PageResults.java
new file mode 100644
index 0000000..034ac81
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/po/PageResults.java
@@ -0,0 +1,22 @@
+package com.cf.cs.database.pojo.po;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonPropertyOrder({"pageNumber", "pageSize", "totalPage", "totalRow", "items"})
+public class PageResults {
+ private List items;
+ private long pageNumber;
+ private long pageSize;
+ private long totalPage;
+ private long totalRow;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/po/ResPermInfo.java b/cs-database/src/main/java/com/cf/cs/database/pojo/po/ResPermInfo.java
new file mode 100644
index 0000000..bfca66c
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/po/ResPermInfo.java
@@ -0,0 +1,34 @@
+package com.cf.cs.database.pojo.po;
+
+import com.houkunlin.system.dict.starter.json.DictText;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(name = "资源权限信息")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResPermInfo {
+ @Schema(description = "资源id")
+ private Long id;
+
+ @Schema(description = "资源路径")
+ private String path;
+
+ @Schema(description = "资源名称")
+ private String name;
+
+ @Schema(description = "资源 HTTP 请求类型")
+ private String httpMethod;
+
+ @Schema(description = "资源类型 ID")
+ @DictText(value = "sys_res_type", fieldName = "resTypeName")
+ private Integer resTypeId;
+
+ @Schema(description = "是否具有访问权限")
+ private Boolean enable;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/pojo/po/UserInfo.java b/cs-database/src/main/java/com/cf/cs/database/pojo/po/UserInfo.java
new file mode 100644
index 0000000..cb122b4
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/pojo/po/UserInfo.java
@@ -0,0 +1,38 @@
+package com.cf.cs.database.pojo.po;
+
+import com.houkunlin.system.dict.starter.json.DictText;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+/**
+ * The type User info.
+ *
+ * @author xajhuang @163.com
+ */
+@Schema(name = "用户信息")
+@Data
+@Builder
+public class UserInfo {
+ @Schema(description = "用户uid")
+ private String uid;
+
+ @Schema(description = "创建时间")
+ private Timestamp createdTime;
+
+ @Schema(description = "创建用户")
+ private Long gender;
+
+ @Schema(description = "用户名")
+ private String username;
+
+ @Schema(description = "用户组ID")
+ @DictText(value = "sys_role_group", fieldName = "roleIdName")
+ private Long roleId;
+
+ @Schema(description = "当前状态: 0-->正常,1-->锁定,2-->禁用,3-->删除")
+ @DictText(value = "CommonStatus", fieldName = "userStatusName")
+ private Integer userStatus;
+}
diff --git a/cs-database/src/main/java/com/cf/cs/database/service/OperationLogDataBaseService.java b/cs-database/src/main/java/com/cf/cs/database/service/OperationLogDataBaseService.java
new file mode 100644
index 0000000..9ebc6fc
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/service/OperationLogDataBaseService.java
@@ -0,0 +1,79 @@
+package com.cf.cs.database.service;
+
+import com.cf.cs.base.annotation.OperationLogAnnotation;
+import com.cf.cs.base.common.ErrorCode;
+import com.cf.cs.database.pojo.entity.OperationLog;
+import com.cf.cs.database.pojo.po.OperationLogDetails;
+import com.cf.cs.database.pojo.po.OperationLogSummary;
+import com.mybatisflex.core.paginate.Page;
+import com.mybatisflex.core.service.IService;
+import jakarta.servlet.http.HttpServletRequest;
+
+import java.util.List;
+
+/**
+ * 系统操作日志 服务层。
+ *
+ * @author mybatis -flex-helper automatic generation
+ * @since 1.0
+ */
+public interface OperationLogDataBaseService extends IService {
+ /**
+ * System operation log.
+ *
+ * @param call the call
+ * @param request the request
+ * @param result the result
+ * @param annotation the annotation
+ * @param errorCode the error code
+ */
+ void systemOperationLog(String call, HttpServletRequest request, Object result, OperationLogAnnotation annotation, ErrorCode errorCode);
+
+ /**
+ * System operation log.
+ *
+ * @param call the call
+ * @param request the request
+ * @param result the result
+ * @param module the module
+ * @param optType the opt type
+ * @param desc the desc
+ * @param errorCode the error code
+ */
+ void systemOperationLog(String call,
+ HttpServletRequest request,
+ Object result,
+ String module,
+ String optType,
+ String desc,
+ ErrorCode errorCode);
+
+ /**
+ * Security operation log.
+ *
+ * @param request the request
+ * @param result the result
+ * @param errorCode the error code
+ * @param readme the readme
+ */
+ void securityOperationLog(HttpServletRequest request, Object result, ErrorCode errorCode, String readme);
+
+ /**
+ * Gets system operation summary.
+ *
+ * @param pageNumber the page number
+ * @param pageSize the page size
+ * @param totalSize the total size
+ * @param userName the user name
+ * @return the system operation summary
+ */
+ Page getSystemOperationSummary(Long pageNumber, Long pageSize, Long totalSize, List userName);
+
+ /**
+ * Gets system operation details.
+ *
+ * @param operationId the operation id
+ * @return the system operation details
+ */
+ List getSystemOperationDetails(List operationId);
+}
\ No newline at end of file
diff --git a/cs-database/src/main/java/com/cf/cs/database/service/UserDataBaseService.java b/cs-database/src/main/java/com/cf/cs/database/service/UserDataBaseService.java
new file mode 100644
index 0000000..6b02d86
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/service/UserDataBaseService.java
@@ -0,0 +1,39 @@
+package com.cf.cs.database.service;
+
+
+import com.cf.cs.database.pojo.entity.User;
+import com.cf.cs.database.pojo.po.PageResults;
+import com.cf.cs.database.pojo.po.ResPermInfo;
+import com.cf.cs.database.pojo.po.UserInfo;
+import com.mybatisflex.core.service.IService;
+
+import java.util.List;
+
+/**
+ * 用户表(User)表服务接口
+ *
+ * @author makejava
+ * @since 2023-12-19 17:35:25
+ */
+public interface UserDataBaseService extends IService {
+ User getAccountUserByName(String username);
+
+ User getAccountUserByUid(String uid);
+
+ User getAccountUserById(Long userId);
+
+ UserInfo getUserInfoById(Long userId);
+
+ UserInfo getUserInfoByUid(String uid);
+
+ UserInfo getUserInfoByUsername(String username);
+
+ UserInfo getCurrentUserInfo();
+
+ PageResults getAllUserInfo(Long pageNumber, Long pageSize, Long totalSize);
+
+ List getCurrentUserResourcePerm();
+
+ List getUserResourcePerm(Long userId);
+}
+
diff --git a/cs-database/src/main/java/com/cf/cs/database/service/impl/OperationLogDataBaseServiceImpl.java b/cs-database/src/main/java/com/cf/cs/database/service/impl/OperationLogDataBaseServiceImpl.java
new file mode 100644
index 0000000..4dff82b
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/service/impl/OperationLogDataBaseServiceImpl.java
@@ -0,0 +1,252 @@
+package com.cf.cs.database.service.impl;
+
+import com.cf.cs.base.annotation.OperationLogAnnotation;
+import com.cf.cs.base.common.ErrorCode;
+import com.cf.cs.base.config.CommonConfigure;
+import com.cf.cs.base.exception.CommonErrorCodeException;
+import com.cf.cs.base.misc.ApiContextUtils;
+import com.cf.cs.base.misc.HelperUtils;
+import com.cf.cs.base.pojo.po.ApiContext;
+import com.cf.cs.database.pojo.entity.OperationLog;
+import com.cf.cs.database.mapper.OperationLogMapper;
+import com.cf.cs.database.pojo.po.OperationLogDetails;
+import com.cf.cs.database.pojo.po.OperationLogSummary;
+import com.cf.cs.database.service.OperationLogDataBaseService;
+import com.cf.cs.database.service.UserDataBaseService;
+import com.jayway.jsonpath.JsonPath;
+import com.mybatisflex.core.paginate.Page;
+import com.mybatisflex.core.query.QueryWrapper;
+import com.mybatisflex.spring.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.stereotype.Service;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Optional;
+
+import static com.cf.cs.database.pojo.entity.table.OperationLogTableDef.OPERATION_LOG;
+import static com.cf.cs.database.pojo.entity.table.UserTableDef.USER;
+import static com.mybatisflex.core.query.QueryMethods.distinct;
+import static com.mybatisflex.core.query.QueryMethods.select;
+
+/**
+ * 系统操作日志 服务层实现。
+ *
+ * @author mybatis-flex-helper automatic generation
+ * @since 1.0
+ */
+@Service
+@Slf4j
+public class OperationLogDataBaseServiceImpl extends ServiceImpl implements OperationLogDataBaseService {
+ private final int MAX_DB_STRING = 4090;
+
+ @Resource
+ private ServerProperties serverProperties;
+
+ @Resource
+ private UserDataBaseService userService;
+
+ @Resource
+ private OperationLogMapper operationLogMapper;
+
+ @Override
+ public void systemOperationLog(String call,
+ HttpServletRequest request,
+ Object result,
+ OperationLogAnnotation annotation,
+ ErrorCode errorCode) {
+ if (annotation != null) {
+ systemOperationLog(call, request, result, annotation.OperationModule(), annotation.OperationType(),
+ annotation.OperationDesc(), errorCode);
+ } else {
+ systemOperationLog(call, request, result, "", "", "", errorCode);
+ }
+ }
+
+ @Override
+ public void securityOperationLog(HttpServletRequest request, Object result, ErrorCode errorCode, String readme) {
+ try {
+ ApiContext ctx = ApiContextUtils.get();
+ OperationLog optLog = new OperationLog();
+
+ if (request.getRequestURI().startsWith(CommonConfigure.PROJECT_PREFIX_URL + "/error")) {
+ return;
+ }
+
+ optLog.setOperationStatus(errorCode.getDescription());
+
+ //获取注解操作信息
+ optLog.setModule("系统安全模块");
+ optLog.setOperationType("认证/鉴权");
+ optLog.setDescription(readme);
+ optLog.setUserId(-1L);
+
+ //操作时间
+ optLog.setOperationTime(new Timestamp(System.currentTimeMillis()));
+ // 请求方法
+ optLog.setHttpMethod(request.getMethod());
+ // 请求URL
+ String prefixUrl = Optional.ofNullable(serverProperties.getServlet().getContextPath()).orElse("");
+ String url = request.getRequestURI().replaceFirst("^" + prefixUrl, "");
+ optLog.setHttpPath(url);
+
+ // 仅处理 RESTful 接口
+ if (url.startsWith("/api")) {
+ // 登录接口不包含 Authorization 信息
+ if (url.lastIndexOf("login") != -1) {
+ optLog.setCallFunction("login");
+ optLog.setUserId(ctx.getId() != null ? ctx.getId() : -1L);
+ } else {
+ if (url.lastIndexOf("logout") != -1) {
+ optLog.setCallFunction("logout");
+ }
+
+ if (HelperUtils.stringNotEmptyOrNull(ctx.getJwt())) {
+ optLog.setDescription(ctx.getUsername() + " " + optLog.getDescription());
+ optLog.setUserId(ctx.getId() != null ? ctx.getId() : -1L);
+ }
+ }
+ }
+
+ //操作IP
+ optLog.setRequestIp(HelperUtils.getHttpRequestSrcIp(request));
+ //返回值信息
+ optLog.setResult(HelperUtils.truncateString(HelperUtils.getJson(result), MAX_DB_STRING));
+ // 请求Headers
+ optLog.setRequestHeaders(HelperUtils.truncateString(HelperUtils.getHttpRequestHeaders(request), MAX_DB_STRING));
+ // 响应延时
+ optLog.setExpendTime(System.currentTimeMillis() - ctx.getRequestTime());
+ // 请求信息
+ String reqJson = ctx.getRequestBody();
+ optLog.setRequest(HelperUtils.truncateString(reqJson, MAX_DB_STRING));
+
+ if (HelperUtils.stringNotEmptyOrNull(reqJson)) {
+ // 传输延时
+ Long reqTime = Optional.ofNullable((Long) JsonPath.read(reqJson, "$.timeStamp")).orElse(0L);
+ optLog.setTransmitDelay(ctx.getRequestTime() - reqTime);
+ }
+
+ //保存日志
+ operationLogMapper.insert(optLog, true);
+ log.trace("{}", HelperUtils.getJson(optLog));
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ @Override
+ public Page getSystemOperationSummary(Long pageNumber,
+ Long pageSize,
+ Long totalSize,
+ List userName) {
+ QueryWrapper wrapper;
+
+ ApiContext ctx = ApiContextUtils.get();
+
+ String username = ctx.getUsername();
+ // 当前已经有合法的认证用户
+ if (HelperUtils.stringNotEmptyOrNull(username)) {
+ if (userName != null && !userName.isEmpty()) {
+ List idArray = userName.stream()
+ .filter(k -> userService.getAccountUserByName(k) != null)
+ .map(k -> userService.getAccountUserByName(k).getId())
+ .toList();
+
+ wrapper = new QueryWrapper().select(OPERATION_LOG.ALL_COLUMNS)
+ .from(OPERATION_LOG.as("o"), USER.as("u1"))
+ .where(OPERATION_LOG.USER_ID.eq(USER.ID)
+ .and(USER.ID.in(idArray))
+ .and(USER.ROLE_ID.ge(
+ select(distinct(USER.ROLE_ID)).from(
+ USER.as("u"))
+ .where(USER.ID.eq(
+ ctx.getId())))));
+ } else {
+ wrapper = new QueryWrapper().select(OPERATION_LOG.ALL_COLUMNS)
+ .from(OPERATION_LOG.as("o"), USER.as("u1"))
+ .where(OPERATION_LOG.USER_ID.eq(USER.ID)
+ .and(USER.ROLE_ID.ge(
+ select(distinct(USER.ROLE_ID)).from(
+ USER.as("u"))
+ .where(USER.ID.eq(
+ ctx.getId())))));
+ }
+
+ return operationLogMapper.paginateAs(pageNumber, pageSize, totalSize, wrapper, OperationLogSummary.class);
+ } else {
+ log.error("Current User is not authentication.");
+ throw new CommonErrorCodeException(ErrorCode.ERR_LOGOUT);
+ }
+ }
+
+ @Override
+ public List getSystemOperationDetails(List operationId) {
+ QueryWrapper wrapper = QueryWrapper.create()
+ .from(OPERATION_LOG)
+ .select()
+ .where(OPERATION_LOG.ID.in(operationId));
+ return operationLogMapper.selectListByQueryAs(wrapper, OperationLogDetails.class);
+ }
+
+ @Override
+ public void systemOperationLog(String call,
+ HttpServletRequest request,
+ Object result,
+ String module,
+ String optType,
+ String desc,
+ ErrorCode errorCode) {
+ try {
+ ApiContext ctx = ApiContextUtils.get();
+ OperationLog optLog = new OperationLog();
+
+ if (request.getRequestURI().startsWith(CommonConfigure.PROJECT_PREFIX_URL + "/error")) {
+ return;
+ }
+
+ optLog.setOperationStatus(errorCode.getDescription());
+ optLog.setCallFunction(call);
+ //获取注解操作信息
+ optLog.setModule(module);
+ optLog.setOperationType(optType);
+ optLog.setDescription(desc);
+ //操作时间
+ optLog.setOperationTime(new Timestamp(System.currentTimeMillis()));
+ // 请求方法
+ optLog.setHttpMethod(request.getMethod());
+ // 请求URL
+ String prefixUrl = Optional.ofNullable(serverProperties.getServlet().getContextPath()).orElse("");
+ String url = request.getRequestURI().replaceFirst("^" + prefixUrl, "");
+ optLog.setHttpPath(url);
+
+ //操作用户
+ optLog.setUserId(ctx.getId());
+
+ //操作IP
+ optLog.setRequestIp(HelperUtils.getHttpRequestSrcIp(request));
+ //返回值信息
+ optLog.setResult(HelperUtils.truncateString(HelperUtils.getJson(result), MAX_DB_STRING));
+ // 请求Headers
+ optLog.setRequestHeaders(HelperUtils.truncateString(HelperUtils.getHttpRequestHeaders(request), MAX_DB_STRING));
+ // 请求信息
+ String reqJson = ctx.getRequestBody();
+ optLog.setRequest(HelperUtils.truncateString(reqJson, MAX_DB_STRING));
+
+ // 响应延时
+ optLog.setExpendTime(System.currentTimeMillis() - ctx.getRequestTime());
+ if (HelperUtils.stringNotEmptyOrNull(reqJson)) {
+ // 传输延时
+ Long reqTime = Optional.ofNullable((Long) JsonPath.read(reqJson, "$.timeStamp")).orElse(0L);
+ optLog.setTransmitDelay(ctx.getRequestTime() - reqTime);
+ }
+
+ //保存日志
+ operationLogMapper.insert(optLog, true);
+ log.trace("{}", HelperUtils.getJson(optLog));
+ } catch (Exception ignored) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/cs-database/src/main/java/com/cf/cs/database/service/impl/UserDataBaseServiceImpl.java b/cs-database/src/main/java/com/cf/cs/database/service/impl/UserDataBaseServiceImpl.java
new file mode 100644
index 0000000..c3914aa
--- /dev/null
+++ b/cs-database/src/main/java/com/cf/cs/database/service/impl/UserDataBaseServiceImpl.java
@@ -0,0 +1,306 @@
+package com.cf.cs.database.service.impl;
+
+
+import com.cf.cs.base.common.ErrorCode;
+import com.cf.cs.base.exception.CommonErrorCodeException;
+import com.cf.cs.base.misc.ApiContextUtils;
+import com.cf.cs.base.misc.HelperUtils;
+import com.cf.cs.database.mapper.ResourceDataMapper;
+import com.cf.cs.database.mapper.ResourceTypeMapper;
+import com.cf.cs.database.mapper.RoleMapper;
+import com.cf.cs.database.mapper.RoleResourceMapper;
+import com.cf.cs.database.mapper.UserCredentialMapper;
+import com.cf.cs.database.mapper.UserMapper;
+import com.cf.cs.database.pojo.entity.ResourceData;
+import com.cf.cs.database.pojo.entity.RoleResource;
+import com.cf.cs.database.pojo.entity.User;
+import com.cf.cs.database.pojo.po.PageResults;
+import com.cf.cs.database.pojo.po.ResPermInfo;
+import com.cf.cs.database.pojo.po.UserInfo;
+import com.cf.cs.database.service.UserDataBaseService;
+import com.mybatisflex.core.paginate.Page;
+import com.mybatisflex.core.query.QueryWrapper;
+import com.mybatisflex.spring.service.impl.ServiceImpl;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.cf.cs.database.pojo.entity.table.RoleResourceTableDef.ROLE_RESOURCE;
+import static com.cf.cs.database.pojo.entity.table.UserTableDef.USER;
+
+/**
+ * 用户表(User)表服务实现类
+ *
+ * @author makejava
+ * @since 2023-12-19 17:35:26
+ */
+@Service("userService")
+@Slf4j
+public class UserDataBaseServiceImpl extends ServiceImpl implements UserDataBaseService {
+ private final Map resourceType = new HashMap<>();
+
+ @Resource
+ private ResourceDataMapper resDataMapper;
+
+ @Resource
+ private RoleResourceMapper roleResourceMapper;
+
+ @Resource
+ private RoleMapper roleMapper;
+
+ @Resource
+ private UserMapper userMapper;
+
+ @Resource
+ private UserCredentialMapper userCredentialMapper;
+
+ @Resource
+ private ResourceTypeMapper resourceTypeMapper;
+
+ private User queryUser(QueryWrapper wrapper) {
+ return this.getMapper().selectOneWithRelationsByQuery(wrapper);
+ }
+
+ @Override
+ public User getAccountUserByName(String username) {
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.USERNAME.eq(username));
+ return (username == null || username.isEmpty()) ? null : queryUser(wrapper);
+ }
+
+ @Override
+ public User getAccountUserByUid(String uid) {
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.UID.eq(uid));
+ return (!HelperUtils.stringNotEmptyOrNull(uid)) ? null : queryUser(wrapper);
+ }
+
+ @Override
+ public User getAccountUserById(Long userId) {
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.ID.eq(userId));
+ return (userId == null) ? null : queryUser(wrapper);
+ }
+
+ @Override
+ public UserInfo getUserInfoById(Long userId) {
+ // 获取用户信息
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.ID.eq(userId));
+ User user = queryUser(wrapper);
+
+ if (user == null) {
+ log.error("Current User is not exists.");
+ throw new CommonErrorCodeException(ErrorCode.ERR_USERNOTFOUND);
+ }
+
+ // 低优先级用户不能获取高优先级用户信息
+ if (verifyCurrentExceedPermission(user)) {
+ throw new CommonErrorCodeException(ErrorCode.ERR_PERMISSION);
+ }
+
+ return UserInfo.builder().uid(user.getUid()).createdTime(user.getCreatedTime()).gender(user.getGender()).username(
+ user.getUsername()).roleId(user.getRoleId()).userStatus(user.getUserCredential().getState()).build();
+ }
+
+ @Override
+ public UserInfo getUserInfoByUid(String uid) {
+ // 获取用户信息
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.UID.eq(uid));
+ User user = queryUser(wrapper);
+
+ if (user == null) {
+ log.error("Current User is not exists.");
+ throw new CommonErrorCodeException(ErrorCode.ERR_USERNOTFOUND);
+ }
+
+ // 低优先级用户不能获取高优先级用户信息
+ if (verifyCurrentExceedPermission(user)) {
+ throw new CommonErrorCodeException(ErrorCode.ERR_PERMISSION);
+ }
+
+ return UserInfo.builder().uid(user.getUid()).createdTime(user.getCreatedTime()).gender(user.getGender()).username(
+ user.getUsername()).roleId(user.getRoleId()).userStatus(user.getUserCredential().getState()).build();
+ }
+
+ @Override
+ public UserInfo getUserInfoByUsername(String username) {
+ // 获取用户信息
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.USERNAME.eq(username));
+ User user = queryUser(wrapper);
+
+ if (user == null) {
+ log.error("Current User({}) is not exists.", username);
+ throw new CommonErrorCodeException(ErrorCode.ERR_USERNOTFOUND);
+ }
+
+ return getUserInfoById(user.getId());
+ }
+
+ @Override
+ public UserInfo getCurrentUserInfo() {
+ String username = ApiContextUtils.get().getUsername();
+ User user = getAccountUserByName(username);
+
+ if (user == null) {
+ log.error("Current login user not found: [{}]", username);
+ throw new CommonErrorCodeException(ErrorCode.ERR_TOKENNOTFOUND);
+ }
+
+ return UserInfo.builder().uid(user.getUid()).createdTime(user.getCreatedTime()).gender(user.getGender()).username(
+ user.getUsername()).roleId(user.getRoleId()).userStatus(user.getUserCredential().getState()).build();
+ }
+
+ @Override
+ public PageResults getAllUserInfo(Long pageNumber, Long pageSize, Long totalSize) {
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select();
+ List ui = new ArrayList<>();
+
+ Page user = userMapper.paginateWithRelations(pageNumber, pageSize, totalSize, wrapper);
+
+ user.getRecords().forEach(k -> ui.add(UserInfo.builder()
+ .uid(k.getUid())
+ .createdTime(k.getCreatedTime())
+ .gender(k.getGender())
+ .username(k.getUsername())
+ .roleId(k.getRoleId())
+ .userStatus(k.getUserCredential().getState())
+ .build()));
+
+ return PageResults.builder()
+ .items(ui)
+ .pageNumber(user.getPageNumber())
+ .pageSize(user.getPageSize())
+ .totalPage(user.getTotalPage())
+ .totalRow(user.getTotalRow())
+ .build();
+ }
+
+ @Override
+ public List getCurrentUserResourcePerm() {
+ List res;
+
+ String username = ApiContextUtils.get().getUsername();
+ User user = getAccountUserByName(username);
+
+ if (user == null) {
+ log.error("Current login user not found: [{}]", username);
+ throw new CommonErrorCodeException(ErrorCode.ERR_TOKENNOTFOUND);
+ }
+
+ List result = new ArrayList<>();
+ QueryWrapper wrapper = QueryWrapper.create().from(ROLE_RESOURCE).select().where(
+ ROLE_RESOURCE.ROLE_ID.eq(user.getId()));
+ List roleRes = roleResourceMapper.selectListWithRelationsByQuery(wrapper);
+
+ roleRes.forEach(k -> result.add(ResPermInfo.builder()
+ .id(k.getResourceId())
+ .name(k.getResources().getName())
+ .path(k.getResources().getPath())
+ //.resType(k.getResources().getResType().getTypeId())
+ .resTypeId(k.getResources().getResType().getTypeId())
+ .httpMethod(k.getResources().getHttpMethod())
+ .enable(k.getAuthorize())
+ .build()));
+
+ res = resDataMapper.selectAllWithRelations().stream().filter(
+ k -> roleRes.stream().noneMatch(m -> m.getResources().getPath().equals(k.getPath()))).toList();
+
+ res.forEach(k -> result.add(ResPermInfo.builder()
+ .id(k.getId())
+ .name(k.getName())
+ .path(k.getPath())
+ .httpMethod(k.getHttpMethod())
+ .resTypeId(k.getResType().getTypeId())
+ .enable(false)
+ .build()));
+
+ return result;
+ }
+
+ @Override
+ public List getUserResourcePerm(Long userId) {
+ List res;
+
+ // 获取用户信息
+ QueryWrapper wrapper = QueryWrapper.create().from(USER).select().where(USER.ID.eq(userId));
+ User user = queryUser(wrapper);
+
+ if (user == null) {
+ log.error("Current User is not exists.");
+ throw new CommonErrorCodeException(ErrorCode.ERR_USERNOTFOUND);
+ }
+
+ // 低优先级用户不能获取高优先级用户信息
+ if (verifyCurrentExceedPermission(user)) {
+ throw new CommonErrorCodeException(ErrorCode.ERR_PERMISSION);
+ }
+
+ List result = new ArrayList<>();
+ wrapper = QueryWrapper.create().from(ROLE_RESOURCE).select().where(ROLE_RESOURCE.ROLE_ID.eq(user.getId()));
+ List roleRes = roleResourceMapper.selectListWithRelationsByQuery(wrapper);
+
+ roleRes.forEach(k -> result.add(ResPermInfo.builder()
+ .id(k.getResourceId())
+ .name(k.getResources().getName())
+ .path(k.getResources().getPath())
+ .httpMethod(k.getResources().getHttpMethod())
+ //.resType(k.getResources().getResType().getTypeId())
+ .resTypeId(k.getResources().getResType().getTypeId())
+ .enable(k.getAuthorize())
+ .build()));
+
+ res = resDataMapper.selectAllWithRelations().stream().filter(
+ k -> roleRes.stream().noneMatch(m -> m.getResources().getPath().equals(k.getPath()))).toList();
+
+ res.forEach(k -> result.add(ResPermInfo.builder()
+ .id(k.getId())
+ .name(k.getName())
+ .path(k.getPath())
+ .resTypeId(k.getResType().getTypeId())
+ .httpMethod(k.getHttpMethod())
+ .enable(false)
+ .build()));
+
+ return result;
+ }
+
+ private boolean verifyCurrentExceedPermission(User accessUser) {
+ String loginUsername = ApiContextUtils.get().getUsername();
+
+ if (!HelperUtils.stringNotEmptyOrNull(loginUsername)) {
+ log.error("Current login user not found: [{}]", accessUser.getUsername());
+ throw new CommonErrorCodeException(ErrorCode.ERR_TOKENNOTFOUND);
+ }
+
+ User logUser = getAccountUserByName(loginUsername);
+
+ if (logUser == null) {
+ log.error("Current login user not found: [{}]", loginUsername);
+ throw new CommonErrorCodeException(ErrorCode.ERR_TOKENNOTFOUND);
+ }
+
+ // 低优先级用户不能获取高优先级用户信息
+ if (logUser.getId() <= accessUser.getRoleId()) {
+ return false;
+ }
+
+ log.error("Permission check deny: login user{}, request user{}", logUser.getId(), accessUser.getRoleId());
+ return true;
+ }
+
+ @PostConstruct
+ public void init() {
+ // 在组件初始化后执行的逻辑
+ resourceTypeMapper.selectAll().forEach(k -> {
+ if (!resourceType.containsKey(k.getTypeId())) {
+ resourceType.put(k.getTypeId(), k.getName());
+ }
+ });
+ // 可以在这里进行一些初始化操作,如初始化参数、加载数据等
+ }
+}
diff --git a/cs-database/src/main/resources/rbac/clean_database.sql b/cs-database/src/main/resources/rbac/clean_database.sql
new file mode 100644
index 0000000..ed4cc61
--- /dev/null
+++ b/cs-database/src/main/resources/rbac/clean_database.sql
@@ -0,0 +1,15 @@
+SET NAMES utf8mb3;
+SET FOREIGN_KEY_CHECKS = 0;
+
+DROP TABLE IF EXISTS `rbac_role_resource`;
+DROP TABLE IF EXISTS `rbac_role`;
+DROP TABLE IF EXISTS `rbac_user`;
+DROP TABLE IF EXISTS `rbac_user_credential`;
+DROP TABLE IF EXISTS `rbac_resource_data`;
+DROP TABLE IF EXISTS `rbac_resource_type`;
+
+
+DROP TABLE IF EXISTS `sys_operation_log`;
+DROP TABLE IF EXISTS `sys_dict_data`;
+DROP TABLE IF EXISTS `sys_dict_type`;
+SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
diff --git a/cs-database/src/main/resources/rbac/data.sql b/cs-database/src/main/resources/rbac/data.sql
new file mode 100644
index 0000000..b4298bf
--- /dev/null
+++ b/cs-database/src/main/resources/rbac/data.sql
@@ -0,0 +1,212 @@
+-- 关闭外键约束检查
+set foreign_key_checks = 0;
+
+INSERT IGNORE INTO rbac_user (id, uid, username, gender, role_id) VALUES (1, 'e472582b-88b9-4fe8-8ca7-c8e3b0aa2851', 'admin', 0, 1);
+INSERT IGNORE INTO rbac_user (id, uid, username, gender, role_id) VALUES (2, '22adc004-a9f6-4a5d-8be3-ae3629a4ba1b', 'user', 1, 3);
+INSERT IGNORE INTO rbac_user (id, uid, username, gender, role_id) VALUES (3, '44ede496-d538-4a1d-afb9-bc409f752738', 'guest', 0, 4);
+
+INSERT IGNORE INTO rbac_role (id, available, description, name) VALUES (1, true, '超级管理员可以对企业内的所有用户进行管理,请谨慎修改超管权限', 'ADMIN');
+INSERT IGNORE INTO rbac_role (id, available, description, name) VALUES (2, true, '项目开发人员', 'DEVELOPMENT');
+INSERT IGNORE INTO rbac_role (id, available, description, name) VALUES (3, true, '普通的用户', 'USER');
+INSERT IGNORE INTO rbac_role (id, available, description, name) VALUES (4, false, '系统访客,不需要认证,最小权限', 'GUEST');
+
+INSERT IGNORE INTO rbac_user_credential (id, credential, identifier, identity_type, user_id, state, error_cnt) VALUES (1, '$2a$10$5Arh4lqTumXH5b5J0cQ/D.Sc3Fs0wlB1otRm91PTep3q/dxjy0VyC', 'admin', 0, 1, 0, 0);
+INSERT IGNORE INTO rbac_user_credential (id, credential, identifier, identity_type, user_id, state, error_cnt) VALUES (2, '$2a$10$wCwH9D1.ushoN7ywoh0arepzP79vZuyy6LuKBtEVY3quQiQMjQe.q', 'user', 0, 2, 0, 0);
+INSERT IGNORE INTO rbac_user_credential (id, credential, identifier, identity_type, user_id, state, error_cnt) VALUES (3, '$2a$10$IUZ.LdcBLWwmNhNPhy/zSOiDPweRp0kkiVn7I5gULTj9CgRUfhu.q', 'guest', 0, 3, 0, 0);
+
+-- ----------------------------
+-- Records of resource_type
+-- ----------------------------
+INSERT IGNORE INTO rbac_resource_type VALUES(0, '路由');
+INSERT IGNORE INTO rbac_resource_type VALUES(1, '菜单');
+INSERT IGNORE INTO rbac_resource_type VALUES(2, '按钮');
+
+-- ----------------------------
+-- Records of resource
+-- ----------------------------
+INSERT IGNORE INTO rbac_resource_data VALUES (1, '98ca121c-56e7-4aa7-9351-8d9633f768a1', '/api/version', '获取版本信息', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (2, '673f62f0-3ca7-41f1-82d0-8e3d2ac47512', '/api/version', '获取版本信息', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (100, 'f3b718ee-aa58-4b14-b466-1412b6e35c74', '/api/operation/summary', '获取操作日志摘要', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (101, 'acba3926-6e5d-4a80-a957-a045b4e76c7e', '/api/operation/details', '获取操作日志详情', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (200, 'c50d5501-4483-4556-bdb5-1c1cd66c6980', '/api/permission/allRoles', '获取当前所有用户组', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (201, '21374966-ab7f-4d22-82af-6199a6c14616', '/api/permission/resourcePermission', '获取当前用户资源权限', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (202, '86114665-35d8-40b9-86d0-84fdbda4eadc', '/api/permission/resourcePermission', '获取用户资源权限', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (203, '9434daf9-ebb9-48ab-8c4e-ecf8edef9f76', '/api/permission/resource', '注册新资源', 'PUT', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (204, '995e26c0-82df-4751-8b2d-a62b29cd7385', '/api/permission/resource', '注册新资源', 'DELETE', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (300, '58e36be5-f725-4d98-bd7d-8f7377219ed6', '/api/user/userInfo', '获取用户信息', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (301, 'fa2b3740-8672-49d3-9792-25976b767ade', '/api/user/userInfo', '获取用户信息', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (302, '221c8d8e-c47a-4200-88a8-34d374a76d01', '/api/user/register', '注册新用户', 'PUT', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (303, '8adf6875-2be4-459e-9c1d-3bb87114cb08', '/api/user/remove', '删除用户', 'DELETE', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (304, '4c6c859b-2625-45eb-83b8-1426ff96dbe6', '/api/user/userList', '分页获取当前所有用户', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (400, '8ac928d8-5a6a-47c7-8697-0fb9ebd7249d', '/api/dict/enum/allDict', '获取所以枚举字典列表', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (401, '9ecf1662-f891-4829-8d3e-81c42bf22e2a', '/api/dict/enum/dictContent', '获取枚举字典详细内容', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (402, 'C083F441-9624-AF2C-B353-0768F9C0A932', '/api/dict/user/add', '新增用户字典', 'PUT', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (403, '953cea37-cc7a-4e7e-bd86-cb3c14daa8c4', '/api/dict/user/upgrade', '修改用户字典', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (404, '247674fb-759d-4b01-8d35-2c0436d2ed99', '/api/dict/user/delete', '删除用户字典', 'DELETE', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (405, '54b43614-45c6-4672-a1d8-fa8f326d5e53', '/api/dict/user/allDict', '分页获取所有用户字典', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (406, 'e441dbb4-b844-461c-a5f8-07ee3fa658cc', '/api/dict/user/getDictContent', '获取用户字典详细信息', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (407, 'c803571e-ba0d-4f3d-bcc8-76488b1af22a', '/api/dict/user/addDictContent', '新增用户字典详细信息', 'PUT', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (408, '99106f7a-6c4e-4438-ad40-65ed9417d0b4', '/api/dict/user/upgradeDictContent', '更新用户字典详细信息', 'POST', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (409, 'a4c04e8f-d495-46ca-b67e-79cc9a91d623', '/api/dict/user/deleteDictContent', '删除用户字典详细信息', 'DELETE', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (500, '3e7b6439-8d66-4409-84db-16fcbb115215', '/api/systemInfo/osInfo', '获取操作系统信息', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (501, 'a958211f-083e-4a2d-b21d-5442090486d2', '/api/systemInfo/processorInfo', '获取系统处理器信息', 'GET', 0);
+INSERT IGNORE INTO rbac_resource_data VALUES (502, 'f5dcb609-692d-4f81-b3fa-0f4dc3c891fb', '/api/systemInfo/hwInfo', '获取系统硬件信息', 'GET', 0);
+
+-- ----------------------------
+-- Records of role_resource
+-- (role_id, resource_id, authorize)
+-- ----------------------------
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 1, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 2, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 100, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 101, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 200, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 201, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 202, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 203, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 204, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 300, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 301, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 302, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 303, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 304, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 400, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 401, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 402, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 403, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 404, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 405, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 406, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 407, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 408, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 409, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 500, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 501, 1);
+INSERT IGNORE INTO rbac_role_resource VALUES (1, 502, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (2, 1, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (2, 2, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (2, 3, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (2, 4, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (2, 5, 1);
+#
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (3, 1, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (3, 3, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (3, 4, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (3, 5, 1);
+#
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (4, 1, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (4, 3, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (4, 4, 1);
+# INSERT IGNORE INTO role_resource (role_id, resource_id, authorize) VALUES (4, 5, 1);
+
+-- ----------------------------
+-- Records of casbin_rule
+-- ----------------------------
+# INSERT IGNORE INTO `casbin_rule` VALUES (1, 'g', 'admin', 'ADMIN', NULL, NULL, NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (2, 'g', 'user', 'DEVELOPMENT', NULL, NULL, NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (3, 'g', 'development', 'USER', NULL, NULL, NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (4, 'g', 'guest', 'GUEST', NULL, NULL, NULL, NULL);
+#
+# INSERT IGNORE INTO `casbin_rule` VALUES (5, 'p', 'ADMIN', '/api/version', '(GET)|(POST)', 'allow', NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (6, 'p', 'DEVELOPMENT', '/api/version', 'GET', 'allow', NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (7, 'p', 'USER', '/api/version', 'GET', 'allow', NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (8, 'p', 'GUEST', '/api/version', 'GET', 'allow', NULL, NULL);
+#
+# INSERT IGNORE INTO `casbin_rule` VALUES (9, 'p', 'DEVELOPMENT', '/swagger-ui/*', 'GET', 'allow', NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (10, 'p', 'USER', '/swagger-ui/*', 'GET', 'deny', NULL, NULL);
+# INSERT IGNORE INTO `casbin_rule` VALUES (11, 'p', 'GUEST', '/swagger-ui/*', 'GET', 'deny', NULL, NULL);
+
+# INSERT IGNORE INTO user_role (user_id, role_id) VALUES (1, 1);
+# INSERT IGNORE INTO user_role (user_id, role_id) VALUES (2, 3);
+# INSERT IGNORE INTO user_role (user_id, role_id) VALUES (3, 4);
+#
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (1, '根节点', null, '*', null, null, null);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (2, '仪表盘', null, 'dashboard', 0, '/dashboard', 1);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (3, '系统管理', null, 'sys', 0, '/sys', 1);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (4, '用户管理', null, 'user:view', 0, '/users', 3);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (5, '角色管理', null, 'role:view', 0, '/roles', 3);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (6, '权限资源', null, 'resource:view', 0, '/resources', 3);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (7, '查看用户', null, 'user:view', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (8, '新增用户', null, 'user:create', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (9, '修改用户', null, 'user:update', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (10, '删除用户', null, 'user:delete', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (11, '查看角色', null, 'role:view', 1, null, 5);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (12, '新增角色', null, 'role:create', 1, null, 5);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (13, '修改角色', null, 'role:update', 1, null, 5);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (14, '删除角色', null, 'role:delete', 1, null, 5);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (15, '查看资源', null, 'resource:view', 1, null, 6);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (16, '新增资源', null, 'resource:create', 1, null, 6);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (17, '修改资源', null, 'resource:update', 1, null, 6);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (18, '删除资源', null, 'resource:delete', 1, null, 6);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (19, '新增组织架构', null, 'organization:create', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (20, '修改组织架构', null, 'organization:update', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (21, '删除组织架构', null, 'organization:delete', 1, null, 4);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (22, '操作日志', null, 'log:view', 0, '/logs', 3);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (23, '清空日志', null, 'log:clean', 1, null, 22);
+# INSERT IGNORE INTO resource (id, name, parent_ids, permission, type, url, parent_id) VALUES (24, '查看日志', null, 'log:view', 1, null, 22);
+#
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 2);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 3);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 4);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 5);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 6);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 7);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 8);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 9);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 10);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 11);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 12);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 13);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 14);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 15);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 16);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 17);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 18);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 19);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 20);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 21);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 22);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 23);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (1, 24);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 2);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 3);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 6);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 15);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 16);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 17);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 18);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 22);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 23);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (2, 24);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (3, 2);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 2);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 3);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 4);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 5);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 6);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 7);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 11);
+# INSERT IGNORE INTO role_resource (role_id, resource_id) VALUES (4, 15);
+
+#insert into sys_dict_type values(1, '用户性别', 'sys_user_sex', '0', 'admin', sysdate(), '', null, '用户性别列表');
+#INSERT IGNORE INTO rbac_user (id, uid, username, gender, role_id) VALUES (3, '44ede496-d538-4a1d-afb9-bc409f752738', 'guest', 0, 4);
+INSERT IGNORE INTO sys_dict_type (id, dict_name, dict_type, create_by, remark) VALUES (1, '资源类型', 'sys_res_type', 'admin', '资源类型列表');
+INSERT IGNORE INTO sys_dict_type (id, dict_name, dict_type, create_by, remark) VALUES (2, '用户组', 'sys_role_group', 'admin', '用户组列表');
+
+
+INSERT IGNORE INTO sys_dict_data VALUES (1, 1, '路由', 0, 1, '', '','Y', 'admin', CURRENT_TIMESTAMP(6), '', null, 'URI 路由资源', null);
+INSERT IGNORE INTO sys_dict_data VALUES (2, 2, '菜单', 1, 1, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 菜单资源', null);
+INSERT IGNORE INTO sys_dict_data VALUES (3, 3, '按钮', 2, 1, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 按钮资源', null);
+
+INSERT IGNORE INTO sys_dict_data VALUES (4, 1, 'ADMIN', 1, 2, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, '超级管理员可以对企业内的所有用户进行管理,请谨慎修改超管权限', null);
+INSERT IGNORE INTO sys_dict_data VALUES (5, 2, 'DEVELOPMENT', 2, 2, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, '项目开发人员', null);
+INSERT IGNORE INTO sys_dict_data VALUES (6, 3, 'USER', 3, 2, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, '普通的用户', null);
+INSERT IGNORE INTO sys_dict_data VALUES (7, 4, 'GUEST', 4, 2, '', '','N', 'admin', CURRENT_TIMESTAMP(6), '', null, '系统访客,不需要认证,最小权限', null);
+
+# INSERT IGNORE INTO sys_dict_data VALUES (4, 1, '正常', '0', 'sys_common_status', '', '','Y', '0', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 按钮资源', null);
+# INSERT IGNORE INTO sys_dict_data VALUES (5, 2, '已锁定', '1', 'sys_common_status', '', '','N', '0', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 按钮资源', null);
+# INSERT IGNORE INTO sys_dict_data VALUES (6, 3, '已禁用', '2', 'sys_common_status', '', '','N', '0', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 按钮资源', null);
+# INSERT IGNORE INTO sys_dict_data VALUES (7, 4, '已删除', '3', 'sys_common_status', '', '','N', '0', 'admin', CURRENT_TIMESTAMP(6), '', null, 'UI 按钮资源', null);
+
+-- 开启外键约束检查
+set foreign_key_checks = 1;
\ No newline at end of file
diff --git a/cs-database/src/main/resources/rbac/schema.sql b/cs-database/src/main/resources/rbac/schema.sql
new file mode 100644
index 0000000..c0628d9
--- /dev/null
+++ b/cs-database/src/main/resources/rbac/schema.sql
@@ -0,0 +1,220 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server : 腾讯云
+ Source Server Type : MySQL
+ Source Server Version : 80033
+ Source Host : 101.35.234.160:32306
+ Source Schema : admin3
+
+ Target Server Type : MySQL
+ Target Server Version : 80033
+ File Encoding : 65001
+
+ Date: 07/12/2023 16:34:32
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for role
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_role`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `available` bit(1) NULL DEFAULT NULL COMMENT '是否有效',
+ `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限描述',
+ `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '权限名称',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `UK_8sewwnpamngi6b1dwaa88askk` (`name` ASC) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 5
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic COMMENT '权限';
+
+-- ----------------------------
+-- Table structure for role_resource
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_role_resource`
+(
+ `role_id` bigint NOT NULL COMMENT '权限id',
+ `resource_id` bigint NOT NULL COMMENT '权限资源id',
+ `authorize` bit(1) NULL DEFAULT NULL COMMENT '0: deny, 1: allow',
+ PRIMARY KEY (`resource_id`, `role_id`) USING BTREE,
+ INDEX `FKh8lunkrwoyio367ec8y12bis1` (`role_id` ASC) USING BTREE,
+ CONSTRAINT `FKh8lunkrwoyio367ec8y12bis1` FOREIGN KEY (`role_id`) REFERENCES `rbac_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
+ CONSTRAINT `FKr2orp5em3dob6f299ra9oyexr` FOREIGN KEY (`resource_id`) REFERENCES `rbac_resource_data` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic COMMENT '权限资源';
+
+-- ----------------------------
+-- Table structure for user
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_user`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `uid` varchar(48) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL UNIQUE COMMENT '用户UUID',
+ `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
+ `created_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `gender` bigint NOT NULL COMMENT '创建用户',
+ `role_id` bigint(20) NOT NULL COMMENT '用户权限组',
+ `delete_time` datetime NULL DEFAULT NULL COMMENT '逻辑删除标记',
+ PRIMARY KEY (`id`) USING BTREE,
+ INDEX `fk_role_id` (`role_id`) USING BTREE,
+ CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `rbac_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1000
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic COMMENT '用户表';
+
+-- ----------------------------
+-- Table structure for user_credential
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_user_credential`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `credential` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户密码',
+ `identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户标识',
+ `identity_type` smallint NULL DEFAULT NULL COMMENT '登录类型',
+ `user_id` bigint NOT NULL DEFAULT -1 COMMENT '用户id',
+ `state` smallint NOT NULL COMMENT '当前状态(CommonStatus):0-->正常,1-->锁定,2-->禁用,3-->删除',
+ `error_cnt` smallint NOT NULL DEFAULT 0 COMMENT '密码错误次数',
+ `lock_at` datetime(6) NULL COMMENT '账户锁定时间',
+ `delete_time` datetime NULL DEFAULT NULL COMMENT '逻辑删除标记',
+ PRIMARY KEY (`id`) USING BTREE,
+ INDEX `FK6y499rs9ocqqa3kdpu2f32m86` (`user_id` ASC) USING BTREE,
+ CONSTRAINT `FK6y499rs9ocqqa3kdpu2f32m86` FOREIGN KEY (`user_id`) REFERENCES `rbac_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1000
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic COMMENT '用户认证';
+
+-- ----------------------------
+-- Table structure for user_role
+-- ----------------------------
+-- DROP TABLE IF EXISTS `user_role`;
+-- CREATE TABLE `user_role`
+-- (
+-- `user_id` bigint NOT NULL COMMENT '用户id',
+-- `role_id` bigint NOT NULL COMMENT '权限id',
+-- PRIMARY KEY (`role_id`, `user_id`) USING BTREE,
+-- INDEX `FKfgsgxvihks805qcq8sq26ab7c` (`user_id` ASC) USING BTREE,
+-- CONSTRAINT `FKa68196081fvovjhkek5m97n3y` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
+-- CONSTRAINT `FKfgsgxvihks805qcq8sq26ab7c` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+-- ) ENGINE = InnoDB
+-- CHARACTER SET = utf8mb4
+-- COLLATE = utf8mb4_general_ci
+-- ROW_FORMAT = Dynamic COMMENT '用户权限';
+
+-- ----------------------------
+-- Table structure for resource
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_resource_data`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `uid` varchar(48) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL UNIQUE COMMENT '资源UUID',
+ `path` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '资源URL',
+ `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '资源名称',
+ `http_method` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'GET' COMMENT '资源访问 HTTP 方法 GET/POST/DELETE/...',
+ `type_id` smallint NOT NULL COMMENT '资源类型(resource_type):0-->路由,1-->菜单,2-->按钮,...',
+ CONSTRAINT `FKa68196081fvovjhkekresourcetype` FOREIGN KEY (`type_id`) REFERENCES `rbac_resource_type` (`type_id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1000
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for resource
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `rbac_resource_type`
+(
+ `type_id` smallint NOT NULL COMMENT '资源类型:0-->路由,1-->菜单,2-->按钮,...',
+ `name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '资源名称',
+ PRIMARY KEY (`type_id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1000
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for stored_event
+-- ----------------------------
+CREATE TABLE IF NOT EXISTS `sys_operation_log`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `uid` varchar(48) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL UNIQUE COMMENT '操作日志UUID',
+ `module` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作模块',
+ `operation_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作类型',
+ `operation_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作状态',
+ `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作说明',
+ `request_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求来源 IP 地址',
+ `call_function` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求接口',
+ `http_method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'HTTP 请求类型',
+ `http_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求URI',
+ `transmit_delay` bigint NULL DEFAULT NULL COMMENT '传输延时(ms)',
+ `expend_time` bigint NULL DEFAULT NULL COMMENT '响应时间(ms)',
+ `user_id` bigint NULL DEFAULT NULL COMMENT '操作用户id',
+ `operation_time` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '操作时间',
+ `request_headers` varchar(4095) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'HTTP 请求头所有参数',
+ `request` varchar(4095) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作请求参数',
+ `result` varchar(4095) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作返回结果',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci
+ ROW_FORMAT = Dynamic COMMENT '系统操作日志';
+
+CREATE TABLE IF NOT EXISTS `sys_dict_data`
+(
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典编码',
+ `dict_sort` int(4) NULL DEFAULT 0 COMMENT '字典排序',
+ `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典标签',
+ `dict_value` smallint NOT NULL COMMENT '字典键值',
+ `type_id` bigint(20) NOT NULL COMMENT '字典类型',
+ `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)',
+ `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表格回显样式',
+ `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)',
+ `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+ `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
+ `delete_time` datetime NULL DEFAULT NULL COMMENT '逻辑删除标记',
+ CONSTRAINT `FKa68196081fvovjhkekdicttype` FOREIGN KEY (`type_id`) REFERENCES `sys_dict_type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 100
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci COMMENT = '字典数据表'
+ ROW_FORMAT = Dynamic;
+
+CREATE TABLE IF NOT EXISTS `sys_dict_type`
+(
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典主键',
+ `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典名称',
+ `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型',
+ `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime(6) NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间',
+ `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime(6) NULL DEFAULT NULL COMMENT '更新时间',
+ `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
+ `delete_time` datetime NULL DEFAULT NULL COMMENT '逻辑删除标记',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `dict_type` (`dict_type`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 100
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_general_ci COMMENT = '字典类型表'
+ ROW_FORMAT = Dynamic;
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/cs-database/src/test/java/com/cf/cs/database/CsDatabaseApplicationTests.java b/cs-database/src/test/java/com/cf/cs/database/CsDatabaseApplicationTests.java
new file mode 100644
index 0000000..5211df4
--- /dev/null
+++ b/cs-database/src/test/java/com/cf/cs/database/CsDatabaseApplicationTests.java
@@ -0,0 +1,13 @@
+package com.cf.cs.database;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class CsDatabaseApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/cs-protocol/pom.xml b/cs-protocol/pom.xml
new file mode 100644
index 0000000..e345586
--- /dev/null
+++ b/cs-protocol/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ com.cf.cs
+ IntegrateService
+ 0.0.1-dev
+
+
+ cs-protocol
+ cs-protocol
+ cs-protocol
+ jar
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.cf.cs
+ cs-base
+ ${cs-package.version}
+ compile
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/CsProtocolApplication.java b/cs-protocol/src/main/java/com/cf/cs/protocol/CsProtocolApplication.java
new file mode 100644
index 0000000..5e71f5d
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/CsProtocolApplication.java
@@ -0,0 +1,23 @@
+package com.cf.cs.protocol;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type Cs protocol application.
+ *
+ * @author xajhuang @163.com
+ */
+@SpringBootApplication
+public class CsProtocolApplication {
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(CsProtocolApplication.class, args);
+ }
+
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/config/ProtocolConfigure.java b/cs-protocol/src/main/java/com/cf/cs/protocol/config/ProtocolConfigure.java
new file mode 100644
index 0000000..4d84c41
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/config/ProtocolConfigure.java
@@ -0,0 +1,56 @@
+package com.cf.cs.protocol.config;
+
+import jakarta.annotation.PostConstruct;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Optional;
+
+/**
+ * The type Protocol configure.
+ *
+ * @author xajhuang @163.com
+ */
+@Data
+@ConfigurationProperties(prefix = "protocol")
+@Configuration
+@Slf4j
+public class ProtocolConfigure {
+ /**
+ * The constant CHECK_TIMESTAMP.
+ */
+ public static boolean CHECK_TIMESTAMP;
+ /**
+ * The Timeout of seconds.
+ */
+ public static long TIMEOUT_OF_SECONDS;
+ /**
+ * The Security protocol type.
+ */
+ public static int SECURITY_PROTOCOL_TYPE;
+
+ private Boolean checkTimestamp;
+ private Integer timeoutOfSeconds;
+ private Integer cryptoType;
+ private String cryptoKey;
+
+ @PostConstruct
+ private void initGlobalValue() {
+ log.info("Current: checkTimestamp = {}, timeoutOfSeconds = {}", checkTimestamp, timeoutOfSeconds);
+
+ ProtocolConfigure.CHECK_TIMESTAMP = Optional.ofNullable(checkTimestamp).orElse(false);
+ ProtocolConfigure.TIMEOUT_OF_SECONDS = Optional.ofNullable(timeoutOfSeconds).orElse(30);
+ ProtocolConfigure.SECURITY_PROTOCOL_TYPE = Optional.ofNullable(cryptoType).orElse(0);
+ }
+
+ /**
+ * Gets timeout of millisecond.
+ *
+ * @return the timeout of millisecond
+ */
+ public Long getTimeoutOfMillisecond() {
+ return (long) (timeoutOfSeconds * 1000);
+ }
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/base/BaseProtocol.java b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/base/BaseProtocol.java
new file mode 100644
index 0000000..7202253
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/base/BaseProtocol.java
@@ -0,0 +1,46 @@
+package com.cf.cs.protocol.pojo.base;
+
+import com.cf.cs.protocol.validation.group.ValidGroups;
+import com.cf.cs.protocol.validation.valids.ValidProtocolTimestamp;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Range;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * The type Base protocol.
+ *
+ * @param the type parameter
+ * @author xajhuang @163.com
+ */
+@Data
+@NoArgsConstructor
+@JsonPropertyOrder({"ver", "cryptoType", "timeStamp", "msgContent"})
+@JsonIgnoreProperties
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BaseProtocol implements Serializable {
+ @Serial
+ private static final long serialVersionUID = -32326523643641L;
+
+ @NotNull(message = "ver 字段不能为空", groups = ValidGroups.ProtocolCommonValid.class)
+ @Range(min = 1, max = 9999, message = "ver 字段最小值为 1", groups = ValidGroups.ProtocolCommonValid.class)
+ private Integer ver;
+
+ @NotNull(message = "cryptoType 字段不能为空", groups = ValidGroups.ProtocolCommonValid.class)
+ @Range(min = 0, max = 4, message = "cryptoType 字段取值为 [0, 4]", groups = ValidGroups.ProtocolCommonValid.class)
+ private Integer cryptoType;
+
+ @NotNull(message = "timeStamp 字段不能为空", groups = ValidGroups.ProtocolCommonValid.class)
+ @ValidProtocolTimestamp(message = "timeStamp 字段值与当前时间差不能大于超时配置", groups = ValidGroups.ProtocolCommonValid.class)
+ private Long timeStamp;
+
+ @Valid
+ private T msgContent;
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/BaseRespStatus.java b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/BaseRespStatus.java
new file mode 100644
index 0000000..c4c5edd
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/BaseRespStatus.java
@@ -0,0 +1,19 @@
+package com.cf.cs.protocol.pojo.po;
+
+import com.cf.cs.base.common.ErrorCode;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The type Base resp status.
+ *
+ * @author xajhuang @163.com
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BaseRespStatus {
+ private Integer status = ErrorCode.ERR_OK.getCode();
+ private String[] message = new String[] {ErrorCode.ERR_OK.getDescription()};
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/VersionInfo.java b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/VersionInfo.java
new file mode 100644
index 0000000..728eaa6
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/po/VersionInfo.java
@@ -0,0 +1,24 @@
+package com.cf.cs.protocol.pojo.po;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The type Version info.
+ *
+ * @author xajhuang @163.com
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class VersionInfo {
+ private String commitId;
+ private String commitDescribe;
+ private String commitTime;
+ private String tagName;
+ private String buildTime;
+ private String gitBranch;
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/ProtocolResp.java b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/ProtocolResp.java
new file mode 100644
index 0000000..2378065
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/ProtocolResp.java
@@ -0,0 +1,90 @@
+package com.cf.cs.protocol.pojo.vo;
+
+import com.cf.cs.base.common.CommonEnumHandler;
+import com.cf.cs.base.common.ConstValue;
+import com.cf.cs.base.common.ErrorCode;
+import com.cf.cs.protocol.config.ProtocolConfigure;
+import com.cf.cs.protocol.pojo.base.BaseProtocol;
+import com.cf.cs.protocol.pojo.po.BaseRespStatus;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * The type Protocol resp.
+ *
+ * @param the type parameter
+ * @author xajhuang @163.com
+ */
+@Slf4j
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonPropertyOrder({"ver", "cryptoType", "timeStamp", "code", "msgContent"})
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProtocolResp extends BaseProtocol {
+ private Integer code;
+
+ private static ProtocolResp result(ErrorCode err, Integer httpCode, T respMsg) {
+ ProtocolResp resp = new ProtocolResp<>();
+
+ resp.setVer(ConstValue.Protocol.VERSION);
+ resp.setCode(httpCode);
+ resp.setCryptoType(ProtocolConfigure.SECURITY_PROTOCOL_TYPE);
+ resp.setTimeStamp(System.currentTimeMillis());
+ resp.setMsgContent(respMsg);
+ return resp;
+ }
+
+ /**
+ * Result protocol resp.
+ *
+ * @param the type parameter
+ * @param err the err
+ * @param respMsg the resp msg
+ * @return the protocol resp
+ */
+ public static ProtocolResp result(ErrorCode err, T respMsg) {
+ return result(err, err.getHttpCode(), respMsg);
+ }
+
+ /**
+ * Result protocol resp.
+ *
+ * @param err the err
+ * @return the protocol resp
+ */
+ public static ProtocolResp result(ErrorCode err) {
+ BaseRespStatus rspMsg = new BaseRespStatus(err.getCode(), new String[] {err.getDescription()});
+ return result(err, err.getHttpCode(), rspMsg);
+ }
+
+ /**
+ * Result protocol resp.
+ *
+ * @param the type parameter
+ * @param respMsg the resp msg
+ * @return the protocol resp
+ */
+ public static ProtocolResp result(T respMsg) {
+ return result(CommonEnumHandler.codeOf(ErrorCode.class, respMsg.getStatus()), respMsg);
+ }
+
+ /**
+ * Result protocol resp.
+ *
+ * @param errCode the err code
+ * @param httpCode the http code
+ * @param message the message
+ * @return the protocol resp
+ */
+ public static ProtocolResp result(ErrorCode errCode, Integer httpCode, String[] message) {
+ BaseRespStatus rspMsg = new BaseRespStatus(errCode.getCode(), message);
+ return result(errCode, httpCode, rspMsg);
+ }
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/VersionResp.java b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/VersionResp.java
new file mode 100644
index 0000000..fa525b0
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/pojo/vo/VersionResp.java
@@ -0,0 +1,25 @@
+package com.cf.cs.protocol.pojo.vo;
+
+import com.cf.cs.protocol.pojo.po.BaseRespStatus;
+import com.cf.cs.protocol.pojo.po.VersionInfo;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * The type Version resp.
+ *
+ * @author xajhuang @163.com
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@JsonPropertyOrder({"version", "status", "message"})
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class VersionResp extends BaseRespStatus {
+ private VersionInfo version;
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/JsonViewGroups.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/JsonViewGroups.java
new file mode 100644
index 0000000..1796770
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/JsonViewGroups.java
@@ -0,0 +1,29 @@
+package com.cf.cs.protocol.validation.group;
+
+/**
+ * The type Json view groups.
+ *
+ * @author xajhuang @163.com
+ */
+public class JsonViewGroups {
+ /**
+ * The type Common view.
+ *
+ * @author xajhuang @163.com
+ */
+ public static class CommonView {}
+
+ /**
+ * The type Dict content response.
+ *
+ * @author xajhuang @163.com
+ */
+ public static class DictContentResponse extends CommonView {}
+
+ /**
+ * The type Dict content request.
+ *
+ * @author xajhuang @163.com
+ */
+ public static class DictContentRequest extends CommonView {}
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/ValidGroups.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/ValidGroups.java
new file mode 100644
index 0000000..6f09f64
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/group/ValidGroups.java
@@ -0,0 +1,105 @@
+package com.cf.cs.protocol.validation.group;
+
+/**
+ * The interface Valid groups.
+ *
+ * @author xajhuang @163.com
+ */
+public interface ValidGroups {
+
+ /**
+ * The interface Protocol common valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface ProtocolCommonValid {
+ }
+
+ /**
+ * The interface Base protocol valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface BaseProtocolValid extends ProtocolCommonValid {
+ }
+
+ /**
+ * The interface Base paged req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface BasePagedReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Login req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface LoginReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Logout req valid.
+ *
+ * @author
+ */
+ interface LogoutReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Operation log req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface OperationLogReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface User id req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface UserIdReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface User req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface UserReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Resource req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface ResourceReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Resource info valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface ResourceInfoValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Dict req valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface DictReqValid extends BaseProtocolValid {
+ }
+
+ /**
+ * The interface Dict req content valid.
+ *
+ * @author xajhuang @163.com
+ */
+ interface DictReqContentValid extends BaseProtocolValid {
+ }
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/UUID.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/UUID.java
new file mode 100644
index 0000000..c7e4e05
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/UUID.java
@@ -0,0 +1,42 @@
+package com.cf.cs.protocol.validation.valids;
+
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+import jakarta.validation.constraints.Pattern;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The interface Uuid.
+ *
+ * @author xajhuang @163.com
+ */
+@Target(ElementType.FIELD)
+@Constraint(validatedBy = {})
+@Retention(RetentionPolicy.RUNTIME)
+@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
+public @interface UUID {
+ /**
+ * Message string.
+ *
+ * @return the string
+ */
+ String message() default "{invalid.uuid}";
+
+ /**
+ * Groups class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class>[] groups() default {};
+
+ /**
+ * Payload class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class extends Payload>[] payload() default {};
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidHttpMethod.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidHttpMethod.java
new file mode 100644
index 0000000..f5dd682
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidHttpMethod.java
@@ -0,0 +1,43 @@
+package com.cf.cs.protocol.validation.valids;
+
+import com.cf.cs.protocol.validation.valids.impl.ValidHttpMethodImpl;
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+
+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;
+
+/**
+ * The interface Valid http method.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = {ValidHttpMethodImpl.class})
+public @interface ValidHttpMethod {
+ /**
+ * Message string.
+ *
+ * @return the string
+ */
+ String message() default "";
+
+ /**
+ * Groups class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class>[] groups() default {};
+
+ /**
+ * Payload class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class extends Payload>[] payload() default {};
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidPageSize.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidPageSize.java
new file mode 100644
index 0000000..d5a208b
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidPageSize.java
@@ -0,0 +1,43 @@
+package com.cf.cs.protocol.validation.valids;
+
+import com.cf.cs.protocol.validation.valids.impl.ValidPageSizeImpl;
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+
+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;
+
+/**
+ * The interface Valid page size.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = {ValidPageSizeImpl.class})
+public @interface ValidPageSize {
+ /**
+ * Message string.
+ *
+ * @return the string
+ */
+ String message();
+
+ /**
+ * Groups class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class>[] groups() default {};
+
+ /**
+ * Payload class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class extends Payload>[] payload() default {};
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidProtocolTimestamp.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidProtocolTimestamp.java
new file mode 100644
index 0000000..7567ad7
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/ValidProtocolTimestamp.java
@@ -0,0 +1,43 @@
+package com.cf.cs.protocol.validation.valids;
+
+import com.cf.cs.protocol.validation.valids.impl.ValidProtocolTimestampImpl;
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+
+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;
+
+/**
+ * The interface Valid protocol timestamp.
+ *
+ * @author xajhuang @163.com
+ */
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = {ValidProtocolTimestampImpl.class})
+public @interface ValidProtocolTimestamp {
+ /**
+ * Message string.
+ *
+ * @return the string
+ */
+ String message();
+
+ /**
+ * Groups class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class>[] groups() default {};
+
+ /**
+ * Payload class [ ].
+ *
+ * @return the class [ ]
+ */
+ Class extends Payload>[] payload() default {};
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidHttpMethodImpl.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidHttpMethodImpl.java
new file mode 100644
index 0000000..7f7dcba
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidHttpMethodImpl.java
@@ -0,0 +1,41 @@
+package com.cf.cs.protocol.validation.valids.impl;
+
+import com.cf.cs.protocol.validation.valids.ValidHttpMethod;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import java.util.List;
+
+/**
+ * The type Valid http method.
+ *
+ * @author xajhuang @163.com
+ */
+public class ValidHttpMethodImpl implements ConstraintValidator> {
+ @Override
+ public void initialize(ValidHttpMethod constraintAnnotation) {
+
+ ConstraintValidator.super.initialize(constraintAnnotation);
+ }
+
+ @Override
+ public boolean isValid(List strings, ConstraintValidatorContext context) {
+ StringBuilder errMsg = new StringBuilder();
+
+ strings.forEach(k -> {
+ if (RequestMethod.resolve(k.toUpperCase()) == null) {
+ errMsg.append("[")
+ .append(k)
+ .append("]: 不是合法的 HTTP 请求方法");
+ }
+ });
+
+ if (!errMsg.isEmpty()) {
+ context.disableDefaultConstraintViolation();
+ context.buildConstraintViolationWithTemplate(errMsg.toString()).addConstraintViolation();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidPageSizeImpl.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidPageSizeImpl.java
new file mode 100644
index 0000000..7dd00a7
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidPageSizeImpl.java
@@ -0,0 +1,22 @@
+package com.cf.cs.protocol.validation.valids.impl;
+
+import com.cf.cs.protocol.validation.valids.ValidPageSize;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+/**
+ * The type Valid page size.
+ *
+ * @author xajhuang @163.com
+ */
+public class ValidPageSizeImpl implements ConstraintValidator {
+ @Override
+ public void initialize(ValidPageSize constraintAnnotation) {
+ ConstraintValidator.super.initialize(constraintAnnotation);
+ }
+
+ @Override
+ public boolean isValid(Long pageSize, ConstraintValidatorContext constraintValidatorContext) {
+ return pageSize % 5 == 0;
+ }
+}
diff --git a/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidProtocolTimestampImpl.java b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidProtocolTimestampImpl.java
new file mode 100644
index 0000000..95f9973
--- /dev/null
+++ b/cs-protocol/src/main/java/com/cf/cs/protocol/validation/valids/impl/ValidProtocolTimestampImpl.java
@@ -0,0 +1,55 @@
+package com.cf.cs.protocol.validation.valids.impl;
+
+
+import com.cf.cs.protocol.config.ProtocolConfigure;
+import com.cf.cs.protocol.validation.valids.ValidProtocolTimestamp;
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+
+import java.text.SimpleDateFormat;
+
+
+/**
+ * The type Valid protocol timestamp.
+ *
+ * @author xajhuang @163.com
+ */
+public class ValidProtocolTimestampImpl implements ConstraintValidator {
+
+ @Override
+ public void initialize(ValidProtocolTimestamp constraintAnnotation) {
+ ConstraintValidator.super.initialize(constraintAnnotation);
+ }
+
+ @Override
+ public boolean isValid(Long timeStamp, ConstraintValidatorContext constraintValidatorContext) {
+
+ if (!ProtocolConfigure.CHECK_TIMESTAMP) {
+ return true;
+ }
+
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ String date = format.format(timeStamp);
+ String current = format.format(System.currentTimeMillis());
+
+
+ if (timeStamp > System.currentTimeMillis()) {
+ String errMsg = String.format("请求时间[%s] 大于当前服务器时间 [%s]", date, current);
+ //禁用默认的message的值
+ constraintValidatorContext.disableDefaultConstraintViolation();
+ //重新添加错误提示语句
+ constraintValidatorContext.buildConstraintViolationWithTemplate(errMsg).addConstraintViolation();
+ return false;
+ } else if (System.currentTimeMillis() - timeStamp > ProtocolConfigure.TIMEOUT_OF_SECONDS * 1000L) {
+ String errMsg = String.format("请求时间[%s] 延时超过当前服务器时间[%s] 允许范围 %d(S)", date, current,
+ ProtocolConfigure.TIMEOUT_OF_SECONDS);
+ //禁用默认的message的值
+ constraintValidatorContext.disableDefaultConstraintViolation();
+ //重新添加错误提示语句
+ constraintValidatorContext.buildConstraintViolationWithTemplate(errMsg).addConstraintViolation();
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/cs-protocol/src/test/java/com/cf/cs/protocol/CsProtocolApplicationTests.java b/cs-protocol/src/test/java/com/cf/cs/protocol/CsProtocolApplicationTests.java
new file mode 100644
index 0000000..987a8e8
--- /dev/null
+++ b/cs-protocol/src/test/java/com/cf/cs/protocol/CsProtocolApplicationTests.java
@@ -0,0 +1,13 @@
+package com.cf.cs.protocol;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class CsProtocolApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/cs-restful/pom.xml b/cs-restful/pom.xml
index 328f631..0688c5d 100644
--- a/cs-restful/pom.xml
+++ b/cs-restful/pom.xml
@@ -21,13 +21,22 @@
org.springframework.boot
spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
-
org.springframework.boot
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-undertow
+
org.springdoc
@@ -40,6 +49,30 @@
2.3.0
+
+ com.cf.cs
+ cs-database
+ ${cs-package.version}
+ compile
+
+
+ com.cf.cs
+ cs-protocol
+ ${cs-package.version}
+ compile
+
+
+ com.cf.cs
+ cs-crypto
+ ${cs-package.version}
+ compile
+
+
+ com.cf.cs
+ cs-services
+ ${cs-package.version}
+ compile
+
com.cf.cs
cs-web
diff --git a/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java b/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java
index 65a6770..e07a4c6 100644
--- a/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java
+++ b/cs-restful/src/main/java/com/cf/cs/restful/CsRestfulApplication.java
@@ -8,7 +8,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
*
* @author xajhuang @163.com
*/
-@SpringBootApplication(scanBasePackages = {"com.cf.cs.base", "com.cf.cs.restful", "com.cf.cs.web"})
+@SpringBootApplication(scanBasePackages = {"com.cf.cs.base", "com.cf.cs.database", "com.cf.cs.protocol",
+ "com.cf.cs.services", "com.cf.cs.restful", "com.cf.cs.web"})
public class CsRestfulApplication {
/**
diff --git a/cs-restful/src/main/java/com/cf/cs/restful/controller/CommonFrameworkApi.java b/cs-restful/src/main/java/com/cf/cs/restful/controller/CommonFrameworkApi.java
new file mode 100644
index 0000000..229cf61
--- /dev/null
+++ b/cs-restful/src/main/java/com/cf/cs/restful/controller/CommonFrameworkApi.java
@@ -0,0 +1,62 @@
+package com.cf.cs.restful.controller;
+
+import com.cf.cs.crypto.annotation.DecryptionProtocol;
+import com.cf.cs.crypto.annotation.EncryptionProtocol;
+import com.cf.cs.protocol.pojo.po.BaseRespStatus;
+import com.cf.cs.protocol.pojo.po.VersionInfo;
+import com.cf.cs.protocol.pojo.vo.ProtocolResp;
+import com.cf.cs.protocol.pojo.vo.VersionResp;
+import com.cf.cs.base.annotation.OperationLogAnnotation;
+import com.cf.cs.web.configure.ProjectGitVersionInfo;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@Slf4j
+@Tag(name = "通用接口")
+@RequestMapping(value = "/api")
+public class CommonFrameworkApi {
+ @Resource
+ private ProjectGitVersionInfo prgVer;
+
+ @EncryptionProtocol
+ @DecryptionProtocol
+ @PostMapping("/version")
+ @ResponseBody
+ @OperationLogAnnotation(OperationModule = "通用模块", OperationType = "读取", OperationDesc = "获取当前系统版本信息")
+ public ProtocolResp extends BaseRespStatus> getVersion() {
+ return ProtocolResp.result(VersionResp.builder()
+ .version(VersionInfo.builder()
+ .commitId(prgVer.getCommitId())
+ .commitDescribe(prgVer.getCommitDescribe())
+ .commitTime(prgVer.getCommitTime())
+ .tagName(prgVer.getTagName())
+ .buildTime(prgVer.getBuildTime())
+ .gitBranch(prgVer.getGitBranch())
+ .build())
+ .build());
+ }
+
+ @GetMapping("/version")
+ @ResponseBody
+ @EncryptionProtocol
+ @OperationLogAnnotation(OperationModule = "通用模块", OperationType = "读取", OperationDesc = "获取当前系统版本信息")
+ public ProtocolResp extends BaseRespStatus> getVersionV2() {
+ return ProtocolResp.result(VersionResp.builder()
+ .version(VersionInfo.builder()
+ .commitId(prgVer.getCommitId())
+ .commitDescribe(prgVer.getCommitDescribe())
+ .commitTime(prgVer.getCommitTime())
+ .tagName(prgVer.getTagName())
+ .buildTime(prgVer.getBuildTime())
+ .gitBranch(prgVer.getGitBranch())
+ .build())
+ .build());
+ }
+}
diff --git a/cs-services/pom.xml b/cs-services/pom.xml
new file mode 100644
index 0000000..0e6044c
--- /dev/null
+++ b/cs-services/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ com.cf.cs
+ IntegrateService
+ 0.0.1-dev
+
+
+ cs-services
+ cs-services
+ cs-services
+ jar
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/cs-services/src/main/java/com/cf/cs/services/CsServicesApplication.java b/cs-services/src/main/java/com/cf/cs/services/CsServicesApplication.java
new file mode 100644
index 0000000..f3b6d35
--- /dev/null
+++ b/cs-services/src/main/java/com/cf/cs/services/CsServicesApplication.java
@@ -0,0 +1,23 @@
+package com.cf.cs.services;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The type Cs services application.
+ *
+ * @author xajhuang @163.com
+ */
+@SpringBootApplication
+public class CsServicesApplication {
+
+ /**
+ * The entry point of application.
+ *
+ * @param args the input arguments
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(CsServicesApplication.class, args);
+ }
+
+}
diff --git a/cs-services/src/test/java/com/cf/cs/services/CsServicesApplicationTests.java b/cs-services/src/test/java/com/cf/cs/services/CsServicesApplicationTests.java
new file mode 100644
index 0000000..fc96476
--- /dev/null
+++ b/cs-services/src/test/java/com/cf/cs/services/CsServicesApplicationTests.java
@@ -0,0 +1,13 @@
+package com.cf.cs.services;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class CsServicesApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/cs-web/pom.xml b/cs-web/pom.xml
index 1e92245..8f98bc6 100644
--- a/cs-web/pom.xml
+++ b/cs-web/pom.xml
@@ -16,15 +16,9 @@
org.springframework.boot
- spring-boot-starter-cache
+ spring-boot-starter-test
+ test
-
-
- com.github.ben-manes.caffeine
- caffeine
- 3.1.8
-
-
com.cf.cs
cs-base
diff --git a/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyCacheWrapper.java b/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyCacheWrapper.java
new file mode 100644
index 0000000..bb6d9ec
--- /dev/null
+++ b/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyCacheWrapper.java
@@ -0,0 +1,109 @@
+package com.cf.cs.web.interceptor;
+
+import com.cf.cs.base.misc.ApiContextUtils;
+import com.cf.cs.base.misc.HelperUtils;
+import jakarta.servlet.ReadListener;
+import jakarta.servlet.ServletInputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The type Request body cache wrapper.
+ *
+ * @author xajhuang @163.com
+ */
+@Getter
+@Slf4j
+public class RequestBodyCacheWrapper extends HttpServletRequestWrapper {
+ private final Long reqTimeStamp = System.currentTimeMillis();
+ private final Map headers = new HashMap<>();
+ private String body;
+
+ /**
+ * Instantiates a new Request body cache wrapper.
+ *
+ * @param request the request
+ * @throws IOException the io exception
+ */
+ public RequestBodyCacheWrapper(HttpServletRequest request) throws IOException {
+ super(request);
+
+ StringBuilder stringBuilder = new StringBuilder();
+ BufferedReader bufferedReader = null;
+ try (InputStream inputStream = request.getInputStream()) {
+ if (inputStream != null) {
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ char[] charBuffer = new char[128];
+ int bytesRead;
+ while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
+ stringBuilder.append(charBuffer, 0, bytesRead);
+ }
+ }
+ } catch (Exception e) {
+ log.error("RequestWrapper read error :{}", e.getMessage());
+ } finally {
+
+ if (bufferedReader != null) {
+ bufferedReader.close();
+ }
+ }
+
+ try {
+ Object obj = HelperUtils.jsonGetObject(stringBuilder.toString(), Object.class);
+ body = HelperUtils.getJson(obj);
+
+ Enumeration enumeration = request.getHeaderNames();
+ while (enumeration.hasMoreElements()) {
+ String name = enumeration.nextElement();
+ String value = request.getHeader(name);
+ headers.put(name, value);
+ }
+ } catch (Exception e) {
+ body = "";
+ } finally {
+ ApiContextUtils.setRequestInfo(body, reqTimeStamp);
+ }
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
+ return new ServletInputStream() {
+ @Override
+ public boolean isFinished() {
+ return false;
+ }
+
+ @Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+ }
+
+ @Override
+ public int read() {
+ return byteArrayInputStream.read();
+ }
+ };
+ }
+
+ @Override
+ public BufferedReader getReader() {
+ return new BufferedReader(new InputStreamReader(this.getInputStream(), StandardCharsets.UTF_8));
+ }
+}
diff --git a/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyFilter.java b/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyFilter.java
new file mode 100644
index 0000000..a2a63d5
--- /dev/null
+++ b/cs-web/src/main/java/com/cf/cs/web/interceptor/RequestBodyFilter.java
@@ -0,0 +1,45 @@
+package com.cf.cs.web.interceptor;
+
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.annotation.WebFilter;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+/**
+ * The type Request body filter.
+ *
+ * @author xajhuang @163.com
+ */
+@Component
+@WebFilter(filterName = "RequestBodyFilter", urlPatterns = "/")
+@Order(10000)
+public class RequestBodyFilter implements Filter {
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ Filter.super.init(filterConfig);
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,
+ ServletException {
+ ServletRequest requestWrapper = null;
+ if (servletRequest instanceof HttpServletRequest) {
+ requestWrapper = new RequestBodyCacheWrapper((HttpServletRequest) servletRequest);
+ }
+ //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中
+ // 在chain.doFiler方法中传递新的request对象
+ if (null == requestWrapper) {
+ filterChain.doFilter(servletRequest, servletResponse);
+ } else {
+ filterChain.doFilter(requestWrapper, servletResponse);
+ }
+ }
+}
\ No newline at end of file
diff --git a/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java b/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java
index e4e7de4..b8e633e 100644
--- a/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java
+++ b/cs-web/src/main/java/com/cf/cs/web/setup/SystemInitial.java
@@ -1,6 +1,6 @@
package com.cf.cs.web.setup;
-import com.cf.cs.web.configure.CommonConfigure;
+import com.cf.cs.base.config.CommonConfigure;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
diff --git a/pom.xml b/pom.xml
index 9e8d250..a10aa51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,6 +25,9 @@
cs-base
cs-crypto
+ cs-protocol
+ cs-database
+ cs-services
cs-web
cs-restful