Files
everything-is-suitable/docs/superpowers/specs/2026-04-27-pure-client-transformation-design.md
T
张翔 a39b4388f3 chore: 添加文档、资源与测试输出
- assets/ 静态资源
- docs/superpowers/ 技能文档
- dogfood-output/ 测试验证输出
2026-04-29 21:17:10 +08:00

375 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 纯客户端转型设计规格
> 日期: 2026-04-27
> 状态: 已批准
> 作者: Zhang Xiang
## 1. 概述
将 Everything Is Suitable 从 C/S 架构(UniApp + Java Spring Boot + PostgreSQL)转型为纯客户端 App,通过 App Store、Google Play、华为/OPPO/小米等应用商店进行买断制付费分发,完全移除服务端。
产品定位:**中国传统文化研究工具**。
## 2. 决策记录
| 决策项 | 选择 | 理由 |
|-------|------|------|
| 架构方案 | UniApp 继续演进 | 复用现有 UI,跨平台覆盖最广,风险最低 |
| 目标平台 | iOS + Android (Google Play) + 国内安卓商店 | 最大化覆盖面 |
| 付费模式 | 买断制付费下载 | 纯客户端最简变现方式 |
| 功能范围 | 第一版包含全部核心功能 | 黄历+紫微+运势全部移植 |
| 后端处理 | 完全删除 | 不再需要服务端 |
| 数据存储 | 纯本地存储 + 可选 iCloud 同步 | 无服务端,数据在设备本地 |
| CI/CD | Jenkins | 团队现有基础设施 |
## 3. 整体架构
### 3.1 转型后架构
```
┌─────────────────────────────────────────────────────┐
│ 纯客户端 App (UniApp) │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ 表现层 (Pages / Components) │ │
│ │ 黄历查询页 | 紫微排盘页 | 运势分析页 | 搜索页 │ │
│ └───────────────────┬──────────────────────────┘ │
│ │ │
│ ┌───────────────────▼──────────────────────────┐ │
│ │ 服务层 (Local Services) │ │
│ │ AlmanacService | ZiweiService | FortuneService│ │
│ │ SearchService | TemplateService │ │
│ └───────────────────┬──────────────────────────┘ │
│ │ │
│ ┌───────────────────▼──────────────────────────┐ │
│ │ 算法层 (Core Algorithms) │ │
│ │ lunar.ts | almanac.ts | ziwei.ts | fortune.ts│ │
│ │ sanFangSiZheng.ts | heavenlyStems.ts │ │
│ └───────────────────┬──────────────────────────┘ │
│ │ │
│ ┌───────────────────▼──────────────────────────┐ │
│ │ 基础设施层 (Infrastructure) │ │
│ │ LRUCache | PerformanceMonitor | Storage │ │
│ │ ExportImport | CloudSync(iCloud/GDrive) │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
### 3.2 核心模块映射 (Java → TypeScript)
| Java 模块 | TypeScript 目标 | 关键类/方法 |
|-----------|----------------|------------|
| `AlmanacServiceImpl` | `almanac.ts` | getAlmanacByDate, getAlmanacsByRange |
| `AlmanacSearchHandler` | `searchService.ts` (重写) | search, searchByKeyword |
| `ZiweiChartServiceImpl` | `ziwei.ts` | generateChart, getPalaceInfo |
| `ZiweiAlgorithmUtil` (1025行) | `ziweiAlgorithm.ts` | 排盘核心算法 |
| `SanFangSiZhengUtil` (249行) | `sanFangSiZheng.ts` | 三方四正计算 |
| `FortuneAnalysisServiceImpl` | `fortune.ts` | daily/monthly/yearly/overall |
| `DailyFortuneStrategy` (229行) | `fortuneStrategy.ts` | 日运策略 |
| `MonthlyFortuneStrategy` (404行) | `fortuneStrategy.ts` | 月运策略 |
| `LunarCalendarServiceImpl` | 已有 `lunar.ts` | 无需移植 |
| `CalendarServiceImpl` | `calendar.ts` | 日历相关 |
### 3.3 转型后目录结构
```
everything-is-suitable/
├── everything-is-suitable-uniapp/ # 唯一保留的项目
│ ├── src/
│ │ ├── algorithms/ # 新增:核心算法层
│ │ │ ├── almanac.ts
│ │ │ ├── ziwei.ts
│ │ │ ├── ziweiAlgorithm.ts
│ │ │ ├── sanFangSiZheng.ts
│ │ │ ├── fortune.ts
│ │ │ ├── fortuneStrategy.ts
│ │ │ ├── calendar.ts
│ │ │ └── types.ts # 算法层共享类型
│ │ ├── services/ # 重写:本地服务层
│ │ │ ├── almanacService.ts
│ │ │ ├── ziweiService.ts
│ │ │ ├── fortuneService.ts
│ │ │ ├── searchService.ts
│ │ │ └── templateService.ts
│ │ ├── utils/ # 保留+增强
│ │ │ ├── lunar.ts # 已有
│ │ │ ├── lruCache.ts # 已有
│ │ │ ├── searchOptimizer.ts # 已有
│ │ │ ├── performanceMonitor.ts # 已有
│ │ │ ├── storage.ts # 新增:统一本地存储
│ │ │ ├── exportImport.ts # 新增:数据导出导入
│ │ │ └── errorHandler.ts # 已有
│ │ ├── components/ # 保留
│ │ ├── pages/ # 保留+新增
│ │ │ ├── almanac-search/ # 已有
│ │ │ ├── ziwei/ # 新增:紫微排盘页
│ │ │ └── fortune/ # 新增:运势分析页
│ │ └── types/ # 保留+扩展
│ ├── package.json
│ ├── Jenkinsfile # 新增:Jenkins CI
│ └── ...
└── (其他目录全部删除)
```
## 4. 核心算法移植策略
### 4.1 移植原则
1. **算法逻辑 1:1 移植**:不重构算法,保持与 Java 代码逻辑一致,便于交叉验证
2. **类型先行**:先移植枚举和领域模型,再移植算法
3. **测试驱动**:每个算法移植后,用 Java 端的现有测试用例做交叉验证
### 4.2 移植分层顺序
**Step 1: 枚举与常量 (Enums)**
- HeavenlyStem (天干)
- EarthlyBranch (地支)
- MajorStar (主星)
- PalaceType (宫位类型)
- StarNature (星性)
- TransformationType (四化类型)
- FortuneType (运势类型)
- StarBrightness (星曜亮度)
**Step 2: 领域模型 (Domain Models)**
- BirthInfo (出生信息)
- ZiweiChart (命盘)
- Palace (宫位)
- StarInfo (星曜信息)
- DailyFortune (日运)
- MonthlyFortune (月运)
- Almanac (黄历)
- LunarDate (农历日期 - 已有)
**Step 3: 核心算法 (Algorithms)**
- ZiweiAlgorithmUtil → ziweiAlgorithm.ts (排盘核心)
- SanFangSiZhengUtil → sanFangSiZheng.ts (三方四正)
- FortuneStrategy → fortuneStrategy.ts (运势策略)
- AlmanacService → almanac.ts (黄历计算)
**Step 4: 服务层 (Services)**
- ZiweiChartService → ziweiService.ts
- FortuneAnalysisService → fortuneService.ts
- AlmanacService → almanacService.ts
- SearchService → searchService.ts (重写为本地搜索)
### 4.3 Java → TypeScript 关键差异处理
| Java 特性 | TypeScript 对应 | 注意事项 |
|-----------|----------------|---------|
| `int` 除法自动截断 | `Math.floor()` | 必须显式处理 |
| `enum` | `enum` + 辅助方法 | fromIndex/fromName 等 |
| `List<T>` | `T[]` | 数组操作 |
| `Map<K,V>` | `Map<K,V>` | 保持一致 |
| Caffeine Cache | LRUCache (已有) | 已有实现 |
| `Optional<T>` | `T \| null` | 空值处理 |
| `record` | `interface` | 不可变用 readonly |
| `switch` 表达式 | `switch` 语句 | 无表达式形式 |
### 4.4 交叉验证策略
每个算法移植后,使用 Java 端现有测试用例生成黄金数据集:
1. 从 Java 测试用例中提取输入/输出对
2. 在 TypeScript 中用相同输入执行
3. 比对输出,允许浮点误差 < 0.001
4. 100% 通过才算移植成功
## 5. 后端依赖移除与本地服务替换
### 5.1 需要删除的目录和文件
| 目标 | 处理方式 |
|------|---------|
| `everything-is-suitable-api/` | 整个目录删除 |
| `everything-is-suitable-admin/` | 整个目录删除 |
| `everything-is-suitable-test/` | 整个目录删除 |
| `docker-compose.yml` | 删除 |
| `docker-compose.*.yml` | 删除 |
| `Dockerfile*` | 删除 |
| `.woodpecker.yml` | 删除,替换为 Jenkinsfile |
| `DEPLOYMENT.md` | 删除 |
| `WOODPECKER_CI.md` | 删除 |
| `STARTUP_GUIDE.md` | 删除 |
| `config/` (根目录) | 删除 |
### 5.2 需要从 UniApp 中移除的文件
| 文件 | 替代方案 |
|------|---------|
| `src/utils/httpClient.ts` | 删除,本地服务直接调用 |
| `src/utils/tokenManager.ts` | 删除,无需认证 |
| `src/types/api.ts` | 删除,无远程 API |
| `config/` (baseURL 等) | 删除,无远程端点 |
### 5.3 本地服务替换映射
| 远程 API 调用 | 本地服务调用 |
|--------------|------------|
| `httpClient.get('/almanac/{date}')` | `almanacService.getByDate(date)` |
| `httpClient.get('/almanac/range')` | `almanacService.getByRange(start, end)` |
| `httpClient.post('/almanac/search')` | `searchService.search(request)` |
| `httpClient.post('/fortune/daily')` | `fortuneService.getDaily(birthInfo, date)` |
| `httpClient.post('/fortune/monthly')` | `fortuneService.getMonthly(birthInfo, month)` |
| `httpClient.post('/fortune/yearly')` | `fortuneService.getYearly(birthInfo, year)` |
| `httpClient.post('/fortune/overall')` | `fortuneService.getOverall(birthInfo)` |
| `httpClient.post('/ziwei/chart')` | `ziweiService.generateChart(birthInfo)` |
### 5.4 统一本地存储层
新增 `utils/storage.ts`,封装 `uni.storage`
- `get<T>(key: string): T | null`
- `set<T>(key: string, value: T): void`
- `remove(key: string): void`
- `clear(): void`
- `enableCloudSync(): void` (后续版本:iCloud/Google Drive)
- `syncToCloud(): Promise<void>` (后续版本)
- `syncFromCloud(): Promise<void>` (后续版本)
第一版仅实现纯本地存储,云同步功能在后续版本中添加。
## 6. 付费分发与商店适配
### 6.1 付费模式
买断制付费下载,一次性购买永久使用。
| 平台 | 实现方式 | 费用 |
|------|---------|------|
| App Store | Paid Application | Apple Developer $99/年 |
| Google Play | Paid App | Google Play Developer $25 一次性 |
| 华为应用市场 | 付费下载 | 华为开发者账号 |
| OPPO/小米 | 付费下载 | 各自开发者账号 |
### 6.2 内容合规:传统文化定位策略
所有文案和 UI 必须遵循"传统文化研究工具"定位。
**禁用词替换表:**
| 禁用词 | 替代词 |
|-------|-------|
| 算命 | 命理研究 |
| 预测 | 参考分析 |
| 占卜 | 传统卜筮文化研究 |
| 运势 | 时令参考 |
| 吉凶 | 传统宜忌参考 |
| 风水 | 传统堪舆文化 |
**App 描述模板:**
> 本应用是一款中国传统文化研究工具,基于传统历法学、紫微斗数学等传统文化体系,提供黄历查询、命盘排布、时令参考等功能。所有内容仅供传统文化学术研究参考,不构成任何决策建议。
### 6.3 各平台审核要点
| 平台 | 关键审核点 | 应对策略 |
|------|-----------|---------|
| App Store | 2.5.2 功能完整 | 确保离线可用、无空白页 |
| App Store | 命理类需标注"娱乐" | 描述中标注"传统文化研究,仅供学术参考" |
| Google Play | 无特殊命理限制 | 正常提交 |
| 华为 | 对"迷信"内容敏感 | 强调"传统文化""学术研究"定位 |
| OPPO/小米 | 类似华为 | 同上 + 提供免责声明 |
## 7. 测试策略与质量保障
### 7.1 分层测试策略
```
┌─────────────────────────────────────┐
│ E2E 测试 (Playwright) │ 关键用户流程
├─────────────────────────────────────┤
│ 集成测试 (Vitest) │ 服务层 + 算法层联动
├─────────────────────────────────────┤
│ 单元测试 (Vitest) │ 算法正确性
├─────────────────────────────────────┤
│ 交叉验证测试 (Vitest) │ Java vs TS 结果比对
└─────────────────────────────────────┘
```
### 7.2 交叉验证测试
从 Java 端测试用例中提取黄金数据,确保 TypeScript 移植结果与 Java 完全一致。
测试用例来源:
- `ZiweiAlgorithmUtilTest.java` (494行)
- `ComprehensiveAlmanacServiceTest.java`
- `DailyFortuneTest.java` (334行)
- `AlmanacSearchHandlerTest.java` (490行)
### 7.3 质量门禁
| 指标 | 标准 |
|------|------|
| 算法层单元测试覆盖率 | >= 90% |
| 服务层单元测试覆盖率 | >= 80% |
| 交叉验证通过率 | 100% |
| E2E 关键路径通过率 | 100% |
| Lint 错误 | 0 |
| TypeScript 严格模式 | 开启 |
## 8. CI/CD (Jenkins)
```groovy
pipeline {
agent any
environment {
NODE_VERSION = '20'
PROJECT_DIR = 'everything-is-suitable-uniapp'
}
stages {
stage('Install') {
steps {
dir(env.PROJECT_DIR) { sh 'npm ci' }
}
}
stage('Lint') {
steps {
dir(env.PROJECT_DIR) { sh 'npm run lint' }
}
}
stage('Unit Test') {
steps {
dir(env.PROJECT_DIR) { sh 'npm run test' }
}
post {
always { junit "${env.PROJECT_DIR}/test-results/*.xml" }
}
}
stage('Build H5') {
steps {
dir(env.PROJECT_DIR) { sh 'npm run build:h5' }
}
}
stage('Build Android') {
when { branch 'main' }
steps {
dir(env.PROJECT_DIR) { sh 'npm run build:app-android' }
}
}
stage('Build iOS') {
when { branch 'main' }
steps {
dir(env.PROJECT_DIR) { sh 'npm run build:app-ios' }
}
}
}
}
```
## 9. ICP 备案说明
纯客户端 App(无后端服务)不需要 ICP 备案。这不是"绕过",而是法律上的"不适用"——ICP 备案规制的是"互联网信息服务提供者",纯客户端 App 没有服务端,不构成信息服务提供者。
国内应用商店(华为/OPPO/小米)可能要求声明"本应用为纯客户端应用,无后端服务,不涉及互联网信息服务"。
## 10. 风险与缓解
| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| 算法移植正确性 | 高 | 交叉验证测试 + 黄金数据集 |
| 命理类内容审核 | 高 | 传统文化定位 + 合规文案 |
| App 体积过大 | 中 | 按需加载 + 数据压缩 |
| 算法性能瓶颈 | 低 | Web Worker 隔离 + LRUCache |
| 越狱盗版 | 低 | 可接受风险,商店内购保护 |