@@ -6,7 +6,8 @@ from account import views as account_views |
||
6 | 6 |
from account import tourguide_views |
7 | 7 |
from geo import views as geo_views |
8 | 8 |
from group import views as group_views |
9 |
-from group import groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupuser_views |
|
9 |
+from group import (groupuser_views, lensman_views, tourguidegroup_views, tourguidegroupadmin_views, |
|
10 |
+ tourguidegroupuser_views) |
|
10 | 11 |
from message import views as message_views |
11 | 12 |
from miniapp import views as mini_views |
12 | 13 |
from operation import views as op_views |
@@ -79,6 +80,10 @@ urlpatterns += [ |
||
79 | 80 |
# url(r'^tg/gather/end$', tourguidegroup_views.tg_group_gather_end_api, name='tg_group_gather_end_api'), # 旅行团集合结束,清理数据 |
80 | 81 |
url(r'^tg/token$', tourguidegroup_views.tg_group_token_api, name='tg_group_token_api'), # 旅行团权限管理票据 |
81 | 82 |
url(r'^tg/transfer$', tourguidegroup_views.tg_group_transfer_api, name='tg_group_transfer_api'), # 旅行团权限管理转移 |
83 |
+ |
|
84 |
+ url(r'^tg/admin/list$', tourguidegroupadmin_views.tg_group_admin_list_api, name='tg_group_admin_list_api'), # 旅行团管理员列表 |
|
85 |
+ url(r'^tg/admin/recovery$', tourguidegroupadmin_views.tg_group_admin_recovery_api, name='tg_group_admin_recovery_api'), # 旅行团管理员权限回收,管理员主动,团成员被动 |
|
86 |
+ url(r'^tg/admin/waiver$', tourguidegroupadmin_views.tg_group_admin_waiver_api, name='tg_group_admin_waiver_api'), # 旅行团管理员权限放弃 |
|
82 | 87 |
] |
83 | 88 |
|
84 | 89 |
# 旅行团成员相关 |
@@ -88,9 +88,13 @@ def group_user_remove_api(request): |
||
88 | 88 |
return response(GroupStatusCode.GROUP_NOT_FOUND) |
89 | 89 |
|
90 | 90 |
# 权限校验 |
91 |
- if group.admin_id != admin_id or group.admin_id == user_id: # 管理员也不允许将自己移除 |
|
91 |
+ if group.admin_id != admin_id: |
|
92 | 92 |
return response(GroupStatusCode.NO_REMOVE_PERMISSION) |
93 | 93 |
|
94 |
+ # 管理员也不允许将自己移除 |
|
95 |
+ if group.admin_id == user_id: |
|
96 |
+ return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF) |
|
97 |
+ |
|
94 | 98 |
# 群组用户校验 |
95 | 99 |
try: |
96 | 100 |
group_user = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, status=True) |
@@ -177,6 +177,22 @@ class GroupUserInfo(CreateUpdateMixin): |
||
177 | 177 |
'remark': self.remark, |
178 | 178 |
} |
179 | 179 |
|
180 |
+ @property |
|
181 |
+ def admin_info(self): |
|
182 |
+ return { |
|
183 |
+ 'user_id': self.user_id, |
|
184 |
+ 'nickname': self.nickname, |
|
185 |
+ 'avatar': self.avatar, |
|
186 |
+ 'admin': self.admin, |
|
187 |
+ 'subadmin': self.subadmin, |
|
188 |
+ 'name': self.name, |
|
189 |
+ 'phone': self.phone, |
|
190 |
+ 'relative_persons': self.relative_persons, |
|
191 |
+ 'authority': self.authority, |
|
192 |
+ 'remark': self.remark, |
|
193 |
+ 'status': self.status, |
|
194 |
+ } |
|
195 |
+ |
|
180 | 196 |
|
181 | 197 |
class GroupPhotoInfo(CreateUpdateMixin): |
182 | 198 |
APP_GROUP = 0 |
@@ -13,6 +13,7 @@ from TimeConvert import TimeConvert as tc |
||
13 | 13 |
|
14 | 14 |
from account.models import UserInfo |
15 | 15 |
from group.models import GroupInfo, GroupUserInfo |
16 |
+from utils.admin_utils import is_group_admin, is_group_subadmin |
|
16 | 17 |
from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, TokenStatusCode, UserStatusCode |
17 | 18 |
from utils.error.response_utils import response |
18 | 19 |
from utils.redis.connect import r |
@@ -263,8 +264,8 @@ def tg_group_gather_start_api(request): |
||
263 | 264 |
return response(GroupStatusCode.GROUP_NOT_FOUND) |
264 | 265 |
|
265 | 266 |
# 权限校验 |
266 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists(): |
|
267 |
- return response(GroupStatusCode.NO_UPDATE_PERMISSION) |
|
267 |
+ if not is_group_subadmin(group_id, admin_id): |
|
268 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
268 | 269 |
|
269 | 270 |
# 集合信息设置 |
270 | 271 |
group.gather_at = gather_at |
@@ -331,8 +332,8 @@ def tg_group_transfer_api(request): |
||
331 | 332 |
return response(GroupStatusCode.GROUP_NOT_FOUND) |
332 | 333 |
|
333 | 334 |
# 权限校验 |
334 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, admin=True, status=True).exists(): |
|
335 |
- return response(GroupStatusCode.NO_TRANSFER_PERMISSION) |
|
335 |
+ if not is_group_admin(group_id, admin_id): |
|
336 |
+ return response(GroupStatusCode.NOT_GROUP_ADMIN) |
|
336 | 337 |
|
337 | 338 |
# 群组用户记录创建,若记录不存在,则创建,若记录已存在,则更新 |
338 | 339 |
group_user, created = GroupUserInfo.objects.get_or_create( |
@@ -0,0 +1,89 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from __future__ import division |
|
4 |
+ |
|
5 |
+import json |
|
6 |
+ |
|
7 |
+from django.conf import settings |
|
8 |
+from django.db import transaction |
|
9 |
+from logit import logit |
|
10 |
+from TimeConvert import TimeConvert as tc |
|
11 |
+ |
|
12 |
+from account.models import UserInfo |
|
13 |
+from group.models import GroupInfo, GroupUserInfo |
|
14 |
+from utils.admin_utils import is_group_admin, is_group_subadmin |
|
15 |
+from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, UserStatusCode |
|
16 |
+from utils.error.response_utils import response |
|
17 |
+from utils.group_photo_utils import get_current_photos |
|
18 |
+from utils.redis.connect import r |
|
19 |
+from utils.redis.rgroup import get_group_info, get_group_users_info, get_group_users_kv_info, set_group_users_info |
|
20 |
+from utils.redis.rkeys import (GROUP_LAST_PHOTO_PK, GROUP_USERS_DELETED_SET, GROUP_USERS_PASSED_SET, |
|
21 |
+ GROUP_USERS_QUIT_SET, GROUP_USERS_REFUSED_SET, TOUR_GUIDE_GROUP_CUR_GATHER_INFO, |
|
22 |
+ TOUR_GUIDE_GROUP_CUR_SESSION, TOUR_GUIDE_GROUP_GEO_INFO, TOUR_GUIDE_GROUP_GEO_SUBMIT_DT, |
|
23 |
+ TOUR_GUIDE_GROUP_USER_GEO_LIST) |
|
24 |
+from utils.redis.rtourguide import get_tour_guide_own_group |
|
25 |
+from utils.redis.rtouruser import set_tour_user_belong_group |
|
26 |
+ |
|
27 |
+ |
|
28 |
+@logit |
|
29 |
+def tg_group_admin_list_api(request): |
|
30 |
+ """ 旅行团管理员列表 """ |
|
31 |
+ group_id = request.POST.get('group_id', '') |
|
32 |
+ admin_id = request.POST.get('admin_id', '') # 导游唯一标识 |
|
33 |
+ |
|
34 |
+ # 权限校验 |
|
35 |
+ if not is_group_admin(group_id, admin_id): |
|
36 |
+ return response(GroupStatusCode.NOT_GROUP_ADMIN) |
|
37 |
+ |
|
38 |
+ admins = GroupUserInfo.objects.filter(group_id=group_id, subadmin=True) |
|
39 |
+ admins = [admin.admin_info for admin in admins] |
|
40 |
+ |
|
41 |
+ return response(200, 'Get Tour Guide Group Admin List Success', u'获取旅行团管理员列表成功', { |
|
42 |
+ 'group_id': group_id, |
|
43 |
+ 'admins': admins, |
|
44 |
+ }) |
|
45 |
+ |
|
46 |
+ |
|
47 |
+@logit |
|
48 |
+def tg_group_admin_recovery_api(request): |
|
49 |
+ """ 旅行团管理员权限回收,管理员主动,团成员被动 """ |
|
50 |
+ group_id = request.POST.get('group_id', '') |
|
51 |
+ admin_id = request.POST.get('admin_id', '') # 导游唯一标识 |
|
52 |
+ user_id = request.POST.get('user_id', '') |
|
53 |
+ |
|
54 |
+ # 权限校验 |
|
55 |
+ if not is_group_admin(group_id, admin_id): |
|
56 |
+ return response(GroupStatusCode.NOT_GROUP_ADMIN) |
|
57 |
+ |
|
58 |
+ # 管理员也不允许将自己移除 |
|
59 |
+ if admin_id == user_id: |
|
60 |
+ return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF) |
|
61 |
+ |
|
62 |
+ try: |
|
63 |
+ subadmin = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, subadmin=True) |
|
64 |
+ except GroupUserInfo.DoesNotExist: |
|
65 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
66 |
+ |
|
67 |
+ # 权限回收 |
|
68 |
+ subadmin.status = False |
|
69 |
+ subadmin.save() |
|
70 |
+ |
|
71 |
+ return response(200, 'Tour Guide Group Admin Right Recovery Success', u'旅行团管理员权限回收成功') |
|
72 |
+ |
|
73 |
+ |
|
74 |
+@logit |
|
75 |
+def tg_group_admin_waiver_api(request): |
|
76 |
+ """ 旅行团管理员权限放弃 """ |
|
77 |
+ group_id = request.POST.get('group_id', '') |
|
78 |
+ user_id = request.POST.get('user_id', '') |
|
79 |
+ |
|
80 |
+ try: |
|
81 |
+ subadmin = GroupUserInfo.objects.get(group_id=group_id, user_id=user_id, subadmin=True) |
|
82 |
+ except GroupUserInfo.DoesNotExist: |
|
83 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
84 |
+ |
|
85 |
+ # 权限回收 |
|
86 |
+ subadmin.status = False |
|
87 |
+ subadmin.save() |
|
88 |
+ |
|
89 |
+ return response(200, 'Tour Guide Group Admin Right Waiver Success', u'旅行团管理员权限放弃成功') |
@@ -11,6 +11,7 @@ from TimeConvert import TimeConvert as tc |
||
11 | 11 |
|
12 | 12 |
from account.models import UserInfo |
13 | 13 |
from group.models import GroupInfo, GroupUserInfo |
14 |
+from utils.admin_utils import is_group_subadmin |
|
14 | 15 |
from utils.error.errno_utils import GroupStatusCode, GroupUserStatusCode, UserStatusCode |
15 | 16 |
from utils.error.response_utils import response |
16 | 17 |
from utils.group_photo_utils import get_current_photos |
@@ -127,8 +128,12 @@ def tgu_group_user_remove_api(request): |
||
127 | 128 |
return response(GroupStatusCode.GROUP_NOT_FOUND) |
128 | 129 |
|
129 | 130 |
# 权限校验 |
130 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists() or admin_id == user_id: # 管理员也不允许将自己移除 |
|
131 |
- return response(GroupStatusCode.NO_UPDATE_PERMISSION) |
|
131 |
+ if not is_group_subadmin(group_id, admin_id): |
|
132 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
133 |
+ |
|
134 |
+ # 管理员也不允许将自己移除 |
|
135 |
+ if admin_id == user_id: |
|
136 |
+ return response(GroupStatusCode.ADMIN_CANNOT_HANDLE_SELF) |
|
132 | 137 |
|
133 | 138 |
# 群组用户校验 |
134 | 139 |
try: |
@@ -179,8 +184,8 @@ def tgu_group_user_update_api(request): |
||
179 | 184 |
|
180 | 185 |
# 权限校验 |
181 | 186 |
if admin_id: |
182 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists(): |
|
183 |
- return response(GroupStatusCode.NO_UPDATE_PERMISSION) |
|
187 |
+ if not is_group_subadmin(group_id, admin_id): |
|
188 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
184 | 189 |
else: |
185 | 190 |
if not GroupUserInfo.objects.filter(group_id=group_id, user_id=user_id, status=True).exists(): |
186 | 191 |
return response(GroupStatusCode.NO_UPDATE_PERMISSION) |
@@ -237,8 +242,8 @@ def tgu_group_user_locations_api(request): |
||
237 | 242 |
admin_id = request.POST.get('admin_id', '') # 导游唯一标识 |
238 | 243 |
|
239 | 244 |
# 权限校验 |
240 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists(): |
|
241 |
- return response(GroupStatusCode.NO_LOCATION_PERMISSION) |
|
245 |
+ if not is_group_subadmin(group_id, admin_id): |
|
246 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
242 | 247 |
|
243 | 248 |
# 获取集合经纬度 |
244 | 249 |
gather_info = json.loads(r.get(TOUR_GUIDE_GROUP_CUR_GATHER_INFO % group_id) or '{}') |
@@ -272,8 +277,8 @@ def tgu_group_user_location_api(request): |
||
272 | 277 |
user_id = request.POST.get('user_id', '') |
273 | 278 |
|
274 | 279 |
# 权限校验 |
275 |
- if not GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists(): |
|
276 |
- return response(GroupStatusCode.NO_LOCATION_PERMISSION) |
|
280 |
+ if not is_group_subadmin(group_id, admin_id): |
|
281 |
+ return response(GroupStatusCode.NOT_GROUP_SUBADMIN) |
|
277 | 282 |
|
278 | 283 |
session_id = r.get(TOUR_GUIDE_GROUP_CUR_SESSION % group_id) |
279 | 284 |
locations = r.lrange(TOUR_GUIDE_GROUP_USER_GEO_LIST % (group_id, session_id, user_id), 0, -1) |
@@ -0,0 +1,11 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from group.models import GroupUserInfo |
|
4 |
+ |
|
5 |
+ |
|
6 |
+def is_group_admin(group_id, admin_id): |
|
7 |
+ return GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, admin=True, status=True).exists() |
|
8 |
+ |
|
9 |
+ |
|
10 |
+def is_group_subadmin(group_id, admin_id): |
|
11 |
+ return GroupUserInfo.objects.filter(group_id=group_id, user_id=admin_id, subadmin=True, status=True).exists() |
@@ -57,24 +57,27 @@ class GroupStatusCode(BaseStatusCode): |
||
57 | 57 |
""" 群组/团相关错误码 4020xx """ |
58 | 58 |
GROUP_NOT_FOUND = StatusCodeField(402001, 'Group Not Found', description=u'群组不存在') |
59 | 59 |
GROUP_HAS_LOCKED = StatusCodeField(402002, 'Group Has Locked', description=u'群组已锁定') |
60 |
- NOT_GROUP_ADMIN = StatusCodeField(402003, 'Not Group Admin', description=u'非群组管理员') |
|
60 |
+ # 管理员 |
|
61 |
+ NOT_GROUP_ADMIN = StatusCodeField(402010, 'Not Group Admin', description=u'非群组管理员') |
|
62 |
+ NOT_GROUP_SUBADMIN = StatusCodeField(402011, 'Not Group Sub Admin', description=u'非群组协同管理员') |
|
63 |
+ ADMIN_CANNOT_HANDLE_SELF = StatusCodeField(402012, 'Admin Cannot Handle Self', description=u'群组管理员无法操作自身') |
|
61 | 64 |
# 权限 |
62 |
- NO_UPDATE_PERMISSION = StatusCodeField(402010, 'No Update Permission', description=u'没有更新权限') |
|
63 |
- NO_LOCK_PERMISSION = StatusCodeField(402011, 'No Lock Permission', description=u'没有锁定权限') |
|
64 |
- NO_UNLOCK_PERMISSION = StatusCodeField(402012, 'No Unlock Permission', description=u'没有解锁权限') |
|
65 |
- NO_REMOVE_PERMISSION = StatusCodeField(402013, 'No Remove Permission', description=u'没有移除权限') |
|
66 |
- NO_QUIT_PERMISSION = StatusCodeField(402014, 'No Quit Permission', description=u'没有退出权限') |
|
67 |
- NO_PASS_PERMISSION = StatusCodeField(402015, 'No Pass Permission', description=u'没有通过权限') |
|
68 |
- NO_REFUSE_PERMISSION = StatusCodeField(402016, 'No Refuse Permission', description=u'没有拒绝权限') |
|
69 |
- NO_CLOSE_PERMISSION = StatusCodeField(402017, 'No Close Permission', description=u'没有关闭权限') |
|
70 |
- NO_TRANSFER_PERMISSION = StatusCodeField(402018, 'No Transfer Permission', description=u'没有转移权限') |
|
71 |
- NO_LOCATION_PERMISSION = StatusCodeField(402019, 'No Location Permission', description=u'没有地理位置权限') |
|
65 |
+ NO_UPDATE_PERMISSION = StatusCodeField(402020, 'No Update Permission', description=u'无更新权限') |
|
66 |
+ NO_LOCK_PERMISSION = StatusCodeField(402021, 'No Lock Permission', description=u'无锁定权限') |
|
67 |
+ NO_UNLOCK_PERMISSION = StatusCodeField(402022, 'No Unlock Permission', description=u'无解锁权限') |
|
68 |
+ NO_REMOVE_PERMISSION = StatusCodeField(402023, 'No Remove Permission', description=u'无移除权限') |
|
69 |
+ NO_QUIT_PERMISSION = StatusCodeField(402024, 'No Quit Permission', description=u'无退出权限') |
|
70 |
+ NO_PASS_PERMISSION = StatusCodeField(402025, 'No Pass Permission', description=u'无通过权限') |
|
71 |
+ NO_REFUSE_PERMISSION = StatusCodeField(402026, 'No Refuse Permission', description=u'无拒绝权限') |
|
72 |
+ NO_CLOSE_PERMISSION = StatusCodeField(402027, 'No Close Permission', description=u'无关闭权限') |
|
73 |
+ NO_TRANSFER_PERMISSION = StatusCodeField(402028, 'No Transfer Permission', description=u'无转移权限') |
|
74 |
+ NO_LOCATION_PERMISSION = StatusCodeField(402029, 'No Location Permission', description=u'无地理位置权限') |
|
72 | 75 |
# 请求 |
73 |
- DUPLICATE_JOIN_REQUEST = StatusCodeField(402020, 'Duplicate Join Request', description=u'重复加群申请') |
|
74 |
- JOIN_REQUEST_NOT_FOUND = StatusCodeField(402021, 'Join Request Not Found', description=u'加群申请不存在') |
|
76 |
+ DUPLICATE_JOIN_REQUEST = StatusCodeField(402030, 'Duplicate Join Request', description=u'重复加群申请') |
|
77 |
+ JOIN_REQUEST_NOT_FOUND = StatusCodeField(402031, 'Join Request Not Found', description=u'加群申请不存在') |
|
75 | 78 |
# 旅行团 |
76 |
- GROUP_HAS_ENDED = StatusCodeField(402030, 'Group Has Ended', description=u'群组已结束') |
|
77 |
- COULD_HAVE_ONLY_ONE_ACTIVE_GROUP = StatusCodeField(402031, 'Could Have Only One Active Group', description=u'只能创建一个活跃团') |
|
79 |
+ GROUP_HAS_ENDED = StatusCodeField(402040, 'Group Has Ended', description=u'群组已结束') |
|
80 |
+ COULD_HAVE_ONLY_ONE_ACTIVE_GROUP = StatusCodeField(402041, 'Could Have Only One Active Group', description=u'只能创建一个活跃团') |
|
78 | 81 |
|
79 | 82 |
|
80 | 83 |
class GroupUserStatusCode(BaseStatusCode): |
@@ -104,7 +107,7 @@ class OrderStatusCode(BaseStatusCode): |
||
104 | 107 |
WX_ORDER_PAY_FAIL = StatusCodeField(404009, 'WX Order Pay Fail', description=u'微信支付失败') |
105 | 108 |
SIGN_CHECK_FAIL = StatusCodeField(404010, 'Sign Check Fail', description=u'签名校验失败') |
106 | 109 |
FEE_CHECK_FAIL = StatusCodeField(404011, 'FEE Check Fail', description=u'金额校验失败') |
107 |
- NO_DETAIL_PERMISSION = StatusCodeField(404015, 'No Detail Permission', description=u'没有详情权限') |
|
110 |
+ NO_DETAIL_PERMISSION = StatusCodeField(404015, 'No Detail Permission', description=u'无详情权限') |
|
108 | 111 |
WX_ORDER_PAID_ALREADY_EXISTS = StatusCodeField(404020, 'WX Order Paid Already Exists', description=u'照片已购买') |
109 | 112 |
|
110 | 113 |
|