docs: plan student home new module dashboard

dev-QQq
chenyuan 4 weeks ago
parent 214ea32737
commit 2a8610b8da

@ -0,0 +1,160 @@
# 学生首页新版实训模块展示 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Replace every student-home module display with the current training-report modules and remove the legacy five-module dashboard.
**Architecture:** `src/views/student/index.vue` will request `GET /api/student/experiment-report/current` and derive the score chart, score table, and task-progress chart from its participating modules. The legacy study-time request remains only to show one aggregate effective-learning-time number; it supplies no module names, chart slices, or module rows.
**Tech Stack:** Vue 3 Composition API, Element Plus, ECharts 5, existing Axios request wrapper, Node `assert` static checks, Vite 3.
## Global Constraints
- The homepage must show only: 互联网产品开发基础认知、市场洞察与需求分析、产品规划与设计、产品开发与测试验证、产品上线与运营推广,以及已发布时的综合实训。
- `综合实训` is rendered only when the report module has `participating !== false`.
- No homepage component may call `getStuWeightScore`, `getRouters`, or use the old five-module field names for module-level display.
- Score, score share, and completion progress must derive from the same `getCurrentExperimentReport()` response.
- Preserve effective learning time only as a single aggregate number; do not map legacy time fields to new modules.
---
## File Structure
- `src/views/student/index.vue` — student-home dashboard; replaces hard-coded old modules with report-driven score and progress views.
- `tests/student-home-new-modules.static.test.cjs` — guards the report-data contract and prevents reintroduction of the old module dashboard.
### Task 1: Report-driven student-home dashboard
**Files:**
- Modify: `src/views/student/index.vue`
- Create: `tests/student-home-new-modules.static.test.cjs`
**Interfaces:**
- Consumes: `getCurrentExperimentReport(): Promise<{ data: { totalScore: number, modules: Array<{ moduleName: string, weight: number, score: number, participating: boolean, completedTaskCount: number, totalTaskCount: number }> } }>` from `src/api/index.js`.
- Consumes: `getStudyTime({ userId }): Promise<{ data: Record<string, number> }>` only to calculate a single aggregate duration.
- Produces: `participatingModules`, a computed list used by both ECharts options and the score/progress tables.
- [ ] **Step 1: Write the failing static contract test**
Create `tests/student-home-new-modules.static.test.cjs` with the following checks:
```js
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const root = path.resolve(__dirname, '..');
const page = fs.readFileSync(path.join(root, 'src/views/student/index.vue'), 'utf8');
assert(/getCurrentExperimentReport/.test(page));
assert(/participatingModules/.test(page));
assert(/completedTaskCount/.test(page));
assert(/totalTaskCount/.test(page));
assert(/moduleName/.test(page));
assert(!/getStuWeightScore\(/.test(page));
assert(!/getRouters\(/.test(page));
assert(!/市场需求挖掘|产品投放测试|供应渠道管理|产品评估与考核/.test(page));
console.log('student home new module static checks passed');
```
- [ ] **Step 2: Run the test to verify it fails**
Run: `node tests/student-home-new-modules.static.test.cjs`
Expected: failure because `src/views/student/index.vue` still uses `getStuWeightScore`, `getRouters`, and hard-coded old module labels.
- [ ] **Step 3: Replace the hard-coded dashboard with report data**
In `src/views/student/index.vue`:
```js
const report = ref({ totalScore: 0, modules: [] });
const loading = ref(true);
const loadError = ref('');
const participatingModules = computed(() =>
(report.value.modules || []).filter((module) => module.participating !== false)
);
const totalTime = computed(() =>
Object.values(studyTime.value || {}).reduce((total, value) => total + (Number(value) || 0), 0)
);
```
Replace the score pie data with:
```js
data: participatingModules.value.map((module, index) => ({
name: module.moduleName,
value: Number(module.score) || 0,
itemStyle: { color: MODULE_COLORS[index % MODULE_COLORS.length] }
}))
```
Render the score table with `v-for` rows from `participatingModules`, showing `moduleName`, `weight * 100`, `score`, and `completedTaskCount / totalTaskCount`. Replace the second legacy “我的成绩” card with “实训进度概览”: an ECharts bar chart whose series are `completedTaskCount` and remaining task count, plus a compact module-progress list. Keep the effective-learning-time card but remove the legacy doughnut chart and old five-row time list.
Load dashboard data through `getCurrentExperimentReport()` and `getStudyTime({ userId })`. On report failure, set `loadError` and render an `el-alert`; do not create old-module fallback rows. Create ECharts instances once, resize them through one lifecycle-managed listener, and dispose both in `onBeforeUnmount`.
- [ ] **Step 4: Run the static contract test to verify it passes**
Run: `node tests/student-home-new-modules.static.test.cjs`
Expected: `student home new module static checks passed`.
- [ ] **Step 5: Commit the dashboard change**
```bash
git add src/views/student/index.vue tests/student-home-new-modules.static.test.cjs
git commit -m "feat: show new training modules on student home"
```
### Task 2: Build and visual verification
**Files:**
- Verify: `src/views/student/index.vue`
- Verify: `tests/student-home-new-modules.static.test.cjs`
**Interfaces:**
- Consumes: Task 1s report-driven dashboard and static contract test.
- Produces: a production Vite bundle that contains no old-module dashboard source.
- [ ] **Step 1: Run all relevant static checks**
Run:
```bash
node tests/student-home-new-modules.static.test.cjs
node tests/student-experiment-report.static.test.cjs
```
Expected: both commands exit with status 0.
- [ ] **Step 2: Build the frontend production bundle**
Run: `npm run build:prod`
Expected: Vite completes successfully. Existing warnings about `::v-deep`, `top1.png`, or large chunks may be recorded but must not become build errors.
- [ ] **Step 3: Verify the rendered student homepage**
Run the local frontend and, with an authenticated student whose class has published comprehensive training, verify:
```text
成绩饼图、成绩表、实训进度概览都显示六个新版模块;
综合实训未发布时只显示前五个新版模块;
页面上不存在旧五模块名称或旧模块时间占比图。
```
- [ ] **Step 4: Commit verification-only changes if any**
If Step 13 created no source changes, do not create an empty commit. If a source correction was needed, add only that correction and commit it with:
```bash
git add src/views/student/index.vue tests/student-home-new-modules.static.test.cjs
git commit -m "fix: complete student home module dashboard"
```
## Self-Review
- Spec coverage: Task 1 replaces the legacy five-module score and time dashboard, filters unpublished comprehensive training, uses one report response for all module-level cards, retains only aggregate study time, and adds explicit load-error handling. Task 2 validates the contract, build, and both comprehensive-training visibility states.
- Placeholder scan: no deferred implementation markers or unspecified test steps remain.
- Type consistency: `participatingModules` is the shared source for score and progress visualizations; all module fields match `StudentExperimentReportModuleDTO`.
Loading…
Cancel
Save