diff --git a/apps/admin/src/api/uploads.ts b/apps/admin/src/api/uploads.ts new file mode 100644 index 0000000..9d70905 --- /dev/null +++ b/apps/admin/src/api/uploads.ts @@ -0,0 +1,18 @@ +/** + * 照片直传域(对齐 @photo/contracts tags [uploads]): + * init(预签名)→ PUT staging → complete(受理;处理异步)。 + * 管理端「上传照片」与 App 同链路(clientTaskId 幂等)。 + */ +import request from '@/utils/http' + +/** 初始化照片直传(返回 staging 直传凭证) */ +export function fetchInitUpload(data: Api.Album.UploadInitPayload) { + return request.post({ url: '/v1/uploads', data }) +} + +/** 完成直传(服务端核验后受理照片处理;返回 photoId) */ +export function fetchCompleteUpload(uploadId: string) { + return request.post({ + url: `/v1/uploads/${uploadId}/complete` + }) +} diff --git a/apps/admin/src/locales/langs/en.json b/apps/admin/src/locales/langs/en.json index a48ad6b..10eeea5 100644 --- a/apps/admin/src/locales/langs/en.json +++ b/apps/admin/src/locales/langs/en.json @@ -503,7 +503,11 @@ "batchColReason": "Reason", "view": "Details", "selectedCount": "{n} selected", - "onlyPublicSelectable": "Only published photos can be selected" + "onlyPublicSelectable": "Only published photos can be selected", + "upload": "Upload photos", + "uploadBadType": "unsupported type", + "uploadResult": "Uploaded: {ok} ok, {fail} failed", + "uploadResultAllOk": "Uploaded {ok}; visible when processed" }, "transfer": { "entry": "Transfer Owner", diff --git a/apps/admin/src/locales/langs/zh.json b/apps/admin/src/locales/langs/zh.json index 325fdb7..0d51a74 100644 --- a/apps/admin/src/locales/langs/zh.json +++ b/apps/admin/src/locales/langs/zh.json @@ -503,7 +503,11 @@ "batchColReason": "原因", "view": "详情", "selectedCount": "{n} 张已选", - "onlyPublicSelectable": "仅已公开照片可批量选择" + "onlyPublicSelectable": "仅已公开照片可批量选择", + "upload": "上传照片", + "uploadBadType": "类型不支持", + "uploadResult": "上传完成:成功 {ok} 张,失败 {fail} 张", + "uploadResultAllOk": "已上传 {ok} 张,处理完成后显示" }, "transfer": { "entry": "负责人交接", diff --git a/apps/admin/src/types/api/album.d.ts b/apps/admin/src/types/api/album.d.ts index 21dc9ec..e794d6e 100644 --- a/apps/admin/src/types/api/album.d.ts +++ b/apps/admin/src/types/api/album.d.ts @@ -202,6 +202,29 @@ declare namespace Api { /** 照片可见性 */ type PhotoVisibility = 'unpublished' | 'published' | 'hidden' | 'deleted' + /** 照片直传初始化请求(POST /v1/uploads;与 App 同链路) */ + interface UploadInitPayload { + albumId: string + clientTaskId: string + filename: string + bytes: number + contentType: 'image/jpeg' | 'image/png' | 'image/heic' + categoryId?: string + } + + /** 直传会话(init/renew 响应;PUT staging 后 complete 换取处理受理) */ + interface UploadSession { + uploadId: string + objectKey: string + credential: UploadCredential + } + + /** 直传完成响应(受理:处理异步,状态经照片列表 processingState 观察) */ + interface UploadCompleteResponse { + photoId: string + state: string + } + /** 照片处理状态 */ type PhotoProcessingState = 'pending_upload' | 'uploaded' | 'processing' | 'ready' | 'processing_failed' diff --git a/apps/admin/src/views/albums/detail/AlbumPhotos.vue b/apps/admin/src/views/albums/detail/AlbumPhotos.vue index 8bc6695..9a9e71f 100644 --- a/apps/admin/src/views/albums/detail/AlbumPhotos.vue +++ b/apps/admin/src/views/albums/detail/AlbumPhotos.vue @@ -37,6 +37,25 @@ :label="categoryLabel(category)" /> + + {{ t('albumsManage.photos.upload') }} + ({{ uploadingCount }}) + +