lktop-app-project

star 0

Use when working in ~/Code/lktop/app or when the user says ‘按 lktopapp 项目约束来做’. Applies the repo's uni-app/HBuilderX, BLE charger, firmware OTA, and product-management constraints.

cstcen By cstcen schedule Updated 6/6/2026

name: lktop-app-project description: "Use when working in ~/Code/lktop/app or when the user says ‘按 lktopapp 项目约束来做’. Applies the repo's uni-app/HBuilderX, BLE charger, firmware OTA, and product-management constraints." version: 1.2.0 author: Hermes Agent license: MIT metadata: hermes: tags: [project, uni-app, hbuilderx, ble, firmware, product-management] related_skills: [uni-app, hbuilderx-cli, writing-plans, systematic-debugging]


LKTOP App 项目 Skill

Overview

这是 ~/Code/lktop/app 项目的专用项目约束 Skill。

当用户说“按 lktopapp 项目约束来做”时,默认应套用这份规则,而不是把它当成一个普通的 uni-app demo、通用蓝牙示例项目,或者纯 UI 壳工程来处理。

这个项目本质上是一个面向 BLE 充电器设备的配套 App,当前代码已体现出以下核心能力:

  • 搜索并连接 BLE 充电器设备
  • 管理已连接设备与重连/替换入口
  • 查看设备详情与设置项
  • 检查固件版本、选择版本并执行设备固件升级
  • 提供意见反馈入口
  • 通过 uniCloud-tcb 中的 firmware 云对象支撑固件能力

它不是空白项目,也不是只停留在概念验证阶段;产品、研发、测试判断必须优先基于当前仓库真实代码事实

When to Use

在以下场景使用本 Skill:

  • 你正在 ~/Code/lktop/app 仓库内工作
  • 用户说“按 lktopapp 项目约束来做”
  • 用户要求你做这个项目的产品经理、研发协作助手、需求分析、排查、文档、构建或发布支持
  • 需求涉及 uni-app 页面结构、BLE 连接、充电器设备控制、固件升级、反馈链路
  • 需求涉及 HBuilderX / HBuilderX CLI / uni-app 多端构建与打包
  • 需求涉及 uniCloud-tcbfirmware 云对象

默认不要把这个项目误判成:

  • 普通营销型 App
  • 纯 Web H5 页面项目
  • 没有后端/云对象依赖的纯前端仓库
  • index.vue 为首页的常规 uni-app 模板项目

如果任务已经超出 app 单仓库,开始同时涉及 website / admin / website-next / admin-next / lktop-platform 的产品边界、迁移关系或多项目统筹,应额外加载 lktop-product-portfolio skill。

Quick Facts

  • 仓库路径:~/Code/lktop/app
  • 工程类型:HBuilderX 管理的 uni-app 项目
  • 技术栈:uni-app + Vue 3
  • 关键能力域:BLE 设备接入 / 设备详情与控制 / 设备固件 OTA / 反馈入口
  • 固件服务:uniCloud-tcb/cloudfunctions/firmware/index.obj.js
  • 当前 PRD:docs/lktop-app-prd-v1.md
  • 当前页面注册基线:pages.json
  • App 启动会预热 firmware 云对象
  • 当前代码基线中,真实主入口页是 pages/devices/connected/connected
  • manifest.json 显示当前版本基线为 1.0.71 / 1071
  • 仓库内已有经验证的 Harmony debug HAP 构建脚本:scripts/build-harmony-debug-hap.sh
  • 鸿蒙正式签名包当前走 cli pack app-harmony --project /Users/chester/Code/lktop/app,产物与 pack.info 位于 unpackage/dist/build/app-harmony/build/outputs/release/
  • 当前仓库的 Harmony 签名材料实际放在 harmony-configs/,构建出的临时 Harmony 工程会复制这些文件到 unpackage/dist/build/app-harmony/;正式发布 release profile 应使用 lktopappRelease.p7b,不要使用历史/测试 profile lktopapp_cbtRelease.p7b
  • 构建产物交付给用户时,最终回复应包含纯文本可复制的直链(优先用代码块包住 URL),不要只给富文本描述或不可直接复制的链接呈现
  • 当前工程已体现多端配置,不应按单端 demo 理解
  • 设备图片已统一为全平台 256×256 RGBA PNG(实物照片),MC326 与 MINI 共用同一照片(charger-mini.pngcharger-mc326.png 的副本),详见 references/cross-platform-device-images.md
  • 当前活跃特性分支:feat/mc326-v1-1-device-profile-ota(13 文件变更 vs master,含 device-profile.js、设备图片、charger/searching/connected/upgrade 页面改动,以及 firmware 云对象 channel 筛选)
  • 新增核心文件 utils/device-profile.js(型号识别、路由、图片映射、firmwareChannel 推导),全平台共用,详见 references/device-profile-and-ota-channel-touchpoints.md

产品经理默认工作方式

当用户让我“作为这个项目的产品经理”时,默认不是只做文案整理,而是按下面模式工作:

  1. 先基于代码事实做现状盘点

    • 先看 pages.jsonApp.vue、目标页面、相关 utils、云对象
    • 再给出产品判断,不先写空泛建议
  2. 优先从用户链路而不是页面孤岛出发 默认按 4 条链路思考:

    • 接入链路:搜索、授权、连接、首连成功
    • 回访链路:已连接设备、重进、替换设备、状态恢复
    • 升级链路:检查版本、选择版本、下载、OTA、失败收口
    • 反馈闭环:问题触发、反馈提交、后续跟踪
  3. 每次分析都区分“现状事实 / 问题判断 / 建议动作”

    • 现状事实:当前代码里已经存在什么
    • 问题判断:哪里会伤害转化、成功率、理解成本、售后效率
    • 建议动作:下一步该改什么、为什么、优先级多高
  4. 优先级判断优先看主链路成功率 默认优先级排序:

    • P0:影响连接成功、升级成功、设备可控、严重误导用户
    • P1:影响高频效率、失败恢复、跨页状态一致性
    • P2:影响理解成本、信息表达、次要体验细节
    • P3:装饰性优化、风格统一、非关键文案润色
  5. 默认把自己当“产品 + 研发协同 PM”,不是纯业务 PM

    • 结论要能落到页面、状态、接口/云对象、构建链路
    • 避免只写抽象愿景,不可执行
  6. 当用户明确要“方案 / 需求分析 / 接入方案”时,先直答当前问题,禁止上下文漂移

    • 先围绕当前 ask 输出:现状事实、差距、方案、影响范围、风险、验收口径
    • 不要先汇报“我有什么 skill / 记忆 / 能力 / 之前做过什么”,除非用户问的就是这些
    • 不要把上一任务(如构建、上传、发包、git、部署)的结果带进本轮方案回答,除非它与当前方案直接相关
    • 如果前一轮刚做过别的事情,回答前先重新对齐用户的最新一句话,避免把“我能做什么”错答成“我建议怎么接入”
  7. 当用户问的是“你有没有这种技能 / 记忆 / 现成链路”时,先直接回答能力边界,再决定是否执行

    • 先明确回答:有/没有;有哪些已加载或相关 skill;有哪些项目记忆/仓库事实可支撑当前请求
    • 如果用户当前 ask 只是确认能力、技能、记忆、现成流程,默认先回答能力清单与约束,不要直接切回仓库里另一个进行中的代码任务
    • 如果本轮任务类型已经从“代码改造/排查”切换成“构建/打包/上传/发链接”,必须先重新分类任务,再进入对应 workflow;不要被旧的 active task list、context compaction 里保留下来的 TODO、或刚才读到的代码上下文牵走
    • 看到会话里仍显示 earlier active tasks / preserved task list 时,把它们当成背景状态,不是覆盖用户最新一句话的新指令;必须先对齐最新用户 ask
    • 只有在回答完 capability 之后,且用户明确要继续执行时,再进入实际打包、上传、托管、发链路步骤

默认输出结构

如果用户没有指定格式,默认优先输出以下其中一种:

A. 产品分析

  1. 目标问题 / 当前任务
  2. 现状事实
  3. 关键问题
  4. 用户影响
  5. 优先级判断
  6. 建议方案
  7. 验收口径

B. 需求拆解

  1. 背景
  2. 目标
  3. In Scope
  4. Out of Scope
  5. 功能点拆解
  6. 风险与依赖
  7. 验收标准
  8. 待确认问题

C. 页面/流程评审

  1. 当前角色定位
  2. 上下游页面关系
  3. 主要断点
  4. 建议调整
  5. 影响范围
  6. 是否需要联动改动

D. 版本规划 / 优先级建议

  1. 必做项
  2. 应做项
  3. 可延后项
  4. 不建议现在做的项
  5. 排序理由

产品判断基线

1. 真实首页判断必须以 pages.json 为准

当前项目里,真实主入口页是 connected.vue,不是 index.vue

默认规则:

  • 页面入口、首页定义、用户首屏旅程判断时,优先看 pages.json
  • 不要因为存在 pages/index/index.vue 就默认把它当成当前首页
  • 如果讨论“首页改版”“首屏链路”“首次进入体验”,默认先从 connected.vuesearching.vue 的关系切入

2. 产品本质是 BLE 设备配套 App,不是普通内容型 App

这个项目的产品主链路是:

  • 已连接设备页 connected
  • 搜索/接入页 searching
  • 设备详情/控制台页 charger
  • 固件升级页 upgrade
  • 反馈页 feedback

默认处理原则:

  • 任何需求分析都要围绕“连接成功率、设备操作效率、升级成功率、失败收口”来判断优先级
  • 不要把页面优化只理解为视觉改版;必须考虑设备状态、连接链路与异常恢复
  • 需求拆解时,优先把“接入链路”“回访链路”“升级链路”“反馈闭环”分开看

3. 必须严格区分 App 更新 与 设备固件 OTA

当前仓库同时存在:

  • uni_modules/uni-upgrade-center-app/pages/upgrade-popup:更接近 App 包更新能力
  • pages/devices/upgrade/upgrade.vue:设备固件 OTA 能力

默认规则:

  • 讨论升级时,先明确是在说 App 更新还是设备固件升级
  • 如果用户没有明确说明,而语境在设备详情、设备版本、固件列表、BLE 传输,则默认指设备固件 OTA
  • 不要把两个升级能力混写成同一个需求

4. 与固件相关的判断要同时看 App 侧与云对象侧

当前固件能力不是纯前端假数据:

  • App.vue 启动时会预热 firmware 云对象
  • 云对象位于 uniCloud-tcb/cloudfunctions/firmware/index.obj.js

因此:

  • 涉及版本列表、升级资格、下载地址、固件筛选时,不能只看页面代码
  • 如果升级行为异常,要同时检查页面、BLE 传输链路和 firmware 云对象
  • 不要凭空设计未被当前代码证明存在的云端能力

5. HBuilderX / HBuilderX CLI 是正式构建链路的一部分

这是 HBuilderX 管理的 uni-app 项目,涉及多端构建与打包时,默认优先考虑:

  • HBuilderX 工程结构本身
  • manifest.json 中的多端配置
  • hbuilderx-cli skill 中定义的 CLI 构建/打包方式
  • uni-app skill 中的框架约束

默认规则:

  • 做构建、打包、云函数、HarmonyOS HAP、App 资源生成等任务时,优先加载/遵守 hbuilderx-cliuni-app 技能
  • 不要擅自把项目改造成 Vite-only、纯 npm-only 或其他不兼容的构建方式
  • 不凭印象拼 HBuilderX CLI 命令;需要以 skill 中的命令形式和参数约束为准
  • 如果只是做产品分析或页面改动,不必为了“工程现代化”顺手重构构建体系

6. BLE 是高风险核心域,不能轻率重构

仓库中 BLE 相关逻辑集中在 utils/ble-*、连接状态管理、设备连接列表、通知恢复等模块。

默认规则:

  • 涉及连接、重连、扫描、后台前台切换、升级传输时,按高风险区域处理
  • 没有明确证据时,不要假设连接问题只来自 UI 或只来自权限
  • 任何产品结论都要考虑平台差异、BLE 栈限制和状态同步问题
  • 当前仓库的厂商广播解析已确认采用:companyId(0xACCA) + secondaryMark(0xAFFA) + productType/productSeries/productModel + 14 字节 ASCII 序列号 + 00 00 保留字节;旧 6 字节 HEX 仅作为兼容回退
  • 如果下游逻辑使用 deviceIdBytes,要先确认它依赖的是“历史 6 字节标识”还是“当前序列号字节”,避免把字段名当成协议事实

7. 平台差异是产品事实,不是实现噪音

App.vue 已明确体现平台差异:

  • HarmonyOS:进入后台时尽量保持 BLE 连接
  • Android / iOS:进入后台时会断开 BLE 连接以释放 GATT 资源

默认规则:

  • 讨论“后台切回前台后为什么断了”“为什么鸿蒙和 Android 行为不同”时,不要把这种差异直接定义成 bug
  • 需求、测试用例和验收标准应按平台区分
  • 如果做连接恢复体验优化,应先确认目标平台

8. 当前反馈页并不等于真实客服闭环

当前 pages/feedback/feedback.vue 中已有明显“模拟提交延迟”的实现痕迹。

默认规则:

  • 不要把反馈页现状描述成已打通完整服务闭环
  • 任何关于售后、工单、问题追踪的结论,都应先确认后端是否真实接入
  • 产品分析里应把反馈链路缺口视为现状问题,而不是已完成能力

9. 产品讨论优先基于现有 PRD 与代码事实,而不是脑补

当前仓库已存在 docs/lktop-app-prd-v1.md

默认规则:

  • 做产品分析、任务拆解、评审摘要时,优先对齐 PRD 与现有代码
  • 没被当前代码和文档证实的业务规则,必须明确标注为“假设”或“待确认”
  • 不要把 demo 风格建议直接上升为正式需求

默认工作流

处理这个项目的需求时,默认按下面顺序:

  1. 先判断需求属于哪一类:
    • 产品分析 / PRD / 任务拆解
    • 页面与交互改动
    • BLE 连接/状态问题
    • 固件升级 / 云对象问题
    • HBuilderX CLI 构建/打包/部署
  2. 先读与本次需求直接相关的代码与文档,不凭记忆推断。
  3. 如涉及页面与链路判断,先核对 pages.jsonApp.vue、相关页面 .vue 文件。
  4. 如涉及升级,先区分 App 更新 vs 设备固件 OTA,再看 upgrade.vuefirmware 云对象。
  5. 如涉及构建/打包/发布,优先参考 manifest.jsonhbuilderx-cli skill。
  6. 输出时默认给出“事实、问题、建议、优先级、验证方式”五要素。
  7. 改动时只做和需求直接相关的最小变更,不顺手大改 BLE、构建体系或页面架构。
  8. 完成后根据任务类型做相应验证,而不是只看代码通过与否。

参考文件

优先参考这些文件:

  • docs/lktop-app-prd-v1.md
  • docs/lktop-app-prd-skeleton.md
  • pages.json
  • App.vue
  • manifest.json
  • package.json
  • pages/devices/connected/connected.vue
  • pages/devices/searching/searching.vue
  • pages/devices/charger/charger.vue
  • pages/devices/upgrade/upgrade.vue
  • pages/feedback/feedback.vue
  • uniCloud-tcb/cloudfunctions/firmware/index.obj.js
  • utils/ble-*.js
  • references/ble-platform-architecture.md(BLE 模块跨平台代码架构:哪些文件是 Harmony 专有 API 层、哪些是通用逻辑层,以及跨平台同步的判断规则)
  • references/harmony-debug-hap-workflow.md
  • references/harmony-release-app-workflow.md(鸿蒙正式签名包 .app 的已验证构建与核验流程)
  • references/harmony-release-app-hosting-links.md(鸿蒙正式 .app 上传到前端托管并返回提审下载直链的已验证流程)
  • references/harmony-privacy-consent-gate.md(HarmonyOS 不消费 androidPrivacy.json 时,自定义隐私协议弹窗与 uniCloud/BLE/权限 gate 的实现触点与验收口径)
  • references/harmony-hap-hosting-links.md(HAP 上传到前端托管并返回可下载直链的已验证流程)
  • references/ble-watchdog-vs-device-info.md(连接后 0x180A 设备信息读取与 charger proto watchdog 误判的排查要点)
  • references/device-profile-and-ota-channel-touchpoints.md(device profile 数据源/路由/存储/OTA channel 现状、已落地实现触点,以及 MC326 硬件改版兼容的已确认决策)
  • references/v1-1-firmware-channel-guard.md(V1.1 中 firmwareChannel 为空时 OTA 入口/升级页的保守拦截触点与验收口径)
  • references/cross-platform-device-images.md(SVG 图片在微信小程序/Android/iOS 上的兼容性问题,以及 macOS 上 SVG → PNG 转换工具链)
  • references/android-cloud-pack-workflow.md(HBuilderX CLI Android 云打包工作流、交互式提示的 expect 处理方案、构建时间线与常见坑)
  • references/ios-cloud-pack-workflow.md(HBuilderX CLI iOS 云打包工作流、Bundle ID 配置踩坑记录、证书/profile 路径与密码配置位置,以及 minified 插件源码逆向排查经验)
  • references/ble-state-machine-pitfalls.md(BLE Pipeline STOPPED 状态死锁与 isScanning 标志位不一致的排查要点:断连后重连无效、微信小程序后续搜索失败)
  • references/lktop-feishu-bitable-task-tracker.md(飞书多维表格任务跟踪:Base/表结构、新建项目+任务的完整 lark-cli 流程与验证命令)
  • references/wechat-mp-upload-workflow.md(微信小程序编译上传的完整工作流:HBuilderX 编译 → 微信开发者工具 CLI 上传 / preview 二维码生成,已弃用 miniprogram-ci)
  • references/firmware-channel-admin-alignment.md(当 App OTA 查询依赖 firmwareChannel 时,旧 admin 固件版本运营表单/schema/list 的字段对齐检查清单)
  • references/lito-firmware-channel-verification.md(LITO 返回全部 charger 固件版本时的排查路径、云对象部署验证命令、同事手持设备检查清单)
  • references/www-lktop-cn-domain-migration.mdwww.lktop.cn 在 APP 中的引用盘点、旧 hash URL 映射、Nginx 反向代理迁移方案)
  • references/cos-apk-upload.md(APK 上传到腾讯云 COS + CDN 分发:凭证获取、上传脚本、验证流程,替代已失效的 www.lktop.cn 前端托管)
  • references/admin-next-local-dev.md(admin-next 本地开发环境:npm vs pnpm、Node v22、zsh session restore 绕过、NODE_ENV 缓存陷坑、启动与验证命令)

One-Shot Recipes

场景 A:做产品分析 / PRD / 需求拆解

默认动作:

  1. 先看 docs/lktop-app-prd-v1.md
  2. 再回读 pages.jsonApp.vue、相关页面源码核对事实
  3. 输出时优先围绕:接入链路、回访链路、升级链路、反馈闭环
  4. 明确区分“代码已实现”“代码有雏形”“尚未实现/待确认”
  5. 默认补一个优先级判断,不只描述现状

场景 B:做页面 / 交互优化

默认动作:

  1. 先确认目标页在当前路由中的真实角色
  2. 不要误把 index.vue 当成当前首页
  3. 如果改动会影响连接、升级、设置入口,要同步考虑相关页面跳转和状态文案
  4. 完成后至少回看关键路径是否仍闭环
  5. 输出时说明这次改动影响的是哪一条用户链路

场景 C:排查 BLE 连接或状态问题

默认动作:

  1. 先确认发生在哪个平台
  2. 再确认问题落在扫描、连接、已连接列表、通知恢复、前后台切换中的哪一段
  3. 不把 BLE 问题简单归因到单一文件
  4. 优先做最小修复与验证,不轻易全链路重写
  5. 如果给产品建议,必须说清是"连接成功率问题"还是"恢复体验问题"
  6. 如涉及广播识别,优先核对 utils/ble-adv-parser.jsreferences/ble-manufacturer-advertisement.md,确认当前设备到底是 14 字节 ASCII 序列号 还是旧 6 字节 HEX 回退格式
  7. 必须先区分标准 GATT Device Information Service (0x180A)充电器 proto 数据通道(00008300/00008301/00008302:前者用于读取 model/serial/firmware/manufacturer 等设备信息,后者才是 charger 页的 notify / proto 请求主通道。不要把"0x180A 读取成功"误判成"charger proto 首包已到"。
  8. 如连接建立后出现"反复启用 notify / 反复读取设备信息 / data-timeout -> restart"循环,优先检查 charger 页 pipeline 的 watchdog 是否过早在 READY 后启动。对本项目,若页面会先走 0x180A 设备信息读取,再等待 00008301 首包 proto 数据,watchdog 应延后到首个 proto 数据到达后再开始计时,否则会把初始化空窗期误判成链路超时。
  9. 用 Node 对 ble-adv-parser.js 做最小验证时,优先构造完整 AD Structure 样本,而不是只传 ManufacturerData 纯 payload;否则会被未预处理的 APP-HARMONY 分支误导
  10. 如用户反馈「点击重连无效」或「设备日志显示未收到 APP 连接请求」:优先检查 ble-pipeline.jsstate.phase 是否为 'STOPPED'scheduleRestart() 在 STOPPED 状态下直接返回(L642),且 restart() 不恢复 phase。这是 Pipeline STOPPED 状态死锁,见 Pitfall #22 与 references/ble-state-machine-pitfalls.md
  11. 如用户反馈「搜索页首次正常,后续搜索不到设备」:优先检查 searching.vue:_cleanupBle() 是否 awaitsafeStopBluetoothDevicesDiscovery;再检查 ble-init.jsisScanning 标志位是否与平台实际扫描状态一致(safeStartBluetoothDevicesDiscovery 的假复用逻辑,L372-374)。这是标志位不一致导致的假扫描,见 Pitfall #23 与 references/ble-state-machine-pitfalls.md

场景 D:处理固件升级 / 版本能力

默认动作:

  1. 先确认是设备固件 OTA,不是 App 更新
  2. 查看 upgrade.vuecharger.vueApp.vueuniCloud-tcb/cloudfunctions/firmware/index.obj.js
  3. 明确当前是否已有版本列表、版本选择、下载地址、升级状态与失败处理
  4. 如果做产品需求,要把失败出口、重试、反馈入口一起考虑
  5. 对 MC326/MINI/LITO 的 V1.1 链路,如果 firmwareChannel 为空,默认按保守策略处理:允许控制,不允许放行 OTA;至少在 charger 页升级入口与 upgrade 页版本拉取/开始升级前做双重 guard,并提示“暂无法识别设备型号,请重新连接后再试”。
  6. 如果 App 云对象已按 firmwareChannel 筛选固件,但 admin-next 尚未承接固件运营,必须同步检查旧 ~/Code/lktop/adminfirmware-versions schema、validator、新增/编辑/列表页是否能录入并展示同名字段;参考 references/firmware-channel-admin-alignment.md
  7. LITO/MINI/MC326 固件隔离应保持 deviceType=charger,用 firmwareChannel 分流;如果详情页显示 LITO 但仍返回全部版本,优先核对 resolveDeviceProfile() 的识别候选是否包含 GATT modelNumber/model,参考 references/lito-firmware-channel-verification.md
  8. 输出时优先回答:升级入口是否清晰、失败是否可恢复、用户是否理解当前状态

场景 F:鸿蒙已验证 → 向 Android/iOS/微信小程序传播修改

当用户说"鸿蒙已验证,现在对安卓/苹果/小程序做相应修改"时的默认动作:

  1. 先确认当前分支、版本号、与 master 的差异(git diff master --stat
  2. 系统性扫描所有 #ifdef APP-HARMONY / #ifndef APP-HARMONY 条件编译块,逐一检查非鸿蒙平台的路径是否有对应实现
  3. 重点检查三类差异:
    • BLE 广播解析:确认 #ifndef APP-HARMONY 分支能正确提取 V1.1 新增字段(productType/productSeries/productModel)
    • 文件读写:确认 MP-WEIXIN(wx.getFileSystemManager)、APP-PLUS(plus.io)分支已覆盖
    • URL 跳转/系统能力:确认各平台有对应的实现(如 uts-openSchema 仅 Harmony,其他平台用 plus.runtime.openURLnavigateTo
    • 注意:设备图片已全平台统一为 PNG,无需检查图片格式差异(详见 references/cross-platform-device-images.md
  4. 做最小修改,不改动已验证的鸿蒙分支逻辑
  5. 提交前至少核对:git diff --check、新增行安全扫描、diff 中无意外引入的鸿蒙代码修改

场景 G:Android 云打包调试包

默认动作:

  1. 确认工作区干净(git status
  2. 优先使用 expect + spawn 处理可能出现的云端队列交互式提示,不要用 yes |echo Y | 管道(CLI 读 /dev/tty 不读 stdin)
  3. 提交命令:cli pack --project ... --platform android --safemode false --android.packagename com.lktop.app --android.androidpacktype 1
  4. 如果用 expect,必须设置 set timeout ≥ 1800(30 分钟);构建分两阶段:本地编译(~10s)→ 云端编译(5-15 分钟,此期间 CLI 无输出)
  5. 构建完成后 APK 落在本地 unpackage/release/apk/lktop__<timestamp>.apk
  6. 上传 COS(推荐 ✅):将 APK 上传到腾讯云 COS(lktop-media-1331053332),通过 CDN(cdn.lktop.cn)分发,获取永久下载直链。详见 references/cos-apk-upload.md
  7. 交付时提供纯文本可复制的直链(优先用代码块包住 URL)
  8. 详见 references/android-cloud-pack-workflow.mdreferences/cos-apk-upload.md

场景 K:向飞书多维表格写入任务记录

当用户要求将 LKTOP App 的 BUG/需求/任务录入飞书多维表格时,默认动作:

  1. 先确认 Base Token(S9BvbM79DakbrCsSqSSc3aaEnQf)、任务表(tblLv3IaYMN3SKTm)、项目表(tbl6WhCgQVf8cjZQ
  2. 检查项目表中是否已存在目标项目记录;不存在则先创建
  3. 获取项目 record_id 后,创建任务记录并通过 fldfhHpt7e(所属项目)link 关联
  4. 任务写入字段:任务状态优先级子项目专属描述实际完成时间所属项目
  5. 完成后用 +record-search 验证写入结果
  6. 详见 references/lktop-feishu-bitable-task-tracker.md

场景 H:iOS 云打包调试包

默认动作:

  1. 确认证书文件存在:p12mobileprovision
  2. 确认 hxiOSResign.jsonCERTYPEapple-dev
  3. 推荐方式:使用 --ios.bundle CLI 参数显式传入 Bundle ID(绕过 manifest.json 的 app-plus 键名和 JSONC 注释导致的解析问题)
  4. 使用 expect + spawn 处理可能的队列交互式提示(同 Android,CLI 读 /dev/tty 不读 stdin)
  5. 命令(推荐 ✅)cli pack --project ... --platform ios --safemode false --ios.bundle cn.lktop.likigo --ios.profile /path/to/profile.mobileprovision --ios.certfile /path/to/cert.p12 --ios.certpassword "密码"
  6. 备用方式:如果 manifest.json 的 plus.distribute.apple 节点完整且 CLI 能正确解析,可省略 --ios.bundle 参数(但不可靠,不推荐)
  7. 构建成功后输出中包含云端临时下载链接(不会像 Android 那样本地有 APK)
  8. 如需永久链接,从临时链接下载 IPA 后上传到前端托管
  9. 详见 references/ios-cloud-pack-workflow.md

场景 I:微信小程序编译上传

默认动作:

  1. 先 HBuilderX 编译:cli publish mp-weixin --project ... --appid wxa10b843e85839619
  2. 再微信开发者工具上传:/Applications/wechatwebdevtools.app/Contents/MacOS/cli upload --project .../unpackage/dist/build/mp-weixin -v "版本号" -d "描述"
    • ⚠️ --project 必须指向编译产物目录 unpackage/dist/build/mp-weixin/,不是项目根目录
  3. 上传完成后 CLI 无法直接生成体验版二维码,需登录微信公众后台获取
  4. CLI 预览二维码生成不可靠preview --qr-format image --qr-outputTypeErrorauto-preview 报二维码路径无效。开发预览码只能通过微信开发者工具 GUI 获取。
  5. 详见 references/wechat-mp-upload-workflow.md

Common Pitfalls

  1. index.vue 当首页。 当前真实主入口是 connected.vue

  2. 把 App 更新和设备固件升级混成一件事。 这是两个不同层级的能力。

  3. 把反馈页误判成已接通完整后端。 现状代码显示仍有模拟提交痕迹。

  4. 为了改一个页面,顺手重构整套 BLE 逻辑。 这是高风险行为。

  5. 0x180A 设备信息读取与 charger proto notify 当成同一条链路。 在本项目里两者是分离的;如果 watchdog 只认 00008301 数据,就不能因为 0x180A 已成功而放松,也不能在 proto 首包到来前误判超时重启。

  6. 忽略平台差异。 HarmonyOS 与 Android/iOS 的 BLE 后台策略不同。

  7. 构建/打包时绕开 HBuilderX CLI 约束。 这个项目不是随便用一套通用 Web 命令就能等价处理的。

  8. 只写产品想象,不校验代码事实。 这个项目已有真实能力,不应用空洞 PRD 覆盖事实。

  9. 输出只有建议,没有优先级和验收口径。 这不符合本项目的 PM 协作要求。

  10. 把 HBuilderX CLI 当成可自由猜参数的工具。 涉及构建、云函数、打包时必须按 skill 中已验证命令执行。

  11. 做 device profile/路由透传时破坏现有 BLE 页面跳转语义。

  • searching.vue -> charger.vue 前,当前实现会先 _cleanupBle() 再导航;不要为了多带几个 query 参数把这个停扫时序删掉。
  • connected.vue 的“重连”不是直接进 charger.vue,而是先回 searching.vue 走 rediscovery,用来刷新 BLE 地址/缓存状态;不要把 profile 透传优化误做成绕过搜索页的直连捷径。
  • charger.vue.applyRouteOptions() 已经会按 serialNumber/deviceId 取 stored record,新增 profile merge 时优先复用这条早期数据源,而不是等到 0x180A 后才初始化页面身份。
  1. cli pack app-harmony 当成 Harmony debug/dev HAP 方案。 对这个仓库,已验证的 debug/dev 包链路是 unpackage/dist/dev/app-harmony + hvigor assembleHap ... buildMode=debug,优先走仓库脚本。

  2. 做鸿蒙正式包时只看 CLI 成功日志,不核验 release 产物与元数据。 对这个仓库,正式包至少要核对 unpackage/dist/build/app-harmony/build/outputs/release/pack.info;如需进一步确认,检查 .app 内部 .hapmodule.json 是否 debug=false

  3. 用通用严格解析误判 uni-app 文件。

  • manifest.json 在 HBuilderX/uni-app 项目中可能是 JSONC(含注释),不能直接用严格 JSON.parse 当作唯一语法检查;如需自动校验,应先用 strip-json-comments 等方式去注释/尾逗号后解析。
  • .vue 文件中 // #ifdef MP-WEIXIN// #ifdef APP-HARMONY 等条件编译块可能在同一函数作用域里声明同名变量;普通 Babel 全量解析会把多端条件块同时解析,从而报出实际平台编译不会同时存在的重复声明。遇到这类验证失败时,先和 HEAD:<file> 做基线比较;若 HEAD 已同样失败,不要把它当成本次 diff 引入的新阻断。
  • 提交前仍要跑 git diff --check、新增行安全扫描,并尽量对新增/改动逻辑做局部审查;不要因为全文件解析有既有条件编译噪音就跳过验证。
  1. 在 MC326/MINI/LITO 兼容实现里把 firmwareChannel 覆盖写进 deviceType
  • deviceType 在当前项目里仍应保持基础设备品类语义(如 charger),不要把它直接改成 charger-mini / charger-lito
  • 机型分流应通过独立的 firmwareChannel 字段完成;云对象查询按 deviceType + firmwareChannel 处理,并在 channel 未命中时仅回退到无 channel 的旧记录
  • 如果把 deviceTypefirmwareChannel 混成一层,会破坏 Scheme B 的兼容目标,也会让旧数据回退语义变得含混。
  1. 在 uni-app 多端项目中使用 SVG 图片作为设备/产品静态资源,但没有为微信小程序和 Android/iOS 准备 PNG 回退。
  • 微信小程序的 <image> 组件不支持 SVG 格式
  • Android/iOS 原生 image 组件对 SVG 的支持不可靠。
  • 鸿蒙平台 SVG 支持良好,但为了一致性和可维护性,本项目已统一使用 PNG 实物照片,并删除了所有设备 SVG 占位图。
  • 当前方案utils/device-profile.js 中全平台统一引用 PNG 常量,不再使用 #ifdef APP-HARMONY / #ifndef APP-HARMONY 条件编译切换格式。
  • 历史方案(已废弃,仅作参考):曾使用条件编译让鸿蒙走 SVG、其他平台走 PNG。
  • 详见 references/cross-platform-device-images.md
  1. V1.1 已接入 profile/OTA channel,但 firmwareChannel 为空时仍放行升级链路。
  • 这会让前端重新退回按 deviceType='charger' 查固件,等于把型号隔离保护绕开。
  • 至少要在 charger.vue 的"检查更新 / 选择固件 / 跳 upgrade"入口,以及 upgrade.vue 的"拉版本列表 / 开始升级"前做双重 guard。
  • 允许控制链路继续可用;禁止的是 OTA 放行,不是整机不可操作。
  1. 微信小程序上传时使用 miniprogram-ci 而非微信开发者工具 CLI。
  • 旧方案 miniprogram-ci 需要全局 npm 安装 + IP 白名单配置,已弃用。
  • ✅ 当前方案:使用微信开发者工具自带的 CLI(/Applications/wechatwebdevtools.app/Contents/MacOS/cli),前提是 DevTools 已打开项目且保持登录态。
  • 编译:cli publish mp-weixin --project ... --appid wxa10b843e85839619(HBuilderX → 微信项目)
  • 上传:cli upload --project .../unpackage/dist/build/mp-weixin -v "版本号" -d "描述"
  • 上传后无法从 CLI 获取体验版二维码,需登录微信公众后台获取;可用 cli preview --qr-format image --qr-output /tmp/qr.png 生成开发预览码。
  • 详见 references/wechat-mp-upload-workflow.md
  1. Android 云打包交互式提示用 pipe 输入(yes | / echo Y |)绕过。
  • HBuilderX CLI 的 Android 云打包在检测到云端队列已有项目时,会弹出 /dev/tty 交互式提示:「是否继续提交?」
  • echo "Y" |yes "Y" |printf 'Y\n' |不会生效——提示读取的是 /dev/tty 而不是 stdin。
  • ✅ 正确做法:使用 expectspawn(提供 PTY):expect -re "是否继续提交" { send "Y\r" }
  • 不要假设 --safemode false--confirm 能跳过这个提示(实测无效)。
  • 详见 references/android-cloud-pack-workflow.md
  1. iOS 云打包持续报 Bundle ID(AppID)不能为空,尽管已在多个位置配置。
  • HBuilderX CLI 的 pack --platform ios 读取的 Bundle ID 来源是 manifest.jsonplus.distribute.apple.appid不是 setting.jsonIOS_APPID,也不是 manifest.jsonios.bundleIdentifier
  • setting.json 是 GUI IDE 使用的配置,HBuilderX 运行期间会覆写 IOS_APPID / IOS_CERTFILE / IOS_PROFILE 为空——不要在 CLI 打包流程中依赖它。
  • 方式 A(manifest.json,不推荐):在 manifest.jsonplus.distribute 下添加 "apple" 节点。但因为 manifest.json 实际使用 app-plus 键而非 plus,且 JSONC 注释可能影响解析,此方式不可靠,已验证即使配置正确仍可能报错。
  • 方式 B(CLI 参数,推荐✅):直接传 --ios.bundle cn.lktop.likigo 绕过 manifest.json 解析问题,配合 --ios.profile / --ios.certfile / --ios.certpassword 完整传入。已验证稳定通过。
  • 辅助:确保项目级 hxiOSResign.json~/Library/Application Support/HBuilder X/projects/<hash>/hxiOSResign.json)存在且 CERTYPEapple-devapple-dis
  • 详见 references/ios-cloud-pack-workflow.md
  1. 用户发送多张设备实物照片时,反复用 PIL 颜色分析/区域采样来猜测型号。
  • 白底产品实物照片的平均 RGB 基本都在灰色范围(~170-200),颜色分析无法区分 MC326/MINI/LITO。
  • 不要像处理彩色 SVG 设计稿一样依赖色相差异;实物照片的型号区分靠外形和标签文字,这些不能用简单的平均色来推断。
  • 正确做法:最多做一次 file + ls -lh 确认文件基本信息后,直接向用户确认"哪张图对应哪个设备型号"。
  • 详见 references/cross-platform-device-images.md
  1. 用户点击管道弹窗「重连」但无效,日志显示 createBLEConnection 从未被调用。
  • 根因:Pipeline 在 maxRestarts 次自动重试后进入 state.phase = 'STOPPED'ble-pipeline.js:627),但 restart()scheduleRestart() 内部检查 if (state.phase === 'STOPPED') return(L642),导致用户的手动重连请求被直接丢弃。
  • restart() 虽重置了 restartCount = 0,但未改变 state.phase,所以 scheduleRestart 在 STOPPED 下立即返回。
  • 同样受影响resume() 也有 if (state.phase === 'STOPPED') return(L681)。
  • 修复方向:restart() 中先将 state.phase 从 STOPPED 恢复,或给 scheduleRestart()force 参数。
  • 详见 references/ble-state-machine-pitfalls.md
  1. 微信小程序首次搜索正常,后续搜索设备列表永远为空,但设备日志显示广播正常。
  • 根因:searching.vue:_cleanupBle() 调用 safeStopBluetoothDevicesDiscovery()await,是 fire-and-forget。
  • 微信小程序在 onHide 时可能挂起页面 JS 执行,BLE.stopBluetoothDevicesDiscoverycomplete 回调未调用 → ble-init.jsisScanning 标志位保持 true
  • 下次 safeStartBluetoothDevicesDiscovery 看到 isScanning=truecurrentScanOptionsKey 相同 → 直接返回 { reused: true }(L372-374),未启动实际扫描。
  • Android 原生 APP 理论上也可能触发(系统高负载/BLE 操作延迟大时),但微信小程序因 onHide JS 挂起机制几乎必现。
  • 修复方向:_cleanupBle()awaitsafeStartBluetoothDevicesDiscovery 增加僵尸扫描主动检测(超时无设备回调则重置并重启)。
  • 详见 references/ble-state-machine-pitfalls.md
  1. Vue methods 里加 await 时漏了 async 声明。
  • 在非 async 的 Vue methods 函数体内 patch 加了 await 调用,但忘记把函数声明从 methodName() { 改成 async methodName() {
  • HBuilderX/uni-app 的 Vite + vue/compiler-sfc 会直接报错:[vite:vue] [vue/compiler-sfc] Unexpected reserved word 'await'
  • 这是一个两处联动修改:不能只 patch 调用行而漏掉函数签名行。
  • 如果漏掉,Android 云打包和微信小程序编译都会失败(两者共享同一源码,编译期即暴露)。
  • 修复后必须重新编译验证,不要假设「patch 看起来对就行」。
  1. Android 云打包 CLI 轮询长时间无输出时误以为正常排队。
  • CLI 正常每 60 秒轮询一次队列位置;如果 8 分钟以上无任何输出,说明 CLI 与 DCloud 云端连接已断开。
  • Kill + restart 不会丢失已提交的打包任务(提交发生在"向云端发送打包请求..."阶段,早于轮询)。
  • 重启后的 CLI 会重新附加到同一云端任务并恢复状态轮询。
  1. 微信小程序上传时把 uni-app 项目根目录当成 --project 参数传给微信 CLI。
  • 微信开发者工具 CLI 的 upload/preview 命令需要编译后的原生小程序项目(含 app.json + project.config.json)。
  • uni-app 项目根目录没有这些文件 → 报错 app.json: 在项目根目录未找到 app.json
  • ✅ 正确路径:unpackage/dist/build/mp-weixin/unpackage/dist/dev/mp-weixin/
  • 如果 open 命令也需要指定 AppID:--appid wxa10b843e85839619,否则 Using AppID: undefined 会静默失败。

Verification Checklist

  • 已先核对相关代码与文档,而不是凭印象下结论
  • 如涉及首页/入口,已以 pages.json 为准
  • 如涉及升级,已区分 App 更新与设备固件 OTA
  • 如是 V1.1 device profile / OTA channel 场景,已确认 firmwareChannel 为空时不会放行 OTA(charger 入口 + upgrade 页双重 guard)
  • 如涉及 BLE,已确认平台与问题所在线路段
  • 如涉及构建/打包,已参考 hbuilderx-cliuni-app 技能
  • 如涉及反馈链路,没有把模拟能力描述成真实闭环
  • 输出中包含事实、问题、建议、优先级、验证方式中的核心要素
  • 输出中的产品判断与当前仓库事实一致

Notes

这是当前可直接用于 ~/Code/lktop/app 的正式项目约束 Skill。

后续如果页面入口、BLE 架构、升级链路、云对象能力、HBuilderX 构建链路或产品文档基线发生明显变化,应同步更新本 Skill。

Install via CLI
npx skills add https://github.com/cstcen/skills --skill lktop-app-project
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator