805 lines
27 KiB
PHP
805 lines
27 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
// +----------------------------------------------------------------------
|
||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||
// +----------------------------------------------------------------------
|
||
// | swiftAdmin.net High Speed Development Framework
|
||
// +----------------------------------------------------------------------
|
||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||
// +----------------------------------------------------------------------
|
||
namespace app\admin\controller\developer;
|
||
|
||
use app\admin\model\developer\Generate;
|
||
use app\AdminController;
|
||
use app\common\model\system\AdminRules;
|
||
use system\Form;
|
||
use think\db\exception\DataNotFoundException;
|
||
use think\db\exception\DbException;
|
||
use think\db\exception\ModelNotFoundException;
|
||
use think\facade\Db;
|
||
use think\helper\Str;
|
||
|
||
/**
|
||
* 一键CURD管理
|
||
* <!--Developer-->
|
||
* Class Curd
|
||
* @package app\admin\controller\developer
|
||
*/
|
||
class Curd extends AdminController
|
||
{
|
||
/**
|
||
* 数据表前缀
|
||
*
|
||
* @var mixed
|
||
*/
|
||
public mixed $prefix = 'sa_';
|
||
|
||
/**
|
||
* 获取菜单
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $menus = [];
|
||
|
||
/**
|
||
* 关联表信息
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $relation = [];
|
||
|
||
/**
|
||
* 函数体
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $methods = [];
|
||
|
||
/**
|
||
* 模板路径
|
||
*
|
||
* @var string
|
||
*/
|
||
public string $templatePath = '';
|
||
|
||
/**
|
||
* 模板文件
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $templateFiles = [];
|
||
|
||
/**
|
||
* 添加时间字段
|
||
* @var string
|
||
*/
|
||
protected string $createTimeField = 'create_time';
|
||
|
||
/**
|
||
* 更新时间字段
|
||
* @var string
|
||
*/
|
||
protected string $updateTimeField = 'update_time';
|
||
|
||
/**
|
||
* 软删除时间字段
|
||
* @var string
|
||
*/
|
||
protected string $deleteTimeField = 'delete_time';
|
||
|
||
/**
|
||
* 过滤默认模板
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $filterMethod = ['index', 'add', 'edit', 'del', 'status'];
|
||
|
||
/**
|
||
* 限定特定组件
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $mustbeComponent = ['set', 'text', 'json'];
|
||
|
||
/**
|
||
* 修改器字段
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $modifyFieldAttr = ['set', 'text', 'json'];
|
||
|
||
/**
|
||
* 保留字段
|
||
*
|
||
* @var string
|
||
*/
|
||
public string $keepField = 'status';
|
||
|
||
/**
|
||
* 查询字段[SELECT]
|
||
*
|
||
* @var array
|
||
*/
|
||
public array $dropdown = ['radio', 'checkbox', 'select'];
|
||
|
||
/**
|
||
* COLS换行符
|
||
*
|
||
* @var string
|
||
*/
|
||
public string $commaEol = ',' . PHP_EOL;
|
||
|
||
/**
|
||
* 受保护的表
|
||
* 禁止CURD操作
|
||
* @var array
|
||
*/
|
||
protected array $protectTable = [
|
||
"admin", "admin_access", "admin_group", "admin_rules", "company", "department",
|
||
"dictionary", "generate", "jobs", "user", "user_group", "user_third", "user_validate"
|
||
];
|
||
|
||
/**
|
||
* 类保留关键字
|
||
*
|
||
* @var array
|
||
*/
|
||
protected array $internalKeywords = [
|
||
'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch',
|
||
'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else',
|
||
'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile',
|
||
'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements',
|
||
'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new',
|
||
'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch',
|
||
'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield', 'readonly', 'match', 'fn'
|
||
];
|
||
|
||
// 初始化操作
|
||
public function __construct()
|
||
{
|
||
parent::__construct();
|
||
$this->model = new Generate();
|
||
$this->prefix = function_exists('get_env') ? get_env('DATABASE_PREFIX') : getenv('DATABASE_PREFIX');
|
||
}
|
||
|
||
/**
|
||
* 生成CURD代码
|
||
* @return \support\Response
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
*/
|
||
public function build(): \support\Response
|
||
{
|
||
$id = input('id');
|
||
$data = $this->model->find($id);
|
||
|
||
if ($data['status'] && !$data['force']) {
|
||
return $this->error('该表已经生成过了');
|
||
}
|
||
|
||
$table = str_replace($this->prefix, '', $data['table']);
|
||
if ($this->filterSystemTable($table)) {
|
||
return $this->error('禁止操作系统表');
|
||
}
|
||
|
||
// 命名空间
|
||
$replaces = [];
|
||
$controller = $data['controller'];
|
||
$module = $data['global'] ? 'common' : 'admin';
|
||
$element = ['controller', 'model', 'validate'];
|
||
|
||
try {
|
||
|
||
foreach ($element as $key => $item) {
|
||
$result = $this->parseNameData($item == 'controller' ? 'admin' : $module, $controller, $key ? $table : '', $item);
|
||
list($replaces[$item . 'Name'], $replaces[$item . 'Namespace'], $replaces[$item . 'File']) = $result;
|
||
}
|
||
|
||
$this->getTemplatePath($controller);
|
||
list($this->menus, $this->methods, $this->templateFiles) = $this->getMenuMethods($data->toArray());
|
||
|
||
// 获取字段
|
||
$adviceField = [];
|
||
$adviceSearch = [];
|
||
$everySearch = [];
|
||
|
||
// 字段属性值
|
||
$colsFields = [];
|
||
$fieldAttrArr = [];
|
||
|
||
// 表单设计
|
||
$formDesign = [];
|
||
$formItem = [];
|
||
$formType = $data['formType'];
|
||
if (!empty($data['formDesign'])) {
|
||
$formDesign = json_decode($data['formDesign'], true);
|
||
}
|
||
|
||
$this->tableFields = Db::name($table)->getFields();
|
||
$listFields = explode(',', $data['listField']);
|
||
foreach ($this->tableFields as $key => $value) {
|
||
$field = $value['name'];
|
||
$comment = str_replace(':', ';', $value['comment']);
|
||
if (empty($comment)) {
|
||
return $this->error($field . " 字段注释不能为空");
|
||
}
|
||
|
||
$this->tableFields[$key]['title'] = explode(';', $comment)[0];
|
||
|
||
// 是否存在状态字段
|
||
if ($field == $this->keepField) {
|
||
$adviceSearch[] = $field;
|
||
}
|
||
|
||
// 获取字段类型
|
||
$everySearch[] = $field;
|
||
$type = explode('(', $value['type'])[0];
|
||
|
||
// 限定组件类型
|
||
if (in_array($type, $this->mustbeComponent)) {
|
||
$this->validComponent($field, $type, $formDesign);
|
||
}
|
||
|
||
if (in_array($type, $this->modifyFieldAttr)) {
|
||
$fieldAttrArr[] = $this->getFieldAttrArr($field, $type);
|
||
}
|
||
|
||
if (empty($adviceField)
|
||
|| ($adviceField['type'] != 'varchar' && $type == 'varchar')) {
|
||
$adviceField = [
|
||
'field' => $field,
|
||
'type' => $type,
|
||
];
|
||
}
|
||
|
||
if (in_array($field, $listFields)) {
|
||
$colsFields[] = [
|
||
'field' => $field,
|
||
'title' => '{:__("' . $this->tableFields[$key]['title'] . '")}',
|
||
];
|
||
}
|
||
}
|
||
|
||
// 推荐搜索片段
|
||
$adviceSearch[] = $adviceField['field'];
|
||
$adviceSearchHtml = $this->getAdviceSearch($adviceSearch, $formDesign);
|
||
|
||
// 获取全部搜索字段
|
||
$everySearch = array_diff($everySearch, $adviceSearch);
|
||
$everySearchHtml = $this->getAdviceSearch($everySearch, $formDesign);
|
||
$controller = substr($controller, 0, (strrpos($controller, '/') + 1));
|
||
$colsListArr = $this->getColsListFields($colsFields, $formDesign);
|
||
|
||
$replaces['table'] = $table;
|
||
$replaces['title'] = $data['title'];
|
||
$replaces['pluginClass'] = $data['plugin'];
|
||
$replaces['controller'] = $controller;
|
||
$replaces['controllerDiy'] = $this->getMethodString($this->methods);
|
||
$replaces['colsListArr'] = $colsListArr;
|
||
$replaces['fieldAttrArr'] = implode(PHP_EOL . PHP_EOL, $fieldAttrArr);
|
||
$replaces['adviceSearchHtml'] = $adviceSearchHtml;
|
||
$replaces['everySearchHtml'] = $everySearchHtml;
|
||
$replaces['relationMethodList'] = $this->getRelationMethodList($data['relation']);
|
||
$replaces['FormArea'] = $data['width'] . ',' . $data['height'];
|
||
$replaces['softDelete'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "use SoftDelete;" : '';
|
||
$replaces['softDeleteClassPath'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "use think\model\concern\SoftDelete;" : '';
|
||
$replaces['createTime'] = array_key_exists($this->createTimeField, $this->tableFields) ? "'$this->createTimeField'" : 'false';
|
||
$replaces['updateTime'] = array_key_exists($this->updateTimeField, $this->tableFields) ? "'$this->updateTimeField'" : 'false';
|
||
$replaces['deleteTime'] = array_key_exists($this->deleteTimeField, $this->tableFields) ? "'$this->deleteTimeField'" : 'false';
|
||
|
||
// 生成控制器/模型/验证器规则
|
||
foreach ($element as $index => $item) {
|
||
if ($index == 0
|
||
&& (!$data['create'] || !$data['listField'])) {
|
||
continue;
|
||
}
|
||
|
||
$code = read_file($this->getStubTpl($item));
|
||
foreach ($replaces as $key => $value) {
|
||
$code = str_replace("{%$key%}", $value, $code);
|
||
}
|
||
|
||
write_file($replaces[$item . 'File'], $code);
|
||
}
|
||
|
||
// 生成表单元素
|
||
$template = $formType ? 'add' : 'inside';
|
||
$formHtml = read_file($this->getStubTpl($template));
|
||
if (!empty($formDesign) && $data['listField']) {
|
||
|
||
foreach ($formDesign as $key => $value) {
|
||
$formItem[$key] = Form::itemElem($value, $formType);
|
||
}
|
||
|
||
$formItem = implode(PHP_EOL, $formItem);
|
||
$formHtml = str_replace(['{formItems}', '{pluginClass}'], [$formItem, $replaces['pluginClass']], $formHtml);
|
||
$formType && write_file($this->templatePath . 'add.html', $formHtml);
|
||
}
|
||
|
||
// 生成首页模板
|
||
$indexHtml = read_file($this->getStubTpl($formType ? 'index' : 'index_inside'));
|
||
if (!empty($data['listField'])) {
|
||
$replaces['editforms'] = $formType ? '' : $formHtml;
|
||
foreach ($replaces as $key => $value) {
|
||
$indexHtml = str_replace("{%$key%}", $value, $indexHtml);
|
||
}
|
||
if (empty($formDesign)) {
|
||
$indexHtml = preg_replace('/<!--formBegin-->(.*)<!--formEnd-->/isU', '', $indexHtml);
|
||
}
|
||
write_file($this->templatePath . 'index.html', str_replace('{pluginClass}', $replaces['pluginClass'], $indexHtml));
|
||
}
|
||
|
||
// 生成扩展模板
|
||
$extendHtml = read_file($this->getStubTpl('extend'));
|
||
$extendHtml = str_replace('{pluginClass}', $replaces['pluginClass'], $extendHtml);
|
||
foreach ($this->methods as $method) {
|
||
write_file($this->templatePath . Str::snake($method) . '.html', $extendHtml);
|
||
}
|
||
|
||
// 生成CURD菜单
|
||
if ($data['create'] && !empty($data['listField'])) {
|
||
AdminRules::createMenu([$this->menus], $replaces['pluginClass'] ?: $table, $data['pid']);
|
||
}
|
||
|
||
// 更新生成状态
|
||
$data->save(['status' => 1]);
|
||
|
||
} catch (\Throwable $e) {
|
||
return $this->error($e->getMessage());
|
||
}
|
||
|
||
return $this->success('生成成功');
|
||
}
|
||
|
||
/**
|
||
* 清理内容
|
||
* @return mixed|void
|
||
* @throws DataNotFoundException
|
||
* @throws DbException
|
||
* @throws ModelNotFoundException
|
||
*/
|
||
public function clear()
|
||
{
|
||
$id = input('id');
|
||
if (request()->isAjax()) {
|
||
|
||
$data = $this->model->find($id);
|
||
$table = str_replace($this->prefix, '', $data['table']);
|
||
$controller = $data['controller'];
|
||
try {
|
||
|
||
$module = $data['global'] ? 'common' : 'admin';
|
||
$element = ['controller', 'model', 'validate'];
|
||
foreach ($element as $key => $item) {
|
||
$result = $this->parseNameData($item == 'controller' ? 'admin' : $module, $controller, $key ? $table : '', $item);
|
||
$file = end($result);
|
||
if (file_exists($file)) {
|
||
unlink($file);
|
||
}
|
||
// 删除空文件夹
|
||
remove_empty_dir(dirname($file));
|
||
}
|
||
|
||
list($this->menus, $this->methods, $this->templateFiles) = $this->getMenuMethods($data->toArray());
|
||
recursive_delete($this->getTemplatePath($controller));
|
||
AdminRules::disabled($table, true);
|
||
$data->save(['status' => 0]);
|
||
} catch (\Throwable $th) {
|
||
return $this->error($th->getMessage());
|
||
}
|
||
|
||
return $this->success('删除成功');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取列表字段
|
||
* @param array $colsFields
|
||
* @param array $formDesign
|
||
* @return string
|
||
*/
|
||
public function getColsListFields(array $colsFields = [], array $formDesign = []): string
|
||
{
|
||
$colsListArr = [];
|
||
foreach ($colsFields as $key => $value) {
|
||
|
||
// 过滤删除字段
|
||
$colsLine = [];
|
||
$colsField = $value['field'];
|
||
$colsTitle = $value['title'];
|
||
if ($colsField == $this->deleteTimeField) {
|
||
continue;
|
||
}
|
||
|
||
// 获取每一列参数合集
|
||
$colsLine[] = "field:'$colsField'";
|
||
if ($colsField == $this->keepField) {
|
||
$colsLine[] = "templet: '#columnStatus'";
|
||
}
|
||
|
||
$item = $this->recursiveComponent($colsField, $formDesign);
|
||
if (!empty($item) && is_array($item)) {
|
||
$colsArr = '';
|
||
$colsTag = $item['tag'];
|
||
if (in_array($colsTag, $this->dropdown)) {
|
||
$colsArr = $item['options'];
|
||
foreach ($colsArr as $index => $elem) {
|
||
$colsArr[$index]['title'] = "{:__('" . $elem['title'] . "')}";
|
||
}
|
||
$colsArr = json_encode($colsArr, JSON_UNESCAPED_UNICODE);
|
||
$colsTpl = read_file($this->getStubTpl('list/' . $colsTag));
|
||
} else if ($colsTag == 'upload') {
|
||
$colsTpl = read_file($this->getStubTpl('list/' . $item['uploadtype']));
|
||
} else {
|
||
$colsTpl = read_file($this->getStubTpl('list/' . $colsTag));
|
||
}
|
||
if (!empty($colsTpl)) {
|
||
$colsLine[] = str_replace(['{colsArr}', '{field}'], [$colsArr, $colsField], $colsTpl);
|
||
}
|
||
}
|
||
|
||
$colsLine[] = "title:'$colsTitle'";
|
||
$colsListArr[$key] = '{' . implode(',', $colsLine) . '}';
|
||
}
|
||
|
||
$colsListArr = implode($this->commaEol, $colsListArr);
|
||
return $colsListArr ? $colsListArr . ',' : $colsListArr;
|
||
}
|
||
|
||
/**
|
||
* 获取修改器
|
||
* @param string|null $field
|
||
* @param string|null $type
|
||
* @param string $subTpl
|
||
* @return array|false|string|string[]
|
||
*/
|
||
public function getFieldAttrArr(string $field = null, string $type = null, string $subTpl = 'change')
|
||
{
|
||
$tplPath = $subTpl . '/' . $type;
|
||
$methods = read_file($this->getStubTpl($tplPath));
|
||
|
||
if (!empty($methods)) {
|
||
$methods = str_replace('{%field%}', ucfirst($field), $methods);
|
||
}
|
||
|
||
return $methods;
|
||
}
|
||
|
||
/**
|
||
* 验证组件
|
||
* @param string|null $field
|
||
* @param string|null $type
|
||
* @param array $data
|
||
* @return mixed
|
||
*/
|
||
public function validComponent(string $field, string $type, array $data = [])
|
||
{
|
||
if (!$field || !$data) {
|
||
return false;
|
||
}
|
||
|
||
$result = $this->recursiveComponent($field, $data);
|
||
|
||
if (!empty($result)) {
|
||
|
||
$tag = strtolower($result['tag']);
|
||
switch ($type) {
|
||
case 'set':
|
||
if ($tag != 'checkbox') {
|
||
return $this->error($field . ' 组件类型限定为checkbox');
|
||
}
|
||
break;
|
||
case 'json':
|
||
if ($tag != 'json') {
|
||
return $this->error($field . ' 组件类型限定为json');
|
||
}
|
||
break;
|
||
case 'text': // 限定TEXT字段类型必须为多文件上传
|
||
if ($tag != 'upload' || $result['uploadtype'] != 'multiple') {
|
||
return $this->error($field . ' 字段类型为text时,组件类型限定为多文件上传');
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 查找组件
|
||
* @param string $field
|
||
* @param array $data
|
||
* @return mixed
|
||
*/
|
||
public function recursiveComponent(string $field = '', array $data = [])
|
||
{
|
||
foreach ($data as $value) {
|
||
|
||
if ($field == $value['name']) {
|
||
return $value;
|
||
}
|
||
|
||
if (isset($value['children']) && $value['children']) {
|
||
$subElem = $value['children'];
|
||
foreach ($subElem as $child) {
|
||
$item = $this->recursiveComponent($field, $child['children']);
|
||
if (!empty($item)) {
|
||
return $item;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 搜索模板
|
||
* @param array $searchArr
|
||
* @param array $formArr
|
||
* @return false|string
|
||
*/
|
||
public function getAdviceSearch(array $searchArr = [], array $formArr = [])
|
||
{
|
||
if (!$searchArr) {
|
||
return false;
|
||
}
|
||
|
||
$varData = '';
|
||
$searchHtml = [];
|
||
foreach ($searchArr as $searchField) {
|
||
|
||
if ($searchField == $this->deleteTimeField) {
|
||
continue;
|
||
}
|
||
|
||
if ($searchField == $this->keepField) {
|
||
$rhtml = read_file($this->getStubTpl('search/status'));
|
||
} else if (in_array($searchField, [$this->createTimeField, $this->updateTimeField])) {
|
||
$rhtml = read_file($this->getStubTpl('search/datetime'));
|
||
} else {
|
||
|
||
$result = $this->recursiveComponent($searchField, $formArr);
|
||
if ($result && in_array($result['tag'], $this->dropdown)) {
|
||
$varData = Form::validOptions($result['options']);
|
||
$rhtml = read_file($this->getStubTpl('search/select'));
|
||
} else if ($result && in_array($result['tag'], ['slider'])) {
|
||
$rhtml = read_file($this->getStubTpl('search/slider'));
|
||
$rhtml = str_replace(
|
||
['{default}', '{theme}', '{step}', '{max}', '{min}'],
|
||
[$result['data_default'], $result['data_theme'], $result['data_step'], $result['data_max'], $result['data_min']],
|
||
$rhtml
|
||
);
|
||
} else if ($result && $result['tag'] == 'cascader') {
|
||
$rhtml = read_file($this->getStubTpl('search/cascader'));
|
||
} else if ($result && $result['tag'] == 'date') {
|
||
$rhtml = read_file($this->getStubTpl('search/datetime'));
|
||
} else if ($result && $result['tag'] == 'rate') {
|
||
$rhtml = read_file($this->getStubTpl('search/rate'));
|
||
$rhtml = str_replace(['{theme}', '{length}'], [$result['data_theme'], $result['data_length']], $rhtml);
|
||
} else {
|
||
$rhtml = read_file($this->getStubTpl('search/input'));
|
||
}
|
||
}
|
||
|
||
$replace = [
|
||
'field' => $searchField,
|
||
'title' => $this->tableFields[$searchField]['title'],
|
||
'varlist' => ucfirst($searchField) . '_list',
|
||
'vardata' => $varData,
|
||
];
|
||
|
||
foreach ($replace as $key => $value) {
|
||
$rhtml = str_replace("{%$key%}", $value, $rhtml);
|
||
}
|
||
|
||
$searchHtml[] = $rhtml;
|
||
}
|
||
|
||
return implode(PHP_EOL . PHP_EOL, $searchHtml);
|
||
}
|
||
|
||
/**
|
||
* 获取菜单函数
|
||
* @param array $data
|
||
* @return array
|
||
* @throws \Exception
|
||
*/
|
||
protected function getMenuMethods(array $data = []): array
|
||
{
|
||
if (empty($data) || !is_array($data)) {
|
||
throw new \Exception("Error Params Request", 1);
|
||
}
|
||
|
||
if (!is_array($data['menus'])) {
|
||
$data['menus'] = unserialize($data['menus']);
|
||
}
|
||
|
||
$MenuRules = [
|
||
'title' => $data['title'],
|
||
'router' => $data['controller'],
|
||
'icon' => $data['icon'] ?: '',
|
||
'pid' => $data['pid'],
|
||
'auth' => $data['auth'],
|
||
];
|
||
|
||
foreach ($data['menus'] as $key => $value) {
|
||
$MenuRules['children'][$key] = [
|
||
'title' => $value['title'],
|
||
'router' => $value['router'],
|
||
'auth' => $value['auth'],
|
||
'type' => $value['type'],
|
||
];
|
||
$parse = explode(':', $value['route']);
|
||
$parse = end($parse);
|
||
if (!in_array($parse, $this->filterMethod)) {
|
||
$this->methods[$key] = $parse;
|
||
$this->templateFiles[$key] = Str::snake($parse);
|
||
}
|
||
}
|
||
|
||
return [$MenuRules, $this->methods, $this->templateFiles];
|
||
}
|
||
|
||
/**
|
||
* 获取其他函数
|
||
* @param array $methods
|
||
* @return string
|
||
*/
|
||
protected function getMethodString(array $methods = []): string
|
||
{
|
||
$outsMethod = PHP_EOL;
|
||
foreach ($methods as $method) {
|
||
if (!in_array($method, $this->filterMethod)) {
|
||
$outsMethod .= str_replace('method', $method, read_file($this->getStubTpl('method')));
|
||
}
|
||
}
|
||
return $outsMethod;
|
||
}
|
||
|
||
/**
|
||
* 获取关联表信息
|
||
* id style KEY
|
||
* @param $relation
|
||
* @return string
|
||
* @throws \Exception
|
||
*/
|
||
protected function getRelationMethodList($relation): string
|
||
{
|
||
$relationString = PHP_EOL;
|
||
if (!empty($relation) && !is_array($relation)) {
|
||
|
||
$relation = unserialize($relation);
|
||
foreach ($relation as $value) {
|
||
|
||
if (!$value) {
|
||
continue;
|
||
}
|
||
$table = str_replace($this->prefix, '', $value['table']);
|
||
$schema = Db::query("SHOW TABLE STATUS LIKE '$table'");
|
||
$studly = Str::studly($table);
|
||
|
||
// 直接判断是否存在
|
||
// 可提交遍历命名空间PR
|
||
if (in_array($table,$this->protectTable)) {
|
||
$studly = '\\app\\common\\model\\system\\' . $studly;
|
||
} else {
|
||
$namespace = '\\app\\admin\\model\\'.$studly;
|
||
if (class_exists($namespace)) {
|
||
$studly = $namespace;
|
||
}
|
||
}
|
||
|
||
// 拼接关联语句
|
||
$localKey = $value['localKey'];
|
||
$foreignKey = $value['foreignKey'];
|
||
$str_relation = '$this->' . $value['style'] . '(' . $studly . '::Class,' . "'$foreignKey','$localKey')";
|
||
|
||
$bindField = [];
|
||
if ($value['relationField']) {
|
||
$bindField = explode(',', $value['relationField']);
|
||
$bindField = array_unique(array_filter($bindField));
|
||
$str_relation .= '->bind(' . str_replace('"', '\'', json_encode($bindField)) . ')';
|
||
}
|
||
|
||
try {
|
||
|
||
$Comment = $schema[0]['Comment'] ?? $value['table'];
|
||
$table = Str::camel($table);
|
||
$relationString .= ' /**';
|
||
$relationString .= PHP_EOL . ' * 定义 ' . $Comment . ' 关联模型';
|
||
$relationString .= PHP_EOL . ' * @localKey ' . $localKey;
|
||
$relationString .= PHP_EOL . ' * @bind ' . implode(',', $bindField);
|
||
$relationString .= PHP_EOL . ' */';
|
||
$relationString .= PHP_EOL . ' public function ' . $table . '()';
|
||
$relationString .= PHP_EOL . ' {';
|
||
$relationString .= PHP_EOL . ' return ' . $str_relation . ';';
|
||
$relationString .= PHP_EOL . ' }';
|
||
$relationString .= PHP_EOL;
|
||
} catch (\Throwable $th) {
|
||
throw new \Exception($th->getMessage());
|
||
}
|
||
}
|
||
}
|
||
|
||
return $relationString;
|
||
}
|
||
|
||
/**
|
||
* 获取文件信息
|
||
* @param string $module
|
||
* @param string $name
|
||
* @param string $table
|
||
* @param string $type
|
||
* @return array
|
||
* @throws \Exception
|
||
*/
|
||
protected function parseNameData(string $module, string $name, string $table = '', string $type = 'controller'): array
|
||
{
|
||
$array = str_replace(['.', '/', '\\'], '/', $name);
|
||
$array = array_filter(explode('/', $array));
|
||
if (substr($name, 0 - strlen('/')) != '/') {
|
||
array_pop($array);
|
||
}
|
||
|
||
$parseName = $type == 'controller' ? ucfirst(end($array)) : Str::studly($table);
|
||
if (in_array(strtolower($parseName), $this->internalKeywords)) {
|
||
throw new \Exception('类名称不能使用内置关键字' . $parseName);
|
||
}
|
||
|
||
array_pop($array);
|
||
$appNamespace = "app\\{$module}\\$type" . ($array ? "\\" . implode("\\", $array) : "");
|
||
$parseFile = root_path() . $appNamespace . DIRECTORY_SEPARATOR . $parseName . '.php';
|
||
$parseFile = str_replace('\\', '/', $parseFile);
|
||
return [$parseName, $appNamespace, $parseFile];
|
||
}
|
||
|
||
/**
|
||
* @param $table
|
||
* @return bool
|
||
*/
|
||
protected function filterSystemTable($table): bool
|
||
{
|
||
if (in_array($table, $this->protectTable)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 获取模板文件
|
||
* @param [type] $name
|
||
* @return string
|
||
*/
|
||
protected function getStubTpl($name): string
|
||
{
|
||
return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . $name . '.stub';
|
||
}
|
||
|
||
/**
|
||
* 获取代码模板
|
||
* @param [type] $name
|
||
* @return string
|
||
*/
|
||
protected function getTemplatePath($name): string
|
||
{
|
||
$this->templatePath = root_path('app/admin/view');
|
||
$array = str_replace(['.', '/', '\\'], '/', $name);
|
||
$array = array_filter(explode('/', $array));
|
||
if (substr($name, 0 - strlen('/')) != '/') {
|
||
array_pop($array);
|
||
}
|
||
|
||
foreach ($array as $value) {
|
||
$value = Str::snake($value);
|
||
$this->templatePath .= $value . DIRECTORY_SEPARATOR;
|
||
}
|
||
|
||
return $this->templatePath;
|
||
}
|
||
}
|