文档目录
代码复用策略

简介

本技术文档围绕 DouPHP 在小程序与 Web 端之间的业务逻辑复用展开,重点说明如何通过统一的后端服务层、一致的 API 信封与类型契约、以及前端 HTTP 封装实现前后端解耦。文档同时给出可复用的服务模块设计范式(HTTP 请求封装、数据处理函数、工具方法),并介绍构建时的代码分割与打包策略,以优化小程序包大小与加载性能。

项目结构

DouPHP 采用“多入口 + 共享内核”的架构:

  • 前台入口 index.php:负责路由委派、异常处理与页面/JSON 响应。
  • API 入口 api/index.php:面向小程序与外部客户端提供 JSON API。
  • 后台入口 admin/index.php:管理端路由与异常处理。
  • 核心引导 core/bootstrap.php:定义路径常量、自动加载、容器与门面注册等。
  • 小程序 miniprogram/default:包含 TypeScript 类型定义、HTTP 封装、应用引导服务等。
graph TB
A["前台入口<br/>index.php"] --> B["核心引导<br/>core/bootstrap.php"]
C["API 入口<br/>api/index.php"] --> B
D["后台入口<br/>admin/index.php"] --> B
C --> E["API 路由<br/>api/route/index.php"]
F["小程序 HTTP 封装<br/>services/http.ts"] --> C
G["小程序类型契约<br/>types/api.d.ts"] --> F
H["小程序引导服务<br/>services/bootstrap.ts"] --> F

核心组件

  • 统一引导与容器:core/bootstrap.php 完成路径常量、自动加载、DI 容器、门面与助手注册,确保三端共享同一运行环境。
  • 多入口路由委派:各入口通过 Route::setDelegate 委派到对应 Router,并在 Init::boot 后执行调度。
  • API 信封与错误码:后端统一返回 {code, message, data, errors, request_id};小程序侧解析为 ApiError 或业务数据。
  • 小程序 HTTP 封装:统一拦截器、缓存、去重、调试增强,屏蔽底层 wx.request 差异。
  • 类型契约:小程序 types/api.d.ts 定义 ApiEnvelope、Features、BootstrapData 等强类型,约束前后端契约。

架构总览

下图展示小程序调用后端 API 的端到端流程,体现“前端类型契约 + HTTP 封装 + 后端控制器/服务层”的解耦协作。

sequenceDiagram
participant MP as "小程序"
participant HTTP as "HTTP 封装<br/>services/http.ts"
participant API as "API 入口<br/>api/index.php"
participant RT as "API 路由<br/>api/route/index.php"
participant SVC as "服务层<br/>core/service/*"
participant DB as "数据库"
MP->>HTTP : 发起 get/post(含类型约束)
HTTP->>API : 发送请求(携带 token、Content-Type)
API->>RT : 路由分发
RT-->>API : 匹配控制器/动作
API->>SVC : 执行业务逻辑
SVC->>DB : 读写数据
DB-->>SVC : 结果集
SVC-->>API : 领域对象/DTO
API-->>HTTP : 标准信封 {code,message,data,errors,request_id}
HTTP-->>MP : 解析成功 data<T> 或抛出 ApiError

详细组件分析

后端服务层抽象与复用

  • 服务基类 BaseService 明确职责边界:不直接读取 Request,由 shell 层(admin/front/api)将上下文作为参数传入;ORM 访问通过静态门面,写操作统一 create/hydrated save,读操作支持 with/关联查询。
  • API 控制器 BaseController 继承核心控制器,承载 API 专属逻辑(如会员中心导航复用 Front 端 Builder)。
classDiagram
class BaseService {
<<abstract>>
}
class BaseController {
+buildLinkUserCenter(currentModule) array
}
class 具体服务 {
+read()
+write()
}
class 具体控制器 {
+action()
}
BaseController <|-- 具体控制器
BaseService <|-- 具体服务
具体控制器 --> 具体服务 : "调用"

接口定义统一与类型契约

  • 小程序侧 types/api.d.ts 定义了统一的 API 信封、模块开关 Features、引导数据 BootstrapData 等类型,确保前后端数据结构一致。
  • 引导服务 services/bootstrap.ts 通过 http.get 拉取站点配置、功能开关、语言指纹等,供小程序启动阶段使用。
flowchart TD
Start(["小程序启动"]) --> Fetch["调用 bootstrap 接口"]
Fetch --> Parse["解析 BootstrapData"]
Parse --> Features{"features 是否启用某模块?"}
Features --> |是| Show["渲染对应页面/功能"]
Features --> |否| Hide["隐藏/禁用对应入口"]
Show --> End(["完成"])
Hide --> End

HTTP 请求封装与错误处理

  • 统一信封解析:仅接受 code/message/data/errors/request_id,成功时 resolve(data),失败时 reject(ApiError)。
  • 默认头注入:Content-Type=application/x-www-form-urlencoded、Authorization: Bearer &lt;token>。
  • 拦截器机制:onRequest/onSuccess/onError 可扩展鉴权、埋点、全局错误处理。
  • 缓存与去重:GET 请求支持内存缓存与飞行中 Promise 复用,减少重复请求。
  • 调试增强:request_id 追踪、开发环境弹窗堆栈、控制台打点。
flowchart TD
Req["发起请求"] --> Interp["请求拦截器"]
Interp --> Cache{"命中缓存?"}
Cache --> |是| ReturnCache["返回缓存数据"]
Cache --> |否| Dedupe{"飞行中去重?"}
Dedupe --> |是| Reuse["复用 Promise"]
Dedupe --> |否| WxReq["wx.request"]
WxReq --> Resp{"HTTP 状态码"}
Resp --> |非2xx| ErrHttp["构造 Http ApiError"]
Resp --> |2xx| Envelope["解析信封"]
Envelope --> Ok{"code === 'OK'?"}
Ok --> |是| Success["附加元信息并返回 data"]
Ok --> |否| ErrBiz["构造业务 ApiError"]
ErrHttp --> Done["结束"]
ErrBiz --> Done
Success --> Done
ReturnCache --> Done
Reuse --> Done

构建时代码分割与打包策略

  • 按模块拆分:将页面级与通用能力分离,例如将“订单、商品、用户”等模块拆分为独立分包,按需加载。
  • 公共库抽取:将 http.ts、类型定义、工具函数抽离为公共包,避免重复打包。
  • 资源裁剪:图片、字体按需引入,移除未使用样式与脚本。
  • 预编译与压缩:开启 TS 严格模式、Tree-shaking、代码压缩与 SourceMap(仅开发环境)。
  • 运行时懒加载:首屏仅加载必要模块,其他模块在触发时再加载。

依赖关系分析

  • 入口依赖:三个入口均依赖 core/bootstrap.php 初始化环境与容器。
  • 路由依赖:API 入口通过 api/route/index.php 声明式路由映射到控制器。
  • 前端依赖:小程序 services/http.ts 依赖 types/api.d.ts 的类型约束;services/bootstrap.ts 依赖 http.ts。
  • 服务依赖:控制器与服务层通过核心服务基类与门面进行解耦。
graph LR
BOOT["core/bootstrap.php"] --> APIIDX["api/index.php"]
BOOT --> FRONTIDX["index.php"]
BOOT --> ADMINIDX["admin/index.php"]
APIIDX --> ROUTEIDX["api/route/index.php"]
HTTP["miniprogram/default/services/http.ts"] --> APIIDX
TYPES["miniprogram/default/types/api.d.ts"] --> HTTP
BOOTSTRAP["miniprogram/default/services/bootstrap.ts"] --> HTTP

性能与构建优化

  • 请求层面:利用 GET 缓存与去重减少网络开销;合理设置 TTL 与 revalidate 策略。
  • 首屏优化:仅加载必要模块与资源;延迟加载非关键功能。
  • 包体优化:公共库抽取、Tree-shaking、按需引入第三方库。
  • 监控与诊断:借助 request_id 与调试弹窗快速定位问题。

故障排查指南

  • 统一错误码:后端通过 ApiResponse 返回标准信封;小程序侧解析为 ApiError,包含 code、message、errors、request_id。
  • 调试建议:
    • 检查 request_id 是否与后端日志一致。
    • 确认 Authorization 头是否正确注入。
    • 查看拦截器链是否被意外中断。
    • 对缓存失效场景使用 revalidate 强制刷新。
  • 常见问题:
    • 401/403:检查令牌与权限。
    • 422:校验失败,查看 errors 字段。
    • 500:服务端异常,结合 request_id 定位。

结论

通过“统一引导 + 多入口路由 + 标准化 API 信封 + 小程序类型契约 + HTTP 封装”,DouPHP 实现了小程序与 Web 端的业务逻辑共享与前后端解耦。服务层抽象与控制器基类确保了后端复用性;小程序侧的类型与封装提升了健壮性与可维护性。配合合理的构建与打包策略,可有效控制包体积并提升加载性能。

附录

  • 最佳实践清单:
    • 所有 API 必须遵循统一信封与错误码规范。
    • 新增模块需在类型定义中补齐字段,保持前后端一致。
    • 敏感操作增加鉴权与限流。
    • 使用缓存与去重降低重复请求。
    • 通过 request_id 建立端到端追踪链路。
添加日期:2026-10-05