修复了客服数据统计,强化了商家数据获取接口获取更多数据
This commit is contained in:
86
merchant_ops/services/order_enrich.py
Normal file
86
merchant_ops/services/order_enrich.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""订单响应增强:派单客服信息、头像相对路径。"""
|
||||
from merchant_ops.constants import ACTOR_MERCHANT, ACTOR_STAFF
|
||||
from merchant_ops.models import MerchantOrderDispatch, MerchantStaffMember
|
||||
from users.business_models import User
|
||||
|
||||
|
||||
def user_avatar_relative(user):
|
||||
"""返回用户表 Avatar 相对路径(前端自行拼接 OSS)。"""
|
||||
if not user:
|
||||
return ''
|
||||
av = (getattr(user, 'Avatar', None) or '').strip()
|
||||
if not av:
|
||||
return ''
|
||||
if av.startswith('http://') or av.startswith('https://'):
|
||||
return av
|
||||
return av.lstrip('/')
|
||||
|
||||
|
||||
def get_user_avatar_by_uid(uid):
|
||||
if not uid:
|
||||
return ''
|
||||
u = User.query.filter(UserUID=uid).first()
|
||||
return user_avatar_relative(u)
|
||||
|
||||
|
||||
def get_dispatch_staff_payload(order_id):
|
||||
"""订单派单归属;无记录则 None(商家老板派单可能无 dispatch 记录)。"""
|
||||
if not order_id:
|
||||
return None
|
||||
disp = MerchantOrderDispatch.query.filter(order_id=order_id).first()
|
||||
if not disp:
|
||||
return None
|
||||
if disp.dispatch_actor_type == ACTOR_MERCHANT:
|
||||
return {
|
||||
'dispatch_staff_type': ACTOR_MERCHANT,
|
||||
'dispatch_staff_uid': disp.dispatch_actor_id or '',
|
||||
'dispatch_staff_name': '商家老板',
|
||||
'dispatch_role_code': '',
|
||||
'dispatch_role_name': '商家老板',
|
||||
'dispatch_member_id': None,
|
||||
}
|
||||
if disp.staff_member_id:
|
||||
m = MerchantStaffMember.query.filter(id=disp.staff_member_id).select_related('role').first()
|
||||
if m:
|
||||
return {
|
||||
'dispatch_staff_type': ACTOR_STAFF,
|
||||
'dispatch_staff_uid': m.staff_user_id,
|
||||
'dispatch_staff_name': m.display_name or (m.role.role_name if m.role else m.staff_user_id),
|
||||
'dispatch_role_code': m.role.role_code if m.role else '',
|
||||
'dispatch_role_name': m.role.role_name if m.role else '',
|
||||
'dispatch_member_id': m.id,
|
||||
}
|
||||
return {
|
||||
'dispatch_staff_type': disp.dispatch_actor_type,
|
||||
'dispatch_staff_uid': disp.dispatch_actor_id or '',
|
||||
'dispatch_staff_name': disp.dispatch_actor_id or '',
|
||||
'dispatch_role_code': '',
|
||||
'dispatch_role_name': '',
|
||||
'dispatch_member_id': disp.staff_member_id,
|
||||
}
|
||||
|
||||
|
||||
def enrich_order_detail_data(data, order_id):
|
||||
"""订单详情追加派单客服;打手头像优先用户表相对路径。"""
|
||||
if not data or not isinstance(data, dict):
|
||||
return data
|
||||
payload = get_dispatch_staff_payload(order_id)
|
||||
if payload:
|
||||
data['dispatch_staff'] = payload
|
||||
else:
|
||||
data['dispatch_staff'] = None
|
||||
dashou_uid = data.get('dashou_yonghuid') or data.get('fuwudashou_id') or ''
|
||||
av = get_user_avatar_by_uid(dashou_uid)
|
||||
if av:
|
||||
data['dashou_avatar'] = av
|
||||
return data
|
||||
|
||||
|
||||
def staff_order_list_item(ext):
|
||||
"""子客服订单列表项:不含派单客服字段,打手头像走用户表。"""
|
||||
from merchant_ops.services.order_query import staff_order_to_dict
|
||||
d = staff_order_to_dict(ext)
|
||||
pid = d.get('jiedan_dashou_id')
|
||||
if pid:
|
||||
d['jiedan_dashou_avatar'] = get_user_avatar_by_uid(pid)
|
||||
return d
|
||||
@@ -126,30 +126,49 @@ class StaffMemberListView(APIView):
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
from datetime import date
|
||||
from users.business_models import User
|
||||
from merchant_ops.services.order_enrich import user_avatar_relative
|
||||
|
||||
mid = request.user.UserUID
|
||||
ensure_owner_merchant(mid, request.user)
|
||||
today = date.today()
|
||||
members = MerchantStaffMember.query.filter(
|
||||
merchant_id=mid, status=MEMBER_STATUS_ACTIVE,
|
||||
merchant_id=mid,
|
||||
status__in=[MEMBER_STATUS_ACTIVE, MEMBER_STATUS_DISABLED],
|
||||
).select_related('role')
|
||||
result = []
|
||||
for m in members:
|
||||
stats = MerchantStaffDailyStats.query.filter(member_id=m.id).aggregate(
|
||||
total_stats = MerchantStaffDailyStats.query.filter(member_id=m.id).aggregate(
|
||||
dispatch_count=Sum('dispatch_count'),
|
||||
settle_count=Sum('settle_count'),
|
||||
settle_amount=Sum('settle_amount'),
|
||||
refund_count=Sum('refund_count'),
|
||||
)
|
||||
wallet = m.wallets.first()
|
||||
today_stat = MerchantStaffDailyStats.query.filter(
|
||||
member_id=m.id, stat_date=today,
|
||||
).first()
|
||||
wallet = get_or_create_wallet(m)
|
||||
u = User.query.filter(UserUID=m.staff_user_id).first()
|
||||
result.append({
|
||||
'id': m.id,
|
||||
'uid': m.staff_user_id,
|
||||
'nickname': m.display_name or m.staff_user_id,
|
||||
'isChief': m.role.role_code == 'CHIEF',
|
||||
'isFinance': m.role.role_code == 'FINANCE',
|
||||
'role_name': m.role.role_name,
|
||||
'orderCount': stats['dispatch_count'] or 0,
|
||||
'settleCount': stats['settle_count'] or 0,
|
||||
'settleAmount': str(stats['settle_amount'] or '0.00'),
|
||||
'quota_available': str(wallet.quota_available if wallet else 0),
|
||||
'avatar': user_avatar_relative(u),
|
||||
'role_name': m.role.role_name if m.role else '',
|
||||
'isChief': m.role.role_code == 'CHIEF' if m.role else False,
|
||||
'isFinance': m.role.role_code == 'FINANCE' if m.role else False,
|
||||
'status': m.status,
|
||||
'isDisabled': m.status == MEMBER_STATUS_DISABLED,
|
||||
'todayDispatchCount': today_stat.dispatch_count if today_stat else int(m.today_dispatch_count or 0),
|
||||
'dispatchCount': total_stats['dispatch_count'] or 0,
|
||||
'orderCount': total_stats['dispatch_count'] or 0,
|
||||
'settleCount': total_stats['settle_count'] or 0,
|
||||
'refundCount': total_stats['refund_count'] or 0,
|
||||
'settleAmount': str(total_stats['settle_amount'] or '0.00'),
|
||||
'quota_available': str(wallet.quota_available),
|
||||
'quota_total': str(wallet.quota_total),
|
||||
'quota_used': str(wallet.quota_used),
|
||||
})
|
||||
return Response({'code': 0, 'msg': '成功', 'data': {'list': result}})
|
||||
except Exception as e:
|
||||
|
||||
@@ -13,8 +13,8 @@ from merchant_ops.services.order_query import (
|
||||
staff_apply_order_filters,
|
||||
staff_can_view_all_orders,
|
||||
staff_order_ext_qs,
|
||||
staff_order_to_dict,
|
||||
)
|
||||
from merchant_ops.services.order_enrich import staff_order_list_item
|
||||
from merchant_ops.services.audit import audit_staff
|
||||
from merchant_ops.services.dispatch import staff_dispatch_order
|
||||
from merchant_ops.services.stats import bump_cancel_count, bump_penalty_count, update_merchant_and_staff_stats
|
||||
@@ -77,7 +77,7 @@ class StaffOrderListView(APIView):
|
||||
start = (page - 1) * page_size
|
||||
page_qs = base_qs.order_by('-Order__CreateTime')[start:start + page_size]
|
||||
|
||||
order_list = [staff_order_to_dict(ext) for ext in page_qs]
|
||||
order_list = [staff_order_list_item(ext) for ext in page_qs]
|
||||
|
||||
return Response({
|
||||
'code': 0,
|
||||
@@ -105,6 +105,9 @@ class StaffOrderDetailView(APIView):
|
||||
resp = proxy_merchant_order_view(
|
||||
request, member, ShangjiaDingdanXiangqingView, 'order_detail',
|
||||
)
|
||||
if resp.status_code == 200 and resp.data.get('code') == 0 and resp.data.get('data'):
|
||||
from merchant_ops.services.order_enrich import enrich_order_detail_data
|
||||
enrich_order_detail_data(resp.data['data'], pick_order_id(request.data))
|
||||
return resp
|
||||
except Exception as e:
|
||||
return _err(e)
|
||||
@@ -186,6 +189,11 @@ class StaffRefundView(APIView):
|
||||
resp = proxy_merchant_order_view(request, member, ShangjiaTuikuanShenqingView, 'order_refund_apply')
|
||||
if resp.data.get('code') in (0, 200):
|
||||
audit_staff(member, 'REFUND_APPLY', request, resource_id=pick_order_id(request.data))
|
||||
from orders.models import Order
|
||||
oid = pick_order_id(request.data)
|
||||
o = Order.query.filter(OrderID=oid).first()
|
||||
if o:
|
||||
update_merchant_and_staff_stats(member.merchant_id, member, o.Amount, STAT_ACTION_REFUND)
|
||||
return resp
|
||||
except Exception as e:
|
||||
return _err(e)
|
||||
|
||||
@@ -2310,6 +2310,12 @@ class ShangjiaDingdanXiangqingView(APIView):
|
||||
'xin_dingdan_id': xin_dingdan_id,
|
||||
}
|
||||
|
||||
try:
|
||||
from merchant_ops.services.order_enrich import enrich_order_detail_data
|
||||
enrich_order_detail_data(response_data, dingdan_id)
|
||||
except Exception as e:
|
||||
logger.warning(f'派单客服信息附加失败: {e}')
|
||||
|
||||
return Response({
|
||||
'code': 0,
|
||||
'msg': '成功',
|
||||
|
||||
Reference in New Issue
Block a user