简介
本技术文档面向DouPHP的小程序与Web端适配,聚焦以下目标:
- 明确小程序与Web端的架构差异(运行环境、API接口、组件系统)
- 说明代码复用策略(业务逻辑共享、数据模型统一、接口抽象)
- 阐述平台特性适配(文件存储、网络请求、本地存储、权限管理)
- 介绍小程序特有实现(页面路由、生命周期、事件通信、插件机制)
- 提供迁移案例与发布调试实践
项目结构
- 小程序前端位于 miniprogram/default,采用TypeScript + MobX状态管理,通过统一的HTTP服务访问后端API。
- Web端分为前台 front 与后台 admin,以及对外API接口 api。前后端通过REST风格接口交互。
- 小程序通过 app.json 声明页面路由、全局窗口样式、TabBar与自定义组件;app.ts 负责应用启动、全局错误处理、自动更新与推广解析等。
graph TB
subgraph "小程序"
A["app.json<br/>页面/窗口/TabBar/组件"]
B["app.ts<br/>启动/拦截器/全局状态"]
C["pages/*<br/>页面逻辑"]
D["services/http.js<br/>网络层"]
E["stores/*<br/>状态管理"]
end
subgraph "后端"
F["api/*<br/>控制器/路由"]
G["front/*<br/>前台模板渲染"]
H["admin/*<br/>后台管理"]
end
A --> C
B --> D
C --> D
D --> F
G --> F
H --> F
核心组件
- 小程序应用入口
- app.ts:注册全局HTTP错误拦截、初始化全局状态、计算导航栏高度、处理自动更新与异常上报、解析推广参数。
- app.json:定义小程序页面路由、窗口样式、TabBar与全局组件引用。
- 页面示例
- pages/index/index.ts:首页加载、分类滚动、商品列表分页、触底加载、分享菜单、用户工作态跳转等。
- 后端基类
- api/controller/BaseController.php:API端控制器基类,提供会员中心导航构建能力,供各模块控制器复用。
- front/controller/BaseController.php:前台控制器基类,封装视图响应、成功响应分流(JSON/重定向)、布局变量注入。
架构总览
小程序与Web端的差异主要体现在:
- 运行环境
- 小程序:在微信客户端沙箱中运行,使用wx.* API进行系统能力调用(如路由、存储、设备信息)。
- Web端:浏览器或服务器渲染,使用标准HTTP协议与模板引擎输出HTML。
- API接口
- 小程序通过统一HTTP服务调用后端api/*提供的REST接口,返回结构化JSON。
- Web端前台通过front/渲染模板,后台通过admin/管理数据,两者均可能调用api/*获取数据。
- 组件系统
- 小程序:基于原生组件与自定义组件,通过app.json的usingComponents引入。
- Web端:基于模板与JS/CSS,通常由框架或库组织UI。
sequenceDiagram
participant MP as "小程序页面"
participant HTTP as "HTTP服务"
participant API as "后端API控制器"
participant FRONT as "前台控制器"
participant ADMIN as "后台控制器"
MP->>HTTP : "发起请求(路由映射)"
HTTP->>API : "调用对应控制器方法"
API-->>HTTP : "返回JSON数据"
HTTP-->>MP : "解析并更新状态"
Note over MP,API : "小程序侧通过store与http统一管理数据流"
FRONT-->>API : "前台页面可调用API获取数据"
ADMIN-->>API : "后台管理操作调用API"
详细组件分析
小程序应用入口(app.ts)
- 功能要点
- 注册全局HTTP错误拦截,对未授权错误执行登出流程。
- 启动时解析推广参数user_sn并写入本地缓存。
- 初始化全局状态(站点配置、语言包、导航等),支持离线优先与网络刷新。
- 计算导航栏高度,兼容不同平台与胶囊按钮尺寸。
- 启用自动更新提示与失败处理。
- 非正式版开启vConsole调试,捕获全局异常与未处理Promise拒绝。
- 关键流程
- onLaunch:初始化、解析推广、引导全局store、计算导航高度、自动更新。
- onShow:再次尝试解析推广参数。
- onError/onUnhandledRejection:统一错误日志与调试弹窗。
- onPageNotFound:调试期提示缺失页面路径。
flowchart TD
Start(["应用启动"]) --> Init["初始化全局状态"]
Init --> ParsePromo["解析推广参数 user_sn"]
ParsePromo --> CalcNav["计算导航栏高度"]
CalcNav --> AutoUpdate{"是否可更新?"}
AutoUpdate --> |是| UpdateFlow["检查/提示/重启"]
AutoUpdate --> |否| Ready["进入就绪状态"]
UpdateFlow --> Ready
Ready --> End(["应用可用"])
小程序首页(pages/index/index.ts)
- 功能要点
- 设置页面标题、显示分享菜单。
- 绑定全局commonStore字段(站点、语言、数据、参数、功能开关、导航)。
- 调用后端接口获取首页数据与产品列表。
- 分类横滑进度条计算与状态更新。
- 商品列表分页加载与触底追加。
- 根据用户工作态跳转到工作台。
- 关键流程
- onLoad:初始化数据、拉取首页数据、加载商品列表。
- onReady:恢复认证状态并判断工作态跳转。
- onReachBottom:触发下一页加载。
- 分类滚动:计算可视区与内容宽度,更新进度条百分比。
sequenceDiagram
participant Page as "首页Page"
participant Store as "commonStore"
participant Http as "HTTP服务"
participant API as "后端API"
Page->>Store : "绑定站点/语言/导航等字段"
Page->>Http : "GET 首页数据"
Http->>API : "请求 /index"
API-->>Http : "返回首页数据"
Http-->>Page : "更新分类指示器与滚动状态"
Page->>Http : "GET 商品列表(分页)"
Http->>API : "请求 /product"
API-->>Http : "返回商品列表"
Http-->>Page : "setData 更新列表"
Page->>Page : "onReachBottom 触发下一页"
小程序路由与配置(app.json)
- 页面路由:通过pages数组声明所有页面路径,便于小程序框架管理与预加载。
- 窗口配置:自定义导航栏样式、背景文本颜色、导航栏标题等。
- TabBar:底部导航包含首页、产品中心、购物车、会员中心四个入口。
- 组件引用:全局引入navbar组件,便于多页面复用。
graph LR
A["app.json"] --> B["pages/* 页面路由"]
A --> C["window 窗口配置"]
A --> D["tabBar 底部导航"]
A --> E["usingComponents 全局组件"]
后端API基类(api/controller/BaseController.php)
- 职责
- 作为API端控制器的统一基类,继承核心BaseController。
- 提供buildLinkUserCenter方法,复用前台会员中心导航构建能力。
- 保证API控制器无模板相关字段,专注于数据响应。
- 设计要点
- 通过容器解析FrontUserCenterNavBuilder,确保前后端导航一致。
- 当用户未登录或模块未安装时返回空结构,避免异常。
classDiagram
class BaseController {
+buildLinkUserCenter(currentModule) array
}
class FrontUserCenterNavBuilder {
+build(currentModule) array
}
BaseController --> FrontUserCenterNavBuilder : "复用导航构建"
后端前台基类(front/controller/BaseController.php)
- 职责
- 封装view方法,合并布局变量与页面数据。
- respond方法根据请求类型返回JSON或重定向,保证渐进增强。
- layoutVars提供默认布局变量,子类可重写叠加。
- 设计要点
- 对AJAX请求返回标准成功信封,包含redirect_url。
- 对普通表单提交执行303重定向,提升兼容性。
flowchart TD
Start(["前台控制器响应"]) --> CheckJson{"是否JSON请求?"}
CheckJson --> |是| ReturnJson["返回JSON成功信封"]
CheckJson --> |否| Redirect["执行303重定向"]
ReturnJson --> End(["结束"])
Redirect --> End
依赖关系分析
- 小程序依赖
- 页面依赖HTTP服务与状态管理,通过路由映射到后端API。
- 应用入口依赖全局配置与工具函数,完成初始化与错误处理。
- 后端依赖
- API控制器依赖核心服务与门面,提供统一的数据响应。
- 前台控制器依赖模板渲染与布局变量,提供Web端页面展示。
- 耦合与内聚
- 小程序内部高内聚:页面、服务、状态解耦清晰。
- 后端分层明确:控制器、服务、模型职责分离。
graph TB
subgraph "小程序"
P["pages/*"] --> S["services/*"]
S --> ST["stores/*"]
end
subgraph "后端"
A["api/*"] --> C["core/*"]
F["front/*"] --> C
M["admin/*"] --> C
end
P --> A
F --> A
M --> A
性能考量
- 小程序端
- 使用MobX状态管理减少重复渲染,结合setData批量更新。
- 分页加载与触底追加降低首屏压力。
- 分类滚动计算缓存视口与内容宽度,避免频繁查询。
- 后端端
- API控制器专注数据响应,减少模板渲染开销。
- 前台控制器按需合并布局变量,避免不必要计算。
- 建议在后端增加缓存层(如Redis)与数据库索引优化。
故障排查指南
- 小程序端
- 全局错误捕获:app.ts中onError与onUnhandledRejection记录异常,调试期弹出提示。
- 页面不存在:onPageNotFound记录缺失路径,便于定位路由错误。
- 网络错误:HTTP服务统一错误拦截,UNAUTHORIZED触发登出流程。
- 后端端
- API基类提供统一响应格式,便于前端统一处理。
- 前台控制器respond方法区分JSON与重定向,确保兼容不同客户端。
结论
DouPHP的小程序与Web端通过清晰的架构分层与统一的API接口实现了良好适配。小程序端利用状态管理与网络层抽象简化开发,后端通过基类封装提升复用性与一致性。建议在后续迭代中继续强化缓存策略、错误监控与跨端组件抽象,以提升整体性能与维护性。
附录
- 开发工具使用
- 微信小程序开发者工具:用于预览、调试与真机测试。
- TypeScript编译:确保类型安全与代码质量。
- 调试技巧
- 启用vConsole:在非正式版开启内置调试面板。
- 全局异常捕获:记录错误堆栈与上下文信息。
- 发布流程
- 版本检查与自动更新:提示用户重启应用以应用新版本。
- 代码审核与上线:遵循微信平台规范进行提审与发布。