library-picturebook-activity/.claude/skills/contest-detail-page.md
2026-01-15 16:35:00 +08:00

311 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 赛事详情页面生成规范
## 概述
本规范用于快速生成赛事管理系统中的详情页面,这类页面具有统一的结构:
- 顶部导航栏(返回按钮 + 标题 + 操作按钮)
- 搜索表单
- 数据表格
## 页面结构
```
┌─────────────────────────────────────────────────┐
│ [← 返回] 页面标题 [操作按钮] │
├─────────────────────────────────────────────────┤
│ 搜索表单: [搜索条件...] [搜索] [重置] │
├─────────────────────────────────────────────────┤
│ 数据表格 │
│ ┌───┬──────┬──────┬──────┬──────┐ │
│ │序号│ 列1 │ 列2 │ 列3 │ 操作 │ │
│ ├───┼──────┼──────┼──────┼──────┤ │
│ │ 1 │ ... │ ... │ ... │ ... │ │
│ └───┴──────┴──────┴──────┴──────┘ │
└─────────────────────────────────────────────────┘
```
## 快速生成指令格式
向 Claude 提供以下格式的指令即可快速生成详情页面:
```
请生成一个详情页面:
页面名称xxx
文件路径xxx
数据来源xxx API
标题:字段名(如 contestName
操作按钮:按钮名称 -> 处理函数
搜索条件:
- 字段1类型
- 字段2类型
表格列:
- 列名1数据字段
- 列名2数据字段
- ...
排序:字段名 + 排序方式(升序/降序)
```
## 配置参数说明
### 1. 基础配置
| 参数 | 说明 | 示例 |
|------|------|------|
| 页面名称 | 显示在标题旁 | 赛果发布详情 |
| 文件路径 | Vue 文件位置 | views/contests/results/Detail.vue |
| 数据来源 | API 模块 | resultsApi / worksApi |
| 标题字段 | 动态标题来源 | record.contestName |
| 返回路径 | 返回按钮跳转 | 上一页 / 指定路径 |
### 2. 操作按钮
| 属性 | 说明 |
|------|------|
| 名称 | 按钮显示文本 |
| 类型 | primary / default / danger |
| 处理函数 | 点击触发的方法 |
| 确认弹窗 | 是否需要二次确认 |
### 3. 搜索条件类型
| 类型 | 说明 | 示例 |
|------|------|------|
| input | 输入框 | 作品编号、账号 |
| select | 下拉选择 | 状态筛选 |
| date | 日期选择 | 提交日期 |
| dateRange | 日期范围 | 时间区间 |
### 4. 表格列渲染类型
| 类型 | 说明 | 示例 |
|------|------|------|
| index | 序号 | 自动计算 |
| text | 纯文本 | 直接显示字段值 |
| nested | 嵌套字段 | record.user?.nickname |
| array | 数组拼接 | teachers.map(t => t.name).join('、') |
| score | 分数格式 | 保留2位小数 |
| tag | 标签样式 | 状态标签 |
| org | 机构信息 | 学校 + 年级 + 班级 |
### 5. 排序配置
| 属性 | 说明 |
|------|------|
| 字段 | 排序依据的字段名 |
| 方式 | asc升序/ desc降序|
## 示例
### 赛果发布详情页
```
请生成一个详情页面:
页面名称:赛果发布详情
文件路径views/contests/results/Detail.vue
数据来源resultsApi.getResults
标题contestName赛事名称
操作按钮:发布赛果 -> handlePublish需确认
搜索条件:
- workNo 作品编号input
- accountNo 报名账号input
表格列:
- 序号index
- 作品编号workNo
- 评委评分finalScore分数格式
- 姓名registration.user.nickname
- 账号registration.user.username
- 机构信息registration.user机构格式
- 指导老师registration.teachers数组拼接
排序finalScore 降序
```
### 报名记录详情页
```
请生成一个详情页面:
页面名称:报名记录
文件路径views/contests/registrations/Records.vue
数据来源registrationsApi.getList
标题contestName赛事名称
操作按钮:无
搜索条件:
- accountNo 报名账号input
- registrationState 审核状态select
表格列:
- 序号index
- 报名账号accountNo
- 姓名user.nickname
- 机构信息user机构格式
- 指导老师teachers数组拼接
- 审核状态registrationState标签
- 报名时间registrationTime日期
- 操作(查看详情、审核)
排序registrationTime 降序
```
## 页面模板代码
```vue
<template>
<div class="detail-page">
<!-- 顶部导航 -->
<div class="page-header">
<div class="header-left">
<a-button type="text" @click="handleBack">
<template #icon><ArrowLeftOutlined /></template>
返回
</a-button>
<span class="page-title">{{ pageTitle }}</span>
</div>
<div class="header-right">
<a-button type="primary" @click="handleAction">
{{ actionButtonText }}
</a-button>
</div>
</div>
<!-- 搜索表单 -->
<a-form
:model="searchParams"
layout="inline"
class="search-form"
@finish="handleSearch"
>
<!-- 根据配置生成搜索项 -->
<a-form-item>
<a-button type="primary" html-type="submit">
<template #icon><SearchOutlined /></template>
搜索
</a-button>
<a-button style="margin-left: 8px" @click="handleReset">
<template #icon><ReloadOutlined /></template>
重置
</a-button>
</a-form-item>
</a-form>
<!-- 数据表格 -->
<a-table
:columns="columns"
:data-source="dataSource"
:loading="loading"
:pagination="pagination"
row-key="id"
@change="handleTableChange"
>
<template #bodyCell="{ column, record, index }">
<!-- 根据配置生成列渲染 -->
</template>
</a-table>
</div>
</template>
```
## 特殊字段渲染规范
### 机构信息org 类型)
```vue
<template v-else-if="column.key === 'org'">
<div>
<div>{{ record.user?.tenant?.name || "-" }}</div>
<div v-if="record.user?.student?.class" class="org-detail">
{{ record.user.student.class.grade?.name }}
{{ record.user.student.class.name }}
</div>
</div>
</template>
```
### 指导老师(数组拼接)
```vue
<template v-else-if="column.key === 'teachers'">
{{ formatTeachers(record.teachers || record.registration?.teachers) }}
</template>
// 格式化函数
const formatTeachers = (teachers: any[]) => {
if (!teachers || teachers.length === 0) return "-"
return teachers.map(t => t.user?.nickname || t.user?.username).join("、")
}
```
### 分数格式
```vue
<template v-else-if="column.key === 'score'">
<span v-if="record.finalScore !== null" class="score">
{{ Number(record.finalScore).toFixed(2) }}
</span>
<span v-else>-</span>
</template>
```
## 样式规范
```css
.detail-page {
padding: 0;
}
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: #fff;
border-radius: 8px;
margin-bottom: 16px;
}
.header-left {
display: flex;
align-items: center;
gap: 8px;
}
.page-title {
font-size: 16px;
font-weight: 500;
}
.search-form {
margin-bottom: 16px;
padding: 16px;
background: #fff;
border-radius: 8px;
}
.org-detail {
font-size: 12px;
color: #666;
margin-top: 2px;
}
.score {
font-weight: bold;
color: #52c41a;
}
```
## 注意事项
1. **API 数据**:确保后端返回了所需的关联数据(如 user、teachers、tenant、student.class.grade
2. **排序字段**:需要后端支持对应字段的排序
3. **权限控制**:操作按钮需要配置权限检查
4. **空值处理**:所有字段都需要处理空值情况,显示 "-"
5. **嵌套数据**:使用可选链操作符 `?.` 避免空指针错误