1. 系统概述
天蓬客服是一套面向企业的「智能在线客服 + 多租户工单」SaaS 系统。它把网站、微信、App、H5、小红书、闲鱼等多个渠道的客户咨询,统一汇聚到客服工作台,由坐席实时接待,并支持知识库自动应答、快捷回复、会话转接、工单流转与多租户账号隔离。
产品定位
- 企业对外:一个轻量、科技蓝白风格的客服入口,客户无需注册即可咨询。
- 坐席对内:一个实时工作台,集中处理所有渠道的会话、访客画像与工单。
- 管理员:一个后台,管理账号、坐席、套餐、支付、渠道与系统配置。
三大核心角色
| 角色 | 入口 | 典型动作 |
|---|---|---|
| 访客(客户) | 网站挂件 / 微信 / H5 / 各渠道 | 发起咨询、查看帮助 |
| 坐席(客服) | /agent 工作台 | 接待会话、转接、标记、关闭、查知识库 |
| 管理员 | /admin 后台 | 管账号、坐席、套餐、支付、渠道、审计、短信 |
2. 技术架构
系统采用「反代 → 应用容器 → 数据库」三层架构,单进程 Node 服务同时承载 API、WebSocket 与前端静态资源:
/ 与 /ws,完成 WebSocket 协议升级/api/* REST 接口、/ws 实时 WebSocket、web/dist 前端静态托管、sitemap.xml / robots.txt技术栈
| 层 | 技术 | 说明 |
|---|---|---|
| 前端 | Vue 3 + Vite + Vue Router(history 模式) | 单页应用,构建产物由后端托管 |
| 后端 | Node.js + Express | 单进程同时提供 API、WebSocket 与静态资源 |
| 数据库 | MySQL(mysql2 连接池) | 账号 / 坐席 / 会话 / 消息 / 工单 / 知识库 / 渠道等 |
| 实时 | 原生 ws WebSocket | 会话列表、消息、审计日志实时推送 |
| 微信 | 原生 https(不引第三方 HTTP 客户端) | 扫码登录 OAuth2、用户信息获取 |
| 短信 | 联麓信息模板短信 API | 手机号绑定验证码;未配置时开发态回显 |
| 部署 | Docker 多阶段构建 + 1Panel | 前端 build 与后端运行时合并为单镜像 |
路由模式(history)
前端使用 createWebHistory(),URL 无 #。直接访问 /admin、/agent、/embed 或刷新子路由时,由后端 app.get('*') 回退到 index.html 交由前端接管;其中登录后控制台页回退时注入 noindex,避免被搜索引擎收录为重复首页。
3. 核心功能
3.1 在线客服工作台(/agent)
坐席的统一工作界面:
- 实时会话:WebSocket 推送新消息、会话状态变更,无需刷新。
- 访客画像:姓名、来源渠道、标签、备注、历史会话。
- 会话操作:转接其他坐席、打标签、关闭会话。
- 快捷回复:常用话术一键发送。
- 知识库(机器人):命中关键词时自动应答;
__TRANSFER__指令触发转人工。 - 多渠道标识:每条会话按渠道显示品牌色(微信绿、小红书红、闲鱼橙等)。
3.2 多渠道接入
系统在 seed.js 预置渠道,管理员可在后台启用 / 禁用并填写配置:
| 渠道 | key | 类别 | 状态 |
|---|---|---|---|
| 微信 | wechat | 社交平台 | 启用 |
| 网站挂件 | web | 自有渠道 | 启用 |
| H5 | h5 | 自有渠道 | 启用 |
| 支付宝 | alipay | 社交平台 | 可选 |
| 抖音 | douyin | 短视频 | 可选 |
| 快手 | kuaishou | 短视频 | 可选 |
| 企业微信 | wecom | 社交平台 | 可选 |
| App | app | 移动端 | 可选 |
| 小红书 | xiaohongshu | 社交平台 | 可选 |
| 闲鱼 | xianyu | 电商平台 | 可选 |
接入某渠道 = 在后台填入对应开放平台凭证(如微信 AppID / AppSecret、小红书 Client Key、淘宝开放平台 AppKey 等),保存后该渠道咨询自动汇聚到工作台。
3.3 微信扫码登录 + 手机号绑定闸门
登录链路(server/routes/wechat.js):
- 客户扫码 → 微信 OAuth2 授权 → 回调
GET /api/wechat/callback。 - 服务端按
openid查找坐席;不存在则自动注册新账号 + 新坐席(扫码即注册)。 - 手机号闸门:若该坐席未绑定手机号,不下发完整会话,而是下发
bindToken(HMAC-SHA256 签名,10 分钟有效)。 - 前端弹出手机号绑定弹窗 → 调
/api/sms/send发验证码 →/api/sms/verify校验并绑定 → 换取完整会话令牌(写入 httpOnly Cookie)。
3.4 短信验证码(联麓信息)
模块:server/sms.js + server/routes/sms.js。
- 真实通道:配置联麓
MchId / AppId / key / SignName / TemplateId后,调用模板短信 API 真实下发。 - 开发态(默认):未配置真实凭证时,验证码不真实发送,仅在发送记录中回显(
channel='dev'),便于联调。 - 限流:同手机号 60 秒冷却、10 分钟内最多 5 次、验证码有效期 10 分钟、最多试 5 次。
- 管理后台:
/api/sms分页展示发送记录(时间 / 手机号 / 场景 / 通道 / 状态 / 明细);/api/sms/config脱敏展示与保存联麓配置。
3.5 管理后台(/admin)
| 模块 | 说明 |
|---|---|
| 账号管理 | 多租户账号(公司、套餐、坐席数、状态、到期)增删改查 |
| 坐席管理 | 坐席资料、角色(superadmin / agent)、工号、在线状态 |
| 套餐与支付 | 免费版 / 标准版 / 专业版 / 旗舰版;微信支付 / 支付宝;沙箱模拟支付 |
| 知识库 | 机器人规则(关键词 → 答案) |
| 渠道配置 | 各渠道启用 / 禁用与凭证 |
| 微信配置 | 微信开放平台网站应用 AppID / AppSecret、回调地址 |
| 短信配置 | 联麓凭证 |
| 审计日志 | 关键操作留痕,实时刷新 |
| 短信记录 | 验证码发送明细 |
3.6 支付与套餐
- 套餐档位存于
meta.plans_config,动态读取。 - 下单:
POST /api/workbench/orders(planKey + channel)。 - 支付:支付宝非沙箱走
verifyAlipay验签;微信支付沙箱自动切换。 - 升级:幂等
applyPaid,避免重复计费。
3.7 SEO 与搜索引擎收录
| 资源 | 路径 | 说明 |
|---|---|---|
| 站点地图 | /sitemap.xml | 动态生成,含首页 + 静态内容页 |
| 爬虫规则 | /robots.txt | 允许抓取,Disallow 控制台 / 接口,声明 sitemap |
| 品牌分享图 | /og-image.jpg | 1200×630,社交分享卡片用 |
| 静态内容页 | /pages/*.html | product / pricing / solutions / cases / help / about / contact / manual / dev / changelog,真实路径、自带 SEO meta + JSON-LD |
| 百度主动推送 | deploy/push-baidu.sh | 部署后自动推送公开 URL 至百度 |
| 百度验证 | <meta name="baidu-site-verification"> | 首页 <head> 已植入 |
控制台页(/admin、/agent、/embed)回退时注入noindex,nofollow,不被收录为重复首页。
4. 数据模型(核心表)
| 表 | 作用 |
|---|---|
accounts | 多租户账号(公司、套餐、坐席数、状态) |
agents | 坐席(openid、手机号、角色、工号、在线状态) |
visitors | 访客(来源、标签、备注) |
conversations | 会话(渠道、状态、未读) |
messages | 消息 |
tickets | 工单 |
knowledge | 知识库规则 |
channels | 接入渠道(启用 / 配置) |
sms_logs / sms_codes | 短信记录 / 验证码 |
meta | 全局键值配置(微信、短信、套餐等) |
audit_logs | 审计日志 |
5. 部署与运维
5.1 环境与依赖
- 服务器:1Panel + Docker + OpenResty 反代
- 域名:
im.brt.sn.cn(HTTPS,Let's Encrypt) - 数据库:1Panel MySQL 8.4,库名
tianpeng,监听0.0.0.0:3306 - 应用容器:
deploy-app-1(3000:3000),经host.docker.internal连宿主机 3306
5.2 一键部署
cd deploy cp .env.prod .env # 编辑 DB_PASSWORD / ADMIN_PASSWORD bash up.sh # 等价于 docker compose up -d --build
部署完成后:
- 健康检查:
curl http://127.0.0.1:3000/api/health→{"ok":true,...} - 管理后台:
https://im.brt.sn.cn/admin - 工作台:
https://im.brt.sn.cn/agent
5.3 关键运维命令
docker compose ps # 查看容器状态 docker compose logs -f app # 跟踪应用日志 docker compose restart app # 重启应用 docker compose down # 停止 bash deploy/push-baidu.sh # 手动触发百度推送
5.4 配置项(环境变量)
| 变量 | 说明 | 备注 |
|---|---|---|
DB_HOST / DB_PORT / DB_USER / DB_PASSWORD / DB_NAME | MySQL 连接 | 必须与 mysql 容器 / 1Panel MySQL 一致 |
ADMIN_PASSWORD | 管理后台口令 | 推荐 bcrypt 哈希;默认弱口令 tianpeng888 已禁用 |
SESSION_SECRET | 手机号绑定令牌签名密钥 | 未设则用默认值 |
SITE_BASE | sitemap 站点基址 | 默认 https://im.brt.sn.cn |
BAIDU_PUSH_SITE / BAIDU_PUSH_TOKEN | 百度主动推送 | 部署后自动推送 |
NODE_ENV | 运行环境 | production |
安全提示:默认弱口令tianpeng888已在auth.js中禁用(任何尝试都会被拒绝)。生产环境必须在deploy/.env中将ADMIN_PASSWORD配置为强密码或 bcrypt 哈希,否则后台无法登录。
6. 二次开发指引
6.1 目录结构
server/ 后端
index.js Express 入口(路由挂载、静态托管、history 回退、sitemap)
auth.js 会话/登录/管理员鉴权/手机号绑定令牌
sms.js 联麓短信服务
db.js 数据库访问层(含 ensureSchema 建表与渠道迁移)
seed.js 示例数据(账号/坐席/会话/工单/知识库/渠道)
views.js 会话视图组装
routes/ auth / wechat / sms / channels / conversations / payments ...
web/
src/
router.js Vue Router(history 模式)
constants.js 渠道标签/品牌色/套餐样式 等共享常量(单一数据源)
api.js 前端 API 封装
components/ ChatPanel / VisitorPanel / ConversationList / 管理后台组件 ...
views/ Landing / AgentConsole / AdminConsole / Embed
public/
robots.txt SEO 爬虫规则
og-image.jpg 品牌分享图
pages/ 静态内容页 + seo.css
deploy/
Dockerfile / docker-compose.yml / .env.prod / up.sh / push-baidu.sh / setup-on-server.sh / README.md
docs/ 方案与手册
6.2 新增渠道步骤
server/seed.js的channels数组追加一项(key / name / category / color / icon / enabled / desc)。server/db.jsensureMigrations()追加一条幂等INSERT ... WHERE NOT EXISTS(存量库自动补齐)。web/src/constants.js的CHANNEL_LABELS补充中文标签;若需新品牌色,在CHANNEL_COLORS补充。web/src/components/Icon.vue补充渠道图标(如尚缺)。web/src/views/ChannelView.vue补充该渠道的接入引导(平台、字段、步骤)。
6.3 代码规范要点
- 共享常量集中:渠道标签、品牌色、套餐样式统一在
web/src/constants.js,禁止在组件内散落重复定义。 - 敏感信息脱敏:微信 AppSecret、联麓 key 等仅在服务端保存,对外接口一律走
maskXxx()脱敏。 - 会话令牌安全:坐席 / 管理员令牌写入 httpOnly + SameSite=Strict Cookie(HTTPS 下加 Secure),降低 XSS 冒用。
- 多租户隔离:统计 / 广播 / 升级一律按
accountId过滤,禁止全量listAgents。 - 幂等迁移:
db.ensureMigrations()的渠道 / 字段补齐均用WHERE NOT EXISTS或「仅当为空时写入」,支持重复启动。
7. 常见问题(FAQ)
Q访问 /admin 提示登录失败?
A:默认 tianpeng888 已被禁用。请用 deploy/.env 中 ADMIN_PASSWORD 配置的强密码 / bcrypt 哈希登录。
Q微信扫码后停在「请绑定手机号」?
A:该坐席尚未绑定手机号,属正常闸门逻辑。输入手机号 → 获取验证码(开发态在短信记录里回显)→ 验证后即进入工作台。
Q工作台不实时(消息 / 审计不刷新)?
A:反代需转发 Upgrade / Connection: upgrade 头(1Panel OpenResty 默认已支持)。仍异常请检查反代配置。
Q百度收录慢?
A:确认已提交 https://im.brt.sn.cn/sitemap.xml 至百度搜索资源平台;部署后 push-baidu.sh 会自动推送。控制台页被 noindex,不会被收录。
Q如何扩展公开收录页?
A:在 server/index.js 的 PUBLIC_PAGES 追加路径(真实 HTML 或路由),并同步 deploy/push-baidu.sh 的 URLS 列表。
本手册随系统迭代更新。如有歧义,以线上 im.brt.sn.cn 实际行为与源码注释为准。