自定义命令篇
提示
本篇主要是将laravel-fast-api-youhujun 的自定义命令进行说明,从而提高开发效率
视频演示
DTO
提示
名称可是看做是模型名
单条DTO创建
php artisan make:dto 模块/版本号/业务路径/名称 --type=类型type类型 (get|add|update|delete|mul_delete|disable|mul_disable|move|default|find)
示例:
php artisan make:dto Text\V1\Admin\SuperText\AddSuperTextDTO --type=add执行完以后会创建
App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO.php
批量
php artisan call:dto 模块/版本号/业务路径/名称会自动生成get|add|update|delete|mul_delete|disable|mul_disable|move|default|find 对应的DTO
示例:
php artisan call:dto Text\V1\Admin\SuperText\SuperTextDTO执行后会创建
use App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MoveSuperTextDTO;
Controller-控制器
后端控制器
php artisan make:admin-controller 模块/版本号/业务路径/名称前端控制器
提示
调试完记得删除p('***');die;
php artisan make:phone-controller 模块/版本号/业务路径/名称示例:
php artisan make:admin-controller Text\V1\Admin\SuperText\SuperTextController执行后会创建
app\Http\Controllers\Text\V1\Admin\SuperText\SuperTextController.php
Facade和FacadeService
type (admin-list|admin-tree|phone-list)
提示
admin-list-对应后端列表(通用)
admin-tree-对应后端树形结构
phone-list-对应前端列表(通用)
Facade-门面代理
php artisan make:facade 模块/版本号/业务路径/名称 --type=类型示例:
php artisan make:facade Text\V1\Admin\SuperText\AdminSuperTextFacade --type=admin-list执行后创建
app\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade.php
FacadeService-门面服务
php artisan make:facade-service 模块/版本号/业务路径/名称 --type=类型示例:
php artisan make:facade-service Text\V1\Admin\SuperText\AdminSuperTextFacadeService --type=admin-list执行后创建
app\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService.php
同时生成门面代理和门面服务
php artisan call:facade 模块/版本号/业务路径/名称 --type=类型示例:
php artisan call:facade Text\V1\Admin\SuperText\AdminSuperTextFacade --type=admin-list执行后同时创建
app\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade.php
app\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService.php
Resource
php artisan call:resource 模块/版本号/业务路径/名称示例
php artisan call:resource Text\V1\Es\Admin\SuperText\EsSuperTextResource执行后同时创建
app\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextResource.php
app\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextCollection.php
Api
提示
以下参数都是可选参数
type (admin-list|admin-tree|phone-list)
dto (true|false) 是否创建DTO
resource (true|false) 是否创建resource
model 模型名称
警告
如果不传model参数,则会自动根据模块/版本号/业务路径/名称里面的名称作为模型名称
php artisan call:api 模块/版本号/业务路径/名称 --type=类型 --dto=是否创建DTO --resource=是否创建resource --model=模型名称示例:
php artisan call:api Text\V1\Admin\SuperText --type=admin-list --dto=true --resource=true --model=SuperText或者
php artisan call:api Text\V1\Admin\SuperText --type=admin-list --dto=true --resource=true执行后会同时创建
dto
use App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MoveSuperTextDTO;
controller
app\Http\Controllers\Text\V1\Admin\SuperText\SuperTextController;
facade和facade-service
app\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade;
app\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService;
resource
app\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextResource;
app\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextCollection;
示例代码如下:
DTO
仅以 AddSuperTextDTO 为例
App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO.php
<?php
namespace App\DTOs\Text\V1\Admin\SuperText;
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
use YouHuJun\Tool\App\Facades\V1\Utils\Secret\AESFacade;
use App\Facades\Common\V1\Es\EsQueryFacade;
use App\DTOs\Traits\BaseDTOTrait;
use Illuminate\Support\Facades\Validator;
use App\Exceptions\Common\RuleException;
use App\Rules\Pub\Required;
use App\Rules\Pub\Numeric;
use App\Rules\Pub\CheckUnique;
use App\Rules\Pub\CheckString;
use App\Rules\Pub\CheckBetween;
use App\Rules\Pub\CheckArray;
use App\Rules\Pub\FormatTime;
use App\Rules\Pub\ChineseCodeNumberLine;
/**
* @see \App\Http\Controllers\Text\V1\Admin\SuperText\SuperTextController
*/
#[DocNote('DTO')]
class AddSuperTextDTO
{
use BaseDTOTrait;
#[DocNote('雪花id')]
public ?int $replace_uid = 0;
#[DocNote('原始手机号')]
public string $phone = '';
#[DocNote('AES加密手机号')]
public ?string $phone_cipher = '';
#[DocNote('HASH加密手机号')]
public ?string $phone_hash = '';
#[DocNote('脱敏手机号')]
public ?string $phone_mask = '';
#[DocNote('名称')]
public ?string $name = '';
#[DocNote('编码')]
public ?string $code = '';
#[DocNote('类型')]
public ?int $type = 10;
#[DocNote('备注')]
public ?string $note = '';
#[DocNote('排序')]
public ?int $sort = 100;
#[DocNote('地区分类级联')]
public array $region_cascader_array = [];
#[DocNote('地区分类级联级联json')]
public ?string $region_cascader_json = null;
#[DocParams('字段映射,核心约定必须实现')]
public function getFieldMap(): array
{
return ['replace_uid','phone', 'name', 'code', 'type','note','sort','region_cascader_array'];
}
#[DocParams('校验规则')]
public function rules(): array
{
$esIndexName = config('common_es.indices.replace');
return [
'replace_uid' => ['bail', new Required(), new Numeric()],
//'phone' => ['bail', new Required(), new CheckString(), new Phone(), new CheckUnique($esIndexName, 'phone')],
//'name' => ['bail', new Required(), new CheckString(), new CheckUnique($esIndexName, 'name')],
//'code' => ['bail', 'nullable', new CheckString(), new CheckUnique($esIndexName, 'code')],
'type' => ['bail', 'nullable', new Numeric()],
'note' => ['bail', 'nullable', new CheckString()],
'sort' => ['bail', 'nullable', new Numeric()],
'region_cascader_array' => ['bail', new Required(), new CheckArray()],
];
}
#[DocParams('验证字段')]
public function validate(array $data): self
{
$validator = Validator::make($data, $this->rules(), []);
$validated = $validator->validated();
$requiredFields = ['replace_uid', 'name','type', 'region_cascader_array'];
foreach ($requiredFields as $field) {
if (!isset($validated[$field])) {
throw new RuleException('RuleRequiredError', $field);
}
}
$this->fill($validated);
$this->formatFields();
return $this;
}
#[DocParams('格式化|过滤|处理字段')]
public function formatFields(): self
{
foreach ($this->getFieldMap() as $field) {
$this->$field = f($this->$field);
}
if(!empty($this->region_cascader_array)){
$this->region_cascader_json = json_encode($this->region_cascader_array);
}
$aesKey = config('common.aes.key');
if($this->phone){
$this->phone_cipher = AESFacade::encrypt($this->phone, $aesKey);
$this->phone_hash = make_hash_pass($this->phone);
$this->phone_mask = mask_string($this->phone, 3, 4);
}
return $this;
}
}Controller
app\Http\Controllers\Text\V1\Admin\SuperText\SuperTextController.php
<?php
namespace App\Http\Controllers\Text\V1\Admin\SuperText;
//Laravel
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
//DTO
use App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MoveSuperTextDTO;
//Facade
use App\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade;
/**
* @see \App\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService
*/
#[DocNote('控制器')]
class SuperTextController extends Controller
{
#[DocParams('获取替换列表',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function getSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new GetSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::getSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('添加替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function addSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new AddSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::addSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('修改替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function updateSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new UpdateSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::updateSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('删除替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function deleteSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new DeleteSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::deleteSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('批量删除替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function multipleDeleteSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new MultipleDeleteSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::multipleDeleteSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('禁用替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function disableSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new DisableSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::disableSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('批量禁用替换',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function multipleDisableSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new MultipleDisableSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::multipleDisableSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('获取默认选项',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function defaultSuperText(Request $request)
{
$result = code(\config('admin_code.AdminAuthError'));
$adminObject = Auth::guard('admin_token')->user();
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new DefaultSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::defaultSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('查找选项',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function findSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new FindSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::findSuperText($requestDTO, $adminObject);
}
return $result;
}
#[DocParams('树形移动',['request'=>['type'=>'\Illuminate\Http\Request','note'=>'请求对象'],'return'=>['type'=>'array','note'=>'返回数据']])]
public function moveSuperText(Request $request)
{
$adminObject = Auth::guard('admin_token')->user();
$result = code(\config('admin_code.AdminAuthError'));
if (Gate::forUser($adminObject)->allows('admin-role')) {
$requestDTO = (new MoveSuperTextDTO())->validate($request->all());
p($requestDTO);
die;
$result = AdminSuperTextFacade::moveSuperText($requestDTO, $adminObject);
}
return $result;
}
}Facade和FacadeService
app\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade.php
<?php
namespace App\Facades\Text\V1\Admin\SuperText;
use Illuminate\Support\Facades\Facade;
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
//DTO
use App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO;
//模型
use App\Models\LaravelFastApi\V1\Admin\Admin;
/**
* @see \App\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService
*/
#[DocNote('门面代理')]
class AdminSuperTextFacade extends Facade
{
#[DocParams('静态代理方法', ['return' => ['type' => 'string', 'note' => '绑定门面服务的类名']])]
protected static function getFacadeAccessor()
{
return "AdminSuperTextFacade";
}
#[DocParams('测试方法', ['return' => ['type' => 'mixed', 'note' => '测试方法']])]
public static function test():mixed
{
return static::getFacadeRoot()->test();
}
#[DocParams('获取列表', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function getSuperText(GetSuperTextDTO $requestDTO, ?Admin $adminObject)
{
return static::getFacadeRoot()->getSuperText($requestDTO, $adminObject);
}
#[DocParams('添加', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function addSuperText(AddSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->addSuperText($requestDTO, $adminObject);
}
#[DocParams('关联批量添加', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function bindSuperText(AddSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->bindSuperText($requestDTO, $adminObject);
}
#[DocParams('更新', ['requestDTO' => ['type' => ' App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function updateSuperText(UpdateSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->updateSuperText($requestDTO, $adminObject);
}
#[DocParams('删除', ['requestDTO' => ['type' => ' App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function deleteSuperText(DeleteSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->deleteSuperText($requestDTO, $adminObject);
}
#[DocParams('批量删除', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function multipleDeleteSuperText(MultipleDeleteSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->multipleDeleteSuperText($requestDTO, $adminObject);
}
#[DocParams('禁用', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function disableSuperText(DisableSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->disableSuperText($requestDTO, $adminObject);
}
#[DocParams('批量禁用', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function multipleDisableSuperText(MultipleDisableSuperTextDTO $requestDTO, Admin $adminObject)
{
return static::getFacadeRoot()->multipleDisableSuperText($requestDTO, $adminObject);
}
#[DocParams('获取默认选项配合前端', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function defaultSuperText(DefaultSuperTextDTO $requestDTO, ?Admin $adminObject)
{
return static::getFacadeRoot()->defaultSuperText($requestDTO, $adminObject);
}
#[DocParams('获取默认选项配合前端', ['requestDTO' => ['type' => '\ App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public static function findSuperText(FindSuperTextDTO $requestDTO, ?Admin $adminObject)
{
return static::getFacadeRoot()->findSuperText($requestDTO, $adminObject);
}
}app\Services\Facade\Text\V1\Admin\SuperText\AdminSuperTextFacadeService.php
<?php
namespace App\Services\Facade\Text\V1\Admin\SuperText;
//laravel
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
//注解
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
use App\Facades\Common\V1\Es\EsQueryFacade;
use App\Facades\Common\V1\Shard\ShardHelperFacade;
use YouHuJun\Tool\App\Facades\V1\Utils\Shard\ShardFacade;
use YouHuJun\Tool\App\Facades\V1\Es\EsFacade;
use App\Services\Facade\Traits\V1\Es\EsAlwaysService;
use App\Exceptions\Admin\CommonException;
use App\Events\Admin\CommonEvent;
//DTO
use App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO;
use App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO;
use App\DTOs\Contracts\V1\Text\V1\Admin\SuperText\DOSuperTextHandleContractDTO;
//模型
use App\Models\LaravelFastApi\V1\Text\V1\Admin\SuperText;
use App\Models\LaravelFastApi\V1\Admin\Admin;
//resource
use App\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextResource;
use App\Http\Resources\Text\V1\Es\Admin\SuperText\EsSuperTextCollection;
//契约
use App\Contracts\V1\Text\V1\Admin\SuperText\DoSuperTextHandlerContract;
//队列 示例中没有队列,特殊情况需要异步处理的使用Job队列
/**
* @see \App\Http\Controllers\Text\V1\Admin\SuperText\SuperTextController
* @see \App\Facades\Text\V1\Admin\SuperText\AdminSuperTextFacade
*/
#[DocNote('门面服务')]
class AdminSuperTextFacadeService
{
use EsAlwaysService;
#[DocParams('测试方法')]
public function test()
{
echo "AdminSuperTextFacadeService test";
}
#[DocNote('excel表格导入导出使用')]
protected static string $storage_public_path = DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR;
#[DocNote('es最大查询数量')]
protected const ES_MAX_RESULT = 'common_es.max_result_window';
#[DocNote('替换ES索引')]
protected const ES_REPLACE_INDEX = 'common_es.indices.replce';
#[DocNote('ES关联索引')]
protected const ES_UNION_INDEX = 'common_es.indices.union';
#[DocNote('排序映射')]
protected static array $sortMapArray = [
'1' => ['created_time', 'asc'],
'2' => ['created_time', 'desc'],
];
#[DocNote('搜索映射')]
protected static array $searchItemMapArray = [
'phone',
];
#[DocParams('excel批量导入数据', ['path' => ['type' => 'string', 'note' => '文件路径'], 'return' => ['type' => 'void']])]
public function importData(string $path): bool
{
$result = 0;
$exists = Storage::disk('public')->exists($path);
if ($exists) {
ExcelFacade::initReadExcel(storage_path(self::$storage_public_path . $path));
ExcelFacade::setWorkSheet(0);
$excelData = ExcelFacade::getDataByRow();
array_shift($excelData);
$insertDataArray = [];
foreach ($excelData as $value) {
$insertDataArray[] =
[
'superText_name' => $value[0],
'superText_code' => empty($value[1]) ? null : $value[1],
'is_default' => empty($value[2]) ? 0 : $value[2],
'sort' => empty($value[3]) ? 100 : $value[3]
];
}
DB::beginTransaction();
$maxBefore = Replce::max('id');
$result = Replce::insert($insertDataArray);
$maxAfter = Replce::max('id');
// 区间 ID 就是这批插入的数据
$id_array = range($maxBefore + 1, $maxAfter);
if (!$result) {
plog(['error' => '替换导入数据失败', '$result' => $result, '$insertDataArray' => $insertDataArray, '$path' => $path], 'AdminSuperTextFacadeService', 'importDataError');
DB::rollBack();
}
$superTextCollection = Replce::whereIn('id', $id_array)->get();
$indexName = config(self::ES_REPLACE_INDEX);
$insertDataArray = [];
foreach ($superTextCollection as $superTextObject) {
$insertDataArray[] = [
'_docId' => $superTextObject->id,
'id' => $superTextObject->id,
'superText_name' => $superTextObject->superText_name,
'superText_code' => $superTextObject->superText_code,
'is_default' => $superTextObject->is_default,
'sort' => $superTextObject->sort,
'created_time' => $superTextObject->created_time,
'updated_time' => $superTextObject->updated_time,
'created_at' => $superTextObject->created_at,
'updated_at' => $superTextObject->updated_at,
'deleted_at' => $superTextObject->deleted_at,
];
}
$esResult = EsFacade::batchActDoc($indexName, $insertDataArray);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
$result = 0;
plog(['error' => 'es批量添加替换配置失败', '$esResult' => $esResult, '$insertDataArray' => $insertDataArray, '$path' => $path], 'AdminSuperTextFacadeService', 'importData');
DB::rollBack();
}
DB::commit();
}
return $result;
}
#[DocParams('excel批量导出数据', ['superTextList' => ['type' => 'array', 'note' => '导出数据,二维数组'], 'return' => ['type' => 'string', 'note' => '导出excel表标题']])]
protected function exportData(array $superTextListCollection)
{
$cloumn = [['账号', '手机号', '昵称', '姓名', '身份证号', '性别', '生日', '说明', '注册时间']];
$dataArray = [];
foreach ($superTextListCollection as $superTextObject) {
$listArray = [];
$listArray[] = $superTextObject?->account_name??'';
$listArray[] = $superTextObject?->phone_mask??'';
$listArray[] = $superTextObject?->nick_name??'';
$listArray[] = $superTextObject?->real_name??'';
$listArray[] = $superTextObject?->id_number_mask??'';
if (isset($superTextObject?->sex)) {
$listArray[] = $superTextObject?->sex == 1 ? '男' : '女';
} else {
$listArray[] = '未知';
}
$listArray[] = $superTextObject?->solar_birthday_at??'';
$listArray[] = $superTextObject?->introduction??'';
$listArray[] = $superTextObject?->created_at??'';
$dataArray[] = $listArray;
}
$title = "替换表" . date('YmdHis');
$path = self::$storage_public_path . "SuperText";
$savePath = storage_path($path);
ExcelFacade::exportExcelData($cloumn, $dataArray, $title, $savePath);
return $title;
}
#[DocParams('获取列表', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\GetSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function getSuperText(GetSuperTextDTO $requestDTO, ?Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'获取失败','error'=>'GetSuperTextError'];
$perPage = $requestDTO->pageSize;
$currentPage = $requestDTO->currentPage;
$max_size = config(self::ES_MAX_RESULT);
$esIndexName = config(self::ES_REPLACE_INDEX);
// 1. 初始化ES查询构造器
$esQuery = EsQueryFacade::index($esIndexName);
// 默认全局查询未删除
$esQuery->whereNull('deleted_at');
// 模糊搜索(手机号/姓名等)
if (isset($requestDTO->findSelectIndex) && isset($requestDTO->find) && !empty($requestDTO->find)) {
$findIndex = $requestDTO->findSelectIndex;
$findValue = $requestDTO->find;
$searchField = self::$searchItemMapArray[$findIndex] ?? '';
// 配置common.pass_convert_check_array:存放需要【加盐哈希精准检索】的敏感字段
$pass_convert_check_array = config('common.pass_convert_check_array');
if (in_array($searchField, $pass_convert_check_array)) {
$findValueHash = make_hash_pass($findValue);
$esQuery->where($searchField.'_hash', $findValueHash);
}else{
$esQuery->whereLike($searchField, $findValue);
}
}
// 时间范围
if (isset($requestDTO->timeRange) && \count($requestDTO->timeRange)) {
$startTime = strtotime($requestDTO->timeRange[0]);
$endTime = strtotime($requestDTO->timeRange[1]);
$esQuery->whereBetween('created_time', [$startTime, $endTime]);
}
//排序
if (isset($requestDTO->sortType)) {
$sortType = $requestDTO->sortType;
$esQuery->orderBy(self::$sortMapArray[$sortType][0], self::$sortMapArray[$sortType][1]);
}
// 导出逻辑(完全按你的真实业务)
$download = null;
if (isset($requestDTO->isExport) && $requestDTO->isExport == 1) {
if ($requestDTO->exportType) {
$title = '';
// 本页导出
if ($requestDTO->exportType == 1) {
// 直接用已配置的 esQuery get()
$exportColelction = $esQuery->page($currentPage, $perPage)->get();
$title = $this->exportData($exportColelction); // 直接下载,中断,不回头
}
$maxExportAll = 50000;
$totalCount = $esQuery->count(false);
// 全部导出
if ($requestDTO->exportType == 2) {
if ($totalCount > $maxExportAll) {
return ['code' => 10000, 'msg' => "数据超过{$maxExportAll}条,请缩小筛选条件再导出"];
}
// 不带分页,get() 自动用 10000 兜底
$exportColelction = $esQuery->get();
$title = $this->exportData($exportColelction); // 直接下载,中断
}
$exists = Storage::disk('public')->exists("excel/{$title}.xlsx");
if ($exists) {
$download = asset("storage/excel/{$title}.xlsx");
}
if ($download) {
$result = ['code' => 0, 'msg' => '获取替换列表成功!', 'download' => $download];
} else {
$result = ['code' => 10000, 'msg' => '获取替换列表失败!'];
}
return $result;
}
}
// 执行分页查询(返回Laravel标准分页对象)
$paginator = $esQuery->page($currentPage, $perPage)->paginate();
//处理关联数据
$collection = collect($paginator->items());
$esUnionCollection = $this->getUnionCollection($collection);
$orginCollection = $this->getOriginUnionCollection($collection);
$relateMapCollection = collect(['union'=>$esUnionCollection,'origin'=>$orginCollection]);
//p($paginator);
$result = new EsSuperTextCollection($paginator, ['code' => 0, 'msg' => '获取列表成功!'], $relateMapCollection, $download);
return $result;
}
#[DocParams('添加', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function addSuperText(AddSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'添加失败','error'=>'AddSuperTextError'];
DB::beginTransaction();
$esIndexName = config(self::ES_REPLACE_INDEX);
// 分片业务UID 根据分库分表自行调整
$bussiness_uid = 0;
$superText_uid = get_snow_flake_id();
$insertDataArray = [];
foreach ($requestDTO as $key => $value) {
if (isset($value)) {
$insertDataArray[$key] = $value;
}
}
$insertDataArray['superText_uid'] = $superText_uid;
$insertDataArray['bussiness_uid'] = $bussiness_uid;
$superTextObject = ShardHelperFacade::createWithShard(SuperText::class, $bussiness_uid, $insertDataArray);
if (!isset($superTextObject->biz_id)) {
throw new CommonException(['code'=>10000,'msg'=>'添加失败','error'=>'AddSuperTextError']);
}
//es处理 复杂业务放置到Event中处理
$esHas = es_check_data_exist($esIndexName,'superText_uid',$superText_uid);
if(!$esHas){
$configKey = get_shard_config_key();
$esInsertDataArray = [];
foreach ($superTextObject->toArray() as $key => $value) {
$esInsertDataArray[$key] = $value;
}
$configKey = get_shard_config_key();
$esInsertDataArray['_docId'] = $superTextObject->biz_id;
$esInsertDataArray['shard_key'] = $superTextObject->shard_key;
$esInsertDataArray['shard_db'] = ShardFacade::getDbName($superTextObject->biz_id, $configKey);
$esInsertDataArray['shard_table'] = ShardFacade::getTableName($superTextObject->biz_id, 'superText', $configKey);
$esResult = EsFacade::createDoc($esIndexName, $esInsertDataArray, $superTextObject->biz_id);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
plog(['error' => 'es添加失败', '$esResult' => $esResult, '$esInsertDataArray' => $esInsertDataArray, '$adminObject' => $adminObject, '$superTextObject' => $superTextObject], 'AdminSuperTextFacadeService', 'addSuperTextError');
throw new CommonException(['code'=>10000,'msg'=>'es添加失败','error'=>'EsAddSuperTextError']);
}
}
//契约插件
$businessDTO = new DOSuperTextHandleContractDTO();
$businessDTO->$superTextObject = $superTextObject;
$businessDTO->adminObject = $adminObject;
app(DoSuperTextHandlerContract::class)->handle($businessDTO);
CommonEvent::dispatch($adminObject, $requestDTO, ['code'=>10000,'info'=>'添加','event'=>'AddSuperText']);
DB::commit();
$result = code(['code' => 0, 'msg' => '添加成功!']);
return $result;
}
#[DocParams('关联批量添加', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\AddSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function bindSuperText(AddSuperTextDTO $requestDTO, Admin $adminObject)
{
//这行情况一般跟树形系统配置关联
$result = ['code'=>10000,'msg'=>'关联失败','error'=>'BindSuperTextError'];
$esIndexName = config(self::ES_REPLACE_INDEX);
$system_config_id = $requestDTO->system_config_id??0;
$business_uid = $requestDTO->business_uid??0;
// $this->init(new SuperText,$esIndexName);
$systemConfigIdArray = [];
$systemConfigDataArray = $this->getAllChildren($system_config_id);
$systemConfigIdArray = $systemConfigDataArray['idDataArray'];
//补上当前产品分类
array_unshift($systemConfigIdArray, $system_config_id);
$insertData = [];
$system_business_uid = get_system_shop_uid();
foreach ($systemConfigIdArray as $key => $systemConfigId) {
$insertData[$key] = [
'superText_uid' => get_snow_flake_id(),
'system_config_id' => $systemConfigId,
'bussiness_reuqest_uid' => $business_uid,
'bussiness_uid' => $system_business_uid,
'is_default' => 1,
'sort' => 100,
'created_time' => time(),
'created_at' => get_now_date_time(),
'updated_at' => null,
'updated_time' => 0,
'deleted_at' => null
];
}
$bindResult = ShardHelperFacade::insertBatchWithShard(SuperText::class, $insertData, 'bussiness_uid');
if (!$bindResult) {
throw new CommonException(['code'=>10000,'msg'=>'绑定失败','error'=>'BindSuperTextError']);
}
$esUnionsIndexName = config(self::ES_REPLACE_INDEX);
$esBatchDataArray = [];
$configKey = get_shard_config_key();
foreach ($insertData as $key => $insertDataItem) {
$esBatchDataArray[$key] = [
'_docId' => $insertDataItem['superText_uid'],
'shard_key' => ShardFacade::getShardKey($insertDataItem['bussiness_uid'], $configKey),
'shard_db' => ShardFacade::getDbName($insertDataItem['bussiness_uid'], $configKey),
'shard_table' => ShardFacade::getTableName($insertDataItem['bussiness_uid'], 'superText', $configKey),
'superText_uid' => $insertDataItem['superText_uid'],
'system_config_id' => $insertDataItem['system_config_id'],
'bussiness_reuqest_uid' => $insertDataItem['bussiness_reuqest_uid'],
'bussiness_uid' => $insertDataItem['bussiness_uid'],
'is_default' => $insertDataItem['is_default'],
'sort' => $insertDataItem['sort'],
'created_at' => $insertDataItem['created_at'],
'created_time' => $insertDataItem['created_time'],
'updated_at' => null,
'updated_time' => 0,
'deleted_at' => null
];
}
$esResult = EsFacade::batchActDoc($esUnionsIndexName, $esBatchDataArray);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
plog(['error' => 'es批量分类关联失败', '$esResult' => $esResult, '$esBatchDataArray' => $esBatchDataArray, '$adminObject' => $adminObject], 'AdminSuperTextFacadeService', 'bindSuperTextError');
throw new CommonException(['code'=>10000,'msg'=>'es绑定失败','error'=>'EsBindSuperTextError']);
}
CommonEvent::dispatch($adminObject, $requestDTO, ['code'=>10000,'info'=>'es绑定','event'=>'BindSuperText']);
$result = code(['code' => 0, 'msg' => '绑定成功']);
return $result;
}
#[DocParams('更新', ['requestDTO' => ['type' => 'App\DTOs\Text\V1\Admin\SuperText\UpdateSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function updateSuperText(UpdateSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'更新失败','error'=>'UpdateSuperTextError'];
$esIndexName = config(self::ES_REPLACE_INDEX);
$superText_uid = $requestDTO->superText_uid;
//先从es查询
$esSuperTextObject = EsQueryFacade::index($esIndexName)->whereNull('deleted_at')->where('superText_uid', $superText_uid)->get()->first();
//降级熔断
if (!isset($esSuperTextObject->superText_uid)) {
throw new CommonException(['code'=>10000,'msg'=>'es数据不存在','error'=>'EsServiceBusyError']);
}
$superTextObject = SuperText::queryByShard($esSuperTextObject->business_uid)->where('superText_uid', $superText_uid)->first();
if (!isset($superTextObject->biz_id)) {
throw new CommonException(['code'=>10000,'msg'=>'数据不存在','error'=>'ThisDataNotExistsError']);
}
$updateDataArray = [];
foreach ($requestDTO as $key => $value) {
$updateDataArray[$key] = $value;
}
$updateDataArray['updated_at'] = get_now_date_time();
$updateDataArray['updated_time'] = time();
$updateResult = $superTextObject->updateWithShard($updateDataArray);
if (!$updateResult) {
throw new CommonException(['code'=>10000,'msg'=>'更新失败','error'=>'UpdateSuperTextError']);
}
$superTextObject = $superTextObject->fresh();
//es同步 复杂业务放置到Event中处理
$esResult = EsFacade::updateDoc($esIndexName, $superTextObject->biz_id, $updateDataArray);
if (!isset($esResult['code']) || $esResult['code'] != 0) {
plog(['info' => 'EsUpdateSuperTextError', '$esResult' => $esResult], 'AdminSuperTextFacadeService', 'updateSuperText');
throw new CommonException(['code'=>10000,'msg'=>'es更新失败','error'=>'EsUpdateSuperTextError']);
}
CommonEvent::dispatch($adminObject, $requestDTO, ['code'=>10000,'info'=>'更新','event'=>'UpdateSuperText']);
$result = code(['code' => 0, 'msg' => '更新成功!']);
return $result;
}
#[DocParams('删除', ['requestDTO' => ['type' => 'App\DTOs\Text\V1\Admin\SuperText\DeleteSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function deleteSuperText(DeleteSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'删除失败','error'=>'DeleteSuperTextError'];
$esIndexName = config(self::ES_REPLACE_INDEX);
$superText_uid = $requestDTO->superText_uid;
//系统级数据不可以删除
$max_size = config(self::ES_MAX_RESULT);
$systemSuperTextUidArray = EsQueryFacade::index($esIndexName)->limit($max_size)->whereIn('field', ['value'])->get()->pluck('superText_uid')->toArray();
//检测
$checkResult = in_array($superText_uid, $systemSuperTextUidArray);
if ($checkResult) {
throw new CommonException(['code'=>10000,'msg'=>'系统数据不可以删除','error'=>'DeleteSystemSuperTextError']);
}
$esSuperTextObject = EsQueryFacade::index($esIndexName)->where('superText_uid', $superText_uid)->get()->first();
//降级熔断
if (!isset($esSuperTextObject->superText_uid)) {
throw new CommonException(['code'=>10000,'msg'=>'es数据不存在','error'=>'ServiceBusyError']);
}
$superTextObject = SuperText::queryByShard($esSuperTextObject->business_uid)->where('superText_uid', $superText_uid)->first();
if (!$superTextObject) {
throw new CommonException(['code'=>10000,'msg'=>'数据不存在','error'=>'ThisDataNotExistsError']);
}
$updateDataArray = ['deleted_at' => get_now_date_time()];
$superTextUpdateResult = $superTextObject->updateWithShard($updateDataArray);
if (!$superTextUpdateResult) {
throw new CommonException(['code'=>10000,'msg'=>'删除失败','error'=>'DeleteSuperTextError']);
}
$superTextObject = $superTextObject->fresh();
//es处理 复杂业务放置到Event中处理
$updateDataArray = [
'deleted_at' => \get_now_date_time(),
'updated_time' => $superTextObject->updated_time,
'updated_at' => $superTextObject->updated_at,
];
$esResult = EsFacade::updateDoc($esIndexName, $superTextObject->biz_id, $updateDataArray);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
plog(['error' => 'es删除失败', '$esResult' => $esResult, '$updateDataArray' => $updateDataArray, '$adminObject' => $adminObject, '$superTextObject' => $superTextObject], 'AdminSuperTextFacadeService', 'deleteSuperTextError');
throw new CommonException(['code'=>10000,'msg'=>'es删除失败','error'=>'EsDeleteSuperTextError']);
}
CommonEvent::dispatch($adminObject, $requestDTO,['code'=>10000,'info'=>'删除','event'=>'DeleteSuperText']);
$result = code(['code' => 0, 'msg' => '删除成功!']);
return $result;
}
#[DocParams('批量删除', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\MultipleDeleteSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function multipleDeleteSuperText(MultipleDeleteSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'批量删除失败','error'=>'MultipleDeleteSuperTextError'];
$esIndexName = config(self::ES_REPLACE_INDEX);
$select_uid_array = $requestDTO->select_uid_array;
//系统数据不可以删除
$max_size = config(self::ES_MAX_RESULT);
$systemSuperTextUidArray = EsQueryFacade::index($esIndexName)->orWhere('field', 'value')->orWhere('field', 'value')->orWhere('field', 'value')->limit($max_size)->get()->pluck('superText_uid')->toArray();
//取交集
$intersection = array_intersect($systemSuperTextUidArray, $select_uid_array);
if (!empty($intersection)) {
throw new CommonException(['code'=>10000,'msg'=>'系统数据不可以删除','error'=>'MultipleDeleteSystemSuperTextError']);
}
if (count($select_uid_array)) {
$superTextColelction = EsQueryFacade::index($esIndexName)->whereIn('superText_uid', $select_uid_array)->get();
//映射容器数组
$mapGroup = [];
foreach ($superTextColelction as $superTextObject) {
$mapGroup[$superTextObject->business_uid][] = $superTextObject->superText_uid;
}
foreach ($mapGroup as $business_uid => $superText_uid_array) {
foreach ($superText_uid_array as $superText_uid) {
//数据格式
//['business_uid'=>'superText_uid'];
$superTextObject = SuperText::queryByShard($business_uid)->where('superText_uid', $superText_uid)->first();
if (!$superTextObject) {
// 跳过不存在/已禁用的
continue;
}
$superTextObject->updateWithShard([
'deleted_at' => \get_now_date_time(),
]);
//es更新 复杂业务放置到Event中处理
$superTextObject = $superTextObject->fresh();
$updateDataArray = [
'deleted_at' => \get_now_date_time(),
'updated_time' => $superTextObject->updated_time,
'updated_at' => $superTextObject->updated_at,
];
$esResult = EsFacade::updateDoc($esIndexName, $superTextObject->biz_id, $updateDataArray);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
plog(['error' => 'es删除失败', '$esResult' => $esResult, '$updateDataArray' => $updateDataArray, '$adminObject' => $adminObject, '$superTextObject' => $superTextObject], 'AdminSuperTextFacadeService', 'multipleDeleteSuperTextError');
continue;
}
}
}
}
CommonEvent::dispatch($adminObject, $requestDTO,['code'=>10000,'info'=>'批量删除','event'=>'MultipleDeleteSuperText']);
$result = code(['code' => 0, 'msg' => '批量删除成功!']);
return $result;
}
#[DocParams('禁用', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\DisableSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function disableSuperText(DisableSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'禁用复用失败','error'=>'DisableSuperTextError'];
$superText_uid = $requestDTO->superText_uid;
$status = $requestDTO->status;
//es同步 复杂业务放置到Event中处理
$esIndexName = config(self::ES_REPLACE_INDEX);
$esRepalceObject = EsQueryFacade::index($esIndexName)->whereNull('deleted_at')->where('superText_uid',$superText_uid)->get()->first();
if(!isset($esRepalceObject->superText_uid)){
throw new CommonException(['code' => 10000, 'msg' => '数据不存在', 'error' => 'EsDataNotExistError']);
}
$checkResult = $this->checkIsSystemSuperTextBySuperTextUid($superText_uid);
if ($checkResult) {
throw new CommonException(['code'=>10000,'msg'=>'系统数据不可禁用','error'=>'DisableSystemSuperTextError']);
}
$superTextObject = SuperText::queryByShard($esRepalceObject->business_uid)->where('account_status', 1)->first();
if (!isset($superTextObject->biz_id)) {
throw new CommonException(['code'=>10000,'msg'=>'数据不存在','error'=>'SuperTextNotExistError']);
}
$updateDataArray = ['status' => $status];
$superTextUpdateResult = $superTextObject->updateWithShard($updateDataArray);
if (!$superTextUpdateResult) {
throw new CommonException(['code'=>10000,'msg'=>'禁用复用失败','error'=>'DisableSuperTextError']);
}
$esResult = EsFacade::updateDoc($esIndexName, $superTextObject->biz_id, $updateDataArray);
if (!isset($esResult['code']) || $esResult['code'] != 0) {
plog(['info' => 'EsDisableSuperTextError', '$esResult' => $esResult], 'AdminSuperTextFacadeService', 'disableSuperText');
}
CommonEvent::dispatch($adminObject, $requestDTO, ['code'=>10000,'info'=>'禁用','event'=>'DisableSuperText']);
$result = code(['code' => 0, 'msg' => '禁用成功!']);
return $result;
}
#[DocParams('批量禁用', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\MultipleDisableSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function multipleDisableSuperText(MultipleDisableSuperTextDTO $requestDTO, Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'批量禁用复用失败','error'=>'MultipleDisableSuperTextError'];
$esIndexNam = config(self::ES_REPLACE_INDEX);
$select_uid_array = $requestDTO->select_uid_array;
$status = $requestDTO->status;
//如果禁用
if (!$status) {
//注意系统级不可以禁用
$systemSuperTextUidArray = EsQueryFacade::index($esIndexNam)->whereIn('field', ['value'])->get()->pluck('superText_uid')->toArray();
//取交集
$intersection = array_intersect($systemSuperTextUidArray, $select_uid_array);
if (!empty($intersection)) {
throw new CommonException(['code'=>10000,'msg'=>'系统数据不可批量禁用复用','error'=>'MultipleDisableSystemAdminError']);
}
}
if (count($select_uid_array)) {
$superTextColelction = EsQueryFacade::index($esIndexNam)->whereIn('superText_uid', $select_uid_array)->get();
$mapGroup = [];
foreach ($superTextColelction as $superTextObject) {
$mapGroup[$superTextObject->business_uid][] = $superTextObject->superText_uid;
}
foreach ($mapGroup as $business_uid => $superText_uid_array) {
foreach ($superText_uid_array as $superText_uid) {
$superTextObject = SuperText::queryByShard($business_uid)->where('superText_uid', $superText_uid)->where('status', !$status)->first();
if (!$superTextObject) {
// 跳过不存在/已禁用的
continue;
}
$superTextObject->updateWithShard([
'status' => $status,
]);
//es处理 复杂业务放置到Event中处理
$superTextObject = $superTextObject->fresh();
$updateDataArray = [
'status' => $superTextObject->status,
'updated_time' => $superTextObject->updated_time,
'updated_at' => $superTextObject->updated_at,
];
$esResult = EsFacade::updateDoc($esIndexNam, $superTextObject->biz_id, $updateDataArray);
if (!isset($esResult['code']) || $esResult['code'] !== 0) {
plog(['error' => 'es禁用失败', '$esResult' => $esResult, '$updateDataArray' => $updateDataArray, '$adminObject' => $adminObject, '$superTextObject' => $superTextObject], 'AdminSuperTextFacadeService', 'multipleDisableSuperText');
continue;
}
}
}
}
CommonEvent::dispatch($superTextObject, $requestDTO, ['code'=>10000,'info'=>'批量禁用','event'=>'MultipleDisableSuperText']);
$result = code(['code' => 0, 'msg' => '批量禁用成功!']);
return $result;
}
#[DocParams('获取默认选项配合前端', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\DefaultSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function defaultSuperText(DefaultSuperTextDTO $requestDTO, ?Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'获取默认选项','error'=>'GetDefaultSuperTextError'];
$account_status = $requestDTO?->account_status??1;
$esIndexName = config(self::ES_REPLACE_INDEX);
$limit = $requestDTO->limit;
$superTextCollection = EsQueryFacade::index($esIndexName)->whereNull('deleted_at')->where('account_status', $account_status)->limit($limit)->orderBy('created_time', 'asc')->get();
if (!optional($superTextCollection)) {
throw new CommonException(['code'=>10000,'msg'=>'获取默认选项','error'=>'GetDefaultSuperTextError']);
}
$esUnionCollection = $this->getUnionCollection($superTextCollection);
EsSuperTextResource::setUnionCollection($esUnionCollection);
$data['data'] = EsSuperTextResource::collection($superTextCollection);
$result = code(['code' => 0, 'msg' => '获取默认选项成功!'], $data);
return $result;
}
#[DocParams('获取默认选项配合前端', ['requestDTO' => ['type' => '\App\DTOs\Text\V1\Admin\SuperText\FindSuperTextDTO', 'note' => '请求DTO'], 'adminObject' => ['type' => 'App\Models\LaravelFastApi\V1\Admin\Admin', 'note' => '管理员对象'], 'return' => ['type' => 'array', 'note' => '返回格式数据']])]
public function findSuperText(FindSuperTextDTO $requestDTO, ?Admin $adminObject)
{
$result = ['code'=>10000,'msg'=>'查找选项','error'=>'FindSuperTextError'];
$esIndexName = config(self::ES_REPLACE_INDEX);
$max_size = config(self::ES_MAX_RESULT);
$esQuery = EsQueryFacade::index($esIndexName);
$esQuery->setQueryField(['name', 'code'])->orWhereLike('name', $requestDTO->find)
->orWhereLike('code', $requestDTO->find);
$superTextCollection = $esQuery
->limit($max_size)
->orderBy('created_time', 'asc')
->get()
->filter(fn($item) => empty($item->deleted_at))
->values();
if (!optional($superTextCollection)) {
throw new CommonException(['code'=>10000,'msg'=>'查找选项','error'=>'FindSuperTextError']);
}
$esUnionCollection = $this->getUnionCollection($superTextCollection);
EsSuperTextResource::setUnionCollection($esUnionCollection);
$data['data'] = EsSuperTextResource::collection($superTextCollection);
$result = code(['code' => 0, 'msg' => '查找选项成功!'], $data);
return $result;
}
#[DocParams('获取关联数据集合', ['esCollection' => ['type' => 'Illuminate\Support\Collection', 'note' => '原始数据集合'], 'return' => ['type' => 'Illuminate\Support\Collection', 'note' => '返回格式数据']])]
protected function getUnionCollection(Collection $esCollection): Collection
{
$max_size = config(self::ES_MAX_RESULT);
$union_uid_array = array_unique($esCollection->pluck('union_uid')->toArray());
//p($union_uid_array);die;
$esUnionCollection = collect([]);
if (count($union_uid_array)) {
$esUnionIndexName = config(self::ES_UNION_INDEX);
$esQuery = EsQueryFacade::index($esUnionIndexName);
$esUnionCollection = $esQuery->whereNull('deleted_at')->whereIn('union_uid', $union_uid_array)->limit($max_size)->get();
$esUnionCollection = $esUnionCollection->keyBy('union_uid');
}
return $esUnionCollection;
}
#[DocParams('获取需要内存拼装的数据集合', ['esCollection' => ['type' => 'Illuminate\Support\Collection', 'note' => '原始数据集合'], 'return' => ['type' => 'Illuminate\Support\Collection', 'note' => '处理后的原始数据集合']])]
protected function getOriginUnionCollection(Collection $esCollection): Collection
{
$max_size = config(self::ES_MAX_RESULT);
//这里根据实际业务需要自行完善补充,下面代码仅为参考示例
$resultCollection = $esCollection->keyBy('user_uid');
$user_uid_array = array_unique($esCollection->pluck('user_uid')->toArray());
$esUserRoleUnionCollection = collect([]);
$esRoleCollection = collect([]);
if(count($user_uid_array)){
$indexName = config(self::ES_UNION_INDEX);
$esUserRoleUnionCollection = EsQueryFacade::index($indexName)->whereNull('deleted_at')->whereIn('user_uid', $user_uid_array)->limit($max_size)->get();
//p($esUserRoleUnionCollection);die;
$role_id_array = array_unique($esUserRoleUnionCollection->pluck('role_id')->toArray());
$roleIndexName = config(self::ES_UNION_INDEX);
if(count($role_id_array)){
$esRoleCollection= EsQueryFacade::index($roleIndexName)->whereNull('deleted_at')->whereIn('id', $role_id_array)->get();
}
}
foreach($resultCollection as $user_uid => &$esUserObject){
$role_name_array = [];
foreach ($esUserRoleUnionCollection as $esUserRoleUnionObject) {
if($esUserRoleUnionObject->user_uid == $user_uid){
$role_id = $esUserRoleUnionObject->role_id;
$roleObject = $esRoleCollection->where('id', $role_id)->first();
//p($roleObject);
if(isset($roleObject->role_name)){
$role_name_array[] = $roleObject->role_name;
}
}
}
$esUserObject->role_name_array = array_unique($role_name_array);
}
return $resultCollection;
}
#[DocParams('检查是否为系统替换', ['superText_uid' => ['type' => 'int', 'note' => '替换UID'], 'return' => ['type' => 'bool', 'note' => '是否为系统替换']])]
protected function checkIsSystemSuperTextBySuperTextUid(int $superText_uid)
{
//这里根据实际业务需要自行完善补充
return false;
}
#[DocParams('清理redis缓存', ['return' => ['type' => 'void']])]
protected function clearSuperTextRedisCache(): void
{
//redis缓存处理
$redisKey = config('common_redis.superText.key');
$redisField = config('common_redis.superText.field');
Redis::hdel($redisKey, $redisField);
// 清除 ES 全量节点中间缓存,确保下次从 ES 重新拉取最新数据
$this->clearEsTreeCache();
}
}契约
Contract
php artisan make:contract 模块/版本号/业务路径/名称 --base=基础模块名称 --business=业务模块名称示例
php artisan make:contract Text\V1\Admin\SuperText\AddSuperTextHandleContract --base=Text --business=TextTwo执行后生成如下文件
app\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract.php
ContractService
php artisan make:contract-service 模块/版本号/业务路径/名称示例:
php artisan make:contract-service Text\V1\Admin\SuperText\TextAddSuperTextHandleContractService
php artisan make:contract-service TextTwo\V1\Admin\SuperText\TextTwoAddSuperTextHandleContractService --base=Text执行后生成如下文件:
app\Services\Contract\Text\V1\Admin\SuperText\TextAddSuperTextHandleContractService.php
app\Services\Contract\TextTwo\V1\Admin\SuperText\TextTwoAddSuperTextHandleContractService.php
同时创建契约服务和契约
提示
注意该命令同时会生成业务流转需要的业务DTO
php artisan call:contract 模块/版本号/业务路径/名称 --base=基础模块名称 --business=业务模块名称示例:
php artisan call:contract Text\V1\Admin\SuperText\AddSuperTextHandleContract --base=Text --business=TextTwo执行后生成如下文件:
app\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract.php
app\Services\Contract\Text\V1\Admin\SuperText\TextAddSuperTextHandleContractService.php
app\Services\Contract\TextTwo\V1\Admin\SuperText\TextTwoAddSuperTextHandleContractService.php
app\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO.php
示例代码如下:
app\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract.php
<?php
namespace App\Contracts\Text\V1\Admin\SuperText;
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
use App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO;
/**
* @see \App\Services\Contract\Text\V1\Admin\SuperText\TextAddSuperTextHandleContractService
* @see \App\Services\Contract\TextTwo\V1\Admin\SuperText\TextTwoAddSuperTextHandleContractService
*/
#[DocNote('插件契约')]
interface AddSuperTextHandleContract
{
#[DocParams('契约回调',['AddSuperTextHandleContractDTO'=>['type'=>'App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO','note'=>'业务DTO'],'return'=>['type'=>'void']])]
public function handle(AddSuperTextHandleContractDTO $businessContractDTO):void;
}app\Services\Contract\Text\V1\Admin\SuperText\TextAddSuperTextHandleContractService.php
<?php
namespace App\Services\Contract\Text\V1\Admin\SuperText;
//Laravel
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
//注解
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
//DTO
use App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO;
//Contract
use App\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract;
/**
* @see \App\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract
*/
#[DocNote('契约服务')]
class TextAddSuperTextHandleContractService implements AddSuperTextHandleContract
{
#[DocParams('契约回调',['AddSuperTextHandleContractDTO'=>['type'=>'\App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO','note'=>'业务参数DTO'],'return'=>['type'=>'void']])]
public function handle(AddSuperTextHandleContractDTO $businessContractDTO):void
{
plog(['info' => '消息日志','AddSuperTextHandleContractDTO' => $businessContractDTO], 'TextAddSuperTextHandleContractService', 'handle');
}
}app\Services\Contract\TextTwo\V1\Admin\SuperText\TextTwoAddSuperTextHandleContractService.php
<?php
namespace App\Services\Contract\TextTwo\V1\Admin\SuperText;
//Laravel
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
//注解
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
//DTO
use App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO;
//Contract
use App\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract;
/**
* @see \App\Contracts\Text\V1\Admin\SuperText\AddSuperTextHandleContract
*/
#[DocNote('契约服务')]
class TextTwoAddSuperTextHandleContractService implements AddSuperTextHandleContract
{
#[DocParams('契约回调',['AddSuperTextHandleContractDTO'=>['type'=>'\App\DTOs\Contracts\V1\Admin\SuperText\AddSuperTextHandleContractDTO','note'=>'业务参数DTO'],'return'=>['type'=>'void']])]
public function handle(AddSuperTextHandleContractDTO $businessContractDTO):void
{
plog(['info' => '消息日志','AddSuperTextHandleContractDTO' => $businessContractDTO], 'TextTwoAddSuperTextHandleContractService', 'handle');
}
}注意
业务DTO不需要像控制器验证DTO定义,只需要简单定义好强类型业务属性,用作业务流转使用即可
Event和Listener
提示
注意event代码中implements ShouldQueue 如果不用需要去掉
同理listener代码中 implements ShouldQueue 如果不用需要去掉
php artisan call:event 模块/版本号/业务路径/名称示例:
php artisan call:event Text\V1\Admin\SuperText\AddSuperTextEvent执行后会生成如下文件:
app\Events\Text\V1\Admin\SuperText\AddSuperTextEvent.php
app\Listeners\Text\V1\Admin\SuperText\AddSuperTextEvent\AddSuperTextListener.php
示例代码:
app\Events\Text\V1\Admin\SuperText\AddSuperTextEvent.php
<?php
namespace App\Events\Text\V1\Admin\SuperText;
//laravel
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
//注解
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
//模型
use App\Models\LaravelFastApi\V1\User\User;
use App\Models\LaravelFastApi\V1\Admin\Admin;
/**
* @see 事件监听路径
*/
#[DocNote('事件')]
class AddSuperTextEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
#[DocNote('用户对象')]
public User $userObject;
#[DocNote('管理员对象')]
public Admin $adminObject;
#[DocNote('是否开启事务')]
public bool $isTransation;
#[DocParams('Create a new event instance',['userObject'=>['type'=>'App\Models\LaravelFastApi\V1\User\User','note'=>'用户对象'],'adminObject'=>['type'=>'App\Models\LaravelFastApi\V1\Admin\Admin','note'=>'管理员对象'],'isTransation'=>['type'=>'bool','note'=>'是否开启事务'],'return'=>['type'=>'void','note'=>'void']])]
public function __construct(User $userObject,Admin $adminObject,bool $isTransation = false)
{
$this->userObject = $userObject;
$this->adminObject = $adminObject;
$this->isTransation = $isTransation;
}
#[DocParams(' 广播事件名称',['return'=>['type'=>'string','note'=>'事件名称']])]
public function broadcastAs()
{
return 'replaceEventName';
}
#[DocParams('Get the channels the event should broadcast on',['return'=>['type'=>'\Illuminate\Broadcasting\Channel|array','note'=>'获取该活动应广播的频道']])]
public function broadcastOn()
{
return new PrivateChannel('channel-name');
// return new Channel('channel-name');
}
}app\Listeners\Text\V1\Admin\SuperText\AddSuperTextEvent\AddSuperTextListener.php
<?php
namespace App\Listeners\Text\V1\Admin\SuperText\AddSuperTextEvent;
//laravel
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\DB;
//注解
use App\Attributes\Common\DocNote;
use App\Attributes\Common\DocParams;
use App\Exceptions\Admin\CommonException;
use YouHuJun\Tool\App\Facades\V1\Utils\Shard\ShardFacade;
use App\Facades\Common\V1\Shard\ShardHelperFacade;
use YouHuJun\Tool\App\Facades\V1\Es\EsFacade;
/**
* @see 事件地址
*/
#[DocNote('事件监听')]
class AddSuperTextListener implements ShouldQueue
{
use InteractsWithQueue;
#[DocParams('Create the event listener',['return'=>['type'=>'void']])]
public function __construct()
{
//
}
#[DocParams('Handle the event',['event'=>['type'=>'object','note'=>'事件对象'],'return'=>['type'=>'void']])]
public function handle(object $event): void
{
//
}
}