baseline: 批次A-D 成果 + membership 半成品(测试红)

This commit is contained in:
agent
2026-09-11 23:11:35 +08:00
commit b3f3095d53
311 changed files with 40540 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
"""全渠道与电商对接模型:
1. ChannelAccount 电商平台授权店铺配置(抖店、拼多多、1688 等)
2. ChannelOrder 外部拉取订单及本地销售订单映射
3. WebhookEvent 外部回调与事件分发日志
"""
from django.db import models
from apps.core.base_models import TenantScopedModel
class ChannelAccount(TenantScopedModel):
"""渠道授权店铺配置。"""
PLATFORM_CHOICES = [
("douyin", "抖音电商 / 抖店"),
("pinduoduo", "拼多多"),
("1688", "1688 阿里分销"),
("kuaishou", "快手小店"),
("custom", "自定义开放接口"),
]
platform = models.CharField(max_length=32, choices=PLATFORM_CHOICES, default="douyin")
shop_id = models.CharField(max_length=64, help_text="外部平台店铺ID")
shop_name = models.CharField(max_length=128, help_text="店铺名称")
app_key = models.CharField(max_length=128, blank=True, default="")
app_secret = models.CharField(max_length=255, blank=True, default="")
access_token = models.TextField(blank=True, default="")
refresh_token = models.TextField(blank=True, default="")
token_expires_at = models.DateTimeField(null=True, blank=True)
is_active = models.BooleanField(default=True)
# 业务映射默认值
default_warehouse = models.ForeignKey(
"inventory.Warehouse",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
help_text="该店铺订单默认出库仓库",
)
default_customer = models.ForeignKey(
"partner.Customer",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
help_text="该店铺归属的客户(挂账往来)",
)
class Meta:
db_table = "channel_account"
unique_together = [("tenant", "platform", "shop_id")]
verbose_name_plural = "电商店铺配置"
ordering = ["platform", "shop_name"]
def __str__(self):
return f"[{self.get_platform_display()}] {self.shop_name} ({self.shop_id})"
class ChannelOrder(TenantScopedModel):
"""外部渠道拉取的订单。"""
SYNC_STATUS_CHOICES = [
("pending", "待转单"),
("converted", "已转销售单"),
("failed", "转单失败"),
("ignored", "已忽略"),
]
channel_account = models.ForeignKey(
ChannelAccount,
on_delete=models.CASCADE,
related_name="orders",
)
external_order_id = models.CharField(max_length=128, help_text="外部平台订单号")
order_status = models.CharField(max_length=64, default="", help_text="外部平台订单状态(如 PAID, SHIPPED)")
order_amount = models.DecimalField(max_digits=18, decimal_places=4, default=0)
buyer_name = models.CharField(max_length=64, blank=True, default="")
buyer_phone = models.CharField(max_length=32, blank=True, default="")
receiver_address = models.CharField(max_length=255, blank=True, default="")
sync_status = models.CharField(max_length=16, choices=SYNC_STATUS_CHOICES, default="pending")
sync_error = models.TextField(blank=True, default="")
# 关联生成的本地销售单
sales_order = models.ForeignKey(
"sales.SalesOrder",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="channel_orders",
help_text="关联的内部销售订单",
)
raw_payload = models.JSONField(default=dict, blank=True, help_text="外部原始订单 JSON")
class Meta:
db_table = "channel_order"
unique_together = [("tenant", "channel_account", "external_order_id")]
verbose_name_plural = "渠道订单"
indexes = [
models.Index(fields=["tenant", "sync_status"]),
models.Index(fields=["tenant", "external_order_id"]),
]
ordering = ["-created_at"]
def __str__(self):
return f"{self.channel_account.shop_name} 订单: {self.external_order_id} [{self.sync_status}]"
class WebhookEvent(TenantScopedModel):
"""Webhook 回调与事件分发日志。"""
DIRECTION_CHOICES = [
("inbound", "外部推送回调"),
("outbound", "本系统向外推送"),
]
STATUS_CHOICES = [
("received", "已接收"),
("processed", "处理成功"),
("failed", "处理失败"),
]
direction = models.CharField(max_length=16, choices=DIRECTION_CHOICES, default="inbound")
event_type = models.CharField(max_length=64, help_text="事件类型,如 order.paid, stock.changed")
source = models.CharField(max_length=32, default="douyin", help_text="来源系统或平台")
payload = models.JSONField(default=dict, blank=True)
status = models.CharField(max_length=16, choices=STATUS_CHOICES, default="received")
error_message = models.TextField(blank=True, default="")
class Meta:
db_table = "channel_webhook_event"
verbose_name_plural = "Webhook事件日志"
ordering = ["-created_at"]