#!/usr/bin/env python
# @Project ：django_base_ai
# @File    : user.py
# @Author  : cx
# @Time    : 11/2/2025
# @Desc    : 用户 CRUD、改密、导入导出、初始化。
import hashlib
import logging
import re
import time
import uuid
from datetime import datetime

import django_filters
from django.contrib.auth.hashers import check_password, make_password
from django.core.cache import cache
from django.db.models import Q
from django_filters.rest_framework import (
    DateTimeFromToRangeFilter,
    FilterSet,
)
from django_restql.fields import DynamicSerializerMethodField
from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated
from rest_framework_simplejwt.tokens import RefreshToken

from django_base_ai import dispatch
from django_base_ai.system.models import Dept, Role, Users
from django_base_ai.system.views.role import RoleSerializer
from django_base_ai.utils.json_response import DetailResponse, ErrorResponse
from django_base_ai.utils.permission import OpenApiPermission
from django_base_ai.utils.request_util import save_login_log
from django_base_ai.utils.serializers import CustomModelSerializer
from django_base_ai.utils.validator import CustomUniqueValidator
from django_base_ai.utils.viewset import CustomModelViewSet

logger = logging.getLogger(__name__)


def recursion(instance, parent, result):
    logger.debug(f"递归获取实例数据: instance={instance}, parent={parent}, result={result}")
    new_instance = getattr(instance, parent, None)
    res = []
    data = getattr(instance, result, None)
    if data:
        res.append(data)
    if new_instance:
        array = recursion(new_instance, parent, result)
        res += array
    logger.debug(f"递归完成，返回结果数量: {len(res)}")
    return res


class UserSerializer(CustomModelSerializer):
    """
    用户管理-序列化器
    """

    dept_name = serializers.CharField(source="dept.name", read_only=True)
    role_info = DynamicSerializerMethodField()

    def get_role_info(self, instance, parsed_query):
        logger.debug(f"获取用户 {instance.username if instance else 'None'} 的角色信息")
        roles = instance.role.all()
        logger.debug(f"找到角色数量: {roles.count()}")
        # You can do what ever you want in here
        # `parsed_query` param is passed to BookSerializer to allow further querying
        serializer = RoleSerializer(roles, many=True, parsed_query=parsed_query)
        return serializer.data

    class Meta:
        model = Users
        read_only_fields = ["id"]
        exclude = ["password", "last_token"]
        extra_kwargs = {
            "post": {"required": False},
        }
        # 指定掩盖码类型
        """
        mask_fields = {
            "mobile": MaskType.MOBILE,
            "name": MaskType.NAME,
            "email": {
                "type": MaskType.CUSTOME,
                "first_value": 2,
                "last_value": 3
            }
        }
        """


class UsersInitSerializer(CustomModelSerializer):
    """
    初始化获取数信息(用于生成初始化json文件)
    """

    def validate_password(self, value):
        """
        对密码进行验证
        """
        logger.info("开始验证用户密码（UsersInitSerializer）")
        password = self.initial_data.get("password")
        if password:
            logger.info("密码已提供，正在进行加密处理")
            return make_password(value)
        logger.warning("未提供密码")
        return value

    def save(self, **kwargs):
        logger.info("开始保存用户初始化数据")
        instance = super().save(**kwargs)
        logger.info(f"用户基础信息已保存，ID: {instance.id}")

        role_key = self.initial_data.get("role_key", [])
        logger.info(f"为用户分配角色: {role_key}")
        role_ids = Role.objects.filter(key__in=role_key).values_list("id", flat=True)
        instance.role.set(role_ids)
        logger.info(f"角色已设置: {list(role_ids)}")

        dept_key = self.initial_data.get("dept_key", None)
        dept_id = Dept.objects.filter(key=dept_key).first() if dept_key else None
        instance.dept = dept_id
        logger.info(f"用户部门已设置: {dept_key if dept_key else 'None'}")

        instance.username = instance.username.lower()
        instance.save()
        logger.info(f"用户初始化完成: {instance.username}")
        return instance

    class Meta:
        model = Users
        fields = [
            "username",
            "email",
            "mobile",
            "avatar",
            "name",
            "gender",
            "user_type",
            "dept",
            "user_type",
            "first_name",
            "last_name",
            "email",
            "is_staff",
            "is_active",
            "creator",
            "dept_belong_id",
            "password",
            "last_login",
            "is_superuser",
        ]
        read_only_fields = ["id"]
        extra_kwargs = {"creator": {"write_only": True}, "dept_belong_id": {"write_only": True}}


class UserCreateSerializer(CustomModelSerializer):
    """
    用户新增-序列化器
    """

    username = serializers.CharField(
        max_length=50,
        validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一")],
    )
    password = serializers.CharField(
        required=False,
    )

    def validate_password(self, value):
        """
        对密码进行验证
        """
        logger.info("开始验证密码")
        password = self.initial_data.get("password")
        if password:
            logger.debug("密码已提供，进行加密")
            return make_password(value)
        logger.warning("未提供密码")
        return value

    def save(self, **kwargs):
        logger.info("开始创建新用户")
        data = super().save(**kwargs)
        logger.info(f"用户已创建，ID: {data.id}, 用户名: {data.username}")
        data.dept_belong_id = data.dept_id
        data.username = data.username.upper()
        data.save()
        logger.info(f"用户名已转换为大写: {data.username}")
        post_list = self.initial_data.get("post", [])
        data.post.set(post_list)
        logger.info(f"用户岗位已设置: {post_list}")
        logger.info(f"用户创建完成: {data.username}")
        return data

    class Meta:
        model = Users
        fields = "__all__"
        read_only_fields = ["id"]
        extra_kwargs = {
            "post": {"required": False},
        }


class UserUpdateSerializer(CustomModelSerializer):
    """
    用户修改-序列化器
    """

    username = serializers.CharField(
        max_length=50,
        validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="账号必须唯一")],
    )
    # password = serializers.CharField(required=False, allow_blank=True)
    mobile = serializers.CharField(
        max_length=50,
        validators=[CustomUniqueValidator(queryset=Users.objects.all(), message="手机号必须唯一")],
        allow_blank=True,
    )

    def save(self, **kwargs):
        logger.info(f"开始更新用户，用户ID: {kwargs.get('instance', {}).id if 'instance' in kwargs else '新建'}")
        data = super().save(**kwargs)
        logger.info(f"用户基础信息已更新，ID: {data.id}")
        data.dept_belong_id = data.dept_id
        data.username = data.username.upper()
        data.save()
        logger.info(f"用户名已转换为大写: {data.username}")
        post_list = self.initial_data.get("post", [])
        data.post.set(post_list)
        logger.info(f"用户岗位已更新: {post_list}")
        logger.info(f"用户更新完成: {data.username}")
        return data

    class Meta:
        model = Users
        read_only_fields = ["id", "password"]
        fields = "__all__"
        extra_kwargs = {
            "post": {"required": False, "read_only": True},
        }


class UserSubordinateSerializer(CustomModelSerializer):
    """
    用户下属
    """

    has_children = serializers.SerializerMethodField()

    def get_has_children(self, instance):
        logger.debug(f"检查用户 {instance.username} 是否有下级")
        has_children = Users.objects.filter(parent_id=instance.id).exists()
        logger.debug(f"用户 {instance.username} 是否有下级: {has_children}")
        return has_children

    class Meta:
        model = Users
        fields = ["id", "username", "name", "email", "avatar", "has_children"]


class UserInfoUpdateSerializer(CustomModelSerializer):
    """
    用户修改-序列化器
    """

    def update(self, instance, validated_data):
        logger.info(f"开始更新用户 {instance.username} 的个人信息")
        result = super().update(instance, validated_data)
        logger.info(f"用户 {instance.username} 的个人信息已更新")
        return result

    class Meta:
        model = Users
        fields = ["email", "avatar", "name", "gender", "mobile", "skin", "parent", "user_config"]
        extra_kwargs = {
            "post": {"required": False, "read_only": True},
        }


class ExportUserProfileSerializer(CustomModelSerializer):
    """
    用户导出 序列化器
    """

    last_login = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
    is_active = serializers.SerializerMethodField(read_only=True)
    dept_name = serializers.CharField(source="dept.name", default="")
    dept_owner = serializers.CharField(source="dept.owner", default="")
    gender = serializers.CharField(source="get_gender_display", read_only=True)

    def get_is_active(self, instance):
        status = "启用" if instance.is_active else "停用"
        logger.debug(f"用户 {instance.username} 状态: {status}")
        return status

    class Meta:
        model = Users
        fields = (
            "username",
            "name",
            "email",
            "mobile",
            "gender",
            "is_active",
            "last_login",
            "dept_name",
            "dept_owner",
            "main_department",
        )


class ImportUserProfileSerializer(CustomModelSerializer):
    password = serializers.CharField(required=True, max_length=50, error_messages={"required": "登录密码不能为空"})

    def save(self, **kwargs):
        logger.info(f"开始导入用户，用户名: {self.initial_data.get('username', '未知')}")
        data = super().save(**kwargs)
        password = self.initial_data.get("password", "p@ssw0rdwcx")
        data.set_password(password)
        data.save()
        logger.info(f"用户导入完成，ID: {data.id}, 用户名: {data.username}")
        return data

    class Meta:
        model = Users
        exclude = (
            "post",
            "user_permissions",
            "groups",
            "is_superuser",
            "date_joined",
        )


class FilterUser(FilterSet):
    is_active = django_filters.BooleanFilter(field_name="is_active", lookup_expr="is_active")
    dept = django_filters.NumberFilter(field_name="dept")
    is_enable = django_filters.BooleanFilter(field_name="is_enable")
    create_datetime = DateTimeFromToRangeFilter("create_datetime")

    class Meta:
        model = Users
        fields = ["name", "username", "mobile", "is_active", "dept", "is_enable", "create_datetime"]


class UserViewSet(CustomModelViewSet):
    """
    用户接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = Users.objects.exclude(is_superuser=1).all()
    serializer_class = UserSerializer
    create_serializer_class = UserCreateSerializer
    update_serializer_class = UserUpdateSerializer
    filter_class = FilterUser
    extra_filter_backends = []  # 允许所有用户查询，选择组织架构需要
    # filter_fields = ["^name", "~username", "^mobile", "is_active", "dept", "user_type", "$dept__name"]
    search_fields = ["username", "name", "gender", "dept__name", "role__name", "dept__name"]
    # 导出
    export_field_label = {
        "username": "用户账号",
        "name": "用户名称",
        "email": "用户邮箱",
        "mobile": "手机号码",
        "gender": "用户性别",
        "is_active": "帐号状态",
        "last_login": "最后登录时间",
        "dept_name": "部门名称",
        "main_department": "主部门",
        "dept_owner": "部门负责人",
    }
    export_serializer_class = ExportUserProfileSerializer
    # 导入
    import_serializer_class = ImportUserProfileSerializer
    import_field_dict = {
        "username": "登录账号",
        "name": "用户名称",
        "email": "用户邮箱",
        "mobile": "手机号码",
        "gender": {
            "title": "用户性别",
            "choices": {
                "data": {"未知": 2, "男": 1, "女": 0},
            },
        },
        "is_active": {
            "title": "帐号状态",
            "choices": {
                "data": {"启用": True, "禁用": False},
            },
        },
        "password": "登录密码",
        "main_department": "主部门",
        "dept": {"title": "部门", "choices": {"queryset": Dept.objects.filter(status=True), "values_name": "name"}},
        "role": {"title": "角色", "choices": {"queryset": Role.objects.filter(status=True), "values_name": "name"}},
    }

    @action(methods=["GET"], detail=False, permission_classes=[OpenApiPermission], authentication_classes=[])
    def open_user_info(self, request, *args, **kwargs):
        """
        第三方API同步用户信息
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        logger.info("第三方API请求获取用户信息列表")
        return self.list(request, *args, **kwargs)

    @action(methods=["POST"], detail=False, permission_classes=[OpenApiPermission], authentication_classes=[])
    def open_create_user_info(self, request, *args, **kwargs):
        """
        第三方API创建用户信息
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        logger.info(f"第三方API请求创建用户: {request.data.get('username', '未知')}")
        return self.create(request, *args, **kwargs)

    @action(methods=["PUT"], detail=False, permission_classes=[OpenApiPermission], authentication_classes=[])
    def open_update_user_info(self, request, *args, **kwargs):
        """
        第三方API创建用户信息
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        logger.info("第三方API请求更新用户信息")
        partial = request.GET.get("partial", False)
        nid = request.GET.get("nid", 0)
        if not nid:
            logger.warning("第三方API更新用户信息参数不合法: nid=0")
            return ErrorResponse(msg="参数不合法")
        logger.info(f"第三方API更新用户信息，用户ID: {nid}")
        instance = Users.objects.get(id=nid)
        serializer = self.get_serializer(instance, data=request.data, request=request, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        if getattr(instance, "_prefetched_objects_cache", None):
            # If 'prefetch_related' has been applied to a queryset跳出, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}
        logger.info(f"第三方API用户信息更新成功，用户ID: {nid}")
        return DetailResponse(data=serializer.data, msg="更新成功")

    @action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated])
    def user_info(self, request):
        """获取当前用户信息"""
        logger.info(f"用户 {request.user.username} 请求获取个人信息")
        user = request.user
        result = {
            "id": user.id,
            "username": user.username,
            "name": user.name,
            "mobile": user.mobile,
            "user_type": user.user_type,
            "gender": user.gender,
            "email": user.email,
            "avatar": user.avatar,
            "dept": user.dept.id if user.dept else None,
            "senior_leader": None
            if not user.parent
            else {
                "id": user.parent.id,
                "avatar": user.parent.avatar,
                "username": user.parent.username,
                "name": user.parent.name,
                "email": user.parent.email,
            },
            "skin": user.skin,
            "user_config": user.user_config,
            "position": user.position,
            "pwd_defaulted": user.pwd_defaulted,
            "is_superuser": user.is_superuser,
            "is_active": user.is_active,
            "is_staff": user.is_staff,
            "role": user.role.values_list("id", flat=True),
        }
        dept = getattr(user, "dept", None)
        if dept:
            result["dept_info"] = {"dept_id": dept.id, "dept_name": dept.name}
        role = getattr(user, "role", None)
        if role:
            result["role_info"] = role.values("id", "name", "key")
        logger.info(f"用户 {request.user.username} 个人信息获取成功")
        return DetailResponse(data=result, msg="获取成功")

    @action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated])
    def my_subordinate(self, request):
        """
        获取当前用户下属
        :param request:
        :return:
        """
        logger.info(f"用户 {request.user.username} 请求获取下属列表")
        user = request.user
        uid = request.GET.get("uid", 0)
        parent_id = uid if uid else user.id
        logger.info(f"查询下属，父级用户ID: {parent_id}")
        queryset = Users.objects.filter(parent_id=parent_id)
        logger.info(f"找到下属数量: {queryset.count()}")
        serializer = UserSubordinateSerializer(queryset, many=True, request=request)
        return DetailResponse(data=serializer.data, msg="获取成功")

    @action(methods=["PUT"], detail=False, permission_classes=[IsAuthenticated])
    def update_user_info(self, request):
        """修改当前用户信息"""
        logger.info(f"用户 {request.user.username} 开始更新个人信息")
        serializer = UserInfoUpdateSerializer(request.user, data=request.data, request=request)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        logger.info(f"用户 {request.user.username} 个人信息更新成功")
        return DetailResponse(data=None, msg="修改成功")

    @action(methods=["PUT"], detail=False, permission_classes=[IsAuthenticated])
    def change_password(self, request, *args, **kwargs):
        """密码修改"""
        logger.info(f"用户 {request.user.username} 开始修改密码")
        try:
            data = request.data
            instance = Users.objects.filter(id=request.user.id).first()
            if not instance:
                logger.warning(f"用户 {request.user.username} 不存在")
                return ErrorResponse(msg="用户不存在")
            old_pwd = data.get("oldPassword")
            new_pwd = data.get("newPassword")
            new_pwd2 = data.get("newPassword2")
            if old_pwd is None or new_pwd is None or new_pwd2 is None:
                logger.warning(f"用户 {request.user.username} 密码修改参数不完整")
                return ErrorResponse(msg="参数不能为空")
            # 验证旧密码
            verify_password = check_password(old_pwd, self.request.user.password)
            if not verify_password:
                verify_password = check_password(
                    hashlib.md5(old_pwd.encode(encoding="UTF-8")).hexdigest(), self.request.user.password
                )
            if not verify_password:
                logger.warning(f"用户 {request.user.username} 旧密码验证失败")
                return ErrorResponse(msg="当前密码输入错误")
            # 验证新密码
            if new_pwd != new_pwd2:
                logger.warning(f"用户 {request.user.username} 两次新密码不匹配")
                return ErrorResponse(msg="两次密码不匹配")
            if check_password(new_pwd, self.request.user.password):
                logger.warning(f"用户 {request.user.username} 新旧密码相同")
                return ErrorResponse(msg="新旧密码相同")
            # 复杂度：密码6-20位，须含大写、数字、特殊符号
            regex = r"^(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{6,20}$"
            if not re.match(regex, new_pwd):
                logger.warning(f"用户 {request.user.username} 新密码不满足复杂度要求")
                return ErrorResponse(msg="新密码不满足要求")
            instance.password = make_password(new_pwd)
            instance.save()
            logger.info(f"用户 {request.user.username} 密码修改成功")
            return DetailResponse(data=None, msg="修改成功")
        except Exception as e:
            logger.error(f"用户 {request.user.username} 密码修改时发生异常: {e}")
            logger.exception(e)
            return ErrorResponse(msg="密码修改失败")

    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated])
    def sso_token(self, request, *args, **kwargs):
        """
        获取用户点单登录token(5分钟内有效)
        """
        logger.info(f"用户 {request.user.username} 请求获取SSO Token")
        try:
            ticket = f"{uuid.uuid4().hex}{int(datetime.now().timestamp())}"
            cache.set(ticket, request.user.id, timeout=300)
            logger.info(f"用户 {request.user.username} SSO Token 生成成功: {ticket[:8]}...")
            return DetailResponse(data=ticket)
        except Exception as e:
            logger.error(f"用户 {request.user.username} 生成SSO Token时发生异常: {e}")
            logger.exception(e)
            return ErrorResponse(msg="SSO Token生成失败")

    @action(methods=["get"], detail=False, permission_classes=[AllowAny], authentication_classes=[])
    def sso_user_info(self, request, *args, **kwargs):
        """
        获取用户点单登录token 匿名请求必须添加 authentication_classes=[]
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        token = request.GET.get("token", "")
        if token == "" or cache.has_key(token) is False:
            return ErrorResponse(msg="参数不合法,请稍后再试")
        uid = cache.get(token, {})
        user_info = Users.objects.filter(id=uid).first()
        cache.delete(token)
        # 用户api权限
        auth_api = []  # list(MenuButton.objects.filter(menu__id__in=menuIds).values("id", "name", "value", "api", "method"))
        white_api = []  # list(ApiWhiteList.objects.values("id", "url", "method", "enable_datasource"))
        role_info = user_info.role.all().values("id", "name", "key", "sort", "status", "admin", "data_range", "remark")
        return DetailResponse(
            data={
                "id": user_info.id,
                "username": user_info.username,
                "name": user_info.name,
                "email": user_info.email,
                "main_department": user_info.main_department,
                "dept": user_info.dept.id if user_info.dept else None,
                "role_info": role_info,
                "auth_api": auth_api,
                "white_api": white_api,
            }
        )

    @action(methods=["PUT"], detail=False, permission_classes=[IsAdminUser])
    def reset_to_default_password(self, request, *args, **kwargs):
        """恢复默认密码"""
        logger.info(f"管理员 {request.user.username} 请求重置用户密码")
        uid = request.data.get("uid", 0)
        instance = Users.objects.filter(id=uid).first()
        if not instance:
            logger.warning(f"未找到用户ID: {uid}")
            return ErrorResponse(msg="未获取到用户")
        logger.info(f"准备重置用户 {instance.username} 的密码")
        instance.set_password(dispatch.get_system_config_values("base.default_password"))
        instance.pwd_defaulted = True
        instance.save()
        logger.info(f"用户 {instance.username} 密码重置成功")
        return DetailResponse(data=None, msg="密码重置成功")

    @action(methods=["post"], detail=False, permission_classes=[IsAuthenticated])
    def check_usernames(self, request, *args, **kwargs):
        """
        验证字符串输入账号是否有效,返回验证成功失败账号信息
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        result = []
        ums = (
            str(request.data.get("ums", ""))
            .replace("，", ",")
            .replace(" ", ",")
            .replace("；", ",")
            .replace(";", ",")
            .replace("\n", ",")
            .strip()
            .upper()
            .split(",")
        )
        ums = [item.strip() for item in ums if item.strip()]  # 去除空字符串
        user_info = Users.objects.filter(Q(username__in=ums) | Q(name__in=ums)).filter(is_active=True)
        user_info_ok = []
        for user in user_info:
            user_info_ok.append(user.username.upper())
            user_info_ok.append(user.name.upper())
            result.append(
                {
                    "id": user.id,
                    "user": user.id,
                    "name": f"{user.name}({user.username.upper()})",
                    "username": user.username.upper(),
                    "avatar": user.avatar if user.avatar else "",
                    "employee_no": user.employee_no,
                    "node_type": 4,
                    "dept__short_name": user.dept.short_name if user.dept else "",
                    "dept__name": user.dept.name if user.dept else "",
                }
            )
        user_info_no = list(filter(None, list(set(ums).difference(set(user_info_ok)))))
        return DetailResponse({"user_info_ok": result, "user_info_no": user_info_no})

    # 通过用户id 获取用户基础信息,用于远程转发显示中文名称
    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated])
    def simple_user_info(self, request, *args, **kwargs):
        uid = request.GET.get("uid", 0)
        if not uid:
            return DetailResponse()
        userinfo = Users.objects.filter(id=uid, is_active=True).first()
        if not userinfo:
            return DetailResponse()
        return DetailResponse(
            data={
                "id": userinfo.id,
                "name": f"{userinfo.name}({userinfo.username.upper()})",
                "username": userinfo.username,
            }
        )

    @action(methods=["get"], detail=False, permission_classes=[AllowAny], authentication_classes=[])
    def allow_simple_user_info(self, request, *args, **kwargs):
        username = str(request.GET.get("username", "")).strip()
        if not username:
            return ErrorResponse(msg="参数错误")
        userinfo = Users.objects.filter(username=username, is_active=True).first()
        if not userinfo:
            return ErrorResponse(msg="用户不存在或禁用")
        return DetailResponse(
            data={
                "id": userinfo.id,
                "name": f"{userinfo.name}",
                "username": userinfo.username,
                "main_department": userinfo.main_department,
            }
        )

    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated])
    def check_single_username(self, request, *args, **kwargs):
        """
        远程搜索,返回单个用户
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        user_name = str(request.GET.get("user_name", "")).strip().upper()
        if not user_name:
            return DetailResponse()
        result = []
        user_info = Users.objects.filter(Q(username__icontains=user_name) | Q(name__icontains=user_name)).filter(
            is_active=True
        )[0:300]
        for user in user_info:
            result.append(
                {
                    "id": str(user.id),
                    "user": user.id,
                    "name": f"{user.name}({user.username.upper()})",
                    "username": user.username.upper(),
                    "avatar": user.avatar if user.avatar else "",
                    "employee_no": user.employee_no,
                    "node_type": 4,
                    "dept__short_name": user.dept.short_name if user.dept else "",
                    "dept__name": user.dept.name if user.dept else "",
                }
            )
        return DetailResponse(result)

    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated])
    def get_ac_code(self, request, *args, **kwargs):
        """
        获取用户授权码
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        current_user_id = request.user.id
        user = Users.objects.get(id=current_user_id, is_active=True)  # 确保用户存在且处于激活状态
        ac_code = user.authorization_code
        if not ac_code:
            # 生成授权码
            ac_code = hashlib.md5(f"{user.username}{uuid.uuid4()}".encode()).hexdigest()
            user.authorization_code = ac_code
            user.save(update_fields=["authorization_code"])
        return DetailResponse(data=ac_code, msg="操作成功")

    @action(methods=["get"], detail=False, permission_classes=[IsAuthenticated])
    def reset_ac_code(self, request, *args, **kwargs):
        """
        重置用户授权码
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        current_user_id = request.user.id
        user = Users.objects.get(id=current_user_id, is_active=True)
        # 生成授权码
        ac_code = f"ac_{hashlib.md5(f'{uuid.uuid4()}_{time.time_ns()}'.encode()).hexdigest()}"
        user.authorization_code = ac_code
        user.save(update_fields=["authorization_code"])
        return DetailResponse(data=ac_code, msg="操作成功")

    @action(methods=["post"], detail=False, permission_classes=[AllowAny], authentication_classes=[])
    def ac_code_to_login(self, request, *args, **kwargs):
        """
        通过授权码ac_code获取用户token
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        username = request.data.get("username", "")
        ac_code = request.data.get("ac_code", "")
        if not username or not ac_code:
            return ErrorResponse(msg="参数不合法")
        user = Users.objects.filter(username=username, is_active=True).first()
        if not user or user.authorization_code != str(ac_code).strip():
            return ErrorResponse(msg="用户不存在或授权码无效")
        # 获得用户后，校验密码并签发token
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        data = {
            "access": access_token,
            "refresh": str(refresh),
            "name": user.name,
            "skin": user.skin,
            "userId": user.id,
            "is_staff": user.is_staff,
            "avatar": user.avatar,
            "pwd_defaulted": user.pwd_defaulted,
            "user_type": user.user_type,
            "role_info": user.role.values("id", "name", "key"),
        }
        user.last_token = access_token
        user.save()
        # 记录登录日志
        save_login_log(request=request, login_type=4, current_user=user)
        # 新增到普通用户组
        return DetailResponse(data)
