diff --git a/docs/superpowers/plans/2026-06-24-personality-tag-library.md b/docs/superpowers/plans/2026-06-24-personality-tag-library.md
new file mode 100644
index 0000000..13a89e1
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-24-personality-tag-library.md
@@ -0,0 +1,1307 @@
+# 小程序编辑资料页:性格标签 / 兴趣爱好 标签库扩展 实现计划
+
+> **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:** 让小程序编辑资料页的性格标签和兴趣爱好支持用户自由新增、删除、管理,标签容器自适应撑开,新增的自定义标签展示在最前面。
+
+**Architecture:** 后端 `UserProfile` 实体新增两个 JSON 字段(`personality_tag_library` / `hobby_library`)存用户专属的完整标签库,原有"已选中标签"字段语义保留不变;前端通过 `stores/app.js` 的 `registrationData` 持有库数据,编辑资料页基于库数据计算有序展示列表,管理页通过 `uni.$emit` 事件将删除结果同步回编辑页。
+
+**Tech Stack:** Spring Boot 2.7 + MyBatis-Plus + MySQL 8(后端),UniApp 3 + Vue 3 Composition API + 微信小程序(前端)。
+
+**Spec 文档:** `docs/superpowers/specs/2026-06-24-personality-tag-library-design.md`
+
+---
+
+## 文件结构总览
+
+### 新增文件
+
+| 文件 | 职责 |
+|---|---|
+| `backend-single/src/main/resources/db/migration/V20260624__add_user_profile_tag_library.sql` | 数据库字段迁移脚本 |
+| `mini-program/src/pages/onboarding/tag-manage.vue` | 管理标签独立页面(性格标签 / 兴趣爱好) |
+
+### 修改文件
+
+| 文件 | 修改内容 |
+|---|---|
+| `backend-single/src/main/java/com/emotion/entity/UserProfile.java` | 新增 `personalityTagLibrary` / `hobbyLibrary` 字段 |
+| `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java` | 同上 |
+| `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java` | 同上 |
+| `backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java` | 同上 |
+| `mini-program/src/services/userProfile.js` | 请求/响应转换增加两个库字段 |
+| `mini-program/src/stores/app.js` | `registrationData` 增加两个库字段 |
+| `mini-program/src/pages.json` | 注册 `tag-manage` 路由 |
+| `mini-program/src/pages/onboarding/index.vue` | 标签区 UI 重构、新增标签弹窗、管理入口、事件监听 |
+
+### 不修改文件
+
+| 文件 | 原因 |
+|---|---|
+| `mini-program/src/pages/main/MineView.vue` | 只读"已选中的标签"(沿用 `hobbies` 字段),不需要感知完整库 |
+| `backend-single/src/main/java/com/emotion/service/impl/UserProfileServiceImpl.java` | 使用 `BeanUtils.copyProperties` 自动映射,新字段透传 |
+| `backend-single/src/main/java/com/emotion/controller/UserProfileController.java` | 同上 |
+
+---
+
+## Task 1: 后端数据库与实体层
+
+**目标:** 给 `t_user_profile` 表新增两个 JSON 字段,同步更新实体类与 3 个 DTO,保证接口透传。
+
+**Files:**
+- Create: `backend-single/src/main/resources/db/migration/V20260624__add_user_profile_tag_library.sql`
+- Modify: `backend-single/src/main/java/com/emotion/entity/UserProfile.java`
+- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java`
+- Modify: `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java`
+- Modify: `backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java`
+
+### Step 1: 创建数据库迁移脚本
+
+创建 `backend-single/src/main/resources/db/migration/V20260624__add_user_profile_tag_library.sql`:
+
+```sql
+-- 用户档案表新增标签库字段,用于存储用户专属的完整标签列表(含剩余预设 + 自定义)
+ALTER TABLE t_user_profile
+ ADD COLUMN personality_tag_library TEXT DEFAULT NULL COMMENT '用户完整性格标签库(JSON数组)',
+ ADD COLUMN hobby_library TEXT DEFAULT NULL COMMENT '用户完整兴趣爱好库(JSON数组)';
+```
+
+### Step 2: UserProfile 实体新增字段
+
+修改 `backend-single/src/main/java/com/emotion/entity/UserProfile.java`。
+
+在 `personalityTags` 字段下方追加两个字段(保持与现有 `personalityTags` / `hobbies` 字段风格一致):
+
+```java
+ /**
+ * 性格标签 (JSON字符串)
+ */
+ @TableField("personality_tags")
+ private String personalityTags;
+
+ /**
+ * 用户完整性格标签库 (JSON字符串,含剩余预设 + 自定义)
+ */
+ @TableField("personality_tag_library")
+ private String personalityTagLibrary;
+
+ /**
+ * 用户完整兴趣爱好库 (JSON字符串,含剩余预设 + 自定义)
+ */
+ @TableField("hobby_library")
+ private String hobbyLibrary;
+```
+
+### Step 3: UserProfileUpdateRequest 新增字段
+
+修改 `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java`。
+
+在 `personalityTags` 字段下方追加:
+
+```java
+ /**
+ * 性格标签 (JSON字符串)
+ */
+ private String personalityTags;
+
+ /**
+ * 用户完整性格标签库 (JSON字符串)
+ */
+ private String personalityTagLibrary;
+
+ /**
+ * 用户完整兴趣爱好库 (JSON字符串)
+ */
+ private String hobbyLibrary;
+```
+
+### Step 4: UserProfileCreateRequest 新增字段
+
+修改 `backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java`。
+
+在 `personalityTags` 字段下方追加:
+
+```java
+ /**
+ * 性格标签 (JSON字符串)
+ */
+ private String personalityTags;
+
+ /**
+ * 用户完整性格标签库 (JSON字符串)
+ */
+ private String personalityTagLibrary;
+
+ /**
+ * 用户完整兴趣爱好库 (JSON字符串)
+ */
+ private String hobbyLibrary;
+```
+
+### Step 5: UserProfileResponse 新增字段
+
+修改 `backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java`。
+
+在 `personalityTags` 字段下方追加:
+
+```java
+ /**
+ * 性格标签 (JSON字符串)
+ */
+ private String personalityTags;
+
+ /**
+ * 用户完整性格标签库 (JSON字符串)
+ */
+ private String personalityTagLibrary;
+
+ /**
+ * 用户完整兴趣爱好库 (JSON字符串)
+ */
+ private String hobbyLibrary;
+```
+
+### Step 6: 本地编译验证
+
+```bash
+cd backend-single
+mvn clean install -DskipTests -pl :backend-single -am
+```
+
+预期:`BUILD SUCCESS`。
+
+### Step 7: 提交
+
+```bash
+git add backend-single/src/main/resources/db/migration/V20260624__add_user_profile_tag_library.sql \
+ backend-single/src/main/java/com/emotion/entity/UserProfile.java \
+ backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileUpdateRequest.java \
+ backend-single/src/main/java/com/emotion/dto/request/userprofile/UserProfileCreateRequest.java \
+ backend-single/src/main/java/com/emotion/dto/response/userprofile/UserProfileResponse.java
+git commit -m "feat:UserProfile 新增性格标签库与兴趣爱好库字段"
+```
+
+---
+
+## Task 2: 前端数据层(services + stores + pages.json)
+
+**目标:** 前端请求/响应转换、全局 store、路由注册全部支持新字段。
+
+**Files:**
+- Modify: `mini-program/src/services/userProfile.js`
+- Modify: `mini-program/src/stores/app.js`
+- Modify: `mini-program/src/pages.json`
+
+### Step 1: services/userProfile.js 响应解析增加库字段
+
+修改 `mini-program/src/services/userProfile.js`。
+
+在 `transformToFrontendFormat` 函数中,解构时增加两个字段,并在返回对象中解析它们:
+
+原代码:
+
+```javascript
+ const {
+ id,
+ userId,
+ nickname,
+ gender,
+ zodiac,
+ profession,
+ mbti,
+ hobbies,
+ childhoodDate,
+ childhoodContent,
+ peakDate,
+ peakContent,
+ valleyDate,
+ valleyContent,
+ futureVision,
+ idealLife,
+ city,
+ industry,
+ company,
+ personalityTags,
+ birthday
+ } = backendData
+```
+
+改为:
+
+```javascript
+ const {
+ id,
+ userId,
+ nickname,
+ gender,
+ zodiac,
+ profession,
+ mbti,
+ hobbies,
+ childhoodDate,
+ childhoodContent,
+ peakDate,
+ peakContent,
+ valleyDate,
+ valleyContent,
+ futureVision,
+ idealLife,
+ city,
+ industry,
+ company,
+ personalityTags,
+ personalityTagLibrary,
+ hobbyLibrary,
+ birthday
+ } = backendData
+```
+
+原返回对象末尾:
+
+```javascript
+ personalityTags: parseJsonArray(personalityTags),
+ birthday: normalizeDate(birthday)
+ }
+```
+
+改为:
+
+```javascript
+ personalityTags: parseJsonArray(personalityTags),
+ personalityTagLibrary: parseJsonArray(personalityTagLibrary),
+ hobbyLibrary: parseJsonArray(hobbyLibrary),
+ birthday: normalizeDate(birthday)
+ }
+```
+
+### Step 2: services/userProfile.js 请求提交增加库字段
+
+修改 `transformToBackendFormat` 函数。
+
+原解构:
+
+```javascript
+ const {
+ id,
+ nickname,
+ gender,
+ zodiac,
+ profession,
+ mbti,
+ hobbies,
+ childhood,
+ joy,
+ low,
+ future,
+ city,
+ industry,
+ company,
+ personalityTags,
+ birthday
+ } = frontendData
+```
+
+改为:
+
+```javascript
+ const {
+ id,
+ nickname,
+ gender,
+ zodiac,
+ profession,
+ mbti,
+ hobbies,
+ childhood,
+ joy,
+ low,
+ future,
+ city,
+ industry,
+ company,
+ personalityTags,
+ personalityTagLibrary,
+ hobbyLibrary,
+ birthday
+ } = frontendData
+```
+
+原返回对象末尾:
+
+```javascript
+ personalityTags: Array.isArray(personalityTags) ? JSON.stringify(personalityTags) : personalityTags,
+ birthday: birthday || null
+ }
+```
+
+改为:
+
+```javascript
+ personalityTags: Array.isArray(personalityTags) ? JSON.stringify(personalityTags) : personalityTags,
+ personalityTagLibrary: Array.isArray(personalityTagLibrary) ? JSON.stringify(personalityTagLibrary) : personalityTagLibrary,
+ hobbyLibrary: Array.isArray(hobbyLibrary) ? JSON.stringify(hobbyLibrary) : hobbyLibrary,
+ birthday: birthday || null
+ }
+```
+
+### Step 3: stores/app.js registrationData 增加库字段
+
+修改 `mini-program/src/stores/app.js`。
+
+原 `state.registrationData`:
+
+```javascript
+ registrationData: {
+ nickname: '',
+ gender: '',
+ mbti: '',
+ zodiac: '',
+ profession: '',
+ hobbies: [],
+ childhood: { date: '', text: '' },
+ joy: { date: '', text: '' },
+ low: { date: '', text: '' },
+ future: { vision: '', ideal: '' },
+ city: '',
+ industry: '',
+ company: '',
+ personalityTags: [],
+ birthday: ''
+ }
+```
+
+改为:
+
+```javascript
+ registrationData: {
+ nickname: '',
+ gender: '',
+ mbti: '',
+ zodiac: '',
+ profession: '',
+ hobbies: [],
+ childhood: { date: '', text: '' },
+ joy: { date: '', text: '' },
+ low: { date: '', text: '' },
+ future: { vision: '', ideal: '' },
+ city: '',
+ industry: '',
+ company: '',
+ personalityTags: [],
+ personalityTagLibrary: [],
+ hobbyLibrary: [],
+ birthday: ''
+ }
+```
+
+### Step 4: pages.json 注册 tag-manage 路由
+
+修改 `mini-program/src/pages.json`。
+
+在 `pages/onboarding/index` 条目后面插入新页面:
+
+```json
+ {
+ "path": "pages/onboarding/index",
+ "style": {
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/onboarding/tag-manage",
+ "style": {
+ "navigationStyle": "custom",
+ "navigationBarTitleText": "管理标签"
+ }
+ },
+```
+
+### Step 5: 提交
+
+```bash
+git add mini-program/src/services/userProfile.js \
+ mini-program/src/stores/app.js \
+ mini-program/src/pages.json
+git commit -m "feat:前端数据层与路由注册支持标签库字段"
+```
+
+---
+
+## Task 3: 编辑资料页数据初始化与兼容
+
+**目标:** 编辑资料页 `form` 持有两个库字段,`syncFromStore` 加载库数据并对老用户做兼容初始化。
+
+**Files:**
+- Modify: `mini-program/src/pages/onboarding/index.vue`
+
+### Step 1: form reactive 增加库字段
+
+修改 `mini-program/src/pages/onboarding/index.vue`。
+
+原 `form`:
+
+```javascript
+const form = reactive({
+ nickname: '',
+ gender: '',
+ zodiac: '',
+ mbti: '',
+ profession: '',
+ city: '',
+ industry: '',
+ company: '',
+ personalityTags: [],
+ hobbies: [],
+ childhood: { date: '', text: '' },
+ joy: { date: '', text: '' },
+ low: { date: '', text: '' },
+ future: { vision: '', ideal: '' }
+})
+```
+
+改为:
+
+```javascript
+const form = reactive({
+ nickname: '',
+ gender: '',
+ zodiac: '',
+ mbti: '',
+ profession: '',
+ city: '',
+ industry: '',
+ company: '',
+ personalityTags: [],
+ hobbies: [],
+ personalityTagLibrary: [],
+ hobbyLibrary: [],
+ childhood: { date: '', text: '' },
+ joy: { date: '', text: '' },
+ low: { date: '', text: '' },
+ future: { vision: '', ideal: '' }
+})
+```
+
+### Step 2: syncFromStore 增加库字段加载与老用户兼容初始化
+
+替换原 `syncFromStore` 函数为:
+
+```javascript
+/**
+ * 合并预设数组与已选数组,去重返回完整库
+ */
+const buildInitialLibrary = (preset, selected) => {
+ const library = [...preset]
+ if (Array.isArray(selected)) {
+ selected.forEach((tag) => {
+ if (!library.includes(tag)) library.push(tag)
+ })
+ }
+ return library
+}
+
+const syncFromStore = () => {
+ const source = store.userProfile || store.registrationData || {}
+
+ // 性格标签库:后端有则用后端,否则用预设 + 已选合并(老用户兼容)
+ const personalityTagLibrary = Array.isArray(source.personalityTagLibrary) && source.personalityTagLibrary.length > 0
+ ? [...source.personalityTagLibrary]
+ : buildInitialLibrary(personalityTags, source.personalityTags)
+
+ // 兴趣爱好库:后端有则用后端,否则用预设 + 已选合并(老用户兼容)
+ const hobbyLibrary = Array.isArray(source.hobbyLibrary) && source.hobbyLibrary.length > 0
+ ? [...source.hobbyLibrary]
+ : buildInitialLibrary(hobbyOptions, source.hobbies)
+
+ 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] : [],
+ personalityTagLibrary,
+ hobbyLibrary,
+ 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 || ''
+}
+```
+
+### Step 3: 提交
+
+```bash
+git add mini-program/src/pages/onboarding/index.vue
+git commit -m "feat:编辑资料页 form 增加库字段并对老用户兼容初始化"
+```
+
+---
+
+## Task 4: 编辑资料页标签区 UI 重构
+
+**目标:** 性格标签、兴趣爱好两个 panel 重构为基于库数据计算的有序展示列表,标题行右侧新增"管理"按钮,末尾"+ 添加"绑定新增弹窗。
+
+**Files:**
+- Modify: `mini-program/src/pages/onboarding/index.vue`
+
+### Step 1: 新增两个 computed 计算有序展示列表
+
+在 `script setup` 中(`syncFromStore` 函数之后)新增:
+
+```javascript
+/**
+ * 性格标签有序展示列表:
+ * 1. 新增的自定义标签(不在预设中)按库顺序排在最前
+ * 2. 已选中的其他标签紧随其后
+ * 3. 其余未选中的预设标签排在最后
+ */
+const displayPersonalityTags = computed(() => {
+ const selectedSet = new Set(form.personalityTags)
+ const presetSet = new Set(personalityTags)
+
+ // 自定义标签:不在预设数组中的标签,按库顺序
+ const customTags = form.personalityTagLibrary.filter((tag) => !presetSet.has(tag))
+ // 已选中的预设标签
+ const selectedPreset = form.personalityTagLibrary.filter(
+ (tag) => presetSet.has(tag) && selectedSet.has(tag)
+ )
+ // 未选中的预设标签
+ const unselectedPreset = form.personalityTagLibrary.filter(
+ (tag) => presetSet.has(tag) && !selectedSet.has(tag)
+ )
+
+ return [...customTags, ...selectedPreset, ...unselectedPreset]
+})
+
+/**
+ * 兴趣爱好有序展示列表(逻辑同上)
+ */
+const displayHobbyTags = computed(() => {
+ const selectedSet = new Set(form.hobbies)
+ const presetSet = new Set(hobbyOptions)
+
+ const customTags = form.hobbyLibrary.filter((tag) => !presetSet.has(tag))
+ const selectedPreset = form.hobbyLibrary.filter(
+ (tag) => presetSet.has(tag) && selectedSet.has(tag)
+ )
+ const unselectedPreset = form.hobbyLibrary.filter(
+ (tag) => presetSet.has(tag) && !selectedSet.has(tag)
+ )
+
+ return [...customTags, ...selectedPreset, ...unselectedPreset]
+})
+```
+
+### Step 2: 替换性格标签 panel 模板
+
+原性格标签模板(约在 129-145 行):
+
+```html
+
+
+
+ 性格标签
+ (最多选择5个)
+
+
+ {{ tag }}
+ + 添加标签
+
+
+```
+
+替换为:
+
+```html
+
+
+
+
+ 性格标签
+ (最多选择5个)
+
+ 管理
+
+
+ {{ tag }}
+ + 添加标签
+
+
+```
+
+### Step 3: 替换兴趣爱好 panel 模板
+
+原兴趣爱好模板(约在 147-165 行):
+
+```html
+
+
+
+
+ 兴趣爱好
+ (最多选择5个)
+
+ + 自定义兴趣
+
+
+ {{ tag }}
+
+
+```
+
+替换为:
+
+```html
+
+
+
+
+ 兴趣爱好
+ (最多选择5个)
+
+ 管理
+
+
+ {{ tag }}
+ + 添加兴趣
+
+
+```
+
+### Step 4: 新增管理页跳转与标签新增函数(替换旧 addCustomHobby)
+
+在 `script setup` 中删除原 `addCustomHobby` 函数,替换为以下三个函数:
+
+```javascript
+/**
+ * 跳转到管理标签页面
+ */
+const goTagManage = (type) => {
+ uni.navigateTo({
+ url: `/pages/onboarding/tag-manage?type=${type}`
+ })
+}
+
+/**
+ * 新增自定义标签(性格标签 / 兴趣爱好通用)
+ * @param {string} type 'personality' 或 'hobby'
+ */
+const addCustomTag = (type) => {
+ const isPersonality = type === 'personality'
+ const library = isPersonality ? form.personalityTagLibrary : form.hobbyLibrary
+ const selected = isPersonality ? form.personalityTags : form.hobbies
+ const title = isPersonality ? '添加性格标签' : '添加兴趣爱好'
+
+ uni.showModal({
+ title,
+ editable: true,
+ placeholderText: '请输入标签(最多8个字符)',
+ success: (res) => {
+ const value = String(res.content || '').trim()
+ if (!res.confirm) return
+ if (!value) {
+ uni.showToast({ title: '请输入标签内容', icon: 'none' })
+ return
+ }
+ if (value.length > 8) {
+ uni.showToast({ title: '标签最多8个字符', icon: 'none' })
+ return
+ }
+ if (library.includes(value)) {
+ uni.showToast({ title: '标签已存在', icon: 'none' })
+ return
+ }
+ // 新标签插入到库数组最前面
+ library.unshift(value)
+ // 若已选未满 5 个,自动加入已选;否则仅提示
+ if (selected.length >= 5) {
+ uni.showToast({ title: '已达上限,仅加入标签库', icon: 'none' })
+ return
+ }
+ selected.push(value)
+ }
+ })
+}
+```
+
+### Step 5: 样式调整 — "管理"链接样式
+
+在 `
+```
+
+### Step 2: 启动 H5 开发服务器预览
+
+```bash
+cd mini-program
+npm run dev:h5
+```
+
+在浏览器中打开 `http://localhost:5173`,登录后进入编辑资料页,验证:
+- 性格标签、兴趣爱好 panel 标题右侧显示"管理"链接。
+- 点击"管理"跳转管理页,页面标题显示"管理性格标签"或"管理兴趣爱好"。
+- 每行标签右侧显示 × 按钮,左滑显示"删除"按钮。
+- 点击 × 或滑动后点击删除,弹出确认对话框。
+- 确认后标签从列表消失。
+
+### Step 3: 提交
+
+```bash
+git add mini-program/src/pages/onboarding/tag-manage.vue
+git commit -m "feat:新增管理标签独立页面,支持左滑与 × 按钮删除"
+```
+
+---
+
+## Task 7: 端到端浏览器验证
+
+**目标:** 在浏览器 H5 模式下覆盖 spec 所有 10 条验收标准。
+
+### Step 1: 重启后端(已修改 Java 实体)
+
+```bash
+python dev-services.py restart backend-single
+```
+
+等待启动完成,查看终端无报错。
+
+### Step 2: 启动前端
+
+```bash
+python dev-services.py start mini-program
+```
+
+在浏览器中打开 `http://localhost:5284`。
+
+### Step 3: 逐条验证验收标准
+
+| # | 验收标准 | 验证方法 |
+|---|---|---|
+| 1 | 标签容器高度自适应撑开,无截断 | 添加多个标签后观察面板是否自动增高 |
+| 2 | 新增标签出现在列表最前面 | 点击"+ 添加标签"/"+ 添加兴趣",弹窗输入后观察位置 |
+| 3 | 重复输入同名标签,toast 提示"标签已存在" | 输入已存在的标签名,验证 toast |
+| 4 | 空输入、超长输入 toast 提示对应原因 | 分别提交空内容、9 字符内容,验证 toast |
+| 5 | "管理"按钮跳转管理页,列表展示全部标签 | 点击"管理",验证页面标题与列表 |
+| 6 | 管理页左滑或点 × 删除标签,二次确认后消失 | 分别测试左滑、点 ×,确认 modal 弹出 |
+| 7 | 删除已在"已选"中的标签,返回编辑资料页后已选同步移除 | 先选中某标签,管理页删除后返回观察 |
+| 8 | 保存后重新进入编辑资料页,新增标签仍在最前 | 保存→重新进入,验证顺序 |
+| 9 | 老用户首次进入编辑资料页,已选标签保留,预设标签可见 | 使用无新字段用户登录,验证库初始化 |
+| 10 | 接口失败时,页面保留原状态并 toast 真实错误 | 断网或后端停止后保存,验证 toast 真实错误 |
+
+### Step 4: 最终提交
+
+所有验收标准通过后,合并所有改动提交(如果之前未 commit):
+
+```bash
+git status
+```
+
+确认工作区干净,无遗留未提交改动。
+
+---
+
+## 执行顺序建议
+
+1. Task 1(后端)→ 重启后端
+2. Task 2(前端数据层)→ Task 3(编辑页数据初始化)→ Task 4(编辑页 UI)→ Task 5(保存 + 事件)→ Task 6(管理页)
+3. Task 7(端到端验证)
+
+Task 1 必须先完成并重启后端,否则后续前端请求会拿到旧响应结构。Task 2~6 顺序基本线性,每完成一个 task 可启动 H5 预览一次确认无回归。