feat: 小程序端 UI 优化与纯客户端化改造

- 移除微信订阅推送功能(云函数/订阅管理页),回归纯客户端零后端架构
- 新增今日黄历默认展示卡片 TodayAlmanacCard(9 语言翻译)
- i18n 修复:启用 globalInjection 修复 $t 未注入,插值消息全部改为
  Messages Functions 适配小程序端(63 处)
- 修复底部导航切换失效与运势页数据不刷新
- 统一设计令牌(深褐主色 + 印红强调色),组件 UI 规范重构
- 图标 iconfont 化(FontAwesome 子集化,修复 Android 豆腐块)
- 新增 postcss-px2rpx 机型自适应(仅 mp-weixin 构建生效)
- 新增 5 个用户旅程 E2E 测试(31 用例)与验收报告
- 补充微信小程序项目配置(appid)
This commit is contained in:
2026-08-28 07:51:02 +08:00
parent de11398720
commit 810081ac0a
72 changed files with 2242 additions and 1468 deletions
@@ -0,0 +1,127 @@
import { test, expect } from '@playwright/test'
import { setDateInput, gotoPage } from './helpers'
/**
* 用户旅程 J-FORTUNE(Common):运势分析完整旅程
*
* 用户目标:查看自己(已排盘)在指定日期的运势走势
*
* 旅程步骤:
* 1. 前置:在排盘页完成排盘(结果自动持久化到本地)
* 2. 导航到运势页(读取排盘数据)
* 3. 查看日运(总分、四维建议、幸运要素)
* 4. 切换日期 → 运势随日期更新
* 5. 切换月运标签 → 月运区域与月份选择器可用
*
* 错误恢复场景:
* E1. 无排盘数据时进入运势页 → 显示"请先排盘"提示
*/
test.describe('旅程 J-FORTUNE:运势分析完整旅程', () => {
test.describe.configure({ mode: 'serial' })
/** 前置:完成排盘(结果持久化到 eis_ziwei_chart) */
async function prepareChart(page: import('@playwright/test').Page): Promise<void> {
await gotoPage(page, '/pages/ziwei/index')
await setDateInput(page, 'input[type="date"]', '1990-01-01')
await page.locator('[data-test="generate-btn"]').click()
await page.waitForTimeout(1500)
}
test('STEP 1: 前置排盘(结果持久化到本地)', async ({ page }) => {
await prepareChart(page)
await expect(page.locator('.chart-result')).toBeVisible()
// 验证排盘结果已持久化到 localStorage
const stored = await page.evaluate(() => localStorage.getItem('eis_ziwei_chart'))
expect(stored).toBeTruthy()
const chart = JSON.parse(stored as string)
expect(chart.palaces.length).toBe(12)
})
test('STEP 2: 排盘后导航到运势页(读取排盘数据)', async ({ page }) => {
await prepareChart(page)
await gotoPage(page, '/pages/fortune/index')
expect(page.url()).toContain('/#/pages/fortune/index')
await expect(page.locator('[data-test="fortune-tabs"]')).toBeVisible()
// 排盘数据已加载(运势页正常渲染)
await expect(page.locator('.daily-fortune')).toBeVisible()
})
test('STEP 3: 查看当日运势(总分/等级/建议/幸运要素)', async ({ page }) => {
await prepareChart(page)
await gotoPage(page, '/pages/fortune/index')
// 切换日期触发日运生成(进入页面默认不自动生成;页面仅一个 date input)
await setDateInput(page, 'input[type="date"]', '2026-08-20')
await page.waitForTimeout(800)
// 日运结果可见
await expect(page.locator('.fortune-result')).toBeVisible()
const overallScore = await page.locator('.overall-score').textContent()
expect(overallScore && overallScore.length).toBeGreaterThan(0)
// 四维建议
const adviceCount = await page.locator('.advice').count()
expect(adviceCount).toBeGreaterThanOrEqual(4)
// 幸运要素
const luckyCount = await page.locator('.lucky').count()
expect(luckyCount).toBeGreaterThanOrEqual(3)
})
test('STEP 4: 切换日期 → 运势更新', async ({ page }) => {
await prepareChart(page)
await gotoPage(page, '/pages/fortune/index')
// 先触发一次日期变更生成日运
await setDateInput(page, 'input[type="date"]', '2026-08-20')
await page.waitForTimeout(800)
const scoreBefore = await page.locator('.overall-score').textContent()
// 切换日期到另一天,运势重新生成
await setDateInput(page, 'input[type="date"]', '2026-08-21')
await page.waitForTimeout(800)
const scoreAfter = await page.locator('.overall-score').textContent()
expect(scoreAfter).toBeTruthy()
})
test('STEP 5: 切换月运标签 → 查看月运', async ({ page }) => {
await prepareChart(page)
await gotoPage(page, '/pages/fortune/index')
// 切换到月运
await page.locator('.tab').nth(1).click()
await page.waitForTimeout(1000)
await expect(page.locator('.monthly-fortune')).toBeVisible()
// 月运日期选择器显示当前月份(YYYY-MM)
const monthDisplay = await page.locator('.monthly-fortune .date-picker').textContent()
expect(monthDisplay).toMatch(/^\d{4}-\d{2}$/)
// 月运月份选择器可打开(H5 端为 3D 滚轮,精确选月由小程序原生 picker 提供)
await page.locator('.monthly-fortune .date-picker').click()
await page.waitForTimeout(600)
const pickerOpened = await page.evaluate(() => {
return document.querySelectorAll('.uni-picker-item').length > 0
})
expect(pickerOpened).toBe(true)
await page.locator('.uni-picker-action-cancel').click({ force: true, timeout: 3000 }).catch(() => {})
await page.waitForTimeout(300)
})
test('E1: 无排盘数据时进入运势页 → 显示提示', async ({ page }) => {
// 清空本地排盘数据
await gotoPage(page, '/pages/fortune/index')
await page.evaluate(() => localStorage.removeItem('eis_ziwei_chart'))
await page.reload()
await page.waitForLoadState('networkidle')
await page.waitForTimeout(1000)
// 无排盘时显示提示,且无运势结果
await expect(page.locator('.no-chart-hint')).toBeVisible()
const resultVisible = await page.locator('.fortune-result').isVisible().catch(() => false)
expect(resultVisible).toBe(false)
})
})