Files
dukang/.workbuddy/memory/2026-08-16.md
T
jacy 1c91e6bae9
CI / verify (push) Has been cancelled
v3.4.17 门店套餐审核快捷入口
2026-08-16 11:57:01 +08:00

6.0 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,代理是路径匹配不受影响。