# 模型基本操作

<cite>
**本文引用的文件**
- [AGENTS.MD](file://AGENTS.MD)
- [UserModel.php](file://vendor/thinkcmf/cmf/src/model/UserModel.php)
- [RoleModel.php](file://vendor/thinkcmf/cmf/src/model/RoleModel.php)
- [AuthAccessModel.php](file://vendor/thinkcmf/cmf/src/model/AuthAccessModel.php)
- [OptionModel.php](file://vendor/thinkcmf/cmf/src/model/OptionModel.php)
- [common.php](file://vendor/thinkcmf/cmf/src/common.php)
- [AdminBaseController.php](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php)
- [RestBaseController.php](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php)
- [Auth.php](file://vendor/thinkcmf/cmf/src/lib/Auth.php)
- [Upload.php](file://vendor/thinkcmf/cmf/src/lib/Upload.php)
- [frontend.js](file://public/static/js/frontend.js)
- [jquery.validate.js](file://public/static/js/jquery.validate/jquery.validate.js)
- [validate.js](file://public/static/js/validate.js)
- [ajaxForm.js](file://public/static/js/ajaxForm.js)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南聚焦 ThinkCMF 的“模型基本操作”，围绕以下主题展开：模型类的创建与使用、模型继承关系与命名规范、数据增删改查（save、delete、find、select 等）、模型实例化方式（new 与静态调用）、数据验证机制（字段规则与自定义验证）、批量操作示例与最佳实践。文档在保证技术准确性的同时，尽量以循序渐进的方式呈现，便于不同背景的开发者快速上手。

## 项目结构
- ThinkCMF 的模型层位于 vendor/thinkcmf/cmf/src/model 下，统一继承自 ThinkPHP 的 Model 基类，并通过命名空间 cmf\model 进行组织。
- 控制器层位于 vendor/thinkcmf/cmf/src/controller 下，包含 AdminBaseController、RestBaseController 等，它们在业务流程中会频繁使用模型进行数据操作。
- 开发规范与数据库规范位于 AGENTS.MD，其中明确了命名规范、表与字段命名、时间戳与软删除等约定，是编写模型与 SQL 查询的重要依据。
- 前端交互与表单校验位于 public/static/js 目录，包含前端校验与批量操作触发逻辑，有助于理解前后端协作的数据流。

```mermaid
graph TB
subgraph "模型层"
M_User["UserModel"]
M_Role["RoleModel"]
M_Access["AuthAccessModel"]
M_Option["OptionModel"]
end
subgraph "控制器层"
C_Admin["AdminBaseController"]
C_Rest["RestBaseController"]
end
subgraph "公共与工具"
G_Common["common.php"]
L_Auth["Auth.php"]
L_Upload["Upload.php"]
end
subgraph "前端与校验"
J_Front["frontend.js"]
J_Validate["jquery.validate.js"]
J_ValidateExt["validate.js"]
J_AjaxForm["ajaxForm.js"]
end
C_Admin --> M_User
C_Rest --> M_User
G_Common --> M_Option
L_Auth --> M_Role
L_Auth --> M_Access
L_Upload --> M_User
J_Front --> C_Admin
J_Validate --> J_Front
J_ValidateExt --> J_Validate
J_AjaxForm --> J_Front
```

图表来源
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [RoleModel.php:15-25](file://vendor/thinkcmf/cmf/src/model/RoleModel.php#L15-L25)
- [AuthAccessModel.php:15-23](file://vendor/thinkcmf/cmf/src/model/AuthAccessModel.php#L15-L23)
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [AdminBaseController.php:41-41](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L41-L41)
- [RestBaseController.php:117-117](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php#L117-L117)
- [common.php:11-11](file://vendor/thinkcmf/cmf/src/common.php#L11-L11)
- [Auth.php:12-16](file://vendor/thinkcmf/cmf/src/lib/Auth.php#L12-L16)
- [Upload.php:15-15](file://vendor/thinkcmf/cmf/src/lib/Upload.php#L15-L15)
- [frontend.js:78-101](file://public/static/js/frontend.js#L78-L101)
- [jquery.validate.js:724-749](file://public/static/js/jquery.validate/jquery.validate.js#L724-L749)
- [validate.js:511-539](file://public/static/js/validate.js#L511-L539)
- [ajaxForm.js:1247-1303](file://public/static/js/ajaxForm.js#L1247-L1303)

章节来源
- [AGENTS.MD:448-507](file://AGENTS.MD#L448-L507)
- [AGENTS.MD:365-445](file://AGENTS.MD#L365-L445)

## 核心组件
- 模型基类与命名空间
  - 所有业务模型均继承自 ThinkPHP 的 Model，并位于 cmf\model 命名空间下，确保统一的生命周期与 ORM 能力。
- 关键模型示例
  - UserModel：定义表名、自动时间戳、字段类型（如 more 为数组）。
  - RoleModel：定义表名与自动时间戳。
  - AuthAccessModel：定义表名。
  - OptionModel：定义表名与字段类型（option_value 为数组）。
- 控制器中的模型使用
  - AdminBaseController 与 RestBaseController 在具体业务中通过模型执行查询与鉴权等操作。

章节来源
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [RoleModel.php:15-25](file://vendor/thinkcmf/cmf/src/model/RoleModel.php#L15-L25)
- [AuthAccessModel.php:15-23](file://vendor/thinkcmf/cmf/src/model/AuthAccessModel.php#L15-L23)
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [AdminBaseController.php:41-41](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L41-L41)
- [RestBaseController.php:117-117](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php#L117-L117)

## 架构总览
ThinkCMF 的模型层采用“控制器-模型”分层，控制器负责请求处理与业务编排，模型负责数据持久化与查询封装。开发规范对命名、表结构、字段类型有明确约束，确保跨模块一致性。

```mermaid
classDiagram
class Model {
<<ThinkPHP>>
}
class UserModel {
+name : string
+autoWriteTimestamp : bool|string
+updateTime : bool|string
+type : array
}
class RoleModel {
+name : string
+autoWriteTimestamp : bool|string
}
class AuthAccessModel {
+name : string
}
class OptionModel {
+name : string
+type : array
}
UserModel --|> Model
RoleModel --|> Model
AuthAccessModel --|> Model
OptionModel --|> Model
```

图表来源
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [RoleModel.php:15-25](file://vendor/thinkcmf/cmf/src/model/RoleModel.php#L15-L25)
- [AuthAccessModel.php:15-23](file://vendor/thinkcmf/cmf/src/model/AuthAccessModel.php#L15-L23)
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)

## 详细组件分析

### 模型类创建与使用
- 继承关系
  - 所有业务模型均继承自 ThinkPHP 的 Model，具备 save、delete、find、select 等 ORM 能力。
- 命名规范
  - 类名：驼峰法（首字母大写），如 UserModel、RoleModel。
  - 文件名：类名对应文件，统一 .php 后缀。
  - 命名空间：cmf\model。
  - 表名：模型属性 name 指定，遵循小写+下划线，如 user、role、auth_access、option。
- 字段类型与时间戳
  - 通过 $type 定义字段类型（如数组），提升序列化/反序列化一致性。
  - 通过 $autoWriteTimestamp、$updateTime 控制时间戳写入策略，符合 AGENTS.MD 的字段约定。

章节来源
- [AGENTS.MD:450-483](file://AGENTS.MD#L450-L483)
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [RoleModel.php:15-25](file://vendor/thinkcmf/cmf/src/model/RoleModel.php#L15-L25)
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)

### 数据增删改查（save、delete、find、select）
- save()
  - 用于新增或更新记录，遵循 ThinkPHP 的 ORM 行为；结合模型的时间戳与字段类型配置，可实现自动填充与类型转换。
- delete()
  - 删除记录，建议配合软删除字段（如 delete_time）与状态字段（如 status）实现安全删除。
- find()
  - 单条记录查询，常与 where 条件组合使用。
- select()
  - 多条记录查询，常与 limit、order、where 等条件组合使用。
- 实战参考
  - 控制器中通过模型进行查询与鉴权，例如在 AdminBaseController 与 RestBaseController 中对 UserModel 的使用。

```mermaid
sequenceDiagram
participant C as "控制器"
participant U as "UserModel"
participant DB as "数据库"
C->>U : "find()/select()"
U->>DB : "执行查询"
DB-->>U : "返回结果集"
U-->>C : "模型对象/数组"
C->>U : "save()新增/更新"
U->>DB : "INSERT/UPDATE"
DB-->>U : "影响行数/主键"
U-->>C : "布尔/对象"
C->>U : "delete()"
U->>DB : "DELETE"
DB-->>U : "影响行数"
U-->>C : "布尔"
```

图表来源
- [AdminBaseController.php:41-41](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L41-L41)
- [RestBaseController.php:117-117](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php#L117-L117)
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)

章节来源
- [AdminBaseController.php:41-41](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L41-L41)
- [RestBaseController.php:117-117](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php#L117-L117)

### 模型实例化方式（new 与静态调用）
- new 方式
  - 适用于需要对单个模型实例进行复杂定制或链式调用的场景。
- 静态调用方式
  - 通过类名直接调用模型的静态方法（如 where、find、select），简洁高效，适合常规查询与批量操作。
- 最佳实践
  - 对于简单查询与批量操作，推荐使用静态调用；对于需要复用实例或复杂状态管理的场景，可使用 new。

章节来源
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)

### 数据验证机制（字段验证规则与自定义验证）
- 前端校验
  - 使用 jQuery Validation 插件进行客户端校验，支持自定义消息、依赖规则与参数规范化。
- 自定义验证方法
  - 可通过规则对象的 method 与 param 定义验证逻辑，结合 normalize 方法对输入进行预处理。
- 后端校验
  - 结合控制器与模型，对关键字段进行服务端二次校验，确保数据安全与一致性。
- 建议
  - 前端仅做体验优化，后端必须进行严格校验；对富文本字段注意转义与 URL 替换处理。

```mermaid
flowchart TD
Start(["开始"]) --> GetVal["获取字段值"]
GetVal --> Normalize["规范化/去重空格"]
Normalize --> HasRules{"是否存在规则？"}
HasRules --> |否| Skip["跳过校验"]
HasRules --> |是| Apply["应用规则<br/>required/min/max/rangelength..."]
Apply --> Result{"校验通过？"}
Result --> |否| ShowMsg["显示错误消息"]
Result --> |是| Next["继续后续处理"]
Skip --> Next
ShowMsg --> End(["结束"])
Next --> End
```

图表来源
- [jquery.validate.js:724-749](file://public/static/js/jquery.validate/jquery.validate.js#L724-L749)
- [validate.js:511-539](file://public/static/js/validate.js#L511-L539)
- [validate.js:830-885](file://public/static/js/validate.js#L830-L885)

章节来源
- [jquery.validate.js:724-749](file://public/static/js/jquery.validate/jquery.validate.js#L724-L749)
- [validate.js:511-539](file://public/static/js/validate.js#L511-L539)
- [validate.js:830-885](file://public/static/js/validate.js#L830-L885)

### 批量操作（批量插入、更新与删除）
- 批量插入
  - 使用模型的批量写入能力，结合事务确保原子性；对富文本字段进行必要的转义与 URL 替换。
- 批量更新
  - 通过 where 条件与字段映射进行批量更新，注意更新范围与并发安全。
- 批量删除
  - 前端通过批量勾选与确认弹窗触发删除，后端执行安全删除（软删除优先）。
- 前端交互
  - 使用 frontend.js 的批量检查与确认逻辑，结合 ajaxForm.js 获取表单值，确保只删除选中项。

```mermaid
sequenceDiagram
participant UI as "前端界面"
participant F as "frontend.js"
participant AF as "ajaxForm.js"
participant C as "控制器"
participant M as "模型"
UI->>F : "点击批量按钮"
F->>UI : "弹出确认对话框"
UI-->>F : "确认/取消"
F->>AF : "收集选中项"
AF-->>F : "返回选中值"
F->>C : "AJAX 请求含批量参数"
C->>M : "批量删除/更新"
M-->>C : "返回结果"
C-->>F : "响应 JSON"
F-->>UI : "刷新/提示"
```

图表来源
- [frontend.js:78-101](file://public/static/js/frontend.js#L78-L101)
- [frontend.js:330-358](file://public/static/js/frontend.js#L330-L358)
- [ajaxForm.js:1247-1303](file://public/static/js/ajaxForm.js#L1247-L1303)

章节来源
- [frontend.js:78-101](file://public/static/js/frontend.js#L78-L101)
- [frontend.js:330-358](file://public/static/js/frontend.js#L330-L358)
- [ajaxForm.js:1247-1303](file://public/static/js/ajaxForm.js#L1247-L1303)

### 数据库规范与字段约定
- 表命名与字段命名
  - 表名与字段名统一使用小写+下划线；默认表前缀 cmf_；非核心应用表带应用前缀；插件表带插件前缀。
- 通用字段
  - id、create_time、update_time、delete_time、status、list_order、remark、description 等。
- 特殊字段
  - 布尔类型以 is_/has_/exist_/can_ 开头；文件相关字段 image、thumbnail、photos；用户相关字段 user_id；扩展字段 more；层级关系字段 parent_id。
- 时间戳与类型
  - 自动时间戳与字段类型（如数组）需与模型配置一致，确保序列化与反序列化正确。

章节来源
- [AGENTS.MD:365-445](file://AGENTS.MD#L365-L445)

## 依赖分析
- 模型依赖
  - 所有模型依赖 ThinkPHP 的 Model 基类，提供统一的 ORM 能力。
- 控制器依赖
  - AdminBaseController 与 RestBaseController 依赖 UserModel 进行用户信息与鉴权查询。
- 公共与工具依赖
  - common.php 引用 OptionModel；Auth.php 引用 RoleModel、AuthAccessModel、RoleUserModel、UserModel；Upload.php 引用 AssetModel。
- 前端依赖
  - frontend.js 依赖 noty 与 jQuery AJAX；jquery.validate.js 与 validate.js 提供表单校验；ajaxForm.js 提供表单值收集。

```mermaid
graph LR
M_User["UserModel"] --> TP["ThinkPHP Model"]
M_Role["RoleModel"] --> TP
M_Access["AuthAccessModel"] --> TP
M_Option["OptionModel"] --> TP
C_Admin["AdminBaseController"] --> M_User
C_Rest["RestBaseController"] --> M_User
G_Common["common.php"] --> M_Option
L_Auth["Auth.php"] --> M_Role
L_Auth --> M_Access
L_Upload["Upload.php"] --> M_User
J_Front["frontend.js"] --> J_Noty["noty"]
J_Front --> J_AJAX["jQuery AJAX"]
J_Validate["jquery.validate.js"] --> J_Front
J_ValidateExt["validate.js"] --> J_Validate
J_AjaxForm["ajaxForm.js"] --> J_Front
```

图表来源
- [UserModel.php:15-44](file://vendor/thinkcmf/cmf/src/model/UserModel.php#L15-L44)
- [RoleModel.php:15-25](file://vendor/thinkcmf/cmf/src/model/RoleModel.php#L15-L25)
- [AuthAccessModel.php:15-23](file://vendor/thinkcmf/cmf/src/model/AuthAccessModel.php#L15-L23)
- [OptionModel.php:15-32](file://vendor/thinkcmf/cmf/src/model/OptionModel.php#L15-L32)
- [AdminBaseController.php:41-41](file://vendor/thinkcmf/cmf/src/controller/AdminBaseController.php#L41-L41)
- [RestBaseController.php:117-117](file://vendor/thinkcmf/cmf/src/controller/RestBaseController.php#L117-L117)
- [common.php:11-11](file://vendor/thinkcmf/cmf/src/common.php#L11-L11)
- [Auth.php:12-16](file://vendor/thinkcmf/cmf/src/lib/Auth.php#L12-L16)
- [Upload.php:15-15](file://vendor/thinkcmf/cmf/src/lib/Upload.php#L15-L15)
- [frontend.js:330-358](file://public/static/js/frontend.js#L330-L358)
- [jquery.validate.js:724-749](file://public/static/js/jquery.validate/jquery.validate.js#L724-L749)
- [validate.js:511-539](file://public/static/js/validate.js#L511-L539)
- [ajaxForm.js:1247-1303](file://public/static/js/ajaxForm.js#L1247-L1303)

章节来源
- [common.php:11-11](file://vendor/thinkcmf/cmf/src/common.php#L11-L11)
- [Auth.php:12-16](file://vendor/thinkcmf/cmf/src/lib/Auth.php#L12-L16)
- [Upload.php:15-15](file://vendor/thinkcmf/cmf/src/lib/Upload.php#L15-L15)

## 性能考虑
- 查询优化
  - 合理使用索引字段（如主键 id、user_id、status）；避免 N+1 查询；必要时使用 join 与分页。
- 写入优化
  - 批量插入/更新时使用事务；减少不必要的字段写入；对大字段（如 more、photos）按需序列化。
- 前端交互
  - 批量操作前进行本地校验与确认，减少无效请求；合理使用缓存与延迟加载。

## 故障排查指南
- 常见问题
  - 字段类型不匹配：检查模型 $type 配置与数据库字段类型是否一致。
  - 时间戳异常：确认 $autoWriteTimestamp 与 $updateTime 设置是否符合预期。
  - 软删除未生效：确认 delete_time 字段存在且查询时未被忽略。
  - 前端批量删除无效：检查前端确认逻辑与 ajaxForm 收集的值是否正确。
- 建议
  - 对富文本字段进行入库前转义与 URL 替换，显示时再还原。
  - 对关键字段在控制器层进行服务端二次校验，避免前端绕过。

章节来源
- [jquery.validate.js:724-749](file://public/static/js/jquery.validate/jquery.validate.js#L724-L749)
- [validate.js:511-539](file://public/static/js/validate.js#L511-L539)
- [frontend.js:330-358](file://public/static/js/frontend.js#L330-L358)
- [ajaxForm.js:1247-1303](file://public/static/js/ajaxForm.js#L1247-L1303)

## 结论
ThinkCMF 的模型层以 ThinkPHP 的 Model 为基础，结合统一的命名规范与数据库约定，提供了稳定可靠的 CRUD 能力。通过合理的模型设计、严格的前后端校验与批量操作流程，可以有效提升系统的可维护性与安全性。建议在实际开发中遵循本文的命名与规范，善用模型的 save、delete、find、select 等方法，并结合事务与校验机制保障数据质量。

## 附录
- 开发规范摘要
  - 类名：驼峰法（首字母大写）
  - 文件名：类名对应，统一 .php
  - 命名空间：cmf\model
  - 表名与字段名：小写+下划线
  - 通用字段：id、create_time、update_time、delete_time、status、list_order、remark、description
  - 特殊字段：布尔类型以 is_/has_/exist_/can_ 开头；文件相关 image、thumbnail、photos；用户相关 user_id；扩展字段 more；层级 parent_id

章节来源
- [AGENTS.MD:450-483](file://AGENTS.MD#L450-L483)
- [AGENTS.MD:365-445](file://AGENTS.MD#L365-L445)