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

7.8 KiB
Raw Blame History

当前数据库是本机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 .envADMIN_DB_*
tenantPool bill_query(业务库) 127.0.0.1:15432FRP 隧道 → 本机 PG trust(用户 freedak,无需密码) tenant_configs.db_port=15432
pool bill_query(业务库) 127.0.0.1:15432FRP 隧道 → 本机 PG trust(用户 freedak,无需密码) .envDB_*

⚠️ tenant_configs 表中 db_port 必须为 15432FRP 隧道),db_password 为 NULLtrust 认证)。 ⚠️ adminPool 连接服务器本地 5432,需要 ADMIN_DB_PASSWORD=sbrain2026

数据库分布

数据库 位置 存储内容
sbrain_admin 服务器本地 PostgreSQL5432 平台管理员、租户配置(tenant_configs)、所有租户用户(tenant_users
bill_query 本机 PostgreSQL(通过 frp 暴露为 15432 租户业务数据(销售、任务、成本分析等)

多租户数据隔离

  • 认证流程:用户登录 → 查 sbrain_admin.tenant_users → bcrypt 验证 → JWT 含 tenantId
  • 数据隔离:业务请求 → tenantDbMiddleware 根据 JWT 中的 tenantIdtenant_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 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):

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

管理命令

# 停止 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 未运行时)

cd /Users/freedak/frp && ./frpc -c frpc.toml &

本地开发

后端开发

cd server && npm run dev

后端运行在 http://localhost:3333,连接本地 PostgreSQLlocalhost:5432,数据库 bill_query)。

前端开发

cd client && npm run dev

访问 http://localhost:5173Vite proxy 自动转发 /apilocalhost:3333)。

服务器后端管理

# 查看后端状态
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_adminSCRAM 认证,用户 sbrain_admin,密码 sbrain2026
  • tenantPool / pool 连 FRP 隧道 15432 的 bill_querytrust 认证,用户 freedak,无需密码)
  • tenant_configs 表中 db_port 必须为 15432db_password 为 NULLtrust 认证)
  • pg 库在 password 为空字符串时会触发 SCRAM 认证失败,因此 admin-pool.tsdatabase.tstenant-db.ts 中空密码时不传 password 参数
  • deploy.sh 每次部署会覆盖服务器 .env,其中包含 ADMIN_DB_* 配置(ADMIN_DB_PORT=5432ADMIN_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/.envDB_PORT=15432 连接 frp 隧道端口
  • frpc 断开后线上前端 API 会失效,需重新启动 frpc
  • launchd 服务开机自启,关闭 IDE/终端不影响;仅注销/关机时停止,下次登录/开机自动恢复

0.1/0.2分支为 SBrainCO,备份在/Volumes/Projects/2026/SBrainCO-20260805.zip 0.3分支为 SBrainCO3