mach-cms的前台,用vue写的
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

8.3 KiB

Agent2 Prompt: Mach-CMS Frontend Phase 2 Implementation

你的角色

你是前端开发 Agent,负责实现 Mach-CMS Phase 2 功能。你不是设计师,只按契约和规范实现功能。

契约文件(唯一真理来源)

后端仓库根目录下的 openapi.yaml 是你唯一的 API 规范。

技术栈

  • Vue 3.4+
  • TypeScript 5.4+(严格模式)
  • Vite 5.2+
  • Vue Router 4.3+
  • Pinia 2.1+
  • Axios 1.7+
  • OpenAPI Generator 7.6.0
  • marked / markdown-it(Markdown 渲染)
  • DOMPurify(XSS 防护)
  • highlight.js 或 prismjs(代码高亮)

项目状态

Phase 1 已完成:

  • OpenAPI 代码生成配置
  • Axios 客户端封装(含 401 自动刷新)
  • Pinia auth store
  • Vue Router + 路由守卫
  • 首页文章列表、文章详情、搜索页
  • 登录页、管理后台布局、文章列表/编辑器、标签管理

重要修正:basePath

client.ts 中所有 API 实例化时,basePath 必须传空字符串 ''

export const authApi = new AuthApi(config, '', axiosInstance)
export const articlesApi = new ArticlesApi(config, '', axiosInstance)
export const articleAdminApi = new ArticleAdminApi(config, '', axiosInstance)
export const tagsApi = new TagsApi(config, '', axiosInstance)
export const mediaApi = new MediaApi(config, '', axiosInstance)
export const searchApi = new SearchApi(config, '', axiosInstance)
// Phase 2 新增
export const commentsApi = new CommentsApi(config, '', axiosInstance)
export const commentAdminApi = new CommentAdminApi(config, '', axiosInstance)
export const userAdminApi = new UserAdminApi(config, '', axiosInstance)

原因:Vite 代理已配置 /apilocalhost:8080,生成代码的 BASE_PATH 也是 /api,若不覆盖会导致 /api/api/xxx

纪律:每次 npm run api:generate 后,检查 client.ts 中 basePath 是否为 ''

你的任务(按顺序执行,逐项验收)

Task 1: 重新生成 API 代码

后端更新 openapi.yaml 至 0.2.0 后,执行:

npm run api:generate

确认生成:

  • CommentResponse, CommentSubmitRequest
  • UserInfo, UpdateRoleRequest
  • CommentAdminApi, UserAdminApi
  • StoredFile 增加 thumbnailUrl

Task 2: 注册页面

文件:src/views/RegisterView.vue

  • 路由 /register
  • 表单:用户名(3-50 字符)、密码(6-100 字符)、确认密码、邮箱(可选)
  • 前端校验:密码与确认密码一致
  • 调用 authApi.register({ username, password, email })
  • 注册成功后自动调用 authStore.login() 并跳转 /admin
  • 已登录用户访问 /register 自动跳转 /admin

路由配置更新:router/index.ts 添加 /register 路由

Task 3: 评论组件

文件:src/components/CommentSection.vue

  • Props:slug: string
  • 功能:
    • 加载评论:GET /api/articles/{slug}/comments
    • 展示评论列表(作者名、内容、时间)
    • 评论提交表单:昵称(必填)、邮箱(可选)、内容(必填)
    • 提交后提示"评论已提交,等待审核"
  • 样式:简单即可,每条评论有分隔线

文件:src/views/ArticleDetailView.vue

  • 底部引入 <CommentSection :slug="slug" />

Task 4: Markdown 渲染 + XSS 防护

npm install marked dompurify highlight.js
npm install -D @types/dompurify @types/marked

文件:src/utils/markdown.ts

import { marked } from 'marked'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'

marked.setOptions({
  highlight: (code, lang) => {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value
    }
    return hljs.highlightAuto(code).value
  }
})

export function renderMarkdown(content: string): string {
  const rawHtml = marked.parse(content) as string
  return DOMPurify.sanitize(rawHtml)
}

文件:src/views/ArticleDetailView.vue

  • 文章内容用 v-html="renderMarkdown(article.content)"
  • 引入 highlight.js 样式

Task 5: 前台标签云

文件:src/components/TagCloud.vue

  • 调用 tagsApi.listTags()
  • 展示所有标签,标签大小按 articleCount 比例(简单实现:用不同 font-size class)
  • 点击标签跳转首页并过滤该标签文章(可选,先实现展示即可)

文件:src/views/HomeView.vue

  • 侧边栏或底部引入 <TagCloud />

Task 6: 管理后台增强

6.1 评论审核页

文件:src/views/admin/CommentReviewView.vue

  • 路由 /admin/comments
  • 调用 commentAdminApi.listPendingComments()
  • 表格:作者、邮箱、内容、文章标题、提交时间
  • 操作:通过、拒绝、删除
  • 通过后评论在前台显示

6.2 用户管理页

文件:src/views/admin/UserListView.vue

  • 路由 /admin/users
  • 调用 userAdminApi.listUsers()
  • 表格:用户名、邮箱、角色、状态、注册时间
  • 操作:修改角色(下拉选择 ADMIN/EDITOR/VISITOR)、启用/禁用
  • 只有 ADMIN 可见此菜单项(路由守卫或菜单条件渲染)

6.3 菜单更新

文件:src/views/admin/AdminLayout.vue

  • 侧边栏新增:评论审核、用户管理
  • 根据当前用户角色条件显示(先实现显示,权限由后端控制)

Task 7: 图片上传集成到编辑器

文件:src/views/admin/ArticleEditorView.vue

  • 封面图:点击上传按钮 → mediaApi.upload() → 返回 url 填入表单
  • 内容区粘贴图片:监听 paste 事件,提取图片文件 → 上传 → 插入 Markdown 图片语法 ![alt](url)

代码规范(违反 = 拒收)

# 规则
1 禁止手写 API 类型,必须从 openapi.yaml 生成
2 禁止直接 import axios,统一用 src/api/client.ts
3 组件必须用 <script setup lang="ts">
4 API 响应必须用生成代码中的类型,禁止 any
5 路由跳转用 useRouter(),禁止 window.location(除 401 跳转)
6 异步操作必须 try/catch,错误用 alert 或控制台输出
7 图片上传用 FormData,Content-Type 让浏览器自动设置
8 集合默认 [],禁止 undefined 作为列表值
9 路由参数用 useRoute() 获取

Git 规范(必须遵守)

  • 直接在 main 分支开发,commit 后立即 git push origin main
  • Conventional Commits:type(scope): subject
  • 单 commit 单意图,文件 ≤ 10,行数 ≤ 200
  • 每次 commit 前 npm run build 通过(无 TS 错误)
  • 提交信息用英文、祈使句、首字母小写、≤ 50 字符

Scope(前端)page component store api router type asset config contract

示例

feat(page): add register view with form validation
feat(component): add CommentSection for article detail
feat(component): add TagCloud with article count sizing
feat(page): add comment review page in admin
feat(page): add user management page with role editing
chore(api-gen): regenerate types from openapi.yaml v0.2.0
fix(api): set basePath to empty string to avoid /api/api

与 CDD 结合的提交顺序

  1. chore(api-gen): regenerate types from openapi.yaml v0.2.0(契约更新后)
  2. feat(page): add register view
  3. feat(component): add CommentSection with submit form
  4. feat(component): add markdown renderer with syntax highlight
  5. feat(component): add TagCloud component
  6. feat(page): add admin comment review page
  7. feat(page): add admin user management page
  8. feat(component): integrate image upload in article editor

验收标准

  • npm run api:generate 成功,生成 Comment/User 相关类型
  • npm run build 无 TS 错误
  • /register 页面可用,注册后自动登录跳转
  • 文章详情页显示评论区,可提交评论,提交后提示审核中
  • Markdown 渲染正确,代码块有高亮,XSS 被过滤
  • 标签云显示正常,大小按文章数变化
  • 后台评论审核页可列出待审核评论,通过/拒绝/删除生效
  • 后台用户管理页可查看用户列表,修改角色
  • 文章编辑器可上传封面图,粘贴图片到内容区
  • 所有 commit 符合 Conventional Commits 规范

CDD 纪律

  • 只修改前端代码,禁止修改后端仓库
  • 发现 openapi.yaml 与实际返回不符,停止开发,上报问题
  • 每次后端接口变更后,必须重新生成 API 代码
  • 禁止修改 src/generated/api/ 目录下的任何文件