\App\Services\AdminMaintainFileService

文件维护服务

职责:归属校验——列表经 DataScopeService 过滤;单个文件的读/改/删/复制操作 统一走 assertOwned()(非豁免操作者只能操作自己 user_id 的文件), 豁免语义(超管或 is_exempt 角色)与列表过滤一致。 公共目录模型——td_sys_file_folder.user_id=0 即公共目录树,全员可见; 豁免管理员拥有全部公共目录的完整维护权(is_file_maintainer 标志已废弃)。

┌────────────────── 分区导航(按此顺序阅读)──────────────────┐ 分区 1 · 列表与统计(读) list / trashList / usage / userStats / overview / duplicates / danglingRefs 分区 2 · 目录管理 folders / folderCreate / folderUpdate / folderDestroy 分区 3 · 公共目录 publicFolderCreate / publicFolderUpdate / publicFolderDestroy 分区 4 · 下载与引用(读) preview / download / refs 分区 5 · 上传与编辑 create / update / rename 分区 6 · 复制与移动 copy / batchCopy / move / batchMove 分区 7 · 回收站 trash / restore / destroyPermanently / batchTrash batchRestore / purgeTrash / cleanTrash 分区 8 · 内部辅助 attachRefCounts / buildQuery / assertVisible / assertOwned filterOwnedIds / effectiveQuota / assertQuota / quotaUsedBytes assertQuotaWithUsed / assertNotDescendant / assertFolderParent assertPublicFolderManager / assertPublicFolderParent / assertNotPublicFolder isPublicMaintainer / publicFolderIds / folderIsPublic assertFolderNameUnique / assertFolderOwned / refConsumer └────────────────────────────────────────────────────────────┘

Summary

Methods
Properties
Constants
paginate()
trashList()
usage()
userStats()
overview()
duplicates()
danglingRefs()
folders()
folderCreate()
folderUpdate()
folderDestroy()
publicFolderCreate()
publicFolderUpdate()
publicFolderDestroy()
preview()
download()
refs()
create()
update()
rename()
copy()
batchCopy()
move()
batchMove()
trash()
restore()
destroyPermanently()
batchTrash()
batchRestore()
purgeTrash()
cleanTrash()
No public properties found
FILE_REF_CONSUMERS
SORTABLE_COLUMNS
No protected methods found
No protected properties found
N/A
deletePhysicalFiles()
attachRefCounts()
attachUserNames()
refConsumer()
referencedFileIds()
duplicateHeads()
danglingFileMap()
sortColumn()
sortDirection()
buildQuery()
applyTextAndCategoryFilters()
applySizeAndDateFilters()
applyVisibility()
assertVisible()
assertOwned()
filterOwnedIds()
effectiveQuota()
assertQuota()
notifyQuotaExceeded()
quotaUsedBytes()
assertQuotaWithUsed()
assertNotDescendant()
assertFolderParent()
assertPublicFolderManager()
assertPublicFolderParent()
assertNotPublicFolder()
isPublicMaintainer()
publicFolderIds()
folderIsPublic()
assertFolderNameUnique()
updateFolderCommon()
assertFolderEmpty()
assertFolderOwned()
$publicFolderIdsMemo
N/A

Constants

FILE_REF_CONSUMERS

FILE_REF_CONSUMERS = ['site.logo' => '登录页与后台顶栏 Logo', 'site.favicon' => '浏览器标签页图标(favicon)']

配置 key → 功能说明(文件引用「被什么功能用」的消费点标注)。 新增 image/file 配置项并接功能时在此补充;未覆盖项回落配置定义 remark,再空则 null。

SORTABLE_COLUMNS

SORTABLE_COLUMNS = ['created_at', 'file_size', 'file_name']

列表排序字段白名单(运维台账排序;非法值回落 created_at)

Properties

$publicFolderIdsMemo

$publicFolderIdsMemo : ?array

实例级公共目录 id 缓存(勿用 static——static 跨请求/测试进程残留会读到过期 id)

Type

?array

Methods

paginate()

paginate(array  $filters = [], int  $perPage = 15) : \Illuminate\Contracts\Pagination\LengthAwarePaginator

文件列表(分页,附每条文件的引用计数 file_refs_count)。

Parameters

array $filters

keyword / file_type / folder_id / source / user_id(豁免) / min_size / created_from / created_to / orphan / sort / order

int $perPage

Returns

\Illuminate\Contracts\Pagination\LengthAwarePaginator —

trashList()

trashList(array  $filters = [], int  $perPage = 15) : mixed

回收站列表(分页,附引用计数;筛选/排序参数与正常列表同契约)。

Parameters

array $filters
int $perPage

Returns

mixed —

usage()

usage(int  $userId) : array

空间用量(我的空间统计:总大小/文件数 + 按类型分段)。

Parameters

int $userId

Returns

array —

userStats()

userStats() : array

全站用户文件统计(平台全局视角:文件维护用户导航数据源)。

按 user_id 聚合正常文件(回收站不计),返回每用户 文件数/总大小, 姓名 real_name 空回落 username;仅列有文件的用户,按总大小降序。 豁免专属——非豁免抛 403。

Returns

array —

overview()

overview() : array

全站文件概览聚合(运维台账顶栏数据源)。

全站口径:total_(正常文件数/总字节)、today_count(今日新增)、 trash_(回收站数量/字节)、user_count(正常文件去重上传者数)、 orphan_count(正常文件中无引用数,同 orphan 筛选语义)、 dup_group_count/dup_wasted_bytes(内容哈希重复族数/浪费字节=(族内数量-1)×族内 MAX(file_size))、 dangling_count(悬空引用去重文件 id 数:记录缺失或已在回收站)、 by_type(正常文件按 file_type 聚合 size/count,按 size 降序)。 豁免专属——非豁免抛 403;挂 sys:file:stats 缓存(依赖 td_sys_files,增删改自动失效)。

Returns

array —

duplicates()

duplicates() : array

全站重复文件聚族(运维台账「重复文件」视图数据源)。

内容哈希 file_hash 聚族:正常文件、hash 非空、族内 ≥2;族按浪费字节降序, 明细上限 50 族(防大库撑爆响应),summary 统计全量族不受截断; 族内 files 按 created_at 升序(最早=建议保留的那份),批量补 user_name 防 N+1。 豁免专属——非豁免抛 403;挂 sys:file:stats 缓存(实际 key = sys:file:stats:duplicates)。

Returns

array —

danglingRefs()

danglingRefs() : array

配置侧悬空引用清单(运维台账「悬空引用」视图数据源)。

从配置侧出发:已存值(join 定义,type image/file)+ 定义默认值两来源, 按数值型文件 id 聚族(refs 结构与 refs() 一致,consumer 带上); 逐 id 批量比对 td_sys_files:记录不存在=missing(file_name=null)、 file_status=回收站=trash(带 file_name);只返回悬空项,按 file_id 降序。 豁免专属——非豁免抛 403;挂 sys:file:stats 缓存(实际 key = sys:file:stats:dangling-refs)。

Returns

array —

folders()

folders(int  $userId) : array

目录列表(平铺,parent_id 组装由前端完成;附每目录正常文件计数)。

返回双分区(公共目录模型):personal=个人空间(一人一棵树, 豁免管理员传 userId 可看任意用户目录);public=公共空间(user_id=0 系统树, 全员可见、豁免/维护标志用户可写)。公共目录附 is_public=1 与 can_write, can_manage_public=操作者对公共空间的完整管理权(建/改/删目录 + 目录内文件写操作)。

Parameters

int $userId

Returns

array —

folderCreate()

folderCreate(int  $userId, string  $name, int  $parentId, int  $sort) : \App\Models\SysFileFolder

新建目录(同级重名拦截;父级须为同用户目录)。

Parameters

int $userId
string $name
int $parentId
int $sort

Throws

\InvalidArgumentException

Returns

\App\Models\SysFileFolder —

folderUpdate()

folderUpdate(\App\Models\SysFileFolder  $folder, array  $data) : \App\Models\SysFileFolder

更新目录(重命名/移父级/排序)。防环:父级不能是自身子树。 公共编排单源:updateFolderCommon(个人/公共目录共用)。

Parameters

\App\Models\SysFileFolder $folder
array $data

Throws

\InvalidArgumentException

Returns

\App\Models\SysFileFolder —

folderDestroy()

folderDestroy(\App\Models\SysFileFolder  $folder) : void

删除目录(空目录才允许:有子目录或文件 400;仅删记录,物理文件不动)。

Parameters

\App\Models\SysFileFolder $folder

Throws

\InvalidArgumentException

publicFolderCreate()

publicFolderCreate(string  $name, int  $parentId, int  $sort) : \App\Models\SysFileFolder

新建公共目录。

Parameters

string $name
int $parentId
int $sort

Throws

\InvalidArgumentException

无权管理公共目录时抛 403

Returns

\App\Models\SysFileFolder —

publicFolderUpdate()

publicFolderUpdate(\App\Models\SysFileFolder  $folder, array  $data) : \App\Models\SysFileFolder

更新公共目录(重命名/移父级/排序/启停)。防环与个人目录同规(user_id=0 树内判链)。 公共编排单源:updateFolderCommon。

Parameters

\App\Models\SysFileFolder $folder
array $data

Throws

\InvalidArgumentException

无权管理或目标非法时抛错

Returns

\App\Models\SysFileFolder —

publicFolderDestroy()

publicFolderDestroy(\App\Models\SysFileFolder  $folder) : void

删除公共目录(空目录才允许:有子目录或文件 400;仅删记录,物理文件不动)。

Parameters

\App\Models\SysFileFolder $folder

Throws

\InvalidArgumentException

无权管理或目录非空时抛错

preview()

preview(\App\Models\SysFile  $file, string  $variant = 'original') : array

图片内联预览(净化/缩略图体系配套)。

variant=thumb 取缩略图变体(无则回落原图);仅图片类允许内联(防 SVG/HTML 内联执行面, 且上传白名单本就不含 svg);其余类型引导走鉴权下载。可见性校验与下载同规。 HTTP 响应组装(StreamedResponse)归位 Controller,Service 只回文件指针信息。

Parameters

\App\Models\SysFile $file
string $variant

Throws

\InvalidArgumentException

非图片/无权访问

Returns

array —

download()

download(\App\Models\SysFile  $file) : array

鉴权下载:仅正常状态且通过**可见性**校验的文件可下载, 响应为强制附件下载(Content-Disposition: attachment),不内联渲染——私有盘无公开 URL。 共享文件所有登录用户可下载引用;操作权仍仅本人 + 豁免。 HTTP 响应组装归位 Controller,Service 只回文件指针信息。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权访问抛 403,文件状态异常抛 400

Returns

array —

refs()

refs(\App\Models\SysFile  $file) : array

文件反向引用查询:找出引用了该文件的配置项。

业务表单经 FileUpload 组件引用文件时,配置值存文件 id 字符串。 只匹配 image/file 类型定义的 value(防数字型配置项值误判); 定义默认值中引用一并返回(值未覆盖时默认值生效,via=default)。

Parameters

\App\Models\SysFile $file

Returns

array —

create()

create(\Illuminate\Http\UploadedFile  $file, string  $fileType, string|null  $fileTarget = null, int  $isShared = SysFile::SHARED_NO, string  $scene = 'default', int  $folderId, string  $fromPath = '') : array

上传文件(凡上传必登记:场景烙印 + 逻辑目录 + 来源页面)。

Parameters

\Illuminate\Http\UploadedFile $file

上传文件实例

string $fileType

文件分类

string|null $fileTarget

文件标签

int $isShared

共享状态(0=私有 1=共享,默认私有)

string $scene

上传场景(FileScene 注册表 key)

int $folderId

归属目录 id(0=根目录;非 0 须为本人目录)

string $fromPath

来源页面路径(前端自动捕获)

Throws

\InvalidArgumentException

Returns

array —

update()

update(\App\Models\SysFile  $file, array  $data) : \App\Models\SysFile

更新文件元信息。

Parameters

\App\Models\SysFile $file
array $data

Throws

\InvalidArgumentException

无权操作时抛 403

Returns

\App\Models\SysFile —

rename()

rename(\App\Models\SysFile  $file, string  $fileName) : \App\Models\SysFile

重命名(修改原始文件名)。

扩展名闸门:新扩展名必须在分类白名单内(FileUploadHelper::isAllowedExtension), 堵住「上传 txt → 改名 md/html」类绕过——预览端按扩展名选渲染器, 非法扩展名可触发非预期渲染路径(存储型 XSS 面)。

Parameters

\App\Models\SysFile $file
string $fileName

Throws

\InvalidArgumentException

无权操作时抛 403 / 扩展名不允许

Returns

\App\Models\SysFile —

copy()

copy(\App\Models\SysFile  $file, ?int  $usedBytes = null, ?int  $quota = null) : \App\Models\SysFile

复制文件。

在同用户目录下创建文件副本,生成新的 DB 记录。

Parameters

\App\Models\SysFile $file
?int $usedBytes
?int $quota

Throws

\InvalidArgumentException

无权操作时抛 403

Returns

\App\Models\SysFile —

batchCopy()

batchCopy(int[]  $ids) : array

批量复制。

先按归属过滤 ids,被过滤及复制失败的计入 skipped。

配额一次预取(已用空间一次 sum + 生效配额一次查询),循环内内存递减—— 替代逐文件全量 sum(file_size) + find(用户)。

Parameters

int[] $ids

Returns

array —

move()

move(\App\Models\SysFile  $file, int  $folderId) : \App\Models\SysFile

移动文件到目录。目标目录须属于文件所属用户。

Parameters

\App\Models\SysFile $file
int $folderId

Throws

\InvalidArgumentException

无权操作或目录非法时抛错

Returns

\App\Models\SysFile —

batchMove()

batchMove(int[]  $ids, int  $folderId) : array

批量移动到目录。

先按归属过滤 ids,被过滤的计入 skipped;目标目录须属于操作者 (非豁免批量只能动自己的文件,目录天然也是自己的)。

Parameters

int[] $ids
int $folderId

Returns

array —

trash()

trash(\App\Models\SysFile  $file) : void

移入回收站。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权操作时抛 403

restore()

restore(\App\Models\SysFile  $file) : void

从回收站恢复。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权操作时抛 403

destroyPermanently()

destroyPermanently(\App\Models\SysFile  $file) : void

彻底删除(物理删除,仅回收站内文件)。

物理文件(含缩略图变体)与 DB 记录一并清理,不可恢复。 此前「彻底删除」实为重复软删,物理文件永不清理。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权操作时抛 403;不在回收站时抛 400

batchTrash()

batchTrash(int[]  $ids) : array

批量移入回收站。

先按归属过滤 ids,被过滤的计入 skipped。

Parameters

int[] $ids

Returns

array —

batchRestore()

batchRestore(int[]  $ids) : array

批量恢复。

先按归属过滤 ids,被过滤的计入 skipped。

Parameters

int[] $ids

Returns

array —

purgeTrash()

purgeTrash() : int

清空回收站。

豁免操作者全量清理,非豁免操作者只清自己上传的回收站文件(等价于 filterOwnedIds 语义)。 chunkById 分批处理,避免回收站上万行时一次全量 pluck。

Returns

int —

清理数量

cleanTrash()

cleanTrash(int  $retentionDays) : int

按保留天数清理回收站(file:clean-trash 命令与 file.trash_retention_days 配置配套)。

只清全库回收站(管理员运维口径,非按用户);物理文件与 DB 记录一并清理(同 purgeTrash)。

Parameters

int $retentionDays

保留天数;0/负 = 全部清空

Returns

int —

清理数量

deletePhysicalFiles()

deletePhysicalFiles(\App\Models\SysFile  $file) : void

物理文件 + 缩略图变体删除(单源:彻底删除/清空回收站/按天清理三处共用)。 原文件存在才删;缩略图与原文同路径或为空时跳过。

Parameters

\App\Models\SysFile $file

attachRefCounts()

attachRefCounts(\Illuminate\Contracts\Pagination\LengthAwarePaginator  $files) : void

批量附加引用计数(file_refs_count):一次查当前页全部文件的 已存值引用 + 定义默认值引用,避免 N+1。

Parameters

\Illuminate\Contracts\Pagination\LengthAwarePaginator $files

attachUserNames()

attachUserNames(\Illuminate\Contracts\Pagination\LengthAwarePaginator  $files) : void

附件上传者姓名(台账视角「谁的文件」列):分页后批量取 td_sys_user, real_name 为空回落 username;无主用户(如历史 user_id=0)留空。

Parameters

\Illuminate\Contracts\Pagination\LengthAwarePaginator $files

refConsumer()

refConsumer(string  $key, string  $remark) : ?string

引用功能说明:消费点映射优先,回落配置定义 remark,再空则 null

Parameters

string $key
string $remark

Returns

?string —

referencedFileIds()

referencedFileIds() : int[]

被引用文件 id 集(image/file 类型配置的已存值 + 定义默认值,字符串匹配文件 id)。

与 attachRefCounts 同一引用语义,供 orphan 筛选/overview 孤儿计数取反使用; 配置项数量级小,全量 pluck 后 PHP 侧过滤 is_numeric 转 int 去重(DB 无关, 避免字符串列与 int 直接比较在 PostgreSQL 下报错)。

Returns

int[] —

duplicateHeads()

duplicateHeads() : \Illuminate\Support\Collection

重复族头聚合:正常文件、file_hash 非空、族内 ≥2,按浪费字节降序。

族大小按 MAX(file_size) 计(同族内容相同、大小偶有元数据差异); 浪费字节 = (族内数量-1)×族大小。overview.dup_* 与 duplicates() 共用本口径。

Returns

\Illuminate\Support\Collection —

danglingFileMap()

danglingFileMap(int[]  $ids) : array

悬空引用判定:给定被引用文件 id 集,批量 whereIn 比对 td_sys_files, 返回悬空项 [id => [status, file_name]]——记录不存在=missing(file_name=null)、 file_status=回收站=trash(带 file_name)。overview.dangling_count 与 danglingRefs() 共用。

Parameters

int[] $ids

Returns

array —

sortColumn()

sortColumn(array  $filters) : string

排序字段白名单校验(非法值回落 created_at)

Parameters

array $filters

Returns

string —

sortDirection()

sortDirection(array  $filters) : string

排序方向校验(仅 asc/desc,非法值回落 desc)

Parameters

array $filters

Returns

string —

buildQuery()

buildQuery(array  $filters, int  $status) : mixed

构建文件查询:状态 + 筛选 + 可见性过滤

Parameters

array $filters
int $status

Returns

mixed —

applyTextAndCategoryFilters()

applyTextAndCategoryFilters(mixed  $query, array  $filters) : void

文本/分类筛选:关键词(名称/类型/目标)、文件类型、逻辑目录、上传场景、共享状态。

Parameters

mixed $query
array $filters

applySizeAndDateFilters()

applySizeAndDateFilters(mixed  $query, array  $filters) : void

大小/日期/孤儿筛选:最小文件大小、上传日期闭区间、孤儿(无引用)。

Parameters

mixed $query
array $filters

applyVisibility()

applyVisibility(mixed  $query, array  $filters, int  $status) : void

可见性过滤(单源:台账/回收站两态共用编排): 豁免管理员=全部,且可按上传者筛选(台账维度); 非豁免=本人上传 OR 共享(is_shared=1)OR 公共目录(公共目录文件全员可见)—— 替代原 DataScopeService 组织轴过滤,文件模块自身的可见性模型为「本人+共享+公共」; 回收站是操作区:非豁免仅见自己的(别人的共享/公共文件不会出现在你的回收站), 维护标志用户额外可见公共目录中的回收站文件(自己移入的要能恢复/清空)。

Parameters

mixed $query
array $filters
int $status

assertVisible()

assertVisible(\App\Models\SysFile  $file) : void

单个文件可见性校验:本人 / 共享(is_shared=1) / 公共目录 / 豁免 可见。 用于详情、下载、业务引用;操作(改/删/重命名/回收站/复制)仍走 assertOwned。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权访问时抛 403

assertOwned()

assertOwned(\App\Models\SysFile  $file) : void

单个文件归属校验:非豁免操作者只能操作自己上传的文件; 公共目录维护标志用户可操作公共目录内的文件(担责授权)。

豁免判定与列表过滤同源(DataScopeService::isExempt:超管或 is_exempt 角色)。

Parameters

\App\Models\SysFile $file

Throws

\InvalidArgumentException

无权操作时抛 403

filterOwnedIds()

filterOwnedIds(int[]  $ids) : array

按归属过滤文件 id 列表,返回 [可操作 id 集, 被过滤数量]。

Parameters

int[] $ids

Returns

array —

effectiveQuota()

effectiveQuota(int  $userId) : ?int

用户生效配额(字节;null=不限)。

超管/豁免用户不限;quota_mb=-1 不限;0/null 跟随全局默认 FILE 分组 file.quota_mb 配置(MB)。

Parameters

int $userId

Returns

?int —

assertQuota()

assertQuota(int  $userId, int  $addBytes) : void

空间配额校验:已用空间(正常+回收站)+ 新增大小 > 生效配额 → 400。

超限时向该用户发送配额提醒(biz_key 每日一条幂等),随后照常抛出 400。

Parameters

int $userId
int $addBytes

Throws

\InvalidArgumentException

空间不足抛 400

notifyQuotaExceeded()

notifyQuotaExceeded(int  $userId) : void

配额超限站内提醒(事件无感派发:WriteMessageNotify 监听落库; biz_key 每日一条幂等,随后照常抛 400)。

Parameters

int $userId

quotaUsedBytes()

quotaUsedBytes(int  $userId) : int

已用空间(正常+回收站)字节数

Parameters

int $userId

Returns

int —

assertQuotaWithUsed()

assertQuotaWithUsed(int  $usedBytes, int  $addBytes, ?int  $quota) : void

配额校验(批量路径预取用量+配额后内存递减,替代逐文件全量 sum+find)。

Parameters

int $usedBytes
int $addBytes
?int $quota

Throws

\InvalidArgumentException

空间不足抛 400

assertNotDescendant()

assertNotDescendant(int  $userId, int  $parentId, int  $selfId) : void

防环校验:目标父级不能是自身或自身子目录。

一次拉取该用户全量 parent_id 映射(个人目录树规模小),沿父链上溯判环, 替代逐层查库;guard 上限 = 节点数 + 1,数据异常成环时终止而非死循环。

Parameters

int $userId
int $parentId
int $selfId

Throws

\InvalidArgumentException

目标父级位于自身子树内时抛错

assertFolderParent()

assertFolderParent(int  $userId, int  $folderId) : void

目录写入校验(公共目录模型):目录须存在,且—— 公共目录(user_id=0):操作者须是豁免或公共目录维护标志用户; 个人目录:须属于指定用户。

文件移动/上传落目录/建子目录共用。

Parameters

int $userId
int $folderId

Throws

\InvalidArgumentException

目录不存在、不属于该用户或无权写入时抛错

assertPublicFolderManager()

assertPublicFolderManager() : void

公共目录管理权校验:仅豁免管理员(超管/is_exempt 角色/超管岗位) 可建/改/删公共目录(is_file_maintainer 标志已废弃,治理权收敛到管理员层)。

Throws

\InvalidArgumentException

无权管理公共目录时抛 403

assertPublicFolderParent()

assertPublicFolderParent(int  $parentId) : void

公共目录父级校验:父级须为公共目录(user_id=0),0=公共空间顶级

Parameters

int $parentId

assertNotPublicFolder()

assertNotPublicFolder(\App\Models\SysFileFolder  $folder) : void

个人目录接口护栏:公共目录(user_id=0)只能走公共目录管理接口

Parameters

\App\Models\SysFileFolder $folder

isPublicMaintainer()

isPublicMaintainer(?\App\Models\SysUser  $user) : bool

操作者是否具备公共目录完整维护权:仅豁免管理员(超管/is_exempt 角色/超管岗位)。 「文件目录员」(is_file_maintainer 标志)已废弃——公共目录治理权收敛到管理员层。

Parameters

?\App\Models\SysUser $user

Returns

bool —

publicFolderIds()

publicFolderIds() : int[]

全部公共目录 id(user_id=0;同实例内多次判定共用,目录树规模小)。

Returns

int[] —

folderIsPublic()

folderIsPublic(int  $folderId) : bool

目录是否公共目录(folder_id 必须 >0——0=个人根目录,公共目录必有实体行)

Parameters

int $folderId

Returns

bool —

assertFolderNameUnique()

assertFolderNameUnique(int  $userId, int  $parentId, string  $name, int  $exceptId) : void

同级目录重名校验。

Parameters

int $userId
int $parentId
string $name
int $exceptId

Throws

\InvalidArgumentException

同级已存在同名目录时抛错

updateFolderCommon()

updateFolderCommon(\App\Models\SysFileFolder  $folder, array  $data, int  $ownerUserId, callable  $assertParent) : \App\Models\SysFileFolder

目录更新公共编排(单源:folderUpdate/publicFolderUpdate 共用)。 防环(不能移动到自身/后代下)、同级重名、白名单 update; 权限校验(归属/公共管理)由调用方先行完成。

Parameters

\App\Models\SysFileFolder $folder
array $data
int $ownerUserId
callable $assertParent

Returns

\App\Models\SysFileFolder —

assertFolderEmpty()

assertFolderEmpty(\App\Models\SysFileFolder  $folder) : void

空目录校验(单源:folderDestroy/publicFolderDestroy 共用)。 有子目录或文件即拒绝。

Parameters

\App\Models\SysFileFolder $folder

Throws

\InvalidArgumentException

目录非空时抛错

assertFolderOwned()

assertFolderOwned(\App\Models\SysFileFolder  $folder) : void

目录操作权校验:非豁免操作者只能操作自己的目录。

Parameters

\App\Models\SysFileFolder $folder

Throws

\InvalidArgumentException

无权操作时抛 403