136 lines
3.8 KiB
PHP
136 lines
3.8 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
namespace App\Service;
|
|||
|
|
|
|||
|
|
use App\BaseApp\BaseService;
|
|||
|
|
use App\Models\FileFolderModel;
|
|||
|
|
use App\Models\FileModel;
|
|||
|
|
use Exception;
|
|||
|
|
use Psr\Container\ContainerExceptionInterface;
|
|||
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 素材文件夹
|
|||
|
|
*
|
|||
|
|
* 纯逻辑目录:只改 nl_file.folder_id,不碰对象在 OSS 上的实际路径。
|
|||
|
|
*/
|
|||
|
|
class FileFolderService extends BaseService
|
|||
|
|
{
|
|||
|
|
public function __construct()
|
|||
|
|
{
|
|||
|
|
parent::__construct();
|
|||
|
|
$this->model = FileFolderModel::class;
|
|||
|
|
$this->selectField = ['id', 'pid', 'name', 'sort', 'status', 'created_at', 'updated_at'];
|
|||
|
|
$this->queryField = ['name' => 'like', 'pid' => '=', 'status' => '='];
|
|||
|
|
$this->orderBy = ['name' => 'sort', 'sort' => 'asc'];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 列表,带每个文件夹下的素材数
|
|||
|
|
*
|
|||
|
|
* @throws ContainerExceptionInterface
|
|||
|
|
* @throws NotFoundExceptionInterface
|
|||
|
|
*/
|
|||
|
|
public function list(): array
|
|||
|
|
{
|
|||
|
|
$result = $this->getPageList();
|
|||
|
|
$ids = array_column($result['items'], 'id');
|
|||
|
|
$counts = empty($ids)
|
|||
|
|
? []
|
|||
|
|
: FileModel::whereIn('folder_id', $ids)
|
|||
|
|
->where('deleted_at', 0)
|
|||
|
|
->selectRaw('folder_id, COUNT(*) as total')
|
|||
|
|
->groupBy('folder_id')
|
|||
|
|
->pluck('total', 'folder_id')
|
|||
|
|
->all();
|
|||
|
|
|
|||
|
|
foreach ($result['items'] as &$item) {
|
|||
|
|
$item['file_count'] = (int) ($counts[$item['id']] ?? 0);
|
|||
|
|
}
|
|||
|
|
unset($item);
|
|||
|
|
return $result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 目录树,素材库左侧栏直接用它渲染
|
|||
|
|
*/
|
|||
|
|
public function option(): array
|
|||
|
|
{
|
|||
|
|
$rows = FileFolderModel::where('deleted_at', 0)
|
|||
|
|
->orderBy('sort')
|
|||
|
|
->orderBy('id')
|
|||
|
|
->get(['id', 'pid', 'name', 'sort'])
|
|||
|
|
->toArray();
|
|||
|
|
return $this->utils->tree($rows);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @throws Exception
|
|||
|
|
*/
|
|||
|
|
public function detail($id): mixed
|
|||
|
|
{
|
|||
|
|
return $this->getDetail($id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @throws Exception
|
|||
|
|
*/
|
|||
|
|
public function create($params): mixed
|
|||
|
|
{
|
|||
|
|
$params['pid'] = $this->assertParent((int) ($params['pid'] ?? 0));
|
|||
|
|
return $this->insert($params);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @throws Exception
|
|||
|
|
*/
|
|||
|
|
public function update($id, $params): mixed
|
|||
|
|
{
|
|||
|
|
if (array_key_exists('pid', $params)) {
|
|||
|
|
$pid = (int) $params['pid'];
|
|||
|
|
if ($pid === (int) $id) {
|
|||
|
|
$this->utils->errorThrow('上级文件夹不能是自己');
|
|||
|
|
}
|
|||
|
|
$params['pid'] = $this->assertParent($pid);
|
|||
|
|
}
|
|||
|
|
return $this->save($id, $params);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 删除文件夹:有子目录或仍有素材时拒绝
|
|||
|
|
*
|
|||
|
|
* 直接删会让里面的素材挂在一个查不到的 folder_id 上,
|
|||
|
|
* 按文件夹筛选时那批文件就再也点不出来 —— 文件还在,人找不到。
|
|||
|
|
*
|
|||
|
|
* @throws Exception
|
|||
|
|
*/
|
|||
|
|
public function delete($id): mixed
|
|||
|
|
{
|
|||
|
|
$ids = array_values(array_filter(array_map('intval', is_array($id) ? $id : [$id])));
|
|||
|
|
if (empty($ids)) {
|
|||
|
|
$this->utils->errorThrow('参数错误');
|
|||
|
|
}
|
|||
|
|
if (FileFolderModel::whereIn('pid', $ids)->where('deleted_at', 0)->exists()) {
|
|||
|
|
$this->utils->errorThrow('存在子文件夹,请先删除子文件夹');
|
|||
|
|
}
|
|||
|
|
if (FileModel::whereIn('folder_id', $ids)->where('deleted_at', 0)->exists()) {
|
|||
|
|
$this->utils->errorThrow('该文件夹下仍有素材,请先移动素材');
|
|||
|
|
}
|
|||
|
|
return $this->del($ids);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @throws Exception
|
|||
|
|
*/
|
|||
|
|
private function assertParent(int $pid): int
|
|||
|
|
{
|
|||
|
|
if ($pid <= 0) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
if (!FileFolderModel::where('id', $pid)->where('deleted_at', 0)->exists()) {
|
|||
|
|
$this->utils->notFound('上级文件夹不存在');
|
|||
|
|
}
|
|||
|
|
return $pid;
|
|||
|
|
}
|
|||
|
|
}
|