客服提现列表支持明细状态筛选并补充审核相关字段。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -115,18 +115,34 @@ def load_audit_dakuan_mode_map(audit_ids):
|
||||
def load_audit_meta_map(audit_ids):
|
||||
"""
|
||||
批量取审核表元数据(供后台列表等)
|
||||
返回 {审核记录id: {'dakuan_mode': int, 'shenhe_danhao': str}}
|
||||
返回 {审核记录id: {dakuan_mode, shenhe_danhao, shouxufei, shijidaozhang, ...}}
|
||||
"""
|
||||
if not audit_ids:
|
||||
return {}
|
||||
value_fields = ['id', 'shenhe_danhao']
|
||||
value_fields = [
|
||||
'id', 'shenhe_danhao',
|
||||
'shouxufei', 'shijidaozhang', 'feilv',
|
||||
'fail_reason', 'bhliyou', 'tixian_auto_id', 'zhuangtai',
|
||||
]
|
||||
if has_dakuan_mode_field():
|
||||
value_fields.append('dakuan_mode')
|
||||
# dakuan_mch_id 迁移后才有
|
||||
if any(f.name == 'dakuan_mch_id' for f in TixianShenheJilu._meta.fields):
|
||||
value_fields.append('dakuan_mch_id')
|
||||
|
||||
result = {}
|
||||
for row in TixianShenheJilu.objects.filter(id__in=audit_ids).values(*value_fields):
|
||||
result[row['id']] = {
|
||||
'shenhe_danhao': row.get('shenhe_danhao') or '',
|
||||
'dakuan_mode': row.get('dakuan_mode', DAKUAN_MODE_AUTO),
|
||||
'shouxufei': str(row['shouxufei']) if row.get('shouxufei') is not None else '',
|
||||
'shijidaozhang': str(row['shijidaozhang']) if row.get('shijidaozhang') is not None else '',
|
||||
'feilv': str(row['feilv']) if row.get('feilv') is not None else '',
|
||||
'fail_reason': row.get('fail_reason') or '',
|
||||
'bhliyou': row.get('bhliyou') or '',
|
||||
'tixian_auto_id': row.get('tixian_auto_id') or '',
|
||||
'dakuan_mch_id': row.get('dakuan_mch_id') or '',
|
||||
'audit_zhuangtai': row.get('zhuangtai'),
|
||||
}
|
||||
return result
|
||||
|
||||
|
||||
103
yonghu/views.py
103
yonghu/views.py
@@ -11676,28 +11676,15 @@ class KefuWithdrawListView(APIView):
|
||||
"phone": "客服手机号",
|
||||
"page": 1,
|
||||
"page_size": 20,
|
||||
"status": 1(待审核)/2(已处理),
|
||||
"type": 1(打手佣金)/2(管事分红)/3(组长分红)/4(审核官分佣)/5(打手押金)/6(商家余额), 可选
|
||||
"status": 1(待审核)/2(已处理), # 未传 zhuangtai 时生效
|
||||
"zhuangtai": 1~6, # 明细状态精确筛选,传入时优先于 status
|
||||
"type": 1~6 可选,
|
||||
"payment": 1(微信)/2(支付宝) 可选,
|
||||
"search_uid": "用户ID搜索" 可选,
|
||||
"date": "YYYY-MM-DD" 可选,
|
||||
"min_amount": 0, # 最小提现金额(元)可选
|
||||
"max_amount": 999999, # 最大提现金额(元)可选
|
||||
"dakuan_mode": 1 # 打款方式:1手动打款 2自动打款,可选
|
||||
}
|
||||
认证:JWT
|
||||
返回:{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"list": [提现记录],
|
||||
"total": 总数,
|
||||
"stats": {
|
||||
"total": 总记录数,
|
||||
"awaiting": 待审核数,
|
||||
"processed": 已处理数,
|
||||
"total_amount": "总金额(元)"
|
||||
}
|
||||
}
|
||||
"min_amount": 0,
|
||||
"max_amount": 999999,
|
||||
"dakuan_mode": 1手动/2自动 可选
|
||||
}
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
@@ -11757,6 +11744,7 @@ class KefuWithdrawListView(APIView):
|
||||
page_size = min(max(page_size, 1), 100)
|
||||
|
||||
status_filter = request.data.get('status')
|
||||
zhuangtai_filter = request.data.get('zhuangtai')
|
||||
type_filter = request.data.get('type')
|
||||
payment_filter = request.data.get('payment')
|
||||
search_uid = (request.data.get('search_uid') or '').strip()
|
||||
@@ -11774,13 +11762,22 @@ class KefuWithdrawListView(APIView):
|
||||
if '005bb' not in permissions:
|
||||
return Response({'code': 403, 'msg': '您无权查看平台订单列表'})
|
||||
|
||||
q = Q()
|
||||
|
||||
try:
|
||||
status_val = int(status_filter) if status_filter is not None and str(status_filter).strip() != '' else None
|
||||
except (TypeError, ValueError):
|
||||
status_val = None
|
||||
|
||||
try:
|
||||
zhuangtai_val = (
|
||||
int(zhuangtai_filter)
|
||||
if zhuangtai_filter is not None and str(zhuangtai_filter).strip() != ''
|
||||
else None
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
zhuangtai_val = None
|
||||
if zhuangtai_val is not None and zhuangtai_val not in (1, 2, 3, 4, 5, 6):
|
||||
return Response({'code': 400, 'msg': 'zhuangtai 仅支持 1~6'})
|
||||
|
||||
try:
|
||||
dakuan_mode_val = int(dakuan_mode_filter) if dakuan_mode_filter is not None and str(dakuan_mode_filter).strip() != '' else None
|
||||
except (TypeError, ValueError):
|
||||
@@ -11789,14 +11786,7 @@ class KefuWithdrawListView(APIView):
|
||||
# 未传打款方式参数 → 默认手动打款(1)
|
||||
effective_dakuan = dakuan_mode_val if dakuan_mode_val in (1, 2) else 1
|
||||
|
||||
if status_val == 1:
|
||||
q &= Q(zhuangtai=1)
|
||||
elif status_val == 2:
|
||||
if effective_dakuan == 2:
|
||||
q &= Q(zhuangtai__in=[2, 3, 4, 5, 6])
|
||||
else:
|
||||
q &= Q(zhuangtai__in=[2, 3])
|
||||
|
||||
q = Q()
|
||||
if type_filter is not None and str(type_filter).strip() != '':
|
||||
try:
|
||||
type_val = int(type_filter)
|
||||
@@ -11843,25 +11833,52 @@ class KefuWithdrawListView(APIView):
|
||||
'data': {
|
||||
'list': [],
|
||||
'total': 0,
|
||||
'stats': {'total': 0, 'awaiting': 0, 'processed': 0, 'total_amount': '0.00'},
|
||||
'stats': {
|
||||
'total': 0, 'awaiting': 0, 'processed': 0,
|
||||
'pending_collect': 0, 'success': 0, 'fail': 0,
|
||||
'total_amount': '0.00',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
processed_statuses = [2, 3, 4, 5, 6] if effective_dakuan == 2 else [2, 3]
|
||||
|
||||
base_qs = self._list_queryset(q, shenhe_field_ok)
|
||||
total_count = base_qs.count()
|
||||
awaiting_count = self._list_queryset(q & Q(zhuangtai=1), shenhe_field_ok).count()
|
||||
# 统计用:不含明细/粗粒度状态,便于顶栏卡片在任意页可用
|
||||
q_for_stats = q
|
||||
awaiting_count = self._list_queryset(q_for_stats & Q(zhuangtai=1), shenhe_field_ok).count()
|
||||
processed_count = self._list_queryset(
|
||||
q & Q(zhuangtai__in=processed_statuses), shenhe_field_ok,
|
||||
q_for_stats & Q(zhuangtai__in=processed_statuses), shenhe_field_ok,
|
||||
).count()
|
||||
pending_collect_count = self._list_queryset(
|
||||
q_for_stats & Q(zhuangtai=6), shenhe_field_ok,
|
||||
).count() if effective_dakuan == 2 else 0
|
||||
success_count = self._list_queryset(q_for_stats & Q(zhuangtai=2), shenhe_field_ok).count()
|
||||
fail_count = self._list_queryset(
|
||||
q_for_stats & Q(zhuangtai__in=([3, 5] if effective_dakuan == 2 else [3])),
|
||||
shenhe_field_ok,
|
||||
).count()
|
||||
stats_total = self._list_queryset(q_for_stats, shenhe_field_ok).count()
|
||||
|
||||
# 列表用:明细状态优先;否则粗粒度 status
|
||||
q_list = q
|
||||
if zhuangtai_val is not None:
|
||||
q_list &= Q(zhuangtai=zhuangtai_val)
|
||||
elif status_val == 1:
|
||||
q_list &= Q(zhuangtai=1)
|
||||
elif status_val == 2:
|
||||
q_list &= Q(zhuangtai__in=processed_statuses)
|
||||
|
||||
base_qs = self._list_queryset(q_list, shenhe_field_ok)
|
||||
agg = base_qs.aggregate(total=Sum('jine'))
|
||||
total_amount = agg.get('total') or 0
|
||||
|
||||
stats = {
|
||||
'total': total_count,
|
||||
'total': stats_total,
|
||||
'awaiting': awaiting_count,
|
||||
'processed': processed_count,
|
||||
'pending_collect': pending_collect_count,
|
||||
'success': success_count,
|
||||
'fail': fail_count,
|
||||
'total_amount': str(round(float(total_amount), 2)),
|
||||
}
|
||||
|
||||
@@ -11891,8 +11908,10 @@ class KefuWithdrawListView(APIView):
|
||||
for item in records:
|
||||
shenhe_jilu_id = getattr(item, 'shenhe_jilu_id', None) if shenhe_field_ok else None
|
||||
shenhe_danhao = (getattr(item, 'shenhe_danhao', None) or '') if shenhe_field_ok else ''
|
||||
audit_meta = audit_meta_map.get(shenhe_jilu_id, {}) if shenhe_jilu_id else {}
|
||||
if shenhe_jilu_id and not shenhe_danhao:
|
||||
shenhe_danhao = audit_meta_map.get(shenhe_jilu_id, {}).get('shenhe_danhao', '')
|
||||
shenhe_danhao = audit_meta.get('shenhe_danhao', '')
|
||||
fail_reason = audit_meta.get('fail_reason') or ''
|
||||
list_data.append({
|
||||
'id': item.id,
|
||||
'shenhe_jilu_id': shenhe_jilu_id,
|
||||
@@ -11906,10 +11925,20 @@ class KefuWithdrawListView(APIView):
|
||||
'skzhanghao': item.skzhanghao or '',
|
||||
'jine': str(item.jine) if item.jine is not None else '0.00',
|
||||
'zhuangtai': item.zhuangtai,
|
||||
'zhuangtai_text': {
|
||||
1: '审核中', 2: '提现成功', 3: '提现失败',
|
||||
4: '审核成功', 5: '审核失败', 6: '待收款',
|
||||
}.get(item.zhuangtai, '未知'),
|
||||
'fangshi': item.fangshi,
|
||||
'dakuan_mode': self._resolve_row_dakuan_mode(item, audit_mode_map, shenhe_field_ok),
|
||||
'shenheid': item.shenheid or '',
|
||||
'bhliyou': item.bhliyou or '',
|
||||
'bhliyou': item.bhliyou or audit_meta.get('bhliyou') or '',
|
||||
'fail_reason': fail_reason,
|
||||
'shouxufei': audit_meta.get('shouxufei') or '',
|
||||
'shijidaozhang': audit_meta.get('shijidaozhang') or '',
|
||||
'feilv': audit_meta.get('feilv') or '',
|
||||
'dakuan_mch_id': audit_meta.get('dakuan_mch_id') or '',
|
||||
'tixian_auto_id': audit_meta.get('tixian_auto_id') or '',
|
||||
'create_time': item.create_time.strftime('%Y-%m-%d %H:%M:%S') if item.create_time else '',
|
||||
'update_time': item.update_time.strftime('%Y-%m-%d %H:%M:%S') if item.update_time else '',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user