from rest_framework import serializers, status, permissions from rest_framework.response import Response from rest_framework.views import APIView from stateflow import models as stateflow_models from stateflow import services as stateflow_services class BusinessObjectCloneRequestSerializer(serializers.Serializer): business_object_id = serializers.IntegerField(min_value=1) # 调用方必须显式传入 content_type 与 object_id: # - content_type:仅用于校验与源对象一致(不做额外校验) # - object_id:克隆后的新业务对象 ID(必须与源对象不同) content_type = serializers.IntegerField(min_value=1, allow_null=True) object_id = serializers.IntegerField(min_value=1, allow_null=True) class BusinessObjectCloneView(APIView): """ 克隆 BusinessObject(含所有状态流转记录与工艺参数记录) POST /api/v2/stateflow/business-objects/clone/ 请求体: { "business_object_id": 123, "content_type": 9, "object_id": 456 } 返回: { "business_object_id": 456 } """ permission_classes = [permissions.IsAuthenticated] def post(self, request): srz = BusinessObjectCloneRequestSerializer(data=request.data) srz.is_valid(raise_exception=True) bo_id = srz.validated_data['business_object_id'] expected_content_type_id = srz.validated_data.get('content_type') new_object_id = srz.validated_data.get('object_id') try: bo = stateflow_models.BusinessObject.objects.get(id=bo_id) except stateflow_models.BusinessObject.DoesNotExist: return Response({'detail': 'business_object 不存在'}, status=status.HTTP_404_NOT_FOUND) try: cloned = stateflow_services.clone_business_object( bo, new_object_id=new_object_id, expected_content_type_id=expected_content_type_id, ) except ValueError as e: return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST) return Response({'business_object_id': cloned.id})