1
0
forked from erp-dev/erp

feat: hpname and external_order_id + product_name unique together

This commit is contained in:
2026-03-23 19:06:11 +08:00
parent b58667ca52
commit eb5fae1ce7
6 changed files with 251 additions and 10 deletions

View File

@@ -0,0 +1,90 @@
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q
from api_v1.tasks import _fetch_external_product_image, _upload_product_image
from basic_info.models import Product
class Command(BaseCommand):
help = '为没有图片的 Product 通过外部 image API 回补图片(使用 name_b64=base64url(product.name)'
def add_arguments(self, parser):
parser.add_argument('--merchant-id', type=int, help='仅处理指定商户的产品')
parser.add_argument('--product-id', type=int, help='仅处理指定产品')
parser.add_argument('--limit', type=int, help='最多处理多少条产品')
parser.add_argument(
'--dry-run',
action='store_true',
help='仅输出将处理的产品,不实际请求外部 API 或写库',
)
def handle(self, *args, **options):
queryset = Product.objects.filter(
Q(image__isnull=True) | Q(image=''),
).exclude(
name__isnull=True,
).exclude(
name='',
).select_related('merchant')
merchant_id = options.get('merchant_id')
if merchant_id:
queryset = queryset.filter(merchant_id=merchant_id)
product_id = options.get('product_id')
if product_id:
queryset = queryset.filter(id=product_id)
queryset = queryset.order_by('id')
limit = options.get('limit')
if limit is not None:
if int(limit) <= 0:
raise CommandError('--limit 必须大于 0')
queryset = queryset[: int(limit)]
products = list(queryset)
self.stdout.write(f'待处理产品数: {len(products)}')
if options.get('dry_run'):
for product in products:
self.stdout.write(
f'[DRY-RUN] product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
)
self.stdout.write(self.style.SUCCESS('dry-run 完成'))
return
success_count = 0
failed_count = 0
skipped_count = 0
for product in products:
if product.image:
skipped_count += 1
continue
try:
image_payload = _fetch_external_product_image(product.name)
_upload_product_image(product, image_payload)
except Exception as exc:
failed_count += 1
self.stderr.write(
self.style.ERROR(
f'补图失败: product_id={product.id} merchant_id={product.merchant_id} '
f'name={product.name} error={exc}'
)
)
continue
success_count += 1
self.stdout.write(
self.style.SUCCESS(
f'补图成功: product_id={product.id} merchant_id={product.merchant_id} name={product.name}'
)
)
self.stdout.write(
self.style.SUCCESS(
f'完成: total={len(products)} success={success_count} failed={failed_count} skipped={skipped_count}'
)
)