feat: 成交指标新表+可控自动结算(默认关,仅新进结算中eligible)

按设计文档:SettlementTime起表;关开关清eligible;定时任务只结到期eligible单;打款走统一结单;指标从stats_since起幂等记账。不打开旧全局ORDER_AUTO_SETTLEMENT。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-27 01:28:44 +08:00
parent 97040c552e
commit 0e102fbcba
13 changed files with 840 additions and 26 deletions

View File

@@ -0,0 +1,22 @@
# 订单 AutoSettleEligible + jituan 成交/自动结算配置与指标表
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0015_merchantorderext_bossphone'),
]
operations = [
migrations.AddField(
model_name='order',
name='AutoSettleEligible',
field=models.BooleanField(
db_column='auto_settle_eligible',
db_index=True,
default=False,
verbose_name='允许自动结算',
),
),
]

View File

@@ -156,6 +156,11 @@ class Order(QModel):
null=True, blank=True,
db_column='status_8_time', verbose_name='状态变为8的时间',
)
# 可控自动结算:仅「俱乐部开启后新进入结算中」的单为 True老单永不置 True
AutoSettleEligible = models.BooleanField(
default=False, db_index=True,
db_column='auto_settle_eligible', verbose_name='允许自动结算',
)
# ---- 时间戳 ----
CreateTime = models.DateTimeField(
auto_now_add=True,

View File

@@ -6,11 +6,9 @@
import sys
import importlib
import logging
from django.db.models.signals import pre_save
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from django.conf import settings
from django.utils import timezone
from gvsdsdk.fluent import db, func, FQ
import logging
logger = logging.getLogger(__name__)
@@ -42,30 +40,42 @@ ensure_redis_loaded()
@receiver(pre_save, sender='orders.Order')
def handle_order_status_8(sender, instance, **kwargs):
"""
订单状态变为8时的信号处理。
ORDER_AUTO_SETTLEMENT_ENABLED=False 时不提交任何 Celery 超时结算任务。
订单进入/离开结算中(8)
- 写/清 SettlementTime进结算时刻
- 俱乐部自动结算开启后新进 8 → AutoSettleEligible否则永不 eligible老单安全
旧全局 ORDER_AUTO_SETTLEMENT_ENABLED 保持 False不投递旧延时任务。
"""
if not getattr(settings, 'ORDER_AUTO_SETTLEMENT_ENABLED', False):
if instance.pk is None:
return
try:
from orders.models import Order
old = Order.query.filter(pk=instance.pk).values_list('Status', flat=True).first()
if old != 8 and instance.Status == 8:
instance.SettlementTime = timezone.now()
instance.pending_dispatch = False
instance.auto_task_id = ''
instance.auto_expire_at = None
elif old == 8 and instance.Status != 8:
instance.SettlementTime = None
instance.pending_dispatch = False
instance.auto_task_id = ''
except Exception as e:
logger.error(f'信号处理失败: {e}')
if instance.pk is None:
return
try:
from orders.models import Order
from jituan.services.order_deal import apply_enter_status_8, apply_leave_status_8
# --- 以下原自动结算逻辑保留备查(开关打开时才启用,当前生产应为 False---
old = Order.query.filter(pk=instance.pk).values_list('Status', flat=True).first()
if old != 8 and instance.Status == 8:
apply_enter_status_8(instance)
elif old == 8 and instance.Status != 8:
# 成交时长:在清空 SettlementTime 前挂到实例上供 post_save 指标使用
instance._deal_settle_started_at = instance.SettlementTime
apply_leave_status_8(instance)
except Exception as e:
logger.error(f'结算中信号处理失败: {e}')
@receiver(post_save, sender='orders.Order')
def handle_order_deal_stats(sender, instance, created, **kwargs):
"""成交指标:入池 / 完成 / 退款(统计开关关闭或 since 前订单自动跳过)。"""
try:
from jituan.services import deal_stats as ds
if created:
return
# 入池:有打手且进行中/结算中/已完成等
if instance.PlayerID and instance.Status in (2, 3, 4, 5, 6, 8):
ds.on_order_enter_pool(instance)
if instance.Status == 3:
started = getattr(instance, '_deal_settle_started_at', None)
ds.on_order_completed(instance, settle_started_at=started)
elif instance.Status == 5:
ds.on_order_refunded(instance)
except Exception as e:
logger.error(f'成交指标信号处理失败: {e}')