Rodger-Wang
|
c14580d7db
|
client: 设备默认图去背;AI 页编排跟随设备;香薰 AI 回复走蓝牙;OTA 状态如实显示
设备默认图
- default.png / default_icon.png 是 assets/images/devices 里仅有的两张**不透明带底图**
(892×1152 竖版海报 + 浅蓝渐变底),而设备页展示区是 1.14:1 的横宽框,
BoxFit.contain 后成了中间一条窄的蓝色卡片、左右大片留白,深色模式下尤其突兀。
改成去背透明(948×828 / 176×154),主体自己铺满框、周围就是页面背景,代码零适配。
- device_images.dart 记下这条约定,免得以后又丢一张竖版带底图进来。
AI 页按设备铺编排(连着香薰却显示全量功能)
- _load() 的一次性迁移会改 enabledIds 却**不更新基线 _lastAppliedKey**,
尤其 _migrateDefaultLayout 会把 defaultEnabled 里缺的全部 append 回来 ——
香薰编排铺成 3 项,重启后被追加成 11 项,基线还停在 3 项,
于是 applyDeviceDefaults 判定「用户动过编排」,从此再也不铺,且怎么重连都恢复不了。
现在:当前编排若是自动铺的就整个跳过这些迁移;已经坏掉的装机由
_rebaseDeviceDefaultsBaseline 一次性把基线抬到现状(判据收紧到迁移留下的特征形态)。
- AgentDefaults.bind 补跑一次当前状态:GetX 的 ever 拿不到绑定那一刻已有的值,
而设备是被动回连的,完全可能赶在 bind 之前就绪。
- 断开设备后回退到 DeviceHub.lastKnownVendor:设备图和「设备管理」在断连后都显示
最近那台设备,AI 页却停在上一台铺的编排里,于是出现「图是耳机、功能是香薰」。
为此给 DeviceHub 加 lastKnownVendor,并把它与 lastKnownName 抽成同一个来源 ——
各算各的就还会自相矛盾。
- test/agent_module_defaults_test.dart 6 个用例守这条规则。
车载香薰唤醒 AI 后回复从手机扬声器出来
- 下行本来就设计成走经典蓝牙 A2DP,坏在共用的音频会话上:defaultToSpeaker 把输出
钉在内置扬声器,选项里只有 allowBluetooth(HFP)而没有 allowBluetoothA2dp
(playAndRecord 下 A2DP 输出默认是关的)。而这条链路采音在设备上走 BLE opus,
手机压根不录音,用 playAndRecord 本身就是错配。
- EmaiAudioSession 分档:香薰走新的 playbackOnly(.playback 类别,输出跟随系统路由),
EMAI 页「按住说话」仍是 playAndRecord(去掉 defaultToSpeaker 会退回听筒,更糟),
只补上 allowBluetoothA2dp。原生 PcmSpeakerPlayer 明确不碰 AVAudioSession,改这一处即可。
固件升级页
- 后台没给产品配过固件时,页面显示的是绿色的「已是最新」——这是假话,会让人以为
手上固件是最新的而不再去查。改成三态:找不到产品配置 / 服务端暂无固件版本 / 有新版本·已是最新。
新文案 otaNoServerVersion 已补齐 41 个语言文件(i18n_audit total_missing=0)。
- 产品找到但版本为空时打一条点名 warn,不再和「拉取失败」混在一起。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
4 weeks ago |
Rodger-Wang
|
e00b617025
|
services,admin,client: 服务配置按应用隔离、应用参数下线、客户端凭据走加密 v3
后台
- 服务配置去掉「全局默认」层,svc_config / svc_region_override / echomeet_orch
/ echomeet_orch_setting / echomeet_template 五张表统一按 app_name 隔离,
启动迁移 migrate_scope.go 幂等分配(首个应用原地改名保 id,其余拷贝);
写接口 app_name 必填(scope_check.go)。
- 类别落库 svc_category,可增删改;内置 11 个 id 不可改不可删,运行时语义仍只挂 comm.SvcCat*。
- 「应用参数」标签页下线:业务库 config 表不再随 user_getappconfig 下发,
migrate_appparams.go 把 AGENT_TYPE / MOBILE_ELF_* 迁到服务 llm_mobile_elf、
iapCustomerServiceQQ 迁到 app_params,COMPUTE_*/NEWUSER_GIFT_* 留在 config 表不下发,
无人读的音乐/公码/导航/COS_*/MeetServers 删除,其余键保留并在启动日志告警。
- 删除 console appcfg/* 与 api 模块的 get/add/update/delconfig、唤醒音四个接口(无调用方)。
- 修 getmcpservers 仍查全局层导致 MCP 类服务永远读不到。
客户端
- 凭据改走结构化通道:user_getappconfig_v3 整体 AES-CBC 加密(api_crypto.dart,
拦截器须排在 AuthInterceptor 之前),AppConfig.cred(svcId, field, envKey) 取值,
老键名只作兜底;lib 内 AppConfig.env( 已降到 0 处调用。
- 图片翻译的 ALIBABA_VL_MODEL / ENDPOINT 改挂 ast_alibaba。
启动日志
- 删除 sys/auth/firebase(google_auth 的重复实现,零调用方,且同一错误刷两行)。
- api 模块不再每次启动无条件插入默认超管(Duplicate entry 'admin')。
- sys/auth/* 五个包的 logger 名从复制来的 sys.tavily 各改各名;
google_auth 启动时即判断配置是否可用。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
4 weeks ago |
Rodger-Wang
|
27cabe1bde
|
client: 设备内核抽象、Smartcar 车载香薰接入与语音纪要等一批改动
工作区里累积的 Flutter 客户端改动,随本轮一并入库。主要涉及:
- lib/devices/ 设备内核:DeviceHub / DevicePlugin / DeviceSession 抽象,
恒玄(bes)、EaiRec 支架(holder)、Smartcar 车载香薰(smartcar) 各自的插件实现,
业务层不再直接依赖任何厂商类;分层边界由 test/devices/ 下的测试守着
- local_plugins/device_plugin_interface、device_smartcar、recorder_holder:
纯 Dart 契约与原生侧实现
- lib/modules/ 能力模块注册表、语音纪要、OTA 升级等模块
- test/ 新增设备协议、Ogg Opus 时长、模块注册表、路由等金测试
- ios/sync_spm_platform.sh:修 Xcode 直接构建时 SPM 平台版本被打回 13.0 的问题
验证:dart analyze lib 无 error(264 条 warning 均为 HEAD 上既有的 unused_import /
avoid_print 等 lint,非本次引入)。未跑真机与打包。
注:这批不是本次会话中由 Claude 编写的,此处仅做入库。
|
4 weeks ago |
Rodger-Wang
|
46c815eb87
|
修拾忆页第一次打开就报错:解包口径写错 + 红条抑制漏了 memory_list
两个都是我上一轮引入的,表现叠在一起就是「第一次打开拾忆界面抛异常」。
## 1) MemoryService 的解包口径写错(严重,后端一部署就全线失效)
DioManager.request 结尾是 `return response.data;` —— 返回的是 **data 本身**,
不是 Response。全仓既有调用方都直接下标取字段(my_devices 的 response['devices']、
bes_device_auth 的 resp['device'])。
而 MemoryService._data 写的是 `resp.data`。因为 request 的返回类型是 dynamic,
**编译与 dart analyze 都不报错**;后端还没部署时返回 null,正好走空分支,
所以本地一路绿灯。一旦服务端真的返回成功,每一次 memory 调用都会抛
NoSuchMethodError —— 也就是说这个功能在部署之后才会开始全面失效。
已改成 `if (resp is Map) return Map<String, dynamic>.from(resp);`,
并加 test/memory_service_unwrap_test.dart 把四种形状(成功有数据 / 成功空 {} /
业务错误 null / 传进来个对象)都钉住,任何人改回 .data 都会红。
## 2) 红条抑制名单漏了 memory_list
上一轮只加了 memory_today / memory_upcoming,**漏了 memory_list** —— 而它正是
打开拾忆页第一个调的接口(TodoTab.initState → refreshFromServer)。
后端没部署时网关返回 NoFindServiceHandleFunc,AuthInterceptor 就把
"[Handle Http] no found handle memory_list" 原样弹给用户。
改成按 `/api/home/memory_` 前缀整条抑制,读写两种情况都成立:
读在打开页面与切前台时自动调,页面自己有行内空态与「显示的是本地缓存」提示;
写的调用点各自弹了本地化的 memSaveFailed / memDeleteFailed / memCompleteFailed,
不挡的话会弹两条。逐个列举正是漏掉 memory_list 的原因,改前缀。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
1 month ago |
Rodger-Wang
|
2d1ee0b783
|
apps/client 首次入库(Flutter 移动端)
从 /Users/yunyanzhineng/work/eaimar_client-main 搬入,未带原 .git,历史留在原仓库。
3215 个文件 / 约 118MB,其中约 40MB 是构建必需的预编译 SDK(azure_speech 的
MicrosoftCognitiveServicesSpeech.xcframework、device_jieli 的 JL_BLEKit 等)。
build/ (5.2G)、ios/Pods/ (311M)、android/.gradle/ (120M) 已由 .gitignore 挡掉。
本次入库的代码包含两项刚做完的改动:
1) 游客登录入口接上服务端开关。此前 _checkGuestLoginConfig() 恒定写死 true,
入口根本不读配置。现改为取服务端算好的结论,并把入口所在的 Builder 改成 Obx
——配置是异步拿到的,Builder 只渲染 onInit 时的初值 false,入口再也不会出现。
拿不到配置时按隐藏处理:默认显示会在送审期把不该露的入口露给审核员。
⚠️ 已发布的老客户端关不掉(写死 true),只对本版及以后生效。
2) iOS 上架合规修复:
- 移除 ATT/IDFA:删掉 Info.plist 的 NSUserTrackingUsageDescription、
SKAdNetworkItems、NSAdvertisingAttributionReportEndpoint,删掉 splash 里的
授权请求与 app_tracking_transparency 依赖。本 App 从不读取 IDFA,也没有任何
广告/归因 SDK,弹框纯粹劝退用户,还要在 App Store Connect 申报追踪数据类型。
- ios/Podfile 里那段 config.build_settings.delete('NSUserTrackingUsageDescription')
是无效代码(该 key 在 Info.plist 里,不是 build setting),换成注释说明。
- 通讯录符号(ITMS-90683 被拒原因)随之一并解决:permission_handler 走 SPM 后
按 Info.plist 有无对应 key 决定编不编,判定结果被 SwiftPM 按内容哈希缓存,
改完 plist 必须清 DerivedData 与 manifests 缓存才会重新求值。
另附 GOOGLE_PLAY_RELEASE_CHECKLIST.md:Google Play 上架阻塞项的实测梳理
(targetSdk 36 与 Billing 8 的 2026-08-31 期限、16KB 页对齐不合规的两个 .so、
支付回退逻辑的下架风险)。
⚠️ android/app/sign/ 下的 eaimar.keystore 与 Eaimar.properties(含明文签名密码)
随本次提交入库,与本仓库"私有仓库下接受真实凭据"的既有取舍一致。
仓库若要公开,这两个必须先摘出去。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
1 month ago |