fix: separate penalty czjilu from merchant recharge and correct finance stats

This commit is contained in:
XingQue
2026-06-27 18:50:32 +08:00
parent 65477592af
commit 54f8e23488
9 changed files with 249 additions and 240 deletions

View File

@@ -7663,228 +7663,29 @@ class CwqtczhqView(APIView):
if 'qtczcaiwu' not in permissions:
return Response({'code': 403, 'msg': '无其他充值财务查看权限'}, status=403)
from jituan.services.finance_detail_stats import build_chongzhi_finance_payload
granularity = request.data.get('granularity', 'day')
year = request.data.get('year')
month = request.data.get('month')
types = request.data.get('types', [2, 3, 4, 5, 6]) # 默认全部
types = request.data.get('types', [2, 3, 4, 5, 6])
summary_date = request.data.get('summary_date')
if isinstance(types, list) and len(types) == 0:
types = [2, 3, 4, 5, 6]
now = date.today()
data, err = build_chongzhi_finance_payload(
request, granularity, year, month, types, summary_date,
)
if err:
return Response({'code': 1, 'msg': err}, status=400)
# ---------- 时间范围(用于曲线图) ----------
if granularity == 'day':
if not year or not month:
return Response({'code': 1, 'msg': '按日统计需要年份和月份'}, status=400)
start_date = date(year, month, 1)
end_date = date(year, month + 1, 1) if month < 12 else date(year + 1, 1, 1)
trunc_func = TruncDate('CreateTime')
# 默认汇总日期
if not summary_date:
summary_date = now.strftime('%Y-%m-%d')
summary_q = datetime.strptime(summary_date, '%Y-%m-%d').date()
elif granularity == 'month':
if not year:
return Response({'code': 1, 'msg': '按月统计需要年份'}, status=400)
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncMonth('CreateTime')
if not summary_date:
summary_date = now.strftime('%Y-%m')
summary_q = datetime.strptime(summary_date + '-01', '%Y-%m-%d').date()
elif granularity == 'year':
year = year or now.year
start_date = date(year, 1, 1)
end_date = date(year + 1, 1, 1)
trunc_func = TruncYear('CreateTime')
if not summary_date:
summary_date = str(year)
summary_q = date(year, 1, 1)
else:
return Response({'code': 1, 'msg': '无效的颗粒度'}, status=400)
start_dt = datetime.combine(start_date, datetime.min.time())
end_dt = datetime.combine(end_date, datetime.min.time())
# ---------- 构建时间序列 ----------
time_series_map = {} # period_str -> { type_code: {count, amount, profit, fenhong_count, fenhong_amount} }
def ensure_date(ds):
if ds not in time_series_map:
time_series_map[ds] = {}
return time_series_map[ds]
# 1. 处理充值记录Czjilu—— 完全不变
cz_types = [t for t in types if t in [2, 3, 4, 5]]
if cz_types:
cz_qs = filter_queryset_by_club(
Czjilu.query.filter(
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
leixing__in=cz_types,
zhuangtai=3,
),
request,
).annotate(
period=trunc_func
).values('period', 'leixing').annotate(
total_count=Count('id'),
total_amount=Sum('jine')
).order_by('period', 'leixing')
for item in cz_qs:
period_str = item['period'].strftime('%Y-%m-%d') if granularity == 'day' else \
item['period'].strftime('%Y-%m') if granularity == 'month' else \
item['period'].strftime('%Y')
lx = item['leixing']
amount = float(item['total_amount'] or 0)
count = item['total_count']
# 收益:积分(3)收益为金额本身其他为0
profit = amount if lx == 3 else 0.0
day_data = ensure_date(period_str)
day_data[str(lx)] = {
'count': count,
'amount': amount,
'profit': profit,
'fenhong_count': 0, # 充值类型无分红
'fenhong_amount': 0.0
}
# 2. 处理罚款Penalty—— 修改:直接从 Penalty 表获取分红总额和分红笔数
if 6 in types:
# 使用一次聚合查询,同时获取罚款笔数、罚款金额、分红总额、分红笔数
penalty_qs = filter_penalty_qs(
Penalty.query.filter(
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
Status=2,
),
request,
).annotate(
period=trunc_func
).values('period').annotate(
penalty_count=Count('id'),
penalty_amount=Sum('FineAmount'),
# 直接使用罚单表中的申请人分红金额字段
fenhong_amount=Sum('ApplicantBonusAmount'),
fenhong_count=Count('id', filter=Q(ApplicantBonusAmount__gt=0))
).order_by('period')
for item in penalty_qs:
period_str = item['period'].strftime('%Y-%m-%d') if granularity == 'day' else \
item['period'].strftime('%Y-%m') if granularity == 'month' else \
item['period'].strftime('%Y')
day_data = ensure_date(period_str)
penalty_amt = float(item['penalty_amount'] or 0)
fenhong_amt = float(item['fenhong_amount'] or 0)
profit = round(penalty_amt - fenhong_amt, 2)
day_data['6'] = {
'count': item['penalty_count'],
'amount': penalty_amt,
'profit': profit,
'fenhong_count': item['fenhong_count'],
'fenhong_amount': fenhong_amt
}
# 构造有序时间序列列表
time_series = []
for period_str in sorted(time_series_map.keys()):
entry = {'date': period_str, 'types': {}}
for type_code in sorted(time_series_map[period_str].keys()):
entry['types'][type_code] = time_series_map[period_str][type_code]
time_series.append(entry)
# ---------- 汇总指定日期summary—— 完全保留原逻辑,仅将罚款部分改为从 Penalty 表直接取分红 ----------
summary_result = {'by_type': {}, 'total_count': 0, 'total_amount': 0.0, 'total_profit': 0.0}
# 汇总充值类型(完全不变)
for lx in cz_types:
filter_kwargs = {
'leixing': lx,
'zhuangtai': 3,
}
if granularity == 'day':
filter_kwargs['CreateTime__date'] = summary_q
elif granularity == 'month':
filter_kwargs['CreateTime__year'] = summary_q.year
filter_kwargs['CreateTime__month'] = summary_q.month
else:
filter_kwargs['CreateTime__year'] = summary_q.year
agg = filter_queryset_by_club(
Czjilu.query.filter(**filter_kwargs), request,
).aggregate(count=Count('id'), amount=Sum('jine'))
count = agg['count'] or 0
amount = float(agg['amount'] or 0)
profit = amount if lx == 3 else 0.0
summary_result['by_type'][str(lx)] = {
'count': count,
'amount': round(amount, 2),
'profit': round(profit, 2),
'fenhong_count': 0,
'fenhong_amount': 0.0
}
summary_result['total_count'] += count
summary_result['total_amount'] += amount
summary_result['total_profit'] += profit
# 汇总罚款(修改:从 Penalty 表直接取分红,不再查询 PenaltyBonus
if 6 in types:
penalty_filter = {
'Status': 2,
}
if granularity == 'day':
penalty_filter['CreateTime__date'] = summary_q
elif granularity == 'month':
penalty_filter['CreateTime__year'] = summary_q.year
penalty_filter['CreateTime__month'] = summary_q.month
else:
penalty_filter['CreateTime__year'] = summary_q.year
# 一次聚合:罚款笔数、金额、分红总额、分红笔数
agg = filter_penalty_qs(
Penalty.query.filter(**penalty_filter), request,
).aggregate(
count=Count('id'),
amount=Sum('FineAmount'),
fenhong_amount=Sum('ApplicantBonusAmount'),
fenhong_count=Count('id', filter=Q(ApplicantBonusAmount__gt=0))
)
penalty_count = agg['count'] or 0
penalty_amount = float(agg['amount'] or 0)
fh_amount = float(agg['fenhong_amount'] or 0)
fh_count = agg['fenhong_count'] or 0
profit = round(penalty_amount - fh_amount, 2)
summary_result['by_type']['6'] = {
'count': penalty_count,
'amount': round(penalty_amount, 2),
'profit': profit,
'fenhong_count': fh_count,
'fenhong_amount': round(fh_amount, 2)
}
summary_result['total_count'] += penalty_count
summary_result['total_amount'] += penalty_amount
summary_result['total_profit'] += profit
summary_result['total_amount'] = round(summary_result['total_amount'], 2)
summary_result['total_profit'] = round(summary_result['total_profit'], 2)
return Response({
'code': 0,
'msg': 'ok',
'data': {
'time_series': time_series,
'summary': summary_result
}
})
return Response({'code': 0, 'msg': 'ok', 'data': data})
except Exception as e:
logger.exception("CwqtczhqView 接口错误")
return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500)
'''class CwqtczhqView(APIView):
'''class CwqtczhqView_LEGACY(APIView):
"""
其他充值/罚款数据统计(非会员充值)
POST /houtai/cwqtczhq

View File

@@ -20,6 +20,12 @@ def _club_id_from_user_uid(uid):
return None
def penalty_cz_club_id(fadan):
"""罚款支付 czjilu.club_id与罚单归属一致申请人俱乐部"""
cid = (getattr(fadan, 'ClubID', None) or '').strip()
return cid or CLUB_ID_DEFAULT
def resolve_penalty_club_id(
order=None,
penalized_user_id=None,

View File

@@ -1,7 +1,8 @@
"""财务子模块统计(订单/会员/其他充值),供 /jituan/houtai/*;旧 /houtai/* 不变。"""
from datetime import date, datetime
from decimal import Decimal
from django.db.models import Count, Q, Sum
from django.db.models import Case, Count, DecimalField, Q, Sum, Value, When
from django.db.models.functions import TruncDate, TruncMonth, TruncYear
from jituan.constants import DATA_SCOPE_ALL
@@ -13,6 +14,7 @@ from jituan.services.club_context import (
)
from jituan.services.club_penalty import filter_gsfenhong_qs, filter_penalty_qs
from orders.models import Order, Penalty
from products.czjilu_types import CZJILU_LEIXING_SHANGJIA, exclude_penalty_from_cz_qs
from products.models import Czjilu, Gsfenhong, Huiyuan, ShangpinLeixing
from rank.models import Bankuai
@@ -77,6 +79,57 @@ def _summary_date_filter(granularity, summary_q, field_prefix='CreateTime'):
return {f'{field_prefix}__year': summary_q.year}
def _penalty_trunc_func(granularity):
if granularity == 'day':
return TruncDate('UpdateTime')
if granularity == 'month':
return TruncMonth('UpdateTime')
return TruncYear('UpdateTime')
def _penalty_fenhong_aggregates():
"""罚款分红只统计已入账BonusCredited与 process_fadan_fenhong 一致。"""
zero = Value(Decimal('0.00'), output_field=DecimalField(max_digits=12, decimal_places=2))
return {
'fenhong_amount': Sum(
Case(
When(BonusCredited=True, then='ApplicantBonusAmount'),
default=zero,
output_field=DecimalField(max_digits=12, decimal_places=2),
)
),
'fenhong_count': Count(
'id',
filter=Q(BonusCredited=True, ApplicantBonusAmount__gt=0),
),
}
def _czjilu_finance_qs(request, start_dt, end_dt, cz_types):
"""充值财务 czjilu已支付type4 排除罚款误标。"""
qs = filter_queryset_by_club(
Czjilu.query.filter(
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
leixing__in=cz_types,
zhuangtai=3,
),
request,
)
if CZJILU_LEIXING_SHANGJIA in cz_types:
qs = exclude_penalty_from_cz_qs(qs)
return qs
def _czjilu_summary_qs(request, lx, granularity, summary_q):
filter_kwargs = {'leixing': lx, 'zhuangtai': 3}
filter_kwargs.update(_summary_date_filter(granularity, summary_q))
qs = filter_queryset_by_club(Czjilu.query.filter(**filter_kwargs), request)
if lx == CZJILU_LEIXING_SHANGJIA:
qs = exclude_penalty_from_cz_qs(qs)
return qs
def build_order_types_payload():
types = ShangpinLeixing.query.filter(shenhezhuangtai=1).values('id', 'jieshao')
return list(types)
@@ -209,15 +262,9 @@ def build_chongzhi_finance_payload(request, granularity, year, month, types=None
cz_types = [t for t in types if t in [2, 3, 4, 5]]
if cz_types:
cz_qs = filter_queryset_by_club(
Czjilu.query.filter(
CreateTime__gte=start_dt,
CreateTime__lt=end_dt,
leixing__in=cz_types,
zhuangtai=3,
),
request,
).annotate(period=trunc_func).values('period', 'leixing').annotate(
cz_qs = _czjilu_finance_qs(request, start_dt, end_dt, cz_types).annotate(
period=trunc_func,
).values('period', 'leixing').annotate(
total_count=Count('id'),
total_amount=Sum('jine'),
).order_by('period', 'leixing')
@@ -242,14 +289,18 @@ def build_chongzhi_finance_payload(request, granularity, year, month, types=None
}
if 6 in types:
penalty_trunc = _penalty_trunc_func(granularity)
penalty_qs = filter_penalty_qs(
Penalty.query.filter(CreateTime__gte=start_dt, CreateTime__lt=end_dt, Status=2),
Penalty.query.filter(
UpdateTime__gte=start_dt,
UpdateTime__lt=end_dt,
Status=2,
),
request,
).annotate(period=trunc_func).values('period').annotate(
).annotate(period=penalty_trunc).values('period').annotate(
penalty_count=Count('id'),
penalty_amount=Sum('FineAmount'),
fenhong_amount=Sum('ApplicantBonusAmount'),
fenhong_count=Count('id', filter=Q(ApplicantBonusAmount__gt=0)),
**_penalty_fenhong_aggregates(),
).order_by('period')
for item in penalty_qs:
@@ -279,9 +330,7 @@ def build_chongzhi_finance_payload(request, granularity, year, month, types=None
summary_result = {'by_type': {}, 'total_count': 0, 'total_amount': 0.0, 'total_profit': 0.0}
for lx in cz_types:
filter_kwargs = {'leixing': lx, 'zhuangtai': 3}
filter_kwargs.update(_summary_date_filter(granularity, summary_q))
agg = filter_queryset_by_club(Czjilu.query.filter(**filter_kwargs), request).aggregate(
agg = _czjilu_summary_qs(request, lx, granularity, summary_q).aggregate(
count=Count('id'), amount=Sum('jine'),
)
count = agg['count'] or 0
@@ -300,12 +349,11 @@ def build_chongzhi_finance_payload(request, granularity, year, month, types=None
if 6 in types:
penalty_filter = {'Status': 2}
penalty_filter.update(_summary_date_filter(granularity, summary_q))
penalty_filter.update(_summary_date_filter(granularity, summary_q, field_prefix='UpdateTime'))
agg = filter_penalty_qs(Penalty.query.filter(**penalty_filter), request).aggregate(
count=Count('id'),
amount=Sum('FineAmount'),
fenhong_amount=Sum('ApplicantBonusAmount'),
fenhong_count=Count('id', filter=Q(ApplicantBonusAmount__gt=0)),
**_penalty_fenhong_aggregates(),
)
penalty_count = agg['count'] or 0
penalty_amount = float(agg['amount'] or 0)

View File

@@ -309,8 +309,8 @@ def sync_szjilu_income_from_logs():
# 订单已付款且非退款repair 错误地把 Status=5 退款单也计入了收入)
_ORDER_INCOME_STATUSES = [1, 2, 3, 4, 6, 7, 8]
# 微信充值类 czjilu会员/押金/积分/商家/罚单/考核
_CZ_WECHAT_LEIXING = [1, 2, 3, 4, 5]
# 微信充值类 czjilu会员/押金/积分/商家/考核/罚款
_CZ_WECHAT_LEIXING = [1, 2, 3, 4, 5, 6]
def collect_canonical_wechat_income_for_date(stat_date, existing_refs=None):
@@ -701,7 +701,7 @@ def reset_all_daily_szjilu():
# 合法微信支付收入(不含退款 Status=5
_LEGIT_ORDER_STATUSES = [1, 2, 3, 4, 6, 7, 8]
_LEGIT_CZ_LEIXING = [1, 2, 3, 4, 5]
_LEGIT_CZ_LEIXING = [1, 2, 3, 4, 5, 6]
def collect_legitimate_wechat_payments(since_year, until_year):

81
products/czjilu_types.py Normal file
View File

@@ -0,0 +1,81 @@
"""czjilu 充值类型常量与查询辅助(避免罚款与商家充值混用 leixing=4"""
from django.conf import settings
from django.db.models import Q
# 与 czjilu.leixing 一致
CZJILU_LEIXING_HUIYUAN = 1
CZJILU_LEIXING_YAJIN = 2
CZJILU_LEIXING_JIFEN = 3
CZJILU_LEIXING_SHANGJIA = 4
CZJILU_LEIXING_KAOHE = 5
CZJILU_LEIXING_FAKUAN = 6
CZJILU_PAID_STATUS = 3
FAKUAN_ORDER_PREFIX = 'FK'
PENALTY_SHUOMING_MARKER = '罚款'
PENALTY_FADAN_TAG = '#fadan:'
def penalty_cz_shuoming(fadan_id):
"""罚款微信支付/抵扣流水说明(含罚单 ID 便于对账)。"""
desc = getattr(settings, 'FAKUAN_PAY_DESCRIPTION', '罚款缴纳')
return f'{desc}{PENALTY_FADAN_TAG}{fadan_id}'
def is_legacy_penalty_leixing4(cz):
"""历史误写 leixing=4 的罚款流水。"""
dingdan = (getattr(cz, 'dingdan_id', None) or '').strip()
shuoming = (getattr(cz, 'shuoming', None) or '')
if dingdan.startswith(FAKUAN_ORDER_PREFIX):
return True
if PENALTY_SHUOMING_MARKER in shuoming:
return True
if PENALTY_FADAN_TAG in shuoming:
return True
return False
def is_penalty_czjilu(cz):
leixing = getattr(cz, 'leixing', None)
if leixing == CZJILU_LEIXING_FAKUAN:
return True
if leixing == CZJILU_LEIXING_SHANGJIA:
return is_legacy_penalty_leixing4(cz)
return False
def is_merchant_recharge_czjilu(cz):
return (
getattr(cz, 'leixing', None) == CZJILU_LEIXING_SHANGJIA
and not is_legacy_penalty_leixing4(cz)
)
def exclude_penalty_from_cz_qs(qs):
"""从 czjilu 查询中排除罚款流水(含历史 leixing=4 误标)。"""
return qs.exclude(
Q(leixing=CZJILU_LEIXING_FAKUAN)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, dingdan_id__startswith=FAKUAN_ORDER_PREFIX)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_SHUOMING_MARKER)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_FADAN_TAG)
)
def merchant_recharge_cz_qs(qs):
"""仅真·商家余额充值(微信 CzSJ… 或 leixing=4 且非罚款)。"""
prefix = getattr(settings, 'SHANGJIA_CZ_PREFIX', 'CzSJ')
return exclude_penalty_from_cz_qs(qs).filter(
leixing=CZJILU_LEIXING_SHANGJIA,
dingdan_id__startswith=prefix,
)
def penalty_payment_cz_qs(qs):
"""罚款支付流水(微信 FK… 或 leixing=6 / 历史误标)。"""
return qs.filter(
Q(leixing=CZJILU_LEIXING_FAKUAN)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, dingdan_id__startswith=FAKUAN_ORDER_PREFIX)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_SHUOMING_MARKER)
| Q(leixing=CZJILU_LEIXING_SHANGJIA, shuoming__icontains=PENALTY_FADAN_TAG)
)

View File

@@ -0,0 +1,41 @@
# 历史罚款 czjilu 从 leixing=4 纠正为 6club_id 对齐罚单申请人俱乐部
from django.db import migrations
from products.czjilu_types import (
CZJILU_LEIXING_FAKUAN,
CZJILU_LEIXING_SHANGJIA,
is_legacy_penalty_leixing4,
)
def _backfill_penalty_czjilu(apps, schema_editor):
Czjilu = apps.get_model('products', 'Czjilu')
Penalty = apps.get_model('orders', 'Penalty')
for cz in Czjilu.objects.filter(leixing=CZJILU_LEIXING_SHANGJIA).iterator():
if not is_legacy_penalty_leixing4(cz):
continue
updates = {'leixing': CZJILU_LEIXING_FAKUAN}
shuoming = (cz.shuoming or '')
if '#fadan:' in shuoming:
try:
fadan_id = int(shuoming.split('#fadan:')[1].split()[0].strip())
fadan = Penalty.objects.filter(id=fadan_id).first()
if fadan and getattr(fadan, 'ClubID', None):
updates['club_id'] = fadan.ClubID
except (ValueError, IndexError):
pass
Czjilu.objects.filter(pk=cz.pk).update(**updates)
class Migration(migrations.Migration):
dependencies = [
('products', '0006_member_trial_fields'),
('orders', '0009_penalty_bonus_lock_fields'),
]
operations = [
migrations.RunPython(_backfill_penalty_czjilu, migrations.RunPython.noop),
]

View File

@@ -215,7 +215,10 @@ class Czjilu(QModel):
zhuangtai = models.IntegerField(null=True, blank=True, verbose_name='订单状态')
yonghuid = models.CharField(max_length=7, db_index=True, verbose_name='用户ID')
jine = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='订单金额')
leixing = models.IntegerField(null=True, blank=True, verbose_name='充值类型1:会员2:押金,3:积分,4:商家')
leixing = models.IntegerField(
null=True, blank=True,
verbose_name='充值类型1:会员2:押金3:积分4:商家充值5:考核6:罚款缴纳',
)
shuoming = models.CharField(max_length=100, null=True, blank=True, verbose_name='订单说明')
club_id = models.CharField(
max_length=16, default='xq', db_index=True, verbose_name='所属俱乐部',

View File

@@ -2278,6 +2278,14 @@ class ShangjiaHuitiao(View):
logger.error(f"商家订单不存在: {out_trade_no}")
return self.wechat_response('FAIL', '订单不存在')
from products.czjilu_types import is_merchant_recharge_czjilu
if not is_merchant_recharge_czjilu(order):
logger.error(
'非商家充值订单误入商家回调: %s, leixing=%s, shuoming=%s',
out_trade_no, order.leixing, order.shuoming,
)
return self.wechat_response('FAIL', '订单类型错误')
# 5. 检查订单状态是否为未支付9
if order.zhuangtai != 9:
logger.warning(f"商家订单状态不是未支付: {order.dingdan_id}, 当前状态: {order.zhuangtai}")
@@ -5986,16 +5994,30 @@ class DsqrgmdhView(APIView):
action_desc = f"缴纳罚款 {target_price}"
shuoming = f"{identity['name']}抵扣 {action_desc},抵扣金额{required}"
cz_leixing = leixing
cz_club_id = club_id
cz_zhuangtai = 1
if leixing == 4:
from jituan.services.club_penalty import penalty_cz_club_id
from products.czjilu_types import (
CZJILU_LEIXING_FAKUAN,
CZJILU_PAID_STATUS,
PENALTY_FADAN_TAG,
)
cz_leixing = CZJILU_LEIXING_FAKUAN
cz_club_id = penalty_cz_club_id(fadan_obj)
cz_zhuangtai = CZJILU_PAID_STATUS
shuoming = f"{shuoming}{PENALTY_FADAN_TAG}{fadan_obj.id}"
member_purchase_days = 0
czjilu_kwargs = {
'dingdan_id': dingdan_id,
'zhuangtai': 1,
'zhuangtai': cz_zhuangtai,
'yonghuid': yonghuid,
'jine': required,
'leixing': leixing,
'leixing': cz_leixing,
'shuoming': shuoming,
'club_id': club_id,
'club_id': cz_club_id,
}
if leixing == 1:
from jituan.services.member_recharge import club_huiyuan_sellable

View File

@@ -12011,8 +12011,10 @@ class FaKuanPayView(APIView):
random_num = random.randint(0, 99)
dingdanid = f"FK{timestamp_ms:011d}{timestamp_ns:06d}{random_num:02d}"
from jituan.services.club_write import resolve_club_id_for_write
from jituan.services.club_penalty import penalty_cz_club_id
from jituan.services.club_user import get_payment_openid
from products.czjilu_types import CZJILU_LEIXING_FAKUAN, penalty_cz_shuoming
pay_openid, _ = get_payment_openid(request)
if not pay_openid:
return Response({
@@ -12025,9 +12027,9 @@ class FaKuanPayView(APIView):
zhuangtai=9,
yonghuid=request.user.UserUID,
jine=jine,
leixing=4,
shuoming=f'{settings.FAKUAN_PAY_DESCRIPTION}#fadan:{fadan.id}',
club_id=resolve_club_id_for_write(request, request.user),
leixing=CZJILU_LEIXING_FAKUAN,
shuoming=penalty_cz_shuoming(fadan.id),
club_id=penalty_cz_club_id(fadan),
)
try:
@@ -12233,6 +12235,11 @@ class FaKuanHuitiaoView(View):
logger.error(f"订单不存在: {out_trade_no}")
return self.wechat_response('FAIL', '订单不存在')
from products.czjilu_types import is_penalty_czjilu
if not is_penalty_czjilu(order):
logger.error(f"非罚款支付订单误入罚款回调: {out_trade_no}, leixing={order.leixing}")
return self.wechat_response('FAIL', '订单类型错误')
# 5. 检查订单状态是否为未支付9
if order.zhuangtai != 9:
logger.warning(f"订单状态不是未支付: {order.dingdan_id}, 当前状态: {order.zhuangtai}")