feat: 客服聊天按用户俱乐部过滤待接入会话

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-28 14:08:59 +08:00
parent 2ff5df09bc
commit 5cfb4a1b2b
3 changed files with 77 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ from .view import (GetRolePermissionView,
ModifyProductTypeZoneView, GetRateView, ModifyRateView, PopupNoticeListAPIView, PopupNoticeModifyAPIView,ShopListView,
ShopModifyView, ShopPublicTypeAndAuditView, ShopListForProductView, ShopProductModifyView,
ShopProductTypeMappingView, ProductListView, ProductModifyView, ShopCopyCatalogView, KefuChatPermissionsView,
KefuImUserClubFilterView,
FineApplyView, PunishDashouView,
FaKuanTongJiView, FaKuanLieBiaoView, FaKuanChuLiView, FaKuanChuangJianView, FaKuanPingTaiShenHeView,
HqbkxxView,BkxgView,CaiwuView,CwhybkhqView, HybkjtsjView, SzxxView, CwddhqlxView, CwhqjtddsjView,
@@ -90,6 +91,7 @@ urlpatterns = [
path('htfzdpspsj', ShopCopyCatalogView.as_view(), name='后台复制店铺商品目录'),
path('kfhqltqx', KefuChatPermissionsView.as_view(), name='后台获取客服聊天配置'),
path('kfimssclub', KefuImUserClubFilterView.as_view(), name='客服聊天按俱乐部过滤客户ID'),
path('htglyhqcfsltj', FaKuanTongJiView.as_view(),name='后台罚单统计图片'), # 罚款统计

View File

@@ -36,7 +36,7 @@ from .views.kefu import (
KefuGetDashouListView, KefuGetDashouDetailView, KefuUpdateDashouView,
KefuGetShangjiaListView, KefuGetShangjiaDetailView, KefuUpdateShangjiaView,
KefuAddShangjiaView,
KefuChatPermissionsView,
KefuChatPermissionsView, KefuImUserClubFilterView,
DashouGiftHuiyuanSaveView, DashouGiftHuiyuanRemoveView,
)
from .views.products import (
@@ -102,7 +102,7 @@ __all__ = [
'DashouGiftHuiyuanSaveView', 'DashouGiftHuiyuanRemoveView',
'KefuGetShangjiaListView', 'KefuGetShangjiaDetailView', 'KefuUpdateShangjiaView',
'KefuAddShangjiaView',
'KefuChatPermissionsView',
'KefuChatPermissionsView', 'KefuImUserClubFilterView',
# products
'GetProductBaseDataView', 'GetProductListView', 'SaveProductOrderView',
'AddProductView', 'DeleteProductView', 'GetProductDetailView', 'UpdateProductView',

View File

@@ -77,6 +77,7 @@ from users.models import (
UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan
)
from users.business_models import User
from jituan.constants import CLUB_ID_DEFAULT
## orders
from orders.models import (
@@ -1315,6 +1316,78 @@ class KefuChatPermissionsView(APIView):
})
class KefuImUserClubFilterView(APIView):
"""
批量校验 GoEasy 客户 ID 所属俱乐部(供客服待接入/已接入列表前端过滤)。
POST /houtai/kfimssclub
Body: { "phone": "客服手机号", "im_ids": ["Boss1234567", "Ds7654321"] }
返回 allowed_ids当前后台俱乐部可见的 IM ID集团汇总则全部可解析的都返回
"""
permission_classes = [IsAuthenticated]
parser_classes = [JSONParser]
_IM_UID_RE = re.compile(
r'^(Boss|Ds|Sj|Gs|Zz|Guanshi|Zuzhang|Kaoheguan)(\d+)$',
re.IGNORECASE,
)
def post(self, request):
phone = (request.data.get('phone') or request.data.get('username') or '').strip()
kefu_obj, permissions = verify_kefu_permission(request, phone or None)
if kefu_obj is None:
return permissions
if not any(p in CHAT_PERM_CODES for p in permissions):
return Response({'code': 403, 'msg': '无聊天权限', 'data': None})
raw_ids = request.data.get('im_ids') or request.data.get('ids') or []
if not isinstance(raw_ids, list):
return Response({'code': 400, 'msg': 'im_ids 必须为数组', 'data': None})
# 去重、截断,避免一次打太多
im_ids = []
seen = set()
for x in raw_ids[:200]:
s = str(x or '').strip()
if s and s not in seen:
seen.add(s)
im_ids.append(s)
uid_to_ims = {}
for im_id in im_ids:
m = self._IM_UID_RE.match(im_id)
if not m:
continue
uid = m.group(2)
uid_to_ims.setdefault(uid, []).append(im_id)
club_map = {}
if uid_to_ims:
for u in User.query.filter(UserUID__in=list(uid_to_ims.keys())).only('UserUID', 'ClubID'):
cid = (getattr(u, 'ClubID', None) or '').strip() or CLUB_ID_DEFAULT
for im_id in uid_to_ims.get(u.UserUID, []):
club_map[im_id] = cid
from jituan.constants import DATA_SCOPE_ALL
from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope
scope = resolve_club_scope(request)
if scope == DATA_SCOPE_ALL:
allowed_ids = [i for i in im_ids if i in club_map]
else:
current = resolve_club_id_from_request(request)
allowed_ids = [i for i in im_ids if club_map.get(i) == current]
return Response({
'code': 0,
'msg': 'ok',
'data': {
'allowed_ids': allowed_ids,
'club_map': club_map,
'scope': 'all' if scope == DATA_SCOPE_ALL else 'single',
},
})
class DashouGiftHuiyuanSaveView(APIView):
"""
赠送会员 / 改期(免费接单资格,写入 dashou_zengsong_huiyuan