"""orders.views.boss_orders - auto-generated by split script.""" # ==================== 标准库 ==================== import hmac import os import json import time import random import string import traceback import threading import requests import hashlib import xml.etree.ElementTree as ET import xmltodict import logging from decimal import Decimal from django.conf import settings from django.db import models, transaction from gvsdsdk.fluent import db, func, FQ from django.db.models import F, Q, OuterRef, Subquery from django.core.cache import cache from django.core.exceptions import ObjectDoesNotExist from django.http import HttpResponse from django.utils import timezone from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import permissions, status from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.parsers import JSONParser from rest_framework.throttling import AnonRateThrottle from rest_framework_simplejwt.authentication import JWTAuthentication from tencentcloud.common import credential from tencentcloud.common.profile.client_profile import ClientProfile from tencentcloud.common.profile.http_profile import HttpProfile from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException from tencentcloud.sts.v20180813 import sts_client, models from utils.weixin_broadcast import WeixinBroadcastSender from utils.money import yuan_to_fen from utils.chat_utils import ( _send_group_message, _subscribe_users_to_group, establish_order_chat, prepare_order_group_chat, resolve_pair_group_id, parse_pair_from_group_id, resolve_pair_from_order, check_pair_chat_permission, query_pair_orders, order_to_chat_dict, ) from utils.fadan_utils import check_fadan_qiangdan_eligible from orders.utils import ( calc_shangjia_order_fencheng, update_daily_payout, settle_shangjia_order_guanshi_fenhong ) from shop.utils import calculate_pingtai_and_dianpu_shouyi, validate_shangpin_and_dianpu, update_dianpu_daily_stat from products.utils import update_shangpin_daily_stat from backend.utils import update_shangjia_daily, update_dashou_daily_by_action, pick_leixing_id, datetime_aliases, fmt_datetime from rank.services import record_dashou_biaoxian from rank.utils import check_dashou_biaoqian_required from orders.notice_tasks import dingdan_guangbo from ..models import ( Order, MerchantOrderExt, PlatformOrderExt, PlayerDeliveryImage, PenaltyRecord, PenaltyEvidenceImage, Penalty, PenaltyAppealImage, PenaltyBonus, PenaltyBonusRate, CommissionRate, PlayerRating, RefundRecord, ) from jituan.services.club_config import get_commission_rate, get_commission_rate_object from jituan.services.club_context import resolve_club_id_from_request from jituan.services.club_user import get_payment_openid from jituan.services.club_penalty import resolve_penalty_club_id, resolve_penalty_record_club_id from users.fadan_fenhong_utils import lock_penalty_bonus from users.fadan_fenhong_utils import lock_penalty_bonus from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai from users.models import UserDashou, UserShangjia, UserBoss from users.business_models import User from rank.models import DashouBiaoxian, Chenghao, DingdanBiaoqian, YonghuChenghao from config.models import ( ShangjiaLianjie ) logger = logging.getLogger(__name__) class DingdanHuoquView(APIView): """订单获取接口""" permission_classes = [IsAuthenticated] def post(self, request): # 获取当前登录用户 try: current_user = request.user yonghuid = current_user.UserUID except Exception as e: return Response({ 'code': 1, 'msg': '用户认证失败', 'data': None }) # 获取前端参数 try: data = request.data zhuangtai_list = data.get('zhuangtai_list', []) page = int(data.get('page', 1)) page_size = int(data.get('page_size', 10)) except Exception as e: return Response({ 'code': 2, 'msg': '参数格式错误', 'data': None }) # 参数验证 if not isinstance(zhuangtai_list, list) or len(zhuangtai_list) == 0: return Response({ 'code': 3, 'msg': '状态列表不能为空', 'data': None }) if page < 1: page = 1 if page_size <= 0: page_size = 10 try: # 查询扩展表,获取用户的所有订单ID pingtai_orders = PlatformOrderExt.query.filter(BossID=yonghuid) pingtai_order_ids = list(pingtai_orders.values_list('Order__OrderID', flat=True)) if not pingtai_order_ids: return Response({ 'code': 0, 'msg': '成功', 'data': { 'list': [], 'has_more': False, 'total': 0 } }) # 查询主表 status_query = Q() if zhuangtai_list != [1, 2, 3, 4, 5, 6, 7, 8]: status_query = Q(Status__in=zhuangtai_list) query = Q(OrderID__in=pingtai_order_ids) & status_query orders = Order.query.filter(query).order_by('-CreateTime') #total_orders = orders.count() # 手动分页逻辑 start_index = (page - 1) * page_size end_index = start_index + page_size # 获取当前页的数据 current_page_orders = orders[start_index:end_index] # 构建返回数据 order_list = [] for order in current_page_orders: order_data = { 'dingdanId': order.OrderID, 'zhuangtai': order.Status, 'jine': float(order.Amount) if order.Amount else 0.0, 'tupian': order.ImageURL or '', 'jieshao': order.Description or '', 'beizhu': order.Remark or '', 'nicheng': order.Nickname or '', 'chuangjianshijian': fmt_datetime(order.CreateTime), 'create_time': fmt_datetime(order.CreateTime), } order_list.append(order_data) # 判断是否还有更多数据 current_page_count = len(current_page_orders) has_more = current_page_count == page_size return Response({ 'code': 0, 'msg': '成功', 'data': { 'list': order_list, 'has_more': has_more, #'total': total_orders } }) except Exception as e: return Response({ 'code': 4, 'msg': '服务器内部错误', 'data': None }) class DingdanXiangqingView(APIView): """订单详情接口""" permission_classes = [IsAuthenticated] def post(self, request): # 获取当前登录用户 try: current_user = request.user yonghuid = current_user.UserUID except Exception as e: return Response({ 'code': 1, 'msg': '用户认证失败', 'data': None }) # 获取前端参数 try: data = request.data dingdan_id = data.get('dingdanId', '') except Exception as e: return Response({ 'code': 2, 'msg': '参数格式错误', 'data': None }) # 参数验证 if not dingdan_id: return Response({ 'code': 3, 'msg': '订单ID不能为空', 'data': None }) try: # 1. 验证订单是否属于当前用户 # 查询平台订单扩展表,检查laoban_id是否等于当前用户 pingtai_kuozhan = PlatformOrderExt.query.filter( BossID=yonghuid, Order__OrderID=dingdan_id ).first() if not pingtai_kuozhan: # 如果不是平台订单,检查商家订单 shangjia_kuozhan = MerchantOrderExt.query.filter( MerchantID=yonghuid, Order__OrderID=dingdan_id ).first() if not shangjia_kuozhan: return Response({ 'code': 4, 'msg': '订单不存在或无权限查看', 'data': None }) # 2. 查询订单主表 dingdan = Order.query.filter(OrderID=dingdan_id).first() if not dingdan: return Response({ 'code': 5, 'msg': '订单不存在', 'data': None }) # 3. 获取订单信息 zhuangtai = dingdan.Status or 0 zhiding_id = dingdan.AssignedID or '' jiedan_dashou_id = dingdan.PlayerID or '' dashou_liuyan = dingdan.PlayerRemark or '' # 4. 查询打手交付图片 dashoutupian_records = PlayerDeliveryImage.query.filter( OrderID=dingdan_id ).order_by('CreateTime')[:9] # 最多取9条 dashoujiaofu_list = [] for record in dashoutupian_records: if record.ImageURL: dashoujiaofu_list.append(record.ImageURL) # 5. 构建返回数据(字段名与前端对应) response_data = { 'zhuangtai': zhuangtai, # 订单状态 'zhiding': zhiding_id, # 指定打手ID 'jiedan_dashou_id': jiedan_dashou_id, # 服务打手ID 'dashouliuyan': dashou_liuyan, # 打手留言 'dashoujiaofu': dashoujiaofu_list # 打手交付图片列表 } # 6. 返回成功响应 return Response({ 'code': 0, 'msg': '成功', 'data': response_data }) except Exception as e: print(f"订单详情查询失败: {str(e)}") return Response({ 'code': 6, 'msg': '服务器内部错误', 'data': None }) class JiedanView(APIView): """结单接口""" permission_classes = [IsAuthenticated] def post(self, request): # 获取当前登录用户 try: current_user = request.user yonghuid = current_user.UserUID except Exception as e: return Response({ 'code': 1, 'msg': '用户认证失败', 'data': None }) # 获取前端参数 try: data = request.data dingdan_id = data.get('dingdanId', '') pingfen = int(data.get('pingfen', 0)) # 评分,默认0 liuyan = data.get('liuyan', '') # 留言,默认空 except Exception as e: return Response({ 'code': 2, 'msg': '参数格式错误', 'data': None }) # 参数验证 if not dingdan_id: return Response({ 'code': 3, 'msg': '订单ID不能为空', 'data': None }) # 验证评分范围 if pingfen < 0 or pingfen > 5: return Response({ 'code': 4, 'msg': '评分必须在0-5分之间', 'data': None }) # 使用事务确保数据一致性 try: with transaction.atomic(): # 1. 验证订单是否存在且属于当前用户 pingtai_kuozhan = PlatformOrderExt.query.filter( BossID=yonghuid, Order__OrderID=dingdan_id ).select_related('Order').first() if not pingtai_kuozhan: return Response({ 'code': 5, 'msg': '订单不存在或无权限操作', 'data': None }) dingdan = pingtai_kuozhan.Order # 2. 验证订单状态(必须是结算中 - 状态8) if dingdan.Status != 8: return Response({ 'code': 6, 'msg': '订单不在结算状态,无法结单', 'data': None }) # 3. 获取订单相关数据 dashou_fencheng = dingdan.PlayerCommission or Decimal('0.00') # 打手分成 jiedan_dashou_id = dingdan.PlayerID or '' # 接单打手ID shangpin_id = dingdan.ProductID # 商品ID # 4. 更新平台扩展表的老板评价(如果有留言) if liuyan: pingtai_kuozhan.BossReview = liuyan pingtai_kuozhan.save() # 5. 如果有评分,更新评分表 if pingfen > 0 and jiedan_dashou_id: # 使用filter查询,更健壮 pingfen_records = PlayerRating.query.filter(PlayerID=jiedan_dashou_id) if pingfen_records.exists(): # 已有记录,更新 pingfen_record = pingfen_records.first() pingfen_record.TotalScore += Decimal(str(pingfen)) pingfen_record.RatingCount += 1 pingfen_record.save() else: # 新记录,创建 PlayerRating.query.create( PlayerID=jiedan_dashou_id, TotalScore=Decimal(str(pingfen)), RatingCount=1 ) # 6. 更新商品真实销量(如果有商品ID) if shangpin_id: shangpin_records = Shangpin.query.filter(id=shangpin_id) if shangpin_records.exists(): shangpin = shangpin_records.first() # 检查字段是否存在 if hasattr(shangpin, 'zhenshi_xiaoliang'): shangpin.zhenshi_xiaoliang = (shangpin.zhenshi_xiaoliang or 0) + 1 shangpin.save() # 7. 更新打手扩展表(如果有打手ID和分成) if jiedan_dashou_id and dashou_fencheng > 0: # 查询打手用户 dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first() if dashou_user: # 查询打手扩展表 dashou_kuozhan = UserDashou.query.filter(user=dashou_user).first() if dashou_kuozhan: # 更新四个金额字段 dashou_kuozhan.zonge = (dashou_kuozhan.zonge or Decimal('0.00')) + dashou_fencheng dashou_kuozhan.yue = (dashou_kuozhan.yue or Decimal('0.00')) + dashou_fencheng dashou_kuozhan.jinrishouyi = (dashou_kuozhan.jinrishouyi or Decimal( '0.00')) + dashou_fencheng dashou_kuozhan.jinyueshouyi = (dashou_kuozhan.jinyueshouyi or Decimal( '0.00')) + dashou_fencheng # 成交总量加1 dashou_kuozhan.chengjiaozongliang = (dashou_kuozhan.chengjiaozongliang or 0) + 1 # 状态改为数字1 dashou_kuozhan.zhuangtai = 1 dashou_kuozhan.save() # 8. 更新订单状态为已完成(状态3) dingdan.Status = 3 dingdan.save() # 🔥 新增:调用打手每日统计(成交) try: update_dashou_daily_by_action( yonghuid=jiedan_dashou_id, amount=dashou_fencheng, action=2 # 2 表示成交(结算) ) logger.info(f"打手 {jiedan_dashou_id} 每日统计更新成功") except Exception as e: logger.error(f"打手每日统计更新失败: {e}") # 不影响主流程 # ========== 新增:商品和店铺每日统计 ========== try: # 商品每日统计(只要有商品ID就执行) if dingdan.ProductID: # 从扩展表获取已计算好的收益值(下单时已存储) pingtai_shouyi = Decimal('0.00') dianpu_shouyi = Decimal('0.00') if hasattr(dingdan, 'pingtai_kuozhan'): pingtai_shouyi = dingdan.pingtai_kuozhan.PlatformIncome or Decimal('0.00') dianpu_shouyi = dingdan.pingtai_kuozhan.ShopIncome or Decimal('0.00') update_shangpin_daily_stat( ProductID=dingdan.ProductID, caozuo_leixing=2, # 2 = 结单 dingdan_jiage=dingdan.Amount, PlatformIncome=pingtai_shouyi, dianpu_zongshouyi=dianpu_shouyi ) logger.info(f"商品统计更新完成,商品ID: {dingdan.ProductID}") # 店铺每日统计(仅当存在店铺ID时执行) # ========== 修改为 ========== # 店铺每日统计(包含上级分红) dianpu_id = None shangji_id = None shangji_fen = Decimal('0.00') if hasattr(dingdan, 'pingtai_kuozhan'): dianpu_id = dingdan.pingtai_kuozhan.ShopID shangji_id = dingdan.pingtai_kuozhan.ParentShopID shangji_fen = dingdan.pingtai_kuozhan.ParentBonus or Decimal('0.00') if dianpu_id: dianpu_shouyi = dingdan.pingtai_kuozhan.ShopIncome or Decimal('0.00') update_dianpu_daily_stat( ShopID=dianpu_id, caozuo_leixing=2, # 结算 dingdan_jiage=dingdan.Amount, ShopIncome=dianpu_shouyi, shangji_ShopID=shangji_id, # 新增:上级店铺ID ParentBonus=shangji_fen # 新增:该单给上级的分红 ) logger.info(f"店铺统计更新完成,店铺ID: {dianpu_id}, 上级ID: {shangji_id}, 上级分红: {shangji_fen}") '''dianpu_id = None if hasattr(dingdan, 'pingtai_kuozhan'): dianpu_id = dingdan.pingtai_kuozhan.ShopID if dianpu_id: dianpu_shouyi = dingdan.pingtai_kuozhan.ShopIncome or Decimal('0.00') update_dianpu_daily_stat( ShopID=dianpu_id, caozuo_leixing=2, # 2 = 结单 dingdan_jiage=dingdan.Amount, ShopIncome=dianpu_shouyi ) logger.info(f"店铺统计更新完成,店铺ID: {dianpu_id}")''' except Exception as e: logger.error(f"商品/店铺统计更新失败: {e}") logger.error(traceback.format_exc()) # 统计失败不影响主流程 # ============================================= # 9. 返回成功响应 return Response({ 'code': 0, 'msg': '结单成功', 'data': None }) except Exception as e: # 事务会自动回滚 return Response({ 'code': 7, 'msg': '结单失败,服务器内部错误', 'data': None }) class DingdanXiangqingView2(APIView): """订单详情接口(老板端)- 返回完整评价信息""" permission_classes = [IsAuthenticated] def post(self, request): try: yonghuid = request.user.UserUID except Exception: return Response({'code': 1, 'msg': '用户认证失败', 'data': None}) dingdan_id = request.data.get('dingdanId', '') if not dingdan_id: return Response({'code': 2, 'msg': '订单ID不能为空', 'data': None}) try: # 权限验证 pingtai_ext = PlatformOrderExt.query.filter( BossID=yonghuid, Order__OrderID=dingdan_id ).select_related('Order').first() if not pingtai_ext: return Response({'code': 3, 'msg': '订单不存在或无权限查看', 'data': None}) order = pingtai_ext.Order zhuangtai = order.Status or 0 jiedan_dashou_id = order.PlayerID or '' dashou_liuyan = order.PlayerRemark or '' UpdateTime = order.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if order.UpdateTime else '' # 交付图片 dashoujiaofu_list = list( PlayerDeliveryImage.query.filter(OrderID=dingdan_id) .order_by('CreateTime')[:9] .values_list('ImageURL', flat=True) ) # 打手信息 dashou_nicheng = '' dashou_touxiang = '' jiedan_time = '' tijiao_time = '' if jiedan_dashou_id: dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first() if dashou_user: dashou_touxiang = dashou_user.Avatar or '' try: dashou_nicheng = dashou_user.DashouProfile.nicheng or '' except UserDashou.DoesNotExist: pass biaoxian = DashouBiaoxian.query.filter( OrderID=dingdan_id, dashou_id=jiedan_dashou_id ).first() if biaoxian: if biaoxian.jiedan_time: jiedan_time = biaoxian.jiedan_time.strftime('%Y-%m-%d %H:%M:%S') if biaoxian.tijiao_time: tijiao_time = biaoxian.tijiao_time.strftime('%Y-%m-%d %H:%M:%S') # 老板自己的评价(如果已经结算过,可能已有评价) laoban_pingjia = pingtai_ext.BossReview or '' shangxian_sudu = None fuwu_taidu = None fanche_cishu = None if jiedan_dashou_id and zhuangtai in [3, 4, 5, 6]: # 已完成或退款相关状态才可能有评价 biaoxian = DashouBiaoxian.query.filter( OrderID=dingdan_id, dashou_id=jiedan_dashou_id ).first() if biaoxian: shangxian_sudu = biaoxian.shangxian_sudu fuwu_taidu = biaoxian.fuwu_taidu fanche_cishu = biaoxian.fanche_cishu data = { 'zhuangtai': zhuangtai, 'dashou': jiedan_dashou_id, 'dashou_nicheng': dashou_nicheng, 'dashou_touxiang': dashou_touxiang, 'dashouliuyan': dashou_liuyan, 'dashoujiaofu': dashoujiaofu_list, 'UpdateTime': UpdateTime, 'jiedan_time': jiedan_time, 'tijiao_time': tijiao_time, 'laoban_pingjia': laoban_pingjia, 'shangxian_sudu': shangxian_sudu, # 1-5 或 null 'fuwu_taidu': fuwu_taidu, # 1-5 或 null 'fanche_cishu': fanche_cishu # int 或 null } return Response({'code': 0, 'msg': '成功', 'data': data}) except Exception as e: logger.error(f"订单详情查询异常: {e}", exc_info=True) return Response({'code': 4, 'msg': '服务器内部错误', 'data': None}) class JiedanView2(APIView): """结单接口(老板端)- 接收全新评价字段并写入表现表""" permission_classes = [IsAuthenticated] def post(self, request): # 1. 用户认证 try: current_user = request.user yonghuid = current_user.UserUID except Exception: return Response({'code': 1, 'msg': '用户认证失败', 'data': None}) # 2. 获取参数(字段名与前端完全一致) try: data = request.data dingdan_id = data.get('dingdanId', '') fanche_cishu = data.get('fanche_cishu') # 前端传的字符串或数字,后端转为整数 shangxian_sudu = data.get('shangxian_sudu') fuwu_taidu = data.get('fuwu_taidu') liuyan = data.get('liuyan', '') except Exception: return Response({'code': 2, 'msg': '参数格式错误', 'data': None}) # 参数校验 if not dingdan_id: return Response({'code': 3, 'msg': '订单ID不能为空', 'data': None}) # 转换并校验必填评价字段 try: fanche_cishu = int(fanche_cishu) if fanche_cishu is not None else None shangxian_sudu = int(shangxian_sudu) if shangxian_sudu is not None else None fuwu_taidu = int(fuwu_taidu) if fuwu_taidu is not None else None except (ValueError, TypeError): return Response({'code': 4, 'msg': '评价参数必须为整数', 'data': None}) if fanche_cishu is None: return Response({'code': 5, 'msg': '翻车次数不能为空', 'data': None}) if not (1 <= shangxian_sudu <= 5 and 1 <= fuwu_taidu <= 5): return Response({'code': 6, 'msg': '评价分数必须在1-5之间', 'data': None}) # 使用事务保证数据一致性 try: with transaction.atomic(): # 3. 权限验证:订单属于当前老板 pingtai_ext = PlatformOrderExt.query.filter( BossID=yonghuid, Order__OrderID=dingdan_id ).select_related('Order').first() if not pingtai_ext: return Response({'code': 7, 'msg': '订单不存在或无权限操作', 'data': None}) order = pingtai_ext.Order # 4. 状态校验:必须是结算中(状态8) if order.Status != 8: return Response({'code': 8, 'msg': '订单不在结算状态', 'data': None}) # 5. 提取订单关键数据 dashou_fencheng = order.PlayerCommission or Decimal('0.00') jiedan_dashou_id = order.PlayerID or '' shangpin_id = order.ProductID # 6. 保存老板评价(兼容旧逻辑) if liuyan: pingtai_ext.BossReview = liuyan pingtai_ext.save() # 7. 更新评分表(用服务态度分作为综合评分,保留原有统计) if jiedan_dashou_id and fuwu_taidu: pingfen_records = PlayerRating.query.filter(PlayerID=jiedan_dashou_id) if pingfen_records.exists(): pf = pingfen_records.first() pf.TotalScore += Decimal(str(fuwu_taidu)) pf.RatingCount += 1 pf.save() else: PlayerRating.query.create( PlayerID=jiedan_dashou_id, TotalScore=Decimal(str(fuwu_taidu)), RatingCount=1 ) # 8. 更新商品真实销量 if shangpin_id: shangpin_qs = Shangpin.query.filter(id=shangpin_id) if shangpin_qs.exists(): sp = shangpin_qs.first() if hasattr(sp, 'zhenshi_xiaoliang'): sp.zhenshi_xiaoliang = (sp.zhenshi_xiaoliang or 0) + 1 sp.save() # 9. 更新打手收益与状态 if jiedan_dashou_id and dashou_fencheng > 0: dashou_user = User.query.filter(UserUID=jiedan_dashou_id).first() if dashou_user: try: dashou_ext = dashou_user.DashouProfile dashou_ext.zonge = (dashou_ext.zonge or Decimal('0.00')) + dashou_fencheng dashou_ext.yue = (dashou_ext.yue or Decimal('0.00')) + dashou_fencheng dashou_ext.jinrishouyi = (dashou_ext.jinrishouyi or Decimal('0.00')) + dashou_fencheng dashou_ext.jinyueshouyi = (dashou_ext.jinyueshouyi or Decimal('0.00')) + dashou_fencheng dashou_ext.chengjiaozongliang = (dashou_ext.chengjiaozongliang or 0) + 1 dashou_ext.zhuangtai = 1 dashou_ext.save() except UserDashou.DoesNotExist: pass # 10. 更新订单状态为已完成 order.Status = 3 order.save() # 11. 打手每日统计(成交) try: update_dashou_daily_by_action( UserID=jiedan_dashou_id, amount=dashou_fencheng, action=2 # 2=结算/成交 ) except Exception as e: logger.error(f"打手每日统计失败: {e}") # 12. 商品/店铺每日统计 try: if shangpin_id: # 从扩展表取已计算收益 pingtai_shouyi = Decimal('0.00') dianpu_shouyi = Decimal('0.00') if hasattr(order, 'pingtai_kuozhan'): pingtai_shouyi = order.pingtai_kuozhan.PlatformIncome or Decimal('0.00') dianpu_shouyi = order.pingtai_kuozhan.ShopIncome or Decimal('0.00') update_shangpin_daily_stat( ProductID=shangpin_id, caozuo_leixing=2, dingdan_jiage=order.Amount, PlatformIncome=pingtai_shouyi, dianpu_zongshouyi=dianpu_shouyi ) # 店铺统计(含上级分红) if hasattr(order, 'pingtai_kuozhan'): dianpu_id = order.pingtai_kuozhan.ShopID shangji_id = order.pingtai_kuozhan.ParentShopID shangji_fen = order.pingtai_kuozhan.ParentBonus or Decimal('0.00') if dianpu_id: update_dianpu_daily_stat( ShopID=dianpu_id, caozuo_leixing=2, dingdan_jiage=order.Amount, ShopIncome=dianpu_shouyi, shangji_ShopID=shangji_id, ParentBonus=shangji_fen ) except Exception as e: logger.error(f"商品/店铺统计失败: {e}") # 14. 🆕 写入打手表现表(结算评价) if jiedan_dashou_id: record_dashou_biaoxian( dingdan_id=dingdan_id, dashou_id=jiedan_dashou_id, xingwei=3, # 3=结算 fanche_RatingCount=fanche_cishu, shangxian_sudu=shangxian_sudu, fuwu_taidu=fuwu_taidu # bankuai 暂不传入,后续可从订单商品关联 ) # 15. 返回成功 return Response({'code': 0, 'msg': '结单成功', 'data': None}) except Exception as e: logger.error(f"结单事务异常: {e}", exc_info=True) return Response({'code': 9, 'msg': '服务器内部错误,结单失败', 'data': None})