Files
yjearth/src/main/java/com/yj/earth/business/controller/IconLibraryController.java
2025-09-29 13:56:36 +08:00

398 lines
16 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.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yj.earth.annotation.CheckAuth;
import com.yj.earth.business.domain.IconLibrary;
import com.yj.earth.business.domain.IconType;
import com.yj.earth.business.service.FileInfoService;
import com.yj.earth.business.service.IconLibraryService;
import com.yj.earth.common.util.ApiResponse;
import com.yj.earth.common.util.SQLiteUtil;
import com.yj.earth.dto.iconLibrary.AddIconTypeDto;
import com.yj.earth.dto.iconLibrary.CreateIconLibraryDto;
import com.yj.earth.dto.iconLibrary.DragIconTypeDto;
import com.yj.earth.dto.iconLibrary.UpdateIconTypeNameDto;
import com.yj.earth.vo.IconTypeVo;
import com.yj.earth.vo.IconVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.util.StringUtils;
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.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Tag(name = "图标库管理")
@CheckAuth
@RestController
@RequestMapping("/iconLibrary")
public class IconLibraryController {
@Resource
private IconLibraryService iconLibraryService;
@Resource
private FileInfoService fileInfoService;
@Operation(summary = "创建图标库")
@PostMapping("/createIconLibrary")
public ApiResponse createIconLibrary(@RequestBody CreateIconLibraryDto createIconLibraryDto) {
try {
// 参数校验与路径处理
String folderPath = createIconLibraryDto.getPath();
String iconName = createIconLibraryDto.getName();
File parentDir = new File(folderPath);
File iconFile = new File(parentDir, iconName);
String iconPath = iconFile.getAbsolutePath().replace("\\", "/");
// 检查父目录(不存在则创建)
if (!parentDir.exists()) {
boolean mkdirsSuccess = parentDir.mkdirs();
if (!mkdirsSuccess) {
return ApiResponse.failure("创建图标库父目录失败:" + folderPath);
}
}
// 检查图标库文件是否已存在
if (iconFile.exists()) {
if (iconFile.isDirectory()) {
return ApiResponse.failure("同名目录已存在、无法创建图标库文件:" + iconPath);
}
return ApiResponse.failure("图标库文件已存在:" + iconPath);
}
// 创建图标库文件
boolean createSuccess = iconFile.createNewFile();
if (!createSuccess) {
return ApiResponse.failure("创建图标库文件失败:" + iconPath);
}
// 新增图标库记录并初始化SQLite表结构
addIconLibrary(iconPath);
SQLiteUtil.initializationIcon(iconPath);
return ApiResponse.success(null);
} catch (Exception e) {
return ApiResponse.failure("创建图标库失败:" + e.getMessage());
}
}
@Operation(summary = "导入图标库")
@PostMapping("/importIconLibrary")
public ApiResponse importIconLibrary(@RequestParam("iconPath") @Parameter(description = "图标库路径") String iconPath) {
addIconLibrary(iconPath);
return ApiResponse.success(null);
}
@Operation(summary = "添加图标类型")
@PostMapping("/addIconType")
public ApiResponse addIconType(@RequestBody AddIconTypeDto addIconTypeDto) throws SQLException, IllegalAccessException, InstantiationException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 检查父级图标类型是否存在
String parentId = addIconTypeDto.getParentId();
if (parentId != null) {
String sql = "SELECT * FROM icon_type WHERE id = ?";
List<Object> params = new ArrayList<>();
params.add(parentId);
IconType iconType = SQLiteUtil.queryForObject(iconPath, sql, params, IconType.class);
if (iconType == null) {
return ApiResponse.failure("父级图标类型不存在");
}
}
// 插入图标类型
String sql = "INSERT INTO icon_type " +
"(id, name, parent_id, tree_index, created_at) " +
"VALUES (?, ?, ?, ?, ?)";
List<Object> params = new ArrayList<>();
params.add(UUID.fastUUID().toString(true));
params.add(addIconTypeDto.getName());
params.add(addIconTypeDto.getParentId());
params.add(0);
params.add(LocalDateTime.now());
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
@Operation(summary = "删除图标类型")
@PostMapping("/deleteIconType")
public ApiResponse deleteIconType(@Parameter(description = "图标类型ID") @RequestParam("iconTypeId") String iconTypeId) throws SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 删除图标类型
String sql = "DELETE FROM icon_type WHERE id = ?";
List<Object> params = new ArrayList<>();
params.add(iconTypeId);
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
@Operation(summary = "修改图标类型名称")
@PostMapping("/updateIconTypeName")
public ApiResponse updateIconTypeName(@RequestBody UpdateIconTypeNameDto updateIconTypeNameDto) throws SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 更新图标类型名称
String sql = "UPDATE icon_type SET name = ? WHERE id = ?";
List<Object> params = new ArrayList<>();
params.add(updateIconTypeNameDto.getName());
params.add(updateIconTypeNameDto.getId());
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
@Operation(summary = "图标类型列表")
@GetMapping("/iconTypeTree")
public ApiResponse iconTypeTree() throws SQLException, IllegalAccessException, InstantiationException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 查询所有图标类型
String sql = """
SELECT id, name, parent_id as parentId,
tree_index as treeIndex, created_at as createdAt,
updated_at as updatedAt FROM icon_type ORDER BY tree_index ASC
""";
List<IconType> iconTypes = SQLiteUtil.queryForList(iconPath, sql, null, IconType.class);
// 构建树形结构
List<IconTypeVo> treeList = buildIconTypeTree(iconTypes);
return ApiResponse.success(treeList);
}
@Operation(summary = "拖动图标类型树")
@PostMapping("/dragIconType")
public ApiResponse dragIconType(@RequestBody DragIconTypeDto dragIconTypeDto) throws SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 动态构建更新SQL
List<String> updateFields = new ArrayList<>();
List<Object> params = new ArrayList<>();
if (dragIconTypeDto.getParentId() != null) {
updateFields.add("parent_id = ?");
params.add(dragIconTypeDto.getParentId());
}
if (dragIconTypeDto.getTreeIndex() != null) {
updateFields.add("tree_index = ?");
params.add(dragIconTypeDto.getTreeIndex());
}
String sql = "UPDATE icon_type SET " + String.join(", ", updateFields) + " WHERE id = ?";
params.add(dragIconTypeDto.getId());
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
@Operation(summary = "添加图标文件")
@PostMapping("/addIconFile")
public ApiResponse addIconFile(@RequestParam("files") MultipartFile[] files,
@Parameter(description = "图标类型ID") @RequestParam("iconTypeId") String iconTypeId)
throws IOException, SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 循环处理上传文件
for (MultipartFile file : files) {
if (file.isEmpty()) continue;
String fileName = file.getOriginalFilename();
if (fileName == null) continue;
String fileSuffix = FileUtil.extName(fileName);
String fileNameWithoutSuffix = FileUtil.mainName(fileName);
// 上传文件并获取访问URL
String url = fileInfoService.uploadWithPreview(file);
// 插入图标记录
String sql = "INSERT INTO icon " +
"(id, icon_type_id, icon_name, icon_type, data, created_at) " +
"VALUES (?, ?, ?, ?, ?, ?)";
List<Object> params = new ArrayList<>();
params.add(UUID.fastUUID().toString(true));
params.add(iconTypeId);
params.add(fileNameWithoutSuffix);
params.add(fileSuffix);
params.add(url);
params.add(LocalDateTime.now());
SQLiteUtil.executeUpdate(iconPath, sql, params);
}
return ApiResponse.success(null);
}
@Operation(summary = "根据图标类型查看图标列表")
@PostMapping("/iconList")
public ApiResponse iconList(@Parameter(description = "图标类型ID") @RequestParam("iconTypeId") String iconTypeId)
throws SQLException, IllegalAccessException, InstantiationException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 多表联查图标数据
String sql = """
SELECT
icon.id,
icon.icon_type_id as iconTypeId,
icon.icon_name as iconName,
icon.icon_type as iconType,
icon.data,
icon.view,
icon.created_at as createdAt,
icon.updated_at as updatedAt,
icon_type.name as iconTypeName
FROM icon
JOIN icon_type ON icon.icon_type_id = icon_type.id
WHERE icon.icon_type_id = ?
""";
List<Object> params = new ArrayList<>();
params.add(iconTypeId);
List<IconVo> iconVos = SQLiteUtil.queryForList(iconPath, sql, params, IconVo.class);
return ApiResponse.success(iconVos);
}
@Operation(summary = "更新图标信息")
@PostMapping("/updateIconInfo")
public ApiResponse updateIconInfo(@Parameter(description = "图标ID") @RequestParam("iconId") String iconId,
@Parameter(description = "图标名称") @RequestParam(value = "iconName", required = false) String iconName)
throws SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 无更新字段直接返回成功
if (!StringUtils.hasText(iconName)) {
return ApiResponse.success(null);
}
// 更新图标名称
String sql = "UPDATE icon SET updated_at = ?, icon_name = ? WHERE id = ?";
List<Object> params = new ArrayList<>();
params.add(LocalDateTime.now());
params.add(iconName);
params.add(iconId);
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
@Operation(summary = "删除图标")
@PostMapping("/deleteIcon")
public ApiResponse deleteIcon(@Parameter(description = "图标ID") @RequestParam("iconId") String iconId) throws SQLException {
String iconPath = getIconLibrary();
if (iconPath == null) {
return ApiResponse.failure("请先创建或导入图标库");
}
// 删除图标
String sql = "DELETE FROM icon WHERE id = ?";
List<Object> params = new ArrayList<>();
params.add(iconId);
SQLiteUtil.executeUpdate(iconPath, sql, params);
return ApiResponse.success(null);
}
/**
* 构建图标类型树形结构
*
* @param iconTypes 图标类型列表
* @return 树形结构列表
*/
private List<IconTypeVo> buildIconTypeTree(List<IconType> iconTypes) {
// 转换为VO列表
List<IconTypeVo> treeNodes = iconTypes.stream()
.map(IconTypeVo::new)
.collect(Collectors.toList());
// 构建ID到VO的映射便于快速查找父节点
Map<String, IconTypeVo> nodeMap = treeNodes.stream()
.collect(Collectors.toMap(IconTypeVo::getId, node -> node));
// 组装树形结构
List<IconTypeVo> rootNodes = new ArrayList<>();
for (IconTypeVo node : treeNodes) {
String parentId = node.getParentId();
if (parentId == null || parentId.isEmpty()) {
// 无父节点 → 根节点
rootNodes.add(node);
} else {
// 有父节点 → 加入父节点的子列表
IconTypeVo parentNode = nodeMap.get(parentId);
if (parentNode != null) {
parentNode.getChildren().add(node);
}
}
}
return rootNodes;
}
/**
* 获取当前启用的图标库路径
*
* @return 图标库路径null表示无启用的图标库
*/
private String getIconLibrary() {
LambdaQueryWrapper<IconLibrary> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(IconLibrary::getIsEnable, 1);
IconLibrary iconLibrary = iconLibraryService.getOne(queryWrapper);
return iconLibrary == null ? null : iconLibrary.getPath();
}
private void addIconLibrary(String iconPath) {
// 查询所有图标库并置为禁用
List<IconLibrary> iconLibraries = iconLibraryService.list();
for (IconLibrary iconLibrary : iconLibraries) {
iconLibrary.setIsEnable(0);
iconLibraryService.updateById(iconLibrary);
}
// 检查路径是否已存在(存在则启用、不存在则新增)
LambdaQueryWrapper<IconLibrary> pathWrapper = new LambdaQueryWrapper<>();
pathWrapper.eq(IconLibrary::getPath, iconPath);
IconLibrary existingIconLib = iconLibraryService.getOne(pathWrapper);
if (existingIconLib != null) {
existingIconLib.setIsEnable(1);
iconLibraryService.updateById(existingIconLib);
} else {
// 新增图标库记录
IconLibrary newIconLib = new IconLibrary();
File iconFile = FileUtil.file(iconPath);
newIconLib.setId(UUID.fastUUID().toString(true));
newIconLib.setPath(iconPath);
newIconLib.setName(FileUtil.extName(iconFile));
newIconLib.setIsEnable(1);
iconLibraryService.save(newIconLib);
}
}
}