Files
dukang/.workbuddy/memory/2026-08-16.md
T
jacy c0ce494732
CI / verify (pull_request) Has been cancelled
提交workbuddy记忆缓存
2026-08-16 12:29:07 +08:00

10 KiB
Raw Blame History

2026-08-16

新增:线上库同步本地 CLI 工具

  • 文件:deploy/sync-prod-db-to-local.sh(新建,未提交)
  • 用途:将生产库 dukang_prod(阿里云 RDS rm-bp139andp1aa385i9.mysql.rds.aliyuncs.com:3306,用户 dukangadmin)同步到本地 Docker MySQL dukang_haokelocalhost:6016 / 容器内 dukang-v1-mysqlroot/root)。
  • 原理:SSH 隧道借道 dukang-server-L 6018:rds:3306)→ 本地无 mysql 客户端,故在 dukang-v1-mysql 容器内跑 mysqldump/mysql,经 host.docker.internal:TUNNEL_PORT 连隧道;管道直导,不落临时文件。
  • 安全:默认先 docker exec mysqldump 备份本地到 deploy/backups/;需 --yes 跳过交互确认;--dry-run 只读远端 DATABASE_URL 并打印计划。
  • 远端凭据从 /opt/dukang/server/dukang-api/.env.production 的 DATABASE_URL 运行时解析(密码经 MYSQL_PWD 环境变量传入,避免命令行暴露)。
  • 已知限制:不支持密码含 @prod DB 名与本地不同(dukang_prod→dukang_haoke)靠 mysqldump 不带 --databases 实现库名映射。
  • 状态:仅跑通 --dry-run,未执行真实同步(待用户确认,因会覆盖本地库并拉取生产数据)。

修复:首次同步失败的根因

  • 失败现象:mysqldump 退出码 2,提示 本地库可能处于不一致状态(工具自身的失败兜底提示)。
  • 真实根因有两条:
    1. 密码解析错误:生产 DB 密码含 @ 字符(passHasAt=true)。原 bash 解析用「第一个 @」切分 userinfo/host,把密码里 @ 之后的部分截断,导致 Access denied。 修复:改为在服务端用 new URL() 解析,base64 回传各字段(user/host/port/db/password),本地 base64 -d 还原,彻底免疫 @/:/$ 等特殊字符。服务端 auth 测试 authTestStatus=0 验证密码正确。
    2. 权限不足dukangadmin(应用库用户)无 RELOAD/FLUSH_TABLES 权限。--single-transaction 仍会触发全局 FLUSH TABLES → Access denied。 修复:mysqldump 改用 --lock-tables=0(不发起 FTWRL+ --set-gtid-purged=OFF(RDS 启用 GTID,否则本地恢复会报 GTID_PURGED 错误),并保留 --skip-routines --skip-events --column-statistics=0 --no-tablespaces --add-drop-table --skip-triggers --no-create-db
  • 验证:结构导出(--no-data)在 4 组 flag 中仅 --lock-tables=0 / --skip-lock-tables(不含 --single-transaction)退出 0。
  • 现工具已修正并实际执行同步(--yes,先自动备份本地到 deploy/backups/)。
  • 注意:--lock-tables=0 无事务一致性快照;生产库在线写入期间导出可能有极小不一致,但恢复时 mysqldump 自带 FOREIGN_KEY_CHECKS=0,_dev 库可接受。若需完全一致快照,可给 dukangadmin 授 RELOAD 后用 --single-transaction。

修改:套餐审核导航样式恢复一致

  • 文件:apps/admin-web/src/layouts/AdminLayout.tsxattachPackageAuditBadge/store-package-audits 项)。
  • 诉求演变:用户先要求「文字恒为白色」→ 后改为「不要单独处理,保持与子菜单一致,只是多一个待审徽章图标」。
  • 最终实现:label 改为 <span style={{display:'inline-flex',gap:6}}>套餐审核{pendingCount>0 && <Badge count size="small"/>}</span>。文字无强制颜色,随菜单主题继承 normal/hover/selected 颜色;徽章仅 pendingCount>0 时作为图标提示,不参与着色。

发布流水线(本次收尾,含之前未上线的 8+1 文件)

  • 背景:此前「联系电话脱敏+套餐多行输入+同步工具」等 9 文件 commit 8de4179 已 push dev_jacy/dev/main,但生产发布失败deploy.env 丢失导致 未配置 DEPLOY_HOST)。
  • 修复发布:deploy.env 是 gitignore 的本地密钥文件,已丢失不可找回;改用 SSH 别名 dukang-server~/.ssh/configHostName 47.110.129.57 / User root / IdentityFile pem)覆盖:bash deploy/deploy-prod.sh --host dukang-server -- --skip-db
  • 关键排查:origin/* 本地缓存 ref 多次陈旧(误报 ahead/behind),必须以 git ls-remote 为准。本次真实远端:dev_jacy=8de4179、dev=c05cd0e、main=bac5c7a,与本地一致,无丢失。
  • 本次提交:bafb342 fix(admin) 套餐审核样式 → push dev_jacy → merge dev(0bfc19b) → merge main(029fd69) → push。
  • 发布结果:DEPLOY_EXIT=0==> 发版完成 (production),健康检查 api:200 / mini-user(h5):200,系统版本记录 commit 029fd69
  • 提示:以后若想恢复标准 bash deploy/deploy-prod.sh(不带 --host),需重建 deploy/deploy.env(从 deploy.env.example 复制,填入 DEPLOY_HOST=47.110.129.57 等;该文件 gitignore,勿提交)。

排查:h5-partner 本地 /login 调 /partner/me 报 401

  • 现象:http://localhost:5176/login 启动后控制台报 GET /api/v1/partner/me 401 (Unauthorized)
  • 结论:不是 bug,是登录页的「过期 token 探测」。链路:Vite 代理 /apilocalhost:3010(正常);后端返回 {"code":401,"message":"Missing token"}(说明后端在线、代理通)。ensureSession()api.ts:244)只在 localStorage 有 token 时才打 /partner/me;无 token 直接返回未登录。所以 401 来自之前测试残留的失效 token → 前端静默清除并展示登录表单,不崩、不弹错。刷新页面(token 已清)即不再出现。
  • 本地登录方式(关键,README 已过期):
    • MOCK_SMS=true(.env),短信走 mock,不连运营商;固定码 MOCK_SMS_FIXED_CODE 默认 999888README 写的 123456 已不准)。
    • README 的测试号 13700000001 不在本地同步库;本地 partner_account 共 9 个,可用真实号如 18049821889(Jacy) / 13073729990(queen)(均 ACTIVE)。
    • 流程:填真实合伙人手机号 → 获取验证码 → 验证码打印在 pnpm dev:api 后端终端Mock SMS → 180****8889 code=XXXXXX)→ 填码登录。
    • 注意 h5-partner 默认 5175,本次因 5175 被占自动落到 5176,代理是路径匹配不受影响。

发布:v3.4.17 门店套餐审核快捷入口 上生产

  • 提交 1c91e6bdev_jacy 上,含后端 admin-stores.service.ts + AdminStorePackagesSection/StorePackageAuditsPage/StoresPage 三前端 + 开发计划文档)。
  • 流水线:直接快进推送(避免 git checkout 工作树不刷新):git push origin dev_jacy + dev_jacy:dev + dev_jacy:main,三分支统一到 1c91e6b;本地 git branch -f dev/main origin/* 同步。
  • 部署:bash deploy/deploy-prod.sh --host dukang-server -- --skip-db(后端仅给列表响应加字段,无 schema 变更,故 skip-db)。
  • 结果:DEPLOY_EXIT=0,新 tag v3.4.17,全部应用构建通过,PM2 重启 dukang-api/h5-shop/h5-partner/admin-web(另拉起 h5-user),健康检查 api:200 / mini-user(h5):200,系统版本记录 commit 1c91e6b

发布:v3.4.18 套餐变更对比逐字段列出变动明细

  • 需求:套餐变更对比「将变动的地方详细列出来」(之前只给「新增/删除/变更/未变」粗粒度标记,不列具体字段)。
  • 改动仅在 apps/admin-web/src/pages/StorePackageAuditsPage.tsx
    • 新增 fieldChanges(live, proposed):逐字段比对 价格/套餐名称/菜品内容/可用时间/其他说明/图片,产出 label+旧值→新值 明细。
    • diffPackages 给「变更」行附 changes
    • PackageDetailCard 在「待审核」卡片底部渲染「变更明细」块(旧值删除线 → 新值加粗,橙色块)。
    • 抽屉顶部加「新增 X · 删除 Y · 变更 Z · 未变 W」汇总条。
  • 提交 bbd7e52feat(admin) 套餐变更对比逐字段列出变动明细),快进推送 dev_jacy/dev/main。
  • 部署:bash deploy/deploy-prod.sh --host dukang-server -- --skip-db(无 schema 变更)。
  • 结果:构建通过、PM2 重启 admin-web 等、健康检查 api:200 / mini-user(h5):200,系统版本记录 commit bbd7e52(无精确 tag,记 tag=-,无害)。
  • 已知局限:配对按「套餐名称」(空则索引) 位置匹配;若套餐被改名,会误判为「删除旧名+新增新名」而非「变更」,故名称变更不会出现在逐字段明细里。

优化:套餐变更对比·逐字差异 + 文档并入 v3.4.17

  • 需求:变动明细要能定位到文本中具体哪些字变了(逐字检查),且把开发计划文档合并到 v3.4.17 文档里(不再单独留 v3.4.18 文档)。
  • 代码改动(仍仅 StorePackageAuditsPage.tsx):
    • diffText(a,b)LCS 动态规划 (dp[i][j])+回溯,产出 equal/delete/insert 段落并合并相邻同类型;O(|a|·|b|),字段长度可控。
    • TextDiff({oldText,newText}):两行渲染——「原:」红删线标被删字、「新:」绿标新增字。
    • FieldChange 增加 kind: 'text'|'value':价格/图片走 旧→新;套餐名称/菜品内容/可用时间/其他说明走 TextDiff 逐字高亮。
    • 杜康好客-v3.4.17-门店套餐审核快捷入口.md 新增第 F 节「套餐变更对比·逐字段/逐字明细」,并把原先 v3.4.18 的字段级说明并入,删去独立 v3.4.18 文档计划。
  • 提交 ecd9973,快进推送 dev_jacy/dev/main,部署 --host dukang-server -- --skip-db
  • 结果:构建通过、健康检查 api:200 / mini-user(h5):200,系统版本记录 commit ecd9973tag=-,无害)。
  • 验证要点:开任一「变更」套餐的待审核卡片 → 底部「变更明细」→ 菜品/说明等文本以红删+绿增逐字呈现。

优化:h5-partner 门店详情·门店套餐「编辑套餐」按钮

  • 需求:按钮缩小、靠最右侧、保持美观。根因:.partner-btn-outline 是整行大按钮(flex:1; height:48px; font-size:16px),放在卡片标题右侧会被拉伸成大块。
  • 改动:apps/h5-partner/src/styles.css 新增 .partner-btn-outline--compactflex:none; height:30px; padding:0 14px; font-size:13px; font-weight:500; border-radius:var(--radius-sm); color:var(--color-primary)hover 用 color-mix 8% 底色);StoreDetailPage.tsx:288 的「编辑套餐」按钮加该类(父级 space-between 已保证贴右)。
  • 提交 69e201f,快进推送 dev_jacy/dev/main,部署 --host dukang-server -- --skip-db
  • 结果:构建通过、PM2 重启 h5-partner、健康检查 api:200 / mini-user(h5):200,系统版本记录 commit 69e201ftag=-,无害)。
  • 注意:StoreDetailPage.tsx:311 有个历史遗留 TS 错误(status === 'CLOSED' 类型无重叠),与本改动无关,未动。