多模块重构 5:infra 模块的初始化

This commit is contained in:
YunaiV
2022-01-31 13:51:40 +08:00
parent 4bc8dc65b4
commit dc11dfc215
130 changed files with 507 additions and 408 deletions

View File

@@ -1,22 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.controller.file.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ApiModel(value = "文件 Response VO", description = "不返回 content 字段,太大")
@Data
public class InfFileRespVO {
@ApiModelProperty(value = "文件路径", required = true, example = "yudao.jpg")
private String id;
@ApiModelProperty(value = "文件类型", required = true, example = "jpg")
private String type;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@@ -1,15 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.convert.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiAccessLogDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface InfApiAccessLogCoreConvert {
InfApiAccessLogCoreConvert INSTANCE = Mappers.getMapper(InfApiAccessLogCoreConvert.class);
InfApiAccessLogDO convert(ApiAccessLogCreateReqDTO bean);
}

View File

@@ -1,15 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.convert.logger;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface InfApiErrorLogCoreConvert {
InfApiErrorLogCoreConvert INSTANCE = Mappers.getMapper(InfApiErrorLogCoreConvert.class);
InfApiErrorLogDO convert(ApiErrorLogCreateReqDTO bean);
}

View File

@@ -1,6 +0,0 @@
/**
* 提供 POJO 类的实体转换
*
* 目前使用 MapStruct 框架
*/
package cn.iocoder.yudao.coreservice.modules.infra.convert;

View File

@@ -1,64 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.config;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 参数配置表
*
* @author 芋道源码
*/
@TableName("inf_config")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InfConfigDO extends BaseDO {
/**
* 参数主键
*/
@TableId
private Long id;
/**
* 参数分组
*/
@TableField("`group`")
private String group;
/**
* 参数名称
*/
private String name;
/**
* 参数键名
*/
@TableField("`key`")
private String key;
/**
* 参数键值
*/
private String value;
/**
* 参数类型
*
* 枚举 {@link InfConfigTypeEnum}
*/
@TableField("`type`")
private Integer type;
/**
* 是否敏感
*
* 对于敏感配置,需要管理权限才能查看
*/
@TableField("`sensitive`")
private Boolean sensitive;
/**
* 备注
*/
private String remark;
}

View File

@@ -1,44 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.io.InputStream;
/**
* 文件表
*
* @author 芋道源码
*/
@Data
@TableName("inf_file")
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfFileDO extends TenantBaseDO {
/**
* 文件路径
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 文件类型
*
* 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取
*/
@TableField(value = "`type`")
private String type;
/**
* 文件内容
*/
private byte[] content;
}

View File

@@ -1,107 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
/**
* API 访问日志
*
* @author 芋道源码
*/
@TableName("inf_api_access_log")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfApiAccessLogDO extends TenantBaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 链路追踪编号
*
* 一般来说通过链路追踪编号可以将访问日志错误日志链路追踪日志logger 打印日志等,结合在一起,从而进行排错。
*/
private String traceId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*
* 枚举 {@link UserTypeEnum}
*/
private Integer userType;
/**
* 应用名
*
* 目前读取 `spring.application.name` 配置项
*/
private String applicationName;
// ========== 请求相关字段 ==========
/**
* 请求方法名
*/
private String requestMethod;
/**
* 访问地址
*/
private String requestUrl;
/**
* 请求参数
*
* query: Query String
* body: Quest Body
*/
private String requestParams;
/**
* 用户 IP
*/
private String userIp;
/**
* 浏览器 UA
*/
private String userAgent;
// ========== 执行相关字段 ==========
/**
* 开始请求时间
*/
private Date beginTime;
/**
* 结束请求时间
*/
private Date endTime;
/**
* 执行时长,单位:毫秒
*/
private Integer duration;
/**
* 结果码
*
* 目前使用的 {@link CommonResult#getCode()} 属性
*/
private Integer resultCode;
/**
* 结果提示
*
* 目前使用的 {@link CommonResult#getMsg()} 属性
*/
private String resultMsg;
}

View File

@@ -1,154 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger;
import cn.iocoder.yudao.coreservice.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.Date;
/**
* API 异常数据
*
* @author 芋道源码
*/
@TableName("inf_api_error_log")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InfApiErrorLogDO extends TenantBaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 用户编号
*/
private Long userId;
/**
* 链路追踪编号
*
* 一般来说通过链路追踪编号可以将访问日志错误日志链路追踪日志logger 打印日志等,结合在一起,从而进行排错。
*/
private String traceId;
/**
* 用户类型
*
* 枚举 {@link UserTypeEnum}
*/
private Integer userType;
/**
* 应用名
*
* 目前读取 spring.application.name
*/
private String applicationName;
// ========== 请求相关字段 ==========
/**
* 请求方法名
*/
private String requestMethod;
/**
* 访问地址
*/
private String requestUrl;
/**
* 请求参数
*
* query: Query String
* body: Quest Body
*/
private String requestParams;
/**
* 用户 IP
*/
private String userIp;
/**
* 浏览器 UA
*/
private String userAgent;
// ========== 异常相关字段 ==========
/**
* 异常发生时间
*/
private Date exceptionTime;
/**
* 异常名
*
* {@link Throwable#getClass()} 的类全名
*/
private String exceptionName;
/**
* 异常导致的消息
*
* {@link cn.hutool.core.exceptions.ExceptionUtil#getMessage(Throwable)}
*/
private String exceptionMessage;
/**
* 异常导致的根消息
*
* {@link cn.hutool.core.exceptions.ExceptionUtil#getRootCauseMessage(Throwable)}
*/
private String exceptionRootCauseMessage;
/**
* 异常的栈轨迹
*
* {@link org.apache.commons.lang3.exception.ExceptionUtils#getStackTrace(Throwable)}
*/
private String exceptionStackTrace;
/**
* 异常发生的类全名
*
* {@link StackTraceElement#getClassName()}
*/
private String exceptionClassName;
/**
* 异常发生的类文件
*
* {@link StackTraceElement#getFileName()}
*/
private String exceptionFileName;
/**
* 异常发生的方法名
*
* {@link StackTraceElement#getMethodName()}
*/
private String exceptionMethodName;
/**
* 异常发生的方法所在行
*
* {@link StackTraceElement#getLineNumber()}
*/
private Integer exceptionLineNumber;
// ========== 处理相关字段 ==========
/**
* 处理状态
*
* 枚举 {@link InfApiErrorLogProcessStatusEnum}
*/
private Integer processStatus;
/**
* 处理时间
*/
private Date processTime;
/**
* 处理用户编号
*
* 关联 cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO.SysUserDO#getId()
*/
private Long processUserId;
}

View File

@@ -1,39 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.config;
import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO;
import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.util.Date;
import java.util.List;
/**
* ConfigFrameworkDAO Core 实现类
*
* @author 芋道源码
*/
public class InfConfigCoreDAOImpl implements ConfigFrameworkDAO {
private final JdbcTemplate jdbcTemplate;
public InfConfigCoreDAOImpl(String jdbcUrl, String username, String password) {
DataSource dataSource = new DriverManagerDataSource(jdbcUrl, username, password);
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) {
return jdbcTemplate.query("SELECT id FROM inf_config WHERE update_time > ? LIMIT 1",
ResultSet::next, maxUpdateTime);
}
@Override
public List<ConfigRespDTO> selectList() {
return jdbcTemplate.query("SELECT `key`, `value`, update_time, deleted FROM inf_config", new BeanPropertyRowMapper<>(ConfigRespDTO.class));
}
}

View File

@@ -1,28 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.file;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface InfFileCoreMapper extends BaseMapperX<InfFileDO> {
default Integer selectCountById(String id) {
return selectCount(InfFileDO::getId, id);
}
/**
* 基于 Path 获取文件
* 实际上,是基于 ID 查询
* 由于前端使用 <img /> 的方式获取图片,所以需要忽略租户的查询
*
* @param path 路径
* @return 文件
*/
@InterceptorIgnore(tenantLine = "true")
default InfFileDO selectByPath(String path) {
return selectById(path);
}
}

View File

@@ -1,14 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.logger;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiAccessLogDO;
import org.apache.ibatis.annotations.Mapper;
/**
* API 访问日志 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface InfApiAccessLogCoreMapper extends BaseMapperX<InfApiAccessLogDO> {
}

View File

@@ -1,9 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.logger;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface InfApiErrorLogCoreMapper extends BaseMapperX<InfApiErrorLogDO> {
}

View File

@@ -1,16 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* System 错误码枚举类
*
* system 系统,使用 1-006-000-000 段
*/
public interface SysErrorCodeConstants {
// ========= 文件相关 1006001000=================
ErrorCode FILE_PATH_EXISTS = new ErrorCode(1006001000, "文件路径已存在");
ErrorCode FILE_NOT_EXISTS = new ErrorCode(1006001002, "文件不存在");
}

View File

@@ -1,28 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.enums.logger;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* API 异常数据的处理状态
*
* @author 芋道源码
*/
@AllArgsConstructor
@Getter
public enum InfApiErrorLogProcessStatusEnum {
INIT(0, "未处理"),
DONE(1, "已处理"),
IGNORE(2, "已忽略");
/**
* 状态
*/
private final Integer status;
/**
* 资源类型名
*/
private final String name;
}

View File

@@ -1,12 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.framework.file.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 文件 配置类
*/
@Configuration
@EnableConfigurationProperties(FileProperties.class)
public class FileConfiguration {
}

View File

@@ -1,22 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.framework.file.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
@ConfigurationProperties(prefix = "yudao.file")
@Validated
@Data
public class FileProperties {
/**
* 对应 InfFileController 的 getFile 方法
*/
@NotNull(message = "基础文件路径不能为空")
private String basePath;
// TODO 七牛、等等
}

View File

@@ -1,16 +0,0 @@
/**
* 文件的存储,推荐使用七牛、阿里云、华为云、腾讯云等文件服务
*
* 在不采用云服务的情况下,我们有几种技术选型:
* 方案 1. 使用自建的文件服务,例如说 minIO、FastDFS 等等
* 方案 2. 使用服务器的文件系统存储
* 方案 3. 使用数据库进行存储
*
* 如果考虑额外在搭建服务,推荐方案 1。
* 对于方案 2 来说,如果要实现文件存储的高可用,需要多台服务器之间做实时同步,可以基于 rsync + inotify 来做
* 对于方案 3 的话,实现起来最简单,但是数据库本身不适合存储海量的文件
*
* 综合考虑,暂时使用方案 3 的方式,比较适合这样一个 all in one 的项目。
* 随着文件的量级大了之后,还是推荐采用云服务。
*/
package cn.iocoder.yudao.coreservice.modules.infra.framework.file;

View File

@@ -1,7 +0,0 @@
/**
* infra 包下,我们放基础设施的运维与管理,支撑上层的通用与核心业务。
* 例如说:定时任务的管理、服务器的信息等等
*
* 缩写inf
*/
package cn.iocoder.yudao.coreservice.modules.infra;

View File

@@ -1,35 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.file;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
/**
* core service 文件接口
*
* @author 宋天
*/
public interface InfFileCoreService {
/**
* 保存文件,并返回文件的访问路径
*
* @param path 文件路径
* @param content 文件内容
* @return 文件路径
*/
String createFile(String path, byte[] content);
/**
* 删除文件
*
* @param id 编号
*/
void deleteFile(String id);
/**
* 获得文件
*
* @param path 文件路径
* @return 文件
*/
InfFileDO getFile(String path);
}

View File

@@ -1,64 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.file.impl;
import cn.hutool.core.io.FileTypeUtil;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.file.InfFileDO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.file.InfFileCoreMapper;
import cn.iocoder.yudao.coreservice.modules.infra.framework.file.config.FileProperties;
import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import static cn.iocoder.yudao.coreservice.modules.infra.enums.SysErrorCodeConstants.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* core service 文件实现类
*
* @author 宋天
*/
@Service
public class InfFileCoreServiceImpl implements InfFileCoreService {
@Resource
private InfFileCoreMapper fileMapper;
@Resource
private FileProperties fileProperties;
@Override
public String createFile(String path, byte[] content) {
if (fileMapper.selectCountById(path) > 0) {
throw exception(FILE_PATH_EXISTS);
}
// 保存到数据库
InfFileDO file = new InfFileDO();
file.setId(path);
file.setType(FileTypeUtil.getType(new ByteArrayInputStream(content)));
file.setContent(content);
fileMapper.insert(file);
// 拼接路径返回
return fileProperties.getBasePath() + path;
}
@Override
public void deleteFile(String id) {
// 校验存在
this.validateFileExists(id);
// 更新
fileMapper.deleteById(id);
}
private void validateFileExists(String id) {
if (fileMapper.selectById(id) == null) {
throw exception(FILE_NOT_EXISTS);
}
}
@Override
public InfFileDO getFile(String path) {
return fileMapper.selectByPath(path);
}
}

View File

@@ -1,12 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
/**
* API 访问日志 Service 接口
*
* @author 芋道源码
*/
public interface InfApiAccessLogCoreService extends ApiAccessLogFrameworkService {
}

View File

@@ -1,12 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.logger;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
/**
* API 错误日志 Service 接口
*
* @author 芋道源码
*/
public interface InfApiErrorLogCoreService extends ApiErrorLogFrameworkService {
}

View File

@@ -1,35 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.logger.impl;
import cn.iocoder.yudao.coreservice.modules.infra.convert.logger.InfApiAccessLogCoreConvert;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateReqDTO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiAccessLogDO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.logger.InfApiAccessLogCoreMapper;
import cn.iocoder.yudao.coreservice.modules.infra.service.logger.InfApiAccessLogCoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 访问日志 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class InfApiAccessLogCoreServiceImpl implements InfApiAccessLogCoreService {
@Resource
private InfApiAccessLogCoreMapper apiAccessLogMapper;
@Override
@Async
public void createApiAccessLogAsync(ApiAccessLogCreateReqDTO createDTO) {
InfApiAccessLogDO apiAccessLog = InfApiAccessLogCoreConvert.INSTANCE.convert(createDTO);
apiAccessLogMapper.insert(apiAccessLog);
}
}

View File

@@ -1,37 +0,0 @@
package cn.iocoder.yudao.coreservice.modules.infra.service.logger.impl;
import cn.iocoder.yudao.coreservice.modules.infra.convert.logger.InfApiErrorLogCoreConvert;
import cn.iocoder.yudao.coreservice.modules.infra.dal.dataobject.logger.InfApiErrorLogDO;
import cn.iocoder.yudao.coreservice.modules.infra.dal.mysql.logger.InfApiErrorLogCoreMapper;
import cn.iocoder.yudao.coreservice.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum;
import cn.iocoder.yudao.coreservice.modules.infra.service.logger.InfApiErrorLogCoreService;
import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API 错误日志 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
@Slf4j
public class InfApiErrorLogCoreServiceImpl implements InfApiErrorLogCoreService {
@Resource
private InfApiErrorLogCoreMapper apiErrorLogMapper;
@Override
@Async
public void createApiErrorLogAsync(ApiErrorLogCreateReqDTO createDTO) {
InfApiErrorLogDO apiErrorLog = InfApiErrorLogCoreConvert.INSTANCE.convert(createDTO);
apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus());
apiErrorLogMapper.insert(apiErrorLog);
}
}