文档目录
工具类组件

简介

本文件面向 DouPHP 小程序端的工具类组件,系统化梳理并文档化以下能力:

  • 日期与数字格式化
  • 验证码倒计时控制
  • 统一 HTTP 请求封装(信封解析、缓存/去重、拦截器、调试)
  • 本地存储与鉴权联动(登录态校验)
  • 路由生成与 URL 拼接
  • UI 辅助(提示、跳转、分享菜单)
  • 国际化字符串读取
  • TabBar 运行时判定

目标读者包括前端开发者与后端接入者,帮助快速理解各工具函数的使用方法、参数说明、返回值格式,并提供实际使用场景的参考路径与最佳实践。

项目结构

DouPHP 小程序端工具集中在 miniprogram/default/utils 与 miniprogram/default/services 两个目录:

  • utils:通用工具函数(格式化、倒计时、环境探测、路由、UI、URL、国际化、TabBar)
  • services:业务级服务封装(HTTP 网络层、文件上传)
graph TB
subgraph "工具(utils)"
F["format.ts<br/>数字/时间格式化"]
C["countdown.ts<br/>验证码倒计时"]
E["env.ts<br/>运行环境探测"]
R["route.ts<br/>命名路由生成"]
U["ui.ts<br/>toast/跳转/分享"]
UR["url.ts<br/>历史URL拼接(弃用)"]
I["i18n.ts<br/>语言包读取"]
T["tabbar.ts<br/>TabBar运行时判定"]
end
subgraph "服务(services)"
H["http.ts<br/>统一HTTP层"]
UP["upload.ts<br/>文件上传/删除"]
end
H --> E
H --> R
UP --> H
UP --> R
U --> T
U --> R

核心组件

  • 数据格式化:format.ts 提供数字补零与时间格式化,保证展示一致性。
  • 倒计时:countdown.ts 提供验证码按钮倒计时,自动管理定时器与页面状态。
  • 网络请求:services/http.ts 提供统一 HTTP 层,支持信封解析、缓存/TTL、请求去重、拦截器、调试增强。
  • 文件上传:services/upload.ts 封装选图、上传、删除流程,并与鉴权联动。
  • 路由与URL:utils/route.ts 提供命名路由生成;utils/url.ts 保留历史兼容。
  • UI 辅助:utils/ui.ts 提供 toast、跳转策略、分享菜单等。
  • 国际化:utils/i18n.ts 提供运行时语言包读取。
  • 环境探测:utils/env.ts 提供开发/生产环境判断与服务端调试开关。
  • TabBar:utils/tabbar.ts 提供运行时 TabBar 判定,避免硬编码。

架构总览

小程序工具层以“服务 + 工具”分层组织:

  • 服务层(services):对外暴露稳定接口(如 http.get/post、upload.filebox),内部复用工具与配置。
  • 工具层(utils):无副作用或低耦合的纯函数,供服务层与页面调用。
sequenceDiagram
participant Page as "业务页面"
participant Http as "http.ts"
participant Env as "env.ts"
participant Route as "route.ts"
participant Wx as "微信API"
Page->>Http : 调用 get/post/put/del
Http->>Env : isDebugEnv()
Http->>Wx : wx.request(...)
Wx-->>Http : success/fail
Http->>Http : 解析信封/缓存/去重/拦截器
Http-->>Page : Promise<T> 或 ApiError
Note over Page,Http : 错误时记录 request_id,便于追踪

详细组件分析

数据格式化(format.ts)

  • 功能
    • formatNumber(n): 将数字转为两位字符串,不足补前导零。
    • formatTime(date): 将 Date 对象格式化为 "YYYY/M/D HH:MM:SS"。
  • 参数与返回
    • formatNumber: 入参 number;返回 string。
    • formatTime: 入参 Date;返回 string。
  • 使用场景
    • 列表时间列统一显示格式。
    • 表单输入框数值对齐显示。
  • 复杂度
    • O(1) 时间与空间。

验证码倒计时(countdown.ts)

  • 功能
    • captchaCountdown(page, options): 为 Page 实例注入 start/stop 方法,驱动 data.countdown 字段变化。
  • 参数与返回
    • page: WechatMiniprogram.Page.TrivialInstance。
    • options.field: 可选,绑定的 data 字段名,默认 'countdown'。
    • options.seconds: 可选,默认秒数,默认 60。
    • 返回: { start(seconds?), stop(): void }。
  • 使用示例(概念性)
    • onLoad: this.countdown = captchaCountdown(this)
    • 发送成功后: this.countdown.start(60)
    • onUnload: this.countdown.stop()
  • 注意事项
    • 确保在页面卸载时停止定时器,避免内存泄漏。

统一 HTTP 层(services/http.ts)

  • 职责
    • 信封解析:code === 'OK' 视为成功,否则抛出 ApiError。
    • 默认头注入:Content-Type=application/x-www-form-urlencoded、Authorization: Bearer &lt;api_token>。
    • 拦截器:onRequest/onSuccess/onError。
    • 去重:相同 GET 在飞行中复用同一 Promise。
    • 缓存+TTL:opts.cache 命中且未过期直接返回;opts.revalidate 强制刷新。
    • 调试:request_id 装饰、Console/vConsole 打点、服务端异常 modal(仅调试环境)。
  • 关键类型
    • RequestConfig: url/data/method/header/responseType。
    • RequestOpts: cache/ttl/revalidate/dedupe。
    • ApiError: code/statusCode/errors/data/request_id。
  • 主要 API
    • request(config, opts?): Promise&lt;T>
    • get/post/put/del(url, data?, opts?)
    • clearCache(prefix?)
    • getLastRequestId(): string
    • http.onRequest/onSuccess/onError(fn)
  • 流程图(请求生命周期)
flowchart TD
Start(["进入 request"]) --> BuildCfg["构建默认请求配置<br/>注入Header/Token"]
BuildCfg --> Interceptors{"执行请求拦截器"}
Interceptors --> CacheCheck{"启用缓存且未revalidate?"}
CacheCheck --> |是| HitCache["命中内存缓存直接返回"]
CacheCheck --> |否| DedupeCheck{"GET且去重开启且有进行中请求?"}
DedupeCheck --> |是| ReusePromise["复用进行中Promise"]
DedupeCheck --> |否| DoRequest["发起wx.request"]
DoRequest --> Success{"HTTP状态码2xx?"}
Success --> |否| ParseHttpErr["解析信封构造ApiError"]
ParseHttpErr --> ErrorIntercept["执行错误拦截器"]
ErrorIntercept --> Reject["reject(ApiError)"]
Success --> |是| ParseBody["解析信封"]
ParseBody --> Ok{"code==='OK'?"}
Ok --> |否| BizErr["构造业务ApiError"]
BizErr --> ErrorIntercept
Ok --> |是| AttachMeta["附加__message/__request_id"]
AttachMeta --> SaveCache["写入内存缓存(若启用)"]
SaveCache --> SuccessIntercept["执行成功拦截器"]
SuccessIntercept --> Resolve["resolve(data)"]
HitCache --> Resolve
ReusePromise --> Resolve

文件上传与删除(services/upload.ts)

  • 功能
    • filebox(params, callback): 选择图片并上传至 user/filebox,回调返回 img_list。
    • fileDel(params, callback): 删除已上传图片,回调返回剩余 img_list。
  • 参数与返回
    • params.dataset.type/module/item_id/folder/draft_token: 上传元信息。
    • params.dataset.number: 删除的文件编号。
    • callback(imgList): 回调返回图片数组。
  • 鉴权联动
    • 先 authStore.ensureLogin(),未登录自动跳转登录页。
  • 使用场景
    • 商品详情多图上传、草稿箱附件上传。

命名路由生成(utils/route.ts)

  • 功能
    • route(name, params?): 根据后台同步的路由表生成最终 URL,支持占位符替换与 query 拼接。
  • 行为
    • 当 rewrite_enable 关闭时回退 index.php?route= 形态。
    • 缺失路由键抛错,便于早期发现。
  • 使用场景
    • 所有页面跳转与外链生成统一走此函数,避免硬编码路径。

历史 URL 拼接(utils/url.ts)

  • 功能
    • douUrl(module, ...args): 历史兼容的 URL 拼接工具,已标记弃用。
  • 建议
    • 新代码一律改用 route(name, params)。

UI 辅助(utils/ui.ts)

  • 功能
    • douGetCurrentPages(): 获取当前页带参数的相对路径。
    • douPageTo(url): 智能跳转(已在栈内则回退;tabBar 页 switchTab;其余 redirectTo)。
    • douMsg(message, url='back', time=2000): 提示后按规则跳转。
    • showShareMenu(): 开启转发与朋友圈分享。
  • 使用场景
    • 操作反馈与导航一体化,减少重复逻辑。

国际化读取(utils/i18n.ts)

  • 功能
    • lang(key, fallback?): 从 commonStore.lang 读取译串,未命中返回 fallback 或 key。
  • 使用场景
    • wx.showModal / wx.showToast 等运行时提示文案。

运行环境探测(utils/env.ts)

  • 功能
    • isDebugEnv(): 非正式版(develop/trial)返回 true,release 恒 false。
    • isServerDebug(): 镜像 site.ts 的 debug_enable,用于服务端调试开关。
  • 使用场景
    • 仅在调试环境打印日志或弹出堆栈提示。

TabBar 运行时判定(utils/tabbar.ts)

  • 功能
    • normalizePagePath(p): 规范化页面路径(去前缀斜杠、去查询串、去渲染后缀)。
    • resolveTabIndex(pagePath): 返回 tabBar.list 中的真实下标,不在则 -1。
    • isTabBarPath(pagePath): 是否 tabBar 页。
  • 使用场景
    • 决定跳转方式(switchTab vs redirectTo/navigateTo),避免写死路径白名单。

依赖关系分析

  • http.ts 依赖 env.ts(调试开关)、route.ts(可选,用于生成 URL)、微信 API。
  • upload.ts 依赖 http.ts、route.ts、authStore(鉴权)。
  • ui.ts 依赖 tabbar.ts(TabBar 判定)、route.ts(跳转目标)。
  • route.ts 依赖 site.ts 配置(mp_url、rewrite_enable)与 routes.generated.ts。
  • i18n.ts 依赖 commonStore(语言包)。
graph LR
HTTP["http.ts"] --> ENV["env.ts"]
HTTP --> ROUTE["route.ts"]
UPLOAD["upload.ts"] --> HTTP
UPLOAD --> ROUTE
UI["ui.ts"] --> TABBAR["tabbar.ts"]
UI --> ROUTE

性能考虑

  • 网络请求
    • 合理使用 cache 与 ttl 降低重复请求;对热点列表数据可设置较长 TTL。
    • 利用 dedupe 避免并发重复请求,减少服务器压力。
    • 使用 revalidate 实现 SWR 模式,兼顾时效性与性能。
  • 内存与定时器
    • 倒计时务必在页面卸载时 stop,防止内存泄漏。
    • 清理 http.clearCache 避免长期驻留大对象。
  • 渲染与跳转
    • 使用 isTabBarPath 动态决策跳转方式,避免写死导致的不必要重绘。
    • 批量 setData 减少频繁更新。
  • 调试开销
    • 仅在 isDebugEnv 下执行额外日志与弹窗,生产环境保持静默。

故障排查指南

  • 网络请求失败
    • 检查 ApiError.code 与 statusCode,定位 HTTP 错误或业务错误。
    • 通过 getLastRequestId() 与服务端日志对照。
    • 在调试环境查看可能弹出的服务端异常堆栈。
  • 缓存问题
    • 确认是否设置了 cache/revalidate;必要时调用 clearCache(prefix) 清理。
  • 跳转异常
    • 使用 isTabBarPath 判断是否为 tabBar 页,再选择 switchTab/redirectTo。
    • 使用 route() 生成 URL,避免手写路径不一致。
  • 倒计时不生效
    • 确认 field 绑定正确,且在 onUnload 中调用 stop。
  • 国际化缺失
    • 确认 commonStore.lang 已加载,lang(key, fallback) 提供兜底文案。

结论

DouPHP 小程序工具类组件围绕“稳定、可观测、可扩展”的目标设计:

  • 通过统一 HTTP 层屏蔽底层差异,提供缓存、去重、拦截器与调试能力。
  • 工具函数聚焦单一职责,便于复用与测试。
  • 借助运行时 TabBar 判定与命名路由,提升可维护性与跨站点适配能力。 建议在业务中优先采用这些工具,遵循本文的最佳实践以获得更稳定的体验与更高的性能。

附录:扩展与自定义规范

  • 新增工具函数
    • 放在 utils 下,保持无副作用或最小副作用,明确入参与返回值类型。
    • 如需访问配置,优先从 config/site.ts 读取,避免 getApp().mp_url。
  • 扩展 HTTP 层
    • 通过 http.onRequest/onSuccess/onError 注册拦截器,集中处理认证、埋点、重试等。
    • 对特定模块可封装专用 service,复用 http 与 route。
  • 自定义上传流程
    • 基于 upload.ts 扩展新的业务字段,保持鉴权前置。
  • 路由与 URL
    • 统一使用 route(name, params),不再手写路径;历史兼容仅限过渡期。
  • 国际化
    • 新增 key 需同步到语言包,并在 i18n.ts 侧提供 fallback 保障。
  • 调试与监控
    • 使用 isDebugEnv 控制调试输出;结合 getLastRequestId 进行问题追踪。
添加日期:2026-10-05