Files
yjearth/src/main/java/com/yj/earth/business/controller/SourceController.java
2025-09-16 11:41:45 +08:00

316 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.yj.earth.business.controller;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yj.earth.annotation.CheckAuth;
import com.yj.earth.business.domain.FileInfo;
import com.yj.earth.business.domain.Role;
import com.yj.earth.business.domain.Source;
import com.yj.earth.business.service.*;
import com.yj.earth.common.service.SourceDataGenerator;
import com.yj.earth.common.service.SourceParamsValidator;
import com.yj.earth.common.util.ApiResponse;
import com.yj.earth.common.util.MapUtil;
import com.yj.earth.dto.source.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import static com.yj.earth.common.constant.GlobalConstant.DIRECTORY;
import static com.yj.earth.common.constant.GlobalConstant.SHOW;
@Slf4j
@Tag(name = "树形结构管理")
@RestController
@RequestMapping("/source")
public class SourceController {
@Resource
private SourceService sourceService;
@Resource
private UserService userService;
@Resource
private RoleSourceService roleSourceService;
@Resource
private RoleService roleService;
@Resource
private SourceParamsValidator sourceParamsValidator;
@Resource
private SourceDataGenerator sourceDataGenerator;
@Resource
private FileInfoService fileInfoService;
@Resource
private FileInfoController fileInfoControllerl;
@Value("${file.upload.path}")
private String uploadPath;
@PostMapping("/addDirectory")
@Operation(summary = "新增目录资源")
public ApiResponse addDirectory(@RequestBody AddDirectoryDto addDirectoryDto) {
// 校验是否通过
String message = sourceService.checkIsPass(addDirectoryDto.getParentId(), addDirectoryDto.getSourceName());
if (message != null) {
return ApiResponse.failure(message);
}
// 通过之后保存资源
Source source = new Source();
BeanUtils.copyProperties(addDirectoryDto, source);
source.setSourceType(DIRECTORY);
source.setIsShow(SHOW);
sourceService.save(source);
// 添加资源到该用户的角色下
roleSourceService.addRoleSource(userService.getById(StpUtil.getLoginIdAsString()).getRoleId(), source.getId());
return ApiResponse.success(source);
}
@Operation(summary = "新增模型资源")
@PostMapping("/addModelSource")
public ApiResponse addModelSource(@RequestBody AddModelSourceDto addModelSourceDto) {
// 获取资源绝对路径
String sourcePath = addModelSourceDto.getSourcePath();
// 获取资源名称
String sourceName = FileUtil.mainName(sourcePath);
// 校验是否通过
String message = sourceService.checkIsPass(addModelSourceDto.getParentId(), sourceName);
if (message != null) {
return ApiResponse.failure(message);
}
// 调用SDK加载资源
String sourceId = sourceService.addAndGetSourceId(sourcePath);
// 获取文件路径并处理详情
String detail = sourceService.getDetail(sourcePath, sourceId);
// 构建并保存资源对象
Source source = new Source();
source.setId(addModelSourceDto.getId());
source.setSourcePath(sourcePath);
source.setSourceName(sourceName);
source.setParentId(addModelSourceDto.getParentId());
source.setTreeIndex(addModelSourceDto.getTreeIndex());
source.setParams(addModelSourceDto.getParams());
source.setDetail(detail);
source.setSourceType(MapUtil.getString(MapUtil.jsonToMap(detail), "fileType"));
source.setIsShow(SHOW);
sourceService.save(source);
// 添加资源到该用户的角色下
roleSourceService.addRoleSource(userService.getById(StpUtil.getLoginIdAsString()).getRoleId(), source.getId());
return ApiResponse.success(source);
}
@Operation(summary = "新增其他资源")
@PostMapping("/addOtherSource")
public ApiResponse addOtherSource(@RequestBody AddOtherSourceDto addOtherSourceDto) throws JsonProcessingException {
// 校验是否通过
String message = sourceService.checkIsPass(addOtherSourceDto.getParentId(), addOtherSourceDto.getSourceName());
if (message != null) {
return ApiResponse.failure(message);
}
// 验证并转换参数
Object validatedParams = sourceParamsValidator.validateAndConvert(
addOtherSourceDto.getSourceType(),
addOtherSourceDto.getParams()
);
Source source = new Source();
BeanUtils.copyProperties(addOtherSourceDto, source);
source.setIsShow(SHOW);
source.setParams(MapUtil.objectToJson(validatedParams));
sourceService.save(source);
// 添加资源到该用户的角色下
roleSourceService.addRoleSource(userService.getById(StpUtil.getLoginIdAsString()).getRoleId(), source.getId());
return ApiResponse.success(source);
}
@Operation(summary = "更新资源信息")
@PostMapping("/update")
public ApiResponse updateSource(@RequestBody UpdateSourceDto updateSourceDto) {
// 查询资源
Source source = sourceService.getById(updateSourceDto.getId());
if (source == null) {
return ApiResponse.failure("资源不存在");
}
// 更新基本信息
BeanUtils.copyProperties(updateSourceDto, source);
// 处理参数更新
if (updateSourceDto.getParams() != null && !updateSourceDto.getParams().isEmpty()) {
// 获取类型
String sourceType = source.getSourceType();
// 验证参数
Object validatedParams = sourceParamsValidator.validateAndConvert(
sourceType,
updateSourceDto.getParams()
);
// 获取原始数据的 Map 并合并新参数
Map<String, Object> dataMap = MapUtil.jsonToMap(source.getParams());
MapUtil.mergeMaps(dataMap, updateSourceDto.getParams());
source.setParams(MapUtil.mapToString(dataMap));
}
// 保存更新
sourceService.updateById(source);
return ApiResponse.success(source);
}
@Operation(summary = "获取资源列表")
@GetMapping("/list")
public ApiResponse list() {
return ApiResponse.success(sourceService.getSourceListByUserId(StpUtil.getLoginIdAsString()));
}
@Operation(summary = "删除资源数据")
@PostMapping("/delete")
public ApiResponse delete(@RequestBody DeleteSourceDto deleteSourceDto) {
if (deleteSourceDto.getIds() == null || deleteSourceDto.getIds().isEmpty()) {
return ApiResponse.failure("资源ID列表不能为空");
}
// 收集所有需要删除的资源ID包括子资源
Set<String> allIds = new HashSet<>();
for (String id : deleteSourceDto.getIds()) {
// 获取资源
Source source = sourceService.getById(id);
if (source == null) {
return ApiResponse.failure("资源ID为" + id + "的资源不存在");
}
// 查询ID等于自身或者父级ID等于自身的资源
LambdaQueryWrapper<Source> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Source::getId, source.getId())
.or()
.eq(Source::getParentId, source.getId());
List<Source> list = sourceService.list(queryWrapper);
// 筛选ID列表并添加到总集合中
list.stream().map(Source::getId).forEach(allIds::add);
}
// 删除这些资源
sourceService.removeByIds(allIds);
// 删除这些资源下的所有角色资源关系
roleSourceService.deleteRoleSource(
userService.getById(StpUtil.getLoginIdAsString()).getRoleId(),
new ArrayList<>(allIds)
);
return ApiResponse.success(null);
}
@PostMapping("/uploadLocationImage")
@Operation(summary = "新增定位图片")
public ApiResponse uploadLocationImage(@RequestParam("ids") @Parameter(description = "上传定位图片ID列表") List<String> ids,
@RequestParam(value = "parentId", required = false) @Parameter(description = "父节点ID") String parentId,
@RequestParam(value = "treeIndex", required = false) @Parameter(description = "树状索引") Integer treeIndex,
@RequestParam("files") @Parameter(description = "带有定位的图片文件", required = true) MultipartFile[] files) {
for (int i = 0; i < files.length; i++) {
String detail = fileInfoControllerl.handleLocationImageUpload(files[i]);
// 构建并保存资源对象
Source source = new Source();
source.setId(ids.get(i));
source.setSourceName(files[i].getOriginalFilename());
source.setParentId(parentId);
source.setSourceType("locationImage");
source.setTreeIndex(treeIndex);
source.setDetail(detail);
source.setIsShow(SHOW);
sourceService.save(source);
// 添加资源到该用户的角色下
roleSourceService.addRoleSource(userService.getById(StpUtil.getLoginIdAsString()).getRoleId(), source.getId());
}
return ApiResponse.success(null);
}
@GetMapping("/type")
@Operation(summary = "获取已有类型")
public ApiResponse getSupportedSourceTypes() {
Set<String> supportedTypes = sourceParamsValidator.getSupportedSourceTypes();
return ApiResponse.success(supportedTypes);
}
@Operation(summary = "获取示例数据")
@GetMapping("/paramsExample")
public String getExampleData(String sourceType) throws JsonProcessingException {
return sourceDataGenerator.generateDefaultJson(sourceType);
}
@Operation(summary = "设置默认数据")
@GetMapping("/default")
public ApiResponse getDefaultData() {
log.info("开始初始化默认资源数据");
String userId = StpUtil.getLoginIdAsString();
String roleId = userService.getById(userId).getRoleId();
// 创建一级目录
createSourceIfNotExists("倾斜模型", "directory", null, 0, 1, roleId);
createSourceIfNotExists("人工模型", "directory", null, 0, 1, roleId);
createSourceIfNotExists("卫星底图", "directory", null, 0, 1, roleId);
createSourceIfNotExists("地形", "directory", null, 0, 1, roleId);
// 创建"在线图源"目录及其子资源
Source onlineSource = createSourceIfNotExists("在线图源", "directory", null, 0, 1, roleId);
if (onlineSource != null) {
String onlineSourceId = onlineSource.getId();
createSourceIfNotExists("卫星图", "arcgisWximagery", onlineSourceId, 0, 1, roleId);
createSourceIfNotExists("暗黑地图", "arcgisBlueImagery", onlineSourceId, 0, 1, roleId);
createSourceIfNotExists("路网图", "gdlwImagery", onlineSourceId, 0, 1, roleId);
createSourceIfNotExists("矢量图", "gdslImagery", onlineSourceId, 0, 1, roleId);
}
log.info("默认资源数据初始化完成");
return ApiResponse.success(null);
}
/**
* 检查资源是否存在、不存在则创建并关联角色资源
*/
private Source createSourceIfNotExists(String sourceName, String sourceType, String parentId, int treeIndex, int isShow, String roleId) {
// 检查资源是否已存在通过名称和父ID组合判断唯一性
Source existingSource = sourceService.getOne(new LambdaQueryWrapper<Source>()
.eq(Source::getSourceName, sourceName)
.eq(parentId != null, Source::getParentId, parentId)
.isNull(parentId == null, Source::getParentId));
if (existingSource != null) {
return existingSource;
}
// 不存在则创建新资源
try {
Source newSource = new Source();
newSource.setId(cn.hutool.core.lang.UUID.fastUUID().toString(true));
newSource.setSourceName(sourceName);
newSource.setSourceType(sourceType);
newSource.setParentId(parentId);
newSource.setTreeIndex(treeIndex);
newSource.setIsShow(isShow);
sourceService.save(newSource);
// 关联角色资源
roleSourceService.addRoleSource(roleId, newSource.getId());
return newSource;
} catch (Exception e) {
return null;
}
}
}