feat(mobile): upload engine with preparation, batching states and retries
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -81,8 +81,9 @@ class UploadCredential {
|
||||
/// `initUpload`,POST /uploads):幂等初始化——相同 clientTaskId 且参数
|
||||
/// 一致时返回原会话,参数不一致 409(UPLOAD_SESSION_CONFLICT)。
|
||||
///
|
||||
/// 注:契约增补(P3 计划 Task 3)将顺带加入可选 sourceDeviceId
|
||||
/// (A19 设备来源语义);当前以契约现状为准,不含该字段。
|
||||
/// sourceDeviceId 为 P3 Task 3 契约增补(已落地):客户端首次生成并
|
||||
/// 持久的设备标识(A19 设备来源语义,见 core/device_id.dart);可选,
|
||||
/// 同一 clientTaskId 幂等重放时服务端保留首次落库的值。
|
||||
class UploadInitRequest {
|
||||
const UploadInitRequest({
|
||||
required this.albumId,
|
||||
@@ -91,6 +92,7 @@ class UploadInitRequest {
|
||||
required this.bytes,
|
||||
required this.contentType,
|
||||
this.categoryId,
|
||||
this.sourceDeviceId,
|
||||
});
|
||||
|
||||
/// 目标相册 ID。
|
||||
@@ -111,6 +113,9 @@ class UploadInitRequest {
|
||||
/// MIME 类型(白名单 image/jpeg | image/png | image/heic)。
|
||||
final String contentType;
|
||||
|
||||
/// 发起设备标识(可选,minLength 8 / maxLength 64;A19)。
|
||||
final String? sourceDeviceId;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'albumId': albumId,
|
||||
if (categoryId != null) 'categoryId': categoryId,
|
||||
@@ -118,6 +123,7 @@ class UploadInitRequest {
|
||||
'filename': filename,
|
||||
'bytes': bytes,
|
||||
'contentType': contentType,
|
||||
if (sourceDeviceId != null) 'sourceDeviceId': sourceDeviceId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -243,6 +249,7 @@ class UploadSessionRecord {
|
||||
required this.contentType,
|
||||
required this.createdAt,
|
||||
required this.photo,
|
||||
this.sourceDeviceId,
|
||||
});
|
||||
|
||||
factory UploadSessionRecord.fromJson(Map<String, dynamic> json) =>
|
||||
@@ -257,6 +264,7 @@ class UploadSessionRecord {
|
||||
photo: UploadSessionPhoto.fromJson(
|
||||
json['photo'] as Map<String, dynamic>,
|
||||
),
|
||||
sourceDeviceId: json['sourceDeviceId'] as String?,
|
||||
);
|
||||
|
||||
/// 上传会话 ID。
|
||||
@@ -280,6 +288,9 @@ class UploadSessionRecord {
|
||||
/// 会话创建时间。
|
||||
final DateTime createdAt;
|
||||
|
||||
/// 发起设备标识(init 时未携带为 null;P3 Task 3 契约增补,A19)。
|
||||
final String? sourceDeviceId;
|
||||
|
||||
/// 会话关联照片的当前状态。
|
||||
final UploadSessionPhoto photo;
|
||||
|
||||
@@ -291,6 +302,7 @@ class UploadSessionRecord {
|
||||
'expectedBytes': expectedBytes,
|
||||
'contentType': contentType,
|
||||
'createdAt': createdAt.toUtc().toIso8601String(),
|
||||
if (sourceDeviceId != null) 'sourceDeviceId': sourceDeviceId,
|
||||
'photo': photo.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user