AI代码生成工具

This commit is contained in:
李琦
2026-08-11 09:39:41 +08:00
parent cab69b4193
commit 21f39eed85
8 changed files with 431 additions and 4 deletions

View File

@@ -67,6 +67,19 @@ class CodeGenerationService
private string $viewSearch = '';
private string $searchField = '';
private string $viewData = '';
/** uniapp C 端表单字段 HTML 片段 */
private string $uniFormFields = '';
/** uniapp 表单默认值片段 */
private string $uniFormDefaults = '';
/** uniapp 表单编辑回填片段 */
private string $uniFormAssign = '';
/** uniapp 详情信息行片段 */
private string $uniDetailRows = '';
/** uniapp 卡片标题字段名 */
private string $uniTitleField = 'id';
/** uniapp 卡片副标题字段名 */
private string $uniSubtitleField = '';
private bool $uniTitlePicked = false;
private array $tmpFile = [];
public function __construct()
@@ -228,6 +241,23 @@ class CodeGenerationService
// 生成唯一的临时目录名
$this->tempDir = 'temp/templates/' . $this->upperCamelCase . '-' . $this->uniqid;
Storage::makeDirectory($this->tempDir);
// 重置动态拼接字段,避免批量生成串数据
$this->selectField = '"id"';
$this->insertField = '';
$this->updateField = '';
$this->viewForm = '';
$this->viewSearch = '';
$this->searchField = '';
$this->viewData = '';
$this->uniFormFields = '';
$this->uniFormDefaults = '';
$this->uniFormAssign = '';
$this->uniDetailRows = '';
$this->uniTitleField = 'id';
$this->uniSubtitleField = '';
$this->uniTitlePicked = false;
$this->sql = '';
$this->tmpFile = [];
}
/**
@@ -256,8 +286,10 @@ class CodeGenerationService
$this->genRoute();
// 执行sql
$this->querySql();
// 生成视图
// 生成 PC 视图Vben
$this->genViews();
// 生成 uniapp 视图(微信小程序 + App + H5C 端风格)
$this->genUniappViews();
// 生成菜单
$this->genMenu();
DB::commit();
@@ -389,7 +421,7 @@ class CodeGenerationService
}
/**
* 生成前端部分文件
* 生成 PC 前端文件Vben写入 zip view/ 目录
* @return void
*/
private function genViews(): void
@@ -413,6 +445,31 @@ class CodeGenerationService
}
}
/**
* 生成 uniapp 前端文件C list/detail/form 三页),写入 zip uniapp/ 目录
* 禁止抽屉主路径;必须兼容微信小程序+App+H5
* @return void
*/
private function genUniappViews(): void
{
$appPath = app_path();
$uniList = [
'uni-api' => 'api/index.ts',
'uni-list' => 'pages/list.vue',
'uni-detail' => 'pages/detail.vue',
'uni-form' => 'pages/form.vue',
'uni-readme' => 'PAGES_JSON_SNIPPET.md',
];
foreach ($uniList as $k => $v) {
$this->strReplaceTmp(
$appPath . '/template/uniapp/' . $v,
$this->tempDir . "/uniapp/{$this->dashCase}/" . $v,
'uniapp',
$k
);
}
}
/**
* 生成菜单/授权
*
@@ -477,6 +534,20 @@ class CodeGenerationService
case 'view-table':
$newFile = str_replace("// 生成的列表字段", "// 生成的列表字段 \r ". $this->viewData, $newFile);
break;
case 'uni-list':
$newFile = str_replace('UNI_TITLE_FIELD', $this->uniTitleField, $newFile);
$newFile = str_replace('UNI_SUBTITLE_FIELD', $this->uniSubtitleField ?: $this->uniTitleField, $newFile);
break;
case 'uni-detail':
$newFile = str_replace('// UNI_DETAIL_ROWS', $this->uniDetailRows ?: '', $newFile);
$newFile = str_replace('UNI_TITLE_FIELD', $this->uniTitleField, $newFile);
$newFile = str_replace('UNI_SUBTITLE_FIELD', $this->uniSubtitleField ?: $this->uniTitleField, $newFile);
break;
case 'uni-form':
$newFile = str_replace('<!-- UNI_FORM_FIELDS -->', $this->uniFormFields ?: '<!-- 无表单字段 -->', $newFile);
$newFile = str_replace('// UNI_FORM_DEFAULTS', $this->uniFormDefaults ?: '', $newFile);
$newFile = str_replace('// UNI_FORM_ASSIGN', $this->uniFormAssign ?: '', $newFile);
break;
}
$this->tmpFile[$type][$fileKey] = $newFile;
@@ -510,6 +581,22 @@ class CodeGenerationService
$this->insertField .= !empty($this->insertField) ? '","' . $item['name'] : $item['name'];
$this->updateField .= !empty($this->updateField) ? '","' . $item['name'] : 'id","' . $item['name'];
$this->viewForm .= "{\n fieldName: '" . $item['name'] . "',\n label: '" . $item['comment'] . "',\n component: '" . $item['formType'] . "',\n rules: " . $isNull . ",\n },\n";
// uniapp C 端表单:用 input 承载,避免生成 Vben 组件名
$name = $item['name'];
$label = $item['comment'] ?: $name;
$this->uniFormDefaults .= " {$name}: '',\n";
$this->uniFormAssign .= " {$name}: info?.{$name} ?? '',\n";
$this->uniDetailRows .= " { label: '{$label}', value: info.value.{$name} },\n";
$this->uniFormFields .= "<view class=\"form-item\">\n"
. " <text class=\"label\">{$label}</text>\n"
. " <input v-model=\"form.{$name}\" class=\"input\" placeholder=\"{$label}\" />\n"
. " </view>\n";
if (!$this->uniTitlePicked) {
$this->uniTitleField = $name;
$this->uniTitlePicked = true;
} elseif ($this->uniSubtitleField === '') {
$this->uniSubtitleField = $name;
}
}
// 设置搜索字段
if ($item['search']) {