MakeFortune 不是单一业务站点,而是一个长期演进的 ThinkPHP 6 多应用工程。它同时承载内容、电商、社群、设备、短剧、AI、企业微信和工具类应用,并配套多个 uni-app 用户端与独立管理端。准确理解它的方式是“共享基础设施的模块化单体”,而不是把每个目录都当成已经独立部署的微服务。
物理组成与交付物
| 物理部分 | 主要内容 | 交付方式 |
|---|---|---|
| PHP 主工程 | GuessLipstick、chigua、dd、gl、haowu、mj、mk、note、sai、sj、ve、auto_host 等多应用 |
同一 ThinkPHP 运行环境按应用路由提供服务 |
| 管理端项目 | ChiGuaAdmin、DuoAdmin、HaoWuAdmin、MkAdmin、VeAdmin、duoduoadmin |
各自构建为静态管理站 |
| 用户端项目 | MakeFortune、sj、wcfui 等 uni-app 工程 |
H5、小程序或 App |
| 命令与计划任务 | 短剧处理、内容同步、社群同步和统计任务 | CLI、Cron 或常驻任务 |
| 公共依赖 | Redis、微信/企业微信、OSS/COS、腾讯 VOD、短信、日志、Telegram、OpenAI | 由服务端统一接入的外部设施 |
多个前端与业务应用可以分别发布,但当前后端仍共享进程、依赖和数据库连接。一个应用的阻塞调用、内存泄漏或错误配置可能影响同一 PHP 服务中的其他应用。
总体拓扑
flowchart TB Admins[多个管理端] --> Gateway[ThinkPHP 多应用路由] Clients[uni-app / H5 / 小程序] --> Gateway Third[第三方回调 / 机器人 / 设备] --> Gateway Cron[Command / Crontab] --> Apps[业务应用模块] Gateway --> Apps Apps --> Common[公共控制器 / 配置 / 基础服务] Apps --> DB[(共享数据库)] Apps --> Redis[(Redis)] Apps --> Media[OSS / COS / VOD / M3U8] Apps --> Channels[微信 / 支付 / 短信 / Telegram] Apps --> WeCom[企业微信开放平台] Apps --> Content[内容来源 / Spider / OpenAI] Apps --> Device[MQTT / 行业设备]
应用地图
| 应用 | 主要入口 | 核心职责 |
|---|---|---|
GuessLipstick |
H5、微信通知 | 口红竞猜主题、礼物、投诉、会员与订单 |
chigua |
Admin、H5、Third、支付通知 | 吃瓜内容、平台配置、会员、订单和 URL 策略 |
dd |
Admin、H5、Common/Cron | 活动、商品、抽奖、任务以及社群和活动同步 |
gl |
Application、Third | 渠道、应用配置和会员接入 |
haowu |
Admin、H5、Third | 商品、广告、通知、用户和运营统计 |
mj |
Admin、H5、MP、Third、MQTT/支付通知 | 设备、代理、装修、订单和第三方设备服务 |
mk |
Admin、H5、Common | 渠道、渠道用户和统计图表 |
note |
H5、支付通知 | 笔记、商店、会员、装修与订单 |
sai |
Admin、MP、Third、支付通知 | 商品、广告、聊天、分类、会员、订单和统计 |
sj |
Member、Shop、Notify、Crontab | 跨模块聚合、商店、Telegram 和定时同步 |
ve |
Admin、H5、Notify、Third、Command | 短剧、分集、商品、广告、会员、订单、采集和 VOD |
auto_host / duitang_thumb |
Web 工具入口 | COS 托管管理与图片转换等辅助能力 |
| 企业微信子系统 | duoduoadmin、公共适配层 |
服务商应用、授权企业、成员、部门、群聊和接口许可 |
这些应用的完整页面和领域清单见应用与模块。架构页更关注它们怎样共用运行环境,以及依赖应该朝哪个方向流动。
单个应用的内部结构
多数业务应用采用相似的目录语言:
1 | Controller / Command / Notify |
- Controller 按 Admin、H5、MP、Third、Notify 或 Crontab 区分协议与调用方;
- Plan 组织 Channel、Member、Order、Product、Stat 等业务用例;
- Core 和
Kernel/BaseCore保存应用初始化、基础上下文与共用行为; - Helper 处理筛选、创建、图表或 HTTP 适配等局部细节;
- Route 决定各入口的 URL 与中间件。
这是一种可维护的方向,但边界必须靠代码约束:Controller 不应直接拼接复杂 SQL 或调用多个外部 SDK,Plan 也不应越过其他应用的公开服务直接修改对方表。
入口协议与信任边界
| 入口类型 | 典型调用方 | 必须完成的校验 |
|---|---|---|
admin |
业务运营后台 | 管理员会话、角色权限、数据范围和操作日志 |
h5 |
登录用户、公众号或普通 Web | 用户会话、渠道、资源归属和频率限制 |
mp |
微信小程序 | 小程序身份、应用配置、用户绑定和接口签名 |
third / application |
外部系统 | App ID、时间戳、随机数、签名、重放保护和 IP 策略 |
notify |
支付、VOD、MQTT、Telegram 等回调 | 来源验签、幂等业务号、原始报文存档和快速响应 |
crontab / command |
调度器和运维 | 仅内网或 CLI 可用、分布式锁和可重入执行 |
不同入口即使调用同一个 Plan,也应先把身份转换成统一业务上下文。第三方传入的用户、渠道、订单或设备编号不能绕过服务端归属校验。
核心业务群
内容、商品与营销
chigua、haowu、dd、note 和 sai 都涉及内容、商品、广告、活动、会员或订单,但领域含义并不完全相同。适合共用的是支付、文件、渠道登录和基础分页;商品上下架、活动资格、笔记订单和聊天规则应留在对应应用。
跨应用复用时提供稳定服务接口,例如“读取公开商品摘要”或“根据外部会员映射取得用户”,不要让一个应用直接依赖另一个应用的控制器、页面字段或全部数据表。
短剧与媒体
ve 覆盖短剧、分集、商品、广告、会员、订单、统计、内容采集、URL 策略、签名与腾讯 VOD。媒体链路通常包括:采集元数据、建立剧集、提交或接收媒体、VOD 回调、生成播放资源、发布和播放统计。
原始视频、转码任务、播放文件和业务剧集应分别建模。VOD 回调可能重复或乱序,必须按远端任务号幂等处理;播放地址可以缓存,但剧集发布状态和媒体归属保存在数据库。
设备与行业接入
mj 同时包含设备、代理、小程序装修、订单、MQTT 通知和第三方设备接口。HTTP 负责配置和业务事实,MQTT 适合发送轻量指令与接收状态。设备 Topic 按设备身份授权,大文件和完整配置通过签名 HTTP 地址获取。
设备离线时仍应保留待执行命令或版本号;重连后按幂等任务号补发。支付回调、设备回调和普通用户请求不应共享同一套宽松鉴权。
社群与聚合任务
dd 和 sj 包含活动、群成员、消息、笔记和商品等同步逻辑,sj 还接入 Telegram。同步任务需要保存游标、来源 ID、最近成功时间和错误原因,避免每次全量扫描。外部数据先落入本应用的映射或暂存表,再转换为领域对象。
企业微信开放平台
企业微信子系统管理服务商应用与授权企业的关系,并同步部门、成员和客户群。运营任务引用授权企业、成员或群聊的稳定标识,不能只保存展示名称。接口许可还包含账号、订单、激活和同步状态,是独立于普通会员订单的生命周期。
第三方应用授权、回调票据、企业令牌和通讯录同步具有不同有效期与权限范围,需要由统一适配层管理。完整边界和流程见企业微信集成。
共享基础设施
Composer 依赖表明工程集中接入了 Redis、EasyWeChat、阿里云 OSS、腾讯 COS/VOD、M3U8、短信、日志、Telegram、OpenAI 和内容采集工具。它们应通过内部适配层使用,而不是由每个 Controller 单独初始化 SDK。
| 能力 | 统一接口应负责 | 业务应用负责 |
|---|---|---|
| 微信、企业微信与支付 | 客户端初始化、授权令牌、签名、回调验签、错误标准化 | 业务订单状态、组织映射与权益发放 |
| 文件与媒体 | 上传、对象 Key、签名 URL、VOD 任务 | 文件归属和发布条件 |
| Redis | 连接、Key 规范、锁和缓存封装 | TTL、失效条件和业务维度 |
| 短信与日志 | 供应商适配、脱敏和失败重试 | 发送场景和接收人资格 |
| AI 与采集 | HTTP、限流、超时、解析和来源记录 | 内容审核、去重和发布决策 |
| Telegram / 设备 | 协议、签名、重连和消息投递 | 业务命令、状态机和权限 |
公共层只接纳稳定且语义一致的能力。两个应用中名字相同的 Member 或 Order 不一定是同一个领域对象,强行共表会增加后续拆分成本。
数据边界与跨应用协作
当前共享数据库降低了早期交付成本,也带来三类风险:表名与字段冲突、跨应用直接写入、一次迁移影响全部应用。建议按以下规则治理:
- 表和缓存 Key 使用应用命名空间;
- 每个应用拥有自己的业务表,其他应用只通过查询服务或事件读取;
- 跨应用引用保存“来源应用 + 外部业务 ID”,不复制对方可变主键语义;
- 数据库迁移按应用分组并可独立回滚;
- 公共账号映射与业务会员资料分开;
- 统计或搜索投影可以跨应用汇总,但不成为交易事实来源。
应用间需要同步时,可先使用本地事件表与异步消费者。这样即使仍在同一仓库和数据库,也能建立未来拆分所需的契约。
典型交易与回调流程
以会员或内容订单为例:
- H5/小程序验证渠道、用户和商品,创建平台业务订单;
- 支付适配层创建第三方支付单并返回支付参数;
- 支付平台调用对应应用的
Notify入口; - 回调先验签、核对商户号、订单号与金额,再锁定业务订单;
- 首次成功回调发放会员或内容权益,并写订单事件;
- 重复回调只返回成功,不重复发货;
- 对账任务扫描支付成功但业务未完成的异常单并补偿。
通知控制器只完成协议校验和快速应答,耗时的媒体、统计、Telegram 或内容同步进入异步任务。
部署与故障域
| 运行单元 | 当前或建议形态 | 主要故障影响 |
|---|---|---|
| 多个管理端和用户端 | 静态站按应用独立发布 | 单个页面不可用,不影响其他前端 |
| ThinkPHP HTTP 服务 | 初期共享部署,按请求入口限流 | 一个应用慢请求可能拖累全部应用 |
| Command / Cron | 与 Web 进程分离,按任务加锁 | 同步和统计延迟,不阻塞用户请求 |
| 回调入口 | 独立路由、短超时、快速落库 | 回调积压,可由对账补偿 |
| 媒体与采集 Worker | 限制并发和内存,独立队列 | 新内容延迟,不影响已发布内容 |
| MySQL / Redis | 事实与临时状态分开 | 数据库故障停止写入;缓存故障按应用降级 |
| 外部平台 | 每个适配器独立熔断 | 单个供应商异常不扩散到全部业务 |
不需要立刻把所有应用拆成微服务。先把长任务、回调和外部调用从 Web 请求隔离,通常就能显著缩小故障影响。
安全与配置
- 数据库、Redis、微信、支付、云存储、VOD、Telegram 和 AI 凭据全部进入环境变量或密钥服务;
- 对源码中曾出现的固定凭据进行轮换,不在文档、日志或响应中输出;
- Admin、H5、MP、Third、Notify 使用不同的鉴权中间件和限流策略;
- 上传文件校验类型、大小、真实内容和对象路径,媒体回调校验来源与任务归属;
- Spider 和外部 URL 请求限制协议、域名、重定向和内网地址,防止 SSRF;
- 日志记录请求 ID、应用、业务单号和错误类别,同时脱敏 Token、手机号和原始消息。
渐进式演进顺序
- 配置治理:统一环境变量和密钥轮换,移除各应用自行读取固定配置;
- 入口中间件:标准化 Admin、H5、MP、Third、Notify 与 Cron 的身份和错误响应;
- 外部适配器:收口微信、企业微信、支付、存储、VOD、Telegram、AI 与采集 SDK;
- 交易状态机:统一订单、支付、回调、退款和权益发放的幂等规则;
- 异步隔离:把媒体、同步、采集和批量统计迁入独立 Worker;
- 应用数据边界:禁止新代码跨应用直接写表,使用服务或本地事件协作;
- 可观测性:按应用统计请求量、慢查询、队列积压、外部调用和回调失败;
- 按价值拆分:只有当某应用需要独立扩容、发布、合规或团队所有权时,再拆成独立服务。