系统配置修改

This commit is contained in:
2025-12-09 18:07:44 +08:00
parent e242ff172c
commit b59babed0a
33 changed files with 1177 additions and 128 deletions

View File

@@ -29,6 +29,10 @@
<groupId>org.xyzh.apis</groupId>
<artifactId>api-file</artifactId>
</dependency>
<dependency>
<groupId>org.xyzh.apis</groupId>
<artifactId>api-system</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>

View File

@@ -0,0 +1,145 @@
package org.xyzh.file.config;
import io.minio.MinioClient;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xyzh.api.system.service.SysConfigService;
import org.apache.dubbo.config.annotation.DubboReference;
import jakarta.annotation.PostConstruct;
/**
* @description MinIO 配置类,从数据库读取配置信息
* @filename MinioConfig.java
* @author yslg
* @copyright yslg
* @since 2025-12-09
*/
@Data
@Component
public class MinioConfig {
private static final Logger logger = LoggerFactory.getLogger(MinioConfig.class);
@DubboReference(version = "1.0.0", group = "system", timeout = 3000, retries = 0)
private SysConfigService sysConfigService;
// MinIO 配置项的键名
private static final String MINIO_ENDPOINT_KEY = "minio.endpoint";
private static final String MINIO_ACCESS_KEY = "minio.accessKey";
private static final String MINIO_SECRET_KEY = "minio.secretKey";
private static final String MINIO_BUCKET_NAME_KEY = "minio.bucketName";
private static final String MINIO_PUBLIC_URL_KEY = "minio.publicUrl";
// 默认值
private static final String DEFAULT_ENDPOINT = "http://localhost:9000";
private static final String DEFAULT_ACCESS_KEY = "minioadmin";
private static final String DEFAULT_SECRET_KEY = "minioadmin123";
private static final String DEFAULT_BUCKET_NAME = "urban-lifeline";
private static final String DEFAULT_PUBLIC_URL = "http://localhost:9000";
// 配置属性
private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;
private String publicUrl;
private MinioClient minioClient;
@PostConstruct
public void init() {
loadConfig();
initClient();
}
/**
* 从数据库加载MinIO配置
*/
private void loadConfig() {
try {
endpoint = sysConfigService.getStringConfig(MINIO_ENDPOINT_KEY);
accessKey = sysConfigService.getStringConfig(MINIO_ACCESS_KEY);
secretKey = sysConfigService.getStringConfig(MINIO_SECRET_KEY);
bucketName = sysConfigService.getStringConfig(MINIO_BUCKET_NAME_KEY);
publicUrl = sysConfigService.getStringConfig(MINIO_PUBLIC_URL_KEY);
// 使用默认值如果配置不存在
if (endpoint == null || endpoint.trim().isEmpty()) {
endpoint = DEFAULT_ENDPOINT;
logger.warn("未找到MinIO endpoint配置使用默认值: {}", DEFAULT_ENDPOINT);
}
if (accessKey == null || accessKey.trim().isEmpty()) {
accessKey = DEFAULT_ACCESS_KEY;
logger.warn("未找到MinIO accessKey配置使用默认值");
}
if (secretKey == null || secretKey.trim().isEmpty()) {
secretKey = DEFAULT_SECRET_KEY;
logger.warn("未找到MinIO secretKey配置使用默认值");
}
if (bucketName == null || bucketName.trim().isEmpty()) {
bucketName = DEFAULT_BUCKET_NAME;
logger.warn("未找到MinIO bucketName配置使用默认值: {}", DEFAULT_BUCKET_NAME);
}
if (publicUrl == null || publicUrl.trim().isEmpty()) {
publicUrl = endpoint; // 默认使用endpoint作为公网访问地址
logger.warn("未找到MinIO publicUrl配置使用endpoint作为默认值: {}", endpoint);
}
logger.info("MinIO配置加载完成 - endpoint: {}, bucketName: {}", endpoint, bucketName);
} catch (Exception e) {
logger.error("加载MinIO配置失败使用默认配置", e);
endpoint = DEFAULT_ENDPOINT;
accessKey = DEFAULT_ACCESS_KEY;
secretKey = DEFAULT_SECRET_KEY;
bucketName = DEFAULT_BUCKET_NAME;
publicUrl = DEFAULT_PUBLIC_URL;
}
}
/**
* 初始化MinIO客户端
*/
private void initClient() {
try {
minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
logger.info("MinIO客户端初始化成功");
} catch (Exception e) {
logger.error("MinIO客户端初始化失败", e);
throw new RuntimeException("MinIO客户端初始化失败", e);
}
}
/**
* 重新加载配置
*/
public void reloadConfig() {
logger.info("重新加载MinIO配置");
loadConfig();
initClient();
}
/**
* 获取MinIO客户端
*/
public MinioClient getMinioClient() {
return minioClient;
}
/**
* 构建文件的公网访问URL
* @param objectName 对象名称
* @return 完整的文件访问URL
*/
public String buildFileUrl(String objectName) {
return publicUrl + "/" + bucketName + "/" + objectName;
}
}

View File

@@ -0,0 +1,87 @@
package org.xyzh.file.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.xyzh.api.file.dto.TbSysFileDTO;
/**
* @description 文件Mapper接口
* @filename FileMapper.java
* @author yslg
* @copyright yslg
* @since 2025-12-09
*/
@Mapper
public interface FileMapper extends BaseMapper<TbSysFileDTO> {
/**
* 根据文件ID查询文件信息自定义方法替代selectById
* @param fileId 文件ID
* @return 文件信息
*/
@Select("SELECT * FROM file.tb_sys_file WHERE file_id = #{fileId} AND deleted = 0")
TbSysFileDTO selectByFileId(@Param("fileId") String fileId);
/**
* 插入文件记录(自定义方法)
* @param fileDTO 文件DTO
* @return 影响行数
*/
int insertFile(TbSysFileDTO fileDTO);
/**
* 根据文件ID更新文件信息自定义方法替代updateById
* @param fileDTO 文件DTO
* @return 影响行数
*/
int updateByFileId(TbSysFileDTO fileDTO);
/**
* 根据文件ID逻辑删除文件自定义方法
* @param fileId 文件ID
* @param updater 更新者
* @return 影响行数
*/
@Update("UPDATE file.tb_sys_file SET deleted = 1, delete_time = CURRENT_TIMESTAMP, updater = #{updater} WHERE file_id = #{fileId}")
int deleteByFileId(@Param("fileId") String fileId, @Param("updater") String updater);
/**
* 根据模块和业务ID查询文件列表
* @param module 模块
* @param businessId 业务ID
* @return 文件列表
*/
@Select("SELECT * FROM file.tb_sys_file WHERE module = #{module} AND business_id = #{businessId} AND deleted = 0 ORDER BY create_time DESC")
List<TbSysFileDTO> selectByModuleAndBusinessId(@Param("module") String module, @Param("businessId") String businessId);
/**
* 根据上传者查询文件列表
* @param uploader 上传者用户ID
* @return 文件列表
*/
@Select("SELECT * FROM file.tb_sys_file WHERE uploader = #{uploader} AND deleted = 0 ORDER BY create_time DESC")
List<TbSysFileDTO> selectByUploader(@Param("uploader") String uploader);
/**
* 根据MD5查询文件用于防重复上传
* @param md5Hash MD5哈希值
* @return 文件信息
*/
@Select("SELECT * FROM file.tb_sys_file WHERE md5_hash = #{md5Hash} AND deleted = 0 LIMIT 1")
TbSysFileDTO selectByMd5Hash(@Param("md5Hash") String md5Hash);
/**
* 根据MinIO对象名称查询文件
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @return 文件信息
*/
@Select("SELECT * FROM file.tb_sys_file WHERE bucket_name = #{bucketName} AND object_name = #{objectName} AND deleted = 0")
TbSysFileDTO selectByMinioObject(@Param("bucketName") String bucketName, @Param("objectName") String objectName);
}

View File

@@ -0,0 +1,307 @@
package org.xyzh.file.service.impl;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.beans.BeanUtils; // 不再需要BeanUtils
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import org.xyzh.api.file.dto.TbSysFileDTO;
import org.xyzh.api.file.service.FileService;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.file.config.MinioConfig;
import org.xyzh.file.mapper.FileMapper;
import org.xyzh.file.util.MinioUtil;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @description 文件服务实现类
* @filename FileServiceImpl.java
* @author yslg
* @copyright yslg
* @since 2025-12-09
*/
@DubboService(
version = "1.0.0",
group = "file",
timeout = 3000,
retries = 0
)
public class FileServiceImpl implements FileService {
private static final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
@Autowired
private MinioConfig minioConfig;
@Autowired
private MinioUtil minioUtil;
@Autowired
private FileMapper fileMapper;
@Override
public ResultDomain<TbSysFileDTO> uploadFile(MultipartFile file, String module, String businessId) {
try {
if (file == null || file.isEmpty()) {
return ResultDomain.failure("文件不能为空");
}
// 生成文件信息
String originalFilename = file.getOriginalFilename();
String extension = getFileExtension(originalFilename);
String contentType = file.getContentType();
long size = file.getSize();
// 生成唯一的对象名称
String objectName = generateObjectName(originalFilename, module);
// 计算文件MD5
String md5Hash = calculateMD5(file.getBytes());
// 上传到MinIO
String bucketName = minioConfig.getBucketName();
boolean uploadSuccess = minioUtil.uploadFile(
bucketName,
objectName,
file.getInputStream(),
size,
contentType
);
if (!uploadSuccess) {
return ResultDomain.failure("文件上传到MinIO失败");
}
// 构建文件访问URL
String fileUrl = minioConfig.buildFileUrl(objectName);
// 保存到数据库
TbSysFileDTO fileDTO = new TbSysFileDTO();
fileDTO.setOptsn(UUID.randomUUID().toString());
fileDTO.setFileId(UUID.randomUUID().toString());
fileDTO.setName(originalFilename);
fileDTO.setPath(objectName);
fileDTO.setSize(size);
fileDTO.setType(extension);
fileDTO.setStorageType("MINIO");
fileDTO.setMimeType(contentType);
fileDTO.setUrl(fileUrl);
fileDTO.setStatus("NORMAL");
fileDTO.setModule(module);
fileDTO.setBusinessId(businessId);
fileDTO.setObjectName(objectName);
fileDTO.setBucketName(bucketName);
fileDTO.setMd5Hash(md5Hash);
fileDTO.setExtension(extension);
fileDTO.setCreateTime(new java.util.Date());
int result = fileMapper.insertFile(fileDTO);
if (result <= 0) {
// 如果数据库保存失败删除MinIO中的文件
minioUtil.deleteFile(bucketName, objectName);
return ResultDomain.failure("文件信息保存失败");
}
logger.info("文件上传成功: {}, 大小: {} bytes", originalFilename, size);
return ResultDomain.success("文件上传成功", fileDTO);
} catch (Exception e) {
logger.error("文件上传失败", e);
return ResultDomain.failure("文件上传失败: " + e.getMessage());
}
}
@Override
public ResultDomain<TbSysFileDTO> batchUploadFiles(MultipartFile[] files, String module, String businessId, String uploader) {
try {
if (files == null || files.length == 0) {
return ResultDomain.failure("文件列表不能为空");
}
List<TbSysFileDTO> uploadedFiles = new ArrayList<>();
for (MultipartFile file : files) {
ResultDomain<TbSysFileDTO> result = uploadFile(file, module, businessId);
if (result.getSuccess()) {
TbSysFileDTO fileDTO = result.getData();
fileDTO.setUploader(uploader);
uploadedFiles.add(fileDTO);
} else {
// 如果有文件上传失败,记录日志但继续处理其他文件
logger.warn("文件上传失败: {}, 原因: {}", file.getOriginalFilename(), result.getMessage());
}
}
if (uploadedFiles.isEmpty()) {
return ResultDomain.failure("所有文件上传失败");
}
// 返回上传成功的文件列表(这里简化处理,实际可能需要返回详细结果)
TbSysFileDTO resultDTO = new TbSysFileDTO();
// 可以在这里设置批量上传的汇总信息
logger.info("批量文件上传完成,成功: {}, 总数: {}", uploadedFiles.size(), files.length);
return ResultDomain.success("批量文件上传成功", resultDTO);
} catch (Exception e) {
logger.error("批量文件上传失败", e);
return ResultDomain.failure("批量文件上传失败: " + e.getMessage());
}
}
@Override
public ResultDomain<Boolean> deleteFile(String fileId) {
try {
// 从数据库获取文件信息
TbSysFileDTO sysFile = fileMapper.selectByFileId(fileId);
if (sysFile == null) {
return ResultDomain.failure("文件不存在");
}
// 删除MinIO中的文件
minioUtil.deleteFile(sysFile.getBucketName(), sysFile.getObjectName());
// 逻辑删除数据库记录
int result = fileMapper.deleteByFileId(fileId, "system");
if (result > 0) {
logger.info("文件删除成功: {}", fileId);
return ResultDomain.success("文件删除成功", true);
} else {
return ResultDomain.failure("文件删除失败");
}
} catch (Exception e) {
logger.error("文件删除失败: {}", fileId, e);
return ResultDomain.failure("文件删除失败: " + e.getMessage());
}
}
@Override
public ResultDomain<TbSysFileDTO> batchDeleteFiles(String[] fileIds) {
try {
if (fileIds == null || fileIds.length == 0) {
return ResultDomain.failure("文件ID列表不能为空");
}
int successCount = 0;
for (String fileId : fileIds) {
ResultDomain<Boolean> result = deleteFile(fileId);
if (result.getSuccess()) {
successCount++;
}
}
TbSysFileDTO resultDTO = new TbSysFileDTO();
// 可以在这里设置批量删除的结果统计
logger.info("批量文件删除完成,成功: {}, 总数: {}", successCount, fileIds.length);
return ResultDomain.success("批量文件删除完成", resultDTO);
} catch (Exception e) {
logger.error("批量文件删除失败", e);
return ResultDomain.failure("批量文件删除失败: " + e.getMessage());
}
}
@Override
public ResultDomain<byte[]> downloadFile(String fileId) {
try {
// 从数据库获取文件信息
TbSysFileDTO sysFile = fileMapper.selectByFileId(fileId);
if (sysFile == null) {
return ResultDomain.failure("文件不存在");
}
// 从MinIO下载文件
InputStream inputStream = minioUtil.downloadFile(sysFile.getBucketName(), sysFile.getObjectName());
if (inputStream == null) {
return ResultDomain.failure("文件下载失败");
}
// 将输入流转换为字节数组
byte[] data = inputStream.readAllBytes();
inputStream.close();
logger.info("文件下载成功: {}", fileId);
return ResultDomain.success("文件下载成功", data);
} catch (Exception e) {
logger.error("文件下载失败: {}", fileId, e);
return ResultDomain.failure("文件下载失败: " + e.getMessage());
}
}
@Override
public ResultDomain<TbSysFileDTO> getFileById(String fileId) {
try {
TbSysFileDTO sysFile = fileMapper.selectByFileId(fileId);
if (sysFile == null) {
return ResultDomain.failure("文件不存在");
}
return ResultDomain.success("获取文件信息成功", sysFile);
} catch (Exception e) {
logger.error("查询文件失败: {}", fileId, e);
return ResultDomain.failure("查询文件失败: " + e.getMessage());
}
}
@Override
public ResultDomain<TbSysFileDTO> saveTempFile(MultipartFile file, String module, String businessId) {
try {
// 临时文件上传逻辑与普通上传相同,但可以添加特殊标识
ResultDomain<TbSysFileDTO> result = uploadFile(file, module, businessId);
if (result.getSuccess()) {
TbSysFileDTO fileDTO = result.getData();
fileDTO.setStatus("TEMP"); // 标记为临时文件
// 更新数据库中的状态
fileMapper.updateByFileId(fileDTO);
}
return result;
} catch (Exception e) {
logger.error("临时文件保存失败", e);
return ResultDomain.failure("临时文件保存失败: " + e.getMessage());
}
}
/**
* 生成唯一的对象名称
*/
private String generateObjectName(String originalFilename, String module) {
String extension = getFileExtension(originalFilename);
String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
String uuid = UUID.randomUUID().toString().replace("-", "");
return String.format("%s/%s/%s%s", module, date, uuid, extension);
}
/**
* 获取文件扩展名
*/
private String getFileExtension(String filename) {
if (filename == null || !filename.contains(".")) {
return "";
}
return filename.substring(filename.lastIndexOf("."));
}
/**
* 计算文件MD5值
*/
private String calculateMD5(byte[] data) {
return DigestUtils.md5DigestAsHex(data);
}
}

View File

@@ -0,0 +1,222 @@
package org.xyzh.file.util;
import io.minio.*;
import io.minio.http.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xyzh.file.config.MinioConfig;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
/**
* @description MinIO 工具类
* @filename MinioUtil.java
* @author yslg
* @copyright yslg
* @since 2025-12-09
*/
@Component
public class MinioUtil {
private static final Logger logger = LoggerFactory.getLogger(MinioUtil.class);
@Autowired
private MinioConfig minioConfig;
/**
* 检查存储桶是否存在,如果不存在则创建
* @param bucketName 存储桶名称
* @return true 成功false 失败
*/
public boolean createBucketIfNotExists(String bucketName) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
// 检查存储桶是否存在
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder()
.bucket(bucketName)
.build());
if (!exists) {
// 创建存储桶
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
logger.info("成功创建存储桶: {}", bucketName);
}
return true;
} catch (Exception e) {
logger.error("创建存储桶失败: {}", bucketName, e);
return false;
}
}
/**
* 上传文件到MinIO
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @param inputStream 文件输入流
* @param size 文件大小
* @param contentType 文件类型
* @return true 成功false 失败
*/
public boolean uploadFile(String bucketName, String objectName, InputStream inputStream, long size, String contentType) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
// 确保存储桶存在
if (!createBucketIfNotExists(bucketName)) {
return false;
}
// 上传文件
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, size, -1)
.contentType(contentType)
.build());
logger.info("文件上传成功: {}/{}", bucketName, objectName);
return true;
} catch (Exception e) {
logger.error("文件上传失败: {}/{}", bucketName, objectName, e);
return false;
}
}
/**
* 上传字节数组到MinIO
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @param data 字节数组
* @param contentType 文件类型
* @return true 成功false 失败
*/
public boolean uploadFile(String bucketName, String objectName, byte[] data, String contentType) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(data)) {
return uploadFile(bucketName, objectName, inputStream, data.length, contentType);
} catch (IOException e) {
logger.error("创建字节数组输入流失败", e);
return false;
}
}
/**
* 下载文件
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @return 文件输入流失败返回null
*/
public InputStream downloadFile(String bucketName, String objectName) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
return minioClient.getObject(GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
} catch (Exception e) {
logger.error("文件下载失败: {}/{}", bucketName, objectName, e);
return null;
}
}
/**
* 删除文件
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @return true 成功false 失败
*/
public boolean deleteFile(String bucketName, String objectName) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
minioClient.removeObject(RemoveObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
logger.info("文件删除成功: {}/{}", bucketName, objectName);
return true;
} catch (Exception e) {
logger.error("文件删除失败: {}/{}", bucketName, objectName, e);
return false;
}
}
/**
* 获取文件的预签名URL用于临时访问
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @param expiry 过期时间(秒)
* @return 预签名URL失败返回null
*/
public String getPresignedUrl(String bucketName, String objectName, int expiry) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName)
.object(objectName)
.expiry(expiry, TimeUnit.SECONDS)
.build());
} catch (Exception e) {
logger.error("生成预签名URL失败: {}/{}", bucketName, objectName, e);
return null;
}
}
/**
* 检查文件是否存在
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @return true 存在false 不存在
*/
public boolean fileExists(String bucketName, String objectName) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
minioClient.statObject(StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取文件信息
* @param bucketName 存储桶名称
* @param objectName 对象名称
* @return 文件信息失败返回null
*/
public StatObjectResponse getFileInfo(String bucketName, String objectName) {
try {
MinioClient minioClient = minioConfig.getMinioClient();
return minioClient.statObject(StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
} catch (Exception e) {
logger.error("获取文件信息失败: {}/{}", bucketName, objectName, e);
return null;
}
}
}

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.xyzh.file.mapper.FileMapper">
<!-- 文件信息结果映射 -->
<resultMap id="fileResultMap" type="org.xyzh.api.file.dto.TbSysFileDTO">
<!-- 主键字段必须在最前面 -->
<id column="file_id" property="fileId"/>
<!-- BaseDTO 字段 -->
<result column="optsn" property="optsn"/>
<result column="creator" property="creator"/>
<result column="updater" property="updater"/>
<result column="dept_path" property="deptPath"/>
<result column="remark" property="remark"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="delete_time" property="deleteTime"/>
<result column="deleted" property="deleted"/>
<!-- TbSysFileDTO 特有字段 -->
<result column="name" property="name"/>
<result column="path" property="path"/>
<result column="size" property="size"/>
<result column="type" property="type"/>
<result column="storage_type" property="storageType"/>
<result column="mime_type" property="mimeType"/>
<result column="url" property="url"/>
<result column="status" property="status"/>
<result column="module" property="module"/>
<result column="business_id" property="businessId"/>
<result column="uploader" property="uploader"/>
<result column="object_name" property="objectName"/>
<result column="bucket_name" property="bucketName"/>
<result column="md5_hash" property="md5Hash"/>
<result column="extension" property="extension"/>
</resultMap>
<!-- 插入文件记录 -->
<insert id="insertFile" parameterType="org.xyzh.api.file.dto.TbSysFileDTO">
INSERT INTO file.tb_sys_file (
<!-- 必填字段无默认值的NOT NULL字段 -->
optsn, file_id, name, path, size
<!-- 可选字段(包括有默认值的字段) -->
<if test="creator != null">, creator</if>
<if test="updater != null">, updater</if>
<if test="deptPath != null">, dept_path</if>
<if test="remark != null">, remark</if>
<if test="createTime != null">, create_time</if>
<if test="updateTime != null">, update_time</if>
<if test="deleteTime != null">, delete_time</if>
<if test="deleted != null">, deleted</if>
<if test="type != null">, type</if>
<if test="storageType != null">, storage_type</if>
<if test="mimeType != null">, mime_type</if>
<if test="url != null">, url</if>
<if test="status != null">, status</if>
<if test="module != null">, module</if>
<if test="businessId != null">, business_id</if>
<if test="uploader != null">, uploader</if>
<if test="objectName != null">, object_name</if>
<if test="bucketName != null">, bucket_name</if>
<if test="md5Hash != null">, md5_hash</if>
<if test="extension != null">, extension</if>
) VALUES (
<!-- 必填字段值 -->
#{optsn}, #{fileId}, #{name}, #{path}, #{size}
<!-- 可选字段值 -->
<if test="creator != null">, #{creator}</if>
<if test="updater != null">, #{updater}</if>
<if test="deptPath != null">, #{deptPath}</if>
<if test="remark != null">, #{remark}</if>
<if test="createTime != null">, #{createTime}</if>
<if test="updateTime != null">, #{updateTime}</if>
<if test="deleteTime != null">, #{deleteTime}</if>
<if test="deleted != null">, #{deleted}</if>
<if test="type != null">, #{type}</if>
<if test="storageType != null">, #{storageType}</if>
<if test="mimeType != null">, #{mimeType}</if>
<if test="url != null">, #{url}</if>
<if test="status != null">, #{status}</if>
<if test="module != null">, #{module}</if>
<if test="businessId != null">, #{businessId}</if>
<if test="uploader != null">, #{uploader}</if>
<if test="objectName != null">, #{objectName}</if>
<if test="bucketName != null">, #{bucketName}</if>
<if test="md5Hash != null">, #{md5Hash}</if>
<if test="extension != null">, #{extension}</if>
)
</insert>
<!-- 根据文件ID更新文件信息 -->
<update id="updateByFileId" parameterType="org.xyzh.api.file.dto.TbSysFileDTO">
UPDATE file.tb_sys_file
<set>
<if test="updater != null">updater = #{updater},</if>
<if test="deptPath != null">dept_path = #{deptPath},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = CURRENT_TIMESTAMP,
<if test="name != null">name = #{name},</if>
<if test="path != null">path = #{path},</if>
<if test="size != null">size = #{size},</if>
<if test="type != null">type = #{type},</if>
<if test="storageType != null">storage_type = #{storageType},</if>
<if test="mimeType != null">mime_type = #{mimeType},</if>
<if test="url != null">url = #{url},</if>
<if test="status != null">status = #{status},</if>
<if test="module != null">module = #{module},</if>
<if test="businessId != null">business_id = #{businessId},</if>
<if test="uploader != null">uploader = #{uploader},</if>
<if test="objectName != null">object_name = #{objectName},</if>
<if test="bucketName != null">bucket_name = #{bucketName},</if>
<if test="md5Hash != null">md5_hash = #{md5Hash},</if>
<if test="extension != null">extension = #{extension}</if>
</set>
WHERE file_id = #{fileId} AND ( deleted IS NULL OR deleted = false)
</update>
</mapper>