简介
本技术文档聚焦 DouPHP 通信服务,覆盖聊天系统、评论系统、邮件发送、短信通知等能力,并说明与第三方平台(如微信、短信服务商)的集成方式。文档从系统架构、组件职责、数据流、错误处理、性能与可靠性等方面展开,并提供可操作的开发示例与最佳实践,帮助开发者快速实现消息发送、用户通知、反馈收集等功能。
项目结构
通信相关能力在项目中按“模块 + 端(前台/后台/API)+ 服务层”组织:
- 聊天:后台管理侧提供应用、会话、配额、任务、知识库等管理能力;模型与控制器位于 module/chat 下。
- 邮件:后台订阅邮箱管理与列表操作由 admin/service/email 提供服务;模块内包含前后端控制器与服务。
- 短信:统一入口 Sms 门面与阿里云实现 Alisms 位于 core/library/sms;后台参数初始化在 admin/service/sms。
- 微信:后台菜单与素材管理由 admin/service/weixin;小程序登录与解密由 api/controller/user/WeixinController。
graph TB
subgraph "后台管理"
A["chat/ApplicationService"] --> B["email/EmailService"]
A --> C["sms/SmsService"]
A --> D["weixin/WeixinService"]
end
subgraph "API/小程序"
E["user/WeixinController"]
end
subgraph "通用库"
F["sms/Sms 门面"] --> G["sms/src/Alisms 阿里云实现"]
end
subgraph "前端"
H["captcha.js 验证码按钮"]
end
H --> F
E --> D
核心组件
- 聊天应用服务:负责聊天应用的列表、新增、编辑、删除、默认应用唯一性约束、批量操作等。
- 邮件订阅服务:负责订阅邮箱列表展示、标记已读、批量删除等操作。
- 短信服务:统一入口创建客户端、发送短信、验证码流程、限频校验、签名与模板参数组装。
- 微信服务:后台菜单/素材管理;小程序登录与手机号解密等 API 能力。
架构总览
通信服务采用“门面 + 具体实现”的分层设计:
- 门面层:Sms 门面屏蔽底层差异,提供 sendSms 等便捷方法。
- 实现层:Alisms 封装阿里云短信 API 调用、签名、错误码映射与日志记录。
- 业务层:各模块 Service 聚合领域逻辑(如聊天应用管理、邮件订阅管理、短信参数初始化)。
- 接入层:后台控制器/API 控制器通过 Service 暴露能力;前端通过 JS 触发短信验证码流程。
sequenceDiagram
participant FE as "前端页面"
participant SMS as "Sms 门面"
participant ALI as "Alisms 实现"
participant CFG as "配置中心"
participant LOG as "日志"
FE->>SMS : sendSms(手机号, 模板代码, 模板参数)
SMS->>ALI : createClient() / sendSms(...)
ALI->>CFG : 读取 AccessKey/签名/模板等配置
ALI->>ALI : 组装请求参数与签名
ALI->>ALI : HTTP 请求阿里云短信接口
ALI-->>SMS : 返回 success 或错误码
SMS-->>FE : 响应结果
Note over ALI,LOG : 异常与错误码写入日志
详细组件分析
聊天应用服务(ApplicationService)
- 职责:聊天应用的数据维护、默认应用唯一性保证、分页与筛选、审计日志。
- 关键点:
- 列表构建时批量获取关联模型名称,避免 N+1 查询。
- 插入/更新后确保全表恰好一个 is_default,单条存在时强制默认。
- 删除支持二次确认与批量删除,并记录审计日志。
flowchart TD
Start(["进入 ApplicationService"]) --> List["构建列表数据<br/>筛选/分页/关联模型名"]
List --> InsertOrUpdate{"新增/更新?"}
InsertOrUpdate --> |是| EnsureDefault["确保唯一默认应用"]
EnsureDefault --> Audit["记录审计日志"]
InsertOrUpdate --> |否| DeleteCheck{"删除/批量删除?"}
DeleteCheck --> |是| Confirm["二次确认/批量删除"]
Confirm --> EnsureDefault2["恢复默认应用不变量"]
EnsureDefault2 --> End(["完成"])
Audit --> End
DeleteCheck --> |否| End
邮件订阅服务(EmailService)
- 职责:订阅邮箱列表展示、标记已读并重定向、批量删除。
- 关键点:
- 列表分页与状态语言化。
- 标记已读后使用重定向保持当前页上下文。
- 批量删除前校验选择项并记录审计日志。
短信服务(Sms 门面与 Alisms 实现)
- 职责:统一短信发送入口、验证码流程、限频与令牌校验、阿里云 API 调用与错误码映射。
- 关键点:
- 门面提供 sendSms 便捷方法,内部创建客户端并委托实现。
- Alisms 负责参数组装、签名计算、HTTP 请求、错误码映射与日志记录。
- 验证码流程:生成 token -> 校验 -> 发送短信 -> 缓存验证码与时间戳 -> 限频控制。
- 限频:基于 Session 或存储 token 的时间戳进行间隔控制。
sequenceDiagram
participant FE as "前端(captcha.js)"
participant SMS as "Sms 门面"
participant ALI as "Alisms"
participant SESS as "Session/存储"
participant LOG as "日志"
FE->>SMS : sendSms(手机号, 模板代码, 模板参数)
SMS->>ALI : createClient()/sendSms(...)
ALI->>SESS : smsTokenSet() 生成令牌
ALI->>ALI : captcha(sms_token, mobile) 校验与发送
ALI->>SESS : 缓存验证码、时间戳
ALI-->>SMS : success 或错误信息
SMS-->>FE : 返回结果
Note over ALI,LOG : 异常/错误码记录日志
微信服务(后台与小程序)
- 后台 WeixinService:提供微信公众号菜单、素材、参数等管理能力,封装 WeixinCore 客户端。
- 小程序 WeixinController:处理 jscode2session、手机号解密等能力,配合用户认证与联系人查询服务。
classDiagram
class WeixinService {
+getWeixinClient()
+buildWeixinMenuListData()
+buildWeixinMenuCreateData()
}
class WeixinController {
+__construct(userAuthService, userService, apiTokenService, contactQuery)
}
WeixinController --> WeixinService : "通过路由/服务协作"
依赖关系分析
- 聊天应用服务依赖 AI 网关以获取模型列表与名称,同时依赖数据库与审计服务。
- 邮件服务依赖 Email 模型与审计服务。
- 短信服务依赖配置中心、Session/存储、日志与阿里云短信 API。
- 微信服务依赖 WeixinCore 客户端与用户认证/联系人查询服务。
graph LR
AppSvc["ApplicationService"] --> Gateway["AiGateway"]
AppSvc --> DB["DB/ORM"]
AppSvc --> Audit["审计日志"]
EmailSvc["EmailService"] --> ModelE["Email 模型"]
EmailSvc --> Audit
SmsFacade["Sms 门面"] --> Impl["Alisms 实现"]
Impl --> Config["配置中心"]
Impl --> Store["Session/存储"]
Impl --> Log["日志"]
Impl --> Ali["阿里云短信API"]
WxAdmin["WeixinService"] --> Core["WeixinCore"]
WxApi["WeixinController"] --> Auth["用户认证"]
WxApi --> Contact["联系人查询"]
性能与可靠性
- 性能优化
- 聊天应用列表一次性 IN 查询关联模型名称,避免 N+1 查询。
- 分页与默认排序提升大数据量下的列表性能。
- 短信发送使用短超时与异步化建议(见下文),降低阻塞。
- 可靠性保障
- 短信错误码映射与日志记录,便于定位问题。
- 验证码令牌与时间戳缓存,防止重复提交与暴力破解。
- 默认应用唯一性约束,保证业务一致性。
- 异步与队列(建议)
- 将短信发送、邮件发送、微信消息推送等耗时操作放入消息队列(如 Redis/RabbitMQ),实现削峰填谷与重试机制。
- 对失败消息设置重试策略与死信队列,结合审计日志追踪。
- 使用幂等键(如订单号+动作)避免重复投递。
故障排查指南
- 短信发送失败
- 检查模板参数是否完整、签名与模板是否审核通过、账户余额与频率限制。
- 查看日志中的错误码与请求参数,定位具体原因。
- 验证码无法发送
- 校验前端传入的 sms_token 与手机号格式。
- 检查 Session/存储中验证码与时间戳是否有效,确认限频逻辑。
- 聊天应用默认冲突
- 确认插入/更新后 ensureSingleDefault 与 ensureDefaultInvariant 执行成功。
- 微信能力异常
- 核对后台参数(AppID/AppSecret/Token)是否正确。
- 小程序登录流程中 code、rawData、signature、iv 是否完整。
结论
DouPHP 通信服务通过清晰的分层与模块化设计,实现了聊天、邮件、短信与微信等核心能力。短信服务采用门面与实现分离,具备良好的扩展性与可维护性;聊天应用服务保证了关键业务不变量;微信服务覆盖了后台管理与小程序登录场景。建议在现有基础上引入消息队列与重试机制,进一步提升系统的吞吐与可靠性。
附录:开发示例与最佳实践
-
发送短信(验证码)
- 前端调用:点击按钮触发验证码发送,携带类型、账号、验证码令牌等参数。
- 后端流程:生成令牌 -> 校验 -> 发送短信 -> 缓存验证码与时间戳 -> 限频控制。
- 参考路径:captcha.js(前端模板):1-44、Alisms.php:157-259
-
用户通知(邮件/短信/微信)
- 邮件:通过 EmailService 管理订阅邮箱,结合模板引擎发送邮件。
- 短信:通过 Sms 门面统一发送,注意模板参数与频率限制。
- 微信:通过 WeixinService 管理公众号能力,小程序端通过 WeixinController 完成登录与解密。
- 参考路径:EmailService.php:37-90、Sms.php:47-62、WeixinService.php:59-95、WeixinController.php:41-73
-
反馈收集(表单/留言)
- 在前端收集用户反馈,后端进行校验与存储,必要时触发通知(短信/邮件/微信)。
- 建议加入内容审核与垃圾信息过滤(关键词、正则、第三方审核服务)。
-
消息队列与异步处理(建议)
- 将耗时任务(短信、邮件、微信推送)入队,消费者异步处理,支持重试与死信。
- 使用幂等键与去重策略,保证消息可靠性与一致性。
-
用户体验优化
- 前端增加加载态与倒计时,避免重复提交。
- 错误提示友好化,结合日志与监控快速定位问题。