签入版本

This commit is contained in:
2026-10-08 17:50:29 +08:00
parent 809750b47e
commit e213a9b31d
444 changed files with 39366 additions and 37533 deletions
@@ -1,33 +1,32 @@
# 10.4 表结构解析引擎
:::tip 概述
解析引擎读取数据库表的字段信息(名称、类型、注释、是否必填等),并自动分析字段属性(图片、富文本、选项、外键等),作为代码生成的数据源。支持 MySQL、PostgreSQL、SQL Server、Oracle、SQLite 五种数据库。
解析引擎读取数据库表的字段信息(名称、类型、注释、是否必填等),并自动分析字段属性(图片、富文本、选项等),作为代码生成的数据源。支持 MySQL、PostgreSQL、SQL Server、Oracle、SQLite 五种数据库。
:::
## 多数据库适配
```php
// app/service/GeneratorService.php
// app/Services/GeneratorService.php
// 获取当前数据库驱动类型
protected function getDbDriver(): string
{
$default = config('database.default', 'mysql');
return strtolower(config("database.connections.{$default}.type", $default));
}
// 根据驱动分发到对应的查询实现
// 根据默认数据库驱动分发到对应的查询实现
public function getTableList(): array
{
$driver = $this->getDbDriver();
// MySQL: SHOW TABLE STATUS
// PostgreSQL: information_schema.tables
// SQL Server: sys.tables
// Oracle: all_tables
// SQLite: sqlite_master
$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` 等),输出统一的字段结构。
## 基础解析内容
| 信息 | 用途 |
@@ -35,23 +34,25 @@ public function getTableList(): array
| 字段名 | 生成属性名、查询条件 |
| 字段类型 | 生成验证规则、表单组件 |
| 字段注释 | 生成标签名、注释 |
| 是否必填 | 生成 require 验证规则 |
| 是否必填 | 生成 required 验证规则(`!isNull && default === null`) |
| 默认值 | 生成默认值配置 |
| 索引信息 | 判断是否唯一校验 |
| 字段顺序 | 表单 / 列表字段顺序与表结构保持一致 |
## 字段类型映射
| 数据库类型 | 归一化类型 | 表单组件 | 验证规则 |
|-----------|---------|---------|---------|
| VARCHAR | CharField | Input | max:N |
| TEXT | TextField | Editor | - |
| INT | IntegerField | InputNumber | number |
| TINYINT | IntegerField | Select / Radio | in:0,1 |
| DECIMAL | DecimalField | InputNumber | float |
| DATETIME | DateTimeField | DatePicker | date |
| DATE | DateField | DatePicker | date |
| TIME | TimeField | TimePicker | - |
| BOOLEAN | BooleanField | Switch | - |
原始类型先经 `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 | - |
## 字段自动识别规则
@@ -64,7 +65,7 @@ public function getTableList(): array
| 类型 | VARCHAR |
| 匹配 | 注释或字段名匹配 `/图片\|封面\|头像\|logo\|icon\|image\|avatar\|photo/i` |
识别后:`is_image = true`,归入 `file_fields`,前端用 ElAvatar 渲染。
识别后:`is_image = true`,归入 `file` 字段组,前端用 ElAvatar 渲染。
### 富文本字段
@@ -73,7 +74,7 @@ public function getTableList(): array
| 类型 | TEXT |
| 匹配 | 注释匹配 `/内容\|详情\|正文/i` |
识别后:`is_rich_text = true`,归入 `content_fields`,自动处理临时文件和图片占位符。
识别后:`is_rich_text = true`,归入 `content` 字段组,自动处理临时文件和图片占位符。
### 多行文本字段
@@ -86,7 +87,7 @@ public function getTableList(): array
### 选项字段(枚举)
解析引擎从字段注释中自动解析选项,支持以下注释格式:
解析引擎从字段注释中自动解析选项(`parseChoicesFromComment()`),支持以下注释格式:
```text
状态:1-启用 2-停用 ← 中文冒号 + 数字-文字
@@ -97,10 +98,10 @@ public function getTableList(): array
解析规则:
1. 以冒号(中文 `:` 或英文 `:`)分割,取冒号后面的部分
2. 匹配 `数字-文字` 或 `数字:文字` 格式
2. 匹配 `数字-文字` 或 `数字:文字` 格式(正则 `(\d+)\s*[\-\:]\s*(.+?)(?=\s+\d+[\-\:]|$)`)
3. 每个匹配项生成一个选项:`{value: 数字, label: 文字, type: 标签颜色}`
标签颜色映射:
标签颜色映射(`guessChoiceTagType()`):
| 选项值 | 标签颜色 | Element Plus type |
|--------|---------|-------------------|
@@ -109,14 +110,14 @@ public function getTableList(): array
| 3 | 橙色 | `warning` |
| 其他 | 灰色 | `info` |
识别后:`choices` 数组非空,自动归入 `eq_fields`(精确匹配)和 `serialize_maps`(字典映射)。
识别后:`choices` 数组非空,自动归入 `eq` 字段组(精确匹配)和 `serialize_maps`(字典映射,编码为 `{模块名}_{字段名}`)。
### 状态字段自动补全
| 条件 | 规则 |
|------|------|
| 字段名 | `status` |
| 类型 | INT |
| 类型 | int |
| 前提 | 注释中未解析出选项 |
自动生成默认选项:
@@ -131,9 +132,9 @@ public function getTableList(): array
| 条件 | 规则 |
|------|------|
| 类型 | VARCHAR |
| 匹配 | 字段名匹配 `/名称\|标题\|name\|title\|username\|realname\|nickname\|job_name\|category_name\|dept_name\|role_name/i` |
| 匹配 | 字段名匹配 `/名称\|标题\|name\|title\|username\|realname/i` |
识别后:归入 `like_fields`,分页查询时 LIKE 匹配,同时加入筛选表单。
识别后:归入 `like` 字段组,分页查询时 LIKE 匹配,同时加入筛选表单。
### 唯一字段
@@ -141,15 +142,7 @@ public function getTableList(): array
|------|------|
| 匹配 | 字段名匹配 `/编码\|code\|username\|mobile\|email\|account/i` |
识别后:归入 `unique_fields`,新增/修改时自动校验唯一性。
### 外键字段
| 条件 | 规则 |
|------|------|
| 匹配 | 字段名以 `_id` 或 `_ids` 结尾(排除 `id` 本身) |
识别后:`is_foreign_key = true`,记录 `fk_target`(如 `dept_id` → `dept`),供模板渲染下拉选择使用。
识别后:归入 `unique` 字段组,新增/修改时由 Service 层自动校验唯一性(见 10.5 与 3.5 Service 层开发)。
### 排序字段
@@ -157,7 +150,7 @@ public function getTableList(): array
|------|------|
| 字段名 | `sort` |
识别后:`has_sort = true`,默认排序改为 `sort asc`(而非 `id desc`)。
识别后:`has_sort = true`,默认排序改为 `sort asc`(`order_field` / `order_type` 变量,而非 `id desc`)。
### 系统字段排除
@@ -167,7 +160,7 @@ public function getTableList(): array
### 字段注释清洗
注释中的选项部分会被自动移除,只保留中文名称:
注释中的选项部分会被自动移除(`cleanFieldComment()`),只保留中文名称:
```text
"案例状态:1-正常 2-禁用" → "案例状态"
@@ -188,12 +181,12 @@ protected function validateTableName(string $tableName): string
```
:::warning 安全提示
涉及表名拼接的 SQL 一律先经 `validateTableName` 校验,只允许字母、数字、下划线,防止 SQL 注入。
涉及表名拼接的 SQL 一律先经 `validateTableName` 校验,只允许字母、数字、下划线,防止 SQL 注入。所有表名解析入口(`parseTableStructure` 及各驱动的列查询)都会先调用该方法。
:::
## 自动创建的权限节点
生成菜单时,自动创建以下 10 个权限节点:
生成菜单时(`createMenu()`),自动创建以下 9 个权限节点:
| 权限码 | 说明 |
|--------|------|
@@ -204,7 +197,6 @@ protected function validateTableName(string $tableName): string
| `sys:{模块名}:update` | 编辑 |
| `sys:{模块名}:delete` | 删除 |
| `sys:{模块名}:batchDelete` | 批量删除 |
| `sys:{模块名}:status` | 状态管理 |
| `sys:{模块名}:import` | 导入 |
| `sys:{模块名}:export` | 导出 |