@ -4,21 +4,27 @@ 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.MilitaryLibrary ;
import com.yj.earth.business.domain.MilitaryType ;
import com.yj.earth.business.domain.MilitaryLibrary ; // 需自定义: 对应军标库配置表( 同ModelLibrary结构)
import com.yj.earth.business.domain.MilitaryType ; // 需自定义: 对应military_type表实体
import com.yj.earth.business.service.FileInfoService ;
import com.yj.earth.business.service.MilitaryLibraryService ;
import com.yj.earth.business.service.MilitaryLibraryService ; // 需自定义: 军标库Service( 同ModelLibraryService逻辑)
import com.yj.earth.common.util.ApiResponse ;
import com.yj.earth.common.util.FileCommonUtil ;
import com.yj.earth.common.util.SQLiteUtil ;
import com.yj.earth.dto.militaryLibrary.AddMilitaryTypeDto ;
import com.yj.earth.dto.militaryLibrary.CreateMilitaryLibraryDto ;
import com.yj.earth.dto.militaryLibrary.DragMilitaryTypeDto ;
import com.yj.earth.dto.militaryLibrary.UpdateMilitaryTypeNameDto ;
import com.yj.earth.vo.MilitaryType Vo ;
import com.yj.earth.vo.MilitaryVo ;
import com.yj.earth.dto.militaryLibrary.AddMilitaryTypeDto ; // 需自定义: 添加军标类型DTO
import com.yj.earth.dto.militaryLibrary.CreateMilitaryLibraryDto ; // 需自定义: 创建军标库DTO
import com.yj.earth.dto.militaryLibrary.DragMilitaryTypeDto ; // 需自定义: 拖动军标类型DTO
import com.yj.earth.dto.militaryLibrary.UpdateMilitaryTypeNameDto ; // 需自定义: 修改军标类型名称DTO
import com.yj.earth.vo.MilitaryData Vo ;
import com.yj.earth.vo.MilitaryType Vo ; // 需自定义: 军标类型树形VO( 同ModelTypeVo结构)
import com.yj.earth.vo.MilitaryVo ; // 需自定义: 军标列表VO( 剔除海报相关字段)
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.http.HttpHeaders ;
import org.springframework.http.HttpStatus ;
import org.springframework.http.MediaType ;
import org.springframework.http.ResponseEntity ;
import org.springframework.util.StringUtils ;
import org.springframework.web.bind.annotation.* ;
import org.springframework.web.multipart.MultipartFile ;
@ -26,9 +32,12 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource ;
import java.io.File ;
import java.io.IOException ;
import java.net.URLEncoder ;
import java.nio.charset.StandardCharsets ;
import java.sql.SQLException ;
import java.time.LocalDateTime ;
import java.util.ArrayList ;
import java.util.Comparator ;
import java.util.List ;
import java.util.Map ;
import java.util.stream.Collectors ;
@ -38,44 +47,52 @@ import java.util.stream.Collectors;
@RestController
@RequestMapping ( " /militaryLibrary " )
public class MilitaryLibraryController {
@Resource
private MilitaryLibraryService militaryLibraryService ;
@Resource
private FileInfoService fileInfoService ;
@Operation ( summary = " 创建军标库 " )
@PostMapping ( " /createMilitaryLibrary " )
public ApiResponse createMilitaryLibrary ( @RequestBody CreateMilitaryLibraryDto createMilitaryLibrary Dto ) {
public ApiResponse createMilitaryLibrary ( @RequestBody CreateMilitaryLibraryDto createDto ) {
try {
// 参数校验
String folderPath = createMilitaryLibrary Dto . getPath ( ) ;
String milit aryName = createMilitaryLibrary Dto . getName ( ) ;
// 处理路径、组合为完整军标库文件路径
// 参数校验与路径处理
String folderPath = createDto . getPath ( ) ;
String libr aryName = createDto . getName ( ) ;
if ( ! StringUtils . hasText ( folderPath ) | | ! StringUtils . hasText ( libraryName ) ) {
return ApiResponse . failure ( " 路径和名称不能为空 " ) ;
}
// 构建完整军标库文件路径( SQLite文件)
File parentDir = new File ( folderPath ) ;
File militaryFile = new File ( parentDir , milit aryName) ;
File militaryFile = new File ( parentDir , libr aryName) ;
String militaryPath = militaryFile . getAbsolutePath ( ) . replace ( " \\ " , " / " ) ;
// 检查父目录是否存在、不存在则创建
// 父目录不存在则创建
if ( ! parentDir . exists ( ) ) {
boolean mkdirsSuccess = parentDir . mkdirs ( ) ;
if ( ! mkdirsSuccess ) {
return ApiResponse . failure ( " 创建父目录失败: " + folderPath ) ;
}
}
// 检查军标库文件是否已存在
// 校验军标库文件是否已存在
if ( militaryFile . exists ( ) ) {
if ( militaryFile . isDirectory ( ) ) {
return ApiResponse . failure ( " 同名目录已存在、 无法创建文件: " + militaryPath ) ;
return ApiResponse . failure ( " 同名目录已存在, 无法创建文件: " + militaryPath ) ;
}
return ApiResponse . failure ( " 军标库文件已存在: " + militaryPath ) ;
}
// 创建军标库文件
boolean createSuccess = militaryFile . createNewFile ( ) ;
if ( ! createSuccess ) {
// 创建SQLite文件
boolean createFile Success = militaryFile . createNewFile ( ) ;
if ( ! createFileSuccess ) {
return ApiResponse . failure ( " 创建军标库文件失败: " + militaryPath ) ;
}
// 添加军标库信息
addMilitaryLibrary ( militaryPath ) ;
// 初始化军标库表结构
SQLiteUtil . initializationMilitary ( militaryPath ) ;
// 添加军标库配置到数据库
addMilitaryLibrary ( militaryPath ) ;
return ApiResponse . success ( null ) ;
} catch ( Exception e ) {
return ApiResponse . failure ( " 创建军标库失败: " + e . getMessage ( ) ) ;
@ -84,304 +101,441 @@ public class MilitaryLibraryController {
@Operation ( summary = " 导入军标库 " )
@PostMapping ( " /importMilitaryLibrary " )
public ApiResponse importMilitaryLibrary ( @RequestParam ( " militaryPath " ) @Parameter ( description = " 军标库路径 " ) String militaryPath ) {
addMilitaryLibrary ( militaryPath ) ;
return ApiResponse . success ( null ) ;
public ApiResponse importMilitaryLibrary (
@RequestParam ( " militaryPath " ) @Parameter ( description = " 军标库SQLite文件路径 " ) String militaryPath ) {
try {
// 校验路径是否存在
File militaryFile = new File ( militaryPath ) ;
if ( ! militaryFile . exists ( ) | | ! militaryFile . isFile ( ) ) {
return ApiResponse . failure ( " 军标库文件不存在: " + militaryPath ) ;
}
// 添加到配置表并启用
addMilitaryLibrary ( militaryPath ) ;
return ApiResponse . success ( null ) ;
} catch ( Exception e ) {
return ApiResponse . failure ( " 导入军标库失败: " + e . getMessage ( ) ) ;
}
}
@Operation ( summary = " 添加军标类型 " )
@PostMapping ( " /addMilitaryType " )
public ApiResponse addMilitaryType ( @RequestBody AddMilitaryTypeDto addMilitaryType Dto ) throws SQLException , IllegalAccessException , InstantiationException {
public ApiResponse addMilitaryType ( @RequestBody AddMilitaryTypeDto addDto ) throws SQLException , IllegalAccessException , InstantiationException {
// 获取当前启用的军标库路径
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 检查父级是否存在
String parentId = addMilitaryTypeDto . getParentId ( ) ;
if ( parentId ! = null ) {
String sql = " SELECT * FROM military_type WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( parentId ) ;
MilitaryType militaryType = SQLiteUtil . queryForObject ( militaryPath , sql , params , MilitaryType . class ) ;
if ( m ilitaryType = = null ) {
return ApiResponse . failure ( " 父级军标类型不存在 " ) ;
// 校验父级类型(若有)
String parentId = addDto . getParentId ( ) ;
if ( StringUtils . hasText ( parentId ) ) {
String checkParentSql = " SELECT id FROM military_type WHERE id = ? " ;
List < Object > parentParams = new ArrayList < > ( ) ;
parentParams . add ( parentId ) ;
M ilitaryType parentType = SQLiteUtil . queryForObject (
militaryPath , checkParentSql , parentParams , MilitaryType . class
) ;
if ( parentType = = null ) {
return ApiResponse . failure ( " 父级军标类型不存在: " + parentId ) ;
}
}
String sql = " INSERT INTO military_type " +
// 插入军标类型
String insertSql = " INSERT INTO military_type " +
" (id, name, parent_id, tree_index, created_at) " +
" VALUES (?, ?, ?, ?, ?) " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( UUID . fastUUID ( ) . toString ( true ) ) ;
params . add ( addMilitaryType Dto . getName ( ) ) ;
params . add ( addMilitaryTypeDto . getP arentId( ) );
params . add ( addDto . getName ( ) ) ;
params . add ( p arentId) ;
params . add ( 0 ) ;
params . add ( LocalDateTime . now ( ) ) ;
SQLiteUtil . executeUpdate ( militaryPath , s ql, params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 删除军标类型 " )
@PostMapping ( " /deleteMilitaryType " )
public ApiResponse deleteMilitaryType ( @Parameter ( description = " 军标类型ID " ) @RequestParam ( " militaryTypeId " ) String militaryTypeId ) throws SQLException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
String sql = " DELETE FROM military_type WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( militaryTypeId ) ;
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
params . add ( LocalDateTime . now ( ) . toString ( ) );
SQLiteUtil . executeUpdate ( militaryPath , insertS ql, params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 修改军标类型名称 " )
@PostMapping ( " /updateMilitaryTypeName " )
public ApiResponse updateMilitaryTypeName ( @RequestBody UpdateMilitaryTypeNameDto updateMilitaryTypeNameDto ) throws SQLException {
public ApiResponse updateMilitaryTypeName ( @RequestBody UpdateMilitaryTypeNameDto updateDto )
throws SQLException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
String sql = " UPDATE military_type SET name = ? WHERE id = ? " ;
// 执行更新
String updateSql = " UPDATE military_type SET name = ?, updated_at = ? WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( updateMilitaryTypeName Dto . getName ( ) ) ;
params . add ( updateMilitaryTypeNameDto . getId ( ) ) ;
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
params . add ( updateDto . getName ( ) ) ;
params . add ( LocalDateTime . now ( ) . toString ( ) ) ;
params . add ( updateDto . getId ( ) ) ;
SQLiteUtil . executeUpdate ( militaryPath , updateSql , params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 军标类型列表 " )
@Ge tMapping ( " /m ilitaryTypeList " )
@Operation ( summary = " 删除 军标类型" )
@Pos tMapping ( " /deleteM ilitaryType " )
public ApiResponse deleteMilitaryType (
@RequestParam ( " militaryTypeId " ) @Parameter ( description = " 军标类型ID " ) String typeId )
throws SQLException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 执行删除
String deleteSql = " DELETE FROM military_type WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( typeId ) ;
SQLiteUtil . executeUpdate ( militaryPath , deleteSql , params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 军标类型树形列表 " )
@GetMapping ( " /militaryTypeTree " )
public ApiResponse militaryTypeTree ( ) throws SQLException , IllegalAccessException , InstantiationException {
String m ilitaryPath = getM ilitaryLibrary ( ) ;
if ( militaryPath = = 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 military_type ORDER BY tree_index ASC
""" ;
List < MilitaryType > militaryTypes = SQLiteUtil . queryForList ( militaryPath , sql , null , MilitaryType . class ) ;
// 转换为树形结构
List < MilitaryTypeVo > treeList = buildMilitaryTypeTree ( militaryTypes ) ;
List < M ilitaryTypeVo > treeList = m ilitaryTypeList ( ) ;
return ApiResponse . success ( treeList ) ;
}
@Operation ( summary = " 拖动军标类型树 " )
@PostMapping ( " /dragMilitaryType " )
public ApiResponse dragMilitaryType ( @RequestBody DragMilitaryTypeDto dragMilitaryTypeDto ) throws SQLException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 动态构建SQL和参数
List < String > updateFields = new ArrayList < > ( ) ;
List < Object > params = new ArrayList < > ( ) ;
// 判断 parentId 是否存在
if ( dragMilitaryTypeDto . getParentId ( ) ! = null ) {
updateFields . add ( " parent_id = ? " ) ;
params . add ( dragMilitaryTypeDto . getParentId ( ) ) ;
}
// 判断 treeIndex 是否存在
if ( dragMilitaryTypeDto . getTreeIndex ( ) ! = null ) {
updateFields . add ( " tree_index = ? " ) ;
params . add ( dragMilitaryTypeDto . getTreeIndex ( ) ) ;
}
// 构建完整 SQL
String sql = " UPDATE military_type SET " + String . join ( " , " , updateFields ) + " WHERE id = ? " ;
params . add ( dragMilitaryTypeDto . getId ( ) ) ;
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 添加军标文件 " )
@PostMapping ( " /addMilitaryFile " )
public ApiResponse addMilitaryFile ( @RequestParam ( " files " ) MultipartFile [ ] files , @Parameter ( description = " 军标类型ID " ) @RequestParam ( " militaryTypeId " ) String militaryT ypeId) throws IOException , SQLException {
// 获取最新 的军标库路径
public ApiResponse addMilitaryFile ( @RequestParam ( " files " ) MultipartFile [ ] files , @RequestParam ( " militaryTypeId " ) @ Parameter ( description = " 军标类型ID " ) String t ypeId) throws IOException , SQLException , IllegalAccessException , InstantiationException {
// 获取当前启用 的军标库
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 循环处理每个上传的文件
// 校验类型是否存在
if ( ! isMilitaryTypeExist ( militaryPath , typeId ) ) {
return ApiResponse . failure ( " 军标类型不存在: " + typeId ) ;
}
// 循环处理每个文件
for ( MultipartFile file : files ) {
// 跳过空文件
if ( file . isEmpty ( ) ) {
continue ;
continue ; // 跳过空文件
}
// 获取文件信息
String fileName = file . getOriginalFilename ( ) ;
if ( fileName = = null ) {
continue ;
}
String fileSuffix = FileUtil . extName ( fileName ) ;
String fileNameWithoutSuffix = FileUtil . mainName ( fileName ) ;
// 构建插入SQL
String sql = " INSERT INTO military " +
" (id, military_type_id, military_name, military_type, data, created_at) " +
// 解析文件名与后缀
String originalFileName = file . getOriginalFilename ( ) ;
if ( originalFileName = = null ) {
continue ;
}
String fileSuffix = FileUtil . extName ( originalFileName ) ;
String fileNameWithoutSuffix = FileUtil . mainName ( originalFileName ) ;
// 插入军标数据
String insertSql = " INSERT INTO military " +
" (id, military_type_id, military_name, military_type, military_data, created_at) " +
" VALUES (?, ?, ?, ?, ?, ?) " ;
String url = fileInfoService . uploadWithPreview ( file ) ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( UUID . fastUUID ( ) . toString ( true ) ) ;
params . add ( militaryT ypeId) ;
params . add ( t ypeId) ;
params . add ( fileNameWithoutSuffix ) ;
params . add ( fileSuffix ) ;
params . add ( url ) ;
params . add ( LocalDateTime . now ( ) ) ;
params . add ( file . getBytes ( ) ) ;
params . add ( LocalDateTime . now ( ) . toString ( ) );
// 执行插入操作
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
SQLiteUtil . executeUpdate ( militaryPath , insertSql , params ) ;
}
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 根据军标类型查看军标列表 " )
@Operation ( summary = " 获取军标文件数据 " )
@GetMapping ( " /data/military/{militaryId}/{fileSuffix} " )
public ResponseEntity < byte [ ] > getMilitaryData ( @PathVariable ( " militaryId " ) @Parameter ( description = " 军标ID " ) String militaryId , @PathVariable ( " fileSuffix " ) @Parameter ( description = " 军标文件后缀 " ) String fileSuffix ) {
try {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ResponseEntity . notFound ( ) . build ( ) ;
}
// 查询军标二进制数据
String querySql = " SELECT military_name, military_data FROM military WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( militaryId ) ;
MilitaryDataVo dataVo = SQLiteUtil . queryForObject (
militaryPath , querySql , params , MilitaryDataVo . class
) ;
if ( dataVo = = null | | dataVo . getMilitaryData ( ) = = null ) {
return ResponseEntity . notFound ( ) . build ( ) ;
}
// 构建响应头【支持中文文件名+预览】
String originalFileName = dataVo . getMilitaryName ( ) + " . " + 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 . getMilitaryData ( ) ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
return ResponseEntity . status ( HttpStatus . INTERNAL_SERVER_ERROR ) . build ( ) ;
}
}
@Operation ( summary = " 根据类型查询军标列表 " )
@PostMapping ( " /militaryList " )
public ApiResponse m ilitaryList( @Parameter ( description = " 军标类型ID " ) @RequestParam ( " militaryTypeId " ) String militaryT ypeId) throws SQLException , IllegalAccessException , InstantiationException {
// 获取最新的军标库
public ApiResponse getM ilitaryList( @RequestParam ( " militaryTypeId " ) @ Parameter ( description = " 军标类型ID " ) String t ypeId) throws SQLException , IllegalAccessException , InstantiationException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 多表联查、查询所有的军标
String sql = """
SELECT
military.id,
military.military_type_id as militaryTypeId,
military.military_name as militaryName,
military.military_type as militaryType,
military.data,
military.view,
military.created_at as createdAt,
military.updated_at as updatedAt,
military_type.name as militaryTypeName from
military JOIN military_type ON military.military_type_id = military_type.id
WHERE military.military_type_id = ?
""" ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( militaryTypeId) ;
List < MilitaryVo > militaryVos = SQLiteUtil . queryForList ( militaryPath , sql , params , MilitaryVo . class ) ;
return ApiResponse . success ( militaryVos ) ;
// 获取当前类型及所有子类型ID( 递归)
List < String > typeIdList = getMilitaryTypeIdsWithChildren ( 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
m.id,
m.military_type_id as militaryTypeId,
m.military_name as militaryName,
m.military_type as militaryType,
m.created_at as createdAt,
m.updated_at as updatedAt,
t.name as militaryTypeName
FROM military m
JOIN military_type t ON m.military_type_id = t.id
WHERE m.military_type_id IN (%s)
ORDER BY m.created_at DESC
""" . replace ( " %s " , idsWithQuotes ) ;
// 查询并转换为VO
List < MilitaryVo > militaryVoList = SQLiteUtil . queryForList (
militaryPath , querySql , null , MilitaryVo . class
) ;
for ( MilitaryVo vo : militaryVoList ) {
vo . setMilitaryDataUrl ( " /militaryLibrary/data/military/ " + vo . getId ( ) + " / " + vo . getMilitaryType ( ) ) ;
}
return ApiResponse . success ( militaryVoList ) ;
}
@Operation ( summary = " 更新军标信息 " )
@PostMapping ( " /upload MilitaryInfo " )
public ApiResponse upload MilitaryInfo (
@Parameter ( description = " 军标ID " ) @RequestParam ( " militaryId " ) String militaryId ,
@Parameter ( description = " 军标名称 " ) @RequestParam ( value = " militaryName " , required = false ) String militaryName )
@Operation ( summary = " 更新军标名称 " )
@PostMapping ( " /update MilitaryInfo " )
public ApiResponse update MilitaryInfo (
@RequestParam ( " militaryId " ) @ Parameter ( description = " 军标ID " ) String militaryId ,
@RequestParam ( " militaryName " ) @Parameter ( description = " 新军标名称 " ) String militaryName )
throws SQLException {
// 获取最新的军标库路径
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 如果没有需要更新的字段、直接返回成功
if ( ! StringUtils . hasText ( militaryName ) ) {
return ApiResponse . success ( null ) ;
}
// 构建更新SQL和参数
String sql = " UPDATE military SET updated_at = ?, military_name = ? WHERE id = ? " ;
String updateSql = " UPDATE military SET military_name = ?, updated_at = ? WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( LocalDateTime . now ( ) ) ;
params . add ( militaryName ) ;
params . add ( LocalDateTime . now ( ) . toString ( ) ) ;
params . add ( militaryId ) ;
// 执行更新
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
SQLiteUtil . executeUpdate ( militaryPath , updateSql , params ) ;
return ApiResponse . success ( null ) ;
}
@Operation ( summary = " 删除军标 " )
@PostMapping ( " /deleteMilitary " )
public ApiResponse deleteMilitary ( @Parameter ( description = " 军标ID " ) @RequestParam ( " militaryId " ) String militaryId ) throws SQLException {
public ApiResponse deleteMilitary ( @RequestParam ( " militaryId " ) @ Parameter ( description = " 军标ID " ) String militaryId ) throws SQLException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
String sql = " DELETE FROM military WHERE id = ? " ;
// 执行删除
String deleteSql = " DELETE FROM military WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( militaryId ) ;
SQLiteUtil . executeUpdate ( militaryPath , sql , params ) ;
return ApiResponse . success ( null ) ;
SQLiteUtil . executeUpdate ( militaryPath , deleteSql , params ) ;
return ApiResponse . success ( " 删除军标成功 " ) ;
}
private List < MilitaryTypeVo > buildMilitaryTypeTree ( List < MilitaryType > militaryTypes ) {
List < MilitaryTypeVo > treeNodes = militaryTypes . stream ( )
. map ( militaryType - > new MilitaryTypeVo ( militaryType ) )
. collect ( Collectors . toList ( ) ) ;
// 构建节点ID到节点的映射
Map < String, M ilitaryTypeVo > nodeMap = treeNodes . stream ( )
. collect ( Collectors . toMap ( MilitaryTypeVo : : getId , node - > node ) ) ;
// 根节点列表
List < MilitaryTypeVo > rootNodes = new ArrayList < > ( ) ;
// 为每个节点添加子节点
for ( MilitaryTypeVo node : treeNodes ) {
String parentId = node . getParentId ( ) ;
@Operation ( summary = " 拖动调整军标类型层级 " )
@PostMapping ( " /dragMilitaryType " )
public ApiResponse dragMilitaryType ( @RequestBody List < DragMilitaryTypeDto > dragDtoList )
throws SQLException , IllegalAccessException , InstantiationException {
String m ilitaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return ApiResponse . failure ( " 请先创建或导入军标库 " ) ;
}
// 批量更新层级和排序
for ( DragMilitaryTypeDto dto : dragDtoList ) {
String updateSql = " UPDATE military_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 ( militaryPath , updateSql , params ) ;
}
// 返回更新后的树形列表
List < MilitaryTypeVo > treeList = militaryTypeList ( ) ;
return ApiResponse . success ( treeList ) ;
}
private String getMilitaryLibrary ( ) {
LambdaQueryWrapper < MilitaryLibrary > queryWrapper = new LambdaQueryWrapper < > ( ) ;
queryWrapper . eq ( MilitaryLibrary : : getIsEnable , 1 ) ; // 1=启用, 0=未启用
MilitaryLibrary library = militaryLibraryService . getOne ( queryWrapper ) ;
return library = = null ? null : library . getPath ( ) ;
}
private void addMilitaryLibrary ( String militaryPath ) {
// 所有已存在的军标库设置为「未启用」
List < MilitaryLibrary > existLibraries = militaryLibraryService . list ( ) ;
for ( MilitaryLibrary library : existLibraries ) {
library . setIsEnable ( 0 ) ;
militaryLibraryService . updateById ( library ) ;
}
// 检查路径是否已存在(存在则启用,不存在则新增)
LambdaQueryWrapper < MilitaryLibrary > pathWrapper = new LambdaQueryWrapper < > ( ) ;
pathWrapper . eq ( MilitaryLibrary : : getPath , militaryPath ) ;
MilitaryLibrary existLibrary = militaryLibraryService . getOne ( pathWrapper ) ;
if ( existLibrary ! = null ) {
existLibrary . setIsEnable ( 1 ) ;
militaryLibraryService . updateById ( existLibrary ) ;
} else {
MilitaryLibrary newLibrary = new MilitaryLibrary ( ) ;
newLibrary . setId ( UUID . fastUUID ( ) . toString ( true ) ) ;
newLibrary . setPath ( militaryPath ) ;
newLibrary . setName ( FileUtil . mainName ( militaryPath ) ) ;
newLibrary . setIsEnable ( 1 ) ;
newLibrary . setCreatedAt ( LocalDateTime . now ( ) ) ;
militaryLibraryService . save ( newLibrary ) ;
}
}
private List < MilitaryTypeVo > militaryTypeList ( ) throws SQLException , IllegalAccessException , InstantiationException {
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = 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 military_type
ORDER BY tree_index ASC
""" ;
List < MilitaryType > typeList = SQLiteUtil . queryForList ( militaryPath , querySql , null , MilitaryType . class ) ;
// 构建树形结构
return buildMilitaryTypeTree ( typeList ) ;
}
private List < MilitaryTypeVo > buildMilitaryTypeTree ( List < MilitaryType > typeList ) {
// 转换为VO
List < MilitaryTypeVo > voList = typeList . stream ( )
. map ( militaryType - > new MilitaryTypeVo ( militaryType ) ) . collect ( Collectors . toList ( ) ) ;
// 构建ID→VO的映射( 方便快速查找父级)
Map < String , MilitaryTypeVo > voMap = voList . stream ( )
. collect ( Collectors . toMap ( MilitaryTypeVo : : getId , vo - > vo ) ) ;
// 组装树形结构
List < MilitaryTypeVo > rootList = new ArrayList < > ( ) ;
for ( MilitaryTypeVo vo : voList ) {
String parentId = vo . getParentId ( ) ;
if ( parentId = = null | | parentId . isEmpty ( ) ) {
// 没有父节点的是根节点
rootNodes . add ( node ) ;
rootList . add ( vo ) ;
} else {
// 找到父节点并添加为子节点
MilitaryTypeVo parentNode = nodeMap . get ( parentId ) ;
if ( parentNode ! = null ) {
parentNode . getChildren ( ) . add ( node ) ;
MilitaryTypeVo parentVo = voMap . get ( parentId ) ;
if ( parentVo ! = null ) {
parentVo . getChildren ( ) . add ( vo ) ;
}
}
}
return rootNodes ;
// 排序
rootList . sort ( Comparator . comparingInt ( MilitaryTypeVo : : getTreeIndex ) ) ;
sortMilitaryTypeChildren ( rootList ) ;
return rootList ;
}
private String ge tMilitaryLibrary ( ) {
// 获取启用的军标库
LambdaQueryWrapper < MilitaryLibrary > queryWrapper = new LambdaQueryWrapper < > ( ) ;
queryWrapper . eq ( MilitaryLibrary : : getIsEnable , 1 ) ;
MilitaryLibrary militaryLibrary = militaryLibraryService . getOne ( queryWrapper ) ;
if ( militaryLibrary = = null ) {
return null ;
}
return militaryLibrary . getPath ( ) ;
}
private void addMilitaryLibrary ( String militaryPath ) {
// 查询系统所有的军标库
List < MilitaryLibrary > militaryLibraries = militaryLibraryService . list ( ) ;
// 遍历并更新状态
for ( MilitaryLibrary militaryLibrary : militaryLibraries ) {
// 设置启用状态为0
militaryLibrary . setIsEnable ( 0 ) ;
militaryLibraryService . updateById ( militaryLibrary ) ;
}
// 检查相同路径的军标库是否已存在
LambdaQueryWrapper < MilitaryLibrary > pathWrapper = new LambdaQueryWrapper < > ( ) ;
pathWrapper . eq ( MilitaryLibrary : : getPath , militaryPath ) ;
MilitaryLibrary existingMilitary = militaryLibraryService . getOne ( pathWrapper ) ;
// 若存在相同路径的军标库、不做处理、仅仅更新状态为显示
if ( existingMilitary ! = null ) {
existingMilitary . setIsEnable ( 1 ) ;
militaryLibraryService . updateById ( existingMilitary ) ;
private void sor tMilitaryTypeChildren ( List < MilitaryTypeVo > voList ) {
if ( voList = = null | | voList . isEmpty ( ) ) {
return ;
} else {
// 新增军标库
MilitaryLibrary newMilitary = new MilitaryLibrary ( ) ;
File file = FileUtil . file ( militaryPath ) ;
newMilitary . setId ( UUID . fastUUID ( ) . toString ( true ) ) ;
newMilitary . setPath ( militaryPath ) ;
newMilitary . setName ( FileUtil . extName ( file ) ) ;
newMilitary . setIsEnable ( 1 ) ;
militaryLibraryService . save ( newMilitary ) ;
}
// 排序当前层级
voList . sort ( Comparator . comparingInt ( MilitaryTypeVo : : getTreeIndex ) ) ;
// 递归排序子层级
for ( MilitaryTypeVo vo : voList ) {
sortMilitaryTypeChildren ( vo . getChildren ( ) ) ;
}
}
private List < String > getMilitaryTypeIdsWithChildren ( String typeId )
throws SQLException , IllegalAccessException , InstantiationException {
List < String > idList = new ArrayList < > ( ) ;
if ( ! StringUtils . hasText ( typeId ) ) {
return idList ;
}
String militaryPath = getMilitaryLibrary ( ) ;
if ( militaryPath = = null ) {
return idList ;
}
// 校验类型是否存在
if ( ! isMilitaryTypeExist ( militaryPath , typeId ) ) {
return idList ;
}
// 递归收集ID( 包含自身)
recursiveGetMilitaryTypeChildren ( militaryPath , typeId , idList ) ;
return idList ;
}
private void recursiveGetMilitaryTypeChildren ( String militaryPath , String currentId , List < String > idList )
throws SQLException , IllegalAccessException , InstantiationException {
// 先添加当前ID
idList . add ( currentId ) ;
// 查询直接子类型
String querySql = " SELECT id FROM military_type WHERE parent_id = ? ORDER BY tree_index ASC " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( currentId ) ;
List < MilitaryType > childList = SQLiteUtil . queryForList (
militaryPath , querySql , params , MilitaryType . class
) ;
// 递归查询子类型的子类型
if ( childList ! = null & & ! childList . isEmpty ( ) ) {
for ( MilitaryType child : childList ) {
recursiveGetMilitaryTypeChildren ( militaryPath , child . getId ( ) , idList ) ;
}
}
}
private boolean isMilitaryTypeExist ( String militaryPath , String typeId )
throws SQLException , IllegalAccessException , InstantiationException {
String checkSql = " SELECT id FROM military_type WHERE id = ? " ;
List < Object > params = new ArrayList < > ( ) ;
params . add ( typeId ) ;
List < MilitaryType > existList = SQLiteUtil . queryForList (
militaryPath , checkSql , params , MilitaryType . class
) ;
return existList ! = null & & ! existList . isEmpty ( ) ;
}
}