1. 备份代码

This commit is contained in:
黄昕 2024-03-06 18:17:09 +08:00
parent aa98887053
commit 4c84457475
74 changed files with 3648 additions and 15 deletions

View File

@ -66,7 +66,7 @@ mybatis :
mapper-locations : classpath*:mappers/*.xml mapper-locations : classpath*:mappers/*.xml
type-aliases-package: com.cmhi.gds.pojo.entry type-aliases-package: com.cmhi.gds.pojo.entry
configuration : configuration :
default-enum-type-handler: com.cmhi.cf.common.CommonEnumHandler default-enum-type-handler: com.cf.cs.database.common.DataBaseEnumHandler
mybatis-flex: mybatis-flex:
global-config: global-config:

View File

@ -27,7 +27,16 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<dependency> <dependency>
<groupId>com.houkunlin</groupId> <groupId>com.houkunlin</groupId>
<artifactId>system-dict-starter</artifactId> <artifactId>system-dict-starter</artifactId>
@ -40,7 +49,6 @@
<version>23.0.0</version> <version>23.0.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -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 ""; // 操作说明
}

View File

@ -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.cf.cs.base.common.CachePool;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;

View File

@ -1,4 +1,4 @@
package com.cf.cs.web.configure; package com.cf.cs.base.config;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;

View File

@ -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<ApiContext> 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();
}
}

View File

@ -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;
}

View File

@ -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 {
}

View File

@ -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 {
}

75
cs-database/pom.xml Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf.cs</groupId>
<artifactId>IntegrateService</artifactId>
<version>0.0.1-dev</version>
</parent>
<artifactId>cs-database</artifactId>
<name>cs-database</name>
<description>cs-database</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>6.2.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot3-starter</artifactId>
<version>1.7.8</version>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<version>1.7.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-base</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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 <E> the type parameter
* @author xajhuang @163.com
*/
public class DataBaseEnumHandler<E extends BaseEnum> extends BaseTypeHandler<E> {
private final Class<E> enumType;
private final List<E> enums;
/**
* Instantiates a new Data base enum handler.
*
* @param type the type
*/
public DataBaseEnumHandler(Class<E> 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);
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<DictData> {
}

View File

@ -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<DictType> {
}

View File

@ -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<OperationLog> {
}

View File

@ -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<ResourceData> {
}

View File

@ -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<ResourceType> {
}

View File

@ -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<Role> {
}

View File

@ -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<RoleResource> {
}

View File

@ -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<UserCredential> {
}

View File

@ -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<User> {
/**
* 批量新增或按主键更新数据MyBatis原生foreach方法
*
* @param entities List<User> 实例对象列表
* @return 影响行数
* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常请自行校验入参
*/
int insertOrUpdateBatch(@Param("entities") List<User> entities);
}

View File

@ -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;
}

View File

@ -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<DictData> dictDataList;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<T> {
private List<T> items;
private long pageNumber;
private long pageSize;
private long totalPage;
private long totalRow;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<OperationLog> {
/**
* 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<OperationLogSummary> getSystemOperationSummary(Long pageNumber, Long pageSize, Long totalSize, List<String> userName);
/**
* Gets system operation details.
*
* @param operationId the operation id
* @return the system operation details
*/
List<OperationLogDetails> getSystemOperationDetails(List<Long> operationId);
}

View File

@ -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> {
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<UserInfo> getAllUserInfo(Long pageNumber, Long pageSize, Long totalSize);
List<ResPermInfo> getCurrentUserResourcePerm();
List<ResPermInfo> getUserResourcePerm(Long userId);
}

View File

@ -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<OperationLogMapper, OperationLog> 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<OperationLogSummary> getSystemOperationSummary(Long pageNumber,
Long pageSize,
Long totalSize,
List<String> userName) {
QueryWrapper wrapper;
ApiContext ctx = ApiContextUtils.get();
String username = ctx.getUsername();
// 当前已经有合法的认证用户
if (HelperUtils.stringNotEmptyOrNull(username)) {
if (userName != null && !userName.isEmpty()) {
List<Long> 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<OperationLogDetails> getSystemOperationDetails(List<Long> 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) {
}
}
}

View File

@ -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<UserMapper, User> implements UserDataBaseService {
private final Map<Integer, String> 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<UserInfo> getAllUserInfo(Long pageNumber, Long pageSize, Long totalSize) {
QueryWrapper wrapper = QueryWrapper.create().from(USER).select();
List<UserInfo> ui = new ArrayList<>();
Page<User> 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.<UserInfo>builder()
.items(ui)
.pageNumber(user.getPageNumber())
.pageSize(user.getPageSize())
.totalPage(user.getTotalPage())
.totalRow(user.getTotalRow())
.build();
}
@Override
public List<ResPermInfo> getCurrentUserResourcePerm() {
List<ResourceData> 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<ResPermInfo> result = new ArrayList<>();
QueryWrapper wrapper = QueryWrapper.create().from(ROLE_RESOURCE).select().where(
ROLE_RESOURCE.ROLE_ID.eq(user.getId()));
List<RoleResource> 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<ResPermInfo> getUserResourcePerm(Long userId) {
List<ResourceData> 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<ResPermInfo> result = new ArrayList<>();
wrapper = QueryWrapper.create().from(ROLE_RESOURCE).select().where(ROLE_RESOURCE.ROLE_ID.eq(user.getId()));
List<RoleResource> 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());
}
});
// 可以在这里进行一些初始化操作如初始化参数加载数据等
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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() {
}
}

43
cs-protocol/pom.xml Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf.cs</groupId>
<artifactId>IntegrateService</artifactId>
<version>0.0.1-dev</version>
</parent>
<artifactId>cs-protocol</artifactId>
<name>cs-protocol</name>
<description>cs-protocol</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-base</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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 <T> the type parameter
* @author xajhuang @163.com
*/
@Data
@NoArgsConstructor
@JsonPropertyOrder({"ver", "cryptoType", "timeStamp", "msgContent"})
@JsonIgnoreProperties
@JsonInclude(JsonInclude.Include.NON_NULL)
public class BaseProtocol<T> 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;
}

View File

@ -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()};
}

View File

@ -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;
}

View File

@ -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 <T> 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<T> extends BaseProtocol<T> {
private Integer code;
private static <T> ProtocolResp<T> result(ErrorCode err, Integer httpCode, T respMsg) {
ProtocolResp<T> 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 <T> the type parameter
* @param err the err
* @param respMsg the resp msg
* @return the protocol resp
*/
public static <T> ProtocolResp<T> 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<BaseRespStatus> result(ErrorCode err) {
BaseRespStatus rspMsg = new BaseRespStatus(err.getCode(), new String[] {err.getDescription()});
return result(err, err.getHttpCode(), rspMsg);
}
/**
* Result protocol resp.
*
* @param <T> the type parameter
* @param respMsg the resp msg
* @return the protocol resp
*/
public static <T extends BaseRespStatus> ProtocolResp<T> 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<BaseRespStatus> result(ErrorCode errCode, Integer httpCode, String[] message) {
BaseRespStatus rspMsg = new BaseRespStatus(errCode.getCode(), message);
return result(errCode, httpCode, rspMsg);
}
}

View File

@ -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;
}

View File

@ -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 {}
}

View File

@ -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 <huangxin@cmhi.chinamoblie.com>
*/
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 {
}
}

View File

@ -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 {};
}

View File

@ -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 {};
}

View File

@ -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 {};
}

View File

@ -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 {};
}

View File

@ -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<ValidHttpMethod, List<String>> {
@Override
public void initialize(ValidHttpMethod constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(List<String> 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;
}
}

View File

@ -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<ValidPageSize, Long> {
@Override
public void initialize(ValidPageSize constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(Long pageSize, ConstraintValidatorContext constraintValidatorContext) {
return pageSize % 5 == 0;
}
}

View File

@ -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<ValidProtocolTimestamp, Long> {
@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;
}
}

View File

@ -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() {
}
}

View File

@ -21,13 +21,22 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
@ -40,6 +49,30 @@
<version>2.3.0</version> <version>2.3.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-database</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-protocol</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-crypto</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.cf.cs</groupId>
<artifactId>cs-services</artifactId>
<version>${cs-package.version}</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.cf.cs</groupId> <groupId>com.cf.cs</groupId>
<artifactId>cs-web</artifactId> <artifactId>cs-web</artifactId>

View File

@ -8,7 +8,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* *
* @author xajhuang @163.com * @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 { public class CsRestfulApplication {
/** /**

View File

@ -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());
}
}

38
cs-services/pom.xml Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf.cs</groupId>
<artifactId>IntegrateService</artifactId>
<version>0.0.1-dev</version>
</parent>
<artifactId>cs-services</artifactId>
<name>cs-services</name>
<description>cs-services</description>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -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);
}
}

View File

@ -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() {
}
}

View File

@ -16,15 +16,9 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<dependency> <dependency>
<groupId>com.cf.cs</groupId> <groupId>com.cf.cs</groupId>
<artifactId>cs-base</artifactId> <artifactId>cs-base</artifactId>

View File

@ -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<String, String> 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<String> 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));
}
}

View File

@ -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);
}
}
}

View File

@ -1,6 +1,6 @@
package com.cf.cs.web.setup; 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 lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -25,6 +25,9 @@
<modules> <modules>
<module>cs-base</module> <module>cs-base</module>
<module>cs-crypto</module> <module>cs-crypto</module>
<module>cs-protocol</module>
<module>cs-database</module>
<module>cs-services</module>
<module>cs-web</module> <module>cs-web</module>
<module>cs-restful</module> <module>cs-restful</module>
</modules> </modules>