From 7099cbbc1e47afc4bb983e8b0dfdede6d3afc87e Mon Sep 17 00:00:00 2001 From: XIE7654 <765462425@qq.com> Date: Thu, 2 Oct 2025 14:27:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=B8=BA=E5=BC=82=E6=AD=A5=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/system/tasks.py | 53 ++++++++++++++++++++++++++++++++---- backend/system/views/user.py | 30 ++++++-------------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/backend/system/tasks.py b/backend/system/tasks.py index c642f91..a4daed9 100644 --- a/backend/system/tasks.py +++ b/backend/system/tasks.py @@ -1,14 +1,55 @@ -# 某个 app 目录下的 tasks.py +import requests + from celery import shared_task +from django.utils import timezone +from system.models import LoginLog, User + @shared_task def add(x, y): return x + y -@shared_task -def sync_temu_order(): - pass + @shared_task -def sync_temu_shipping(): - pass \ No newline at end of file +def update_user_login_info(user_id, client_ip, user_agent): + # 更新用户登录信息 + user = User.objects.get(id=user_id) + user.login_ip = client_ip + user.last_login = timezone.now() + user.save(update_fields=['login_ip', 'last_login']) + + # 获取地理位置信息 + location_info = get_location_from_ip(client_ip) + + # 记录登录日录 + LoginLog.objects.create( + username=user.username, + result=LoginLog.LoginResult.SUCCESS, + user_ip=client_ip, + location=location_info, + user_agent=user_agent + ) + +def get_location_from_ip(ip): + """根据IP地址获取地理位置信息""" + try: + if ip in ['127.0.0.1', 'localhost']: + return "本地网络" + + url = f"http://ip-api.com/json/{ip}?lang=zh-CN" + try: + response = requests.get(url, timeout=5) + data = response.json() + if data["status"] == "success": + location_parts = [data["city"], data["regionName"], data["country"]] + return ', '.join(location_parts) if location_parts else "未知位置" + else: + return f"IP {ip} 查询失败:{data['message']}" + except Exception as e: + return f"IP {ip} 连接错误:{str(e)}" + except Exception as e: + import logging + logger = logging.getLogger(__name__) + logger.error(f"获取IP地址位置信息失败: {str(e)}") + return "位置获取失败" \ No newline at end of file diff --git a/backend/system/views/user.py b/backend/system/views/user.py index 892fa70..d3906f8 100644 --- a/backend/system/views/user.py +++ b/backend/system/views/user.py @@ -1,6 +1,4 @@ import requests -from django.db.models import Prefetch, F -from django.utils import timezone from rest_framework import serializers from rest_framework.authtoken.models import Token from rest_framework.authtoken.views import ObtainAuthToken @@ -9,9 +7,8 @@ from rest_framework.views import APIView from django.contrib.auth.hashers import make_password from rest_framework.permissions import IsAuthenticated from django_filters import rest_framework as filters -from ip2geotools.databases.noncommercial import DbIpCity - -from system.models import User, Menu, LoginLog, Dept +from system.tasks import update_user_login_info +from system.models import User, Menu, Dept from utils.ip_utils import get_client_ip from utils.serializers import CustomModelSerializer @@ -62,23 +59,14 @@ class UserLogin(ObtainAuthToken): # 获取真实IP地址 client_ip = get_client_ip(request) - # 获取IP地址的地理位置信息 - location_info = self.get_location_from_ip(client_ip) - # location_info = '' - - # 更新登录IP和登录时间 - user.login_ip = client_ip - user.last_login = timezone.now() - user.save(update_fields=['login_ip', 'last_login']) - user_data = UserSerializer(user).data - # 记录登录日志 - LoginLog.objects.create( - username=user.username, - result=LoginLog.LoginResult.SUCCESS, - user_ip=client_ip, - location=location_info, - user_agent=request.META.get('HTTP_USER_AGENT', '') + # 异步处理用户登录信息更新和日志记录 + update_user_login_info.delay( + user.id, + client_ip, + request.META.get('HTTP_USER_AGENT', '') ) + + user_data = UserSerializer(user).data # 在序列化后的数据中加入 accessToken user_data['accessToken'] = token.key return Response({