4 Commits

Author SHA1 Message Date
9b039b7abe 修复框架鉴权报错 2026-04-02 11:08:44 +08:00
0429cf62c4 优化CURD代码生成关联 2026-04-01 15:27:23 +08:00
effde58a53 修复CURD代码生成的关联报错 2026-04-01 14:41:41 +08:00
2bb589c4e5 修复CURD代码生成模块-生成的代码报错500 2026-04-01 14:30:18 +08:00
7 changed files with 71 additions and 11 deletions

View File

@@ -581,6 +581,13 @@ class Crud extends Backend
private function parseModelMethods($field, &$modelData): void private function parseModelMethods($field, &$modelData): void
{ {
// MySQL bigint/int 时间戳字段:显式声明为 integer避免 ThinkORM 自动时间戳写入 'now' 字符串
if (in_array($field['name'] ?? '', ['create_time', 'update_time', 'createtime', 'updatetime'], true)
&& in_array($field['type'] ?? '', ['int', 'bigint'], true)
) {
$modelData['fieldType'][$field['name']] = 'integer';
}
if (($field['designType'] ?? '') == 'array') { if (($field['designType'] ?? '') == 'array') {
$modelData['fieldType'][$field['name']] = 'json'; $modelData['fieldType'][$field['name']] = 'json';
} elseif (!in_array($field['name'], ['create_time', 'update_time', 'updatetime', 'createtime']) } elseif (!in_array($field['name'], ['create_time', 'update_time', 'updatetime', 'createtime'])

View File

@@ -3,6 +3,8 @@
namespace {%namespace%}; namespace {%namespace%};
{%use%} {%use%}
use app\common\controller\Backend; use app\common\controller\Backend;
use support\Response;
use Webman\Http\Request as WebmanRequest;
/** /**
* {%tableComment%} * {%tableComment%}

View File

@@ -3,11 +3,11 @@
* 查看 * 查看
* @throws Throwable * @throws Throwable
*/ */
public function index(): void protected function _index(): Response
{ {
// 如果是 select 则转发到 select 方法,若未重写该方法,其实还是继续执行 index // 如果是 select 则转发到 select 方法,若未重写该方法,其实还是继续执行 index
if ($this->request->param('select')) { if ($this->request && $this->request->get('select')) {
$this->select(); return $this->select($this->request);
} }
/** /**
@@ -18,13 +18,14 @@
list($where, $alias, $limit, $order) = $this->queryBuilder(); list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model $res = $this->model
->withJoin($this->withJoinTable, $this->withJoinType) ->withJoin($this->withJoinTable, $this->withJoinType)
->with($this->withJoinTable)
{%relationVisibleFields%} {%relationVisibleFields%}
->alias($alias) ->alias($alias)
->where($where) ->where($where)
->order($order) ->order($order)
->paginate($limit); ->paginate($limit);
$this->success('', [ return $this->success('', [
'list' => $res->items(), 'list' => $res->items(),
'total' => $res->total(), 'total' => $res->total(),
'remark' => get_route_remark(), 'remark' => get_route_remark(),

View File

@@ -1,6 +1,6 @@
public function initialize(): void protected function initController(WebmanRequest $request): ?Response
{ {
parent::initialize();
$this->model = new \{%modelNamespace%}\{%modelName%}();{%filterRule%} $this->model = new \{%modelNamespace%}\{%modelName%}();{%filterRule%}
return null;
} }

View File

@@ -50,6 +50,7 @@ trait Backend
$res = $this->model $res = $this->model
->field($this->indexField) ->field($this->indexField)
->withJoin($this->withJoinTable, $this->withJoinType) ->withJoin($this->withJoinTable, $this->withJoinType)
->with($this->withJoinTable)
->alias($alias) ->alias($alias)
->where($where) ->where($where)
->order($order) ->order($order)
@@ -301,7 +302,40 @@ trait Backend
/** /**
* 加载为 select(远程下拉选择框)数据,子类可覆盖 * 加载为 select(远程下拉选择框)数据,子类可覆盖
*/ */
protected function _select(): void protected function _select(): Response
{ {
if (empty($this->model)) {
return $this->success('', [
'list' => [],
'total' => 0,
]);
}
$pk = $this->model->getPk();
// 远程下拉只要求包含主键与可显示字段;这里尽量返回主键 + quickSearch 字段,避免全量字段带来性能问题
$fields = [$pk];
$quickSearchArr = is_array($this->quickSearchField) ? $this->quickSearchField : explode(',', (string) $this->quickSearchField);
foreach ($quickSearchArr as $f) {
$f = trim((string) $f);
if ($f === '') continue;
$f = str_contains($f, '.') ? substr($f, strrpos($f, '.') + 1) : $f;
if ($f !== '' && !in_array($f, $fields, true)) {
$fields[] = $f;
}
}
list($where, $alias, $limit, $order) = $this->queryBuilder();
$res = $this->model
->field($fields)
->alias($alias)
->where($where)
->order($order)
->paginate($limit);
return $this->success('', [
'list' => $res->items(),
'total' => $res->total(),
]);
} }
} }

View File

@@ -214,9 +214,8 @@ class Backend extends Api
public function select(WebmanRequest $request): Response public function select(WebmanRequest $request): Response
{ {
$response = $this->initializeBackend($request); $response = $this->initializeBackend($request);
if ($response !== null) return $response; if ($response instanceof Response) return $response;
$this->_select(); return $this->_select();
return $this->success();
} }
/** /**

View File

@@ -204,7 +204,24 @@ if (!function_exists('get_controller_path')) {
if (count($parts) < 2) { if (count($parts) < 2) {
return $parts[0] ?? null; return $parts[0] ?? null;
} }
return implode('/', array_slice($parts, 1, -1)) ?: $parts[1]; $segments = array_slice($parts, 1, -1);
if ($segments === []) {
return $parts[1] ?? null;
}
// ThinkPHP 风格段 game.Config -> game/config与 $request->controller 解析结果一致(否则权限节点对不上)
$normalized = [];
foreach ($segments as $seg) {
if (str_contains($seg, '.')) {
$dotPos = strpos($seg, '.');
$mod = substr($seg, 0, $dotPos);
$ctrl = substr($seg, $dotPos + 1);
$normalized[] = strtolower($mod);
$normalized[] = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $ctrl));
} else {
$normalized[] = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $seg));
}
}
return implode('/', $normalized);
} }
} }