文件上传下载修正
This commit is contained in:
@@ -23,7 +23,7 @@ CREATE TABLE file.tb_sys_file (
|
||||
type VARCHAR(50) DEFAULT NULL, -- 文件类型
|
||||
storage_type VARCHAR(50) DEFAULT NULL, -- 存储类型
|
||||
mime_type VARCHAR(255) DEFAULT NULL, -- MIME 类型
|
||||
url VARCHAR(500) DEFAULT NULL, -- 文件访问 URL
|
||||
url VARCHAR(500) DEFAULT NULL, -- 后端下载接口路径(保留用于扩展,建议使用 /api/file/download/{fileId})
|
||||
status VARCHAR(50) DEFAULT NULL, -- 文件状态
|
||||
module VARCHAR(100) DEFAULT NULL, -- 所属模块
|
||||
business_id VARCHAR(50) DEFAULT NULL, -- 业务ID
|
||||
@@ -60,7 +60,7 @@ COMMENT ON COLUMN file.tb_sys_file.size IS '文件大小(字节)';
|
||||
COMMENT ON COLUMN file.tb_sys_file.type IS '文件类型';
|
||||
COMMENT ON COLUMN file.tb_sys_file.storage_type IS '存储类型';
|
||||
COMMENT ON COLUMN file.tb_sys_file.mime_type IS 'MIME 类型';
|
||||
COMMENT ON COLUMN file.tb_sys_file.url IS '文件访问 URL';
|
||||
COMMENT ON COLUMN file.tb_sys_file.url IS '后端下载接口路径(保留用于扩展,建议使用 /api/file/download/{fileId})';
|
||||
COMMENT ON COLUMN file.tb_sys_file.status IS '文件状态';
|
||||
COMMENT ON COLUMN file.tb_sys_file.module IS '所属模块';
|
||||
COMMENT ON COLUMN file.tb_sys_file.business_id IS '业务ID';
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.xyzh.api.ai.service.DifyProxyService;
|
||||
import org.xyzh.api.ai.service.KnowledgeService;
|
||||
import org.xyzh.api.ai.dto.TbKnowledge;
|
||||
import org.xyzh.api.ai.dto.TbKnowledgeFile;
|
||||
import org.xyzh.api.ai.vo.KnowledgeFileVO;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.utils.validation.ValidationResult;
|
||||
@@ -161,19 +162,16 @@ public class KnowledgeController {
|
||||
// ====================== 文件管理 ======================
|
||||
|
||||
/**
|
||||
* @description 获取知识库文档列表
|
||||
* @param knowledgeId 知识库id
|
||||
* @description 获取知识库文档列表(含文件详细信息)
|
||||
* @param pageRequest 分页请求
|
||||
* @author yslg
|
||||
* @since 2025-12-18
|
||||
* @since 2025-12-20
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('ai:knowledge:file:view')")
|
||||
@GetMapping("/{knowledgeId}/documents")
|
||||
public ResultDomain<Map<String, Object>> getDocumentList(
|
||||
@PathVariable("knowledgeId") @NotBlank String knowledgeId,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "20") Integer limit) {
|
||||
logger.info("获取文档列表: knowledgeId={}", knowledgeId);
|
||||
return knowledgeService.getDocumentList(knowledgeId, page, limit);
|
||||
@PostMapping("/{knowledgeId}/documents")
|
||||
public ResultDomain<KnowledgeFileVO> getDocumentList(@RequestBody PageRequest<TbKnowledgeFile> pageRequest) {
|
||||
logger.info("获取文档列表: knowledgeId={}", pageRequest.getFilter().getKnowledgeId());
|
||||
return knowledgeService.getDocumentList(pageRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.xyzh.ai.mapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.api.ai.dto.TbKnowledgeFile;
|
||||
import org.xyzh.api.ai.vo.KnowledgeFileVO;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
|
||||
import java.util.List;
|
||||
@@ -41,9 +42,9 @@ public interface TbKnowledgeFileMapper {
|
||||
);
|
||||
|
||||
/**
|
||||
* 根据知识库ID查询文件列表
|
||||
* 根据知识库ID查询文件列表(关联文件详细信息)
|
||||
*/
|
||||
List<TbKnowledgeFile> selectFilesByKnowledgeId(@Param("knowledgeId") String knowledgeId);
|
||||
List<KnowledgeFileVO> selectFilesByKnowledgeId(@Param("knowledgeId") String knowledgeId);
|
||||
|
||||
/**
|
||||
* 根据文件根ID查询所有版本
|
||||
@@ -51,9 +52,9 @@ public interface TbKnowledgeFileMapper {
|
||||
List<TbKnowledgeFile> selectFileVersions(@Param("fileRootId") String fileRootId);
|
||||
|
||||
/**
|
||||
* 分页查询知识库文件
|
||||
* 分页查询知识库文件(关联文件详细信息)
|
||||
*/
|
||||
List<TbKnowledgeFile> selectFilePage(
|
||||
List<KnowledgeFileVO> selectFilePage(
|
||||
@Param("knowledgeId") String knowledgeId,
|
||||
@Param("pageParam") PageParam pageParam
|
||||
);
|
||||
|
||||
@@ -18,11 +18,14 @@ import org.xyzh.api.ai.dto.TbKnowledge;
|
||||
import org.xyzh.api.ai.dto.TbKnowledgeFile;
|
||||
import org.xyzh.api.ai.service.AIFileUploadService;
|
||||
import org.xyzh.api.ai.service.KnowledgeService;
|
||||
import org.xyzh.api.ai.vo.KnowledgeFileVO;
|
||||
import org.xyzh.api.file.dto.TbSysFileDTO;
|
||||
import org.xyzh.api.file.service.FileService;
|
||||
import org.xyzh.common.core.domain.LoginDomain;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.utils.id.IdUtil;
|
||||
import org.xyzh.common.auth.utils.LoginUtil;
|
||||
|
||||
@@ -405,32 +408,43 @@ public class KnowledgeServiceImpl implements KnowledgeService {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取知识库文档列表(从Dify获取)
|
||||
* @param knowledgeId 知识库ID
|
||||
* @param page 页码(从1开始)
|
||||
* @param limit 每页数量
|
||||
* @return ResultDomain<Map<String, Object>> 文档列表
|
||||
* @description 获取知识库文档列表(查询本地数据库文件)
|
||||
* @param pageRequest 分页请求,filter 中包含 knowledgeId
|
||||
* @return ResultDomain<KnowledgeFileVO> 文档列表
|
||||
* @author yslg
|
||||
* @since 2025-12-18
|
||||
* @since 2025-12-20
|
||||
*/
|
||||
@Override
|
||||
public ResultDomain<Map<String, Object>> getDocumentList(String knowledgeId, Integer page, Integer limit) {
|
||||
TbKnowledge knowledge = knowledgeMapper.selectKnowledgeById(knowledgeId);
|
||||
if (knowledge == null || !StringUtils.hasText(knowledge.getDifyDatasetId())) {
|
||||
return ResultDomain.failure("知识库不存在或未关联Dify");
|
||||
public ResultDomain<KnowledgeFileVO> getDocumentList(PageRequest<TbKnowledgeFile> pageRequest) {
|
||||
TbKnowledgeFile filter = pageRequest.getFilter();
|
||||
if (filter == null || !StringUtils.hasText(filter.getKnowledgeId())) {
|
||||
return ResultDomain.failure("知识库ID不能为空");
|
||||
}
|
||||
|
||||
|
||||
String knowledgeId = filter.getKnowledgeId();
|
||||
|
||||
// 验证知识库是否存在
|
||||
TbKnowledge knowledge = knowledgeMapper.selectKnowledgeById(knowledgeId);
|
||||
if (knowledge == null) {
|
||||
return ResultDomain.failure("知识库不存在");
|
||||
}
|
||||
|
||||
try {
|
||||
DocumentListResponse response = difyApiClient.listDocuments(knowledge.getDifyDatasetId(), page, limit);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("data", response.getData());
|
||||
result.put("total", response.getTotal());
|
||||
result.put("page", response.getPage());
|
||||
result.put("limit", response.getLimit());
|
||||
return ResultDomain.success("查询成功", result);
|
||||
// 分页查询知识库文件(已通过 SQL JOIN 关联文件详细信息)
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
List<KnowledgeFileVO> files = knowledgeFileMapper.selectFilePage(knowledgeId, pageParam);
|
||||
long total = knowledgeFileMapper.countFiles(knowledgeId);
|
||||
|
||||
// 设置总数
|
||||
pageParam.setTotal((int) total);
|
||||
|
||||
// 创建分页结果
|
||||
PageDomain<KnowledgeFileVO> pageDomain = new PageDomain<>(pageParam, files);
|
||||
|
||||
return ResultDomain.success("查询成功", pageDomain);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取Dify文档列表失败: {}", e.getMessage(), e);
|
||||
return ResultDomain.failure("获取文档列表失败: " + e.getMessage());
|
||||
logger.error("获取知识库文件列表失败: knowledgeId={}, error={}", knowledgeId, e.getMessage(), e);
|
||||
return ResultDomain.failure("获取文件列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,26 @@
|
||||
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="KnowledgeFileVOResultMap" type="org.xyzh.api.ai.vo.KnowledgeFileVO">
|
||||
<result column="optsn" property="optsn" jdbcType="VARCHAR"/>
|
||||
<result column="knowledge_id" property="knowledgeId" jdbcType="VARCHAR"/>
|
||||
<result column="file_root_id" property="fileRootId" jdbcType="VARCHAR"/>
|
||||
<result column="file_id" property="fileId" jdbcType="VARCHAR"/>
|
||||
<result column="dify_file_id" property="difyFileId" jdbcType="VARCHAR"/>
|
||||
<result column="version" property="version" jdbcType="INTEGER"/>
|
||||
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="delete_time" property="deleteTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
|
||||
<result column="file_name" property="fileName" jdbcType="VARCHAR"/>
|
||||
<result column="file_path" property="filePath" jdbcType="VARCHAR"/>
|
||||
<result column="file_size" property="fileSize" jdbcType="BIGINT"/>
|
||||
<result column="file_mime_type" property="fileMimeType" jdbcType="VARCHAR"/>
|
||||
<result column="file_url" property="fileUrl" jdbcType="VARCHAR"/>
|
||||
<result column="file_extension" property="fileExtension" jdbcType="VARCHAR"/>
|
||||
<result column="file_md5_hash" property="fileMd5Hash" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
optsn, knowledge_id, file_root_id, file_id, dify_file_id, version,
|
||||
create_time, update_time, delete_time, deleted
|
||||
@@ -53,11 +73,21 @@
|
||||
WHERE knowledge_id = #{knowledgeId} AND file_id = #{fileId} AND deleted = false
|
||||
</select>
|
||||
|
||||
<select id="selectFilesByKnowledgeId" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM ai.tb_knowledge_file
|
||||
WHERE knowledge_id = #{knowledgeId} AND deleted = false
|
||||
ORDER BY create_time DESC
|
||||
<select id="selectFilesByKnowledgeId" resultMap="KnowledgeFileVOResultMap">
|
||||
SELECT
|
||||
kf.optsn, kf.knowledge_id, kf.file_root_id, kf.file_id, kf.dify_file_id, kf.version,
|
||||
kf.create_time, kf.update_time, kf.delete_time, kf.deleted,
|
||||
f.name as file_name,
|
||||
f.path as file_path,
|
||||
f.size as file_size,
|
||||
f.mime_type as file_mime_type,
|
||||
f.url as file_url,
|
||||
f.extension as file_extension,
|
||||
f.md5_hash as file_md5_hash
|
||||
FROM ai.tb_knowledge_file kf
|
||||
LEFT JOIN file.tb_sys_file f ON kf.file_id = f.file_id AND f.deleted = false
|
||||
WHERE kf.knowledge_id = #{knowledgeId} AND kf.deleted = false
|
||||
ORDER BY kf.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectFileVersions" resultMap="BaseResultMap">
|
||||
@@ -67,11 +97,21 @@
|
||||
ORDER BY version DESC
|
||||
</select>
|
||||
|
||||
<select id="selectFilePage" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM ai.tb_knowledge_file
|
||||
WHERE knowledge_id = #{knowledgeId} AND deleted = false
|
||||
ORDER BY create_time DESC
|
||||
<select id="selectFilePage" resultMap="KnowledgeFileVOResultMap">
|
||||
SELECT
|
||||
kf.optsn, kf.knowledge_id, kf.file_root_id, kf.file_id, kf.dify_file_id, kf.version,
|
||||
kf.create_time, kf.update_time, kf.delete_time, kf.deleted,
|
||||
f.name as file_name,
|
||||
f.path as file_path,
|
||||
f.size as file_size,
|
||||
f.mime_type as file_mime_type,
|
||||
f.url as file_url,
|
||||
f.extension as file_extension,
|
||||
f.md5_hash as file_md5_hash
|
||||
FROM ai.tb_knowledge_file kf
|
||||
LEFT JOIN file.tb_sys_file f ON kf.file_id = f.file_id AND f.deleted = false
|
||||
WHERE kf.knowledge_id = #{knowledgeId} AND kf.deleted = false
|
||||
ORDER BY kf.create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ import java.util.Map;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.xyzh.api.ai.dto.TbKnowledge;
|
||||
import org.xyzh.api.ai.dto.TbKnowledgeFile;
|
||||
import org.xyzh.api.ai.vo.KnowledgeFileVO;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
|
||||
public interface KnowledgeService {
|
||||
|
||||
@@ -107,15 +109,13 @@ public interface KnowledgeService {
|
||||
// ================================= 文件管理 =================================
|
||||
|
||||
/**
|
||||
* @description 获取知识库文档列表(从Dify获取)
|
||||
* @param knowledgeId 知识库ID
|
||||
* @param page 页码(从1开始)
|
||||
* @param limit 每页数量
|
||||
* @return ResultDomain<Map<String, Object>> 文档列表
|
||||
* @description 获取知识库文档列表(查询本地数据库,关联文件详细信息)
|
||||
* @param pageRequest 分页请求,filter 中包含 knowledgeId
|
||||
* @return ResultDomain<KnowledgeFileVO> 文档列表(含文件详细信息)
|
||||
* @author yslg
|
||||
* @since 2025-12-18
|
||||
* @since 2025-12-20
|
||||
*/
|
||||
ResultDomain<Map<String, Object>> getDocumentList(String knowledgeId, Integer page, Integer limit);
|
||||
ResultDomain<KnowledgeFileVO> getDocumentList(PageRequest<TbKnowledgeFile> pageRequest);
|
||||
|
||||
/**
|
||||
* @description 上传文件到知识库(完整流程:minio + Dify + 数据库)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.xyzh.api.ai.vo;
|
||||
|
||||
import org.xyzh.api.ai.dto.TbKnowledgeFile;
|
||||
import org.xyzh.common.vo.BaseVO;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* @description 知识库文件视图对象(关联文件信息)
|
||||
* @filename KnowledgeFileVO.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "知识库文件视图对象")
|
||||
public class KnowledgeFileVO extends BaseVO {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// TbKnowledgeFile 的字段
|
||||
@Schema(description = "知识库ID")
|
||||
private String knowledgeId;
|
||||
|
||||
@Schema(description = "文件ID")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件根ID")
|
||||
private String fileRootId;
|
||||
|
||||
@Schema(description = "Dify文件ID")
|
||||
private String difyFileId;
|
||||
|
||||
@Schema(description = "文件版本")
|
||||
private Integer version;
|
||||
|
||||
// TbSysFile 的字段
|
||||
@Schema(description = "文件名")
|
||||
private String fileName;
|
||||
|
||||
@Schema(description = "文件路径")
|
||||
private String filePath;
|
||||
|
||||
@Schema(description = "文件大小(字节)")
|
||||
private Long fileSize;
|
||||
|
||||
@Schema(description = "文件MIME类型")
|
||||
private String fileMimeType;
|
||||
|
||||
@Schema(description = "文件访问URL")
|
||||
private String fileUrl;
|
||||
|
||||
@Schema(description = "文件扩展名")
|
||||
private String fileExtension;
|
||||
|
||||
@Schema(description = "文件MD5值")
|
||||
private String fileMd5Hash;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class FileController {
|
||||
|
||||
@Operation(summary = "获取文件信息")
|
||||
@GetMapping("/{fileId}")
|
||||
public ResultDomain<TbSysFileDTO> getFileById(@PathVariable String fileId) {
|
||||
public ResultDomain<TbSysFileDTO> getFileById(@PathVariable("fileId") String fileId) {
|
||||
return fileService.getFileById(fileId);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class FileController {
|
||||
|
||||
@Operation(summary = "下载文件")
|
||||
@GetMapping("/download/{fileId}")
|
||||
public ResponseEntity<byte[]> downloadFile(@PathVariable String fileId) {
|
||||
public ResponseEntity<byte[]> downloadFile(@PathVariable("fileId") String fileId) {
|
||||
ResultDomain<byte[]> result = fileService.downloadFile(fileId);
|
||||
if (!result.getSuccess() || result.getData() == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
@@ -105,7 +105,7 @@ public class FileController {
|
||||
|
||||
@Operation(summary = "删除文件")
|
||||
@DeleteMapping("/{fileId}")
|
||||
public ResultDomain<Boolean> deleteFile(@PathVariable String fileId) {
|
||||
public ResultDomain<Boolean> deleteFile(@PathVariable("fileId") String fileId) {
|
||||
return fileService.deleteFile(fileId);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @param fileId 文件ID
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE file_id = #{fileId} AND deleted = 0")
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE file_id = #{fileId} AND deleted = false")
|
||||
TbSysFileDTO selectByFileId(@Param("fileId") String fileId);
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @param updater 更新者
|
||||
* @return 影响行数
|
||||
*/
|
||||
@Update("UPDATE file.tb_sys_file SET deleted = 1, delete_time = CURRENT_TIMESTAMP, updater = #{updater} WHERE file_id = #{fileId}")
|
||||
@Update("UPDATE file.tb_sys_file SET deleted = true, delete_time = CURRENT_TIMESTAMP, updater = #{updater} WHERE file_id = #{fileId}")
|
||||
int deleteByFileId(@Param("fileId") String fileId, @Param("updater") String updater);
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @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")
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE module = #{module} AND business_id = #{businessId} AND deleted = false ORDER BY create_time DESC")
|
||||
List<TbSysFileDTO> selectByModuleAndBusinessId(@Param("module") String module, @Param("businessId") String businessId);
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @param uploader 上传者用户ID
|
||||
* @return 文件列表
|
||||
*/
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE uploader = #{uploader} AND deleted = 0 ORDER BY create_time DESC")
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE uploader = #{uploader} AND deleted = false ORDER BY create_time DESC")
|
||||
List<TbSysFileDTO> selectByUploader(@Param("uploader") String uploader);
|
||||
|
||||
/**
|
||||
@@ -73,7 +73,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @param md5Hash MD5哈希值
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE md5_hash = #{md5Hash} AND deleted = 0 LIMIT 1")
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE md5_hash = #{md5Hash} AND deleted = false LIMIT 1")
|
||||
TbSysFileDTO selectByMd5Hash(@Param("md5Hash") String md5Hash);
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @param objectName 对象名称
|
||||
* @return 文件信息
|
||||
*/
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE bucket_name = #{bucketName} AND object_name = #{objectName} AND deleted = 0")
|
||||
@Select("SELECT * FROM file.tb_sys_file WHERE bucket_name = #{bucketName} AND object_name = #{objectName} AND deleted = false")
|
||||
TbSysFileDTO selectByMinioObject(@Param("bucketName") String bucketName, @Param("objectName") String objectName);
|
||||
|
||||
/**
|
||||
@@ -92,6 +92,6 @@ public interface FileMapper extends BaseMapper<TbSysFileDTO> {
|
||||
* @author yslg
|
||||
* @since 2025-12-18
|
||||
*/
|
||||
@Select("SELECT MAX(version) FROM file.tb_sys_file WHERE file_root_id = #{fileRootId} AND deleted = 0")
|
||||
@Select("SELECT MAX(version) FROM file.tb_sys_file WHERE file_root_id = #{fileRootId} AND deleted = false")
|
||||
Integer selectMaxVersionByFileRootId(@Param("fileRootId") String fileRootId);
|
||||
}
|
||||
|
||||
@@ -80,20 +80,19 @@ public class FileServiceImpl implements FileService {
|
||||
return ResultDomain.failure("文件上传到MinIO失败");
|
||||
}
|
||||
|
||||
// 构建文件访问URL
|
||||
String fileUrl = minioConfig.buildFileUrl(objectName);
|
||||
|
||||
// 保存到数据库
|
||||
TbSysFileDTO fileDTO = new TbSysFileDTO();
|
||||
String fileId = UUID.randomUUID().toString();
|
||||
fileDTO.setOptsn(UUID.randomUUID().toString());
|
||||
fileDTO.setFileId(UUID.randomUUID().toString());
|
||||
fileDTO.setFileId(fileId);
|
||||
fileDTO.setName(originalFilename);
|
||||
fileDTO.setPath(objectName);
|
||||
fileDTO.setSize(size);
|
||||
fileDTO.setType(extension);
|
||||
fileDTO.setStorageType("MINIO");
|
||||
fileDTO.setMimeType(contentType);
|
||||
fileDTO.setUrl(fileUrl);
|
||||
// URL 设为 NULL,前端通过后端接口 /api/file/download/{fileId} 下载
|
||||
fileDTO.setUrl(null);
|
||||
fileDTO.setStatus("NORMAL");
|
||||
fileDTO.setModule(module);
|
||||
fileDTO.setBusinessId(businessId);
|
||||
@@ -407,24 +406,26 @@ public class FileServiceImpl implements FileService {
|
||||
return ResultDomain.failure("文件上传到MinIO失败");
|
||||
}
|
||||
|
||||
// 生成文件URL
|
||||
String fileUrl = minioConfig.getEndpoint() + "/" + bucketName + "/" + objectName;
|
||||
|
||||
// 创建文件DTO
|
||||
TbSysFileDTO fileDTO = new TbSysFileDTO();
|
||||
String fileId = UUID.randomUUID().toString().replace("-", "");
|
||||
fileDTO.setOptsn(UUID.randomUUID().toString());
|
||||
fileDTO.setFileId(UUID.randomUUID().toString().replace("-", ""));
|
||||
fileDTO.setFileId(fileId);
|
||||
fileDTO.setName(fileName);
|
||||
fileDTO.setPath(objectName);
|
||||
fileDTO.setUrl(fileUrl);
|
||||
// URL 设为 NULL,前端通过后端接口 /api/file/download/{fileId} 下载
|
||||
fileDTO.setUrl(null);
|
||||
fileDTO.setSize(size);
|
||||
fileDTO.setMimeType(contentType);
|
||||
fileDTO.setExtension(extension);
|
||||
fileDTO.setMd5Hash(md5Hash);
|
||||
fileDTO.setModule(module);
|
||||
fileDTO.setBusinessId(businessId);
|
||||
fileDTO.setStorageType("MINIO");
|
||||
fileDTO.setObjectName(objectName);
|
||||
fileDTO.setBucketName(bucketName);
|
||||
fileDTO.setVersion(1);
|
||||
fileDTO.setFileRootId(fileDTO.getFileId());
|
||||
fileDTO.setFileRootId(fileId);
|
||||
fileDTO.setCreateTime(new java.util.Date());
|
||||
|
||||
// 保存到数据库
|
||||
|
||||
@@ -5,18 +5,19 @@ server:
|
||||
# context-path: /urban-lifeline/file # 微服务架构下,context-path由Gateway管理
|
||||
|
||||
# ================== Auth ====================
|
||||
urban-lifeline:
|
||||
auth:
|
||||
enabled: true
|
||||
whitelist:
|
||||
- /swagger-ui/**
|
||||
- /swagger-ui.html
|
||||
- /v3/api-docs/**
|
||||
- /webjars/**
|
||||
- /favicon.ico
|
||||
- /error
|
||||
- /actuator/health
|
||||
- /actuator/info
|
||||
auth:
|
||||
enabled: true
|
||||
gateway-mode: true
|
||||
whitelist:
|
||||
- /swagger-ui/**
|
||||
- /swagger-ui.html
|
||||
- /v3/api-docs/**
|
||||
- /webjars/**
|
||||
- /favicon.ico
|
||||
- /error
|
||||
- /actuator/health
|
||||
- /actuator/info
|
||||
- /file/download/**
|
||||
|
||||
security:
|
||||
aes:
|
||||
|
||||
@@ -172,6 +172,13 @@ auth:
|
||||
- /doc.html
|
||||
- /favicon.ico
|
||||
- /error
|
||||
# 各服务的 Swagger 文档
|
||||
- /urban-lifeline/*/v3/api-docs/**
|
||||
- /urban-lifeline/*/swagger-ui/**
|
||||
# file 服务白名单
|
||||
- /urban-lifeline/file/download/**
|
||||
# ai 服务白名单
|
||||
- /urban-lifeline/ai/chat/**
|
||||
security:
|
||||
aes:
|
||||
secret-key: MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI= # Base64 编码,32字节(256位)
|
||||
|
||||
Reference in New Issue
Block a user