# CRUD 代码生成逻辑说明

参考 ThinkPHP8 与 Webman 实现，说明各配置项含义及生成流程。

---

## 一、配置项说明

### 1. 生成代码的相对路径（generateRelativePath）

**作用**：作为路径前缀，用于快速组合生成位置。支持多级目录，如 `crud/test` 会生成到 `crud/test` 子目录。

**逻辑**：
- 输入值会替换 `/` 为 `\` 后作为 `table` 参与路径计算
- 与表名等价：`test` 和 `crud/test` 都会触发 `getFileData` 获取默认路径
- 为空时，需先填写**数据表名**，由表名驱动路径计算

**示例**：
- `test` → 控制器 `app/admin/controller/Test.php`，视图 `web/src/views/backend/test/`
- `crud/test` → 控制器 `app/admin/controller/crud/Test.php`，视图 `web/src/views/backend/crud/test/`

---

### 2. 生成的控制器位置（controllerFile）

**作用**：控制器文件的相对路径，如 `app/admin/controller/crud/Test.php`。

**逻辑**：
- 由 `Helper::parseNameData('admin', $tableName, 'controller', $table['controllerFile'])` 计算
- 为空时：按表名解析，如 `test` → `app/admin/controller/Test.php`
- 有值时：按自定义路径解析，会去掉 `app/admin/controller` 前缀后按剩余部分生成

**Webman 适配**：与 ThinkPHP 相同，目录为 `app/admin/controller/`。

---

### 3. 生成的数据模型位置（modelFile）

**作用**：模型文件的相对路径，如 `app/admin/model/crud/Test.php` 或 `app/common/model/Test.php`。

**逻辑**：
- 由 `Helper::parseNameData($app, $tableName, 'model', $table['modelFile'])` 计算
- `$app` 由「公共模型」决定：勾选为 `common`，否则为 `admin`
- 为空时按表名解析

**Webman 适配**：与 ThinkPHP 相同，目录为 `app/admin/model/` 或 `app/common/model/`。

---

### 4. 生成的验证器位置（validateFile）

**作用**：验证器文件的相对路径，如 `app/admin/validate/crud/Test.php`。

**逻辑**：
- 由 `Helper::parseNameData($app, $tableName, 'validate', $table['validateFile'])` 计算
- 与模型使用相同的 `$app`（公共模型或 admin）

**Webman 适配**：与 ThinkPHP 相同，目录为 `app/admin/validate/` 或 `app/common/validate/`。

---

### 5. WEB 端视图目录（webViewsDir）

**作用**：前端 Vue 视图目录，如 `web/src/views/backend/test`。

**逻辑**：
- 由 `Helper::parseWebDirNameData($tableName, 'views', $table['webViewsDir'])` 计算
- 生成 `index.vue`、`popupForm.vue` 及对应语言包
- 为空时按表名解析，如 `test` → `web/src/views/backend/test`

**Webman 适配**：与 ThinkPHP 相同，目录为 `web/src/views/backend/`。

---

### 6. 数据库连接配置标识（databaseConnection）

**作用**：选择使用的数据库连接，对应 `config/thinkorm.php` 中 `connections` 的 key。

**逻辑**：
- ThinkPHP：`config('database.connections')`
- Webman：`config('thinkorm.connections')`，Ajax 的 `getDatabaseConnectionList` 已适配
- 留空使用默认连接：`config('thinkorm.default', 'mysql')`

**Webman 适配**：已从 `database.php` 迁移到 `thinkorm.php`，无需额外修改。

---

## 二、自动填充流程

当**数据表名**或**生成代码的相对路径**变化时：

1. 前端调用 `getFileData(table, commonModel)`
2. 后端 `Crud::getFileData` 根据表名和是否公共模型计算默认路径
3. 返回并填充：
   - `modelFile`
   - `controllerFile`
   - `validateFile`
   - `webViewsDir`

**若这些字段为空**，可能原因：
- **从零新建**：需先输入数据表名（如 `test`），输入后会自动调用 `getFileData` 填充（输入过程中 400ms 防抖触发，无需失焦）
- 表名格式需符合 `^[a-z_][a-z0-9_]*$`（小写字母、数字、下划线）
- 「高级配置」默认展开，可直接看到控制器/模型/验证器/视图路径
- `getFileData` 接口异常（可检查网络或后端日志）
- `getFileData` 已加入 `noNeedLogin`，无需登录即可获取路径（便于设计页加载）

---

## 三、generate 生成流程

```
1. 接收 table、fields 等参数
2. 表设计：handleTableDesign（创建/更新表结构）
3. 路径解析：
   - modelFile = parseNameData(admin|common, tableName, 'model', table.modelFile)
   - validateFile = parseNameData(...)
   - controllerFile = parseNameData('admin', tableName, 'controller', table.controllerFile)
   - webViewsDir = parseWebDirNameData(tableName, 'views', table.webViewsDir)
4. 遍历字段，生成：
   - 模型（Model）
   - 控制器（Controller）
   - 验证器（Validate）
   - index.vue、popupForm.vue
   - 语言包（zh-cn、en）
5. 创建菜单（AdminRule）
```

---

## 四、Webman 与 ThinkPHP 差异

| 项目         | ThinkPHP              | Webman                          |
|--------------|------------------------|----------------------------------|
| 数据库配置   | `config/database.php`  | `config/thinkorm.php`           |
| 默认连接     | `config('database.default')` | `config('thinkorm.default')` |
| 根路径       | `root_path()`          | `root_path()`（同，指向 webman-builadmin 项目根） |
| 控制器初始化 | `initialize()` 自动调用 | 在 `initializeBackend` 中调用 `$this->initialize()` |
| XSS 过滤     | `$request->filter('clean_xss')` | `$inputFilter = 'clean_xss'`，由 Backend trait 在 add/edit 时应用 |

---

## 五、路径解析规则（Helper）

### parseNameData($app, $table, $type, $value)

- `$value` 为空：按 `$table` 解析，下划线 `_` 拆分为目录，末段大驼峰为类名
- `$value` 有值：按自定义路径解析，会去掉 `app/$app/$type` 前缀
- 预设：`admin`→`auth/admin`，`admin_rule`→`auth/rule` 等

**示例（表名 `xxx_yyy_zzz`，均相对于 webman-builadmin 项目根）：**

| 配置项           | 默认值                                   | 公共模型时                             |
|------------------|------------------------------------------|----------------------------------------|
| 生成代码的相对位置 | `xxx_yyy_zzz`                            | -                                       |
| 控制器           | `app/admin/controller/xxx/yyy/Zzz.php`    | -                                       |
| 模型             | `app/admin/model/xxx/yyy/Zzz.php`        | `app/common/model/xxx/yyy/Zzz.php`      |
| 验证器           | `app/admin/validate/xxx/yyy/Zzz.php`      | `app/common/validate/xxx/yyy/Zzz.php`   |
| WEB端视图目录    | `web/src/views/backend/xxx/yyy/zzz`       | -                                       |

**规则：** 表名 `xxx_yyy_zzz` → 前段 `xxx`、`yyy` 为子目录（小写），末段 `zzz` 转为 `Zzz.php`（大驼峰）；视图目录保持全小写。

### parseWebDirNameData($table, $type, $value)

- `$type='views'`：生成 `web/src/views/backend/{path}/{name}`，如 `xxx_yyy_zzz` → `web/src/views/backend/xxx/yyy/zzz`
- `$type='lang'`：生成 `web/src/lang/backend/{lang}/{path}/{name}`
