# 需求进度 ## 当前总目标 - 控制当前 Flutter Android 发包体积,持续定位冗余组件、超大资源和不合理构建配置,并把每一步处理结果落盘记录。 ## 本轮房间动效优化(进行中) - 已按 2026-04-21 当前房间卡顿优化方案先落第一步“统一调度层”:新增房间特效调度器,在全屏 `VAP/SVGA` 高成本特效播放或排队期间,暂缓低优先级的房间进场动画、全局飘屏和座位飞屏入队,待高成本特效清空后按小间隔续播,先减少多条动画链路同一时刻抢主线程的情况。 - 本步只处理“调度时机”,没有改动现有动画内部逻辑:礼物/飞屏/飘屏的现有倍率触发规则、现有上限截断、`customAnimationCount` 现有循环方式和当前视觉表现均保持原样,避免第一步就引入联动回归。 - 已继续落第二步“局部重建/重绘隔离”:房间礼物播报条已从整层 `Consumer` 重建改成每个动画槽位独立 `Selector` 订阅,并把运行态数据拍平成快照,减少 `notifyListeners()` 时 4 个槽位整层一起重建;同时为礼物播报条、进场动画、座位飞屏和全局飘屏 overlay 补充 `RepaintBoundary`,先把高频位移动画和底层页面绘制隔离开,降低同屏重绘面积。 - 第二步同样没有改动任何动画业务规则:礼物播报条合并策略、幸运礼物奖励展示、现有队列时长、`customAnimationCount` 的逐个入队方式、现有上限和触发条件都保持原样,这一步只收敛 rebuild / repaint 成本。 - 已顺手补上高成本特效资源预热接线:当前全屏 `VAP/SVGA` 任务一入队就会触发已有的 preload 逻辑,让排队中的特效在前一个播放期间优先完成 `svga decode / 网络文件落缓存`,减少切到下一段时的首帧等待;这一步复用现有预热能力,不改变任何播放顺序和触发条件。 - 已继续补上图片链路的“按展示尺寸解码 + 排队阶段预热”:`buildCachedImageProvider` 现已支持 `network/file/asset` 三类资源统一按逻辑尺寸生成 provider,并通过 `ResizeImage` 把解码尺寸压到实际展示大小;同时房间礼物播报条、进场动画、全局飘屏与座位飞屏在入队时会对头像/礼物图做异步预热,减少正式播到该条动画时首次解码和图片闪一下的概率。 - 这一轮同样没有改动任何动画规则或队列行为:只补资源命中率和解码尺寸控制,不变更现有播放次数、上限、倍率阈值、`customAnimationCount` 逐个飞行方式和当前视觉逻辑。 - 已继续收口座位飞屏的图片命中链路:当前在真正批量入队逐个飞行前,会先按飞行动画的大图尺寸预热一次礼物图;同时飞屏 overlay 内部会复用同路径同尺寸的 `ImageProvider`,减少 burst 场景里同一张礼物图连续多次构造 provider 和重复命中解析链路的开销。 - 已继续专项收口“顶部礼物信息播报”的连击卡顿:当前已把礼物播报条的“整条入场动画”和“右侧 `xN` 数量脉冲/续命”拆成独立状态,连击到来时不再通过重启整条 5 秒控制器来硬续播,而是只刷新数量脉冲并延长当前播报条的空闲存活时间;同时右侧数量已改为从当前显示值平滑补间到目标值,减少高频连击或本地批量合并时出现的数字跳变、断档和忽大忽小。 - 这一轮同样没有改礼物业务判断口径:未调整礼物连击的触发条件、上限、截断、倍率门槛和 `customAnimationCount` 等既有规则,只优化顶部播报条自身的显示状态机与数量刷新方式。 - 已继续修正连击播报条“单点送 1 个却直接跳 `+5`”的问题:顶部礼物播报条现已接入 `customAnimationCount` 的点击粒度信息,数量动画不再只按合并后的总量做补间,而是按“单次点击对应的数量步长”逐步递进;例如连续点击 5 次、每次送 1 个时,会按 `+1 +1 +1 +1 +1` 的视觉节奏补齐,而不是直接把右侧数量跳成 `+5`。 - 已继续修正连击档位特效偶发“不播”的问题:当前连击 `SVGA` 触发已改为只命中仓库里真实存在资源的档位集合,不再把 `20/88/200...` 这类当前工程里没有对应特效文件的档位当成可播放资源;同时命中判断会按“本次新增后跨过的最高有效资源档位”来触发,避免因为本地批量窗口把多次点击合成一包后,先命中到空资源路径而看起来像整段特效都没播。 - 已按 2026-04-21 最新回归继续修正“飞向麦位的自制动画”缺失问题:座位飞屏现已从房间统一调度器的延后队列中移出,恢复为收到礼物消息后直接入队到全局 `RoomGiftSeatFlightOverlay`;保留既有的图片预热、同会话队列上限和 `customAnimationCount` 逐个飞行逻辑,只撤回此前对这一核心反馈动画的延迟调度,避免用户在礼物命中全屏特效或调度状态未及时清空时误以为飞屏动画消失。 ## 本轮启动优化(非网络) - 已补回启动页正式展示逻辑:当前 `Weekly Star / Last Weekly CP` 两套自定义启动页都改为“本地有缓存才展示、无缓存不展示”;由于现阶段周榜与 CP 榜接口链路都还未 ready,缓存刷新逻辑已先关闭,所以当前启动阶段会直接回退到默认 splash,不再展示这两套定制视觉稿。相关恢复入口已在缓存类里用 `api-ready-launch-splash` 注释标记,后续接口 ready 后可直接搜索接回。 - 已将启动页展示时间收敛为 `3` 秒,并在右上角新增通用 `skip 倒计时` 按钮:当前按钮会按秒级动态展示剩余时间,点击可立即跳过;文案已补齐 `en/ar/tr/bn` 多语言翻译,并按 locale 输出倒计时文本,便于后续继续做 RTL 语言验收。 - 已按 2026-04-20 最新截图反馈重新校准 `Last Weekly CP` 启动页的头像与昵称区域,并在 `SplashPage` 中单独抽出 `_LastWeeklyCpLayout` 手动微调区;后续如果还要继续挪位置,直接改榜一/榜二/榜三的 `frame/avatar/label Rect` 即可,不用再翻布局层级。 - 已按 2026-04-20 最新确认把 `Last Weekly CP` 启动页临时切到“通用头像占位”模式:由于当前 CP 榜正式接口还未就绪,启动页不再读取本地 `cpList` 或当前用户头像,现统一使用默认头像占位与通用昵称,专门用于先校对双人头像位和昵称区域的 UI 位置;后续接口 ready 后再切回真实数据源。 - 已继续扩展启动页方案:桌面 `启动页_cp榜` 的背景图与 CP 榜一/榜二/榜三素材已导入工程,并新增 `Last Weekly CP` 启动页;当前 `SplashPage` 会在 `Weekly Star` 与 `Last Weekly CP` 两套视觉稿之间随机选一张展示,便于一起校对两套 UI 样式。 - 已为 `Last Weekly CP` 启动页补齐本地缓存骨架:新增独立的 CP 榜缓存结构,当前会先把默认占位头像与通用昵称写入本地缓存,后续若改成正式的“有相关缓存才启用”或切到独立榜单来源,只需要替换数据入口,不用重做随机展示和布局层。 - 已按 2026-04-20 新需求在 Flutter 启动页接入 `Weekly Star` 周榜视觉稿:桌面 `启动页_周榜` 的背景图与榜一/榜二/榜三翅膀框素材已导入工程,并替换了原先仅展示静态 logo 的 `SplashPage`,当前会按参考图在启动阶段叠加 3 个头像位和用户名描边文案,便于先校对 UI 样式。 - 已为 `Weekly Star` 启动页补齐本地缓存读写骨架:新增独立缓存辅助类,支持把 `/ranking/top-four-with-reward` 返回的榜单前三头像/昵称写入本地,并在启动时优先读取缓存数据渲染;后续只需要把“当前固定启用”切回“缓存存在时才启用”即可,不用重做布局层。 - 已将 Firebase / Crashlytics 从 `runApp` 前阻塞初始化改为首帧后后台预热,并补充“未就绪时仅本地打印”的异常兜底,减少首屏前平台初始化阻塞。 - 已将 `SocialChatAuthenticationManager`、`SocialChatUserProfileManager` 改为按需创建,避免 splash 阶段就提前触发 Google Sign-In / Firebase 会话检查。 - 已将 deep link、设备信息、缓存目录创建等非首帧必需动作延后到首帧后执行,降低首屏竞争。 - 已优化本地语言初始化:启动时不再重复写入 `SharedPreferences` 并触发一次无意义的 `notifyListeners`。 - 已优化首页容器与 Home 首屏:去掉首次进入时“先 loading 再建 tab”的本地跳变,并将首页 page 列表、底部导航项从 `build` 阶段的重复重建改为复用。 - 本轮按需求暂未处理网络链路上的启动等待,例如审核态检查或远端启动页配置请求。 ## 已完成模块 - 已按 2026-04-20 最新首页视觉需求,为 Party 房间列表前 3 个房卡接入新的本地排名边框 SVGA:桌面“房间排序前三的框”中的 3 份素材已导入工程并挂到首页房卡最上层,仅作用于当前列表前 3 项,其余房卡保持原样;后续又继续为前三房卡底部信息区补了横向与底部安全区,避免外扩边框直接压住国旗、房名和在线人数。同时 `Me` 板块里的 `Recent / Followed` tab 已继续对齐上方首页 tab 的斜体字样式,并移除了点击时的波浪反馈。 - 已按 2026-04-20 最新房间联调继续修正房主在自己房间里的麦位操作回归:当前房主/管理员点击自己所在麦位时,不再被“直接打开资料卡”逻辑短路,会重新回到底部麦位菜单,从而正常看到自己可用的上下麦/禁麦操作;同时上麦、下麦、禁麦、解禁、锁麦、解锁这些动作在接口成功后会立即回写本地麦位状态,并主动补拉一次最新麦位列表,减少房主端自己操作后 UI 状态延迟或短暂错乱。最新已继续收紧“换麦”场景:当前会先本地顺滑切到目标麦位,再在短保护窗内拦住把自己打回旧麦位的旧轮询/旧广播快照;同时补修 `MicRes.copyWith(user: null)` 实际不会清空用户的问题,避免切麦时出现双占位或 `1 -> 4 -> 1 -> 4` 这类来回闪动。 - 已按 2026-04-20 最新调整撤掉 `Wallet -> Recharge` 中新增的 MiFaPay 第三方支付 UI 与页面逻辑:当前充值页仅保留原生 `Google Pay / Apple Pay` 入口与商品列表,`Recharge methods` 区域也已收敛为单一原生支付卡片;此前接入的 MiFaPay 方法选择、底部弹窗、H5 收银台页以及对应页面级状态管理已从现有充值链路移除,避免继续对当前版本产生影响。 - 已按 2026-04-18 联调要求继续收口幸运礼物链路:项目默认 API host 已临时切到 `http://192.168.110.43:1100/` 方便直连测试环境;`/gift/give/lucky-gift` 请求体也已补齐为最新结构,除原有 `giftId/quantity/roomId/acceptUserIds/checkCombo` 外,会稳定携带 `gameId: null`、`accepts: []`、`dynamicContentId: null`、`songId: null` 这几组字段,便于和当前后端参数定义保持一致。 - 已继续补齐 `GAME_LUCKY_GIFT` 的 socket 播报与中奖动效:房间群消息收到该类型后,现在会统一落聊天室中奖消息、奖励弹层队列与发送者余额回写,不再只在 `3x+` 时才触发顶部奖励动画;同时全局飘窗已改为按服务端 `globalNews` 字段决定是否展示,避免再用前端本地倍率硬编码去猜。 - 已按最新 UI 口径重排幸运礼物中奖展示:顶部 `LuckGiftNomorAnimWidget` 不再叠加大头像、倍率和奖励框,只在“单个礼物倍率 `>= 10x`”或“单次中奖金币 `> 5000`”时负责播全屏 `luck_gift_reward_burst.svga`;原本的 `luck_gift_reward_frame.svga` 已改挂到房间礼物播报条最右侧,并在框内显示 `+formattedAwardAmount`,金额文案直接复用此前大头像下方那一份中奖金币额。 - 已按最新确认撤掉播报条里的 lucky combo 特殊样式:房间礼物播报条右侧的 `xN` 数字现已恢复普通礼物样式,不再在这里做幸运礼物 10/20/50/100... 的特殊放大/描边展示;这些 `lucky_gift_combo_count_xxx.svga` 资源仍保留在幸运礼物倍率/数量命中时走全屏特效链,不再和播报条 UI 混在一起。 - 已继续修正幸运礼物中奖播报条右侧奖励框不显示的问题:根因是 `pubspec.yaml` 之前只显式收录了 `sc_images/room/anim/gift/`,但没有把新的 `sc_images/room/anim/luck_gift/` 子目录单独打进 Flutter 资源清单,导致 `luck_gift_reward_frame.svga` 在运行时可引用但未被实际打包;当前已补齐资源目录声明,并为播报条奖励框增加本地 fallback,避免资源异常时再次只剩金额裸字。 - 已按最新文案口径继续收紧幸运礼物中奖消息:聊天室里高倍率幸运礼物提示不再显示冗长的 `Coins / a lucky(magic) gift` 文字,当前已改为直接展示“中奖金额 + 金币图标 + 对应礼物图”,和房间礼物播报条的视觉表达保持一致。 - 已继续微调幸运礼物中奖视觉:房间礼物播报条右侧的 `luck_gift_reward_frame.svga` 已进一步放大,并给右侧区域和主条正文预留了更宽的排版空间,避免资源已经正常显示但因为画布比例和透明边距看起来过小;同时聊天室高亮中奖消息与房间顶部幸运礼物横幅现已统一改成“中奖金额 + 金币图标 + from + 礼物图”的表达,去掉原先 `Coins / a lucky(magic) gift` 这类冗长英文文案;另外全屏 `luck_gift_reward_burst.svga` 也已补上中部金额文案,避免播发时只见特效不见本次实际中奖金币数。 - 已按 2026-04-20 最新联调继续收口幸运礼物播报噪音:顶部幸运礼物飘屏现在会对同一房间、同一送礼人、同一接收人、同一礼物的连续中奖做队列内聚合,不再每来一条都重新追加一个新飘屏;当前展示中的那一条也会直接叠加金币额并刷新,避免“刷礼过快时飘屏一条接一条排队刷过去”。同时飘屏中奖文案已强制收为单行显示,防止金额、`from` 和礼物图被挤成上下两行。 - 已继续修复房间礼物播报条偶发出现两条一模一样内容的问题:此前 `GiftAnimationManager` 只会和“正在播放”的同 `labelId` 项做合并,等待队列里的同类播报不会提前去重,因此高频情况下仍可能排出两条完全一样的条目;当前已改为在入队时同时检查“正在播”和“待播”两侧,命中相同播报键时直接原地合并,不再把重复项继续塞进队列。 - 已按 2026-04-20 最新确认继续调整幸运礼物展示逻辑:房间播报条最右侧的中奖金币现已按同一条播报累计值展示,不再每次中奖只用最后一笔金额覆盖前一笔;幸运礼物顶部飘屏则撤回此前的聚合策略,恢复为每条都单独展示,但仅当服务端倍率达到 `5x` 及以上时才触发飘屏,避免低倍率也持续刷屏;同时 `luck_gift_reward_burst.svga` 的触发链路已补上“当前房间广播兜底 + 事件去重”,即便只收到广播消息也能进队列播放,而同一事件不会因为广播/群消息双到达而重复播发。 - 已继续修正幸运礼物 `burst` 的倍率边界判断:`LuckGiftNomorAnimWidget` 内部此前仍使用旧的“倍率 `> 10x`”严格大于判断,导致刚好命中 `10x` 的中奖虽然会走飘屏链路,但不会实际触发 `luck_gift_reward_burst.svga`;当前已统一改为“倍率 `>= 10x` 或单次中奖金币 `> 5000`”。 - 已继续修正幸运礼物 `burst` 的实际播放链路:此前 `currentPlayingLuckGift` 队列会把所有幸运礼物中奖事件都排进去,哪怕只是低倍率、根本不需要播 `luck_gift_reward_burst.svga` 的那类消息,也会先占掉每次 3 秒的播放时段;这样在刷得比较密时,真正命中 `10x+` 或 `>5000` 金币的事件只是被压在队列后面,视觉上就会像“明明达标了却没触发”。当前已把队列入口改成只接收真正命中 `burst` 条件的事件,并把命中判断收口到同一处,避免顶部飘屏和 `burst` 各自走不同口径。 - 已继续调整幸运礼物播报条的连刷表现:带右侧中奖奖励框的幸运礼物播报现在会固定在各自的坑位上显示,不再跟随普通礼物滚屏那套纵向位移动画反复“刷新整条”;用户连续送同一条幸运礼物时,前端只会在原位更新右侧 `xN` 数量和累计金币,直到连刷停止后再按既有时长自然消失。 - 已继续微调幸运礼物 `burst` 中央金额文案的定位:此前这层 `+金币` 文字仍使用固定 `top` 绝对定位,实际在不同画布比例下会整体偏上,容易跑出 `luck_gift_reward_burst.svga` 中央的金额承载区;当前已改成基于整层居中后再轻微下移的相对锚点,确保金额文案稳定落在特效中间那块 `+****` 的视觉区域内。 - 已继续细调幸运礼物 `burst` 中央金额文案的纵向位置:上一版相对锚点虽然已经回到特效主体内部,但仍略偏下;当前已把对齐点和下移量一起往中间收回一档,让 `+金币` 更接近 `luck_gift_reward_burst.svga` 中央的视觉中线。 - 已继续修正幸运礼物 `burst` 中央金额文案的细节对位:当前已再上移 `2` 个单位,并给金额文本左侧补出额外留白,避免斜体 `+` 号因为字形外扩而贴边或被裁掉,确保 `+金币` 能完整落在特效中部。 - 已继续按最新联调口径修正幸运礼物 `burst` 中央金额文案:当前已去掉文本里的 `+` 字符,仅保留金币数本身显示;同时维持上一版向上微调后的纵向位置,让金额落点保持在特效中部偏上的稳定区域。 - 已继续收口幸运礼物 `burst` 金额文案与 `svga` 本体的时机同步:此前中央金币文本直接跟外层中奖数据显隐,而 `svga` 自身还存在资源加载和单次播放完成的生命周期,所以两者在出现/消失时会有肉眼可见的前后差;当前已给 `SCSvgaAssetWidget` 补上播放开始/结束回调,并让 `burst` 中央金额只在 `svga` 真正开始播时显示、在它播完清帧时一并隐藏。 - 已按 2026-04-21 最新联调继续细调幸运礼物 `burst` 中央金币文案:当前已在现有基础上再向上微调 `4` 个单位、向右微调 `5` 个单位,让金额更贴近特效中部的目标槽位;同时 `burst` 的整体展示时长也已再缩短 `1` 秒,避免命中后在屏上停留过久。 - 已继续修复幸运礼物顶部横幅 `from` 后礼物图标偶发显示不出来的问题:此前这条紫色 lucky gift 横幅只直接使用 socket 下发的 `giftCover/giftUrl` 渲染礼物图,一旦服务端该字段为空或图片加载失败,就只会退回默认占位;当前已把 `giftId` 一并挂进 `SCFloatingMessage`,并在 `FloatingLuckGiftScreenWidget` 内增加“优先用 `giftUrl`,失败时再回退到本地礼物列表缓存中的 `giftPhoto`”的双重兜底,避免横幅末尾再出现空白占位块。 - 已优化语言房麦位/头像的二次确认交互:普通用户点击可上麦的空麦位时,当前会直接执行上麦,不再先弹出只有 `Take the mic / Cancel` 的确认层;普通用户点击房间头像或已占麦位上的用户头像时,也会直接打开个人卡片,不再额外弹出仅含 `Open user profile card / Cancel` 的底部确认。房主/管理员仍保留原有带禁麦、锁麦、邀请上麦等管理动作的底部菜单,避免误删管理能力。 - 已继续收窄语言房个人卡片前的“确认意义”弹层:当前用户在麦位上点击自己的头像时,也会直接打开自己的个人卡片,不再先弹出仅包含 `Leave the mic / Open user profile card / Cancel` 的底部菜单;同时个人卡片内的“离开麦位”入口已替换为新的 `leave` 视觉素材,和最新房间交互稿保持一致。 - 已继续微调语言房个人卡片与送礼 UI:个人卡片底部动作文案现已支持两行居中展示,避免 `Leave the mic` 这类英文按钮被硬截断;房间底部礼物入口也已切换为新的本地 `SVGA` 资源 `room_bottom_gift_button.svga`,保持房间底栏视觉和最新动效稿一致。 - 已按最新要求调整普通静态礼物的自制飞向麦位动画:当前不再对队列里的每一份礼物都重复播放一整段“中央停留 + 飞行”流程,而是改为屏幕中央持续保留一张静态礼物图作为母体;队列中每累积 `1` 个请求,就从中央额外发射 `1` 次飞向目标麦位的动画,同时整体仍维持最多 `5` 个待播/在播请求的上限,避免高频赠送时中央动画反复闪动。 - 已继续优化幸运/CP 礼物连击体验:房间 `Gift/All` 消息面板现在会对短时间内同一发送者、同一目标、同一礼物的连续赠送做聚合更新,不再每点一次就追加一条新消息,而是复用同一条礼物播报并持续刷新成 `xN`;同时礼物页底部发送按钮已补上本地连击反馈,Lucky/CP/Magic 类礼物连续点击时会显示一条从右向左收缩的浅色倒计时渐变条,并同步累加当前连击数量,用户能更直观看到连击窗口是否还在持续。 - 已继续给发送端补齐连击请求聚合:礼物页当前会对 Lucky/CP/Magic 这类连击型礼物启用约 `200ms` 的本地批量窗口,用户在短时间内连续点击 `Send` 时,前端会先把同一礼物、同一目标集合、同一房间的点击数量累加到同一批次里,再统一发一次接口和一次房间 RTM 消息;这样高连击时不再按点击次数直冲 `/gift/batch` 或 `/gift/give/lucky-gift`,同时也避免本地回显和房间消息量被线性放大。 - 已按最新确认回调幸运礼物的“自制飞向麦位动画”策略:不再等整轮连击结束后只飞一次,而是改回按点击次数触发;为兼顾连击体感和队列安全,当前会通过 RTM 额外携带本批次对应的点击次数,让房间端按点击数补齐自制动画,同时同一轮幸运礼物连击的飞行动画队列最多只保留 `5` 个;当连击在 `3s` 内停止后,如果队列里还有待播动画,则只再给 `3s` 消化时间,超时后剩余待播动画会直接清掉。 - 已继续收敛幸运礼物高连击时的播放策略:房间内幸运礼物仍按 3 秒连击会话累计总次数,用来判断当前命中的最高有效档位特效;但自制飞向麦位动画已改回按点击次数触发,并通过“同会话最多保留 5 个待播/在播动画 + 连击结束后额外 3 秒清尾”的方式限制队列膨胀,不再让 `1000` 连击把静态礼物飞行动画排成超长队列;同时幸运礼物的档位特效仍保持只命中当前会话累计数量对应的最高有效档位,不再把中间跨过的 `10/20/30/...` 全部补播一遍。 - 已定位到幸运礼物“中奖通知”使用的是房间页顶层 `LuckGiftNomorAnimWidget`,此前背景一直是静态 `sc_icon_luck_gift_nomore.webp`;当前已改为优先播放本地 `sc_images/room/anim/luck_gift/luck_gift_reward_frame.svga`,而旧 `webp` 实际已不在当前仓库资源内,因此兜底已改为空白占位,避免在 SVGA 初始加载阶段反向触发 `Unable to load asset` 异常。 - 已开始接入幸运礼物连击档位的新动效资源:桌面“幸运礼物相关”目录下的 SVGA 已统一导入到 `sc_images/room/anim/luck_gift/`,并按规范重命名为 `luck_gift_combo_count_10.svga / luck_gift_combo_count_666.svga / luck_gift_combo_count_10000.svga` 这一类统一英文命名;当前连击阈值触发仍复用 `GiftSystemManager.playVisualEffect()`,命中已提供素材的档位时优先播放新的本地 SVGA,未提供素材的档位继续保留旧兜底逻辑,避免影响现有幸运礼物连击链路。 - 已将语言房送礼链路接入新的“中心停留后飞向目标麦位”组件,但只对无自带特效的静态 PNG 礼物生效:当前带自身 `SVGA/MP4/VAP` 动画或被识别为全屏礼物特效的礼物保持原有播放逻辑不变;只有普通 PNG 礼物会额外触发“屏幕中央停留 -> 三连残影飞向被赠送麦位”的补充动效,避免和自带礼物特效重复叠播。 - 已继续收敛语言房送礼飞行动效的命中条件:上一版对普通礼物的过滤过严,既依赖 `giftPhoto` 必须显式以 `.png` 结尾,也会被部分礼物的 `special` 标记误伤,导致不少实际没有自带动画的礼物被提前跳过;当前已改为只排除真实带 `SVGA/MP4/VAP` 动画源的礼物,普通静态封面礼物即使是带 query 的图片 URL、或不是严格 `.png` 后缀,也会正常触发“中心停留 -> 飞向目标麦位”的补充动画。 - 已将语言房送礼飞行动画从房间页内部 `Stack` 提升到应用根层,挂载方式对齐现有 `SVGA/VAP` 礼物特效层:当前该动画会和 `VapPlusSvgaPlayer` 一样在 `main.dart` 的顶层 builder 中全屏绘制,因此不会再被房间内部聊天区、局部动效或页面层级压住,视觉上更靠前、更容易被用户看到。 - 已修复礼物页幸运礼物发送链路:当前 `gift_page` 会按礼物类型分流,普通礼物继续走 `/gift/batch`,`LUCKY_GIFT/LUCK/MAGIC` 改走已存在的 `/gift/give/lucky-gift`;幸运/魔法礼物成功后不再本地伪造普通 `GIFT` 消息,而是改发房间内 `LUCK_GIFT_ANIM_OTHER` 动画消息,避免和后端幸运礼物开奖/补发逻辑打架;同时送礼失败已补用户提示,且对 `standardId` 缺失的幸运礼物增加了前置拦截,避免继续点发送却只有日志没有反馈。 - 已继续补齐幸运礼物前端可见反馈:根据真机日志确认 `giveLuckyGift` 和腾讯 IM 房间消息发送都已成功,当前问题收敛为发送端没有本地回显、且 `LUCK_GIFT_ANIM_OTHER` 收到后未真正接入房间礼物动画;现已在发送成功后先本地触发一轮房间礼物上飘反馈,并把收到的 `LUCK_GIFT_ANIM_OTHER` 直接接入现有房间礼物动画 listener,确保发送端和房间内其它端都能看到即时反应。排障期间临时加过的发送并发锁已在后续需求确认后撤回,不再限制幸运礼物连点。 - 已按最新确认调整幸运礼物点击策略:撤回前一轮为排障临时加上的发送并发锁,恢复幸运礼物可连续点击;当前连点时每次请求仍走 `/gift/give/lucky-gift`,并继续通过本地回显 + `LUCK_GIFT_ANIM_OTHER` 接入现有房间礼物动画 listener 的方式提供与普通礼物一致的即时播报体验。 - 已继续优化房间礼物播报 UI:礼物上飘条目高度与内部约束已重新收紧,修复底部 `bottom overflow`;同时为幸运礼物新增 10/20/50/100/200/300 连击特殊样式,这些档位的连击数字会以更大的“霸气金”渐变字显示,普通礼物与非里程碑连击保持原样式。 - 已修复 `Me -> Friends/Fans 列表 -> 他人主页 -> 返回 Me` 后个人资料串号的问题:`MePage2` 现只读取当前登录用户资料,`SocialChatUserProfileManager.userProfile` 继续只承载“当前查看中的详情页用户”,同时移除了 `syncCurrentUserProfile()` 对详情态的覆盖,避免查看他人资料后把 `Me` 页错误渲染成对方信息。 - 已按本轮动效替换需求完成首页底部 tab 动效接入,并同步将本轮新增本地 `.svga` 资源统一改成项目命名风格:当前 `Home / Explore / Message / Me` 已分别使用 `sc_icon_home_anim.svga / sc_icon_explore_anim.svga / sc_icon_message_anim.svga / sc_icon_me_anim.svga`,并继续保留原有 png 作为失败兜底;后续新增本地动效资源默认也按 `sc_icon_*_anim` 规则命名。 - 已将语言房右侧 `game` 悬浮入口从 emoji 占位替换为本地动效资源,并按最新反馈移除外层圆形 `container`:当前直接使用 `sc_icon_room_game_entry_anim.svga` 本体作为入口展示,尺寸与原入口占位一致;若 SVGA 加载失败,会自动回退到项目原有 `sc_icon_botton_game.png`。 - 已按最新反馈撤回语言房房间麦位声波的 SVGA 替换,当前已恢复为项目原有展示:VIP3/4/5/6 继续使用原先的 `webp` 声波资源,普通麦位回到原来的纯色圆形扩散效果;说话触发阈值与错峰扩散逻辑保持不变。 - 已修复语言房顶部左侧房间榜单入口出现 `right overflowed` 的问题:当前贡献值区域已改为约束宽度 + 自适应缩放文本,不再因为积分位数变长把右箭头顶出容器。 - 已根据最新确认回退首页 Party 区的 `recommend_rank_top` 三个素材替换:财富榜、房间榜、魅力榜前三头像现已恢复为原先版本,不再在该位置叠加 `recommend_rank_top` 动态头像框;相关素材仍保留在工程内并已按规范重命名,后续待确认真正使用位置。 - 已新增通用本地 SVGA 资源组件 `lib/ui_kit/widgets/svga/sc_svga_asset_widget.dart`,用于统一处理本地 assets 解码、内存缓存、单次播放/循环播放和失败兜底;当前首页底部 tab 和语言房 game 按钮已复用这套实现,便于后续继续接入其它本地动效资源。 - 已按最新语言房底部栏视觉需求完成 UI 重构:底部 5 个入口现改为同一水平基线布局,移除礼物按钮原先的中间悬浮 `Stack` 结构,并按最新顺序调整为“输入入口、礼物、麦克风、菜单、消息”;其中消息入口已移动到最右侧,且在麦克风隐藏时,礼物、菜单、消息 3 个入口会自动向右收拢成一组,避免中间留空。 - 已将语言房左侧输入入口改为独立组件:当前已撤回自绘聊天气泡图标方案,直接恢复使用项目原有的 `sc_images/room/icon_room_input_t.png` 资源作为左侧输入 icon,并继续放入约三分之一屏宽的圆角矩形中,右侧保留多语言问候文案 `roomBottomGreeting`,避免继续在自绘气泡尾巴形态上反复调整。 - 已将语言房礼物入口拆成独立组件:礼物图标缩小后当前尺寸只略大于右侧 3 个圆按钮,并保留常驻轻量摇晃动画;根据最新反馈,当前已移除礼物按钮的粒子特效,并进一步去掉礼物入口外层 `container`,直接使用与原先按钮壳同尺寸的礼物图片本体作为可点击 UI,避免额外底壳干扰观感。 - 已统一语言房其余四个入口的按钮壳样式:输入入口、消息、菜单、麦克风现统一使用淡色半透明背景 container,消息红点计数、菜单弹窗、消息跳转和麦克风开关等原有功能逻辑保持不变,本轮只调整 UI 展示与布局层。 - 已继续强化语言房右侧消息与麦克风入口的识别度:消息图标已替换为项目内更明显的信封样式资源 `sc_icon_send_user_message.png`,麦克风图标则在不改变按钮壳尺寸的前提下放大到更接近其它入口的可视大小,减少“图标偏小、不够醒目”的问题。 - 已按最新交互要求调整麦克风隐藏态布局:当第 4 个图标(麦克风)可见时,底部栏保持当前 5 个槽位的位置不变;当麦克风隐藏时,不再为其保留空槽位,礼物、消息、菜单 3 个入口会自动向右收拢成一组,避免右侧中间出现空位。 - 已排查语言房“双设备、不同账号进入同一房间,上麦后无声”的直接原因:当前 RTC 进房时统一以 Agora `Audience` 身份加入频道,见 `lib/services/audio/rtc_manager.dart` 中 `joinChannel()` 的 `clientRoleType: clientRoleAudience`;而本地麦克风开关 `isMic` 默认值为 `true`(当前语义实际是“闭麦”),上麦 `shangMai()` 后只有在 `!isMic` 时才会切到 `Broadcaster` 并取消本地静音,所以“只上麦、不点底部麦克风按钮”时不会发声。 - 已补充语言房当前真实交互结论:现有实现里“上麦”和“开麦”是两个动作。用户点空麦位后只是占麦;还需要再点击底部麦克风按钮,触发 `lib/ui_kit/widgets/room/room_bottom_widget.dart` 中的角色切换,才能真正开始向房间发送音频。 - 已同步补充该需求的后续决策点:如果产品预期是“上麦即能说话”,则需要单独改需求并调整实现为“上麦成功后自动切 `Broadcaster` 且自动开麦”;如果继续保留当前双步骤交互,则至少要补一条明确提示文案/引导,并把“双设备不同账号同房,上麦后需手动开麦才能互听”加入验收用例,避免测试误判为 RTC 故障。 - 已重新收敛语言房无声修复方案:撤回上一轮会影响进房的较大改动后,当前改为只做最小行为修补,不触碰进房和 token/join 链路;已在“底部麦克风点开”和“麦位解除静音且本人处于开麦态”两条路径上补齐 `muteLocalAudioStream(false)`,修正 UI 显示已开麦但 Agora 本地音频流仍保持静音的问题。 - 已按测试收尾要求移除语言房 RTC 诊断面板:该组件仅用于当前无声问题的真机排查,现已从房间页和相关临时诊断代码中整体删除,不作为正式功能保留。 - 已为语言房页面补充右下方 `game` 悬浮入口:入口位于聊天区右下侧、距右侧约 `15.w`、位于底部操作栏上方约 `100.w`,当前先使用代码绘制的 `🎮` 占位图标,并已在实现处标注后续替换为正式 UI 图片资源。 - 已新增语言房游戏底部弹窗:点击 `game` 入口后会从底部弹出约三分之一屏高的面板,采用房间页现有半透明磨砂风格,便于后续继续沿用当前视觉体系。 - 已补齐语言房游戏列表占位结构:弹窗内部先用静态游戏数据驱动,并按“`ListView` 可上下滑动 + 每行 `5` 个图标位”的方式实现,后续只需替换入口图、列表图标和真实接口数据即可继续开发。 - 已排查语言房游戏 H5 无法正常加载的直接原因:当前房内 BAISHUN 游戏页把“加载完成”几乎完全绑定在 H5 主动回调 `gameLoaded` 上,同时 `window.NativeBridge` 又是在 WebView `onPageFinished` 后才注入;真实 H5 若在更早的启动阶段就尝试读取桥接配置或判定 NativeBridge 是否存在,就会错过这次注入,表现为页面一直停留在 `Waiting for gameLoaded...`,因此问题核心更接近“App 与 H5 的桥接初始化时序不稳 + 加载态过度依赖 H5 回调”,而不只是单纯的页面 URL 无法访问。 - 已对语言房游戏 H5 链路补齐客户端兜底:房内游戏页现在会在页面启动阶段提前并重复尝试注入 BAISHUN bridge,不再只等首个 `onPageFinished`;同时加载遮罩已增加超时收口,不会因为 H5 没有及时回调 `gameLoaded` 就无限卡住。桥接侧也已补充 `getConfigSync`、全局配置缓存和 `baishunBridgeReady/baishunConfig` 事件分发,降低 H5 初始化阶段拿不到配置的概率,便于继续和 H5 联调确认其最终采用的接入方式。 - 已按《BAISHUN 游戏对接文档 1.3.2》重新核对客户端桥接协议:文档里的核心要求并不只是 `NativeBridge` 存在,还包括 `getConfig` 入参携带 `jsCallback`、客户端回调指定 JS 函数、以及 Flutter 章节单独列出的 `getConfig / destroy / gameRecharge / gameLoaded` 四个通道名;当前房内游戏桥接已补充这些文档协议的兼容层,便于直接验证真实 H5 当前到底走的是哪一条调用路径。 - 已新增 BAISHUN 临时调试面板,并封装为独立组件 `lib/modules/room_game/views/baishun_debug_panel.dart`:面板会展示 `entryUrl`、桥接注入次数、最近一次 `jsCallback`、最后一条桥接消息及日志列表,并提供 `Reload / Inject / ReplayConfig / Wallet / ClearLogs` 操作,专门用于这次房内游戏 H5 真机联调;该面板不是正式功能,后续调试完成后需要整块删除。 - 已根据 BAISHUN 文档中“`code` 为一次性参数且唯一”的约束继续收紧客户端下发策略:当前房内游戏页在 bootstrap / `pageFinished` 阶段只注入桥接方法,不再主动把完整配置反复推给 H5;真正含 `code` 的配置现在只会在 H5 明确调用 `getConfig` 后回一次,避免因为重复下发一次性 `code` 导致 BAISHUN 后续拉取 `sstoken / user_info` 失败。调试面板也已补充 `ConfigSend` 计数和最近一次配置摘要,便于真机确认是否存在重复下发。 - 已继续增强 BAISHUN 临时调试面板的排障能力:当前已在 H5 侧临时注入 `fetch / XMLHttpRequest / window.onerror / unhandledrejection` 日志回传,相关失败请求、状态码和响应片段会直接显示在 `Recent Logs`,专门用于继续定位当前 `get user info failed` 是否发生在百顺后续拉取 `sstoken / user_info` 的网络链路;这同样只是联调用临时能力,后续调试完成后需要删除。 - 已根据《BAISHUN 游戏对接文档 1.3.2》补齐 `language` 字段兼容:文档表 3 要求传给游戏的语言值是字符串数字枚举(如英文 `2`、阿语 `7`、土耳其语 `10`),而当前客户端真实下发值曾是 `en`;现已在房内游戏页发送配置前统一转换为 BAISHUN 约定值,并把 `raw -> normalized` 结果记录进调试日志,便于继续确认 `get user info failed` 是否由协议字段不匹配导致。 - 已根据最新真机日志继续收敛 BAISHUN 问题边界:当前调试面板已确认 `ConfigSend=1`、`language=2(raw=en)`、`getConfig_1_complete` 与 `gameLoaded_1_complete` 都已正常走通,说明 Flutter 侧桥接、语言字段和“一次性 code 重复下发”目前都不是主要矛盾;同时 `Recent Logs` 里未出现浏览器侧 `fetch/XHR` 失败,但仍出现 `get user info failed` 弹窗与 H5 内部 `InvalidStateError`,因此当前更倾向于 BAISHUN 服务端继续调用商户侧 `/v1/api/get_sstoken` / `/v1/api/get_user_info` 的链路失败,或其返回内容不符合文档要求,H5 页面里的报错更像后续症状而非首因。 - 已继续增强 BAISHUN 临时调试能力用于下一轮真机排障:当前除了原有 `fetch/XHR/window.onerror/unhandledrejection` 外,还会额外回传 H5 的 `console.log/info/warn/error` 与资源加载失败信息,并把本地日志保留条数放宽到 `80` 条、面板日志区适当加高;这些都只服务当前联调,不属于正式功能,问题定位完成后需要一并删除。 - 已通过 2026-04-16 真机最新控制台日志拿到更直接的证据:H5 侧明确打印了 `{"msgId":"Connect","errCode":1015,"errMsg":"1015-SSToken接口错误","data":null}`,并伴随 `WebSocket Error / WebSocket Close / Reconnect` 日志,说明当前问题已可进一步收敛为百顺游戏在建立长连接前获取 `SSToken` 失败;这表明主要矛盾已经不在 Flutter 容器桥接,而在百顺服务端访问商户侧 `/v1/api/get_sstoken` 的链路、该接口的业务结果、或其返回格式与文档约定不一致。 - 已继续定位“游戏画面可见但触摸无响应”的 Flutter 侧原因:当前实现此前一直把 BAISHUN H5 页面放在 `showGeneralDialog` 底部弹层里承载,同时 App 启动时又全局锁定了 `portraitUp`;对于 `FishingStar` 这类横版游戏,这会叠加出“平台视图在弹层容器中的命中不稳定 + iPhone 端实际不支持横屏”的问题。现已改为用独立路由承载 BAISHUN 游戏页,并按启动数据里的 `orientation` 动态切换横竖屏;同时 iOS `Info.plist` 已补充手机横屏支持,便于继续验证横版游戏触摸是否恢复。上述调整仍属于本轮 BAISHUN 联调修正,不是新的正式产品交互。 - 已按最新联调反馈回撤 BAISHUN 页面的横屏适配:当前后续不会接横屏游戏,因此已去掉游戏页按 `orientation` 切换系统方向的逻辑,并撤回 iPhone 端新增的横屏声明,只保留独立路由承载 BAISHUN 页面这一项 Flutter 容器修正。同时已继续增强临时调试,在 H5 侧补充 `pointerdown / touchstart / mousedown / click` 事件回传,用于下一轮真机直接确认“点击是否真的进到了 H5 DOM”;这些输入事件日志依旧只用于本轮排障,后续需要删除。 - 已按当前收尾需求移除 BAISHUN 临时调试面板:`BS DEBUG` 组件和相关调试入口现已从游戏页删除,不再作为正式功能保留;同时游戏页展示高度已恢复为接近半屏的底部弹出样式,回到最初设定的房内游戏视觉形态。 - 已继续微调 BAISHUN 游戏页高度:由于真实 H5 内容本身就是接近半屏,且顶部还需要预留拖拽条和标题栏空间,当前底部游戏页容器高度已从上一版的 `0.56` 屏高上调到 `0.62`,避免视觉上看起来比预期半屏更矮。 - 创建并持续维护进度跟踪文件。 - 已继续排查语言房 gift 动画链路:确认送礼后会同时走本地房间消息、滚屏礼物条和大额礼物全局飘屏三条路径,并修复动画管理器在控制器尚未绑定完成时提前消费队列导致后续动画不再播放的问题。 - 已定位并修复语言房礼物飘屏资源引用错误:代码里误写 `sc_icon_gift_flosc_bg` / `sc_icon_luck_gift_flosc_*`,实际资源文件名为 `float`,导致点击送礼后飘屏背景图加载失败,相关动画无法正常显示。 - 已继续定位语言房礼物特效不播放的根因:后端礼物配置返回的特效标记为 `ANIMATION`,而前端历史代码只识别拼写错误的 `ANIMSCION`,导致送礼后直接跳过全屏/半屏特效播放;现已改为同时兼容两种标记。 - 已继续优化语言房礼物特效播放性能:将礼物资源预热改为“后台串行预加载 + 选中礼物高优先级预加载 + 播放阶段复用同一解码/下载任务”,避免送礼时重复下载或重复解码同一个 `.svga/.mp4`;同时为全屏播放器增加 `RepaintBoundary`,并改为按原始比例渲染、关闭越界绘制,减少整页重绘和过度放大带来的卡顿。 - 已继续优化礼物二级页首屏与翻页加载体验:礼物配置改为会话内复用,避免每次打开礼物面板都重新拉列表;首屏与翻页页卡增加整页骨架态,页面图片预热改为“当前页并发预热 + 下一页提前预热”,并增加“最短可感知骨架时长 + 最长骨架保护窗口”,避免整页骨架一闪而过;超过上限后再切换到真实卡片,并让单个礼物继续使用小 `loading` 占位补齐,整体交互对齐常见直播 app 的礼物面板体验。 - 已修复首页房间封面显示链路:兼容接口 `roomCover/cover` 双字段,并补齐编辑房间成功后的封面内存回写。 - 已继续修复房间设置保存封面后丢失的问题:房间保存接口改为兼容提交 `id/roomId` 与 `roomCover/cover`,并在保存成功后优先保留刚提交的封面、名称、公告,避免被空响应覆盖。 - 已新增按房间 ID 的本地房间资料缓存兜底:首页、我的房间、历史/关注、搜索和再次进入房间都会优先回填最近一次本地保存的封面;同时已将房间封面空态图替换为新的 `sc_no_data.png`。 - 已确认房间封面上传接口与 `PUT /room/profile` 保存接口都返回了正确图片地址,并修正首页/重进房间的取值优先级,避免被列表接口短时间返回的旧封面或无效封面重新覆盖。 - 已继续完善个人主页头像与滚动表现:顶部小头像保持纯头像,主头像恢复头像框叠加;同时将个人主页背景并入可滚动 header,修复滑动时内容与背景不同步的问题。 - 已进一步统一头像框方案:共享头像组件改为“头像居中 + 头像框包边”结构,并对这类静态头像框资源增加白底去除处理,不再简单把头像框整张盖在头像上;个人主页主头像与房间麦位头像现已同步采用这一展示方式。 - 已修复静态头像框透明区域误变黑的问题:调整头像框白底透明化公式后,进入房间时不再出现只有头像附近有颜色、其余房间背景被黑块覆盖的现象。 - 已修复个人主页首屏黑屏与内容区多余圆角问题:为个人页补充稳定的底图/底色占位,避免进入页面时先出现黑屏;同时移除资料内容区顶部多余圆角。 - 已将个人主页首屏占位升级为骨架屏:进入个人页时会先按真实版式展示头像、昵称、计数区、Tab 和资料内容的骨架块,不再先露默认背景等待约 1 秒。 - 已为首页 Party 页补齐首屏骨架屏:顶部 H5 榜单现按三列奖杯卡位展示头像/标题骨架,下方房间区改为双列房卡骨架,并采用深绿底 + 金色描边的项目内风格;同时拆分榜单与房间列表加载态,仅在“首屏无内容加载”时展示骨架,避免下拉刷新时整页闪烁。 - 已为首页 My 板块补齐首屏骨架屏:`My room` 顶部房间卡片改为独立加载态,避免首屏把“正在加载我的房间”误显示成“去创建房间”;`Recent/Followed` 两个子页也已改成同风格双列房卡骨架,进入 tab 时会先展示完整结构占位,再按真实数据切换。 - 已为 `Me` 入口下的 `Store / Bag` 页面补齐首屏骨架屏:四类 `store` 商品页和四类 `bag` 物品页在“首屏空数据加载”阶段都会先展示同风格的三列卡片骨架,不再只显示小菊花;同时已为商品/物品名称补齐宽度约束与省略号处理,避免超长文案顶出卡片。 - 已将通用图片加载占位从静态 `loading` 图片升级为代码绘制的环形转点组件:礼物二级页单卡封面、`Store / Bag` 商品图以及复用共享图片组件的网络图,在“加载中”阶段都会显示动态转圈效果;而图片失败或 `no data` 时仍保持原有占位图,不混淆加载态与空态。 - 已继续细化首页房卡体验:`My` 板块房卡骨架数量已从 `4` 个补齐到 `6` 个,与首页 Party 首屏保持一致;同时将房卡右下角原本的静态绿色“直播中”图片替换为代码驱动的三段式动态音频条,首页、我的、搜索结果和房间浮窗现都会展示跳动效果,不再依赖静态资源图;最新已把动效调整为“单周期完整峰谷 + A/B/C 错峰起伏”的连续波形,观感更接近直播音频电平。 - 已继续微调首页房卡信息密度:房卡底部房名与在线人数字号已统一调小,和动态音频条更协调;同时已移除 `My` 板块顶部 `my room` 标题及其占位,让房间卡片整体上移,对齐更紧凑。 - 已继续微调首页视觉细节:房卡底栏房名再次缩小并轻微上移,和国旗、动态音频条、人数的中线更一致;首页顶部排行骨架也已简化为“3 个圆形头像 + 1 根文本条”,更贴近真实卡片结构。 - 已补回首页 Party 顶部 banner 展示链路:顶部现优先显示原有 `explore` banner,并在该分组为空时自动兜底使用首页 `home` banner,避免整块区域消失;同时首屏 banner 空数据加载阶段已补充同风格骨架占位,不再直接塌陷为零高度。 - 已继续微调首页 Party 顶部 banner 体验:banner 与下方排行组件之间已补齐接近房卡区的纵向间距;当 banner 只有 `1` 张时,会关闭无限轮播与横向回弹,左右滑动不再弹回中间。 - 已继续收窄首页 Party 顶部 banner 骨架样式:banner 骨架现改为更干净的整块占位,不再在中间叠加长方形白条,首屏观感更接近真实 banner 的整体加载。 - 已优化语言房顶部成员入口的点击范围:右上角在线成员区域现已将左侧头像堆叠区与右侧成员图标统一为同一点击热区,用户点击头像区也可直接打开成员列表页。 - 已继续修复房间封面跨用户不同步问题:当列表或进房返回空封面时,客户端会自动补拉 `room/profile/specific` 详情并缓存真实封面;同时房主保存房间资料后会向房间内其他用户派发资料刷新消息,避免只有自己能看到新封面、其他用户仍显示 `no data`。 - 已修复个人主页编辑页头像上传后无变化的问题:上传成功后会先本地回写新头像地址并立即提交;资料更新接口现同时兼容 `userAvatar/avatar` 字段,且不再被紧接着的旧资料回拉覆盖,返回个人主页后头像会即时更新。 - 已进一步定位图片 `no data` 根因并修复客户端加载链:日志确认房间封面详情接口可返回正确公网 `media...` 地址,但用户头像接口会返回 `jvapi.../external/oss/local/...` 这类受保护资源地址;共享图片组件现已对这类地址自动补齐鉴权请求头,避免其它用户侧加载时直接失败为 `no data`。 - 已直接校验头像异常地址的服务端返回:`jvapi.../external/oss/local/...` 当前会返回 `500 local disk file does not exist`,并非单纯鉴权缺失;前端现已在编辑资料成功后与本人资料回拉时优先保留刚上传成功的公网头像,避免再次被这类坏地址覆盖,同时修复了房间消息用户资料缓存未真正失效的笔误。 - 已继续修正个人资料更新接口的提交结构:排查发现注册接口使用嵌套 `profile`,而资料更新接口此前只发扁平字段;现已改为同时提交 `id + 扁平字段 + profile`,并在 `profile` 内同步带上 `userAvatar/avatar`,用于兼容后端可能按嵌套对象取值的情况。 - 已按最新联调结果再次收窄个人资料更新参数:日志已证明后端能收到请求但会忽略新头像地址,当前已改为头像相关只提交单一 `userAvatar` 字段,并移除 `avatar/profile` 冗余结构,便于继续验证后端是否对字段名或重复参数敏感。 - 已继续将个人页头像上传链路与通用资料提交拆开:上传成功后当前会单独触发一次仅含 `userAvatar` 的更新请求,不再混带昵称、性别、年龄、国家等字段,便于排除其它参数对头像更新接口的干扰。 - 已继续收敛个人主页资料编辑页提交行为:当前已移除资料列表页中的 `country` 条目及对应跳转/提交逻辑,并将昵称、性别、生日、Bio、Hobby、头像改为“改哪项只提交哪项”的增量更新;同时修正生日弹窗只会在确认且日期真实变更后才触发提交,避免取消或未改动时误发请求。 - 完成仓库结构、依赖引用、资源体积和 APK 组成的第一轮排查。 - 移除 4 个当前未在业务层直接使用的插件依赖:`loading_indicator_view_plus`、`social_sharing_plus`、`flutter_foreground_task`、`on_audio_query`,并清理相关平台声明。 - 修补 `image_cropper 5.0.1` Android 兼容问题,切换到本地 path 依赖以恢复构建。 - 完成 Android release 签名回退配置,解决仓库缺少 `yumi.jks` / `yumi_debug.jks` 时无法继续本地构建分析的问题。 - 完成 release 包体分析,确认 universal APK 过大主要由多 ABI 与 Agora/Tencent 原生 so 导致。 - 去除 Gradle 中与 Flutter 冲突的硬编码 `abiFilters`,确认 `--split-per-abi` 可以正常产出分架构 APK。 - 完成 TinyPNG 环境核查,并接入可执行的 Ruby 批量压缩脚本。 - 已完成 TinyPNG 第一轮批量压缩,`sc_images + assets` 总量已从 `47.25 MB` 降到 `22.54 MB`。 - 已增强 TinyPNG 脚本,支持断点续跑、单文件目标和失败项重试。 - 已完成 TinyPNG 网络失败项补跑,6 张 `SSL_connect` 异常图片已全部压缩成功。 - 已完成图片压缩后的 release 复测,确认分 ABI APK 体积继续显著下降。 - 已切换 Android `release` 为真正的瘦身模式:开启 `minify`、`shrinkResources`、`zipAlign`。 - 已完成开启瘦身配置后的 Android release 复测,并接入 `split-debug-info` 保存 Dart symbols。 - 已生成统一的 Python 打包脚本 `scripts/build_release.py`,开始接管 `AAB`、分 ABI APK 与 iOS 包流程。 - 已完成 `scripts/build_release.py` 的 Android / iOS 真机冒烟验证,产物归档目录与 manifest 均已生成。 - 已按当前需求再次完成正式 `AAB` 出包。 - 已定位 Google Play 上传阻塞点:当前 `AAB` 使用的是 `Android Debug` 证书签名,不是正式 upload key。 - 已确认当前项目属于“首次上架的新应用”,后续应走 Play App Signing 首发流程,而不是兼容老签名迁移流程。 - 已梳理 Google Play 首次上架所需的 `Play App Signing`、`upload key`、重新打包与提审步骤。 - 已澄清首次生成 `upload keystore` 时的“密钥库口令”是本地自行设置的密码,与 Google 提供的 `deployment_cert.der` 证书文件无关。 - 已为新应用生成正式 `upload keystore`,并接入工程的 release 签名配置。 - 已重新打出正式 `AAB`,并确认其签名已经从 `Android Debug` 切换到新的 upload key。 - 已定位 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 的来源为 Agora `full-screen-sharing` 依赖,并开始从主 Manifest 覆盖移除。 - 已移除 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 相关声明并重新打出正式 `AAB`。 - 已按当前需求打出正式 `arm64-v8a` 单架构 `APK`。 - 已将新的 `google-services.json` 替换进工程,准备重新打包验证。 ## 进行中模块 - 评估 iOS 正式签名参数接入后导出 `.ipa` 的流程。 - 继续评估 Agora 扩展 so 与 release shrink 策略是否还能进一步裁剪。 - 评估 12 张 TinyPNG 不支持解码的特殊 `webp` 是否需要改格式或换工具处理。 ## 关键技术决策 - 先做高置信度瘦身:优先清理未使用插件、ABI 配置和超大图片,暂不贸然删除核心业务能力。 - 避开仓库中用户已有未提交改动,只改必要文件并持续把结果写入本文件。 - 包体分析聚焦 release 产物,不被 `build/`、iOS 中间产物等本地缓存误导。 - Android 架构裁剪交给 Flutter 构建命令驱动,不再在 Gradle 中硬编码 `abiFilters`。 - 对 `image_cropper` 采用本地 path 依赖加最小补丁策略,避免升级带来的业务回归面。 - Android 签名配置采用条件回退:正式 keystore 不存在时自动回退到 debug 签名,仅用于本地分析验证。 - 图片压缩优先走 TinyPNG,以尽量保持画质稳定;失败项按原因分流处理。 - TinyPNG 的 `SSL_connect` 视为可重试网络抖动;`Image could not be decoded` 视为 TinyPNG 对特殊/动图 WebP 的能力边界,先记录不阻塞其余压缩。 ## 已改动文件 - `需求进度.md` - `lib/main.dart` - `lib/modules/wallet/recharge/recharge_page.dart` - `lib/shared/business_logic/models/res/sc_mifa_pay_res.dart` - `lib/shared/business_logic/repositories/config_repository.dart` - `lib/shared/data_sources/sources/repositories/sc_config_repository_imp.dart` - `lib/shared/data_sources/models/enum/sc_gift_type.dart` - `lib/shared/tools/sc_network_image_utils.dart` - `lib/shared/tools/sc_gift_vap_svga_manager.dart` - `lib/shared/tools/sc_room_effect_scheduler.dart` - `lib/services/general/sc_app_general_manager.dart` - `lib/shared/data_sources/sources/local/floating_screen_manager.dart` - `lib/ui_kit/widgets/room/floating/floating_gift_screen_widget.dart` - `lib/ui_kit/widgets/room/floating/floating_luck_gift_screen_widget.dart` - `lib/services/room/rc_room_manager.dart` - `lib/services/gift/gift_animation_manager.dart` - `lib/services/audio/rtc_manager.dart` - `lib/modules/room/voice_room_page.dart` - `lib/ui_kit/widgets/room/anim/l_gift_animal_view.dart` - `lib/ui_kit/widgets/room/anim/room_entrance_screen.dart` - `lib/ui_kit/widgets/room/anim/room_gift_seat_flight_overlay.dart` - `lib/modules/room/edit/room_edit_page.dart` - `lib/modules/user/edit/edit_user_info_page2.dart` - `lib/shared/data_sources/sources/repositories/sc_user_repository_impl.dart` - `lib/shared/data_sources/sources/repositories/sc_room_repository_imp.dart` - `lib/modules/splash/splash_page.dart` - `lib/modules/splash/last_weekly_cp_splash_cache.dart` - `lib/modules/splash/weekly_star_splash_cache.dart` - `lib/shared/tools/sc_room_profile_cache.dart` - `lib/shared/business_logic/models/res/room_res.dart` - `lib/shared/business_logic/models/res/follow_room_res.dart` - `lib/shared/business_logic/models/res/my_room_res.dart` - `lib/shared/business_logic/models/res/sc_edit_room_info_res.dart` - `lib/shared/business_logic/models/res/join_room_res.dart` - `lib/ui_kit/components/sc_compontent.dart` - `lib/ui_kit/components/sc_float_ichart.dart` - `lib/modules/index/index_page.dart` - `lib/modules/room/seat/sc_seat_item.dart` - `lib/ui_kit/widgets/room/room_head_widget.dart` - `lib/ui_kit/widgets/room/room_game_bottom_sheet.dart` - `lib/ui_kit/widgets/svga/sc_svga_asset_widget.dart` - `lib/modules/room/detail/room_detail_page.dart` - `lib/modules/home/popular/party/sc_home_party_page.dart` - `lib/modules/home/popular/mine/sc_home_mine_skeleton.dart` - `lib/modules/home/popular/follow/sc_room_follow_page.dart` - `lib/modules/home/popular/history/sc_room_history_page.dart` - `lib/modules/home/popular/mine/sc_home_mine_page.dart` - `lib/ui_kit/widgets/room/room_live_audio_indicator.dart` - `lib/modules/search/sc_search_page.dart` - `sc_images/index/sc_icon_home_room_rank_border_1.svga` - `sc_images/index/sc_icon_home_room_rank_border_2.svga` - `sc_images/index/sc_icon_home_room_rank_border_3.svga` - `lib/modules/store/headdress/store_headdress_page.dart` - `lib/modules/store/mountains/store_mountains_page.dart` - `lib/modules/store/theme/store_theme_page.dart` - `lib/modules/store/chatbox/store_chatbox_page.dart` - `lib/modules/user/my_items/headdress/bags_headdress_page.dart` - `lib/modules/user/my_items/mountains/bags_mountains_page.dart` - `lib/modules/user/my_items/chatbox/bags_chatbox_page.dart` - `lib/modules/user/my_items/theme/bags_theme_page.dart` - `lib/ui_kit/widgets/store/store_bag_page_helpers.dart` - `sc_images/general/sc_no_data.png` - `sc_images/splash/sc_weekly_star_bg.png` - `sc_images/splash/sc_icon_weekly_star_rank_1.png` - `sc_images/splash/sc_icon_weekly_star_rank_2.png` - `sc_images/splash/sc_icon_weekly_star_rank_3.png` - `sc_images/splash/sc_last_weekly_cp_bg.png` - `sc_images/splash/sc_icon_last_weekly_cp_rank_1.png` - `sc_images/splash/sc_icon_last_weekly_cp_rank_2.png` - `sc_images/splash/sc_icon_last_weekly_cp_rank_3.png` - `.gitignore` - `android/key.properties` - `pubspec.yaml` - `pubspec.lock` - `lib/ui_kit/components/dialog/dialog.dart` - `android/app/src/main/AndroidManifest.xml` - `android/app/google-services.json` - `ios/Runner/Info.plist` - `scripts/tinypng_batch.rb` - `scripts/build_release.py` - `tinypng-progress.json` - `tinypng-report.json` - `local_packages/image_cropper-5.0.1-patched/android/src/main/java/vn/hunghd/flutter/plugins/imagecropper/ImageCropperPlugin.java` - `local_packages/image_cropper-5.0.1-patched/` - `android/app/build.gradle.kts` - `android/app/upload-keystore.jks` - `android/app/upload_certificate.pem` - `build/symbols/android/` - `build/symbols/ios/` - `dist/release/smoke-android/` - `dist/release/smoke-ios/` - `sc_images/` - `assets/` ## 已验证结果 - 已通过代码与资源目录交叉核对确认:房内礼物飘屏当前报错 `Unable to load asset: "sc_images/room/sc_icon_gift_flosc_bg.png"` 的根因是资源名拼写错误,而不是消息未下发;工程内实际存在的资源文件为 `sc_icon_gift_float_bg.png`、`sc_icon_luck_gift_float_bg1~5.png`、`sc_icon_luck_gift_float_n_bg.png`。 - 已确认当前“点击赠送没有动画”至少包含一类前端资源问题:大额礼物/幸运礼物飘屏 widget 已进入渲染,但因为背景图 asset 路径写错而无法显示;全屏 `SVGA/VAP` 特效是否播放仍取决于具体礼物是否带有 `giftSourceUrl`,且 `special` 包含 `ANIMSCION/ANIMATION/GLOBAL_GIFT` 之一。 - 已完成一轮针对卡顿的代码级优化:礼物列表现在只会对真正需要全屏特效的礼物做受控预热;用户选中礼物时会立即高优先级预热该礼物;播放器播放时优先复用内存里的 `MovieEntity` 或同一路径的在途任务,不再重复发起网络下载/重复解码;渲染层也已改为独立重绘边界以减少房间整页跟随重绘。 - 已通过 GiftFX 调试日志确认:示例礼物 `阿拉伯舞蹈` 实际返回 `giftSourceUrl=.svga` 且 `special=ANIMATION`,此前前端因为不识别该标记而输出 `skip local play because special does not include ANIMSCION/GLOBAL_GIFT`;本轮已补齐 `ANIMATION` 兼容判断。 - 礼物二级页当前已按“整页骨架 + 当前页并发预热 + 下一页提前预热 + 单卡小 loading 占位”的方式重构首屏加载策略:首次进入和翻页时不会再直接暴露 `noData` 图,且整页骨架会保留一个可感知时长,不再一闪而过;当前页礼物封面会并发预热而不是等每个格子各自串行体感加载。 - 当前工作区存在用户已有未提交改动,后续处理均避开覆盖。 - 首页 `party/follow/history/mine` 以及房间详情使用的房间封面模型已兼容 `roomCover` 与 `cover` 两种返回字段,上传封面后不会再因为字段名不一致掉回空占位。 - 房间设置保存封面时,前端现在会同时兼容提交和读取两套字段,并在 `PUT /room/profile` 响应或紧接着的房间详情刷新返回空封面时保留刚上传的封面,不再被空值冲掉。 - 已新增本地房间封面兜底缓存:即使服务端短时间仍返回空封面,首页列表、我的房间、搜索结果、房间头部、房间详情和再次进入房间也会继续显示最近一次本地成功保存的封面。 - 已通过实际请求日志确认:`POST /external/oss/upload`、`PUT /room/profile` 和随后 `GET /room/profile/specific` 都已返回正确封面 URL;本轮问题的根因已收敛为首页/列表链路仍可能使用接口短时间回传的旧值,因此本地成功保存的封面现已提升为更高优先级。 - 房间封面空态图已切换为新的 `sc_images/general/sc_no_data.png`,其资源尺寸为 `288x288`。 - 房间资料卡与个人主页使用的用户资料链路已重新对齐:个人页现兼容 `avatar` 别名;顶部小头像不叠加头像框,但主头像会继续叠加头像框资源,且个人页背景已随 header 一起滚动,不再出现内容先滑动、背景停留不动的现象。 - 头像框显示逻辑已改为“框在外、头像在内”的常见样式;针对当前这类带白底的静态头像框资源,已增加白底透明化处理,因此个人主页主头像与房间麦位头像都不会再留下明显白边。 - 静态头像框的透明区域现已保持透明,不会再被错误算成黑色;房间麦位头像、个人主页主头像和其它复用 `head()` 的头像组件进入房间后不会再出现大块黑底遮罩。 - 个人主页现在在数据加载前也会先展示默认背景和底色,不会再闪黑;“About me / Giftwall” 内容区顶部边缘已改为直角,不再额外出现一个圆角缺口。 - 个人主页当前已接入贴合页面结构的骨架屏,占位期间不会先看到背景图单独显示;资料接口返回后再无缝切到真实内容,首屏观感更平滑。 - 首页 Party 页当前已接入贴合真实版式的骨架屏:进入首页首屏时会先看到三张排行卡位与双列房卡占位,骨架配色已跟随页面深绿+鎏金主视觉,不再只显示居中的白色 `loading`;且排行榜与房间区会按各自请求结果独立切换,先返回的区域会先显示真实内容。 - 首页 My 板块当前已接入贴合真实版式的骨架屏:顶部 `My room` 现区分“首次加载中”和“确实未创建房间”,不会再先闪出创建房间卡;`Recent/Followed` 在首屏空数据加载时也会先展示双列房卡骨架,不再只显示小菊花或局部空白。 - `Me` 入口下的 `Store / Bag` 页面当前也已接入深绿主题的三列卡片骨架:首次进入并且列表尚未返回时,会先显示与正式卡片比例一致的占位;接口返回后再切到真实商品/物品卡片。`store` 与 `bag` 卡片标题现都带宽度约束和单行省略,类似截图里的长名称不会再横向撑破布局。 - 图片加载态与空态当前已拆分:共享网络图组件和礼物二级页单卡封面加载时会显示代码绘制的环形转点,不再继续复用 `sc_icon_loading.png`;若图片失败或确实无数据,仍旧保留原先那张占位图,避免把 `loading` 和 `no data` 看成同一种状态。 - 首页与搜索等房卡右下角的在线状态图标当前已改为代码绘制的动态音频条:三根绿条会按不同相位走完整的波峰波谷周期,错峰连续起伏,视觉上更接近直播/语聊房的实时状态;`My` 板块骨架数量也已与 Party 页对齐为 `6` 个。 - 首页房卡底部信息当前已进一步收紧:房名和人数文字比上一版更小,底栏与动态音频条的视觉重心更一致;`My` 页顶部 `my room` 标题也已移除,下方卡片和 tab 会自然上移填充。 - 首页顶部排行骨架当前已进一步收窄为单条标题占位,不再保留两条文本骨架;房卡底栏房名也已再次缩一号并做轻微上移,对齐更贴近设计稿观感。 - 目录体积排查显示:`build/` 约 `4.7G`、`.dart_tool/` 约 `347M`、`ios/` 约 `250M`、`sc_images/` 约 `48M`、`local_packages/` 约 `6.1M`。 - 当前包体过大的主要原因已经确认: - universal APK 带入了 `arm64-v8a`、`armeabi-v7a`、`x86_64` 三套 ABI。 - Agora 与腾讯 IM 原生 so 很大,其中 `libagora-rtc-sdk.so` 合计约 `79.4MB`,`libImSDK.so` 合计约 `10.2MB`。 - 资源目录中 `sc_images/index`、`sc_images/room`、`sc_images/person`、`sc_images/splash` 是最主要的大图来源。 - `flutter build apk --release --target-platform android-arm64 --analyze-size` 已成功执行,当前 universal release APK 约 `271MB`。 - `flutter build apk --release --split-per-abi` 已成功执行,压缩前分架构 APK 约为: - `app-arm64-v8a-release.apk` 约 `161.4MB` - `app-armeabi-v7a-release.apk` 约 `138.8MB` - `app-x86_64-release.apk` 约 `148.6MB` - `loading_indicator_view_plus`、`social_sharing_plus`、`flutter_foreground_task`、`on_audio_query` 已从当前依赖链路中移除。 - 当前图片资源统计为 `412` 张,TinyPNG 两轮处理后总量已从 `47.25 MB` 降到 `22.27 MB`,累计节省约 `24.99 MB`。 - 当前 TinyPNG 已成功压缩 `400` 张图片,剩余失败 `12` 张。 - 当前压缩收益最大的图片包括: - `sc_images/person/sc_icon_edit_userinfo_bg.png`:`2640776 -> 436823`,节省约 `2.10 MB` - `sc_images/splash/sc_splash.png`:`2373335 -> 379804`,节省约 `1.90 MB` - `sc_images/room/sc_icon_room_defaut_bg.png`:`2243222 -> 704696`,节省约 `1.47 MB` - `sc_images/index/sc_icon_index_bg.png`:`1422169 -> 420635`,节省约 `0.96 MB` - 失败项已分型: - `12` 张为 TinyPNG 无法解码的特殊/动图 `webp` - 当前 TinyPNG 进度与统计文件已落盘:`tinypng-progress.json`、`tinypng-report.json` - 图片压缩后再次执行 `flutter build apk --release --split-per-abi`,当前分架构 APK 已下降到: - `app-arm64-v8a-release.apk` 约 `135.2MB`,比压缩前少 `26.2MB` - `app-armeabi-v7a-release.apk` 约 `112.6MB`,比压缩前少 `26.2MB` - `app-x86_64-release.apk` 约 `122.4MB`,比压缩前少 `26.2MB` - 可以确认:这轮图片压缩带来的资源收益已经真实反映到最终 APK 体积中。 - 在开启 `minify`、`shrinkResources`、`zipAlign` 并追加 `--split-debug-info=build/symbols/android` 后,Android release 继续下降为: - `app-release.aab` 约 `181.8MB` - `app-arm64-v8a-release.apk` 约 `128.7MB`,比上一轮 `135.2MB` 再少 `6.5MB` - `app-armeabi-v7a-release.apk` 约 `105.8MB`,比上一轮 `112.6MB` 再少 `6.8MB` - `app-x86_64-release.apk` 约 `115.8MB`,比上一轮 `122.4MB` 再少 `6.6MB` - `build/symbols/android` 已生成 3 份符号文件,总计约 `14MB`,后续可用于 Dart 堆栈还原。 - `scripts/build_release.py --platform android --output-dir dist/release/smoke-android` 已验证通过,归档结果为: - `android/google-play/` 下输出 `yumi-v1.0.0-b1-google-play.aab` 与 Dart symbols - `android/local/` 下输出 `arm64-v8a.apk` 与 `armeabi-v7a.apk` - `android/testing/` 下单独输出 `x86_64-test.apk` - 同时生成 `build_manifest.json`,已记录产物路径、大小和 `sha256` - `scripts/build_release.py --platform ios --output-dir dist/release/smoke-ios` 已验证通过,当前无签名模式下输出: - `ios/archive/yumi-v1.0.0-b1.xcarchive` - `ios/symbols/app.ios-arm64.symbols` - 当前 iOS 无签名构建会跳过 `.ipa` 导出;如需正式 `.ipa`,脚本需追加 `--ios-codesign` - 已将 `dist/` 加入 `.gitignore`,避免打包产物持续污染工作区状态 - 本轮按需执行 `flutter build appbundle --release --split-debug-info=build/symbols/android` 已成功,产物为: - `build/app/outputs/bundle/release/app-release.aab` - 当前 AAB 体积约 `181.8MB` - 本地校验 `app-release.aab` 证书后确认: - 证书所有者为 `C=US, O=Android, CN=Android Debug` - 当前 AAB 的 `SHA1` 为 `6B:72:BF:6F:D1:7A:F2:99:CD:F3:14:EE:18:A6:29:67:F8:05:E6:B4` - 这说明当前 release 构建仍在回退使用 debug signing,无法直接作为 Google Play 正式发布包 - 已生成新的 upload 证书文件: - `android/app/upload-keystore.jks` - `android/app/upload_certificate.pem` - 新 upload key 当前指纹为: - `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3` - `SHA256: 81:D6:3A:43:31:FA:83:87:0E:C3:5B:52:B8:C1:05:7C:3A:32:EC:24:37:0B:11:E4:2F:8C:62:4E:D4:AC:0C:3B` - release 构建已改为从 `android/key.properties` 读取正式 upload keystore,不再依赖当前的 debug 回退配置 - `flutter build appbundle --release --split-debug-info=build/symbols/android` 已重新执行,当前正式产物仍为: - `build/app/outputs/bundle/release/app-release.aab` - 当前 AAB 体积约 `181.8MB` - 重新校验该 AAB 后,签名者已变为: - `CN=Yumi Upload, OU=Mobile, O=Yumi, L=Shanghai, ST=Shanghai, C=CN` - `deployment_cert.der` 已核实为 Google 侧 app signing 证书,指纹为: - `SHA1: 3F:E1:78:DC:C3:29:4F:74:20:DF:27:54:CF:AF:46:46:D6:A1:94:78` - `SHA256: F9:BF:D0:89:F9:D7:FD:B2:53:24:A7:DB:59:E1:52:6F:54:A3:93:95:4E:88:7F:1C:4B:D6:03:66:E7:1A:1F:85` - 已确认当前存在两套不同证书: - 本地 `upload key`:用于你上传 AAB 到 Google Play - Google `app signing key`:用于 Google Play 最终给用户分发签名包 - `FOREGROUND_SERVICE_MEDIA_PROJECTION` 在当前 release 合并报告中的来源已确认是 `io.agora.rtc:full-screen-sharing:4.5.2` - 该依赖同时还带入了: - `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity` - `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService` - 主 Manifest 已添加 `tools:node="remove"` 覆盖规则,准备重新打包验证最终合并结果 - 重新打包后,release manifest merger 报告已显示: - `uses-permission#android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION` - `REJECTED from [io.agora.rtc:full-screen-sharing:4.5.2]` - 当前 release 中已不再检测到以下声明: - `android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION` - `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity` - `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService` - 新的正式产物已重新生成: - `build/app/outputs/bundle/release/app-release.aab` - 当前 AAB 体积仍约 `181.8MB` - 新 AAB 证书仍为本地 upload key: - `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3` - 本轮按需执行 `flutter build apk --release --split-per-abi --target-platform android-arm64 --split-debug-info=build/symbols/android` 已成功,产物为: - `build/app/outputs/flutter-apk/app-arm64-v8a-release.apk` - 当前 `arm64-v8a` APK 体积约 `128.7MB` - 已核对新旧 `google-services.json`: - 原文件与新文件都匹配包名 `com.org.yumi` - 下载文件已成功覆盖到 `android/app/google-services.json` - 当前工程内文件 `SHA256` 为: - `a1706496a01f74d27e6c60598144cecc978934b02a87567e1ced887b5b0185d5` ## 已知问题 - `ios/Podfile.lock` 还保留旧插件记录,因为本轮未执行 `pod install`;但 Flutter 当前依赖链路已经不再包含已移除插件。 - universal APK 仍然会非常大;当前正确发包方式应优先使用 `--split-per-abi` 或直接产出 `aab`。 - 仍有 `12` 张 `webp` 被 TinyPNG 拒绝解码,推测是动画或特殊编码格式,不能继续直接走 TinyPNG 常规压缩。 - `split-debug-info` 会把 Dart symbols 额外落到构建目录,发包时需要和正式包一起留档,不能丢。 - iOS 当前验证走的是 `--no-codesign`,因此只产出 `.xcarchive`,不会自动导出可直接分发的 `.ipa`。 - Flutter/Xcode 当前给出两条 iOS 提醒: - 未来 iOS 版本将要求 `UIScene` 生命周期支持 - Launch image 仍是默认占位资源,提交前建议替换 - `android/key.properties` 保存了本地 upload keystore 口令,必须自行妥善备份,且不要提交到仓库 - 由于已显式移除 Agora 本地屏幕共享相关组件,如果业务后续要启用“屏幕共享/录屏推流”,需要再单独恢复相关 manifest 声明 ## 下一步要做什么 - 将新的 `AAB` 上传到 Play Console,并在首发流程中继续使用 Google 管理的 app signing key。 - 在需要配置 Google 登录、Firebase、支付等生产环境指纹时,优先登记 Google 的 `deployment_cert.der` 指纹;如平台要求上传者证书,再额外登记本地 upload key 指纹。 - 如果需要正式 iOS 分发包,为 `scripts/build_release.py` 补入 `--ios-codesign` 所需签名参数并导出 `.ipa`。 - 继续评估 Agora 扩展库是否都需要,优先核查 `lip sync`、`spatial audio`、`clear vision`、`segmentation`、`face capture` 等扩展 so 能否裁剪。 - 决定是否处理剩余 12 张特殊 `webp`:改格式、换压缩工具,或维持现状。