1
0
forked from erp-dev/erp

feat: added mdy stagging upload to tiia, and change outgoing_date to datetime type

This commit is contained in:
2026-01-22 17:06:23 +08:00
parent 49ac17cf37
commit 7fd44c64aa
18 changed files with 661 additions and 11 deletions

View File

@@ -19,6 +19,10 @@ from flower.utils import (
fetch_customers_from_mingdaoyun,
)
from api_v1.mdy_plate_order_sync import sync_mdy_plate_orders_to_staging
from api_v1.mdy_plate_order_staging_tiia_upload import (
build_default_tiia_rate_limiter,
upload_mdy_plate_order_staging_plate_images_to_tencent_tiia,
)
logger = logging.getLogger(__name__)
@@ -475,6 +479,128 @@ def sync_mdy_plate_orders(
return payload
def _record_mdy_plate_order_staging_tiia_failure(
*,
run_date,
staging: api_models.MDYPlateOrderStaging,
error: str,
details: list[dict] | None = None,
) -> None:
"""
记录“开版暂存 -> TIIA 上传”失败(同一天同一 mdy_rowid 去重attempts 累加)。
"""
obj, _created = api_models.MDYPlateOrderStagingTiiaUploadFailure.objects.get_or_create(
run_date=run_date,
mdy_rowid=staging.mdy_rowid,
defaults={
"staging_id": staging.id,
"error": error or "",
"details": details or [],
"attempts": 0,
"last_attempt_at": timezone.now(),
},
)
obj.staging_id = staging.id
obj.error = error or ""
obj.details = details or []
obj.attempts = int(obj.attempts or 0) + 1
obj.last_attempt_at = timezone.now()
obj.save(update_fields=["staging_id", "error", "details", "attempts", "last_attempt_at", "updated_at"])
@shared_task(bind=True)
def upload_mdy_plate_order_staging_images_to_tencent_tiia(
self,
batch_size: int = 200,
*,
dry_run: bool = False,
):
"""
将 MDYPlateOrderStaging 的“开版图Attachment”上传到腾讯云 TIIA 图库(增量)。
- 游标:使用 api_data_sync.last_rowid 存储 staging 表的 last_id自增主键
- 失败:写入 api_mdy_plate_order_staging_tiia_upload_failure不影响后续继续跑
- 限流:按 settings.TENCENTCLOUD_TIIA_QPS默认 10 qps
"""
run_date = timezone.localdate()
limiter = build_default_tiia_rate_limiter()
last_sync = (
api_models.DataSync.objects.filter(
table_name=api_models.DataSync.TableName.MDY_PLATE_ORDER_STAGING_TIIA_UPLOAD
)
.order_by("-created_at")
.first()
)
last_id = 0
if last_sync and (last_sync.last_rowid or "").strip():
try:
last_id = int(last_sync.last_rowid)
except ValueError:
last_id = 0
qs = api_models.MDYPlateOrderStaging.objects.filter(id__gt=last_id).order_by("id")
if batch_size and batch_size > 0:
qs = qs[:batch_size]
processed = 0
failed_records = 0
latest_id = last_id
latest_ctime = last_sync.last_ctime if last_sync else None
for staging in qs:
processed += 1
latest_id = staging.id
if staging.ctime:
latest_ctime = staging.ctime
try:
result = upload_mdy_plate_order_staging_plate_images_to_tencent_tiia(
staging=staging,
rate_limiter=limiter,
dry_run=dry_run,
)
if int(result.get("failure_count") or 0) > 0:
failed_records += 1
_record_mdy_plate_order_staging_tiia_failure(
run_date=run_date,
staging=staging,
error="部分图片上传失败" if int(result.get("success_count") or 0) > 0 else "图片上传失败",
details=[{"result": result}],
)
except Exception as exc:
failed_records += 1
_record_mdy_plate_order_staging_tiia_failure(
run_date=run_date,
staging=staging,
error=str(exc),
details=[{"error": str(exc), "mdy_rowid": staging.mdy_rowid, "staging_id": staging.id}],
)
api_models.DataSync.objects.create(
table_name=api_models.DataSync.TableName.MDY_PLATE_ORDER_STAGING_TIIA_UPLOAD,
page_index=1,
page_size=batch_size,
synced_rows=processed,
total_count=api_models.MDYPlateOrderStaging.objects.count(),
last_ctime=latest_ctime,
last_rowid=str(latest_id) if latest_id else str(last_id),
note=f"id scan; dry_run={dry_run}",
)
payload = {
"task_id": self.request.id,
"processed": processed,
"failed_records": failed_records,
"last_id": latest_id,
"last_ctime": latest_ctime.isoformat() if latest_ctime else None,
"dry_run": dry_run,
"batch_size": batch_size,
}
logger.info("MDY 开版暂存图片上传到 TIIA 完成: %s", payload)
return payload
@shared_task
def save_api_audit_log(
url: str,