import json import uuid from datetime import datetime from django.db import connection, transaction from django.db.models import CharField, Max from django.db.models.functions import Cast from django.shortcuts import get_object_or_404 from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from apps.common.serializers import ( AiAlgorithmCallLogSerializer, AiAlgorithmEngineSerializer, AiAlgorithmSerializer, ) from apps.core.models import ( AiAlgorithm, AiAlgorithmCallLog, AiAlgorithmEngine, AiAlgorithmModels, AiAlgorithmOutput, AiAlgorithmParams, AiAlgorithmTrainRecords, ) @api_view(["GET"]) @permission_classes([IsAuthenticated]) def search_algorithm(request): algorithm_code = request.GET.get("algorithm_code", None) algorithm_name = request.GET.get("algorithm_name", None) algorithm_class = request.GET.get("algorithm_class", None) scenario = request.GET.get("scenario", None) algorithm_type = request.GET.get("algorithm_type", None) algorithm_status = request.GET.get("algorithm_status", None) development_unit = request.GET.get("development_unit", None) class_code = request.GET.get("class_code", None) page_size = request.GET.get("page_size", None) filter_kwargs = {} if algorithm_code: filter_kwargs["algorithm_code__icontains"] = algorithm_code if algorithm_name: filter_kwargs["algorithm_name__icontains"] = algorithm_name if algorithm_class: filter_kwargs["algorithm_class__exact"] = algorithm_class if scenario: filter_kwargs["scenario__icontains"] = scenario if algorithm_type: filter_kwargs["algorithm_type__exact"] = algorithm_type if algorithm_status: filter_kwargs["algorithm_status__exact"] = algorithm_status if development_unit: filter_kwargs["development_unit__icontains"] = development_unit if class_code: filter_kwargs["labels__icontains"] = class_code algorithms = AiAlgorithm.objects.filter(**filter_kwargs).order_by("algorithm_code") paginator = PageNumberPagination() paginator.page_size = page_size or 10 result_page = paginator.paginate_queryset(algorithms, request) serializer = AiAlgorithmSerializer(result_page, many=True) return paginator.get_paginated_response(serializer.data) @api_view(["GET"]) @permission_classes([IsAuthenticated]) def get_algorithm_tree(request): sql = """ SELECT a.id AS id, a.classcode AS code, a.classname AS name, a.parentid AS parentid FROM ai_algorithm_class a UNION SELECT b.id AS id, b.algorithm_code AS code, b.algorithm_name AS name, b.algorithm_class AS parentid FROM ai_algorithm b ORDER BY code """ with connection.cursor() as cursor: cursor.execute(sql) result = cursor.fetchall() keys = ["id", "code", "name", "parentid"] data = [dict(zip(keys, row)) for row in result] return Response(data) @api_view(["GET"]) @permission_classes([IsAuthenticated]) def get_algorithm_list(request): algorithm_code = request.GET.get("algorithm_code", None) algorithm_name = request.GET.get("algorithm_name", None) algorithm_class = request.GET.get("algorithm_class", None) filter_kwargs = {} if algorithm_code: filter_kwargs["algorithm_code__icontains"] = algorithm_code if algorithm_name: filter_kwargs["algorithm_name__icontains"] = algorithm_name if algorithm_class: filter_kwargs["algorithm_class__exact"] = algorithm_class algorithms = AiAlgorithm.objects.filter(**filter_kwargs).order_by( "algorithm_class", "algorithm_code" ) serializer = AiAlgorithmSerializer(algorithms, many=True) return Response(serializer.data) @api_view(["GET"]) @permission_classes([IsAuthenticated]) def get_algorithm_engines(request): algorithmengines = AiAlgorithmEngine.objects.order_by("enginecode") serializer = AiAlgorithmEngineSerializer(algorithmengines, many=True) return Response(serializer.data) @api_view(["POST"]) @permission_classes([IsAuthenticated]) @transaction.atomic def add_algorithm(request): data = request.data data["id"] = str(uuid.uuid4()) data["creator"] = request.user.username if request.user.username else "creator" data["create_time"] = datetime.now() algorithm_class = data.get("algorithm_class") algorithm_engine = data.get("algorithm_engine") max_algorithm_code = AiAlgorithm.objects.filter(algorithm_class=algorithm_class).aggregate( max_algorithm_code=Max(Cast("algorithm_code", CharField())) ).get("max_algorithm_code") max_algorithm_code = int(max_algorithm_code) if max_algorithm_code is not None else 0 new_algorithm_code = f"{max_algorithm_code + 1:03}" data["algorithm_code"] = new_algorithm_code serializer = AiAlgorithmSerializer(data=data) if serializer.is_valid(): serializer.save() engine = get_object_or_404(AiAlgorithmEngine, id=algorithm_engine) if engine.training_params_template: try: params = json.loads(engine.training_params_template) params_to_save = [ AiAlgorithmParams( id=str(uuid.uuid4()), algorithm_id=data["id"], param_class="01", param_order=param.get("param_order"), param_name=param.get("param_name"), param_desc=param.get("param_desc"), param_type=param.get("param_type"), param_unit=param.get("param_unit"), param_range=param.get("param_range"), default_values=param.get("default_values"), description=param.get("description"), ) for param in params ] AiAlgorithmParams.objects.bulk_create(params_to_save) except json.JSONDecodeError as e: return Response( {"error": f"Invalid JSON in training_params_template: {str(e)}"}, status=status.HTTP_400_BAD_REQUEST, ) return Response({"message": "Algorithm added successfully"}) return Response( {"error": "Invalid data", "details": serializer.errors}, status=status.HTTP_400_BAD_REQUEST, ) @api_view(["GET"]) @permission_classes([IsAuthenticated]) def read_algorithm(request): algorithm_id = request.GET.get("id", None) algorithm = get_object_or_404(AiAlgorithm, id=algorithm_id) serializer = AiAlgorithmSerializer(algorithm) return Response(serializer.data) @api_view(["PUT"]) @permission_classes([IsAuthenticated]) def update_algorithm(request): data = request.data algorithm = get_object_or_404(AiAlgorithm, id=data.get("id")) serializer = AiAlgorithmSerializer(instance=algorithm, data=data, partial=True) if serializer.is_valid(): serializer.save() return Response({"message": "Algorithm updated successfully"}) return Response( {"error": "Invalid data", "details": serializer.errors}, status=status.HTTP_400_BAD_REQUEST, ) @api_view(["DELETE"]) @permission_classes([IsAuthenticated]) @transaction.atomic def delete_algorithm(request): algorithm = get_object_or_404(AiAlgorithm, id=request.GET.get("id")) model_count = AiAlgorithmModels.objects.filter(algorithm_id=algorithm.id).count() if model_count > 0: return Response({"warn": "该算法已经绑定了模型,请先删除算法模型!"}, status=status.HTTP_400_BAD_REQUEST) train_count = AiAlgorithmTrainRecords.objects.filter(algorithm_id=algorithm.id).count() if train_count > 0: return Response( {"warn": "该算法已经存在了模型训练记录,请先删除算法模型训练记录!"}, status=status.HTTP_400_BAD_REQUEST, ) try: AiAlgorithmParams.objects.filter(algorithm_id=algorithm.id).delete() AiAlgorithmOutput.objects.filter(algorithm_id=algorithm.id).delete() algorithm.delete() return Response({"message": "算法删除成功"}, status=status.HTTP_200_OK) except Exception as e: return Response({"error": f"算法删除失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)