简介
本章节面向 DouPHP 小程序端的“表单”能力,围绕表单列表页、表单详情与提交流程进行说明。重点覆盖:
- 输入框、选择器、上传等表单控件在小程序中的使用方式
- 表单数据结构、验证规则、提交处理
- 配置方法、事件处理、错误提示机制
- 复杂表单布局、动态字段、批量操作思路
- 与后端数据接口的交互方式和数据格式化
项目结构
小程序端表单入口位于 miniprogram/default/pages/form,包含页面脚本、模板与配置;后端通过模块 form 的 front 层提供接口,服务层封装业务逻辑,核心服务提供通用能力,请求校验由 Request 类完成,元素定义由 Admin Model 描述。
graph TB
subgraph "小程序前端"
A["form.ts"]
B["form.wxml"]
C["form.json"]
end
subgraph "后端front"
D["FormController.php"]
E["FormService.php"]
F["FormSubmitFormRequest.php"]
end
subgraph "后端core"
G["Core FormService.php"]
end
subgraph "模型与语言"
H["FormElements.php"]
I["form.lang.php"]
end
A --> |HTTP GET/POST| D
D --> E
E --> G
D --> F
E --> H
D --> I
核心组件
- 表单列表页
- 负责加载并展示可用表单卡片,支持分页与上拉加载更多
- 点击卡片跳转到具体表单详情页
- 表单详情页(概念)
- 渲染动态表单元素(输入框、选择器、上传等)
- 收集用户输入,执行前端校验后提交到后端
- 后端接口
- 列表接口:返回表单元数据与封面图
- 详情接口:返回表单元素定义与默认值
- 提交接口:接收表单数据,执行校验与持久化
架构总览
小程序通过 HTTP 服务调用后端 form 模块的 front 控制器,控制器委托服务层获取数据或执行业务逻辑,服务层复用 core 层的通用能力,并使用模型描述表单元素结构,最终将结果返回给小程序。
sequenceDiagram
participant U as "小程序页面(form.ts)"
participant API as "后端控制器(FormController)"
participant S as "服务层(FormService)"
participant CORE as "核心服务(Core FormService)"
participant M as "模型(FormElements)"
participant L as "语言包(form.lang.php)"
U->>API : "GET /form (列表)"
API->>S : "获取表单列表"
S->>CORE : "通用查询/缓存"
S-->>API : "返回表单列表"
API-->>U : "JSON{form_list, page}"
U->>API : "GET /form/detail?id=xxx"
API->>S : "获取表单详情(元素定义)"
S->>M : "读取元素定义"
S-->>API : "返回元素数组"
API-->>U : "JSON{elements, defaults}"
U->>API : "POST /form/submit"
API->>API : "请求校验(FormSubmitFormRequest)"
API->>S : "保存表单数据"
S->>CORE : "事务/日志/通知"
API-->>U : "JSON{success, id}"
详细组件分析
小程序表单列表页
- 功能要点
- 初始化标题与分享菜单
- 绑定全局 store(站点信息、语言、参数、特性)
- 加载表单列表,支持分页与上拉加载更多
- 点击卡片跳转至表单详情页
- 关键流程
- onLoad 中设置页面标题与分享标题,并触发 loadData
- loadData 通过 http.get 调用路由 form,合并下一页数据或标记无更多
- onReachBottom 触发分页加载
- 导航通过 navigator 或 wx.navigateTo 实现
flowchart TD
Start(["页面加载"]) --> Init["设置标题/分享菜单<br/>绑定全局store"]
Init --> LoadList["调用http.get('/form')"]
LoadList --> Merge{"是否追加模式?"}
Merge --> |是| Concat["拼接旧列表与新数据"]
Merge --> |否| SetList["直接设置列表"]
Concat --> Done["更新状态/隐藏加载中"]
SetList --> Done
Done --> Bottom{"触底?"}
Bottom --> |是| NextPage["page+1 并再次加载"]
Bottom --> |否| End(["结束"])
NextPage --> LoadList
表单详情与提交(概念)
- 渲染阶段
- 根据后端返回的元素定义动态渲染输入框、选择器、上传等控件
- 为每个控件绑定双向数据绑定与校验规则
- 提交阶段
- 前端校验通过后组装数据并提交
- 后端通过请求校验类进行安全与格式校验
- 服务层执行业务逻辑并返回统一响应
sequenceDiagram
participant P as "小程序页面"
participant C as "控制器"
participant R as "请求校验"
participant S as "服务层"
participant DB as "存储"
P->>C : "POST /form/submit {data}"
C->>R : "validate(data)"
R-->>C : "通过/失败"
alt 校验失败
C-->>P : "错误消息"
else 校验通过
C->>S : "save(data)"
S->>DB : "写入数据"
DB-->>S : "成功"
S-->>C : "结果"
C-->>P : "成功响应"
end
表单元素定义与国际化
- 元素定义
- 通过 Admin 模型描述表单元素的类型、标签、占位符、选项、校验规则等
- 用于前端动态渲染与后端校验
- 国际化
- 语言包提供多语言文案,如必填提示、错误信息等
- 前端根据当前语言显示对应文案
依赖关系分析
- 小程序页面依赖
- 全局 store(站点、语言、参数、特性)
- HTTP 服务与路由工具
- UI 工具(消息提示、分享菜单)
- 后端依赖
- 控制器依赖服务层与请求校验
- 服务层依赖核心服务与模型
- 语言包提供多语言文案
graph LR
TS["form.ts"] --> HTTP["services/http.js"]
TS --> ROUTE["utils/route.js"]
TS --> UI["utils/ui.js"]
TS --> STORE["stores/index.js"]
CTRL["FormController.php"] --> SVC["FormService.php(front)"]
CTRL --> REQ["FormSubmitFormRequest.php"]
SVC --> CORE["FormService.php(core)"]
SVC --> MODEL["FormElements.php"]
CTRL --> LANG["form.lang.php"]
性能考虑
- 列表分页与懒加载
- 使用分页参数减少首屏数据量
- 上拉加载更多时延迟触发,避免频繁请求
- 网络与缓存
- 合理设置请求超时与重试策略
- 对静态资源与不常变动的元数据进行缓存
- 渲染优化
- 使用 wx:key 提升列表渲染性能
- 图片采用合适 mode 与尺寸,避免重排
故障排查指南
- 常见问题
- 列表为空:检查后端接口返回结构与分页参数
- 无法加载更多:确认 nomore 标志与 page 自增逻辑
- 提交失败:查看请求校验错误与后端返回消息
- 定位步骤
- 打开小程序调试面板,查看网络请求与响应
- 核对后端日志与服务层异常堆栈
- 检查语言包是否正确加载与键名匹配
结论
DouPHP 小程序表单体系以“动态元素 + 前后端协作”为核心:前端基于元素定义渲染控件并收集数据,后端通过请求校验与服务层保障数据安全与一致性。配合分页、缓存与错误提示,可构建稳定高效的表单体验。
附录
- 配置方法
- 在 Admin 侧通过元素模型配置字段类型、标签、占位符、选项与校验规则
- 语言包维护多语言文案,确保提示一致
- 事件处理
- 小程序侧监听输入变化、选择变更、上传完成等事件,实时更新数据
- 提交前执行前端校验,失败则阻止提交并提示
- 复杂场景
- 动态字段:根据上游选择项动态显示/隐藏或新增字段
- 批量操作:在列表页勾选多条记录,统一提交
- 数据格式化
- 日期、金额、图片路径等在提交前进行标准化
- 后端按约定格式入库与返回