新增 accept_order_banner2、boss_center;菜单定义写入 product.turntable,不影响现有俱乐部数据隔离。 Co-authored-by: Cursor <cursoragent@cursor.com>
632 lines
26 KiB
Python
632 lines
26 KiB
Python
import io
|
||
import os
|
||
import re
|
||
import time
|
||
import random
|
||
import secrets
|
||
import hashlib
|
||
import threading
|
||
import urllib.parse
|
||
from decimal import Decimal, InvalidOperation
|
||
|
||
from django.conf import settings
|
||
from django.db import transaction, connection
|
||
from django.db.models import Q, F, Max, Prefetch
|
||
from gvsdsdk.fluent import db, func, FQ
|
||
from django.core.cache import cache
|
||
from django.core.paginator import Paginator
|
||
from django.utils import timezone
|
||
|
||
from rest_framework.views import APIView
|
||
from rest_framework.response import Response
|
||
from rest_framework import status, permissions
|
||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||
from rest_framework.parsers import JSONParser, MultiPartParser, FormParser
|
||
from rest_framework.throttling import AnonRateThrottle, SimpleRateThrottle
|
||
|
||
from utils.oss_utils import upload_to_oss, delete_from_oss, validate_image
|
||
from utils.weixin_broadcast import WeixinBroadcastSender
|
||
from utils.weixin_token import get_weixin_mini_access_token, is_weixin_token_invalid
|
||
# from utils.ip_security import *
|
||
from utils.invitationcode_utils import CreateInvitationCode, VerifyInvitationCode
|
||
|
||
from backend.utils import update_shangjia_daily
|
||
from utils.chat_utils import subscribe_merchant_link_chat
|
||
from utils.pdd_order_validator import validate_pdd_order_id, validate_cn_mobile
|
||
|
||
from ..models import (
|
||
Gonggao, Lunbo, Tupianpeizhi, Qunpeizhi,
|
||
ShangjiaMoban, ShangjiaLianjie, PopupPage, PopupConfig, WithdrawConfig,
|
||
MiniappScriptScene, MiniappScriptAutoReply,
|
||
)
|
||
|
||
from users.models import (
|
||
AdminProfile, UserDashou, UserBoss,
|
||
UserShangjia, UserGuanshi, UserZuzhang
|
||
)
|
||
from users.business_models import User
|
||
|
||
from orders.models import CommissionRate, Order, MerchantOrderExt
|
||
from orders.notice_tasks import dingdan_guangbo
|
||
|
||
from rank.models import Chenghao, DingdanBiaoqian
|
||
|
||
from products.models import ShangpinLeixing, Huiyuangoumai
|
||
|
||
from ..serializers import PopupConfigSerializer
|
||
import traceback
|
||
import requests
|
||
|
||
import logging
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class ShangpinGonggaoView(APIView):
|
||
"""
|
||
商品公告和轮播图接口
|
||
获取类型为1的公告和轮播图
|
||
"""
|
||
throttle_classes = [AnonRateThrottle]
|
||
permission_classes = [AllowAny]
|
||
authentication_classes = []
|
||
|
||
def post(self, request):
|
||
"""
|
||
处理POST请求,返回公告和轮播图数据
|
||
|
||
请求: POST /api/peizhi/shangpingonggao/
|
||
返回: {
|
||
"shangpingonggao": "公告内容字符串",
|
||
"shangpinlunbo": ["轮播图URL1", "轮播图URL2"]
|
||
}
|
||
"""
|
||
try:
|
||
logger.info("收到商品公告和轮播图请求")
|
||
from jituan.services.display_config import (
|
||
get_gonggao_content,
|
||
get_lunbo_urls,
|
||
lunbo_image_type_for_page,
|
||
normalize_page_key,
|
||
)
|
||
|
||
page_key = normalize_page_key(request.data.get('page_key'), image_type=1)
|
||
image_type = lunbo_image_type_for_page(page_key)
|
||
gonggao_content = get_gonggao_content(request, notice_type=1, page_key=page_key)
|
||
lunbo_urls = get_lunbo_urls(request, page_key=page_key, image_type=image_type)
|
||
response_data = {
|
||
"shangpingonggao": gonggao_content,
|
||
"shangpinlunbo": lunbo_urls,
|
||
"page_key": page_key,
|
||
}
|
||
logger.info(f"返回数据:公告长度{len(gonggao_content)},轮播图数量{len(lunbo_urls)} page_key={page_key}")
|
||
# 4. 返回响应
|
||
return Response(response_data, status=status.HTTP_200_OK)
|
||
except Exception as e:
|
||
# 记录异常
|
||
logger.error(f"获取商品公告和轮播图时发生错误:{str(e)}")
|
||
# 返回错误响应
|
||
error_data = {
|
||
"error": "服务器内部错误",
|
||
"detail": "获取数据失败,请稍后重试"
|
||
}
|
||
return Response(error_data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
|
||
|
||
|
||
class AdminConfigQueryView(APIView):
|
||
"""
|
||
管理员获取系统配置接口
|
||
URL: /peizhi/adpzhq
|
||
方法: POST
|
||
权限: JWT Token认证 + 管理员权限
|
||
参数: zhanghao (管理员账号)
|
||
"""
|
||
permission_classes = [permissions.IsAuthenticated]
|
||
|
||
def post(self, request):
|
||
try:
|
||
# 获取前端传递的账号
|
||
zhanghao = request.data.get('zhanghao')
|
||
if not zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不能为空',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 获取当前用户(User实例)
|
||
user_main = request.user
|
||
|
||
# 验证账号:比较user_main的phone与前端传递的zhanghao
|
||
if user_main.Phone != zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不匹配',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
# 验证用户类型是否为管理员
|
||
if user_main.UserType != 'admin':
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
# 验证管理员扩展表是否存在
|
||
try:
|
||
admin_profile = user_main.AdminProfile
|
||
except AdminProfile.DoesNotExist:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
# 查询图片配置
|
||
rule_image = Tupianpeizhi.query.filter(ImageType=1).first()
|
||
default_avatar = Tupianpeizhi.query.filter(ImageType=2).first()
|
||
|
||
# 查询群配置
|
||
qun_configs = Qunpeizhi.query.all()
|
||
qq_groups = []
|
||
for config in qun_configs:
|
||
qq_groups.append({
|
||
'peizhiid': config.GroupType,
|
||
'neirong': config.GroupContent if config.GroupContent else '',
|
||
'qunid': config.GroupID if config.GroupID else '',
|
||
'jieshao': config.Description if config.Description else ''
|
||
})
|
||
|
||
# 查询利率配置
|
||
platform_rate_obj = CommissionRate.query.filter(Platform='1').first()
|
||
shop_rate_obj = CommissionRate.query.filter(Platform='3').first()
|
||
# 🔴【新增】打手提现抽成利率(字符5)
|
||
dashou_withdraw_obj = CommissionRate.query.filter(Platform='5').first()
|
||
# 🔴【新增】管事提现抽成利率(字符6)
|
||
guanshi_withdraw_obj = CommissionRate.query.filter(Platform='6').first()
|
||
|
||
# 构建返回数据
|
||
data = {
|
||
'images': {
|
||
'rule_image': rule_image.ImageURL if rule_image and rule_image.ImageURL else '',
|
||
'default_avatar': default_avatar.ImageURL if default_avatar and default_avatar.ImageURL else ''
|
||
},
|
||
'qq_groups': qq_groups,
|
||
'rates': {
|
||
'platform_rate': float(platform_rate_obj.Rate) if platform_rate_obj and platform_rate_obj.Rate else 0.0,
|
||
'shop_rate': float(shop_rate_obj.Rate) if shop_rate_obj and shop_rate_obj.Rate else 0.0,
|
||
# 🔴【新增】打手提现抽成利率
|
||
'dashou_withdraw_rate': float(
|
||
dashou_withdraw_obj.Rate) if dashou_withdraw_obj and dashou_withdraw_obj.Rate else 0.0,
|
||
# 🔴【新增】管事提现抽成利率
|
||
'guanshi_withdraw_rate': float(
|
||
guanshi_withdraw_obj.Rate) if guanshi_withdraw_obj and guanshi_withdraw_obj.Rate else 0.0
|
||
|
||
}
|
||
}
|
||
|
||
return Response({
|
||
'code': 0,
|
||
'msg': 'success',
|
||
'data': data
|
||
})
|
||
|
||
except Exception as e:
|
||
return Response({
|
||
'code': 99,
|
||
'msg': f'系统错误: {str(e)}',
|
||
'data': None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
|
||
class AdminUploadImageView(APIView):
|
||
"""
|
||
管理员上传配置图片接口
|
||
URL: /peizhi/adxgtp
|
||
方法: POST
|
||
权限: JWT Token认证 + 管理员权限
|
||
参数: zhanghao, leixing (1:打手规则图片, 2:默认头像图片), image (文件)
|
||
"""
|
||
permission_classes = [permissions.IsAuthenticated]
|
||
parser_classes = (MultiPartParser, FormParser)
|
||
|
||
def post(self, request):
|
||
try:
|
||
zhanghao = request.data.get('zhanghao')
|
||
leixing = request.data.get('leixing')
|
||
image_file = request.FILES.get('image')
|
||
|
||
if not zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不能为空',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
if not leixing:
|
||
return Response({
|
||
'code': 2,
|
||
'msg': '图片类型不能为空',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
if not image_file:
|
||
return Response({
|
||
'code': 3,
|
||
'msg': '请选择图片文件',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 验证用户权限
|
||
user_main = request.user
|
||
if user_main.Phone != zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不匹配',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
if user_main.UserType != 'admin':
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
try:
|
||
admin_profile = user_main.AdminProfile
|
||
except AdminProfile.DoesNotExist:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
# 验证图片类型
|
||
if leixing not in ['1', '2']:
|
||
return Response({
|
||
'code': 4,
|
||
'msg': '图片类型错误',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 验证图片文件
|
||
is_valid, error_msg = validate_image(image_file)
|
||
if not is_valid:
|
||
return Response({
|
||
'code': 5,
|
||
'msg': f'图片验证失败: {error_msg}',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 根据类型确定固定相对URL和文件名
|
||
if leixing == '1':
|
||
# 打手规则图片
|
||
fixed_relative_url = 'a_long/dashouguize.jpg'
|
||
oss_file_name = 'dashouguize.jpg'
|
||
else:
|
||
# 默认头像图片
|
||
fixed_relative_url = 'a_long/morentouxiang.jpg'
|
||
oss_file_name = 'morentouxiang.jpg'
|
||
|
||
# 构建OSS文件路径
|
||
oss_file_path = fixed_relative_url # a_long/dashouguize.jpg 或 a_long/morentouxiang.jpg
|
||
|
||
# 上传到OSS(覆盖原有文件)
|
||
image_file.seek(0) # 重置文件指针
|
||
full_url = upload_to_oss(image_file, oss_file_path)
|
||
|
||
if not full_url:
|
||
return Response({
|
||
'code': 6,
|
||
'msg': '图片上传到存储桶失败',
|
||
'data': None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
# 更新数据库
|
||
with transaction.atomic():
|
||
# 获取或创建图片配置记录
|
||
tupian_peizhi, created = Tupianpeizhi.query.get_or_create(ImageType=int(leixing))
|
||
tupian_peizhi.ImageURL = fixed_relative_url
|
||
tupian_peizhi.save()
|
||
|
||
return Response({
|
||
'code': 0,
|
||
'msg': '图片上传成功',
|
||
'data': {
|
||
'image_url': fixed_relative_url
|
||
}
|
||
})
|
||
|
||
except Exception as e:
|
||
return Response({
|
||
'code': 99,
|
||
'msg': f'系统错误: {str(e)}',
|
||
'data': None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
|
||
class AdminUpdateConfigView(APIView):
|
||
"""
|
||
管理员更新系统配置接口(QQ群、利率)- 已修复
|
||
URL: /peizhi/adupdate
|
||
方法: POST
|
||
权限: JWT Token认证 + 管理员权限
|
||
参数:
|
||
- zhanghao: 管理员账号
|
||
- qq_groups: [{"peizhiid": 1, "neirong": "", "qunid": "", "jieshao": ""}, ...] (可选)
|
||
- rates: {"platform_rate": 0.1, "shop_rate": 0.2} (可选)
|
||
"""
|
||
permission_classes = [permissions.IsAuthenticated]
|
||
|
||
def post(self, request):
|
||
try:
|
||
zhanghao = request.data.get('zhanghao')
|
||
if not zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不能为空',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 验证用户权限
|
||
user_main = request.user
|
||
if user_main.Phone != zhanghao:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '账号不匹配',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
if user_main.UserType != 'admin':
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
try:
|
||
admin_profile = user_main.AdminProfile
|
||
except AdminProfile.DoesNotExist:
|
||
return Response({
|
||
'code': 1,
|
||
'msg': '无权限',
|
||
'data': None
|
||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
response_data = {}
|
||
|
||
# 🔴 修复:更新QQ群配置 - 确保根据peizhiid正确更新对应的记录
|
||
qq_groups = request.data.get('qq_groups')
|
||
if qq_groups and isinstance(qq_groups, list):
|
||
# 收集所有 peizhiid,批量预取已有记录(避免循环内 N+1)
|
||
_peizhiids = [g.get('peizhiid') for g in qq_groups if g.get('peizhiid')]
|
||
_existing_map = {}
|
||
if _peizhiids:
|
||
for q in Qunpeizhi.query.filter(GroupType__in=_peizhiids):
|
||
# 如果存在多个相同 peizhiid 的记录,取第一个(应该只有一个)
|
||
if q.GroupType not in _existing_map:
|
||
_existing_map[q.GroupType] = q
|
||
|
||
_to_create = []
|
||
_to_update = []
|
||
updated_groups = []
|
||
for group_data in qq_groups:
|
||
peizhiid = group_data.get('peizhiid')
|
||
if not peizhiid:
|
||
continue
|
||
|
||
neirong = group_data.get('neirong')
|
||
qunid = group_data.get('qunid')
|
||
jieshao = group_data.get('jieshao')
|
||
|
||
qun_config = _existing_map.get(peizhiid)
|
||
if qun_config is not None:
|
||
# 更新已有记录
|
||
if neirong is not None:
|
||
qun_config.GroupContent = neirong or ''
|
||
if qunid is not None:
|
||
qun_config.GroupID = qunid or ''
|
||
if jieshao is not None:
|
||
qun_config.Description = jieshao or ''
|
||
_to_update.append(qun_config)
|
||
else:
|
||
# 不存在则创建新的
|
||
qun_config = Qunpeizhi(
|
||
GroupType=peizhiid,
|
||
GroupContent=neirong or '',
|
||
GroupID=qunid or '',
|
||
Description=jieshao or '',
|
||
)
|
||
_to_create.append(qun_config)
|
||
|
||
updated_groups.append({
|
||
'peizhiid': qun_config.GroupType,
|
||
'neirong': qun_config.GroupContent,
|
||
'qunid': qun_config.GroupID,
|
||
'jieshao': qun_config.Description
|
||
})
|
||
|
||
if _to_create:
|
||
Qunpeizhi.objects.bulk_create(_to_create)
|
||
if _to_update:
|
||
Qunpeizhi.objects.bulk_update(
|
||
_to_update, ['GroupContent', 'GroupID', 'Description']
|
||
)
|
||
|
||
if updated_groups:
|
||
response_data['qq_groups'] = updated_groups
|
||
|
||
# 🔴 修复:更新利率配置 - 确保更新现有记录而不是创建新记录
|
||
rates = request.data.get('rates')
|
||
if rates and isinstance(rates, dict):
|
||
updated_rates = {}
|
||
|
||
# 平台发单利率(类型1,fadanpingtai='1')
|
||
platform_rate = rates.get('platform_rate')
|
||
if platform_rate is not None:
|
||
try:
|
||
platform_rate_float = float(platform_rate)
|
||
if 0 <= platform_rate_float <= 1:
|
||
# 🔴 修复:查询现有记录,如果不存在则创建
|
||
platform_rate_obj = CommissionRate.query.filter(Platform='1').first()
|
||
|
||
if platform_rate_obj:
|
||
# 更新现有记录
|
||
platform_rate_obj.Rate = platform_rate_float
|
||
platform_rate_obj.save()
|
||
else:
|
||
# 创建新记录
|
||
platform_rate_obj = CommissionRate.query.create(
|
||
Rate=platform_rate_float,
|
||
Platform='1'
|
||
)
|
||
|
||
updated_rates['platform_rate'] = platform_rate_float
|
||
else:
|
||
return Response({
|
||
'code': 3,
|
||
'msg': '平台发单利率必须在0-1之间',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
except ValueError:
|
||
return Response({
|
||
'code': 4,
|
||
'msg': '平台发单利率格式错误',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 商家发单利率(类型2,fadanpingtai='2')
|
||
shop_rate = rates.get('shop_rate')
|
||
if shop_rate is not None:
|
||
try:
|
||
shop_rate_float = float(shop_rate)
|
||
if 0 <= shop_rate_float <= 1:
|
||
# 🔴 修复:查询现有记录,如果不存在则创建
|
||
shop_rate_obj = CommissionRate.query.filter(Platform='3').first()
|
||
|
||
if shop_rate_obj:
|
||
# 更新现有记录
|
||
shop_rate_obj.Rate = shop_rate_float
|
||
shop_rate_obj.save()
|
||
else:
|
||
# 创建新记录
|
||
shop_rate_obj = CommissionRate.query.create(
|
||
Rate=shop_rate_float,
|
||
Platform='3'
|
||
)
|
||
|
||
updated_rates['shop_rate'] = shop_rate_float
|
||
else:
|
||
return Response({
|
||
'code': 5,
|
||
'msg': '商家发单利率必须在0-1之间',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
except ValueError:
|
||
return Response({
|
||
'code': 6,
|
||
'msg': '商家发单利率格式错误',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
|
||
|
||
|
||
# 🔴【新增】打手提现抽成利率(类型5,fadanpingtai='5')
|
||
dashou_withdraw_rate = rates.get('dashou_withdraw_rate')
|
||
if dashou_withdraw_rate is not None:
|
||
try:
|
||
dashou_withdraw_rate_float = float(dashou_withdraw_rate)
|
||
if 0 <= dashou_withdraw_rate_float <= 1:
|
||
# 查询现有记录,如果不存在则创建
|
||
dashou_withdraw_obj = CommissionRate.query.filter(Platform='5').first()
|
||
|
||
if dashou_withdraw_obj:
|
||
# 更新现有记录
|
||
dashou_withdraw_obj.Rate = dashou_withdraw_rate_float
|
||
dashou_withdraw_obj.save()
|
||
else:
|
||
# 创建新记录
|
||
dashou_withdraw_obj = CommissionRate.query.create(
|
||
Rate=dashou_withdraw_rate_float,
|
||
Platform='5'
|
||
)
|
||
|
||
updated_rates['dashou_withdraw_rate'] = dashou_withdraw_rate_float
|
||
else:
|
||
return Response({
|
||
'code': 7, # 注意:这里需要调整错误码,不要重复
|
||
'msg': '打手提现抽成利率必须在0-1之间',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
except ValueError:
|
||
return Response({
|
||
'code': 8,
|
||
'msg': '打手提现抽成利率格式错误',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
# 🔴【新增】管事提现抽成利率(类型6,fadanpingtai='6')
|
||
guanshi_withdraw_rate = rates.get('guanshi_withdraw_rate')
|
||
if guanshi_withdraw_rate is not None:
|
||
try:
|
||
guanshi_withdraw_rate_float = float(guanshi_withdraw_rate)
|
||
if 0 <= guanshi_withdraw_rate_float <= 1:
|
||
# 查询现有记录,如果不存在则创建
|
||
guanshi_withdraw_obj = CommissionRate.query.filter(Platform='6').first()
|
||
|
||
if guanshi_withdraw_obj:
|
||
# 更新现有记录
|
||
guanshi_withdraw_obj.Rate = guanshi_withdraw_rate_float
|
||
guanshi_withdraw_obj.save()
|
||
else:
|
||
# 创建新记录
|
||
guanshi_withdraw_obj = CommissionRate.query.create(
|
||
Rate=guanshi_withdraw_rate_float,
|
||
Platform='6'
|
||
)
|
||
|
||
updated_rates['guanshi_withdraw_rate'] = guanshi_withdraw_rate_float
|
||
else:
|
||
return Response({
|
||
'code': 9,
|
||
'msg': '管事提现抽成利率必须在0-1之间',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
except ValueError:
|
||
return Response({
|
||
'code': 10,
|
||
'msg': '管事提现抽成利率格式错误',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
if updated_rates:
|
||
response_data['rates'] = updated_rates
|
||
|
||
# 如果没有任何更新
|
||
if not response_data:
|
||
return Response({
|
||
'code': 7,
|
||
'msg': '没有需要更新的数据',
|
||
'data': None
|
||
}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
return Response({
|
||
'code': 0,
|
||
'msg': '更新成功',
|
||
'data': response_data
|
||
})
|
||
|
||
except Exception as e:
|
||
return Response({
|
||
'code': 99,
|
||
'msg': f'系统错误: {str(e)}',
|
||
'data': None
|
||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||
|
||
|
||
|
||
|