# 本次更新说明（2026-07-03）— 登录门控 + 多租户加价

## 更新主题

**管理端登录改造、嵌入演示客户登录、宿主 API 按客户加价**

| 项目 | 说明 |
|------|------|
| 打包时间 | 2026-07-03 |
| 适用场景 | 服务器**已有**查价项目，同步本次代码 |
| 是否改库 | **不必**重导 `chajia.sql`；安装脚本会自动 `prisma migrate deploy` |
| 是否改 `.env` | **保留**服务器已有 `.env`；可删除已废弃的 `NEXT_PUBLIC_EMBED_DEMO_*` |
| 是否必须清 Redis | **建议**（避免旧报价缓存） |

### 本次主要变更

1. **管理端** `/login`：不再预填/展示演示账号，须手动输入密码
2. **嵌入演示** `/embed-demo`：客户编号 + 密码 `123456` 登录，按客户展示加价并查价
3. **宿主 API**：按 Token 对应 `customer_id` 加价（如 `CUST_002`）
4. **客户管理**：管理端可签发 API Key，多客户无需改 `.env`
5. seed 默认管理员密码改为 **`kj123456`**（已有库需手动改密，见下方）

### 已有服务器：管理员改密

若 `admin_demo` 仍为旧密码 `Demo@123`，登录管理端后在个人设置改密，或在服务器执行：

```bash
cd /home/project/chajia
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml exec rpa-worker \
  node -e "const b=require('bcryptjs');b.hash('kj123456',10).then(h=>console.log(h))"
```

将输出的哈希更新到 `admin_user.password_hash`（用户名 `admin_demo`）。

### 快速更新步骤（场景 B）

```bash
cd /home/project/chajia
cp .env .env.backup.$(date +%Y%m%d)
# 用 zip 解压后的「代码/」覆盖本目录（勿覆盖 .env）
chmod +x deploy/install-bt-host-mysql.sh
bash deploy/install-bt-host-mysql.sh
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml exec redis redis-cli FLUSHDB
```

### 验收

| 页面 | 操作 | 预期 |
|------|------|------|
| `/login` | `admin_demo` / `kj123456` | 进入管理端 |
| `/embed-demo` | `CUST_002` / `123456` | 显示 CUST_002 加价配置并可查价 |
| `/embed-demo` | 换 `CUST_001` 登录 | 加价配置变化 |

---

# 历史说明（2026-07-01）— 首次上服务器

## 更新主题

**Priority1 独立询价链路 + 宿主公开 API + 报价展示与解析修复**

| 项目 | 说明 |
|------|------|
| 打包时间 | 2026-07-01 |
| 适用场景 | 本地开发已久，**第一次**将完整代码同步到服务器 |
| 是否改库 | **首次部署需导入** `数据库/chajia.sql`；仅更新代码时**不必**重导 |
| 是否改 `.env` | **首次**从模板复制并填写；**更新时保留**服务器已有 `.env`，仅**追加**下方新变量 |
| 是否必须清 Redis | **建议**（避免读到旧报价缓存） |

---

## 本次主要功能（相对服务器旧版）

1. **Priority1** 独立询价（LTL 卡片 / FTL 日历），不再复用 MotherShip 结果面板  
2. **宿主公开 API**：`POST /api/host/quote/candidates`、`POST /api/host/quote/submit`  
3. **报价解析修复**：承运商、金额以 Feathery 摘要为准，与官网卡片一致  
4. **MotherShip** 档位解码放宽（Denver→Boston 等路线）  
5. RPA Worker 提速：`RPA_DWELL_MS=0`、`RPA_PRIORITY1_WORKER_FAST=true`
6. **构建修复**：Priority1 类型统一，Docker `npm run build` 可通过
7. **浏览器修复**：Priority1 Worker 使用镜像内置 Chromium（勿在服务器设 `RPA_BROWSER_CHANNEL=chrome`）
8. **暂无报价修复**：Priority1 失败不再误用 MotherShip 历史缓存；无数据时 API 返回明确失败原因
9. **FTL 日历修复**：修复 `Invalid Date`，并按官网真实日期落格显示每日金额

---

## 重要：`.env` 检查（本次必做）

服务器 `.env` 中 **不要** 出现：

```env
RPA_BROWSER_CHANNEL=chrome
```

若存在请删除或注释。Docker Worker 无系统 Chrome，设此项会报：

`Chromium distribution 'chrome' is not found at /opt/google/chrome/chrome`

---

## 零、开发机打包（Windows）

在项目根目录执行：

```powershell
cd X:\work\chajia
powershell -ExecutionPolicy Bypass -File deploy\pack-server-upload.ps1
```

成功后生成目录：

```
上传到服务器/
├── README.md              # 通用说明
├── RELEASE-NOTES.md       # 本次部署/更新详细步骤（必读）（操作步骤）
├── 辅助脚本/              # API 验收（可选）
│   ├── test-denver-boston.sh
│   └── test-peachtree-tremont.sh
├── 代码/                  # ← 上传此目录全部内容到服务器
└── 数据库/                # 首次部署需导入
    ├── chajia.sql
    ├── chajia.sql.gz
    └── README.md
```

将整个 **`上传到服务器`** 文件夹打成 **zip**，用宝塔文件管理 / FTP / `scp` 传到服务器后解压。

---

## 一、场景判断

| 场景 | 你要做的事 |
|------|------------|
| **A. 服务器从未装过查价** | 导入数据库 → 上传代码 → 配置 `.env` → 执行安装脚本 |
| **B. 服务器已有旧版查价** | 只上传 `代码/` 覆盖 → **勿覆盖 `.env`** → 补全新变量 → 执行安装脚本 |

以下以宝塔 + 宿主机 MySQL + Docker 为例（路径 `/home/project/chajia`，端口 `30325`）。

---

## 二、场景 A — 全新首次部署

### 2.1 宝塔 MySQL

1. 创建数据库 **`chajia`**，字符集 **`utf8mb4`**
2. 导入 **`数据库/chajia.sql`**
3. 创建用户 **`chajia`**，授权主机 **`172.%`**（Docker 容器访问宿主机 MySQL）

```sql
-- 示例（密码换成宝塔里实际密码）
GRANT ALL PRIVILEGES ON chajia.* TO 'chajia'@'172.%';
FLUSH PRIVILEGES;
```

### 2.2 上传代码

将 **`代码/`** 内**全部文件**上传到：

```
/home/project/chajia/
```

### 2.3 配置环境变量

```bash
cd /home/project/chajia
cp deploy/.env.bt-host-mysql.example .env
nano .env
```

**必改项**（搜索 `CHANGE_ME` 或对照宝塔）：

| 变量 | 说明 |
|------|------|
| `APP_PORT` | 对外端口，如 `30325` |
| `PUBLIC_HOST` | 服务器内网 IP |
| `MYSQL_PASSWORD` | 宝塔 MySQL 用户 `chajia` 的密码 |
| `DATABASE_URL` | `mysql://chajia:密码@host.docker.internal:3306/chajia`（密码与上一行一致） |
| `JWT_SECRET` | 随机长串 |
| `HOST_SERVICE_TOKENS` | 内网 API Token（JSON 单行） |
| `CUSTOMER_REGISTRY` | 如 `CUST_001` |

模板已含 Priority1 提速项，确认存在即可：

```env
RPA_DWELL_MS=0
RPA_SLOW_MO_MS=0
RPA_PRIORITY1_WORKER_FAST=true
RPA_MOCK_MODE=false
```

### 2.4 安装并启动

```bash
chmod +x deploy/install-bt-host-mysql.sh
bash deploy/install-bt-host-mysql.sh
```

约 **5～15 分钟**（Docker 构建镜像）。完成后脚本会输出内网访问地址。

### 2.5 防火墙

宝塔 / 安全组放行 **`30325`**（内网即可）。**不要**对公网开放 3306、6379。

---

## 三、场景 B — 已有旧版，首次同步本地新代码

### 3.1 备份（强烈建议）

```bash
cd /home/project/chajia
cp .env .env.backup.$(date +%Y%m%d)
# 可选：整目录备份
# cd /home/project && tar czf chajia-backup-$(date +%Y%m%d).tar.gz chajia
```

### 3.2 上传代码

用 **`代码/`** 覆盖 `/home/project/chajia/`，**不要上传或覆盖 `.env`**。

### 3.3 补全 `.env` 新变量（在原有基础上追加）

若服务器 `.env` 较旧，用 `nano .env` 检查并补上（没有则加）：

```env
# Priority1 / Worker 提速
RPA_DWELL_MS=0
RPA_SLOW_MO_MS=0
RPA_QUOTE_POLL_MS=600
RPA_PRIORITY1_WORKER_FAST=true

# 宿主公开 API（按需）
HOST_PUBLIC_API_ENABLED=true
HOST_PUBLIC_DEFAULT_CUSTOMER_ID=CUST_001

# embed-demo 前端 Token（须与 HOST_SERVICE_TOKENS 的 key 一致）
NEXT_PUBLIC_EMBED_DEMO_SERVICE_TOKEN=chajia-neibu-2026
NEXT_PUBLIC_EMBED_DEMO_CUSTOMER_ID=CUST_001
```

改 `.env` 后需**重建 next-app**（见 3.5）。

### 3.4 执行更新

```bash
cd /home/project/chajia
test -f .env && echo "OK: .env exists" || { echo "ERROR: 缺少 .env"; exit 1; }

chmod +x deploy/install-bt-host-mysql.sh
bash deploy/install-bt-host-mysql.sh
```

脚本自动：`docker compose build` → 启动 **next-app + rpa-worker + scheduler + redis** → `prisma migrate deploy`。

### 3.5 若只改了 `.env` 未改代码

```bash
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml up -d --build next-app
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml restart rpa-worker scheduler
```

### 3.6 清空 Redis 报价缓存（建议）

```bash
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml exec redis redis-cli FLUSHDB
```

---

## 四、部署后检查

```bash
cd /home/project/chajia
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml ps
```

应看到 **`next-app`、`rpa-worker`、`scheduler`、`redis`** 均为 **Up**。

```bash
curl -I http://127.0.0.1:30325
```

浏览器访问（IP 换成实际）：

| 用途 | 地址 |
|------|------|
| 嵌入演示 | `http://192.168.2.14:30325/embed-demo` |
| 管理端 | `http://192.168.2.14:30325/admin/alerts` |
| 默认账号 | `admin_demo` / `Demo@123`（上线后请改密） |

查看 Worker 日志：

```bash
docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml logs -f rpa-worker --tail 100
```

---

## 五、验收测试

将 `192.168.2.14:30325` 换成实际 **IP:端口**。

### 5.1 MotherShip 回归（embed-demo → MotherShip）

```bash
export CHAJIA_BASE_URL="http://192.168.2.14:30325"
export CHAJIA_SERVICE_TOKEN="chajia-neibu-2026"
export CHAJIA_CUSTOMER_ID="CUST_001"
bash 辅助脚本/test-denver-boston.sh
```

### 5.2 Priority1（embed-demo 切换到 Priority1）

1. 打开 `/embed-demo`，选择 **Priority1**
2. 填写 LTL 询价（单托 500 lb 等）
3. **预期**：出现官网风格 LTL 卡片；承运商为真实名称（非「未解析承运商」）；金额与官网一致

### 5.3 失败排查

| 现象 | 处理 |
|------|------|
| `Can't connect to MySQL` / P1000 | `.env` 密码与宝塔不一致；用户未授权 `172.%` |
| 询价一直 `processing` | 查 `rpa-worker` 日志；确认 `RPA_MOCK_MODE=false` |
| Priority1 承运商/金额不对 | 确认已**重建 rpa-worker 镜像**（必须跑完整 `install-bt-host-mysql.sh`） |
| embed-demo 卡「正在查询报价」 | `restart rpa-worker`；检查 `GET /api/quotes/{id}` 是否返回 JSON |
| 构建很慢 / 内存不足 | 服务器建议 **4GB+** 内存；构建时勿并发多个 compose build |

---

## 六、常用运维命令

```bash
cd /home/project/chajia
COMPOSE="docker compose --env-file .env -f deploy/docker-compose.bt-host-mysql.yml"

# 查看日志
$COMPOSE logs -f next-app
$COMPOSE logs -f rpa-worker

# 重启全部
$COMPOSE restart

# 仅重启 Worker（改 RPA 逻辑后建议）
$COMPOSE up -d --build rpa-worker

# 停止
$COMPOSE down
```

---

## 七、回滚

保留更新前目录或 zip 备份。出问题时还原文件后：

```bash
bash deploy/install-bt-host-mysql.sh
```

---

## 八、文档索引

| 文档 | 路径 |
|------|------|
| 打包目录说明 | `上传到服务器/README.md` |
| 宝塔部署详解 | `代码/deploy/宝塔部署说明.md` |
| API 对接 | `代码/deploy/API.md` |
| 第三方对接 | `代码/deploy/第三方对接指南.md` |
