Files
SBrainCO/run.md
T
freedakgmail d04e837d9c V3.0: 门店分级与风险等级页面、数据填充脚本、后端API
- 新增V3.0数据库表结构(12-15)和数据填充脚本(16)
- 新增后端路由: store-grade, enterprise, product, intelligence, alert, scheduler, target
- 新增前端页面: StoreGradePage, EnterprisePage, ProductLifecyclePage, IntelligencePage, AlertManagementPage, DataImportPage, SchedulerManagementPage, TargetManagementPage
- 门店分级: 自动分级算法(达成率40%+毛利率25%+会员15%+风险20%)
- 风险等级: 基于mv_store_risk_rating模型展示风险分布和原因
- 弹窗: 雷达图+详细指标+分级原因+风险原因(primary_issue)
- FilterableTable: filterOptions支持{value,label}对象格式
2026-08-05 20:09:39 +08:00

183 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
当前数据库是本机Homebrew PostgreSQL 15,数据库名为 bill_query,端口5432,仅监听 localhost;当前用户 freedak 是超级用户,本机认证方式为 trust。这适合本机开发,但不适合直接照搬到服务器生产环境。前端浏览器也不应直接连接PostgreSQL,必须通过后端API访问。
## 登录账号
### 平台管理员
| 用户名 | 密码 | 角色 | 说明 |
|--------|------|------|------|
| 平台管理员 | 123 | platform_admin | 管理所有租户,登录后进入平台管理后台 |
### 租户用户(存储在服务器 sbrain_admin 数据库)
| 用户名 | 密码 | 角色 | 租户 |
|--------|------|------|------|
| 总部管理员 | 123 | hq | tenant_a(西部马华) |
> 租户管理员(hq)登录后可在系统内创建区域经理、店长、商品部等角色用户。
> 密码使用 bcrypt 加密存储。
## 架构(2026-08-02 更新:SaaS 多租户)
```
浏览器 → https://dm.all8ai.top
→ Nginx(服务器) → /api/ → 127.0.0.1:9333 (服务器后端, pm2管理)
→ 服务器本地 PostgreSQL:5432 → sbrain_admin(平台库:租户配置、用户认证)
→ frp隧道 127.0.0.1:15432 → 本机PostgreSQL:5432 → bill_query(租户业务库)
```
### 数据库连接(重要)
后端连接两个不同的数据库,走不同端口:
| 连接池 | 目标数据库 | 连接地址 | 认证方式 | 配置来源 |
|--------|-----------|---------|---------|---------|
| `adminPool` | `sbrain_admin`(平台库) | `127.0.0.1:5432`(服务器本地 PG | scram-sha-256(用户 `sbrain_admin`,密码 `sbrain2026` | `.env``ADMIN_DB_*` |
| `tenantPool` | `bill_query`(业务库) | `127.0.0.1:15432`(FRP 隧道 → 本机 PG | trust(用户 `freedak`,无需密码) | `tenant_configs.db_port=15432` |
| `pool` | `bill_query`(业务库) | `127.0.0.1:15432`(FRP 隧道 → 本机 PG | trust(用户 `freedak`,无需密码) | `.env``DB_*` |
> ⚠️ `tenant_configs` 表中 `db_port` 必须为 `15432`FRP 隧道),`db_password` 为 NULLtrust 认证)。
> ⚠️ `adminPool` 连接服务器本地 5432,需要 `ADMIN_DB_PASSWORD=sbrain2026`。
### 数据库分布
| 数据库 | 位置 | 存储内容 |
|--------|------|---------|
| `sbrain_admin` | 服务器本地 PostgreSQL(5432 | 平台管理员、租户配置(tenant_configs)、所有租户用户(tenant_users |
| `bill_query` | 本机 PostgreSQL(通过 frp 暴露为 15432) | 租户业务数据(销售、任务、成本分析等) |
### 多租户数据隔离
- **认证流程**:用户登录 → 查 `sbrain_admin.tenant_users` → bcrypt 验证 → JWT 含 `tenantId`
- **数据隔离**:业务请求 → `tenantDbMiddleware` 根据 JWT 中的 `tenantId``tenant_configs` 获取该租户数据库连接信息 → `AsyncLocalStorage` 设置租户连接池 → 所有 `query()` 自动走对应租户数据库
- **租户用户管理**:平台管理员为租户创建管理员(hq),租户管理员在系统内创建区域经理/店长/商品部等用户,均存储在 `sbrain_admin.tenant_users` 表中,通过 `tenant_id` 字段区分
### 关键文件
| 文件 | 职责 |
|------|------|
| `server/src/config/tenant-db.ts` | 租户连接池缓存 + AsyncLocalStorage |
| `server/src/config/admin-pool.ts` | 平台库连接池(通过 `ADMIN_DB_*` 环境变量配置) |
| `server/src/config/database.ts` | 主业务库连接池 + 全局 `query()` 函数(自动注入数据权限) |
| `server/src/middleware/tenant-db.ts` | 根据 JWT tenantId 动态切换数据库 + 注入用户 scope |
| `server/src/middleware/data-scope.ts` | 数据权限工具函数(`getDataScope` / `scopeStoreFilter` |
| `server/src/routes/auth.ts` | 租户用户登录(查 tenant_users + bcrypt |
| `server/src/routes/admin.ts` | 平台管理 API + 租户内用户管理 API |
| `server/sql/11_tenant_management.sql` | 平台数据库建表 SQL |
## 部署流程
### 一键部署(前端+后端)
```bash
bash deploy.sh # 全量部署(后端+前端)
bash deploy.sh server # 只部署后端
bash deploy.sh front # 只部署前端
```
- 后端:rsync 同步到服务器 `/opt/sbrain-server` + npm install + pm2 重启
- 前端:构建 + scp 上传到服务器 `/var/www/dm.all8ai.top`
### 本机 frp 隧道(launchd 系统级服务)
frpc 配置(`/Users/freedak/frp/frpc.toml`):
```toml
serverAddr = "152.136.182.184"
serverPort = 7000
loginFailExit = false
auth.token = "frp_gitea_2026"
[[proxies]]
name = "dm-db"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5432
remotePort = 15432
```
已配置为 macOS launchd 系统级服务,开机自动启动,崩溃自动重启,与 IDE 无关。
| 服务 | plist | 日志 |
|------|-------|------|
| frp 隧道 (5432→15432) | `~/Library/LaunchAgents/com.frp.client.plist` | `~/Library/Logs/frpc.log` |
#### 管理命令
```bash
# 停止 frpc
launchctl bootout gui/$(id -u)/com.frp.client
# 启动 frpc
launchctl load ~/Library/LaunchAgents/com.frp.client.plist
# 查看日志
tail -f ~/Library/Logs/frpc.log
# 检查状态
pgrep -l frpc
curl -s https://dm.all8ai.top/api/health
```
#### 手动启动 frpc(备用,launchd 未运行时)
```bash
cd /Users/freedak/frp && ./frpc -c frpc.toml &
```
## 本地开发
### 后端开发
```bash
cd server && npm run dev
```
后端运行在 `http://localhost:3333`,连接本地 PostgreSQL`localhost:5432`,数据库 `bill_query`)。
### 前端开发
```bash
cd client && npm run dev
```
访问 `http://localhost:5173`Vite proxy 自动转发 `/api``localhost:3333`)。
## 服务器后端管理
```bash
# 查看后端状态
ssh ubuntu@152.136.182.184 'pm2 status sbrain-server'
# 查看后端日志
ssh ubuntu@152.136.182.184 'pm2 logs sbrain-server --lines 50'
# 重启后端
ssh ubuntu@152.136.182.184 'pm2 restart sbrain-server'
# 查看后端 .env
ssh ubuntu@152.136.182.184 'cat /opt/sbrain-server/.env'
```
## 注意事项
- **平台库 `sbrain_admin` 在服务器本地 PostgreSQL5432**,业务库 `bill_query` 在本机 PostgreSQL(通过 frp 暴露为 15432
- `adminPool` 连服务器本地 5432 的 `sbrain_admin`SCRAM 认证,用户 `sbrain_admin`,密码 `sbrain2026`
- `tenantPool` / `pool` 连 FRP 隧道 15432 的 `bill_query`trust 认证,用户 `freedak`,无需密码)
- `tenant_configs` 表中 `db_port` 必须为 `15432``db_password` 为 NULLtrust 认证)
- `pg` 库在 `password` 为空字符串时会触发 SCRAM 认证失败,因此 `admin-pool.ts``database.ts``tenant-db.ts` 中空密码时不传 `password` 参数
- `deploy.sh` 每次部署会覆盖服务器 `.env`,其中包含 `ADMIN_DB_*` 配置(`ADMIN_DB_PORT=5432``ADMIN_DB_PASSWORD=sbrain2026`),修改 `.env` 配置必须同步修改 `deploy.sh`
- 租户用户统一存储在 `sbrain_admin.tenant_users` 表,通过 `tenant_id` 区分租户
- `tenant_users.region` 字段为 `VARCHAR(500)`,区域经理的 `region` 存储逗号分隔的 `store_code` 列表(如 `0010,0011,0014`
- 密码使用 bcrypt 加密,平台管理员密码目前仍为明文(后续可改)
- 本机只需运行 frpc(launchd 自启),后端已部署到服务器
- 修改后端代码后执行 `bash deploy.sh server` 部署到服务器
- 修改前端代码后执行 `bash deploy.sh front` 部署到服务器
- 全量部署执行 `bash deploy.sh`(后端+前端)
- `server/.env`(本机开发用)中 `DB_PORT=5432` 连接本地数据库,不要改为 5433
- 服务器 `/opt/sbrain-server/.env``DB_PORT=15432` 连接 frp 隧道端口
- frpc 断开后线上前端 API 会失效,需重新启动 frpc
- launchd 服务开机自启,关闭 IDE/终端不影响;仅注销/关机时停止,下次登录/开机自动恢复
0.1/0.2分支为 SBrainCO,备份在/Volumes/Projects/2026/SBrainCO-20260805.zip
0.3分支为 SBrainCO3