拆分了 config
This commit is contained in:
718
config/views/admin_stats.py
Normal file
718
config/views/admin_stats.py
Normal file
@@ -0,0 +1,718 @@
|
||||
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 DashouPaihangView(APIView):
|
||||
"""
|
||||
排行榜接口
|
||||
路径:/peizhi/dsph
|
||||
方法:POST
|
||||
认证:JWT Token认证
|
||||
|
||||
请求参数:
|
||||
- leixing: 1=今日收入,2=今月收入
|
||||
- yonghu_leixing: 1=打手,2=管事,3=商家
|
||||
|
||||
返回数据:
|
||||
- code: 0=成功,其他=失败
|
||||
- msg: 提示信息
|
||||
- data: {
|
||||
xianshi: True/False, # 是否展示真实数据
|
||||
paihang_list: [ # 排行榜列表
|
||||
{
|
||||
uid: '用户ID',
|
||||
touxiang: '头像相对URL',
|
||||
nicheng: '用户昵称',
|
||||
jine: 收入金额,
|
||||
mingci: 排名
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
# =============== 可配置参数 ===============
|
||||
# 每次查询返回的最大记录数(可修改)
|
||||
ZUI_DAO_CHA_XUN_SHU_LIANG = 50
|
||||
|
||||
# 最少需要多少人才能展示(可修改)
|
||||
ZUI_SHAO_REN_SHU_YAO_QIU = 1
|
||||
|
||||
# 第一名最低金额要求(单位:元)(可修改)
|
||||
DI_YI_MING_ZUI_DI_JIN_E = Decimal('10.00')
|
||||
|
||||
# 管事第一名最低数量要求(可修改)
|
||||
DI_YI_MING_ZUI_DI_SHU_LIANG = 1
|
||||
# =============== 可配置参数结束 ===============
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
# 获取请求参数 - 修复参数类型问题
|
||||
leixing_str = request.data.get('leixing', '1')
|
||||
yonghu_leixing_str = request.data.get('yonghu_leixing', '1')
|
||||
|
||||
# 转换为整数
|
||||
try:
|
||||
leixing = int(leixing_str)
|
||||
except (ValueError, TypeError):
|
||||
leixing = 1
|
||||
|
||||
try:
|
||||
yonghu_leixing = int(yonghu_leixing_str)
|
||||
except (ValueError, TypeError):
|
||||
yonghu_leixing = 1
|
||||
|
||||
# 参数验证
|
||||
if leixing not in [1, 2]:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'msg': '参数错误:leixing必须为1(今日)或2(今月)',
|
||||
'data': {'xianshi': False}
|
||||
})
|
||||
|
||||
if yonghu_leixing not in [1, 2, 3]:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'msg': '参数错误:yonghu_leixing必须为1(打手)、2(管事)或3(商家)',
|
||||
'data': {'xianshi': False}
|
||||
})
|
||||
|
||||
# 根据用户类型调用不同的查询方法
|
||||
if yonghu_leixing == 1:
|
||||
# 打手排行榜
|
||||
paihang_list, xianshi_flag = self.chaxun_dashou_paihang(leixing)
|
||||
elif yonghu_leixing == 2:
|
||||
# 管事排行榜
|
||||
paihang_list, xianshi_flag = self.chaxun_guanshi_paihang(leixing)
|
||||
else:
|
||||
# 商家排行榜
|
||||
paihang_list, xianshi_flag = self.chaxun_shangjia_paihang(leixing)
|
||||
|
||||
# 返回结果
|
||||
return Response({
|
||||
'code': 0,
|
||||
'msg': '获取成功',
|
||||
'data': {
|
||||
'xianshi': xianshi_flag,
|
||||
'paihang_list': paihang_list
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"排行榜查询失败: {str(e)}", exc_info=True)
|
||||
return Response({
|
||||
'code': 500,
|
||||
'msg': '服务器内部错误',
|
||||
'data': {'xianshi': False}
|
||||
})
|
||||
|
||||
def chaxun_dashou_paihang(self, leixing):
|
||||
"""
|
||||
查询打手排行榜
|
||||
:param leixing: 1=今日收入,2=今月收入
|
||||
:return: (排行榜列表, 是否展示标志)
|
||||
"""
|
||||
# 确定查询的字段
|
||||
if leixing == 1:
|
||||
# 今日收入
|
||||
shouyi_ziduan = 'jinrishouyi'
|
||||
else:
|
||||
# 今月收入
|
||||
shouyi_ziduan = 'jinyueshouyi'
|
||||
|
||||
# 查询条件:收入大于0,打手账号状态正常(1=正常)
|
||||
# 注意:打手表中的zhanghaozhuangtai字段
|
||||
chaxun_tiaojian = Q(**{f'{shouyi_ziduan}__gt': 0}) & Q(zhanghaozhuangtai=1)
|
||||
|
||||
# 查询打手扩展表,并关联用户主表
|
||||
dashou_list = UserDashou.query.select_related('user').filter(
|
||||
chaxun_tiaojian
|
||||
).order_by(f'-{shouyi_ziduan}')[:self.ZUI_DAO_CHA_XUN_SHU_LIANG]
|
||||
|
||||
# 检查是否满足展示条件
|
||||
if len(dashou_list) < self.ZUI_SHAO_REN_SHU_YAO_QIU:
|
||||
# 人数不足,不展示
|
||||
return [], False
|
||||
|
||||
# 检查第一名金额是否达到最低要求
|
||||
if leixing == 1:
|
||||
di_yi_ming_jine = dashou_list[0].jinrishouyi
|
||||
else:
|
||||
di_yi_ming_jine = dashou_list[0].jinyueshouyi
|
||||
|
||||
if di_yi_ming_jine < self.DI_YI_MING_ZUI_DI_JIN_E:
|
||||
# 第一名金额不足,不展示
|
||||
return [], False
|
||||
|
||||
# 构建返回数据
|
||||
paihang_list = []
|
||||
for index, dashou in enumerate(dashou_list):
|
||||
# 获取用户主表信息
|
||||
user_main = dashou.user
|
||||
|
||||
# 打手的昵称直接使用打手扩展表的nicheng字段
|
||||
dashou_nicheng = dashou.nicheng or '未设置昵称'
|
||||
|
||||
# 获取头像(相对URL)
|
||||
touxiang_url = user_main.Avatar or ''
|
||||
|
||||
# 获取收入金额
|
||||
if leixing == 1:
|
||||
shouyi_jine = dashou.jinrishouyi
|
||||
else:
|
||||
shouyi_jine = dashou.jinyueshouyi
|
||||
|
||||
paihang_list.append({
|
||||
'uid': user_main.UserUID,
|
||||
'touxiang': touxiang_url,
|
||||
'nicheng': dashou_nicheng,
|
||||
'jine': float(shouyi_jine), # 转换为float方便前端处理
|
||||
'mingci': index + 1
|
||||
})
|
||||
|
||||
return paihang_list, True
|
||||
|
||||
def chaxun_guanshi_paihang(self, leixing):
|
||||
"""
|
||||
查询管事排行榜
|
||||
:param leixing: 1=今日,2=今月
|
||||
:return: (排行榜列表, 是否展示标志)
|
||||
"""
|
||||
# 确定查询的字段
|
||||
if leixing == 1:
|
||||
# 今日充值打手数量
|
||||
chaxun_ziduan = 'jinrichongzhi'
|
||||
else:
|
||||
# 今月充值打手数量
|
||||
chaxun_ziduan = 'jinyuechongzhi'
|
||||
|
||||
# 查询条件:数量大于0,管事状态正常(状态1为正常)
|
||||
# 注意:管手表中的zhuangtai字段
|
||||
chaxun_tiaojian = Q(**{f'{chaxun_ziduan}__gt': 0}) & Q(zhuangtai=1)
|
||||
|
||||
# 查询管事扩展表,并关联用户主表
|
||||
guanshi_list = UserGuanshi.query.select_related('user').filter(
|
||||
chaxun_tiaojian
|
||||
).order_by(f'-{chaxun_ziduan}')[:self.ZUI_DAO_CHA_XUN_SHU_LIANG]
|
||||
|
||||
# 检查是否满足展示条件
|
||||
if len(guanshi_list) < self.ZUI_SHAO_REN_SHU_YAO_QIU:
|
||||
# 人数不足,不展示
|
||||
return [], False
|
||||
|
||||
# 检查第一名数量是否达到最低要求
|
||||
if leixing == 1:
|
||||
di_yi_ming_shuliang = guanshi_list[0].jinrichongzhi
|
||||
else:
|
||||
di_yi_ming_shuliang = guanshi_list[0].jinyuechongzhi
|
||||
|
||||
if di_yi_ming_shuliang < self.DI_YI_MING_ZUI_DI_SHU_LIANG:
|
||||
# 第一名数量不足,不展示
|
||||
return [], False
|
||||
|
||||
# 构建返回数据
|
||||
paihang_list = []
|
||||
for index, guanshi in enumerate(guanshi_list):
|
||||
# 获取用户主表信息
|
||||
user_main = guanshi.user
|
||||
|
||||
# 管事的昵称需要查询老板扩展表
|
||||
boss_profile = UserBoss.query.filter(user=user_main).first()
|
||||
guanshi_nicheng = boss_profile.nickname if boss_profile else '未设置昵称'
|
||||
|
||||
# 获取头像(相对URL)
|
||||
touxiang_url = user_main.Avatar or ''
|
||||
|
||||
# 获取数量
|
||||
if leixing == 1:
|
||||
chongzhi_shuliang = guanshi.jinrichongzhi
|
||||
else:
|
||||
chongzhi_shuliang = guanshi.jinyuechongzhi
|
||||
|
||||
paihang_list.append({
|
||||
'uid': user_main.UserUID,
|
||||
'touxiang': touxiang_url,
|
||||
'nicheng': guanshi_nicheng,
|
||||
'jine': float(chongzhi_shuliang), # 这里jine字段实际存储的是数量
|
||||
'mingci': index + 1
|
||||
})
|
||||
|
||||
return paihang_list, True
|
||||
|
||||
def chaxun_shangjia_paihang(self, leixing):
|
||||
"""
|
||||
查询商家排行榜
|
||||
:param leixing: 1=今日流水,2=今月流水
|
||||
:return: (排行榜列表, 是否展示标志)
|
||||
"""
|
||||
# 确定查询的字段
|
||||
if leixing == 1:
|
||||
# 今日流水
|
||||
liushui_ziduan = 'jinriliushui'
|
||||
else:
|
||||
# 今月流水
|
||||
liushui_ziduan = 'jinyueliushui'
|
||||
|
||||
# 查询条件:流水大于0,商家状态正常(状态1为正常)
|
||||
# 注意:商家表中的zhuangtai字段
|
||||
chaxun_tiaojian = Q(**{f'{liushui_ziduan}__gt': 0}) & Q(zhuangtai=1)
|
||||
|
||||
# 查询商家扩展表,并关联用户主表
|
||||
shangjia_list = UserShangjia.query.select_related('user').filter(
|
||||
chaxun_tiaojian
|
||||
).order_by(f'-{liushui_ziduan}')[:self.ZUI_DAO_CHA_XUN_SHU_LIANG]
|
||||
|
||||
# 检查是否满足展示条件
|
||||
if len(shangjia_list) < self.ZUI_SHAO_REN_SHU_YAO_QIU:
|
||||
# 人数不足,不展示
|
||||
return [], False
|
||||
|
||||
# 检查第一名金额是否达到最低要求
|
||||
if leixing == 1:
|
||||
di_yi_ming_liushui = shangjia_list[0].jinriliushui
|
||||
else:
|
||||
di_yi_ming_liushui = shangjia_list[0].jinyueliushui
|
||||
|
||||
if di_yi_ming_liushui < self.DI_YI_MING_ZUI_DI_JIN_E:
|
||||
# 第一名流水不足,不展示
|
||||
return [], False
|
||||
|
||||
# 构建返回数据
|
||||
paihang_list = []
|
||||
for index, shangjia in enumerate(shangjia_list):
|
||||
# 获取用户主表信息
|
||||
user_main = shangjia.user
|
||||
|
||||
# 商家的昵称需要查询老板扩展表
|
||||
boss_profile = UserBoss.query.filter(user=user_main).first()
|
||||
shangjia_nicheng = boss_profile.nickname if boss_profile else '未设置昵称'
|
||||
|
||||
# 获取头像(相对URL)
|
||||
touxiang_url = user_main.Avatar or ''
|
||||
|
||||
# 获取流水金额
|
||||
if leixing == 1:
|
||||
liushui_jine = shangjia.jinriliushui
|
||||
else:
|
||||
liushui_jine = shangjia.jinyueliushui
|
||||
|
||||
paihang_list.append({
|
||||
'uid': user_main.UserUID,
|
||||
'touxiang': touxiang_url,
|
||||
'nicheng': shangjia_nicheng,
|
||||
'jine': float(liushui_jine),
|
||||
'mingci': index + 1
|
||||
})
|
||||
|
||||
return paihang_list, True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class GetAdminZhanghaoView(APIView):
|
||||
"""
|
||||
获取管理员账号列表接口
|
||||
路径:/peizhi/adzhhq
|
||||
方法:POST
|
||||
权限:JWT Token + 管理员验证
|
||||
参数:
|
||||
- zhanghao: 当前登录的管理员账号(字符串)
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
# 🔥 1. 身份验证(100%按表模型)
|
||||
user = request.user
|
||||
|
||||
# 获取当前用户的手机号(CharField,字符串类型)
|
||||
current_phone = getattr(user, 'Phone', '')
|
||||
if not current_phone:
|
||||
return Response({
|
||||
'code': 401,
|
||||
'message': '用户手机号信息不完整',
|
||||
'data': None
|
||||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
# 检查前端传递的账号是否匹配(都是字符串)
|
||||
frontend_zhanghao = request.data.get('zhanghao', '').strip()
|
||||
if frontend_zhanghao != current_phone:
|
||||
return Response({
|
||||
'code': 403,
|
||||
'message': '账号不匹配,无权限访问',
|
||||
'data': None
|
||||
}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# 🔥 2. 验证是否为管理员(user_type是CharField,值是'admin'字符串)
|
||||
user_type = getattr(user, 'user_type', '')
|
||||
if user_type != 'admin':
|
||||
# 检查是否有管理员扩展表
|
||||
if not hasattr(user, 'AdminProfile'):
|
||||
return Response({
|
||||
'code': 403,
|
||||
'message': '无管理员权限',
|
||||
'data': None
|
||||
}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# 🔥 3. 查询管理员账号列表(全部按字符串查询)
|
||||
with connection.cursor() as cursor:
|
||||
# 🔥 查询所有管理员账号(user_type='admin' 字符串)
|
||||
# 🔥 phone和yonghuid都是CharField,xiugaiid也是CharField
|
||||
sql = """
|
||||
SELECT
|
||||
um.id,
|
||||
um.phone,
|
||||
um.yonghuid,
|
||||
um.UserType,
|
||||
COALESCE(COUNT(xjl.id), 0) as jilushuliang
|
||||
FROM user_main um
|
||||
LEFT JOIN xiugaijilu xjl ON um.phone = xjl.xiugaiid
|
||||
WHERE um.UserType = 'admin'
|
||||
GROUP BY um.id, um.phone, um.yonghuid, um.UserType
|
||||
ORDER BY um.CreateTime DESC
|
||||
"""
|
||||
|
||||
cursor.execute(sql)
|
||||
results = cursor.fetchall()
|
||||
|
||||
# 🔥 4. 处理查询结果(全部保持字符串类型)
|
||||
zhanghao_list = []
|
||||
for row in results:
|
||||
zhanghao_list.append({
|
||||
#'id': row[0],
|
||||
'id': str(row[1]) if row[1] else str(row[2]), # 🔥 保持字符串
|
||||
'zhanghao':str(row[1]) if row[1] else str(row[2]), # 🔥 保持字符串
|
||||
'yonghuid': str(row[2]) if row[2] else '', # 🔥 保持字符串
|
||||
'user_type': str(row[3]) if row[3] else '', # 🔥 保持字符串
|
||||
'jilushuliang': int(row[4]) # 只有这个是数字
|
||||
})
|
||||
|
||||
return Response({
|
||||
'code': 0,
|
||||
'message': '获取成功',
|
||||
'data': zhanghao_list
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取管理员账号列表失败: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return Response({
|
||||
'code': 500,
|
||||
'message': '系统错误',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
class GetXiugaiJiluView(APIView):
|
||||
"""
|
||||
获取修改记录列表接口
|
||||
路径:/peizhi/adhqxg
|
||||
方法:POST
|
||||
权限:JWT Token + 管理员验证
|
||||
参数:
|
||||
- zhanghao: 当前登录的管理员账号(字符串)
|
||||
- xiugaizhe_zhanghaoid: 选中的管理员账号ID(字符串,对应phone或yonghuid)
|
||||
- page: 页码(整数)
|
||||
- pagesize: 每页条数(整数)
|
||||
"""
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
# 🔥 1. 身份验证(100%按表模型)
|
||||
user = request.user
|
||||
|
||||
# 获取当前用户的手机号(CharField,字符串)
|
||||
current_phone = getattr(user, 'Phone', '')
|
||||
if not current_phone:
|
||||
return Response({
|
||||
'code': 401,
|
||||
'message': '用户手机号信息不完整',
|
||||
'data': None
|
||||
}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
# 检查前端传递的账号是否匹配(字符串比较)
|
||||
frontend_zhanghao = request.data.get('zhanghao', '')
|
||||
if not isinstance(frontend_zhanghao, str):
|
||||
frontend_zhanghao = str(frontend_zhanghao)
|
||||
frontend_zhanghao = frontend_zhanghao.strip()
|
||||
|
||||
if frontend_zhanghao != current_phone:
|
||||
return Response({
|
||||
'code': 403,
|
||||
'message': '账号不匹配,无权限访问',
|
||||
'data': None
|
||||
}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# 🔥 2. 验证是否为管理员(user_type='admin'字符串)
|
||||
user_type = getattr(user, 'user_type', '')
|
||||
if user_type != 'admin':
|
||||
if not hasattr(user, 'AdminProfile'):
|
||||
return Response({
|
||||
'code': 403,
|
||||
'message': '无管理员权限',
|
||||
'data': None
|
||||
}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# 🔥 3. 获取参数(100%按实际类型)
|
||||
# 🔥 xiugaizhe_zhanghaoid 是字符串(对应xiugaiid字段,CharField)
|
||||
xiugaizhe_zhanghaoid_param = request.data.get('xiugaizhe_zhanghaoid', '')
|
||||
|
||||
|
||||
# 🔥 强制转为字符串(因为数据库是CharField)
|
||||
if xiugaizhe_zhanghaoid_param is None:
|
||||
xiugaizhe_zhanghaoid = ''
|
||||
else:
|
||||
# 无论如何都转为字符串
|
||||
xiugaizhe_zhanghaoid = str(xiugaizhe_zhanghaoid_param).strip()
|
||||
|
||||
|
||||
# 🔥 分页参数转为整数
|
||||
try:
|
||||
page = int(request.data.get('page', 1))
|
||||
except:
|
||||
page = 1
|
||||
|
||||
try:
|
||||
pagesize = int(request.data.get('pagesize', 10))
|
||||
except:
|
||||
pagesize = 10
|
||||
|
||||
# 🔥 4. 参数验证
|
||||
if not xiugaizhe_zhanghaoid:
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '修改者账号ID不能为空',
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if page < 1:
|
||||
page = 1
|
||||
if pagesize < 1 or pagesize > 50:
|
||||
pagesize = 10
|
||||
|
||||
# 🔥 5. 高效查询(100%按表字段类型)
|
||||
with connection.cursor() as cursor:
|
||||
# 🔥 5.1 查询总记录数(xiugaiid是CharField,用字符串查询)
|
||||
count_sql = """
|
||||
SELECT COUNT(*)
|
||||
FROM xiugaijilu
|
||||
WHERE xiugaiid = %s
|
||||
"""
|
||||
cursor.execute(count_sql, [xiugaizhe_zhanghaoid])
|
||||
total_count = cursor.fetchone()[0]
|
||||
|
||||
# 🔥 5.2 计算分页
|
||||
offset = (page - 1) * pagesize
|
||||
|
||||
# 🔥 5.3 查询当前页数据(使用参数化查询,防止SQL注入)
|
||||
data_sql = """
|
||||
SELECT
|
||||
xjl.id,
|
||||
xjl.yonghuid, -- CharField
|
||||
xjl.xiugaiid, -- CharField
|
||||
xjl.leixing, -- IntegerField
|
||||
xjl.xiugaitijiao, -- DecimalField
|
||||
xjl.xiugaitijiaoq, -- DecimalField
|
||||
xjl.jifen, -- IntegerField
|
||||
xjl.yjifen, -- IntegerField
|
||||
xjl.yajin, -- DecimalField
|
||||
xjl.yyajin, -- DecimalField
|
||||
xjl.shangjiayue, -- DecimalField
|
||||
xjl.shangjiayueq, -- DecimalField
|
||||
xjl.guanshiyue, -- DecimalField
|
||||
xjl.guanshiyueq, -- DecimalField
|
||||
xjl.huiyuants, -- IntegerField
|
||||
xjl.huiyuan_id, -- CharField
|
||||
xjl.qitashuoming, -- TextField
|
||||
xjl.CreateTime, -- DateTimeField
|
||||
um.avatar -- CharField
|
||||
FROM xiugaijilu xjl
|
||||
LEFT JOIN user_main um ON xjl.yonghuid = um.yonghuid
|
||||
WHERE xjl.xiugaiid = %s
|
||||
ORDER BY xjl.CreateTime DESC
|
||||
LIMIT %s OFFSET %s
|
||||
"""
|
||||
|
||||
cursor.execute(data_sql, [xiugaizhe_zhanghaoid, pagesize, offset])
|
||||
records = cursor.fetchall()
|
||||
|
||||
# 🔥 6. 处理查询结果(严格按照字段类型处理)
|
||||
jilu_list = []
|
||||
for record in records:
|
||||
# 获取修改者账号信息(都是字符串)
|
||||
xiugaizhe_zhanghao = ''
|
||||
with connection.cursor() as cursor2:
|
||||
# 🔥 phone和yonghuid都是CharField,用字符串查询
|
||||
cursor2.execute(
|
||||
"SELECT phone, yonghuid FROM user_main WHERE phone = %s OR yonghuid = %s LIMIT 1",
|
||||
[xiugaizhe_zhanghaoid, xiugaizhe_zhanghaoid]
|
||||
)
|
||||
xiugaizhe_info = cursor2.fetchone()
|
||||
if xiugaizhe_info:
|
||||
# 🔥 都是字符串
|
||||
xiugaizhe_zhanghao = str(xiugaizhe_info[0]) if xiugaizhe_info[0] else str(xiugaizhe_info[1]) if \
|
||||
xiugaizhe_info[1] else xiugaizhe_zhanghaoid
|
||||
|
||||
# 获取会员名称(如果有)
|
||||
huiyuan_mingzi = ''
|
||||
if record[15]: # huiyuan_id是CharField
|
||||
with connection.cursor() as cursor3:
|
||||
cursor3.execute(
|
||||
"SELECT jieshao FROM huiyuan WHERE huiyuan_id = %s LIMIT 1",
|
||||
[str(record[15])] # 🔥 转为字符串查询
|
||||
)
|
||||
huiyuan_info = cursor3.fetchone()
|
||||
if huiyuan_info:
|
||||
huiyuan_mingzi = str(huiyuan_info[0]) if huiyuan_info[0] else ''
|
||||
|
||||
# 🔥 严格按照前端字段名映射,保持正确类型
|
||||
jilu_data = {
|
||||
# 基础字段(字符串)
|
||||
'id': record[0],
|
||||
'beixiugai_yonghuid': str(record[1]) if record[1] else '', # yonghuid
|
||||
'xiugaizhe_id': str(record[2]) if record[2] else '', # xiugaiid
|
||||
'xiugaizhe_zhanghao': xiugaizhe_zhanghao, # 字符串
|
||||
'beixiugai_yonghuleixing': record[3], # leixing是整数
|
||||
|
||||
# 打手字段(Decimal转float,Integer转int)
|
||||
'xiugaihou_dashoutixianjine': float(record[4]) if record[4] is not None else 0.00,
|
||||
'xiugaiqian_dashoutixianjine': float(record[5]) if record[5] is not None else 0.00,
|
||||
'xiugaihou_dashoujifen': int(record[6]) if record[6] is not None else 0,
|
||||
'xiugaiqian_dashoujifen': int(record[7]) if record[7] is not None else 0,
|
||||
'xiugaihou_dashouyajin': float(record[8]) if record[8] is not None else 0.00,
|
||||
'xiugaiqian_dashouyajin': float(record[9]) if record[9] is not None else 0.00,
|
||||
|
||||
# 商家字段
|
||||
'xiugaihou_shangjiayue': float(record[10]) if record[10] is not None else 0.00,
|
||||
'xiugaiqian_shangjiayue': float(record[11]) if record[11] is not None else 0.00,
|
||||
|
||||
# 管事字段
|
||||
'xiugaihou_guanshiyue': float(record[12]) if record[12] is not None else 0.00,
|
||||
'xiugaiqian_guanshiyue': float(record[13]) if record[13] is not None else 0.00,
|
||||
|
||||
# 会员字段
|
||||
'tianjia_huiyuantianshu': int(record[14]) if record[14] is not None else 0,
|
||||
'huiyuan_id': str(record[15]) if record[15] else '', # 字符串
|
||||
'huiyuan_mingzi': huiyuan_mingzi, # 字符串
|
||||
|
||||
# 其他字段
|
||||
'qita_shuoming': str(record[16]) if record[16] else '', # 字符串
|
||||
'xiugai_time': record[17].strftime('%Y-%m-%d %H:%M:%S') if record[17] else None,
|
||||
'touxiang': str(record[18]) if record[18] else '' # avatar是字符串
|
||||
}
|
||||
|
||||
jilu_list.append(jilu_data)
|
||||
|
||||
# 🔥 7. 分页控制
|
||||
queried_records = len(jilu_list)
|
||||
has_more = False
|
||||
|
||||
if queried_records == pagesize:
|
||||
total_queried = (page - 1) * pagesize + queried_records
|
||||
has_more = total_queried < total_count
|
||||
|
||||
return Response({
|
||||
'code': 0,
|
||||
'message': '获取成功',
|
||||
'data': {
|
||||
'list': jilu_list,
|
||||
'zongshuliang': total_count,
|
||||
'dangqian_page': page,
|
||||
'page_size': pagesize,
|
||||
'has_more': has_more,
|
||||
'shijichaxundediaoshuliang': queried_records
|
||||
}
|
||||
}, status=status.HTTP_200_OK)
|
||||
|
||||
except ValueError as e:
|
||||
print(f"参数错误: {str(e)}")
|
||||
return Response({
|
||||
'code': 400,
|
||||
'message': '参数错误',
|
||||
'data': None
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取修改记录失败: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return Response({
|
||||
'code': 500,
|
||||
'message': '系统错误',
|
||||
'data': None
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user