2025/04/13 周日 14:52:40.97

This commit is contained in:
shishishizhan 2025-04-13 14:52:41 +08:00
parent d84dce20c5
commit 38a48ca64b
15 changed files with 195 additions and 49 deletions

View File

@ -294,7 +294,7 @@ if not os.path.exists(os.path.join(BASE_DIR, 'media')):
MEDIA_URL = "/media/" MEDIA_URL = "/media/"
# 项目中存储上传文件的根目录 # 项目中存储上传文件的根目录
MEDIA_ROOT = os.path.join(BASE_DIR, "media") # MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# ================================================= # # ================================================= #
# ******************** 自定义权限 ******************** # # ******************** 自定义权限 ******************** #

View File

@ -12,7 +12,10 @@ from utils.viewset import CustomModelViewSet
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from drf_yasg import openapi from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from utils.imageupload import ImageUpload # 添加七牛云存储工具类导入
from utils.qiniu_storage import QiniuStorage
# 移除原有的图片上传工具
# from utils.imageupload import ImageUpload
from mysystem.models import Users from mysystem.models import Users
from utils.filters import UsersManageTimeFilter from utils.filters import UsersManageTimeFilter
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
@ -136,11 +139,9 @@ class UserManageViewSet(CustomModelViewSet):
# ================================================= # # ================================================= #
#前端获取个人信息 #前端获取个人信息
from utils.qiniu_storage import QiniuStorage
class GetUserinfoView(APIView): class GetUserinfoView(APIView):
'''
前端获取个人信息
get:
'''
authentication_classes = [JWTAuthentication] authentication_classes = [JWTAuthentication]
permission_classes = [] permission_classes = []
@ -148,12 +149,20 @@ class GetUserinfoView(APIView):
data = {} data = {}
user = request.user user = request.user
if request.user.is_authenticated: if request.user.is_authenticated:
if user.avatar:
if 'http' not in user.avatar: # 如果不是完整URL则生成七牛云链接
qiniu = QiniuStorage()
base_url = f'http://{qiniu.domain}/{user.avatar}'
data['avatar'] = qiniu.q.private_download_url(base_url, expires=3600*24*365)
else:
data['avatar'] = user.avatar data['avatar'] = user.avatar
else:
data['avatar'] = ""
data['nickname'] = user.nickname data['nickname'] = user.nickname
data['mobile'] = user.mobile data['mobile'] = user.mobile
data['id'] = user.id data['id'] = user.id
return DetailResponse(data=data) return DetailResponse(data=data)
#匿名用户 # 匿名用户
data['avatar'] = "" data['avatar'] = ""
data['nickname'] = "" data['nickname'] = ""
data['mobile'] = "" data['mobile'] = ""
@ -172,10 +181,42 @@ class uploadImagesView(APIView):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
result = ImageUpload(request,"frontendimages") file = request.FILES.get('file')
if result['code'] == 200 : if not file:
return SuccessResponse(data=result['img'],msg=result['msg']) return ErrorResponse(msg='请选择文件')
else:
qiniu = QiniuStorage()
result = qiniu.upload_data(file, 'frontendimages')
if result['code'] == 200:
return SuccessResponse(data=result['url'], msg=result['msg'])
return ErrorResponse(msg=result['msg'])
class ChangeAvatarView(APIView):
'''
前端app头像修改
post:
功能描述前端app头像修改</br>
参数说明需要登录携带token后才能调用</br>
'''
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
file = request.FILES.get('file')
if not file:
return ErrorResponse(msg='请选择文件')
qiniu = QiniuStorage()
result = qiniu.upload_data(file, 'avatar')
if result['code'] == 200:
user = request.user
# 只存储文件路径部分不存储完整URL
key = result['url']
user.avatar = key
user.save()
return SuccessResponse(data=result['url'], msg=result['msg'])
return ErrorResponse(msg=result['msg']) return ErrorResponse(msg=result['msg'])
class SetUserNicknameView(APIView): class SetUserNicknameView(APIView):
@ -216,25 +257,25 @@ class SetUserNicknameView(APIView):
return SuccessResponse(msg="success") return SuccessResponse(msg="success")
#前端app头像修改 #前端app头像修改
class ChangeAvatarView(APIView): # class ChangeAvatarView(APIView):
''' # '''
前端app头像修改 # 前端app头像修改
post: # post:
功能描述前端app头像修改</br> # 【功能描述】前端app头像修改</br>
参数说明需要登录携带token后才能调用</br> # 【参数说明】无需要登录携带token后才能调用</br>
''' # '''
authentication_classes = [JWTAuthentication] # authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated] # permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs): # def post(self, request, *args, **kwargs):
result = ImageUpload(request,"avatar") # result = ImageUpload(request,"avatar")
if result['code'] == 200 : # if result['code'] == 200 :
user = request.user # user = request.user
user.avatar = result['img'][0] # user.avatar = result['img'][0]
user.save() # user.save()
return SuccessResponse(data=result['img'],msg=result['msg']) # return SuccessResponse(data=result['img'],msg=result['msg'])
else: # else:
return ErrorResponse(msg=result['msg']) # return ErrorResponse(msg=result['msg'])
#注销账号(标记已注销) #注销账号(标记已注销)
class DestroyUserView(APIView): class DestroyUserView(APIView):

View File

@ -17,6 +17,7 @@ from utils.common import get_parameter_dic,get_full_image_url,ast_convert
from utils.filters import UserLeavingMessageTimeFilter,SystemConfigFilter from utils.filters import UserLeavingMessageTimeFilter,SystemConfigFilter
from utils.models import get_all_models_objects from utils.models import get_all_models_objects
from utils.barcode import barCodeGenerate from utils.barcode import barCodeGenerate
from utils.qiniu_storage import QiniuStorage
# Create your views here. # Create your views here.
# ================================================= # # ================================================= #
@ -225,11 +226,23 @@ class PlatformImagesUploadView(APIView):
authentication_classes = [JWTAuthentication] authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
#原上传
# def post(self, request, *args, **kwargs):
# result = ImageUpload(request, "platform")
# if result['code'] == 200:
# return SuccessResponse(data=result['img'], msg=result['msg'])
# else:
# return ErrorResponse(msg=result['msg'])
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
result = ImageUpload(request, "platform") file = request.FILES.get('file')
if not file:
return ErrorResponse(msg='请选择文件')
qiniu = QiniuStorage()
result = qiniu.upload_data(file, 'platform')
if result['code'] == 200: if result['code'] == 200:
return SuccessResponse(data=result['img'], msg=result['msg']) return SuccessResponse(data=result['url'], msg=result['msg'])
else:
return ErrorResponse(msg=result['msg']) return ErrorResponse(msg=result['msg'])
# ================================================= # # ================================================= #

View File

@ -44,7 +44,9 @@ LOGIN_ERROR_RETRY_TIMES = 0 #登录错误次数限制0表示不限制
LOGIN_ERROR_RETRY_TIMEOUT = 60 #登录错误次数过期时间,单位秒 LOGIN_ERROR_RETRY_TIMEOUT = 60 #登录错误次数过期时间,单位秒
FRONTEND_API_LIST = ['/api/app/','/api/xcx/','/api/h5/']#微服务前端接口前缀 FRONTEND_API_LIST = ['/api/app/','/api/xcx/','/api/h5/']#微服务前端接口前缀
#DOMAIN_HOST = "http://47.112.174.207:7070"#控制图片上传后保存所使用到的域名 #DOMAIN_HOST = "http://47.112.174.207:7070"#控制图片上传后保存所使用到的域名
DOMAIN_HOST = "http://etoai.top" # DOMAIN_HOST = "http://etoai.top" #阿里云地址
DOMAIN_HOST = "http://static.etoai.top" #七牛云地址
MEDIA_ROOT = os.path.join(DOMAIN_HOST, "media")
EXEC_LOG_PATH = os.path.join(BASE_DIR, 'logs','lybbnexec.log') EXEC_LOG_PATH = os.path.join(BASE_DIR, 'logs','lybbnexec.log')
TEMP_EXEC_PATH = os.path.join(BASE_DIR, 'logs') TEMP_EXEC_PATH = os.path.join(BASE_DIR, 'logs')
LOG_IP_AREA = True #操作日志是否记录用户IP归属地 LOG_IP_AREA = True #操作日志是否记录用户IP归属地
@ -224,3 +226,14 @@ ALIPAY_APPID = 'xxxxxxxxxxxxxxxxxx'
# 服务器存放证书路径(支付宝支付签发的) # 服务器存放证书路径(支付宝支付签发的)
ALIPAY_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'key', 'app_private_key.pem') ALIPAY_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'key', 'app_private_key.pem')
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'key', 'alipay_public_key.pem') ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'key', 'alipay_public_key.pem')
# 七牛云配置
QINIU_ACCESS_KEY = "uihXkSxCvmOKywpXmnpqSKeiGmjGAOpn8b9wAB9B"
QINIU_SECRET_KEY = "Xz8VMHep6v0LueUNGJV-mrOrase4rZLmT4qpsYAu"
QINIU_BUCKET_NAME = "etoaistatic"
QINIU_BUCKET_DOMAIN = "static.etoai.top" # 你的七牛云域名
QINIU_SECURE_URL = False # 是否使用 HTTPS
# 修改 MEDIA_ROOT 配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 本地临时存储路径

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -147,8 +147,14 @@ class UserViewSet(CustomModelViewSet):
"""修改当前用户信息""" """修改当前用户信息"""
user = request.user user = request.user
reqData = request.data reqData = request.data
Users.objects.filter(id=user.id).update(email=reqData.get('email'),name=reqData.get('name'),gender=reqData.get('gender'),mobile=reqData.get('mobile')) # 添加 avatar 字段到更新列表中
return SuccessResponse(data=None, msg="修改成功") Users.objects.filter(id=user.id).update(
email=reqData.get('email'),
name=reqData.get('name'),
gender=reqData.get('gender'),
mobile=reqData.get('mobile'),
)
return SuccessResponse(data=None, msg="当前用户信息修改成功")
def change_password(self,request,*args, **kwargs): def change_password(self,request,*args, **kwargs):

View File

@ -72,3 +72,8 @@ qqwry-py3
chardet chardet
natsort natsort
pywin32 ; sys_platform == 'win32' pywin32 ; sys_platform == 'win32'
# 七牛云存储
qiniu>=7.13.0
# 图片处理
Pillow>=10.1.0

View File

@ -75,3 +75,8 @@ qqwry-py3
chardet chardet
natsort natsort
pywin32 ; sys_platform == 'win32' pywin32 ; sys_platform == 'win32'
# 七牛云存储
qiniu>=7.13.0
# 图片处理
Pillow>=10.1.0

View File

@ -96,3 +96,8 @@ python-barcode
chardet chardet
natsort natsort
pywin32 ; sys_platform == 'win32' pywin32 ; sys_platform == 'win32'
# 七牛云存储
qiniu>=7.13.0
# 图片处理
Pillow>=10.1.0

View File

@ -0,0 +1,62 @@
from qiniu import Auth, put_file, put_data
from django.conf import settings
import time
import os
from PIL import Image
from io import BytesIO
class QiniuStorage:
def __init__(self):
self.q = Auth(settings.QINIU_ACCESS_KEY, settings.QINIU_SECRET_KEY)
self.bucket_name = settings.QINIU_BUCKET_NAME
self.domain = settings.QINIU_BUCKET_DOMAIN
self.max_size = 5 * 1024 * 1024 # 5MB
self.allowed_types = ['.jpg', '.jpeg', '.png', '.gif']
def compress_image(self, image_data):
"""无损压缩图片"""
img = Image.open(BytesIO(image_data))
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
output = BytesIO()
# 保持原始尺寸,仅优化质量
img.save(output, format='JPEG', quality=85, optimize=True)
return output.getvalue()
def upload_data(self, file_data, file_path):
"""上传文件数据"""
# 检查文件大小
if file_data.size > self.max_size:
return {'code': 400, 'msg': f'文件大小不能超过{self.max_size/1024/1024}MB'}
# 检查文件类型
ext = os.path.splitext(file_data.name)[1].lower()
if ext not in self.allowed_types:
return {'code': 400, 'msg': f'只支持{",".join(self.allowed_types)}格式的图片'}
# 压缩图片
try:
compressed_data = self.compress_image(file_data.read())
except Exception as e:
return {'code': 400, 'msg': f'图片压缩失败:{str(e)}'}
token = self.q.upload_token(self.bucket_name)
timestamp = time.strftime('%Y-%m-%d/%Y%m%d%H%M%S', time.localtime())
key = f"{file_path}/{timestamp}_{str(int(time.time()*1000))[-3:]}{ext}"
try:
ret, info = put_data(token, key, compressed_data)
if info.status_code == 200:
base_url = f'http://{self.domain}/{key}'
private_url = self.q.private_download_url(base_url, expires=3600*24*365)
return {
'code': 200,
'url': private_url,
'msg': '上传成功'
}
except Exception as e:
return {
'code': 400,
'msg': f'上传失败:{str(e)}'
}

View File

@ -65,12 +65,8 @@
let obj= await platformsettingsUploadPlatformImg(param) let obj= await platformsettingsUploadPlatformImg(param)
if(obj.code == 2000) { if(obj.code == 2000) {
let res='' let res=''
if (obj.data.data[0].indexOf("://")>=0){ res = obj.data.data
res = obj.data.data[0] // console.log(res)
}else{
res = url.split('/api')[0]+obj.data.data[0]
}
vm.imageurl = res vm.imageurl = res
} else { } else {
vm.$message.warning(res.msg) vm.$message.warning(res.msg)

View File

@ -169,7 +169,7 @@ module.exports = defineConfig({
}, },
mangle: true, // 混淆变量名 mangle: true, // 混淆变量名
output: { output: {
comments: false // 移除注释 comments: true // 移除注释
} }
} }
}) })