chore: 批量完成2026-05-24版本迭代更新
本次提交涵盖多项功能优化与重构: 1. 重构pro_image_editor依赖为官方托管版本,移除本地包引用 2. 拆分角色表情枚举至独立文件,优化代码复用性 3. 新增壁纸收藏、预加载、健康检测服务与本地存储支持 4. 完善API响应类型安全检查与排行榜服务能力 5. 新增应用锁设置路由与页面支持 6. 优化路由跳转使用常量路径替代硬编码字符串 7. 新增阅读报告分享功能与设置变更日志服务 8. 修复多处类型转换与空指针风险问题 9. 调整API超时时间优化网络请求表现 10. 统一文件头格式与部分UI组件样式
This commit is contained in:
1148
docs/architecture-refactor-spec.md
Normal file
1148
docs/architecture-refactor-spec.md
Normal file
File diff suppressed because it is too large
Load Diff
143
docs/superpowers/plans/2026-05-24-architecture-refactor.md
Normal file
143
docs/superpowers/plans/2026-05-24-architecture-refactor.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# 架构重构与功能增强 实施计划
|
||||
|
||||
> **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:** 修复9项架构不足:动态圆角生效、角色精灵主题化、枚举位置迁移、引导页解耦、设置Provider简化、互斥锁超时、渐变背景优化、个性化页增强、协议页增强
|
||||
|
||||
**Architecture:** 逐项独立修改,每项完成后验证编译通过。动态圆角采用"先写测试→再批量替换"策略确保安全。
|
||||
|
||||
**Tech Stack:** Flutter/Dart, Riverpod, CustomPainter, ThemeExtension
|
||||
|
||||
---
|
||||
|
||||
## Task 1: CharacterExpression 枚举迁移(独立,无依赖)
|
||||
|
||||
**Files:**
|
||||
- Create: `lib/core/constants/character_expression.dart`
|
||||
- Modify: `lib/shared/widgets/animation/appbar_character_sprite.dart`
|
||||
- Modify: `lib/features/onboarding/presentation/onboarding_page.dart`
|
||||
- Modify: `lib/features/home/presentation/home_page.dart`
|
||||
- Modify: `lib/features/home/presentation/home_refresh_indicator.dart`
|
||||
- Modify: `lib/shared/widgets/animation/sprite_loading_indicator.dart`
|
||||
|
||||
- [ ] **Step 1:** 创建 `lib/core/constants/character_expression.dart`,将枚举从 `appbar_character_sprite.dart` 提取出来
|
||||
- [ ] **Step 2:** 修改 `appbar_character_sprite.dart`,删除枚举定义,改为 `import`
|
||||
- [ ] **Step 3:** 修改其他4个引用文件,将 import 路径从 `appbar_character_sprite.dart` 改为 `character_expression.dart`
|
||||
- [ ] **Step 4:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 2: EffectMutex 超时机制(独立)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/core/services/performance/effect_mutex.dart`
|
||||
|
||||
- [ ] **Step 1:** 给 `acquire()` 添加 `Duration? timeout` 参数
|
||||
- [ ] **Step 2:** 当 timeout 不为 null 时,用 `Future.any` + `Future.delayed` 实现超时取消
|
||||
- [ ] **Step 3:** 超时后从 `_pending` 列表移除,complete 一个异常或 null token
|
||||
- [ ] **Step 4:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Onboarding 完成回调解耦(独立)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/features/onboarding/providers/onboarding_provider.dart`
|
||||
|
||||
- [ ] **Step 1:** 在 `completeOnboarding()` 中,将直接调用 `generalSettingsProvider.notifier` 的3行替换为:直接写 KV 存储(与 generalSettingsProvider 使用相同的 key),让 generalSettingsProvider 在下次 build 时自动从 KV 读取
|
||||
- [ ] **Step 2:** 确认 KV key 一致性(`general_shake_to_switch` / `sfx_enabled` / `general_shader_background`)
|
||||
- [ ] **Step 3:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 4: 角色精灵硬编码颜色主题化(独立,大改动)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/shared/widgets/animation/appbar_character_sprite.dart`
|
||||
- Modify: `lib/core/theme/app_theme.dart`(新增角色配色令牌)
|
||||
|
||||
- [ ] **Step 1:** 在 `AppThemeExtension` 中新增角色配色字段:`characterSkinLight`/`characterSkinMid`/`characterSkinDark`/`characterEarInner`/`characterNose`/`characterHair`/`characterOutline`
|
||||
- [ ] **Step 2:** 在 `_lightExtension`/`_darkExtension`/`_amoledExtension` 中定义浅色/深色/AMOLED三套角色配色
|
||||
- [ ] **Step 3:** 修改 `_AppBarCharacterPainter`,将所有硬编码颜色替换为主题令牌参数
|
||||
- [ ] **Step 4:** 修改 `AppBarCharacterSprite.build()` 传递主题颜色到 Painter
|
||||
- [ ] **Step 5:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 5: 动态圆角批量替换(高风险,需测试先行)
|
||||
|
||||
**Files:**
|
||||
- Modify: 100+ 文件,602处 `AppRadius.xxxBorder` → `AppRadius.of(context).xxxBorder`
|
||||
- Create: `test/core/theme/app_radius_test.dart`
|
||||
|
||||
- [ ] **Step 1:** 编写测试文件 `app_radius_test.dart`,验证 `AppRadiusData._fromId` 的4种风格返回正确值
|
||||
- [ ] **Step 2:** 运行测试确认通过
|
||||
- [ ] **Step 3:** 用脚本批量替换:`AppRadius.xsBorder` → `AppRadius.of(context).xsBorder` 等6种模式
|
||||
- [ ] **Step 4:** 手动检查替换结果,修复无 context 的场景(如 Provider/常量定义处)
|
||||
- [ ] **Step 5:** 运行 `flutter analyze` 验证全项目无错误
|
||||
- [ ] **Step 6:** 运行测试确认通过
|
||||
|
||||
---
|
||||
|
||||
## Task 6: general_settings_provider.dart 简化(独立)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/features/mine/settings/providers/general_settings_provider.dart`
|
||||
|
||||
- [ ] **Step 1:** 提取通用 `_setField<T>` 方法,封装"更新state + 写KV"模式
|
||||
- [ ] **Step 2:** 将所有 setter 方法改为调用 `_setField`
|
||||
- [ ] **Step 3:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Mesh渐变背景优化(独立)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/features/onboarding/presentation/widgets/mesh_gradient_background.dart`
|
||||
|
||||
- [ ] **Step 1:** 预计算色块路径:在 `_initBlobs` 中生成 `List<Offset>` 路径点,动画时只做插值
|
||||
- [ ] **Step 2:** 扩展 `_isLowEnd` 判断:iOS 检测 `Platform.isIOS` + 低内存设备列表;Android 检测 `DeviceInfoPlugin` 低 RAM
|
||||
- [ ] **Step 3:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 8: 个性化页增强(依赖 Task 4 角色主题化)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/features/onboarding/presentation/pages/personalization_page.dart`
|
||||
|
||||
- [ ] **Step 1:** 预览卡片增强:实时反映主题模式(浅/深色切换时卡片背景变化)和强调色变化
|
||||
- [ ] **Step 2:** 增加圆角风格选择(3个选项:紧凑/标准/圆润),使用 CupertinoIcons
|
||||
- [ ] **Step 3:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## Task 9: 协议页章节导航 + 权限分组(独立)
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/features/onboarding/presentation/pages/agreement_page.dart`
|
||||
- Modify: `lib/core/services/auth/permission_service.dart`(添加分组字段)
|
||||
|
||||
- [ ] **Step 1:** 给 `AppPermission` 枚举添加 `group` 字段(必要权限/可选权限/系统权限)
|
||||
- [ ] **Step 2:** 修改权限列表展示,按分组显示,每组有标题
|
||||
- [ ] **Step 3:** 协议内容添加章节锚点导航(顶部章节标签)
|
||||
- [ ] **Step 4:** 运行 `flutter analyze` 验证
|
||||
|
||||
---
|
||||
|
||||
## 执行顺序
|
||||
|
||||
```
|
||||
Task 1 (枚举迁移) ─── 独立,可先执行
|
||||
Task 2 (互斥锁超时) ── 独立,可先执行
|
||||
Task 3 (引导页解耦) ── 独立,可先执行
|
||||
Task 4 (角色主题化) ── 独立,但 Task 8 依赖它
|
||||
Task 5 (动态圆角) ──── 高风险,需测试先行
|
||||
Task 6 (设置简化) ──── 独立
|
||||
Task 7 (渐变优化) ──── 独立
|
||||
Task 8 (个性化增强) ── 依赖 Task 4
|
||||
Task 9 (协议页增强) ── 独立
|
||||
```
|
||||
|
||||
可并行:Task 1/2/3/6/7/9 可同时执行
|
||||
串行:Task 4 → Task 8;Task 5 需单独执行(影响面太大)
|
||||
@@ -4,7 +4,7 @@
|
||||
* @author AI Coder
|
||||
* @date 2026-05-14
|
||||
* @desc 赛季排行榜: 赛季列表/排行榜/我的排名/领取奖励
|
||||
* @update v14.103.0 新增_ensureActiveSeason自动创建周赛季,leaderboard和myRank无活跃赛季时自动创建
|
||||
* @update v14.104.0 新增install方法自动建表;install加入noNeedLogin
|
||||
*/
|
||||
|
||||
namespace app\api\controller;
|
||||
@@ -14,7 +14,7 @@ use think\Db;
|
||||
|
||||
class Rank extends Api
|
||||
{
|
||||
protected $noNeedLogin = ['seasons', 'leaderboard'];
|
||||
protected $noNeedLogin = ['seasons', 'leaderboard', 'install'];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
protected $rateLimit = [
|
||||
@@ -219,6 +219,54 @@ class Rank extends Api
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name 安装排行榜表
|
||||
* @desc 自动创建rank_season和rank_record表,并激活当前赛季
|
||||
*/
|
||||
public function install()
|
||||
{
|
||||
$sql1 = "CREATE TABLE IF NOT EXISTS `tool_rank_season` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL DEFAULT '',
|
||||
`type` enum('weekly','monthly') NOT NULL DEFAULT 'weekly',
|
||||
`start_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`end_time` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`status` enum('active','settled','cancelled') NOT NULL DEFAULT 'active',
|
||||
`rewards` text DEFAULT NULL,
|
||||
`createtime` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`updatetime` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||||
|
||||
$sql2 = "CREATE TABLE IF NOT EXISTS `tool_rank_record` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`season_id` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`rank_type` enum('exp','signin','badge','score') NOT NULL DEFAULT 'exp',
|
||||
`user_id` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`rank` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`value` int(11) NOT NULL DEFAULT 0,
|
||||
`reward_claimed` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`createtime` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
`updatetime` int(11) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_season_type` (`season_id`, `rank_type`),
|
||||
KEY `idx_user` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
|
||||
|
||||
try {
|
||||
Db::execute($sql1);
|
||||
Db::execute($sql2);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('建表失败: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$currentSeason = $this->_ensureActiveSeason();
|
||||
$this->success('安装成功', [
|
||||
'tables' => ['tool_rank_season', 'tool_rank_record'],
|
||||
'active_season' => $currentSeason,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name 实时计算排行(前N名)
|
||||
*/
|
||||
|
||||
1117
docs/toolsapi/docs/API_USER_OPERATIONS_DOC.md
Normal file
1117
docs/toolsapi/docs/API_USER_OPERATIONS_DOC.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user