(data: InitChunkUploadModel = Depends(parse_init_chunk_upload))
| 347 | |
| 348 | @chunk_api.post("/upload/init/", dependencies=[Depends(share_required_login)]) |
| 349 | async def init_chunk_upload(data: InitChunkUploadModel = Depends(parse_init_chunk_upload)): |
| 350 | validate_file_type(data.file_name) |
| 351 | # 服务端校验:根据 total_chunks * chunk_size 计算理论最大上传量 |
| 352 | total_chunks = (data.file_size + data.chunk_size - 1) // data.chunk_size |
| 353 | max_possible_size = total_chunks * data.chunk_size |
| 354 | if max_possible_size > settings.uploadSize: |
| 355 | max_size_mb = settings.uploadSize / (1024 * 1024) |
| 356 | raise HTTPException( |
| 357 | status_code=403, detail=f"文件大小超过限制,最大为 {max_size_mb:.2f} MB" |
| 358 | ) |
| 359 | |
| 360 | # # 秒传检查 |
| 361 | # existing = await FileCodes.filter(file_hash=data.file_hash).first() |
| 362 | # if existing: |
| 363 | # if await existing.is_expired(): |
| 364 | # file_storage: FileStorageInterface = storages[settings.file_storage]( |
| 365 | # ) |
| 366 | # await file_storage.delete_file(existing) |
| 367 | # await existing.delete() |
| 368 | # else: |
| 369 | # return APIResponse(detail={ |
| 370 | # "code": existing.code, |
| 371 | # "existed": True, |
| 372 | # "name": f'{existing.prefix}{existing.suffix}' |
| 373 | # }) |
| 374 | |
| 375 | # 断点续传:检查是否存在相同文件的未完成上传会话 |
| 376 | existing_session = await UploadChunk.filter( |
| 377 | chunk_hash=data.file_hash, |
| 378 | chunk_index=-1, |
| 379 | file_size=data.file_size, |
| 380 | file_name=data.file_name, |
| 381 | ).first() |
| 382 | |
| 383 | if existing_session: |
| 384 | if not existing_session.save_path: |
| 385 | await UploadChunk.filter(upload_id=existing_session.upload_id).delete() |
| 386 | else: |
| 387 | uploaded_chunks = await UploadChunk.filter( |
| 388 | upload_id=existing_session.upload_id, completed=True |
| 389 | ).values_list("chunk_index", flat=True) |
| 390 | return APIResponse( |
| 391 | detail={ |
| 392 | "existed": False, |
| 393 | "upload_id": existing_session.upload_id, |
| 394 | "chunk_size": existing_session.chunk_size, |
| 395 | "total_chunks": existing_session.total_chunks, |
| 396 | "uploaded_chunks": list(uploaded_chunks), |
| 397 | } |
| 398 | ) |
| 399 | |
| 400 | # 创建新的上传会话 |
| 401 | upload_id = uuid.uuid4().hex |
| 402 | _, _, _, _, save_path = await get_chunk_file_path_name(data.file_name, upload_id) |
| 403 | await UploadChunk.create( |
| 404 | upload_id=upload_id, |
| 405 | chunk_index=-1, |
| 406 | total_chunks=total_chunks, |
nothing calls this directly
no test coverage detected