From 981d0d047c062d27d8ed5911c2595febb48d159e Mon Sep 17 00:00:00 2001 From: XingQue Date: Tue, 28 Jul 2026 14:08:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=A2=E6=9C=8D=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E6=8C=89=E7=94=A8=E6=88=B7=E4=BF=B1=E4=B9=90=E9=83=A8=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=BE=85=E6=8E=A5=E5=85=A5=E4=BC=9A=E8=AF=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- backend/urls.py | 2 ++ backend/view.py | 4 +-- backend/views/kefu.py | 73 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/backend/urls.py b/backend/urls.py index 88fe5c7..b3f87c8 100644 --- a/backend/urls.py +++ b/backend/urls.py @@ -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='后台罚单统计图片'), # 罚款统计 diff --git a/backend/view.py b/backend/view.py index 0ed2f09..55dbccc 100644 --- a/backend/view.py +++ b/backend/view.py @@ -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', diff --git a/backend/views/kefu.py b/backend/views/kefu.py index 9c87d06..321a648 100644 --- a/backend/views/kefu.py +++ b/backend/views/kefu.py @@ -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)