diff --git a/backend/urls.py b/backend/urls.py index f1a191c..e389b5d 100644 --- a/backend/urls.py +++ b/backend/urls.py @@ -6,7 +6,7 @@ from .view import (GetRolePermissionView, ModifyAdminUserView, KefuGetDashouListView, KefuGetDashouDetailView, KefuUpdateDashouView, KefuGetShangjiaListView, KefuGetShangjiaDetailView, KefuUpdateShangjiaView, GetProductBaseDataView, GetProductListView, SaveProductOrderView, AddProductView, DeleteProductView, GetProductDetailView, UpdateProductView, UpdateMemberView, GetMemberListView, - AddMemberView, GetGuanliListView, GetGuanliDetailView, UpdateGuanliView, GetWithdrawSettingsView, + AddMemberView, GetGuanliListView, GetGuanliDetailView, PromoteGuanshiToZuzhangView, UpdateGuanliView, GetWithdrawSettingsView, UpdateWithdrawSettingsView, GetZuzhangListView, GetZuzhangDetailView, UpdateZuzhangView, GetProductTypeZoneView, ModifyProductTypeZoneView, GetRateView, ModifyRateView, PopupNoticeListAPIView, PopupNoticeModifyAPIView,ShopListView, ShopModifyView, ShopPublicTypeAndAuditView, ShopListForProductView, ShopProductModifyView, @@ -46,6 +46,7 @@ urlpatterns = [ path('hthqgslb', GetGuanliListView.as_view(), name='后台获取管事列表'), path('hthqgsxq', GetGuanliDetailView.as_view(), name='后台获取管事详情信息'), + path('htgssjzz', PromoteGuanshiToZuzhangView.as_view(), name='后台管事升级组长'), path('htxggsxx', UpdateGuanliView.as_view(), name='后台更新管事数据'), path('hthqtxpz', GetWithdrawSettingsView.as_view(), name='后台获取提现配置'), path('htxgtxsz', UpdateWithdrawSettingsView.as_view(), name='后台修改提现配置'), diff --git a/backend/view.py b/backend/view.py index 1b927c6..bea34ce 100644 --- a/backend/view.py +++ b/backend/view.py @@ -2888,6 +2888,7 @@ class GetGuanliDetailView(APIView): return Response({'code': 404, 'msg': '用户不是管事'}) # 基础信息 + is_zuzhang = UserZuzhang.query.filter(user=user).exists() base_data = { 'yonghuid': user.UserUID, 'nickname': boss.nickname if boss else '', @@ -2902,6 +2903,7 @@ class GetGuanliDetailView(APIView): 'jinrichongzhi': guanshi.jinrichongzhi, 'jinyuechongzhi': guanshi.jinyuechongzhi, 'chongzhifenrun': str(guanshi.chongzhifenrun), + 'create_time': guanshi.CreateTime.isoformat() if guanshi.CreateTime else None, 'CreateTime': guanshi.CreateTime.isoformat() if guanshi.CreateTime else None, } @@ -2963,12 +2965,115 @@ class GetGuanliDetailView(APIView): 'custom_first_dividend': custom_first, 'extra_dividend_map': extra_map, 'all_members': all_members, + 'is_zuzhang': is_zuzhang, } }) +def _generate_unique_zuzhang_yaoqingma(yonghuid): + """生成唯一组长邀请码(与小程序组长注册逻辑一致)""" + timestamp = str(int(time.time()))[-6:] + uid_part = yonghuid[-6:] if len(yonghuid) >= 6 else yonghuid.rjust(6, '0') + rand_str = ''.join(random.choices(string.ascii_uppercase + string.digits, k=2)) + base = f"Z{timestamp}{uid_part}{rand_str}" + for _ in range(5): + if not UserZuzhang.query.filter(yaoqingma=base).exists(): + return base + base = base + random.choice(string.digits) + return base + str(int(time.time() * 1000))[-4:] + + +def _create_zuzhang_profile(user): + """为已有用户创建组长扩展记录(默认字段与小程序注册一致)""" + invite_guanshi_count = UserGuanshi.query.filter(yaoqingren=user.UserUID).count() + yaoqingma = _generate_unique_zuzhang_yaoqingma(user.UserUID) + return UserZuzhang.query.create( + user=user, + yaoqingma=yaoqingma, + fenyong_zonge=Decimal('0.00'), + ketixian_jine=Decimal('0.00'), + yaoqing_zongshu=invite_guanshi_count, + jinri_fenyong=Decimal('0.00'), + jinyue_fenyong=Decimal('0.00'), + zhuangtai=1, + jinri_tixian=Decimal('0.00'), + ewai_tixian_xiane=Decimal('0.00'), + kaioi_ewai_tixian=False, + kaioi_ewai_fenhong=False, + ewai_fenhong_jine=Decimal('0.00'), + ) + + +class PromoteGuanshiToZuzhangView(APIView): + """ + 后台将管事用户升级为组长(写入 user_zuzhang 扩展表) + POST /houtai/htgssjzz + 权限:sjzz666 + 参数:username, yonghuid + """ + permission_classes = [IsAuthenticated] + parser_classes = [JSONParser] + + def post(self, request): + username = request.data.get('username', '').strip() + yonghuid = request.data.get('yonghuid', '').strip() + + if not username: + return Response({'code': 401, 'msg': '缺少username'}) + if not yonghuid: + return Response({'code': 400, 'msg': '缺少用户ID'}) + + kefu, permissions = verify_kefu_permission(request, username) + if kefu is None: + return permissions + if 'sjzz666' not in permissions: + return Response({'code': 403, 'msg': '无权限升级组长(需要 sjzz666)'}) + + try: + user = User.query.select_related('GuanshiProfile').get(UserUID=yonghuid) + guanshi = user.GuanshiProfile + except User.DoesNotExist: + return Response({'code': 404, 'msg': '用户不存在'}) + except UserGuanshi.DoesNotExist: + return Response({'code': 404, 'msg': '用户不是管事,无法升级组长'}) + + if UserZuzhang.query.filter(user=user).exists(): + zuzhang = user.ZuzhangProfile + return Response({ + 'code': 400, + 'msg': '该用户已是组长', + 'data': { + 'yonghuid': user.UserUID, + 'yaoqingma': zuzhang.yaoqingma, + }, + }) + + if guanshi.zhuangtai != 1: + return Response({'code': 400, 'msg': '管事账号已禁用,无法升级组长'}) + + try: + with transaction.atomic(): + zuzhang = _create_zuzhang_profile(user) + except IntegrityError: + return Response({'code': 400, 'msg': '升级失败,请稍后重试'}) + + logger.info(f"管事升级组长成功: yonghuid={yonghuid}, yaoqingma={zuzhang.yaoqingma}") + return Response({ + 'code': 0, + 'msg': '已升级为组长', + 'data': { + 'yonghuid': user.UserUID, + 'nickname': getattr(user.BossProfile, 'nickname', '') if hasattr(user, 'BossProfile') else '', + 'yaoqingma': zuzhang.yaoqingma, + 'yaoqing_zongshu': zuzhang.yaoqing_zongshu, + 'ketixian_jine': str(zuzhang.ketixian_jine), + }, + }) + + + class UpdateGuanliView(APIView): """