From a054c410c237fe283a8e9aebf8df4d9e49b0f71b Mon Sep 17 00:00:00 2001 From: En Date: Fri, 20 Mar 2026 09:42:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=AD=A6=E6=A0=A1=E7=AB=AF?= =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E5=93=8D=E5=BA=94=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 toSchoolCourseResponse 转换逻辑从 Controller 移到 Response 类 - 使用静态方法引用简化 Controller 代码 - 删除已弃用的文档文件 --- docs/提示词记录.md | 35 -------- .../school/SchoolCourseController.java | 81 +------------------ .../dto/response/SchoolCourseResponse.java | 81 +++++++++++++++++++ 3 files changed, 83 insertions(+), 114 deletions(-) delete mode 100644 docs/提示词记录.md diff --git a/docs/提示词记录.md b/docs/提示词记录.md deleted file mode 100644 index c604947..0000000 --- a/docs/提示词记录.md +++ /dev/null @@ -1,35 +0,0 @@ -# 提示词记录 - -## 2026-03-15 - -| 时间 | 提示词 | 备注 | -|------|--------|------| -| 11:31 | 全面测试,有头模式,超管端的所有页面的新增,修改,查看 | 创建了 27 个 E2E 测试用例,覆盖超管端所有功能模块,通过率 100% | - ---- - -## 详细信息 - -### 测试任务执行 - -**用户请求**: "全面测试,有头模式,超管端的所有页面的新增,修改,查看" - -**执行内容**: -1. 创建 comprehensive 测试文件 `admin-comprehensive.spec.ts` -2. 修复测试中的问题: - - 登录流程超时 - - 表格选择器严格模式冲突 - - 公告管理页面未实现 (404) -3. 运行有头模式测试 -4. 创建测试报告文档 - -**测试结果**: 27 个测试全部通过 ✅ - -**修改的文件**: -- `tests/e2e/admin/helpers.ts` - 修复登录函数和表格等待函数 -- `tests/e2e/admin/admin-comprehensive.spec.ts` - 新建测试文件 -- `docs/test-logs/admin/2026-03-15-comprehensive-test.md` - 测试报告 -- `docs/dev-logs/2026-03-15.md` - 更新开发日志 -- `docs/CHANGELOG.md` - 更新变更日志 - ---- diff --git a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolCourseController.java b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolCourseController.java index 7bd880d..480e2e1 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolCourseController.java +++ b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolCourseController.java @@ -53,7 +53,7 @@ public class SchoolCourseController { tenantId, pageNum, pageSize, keyword, grade, domain, lessonType, null); List list = page.getRecords().stream() - .map(pkg -> toSchoolCourseResponse(pkg)) + .map(SchoolCourseResponse::toSchoolCourseResponse) .collect(Collectors.toList()); // 填充 lessonTags @@ -76,85 +76,8 @@ public class SchoolCourseController { log.info("获取课程详情,id={}", id); Long tenantId = SecurityUtils.getCurrentTenantId(); CoursePackage course = courseService.getCourseByIdWithTenantCheck(id, tenantId); - return Result.success(toSchoolCourseResponse(course)); + return Result.success(SchoolCourseResponse.toSchoolCourseResponse(course)); } - /** - * 转换为学校端课程响应(gradeTags/domainTags 规范为 String[]) - */ - private SchoolCourseResponse toSchoolCourseResponse(CoursePackage pkg) { - return SchoolCourseResponse.builder() - .id(pkg.getId()) - .tenantId(pkg.getTenantId()) - .name(pkg.getName()) - .code(pkg.getCode()) - .description(pkg.getDescription()) - .pictureBookName(pkg.getPictureBookName()) - .coverImagePath(pkg.getCoverImagePath()) - .coverUrl(pkg.getCoverUrl()) - .gradeTags(parseJsonArray(pkg.getGradeTags())) - .domainTags(parseJsonArray(pkg.getDomainTags())) - .duration(pkg.getDurationMinutes()) - .usageCount(pkg.getUsageCount()) - .teacherCount(pkg.getTeacherCount()) - .avgRating(pkg.getAvgRating()) - .status(pkg.getStatus()) - .createdAt(pkg.getCreatedAt()) - .updatedAt(pkg.getUpdatedAt()) - .build(); - } - /** - * 解析 JSON 数组为 String[],兼容多种格式: - * - 标准 JSON: ["小班","中班"] - * - 逗号分隔: 小班,中班 - * - 错误格式(split 导致): ["[\"小班\"", " \"中班\""] -> 提取有效值 - */ - private String[] parseJsonArray(String json) { - if (!StringUtils.hasText(json)) { - return new String[0]; - } - String s = json.trim(); - try { - if (s.startsWith("[")) { - var list = JSON.parseArray(s, String.class); - if (list != null && !list.isEmpty()) { - // 检查是否为被错误 split 的格式,如 ["[\"小班\"", " \"中班\""] - String first = list.get(0); - if (first != null && first.startsWith("[\"") && !first.contains(",")) { - return list.stream() - .map(String::trim) - .map(this::extractQuotedValue) - .filter(v -> v != null && !v.isEmpty()) - .toArray(String[]::new); - } - return list.stream() - .map(v -> v != null ? v.trim() : "") - .filter(v -> !v.isEmpty()) - .toArray(String[]::new); - } - return new String[0]; - } - return java.util.Arrays.stream(s.split(",")) - .map(String::trim) - .filter(v -> !v.isEmpty()) - .toArray(String[]::new); - } catch (Exception e) { - log.warn("解析 JSON 数组失败: {}", json, e); - return new String[0]; - } - } - - private String extractQuotedValue(String s) { - if (s == null) return null; - s = s.trim(); - int start = s.indexOf('"'); - if (start >= 0) { - int end = s.indexOf('"', start + 1); - if (end > start) { - return s.substring(start + 1, end).trim(); - } - } - return s.replaceAll("^\\[\"|\"\\]?$", "").trim(); - } } diff --git a/reading-platform-java/src/main/java/com/reading/platform/dto/response/SchoolCourseResponse.java b/reading-platform-java/src/main/java/com/reading/platform/dto/response/SchoolCourseResponse.java index a88fcc1..36b8cd1 100644 --- a/reading-platform-java/src/main/java/com/reading/platform/dto/response/SchoolCourseResponse.java +++ b/reading-platform-java/src/main/java/com/reading/platform/dto/response/SchoolCourseResponse.java @@ -1,8 +1,11 @@ package com.reading.platform.dto.response; +import com.alibaba.fastjson2.JSON; +import com.reading.platform.entity.CoursePackage; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; +import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -69,4 +72,82 @@ public class SchoolCourseResponse { @Schema(description = "课程环节标签(列表展示用,仅 name 和 lessonType)") private List lessonTags; + + /** + * 转换为学校端课程响应(gradeTags/domainTags 规范为 String[]) + */ + public static SchoolCourseResponse toSchoolCourseResponse(CoursePackage pkg) { + return SchoolCourseResponse.builder() + .id(pkg.getId()) + .tenantId(pkg.getTenantId()) + .name(pkg.getName()) + .code(pkg.getCode()) + .description(pkg.getDescription()) + .pictureBookName(pkg.getPictureBookName()) + .coverImagePath(pkg.getCoverImagePath()) + .coverUrl(pkg.getCoverUrl()) + .gradeTags(parseJsonArray(pkg.getGradeTags())) + .domainTags(parseJsonArray(pkg.getDomainTags())) + .duration(pkg.getDurationMinutes()) + .usageCount(pkg.getUsageCount()) + .teacherCount(pkg.getTeacherCount()) + .avgRating(pkg.getAvgRating()) + .status(pkg.getStatus()) + .createdAt(pkg.getCreatedAt()) + .updatedAt(pkg.getUpdatedAt()) + .build(); + } + + /** + * 解析 JSON 数组为 String[],兼容多种格式: + * - 标准 JSON: ["小班","中班"] + * - 逗号分隔: 小班,中班 + * - 错误格式(split 导致): ["[\"小班\"", " \"中班\""] -> 提取有效值 + */ + private static String[] parseJsonArray(String json) { + if (!StringUtils.hasText(json)) { + return new String[0]; + } + String s = json.trim(); + try { + if (s.startsWith("[")) { + var list = JSON.parseArray(s, String.class); + if (list != null && !list.isEmpty()) { + // 检查是否为被错误 split 的格式,如 ["[\"小班\"", " \"中班\""] + String first = list.get(0); + if (first != null && first.startsWith("[\"") && !first.contains(",")) { + return list.stream() + .map(String::trim) + .map(SchoolCourseResponse::extractQuotedValue) + .filter(v -> v != null && !v.isEmpty()) + .toArray(String[]::new); + } + return list.stream() + .map(v -> v != null ? v.trim() : "") + .filter(v -> !v.isEmpty()) + .toArray(String[]::new); + } + return new String[0]; + } + return java.util.Arrays.stream(s.split(",")) + .map(String::trim) + .filter(v -> !v.isEmpty()) + .toArray(String[]::new); + } catch (Exception e) { + return new String[0]; + } + } + + private static String extractQuotedValue(String s) { + if (s == null) return null; + s = s.trim(); + int start = s.indexOf('"'); + if (start >= 0) { + int end = s.indexOf('"', start + 1); + if (end > start) { + return s.substring(start + 1, end).trim(); + } + } + return s.replaceAll("^\\[\"|\"\\]?$", "").trim(); + } }