This commit is contained in:
2025-11-28 15:35:06 +08:00
parent 7d8aeedcf2
commit 74bee3e232
18 changed files with 330 additions and 169 deletions

View File

@ -204,8 +204,8 @@ public class MilitaryLibraryController {
@Operation(summary = "军标类型树形列表")
@GetMapping("/militaryTypeTree")
public ApiResponse militaryTypeTree() throws SQLException, IllegalAccessException, InstantiationException {
List<MilitaryTypeVo> treeList = militaryTypeList();
public ApiResponse militaryTypeTree(@Parameter(description = "军标名称") @RequestParam(value = "militaryName", required = false) String militaryName) throws SQLException, IllegalAccessException, InstantiationException {
List<MilitaryTypeVo> treeList = militaryTypeList(militaryName);
return ApiResponse.success(treeList);
}
@ -241,6 +241,7 @@ public class MilitaryLibraryController {
return ApiResponse.success(null);
}
@Operation(summary = "获取军标文件数据")
@GetMapping("/data/military/{militaryId}/{fileSuffix}")
public ResponseEntity<byte[]> getMilitaryData(@PathVariable("militaryId") @Parameter(description = "军标ID") String militaryId, @PathVariable("fileSuffix") @Parameter(description = "军标文件后缀") String fileSuffix) {
@ -275,48 +276,61 @@ public class MilitaryLibraryController {
}
}
@Operation(summary = "根据类型查询军标列表")
@Operation(summary = "根据类型和名称模糊查询军标列表")
@PostMapping("/militaryList")
public ApiResponse getMilitaryList(@RequestParam("militaryTypeId") @Parameter(description = "军标类型ID") String typeId) throws SQLException, IllegalAccessException, InstantiationException {
public ApiResponse getMilitaryList(
@RequestParam("militaryTypeId") @Parameter(description = "军标类型ID") String militaryTypeId,
@Parameter(description = "军标名称模糊查询") @RequestParam(value = "name", required = false) String name)
throws SQLException, IllegalAccessException, InstantiationException {
String militaryPath = getMilitaryLibrary();
if (militaryPath == null) {
return ApiResponse.failure("请先创建或导入军标库");
}
// 获取当前类型及所有子类型ID递归
List<String> typeIdList = getMilitaryTypeIdsWithChildren(typeId);
List<String> typeIdList = getMilitaryTypeIdsWithChildren(militaryTypeId);
if (typeIdList == null || typeIdList.isEmpty()) {
return ApiResponse.success(new ArrayList<>());
}
// 构建IN条件处理SQL注入风险
// 构建IN条件
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);
// 构建SQL语句
StringBuilder sql = new StringBuilder("""
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)
""".formatted(idsWithQuotes));
// 查询并转换为VO
// 如果传入了名称、则增加模糊查询条件
if (name != null && !name.trim().isEmpty()) {
// 直接拼接SQL、注意SQL注入风险
sql.append(" AND m.military_name LIKE '%" + name.trim() + "%'");
}
// 统一添加排序条件
sql.append(" ORDER BY m.created_at DESC");
// 执行查询
List<MilitaryVo> militaryVoList = SQLiteUtil.queryForList(
militaryPath, querySql, null, MilitaryVo.class
militaryPath, sql.toString(), null, MilitaryVo.class
);
for (MilitaryVo vo : militaryVoList) {
vo.setMilitaryDataUrl("/militaryLibrary/data/military/" + vo.getId() + "/" + vo.getMilitaryType());
}
return ApiResponse.success(militaryVoList);
}
@ -407,7 +421,7 @@ public class MilitaryLibraryController {
}
// 返回更新后的树形列表
List<MilitaryTypeVo> treeList = militaryTypeList();
List<MilitaryTypeVo> treeList = militaryTypeList(null);
return ApiResponse.success(treeList);
}
@ -415,7 +429,10 @@ public class MilitaryLibraryController {
LambdaQueryWrapper<MilitaryLibrary> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MilitaryLibrary::getIsEnable, 1); // 1=启用、0=未启用
MilitaryLibrary library = militaryLibraryService.getOne(queryWrapper);
return library == null ? null : library.getPath();
if (library == null) {
throw new RuntimeException("请先创建或导入军标库");
}
return library.getPath();
}
private void addMilitaryLibrary(String militaryPath) {
@ -445,24 +462,44 @@ public class MilitaryLibraryController {
}
}
private List<MilitaryTypeVo> militaryTypeList() throws SQLException, IllegalAccessException, InstantiationException {
/**
* 查询军标分类树形结构
*/
private List<MilitaryTypeVo> militaryTypeList(String militaryName) throws SQLException, IllegalAccessException, InstantiationException {
String militaryPath = getMilitaryLibrary();
if (militaryPath == null) {
return new ArrayList<>();
return null;
}
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);
// 构建基础SQL语句
StringBuilder sqlBuilder = new StringBuilder("""
SELECT DISTINCT military_type.id, military_type.name, military_type.parent_id,
military_type.tree_index, military_type.created_at,
military_type.updated_at
FROM military_type
""");
// 构建树形结构
return buildMilitaryTypeTree(typeList);
// 如果传入了军标名称、则拼接 JOIN 和 WHERE 条件
if (militaryName != null && !militaryName.trim().isEmpty()) {
String trimmedName = militaryName.trim();
// 直接拼接SQL
sqlBuilder.append(" INNER JOIN military ON military_type.id = military.military_type_id");
sqlBuilder.append(" WHERE military.military_name LIKE '%" + trimmedName + "%'");
}
// 为所有查询都加上统一的排序条件
sqlBuilder.append(" ORDER BY military_type.tree_index ASC");
// 执行查询、获取符合条件的军标分类列表
List<MilitaryType> militaryTypes = SQLiteUtil.queryForList(
militaryPath,
sqlBuilder.toString(),
null,
MilitaryType.class
);
// 将扁平的分类列表转换为树形结构
return buildMilitaryTypeTree(militaryTypes);
}
private List<MilitaryTypeVo> buildMilitaryTypeTree(List<MilitaryType> typeList) {