| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 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.IconLibraryService;
 | 
					
						
							|  |  |  |  | import com.yj.earth.common.util.ApiResponse;
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | import com.yj.earth.common.util.FileCommonUtil;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 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;
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | import com.yj.earth.vo.IconDataVo;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 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;
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | import org.springframework.http.HttpHeaders;
 | 
					
						
							|  |  |  |  | import org.springframework.http.HttpStatus;
 | 
					
						
							|  |  |  |  | import org.springframework.http.MediaType;
 | 
					
						
							|  |  |  |  | import org.springframework.http.ResponseEntity;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 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;
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | import java.net.URLEncoder;
 | 
					
						
							|  |  |  |  | import java.nio.charset.StandardCharsets;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | import java.sql.SQLException;
 | 
					
						
							|  |  |  |  | import java.time.LocalDateTime;
 | 
					
						
							|  |  |  |  | import java.util.ArrayList;
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | import java.util.Comparator;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | import java.util.List;
 | 
					
						
							|  |  |  |  | import java.util.Map;
 | 
					
						
							|  |  |  |  | import java.util.stream.Collectors;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | @Tag(name = "图标库管理")
 | 
					
						
							|  |  |  |  | @CheckAuth
 | 
					
						
							|  |  |  |  | @RestController
 | 
					
						
							|  |  |  |  | @RequestMapping("/iconLibrary")
 | 
					
						
							|  |  |  |  | public class IconLibraryController {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     @Resource
 | 
					
						
							|  |  |  |  |     private IconLibraryService iconLibraryService;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "创建图标库")
 | 
					
						
							|  |  |  |  |     @PostMapping("/createIconLibrary")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse createIconLibrary(@RequestBody CreateIconLibraryDto createDto) {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             // 参数校验与路径处理
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             String folderPath = createDto.getPath();
 | 
					
						
							|  |  |  |  |             String libraryName = createDto.getName();
 | 
					
						
							|  |  |  |  |             if (!StringUtils.hasText(folderPath) || !StringUtils.hasText(libraryName)) {
 | 
					
						
							|  |  |  |  |                 return ApiResponse.failure("路径和名称不能为空");
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 构建完整图标库文件路径(SQLite文件)
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             File parentDir = new File(folderPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             File iconFile = new File(parentDir, libraryName);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             String iconPath = iconFile.getAbsolutePath().replace("\\", "/");
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 父目录不存在则创建
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             if (!parentDir.exists()) {
 | 
					
						
							|  |  |  |  |                 boolean mkdirsSuccess = parentDir.mkdirs();
 | 
					
						
							|  |  |  |  |                 if (!mkdirsSuccess) {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |                     return ApiResponse.failure("创建父目录失败:" + folderPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |                 }
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 校验图标库文件是否已存在
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             if (iconFile.exists()) {
 | 
					
						
							|  |  |  |  |                 if (iconFile.isDirectory()) {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |                     return ApiResponse.failure("同名目录已存在,无法创建文件:" + iconPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |                 }
 | 
					
						
							|  |  |  |  |                 return ApiResponse.failure("图标库文件已存在:" + iconPath);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 创建SQLite文件
 | 
					
						
							|  |  |  |  |             boolean createFileSuccess = iconFile.createNewFile();
 | 
					
						
							|  |  |  |  |             if (!createFileSuccess) {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |                 return ApiResponse.failure("创建图标库文件失败:" + iconPath);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 初始化图标库表结构
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             SQLiteUtil.initializationIcon(iconPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 添加图标库配置到数据库
 | 
					
						
							|  |  |  |  |             addIconLibrary(iconPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("创建图标库失败:" + e.getMessage());
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "导入图标库")
 | 
					
						
							|  |  |  |  |     @PostMapping("/importIconLibrary")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse importIconLibrary(
 | 
					
						
							|  |  |  |  |             @RequestParam("iconPath") @Parameter(description = "图标库SQLite文件路径") String iconPath) {
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             // 校验路径是否存在
 | 
					
						
							|  |  |  |  |             File iconFile = new File(iconPath);
 | 
					
						
							|  |  |  |  |             if (!iconFile.exists() || !iconFile.isFile()) {
 | 
					
						
							|  |  |  |  |                 return ApiResponse.failure("图标库文件不存在:" + iconPath);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             // 添加到配置表并启用
 | 
					
						
							|  |  |  |  |             addIconLibrary(iconPath);
 | 
					
						
							|  |  |  |  |             return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("导入图标库失败:" + e.getMessage());
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "添加图标类型")
 | 
					
						
							|  |  |  |  |     @PostMapping("/addIconType")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse addIconType(@RequestBody AddIconTypeDto addDto) throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         // 获取当前启用的图标库路径
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 校验父级类型(若有)
 | 
					
						
							|  |  |  |  |         String parentId = addDto.getParentId();
 | 
					
						
							|  |  |  |  |         if (StringUtils.hasText(parentId)) {
 | 
					
						
							|  |  |  |  |             String checkParentSql = "SELECT id FROM icon_type WHERE id = ?";
 | 
					
						
							|  |  |  |  |             List<Object> parentParams = new ArrayList<>();
 | 
					
						
							|  |  |  |  |             parentParams.add(parentId);
 | 
					
						
							|  |  |  |  |             IconType parentType = SQLiteUtil.queryForObject(
 | 
					
						
							|  |  |  |  |                     iconPath, checkParentSql, parentParams, IconType.class
 | 
					
						
							|  |  |  |  |             );
 | 
					
						
							|  |  |  |  |             if (parentType == null) {
 | 
					
						
							|  |  |  |  |                 return ApiResponse.failure("父级图标类型不存在:" + parentId);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             }
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 插入图标类型
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         String insertSql = "INSERT INTO icon_type " +
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |                 "(id, name, parent_id, tree_index, created_at) " +
 | 
					
						
							|  |  |  |  |                 "VALUES (?, ?, ?, ?, ?)";
 | 
					
						
							|  |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         params.add(UUID.fastUUID().toString(true));
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         params.add(addDto.getName());
 | 
					
						
							|  |  |  |  |         params.add(parentId);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         params.add(0);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         params.add(LocalDateTime.now().toString());
 | 
					
						
							|  |  |  |  |         SQLiteUtil.executeUpdate(iconPath, insertSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "修改图标类型名称")
 | 
					
						
							|  |  |  |  |     @PostMapping("/updateIconTypeName")
 | 
					
						
							|  |  |  |  |     public ApiResponse updateIconTypeName(@RequestBody UpdateIconTypeNameDto updateDto)
 | 
					
						
							|  |  |  |  |             throws SQLException {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 执行更新
 | 
					
						
							|  |  |  |  |         String updateSql = "UPDATE icon_type SET name = ?, updated_at = ? WHERE id = ?";
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         params.add(updateDto.getName());
 | 
					
						
							|  |  |  |  |         params.add(LocalDateTime.now().toString());
 | 
					
						
							|  |  |  |  |         params.add(updateDto.getId());
 | 
					
						
							|  |  |  |  |         SQLiteUtil.executeUpdate(iconPath, updateSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "删除图标类型")
 | 
					
						
							|  |  |  |  |     @PostMapping("/deleteIconType")
 | 
					
						
							|  |  |  |  |     public ApiResponse deleteIconType(
 | 
					
						
							|  |  |  |  |             @RequestParam("iconTypeId") @Parameter(description = "图标类型ID") String typeId)
 | 
					
						
							|  |  |  |  |             throws SQLException {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 执行删除
 | 
					
						
							|  |  |  |  |         String deleteSql = "DELETE FROM icon_type WHERE id = ?";
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         params.add(typeId);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         SQLiteUtil.executeUpdate(iconPath, deleteSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "图标类型树形列表")
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     @GetMapping("/iconTypeTree")
 | 
					
						
							|  |  |  |  |     public ApiResponse iconTypeTree() throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         List<IconTypeVo> treeList = iconTypeList();
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         return ApiResponse.success(treeList);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "添加图标文件")
 | 
					
						
							|  |  |  |  |     @PostMapping("/addIconFile")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse addIconFile(@RequestParam("files") MultipartFile[] files, @RequestParam("iconTypeId") @Parameter(description = "图标类型ID") String typeId) throws IOException, SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         // 获取当前启用的图标库
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 校验类型是否存在
 | 
					
						
							|  |  |  |  |         if (!isIconTypeExist(iconPath, typeId)) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("图标类型不存在:" + typeId);
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 循环处理每个文件
 | 
					
						
							|  |  |  |  |         for (MultipartFile file : files) {
 | 
					
						
							|  |  |  |  |             if (file.isEmpty()) {
 | 
					
						
							|  |  |  |  |                 continue; // 跳过空文件
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 解析文件名与后缀
 | 
					
						
							|  |  |  |  |             String originalFileName = file.getOriginalFilename();
 | 
					
						
							|  |  |  |  |             if (originalFileName == null) {
 | 
					
						
							|  |  |  |  |                 continue;
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             String fileSuffix = FileUtil.extName(originalFileName);
 | 
					
						
							|  |  |  |  |             String fileNameWithoutSuffix = FileUtil.mainName(originalFileName);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             // 插入图标数据
 | 
					
						
							|  |  |  |  |             String insertSql = "INSERT INTO icon " +
 | 
					
						
							|  |  |  |  |                     "(id, icon_type_id, icon_name, icon_type, icon_data, created_at) " +
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |                     "VALUES (?, ?, ?, ?, ?, ?)";
 | 
					
						
							|  |  |  |  |             List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |             params.add(UUID.fastUUID().toString(true));
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             params.add(typeId);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             params.add(fileNameWithoutSuffix);
 | 
					
						
							|  |  |  |  |             params.add(fileSuffix);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             params.add(file.getBytes());
 | 
					
						
							|  |  |  |  |             params.add(LocalDateTime.now().toString());
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             SQLiteUtil.executeUpdate(iconPath, insertSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "获取图标文件数据")
 | 
					
						
							|  |  |  |  |     @GetMapping("/data/icon/{iconId}/{fileSuffix}")
 | 
					
						
							|  |  |  |  |     public ResponseEntity<byte[]> getIconData(@PathVariable("iconId") @Parameter(description = "图标ID") String iconId, @PathVariable("fileSuffix") @Parameter(description = "图标文件后缀") String fileSuffix) {
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |             if (iconPath == null) {
 | 
					
						
							|  |  |  |  |                 return ResponseEntity.notFound().build();
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             // 查询图标二进制数据
 | 
					
						
							|  |  |  |  |             String querySql = "SELECT icon_name, icon_data FROM icon WHERE id = ?";
 | 
					
						
							|  |  |  |  |             List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |             params.add(iconId);
 | 
					
						
							|  |  |  |  |             IconDataVo dataVo = SQLiteUtil.queryForObject(
 | 
					
						
							|  |  |  |  |                     iconPath, querySql, params, IconDataVo.class
 | 
					
						
							|  |  |  |  |             );
 | 
					
						
							|  |  |  |  |             if (dataVo == null || dataVo.getIconData() == null) {
 | 
					
						
							|  |  |  |  |                 return ResponseEntity.notFound().build();
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             // 构建响应头【支持中文文件名+预览】
 | 
					
						
							|  |  |  |  |             String originalFileName = dataVo.getIconName() + "." + fileSuffix;
 | 
					
						
							|  |  |  |  |             String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name());
 | 
					
						
							|  |  |  |  |             MediaType contentType = FileCommonUtil.getImageMediaType(fileSuffix);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             return ResponseEntity.ok()
 | 
					
						
							|  |  |  |  |                     .contentType(contentType)
 | 
					
						
							|  |  |  |  |                     .header(HttpHeaders.CONTENT_DISPOSITION,
 | 
					
						
							|  |  |  |  |                             "inline; filename=\"" + encodedFileName + "\"")
 | 
					
						
							|  |  |  |  |                     .body(dataVo.getIconData());
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             e.printStackTrace();
 | 
					
						
							|  |  |  |  |             return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "根据类型查询图标列表")
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     @PostMapping("/iconList")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse getIconList(@RequestParam("iconTypeId") @Parameter(description = "图标类型ID") String typeId) throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 获取当前类型及所有子类型ID(递归)
 | 
					
						
							|  |  |  |  |         List<String> typeIdList = getIconTypeIdsWithChildren(typeId);
 | 
					
						
							|  |  |  |  |         if (typeIdList == null || typeIdList.isEmpty()) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.success(new ArrayList<>());
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 构建IN条件(处理SQL注入风险)
 | 
					
						
							|  |  |  |  |         String idsWithQuotes = typeIdList.stream()
 | 
					
						
							|  |  |  |  |                 .map(id -> "'" + id + "'")
 | 
					
						
							|  |  |  |  |                 .collect(Collectors.joining(","));
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 多表联查
 | 
					
						
							|  |  |  |  |         String querySql = """
 | 
					
						
							|  |  |  |  |                 SELECT 
 | 
					
						
							|  |  |  |  |                     i.id,
 | 
					
						
							|  |  |  |  |                     i.icon_type_id as iconTypeId,
 | 
					
						
							|  |  |  |  |                     i.icon_name as iconName,
 | 
					
						
							|  |  |  |  |                     i.icon_type as iconType,
 | 
					
						
							|  |  |  |  |                     i.created_at as createdAt,
 | 
					
						
							|  |  |  |  |                     i.updated_at as updatedAt,
 | 
					
						
							|  |  |  |  |                     t.name as iconTypeName 
 | 
					
						
							|  |  |  |  |                 FROM icon i
 | 
					
						
							|  |  |  |  |                 JOIN icon_type t ON i.icon_type_id = t.id
 | 
					
						
							|  |  |  |  |                 WHERE i.icon_type_id IN (%s)
 | 
					
						
							|  |  |  |  |                 ORDER BY i.created_at DESC
 | 
					
						
							|  |  |  |  |                 """.replace("%s", idsWithQuotes);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 查询并转换为VO
 | 
					
						
							|  |  |  |  |         List<IconVo> iconVoList = SQLiteUtil.queryForList(
 | 
					
						
							|  |  |  |  |                 iconPath, querySql, null, IconVo.class
 | 
					
						
							|  |  |  |  |         );
 | 
					
						
							|  |  |  |  |         for (IconVo vo : iconVoList) {
 | 
					
						
							|  |  |  |  |             vo.setIconDataUrl("/iconLibrary/data/icon/" + vo.getId() + "/" + vo.getIconType());
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return ApiResponse.success(iconVoList);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "更新图标名称")
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     @PostMapping("/updateIconInfo")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse updateIconInfo(
 | 
					
						
							|  |  |  |  |             @RequestParam("iconId") @Parameter(description = "图标ID") String iconId,
 | 
					
						
							|  |  |  |  |             @RequestParam("iconName") @Parameter(description = "新图标名称") String iconName)
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |             throws SQLException {
 | 
					
						
							|  |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         String updateSql = "UPDATE icon SET icon_name = ?, updated_at = ? WHERE id = ?";
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         params.add(iconName);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         params.add(LocalDateTime.now().toString());
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         params.add(iconId);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         SQLiteUtil.executeUpdate(iconPath, updateSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         return ApiResponse.success(null);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @Operation(summary = "删除图标")
 | 
					
						
							|  |  |  |  |     @PostMapping("/deleteIcon")
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     public ApiResponse deleteIcon(@RequestParam("iconId") @Parameter(description = "图标ID") String iconId) throws SQLException {
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 执行删除
 | 
					
						
							|  |  |  |  |         String deleteSql = "DELETE FROM icon WHERE id = ?";
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         params.add(iconId);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         SQLiteUtil.executeUpdate(iconPath, deleteSql, params);
 | 
					
						
							|  |  |  |  |         return ApiResponse.success("删除图标成功");
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |     @Operation(summary = "拖动调整图标类型层级")
 | 
					
						
							|  |  |  |  |     @PostMapping("/dragIconType")
 | 
					
						
							|  |  |  |  |     public ApiResponse dragIconType(@RequestBody List<DragIconTypeDto> dragDtoList)
 | 
					
						
							|  |  |  |  |             throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return ApiResponse.failure("请先创建或导入图标库");
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 批量更新层级和排序
 | 
					
						
							|  |  |  |  |         for (DragIconTypeDto dto : dragDtoList) {
 | 
					
						
							|  |  |  |  |             String updateSql = "UPDATE icon_type " +
 | 
					
						
							|  |  |  |  |                     "SET parent_id = ?, tree_index = ?, updated_at = ? " +
 | 
					
						
							|  |  |  |  |                     "WHERE id = ?";
 | 
					
						
							|  |  |  |  |             List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |             params.add(dto.getParentId());
 | 
					
						
							|  |  |  |  |             params.add(dto.getTreeIndex());
 | 
					
						
							|  |  |  |  |             params.add(LocalDateTime.now().toString());
 | 
					
						
							|  |  |  |  |             params.add(dto.getId());
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             SQLiteUtil.executeUpdate(iconPath, updateSql, params);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 返回更新后的树形列表
 | 
					
						
							|  |  |  |  |         List<IconTypeVo> treeList = iconTypeList();
 | 
					
						
							|  |  |  |  |         return ApiResponse.success(treeList);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private String getIconLibrary() {
 | 
					
						
							|  |  |  |  |         LambdaQueryWrapper<IconLibrary> queryWrapper = new LambdaQueryWrapper<>();
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         queryWrapper.eq(IconLibrary::getIsEnable, 1); // 1=启用,0=未启用
 | 
					
						
							|  |  |  |  |         IconLibrary library = iconLibraryService.getOne(queryWrapper);
 | 
					
						
							|  |  |  |  |         return library == null ? null : library.getPath();
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private void addIconLibrary(String iconPath) {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 所有已存在的图标库设置为「未启用」
 | 
					
						
							|  |  |  |  |         List<IconLibrary> existLibraries = iconLibraryService.list();
 | 
					
						
							|  |  |  |  |         for (IconLibrary library : existLibraries) {
 | 
					
						
							|  |  |  |  |             library.setIsEnable(0);
 | 
					
						
							|  |  |  |  |             iconLibraryService.updateById(library);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         // 检查路径是否已存在(存在则启用,不存在则新增)
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         LambdaQueryWrapper<IconLibrary> pathWrapper = new LambdaQueryWrapper<>();
 | 
					
						
							|  |  |  |  |         pathWrapper.eq(IconLibrary::getPath, iconPath);
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         IconLibrary existLibrary = iconLibraryService.getOne(pathWrapper);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |         if (existLibrary != null) {
 | 
					
						
							|  |  |  |  |             existLibrary.setIsEnable(1);
 | 
					
						
							|  |  |  |  |             iconLibraryService.updateById(existLibrary);
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         } else {
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  |             IconLibrary newLibrary = new IconLibrary();
 | 
					
						
							|  |  |  |  |             newLibrary.setId(UUID.fastUUID().toString(true));
 | 
					
						
							|  |  |  |  |             newLibrary.setPath(iconPath);
 | 
					
						
							|  |  |  |  |             newLibrary.setName(FileUtil.mainName(iconPath));
 | 
					
						
							|  |  |  |  |             newLibrary.setIsEnable(1);
 | 
					
						
							|  |  |  |  |             newLibrary.setCreatedAt(LocalDateTime.now());
 | 
					
						
							|  |  |  |  |             iconLibraryService.save(newLibrary);
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private List<IconTypeVo> iconTypeList() throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return new ArrayList<>();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         String querySql = """
 | 
					
						
							|  |  |  |  |                 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> typeList = SQLiteUtil.queryForList(iconPath, querySql, null, IconType.class);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 构建树形结构
 | 
					
						
							|  |  |  |  |         return buildIconTypeTree(typeList);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private List<IconTypeVo> buildIconTypeTree(List<IconType> typeList) {
 | 
					
						
							|  |  |  |  |         // 转换为VO
 | 
					
						
							|  |  |  |  |         List<IconTypeVo> voList = typeList.stream()
 | 
					
						
							|  |  |  |  |                 .map(iconType -> new IconTypeVo(iconType)).collect(Collectors.toList());
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 构建ID→VO的映射(方便快速查找父级)
 | 
					
						
							|  |  |  |  |         Map<String, IconTypeVo> voMap = voList.stream()
 | 
					
						
							|  |  |  |  |                 .collect(Collectors.toMap(IconTypeVo::getId, vo -> vo));
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 组装树形结构
 | 
					
						
							|  |  |  |  |         List<IconTypeVo> rootList = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         for (IconTypeVo vo : voList) {
 | 
					
						
							|  |  |  |  |             String parentId = vo.getParentId();
 | 
					
						
							|  |  |  |  |             if (parentId == null || parentId.isEmpty()) {
 | 
					
						
							|  |  |  |  |                 rootList.add(vo);
 | 
					
						
							|  |  |  |  |             } else {
 | 
					
						
							|  |  |  |  |                 IconTypeVo parentVo = voMap.get(parentId);
 | 
					
						
							|  |  |  |  |                 if (parentVo != null) {
 | 
					
						
							|  |  |  |  |                     parentVo.getChildren().add(vo);
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 排序
 | 
					
						
							|  |  |  |  |         rootList.sort(Comparator.comparingInt(IconTypeVo::getTreeIndex));
 | 
					
						
							|  |  |  |  |         sortIconTypeChildren(rootList);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return rootList;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private void sortIconTypeChildren(List<IconTypeVo> voList) {
 | 
					
						
							|  |  |  |  |         if (voList == null || voList.isEmpty()) {
 | 
					
						
							|  |  |  |  |             return;
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         // 排序当前层级
 | 
					
						
							|  |  |  |  |         voList.sort(Comparator.comparingInt(IconTypeVo::getTreeIndex));
 | 
					
						
							|  |  |  |  |         // 递归排序子层级
 | 
					
						
							|  |  |  |  |         for (IconTypeVo vo : voList) {
 | 
					
						
							|  |  |  |  |             sortIconTypeChildren(vo.getChildren());
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private List<String> getIconTypeIdsWithChildren(String typeId)
 | 
					
						
							|  |  |  |  |             throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         List<String> idList = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         if (!StringUtils.hasText(typeId)) {
 | 
					
						
							|  |  |  |  |             return idList;
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         String iconPath = getIconLibrary();
 | 
					
						
							|  |  |  |  |         if (iconPath == null) {
 | 
					
						
							|  |  |  |  |             return idList;
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 校验类型是否存在
 | 
					
						
							|  |  |  |  |         if (!isIconTypeExist(iconPath, typeId)) {
 | 
					
						
							|  |  |  |  |             return idList;
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-09-30 09:55:07 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 递归收集ID(包含自身)
 | 
					
						
							|  |  |  |  |         recursiveGetIconTypeChildren(iconPath, typeId, idList);
 | 
					
						
							|  |  |  |  |         return idList;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private void recursiveGetIconTypeChildren(String iconPath, String currentId, List<String> idList)
 | 
					
						
							|  |  |  |  |             throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         // 先添加当前ID
 | 
					
						
							|  |  |  |  |         idList.add(currentId);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 查询直接子类型
 | 
					
						
							|  |  |  |  |         String querySql = "SELECT id FROM icon_type WHERE parent_id = ? ORDER BY tree_index ASC";
 | 
					
						
							|  |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         params.add(currentId);
 | 
					
						
							|  |  |  |  |         List<IconType> childList = SQLiteUtil.queryForList(
 | 
					
						
							|  |  |  |  |                 iconPath, querySql, params, IconType.class
 | 
					
						
							|  |  |  |  |         );
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 递归查询子类型的子类型
 | 
					
						
							|  |  |  |  |         if (childList != null && !childList.isEmpty()) {
 | 
					
						
							|  |  |  |  |             for (IconType child : childList) {
 | 
					
						
							|  |  |  |  |                 recursiveGetIconTypeChildren(iconPath, child.getId(), idList);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private boolean isIconTypeExist(String iconPath, String typeId)
 | 
					
						
							|  |  |  |  |             throws SQLException, IllegalAccessException, InstantiationException {
 | 
					
						
							|  |  |  |  |         String checkSql = "SELECT id FROM icon_type WHERE id = ?";
 | 
					
						
							|  |  |  |  |         List<Object> params = new ArrayList<>();
 | 
					
						
							|  |  |  |  |         params.add(typeId);
 | 
					
						
							|  |  |  |  |         List<IconType> existList = SQLiteUtil.queryForList(
 | 
					
						
							|  |  |  |  |                 iconPath, checkSql, params, IconType.class
 | 
					
						
							|  |  |  |  |         );
 | 
					
						
							|  |  |  |  |         return existList != null && !existList.isEmpty();
 | 
					
						
							| 
									
										
										
										
											2025-09-26 13:46:54 +08:00
										 |  |  |  |     }
 | 
					
						
							|  |  |  |  | }
 |