累死了,删除了所有跨平台逻辑,进行了表迁移

This commit is contained in:
2026-06-15 02:09:51 +08:00
parent 8b9dbcba6f
commit 9eb53ee57d
112 changed files with 468 additions and 6208 deletions

View File

@@ -49,12 +49,9 @@ from products.models import ShangpinLeixing, ShangpinZhuanqu, Shangpin, Huiyuan
from orders.models import (
Dingdan, DingdanPingtai, Dashoutupian, Tuikuanjilu,
OrderDashouHistory, CrossPlatformOrderData, Fadan
OrderDashouHistory, Fadan
)
from config.models import ClubConfig, Club
logger = logging.getLogger(__name__)
@@ -2021,8 +2018,6 @@ class SubShopModifyView(APIView):
"""
# 如果有 ClubConfig 模型用于获取存储桶域名,确保导入(如没有可忽略,使用 settings 中的 OSS 域名)
# ---------- 图片域名 ----------
"""
店铺订单管理接口
@@ -2192,22 +2187,9 @@ class ShopOrderStatisticsView(APIView):
def get_oss_domain():
"""
获取对象存储的域名,末尾包含 '/'
优先从跨平台配置表 ClubConfig 中获取本俱乐部的 storage_bucket_domain
如果获取失败或表不存在,则使用预设的 OSS 域名作为降级方案。
返回:字符串,如 'https://example.com/'
"""
try:
# 尝试从跨平台配置中读取
from kuaping.models import ClubConfig
config = ClubConfig.objects.filter(is_self=1).first()
if config and config.storage_bucket_domain:
# 确保域名末尾有 '/'
return config.storage_bucket_domain.rstrip('/') + '/'
except Exception:
# 表不存在或其它异常,忽略,使用下方默认域名
pass
# 默认 OSS 域名,请替换为你的实际域名
return 'https://xingque999qygwuyq-1404472910.cos.ap-shanghai.myqcloud.com/'
return getattr(settings, 'COS_DOMAIN', 'https://xingque999qygwuyq-1404472910.cos.ap-shanghai.myqcloud.com/').rstrip('/') + '/'
# ================================================================
@@ -2674,15 +2656,6 @@ class ShopRefundView(APIView):
logger.exception("退款事务执行失败")
return Response({'code': 500, 'msg': '退款处理失败,请稍后重试'})
# 7. 跨平台通知如果存在对方平台订单ID异步通知不影响主流程
partner_order_id = order.partner_order_id
partner_club_id = order.partner_club_id
if partner_order_id and partner_club_id:
try:
self._notify_partner_refund(dingdan_id, partner_club_id, partner_order_id, reason, order.jine)
except Exception as e:
logger.error(f"跨平台退款通知异常: {e}")
return Response({'code': 200, 'msg': '退款成功'})
# ========== 微信退款 ==========
@@ -2767,53 +2740,6 @@ class ShopRefundView(APIView):
except Exception as e:
logger.error(f"更新退款记录异常: {e}")
# ========== 跨平台通知 ==========
def _notify_partner_refund(self, dingdan_id, partner_club_id, partner_order_id, reason, amount):
"""
通知对方平台我方已退款。
此方法执行不影响主流程,任何异常仅记录日志。
"""
try:
my_config = ClubConfig.objects.filter(is_self=1).first()
if not my_config:
logger.error("未配置我方俱乐部信息,无法通知对方")
return
self_club_id = my_config.club_id
club_rel = Club.objects.get(club_id=self_club_id, partner_club_id=partner_club_id)
partner_domain = club_rel.partner_domain.rstrip('/')
notify_url = f"{partner_domain}/houtai/dfddtk"
payload = {
'order_id': partner_order_id,
'club_id': self_club_id,
'status': 5,
'reason': reason or '店铺退款'
}
resp = requests.post(notify_url, json=payload, timeout=3)
if resp.status_code == 200:
resp_json = resp.json()
if resp_json.get('code') == 0:
# 更新跨平台扩展表状态
cross_data, _ = CrossPlatformOrderData.objects.get_or_create(
dingdan_id=dingdan_id,
defaults={
'partner_order_id': partner_order_id,
'partner_club_id': partner_club_id,
'partner_order_status': resp_json.get('data', {}).get('partner_status', 0),
'partner_dashou_id': resp_json.get('data', {}).get('partner_dashou_id', ''),
'partner_amount': amount or 0,
}
)
if not _:
cross_data.partner_order_status = resp_json.get('data', {}).get('partner_status', 0)
cross_data.save()
else:
logger.warning(f"对方平台返回错误: {resp_json.get('msg')}")
else:
logger.warning(f"通知对方HTTP错误: {resp.status_code}")
except Exception as e:
logger.error(f"通知对方平台异常: {e}")
# ========== 工具方法 ==========
def _generate_nonce_str(self):
return ''.join(random.choices(string.ascii_letters + string.digits, k=32))
@@ -2887,8 +2813,6 @@ class ShopForceCompleteView(APIView):
logger.warning(f"订单 {dingdan_id} 当前状态为 {order.zhuangtai},不是结算中")
return Response({'code': 400, 'msg': f'订单状态不是结算中,当前状态: {order.zhuangtai}'})
# ========== 5. 判断是否为跨平台订单有对方订单ID就认为是跨平台 ==========
is_cross = order.is_cross and (order.partner_order_id or order.partner_club_id)
dashou_id = order.jiedan_dashou_id
dashou_fencheng = order.dashou_fencheng or Decimal('0.00')
jine = order.jine or Decimal('0.00')
@@ -2898,103 +2822,72 @@ class ShopForceCompleteView(APIView):
# 锁定订单行,防止并发
order = Dingdan.objects.select_for_update().get(dingdan_id=dingdan_id)
# ============================
# 情况1跨平台订单我方派单给对方平台打手
# ============================
if is_cross:
# 只需更新我方订单状态,打手在对方平台,不处理我方打手余额
order.zhuangtai = 3 # 已完成
order.clkf = str(shop_id) # 处理人记录为店铺ID
order.save()
if not dashou_id:
return Response({'code': 400, 'msg': '订单无接单打手,无法结算'})
if dashou_fencheng < 0:
return Response({'code': 400, 'msg': '打手分成金额无效'})
# 店铺结算时,若涉及跨平台收益,这里是否要更新店铺统计?
# 根据业务需求,可在此处调用 update_dianpu_daily_stat 等
# 但通常跨平台订单的资金已在对方平台流转,店铺仅作为发单方,
# 收益可能已在其他环节计算,此处可根据需要添加统计。
# ---------- 更新打手余额和统计 ----------
try:
dashou_user = UserMain.objects.get(yonghuid=dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.chengjiaozongliang += 1
dashou_profile.yue += dashou_fencheng
dashou_profile.zonge += dashou_fencheng
dashou_profile.jinrishouyi += dashou_fencheng
dashou_profile.jinyueshouyi += dashou_fencheng
dashou_profile.zhuangtai = 1 # 空闲
dashou_profile.save()
except (UserMain.DoesNotExist, ObjectDoesNotExist):
logger.warning(f"本地订单结算:打手 {dashou_id} 不存在,跳过打手更新")
# 通知对方平台(异步,不影响主流程)
if order.partner_club_id and order.partner_order_id:
transaction.on_commit(
lambda: self._notify_partner_order_complete(
order.partner_club_id,
order.partner_order_id,
shop_id
# ---------- 更新订单状态 ----------
order.zhuangtai = 3
order.clkf = str(shop_id)
order.save()
# ---------- 打手每日统计(成交) ----------
try:
update_dashou_daily_by_action(
yonghuid=dashou_id,
amount=dashou_fencheng,
action=2 # 2 表示成交(结算)
)
except Exception as e:
logger.error(f"打手每日统计更新失败: {e}")
# ---------- 店铺收益统计(结算) ----------
if pingtai_ext.dianpu_shouyi:
try:
# 商品每日统计只要有商品ID就执行
if order.shangpin_id:
# 从扩展表获取已计算好的收益值(下单时已存储)
pingtai_shouyi = Decimal('0.00')
dianpu_shouyi = Decimal('0.00')
if hasattr(order, 'pingtai_kuozhan'):
pingtai_shouyi = order.pingtai_kuozhan.pingtai_shouyi or Decimal('0.00')
dianpu_shouyi = order.pingtai_kuozhan.dianpu_shouyi or Decimal('0.00')
update_shangpin_daily_stat(
shangpin_id=order.shangpin_id,
caozuo_leixing=2, # 3 = 退款
dingdan_jiage=order.jine,
pingtai_shouyi=pingtai_shouyi,
dianpu_zongshouyi=dianpu_shouyi
)
)
logger.info(f"商品统计更新完成商品ID: {order.shangpin_id}")
# ============================
# 情况2本地订单我方打手接单
# ============================
else:
if not dashou_id:
return Response({'code': 400, 'msg': '订单无接单打手,无法结算'})
if dashou_fencheng < 0:
return Response({'code': 400, 'msg': '打手分成金额无效'})
# ---------- 更新打手余额和统计 ----------
try:
dashou_user = UserMain.objects.get(yonghuid=dashou_id)
dashou_profile = dashou_user.dashou_profile
dashou_profile.chengjiaozongliang += 1
dashou_profile.yue += dashou_fencheng
dashou_profile.zonge += dashou_fencheng
dashou_profile.jinrishouyi += dashou_fencheng
dashou_profile.jinyueshouyi += dashou_fencheng
dashou_profile.zhuangtai = 1 # 空闲
dashou_profile.save()
except (UserMain.DoesNotExist, ObjectDoesNotExist):
logger.warning(f"本地订单结算:打手 {dashou_id} 不存在,跳过打手更新")
# ---------- 更新订单状态 ----------
order.zhuangtai = 3
order.clkf = str(shop_id)
order.save()
# ---------- 打手每日统计(成交) ----------
try:
update_dashou_daily_by_action(
yonghuid=dashou_id,
amount=dashou_fencheng,
action=2 # 2 表示成交(结算)
update_dianpu_daily_stat(
dianpu_id=shop_id,
caozuo_leixing=2, # 结算操作
dingdan_jiage=jine,
dianpu_shouyi=pingtai_ext.dianpu_shouyi,
)
except Exception as e:
logger.error(f"打手每日统计更新失败: {e}")
logger.error(f"店铺每日统计更新失败: {e}")
# ---------- 店铺收益统计(结算) ----------
# 根据订单上的店铺收益 (从扩展表取) 更新店铺每日统计及余额
# 前提:订单创建时已存储了 dianpu_shouyi 到扩展表
if pingtai_ext.dianpu_shouyi:
try:
# 商品每日统计只要有商品ID就执行
if order.shangpin_id:
# 从扩展表获取已计算好的收益值(下单时已存储)
pingtai_shouyi = Decimal('0.00')
dianpu_shouyi = Decimal('0.00')
if hasattr(order, 'pingtai_kuozhan'):
pingtai_shouyi = order.pingtai_kuozhan.pingtai_shouyi or Decimal('0.00')
dianpu_shouyi = order.pingtai_kuozhan.dianpu_shouyi or Decimal('0.00')
update_shangpin_daily_stat(
shangpin_id=order.shangpin_id,
caozuo_leixing=2, # 3 = 退款
dingdan_jiage=order.jine,
pingtai_shouyi=pingtai_shouyi,
dianpu_zongshouyi=dianpu_shouyi
)
logger.info(f"商品统计更新完成商品ID: {order.shangpin_id}")
update_dianpu_daily_stat(
dianpu_id=shop_id,
caozuo_leixing=2, # 结算操作
dingdan_jiage=jine,
dianpu_shouyi=pingtai_ext.dianpu_shouyi,
# 如果涉及上级分红,可从扩展表取相应字段传入,此处略
)
except Exception as e:
logger.error(f"店铺每日统计更新失败: {e}")
# ========== 6. 记录操作日志 ==========
# ========== 5. 记录操作日志 ==========
logger.info(f"强制结单成功,订单 {dingdan_id},店铺 {shop_id}")
return Response({'code': 200, 'msg': '强制结单成功'})
@@ -3006,40 +2899,6 @@ class ShopForceCompleteView(APIView):
logger.error(f"强制结单接口异常: {str(e)}", exc_info=True)
return Response({'code': 500, 'msg': '服务器内部错误'})
# ==================== 通知对方平台(异步) ====================
def _notify_partner_order_complete(self, partner_club_id, partner_order_id, shop_id):
"""通知对方平台我方订单已完成状态3"""
try:
# 尝试获取对方域名等配置(与退款接口类似)
my_config = ClubConfig.objects.filter(is_self=1).first()
if not my_config:
logger.error("未配置我方俱乐部信息,无法通知对方")
return
self_club_id = my_config.club_id
club_rel = Club.objects.get(club_id=self_club_id, partner_club_id=partner_club_id)
partner_domain = club_rel.partner_domain.rstrip('/')
notify_url = f"{partner_domain}/houtai/dfddtk"
payload = {
'order_id': partner_order_id,
'club_id': self_club_id,
'status': 3
}
resp = requests.post(notify_url, json=payload, timeout=3)
if resp.status_code == 200:
resp_data = resp.json()
if resp_data.get('code') == 0:
logger.info(f"通知对方订单已完成: {partner_order_id}")
else:
logger.warning(f"对方平台返回错误: {resp_data.get('msg')}")
else:
logger.warning(f"通知对方HTTP错误: {resp.status_code}")
except Exception as e:
logger.error(f"通知对方平台异常: {e}")
@@ -3105,13 +2964,8 @@ class ShopTransferHallView(APIView):
# ---------- 5. 提取关键字段 ----------
current_dashou_id = order.jiedan_dashou_id
zhiding_id = order.zhiding_id
partner_club_id = order.partner_club_id
partner_order_id = order.partner_order_id
dashou_fencheng = order.dashou_fencheng or 0 # 用于退款统计
# 是否跨平台:只要有对方信息即认为是跨平台订单
is_cross = bool(partner_club_id or partner_order_id)
try:
with transaction.atomic():
# 锁定订单行
@@ -3130,8 +2984,8 @@ class ShopTransferHallView(APIView):
operator=str(shop_id)
)
# ---------- 7. 释放本地打手 + 退款统计(仅当非跨平台时处理) ----------
if not is_cross and current_dashou_id:
# ---------- 7. 释放本地打手 + 退款统计 ----------
if current_dashou_id:
try:
dashou_profile = UserDashou.objects.get(user__yonghuid=current_dashou_id)
dashou_profile.zhuangtai = 1 # 设为空闲
@@ -3150,9 +3004,7 @@ class ShopTransferHallView(APIView):
except Exception as e:
logger.error(f"打手每日统计失败: {e}")
# ---------- 8. 清空对方平台信息并重置订单 ----------
order.partner_club_id = None
order.partner_order_id = None
# ---------- 8. 重置订单 ----------
order.jiedan_dashou_id = None
order.clkf = str(shop_id)
@@ -3160,59 +3012,6 @@ class ShopTransferHallView(APIView):
order.zhuangtai = 7 if zhiding_id else 1
order.save()
# ---------- 9. 异步通知对方平台(如果有对方信息) ----------
if is_cross and partner_club_id and partner_order_id:
# 获取我方俱乐部ID
my_club_config = None
try:
my_club_config = ClubConfig.objects.filter(is_self=1).first()
except Exception as e:
logger.error(f"获取俱乐部配置失败: {e}")
if my_club_config:
self_club_id = my_club_config.club_id
def notify():
try:
club_rel = Club.objects.get(club_id=self_club_id, partner_club_id=partner_club_id)
partner_domain = club_rel.partner_domain.rstrip('/')
notify_url = f"{partner_domain}/houtai/kpttzzydt"
payload = {
'order_id': partner_order_id,
'club_id': self_club_id
}
resp = requests.post(notify_url, json=payload, timeout=3)
if resp.status_code == 200:
resp_json = resp.json()
if resp_json.get('code') == 0:
# 更新跨平台订单数据(原接口逻辑)
try:
cross_data, _ = CrossPlatformOrderData.objects.get_or_create(
dingdan_id=dingdan_id,
defaults={
'partner_order_id': partner_order_id,
'partner_club_id': partner_club_id,
'partner_order_status': resp_json.get('data', {}).get('partner_status', 0),
'partner_dashou_id': '',
'partner_amount': order.jine or 0,
}
)
if not _:
cross_data.partner_order_status = resp_json.get('data', {}).get('partner_status', 0)
cross_data.save(update_fields=['partner_order_status'])
logger.info(f"转移大厅通知对方成功: {dingdan_id}")
except Exception as e:
logger.error(f"更新跨平台订单数据失败: {e}")
else:
logger.warning(f"对方平台返回错误: {resp_json.get('msg')}")
else:
logger.warning(f"对方接口HTTP错误: {resp.status_code}")
except Club.DoesNotExist:
logger.error(f"未找到对方俱乐部配置: partner_club_id={partner_club_id}")
except Exception as e:
logger.error(f"转移大厅通知对方异常: {e}")
threading.Thread(target=notify).start()
logger.info(f"转移大厅成功,订单 {dingdan_id}")
return Response({'code': 200, 'msg': '转移大厅成功'})
@@ -3292,13 +3091,8 @@ class ShopFineApplyView(APIView):
if Fadan.objects.filter(beichufa_id=dashou_id, guanliandingdan_id=dingdan_id).exists():
return Response({'code': 400, 'msg': '该打手已被罚款过'})
# ---------- 6. 跨平台相关字段 ----------
partner_order_id = order.partner_order_id or ''
partner_club_id = order.partner_club_id or ''
dispatch_type = order.dispatch_type or 0 # 1=我方派单2=对方派单
# 本地创建罚单的通用函数
def create_local_fadan(partner_club=''):
# ---------- 6. 创建罚单 ----------
with transaction.atomic():
Fadan.objects.create(
beichufa_id=dashou_id,
shenqing_chufa=str(shop_id), # 申请人记为店铺ID
@@ -3309,64 +3103,9 @@ class ShopFineApplyView(APIView):
zhuangtai=1, # 待缴纳
yingxiang_qiangdan=yingxiang_qiangdan,
shenqingren_shenfen=4, # 申请人身份4 店铺管理员
partner_club_id=partner_club,
)
# ---------- 7. 判断处罚流向 ----------
# 情况A没有对方订单ID或对方派单 → 本地处罚
if not partner_order_id or dispatch_type == 2:
with transaction.atomic():
create_local_fadan()
logger.info(f"本地罚款成功: 订单 {dingdan_id}, 打手 {dashou_id}, 金额 {fakuanjine}")
return Response({'code': 200, 'msg': '罚款已生成'})
# ---------- 8. 情况B有对方订单ID且我方派单 → 跨平台通知对方 ----------
# 获取我方俱乐部ID
try:
my_club = ClubConfig.objects.filter(is_self=1).first()
if not my_club:
return Response({'code': 500, 'msg': '系统配置错误,缺少本俱乐部信息'})
self_club_id = my_club.club_id
club_rel = Club.objects.get(club_id=self_club_id, partner_club_id=partner_club_id)
partner_domain = club_rel.partner_domain
except Club.DoesNotExist:
return Response({'code': 500, 'msg': '未找到对方平台配置,无法通知'})
except Exception as e:
logger.error(f"获取对方平台信息失败: {e}")
return Response({'code': 500, 'msg': '获取对方平台信息失败'})
# 构造通知 payload
url = partner_domain.rstrip('/') + '/houtai/kffkdssq_notify'
payload = {
'order_id': partner_order_id, # 对方平台的订单ID
'club_id': self_club_id, # 我方俱乐部ID
'chufaliyou': chufaliyou,
'fakuanjine': fakuanjine,
'yingxiang_qiangdan': yingxiang_qiangdan,
'shenqingren_shenfen': 4, # 店铺管理员身份
'operator': str(shop_id),
}
# 带重试的通知
success = False
for _ in range(2):
try:
resp = requests.post(url, json=payload, timeout=3)
if resp.status_code == 200 and resp.json().get('code') == 0:
success = True
break
except Exception:
continue
if not success:
return Response({'code': 500, 'msg': '通知对方平台失败,请稍后重试'})
# 通知成功后,本地也记录一笔(标记为跨平台)
with transaction.atomic():
create_local_fadan(partner_club=partner_club_id)
logger.info(f"跨平台罚款通知成功: 订单 {dingdan_id}")
return Response({'code': 200, 'msg': '罚款已提交至对方平台'})
logger.info(f"本地罚款成功: 订单 {dingdan_id}, 打手 {dashou_id}, 金额 {fakuanjine}")
return Response({'code': 200, 'msg': '罚款已生成'})
except Exception as e:
logger.error(f"店铺罚款申请异常: {traceback.format_exc()}")