diff --git a/checklist-agent2-phase2.md b/checklist-agent2-phase2.md new file mode 100644 index 0000000..d386b5a --- /dev/null +++ b/checklist-agent2-phase2.md @@ -0,0 +1,199 @@ +# Agent2 前端自查 Checklist - Phase 2 (v0.4) + +> 项目: mach-cms-frontend +> 版本: Phase 2 v0.4 +> 角色: 前端开发 Agent +> 要求: 逐项自查,全部通过后再提交验收 + +--- + +## 0. 环境前置 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 0.1 | 远程仓库可访问 | `git remote -v` 显示正确 origin | ✓ | +| 0.2 | 本地 main 分支最新 | `git pull --rebase origin main` 无冲突 | ✓ | +| 0.3 | Node.js 20+ | `node -v` 输出 v20.x | ✓ | +| 0.4 | 后端已启动 | `http://localhost:8080/actuator/health` 返回 UP | ✓ | + +--- + +## 1. basePath 修正确认 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 1.1 | `client.ts` 中 basePath 为空字符串 | 所有 `new XxxApi(config, '', axiosInstance)` 第二个参数为 `''` | ✓ | +| 1.2 | 无 `/api/api` 请求 | 浏览器 DevTools Network 面板中,请求路径无 `/api/api` 前缀 | ✓ | +| 1.3 | 请求正常到达后端 | 所有 API 请求状态码 200/201,非 404 | ✓ | + +--- + +## 2. Git 规范自查 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 2.1 | 提交历史规范 | `git log --oneline -20` 所有 message 符合 `type(scope): subject` | ✓ | +| 2.2 | 无 "update"/"fix bug" 等垃圾提交 | 全局搜索无此类 message | ✓ | +| 2.3 | 单 commit 行数 ≤ 200 | `git log --stat` 抽查最近 5 个 commit,无超 200 行 | ☐ | △ bfcbf4a=335、459e094=225 超200行(已push历史,本次验收后续 commit 均≤200) | +| 2.4 | 每次 commit 已 push | `git status` 显示 "Your branch is up to date with 'origin/main'" | ✓ | +| 2.5 | 无未提交代码 | `git status` 无未 stage 的修改 | ✓ | + +--- + +## 3. Task 1: API 代码重新生成 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 3.1 | `npm run api:generate` 成功 | 无报错,生成目录更新 | ✓ | +| 3.2 | `src/generated/api/` 存在 | 目录存在且包含 `api.ts` + `models/` | ✓ | +| 3.3 | Comment 类型生成 | `models/` 包含 `comment-response.ts`, `comment-submit-request.ts` | ☐ | ✓* models/ 未单独拆目录(typescript-axios 默认单文件 api.ts),CommentResponse/CommentSubmitRequest 存在于 api.ts | +| 3.4 | User 类型生成 | `models/` 包含 `user-info.ts`, `update-role-request.ts` | ☐ | ✓* UserInfo/UpdateUserRoleRequest 存在于 api.ts(未拆 models/) | +| 3.5 | API 类生成 | `api.ts` 包含 `CommentsApi`, `CommentAdminApi`, `UserAdminApi` | ☐ | ✓* 类名 CommentApi/CommentAdminApi/UserApi(由契约 tag 决定),非清单 Suggest CommentsApi/UserAdminApi | +| 3.6 | `StoredFile` 扩展 | 包含 `thumbnailUrl` 字段 | ✓ | +| 3.7 | `client.ts` 已更新 | 新增 `commentsApi`, `commentAdminApi`, `userAdminApi` 实例,basePath 为 `''` | ☐ | ✓* 实例 commentApi/commentAdminApi/userApi(契约命名) | + +--- + +## 4. Task 2: 注册页面 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 4.1 | 路由存在 | `/register` 可访问 | ✓ | +| 4.2 | 表单字段 | 用户名、密码、确认密码、邮箱 | ✓ | +| 4.3 | 前端校验 | 密码与确认密码不一致时阻止提交 | ✓ | +| 4.4 | 用户名长度校验 | 3-50 字符 | ✓ | +| 4.5 | 密码长度校验 | 6-100 字符 | ✓ | +| 4.6 | 调用注册 API | 点击注册调用 `authApi.register()` | ✓ | +| 4.7 | 注册后自动登录 | 成功后自动调用 `authStore.login()` | ✓ | +| 4.8 | 跳转后台 | 登录成功后进入 `/admin` | ✓ | +| 4.9 | 已登录拦截 | 已登录用户访问 `/register` 自动跳转 `/admin` | ✓ | +| 4.10 | 错误提示 | 注册失败(如用户名已存在)显示错误信息 | ✓ | + +--- + +## 5. Task 3: 评论组件 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 5.1 | `CommentSection.vue` 存在 | `src/components/CommentSection.vue` 存在 | ✓ | +| 5.2 | 接收 slug prop | `` | ✓ | +| 5.3 | 加载评论列表 | 进入文章详情页自动加载评论 | ✓ | +| 5.4 | 只显示已审核 | 未审核评论不显示 | ✓ | +| 5.5 | 提交表单 | 昵称(必填)、邮箱(可选)、内容(必填) | ✓ | +| 5.6 | 提交后提示 | 显示"评论已提交,等待审核" | ✓ | +| 5.7 | 无需登录 | 未登录用户可提交评论 | ✓ | +| 5.8 | 样式 | 评论间有分隔线,时间格式化显示 | ✓ | +| 5.9 | 文章详情页引入 | `ArticleDetailView.vue` 底部包含 `` | ✓ | + +--- + +## 6. Task 4: Markdown 渲染 + XSS 防护 + +| # | 检查项 | 通过标准 | 结果 | +|---|--------|---------|------| +| 6.1 | 依赖安装 | `marked`, `dompurify`, `highlight.js` 已安装 | ✓ | +| 6.2 | `renderMarkdown` 工具 | `src/utils/markdown.ts` 存在 | ✓ | +| 6.3 | Markdown 转 HTML | 标题、段落、列表、链接正确渲染 | ✓ | +| 6.4 | 代码高亮 | 代码块有语法高亮(背景色、关键字着色) | ✓ | +| 6.5 | XSS 过滤 | `DOMPurify.sanitize()` 过滤 ` @@ -92,6 +122,7 @@ onMounted(load) 作者 内容 + 文章标题 状态 提交时间 操作 @@ -104,6 +135,7 @@ onMounted(load)
{{ comment.authorEmail }}
{{ comment.content }} + {{ articleTitle(comment.articleId) }} {{ statusLabel(comment.status) }} @@ -133,6 +165,7 @@ onMounted(load)

共 {{ total }} 条评论

+ diff --git a/src/views/admin/UserListView.vue b/src/views/admin/UserListView.vue index 093fadd..83cff61 100644 --- a/src/views/admin/UserListView.vue +++ b/src/views/admin/UserListView.vue @@ -2,6 +2,7 @@ import { ref, onMounted } from 'vue' import { userApi } from '@/api/client' import { useAuthStore } from '@/stores/auth' +import Pagination from '@/components/Pagination.vue' import type { UserInfo, UserRole } from '@/generated/api' const auth = useAuthStore() @@ -9,6 +10,7 @@ const users = ref([]) const page = ref(1) const size = 10 const total = ref(0) +const totalPages = ref(0) const loading = ref(false) const error = ref(null) @@ -78,8 +80,9 @@ async function load() { try { const resp = await userApi.apiAdminUsersGet(page.value, size) const data = resp.data.data - users.value = data?.list as UserInfo[] ?? [] + users.value = (data?.list as UserInfo[]) ?? [] total.value = Number(data?.total ?? 0) + totalPages.value = Number(data?.totalPages ?? 0) } catch (e) { console.error(e) error.value = '用户列表加载失败' @@ -88,6 +91,11 @@ async function load() { } } +function onPageChange(p: number) { + page.value = p + load() +} + onMounted(load) @@ -145,6 +153,7 @@ onMounted(load)

共 {{ total }} 位用户

+