修复了已知的生产环境问题

This commit is contained in:
2026-06-17 21:25:45 +08:00
parent d00f0d08e5
commit 4aca437d2b
25 changed files with 13547 additions and 13423 deletions

View File

@@ -1,198 +1,198 @@
# utils/chat_utils.py
import json
import logging
import requests
from django.conf import settings
from orders.models import Dingdan, DingdanPingtai, DingdanShangjia
from users.models import UserDashou, UserBoss, UserShangjia
from gvsdsdk.models import User
logger = logging.getLogger('chat_utils')
# ========== 辅助配置获取 ==========
def _get_self_goeasy_appkey():
return getattr(settings, 'GOEASY_APPKEY', '')
def _get_self_goeasy_secret():
return getattr(settings, 'GOEASY_SECRET', '')
# ========== 头像拼接 ==========
def _full_local_avatar(relative_url):
if not relative_url:
return ''
if relative_url.startswith('http'):
return relative_url
return relative_url
# ========== GoEasy 订阅 ==========
def _subscribe_users_to_group(user_ids, group_ids, appkey=None, secret=None):
if not appkey:
appkey = _get_self_goeasy_appkey()
if not secret:
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
url = 'https://rest-hangzhou.goeasy.io/v2/im/subscribe-groups'
body = {"appkey": appkey, "userIds": user_ids, "groupIds": group_ids}
headers = {"Content-Type": "application/json"}
if secret:
headers["Authorization"] = f"Bearer {secret}"
try:
resp = requests.post(url, headers=headers, json=body, timeout=10)
if resp.status_code == 200:
return True
logger.error(f"订阅失败: {resp.status_code} {resp.text}")
return False
except Exception as e:
logger.error(f"订阅异常: {e}", exc_info=True)
return False
# ========== 发送群消息(完整参数) ==========
def _send_group_message(appkey, secret, group_id, sender_id, sender_name, sender_avatar,
message_text, custom_payload=None, group_name=None, order_id=None):
if not appkey:
appkey = _get_self_goeasy_appkey()
if not secret:
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
url = 'https://rest-hangzhou.goeasy.io/v2/im/message'
# to.data 包含群聊展示信息及业务字段
to_data = {
"name": group_name or group_id,
"avatar": sender_avatar or "",
}
if order_id:
to_data["orderId"] = order_id
payload_str = custom_payload.get("text", message_text) if custom_payload else message_text
request_body = {
"appkey": appkey,
"senderId": sender_id,
"senderData": {"avatar": sender_avatar, "name": sender_name},
"to": {
"type": "group",
"id": group_id,
"data": to_data
},
"type": "text",
"payload": payload_str
}
headers = {"Content-Type": "application/json"}
if secret:
headers["Authorization"] = f"Bearer {secret}"
try:
resp = requests.post(url, headers=headers, json=request_body, timeout=10)
if resp.status_code == 200:
return True
logger.error(f"群聊消息发送失败,状态码:{resp.status_code},响应:{resp.text}")
return False
except Exception as e:
logger.error(f"发送群聊消息异常: {e}", exc_info=True)
return False
# ========== 核心入口 ==========
def establish_order_chat(dingdan_id):
try:
order = Dingdan.objects.select_related('pingtai_kuozhan', 'shangjia_kuozhan').get(dingdan_id=dingdan_id)
except Dingdan.DoesNotExist:
logger.error(f"订单 {dingdan_id} 不存在")
return False
dashou_uid = order.jiedan_dashou_id
dashou_goeasy_id = f"Ds{dashou_uid}"
dashou_nickname = f'打手{dashou_uid[:6]}'
dashou_avatar_relative = ''
try:
dashou_user = User.objects.get(yonghuid=dashou_uid)
dashou_avatar_relative = dashou_user.avatar or ''
dashou_profile = UserDashou.objects.get(user=dashou_user)
if dashou_profile.nicheng:
dashou_nickname = dashou_profile.nicheng
except Exception as e:
logger.warning(f"获取打手信息失败: {e}")
dashou_avatar = _full_local_avatar(dashou_avatar_relative)
appkey = _get_self_goeasy_appkey()
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
# 本地订单处理
return _handle_local_order(order, dashou_goeasy_id, dashou_nickname, dashou_avatar, appkey, secret)
# ========== 普通订单 / 我方派单 ==========
def _handle_local_order(order, dashou_goeasy_id, dashou_name, dashou_avatar, appkey, secret):
group_id = f"group_{order.dingdan_id}"
group_name = (order.jieshao[:20] + '') if order.jieshao and len(order.jieshao) > 20 else (order.jieshao or f"订单{order.dingdan_id}")
group_avatar = _full_local_avatar(order.tupian) if order.tupian else _full_local_avatar('')
partner_goeasy_id, partner_name, partner_avatar = _get_local_partner_info(order)
if not partner_goeasy_id:
return False
# 订阅双方
if not _subscribe_users_to_group([dashou_goeasy_id, partner_goeasy_id], [group_id], appkey, secret):
return False
# 1. 打手发送初始化消息
init_msg_text = f"订单已接单,内容:{order.jieshao},备注:{order.beizhu}游戏ID{order.nicheng}"
success1 = _send_group_message(
appkey, secret, group_id, dashou_goeasy_id, dashou_name, group_avatar,
init_msg_text, None, group_name=group_name, order_id=order.dingdan_id
)
# 2. 【新增】派单方也发一条消息,确保他也能看到群聊
partner_msg = f"订单已确认,请开始服务。"
success2 = _send_group_message(
appkey, secret, group_id, partner_goeasy_id, partner_name, partner_avatar,
partner_msg, None, group_name=group_name, order_id=order.dingdan_id
)
return success1 and success2
def _get_local_partner_info(order):
"""本地订单下单方:老板或商家"""
if order.fadan_pingtai == 1: # 老板
try:
ext = order.pingtai_kuozhan
laoban_id = ext.laoban_id
avatar_full = _full_local_avatar('')
nickname = f'老板{laoban_id[:6]}'
try:
boss_user = User.objects.get(yonghuid=laoban_id)
avatar_full = _full_local_avatar(boss_user.avatar or '')
boss_profile = UserBoss.objects.get(user=boss_user)
if boss_profile.nickname:
nickname = boss_profile.nickname
except Exception:
pass
return f"Boss{laoban_id}", nickname, avatar_full
except Exception as e:
logger.error(f"获取老板信息失败: {e}")
return None, None, None
elif order.fadan_pingtai == 2: # 商家
try:
ext = order.shangjia_kuozhan
shangjia_id = ext.shangjia_id
nickname = ext.sjnicheng or f'商家{shangjia_id[:6]}'
avatar_full = _full_local_avatar('')
try:
sj_user = User.objects.get(yonghuid=shangjia_id)
avatar_full = _full_local_avatar(sj_user.avatar or '')
except Exception:
pass
return f"Sj{shangjia_id}", nickname, avatar_full
except Exception as e:
logger.error(f"获取商家信息失败: {e}")
return None, None, None
else:
if order.user1_id:
return order.user1_id, "用户", _full_local_avatar('')
# utils/chat_utils.py
import json
import logging
import requests
from django.conf import settings
from orders.models import Dingdan, DingdanPingtai, DingdanShangjia
from users.models import UserDashou, UserBoss, UserShangjia
from gvsdsdk.models import User
logger = logging.getLogger('chat_utils')
# ========== 辅助配置获取 ==========
def _get_self_goeasy_appkey():
return getattr(settings, 'GOEASY_APPKEY', '')
def _get_self_goeasy_secret():
return getattr(settings, 'GOEASY_SECRET', '')
# ========== 头像拼接 ==========
def _full_local_avatar(relative_url):
if not relative_url:
return ''
if relative_url.startswith('http'):
return relative_url
return relative_url
# ========== GoEasy 订阅 ==========
def _subscribe_users_to_group(user_ids, group_ids, appkey=None, secret=None):
if not appkey:
appkey = _get_self_goeasy_appkey()
if not secret:
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
url = 'https://rest-hangzhou.goeasy.io/v2/im/subscribe-groups'
body = {"appkey": appkey, "userIds": user_ids, "groupIds": group_ids}
headers = {"Content-Type": "application/json"}
if secret:
headers["Authorization"] = f"Bearer {secret}"
try:
resp = requests.post(url, headers=headers, json=body, timeout=10)
if resp.status_code == 200:
return True
logger.error(f"订阅失败: {resp.status_code} {resp.text}")
return False
except Exception as e:
logger.error(f"订阅异常: {e}", exc_info=True)
return False
# ========== 发送群消息(完整参数) ==========
def _send_group_message(appkey, secret, group_id, sender_id, sender_name, sender_avatar,
message_text, custom_payload=None, group_name=None, order_id=None):
if not appkey:
appkey = _get_self_goeasy_appkey()
if not secret:
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
url = 'https://rest-hangzhou.goeasy.io/v2/im/message'
# to.data 包含群聊展示信息及业务字段
to_data = {
"name": group_name or group_id,
"avatar": sender_avatar or "",
}
if order_id:
to_data["orderId"] = order_id
payload_str = custom_payload.get("text", message_text) if custom_payload else message_text
request_body = {
"appkey": appkey,
"senderId": sender_id,
"senderData": {"avatar": sender_avatar, "name": sender_name},
"to": {
"type": "group",
"id": group_id,
"data": to_data
},
"type": "text",
"payload": payload_str
}
headers = {"Content-Type": "application/json"}
if secret:
headers["Authorization"] = f"Bearer {secret}"
try:
resp = requests.post(url, headers=headers, json=request_body, timeout=10)
if resp.status_code == 200:
return True
logger.error(f"群聊消息发送失败,状态码:{resp.status_code},响应:{resp.text}")
return False
except Exception as e:
logger.error(f"发送群聊消息异常: {e}", exc_info=True)
return False
# ========== 核心入口 ==========
def establish_order_chat(dingdan_id):
try:
order = Dingdan.objects.select_related('pingtai_kuozhan', 'shangjia_kuozhan').get(dingdan_id=dingdan_id)
except Dingdan.DoesNotExist:
logger.error(f"订单 {dingdan_id} 不存在")
return False
dashou_uid = order.jiedan_dashou_id
dashou_goeasy_id = f"Ds{dashou_uid}"
dashou_nickname = f'打手{dashou_uid[:6]}'
dashou_avatar_relative = ''
try:
dashou_user = User.objects.get(UserUID=dashou_uid)
dashou_avatar_relative = dashou_user.avatar or ''
dashou_profile = UserDashou.objects.get(user=dashou_user)
if dashou_profile.nicheng:
dashou_nickname = dashou_profile.nicheng
except Exception as e:
logger.warning(f"获取打手信息失败: {e}")
dashou_avatar = _full_local_avatar(dashou_avatar_relative)
appkey = _get_self_goeasy_appkey()
secret = _get_self_goeasy_secret()
if not appkey:
logger.error("GoEasy AppKey 未配置")
return False
# 本地订单处理
return _handle_local_order(order, dashou_goeasy_id, dashou_nickname, dashou_avatar, appkey, secret)
# ========== 普通订单 / 我方派单 ==========
def _handle_local_order(order, dashou_goeasy_id, dashou_name, dashou_avatar, appkey, secret):
group_id = f"group_{order.dingdan_id}"
group_name = (order.jieshao[:20] + '') if order.jieshao and len(order.jieshao) > 20 else (order.jieshao or f"订单{order.dingdan_id}")
group_avatar = _full_local_avatar(order.tupian) if order.tupian else _full_local_avatar('')
partner_goeasy_id, partner_name, partner_avatar = _get_local_partner_info(order)
if not partner_goeasy_id:
return False
# 订阅双方
if not _subscribe_users_to_group([dashou_goeasy_id, partner_goeasy_id], [group_id], appkey, secret):
return False
# 1. 打手发送初始化消息
init_msg_text = f"订单已接单,内容:{order.jieshao},备注:{order.beizhu}游戏ID{order.nicheng}"
success1 = _send_group_message(
appkey, secret, group_id, dashou_goeasy_id, dashou_name, group_avatar,
init_msg_text, None, group_name=group_name, order_id=order.dingdan_id
)
# 2. 【新增】派单方也发一条消息,确保他也能看到群聊
partner_msg = f"订单已确认,请开始服务。"
success2 = _send_group_message(
appkey, secret, group_id, partner_goeasy_id, partner_name, partner_avatar,
partner_msg, None, group_name=group_name, order_id=order.dingdan_id
)
return success1 and success2
def _get_local_partner_info(order):
"""本地订单下单方:老板或商家"""
if order.fadan_pingtai == 1: # 老板
try:
ext = order.pingtai_kuozhan
laoban_id = ext.laoban_id
avatar_full = _full_local_avatar('')
nickname = f'老板{laoban_id[:6]}'
try:
boss_user = User.objects.get(UserUID=laoban_id)
avatar_full = _full_local_avatar(boss_user.avatar or '')
boss_profile = UserBoss.objects.get(user=boss_user)
if boss_profile.nickname:
nickname = boss_profile.nickname
except Exception:
pass
return f"Boss{laoban_id}", nickname, avatar_full
except Exception as e:
logger.error(f"获取老板信息失败: {e}")
return None, None, None
elif order.fadan_pingtai == 2: # 商家
try:
ext = order.shangjia_kuozhan
shangjia_id = ext.shangjia_id
nickname = ext.sjnicheng or f'商家{shangjia_id[:6]}'
avatar_full = _full_local_avatar('')
try:
sj_user = User.objects.get(UserUID=shangjia_id)
avatar_full = _full_local_avatar(sj_user.avatar or '')
except Exception:
pass
return f"Sj{shangjia_id}", nickname, avatar_full
except Exception as e:
logger.error(f"获取商家信息失败: {e}")
return None, None, None
else:
if order.user1_id:
return order.user1_id, "用户", _full_local_avatar('')
return None, None, None