docs: add user profile real data implementation plan
This commit is contained in:
@@ -0,0 +1,692 @@
|
||||
# 小程序用户信息去写死 + 编辑资料保存生效 — 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:** 去除小程序人生轨迹页和编辑资料页的所有硬编码用户信息,扩展后端 `t_user_profile` 表支持 `city`/`industry`/`company`/`personalityTags`/`birthday` 字段,确保编辑资料能完整保存和回显。
|
||||
|
||||
**Architecture:** 后端通过数据库 ALTER + Java 实体/DTO 扩展新增5个字段;前端同步扩展 Service 转换函数和 Store 数据结构,并移除两个页面中所有 `|| '硬编码默认值'` 回退和示例事件数据。
|
||||
|
||||
**Tech Stack:** Java 17 / Spring Boot / MyBatis-Plus / MySQL;uni-app (Vue 3) / JavaScript
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
| 文件 | 改动 | 职责 |
|
||||
|------|------|------|
|
||||
| `sql/emotion_museum_ddl.sql` | 追加 | 数据库迁移:新增5列 |
|
||||
| `backend-single/.../entity/UserProfile.java` | 修改 | ORM 实体新增字段 |
|
||||
| `backend-single/.../request/UserProfileCreateRequest.java` | 修改 | 创建请求 DTO 新增字段 |
|
||||
| `backend-single/.../request/UserProfileUpdateRequest.java` | 修改 | 更新请求 DTO 新增字段 |
|
||||
| `backend-single/.../response/UserProfileResponse.java` | 修改 | 响应 DTO 新增字段 |
|
||||
| `mini-program/src/services/userProfile.js` | 修改 | 前后端数据格式双向转换 |
|
||||
| `mini-program/src/stores/app.js` | 修改 | 全局状态 registrationData 扩展 |
|
||||
| `mini-program/src/pages/main/RecordView.vue` | 修改 | 去除写死默认值和 sampleEvents |
|
||||
| `mini-program/src/pages/onboarding/index.vue` | 修改 | 去除硬编码默认值,空值友好展示 |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 数据库迁移 — 新增5个字段
|
||||
|
||||
**Files:**
|
||||
- Modify: `sql/emotion_museum_ddl.sql`
|
||||
|
||||
- [ ] **Step 1: 追加 ALTER TABLE 语句**
|
||||
|
||||
在 `sql/emotion_museum_ddl.sql` 文件末尾追加:
|
||||
|
||||
```sql
|
||||
-- 用户档案扩展字段:城市、行业、公司、性格标签、生日
|
||||
alter table emotion_museum.t_user_profile
|
||||
add city varchar(100) null comment '所在城市',
|
||||
add industry varchar(100) null comment '行业',
|
||||
add company varchar(200) null comment '公司',
|
||||
add personality_tags json null comment '性格标签列表',
|
||||
add birthday date null comment '生日';
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add sql/emotion_museum_ddl.sql
|
||||
git commit -m "db: add city, industry, company, personality_tags, birthday to t_user_profile"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: 后端实体扩展 — UserProfile.java
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend-single/src/main/java/com/emotion/entity/UserProfile.java`
|
||||
|
||||
- [ ] **Step 1: 在 idealLife 字段后新增5个字段**
|
||||
|
||||
找到 `idealLife` 字段定义(约第115行),在其后、`scripts` 字段前插入:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 所在城市
|
||||
*/
|
||||
@TableField("city")
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 行业
|
||||
*/
|
||||
@TableField("industry")
|
||||
private String industry;
|
||||
|
||||
/**
|
||||
* 公司
|
||||
*/
|
||||
@TableField("company")
|
||||
private String company;
|
||||
|
||||
/**
|
||||
* 性格标签 (JSON字符串)
|
||||
*/
|
||||
@TableField("personality_tags")
|
||||
private String personalityTags;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
@TableField("birthday")
|
||||
private LocalDate birthday;
|
||||
```
|
||||
|
||||
注意:`LocalDate` 的 import 已在文件顶部存在(第12行),无需新增 import。
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend-single/src/main/java/com/emotion/entity/UserProfile.java
|
||||
git commit -m "feat: extend UserProfile entity with city/industry/company/personalityTags/birthday"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 后端创建请求 DTO 扩展 — UserProfileCreateRequest.java
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java`
|
||||
|
||||
- [ ] **Step 1: 在 idealLife 字段后新增5个字段**
|
||||
|
||||
找到 `idealLife` 字段定义(约第86行),在其后、`scripts` 字段前插入:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 所在城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 行业
|
||||
*/
|
||||
private String industry;
|
||||
|
||||
/**
|
||||
* 公司
|
||||
*/
|
||||
private String company;
|
||||
|
||||
/**
|
||||
* 性格标签 (JSON字符串)
|
||||
*/
|
||||
private String personalityTags;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
private LocalDate birthday;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java
|
||||
git commit -m "feat: extend UserProfileCreateRequest with city/industry/company/personalityTags/birthday"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 后端更新请求 DTO 扩展 — UserProfileUpdateRequest.java
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java`
|
||||
|
||||
- [ ] **Step 1: 在 idealLife 字段后新增5个字段**
|
||||
|
||||
找到 `idealLife` 字段定义(约第90行),在其后、`scripts` 字段前插入:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 所在城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 行业
|
||||
*/
|
||||
private String industry;
|
||||
|
||||
/**
|
||||
* 公司
|
||||
*/
|
||||
private String company;
|
||||
|
||||
/**
|
||||
* 性格标签 (JSON字符串)
|
||||
*/
|
||||
private String personalityTags;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
private LocalDate birthday;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java
|
||||
git commit -m "feat: extend UserProfileUpdateRequest with city/industry/company/personalityTags/birthday"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 后端响应 DTO 扩展 — UserProfileResponse.java
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java`
|
||||
|
||||
- [ ] **Step 1: 在 idealLife 字段后新增5个字段**
|
||||
|
||||
找到 `idealLife` 字段定义(约第105行),在其后、`scripts` 字段前插入:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 所在城市
|
||||
*/
|
||||
private String city;
|
||||
|
||||
/**
|
||||
* 行业
|
||||
*/
|
||||
private String industry;
|
||||
|
||||
/**
|
||||
* 公司
|
||||
*/
|
||||
private String company;
|
||||
|
||||
/**
|
||||
* 性格标签 (JSON字符串)
|
||||
*/
|
||||
private String personalityTags;
|
||||
|
||||
/**
|
||||
* 生日
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate birthday;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java
|
||||
git commit -m "feat: extend UserProfileResponse with city/industry/company/personalityTags/birthday"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 前端 Service 扩展 — userProfile.js
|
||||
|
||||
**Files:**
|
||||
- Modify: `mini-program/src/services/userProfile.js`
|
||||
|
||||
- [ ] **Step 1: 扩展 transformToBackendFormat 的解构和返回对象**
|
||||
|
||||
原解构(第47-59行)新增5个字段:
|
||||
|
||||
```js
|
||||
const {
|
||||
id,
|
||||
nickname,
|
||||
gender,
|
||||
zodiac,
|
||||
profession,
|
||||
mbti,
|
||||
hobbies,
|
||||
childhood,
|
||||
joy,
|
||||
low,
|
||||
future,
|
||||
city,
|
||||
industry,
|
||||
company,
|
||||
personalityTags,
|
||||
birthday
|
||||
} = frontendData
|
||||
```
|
||||
|
||||
原返回对象(第61-83行)在 `idealLife` 后新增:
|
||||
|
||||
```js
|
||||
return {
|
||||
id,
|
||||
nickname,
|
||||
gender,
|
||||
zodiac,
|
||||
profession,
|
||||
mbti,
|
||||
// 兴趣爱好转为JSON字符串
|
||||
hobbies: Array.isArray(hobbies) ? JSON.stringify(hobbies) : hobbies,
|
||||
// 童年经历
|
||||
childhoodDate: childhood?.date || null,
|
||||
childhoodContent: childhood?.text || null,
|
||||
// 高光时刻(对应前端的joy)
|
||||
peakDate: joy?.date || null,
|
||||
peakContent: joy?.text || null,
|
||||
// 低谷时期(对应前端的low)
|
||||
valleyDate: low?.date || null,
|
||||
valleyContent: low?.text || null,
|
||||
// 未来期许
|
||||
futureVision: future?.vision || null,
|
||||
// 理想生活状态
|
||||
idealLife: future?.ideal || null,
|
||||
// 新增字段
|
||||
city: city || null,
|
||||
industry: industry || null,
|
||||
company: company || null,
|
||||
personalityTags: Array.isArray(personalityTags) ? JSON.stringify(personalityTags) : personalityTags,
|
||||
birthday: birthday || null
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 扩展 transformToFrontendFormat 的解构和返回对象**
|
||||
|
||||
原解构(第94-111行)新增5个字段:
|
||||
|
||||
```js
|
||||
const {
|
||||
id,
|
||||
userId,
|
||||
nickname,
|
||||
gender,
|
||||
zodiac,
|
||||
profession,
|
||||
mbti,
|
||||
hobbies,
|
||||
childhoodDate,
|
||||
childhoodContent,
|
||||
peakDate,
|
||||
peakContent,
|
||||
valleyDate,
|
||||
valleyContent,
|
||||
futureVision,
|
||||
idealLife,
|
||||
city,
|
||||
industry,
|
||||
company,
|
||||
personalityTags,
|
||||
birthday
|
||||
} = backendData
|
||||
```
|
||||
|
||||
原返回对象(第113-143行)在 `future` 对象后新增:
|
||||
|
||||
```js
|
||||
return {
|
||||
id,
|
||||
userId,
|
||||
nickname: nickname || '',
|
||||
gender: gender || '',
|
||||
zodiac: zodiac || '',
|
||||
profession: profession || '',
|
||||
mbti: mbti || '',
|
||||
// 兴趣爱好从JSON字符串解析
|
||||
hobbies: hobbies ? (typeof hobbies === 'string' ? JSON.parse(hobbies) : hobbies) : [],
|
||||
// 童年经历
|
||||
childhood: {
|
||||
date: childhoodDate || '',
|
||||
text: childhoodContent || ''
|
||||
},
|
||||
// 高光时刻
|
||||
joy: {
|
||||
date: peakDate || '',
|
||||
text: peakContent || ''
|
||||
},
|
||||
// 低谷时期
|
||||
low: {
|
||||
date: valleyDate || '',
|
||||
text: valleyContent || ''
|
||||
},
|
||||
// 未来期许
|
||||
future: {
|
||||
vision: futureVision || '',
|
||||
ideal: idealLife || ''
|
||||
},
|
||||
// 新增字段
|
||||
city: city || '',
|
||||
industry: industry || '',
|
||||
company: company || '',
|
||||
personalityTags: personalityTags ? (typeof personalityTags === 'string' ? JSON.parse(personalityTags) : personalityTags) : [],
|
||||
birthday: birthday || ''
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add mini-program/src/services/userProfile.js
|
||||
git commit -m "feat: add city/industry/company/personalityTags/birthday to userProfile transforms"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: 前端 Store 扩展 — app.js
|
||||
|
||||
**Files:**
|
||||
- Modify: `mini-program/src/stores/app.js`
|
||||
|
||||
- [ ] **Step 1: 扩展 registrationData 初始结构**
|
||||
|
||||
找到 `registrationData` 定义(第19-30行),在 `future` 对象后新增:
|
||||
|
||||
```js
|
||||
registrationData: {
|
||||
nickname: '',
|
||||
gender: '',
|
||||
mbti: '',
|
||||
zodiac: '',
|
||||
profession: '',
|
||||
hobbies: [],
|
||||
childhood: { date: '', text: '' },
|
||||
joy: { date: '', text: '' },
|
||||
low: { date: '', text: '' },
|
||||
future: { vision: '', ideal: '' },
|
||||
city: '',
|
||||
industry: '',
|
||||
company: '',
|
||||
personalityTags: [],
|
||||
birthday: ''
|
||||
}
|
||||
```
|
||||
|
||||
注意:此文件使用 CRLF 行尾(`\r\n`),使用 Edit 工具时请按 Read 工具输出的格式匹配。
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add mini-program/src/stores/app.js
|
||||
git commit -m "feat: extend registrationData with city/industry/company/personalityTags/birthday"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: 人生轨迹页去写死 — RecordView.vue
|
||||
|
||||
**Files:**
|
||||
- Modify: `mini-program/src/pages/main/RecordView.vue`
|
||||
|
||||
- [ ] **Step 1: 删除 sampleEvents 数组**
|
||||
|
||||
删除第143-176行的 `sampleEvents` 数组定义。
|
||||
|
||||
- [ ] **Step 2: 修改 events computed 去除 sampleEvents 回退**
|
||||
|
||||
将第179-182行:
|
||||
```js
|
||||
const events = computed(() => {
|
||||
const list = store.events || []
|
||||
return list.length ? list : sampleEvents
|
||||
})
|
||||
```
|
||||
改为:
|
||||
```js
|
||||
const events = computed(() => store.events || [])
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 修改 heroTags computed 去除硬编码默认值**
|
||||
|
||||
将第183-187行:
|
||||
```js
|
||||
const heroTags = computed(() => {
|
||||
const hobbies = profile.value.hobbies
|
||||
if (Array.isArray(hobbies) && hobbies.length) return hobbies.slice(0, 4)
|
||||
return ['阅读', '旅行', '音乐', '创作']
|
||||
})
|
||||
```
|
||||
改为:
|
||||
```js
|
||||
const heroTags = computed(() => {
|
||||
const hobbies = profile.value.hobbies
|
||||
if (Array.isArray(hobbies) && hobbies.length) return hobbies.slice(0, 4)
|
||||
return []
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 修改 avatar computed 去除硬编码昵称**
|
||||
|
||||
将第189-192行:
|
||||
```js
|
||||
const avatar = computed(() => {
|
||||
const nickname = profile.value.nickname || 'Zoey'
|
||||
return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(nickname)}&backgroundColor=b982ff`
|
||||
})
|
||||
```
|
||||
改为:
|
||||
```js
|
||||
const avatar = computed(() => {
|
||||
const nickname = profile.value.nickname || 'User'
|
||||
return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(nickname)}&backgroundColor=b982ff`
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 修改模板中硬编码默认值**
|
||||
|
||||
将第13行:
|
||||
```vue
|
||||
<text class="profile-name">{{ profile.nickname || 'Zoey' }}</text>
|
||||
```
|
||||
改为:
|
||||
```vue
|
||||
<text class="profile-name">{{ profile.nickname || '未设置' }}</text>
|
||||
```
|
||||
|
||||
将第31行:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.zodiac || '巨蟹座' }}</text>
|
||||
```
|
||||
改为:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.zodiac || '未设置' }}</text>
|
||||
```
|
||||
|
||||
将第38行:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.mbti || 'ENTJ' }}</text>
|
||||
```
|
||||
改为:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.mbti || '未设置' }}</text>
|
||||
```
|
||||
|
||||
将第45行:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.profession || '产品经理' }}</text>
|
||||
```
|
||||
改为:
|
||||
```vue
|
||||
<text class="meta-value">{{ profile.profession || '未设置' }}</text>
|
||||
```
|
||||
|
||||
将第56行:
|
||||
```vue
|
||||
<text class="hobby-text">{{ heroTags.join(' · ') }}</text>
|
||||
```
|
||||
改为:
|
||||
```vue
|
||||
<text class="hobby-text">{{ heroTags.length ? heroTags.join(' · ') : '未设置' }}</text>
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add mini-program/src/pages/main/RecordView.vue
|
||||
git commit -m "fix: remove hardcoded defaults and sampleEvents from RecordView"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 9: 编辑资料页去写死 — onboarding/index.vue
|
||||
|
||||
**Files:**
|
||||
- Modify: `mini-program/src/pages/onboarding/index.vue`
|
||||
|
||||
- [ ] **Step 1: 修改 avatarUrl computed 去除硬编码昵称**
|
||||
|
||||
将第234-238行:
|
||||
```js
|
||||
const avatarUrl = computed(() => {
|
||||
if (avatarLocal.value) return avatarLocal.value
|
||||
const nickname = form.nickname || 'Zoey'
|
||||
return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(nickname)}&backgroundColor=b982ff`
|
||||
})
|
||||
```
|
||||
改为:
|
||||
```js
|
||||
const avatarUrl = computed(() => {
|
||||
if (avatarLocal.value) return avatarLocal.value
|
||||
const nickname = form.nickname || 'User'
|
||||
return `https://api.dicebear.com/7.x/avataaars/svg?seed=${encodeURIComponent(nickname)}&backgroundColor=b982ff`
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 修改 birthdayDisplay computed 去除硬编码日期**
|
||||
|
||||
将第240-244行:
|
||||
```js
|
||||
const birthdayDisplay = computed(() => {
|
||||
if (!birthday.value) return '1998年06月18日'
|
||||
const [year, month, day] = birthday.value.split('-')
|
||||
return `${year}年${month}月${day}日`
|
||||
})
|
||||
```
|
||||
改为:
|
||||
```js
|
||||
const birthdayDisplay = computed(() => {
|
||||
if (!birthday.value) return '请选择生日'
|
||||
const [year, month, day] = birthday.value.split('-')
|
||||
return `${year}年${month}月${day}日`
|
||||
})
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 修改 syncFromStore 去除所有硬编码默认值**
|
||||
|
||||
将第246-265行的 `syncFromStore` 函数整体替换为:
|
||||
|
||||
```js
|
||||
const syncFromStore = () => {
|
||||
const source = store.userProfile || store.registrationData || {}
|
||||
Object.assign(form, {
|
||||
nickname: source.nickname || '',
|
||||
gender: source.gender || '',
|
||||
zodiac: source.zodiac || '',
|
||||
mbti: source.mbti || '',
|
||||
profession: source.profession || '',
|
||||
city: source.city || '',
|
||||
industry: source.industry || '',
|
||||
company: source.company || '',
|
||||
personalityTags: Array.isArray(source.personalityTags) ? [...source.personalityTags] : [],
|
||||
hobbies: Array.isArray(source.hobbies) ? [...source.hobbies] : [],
|
||||
childhood: { date: source.childhood?.date || '', text: source.childhood?.text || '' },
|
||||
joy: { date: source.joy?.date || '', text: source.joy?.text || '' },
|
||||
low: { date: source.low?.date || '', text: source.low?.text || '' },
|
||||
future: { vision: source.future?.vision || '', ideal: source.future?.ideal || '' }
|
||||
})
|
||||
birthday.value = source.birthday || ''
|
||||
}
|
||||
```
|
||||
|
||||
注意:此文件使用 CRLF 行尾(`\r\n`),使用 Edit 工具时请按 Read 工具输出的格式匹配。
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add mini-program/src/pages/onboarding/index.vue
|
||||
git commit -m "fix: remove hardcoded defaults from profile edit page"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 10: 验证测试
|
||||
|
||||
**Files:**
|
||||
- 无需修改,纯验证
|
||||
|
||||
- [ ] **Step 1: 后端编译验证**
|
||||
|
||||
```bash
|
||||
cd backend-single && mvn compile -q
|
||||
```
|
||||
|
||||
预期:编译成功,无错误。
|
||||
|
||||
- [ ] **Step 2: 前端语法检查(如有 linter)**
|
||||
|
||||
```bash
|
||||
cd mini-program && npm run lint 2>/dev/null || echo "No lint script, skipping"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 手动功能验证清单**
|
||||
|
||||
1. 启动后端服务,确认无启动错误。
|
||||
2. 在数据库执行 `DESCRIBE t_user_profile;`,确认 `city`、`industry`、`company`、`personality_tags`、`birthday` 五列已存在。
|
||||
3. 小程序登录后进入"人生轨迹"页:
|
||||
- 未设置资料时,昵称显示"未设置",星座/MBTI/职业显示"未设置",爱好显示"未设置"。
|
||||
- 无人生事件时,显示"还没有人生轨迹"空状态,无 sampleEvents。
|
||||
4. 点击"编辑资料":
|
||||
- 首次进入(无资料)时,所有输入框为空,生日显示"请选择生日",性格标签和爱好无选中项。
|
||||
- 填写所有字段(包括城市、行业、公司、性格标签、生日)后保存。
|
||||
- 保存成功后返回人生轨迹页,数据已更新。
|
||||
- 再次进入编辑资料页,所有字段正确回显。
|
||||
5. 已有用户(老数据,无新字段)登录后,页面正常展示,无报错,新字段显示为空。
|
||||
|
||||
- [ ] **Step 4: Commit(如测试通过)**
|
||||
|
||||
```bash
|
||||
git log --oneline -10
|
||||
```
|
||||
|
||||
预期看到 9 个 commits(Task 1-9 各一个)。
|
||||
|
||||
---
|
||||
|
||||
## Self-Review
|
||||
|
||||
**1. Spec coverage:**
|
||||
- 数据库扩展5个字段 → Task 1 ✅
|
||||
- 后端实体扩展 → Task 2 ✅
|
||||
- 后端 DTO 扩展(Create/Update/Response)→ Task 3/4/5 ✅
|
||||
- 前端 Service 双向转换扩展 → Task 6 ✅
|
||||
- 前端 Store 扩展 → Task 7 ✅
|
||||
- 人生轨迹页去除写死数据和 sampleEvents → Task 8 ✅
|
||||
- 编辑资料页去除硬编码默认值 → Task 9 ✅
|
||||
- 测试验证 → Task 10 ✅
|
||||
|
||||
**2. Placeholder scan:**
|
||||
- 无 TBD/TODO/"implement later"/"fill in details" ✅
|
||||
- 无 "Add appropriate error handling" 等模糊描述 ✅
|
||||
- 无 "Similar to Task N" ✅
|
||||
- 每个代码步骤都包含完整代码 ✅
|
||||
|
||||
**3. Type consistency:**
|
||||
- 后端5个字段名在 Entity/CreateRequest/UpdateRequest/Response 中完全一致:`city`, `industry`, `company`, `personalityTags`, `birthday` ✅
|
||||
- 前端 Service 中 `transformToBackendFormat` 和 `transformToFrontendFormat` 字段名一致 ✅
|
||||
- Store 中 `registrationData` 字段名与 Service 一致 ✅
|
||||
- `personalityTags` 在前端始终作为数组处理,后端作为 JSON 字符串,转换逻辑与 `hobbies` 保持一致 ✅
|
||||
- `birthday` 前后端均为 `yyyy-MM-dd` 字符串格式 ✅
|
||||
Reference in New Issue
Block a user