This commit is contained in:
2026-02-03 22:43:26 +08:00
18 changed files with 613 additions and 8 deletions

View File

@@ -0,0 +1,72 @@
package com.sdm.common.entity.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 文件字典标签枚举
* 固定配置文件元数据响应中需要填充的字典标签字段映射关系
*
* 映射关系:
* - disciplineTypeDictClass/disciplineDictValue → DISCIPLINE_TYPE
* - fileTypeDictClass/fileTypeDictValue → ALL_FILE_TYPE
*/
@Getter
@AllArgsConstructor
public enum FileDictTagEnum {
/**
* 学科类型标签
* 字段: disciplineTypeDictClass, disciplineDictValue
* dictClass: DISCIPLINE_TYPE
*/
DISCIPLINE_TYPE("DISCIPLINE_TYPE", "disciplineTypeDictClass", "disciplineDictValue"),
/**
* 文件类型标签
* 字段: fileTypeDictClass, fileTypeDictValue
* dictClass: ALL_FILE_TYPE
*/
FILE_TYPE("ALL_FILE_TYPE", "fileTypeDictClass", "fileTypeDictValue");
/**
* 字典分类(对应数据库中的 dictClass
*/
private final String dictClass;
/**
* dictClass 字段名(完整字段名,如 disciplineTypeDictClass
*/
private final String dictClassFieldName;
/**
* dictValue 字段名(完整字段名,如 disciplineDictValue
*/
private final String dictValueFieldName;
/**
* 根据 dictClass 获取对应的枚举
* @param dictClass 字典分类
* @return 对应的枚举,如果不存在则返回 null
*/
public static FileDictTagEnum getByDictClass(String dictClass) {
if (dictClass == null) {
return null;
}
for (FileDictTagEnum enumItem : values()) {
if (enumItem.getDictClass().equals(dictClass)) {
return enumItem;
}
}
return null;
}
/**
* 判断是否为配置的字典分类
* @param dictClass 字典分类
* @return 是否配置
*/
public static boolean isConfigured(String dictClass) {
return getByDictClass(dictClass) != null;
}
}

View File

@@ -9,6 +9,9 @@ import java.util.Map;
@Data
@Schema(description = "字典标签查询请求")
public class DictTagReq {
@Schema(description = "字典ID", example = "1234")
private Integer dictId;
@Schema(description = "字典类型", example = "file_type")
private String dictClass;
@@ -27,4 +30,11 @@ public class DictTagReq {
@Schema(description = "字典标签查询项列表")
private List<DictTagReq> items;
}
@Data
@Schema(description = "批量查询字典详情请求")
public static class BatchDictQueryReq {
@Schema(description = "字典标签查询项列表")
private List<DictTagReq> items;
}
}

View File

@@ -1,5 +1,6 @@
package com.sdm.common.entity.resp.data;
import com.alibaba.fastjson2.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -11,6 +12,7 @@ import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* 文件元数据传输对象(用于接口返回给前端)
@@ -61,6 +63,21 @@ public class FileMetadataInfoResp extends BaseResp implements Serializable {
@Schema(description= "文件业务类型1模型文件 2仿真报告、3计算文件、4曲线文件、5云图文件6网格文件7计算过程文件")
private Integer fileType;
// ----------------------------------------------------------------
// 很重要,用于设置标签
@Schema(description = "文件类型字典类")
private String fileTypeDictClass;
@Schema(description = "文件类型字典值")
private String fileTypeDictValue;
@Schema(description = "学科类型字典类")
private String disciplineTypeDictClass;
@Schema(description = "学科类型字典值")
private String disciplineDictValue;
// ----------------------------------------------------------------
@Schema(description = "数据类型1-文件2-文件夹")
private Integer dataType;

View File

@@ -49,4 +49,19 @@ public class SysConfigFeignClientImpl implements ISysConfigFeignClient {
return SdmResponse.failed("字典信息未查询");
}
}
@Override
public SdmResponse<List<DataDictionary>> batchQueryDictionaries(DictTagReq.BatchDictQueryReq req) {
SdmResponse<List<DataDictionary>> sdmResponse;
try {
sdmResponse = sysConfigFeignClient.batchQueryDictionaries(req);
if(!sdmResponse.isSuccess() ||ObjectUtils.isEmpty(sdmResponse.getData())){
return SdmResponse.failed("字典信息未查询");
}
return sdmResponse;
} catch (Exception e) {
log.error("字典信息失败", e);
return SdmResponse.failed("字典信息未查询");
}
}
}

View File

@@ -22,4 +22,12 @@ public interface ISysConfigFeignClient {
@PostMapping(value = "/systemData/multiDictionaryIds")
SdmResponse<Map<String, Map<String, Integer>>> multiQueryDictionaryIds(@RequestBody DictTagReq.BatchDictIdQueryReq req);
/**
* 批量查询字典详情(根据 dictId 列表)
* @param req 包含 dictId 列表的请求
* @return 字典详情列表
*/
@PostMapping(value = "/systemData/batchQueryDictionaries")
SdmResponse<List<DataDictionary>> batchQueryDictionaries(@RequestBody DictTagReq.BatchDictQueryReq req);
}

View File

@@ -314,6 +314,7 @@ public class DataFileController implements IDataFeignClient {
* @param req
* @return
*/
@AutoFillDictTags
@PostMapping(value = "/updateFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "编辑更新文件", description = "更新指定文件")
public SdmResponse updateFile(@Validated UpdateFileReq req) {

View File

@@ -3,6 +3,7 @@ package com.sdm.data.model.entity;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.sdm.common.entity.req.data.SimulationPoolInfo;
@@ -225,4 +226,8 @@ public class FileMetadataInfo implements Serializable {
@Schema(description= "仿真任务池信息列表")
@TableField(exist = false)
private List<PoolInfo> poolInfos;
@Schema(description = "字典标签查询结果缓存(用于审批流程)", hidden = true)
@TableField(exist = false)
private Map<String, Map<String, Integer>> dictTagIdsCache;
}

View File

@@ -8,6 +8,7 @@ import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
@Data
@Schema(description = "更新文件请求参数")
@@ -52,6 +53,28 @@ public class UpdateFileReq {
@Schema(description = "备注信息")
private String remarks;
// ----------------------------------------------------------------
// 很重要,用于设置标签
@Schema(description = "字典标签查询结果缓存", hidden = true)
@JSONField(serialize = false)
private Map<String, Map<String, Integer>> dictTagIdsCache;
@Schema(description = "字典标签查询列表,格式:['fileTypeDictClass','fileTypeDictValue','disciplineTypeDictClass','disciplineDictValue']")
private List<String> dictTags;
@Schema(description = "文件类型字典类")
private String fileTypeDictClass;
@Schema(description = "文件类型字典值")
private String fileTypeDictValue;
@Schema(description = "学科类型字典类")
private String disciplineTypeDictClass;
@Schema(description = "学科类型字典值")
private String disciplineDictValue;
// ----------------------------------------------------------------
@Schema(description = "知识库文件审批模板id")
private String templateId;

View File

@@ -12,6 +12,7 @@ import com.google.common.collect.Sets;
import com.sdm.common.common.SdmResponse;
import com.sdm.common.common.ThreadLocalContext;
import com.sdm.common.entity.ExportExcelFormat;
import com.sdm.common.entity.bo.DataDictionary;
import com.sdm.common.entity.constants.NumberConstants;
import com.sdm.common.entity.constants.PermConstants;
import com.sdm.common.entity.enums.*;
@@ -888,6 +889,9 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
dto.setKnowledgeBaseName(knowledgeBaseName);
return dto;
}).collect(Collectors.toList());
// 批量填充文件标签信息
fillFileTags(dtoList);
PageInfo<FileMetadataInfoResp> page1 = new PageInfo<>(dtoList);
page1.setTotal(total);
return PageUtils.getJsonObjectSdmResponse(dtoList, page1);
@@ -1495,7 +1499,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
fileUserPermissionService,
fileStorageService,
fileSimulationMappingService,
paramObjectService
paramObjectService,
fileTagRelService // 新增:文件标签关系服务
);
// 获取并执行审批结果
@@ -1984,6 +1989,76 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}
/**
* 更新文件标签
* 删除旧标签,插入新标签
*
* @param req 更新文件请求
* @param fileMetadataInfo 文件元数据
* @param dirMetadataInfo 目录元数据
*/
private void updateFileTags(UpdateFileReq req, FileMetadataInfo fileMetadataInfo, FileMetadataInfo dirMetadataInfo) {
Long tenantId = ThreadLocalContext.getTenantId();
Long creatorId = ThreadLocalContext.getUserId();
Long fileId = fileMetadataInfo.getId();
Long dirId = dirMetadataInfo != null ? dirMetadataInfo.getId() : null;
// 1. 收集当前目录和所有祖先目录
List<Long> ancestorDirIds = dirId != null ? collectAncestorDirIds(dirId) : new ArrayList<>();
// 2. 删除文件在所有目录下的旧标签关系
if (!ancestorDirIds.isEmpty()) {
fileTagRelService.lambdaUpdate()
.eq(FileTagRel::getTenantId, tenantId)
.eq(FileTagRel::getFileId, fileId)
.in(FileTagRel::getDirId, ancestorDirIds)
.remove();
}
// 3. 从缓存获取字典标签ID已由AOP切面自动填充
Map<String, Map<String, Integer>> dictIdMap = req.getDictTagIdsCache();
if (dictIdMap == null || dictIdMap.isEmpty()) {
log.warn("Dict tags cache is empty for update, trying to query manually");
dictIdMap = dictTagHelper.queryAndCacheDictTagIds(req);
if (dictIdMap.isEmpty()) {
log.warn("No dictionary ids found for tags update");
return;
}
}
// 4. 构建新的标签关系
List<FileTagRel> newTagRelList = new ArrayList<>();
long fileSize = fileMetadataInfo.getFileSize() != null ? fileMetadataInfo.getFileSize() : 0L;
for (Map.Entry<String, Map<String, Integer>> classEntry : dictIdMap.entrySet()) {
Map<String, Integer> valueMap = classEntry.getValue();
for (Integer dictId : valueMap.values()) {
if (dictId == null) {
continue;
}
// 为所有目录(当前目录 + 祖先目录)创建标签关系
for (Long dirIdItem : ancestorDirIds) {
FileTagRel tagRel = new FileTagRel();
tagRel.setFileId(fileId);
tagRel.setTagId(dictId);
tagRel.setDirId(dirIdItem);
tagRel.setTenantId(tenantId);
tagRel.setCreatorId(creatorId);
tagRel.setFileSize(fileSize);
newTagRelList.add(tagRel);
}
}
}
// 5. 批量插入新标签关系
if (CollectionUtils.isNotEmpty(newTagRelList)) {
fileTagRelService.saveBatch(newTagRelList);
log.info("Updated file tags for fileId: {}, total: {} tags", fileId, newTagRelList.size());
}
}
private void saveFileTags(UploadFilesReq req, FileMetadataInfo fileInfo, FileMetadataInfo dirMetadataInfo,
List<Long> ancestorDirIds) {
if (CollectionUtils.isEmpty(req.getDictTags())) {
@@ -1993,7 +2068,6 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
Long tenantId = ThreadLocalContext.getTenantId();
Long creatorId = ThreadLocalContext.getUserId();
long fileSize = resolveFileSize(req);
Long currentDirId = dirMetadataInfo.getId();
// 从缓存获取字典标签ID已由AOP切面自动填充
Map<String, Map<String, Integer>> dictIdMap = req.getDictTagIdsCache();
@@ -2039,6 +2113,187 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}
}
/**
* 批量填充文件标签信息到 FileMetadataInfoResp
* 从 file_tag_rel 和 simulation_data_dictionary 查询标签,按 dictClass 分组
* 格式disciplineTypeDictClass: DISCIPLINE_TYPE, disciplineDictValue: '流体,机器人,动画'
*
* @param dtoList 文件元数据响应列表
*/
private void fillFileTags(List<FileMetadataInfoResp> dtoList) {
if (CollectionUtils.isEmpty(dtoList)) {
return;
}
Long tenantId = ThreadLocalContext.getTenantId();
// 1. 提取所有文件ID只包含文件类型排除目录
List<Long> fileIds = dtoList.stream()
.filter(dto -> DataTypeEnum.FILE.getValue()==(dto.getDataType()))
.map(FileMetadataInfoResp::getId)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(fileIds)) {
return;
}
// 2. 批量查询 file_tag_rel 获取文件对应的 tagId
List<FileTagRel> fileTagRels = fileTagRelService.lambdaQuery()
.eq(FileTagRel::getTenantId, tenantId)
.in(FileTagRel::getFileId, fileIds)
.select(FileTagRel::getFileId, FileTagRel::getTagId)
.list();
if (CollectionUtils.isEmpty(fileTagRels)) {
return;
}
// 3. 提取所有 tagId
List<Integer> tagIds = fileTagRels.stream()
.map(FileTagRel::getTagId)
.distinct()
.toList();
// 4. 批量查询 simulation_data_dictionary 获取标签详情
List<DictTagReq> dictTagReqs = tagIds.stream()
.map(tagId -> {
DictTagReq req = new DictTagReq();
req.setDictId(tagId);
return req;
})
.collect(Collectors.toList());
DictTagReq.BatchDictQueryReq batchReq = new DictTagReq.BatchDictQueryReq();
batchReq.setItems(dictTagReqs);
SdmResponse<List<DataDictionary>> response = sysConfigFeignClient.batchQueryDictionaries(batchReq);
if (!response.isSuccess() || CollectionUtils.isEmpty(response.getData())) {
log.warn("Batch query dictionaries failed or returned empty");
return;
}
// 5. 构建 tagId -> 字典信息的映射
Map<Integer, DataDictionary> tagIdToDictMap = response.getData().stream()
.filter(dict -> dict.id != null)
.collect(Collectors.toMap(
dict -> dict.id,
dict -> dict,
(v1, v2) -> v1
));
// 6. 构建 fileId -> tagIds 的映射tagId 去重)
Map<Long, List<Integer>> fileToTagsMap = fileTagRels.stream()
.collect(Collectors.groupingBy(
FileTagRel::getFileId,
Collectors.mapping(FileTagRel::getTagId, Collectors.toSet())
))
.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> new ArrayList<>(entry.getValue())
));
// 7. 为每个文件填充标签信息
for (FileMetadataInfoResp dto : dtoList) {
if (!(DataTypeEnum.FILE.getValue()==(dto.getDataType()))) {
continue;
}
List<Integer> fileTags = fileToTagsMap.get(dto.getId());
if (CollectionUtils.isEmpty(fileTags)) {
continue;
}
// 按 dictClass 分组,聚合 dictValue只处理配置的 dictClass
Map<String, List<String>> classToDictValuesMap = new HashMap<>();
for (Integer tagId : fileTags) {
DataDictionary dictInfo = tagIdToDictMap.get(tagId);
if (dictInfo == null) {
continue;
}
String dictClass = dictInfo.dictClass;
String dictValue = dictInfo.dictValue;
// 只处理枚举中配置的 dictClass
if (dictClass != null && dictValue != null && FileDictTagEnum.isConfigured(dictClass)) {
classToDictValuesMap
.computeIfAbsent(dictClass, k -> new ArrayList<>())
.add(dictValue);
}
}
// 设置到 DTO 中(使用枚举配置)
for (Map.Entry<String, List<String>> entry : classToDictValuesMap.entrySet()) {
String dictClass = entry.getKey();
String dictValues = String.join(",", entry.getValue());
// 根据枚举配置设置对应的字段
FileDictTagEnum tagEnum = FileDictTagEnum.getByDictClass(dictClass);
if (tagEnum != null) {
setDictTagFieldsByEnum(dto, tagEnum, dictValues);
}
}
}
}
/**
* 根据枚举配置设置字典标签字段(推荐使用)
* 直接使用枚举配置的完整字段名,无需拼接
*
* @param dto FileMetadataInfoResp 对象
* @param tagEnum 字典标签枚举
* @param dictValues 字典值(逗号分隔)
*/
private void setDictTagFieldsByEnum(FileMetadataInfoResp dto, FileDictTagEnum tagEnum, String dictValues) {
if (tagEnum == null || dictValues == null) {
return;
}
String dictClass = tagEnum.getDictClass();
String dictClassFieldName = tagEnum.getDictClassFieldName();
String dictValueFieldName = tagEnum.getDictValueFieldName();
try {
// 设置 dictClass 字段
Field dictClassField = findField(FileMetadataInfoResp.class, dictClassFieldName);
if (dictClassField != null) {
dictClassField.setAccessible(true);
dictClassField.set(dto, dictClass);
} else {
log.warn("Field '{}' not found in FileMetadataInfoResp, please add field for dictClass: {}",
dictClassFieldName, dictClass);
}
// 设置 dictValue 字段
Field dictValueField = findField(FileMetadataInfoResp.class, dictValueFieldName);
if (dictValueField != null) {
dictValueField.setAccessible(true);
dictValueField.set(dto, dictValues);
} else {
log.warn("Field '{}' not found in FileMetadataInfoResp, please add field for dictClass: {}",
dictValueFieldName, dictClass);
}
} catch (Exception e) {
log.warn("Failed to set dict tag fields for dictClass: {}, error: {}", dictClass, e.getMessage());
}
}
/**
* 在类及其父类中查找字段
*/
private Field findField(Class<?> clazz, String fieldName) {
while (clazz != null && clazz != Object.class) {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
}
return null;
}
private void bindSimulationPool(UploadFilesReq req, FileMetadataInfo fileInfo) {
if (CollectionUtils.isEmpty(req.getSimulationPoolInfoList())) {
@@ -2244,6 +2499,12 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
tempFileMetadataInfo.setCreateTime(fileMetadataInfo.getCreateTime());
tempFileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
tempFileMetadataInfo.setUpdateTime(LocalDateTime.now());
// 保存标签缓存到 tempFileMetadataInfo如果有
if (CollectionUtils.isNotEmpty(req.getDictTags()) && req.getDictTagIdsCache() != null) {
tempFileMetadataInfo.setDictTagIdsCache(req.getDictTagIdsCache());
}
fileMetadataInfo.setTempMetadata(JSONObject.toJSONString(tempFileMetadataInfo));
fileMetadataInfo.setUpdateTime(LocalDateTime.now());
fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
@@ -2285,6 +2546,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
fileMetadataInfo.setUpdateTime(LocalDateTime.now());
fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId());
fileMetadataInfo.setFileType(req.getFileType());
// 更新标签(如果有)
if (CollectionUtils.isNotEmpty(req.getDictTags())) {
updateFileTags(req, fileMetadataInfo, dirMetadataInfo);
}
}
fileMetadataInfoService.updateById(fileMetadataInfo);
@@ -2327,6 +2593,11 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
fileMetadataInfoService.save(newFileInfo);
// 创建文件标签关系(如果有)
if (CollectionUtils.isNotEmpty(req.getDictTags())) {
updateFileTags(req, newFileInfo, dirMetadataInfo);
}
//绑定文件和工况库的关系
if (CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())) {
for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) {

View File

@@ -20,4 +20,5 @@ public class ApproveContext {
private IFileStorageService fileStorageService;
private IFileSimulationMappingService fileSimulationMappingService;
private ISimulationParameterLibraryCategoryObjectService paramObjectService;
private IFileTagRelService fileTagRelService; // 新增:用于标签关系管理
}

View File

@@ -25,6 +25,7 @@ public class ModifyFileApproveStrategy implements ApproveStrategy {
IFileUserPermissionService fileUserPermissionService = context.getFileUserPermissionService();
IFileStorageService fileStorageService = context.getFileStorageService();
IFileSimulationMappingService fileSimulationMappingService = context.getFileSimulationMappingService();
IFileTagRelService fileTagRelService = context.getFileTagRelService();
// 最新的历史版本为
FileMetadataInfo historyMetaData = service.lambdaQuery()
@@ -61,6 +62,9 @@ public class ModifyFileApproveStrategy implements ApproveStrategy {
fileUserPermissionService.remove(new LambdaQueryWrapper<FileUserPermission>().eq(FileUserPermission::getTFilemetaId, metadata.getId()));
fileStorageService.remove(new LambdaQueryWrapper<FileStorage>().eq(FileStorage::getFileId, metadata.getId()));
fileSimulationMappingService.remove(new LambdaQueryWrapper<FileSimulationMapping>().eq(FileSimulationMapping::getFileId, metadata.getId()));
// 删除文件标签关系
fileTagRelService.remove(new LambdaQueryWrapper<FileTagRel>().eq(FileTagRel::getFileId, metadata.getId()));
if (historyMetaData != null) {
historyMetaData.setTempMetadata(null);
historyMetaData.setIsLatest(true);

View File

@@ -7,13 +7,17 @@ import com.sdm.common.entity.enums.ApproveFileDataTypeEnum;
import com.sdm.common.entity.req.data.SimulationPoolInfo;
import com.sdm.data.model.entity.FileMetadataInfo;
import com.sdm.data.model.entity.FileSimulationMapping;
import com.sdm.data.model.entity.FileTagRel;
import com.sdm.data.service.IFileMetadataInfoService;
import com.sdm.data.service.IFileSimulationMappingService;
import com.sdm.data.service.IFileTagRelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
@@ -25,6 +29,7 @@ public class ModifyMetadataApproveStrategy implements ApproveStrategy {
int status = context.getApproveStatus();
IFileMetadataInfoService service = context.getFileMetadataInfoService();
IFileSimulationMappingService fileSimulationMappingService = context.getFileSimulationMappingService();
IFileTagRelService fileTagRelService = context.getFileTagRelService();
// 审批通过
if (NumberConstants.TWO == status) {
@@ -57,6 +62,12 @@ public class ModifyMetadataApproveStrategy implements ApproveStrategy {
}
}
}
// 处理标签更新(如果 tempMetadata 中包含标签信息)
if (updateInfo.getDictTagIdsCache() != null && !updateInfo.getDictTagIdsCache().isEmpty()) {
updateFileTagsAfterApproval(metadata, updateInfo, fileTagRelService);
}
return true;
}
@@ -71,4 +82,66 @@ public class ModifyMetadataApproveStrategy implements ApproveStrategy {
}
return false;
}
/**
* 审批通过后更新文件标签
* 从 updateInfo 中获取标签信息并更新到 file_tag_rel 表
*/
private void updateFileTagsAfterApproval(FileMetadataInfo metadata, FileMetadataInfo updateInfo,
IFileTagRelService fileTagRelService) {
try {
Long tenantId = metadata.getTenantId();
Long creatorId = metadata.getCreatorId();
Long fileId = metadata.getId();
// 从 updateInfo 中获取标签缓存
Map<String, Map<String, Integer>> dictTagIdsCache = updateInfo.getDictTagIdsCache();
if (dictTagIdsCache == null || dictTagIdsCache.isEmpty()) {
return;
}
// 删除旧标签关系(只删除当前租户的)
fileTagRelService.lambdaUpdate()
.eq(FileTagRel::getTenantId, tenantId)
.eq(FileTagRel::getFileId, fileId)
.remove();
// 构建新标签关系
List<FileTagRel> newTagRelList = new ArrayList<>();
Long dirId = updateInfo.getParentId();
Long fileSize = updateInfo.getFileSize() != null ? updateInfo.getFileSize() : 0L;
for (Map.Entry<String, Map<String, Integer>> classEntry : dictTagIdsCache.entrySet()) {
Map<String, Integer> valueMap = classEntry.getValue();
for (Integer dictId : valueMap.values()) {
if (dictId == null) {
continue;
}
// 注意:这里只为当前文件所在目录创建标签关系
// 如果需要为祖先目录也创建,需要从 metadata 中获取 parentId 并递归查询
if (dirId != null) {
FileTagRel tagRel = new FileTagRel();
tagRel.setFileId(fileId);
tagRel.setTagId(dictId);
tagRel.setDirId(dirId);
tagRel.setTenantId(tenantId);
tagRel.setCreatorId(creatorId);
tagRel.setFileSize(fileSize);
newTagRelList.add(tagRel);
}
}
}
// 批量插入新标签关系
if (CollectionUtils.isNotEmpty(newTagRelList)) {
fileTagRelService.saveBatch(newTagRelList);
log.info("Approved and updated file tags for fileId: {}, total: {} tags", fileId, newTagRelList.size());
}
} catch (Exception e) {
log.error("Failed to update file tags after approval for fileId: {}", metadata.getId(), e);
// 不抛出异常,避免影响审批流程
}
}
}

View File

@@ -179,6 +179,15 @@ public class SimulationSystemConfigController implements ISysConfigFeignClient {
return service.multiQueryDictionaryIds(req);
}
/**
* 批量查询字典详情(根据 dictId 列表)
*/
@PostMapping(value = "/batchQueryDictionaries")
@ResponseBody
public SdmResponse<List<DataDictionary>> batchQueryDictionaries(@RequestBody DictTagReq.BatchDictQueryReq req) {
return service.batchQueryDictionaries(req);
}
/**
* 表单管理 展示所有自定义表头的表单表
*/

View File

@@ -79,10 +79,11 @@ public interface SimulationSystemMapper {
@Select("<script>" +
"SELECT id, dictClass, dictValue FROM simulation_data_dictionary " +
"WHERE tenantId = #{tenantId} AND " +
"WHERE tenantId = #{tenantId} AND (" +
"<foreach collection='items' item='item' separator=' OR '>" +
"(dictClass = #{item.dictClass} AND dictValue = #{item.dictValue})" +
"</foreach>" +
")" +
" ORDER BY dictClass, dictValue" +
"</script>")
List<DataDictionary> batchQueryDictionaryIds(@Param("tenantId") long tenantId, @Param("items") List<DictTagReq> items);

View File

@@ -26,7 +26,7 @@ public class SysDataDictionary implements Serializable {
@Schema(description = "表单ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Integer id;
@Schema(description = "字典ID")
private String uuid;

View File

@@ -0,0 +1,39 @@
package com.sdm.system.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 数据字典响应实体
*/
@Data
@Schema(description = "数据字典响应")
public class DataDictionaryResp {
@Schema(description = "字典ID")
private Integer id;
@Schema(description = "字典分类名称")
private String dictClass;
@Schema(description = "字典名称")
private String dictName;
@Schema(description = "字典值")
private String dictValue;
@Schema(description = "字典别名")
private String aliasName;
@Schema(description = "字典值类型")
private String valueType;
@Schema(description = "排序序号")
private Integer dictOrder;
@Schema(description = "字典分类类型")
private String classType;
@Schema(description = "描述信息")
private String comment;
}

View File

@@ -57,6 +57,13 @@ public interface ISimulationSystemConfigService {
SdmResponse<Map<String, Map<String, Integer>>> multiQueryDictionaryIds(DictTagReq.BatchDictIdQueryReq req);
/**
* 批量查询字典详情(根据 dictId 列表)
* @param req 包含 dictId 列表的请求
* @return 字典详情列表
*/
SdmResponse<List<DataDictionary>> batchQueryDictionaries(DictTagReq.BatchDictQueryReq req);
SdmResponse addSystemParamConfig(SystemParamConfigBean configBean);
SdmResponse updateSystemParamConfig(SystemParamConfigBean configBean);

View File

@@ -23,15 +23,13 @@ import com.sdm.common.utils.PageUtils;
import com.sdm.system.dao.SimulationSystemMapper;
import com.sdm.system.model.bo.DictionaryClass;
import com.sdm.system.model.bo.FormConfigure;
import com.sdm.system.model.entity.SysDataDictionary;
import com.sdm.system.model.entity.SysFormConfigure;
import com.sdm.system.model.entity.SysFormUserConfigure;
import com.sdm.system.model.entity.SystemParamConfigBean;
import com.sdm.system.model.req.system.FormConfigureReq;
import com.sdm.system.model.resp.SimuDictionaryResp;
import com.sdm.system.service.IFormConfigureService;
import com.sdm.system.service.IFormUserConfigureService;
import com.sdm.system.service.ISimulationSystemConfigService;
import com.sdm.system.service.ISysUserService;
import com.sdm.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
@@ -77,6 +75,9 @@ public class SimulationSystemConfigServiceImpl extends BaseService implements IS
@Autowired
private IFormUserConfigureService formUserConfigureService;
@Autowired
private IDataDictionaryService dataDictionaryService;
/**
* 添加数据字典
* @param dict
@@ -961,6 +962,54 @@ public class SimulationSystemConfigServiceImpl extends BaseService implements IS
return SdmResponse.success(result);
}
@Override
public SdmResponse<List<DataDictionary>> batchQueryDictionaries(DictTagReq.BatchDictQueryReq req) {
long tenantId = ThreadLocalContext.getTenantId();
if (req.getItems() == null || req.getItems().isEmpty()) {
return SdmResponse.success(new ArrayList<>());
}
// 提取所有 dictId
List<Integer> dictIds = req.getItems().stream()
.map(DictTagReq::getDictId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (dictIds.isEmpty()) {
return SdmResponse.success(new ArrayList<>());
}
// 批量查询字典
List<SysDataDictionary> dictionaries = dataDictionaryService.lambdaQuery()
.eq(SysDataDictionary::getTenantId, tenantId)
.in(SysDataDictionary::getId, dictIds)
.list();
// 转换为 DataDictionary
List<DataDictionary> result = dictionaries.stream()
.map(dict -> {
DataDictionary dataDictionary = new DataDictionary();
dataDictionary.id = dict.getId();
dataDictionary.uuid = dict.getUuid();
dataDictionary.dictClass = dict.getDictClass();
dataDictionary.dictName = dict.getDictName();
dataDictionary.dictValue = dict.getDictValue();
dataDictionary.aliasName = dict.getAliasName();
dataDictionary.valueType = dict.getValueType();
dataDictionary.dictOrder = dict.getDictOrder();
dataDictionary.classType = dict.getClassType();
dataDictionary.comment = dict.getComment();
dataDictionary.tenantId = dict.getTenantId();
dataDictionary.creator = dict.getCreator();
return dataDictionary;
})
.collect(Collectors.toList());
return SdmResponse.success(result);
}
}