{
"phase": {
"id": "phase-5",
"name": "新增页面与功能",
"description": "实现紫微斗数排盘页面、运势分析页面、数据导出/导入功能",
"status": "completed",
"completedAt": "2026-04-28T03:57:24+08:00",
"dependencies": ["phase-4"],
"tasks": [
{
"id": "5.1",
"name": "实现紫微斗数排盘页面",
"description": "创建紫微斗数排盘页面,包含出生信息输入、排盘展示、三方四正分析",
"files": {
"create": ["src/pages/ziwei/index.vue"],
"test": ["src/pages/ziwei/__tests__/index.test.ts"]
},
"steps": [
{
"id": "5.1.1",
"action": "write_test",
"description": "编写紫微页面组件测试",
"code": "import { describe, it, expect } from 'vitest'\nimport { mount } from '@vue/test-utils'\nimport ZiweiPage from '../index.vue'\n\ndescribe('ZiweiPage', () => {\n it('应包含出生信息输入表单', () => {\n const wrapper = mount(ZiweiPage)\n expect(wrapper.find('[data-test=\"birth-form\"]').exists()).toBe(true)\n })\n\n it('应包含排盘按钮', () => {\n const wrapper = mount(ZiweiPage)\n expect(wrapper.find('[data-test=\"generate-btn\"]').exists()).toBe(true)\n })\n\n it('点击排盘按钮应触发计算', async () => {\n const wrapper = mount(ZiweiPage)\n await wrapper.find('[data-test=\"generate-btn\"]').trigger('click')\n expect(wrapper.vm.isCalculating).toBeDefined()\n })\n})",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/ziwei/__tests__/index.test.ts",
"expectedResult": "FAIL - 模块不存在"
},
{
"id": "5.1.2",
"action": "run_test_verify_fail",
"description": "运行测试确认失败",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/ziwei/__tests__/index.test.ts",
"expectedResult": "FAIL"
},
{
"id": "5.1.3",
"action": "write_implementation",
"description": "实现紫微斗数排盘页面",
"code": "\n \n \n 出生信息\n \n 出生日期\n \n {{ birthDate || '请选择' }}\n \n \n \n 出生时辰\n \n {{ hourOptions[hourIndex] }}\n \n \n \n 性别\n \n 男\n 女\n \n \n \n\n \n \n \n\n \n 紫微斗数盘\n \n \n {{ getPalaceName(palace.palaceType) }}\n {{ getBranchName(palace.earthlyBranch) }}\n {{ palace.score }}分\n \n \n {{ getStarName(star.star) }}\n \n \n \n \n \n\n \n 三方四正分析\n 三方平均分:{{ chart.sanFangSiZheng.sanFangScore }}\n 四正平均分:{{ chart.sanFangSiZheng.siZhengScore }}\n \n \n\n\n",
"sourceRef": "设计规格 Section 5.1 紫微斗数排盘页面"
},
{
"id": "5.1.4",
"action": "run_test_verify_pass",
"description": "运行测试确认通过",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/ziwei/__tests__/index.test.ts",
"expectedResult": "PASS - 所有紫微页面测试通过"
},
{
"id": "5.1.5",
"action": "register_page_route",
"description": "在 pages.json 中注册紫微页面路由",
"targetFile": "src/pages.json",
"addEntry": { "path": "pages/ziwei/index", "style": { "navigationBarTitleText": "紫微斗数" } }
},
{
"id": "5.1.6",
"action": "commit",
"message": "feat(pages): 实现紫微斗数排盘页面 - 出生信息输入/排盘展示/三方四正"
}
]
},
{
"id": "5.2",
"name": "实现运势分析页面",
"description": "创建运势分析页面,包含日运/月运/年运展示",
"files": {
"create": ["src/pages/fortune/index.vue"],
"test": ["src/pages/fortune/__tests__/index.test.ts"]
},
"steps": [
{
"id": "5.2.1",
"action": "write_test",
"description": "编写运势页面组件测试",
"code": "import { describe, it, expect } from 'vitest'\nimport { mount } from '@vue/test-utils'\nimport FortunePage from '../index.vue'\n\ndescribe('FortunePage', () => {\n it('应包含运势类型切换', () => {\n const wrapper = mount(FortunePage)\n expect(wrapper.find('[data-test=\"fortune-tabs\"]').exists()).toBe(true)\n })\n\n it('默认应显示日运', () => {\n const wrapper = mount(FortunePage)\n expect(wrapper.vm.activeTab).toBe('daily')\n })\n})",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/fortune/__tests__/index.test.ts",
"expectedResult": "FAIL - 模块不存在"
},
{
"id": "5.2.2",
"action": "run_test_verify_fail",
"description": "运行测试确认失败",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/fortune/__tests__/index.test.ts",
"expectedResult": "FAIL"
},
{
"id": "5.2.3",
"action": "write_implementation",
"description": "实现运势分析页面",
"code": "\n \n \n 日运\n 月运\n \n\n \n \n {{ selectedDate || '选择日期' }}\n \n \n 综合运势:{{ dailyFortune.overallScore }}分\n {{ dailyFortune.overallLuck }}\n \n 事业:{{ dailyFortune.careerAdvice }}\n 财运:{{ dailyFortune.wealthAdvice }}\n 感情:{{ dailyFortune.relationshipAdvice }}\n 健康:{{ dailyFortune.healthAdvice }}\n \n \n 幸运色:{{ dailyFortune.luckyColor }}\n 幸运数字:{{ dailyFortune.luckyNumber }}\n 幸运方位:{{ dailyFortune.luckyDirection }}\n \n \n \n\n \n \n {{ selectedMonth || '选择月份' }}\n \n \n 综合运势:{{ monthlyFortune.overallScore }}分\n {{ monthlyFortune.overallLuck }}\n \n \n \n\n\n",
"sourceRef": "设计规格 Section 5.2 运势分析页面"
},
{
"id": "5.2.4",
"action": "run_test_verify_pass",
"description": "运行测试确认通过",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/pages/fortune/__tests__/index.test.ts",
"expectedResult": "PASS - 所有运势页面测试通过"
},
{
"id": "5.2.5",
"action": "register_page_route",
"description": "在 pages.json 中注册运势页面路由",
"targetFile": "src/pages.json",
"addEntry": { "path": "pages/fortune/index", "style": { "navigationBarTitleText": "运势分析" } }
},
{
"id": "5.2.6",
"action": "commit",
"message": "feat(pages): 实现运势分析页面 - 日运/月运展示"
}
]
},
{
"id": "5.3",
"name": "实现数据导出/导入功能",
"description": "创建 exportImport.ts 工具,支持用户数据导出为 JSON 文件和从 JSON 文件导入恢复",
"files": {
"create": ["src/utils/exportImport.ts"],
"test": ["src/utils/__tests__/exportImport.test.ts"]
},
"steps": [
{
"id": "5.3.1",
"action": "write_test",
"description": "编写导出/导入测试",
"code": "import { describe, it, expect, vi } from 'vitest'\nimport { exportData, importData, validateImportData } from '../exportImport'\n\nvi.stubGlobal('uni', {\n getStorageSync: vi.fn(),\n setStorageSync: vi.fn(),\n})\n\ndescribe('exportData', () => {\n it('应导出包含版本信息的JSON', () => {\n const result = exportData()\n const parsed = JSON.parse(result)\n expect(parsed.version).toBe('1.0.0')\n expect(parsed.exportDate).toBeTruthy()\n expect(parsed.data).toBeDefined()\n })\n})\n\ndescribe('validateImportData', () => {\n it('有效数据应返回true', () => {\n const validJson = JSON.stringify({ version: '1.0.0', exportDate: '2026-04-27', data: {} })\n expect(validateImportData(validJson)).toBe(true)\n })\n\n it('缺少版本信息应返回false', () => {\n const invalidJson = JSON.stringify({ data: {} })\n expect(validateImportData(invalidJson)).toBe(false)\n })\n\n it('无效JSON应返回false', () => {\n expect(validateImportData('not json')).toBe(false)\n })\n})\n\ndescribe('importData', () => {\n it('有效数据应成功导入', () => {\n const validJson = JSON.stringify({ version: '1.0.0', exportDate: '2026-04-27', data: { test_key: 'test_value' } })\n const result = importData(validJson)\n expect(result).toBe(true)\n })\n\n it('无效数据应返回false', () => {\n const result = importData('invalid')\n expect(result).toBe(false)\n })\n})",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/utils/__tests__/exportImport.test.ts",
"expectedResult": "FAIL - 模块不存在"
},
{
"id": "5.3.2",
"action": "run_test_verify_fail",
"description": "运行测试确认失败",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/utils/__tests__/exportImport.test.ts",
"expectedResult": "FAIL"
},
{
"id": "5.3.3",
"action": "write_implementation",
"description": "实现数据导出/导入功能",
"code": "import { storage } from './storage'\n\nconst EXPORT_VERSION = '1.0.0'\n\nexport interface ExportData {\n version: string\n exportDate: string\n data: Record\n}\n\nexport function exportData(): string {\n const data: ExportData = {\n version: EXPORT_VERSION,\n exportDate: new Date().toISOString().split('T')[0],\n data: {},\n }\n\n const storageKeys = [\n 'ziwei_charts',\n 'search_history',\n 'search_templates',\n ]\n\n for (const key of storageKeys) {\n const value = storage.get(key)\n if (value !== null) {\n data.data[key] = value\n }\n }\n\n return JSON.stringify(data, null, 2)\n}\n\nexport function validateImportData(jsonStr: string): boolean {\n try {\n const parsed = JSON.parse(jsonStr) as ExportData\n if (!parsed.version || !parsed.data) return false\n return true\n } catch {\n return false\n }\n}\n\nexport function importData(jsonStr: string): boolean {\n if (!validateImportData(jsonStr)) return false\n\n try {\n const parsed = JSON.parse(jsonStr) as ExportData\n for (const [key, value] of Object.entries(parsed.data)) {\n storage.set(key, value)\n }\n return true\n } catch {\n return false\n }\n}",
"sourceRef": "设计规格 Section 5.4 数据导出/导入"
},
{
"id": "5.3.4",
"action": "run_test_verify_pass",
"description": "运行测试确认通过",
"runCommand": "cd everything-is-suitable-uniapp && npx vitest run src/utils/__tests__/exportImport.test.ts",
"expectedResult": "PASS - 所有导出/导入测试通过"
},
{
"id": "5.3.5",
"action": "commit",
"message": "feat(utils): 实现数据导出/导入功能 - JSON格式导出导入"
}
]
}
]
}
}