folder = $folder; $this->config = $logic->getGroup('upload_config'); $this->path = $this->checkPath(); } /** * 检查并创建上传路径 * @return string */ public function checkPath(): string { $root = Arr::getConfigValue($this->config, 'local_root'); $path = base_path() . DIRECTORY_SEPARATOR . $root . $this->folder . DIRECTORY_SEPARATOR; if (!is_dir($path)) { mkdir($path, 0777, true); } return $path; } /** * 检查切片文件上传状态 * @param $data * @return array */ public function checkChunk($data): array { $allow_file = Arr::getConfigValue($this->config, 'upload_allow_file'); if (!in_array($data['ext'], explode(',', $allow_file))) { throw new ApiException('File format not supported for upload'); } // 检查已经上传的分片文件 for ($i = 0; $i < $data['total']; ++$i) { $chunkFile = $this->path . "{$data['hash']}_{$data['total']}_{$i}.chunk"; if (!file_exists($chunkFile)) { if ($i == 0) { return $this->uploadChunk($data); } else { return ['chunk' => $i, 'status' => 'resume']; } } } // 分片文件已经全部上传 return ['chunk' => $i, 'status' => 'success']; } /** * 上传切片 * @param $data * @return array */ public function uploadChunk($data): array { $allow_file = Arr::getConfigValue($this->config, 'upload_allow_file'); if (!in_array($data['ext'], explode(',', $allow_file))) { throw new ApiException('File format not supported for upload'); } $request = request(); if (!$request) { throw new ApiException('Chunk upload must be called in HTTP request context'); } $uploadFile = current($request->file()); $chunkName = $this->path . "{$data['hash']}_{$data['total']}_{$data['index']}.chunk"; $uploadFile->move($chunkName); if (($data['index'] + 1) == $data['total']) { return $this->mergeChunk($data); } return ['chunk' => $data['index'], 'status' => 'success']; } /** * 合并切片文件 * @param $data * @return array */ public function mergeChunk($data): array { $filePath = $this->path . $data['hash'] . '.' . $data['ext']; $fileHandle = fopen($filePath, 'w'); for ($i = 0; $i < $data['total']; ++$i) { $chunkFile = $this->path . "{$data['hash']}_{$data['total']}_{$i}.chunk"; if (!file_exists($chunkFile)) { throw new ApiException('Chunk file not found, please upload again'); } fwrite($fileHandle, file_get_contents($chunkFile)); unlink($chunkFile); } $domain = Arr::getConfigValue($this->config, 'local_domain'); $uri = Arr::getConfigValue($this->config, 'local_uri'); $baseUrl = $domain . $uri . $this->folder . '/'; $save_path = Arr::getConfigValue($this->config, 'local_root') . $this->folder . '/'; $object_name = $data['hash'] . '.' . $data['ext']; $info['storage_mode'] = 1; $info['category_id'] = 1; $info['origin_name'] = $data['name']; $info['object_name'] = $object_name; $info['hash'] = $data['hash']; $info['mime_type'] = $data['type']; $info['storage_path'] = $save_path . $object_name; $info['suffix'] = $data['ext']; $info['size_byte'] = $data['size']; $info['size_info'] = formatBytes($data['size']); $info['url'] = $baseUrl . $object_name; SystemAttachment::create($info); return $info; } }