Files
fdesk/app/common/traits/crud/CrudServiceTrait_bak2.php
T
2025-07-18 17:32:42 +08:00

270 lines
9.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\common\traits;
use support\Request;
/**
* CrudServiceTrait
*
* 合并了:
* - 扁平化 Request → 查询配置(where/with/order/fields/withFields/dataLimit)
* - 标准增删改查 Service 接口(serviceList/Show/Store/Update/Destroy)
* - 复杂查询入口(complexQuery)
* - 统一后置钩子(postProcess)
*
* 使用方式:
* class XxxService {
* use CrudLogicTrait, CrudServiceTrait;
* protected string $modelClass = \app\xxx\model\Xxx::class;
* }
*/
trait CrudServiceTrait_bak2
{
// use CrudLogicTrait;
// ---------------- Service 接口 ---------------- //
/**
* 列表接口
* - 支持 complex_query=1 → 调用 complexQuery()
* - 否则自动扁平化构建查询配置并分页调用 logicList()
*/
public function serviceList(Request $request)
{
if ($request->get('complex_query') && method_exists($this, 'complexQuery')) {
$data = $this->complexQuery($request->get());
} else {
$cfg = $this->buildQueryConfig($request, 'list');
$limit = (int)$request->get('limit', 15);
$page = (int)$request->get('page', 1);
$data = $this->logicList($cfg, $limit, $page);
}
return $this->postProcess('List', $data);
}
/** 查看单条 */
public function serviceShow(Request $request, $id)
{
$item = $this->logicShow($id, []);
return $this->postProcess('Show', $item);
}
/** 创建 */
public function serviceStore(Request $request)
{
$data = $request->post();
$dl = $this->getDataLimitFromRequest($request);
$item = $this->logicCreate($data, $dl);
return $this->postProcess('Store', $item);
}
/** 更新 */
public function serviceUpdate(Request $request)
{
$key = (new $this->modelClass)->getKeyName();
$id = (int)$request->post($key);
$data = $request->post();
$dl = $this->getDataLimitFromRequest($request);
$item = $this->logicUpdateByPk($id, $data, $dl);
return $this->postProcess('Update', $item);
}
/** 删除 */
public function serviceDestroy(Request $request)
{
$key = (new $this->modelClass)->getKeyName();
$ids = (array)$request->post($key, []);
$result = $this->logicDeleteByPk($ids);
return $this->postProcess('Destroy', $result);
}
// ---------------- 统一后置钩子 ---------------- //
/**
* 各操作后触发 afterService{Op}()
* @param string $op List|Show|Store|Update|Destroy
*/
protected function postProcess(string $op, mixed $data): mixed
{
$hook = "afterService{$op}";
return method_exists($this, $hook)
? $this->{$hook}($data)
: $data;
}
// ---------------- 复杂查询入口 ---------------- //
/**
* 子类 override 实现完全定制的复杂查询
* @param array $params 全部请求参数
*/
protected function complexQuery(array $params)
{
throw new \LogicException('请在子类实现 complexQuery()');
}
// ------------- 辅助:数据权限 & withFields 解析 ------------- //
/** 从请求读取 dataLimitType & dataLimitField → ['type'=>..,'field'=>..] */
protected function getDataLimitFromRequest(Request $req): array
{
$type = $req->get('dataLimitType');
if (!$type) {
return [];
}
return [
'type' => $type,
'field' => $req->get('dataLimitField', 'admin_id'),
];
}
/** 解析 withFields 字符串 "rel:field,field;rel2:..." */
protected function parseWithFields(string $str): array
{
if (!$str) {
return [];
}
$out = [];
foreach (explode(';', $str) as $pair) {
[$rel, $flds] = explode(':', $pair);
$out[$rel] = explode(',', $flds);
}
return $out;
}
// ------------- 扁平化 Request → 查询配置 ------------- //
/**
* 构建完整配置
* 返回 [
* where=>[], with=>[], order=>[], withFields=>?, fields=>?, dataLimit=>[]
* ]
*/
protected function buildQueryConfig(Request $request, string $scene = 'list'): array
{
return [
'where' => $this->buildFilters($request, $scene),
'with' => $this->buildRelations($request, $scene),
'order' => $this->buildOrder($request, $scene),
'withFields' => $this->buildWithFields($request,$scene),
'fields' => $this->buildFields($request, $scene),
'dataLimit' => $this->buildDataLimit($request, $scene),
];
}
/**
* 通用合并方法:取公共配置 + 场景专属配置,若均为 array 则 array_merge
*
* @param mixed $common 公共配置
* @param Request $request
* @param string $scene
* @param string $type Filters|Relations|Order|WithFields|Fields|DataLimit
*/
private function applySceneConfig(
mixed $common,
Request $request,
string $scene,
string $type
): mixed {
$method = 'apply' . ucfirst($scene) . $type;
if (! method_exists($this, $method)) {
return $common;
}
$sceneCfg = $this->{$method}($common, $request);
if (is_array($common) && is_array($sceneCfg)) {
return array_merge($common, $sceneCfg);
}
return $sceneCfg;
}
/** 构建 WHERE:commonFilters + apply{Scene}Filters */
protected function buildFilters(Request $r, string $scene): array
{
$common = $this->commonFilters($r);
return (array)$this->applySceneConfig($common, $r, $scene, 'Filters');
}
/** 构建 with 关联 */
protected function buildRelations(Request $r, string $scene): array
{
$common = $this->commonRelations();
return (array)$this->applySceneConfig($common, $r, $scene, 'Relations');
}
/** 构建 order 排序 */
protected function buildOrder(Request $r, string $scene): array
{
$common = $this->commonOrder();
return (array)$this->applySceneConfig($common, $r, $scene, 'Order');
}
/** 构建 withFields(关联模型字段白名单) */
protected function buildWithFields(Request $r, string $scene): ?array
{
$common = [];
return $this->applySceneConfig($common, $r, $scene, 'WithFields');
}
/** 构建 fields(主表字段白名单) */
protected function buildFields(Request $r, string $scene): ?array
{
$common = [];
return $this->applySceneConfig($common, $r, $scene, 'Fields');
}
/** 构建 dataLimit(数据权限) */
protected function buildDataLimit(Request $r, string $scene): array
{
$common = [];
return (array)$this->applySceneConfig($common, $r, $scene, 'DataLimit');
}
// ------------- 可重写的“公共 + 场景” 方法 ------------- //
// --- common* 系列(全局默认) ---
protected function commonFilters(Request $r): array { return []; }
protected function commonRelations(): array { return []; }
protected function commonOrder(): array { return []; }
// // --- list* 系列 ---
// protected function applyListFilters(array $c, Request $r): array { return $this->listFilters($r); }
// protected function listFilters(Request $r): array { return []; }
// protected function applyListRelations(array $c, Request $r): array { return $this->listRelations(); }
// protected function listRelations(): array { return []; }
// protected function applyListOrder(array $c, Request $r): array { return $this->listOrder($r); }
// protected function listOrder(Request $r): array { return ['created_at'=>'desc']; }
// protected function applyListWithFields(array $c, Request $r): array{ return $this->listWithFields($r); }
// protected function listWithFields(Request $r): array { return []; }
// protected function applyListFields(array $c, Request $r): array { return $this->listFields($r); }
// protected function listFields(Request $r): array { return []; }
// protected function applyListDataLimit(array $c, Request $r): array { return $this->listDataLimit($r); }
// protected function listDataLimit(Request $r): array { return []; }
// // --- detail* 系列 ---
// protected function applyDetailFilters(array $c, Request $r): array { return $this->detailFilters($r); }
// protected function detailFilters(Request $r): array { return ['id'=>$r->get('id')]; }
// protected function applyDetailRelations(array $c, Request $r): array { return $this->detailRelations(); }
// protected function detailRelations(): array { return []; }
// protected function applyDetailOrder(array $c, Request $r): array { return $this->detailOrder($r); }
// protected function detailOrder(Request $r): array { return []; }
// protected function applyDetailWithFields(array $c, Request $r): array{ return $this->detailWithFields($r); }
// protected function detailWithFields(Request $r): array { return []; }
// protected function applyDetailFields(array $c, Request $r): array { return $this->detailFields($r); }
// protected function detailFields(Request $r): array { return []; }
// protected function applyDetailDataLimit(array $c, Request $r): array { return $this->listDataLimit($r); }
// // --- export* 系列(如有需要可 override) ---
// protected function applyExportFilters(array $c, Request $r): array { return $this->exportFilters($r); }
// protected function exportFilters(Request $r): array { return []; }
}