316 lines
13 KiB
Java
316 lines
13 KiB
Java
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;
|
||
}
|
||
}
|
||
}
|