# 10.4 表结构解析引擎 :::tip 概述 解析引擎读取数据库表的字段信息(名称、类型、注释、是否必填等),并自动分析字段属性(图片、富文本、选项等),作为代码生成的数据源。支持 MySQL、PostgreSQL、SQL Server、Oracle、SQLite 五种数据库。 ::: ## 多数据库适配 ```php // app/Services/GeneratorService.php // 根据默认数据库驱动分发到对应的查询实现 public function getTableList(): array { $driver = config('database.default'); return match ($driver) { 'sqlite' => $this->queryTableListSqlite(), // sqlite_master 'mysql' => $this->queryTableListMysql(), // SHOW TABLE STATUS 'pgsql' => $this->queryTableListPgsql(), // information_schema.tables 'sqlsrv' => $this->queryTableListSqlsrv(), // sys.tables 'oracle' => $this->queryTableListOracle(), // all_tables default => $this->queryTableListMysql(), }; } ``` 每种驱动还实现了对应的列解析方法(`PRAGMA table_info` / `information_schema.COLUMNS` / `pg_attribute` 等),输出统一的字段结构。 ## 基础解析内容 | 信息 | 用途 | |------|------| | 字段名 | 生成属性名、查询条件 | | 字段类型 | 生成验证规则、表单组件 | | 字段注释 | 生成标签名、注释 | | 是否必填 | 生成 required 验证规则(`!isNull && default === null`) | | 默认值 | 生成默认值配置 | | 字段顺序 | 表单 / 列表字段顺序与表结构保持一致 | ## 字段类型映射 原始类型先经 `parseFieldType()` 归一化(boolean / int / decimal / varchar / text / datetime / date / time,无法识别归为 varchar),再由 `toConfigType()` 映射为配置类名: | 数据库类型 | 归一化类型 | 配置类名 | 表单组件 | 验证规则 | |-----------|---------|---------|---------|---------| | VARCHAR | varchar | CharField | Input | max:N | | TEXT | text | TextField | Editor | - | | INT / BIGINT / SMALLINT | int | IntegerField | InputNumber | number | | TINYINT | int(`tinyint(1)`/`bit` → boolean) | IntegerField / BooleanField | Select / Radio / Switch | in:0,1 | | DECIMAL / FLOAT / DOUBLE | decimal | DecimalField | InputNumber | float | | DATETIME / TIMESTAMP | datetime | DateTimeField | DatePicker | date | | DATE | date | DateField | DatePicker | date | | TIME | time | TimeField | TimePicker | - | | BOOLEAN / BIT | boolean | BooleanField | Switch | - | ## 字段自动识别规则 解析引擎会自动分析每个字段的属性,识别规则如下: ### 图片字段 | 条件 | 规则 | |------|------| | 类型 | VARCHAR | | 匹配 | 注释或字段名匹配 `/图片\|封面\|头像\|logo\|icon\|image\|avatar\|photo/i` | 识别后:`is_image = true`,归入 `file` 字段组,前端用 ElAvatar 渲染。 ### 富文本字段 | 条件 | 规则 | |------|------| | 类型 | TEXT | | 匹配 | 注释匹配 `/内容\|详情\|正文/i` | 识别后:`is_rich_text = true`,归入 `content` 字段组,自动处理临时文件和图片占位符。 ### 多行文本字段 | 条件 | 规则 | |------|------| | 类型 | VARCHAR | | 匹配 | 注释匹配 `/备注\|说明\|描述\|介绍\|简介/i` | 识别后:`is_textarea = true`,前端用 textarea 组件渲染。 ### 选项字段(枚举) 解析引擎从字段注释中自动解析选项(`parseChoicesFromComment()`),支持以下注释格式: ```text 状态:1-启用 2-停用 ← 中文冒号 + 数字-文字 状态:1-启用 2-停用 ← 英文冒号 + 数字-文字 类型:1:制造业 2:旅游业 ← 中文冒号 + 数字:文字 执行策略:1-立即执行 2-执行一次 3-放弃执行 ``` 解析规则: 1. 以冒号(中文 `:` 或英文 `:`)分割,取冒号后面的部分 2. 匹配 `数字-文字` 或 `数字:文字` 格式(正则 `(\d+)\s*[\-\:]\s*(.+?)(?=\s+\d+[\-\:]|$)`) 3. 每个匹配项生成一个选项:`{value: 数字, label: 文字, type: 标签颜色}` 标签颜色映射(`guessChoiceTagType()`): | 选项值 | 标签颜色 | Element Plus type | |--------|---------|-------------------| | 1 | 绿色 | `success` | | 2 | 红色 | `danger` | | 3 | 橙色 | `warning` | | 其他 | 灰色 | `info` | 识别后:`choices` 数组非空,自动归入 `eq` 字段组(精确匹配)和 `serialize_maps`(字典映射,编码为 `{模块名}_{字段名}`)。 ### 状态字段自动补全 | 条件 | 规则 | |------|------| | 字段名 | `status` | | 类型 | int | | 前提 | 注释中未解析出选项 | 自动生成默认选项: | 值 | 标签 | 颜色 | |----|------|------| | 0 | 正常 | success | | 1 | 停用 | danger | ### 模糊搜索字段 | 条件 | 规则 | |------|------| | 类型 | VARCHAR | | 匹配 | 字段名匹配 `/名称\|标题\|name\|title\|username\|realname/i` | 识别后:归入 `like` 字段组,分页查询时 LIKE 匹配,同时加入筛选表单。 ### 唯一字段 | 条件 | 规则 | |------|------| | 匹配 | 字段名匹配 `/编码\|code\|username\|mobile\|email\|account/i` | 识别后:归入 `unique` 字段组,新增/修改时由 Service 层自动校验唯一性(见 10.5 与 3.5 Service 层开发)。 ### 排序字段 | 条件 | 规则 | |------|------| | 字段名 | `sort` | 识别后:`has_sort = true`,默认排序改为 `sort asc`(`order_field` / `order_type` 变量,而非 `id desc`)。 ### 系统字段排除 以下字段自动从表单和列表中排除: `id`、`tenant_id`、`create_user`、`create_time`、`update_user`、`update_time`、`is_delete` ### 字段注释清洗 注释中的选项部分会被自动移除(`cleanFieldComment()`),只保留中文名称: ```text "案例状态:1-正常 2-禁用" → "案例状态" "执行策略:1-立即执行 2-执行一次 3-放弃执行" → "执行策略" ``` ## 安全校验 ```php // 表名合法性校验(防 SQL 注入) protected function validateTableName(string $tableName): string { if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $tableName)) { throw new \Exception('表名格式不合法: ' . $tableName); } return $tableName; } ``` :::warning 安全提示 涉及表名拼接的 SQL 一律先经 `validateTableName` 校验,只允许字母、数字、下划线,防止 SQL 注入。所有表名解析入口(`parseTableStructure` 及各驱动的列查询)都会先调用该方法。 ::: ## 自动创建的权限节点 生成菜单时(`createMenu()`),自动创建以下 9 个权限节点: | 权限码 | 说明 | |--------|------| | `sys:{模块名}:page` | 分页查询 | | `sys:{模块名}:list` | 列表查询 | | `sys:{模块名}:detail` | 详情查询 | | `sys:{模块名}:add` | 新增 | | `sys:{模块名}:update` | 编辑 | | `sys:{模块名}:delete` | 删除 | | `sys:{模块名}:batchDelete` | 批量删除 | | `sys:{模块名}:import` | 导入 | | `sys:{模块名}:export` | 导出 | ## 相关文档 - [10.5 代码生成引擎](/zh/generator/code-engine.html) - [10.6 自定义模板开发](/zh/generator/templates.html) - [10.7 配置文件详解](/zh/generator/config.html)