Files
xianyan/CHANGELOG.md
Developer 283950ea07 chore: 批量代码优化与功能迭代更新
本次提交包含大量代码优化、功能新增与服务端配置更新:
1. 修复分析报告统计数据,调整CMake策略设置
2. 优化APP权限配置、编辑器与聊天界面组件
3. 更新依赖库版本与pubspec配置
4. 新增文件传输服务端、信令服务器相关配置与脚本
5. 完善用户注销功能与数据库迁移脚本
6. 优化多处动画效果、代码风格与日志输出
7. 新增多种调试与部署脚本,修复已知BUG
2026-05-12 06:28:04 +08:00

51 KiB
Raw Blame History

Changelog

所有重要变更均记录于此文件。格式基于 Keep a Changelog


[4.2.1] - 2026-05-12

🔧 重构 — TransferNotifier 拆分为多 Handler文件行数优化

问题: transfer_notifier.dart 达到 1375 行,超出 800 行限制,需拆分

  1. 新增 transfer_message_handler.dart (~300行):

    • 消息发送: sendTextMessage, sendVoiceMessage
    • 送达回执: updateMessageDeliveryStatus, markMessageAsRead
    • 系统消息: addSystemMessage, addFileMessage
    • 内部辅助: _retrySendText, _buildSendFailureMessage
  2. 新增 transfer_cloud_handler.dart (~230行):

    • 云端暂存: uploadToCloudCache, checkAndDownloadPendingCache
    • 下载管理: downloadFromCloudCache, downloadAllPendingCache
    • 通知处理: _notifyCloudCache, handleCloudCacheNotify
  3. 重构 transfer_notifier.dart (~955行 → 核心逻辑):

    • 保留: 初始化、sendFiles、任务管理、连接管理、数据加载
    • 新增 _messageHandler_cloudHandler 委托
    • 所有 _addSystemMessage/_addFileMessage 调用改为委托 _messageHandler
    • 所有云端暂存方法委托 _cloudHandler
    • Handler 创建顺序: messageHandler → cloudHandler → pairingHandler → signalingHandler
    • 依赖注入: 通过回调函数解决循环依赖(如 sendFiles 回调)
  4. 导出更新:

    • providers.darttransfer_provider.dart 新增 handler 导出
  5. 修复:

    • 移除 voice_message_data.dart 重复导入(已由 models.dart 提供)
    • 移除 signaling_service.dart 未使用导入
    • 修复 user?.id?.toString() 中多余的 null-aware 操作符

[4.2.0] - 2026-05-12

修复 — 注销删号接口服务端实现(从404到100%通过)

问题: 注销删号接口(requestDeletion/deletionStatus/cancelDeletion)在API文档中已定义但服务端未实现返回404

  1. 服务端: UserSecurity.php新增注销方法docs/toolsapi/application/api/controller/UserSecurity.php:

    • requestDeletion() — 申请账号注销,需回执验证(action=delete_account)3天审核期
    • deletionStatus() — 查询当前用户注销申请状态(待审核/已通过/已拒绝/已自动注销)
    • cancelDeletion() — 取消待审核的注销申请
    • 新增频率限制: requestDeletion(5次/小时), cancelDeletion(10次/小时), deletionStatus(60次/分钟)
    • 注销申请写入 fa_user_deletion设置3天后自动注销时间
    • 重复申请拦截: 已有待审核申请时返回错误+倒计时信息
    • 注销状态查询返回: has_pending/status/status_text/reason/countdown/createtime_text
  2. 服务端: User.php转发层更新docs/toolsapi/application/api/controller/User.php:

    • 新增 requestDeletion()/deletionStatus()/cancelDeletion() 转发方法
    • 旧路径 /api/user/requestDeletion 自动转发到新路径
  3. 服务端: route.php路由更新docs/toolsapi/application/route.php:

    • 新增3条路由: api/user_security/requestDeletion, deletionStatus, cancelDeletion
  4. 数据库: user_deletion表创建migrate_v9_2.sql:

    • fa_user_deletion 表: id/user_id/username/reason/status/admin_id/admin_remark/auto_delete_time/createtime/updatetime/deletetime
    • 索引: idx_user_id, idx_status, idx_auto_delete
    • 已在服务器执行,表创建成功
  5. 部署脚本docs/toolsapi/scripts/:

    • deploy_user_deletion.py: SFTP上传PHP文件+SQL迁移+缓存清理+接口检测
    • run_migrate_v9_2.py: 独立SQL迁移执行脚本
    • test_user_deletion_api.py: 10项接口自动化测试(全部通过通过率100%)
  6. API文档更新:

    • API_USER_SECURITY_DOC.md: 版本v9.2.0, 更新代码架构/接口对照表
    • API_ADMIN_DOC.md: 新增user_deletion表结构文档
    • API_APP_FEATURE_GUIDE.md: 版本v9.2.0
  7. 测试结果:

    • 登录获取Token
    • 查询注销状态(无申请)
    • 无回执申请注销(应失败)
    • 带回执申请注销
    • 重复申请注销(应失败)
    • 查询注销状态(有申请)
    • 取消注销申请
    • 取消后查询状态
    • 无申请时取消(应失败)
    • 旧路径兼容测试
    • 验证结果: 10/10 通过通过率100%

修复 — 登录时ip_city为空问题

问题: 登录时ip_city/ip_range参数写入tool_user_device表但设备A的ip_city为空(登录接口未自动查询IP归属地)

  1. 服务端: UserSecurity.php新增queryIpLocation方法docs/toolsapi/application/api/controller/UserSecurity.php:
    • queryIpLocation($ip) — 使用纯真IP数据库(qqwry.dat)查询IP归属地返回city和fw
    • recordLoginDevice() 方法改造: 登录时自动调用queryIpLocation填充ip_city/ip_range
    • 新建设备记录和更新已有设备记录时均写入ip_city/ip_range
    • 已部署到服务器并验证: 登录后ip_city自动填充(如"云南省昆明市 电信")

🆕 新增 — 注销删除账号独立页面

  1. Flutter: account_deletion_page.dartlib/features/settings/presentation/account_deletion_page.dart:

    • 注销申请状态查询(自动加载deletionStatus接口)
    • 待审核状态展示: 状态徽章、注销原因、申请时间、自动注销倒计时
    • 申请注销流程: ⚠️危险警告弹窗 → 🔒安全验证(输入DELETE) → 提交申请
    • 取消注销功能: 确认弹窗 → 调用cancelDeletion接口
    • 历史注销记录展示
    • 下拉刷新、注意事项说明
    • iOS风格UI: GlassContainer毛玻璃卡片、CupertinoAlertDialog、状态徽章颜色映射
  2. Flutter: account_settings_page.dart — 注销入口改为跳转独立页面:

    • 原"注销账号"按钮弹窗逻辑移除,改为 context.push('/settings/account/deletion')
    • 删除 _showDeleteAccountDialog/_confirmDeleteAccount 函数
  3. Flutter: app_router.dart — 新增路由:

    • AppRoutes.accountDeletion = /settings/account/deletion
    • iOS滑入转场动画
  4. 部署脚本docs/toolsapi/scripts/deploy_ip_city_fix.py:

    • 上传UserSecurity.php + 备份 + 缓存清理 + 登录测试验证ip_city

[5.5.0] - 2026-05-12

🚀 传输扩展功能 — 语音消息(F6)

🎙️ 语音消息 (F6)

  1. VoiceMessageData模型voice_message_data.dart:

    • duration/sampleRate/waveform/codec/isRemote字段
    • durationText格式化 / maxDurationMs(60s) / maxFileSize(1MB)
    • toJson/fromJson序列化
  2. VoiceMessageServicevoice_message_service.dart:

    • 录音: AudioRecorder + AAC-LC编码 + 44100Hz + 实时振幅监听
    • 播放: AudioPlayer + 进度监听 + 暂停/恢复/停止
    • 波形: _sampleWaveform(50点采样) + Stream广播
    • 安全: 最短500ms / 最长60s自动停止 / 最大1MB
    • 状态: VoiceRecorderState/VoicePlayerState枚举 + StreamController
  3. VoiceBubblevoice_bubble.dart:

    • 播放/暂停按钮(AnimatedSwitcher)
    • 波形进度条(_AnimatedWaveformPainter: 已播放/未播放双色)
    • 剩余时长显示
    • 播放动画(AnimationController.repeat)
  4. VoiceRecordingOverlayvoice_recording_overlay.dart:

    • 实时波形显示(_LiveWaveformPainter)
    • 录音时长计时
    • 超时预警(50s变红)
    • 上滑取消提示
  5. TransferChatPage集成transfer_chat_page.dart:

    • 输入框为空时显示🎤按钮(长按录音)
    • 输入框有内容时显示发送按钮
    • 麦克风权限检测+CupertinoDialog提示
    • 录音覆盖层(VoiceRecordingOverlay)
  6. TransferNotifier.sendVoiceMessagetransfer_notifier.dart:

    • 创建语音消息(TransferMessageType.voice)
    • 文件校验(存在+大小)
    • 复用sendFiles发送语音文件
    • 送达回执集成

[5.4.0] - 2026-05-12

🚀 传输扩展功能 — 传输统计面板(F9) + Bug修复

📊 传输统计面板 (F9)

  1. TransferStatsServicetransfer_stats_service.dart:

    • 5种聚合查询: getOverview/getDailyTrend/getDeviceRanking/getFileTypeDistribution/getTransferQuality
    • 每日快照写入: writeDailySnapshot(增量更新)
    • 数据模型: DailyStats/DeviceRanking/FileTypeDistribution/TransferQuality/TransferStatsOverview
  2. TransferStatsProvidertransfer_stats_provider.dart:

    • TransferStatsState: overview/dailyTrend/deviceRanking/fileTypeDistribution/quality
    • TransferStatsNotifier: loadAllStats/refreshTrend/writeDailySnapshot
    • Riverpod provider: transferStatsProvider
  3. TransferStatsPagetransfer_stats_page.dart:

    • 总览卡片: 已发送/已接收/平均速度/成功率
    • 趋势折线图: fl_chart LineChart 7天/30天切换
    • 设备排行: Top5设备+奖牌🥇🥈🥉
    • 文件类型饼图: fl_chart PieChart+图例
    • 传输质量: 成功率/失败率/平均速度/最高速度/总任务数
    • 下拉刷新: RefreshIndicator
  4. 路由入口transfer_settings_page.dart:

    • 新增"📊 统计"分组+📈传输统计导航
  5. 数据库CRUDtransfer_database.dart:

    • getStatsRecordByDate/insertStatsRecord/updateStatsRecord/getStatsRecords

🐛 Bug修复

  1. Drift代码生成过期app_database.g.dart:

    • 根因: 新增6张表(CloudCache/TransferStats/Clipboard/Canvas/Voice)未重新生成Drift代码
    • 修复: 运行 dart run build_runner build --delete-conflicting-outputs
  2. CloudCacheRecord命名冲突cloud_cache_provider.dart:

    • 根因: Drift生成的CloudCacheRecord和手写模型CloudCacheRecord同名导致ambiguous_import
    • 修复: 手写模型导入改为 import '...cloud_cache_record.dart' as model;
    • 新增 _driftToModel() 方法转换Drift数据类到手写模型
  3. SignalingService.send不存在transfer_notifier.dart:

    • 修复: 改用 sendCustomMessage(SignalingMessage(...))
    • 修复: currentDeviceIddeviceId
    • 修复: UserModel.id(int) → userId.toString()

[11.2.0] - 2026-05-12

🚀 传输扩展功能 — 云端暂存(CloudCache) 服务端API + 部署 + 测试

☁️ 云端暂存服务端 (F8)

  1. CloudCache.php 控制器docs/toolsapi/application/api/controller/CloudCache.php:

    • ThinkPHP 5.x RESTful API控制器
    • 8个接口: upload/download/list/info/delete/notify/clean/install
    • 安全限制: 未登录10MB/登录50MB文件大小限制
    • 危险文件类型检测: php/jsp/asp/exe/bat/cmd/sh/py等30+种扩展名
    • MIME类型验证: finfo检测+危险MIME类型黑名单
    • 24小时自动清理: cron每小时执行clean接口
    • 速率限制: 每IP每分钟60次请求
    • 文件名安全处理: sanitizeFileName过滤特殊字符
    • 修复: getOriginalName()getFilename()(TP5.0兼容)
    • 修复: finfo_file()传入文件路径而非文件名
    • 修复: 404状态码→410(避免ThinkPHP返回HTML页面)
    • 修复: \Throwable捕获+HttpResponseException透传
  2. 部署脚本docs/toolsapi/scripts/:

    • upload_cloud_cache.py: SFTP上传+备份+权限设置+数据库安装+cron配置
    • test_cloud_cache_api.py: 20项接口测试(全部通过)
    • fix_permissions.py: 目录权限修复(www:www)
    • debug_cloud_cache*.py: 调试脚本
  3. API文档API_FILE_TRANSFER_DOC.md:

    • 新增第六章"云端暂存API (CloudCache)"
    • 10个接口完整文档(安全限制/install/upload/download/list/info/delete/notify/clean/错误码)
  4. TransferProvider集成transfer_notifier.dart + transfer_chat_page.dart:

    • 离线设备→CupertinoDialog提示暂存→上传流程
    • sendFiles支持forceCloudCache参数
    • checkAndDownloadPendingCache上线自动拉取暂存
    • _notifyCloudCache通知接收方

[11.0.0] - 2026-05-12

🚀 传输扩展功能 — 送达回执 + 断点续传 + 文件分流

📨 送达回执 (F5)

  1. DeliveryReceiptServicedelivery_receipt_service.dart:

    • 通过信令服务 delivery-ack 消息类型实现端到端回执
    • 支持 sending → sent → delivered → read 四种状态
    • 自动监听信令消息并更新回执状态
    • 修复 SignalingService API 调用(onMessage 而非 messageStreamsendCustomMessage 返回 void
  2. ReceiptIndicator 组件receipt_indicator.dart:

    • 显示消息送达状态图标(发送中/已发送/已送达/已读)
    • 集成到 TransferBubble 中
  3. TransferMessage 扩展transfer_message.dart:

    • 新增 DeliveryStatus 枚举和 deliveryStatus/deliveredAt/readAt 字段
    • 新增 TransferMessageType.voice 和语音消息字段

⏸️ 断点续传 (F4)

  1. WsRelayResumeHandlerws_relay_resume_handler.dart:

    • 管理文件传输的暂停/恢复/取消/重试逻辑
    • TransferResumeState 记录已接收块索引和缺失块
    • ResumeDecision 智能决策续传策略(缺失>50%建议重新传输)
    • 通过 chunkAck 确认和 resumeRequest 请求缺失块
  2. ChunkAssembler 拆分ws_relay_chunk_assembler.dart:

    • ws_relay_service.dart 拆分出分块组装器
    • 新增 missingChunks 缺失块检测
    • 新增 verifyChecksum 校验和验证
    • 新增 toResumeState/fromResumeState 序列化支持
  3. WsRelayService 断点续传集成ws_relay_service.dart:

    • 发送时每块发送 chunkAck 确认
    • 接收不完整时自动发送 resumeRequest 请求缺失块
    • 新增 sendResumeChunks 方法重传指定块
    • 新增 pauseTransfer/resumeTransfer/cancelTransfer 方法
    • 发送循环中支持暂停等待和取消检测
  4. TransferNotifier 断点续传transfer_notifier.dart:

    • pauseTask/resumeTask/cancelTask 集成 WsRelay 断点续传
    • 新增 retryTask 方法:优先续传缺失块,否则重新开始

📂 文件分流

  1. transfer_provider.dart 拆分 (1475行→4个文件):

    • transfer_state.dart: TransferState 模型 + StateUpdater/StateReader/SystemMessenger typedef
    • transfer_notifier.dart: 核心业务逻辑
    • transfer_pairing_handler.dart: 设备发现和配对功能
    • transfer_signaling_handler.dart: 信令处理、WebRTC、WsRelay、送达回执
    • transfer_provider.dart: barrel export + provider 定义
  2. SignalingMessageType 扩展 — 14种新消息类型:

    • deliveryAck/chunkAck/resumeRequest — 回执与续传
    • voiceMeta — 语音消息
    • cloudCacheNotify — 云缓存通知
    • canvasStroke/canvasCursor/canvasJoin/canvasLeave/canvasSnapshot — 协作画布
    • screenShareOffer/screenShareAnswer/screenShareIce/screenShareControl — 屏幕共享
  3. 数据库迁移 v13 — 6张新表:

    • delivery_receipts — 送达回执记录
    • voice_messages — 语音消息
    • cloud_cache_records — 云缓存记录
    • transfer_stats — 传输统计
    • clipboard_items — 剪贴板条目
    • canvas_strokes — 画布笔画
  4. 服务端信令路由更新signaling_server.php:

    • 新增14种消息类型的路由转发
  5. 服务端Node.js更新index.js (已上传服务器):

    • 新增 pair-request/pair-accept/pair-reject 服务端处理(含持久化)
    • 新增 heartbeat 心跳消息类型
    • 新增 _findPeer 全局设备查找方法
    • 新增 _loadPairingRecords/_savePairingRecords 配对记录持久化
    • 扩展 handledTypes 列表支持新消息类型
    • 通用转发机制支持 delivery-ack/chunk-ack/resume-request/voice-meta/canvas-stroke
    • PM2 重启验证通过,接口测试全部通过
  6. 接口文档更新API_FILE_TRANSFER_DOC.md:

    • 新增第七章 v11.0.0 新增协议(通用转发/送达回执/断点续传/配对信令/语音/画布/屏幕共享/剪贴板)
    • 新增第八章服务器架构说明

[5.49.0] - 2026-05-11

🔧 修复 — 全流程E2E验证通过(100%)

  1. 服务端: IP查询接口修复Webapi.php:
    • 修复不传ip参数时返回"参数不正确"的bug
    • 不传ip时自动使用请求者IP查询归属地
  2. 服务端: 登录接口Token返回修复UserSecurity.php:
    • login接口响应data中增加token字段(之前只在Cookie/Header中返回)
    • register接口响应data中增加token字段
    • 解决API客户端无法获取Token的401认证问题
  3. 信令服务器: register消息处理snapdrop/server/index.js:
    • 新增 _handleRegister 方法处理register消息存储userId/ipCity/ipRange等元数据
    • 修复discoverMyDevices找不到同账号设备的问题(userId未存储到peer对象)
    • 返回registered消息包含peerId和userId
  4. 信令服务器: 跨房间消息转发snapdrop/server/index.js:
    • 修复message.to只在同IP房间查找接收者的bug
    • 改为全局遍历所有房间查找目标peer支持跨IP设备通信
    • transportNegotiate/wsRelay消息现在可以跨IP转发
  5. 全流程E2E验证脚本verify_e2e_full.py (新文件):
    • Phase 1: 用户注册(回执+签名)
    • Phase 2: 登录+IP归属地查询
    • Phase 3: 设备注册+列表+myDevices
    • Phase 4: 文件传输API(健康检查+信令+TURN)
    • Phase 5: WebSocket全流程(注册→发现→协商→文本→文件元数据→文件块→文件完成)
    • Phase 6: 数据一致性验证(用户信息+数据库)
    • Phase 7: 注销删号(接口未部署,跳过)
    • Phase 8: 清理(下线+退出)
    • 验证结果: 25/25 通过通过率100%

⚠️ 已知问题

  • 注销删号接口(requestDeletion/deletionStatus/cancelDeletion)尚未在服务端实现(404) v9.2.0已修复
  • 登录时ip_city/ip_range参数写入tool_user_device表但设备A的ip_city为空(登录接口未自动查询IP归属地) v9.2.0已修复

[5.48.0] - 2026-05-11

新增 — 跨设备文件传输(WebSocket中转+信令服务器+我的设备Tab)

  1. 信令服务器部署 — 服务器 tools.wktyl.com:
    • 安装 Node.js v16.20.2 (CentOS 7 glibc 2.17兼容)
    • 信令服务运行在端口 3001 (PM2守护进程 signaling)
    • Nginx WSS反向代理: wss://tools.wktyl.com:9443127.0.0.1:3001
    • 代码路径: /www/wwwroot/tools.wktyl.com/signaling/
    • Nginx配置: /www/server/panel/vhost/nginx/signaling.conf
  2. 信令服务器扩展snapdrop/server/index.js:
    • 新增 userId 索引支持跨IP同账号设备发现
    • 新增 discoverMyDevices 消息类型按userId查找同账号在线设备
    • 新增 transportNegotiate 消息类型:协商传输协议(WebSocket/WebRTC)
    • 新增 wsRelay 消息类型WebSocket中转消息/文件分片
    • Peer对象扩展: userId/ipCity/ipRange/deviceModel/platform字段
    • register消息支持携带userId/ipCity/ipRange等元数据
  3. 客户端: TransportType枚举扩展transfer_enums.dart:
    • 新增 wsRelay('ws_relay', 'WebSocket中转', '📡') 枚举值
    • isRemote 包含wsRelay; 新增 isRelay getter
  4. 客户端: TransferDevice模型扩展transfer_device.dart:
    • 新增 userId/ipCity/ipRange 字段
    • 新增 hasIpCity/hasIpRange/isAccountDevice/displayLocation getter
    • 新增 fromSignaling 工厂方法:从信令服务器响应构建设备对象
    • copyWith/toJson/fromJson 同步更新
  5. 客户端: SignalingService重构signaling_service.dart:
    • 新增4种消息类型: discoverMyDevices/myDevicesResponse/transportNegotiate/transportNegotiateResponse/wsRelay
    • connect 方法扩展: 支持userId/ipCity/ipRange参数
    • 新增 discoverMyDevices(userId) 方法
    • 新增 sendTransportNegotiate(targetId, transport, payload) 方法
    • 新增 sendWsRelay(targetId, relayType, payload) 方法
    • 新增 onMyDevicesChanged Stream监听我的设备列表变化
    • _handleMessage 路由新增消息类型分发
  6. 客户端: WsRelayServicews_relay_service.dart (新文件):
    • WebSocket中转传输服务支持≤10MB文件传输
    • 文件分片(64KB/chunk) + Base64编码 + MD5校验
    • 支持文本消息中转
    • _ChunkAssembler 接收端分片重组+完整性校验
    • 自动保存接收文件到临时目录
  7. 客户端: TransportRouter扩展transport_router.dart:
    • 集成 WsRelayService新增wsRelay路由选项
    • 同账号设备≤10MB文件优先选择wsRelay(无需P2P打洞)
    • WebRTC降级链增加wsRelay备选
    • getAvailableTransports 包含wsRelay
    • _sendViaTransport 支持wsRelay传输
  8. 客户端: TransferProvider整合transfer_provider.dart:
    • TransferState 新增 myDevices 字段
    • 初始化时创建 WsRelayService 并注入 TransportRouter
    • 新增 discoverMyDevices() 方法
    • 新增 sendFileToMyDevice(device, filePath) 方法
    • connectSignaling 扩展userId/ipCity/ipRange参数
    • _handleSignalingMessage 处理transportNegotiate/wsRelay消息
    • cancelTask/pauseTask/resumeTask 支持wsRelay类型
  9. 客户端: 文件传输页面UIfile_transfer_page.dart:
    • Tab从3个扩展为4个: 发现/📱我的/传输/记录
    • 新增"我的设备"Tab显示同账号在线设备列表
    • 设备卡片显示: 设备名+在线状态+IP归属地+IP地址
    • 快捷操作: 📤发送文件/💬发消息/传输协议标签
    • 空状态引导: 搜索我的设备按钮
    • 刷新按钮: 重新发现同账号设备
  10. 传输服务导出transport_export.dart:
    • 新增 ws_relay_service.dart 导出

[5.47.0] - 2026-05-11

新增 — 我的设备IP归属地显示+登录IP查询+myDevices接口

  1. 服务端: 数据库迁移migrate_v10.sql:
    • tool_user_device 表新增 ip_city(varchar 200) 和 ip_range(varchar 100) 字段
    • registerDevice 接口支持 ip_city/ip_range 参数写入
    • 新增 myDevices 接口 (GET /api/user_center/myDevices),返回同账号在线设备列表
  2. 客户端: IP归属地模型ip_location_result.dart:
    • 新增 IpLocationResult 模型,包含 ip/domain/city/fw/num/queryTime 字段
    • 提供 displayIp/displayCity/displayRange/hasLocation 便捷方法
  3. 客户端: IP查询服务ip_location_service.dart:
    • 新增 IpLocationService 单例服务封装IP归属地查询
    • queryMyIp() 查询本机IP(24小时缓存)
    • forceRefreshMyIp() 强制刷新(登录时调用)
    • queryIp(String ip) 查询指定IP
  4. 客户端: UserDevice模型更新user_model.dart:
    • 新增 ipCity/ipRange 字段
    • 新增 hasIpCity/hasIpRange/displayLocation 便捷方法
    • fromJson 支持 ip_city/ip_range 解析
  5. 客户端: UserCenterService更新user_center_service.dart:
    • registerDevice 新增 ipCity/ipRange 可选参数
    • 新增 myDevices 方法获取同账号在线设备
  6. 客户端: 登录流程改造device_info_service.dart:
    • registerDeviceIfNeeded 登录时先查询IP归属地再传入注册设备接口
    • IP查询失败时降级注册(不阻塞设备注册)
  7. 客户端: 我的设备页面UImy_devices_page.dart:
    • 设备概览卡片显示当前设备IP归属地(📍)
    • 设备卡片显示IP归属地(📍) + IP地址(🌐, 长按复制) + IP段范围
    • 新增 _copyToClipboard 方法支持IP复制
  8. API文档更新:
    • API_USER_CENTER_DOC.md v1.7.0: devices返回ip_city/ip_range; registerDevice新增参数; 新增12.3 myDevices接口
    • API_USER_SECURITY_DOC.md v9.1.0: 所有登录接口新增ip_city/ip_range参数
    • API_APP_FEATURE_GUIDE.md v9.1.0: 模块14更新; v9.1.0新增字段说明

[5.46.0] - 2026-05-11

新增 — 全局Toast业务状态提醒+配对成功对方通知+DeviceCard配对状态

  1. 全局Toast业务提醒transfer_provider.dart:
    • 引入 AppToast 组件在所有关键业务事件中添加Toast弹窗通知
    • 配对流程:配对开始(Info) / 配对成功(Success) / 配对失败(Error) / 对方不可达(Warning) / 配对异常(Error)
    • 消息发送:发送成功(Success) / 发送失败(Error) / 对方离线(Error) / 无IP(Error) / 通道不可用(Error) / 对方未响应(Error)
    • 文件传输:准备发送(Info) / 发送完成(Success) / 发送失败(Error) / 传输失败(Error) / 收到文件(Info)
    • 信令服务:正在连接(Info) / 连接成功(Success) / 连接失败(Error) / 连接超时(Warning)
    • WebRTC正在建立(Info) / 请求已发送(Info) / P2P连接建立(Success) / 收到连接请求(Info) / 已接受请求(Success) / 创建失败(Error) / 应答失败(Error)
    • 设备发现:发现失败(Error)
    • 手动IP配对正在连接(Info) / 连接成功(Success) / 连接失败(Error) / 不可达(Warning)
  2. 对方配对成功通知 — 接收端收到 pairingAccept 消息时:
    • 除了系统消息外,额外弹出 AppToast.showSuccess() Toast通知
    • 接收端收到文本消息时,额外弹出 AppToast.showInfo() Toast通知
    • 确保对方设备能立即看到配对/消息提醒,不再"像死猪一样没反应"
  3. DeviceCard配对状态device_card.dart(前版本已实现,本次确认):
    • 配对成功:绿色"已配对"标签+勾号图标
    • 配对中蓝色loading指示器+"配对中..."文字
    • 未配对在线:蓝色"🤝 配对"按钮
    • 未配对离线:灰色"⚠️ 配对"按钮
    • 已验证:右箭头图标

[5.45.0] - 2026-05-11

📝 文档 — IP查询接口文档分离与增强

  1. IP接口文档独立 — 从 API_TOOL_DOC.md 分离IP查询模块创建独立文档 API_IP_DOC.md:
    • IP归属地查询/api/webapi/ip)完整参数与响应字段说明
    • IP连通性检测/api/ipcheck/checkTCP/ICMP双通道检测文档
    • 本机IP信息查询不传ip参数使用方式
    • 中国IP判断is_china_ip)内部方法说明
  2. App对接增强 — 新增App对接指南章节:
    • Dart数据模型IpLocationResult / IpCheckResult
    • 输入校验建议IPv4正则、端口范围、空值检查
    • 缓存策略建议归属地24h、本机IP不缓存、连通性不缓存
    • 请求频率限制建议
    • UI展示映射表状态颜色映射、字段展示建议
  3. 技术实现说明 — 补充底层实现细节:
    • 纯真IP数据库qqwry.dat二分查找流程
    • Ipcheck TCP/ICMP检测流程
    • 相关文件清单

[5.44.0] - 2026-05-11

新增 — 传输聊天页面网络状态栏(延迟/健康度/信号强度)

  1. Ping延迟检测transfer_chat_page.dart:
    • 新增 _startPing() / _doPing() 方法每5秒通过 Socket.connect 测量到对端设备的TCP延迟
    • 延迟值存储在 _latencyMs 状态变量驱动UI实时更新
    • 连接失败时 _latencyMs = null,信号强度归零,状态显示"离线"
  2. 信号强度计算_updateSignalStrength():
    • <10ms → 1.0(满格),<50ms → 0.8<100ms → 0.6<300ms → 0.4<1000ms → 0.2≥1000ms → 0.0
    • 驱动4格信号柱状图显示
  3. 健康度标签_healthLabel / _healthColor:
    • 极佳(绿) <10ms / 良好(绿) <50ms / 一般(黄) <100ms / 较差(橙) <300ms / 极差(红) / 离线(灰)
  4. 网络状态栏UI_buildNetworkStatusBar():
    • 位于导航栏下方,半透明背景 + 底部分割线
    • 左侧4格信号强度柱状图高度递增激活/未激活颜色区分)
    • 中部:📡天线图标 + 延迟数值(等宽数字 tabularFigures
    • 右侧:健康度徽章(圆点+文字,背景色随健康度变化)
    • 全部使用 AppThemeExtension 主题变量,支持深色/浅色/AMOLED主题

[5.43.0] - 2026-05-11

🔧 修复 — 设备名称区分+HTTP服务器重复绑定+HTTPS→HTTP降级+信令自动连接+发送文件闪退+NFC权限崩溃+消息显示

  1. 设备名称区分 — 不再全部显示"闲言设备":
    • LocalSendConfig.alias 默认值从硬编码"闲言设备"改为 闲言·{主机名}(如"闲言·DESKTOP-ABC"
    • LocalSendConfig.deviceModel 自动检测平台类型Android/iOS/macOS/Windows/Linux
    • TransferDevice.displayAlias 新增计算属性当alias为默认值时自动用 设备型号·IP 区分
    • DeviceCard 使用 displayAlias 替代 alias,设备列表可区分不同设备
    • connectSignaling() 默认别名从"闲言设备"改为读取 localSendService.config.alias
    • signaling_service.dart 注册消息增加 deviceModel 字段
  2. HTTP服务器重复绑定修复SocketException: bind shared flag:
    • LocalSendService 新增 isHttpServerRunning getter检查 _shelfServer != null
    • _ensureHttpServerRunning() 使用 isHttpServerRunning 替代 isRunning后者是discovery标志
    • startHttpServer() 开头增加 _shelfServer != null 检查,已运行时直接返回
  3. 离线设备配对体验优化:
    • DeviceCard 离线设备配对按钮显示为"⚠️ 配对"(灰色+边框),在线设备显示"🤝 配对"(蓝色)
    • sendTextMessage() 错误提示区分三种情况:离线/无IP/未开启传输服务
    • sendFiles() 发送前检查设备在线状态和IP离线且无IP时直接提示
  4. 发送文件闪退修复 — IP为空导致崩溃:
    • LocalSendService.sendFile() 添加 ip.isEmpty 检查,抛出明确异常
    • LocalSendService.sendTextMessage() 添加 ip.isEmpty 检查
    • TcpSocketService.sendFile() 添加 host.isEmpty 检查
  5. HTTPS→HTTP协议降级 — 修复"Connection reset by peer"和"DioExceptionType.unknown":
    • prepareUpload() 新增 useHttp 参数HTTPS失败自动降级HTTPv2→v1→HTTP v2→HTTP v1
    • prepareUpload() 返回结果增加 _usedHttp 标记,sendFile() 据此选择上传协议
    • sendTextMessage() 任何HTTPS DioException都降级HTTP不再限制错误类型
    • prepareUpload() 任何HTTPS DioException都降级HTTP不再限制错误类型
    • 根因HTTP服务器默认不启用HTTPSenableHttps=falseHTTPS握手失败返回DioExceptionType.unknown
    • 验证脚本确认HTTP全部可用HTTPS全部返回DioExceptionType.unknown
  6. 信令服务自动连接 — 修复WebRTC连接无响应:
    • _init() 新增 _autoConnectSignaling() 调用,初始化时自动连接信令服务器
    • _autoConnectSignaling() 添加8秒超时不阻塞主流程
    • SignalingService.connect() 添加6秒连接超时避免长时间阻塞
    • connectSignaling() 移除硬编码 wss://signaling.xianyan.app/ws,使用 SignalingService 默认地址
    • sendTextMessage() 错误提示增加"信令服务未连接"场景
    • 已知问题:wss://tools.wktyl.com:9443 信令服务器当前不可达(端口可能被防火墙阻止)
  7. NFC权限缺失导致APP闪退SecurityException: NFC permission required:
    • AndroidManifest.xml 添加 android.permission.NFC 权限声明
    • AndroidManifest.xml 添加 android.hardware.nfc featurerequired=false不强制NFC硬件
    • AndroidManifest.xml 添加蓝牙权限BLUETOOTH/BLUETOOTH_SCAN/CONNECT/ADVERTISE
    • AndroidManifest.xml 添加WiFi多播权限CHANGE_WIFI_MULTICAST_STATE
    • NfcPairingService.startScan() 添加运行时 isAvailable() 检查
    • 根因nfc_manager插件在Activity.onResume时注册NFC回调缺少权限直接崩溃
  8. 消息显示修复 — 收到消息只显示"收到闲言设备的消息"不显示具体内容:
    • 移除 _localSendMessageSub 中多余的 _addSystemMessage('💬 收到...'),消息本身已显示内容
    • _createSendTask() 添加 mimeType 字段,使用 lookupMimeType() 自动检测
    • 图片消息改用 _buildImageBubble() — 显示图片缩略图预览
    • 视频消息改用 _buildVideoBubble() — 显示缩略图+播放按钮
    • 根因1.多余系统消息遮盖实际内容 2.mimeType未设置导致图片/视频被当作普通文件

[5.42.0] - 2026-05-11

🔧 修复 — 配对后发消息失败+DataChannel not open+传输路由降级+401 Token刷新死锁

  1. 文本消息发送失败修复lib/features/file_transfer/providers/transfer_provider.dart:
    • sendTextMessage() 重写降级逻辑WebRTC消息通道 → 信令服务 → LocalSend HTTP文本消息API
    • 移除旧的"创建临时文件→sendFile"方式,改用新增的 LocalSendService.sendTextMessage() 直接发送
    • 添加 _ensureHttpServerRunning() 方法配对成功后自动启动本机HTTP服务器
    • _init() 初始化时自动启动HTTP服务器确保本机可接收消息
    • pairWithDevice()pairWithManualIp() 配对成功后自动调用 _ensureHttpServerRunning()
    • 新增 _localSendMessageSub 监听LocalSend文本消息接收端自动显示
  2. LocalSend文本消息APIlib/features/file_transfer/services/transport/localsend_service.dart:
    • 新增 /api/localsend/v2/message 端点,接收文本消息并广播到 onIncomingMessage
    • 新增 sendTextMessage() 方法HTTPS POST发送文本HTTPS失败自动降级HTTP
    • 新增 _incomingMessageControlleronIncomingMessage
    • dispose() 中关闭 _incomingMessageController
  3. 传输路由降级修复lib/features/file_transfer/services/transport/transport_router.dart:
    • sendWithFallback() 检查返回的 TransferTask.isFailed,失败时自动降级到下一个传输方式
    • 修复WebRTC sendFile() 返回failed task但不抛异常导致降级链断裂的问题
    • selectRoute() 放宽局域网判断:当 localIp==nullpeer.ip 存在时仍尝试LocalSend/TCP
    • _executeSendTask() 传入 localIp 参数修复路由选择缺少本机IP的问题
  4. 401 Token刷新死锁修复lib/core/network/api_interceptor.dart + docs/toolsapi/application/api/controller/Token.php:
    • 服务端: Token::refresh() 加入 $noNeedLogin 列表内部自行验证token有效性避免token过期后无法刷新的死锁
    • 客户端: 新增并发刷新等待队列 _retryQueue多个请求同时401时排队等待刷新完成后自动重试
    • 客户端: 刷新超时从5秒增加到10秒增强弱网环境下的刷新成功率
    • 客户端: 刷新失败时正确通知所有等待中的请求,避免请求挂起

[5.41.0] - 2026-05-11

🔧 修复 — Provider生命周期安全+dependents.isEmpty断言+布局溢出+资源泄漏

  1. dependents.isEmpty断言修复lib/features/file_transfer/providers/transfer_provider.dart:
    • 构造函数中 _init() 改为 Future.microtask(() => _init()) 延迟初始化避免在widget树构建期间修改provider
    • 所有异步方法添加 mounted 检查:_loadPairedDevices_loadRecentMessages_loadSessionMessagesstartDiscoverystopDiscoverypairWithDevicepairWithQrCodepairWithManualIpremovePairingsendTextMessagecancelTaskpauseTaskresumeTask_executeSendTask_handleIncomingTask_handleIncomingTextMessage
    • _init() 添加 try-catch 全局异常防护
  2. TransferChatPage.initState修复lib/features/file_transfer/presentation/pages/transfer_chat_page.dart:
    • setCurrentSession() 调用从 initState 移至 WidgetsBinding.instance.addPostFrameCallback避免在构建期间修改provider
  3. 危险updateState扩展删除lib/features/file_transfer/presentation/pages/file_transfer_page.dart:
    • 删除 TransferNotifier.updateStateDeviceDiscoveryNotifier.updateState 扩展方法直接访问protected state
    • 替换为正式方法:TransferNotifier.addSimulatedTask()DeviceDiscoveryNotifier.addSimulatedDevices()
  4. DeviceDiscoveryNotifier安全增强lib/features/file_transfer/providers/device_discovery_provider.dart:
    • 添加 _isDisposed 标志,所有状态修改前检查
    • 构造函数中 _init() 改为 Future.microtask(() => _init())
    • dispose() 方法取消所有 StreamSubscription + 调用所有子服务 dispose
    • stopScan() 添加 try-catch 防护每个服务的 stop 调用
  5. UsbDiscoveryService资源泄漏修复lib/features/file_transfer/services/discovery/usb_discovery_service.dart:
    • startMonitoring() 先 cancel 旧订阅再创建新订阅
    • dispose() 调用 stopMonitoring() + 关闭 StreamController
    • 移除未使用的 dart:io import

[5.36.0] - 2026-05-10

🔧 修复 — 登录页面9项问题修复 + 文件拆分

  1. 登录按钮空输入转圈auth/presentation/login_page.dart:
    • _canSubmitLogin(): 增加空值校验未输入时按钮禁用不再触发loading
    • 老用户模式固定返回 false,防止误触
  2. 输入错误无提醒auth/presentation/login_page.dart:
    • 密码登录: 空账户/空密码/密码不足6位 → AppToast.showWarning()
    • 验证码登录: 空邮箱/无效邮箱/空验证码/验证码错误 → AppToast.showError()
    • Token登录: 空Token/长度不足 → AppToast.showWarning()
    • API异常: ApiException 捕获并显示 e.message
    • 老用户模式: 提示迁移中,引导使用其他方式
  3. 白天模式字体不可见auth/presentation/login_form_sections.dart:
    • 所有文本统一使用 ext.textPrimary / ext.textSecondary / ext.textHint
    • 输入框样式使用主题色,确保亮色/暗色模式均可见
  4. 二维码登录入口auth/presentation/login_page.dart:
    • 第三方登录区去掉QQ图标新增 CupertinoIcons.qrcode_viewfinder 二维码图标
    • 点击跳转 AppRoutes.qrcodeLogin 二维码登录页
  5. 退出后不跳转settings/presentation/account_settings_page.dart + profile/presentation/profile_page.dart:
    • _LogoutButton: 退出后 context.go(AppRoutes.login) 跳转登录页
    • 清除Token: 退出后跳转登录页
    • 修改密码成功: 退出后跳转登录页
  6. 协议文字增大auth/presentation/login_page.dart:
    • 协议区域字体从 AppTypography.caption2 升级为 AppTypography.footnote
  7. 子页面左右滑动auth/presentation/login_page.dart:
    • 使用 PageView + PageController 实现密码/验证码/Token/老用户四页滑动
    • BouncingScrollPhysics 提供iOS弹性回弹效果
    • 滑动与 CupertinoSlidingSegmentedControl 双向联动
  8. 老用户子页面优化auth/presentation/login_form_sections.dart:
    • 去掉登录按钮(_canSubmitLogin 返回 false
    • 新增描述卡片: 2019—2023.6期间注册为老用户,保留积分/等级/标识/优先体验权益
    • 提示迁移中,引导使用其他方式登录
  9. 登录成功跳转动画auth/presentation/login_form_sections.dart:
    • LoginSuccessView: 弹性缩放✓图标 + 渐显"登录成功" + 渐显"正在跳转"
    • 800ms后自动 context.go(AppRoutes.home) 跳转首页

📦 重构 — 登录页面文件拆分

  • login_page.dart (784行): 主页面 + 登录视图 + 模式选择 + 社交登录 + 协议 + 登录处理
  • login_form_sections.dart (522行): 密码/验证码/Token/老用户表单 + 通用输入框 + 登录成功动画
  • register_section.dart (478行): 注册区域独立组件,分步式注册流程

[5.35.0] - 2026-05-10

🚀 新增 — 搜索历史云同步功能 (Task 13)

  1. 搜索记录云端同步search/providers/search_provider.dart:
    • _syncSearchToCloud(): 搜索执行后自动调用 UserCenterService.interaction(action: 'search') 记录到云端
    • 离线时搜索记录加入 _pendingCloudSync 队列,联网后自动批量同步
    • _syncPendingToCloud(): 网络恢复时自动同步待上传的搜索记录
  2. 搜索历史双源合并search/providers/search_provider.dart:
    • _fetchServerHistory(): 同时从 SearchAllService.history()UserCenterService.interaction(action: 'history', filterAction: 'search') 获取云端历史
    • _fetchInteractionHistory(): 从互动系统获取用户搜索历史,提取 extra 字段作为关键词
    • 两个数据源独立容错,任一失败不影响另一个
    • 离线时跳过服务端历史拉取
  3. 历史操作云端同步:
    • clearHistory(): 同时清除本地 + 服务端历史 + 待同步队列
    • _clearCloudHistory(): 调用 SearchAllService.clearHistory() 清除云端
    • removeHistory(): 同时从本地和服务端历史列表中移除
  4. 网络状态监听:
    • _onNetworkChanged(): 监听 ConnectivityService.onTypeChange,网络恢复时自动同步待上传记录 + 刷新服务端历史
    • dispose(): 取消网络监听订阅,防止内存泄漏
  5. 搜索页面头部更新search/presentation/search_page.dart

[5.34.0] - 2026-05-10

🚀 新增 — 稍后读智能提醒功能 (Task 14)

  1. ReadlaterReminderServicecore/services/readlater_reminder_service.dart:
    • 监听电池充电状态 (battery_plus),充电时自动检查稍后读列表
    • 4小时冷却期避免频繁推送提醒
    • 过滤未读文章,推送包含未读数量和首篇文章标题的即时通知
    • startMonitoring() / stopMonitoring() / setEnabled() / checkNow() / dispose()
    • SharedPreferences key 复用 notif_charging_readlater,与通知设置页面保持一致
  2. 通知设置页面集成settings/presentation/notification_settings_page.dart:
    • setChargingReadLater() 切换开关时调用 ReadlaterReminderService.setEnabled()
    • 开启时自动启动电池监听,关闭时停止监听
  3. App启动初始化main.dart:
    • 启动时调用 ReadlaterReminderService.startMonitoring()
    • 若用户已开启充电提醒开关,自动恢复电池状态监听

[5.33.0] - 2026-05-10

🚀 新增 — 智能推荐优化 + 标签云系统 (Task 11 & Task 12)

  1. InteractionNotifier 智能推荐方法user_center/providers/interaction_provider.dart:
    • dislikeContent(): 标记不喜欢某内容,支持传入原因
    • blockContent(): 屏蔽某内容
    • getDislikedIds(): 获取已不喜欢的ID集合用于Feed过滤
    • getBlockedIds(): 获取已屏蔽的ID集合用于Feed过滤
  2. 标签云状态管理user_center/providers/tag_cloud_provider.dart:
    • TagItem: 标签数据模型 (name/count/pinyinInitial/targetId/targetType)
    • TagCloudState: 标签云状态 (isLoading/error/tags/filterInitial)
    • TagCloudNotifier: loadTags()/addTag()/filterByInitial()
    • 拼音首字母自动提取 (PinyinHelper)
    • 标签聚合统计 + 拼音首字母排序
    • Riverpod StateNotifierProvider
  3. 标签云展示页面user_center/presentation/tag_cloud_page.dart:
    • iOS风格 CupertinoPageScaffold + CupertinoNavigationBar
    • 顶部拼音索引栏: A-Z + # 横向滚动选择器,活跃字母高亮
    • 标签云区域: Wrap布局频率权重渲染 (高频大字号深色/中频/低频浅色)
    • 点击标签: 弹出详情对话框 (使用次数/拼音/关联ID/类型)
    • 长按标签: 弹出ActionSheet (查看关联/删除)
    • 右上角添加按钮: 弹出输入框 (标签名+关联ID+类型选择)
    • GlassContainer毛玻璃容器包裹
    • flutter_animate入场动画 (fadeIn + scale)
    • CupertinoSliverRefreshControl下拉刷新
    • 空状态/加载中/错误状态展示
  4. 路由app_router.dart: AppRoutes.tagCloud + iosSlideTransition
  5. 导航入口user_center_page.dart: 快捷入口网格新增「🏷️ 标签云」(CupertinoIcons.tag, 0xFFFF9500橙色)

[5.33.0] - 2026-05-10

🚀 新增 — 智能模式切换功能 (Task 10)

  1. SmartModeServicecore/services/smart_mode_service.dart:
    • BrowseMode 枚举: hd / standard / saver
    • 自动模式: 根据网络类型自动切换(WiFi→高清/移动→标准/离线→省流)
    • 手动模式: 关闭自动后可手动选择浏览模式
    • KV持久化: AppKVStore存储自动/手动模式偏好
    • Riverpod Provider: browseModeProvider + isAutoModeProvider
  2. 智能模式设置页面settings/presentation/smart_mode_settings_page.dart:
    • iOS风格CupertinoPageScaffold + CupertinoNavigationBar
    • 📊 状态卡片: 当前模式+网络类型+模式描述(GlassContainer elevated)
    • 🔄 自动模式开关: CupertinoSwitch开启时根据网络自动切换
    • 📱 手动模式选择: 3个选项(高清/标准/省流),自动模式关闭时可用
    • 📋 模式说明: 🎬高清(WiFi/有线) / 📱标准(移动网络) / 📶省流(离线/弱网)
    • flutter_animate入场动画 + GlassContainer毛玻璃容器
    • AppTheme/AppTypography/AppSpacing/AppRadius统一设计令牌
  3. 路由 — 已注册于 app_router.dart (AppRoutes.smartModeSettings + iosSlideTransition)
  4. 导航入口 — 已添加于 general_settings_page.dart 性能分组"智能模式"行

[5.32.0] - 2026-05-10

🚀 新增 — 离线浏览缓存功能 (Task 7)

  1. ConnectivityServicecore/services/connectivity_service.dart:
    • 网络连接状态监听服务,封装 connectivity_plus
    • NetworkType 枚举: wifi / mobile / ethernet / vpn / none / other
    • 网络状态流 Stream供全局监听
    • isOnline / isOffline 便捷属性
    • init() 初始化 + 自动监听网络变化
    • Riverpod Provider: networkTypeProvider (StreamProvider) + isOnlineProvider (Provider)
  2. InteractionNotifier 离线缓存user_center/providers/interaction_provider.dart:
    • recordView() 离线时自动缓存浏览记录到 Hive offlineQueue
    • 在线请求失败时降级缓存到本地
    • _cacheViewOffline(): 写入 offline_view_queue队列上限100条
    • syncCachedViews(): 联网后批量同步缓存的浏览记录到服务端
    • 同步完成后自动清除本地缓存队列

[5.31.0] - 2026-05-10

🚀 新增 — 通知设置页面

  1. 通知设置页面settings/presentation/notification_settings_page.dart:
    • iOS风格CupertinoPageScaffold + CupertinoNavigationBar
    • 📱 每日推荐推送 — CupertinoSwitch开关(默认开启) + CupertinoTimerPicker时间选择(默认8:00)
    • 📝 签到提醒 — CupertinoSwitch开关(默认关闭) + CupertinoTimerPicker时间选择(默认9:00)
    • 📊 学习进度提醒 — CupertinoSwitch开关(默认关闭)
    • 🔋 充电时稍后读提醒 — CupertinoSwitch开关(默认关闭)
    • 毛玻璃容器(GlassContainer + GlassDepth.base)包裹各设置项
    • 开关切换时调用NotificationService调度/取消通知 + NotificationScheduler同步主开关
    • SharedPreferences持久化学习进度/稍后读开关状态
    • AppToast成功提示 + HapticService触觉反馈
    • AppTheme/AppTypography/AppSpacing/AppRadius统一设计令牌
  2. 通知设置ProviderNotificationSettingsNotifier:
    • NotificationSettingsState: 4个开关 + 2个时间(小时/分钟)
    • loadFromPrefs(): 从NotificationService + SharedPreferences加载初始状态
    • setDailyRecommend/setSigninReminder: 双写NotificationService + NotificationScheduler
    • _syncMainSwitch(): 任一开关开启则同步主通知开关
  3. 路由 — 已注册于 app_router.dart (AppRoutes.notificationSettings + iosSlideTransition)
  4. 导航入口 — 已存在于 general_settings_page.dart 通知分组"推送通知"行

[5.30.0] - 2026-05-10

🚀 新增 — 二维码登录页面

  1. 二维码登录页面auth/presentation/qrcode_login_page.dart:
    • 📷 扫码登录Tab: 使用mobile_scanner扫描Web端二维码解析URL中code参数
    • 📱 生成二维码Tab: 调用qrcodeGenerate()生成二维码使用qr_flutter展示
    • iOS风格CupertinoPageScaffold + CupertinoNavigationBar
    • 毛玻璃容器(GlassContainer)包裹各区域
    • 扫描框四角标记 + 半透明遮罩(CustomPainter)
    • 相机权限拒绝时优雅降级显示提示文字
    • 扫码确认后自动弹出成功对话框2秒后自动返回
    • 二维码过期自动提示 + 刷新按钮
    • flutter_animate入场动画(fadeIn/slideY/scale)
    • AppTheme/AppTypography/AppSpacing/AppRadius统一设计令牌
  2. 二维码登录Providerauth/providers/qrcode_login_provider.dart:
    • QrcodeLoginState: step(idle/scanning/confirming/success/error) + qrCode + errorMessage
    • QrcodeLoginNotifier: confirmLogin(code) + generateQrcode() + cancel() + resetToScan() + clearError()
    • qrcodeLoginProvider: StateNotifierProvider

已归档版本

5.29.0(表单校验服务+本地通知服务) / 5.28.0(文件传输助手服务端部署+UI组件补全+我的设备页面+扫码登录+注册校验+推送+通知设置+头像编辑+生物识别设备管理) / 5.27.0(用户中心接口同步与问题修复) / 5.26.0(文件传输助手核心架构) / 5.22.0(聊天多媒体+视觉增强+交互增强) / 4.21.0(聊天会话流Provider+UI+缓存管理) / 5.11.0(通用设置重构+权限管理) / 5.10.0(关于页面+图标统一+tz.local崩溃修复) / 3.9.9(画布样式编辑面板+叠层效果+虚线边框) / 3.9.8(拖拽描边偏移/文本回写/壁纸无限加载/工具抽屉/画布圆角动态调整) / 3.9.7(画布圆角显示+导出修复+401修复) / 3.9.6(画布圆角/文字按钮卡死/描述线条偏移) / 3.9.5(Bug回归修复:壁纸卡死/文字按钮/画布圆角/壁纸源加载/编辑器闭合) / 3.9.4(Bug回归修复:本地化/HTTP明文/画布圆角) / 3.9.3(Bug回归修复:画布圆角/壁纸卡死/文字按钮) / 3.9.2(Bug修复:画布圆角/文字按钮/壁纸/描边) / 3.9.1(Bug修复:历史卡死/同步丢失/画布圆角/emoji替换) / 3.9.0(编辑器增强:拖拽描边+富文本+画布圆角) / 3.8.0 / 2.58.0(六大Bug修复+键盘适配公共类) / 2.57.0(Phase35开发计划5大方向36项功能) / 2.56.0(README全面更新功能梳理+可扩展方向) / 2.55.1(全局代码质量清理188→0issues) / 1.55.0(灵感页面重构联系人列表+长按菜单+搜索+足迹整合) / 1.54.0(修复个人中心+签到Bug+调试信息页) / 1.53.0(修复分类列表不更新+句子空白+骨架屏体验优化) / 1.52.0(修复句子卡片数据永不更新根因修复) / 1.51.0(修复句子卡片循环重复+Slidable切换分类) / 1.50.0(修复频道同步延迟+滑动冲突+卡片重复) / 1.49.0(修复刷新无响应+分类同步+卡片重复+广场空白+滑动冲突) / 1.48.0(修复句子广场无限循环+分类过滤+空白句子+作者显示) / 1.47.0(修复API类型转换崩溃+频道开关同步+句子广场加载) / 1.46.0(句子来源页面改造+混合信息流5种模式+首页卡片来源配置) / 1.45.0(笔记自动保存+字数统计+保存状态+上限提示) / 1.44.2(笔记模块五大Bug修复:时间戳/布局切换/菜单拦截/空标题/删除刷新) / 1.44.1(笔记删除后仍显示-ThinkPHP5查询构建器Bug) / 1.44.0(API集成补全+互动收藏笔记增强+笔记页重新设计) / 1.40.0(用户安全接口升级-回执验证替代邮箱验证码) / 1.39.0(卡片震动/Slidable冲突修复/分类切换优化/API功能全面接入阶段三六) / 1.31.0(API功能全面接入:学习中心/签到增强/国学经典/健康生活/推荐偏好/Feed互动/数据可视化/游戏中心) / 1.30.0(中国传统色页面增强重构) / 1.23.0(Phase A偷工减料修复+Phase B缺失功能补全) / 1.22.0(句子广场交互增强:间距优化/循环滚动/边缘光晕) / 1.21.0(Bug修复:数据管理卡死/Tab抖动/密码页/详情Sheet/字体管理) / 1.20.0 / 1.19.0 / 1.18.0 / 1.17.0 / 1.16.0 / 1.15.0 / 1.14.0 / 1.13.0 / 1.10.0 / 1.7.16 / 1.7.15 / 1.7.14 / 1.7.13 / 1.7.12 / 1.7.11 / 1.7.10 / 1.7.9 / 1.7.8 / 1.7.7 / 1.7.6 / 1.7.5 / 1.7.4 / 1.7.3 / 1.7.2 / 1.7.1 / 1.7.0 / 1.6.4 / 1.6.3 / 1.6.2 / 1.6.1 / 1.6.0 / 1.5.2 / 1.5.1 / 1.5.0 / 1.4.1 / 1.4.0 / 1.3.0 / 1.2.0 / 0.28.x / 0.27.0 / 0.26.0 — 详见 git history