# 无用代码清理 —— 落地文档(2026-09-24) > 基于 2026-09-24 对全仓五个部分(Go 后端、管理后台、Flutter 业务代码、本地插件与原生层、 > 其余文件)的审计,再逐条人工复核后整理。**本文档只包含「删掉不影响现有功能与运行」的项**; > 需要产品拍板或要改部署的,单独列在第七节,不在本轮执行范围内。 ## 一、原则 1. **零引用才删。** 每一项都满足:除了自己的测试,全仓没有任何 import / 调用 / 配置引用; 反射注册的接口另外去客户端、后台、网关白名单核对过没有调用方。 2. **按批执行,每批一个提交,每批跑一次验证。** 批次之间没有依赖,出问题直接 revert 那一个提交。 3. **有连带改动的项,连带改动写在同一行。** 漏掉连带改动的后果都是编译失败(比如删了插件没删 Package.swift 里的引用),这类不会静默出错,但会挡住其他人的构建。 4. **不删数据、不删表、不动线上配置。** 本文档只碰代码与仓库文件。 5. **不删「刻意保留」的东西**,清单见第八节;这些在 CLAUDE.md 里都有记录原因。 验证命令统一如下,各批次引用时只写编号: | 编号 | 命令 | 说明 | |---|---|---| | V-go | `cd apps/services && go build ./... && go vet ./... && go test ./...` | 后端 | | V-admin | `cd apps/admin && npm run build && git checkout -- .nuxt` | 后台(构建会改写 .nuxt,跑完还原;第一批做完就不用还原了) | | V-dart | `cd apps/client && ~/flutter/bin/dart analyze lib && ~/flutter/bin/flutter test` | 客户端静态检查 + 全部测试 | | V-android | `cd apps/client && ~/flutter/bin/flutter build apk --debug` | Android 编译 | | V-ios | `cd apps/client && ~/flutter/bin/flutter build ios --no-codesign && ./ios/sync_spm_platform.sh` | iOS 编译(build 会重置 SPM 平台版本,后面那句必须跟着跑) | --- ## 二、第一批:误进 git 的构建产物与本机产物(约 31MB,零风险) 这些文件都已经在 `.gitignore` 里,但因为是规则加上之前就提交了,忽略规则对它们不生效。 用 `git rm --cached` 只从索引里移除,**工作区文件不动**。 | 路径 | 是什么 | 体积 | |---|---|---| | `apps/services/console` | 本机 `go build` 产出的 ARM64 可执行文件,被误提交 | 29MB | | `apps/admin/.nuxt/**`(45 个文件) | Nuxt 构建产物,每次 `nuxt build/dev` 都改写,制造无意义 diff | 0.9MB | | `apps/services/dump.rdb` | Redis 快照,**可能含数据** | 44KB | | `apps/services/log/console.log`、`apps/services/lego/sys/log/log.log`、`apps/services/lego/sys/gin/log.log`、`apps/services/lego/sys/gin/log-2026-08-20T17-13-40.757.log` | 运行日志 | 小 | | `apps/proto/__pycache__/pb.cpython-310.pyc` | Python 缓存 | 小 | | 10 个 `.DS_Store`(`apps/proto` 1 个、`apps/services` 9 个) | macOS 本机产物 | 100KB | 执行: ```bash git rm --cached apps/services/console apps/services/dump.rdb apps/proto/__pycache__/pb.cpython-310.pyc git rm --cached -r apps/admin/.nuxt git ls-files | grep -E '\.log$|\.DS_Store$' | xargs git rm --cached ``` 验证:V-admin(确认 `.nuxt` 不再出现在 `git status` 里)。 注意:git 历史里这 29MB 还在,要真正回收仓库体积得改写历史,本轮不做。 --- ## 三、第二批:Go 后端(约 1.2 万行,确定无用) ### 3.1 整个包没有任何服务引用 以下每个包,`grep -rl '"yunyan/<包路径>"'` 只命中它自己目录下的测试文件;`go list -deps ./services/...` 也证实没有任何 `main.go` 能走到它们。**整个目录删除**,附带的测试随包一起走。 | 包 | 行数 | 备注 | |---|---|---| | `lego/sys/gin/` | 5404 | 框架里自带的一份 gin 分叉,实际用的是上游 `github.com/gin-gonic/gin` | | `lego/sys/timewheel/` | 684 | | | `lego/sys/sdk/bytedance/tos/` | 173 | | | `lego/sys/lghttp/` | 136 | | | `lego/utils/crypto/gm/`、`gm_java/`、`sra/`、`base64/` | 450 | 其余 crypto 子包(aes 等)在用,别整个删 `crypto/` | | `lego/utils/container/` 根目录的 `.go` 文件 + `addr/`、`ip/`、`sortslice/`、`version/` | 约 1105 | ⚠️ **`container/id/` 在用,必须保留** | | `sys/dify/` | 603 | | | `sys/deepseek/` | 406 | | | `sys/websearch/bingsearch/`、`sys/websearch/bravesearch/` | 516 | | | `sys/qweather/` | 293 | 在用的天气包是 `sys/hefengweather` | | `sys/coze/` | 275 | | | `sys/aliyun/sts/` | 163 | `sys/aliyun/oss` 在用,别整个删 `aliyun/` | | `sys/axml/` | 151 | | | `sys/haifanwu/` | 106 | | ### 3.2 编译进服务但永远走不到的代码 | 路径 | 依据 | 连带改动 | |---|---|---| | `modules/mcp/tool_finance.go`、`tool_spotify_music_play.go`、`tool_spotify_music_playlist.go` | 三个 comp 类型(`FinanceCard`、`SpotifyMusicCard`、`SpotifyMusicListCard`)在 `modules/mcp/module.go` 的 `RegisterComp` 列表里一次都没出现 | 删掉后 `sys/juhe/`(445 行)与 `sys/spotify/`(292 行)也没有引用方,一并删;**`sys/openai/sys_test.go` 第 5、87、93 行 import 了 juhe**,要先删掉那个测试用例 | | `modules/timer/timer_uselog.go` | `modules/timer/module.go:45` 只注册了 `modelComp`,`uselogTimer` 从未装上 | 无。(timer 服务本身是空壳,但要不要下线要一起改 Dockerfile,放第七节) | | `comm/const.go` 里的 `ModuleAuth`、`ModuleChat`、`ModuleMusic`、`ModuleAitools` | 全仓 0 引用 | 无 | ### 3.3 配置模板里没人读的段 `Sys["xxx"]` 的读取点全仓共 35 个,已逐个比对。以下段删掉后服务行为不变: | 文件 | 段 | |---|---| | `deploy/app/confs/home.yaml.example` | `deepseek:`(约第 73 行)、`ali_filetrans:`(约第 129 行,文件转写走 svc 池的 `NewSys`,不读这个段) | | `deploy/app/confs/mcp.yaml.example` | `juhe:`、`spotify:`、`bravesearch:` | | `apps/services/services/console/conf/console.yaml`、`deploy/console/confs/console.yaml.example` | `cos:` 段(console 只读 postgres / redis / nats / email) | | `deploy/app/confs/gateway.yaml.example:35` | 白名单里的 `public_info`,没有任何路由叫这个名 | ⚠️ 这一步只改模板。服务器上的真实 `confs/*.yaml` 里多出来的段不读也不报错,不需要同步改。 验证:V-go。 --- ## 四、第三批:Flutter 业务代码(约 7500 行 + 若干依赖) ### 4.1 从 `main.dart` 不可达的孤儿文件(23 个,6600 行) 判定方法:对每个文件搜 `import '.../<文件名>.dart'`,在 `lib/` 与 `test/` 里都是 0 命中, 或者唯一的引用方也是本表里的孤儿。**整文件删除。** | 文件 | 行数 | 备注 | |---|---|---| | `lib/data/services/speech_impl/volcano_tts_api_service.dart` | 1517 | 火山 ASR/TTS/声音复刻这一组五个文件互相引用、对外零引用。CLAUDE.md 里「VolcanoTts/VolcanoAsrApi 未动」那句已过时 | | `lib/data/services/speech_impl/volcano_asr_api_service.dart` | 904 | | | `lib/data/services/speech_impl/volcano_asr_service.dart` | 439 | | | `lib/data/services/speech_impl/voice_clone_tts_service.dart` | 433 | | | `lib/data/services/speech_impl/volcano_tts_service.dart` | 342 | | | `lib/modules/goods/views/goodsai_view.dart`、`controllers/goodsai_controller.dart`、`bindings/goodsai_binding.dart` | 546 | AI 资源点包页,没有路由;旧额度桶已停用 | | `lib/modules/home/views/widgets/calendar/calendar_task_list.dart` | 514 | | | `lib/modules/home/views/widgets/siri_orb_view.dart` + `lib/core/widgets/global_ai_orb.dart` | 464 | 成对孤立 | | `lib/core/widgets/intro_overlay_builder.dart` | 402 | 唯一用到 `lottie/intro_foriday.json` 的地方 | | `lib/modules/translation/views/widgets/face_to_face_layout.dart` | 267 | | | `lib/modules/translation/views/dialogs/delete_confirm_dialog.dart` | 172 | | | `lib/modules/ota_upgrade/views/ota_upgrade_popup_view.dart`、`model/ota_upgrade_model.dart` | 180 | 杰理 OTA 残留。⚠️ 同目录的 `controllers/ota_download_service.dart` 被 `device_ota_controller` 使用,**是活的** | | `lib/data/models/message_model.dart`、`models/agent.dart`、`models/events/voice_interaction_event.dart` | 230 | | | `lib/core/theme/text_styles.dart`、`lib/core/utils/audio_player_utils.dart`、`lib/data/services/audio_service.dart` | 179 | | | `lib/modules/settings/bindings/settings_binding.dart` | 11 | | ### 4.2 死路由与死入口 | 项 | 行数 | 依据 | 连带改动 | |---|---|---|---| | `lib/modules/voice_replication/` 整个目录 | 673 | `Routes.voiceReplication` 全仓唯一引用在 `translation_middleware_controller.dart:86` 的**注释**里 | 删 `lib/routes/app_routes.dart:30` 的常量、`app_pages.dart:85-86` 的注册与对应 import;跑 `test/routes_test.dart` | ### 4.3 注册了但没人用的服务(890 行) | 服务 | 文件 | 依据 | 连带改动 | |---|---|---|---| | `TranslationUsageService` | `lib/data/services/translation_usage_service.dart`(545 行) | 类名全仓只在定义处出现 | `translation_controller.dart:22` 那条 import 一起删 | | `MicrosoftTranslationService` | `lib/data/services/microsoft_translation_service.dart`(247 行) | 只在 `initial_binding.dart:71` `lazyPut`,没有任何 `find` / `.to` | 删 `initial_binding.dart` 那一行。⚠️ `mt_azure` 凭据下发是服务端的事,不受影响 | | `NavigationManager`、`LocationManager` | `lib/data/services/navigation_manager.dart`、`location_manager.dart`(98 行) | 只在 `initial_binding.dart:127-128` `lazyPut` | 同上 | ### 4.4 `lib/data/services/network/api.dart` 里对应服务端接口已不存在的方法 | 方法 | 行 | 接口 | 服务端 | |---|---|---|---| | `getAliToken` | 195 | `auth_alitoken` | 没有 auth 模块 | | `getMusicUrl` | 275 | `music_getmusicurl` | 音乐服务 9-23 已下线 | | `getproducts` | 257 | `user_getproducts` | 不存在 | 三个都是零调用,调了也是 `code:11`。 ### 4.5 pub.dev 依赖:Dart 侧零 import | 包 | 依据 | 连带 | |---|---|---| | `tencentcloud_cos_sdk_plugin` | COS 已换成 OSS 预签名直传,`package:tencentcloud_cos_sdk_plugin` 0 import | 删后 `flutter pub get`,iOS 要 `pod install`(Podfile.lock 里 QCloudCore 会随之消失) | | `flutter_tts` | 0 import,TTS 走原生与 azure | | | `flutter_shaders` | 0 import(配套的 `shaders/mic_flow.frag` 也零引用,一起删,pubspec 的 `shaders:` 段一并去掉) | | | `flutter_svg` | 0 import,原先给 weather svg 用 | | | `synchronized` | 0 import | | | `markdown` | 0 直接 import;`flutter_markdown` 在用且会自己传递依赖它 | 删的是 pubspec 里的直接声明 | | `pip` | 0 import,原生 swift/kt 里也没有引用;画中画走 `floating_ui_plugin` 自己的 `SubtitlePipController` | | ⚠️ 删依赖会重新生成 `GeneratedPluginRegistrant` 与 iOS SPM 中间包,做完必须跑 `./ios/sync_spm_platform.sh`。 `cupertino_icons` 保留(只提供字体)。`timezone` 见第七节。 ### 4.6 未引用的素材(约 24MB,安装包同步变小) pubspec 声明了、但 `lib/` 与 `local_plugins/*/lib` 里按路径搜索零命中,也没找到拼接路径的写法: | 路径 | 体积 | 连带 | |---|---|---| | `assets/images/agents/`(12 张 png) | 19MB | agents 图走服务端配置 | | `assets/weather/`(507 个 svg) | 2.0MB | 天气页已删 | | `assets/images/explore.png`、`explore1.png`、`explore2.jpg` | 1.7MB | | | `assets/images/defaultPicture.png`、`DefaultPicture.jpg` | 0.85MB | ⚠️ pubspec 第 188 行写的是 `defaultPicture.jpg`,磁盘上是 `DefaultPicture.jpg`,macOS 不分大小写才没报错,Linux 上会构建失败。删掉正好把这个坑一起消掉 | | `assets/images/robot_light.png`、`glasses_light.png`、`qqmusic.png`、`music.png` | 0.3MB | | | `assets/lottie/audio_wave.json`、`intro_foriday.json` | 0.2MB | 后者只被 4.1 的孤儿文件引用 | | `assets/listening.mp3`(pubspec 没声明,本来就不进包) | | | | `shaders/mic_flow2.frag`(pubspec 没声明) | | | 每删一项都要同步删 pubspec.yaml 的对应行。 ### 4.7 `dart analyze` 报出的死方法、死字段、无用 import 这批是活文件里的局部改动,逐条改,改完看 `dart analyze lib` 的 `unused_*` 数量下降即可: - `unused_element`:`goodsvip_view` 的 `_buildGoodsCardByType` / `_buildMetricsForType` / `_buildScenesSection`;`weixinLogin.dart` 的 4 个 `_get*Url`;`picture_translation_view` 3 个;`translation_controller._setupScrollListener`(约 3440 行);`translation_view._buildLanguageSelectionBar`(约 1141 行);`translation_detail_view._buildSummaryContainer`;`permissions_controller._showSuccessMessage` - `unused_field`:`azure_asr._lastStopAt`、`azure_ast._isContinuousRecognitionActive`、`translation_controller._nativePlugin`、`translation_detail_controller` 3 个、`meeting_record._fileOpTimeout`、`translation_list_view._recordingOverlayEntry` - `unused_import`:43 处,集中在 `translation_view` 与 `translation_controller` - ⚠️ `dead_null_aware`(`goods_base_controller` 10 处、`payment_controller` 4 处)**不动**:它们是按非空模型判出来的,模型字段与老包兼容有关 验证:V-dart,再 V-android、V-ios 各跑一次。 --- ## 五、第四批:本地插件与原生层(约 12MB) ### 5.1 整个插件删除 | 插件 | 依据 | 连带改动(漏一条就编不过) | |---|---|---| | `local_plugins/test/` | Flutter 模板 Hello 级插件(`TestPlugin.swift` 29 行)。Dart 无人调 `'test'` 通道;`agent_service` 的 Package.swift 声明了依赖但没有任何 Swift 文件 `import test` | ① 主 `pubspec.yaml` 第 126-127 行;② `local_plugins/agent_service/ios/agent_service/Package.swift` 第 11 行 `.package(path: "../../../test/ios/test")` 与第 26 行 `.product(name: "test", package: "test")` | | `local_plugins/bytedance_speech/` | 不在任何 pubspec 里,不会被注册成插件;没有 iOS 目录;全仓没有 Kotlin 文件 import `com.deep_voice.bytedance_speech` | ① `android/settings.gradle.kts` 第 42 行 `include` 与第 54 行 `projectDir`;② `local_plugins/agent_service/android/build.gradle.kts` 第 54 行 `compileOnly` | ### 5.2 不再链接的二进制与目录 | 路径 | 体积 | 依据 | |---|---|---| | `local_plugins/device_jieli/android/`(含 4 个 aar) | 3.5MB | 该插件 pubspec 的 `platforms:` 只剩 ios(注释写明 Android 已不装配),`settings.gradle.kts` 也没 include 它 | | `apps/client/SpeexKit.xcframework` | 0.5MB | 任何 pbxproj / Package.swift / podspec 都不引用,只在注释里出现 | | `local_plugins/ble_service/ios/ble_service/JLAudioUnitKit.xcframework` | 0.8MB | 该插件 Package.swift 第 21-23 行注释写明「已移除」,binaryTarget 里没有它 | | `android/app/src/main/res/raw/sample.mp3`、`listening.mp3`、`silence.mp3` | 2.3MB | app 包里没有任何 `R.raw.*` / `getIdentifier` 引用(`agent_service` 用的 `R.raw.start/stop/await` 是它自己插件里的) | | `apps/client/GoogleService-Info.plist`(根目录副本)、`assets/config/GoogleService-Info.plist` | 小 | Xcode 工程只引用 `ios/Runner/` 那份;pubspec 也没声明 `assets/config/` | | `local_plugins/swift_sdk_local/Tests/` | 0.24MB | 上游 MCP SDK 自带的单元测试。**必须同时删 `Package.swift` 第 48 行起的 `.testTarget(name: "MCPTests")`**,否则 SPM 加载包时报 target 路径不存在 | | `local_plugins/qq_music/android/.../ApiSample.kt`、`pcm/PcmExampleActivityNew.kt` | 439 行 | 示例代码,零引用,Activity 没在清单里注册 | | `local_plugins/azure_speech/lib/main.dart` | | 模板 Hello World | | `floating_ui_plugin/android/src/test/.../NativePluginTest.java`、`device_jieli/android/src/test/...PluginTest.kt`、`recorder_holder/sdk/example/` | | 脚手架残留。⚠️ `recorder_holder/test/`(ota/rec 4 个测试)是真测试,保留 | ### 5.3 原生死代码 | 项 | 依据 | 连带 | |---|---|---| | `azure_speech` Android 的 `azure_speech/translation` 方法通道、`translation_events` 事件通道、`TranslationMethodHandler`(`AzureSpeechPlugin.kt` 约 554、637、1954 行起)、`MicrosoftTranslationServiceImpl.kt` | Dart 侧没有任何地方打这两个通道名 | `onAttachedToEngine` / `onDetachedFromEngine` 里注册、注销的那几行一起清 | | `agent_service` Dart 包装里 13 个零调用方法:`initialize`、`startAgentService`、`stopAgentService`、`pushAudioData`、`recognizeCallback`、`restoreOriginalAudioState`、`disableBluetoothAudio`、`processTextInput`、`speakText`、`setTtsRate`、`stopAiSteam`、`stopTts`、`processImageInput` | 业务层(`lib/modules/mobile_elf`)只用 startConversation / stopConversation / fetchCredentials / events 等 | 只删 Dart 包装,原生对应方法先留 | | `chat_storage.getRecentMessages` / `getSessions`、`floating_ui_plugin.getInternalView`、`recorder_holder.decodeOpusFile` 的 Dart 包装 | 零调用 | 同上 | ### 5.4 原生配置残留 | 项 | 位置 | 依据 | |---|---|---| | Facebook 登录残留 | Android:`AndroidManifest.xml:115-116` 两条 `com.facebook.sdk` meta-data、`res/values/strings.xml:3,5` 的 `facebook_app_id` / `facebook_client_token`;iOS:`Info.plist` 的 `FacebookAppID` / `FacebookClientToken` / `FacebookAutoLogAppEventsEnabled` / `FacebookAdvertiserIDCollectionEnabled`、URL scheme `fb3829022037361855`、`LSApplicationQueriesSchemes` 里 15 个 `fbapi*` / `fbauth*` | pubspec 没有 FB SDK;Dart 里只剩 `login_controller.dart:529` 的「Facebook登录(已移除)」和一个 FontAwesome 图标 | | `NSMotionUsageDescription` | `ios/Runner/Info.plist` | 全仓没有 CoreMotion / CMPedometer 代码,也没有相关依赖。申报了用不上的权限在审核时可能被质询 | | 火山引擎 Maven 仓库 | `android/build.gradle.kts` | 已经没有任何 volcengine 依赖 | 验证:V-android、V-ios。做完 5.1 之后额外真机跑一次灵犀/移动精灵对话(`agent_service` 链路)与 EaiCar 连接。 --- ## 六、第五批:管理后台与 deploy 零碎(十分钟的事) | 项 | 位置 | 依据 | |---|---|---| | `chipVendorLabel()` | `apps/admin/app/utils/chipvendors.ts:74` | 全仓只有定义处 | | getters `isSuperAdmin`、`isLoggedIn` | `apps/admin/app/stores/auth.ts:82,95` | 没人读;`device.vue:579` 自己写了一个同名 computed。删 getter,或让 device.vue 改用 getter,二选一 | | `revokeCtx.brandid` | `apps/admin/app/pages/device.vue:919` | 写进去了但 `submitRevoke` 不提交它,品牌商下线后的残留 | | `.stat-card` 系列样式 | `apps/admin/app/assets/css/console.css:82` 起约 20 行 | 没有页面用这个类 | | tailwind `content` 里的 `./components/**/*.{vue,ts,tsx}` | `apps/admin/tailwind.config.ts:6` | Nuxt 4 的组件在 `app/components`,这一行扫的目录不存在 | | `pages/meettemplates.vue:6` 的注释 | | 指向不存在的 `MeetTemplateTab.vue`,实际是 `MeetTemplatePanel.vue`,改注释 | | `deploy/admin/env/dev.env.example`、`local.env.example`、`prod.env.example` | | 没有任何脚本引用;`env.example` 自己写着「只一份,不分 local/dev/prod」,这三份里还是旧名 `yunyan-net` / `yunyan-console` | | `deploy/.gitignore` 的 `voitrans/log/` | | 目录早已改名为 `app/` | | `apps/proto/google/protobuf/any.proto` | | 没有任何 .proto import 它,protoc 自带 | | `apps/client/preview/yidong.html` | | 08-29 的 UI 预览稿,零引用 | | `.vscode/settings.json` | 仓库根 | 只有一行 Java 设置,与本项目无关 | 验证:V-admin。 --- ## 七、需要拍板,本轮不执行 | 项 | 规模 | 为什么不能直接删 | |---|---|---| | **`modules/api` 整个服务** | 5831 行 / 76 文件 | 前端所有 `/web/api/*` 请求实际由 console 分发,api 的 75 个接口没有调用方。但它启动时建的 `admin`、`adminreslog`、`app_config`、`global_config`、`agent` 五张表**没有别的服务在建**,其中 `agent` 表还被 `modules/user/model_config.go` 与 console 读。下线前要先把建表搬到 home 或 console | | timer 服务 | 空壳 | 模块里只有一个空 Init,却仍在 `apps/services/Dockerfile.voitrans:41,56` 构建、`entrypoint.voitrans.sh` 启动。下线要一起改这两处,属于部署变动 | | migu 服务(`services/migu` + `modules/migu` + `swagger/migu`) | 687 行 | Dockerfile、build.sh、deploy 里都没有它,从未部署;注释写着「独立部署」,要确认没在别处跑。⚠️ `sys/migu` 被 mcp 的咪咕工具使用,**不能动** | | `modules/agents`(`agents_getagents` / `agents_getagenturl`)、`modules/bailian` + `sys/bailian` | 约 1100 行 | 客户端走的是 `user_getagents_v2/v3`,这两个模块 0 调用;但 agents 还装在 home 的 main.go 里 | | 没人调的反射接口:`user_getstatistics`、`user_pushaction`、`user_updatedevicesetting`、`echomeet_getcapabilities`、`pay_getorderlist`、allhelp 的 8 个 | 约 830 行 | 可能是给未来客户端预留。⚠️ `echomeet_getsummaryservices` 原也在此列,2026-09-26 起语音纪要「生成」弹窗的「总结模型」在用,**不能删** | | deadcode 标出的零散死函数(`findformac`、`getProductForName`、`getChannelAppCfg`、echomeet 的 `getrecords/saverecords/delrecords`、`comm/compute.go` 的 `SaveComputeRates/AdjustUserCompute/GrantUserCompute` 等) | 约 400 行 | 其中一部分只有测试在用;`comm/calltranslate.go` 的打分函数只有 `calltranslate_test.go` 在测,但结构体被 v3 接口用着 | | console 里 admin 不调的接口:`api_delsysconfig`、`api_getsolutionprovider`、`api_getchannel`、`api_getauthcode`、`api_batchresetlicensestatus`、`api_restfactorydevics`、`/apps/bindenv`、`/svcconf/services` | 小 | 改动小但要确认没有脚本在调 | | QQ 音乐 / `MusicManager`(`qq_music_service.dart`、`music_manager.dart`) | 572 行 | 「翻译时暂停外部音乐」这个功能还要不要;`main.dart:112` 的 `deepvoice://qqmusic` scheme 也跟着 | | `translation_middleware` 中间页(`lib/modules/translation/middleware/`) | 385 行 | 唯一入口 `HomeController.openTranslation()` 已无人调用,但路由仍在 `translation/module.dart:27` 注册。要确认产品上不再需要这个中间页 | | `timezone` 依赖 | | Dart 里 0 import、没有 `zonedSchedule` / `TZDateTime`;但 pubspec 第 62 行注释说是给定时提醒准备的,`memory_reminder_scheduler.dart` 目前只用 `show`。确认不做定时提醒就删 | | 翻译 key | 511 个 / 41 个语言文件约 2 万行 | 有 78 处 `变量.tr` 的动态用法,要逐前缀复核;单双引号两种写法都要处理 | | `deploy/app/prod-deploy.sh` 的 `APPS` 表 | 8 个应用 | 正式机只跑 ym 与 deepglass,另外 6 个是云雁/灵谱时代的;默认选中的还是 voitrans,容易误选 | | proto 里零引用的 86 个消息(品牌商、公码、config、全局配置、CosToken、唤醒音、AppSetting、music 两个文件等) | | 功能都已下线;要删得改 .proto 再用 protoc-gen-go v1.36.6 重新生成,然后 `git diff --stat -- apps/services/pb/` 确认只动了预期文件。`pb/aitools_*.pb.go`、`auth_msg.pb.go` 是没有对应 .proto 的孤儿生成文件 | | `device_jieli` 的 3 个 JL xcframework(`JLBmpConvertKit` / `JLDialUnit` / `JLPackageResKit`,5.2MB)与它的 Dart `lib/`、iOS `Sources/` | | 需要真机验证 EaiCar RCSP 认证与支架录音。⚠️ `JL_AdvParse` / `JL_HashPair` / `JLLogHelper` 被 JL_BLEKit 运行时 @rpath 加载,**绝不能删** | | `ble_service` 插件 35 个无人调的方法分发 | | 它的原生类被 agent_service、recorder_holder 依赖,只能精简 Plugin 的分发部分,不能删类 | | `apps/web` 空骨架、`build.sh`(无调用方)、`cmd/syncgoods` + `tools/importappgoods`(一次性迁移工具)、`swagger/` 生成物(Dockerfile 每次重生成) | | 占位或工具,删不删看意愿 | | `docs/migrations/*.sql`、`apps/client/CLIENT_AUDIT.md` 等一次性文档 | | 建议归档到 `docs/archive/`,不删 | --- ## 八、刻意保留,不要动 - pb 里的 `Music*` / `DBMusic` 消息;`DBProduct.devicetype` / `factoryid` 兼容字段;`modules/user/compat.go` - 各表的 `brandid` 列、`DBUser.Isgiveaway`、业务库 `config` 表的 `COS_*` 键、`global_config` 表、`license_*` 旧分表 - `agent_config`、`call_translate_rule` 的读取路径(两表 0 行但 v2/v3 接口仍在下发) - `sys/migu`、`echomeet_alibackcall`、`pay_getgoodssv2`、`/console/health`、`/accounts/topup` - 插件:`speech`、`ble_service`、`chat_api`、`swift_sdk_local`、`classic_bluetooth`、`device_jieli`(Dart 零引用但原生被依赖);`agent_service`(灵犀/移动精灵在大量使用) - 二进制:`MicrosoftCognitiveServicesSpeech.xcframework`、`QPlayAutoSDK`、`opus.xcframework`、`JL_BLEKit` / `JL_OTALib` / `JLAudioUnitKit` / `JL_AdvParse` / `JL_HashPair` / `JLLogHelper` - `ble_service/android/libs/*.aar`、`device_smartcar/android/third_party/aar`(是装进 `~/.m2` 的源文件) - 后台六个只做重定向的旧页面(`appversion` / `channels` / `meettemplates` / `appconfig` / `globalconfig` / `mcpconfig`)、`auth.ts` 的 `hasAccess` 旧 id 兼容 - `Dockerfile.voitrans`、`entrypoint.voitrans.sh`、`CLUSTER_TAG` / `ANALYZE_APP_NAME` 里的 `voitrans-a11`、`deepvoiceclient` scheme(PayPal 回跳) - `apps/client/doc/`(41 语种法律文档源)、`tools/`、`build_channels.sh`、`check_16kb.py`、`.mcp.json`(pubspec 声明为 asset,删了编译失败) --- ## 九、顺带发现的问题(不是死代码,建议另起任务修) 1. **iOS 上 QQ 音乐授权回跳是空转的**:`ios/Runner/AppDelegate.swift:39` 往 `"qq_music"` 通道发 `openUrl`,插件实际注册的通道名是 `com.yunqiinnovation.qq_music`。要么修通道名,要么随第七节的 QQ 音乐一起删。 2. **Android 换机器编不过**:`com.jieli.*` 只能从本机 `~/.m2` 解析。建议改成仓库内的 maven 目录。 3. **CLAUDE.md 三处与实际不符**,清理时顺手改: - 「agent_service 只调了 closeCodec()」→ 实际 `lib/modules/mobile_elf` 大量使用它; - 「杰理 OTA 的 OtaUpgradeController / OtaUpgradeView / OtaCoreService / OtaDownloadService 文件还在」→ 已不存在,只剩 4.1 表里两个孤儿; - 仓库结构图里的 `go.work` → 文件不存在(被 .gitignore 忽略)。 4. `deploy/dl/build.sh` 生成的是 `index.html`,而现行页面是 `download.html` 且已由后台管理;`index.template.html` 与 `download.html` 已分叉,建议只留一份模板并更新 README。 5. 三份 deploy README 与 `prod-build.sh` / `prod-deploy.sh` 头部注释还写着 `docker-registry.ideapsound.com`、`cd deploy/voitrans`,只是文字过时。 --- ## 十、执行与回滚 - 顺序:第一批 → 第二批 → 第三批 → 第四批 → 第五批。每批一个提交,提交信息写明「清理:第 N 批 xxx」,方便按批 revert。 - 每批做完跑对应验证;第三、四批额外各跑一次 V-android 与 V-ios。第四批的 5.1 做完真机过一遍灵犀对话与 EaiCar 连接。 - 全部做完后测试服发一轮(app / console / admin 三个镜像),跑通:登录、通话翻译、语音纪要、设备连接、后台版本与分发页。 - 回滚:`git revert <该批提交>`。第一批 `git rm --cached` 的文件工作区还在,revert 只是把它们加回索引。