|
|
@@ -0,0 +1,458 @@
|
|
|
+# report-confirm 被检测人选择面板整合 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:** 将 `report-confirm.vue` 中被检测人的选择/添加功能整合进"基本信息"卡片:点击被检测人字段原地展开选择面板(候选匹配 + 全量成员 + 新建入口),移除独立"选择家庭成员"卡片与"新建家庭成员表单"卡片。
|
|
|
+
|
|
|
+**Architecture:** 单文件前端改造(`cfc-frontend/pages/health/report-confirm.vue`)。模板层把原独立卡片(L57-131)的内容移入基本信息卡片的被检测人字段下方,包在 `v-if="showMemberPanel"` 面板容器内;逻辑层新增 `showMemberPanel`/`selectedMemberObj`/`selectAndClose`/`toggleMemberPanel`/`syncSelectedMemberObj`/`memberDisplayText`,移除 `selectMember`/`selectCandidate`(其逻辑并入 `selectAndClose`),`loadFamilyMembers` 改为始终调用。`canConfirm`/`doConfirm` 完全不变。无后端改动。
|
|
|
+
|
|
|
+**Tech Stack:** uni-app Vue 2 (Options API) / 微信小程序 mp-weixin
|
|
|
+
|
|
|
+## Global Constraints
|
|
|
+
|
|
|
+- 仅前端:`cfc-frontend/pages/health/report-confirm.vue`,禁止改动后端
|
|
|
+- Vue 2 Options API,禁止 Composition API
|
|
|
+- 禁止可选链 `?.`(用 `&&` 链式判断)
|
|
|
+- 禁止在 `:class` 绑定中调用方法(用内联表达式或计算属性)
|
|
|
+- 禁止中文 CSS 类名/选择器
|
|
|
+- 小程序用 flexbox,禁止 CSS Grid
|
|
|
+- 禁止 `:key` 表达式(用 `idx`/`mIdx` 下标)
|
|
|
+- 统一 `@PostMapping`(本任务无接口变更)
|
|
|
+- 提交信息遵循仓库风格(`feat:` / `fix:` / `docs:` 前缀,中文描述)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 1: 核心改造 — 模板 + 脚本
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `cfc-frontend/pages/health/report-confirm.vue`(模板 L28-55 基本信息卡片、移除 L57-131、脚本 data/computed/onLoad/methods)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Produces: 新 data 字段 `showMemberPanel: false`、`selectedMemberObj: null`;新计算属性 `memberDisplayText`;新方法 `toggleMemberPanel()`、`selectAndClose(member)`、`syncSelectedMemberObj()`;`loadFamilyMembers()` 成功回调内新增 `syncSelectedMemberObj()` 调用;`doAutoCreate()` 成功分支新增回填+收起逻辑;移除 `selectMember(member)`、`selectCandidate(candidate)`。
|
|
|
+
|
|
|
+- [ ] **Step 1: 修改 data() — 新增两个字段**
|
|
|
+
|
|
|
+在 `showCandidatesOnly: false,`(约 L308)之后插入:
|
|
|
+
|
|
|
+```js
|
|
|
+ showCandidatesOnly: false,
|
|
|
+ // 被检测人选择面板
|
|
|
+ showMemberPanel: false,
|
|
|
+ selectedMemberObj: null,
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: 修改 computed — 新增 memberDisplayText**
|
|
|
+
|
|
|
+在 `confidenceDesc()`(约 L351 结束)与 `indicatorGroups()` 之间插入:
|
|
|
+
|
|
|
+```js
|
|
|
+ },
|
|
|
+ memberDisplayText() {
|
|
|
+ var m = this.selectedMemberObj
|
|
|
+ if (m && (m.nickname || m.name)) return m.nickname || m.name
|
|
|
+ if (this.needBind) return '需手动绑定'
|
|
|
+ return this.extractedName || '未识别'
|
|
|
+ },
|
|
|
+ // 指标按类型(category)分组,保持解析顺序,统计需处理(非正常)数量
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 3: 修改 onLoad — loadFamilyMembers 改为始终调用**
|
|
|
+
|
|
|
+将 L427-438 的:
|
|
|
+
|
|
|
+```js
|
|
|
+ // 有候选时优先展示候选列表
|
|
|
+ if (this.candidates.length > 0) {
|
|
|
+ this.showCandidatesOnly = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.needBind) {
|
|
|
+ this.loadFamilyMembers()
|
|
|
+ // 高置信度且已匹配 → 直接选中
|
|
|
+ if (this.matchedMemberId && this.matchConfidence >= 0.8) {
|
|
|
+ this.selectedMemberId = this.matchedMemberId
|
|
|
+ }
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+替换为:
|
|
|
+
|
|
|
+```js
|
|
|
+ // 有候选时优先展示候选列表
|
|
|
+ if (this.candidates.length > 0) {
|
|
|
+ this.showCandidatesOnly = true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 始终加载家庭成员(面板始终可点击,needBind=false 也允许改选)
|
|
|
+ this.loadFamilyMembers()
|
|
|
+
|
|
|
+ if (this.needBind) {
|
|
|
+ // 高置信度且已匹配 → 直接选中
|
|
|
+ if (this.matchedMemberId && this.matchConfidence >= 0.8) {
|
|
|
+ this.selectedMemberId = this.matchedMemberId
|
|
|
+ }
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 4: 修改 loadFamilyMembers — 成功回调同步选中成员**
|
|
|
+
|
|
|
+在 `self.familyMembers = parents.concat(children)` 之后、`.catch` 之前插入 `self.syncSelectedMemberObj()`:
|
|
|
+
|
|
|
+```js
|
|
|
+ loadFamilyMembers() {
|
|
|
+ var self = this
|
|
|
+ // 从后端获取真实家庭成员(家长 + 孩子),storage 中并无该数据
|
|
|
+ getFamilyMembers().then(function(res) {
|
|
|
+ var data = (res && res.data) || {}
|
|
|
+ var parents = (data.parents || []).map(function(p) {
|
|
|
+ return { id: p.id, nickname: p.realName || p.nickname, gender: p.gender, role: 'parent' }
|
|
|
+ })
|
|
|
+ var children = (data.children || []).map(function(c) {
|
|
|
+ return { id: c.id, nickname: c.nickname, gender: c.gender, age: c.age, role: 'child' }
|
|
|
+ })
|
|
|
+ self.familyMembers = parents.concat(children)
|
|
|
+ self.syncSelectedMemberObj()
|
|
|
+ }).catch(function(e) {
|
|
|
+ console.log('加载家庭成员失败', e)
|
|
|
+ self.familyMembers = []
|
|
|
+ })
|
|
|
+ },
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 5: 替换 selectMember/selectCandidate — 新增 toggleMemberPanel / selectAndClose / syncSelectedMemberObj**
|
|
|
+
|
|
|
+删除 `selectMember(member)`(L458-460)与 `selectCandidate(candidate)`(L467-470)两个方法,在原 `selectMember` 位置插入:
|
|
|
+
|
|
|
+```js
|
|
|
+ toggleMemberPanel() {
|
|
|
+ this.showMemberPanel = !this.showMemberPanel
|
|
|
+ if (!this.showMemberPanel) {
|
|
|
+ this.showAutoCreateForm = false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ selectAndClose(member) {
|
|
|
+ var memberId = member.id || member.userId
|
|
|
+ this.selectedMemberId = memberId
|
|
|
+ this.selectedMemberObj = member
|
|
|
+ this.extractedName = member.nickname || member.name || this.extractedName
|
|
|
+ this.extractedGender = member.gender || this.extractedGender
|
|
|
+ this.extractedAge = member.age || this.extractedAge
|
|
|
+ this.showAutoCreateForm = false
|
|
|
+ this.showMemberPanel = false
|
|
|
+ },
|
|
|
+ syncSelectedMemberObj() {
|
|
|
+ if (!this.selectedMemberId) {
|
|
|
+ this.selectedMemberObj = null
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var all = this.familyMembers.concat(this.candidates)
|
|
|
+ for (var i = 0; i < all.length; i++) {
|
|
|
+ var m = all[i]
|
|
|
+ if ((m.id || m.userId) === this.selectedMemberId) {
|
|
|
+ this.selectedMemberObj = m
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+```
|
|
|
+
|
|
|
+注意:删除 `selectCandidate` 时保留其后的 `// === Phase 2: 候选匹配与新建成员 ===` 注释块位置不变。
|
|
|
+
|
|
|
+- [ ] **Step 6: 修改 doAutoCreate — 成功分支回填 + 收起面板**
|
|
|
+
|
|
|
+将成功分支(约 L495-502):
|
|
|
+
|
|
|
+```js
|
|
|
+ if (memberId) {
|
|
|
+ self.createdMemberId = memberId
|
|
|
+ self.selectedMemberId = memberId
|
|
|
+ self.showAutoCreateForm = false
|
|
|
+ uni.showToast({ title: '创建成功', icon: 'success' })
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+替换为:
|
|
|
+
|
|
|
+```js
|
|
|
+ if (memberId) {
|
|
|
+ self.createdMemberId = memberId
|
|
|
+ self.selectedMemberId = memberId
|
|
|
+ self.selectedMemberObj = {
|
|
|
+ id: memberId,
|
|
|
+ nickname: self.newMember.name,
|
|
|
+ gender: self.newMember.gender,
|
|
|
+ age: self.newMember.age
|
|
|
+ }
|
|
|
+ self.extractedName = self.newMember.name
|
|
|
+ self.extractedGender = self.newMember.gender
|
|
|
+ self.extractedAge = self.newMember.age
|
|
|
+ self.showAutoCreateForm = false
|
|
|
+ self.showMemberPanel = false
|
|
|
+ uni.showToast({ title: '创建成功', icon: 'success' })
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 7: 修改模板 — 被检测人行可点击 + 内联面板**
|
|
|
+
|
|
|
+将 L30-34 的被检测人字段行:
|
|
|
+
|
|
|
+```html
|
|
|
+ <view class="field-row">
|
|
|
+ <text class="field-label">被检测人</text>
|
|
|
+ <text class="field-value" v-if="!needBind">{{ extractedName || '未识别' }}</text>
|
|
|
+ <text class="field-value binding-required" v-else>需手动绑定</text>
|
|
|
+ </view>
|
|
|
+```
|
|
|
+
|
|
|
+替换为:
|
|
|
+
|
|
|
+```html
|
|
|
+ <view class="field-row member-select-row" @click="toggleMemberPanel">
|
|
|
+ <text class="field-label">被检测人</text>
|
|
|
+ <text class="field-value" :class="{ 'binding-required': needBind && !selectedMemberObj }">{{ memberDisplayText }}</text>
|
|
|
+ <text class="member-select-arrow">{{ selectedMemberObj ? '修改 ›' : '选择 ›' }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 被检测人选择面板(内联展开) -->
|
|
|
+ <view class="member-panel" v-if="showMemberPanel">
|
|
|
+ <!-- 候选匹配列表(按置信度排序) -->
|
|
|
+ <view class="candidate-section" v-if="candidates.length > 0">
|
|
|
+ <text class="candidate-section-hint">以下成员与报告信息匹配,请选择:</text>
|
|
|
+ <view
|
|
|
+ class="candidate-item"
|
|
|
+ v-for="(cand, idx) in candidates"
|
|
|
+ :key="idx"
|
|
|
+ :class="{ 'candidate-selected': selectedMemberId === (cand.id || cand.userId) }"
|
|
|
+ @click="selectAndClose(cand)"
|
|
|
+ >
|
|
|
+ <view class="candidate-left">
|
|
|
+ <text class="candidate-avatar">{{ (cand.nickname || cand.name || '?').substring(0, 1) }}</text>
|
|
|
+ <view class="candidate-info">
|
|
|
+ <text class="candidate-name">{{ cand.nickname || cand.name || '未知' }}</text>
|
|
|
+ <text class="candidate-detail" v-if="cand.gender || cand.age">{{ genderText(cand.gender) }}{{ cand.age ? ' · ' + cand.age + '岁' : '' }}</text>
|
|
|
+ <text class="candidate-fields" v-if="cand.matchFields">匹配: {{ cand.matchFields }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="candidate-right">
|
|
|
+ <view class="score-bar-track">
|
|
|
+ <view class="score-bar-fill" :style="'width:' + (cand.similarityScore * 100) + '%'"></view>
|
|
|
+ </view>
|
|
|
+ <text class="score-text">{{ Math.round(cand.similarityScore * 100) }}%</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 全量家庭成员列表(后备) -->
|
|
|
+ <view class="member-list" v-if="familyMembers.length > 0 && (candidates.length === 0 || !showCandidatesOnly)">
|
|
|
+ <view
|
|
|
+ class="member-item"
|
|
|
+ v-for="(member, mIdx) in familyMembers"
|
|
|
+ :key="mIdx"
|
|
|
+ :class="{ 'member-selected': selectedMemberId === (member.userId || member.id) }"
|
|
|
+ @click="selectAndClose(member)"
|
|
|
+ >
|
|
|
+ <text class="member-avatar">{{ (member.nickname || '?').substring(0, 1) }}</text>
|
|
|
+ <text class="member-name">{{ member.nickname || '未知' }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 新建成员入口 -->
|
|
|
+ <view class="create-member-entry" @click="toggleAutoCreate">
|
|
|
+ <text class="create-member-icon">+</text>
|
|
|
+ <text class="create-member-text">{{ showAutoCreateForm ? '收起新建表单' : '不在列表中?新建家庭成员' }}</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 新建成员表单(面板内嵌) -->
|
|
|
+ <view class="auto-create-inline" v-if="showAutoCreateForm">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-item-label">姓名</text>
|
|
|
+ <input class="form-item-input" v-model="newMember.name" placeholder="请输入姓名" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-item-label">性别</text>
|
|
|
+ <view class="gender-selector">
|
|
|
+ <text class="gender-option" :class="{ 'gender-selected': newMember.gender === 'male' }" @click="newMember.gender = 'male'">男</text>
|
|
|
+ <text class="gender-option" :class="{ 'gender-selected': newMember.gender === 'female' }" @click="newMember.gender = 'female'">女</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="form-item-label">年龄</text>
|
|
|
+ <input class="form-item-input" type="number" v-model="newMember.age" placeholder="请输入年龄" />
|
|
|
+ </view>
|
|
|
+ <view class="btn-create-submit" :class="{ 'btn-disabled': creatingMember }" @click="doAutoCreate">
|
|
|
+ <text v-if="creatingMember">创建中...</text>
|
|
|
+ <text v-else>确认创建</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 8: 修改模板 — 删除独立"选择家庭成员"卡片与"新建家庭成员表单"卡片**
|
|
|
+
|
|
|
+删除整个 L57-107(`<!-- 家庭成员绑定(含候选推荐) -->` 卡片,`v-if="needBind"`)与 L109-131(`<!-- 新建家庭成员表单 -->` 卡片,`v-if="showAutoCreateForm"`)。删除后,`<!-- 舌诊指标(只读展示) -->` 注释成为基本信息卡片后的下一块。
|
|
|
+
|
|
|
+- [ ] **Step 9: 验证脚本层无残留引用**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+grep -n "selectCandidate\|selectMember(" pages/health/report-confirm.vue
|
|
|
+grep -n "选择家庭成员\|auto-create-card" pages/health/report-confirm.vue
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 无输出(0 匹配)。若有残留(如 `showCandidatesOnly` 定义仍在 data 中是正常的),逐个确认属于新增逻辑或保留逻辑。
|
|
|
+
|
|
|
+- [ ] **Step 10: 构建验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+npm run build:mp-weixin
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 退出码 0,输出无 `ERROR`(允许 3 个既有 `"export 'components' was not found"` warning)。构建产物出现在 `dist/build/mp-weixin/pages/health/`。
|
|
|
+
|
|
|
+- [ ] **Step 11: 检查编译产物 — 无方法调用泄漏进 WXML 类绑定**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+Select-String -Path "dist/build/mp-weixin/pages/health/report-confirm.wxml" -Pattern "selectAndClose|selectCandidate|selectMember|memberDisplayText|toggleMemberPanel" | ForEach-Object { $_.Line.Substring(0, [Math]::Min(200, $_.Line.Length)) }
|
|
|
+```
|
|
|
+
|
|
|
+Expected: `selectAndClose`/`toggleMemberPanel` 以 `data-event-opts` 事件绑定形式存在;`memberDisplayText` 被编译为预计算值(如 `{{...mN}}` 形式,非函数调用);`selectCandidate`/`selectMember` 不出现。
|
|
|
+
|
|
|
+- [ ] **Step 12: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd D:\workspace\cfc
|
|
|
+git add cfc-frontend/pages/health/report-confirm.vue
|
|
|
+git commit -m "feat: report-confirm 被检测人选择整合进基本信息卡片(内联面板+移除独立卡片)"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 2: 样式补充与死样式清理
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `cfc-frontend/pages/health/report-confirm.vue`(`<style scoped>` 块)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 1 新增的模板类 `member-select-row` / `member-select-arrow` / `member-panel` / `auto-create-inline`
|
|
|
+- Produces: 以上 4 个类的基础样式;移除死样式 `.auto-create-card`
|
|
|
+
|
|
|
+- [ ] **Step 1: 新增被检测人行与面板样式**
|
|
|
+
|
|
|
+在 `.field-value.binding-required` 规则(约 L833-835)之后插入:
|
|
|
+
|
|
|
+```css
|
|
|
+.member-select-row {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.member-select-row:active {
|
|
|
+ opacity: 0.7;
|
|
|
+}
|
|
|
+.member-select-arrow {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #5B9BD5;
|
|
|
+ margin-left: 12rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+.member-panel {
|
|
|
+ background: #F8FAFB;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ margin: 8rpx 0 16rpx;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: 移除死样式 .auto-create-card**
|
|
|
+
|
|
|
+删除(约 L1365-1368):
|
|
|
+
|
|
|
+```css
|
|
|
+/* ===== Phase 2: 新建成员表单 ===== */
|
|
|
+.auto-create-card {
|
|
|
+ border: 2rpx solid #E3F2FD;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+将注释改为 `/* ===== Phase 2: 新建成员表单(面板内嵌) ===== */`,保留其后的 `.form-item` 等规则。
|
|
|
+
|
|
|
+- [ ] **Step 3: 构建验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+npm run build:mp-weixin
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 退出码 0,无 `ERROR`。
|
|
|
+
|
|
|
+- [ ] **Step 4: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd D:\workspace\cfc
|
|
|
+git add cfc-frontend/pages/health/report-confirm.vue
|
|
|
+git commit -m "feat: report-confirm 面板样式 + 清理 auto-create-card 死样式"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 3: 终验与提交
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Verify: `cfc-frontend/pages/health/report-confirm.vue`、构建产物
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 1-2 全部改动
|
|
|
+
|
|
|
+- [ ] **Step 1: 全量残留检查**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+grep -n "selectCandidate\|selectMember\|auto-create-card\|选择家庭成员" pages/health/report-confirm.vue
|
|
|
+grep -c "showMemberPanel\|selectedMemberObj\|selectAndClose\|toggleMemberPanel\|syncSelectedMemberObj\|memberDisplayText" pages/health/report-confirm.vue
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 第一个命令 0 匹配;第二个命令 ≥ 6(每个新符号至少出现 1 次)。
|
|
|
+
|
|
|
+- [ ] **Step 2: 逻辑核对(人工阅读)**
|
|
|
+
|
|
|
+阅读 `cfc-frontend/pages/health/report-confirm.vue` 确认:
|
|
|
+1. `canConfirm` 计算属性未改动(`needBind && !selectedMemberId && !createdMemberId` → false)
|
|
|
+2. `doConfirm` 的 subjectId 优先级未改动(selectedMemberId > createdMemberId > matchedMemberId > memberId)
|
|
|
+3. 模板中不再有独立的选择/新建卡片,面板仅在 `showMemberPanel` 为 true 时渲染
|
|
|
+4. 面板内新建表单提交走 `doAutoCreate`(非 `addFamilyMember` 直调)
|
|
|
+5. 无中文 CSS 类名、无可选链 `?.`、无 `:class` 方法调用
|
|
|
+
|
|
|
+- [ ] **Step 3: 最终构建**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd cfc-frontend
|
|
|
+npm run build:mp-weixin
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 退出码 0,无 `ERROR`。
|
|
|
+
|
|
|
+- [ ] **Step 4: 更新 PROJECT-OVERVIEW.md 计划索引**
|
|
|
+
|
|
|
+在 `docs/superpowers/PROJECT-OVERVIEW.md` 的"实施计划(plans/)"表格末尾新增:
|
|
|
+
|
|
|
+```markdown
|
|
|
+| `2026-08-04-report-confirm-member-selector.md` | 🟡 计划中 | 被检测人选择面板整合实现计划(report-confirm.vue 单文件) |
|
|
|
+```
|
|
|
+
|
|
|
+并提交:
|
|
|
+
|
|
|
+```bash
|
|
|
+cd D:\workspace\cfc
|
|
|
+git add docs/superpowers/PROJECT-OVERVIEW.md
|
|
|
+git commit -m "docs: PROJECT-OVERVIEW 登记 report-confirm 选择面板实现计划"
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 5: 汇总提交状态**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd D:\workspace\cfc
|
|
|
+git log --oneline -5
|
|
|
+git status --short
|
|
|
+```
|
|
|
+
|
|
|
+Expected: 最近 3 个 commit 为本计划的 Task 1/2/3 提交;`git status --short` 无未提交改动(除本计划外的既有改动除外)。
|