// +---------------------------------------------------------------------- declare(strict_types=1); namespace app\api\controller\v1; use think\facade\Log; use ywxapp\controller\ApiBase; use ywxapp\model\CommonAttachment; use ywxapp\service\FileStorageService; /** * 附件管理(需登录)。 * * 上传统一走 /api/v1/common/upload(FileStorageService),成功后自动写入 * common_attachment 表;本控制器提供当前用户附件的分页查询与删除。 * * 删除 = 物理删除文件(经 FileDelete 事件,插件可接管 OSS/FTP)+ 软删记录(delete_at)。 */ class Attachment extends ApiBase { /** * 我的附件列表(分页)。 * * @param int $page 页码(默认 1) * @param int $size 每页条数(默认 20,上限 100) * @param string $module 模块过滤(可选,如 api / forum / chat) * * @return \think\Response JSON 响应,成功携带 data.list 与 data.total * * @route GET /api/v1/attachment/list */ public function list() { $page = max(1, (int) $this->request->get('page', 1)); $size = min(100, max(1, (int) $this->request->get('size', 20))); $module = trim((string) $this->request->get('module', '')); $query = CommonAttachment::where('uid', $this->uid()); if ($module !== '') { $query->where('module', $module); } $paginate = $query->order('id', 'desc')->paginate([ 'list_rows' => $size, 'page' => $page, ]); $items = array_map(function ($item) { return $item->toArray(); }, $paginate->items()); return $this->apiSuccess([ 'list' => $items, 'total' => $paginate->total(), ], 'ok'); } /** * 删除附件(仅限本人附件)。 * * 步骤:物理删除文件(FileDelete 事件可接管,失败不阻断)→ 软删记录。 * * @param int $id 附件 ID(必填) * * @return \think\Response JSON 响应,携带 deleted_file 表示物理文件是否已删除 * * @route POST /api/v1/attachment/delete */ public function delete() { $id = (int) $this->request->post('id', 0); if ($id <= 0) { return $this->apiError('参数错误'); } $att = CommonAttachment::where('uid', $this->uid())->find($id); if (!$att) { return $this->apiError('附件不存在'); } $deletedFile = false; try { $deletedFile = (new FileStorageService())->delete((string) $att->path, ['id' => $att->id]); } catch (\Throwable $e) { Log::error('附件物理删除失败 id=' . $att->id . ' ' . $e->getMessage()); } $att->delete(); // 软删 return $this->apiSuccess(['deleted_file' => $deletedFile], '删除成功'); } }