6.0 KiB
6.0 KiB
2026-08-16
新增:线上库同步本地 CLI 工具
- 文件:
deploy/sync-prod-db-to-local.sh(新建,未提交) - 用途:将生产库
dukang_prod(阿里云 RDSrm-bp139andp1aa385i9.mysql.rds.aliyuncs.com:3306,用户dukangadmin)同步到本地 Docker MySQLdukang_haoke(localhost:6016 / 容器内dukang-v1-mysql,root/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,提示本地库可能处于不一致状态(工具自身的失败兜底提示)。 - 真实根因有两条:
- 密码解析错误:生产 DB 密码含
@字符(passHasAt=true)。原 bash 解析用「第一个 @」切分 userinfo/host,把密码里@之后的部分截断,导致 Access denied。 修复:改为在服务端用new URL()解析,base64 回传各字段(user/host/port/db/password),本地base64 -d还原,彻底免疫@/:/$等特殊字符。服务端 auth 测试authTestStatus=0验证密码正确。 - 权限不足:
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。
- 密码解析错误:生产 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.tsx的attachPackageAuditBadge(/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/config:HostName 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,与本地一致,无丢失。 - 本次提交:
bafb342fix(admin) 套餐审核样式 → push dev_jacy → merge dev(0bfc19b) → merge main(029fd69) → push。 - 发布结果:
DEPLOY_EXIT=0,==> 发版完成 (production),健康检查 api:200 / mini-user(h5):200,系统版本记录 commit029fd69。 - 提示:以后若想恢复标准
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 代理
/api→localhost: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默认999888(README 写的 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,代理是路径匹配不受影响。