diff --git a/MangoServer/src/auto_test/auto_api/urls.py b/MangoServer/src/auto_test/auto_api/urls.py index fd9538b4..3c00122d 100644 --- a/MangoServer/src/auto_test/auto_api/urls.py +++ b/MangoServer/src/auto_test/auto_api/urls.py @@ -20,6 +20,7 @@ urlpatterns = [ path("info/type", ApiInfoViews.as_view({'put': 'put_api_info_type'})), path("info/copy", ApiInfoViews.as_view({'post': 'copy_api_info'})), path("info/import/api", ApiInfoViews.as_view({'post': 'import_api'})), + path("upload/api", ApiInfoViews.as_view({'post': 'post_upload_api'})), # path("case", ApiCaseCRUD.as_view()), path("case/test", ApiCaseViews.as_view({'get': 'api_test_case'})), @@ -33,7 +34,8 @@ urlpatterns = [ path("case/detailed/refresh", ApiCaseDetailedViews.as_view({'put': 'put_refresh_api_info'})), # path("case/detailed/parameter", ApiCaseDetailedParameterCRUD.as_view()), - path("case/detailed/parameter/test/jsonpath", ApiCaseDetailedParameterViews.as_view({'post': 'post_test_jsonpath'})), + path("case/detailed/parameter/test/jsonpath", + ApiCaseDetailedParameterViews.as_view({'post': 'post_test_jsonpath'})), # path("public", ApiPublicCRUD.as_view()), path("public/status", ApiPublicViews.as_view({'put': 'put_status'})), diff --git a/MangoServer/src/auto_test/auto_api/views/api_info.py b/MangoServer/src/auto_test/auto_api/views/api_info.py index 0098e8b4..b47ded44 100644 --- a/MangoServer/src/auto_test/auto_api/views/api_info.py +++ b/MangoServer/src/auto_test/auto_api/views/api_info.py @@ -6,6 +6,7 @@ import json from urllib.parse import urlparse, parse_qs +import pandas as pd from curlparser import parse from django.forms import model_to_dict from rest_framework import serializers @@ -15,6 +16,7 @@ from rest_framework.viewsets import ViewSet from src.auto_test.auto_api.models import ApiInfo from src.auto_test.auto_api.service.test_case.test_api_info import TestApiInfo +from src.auto_test.auto_system.models import ProjectProduct, ProductModule from src.auto_test.auto_system.views.product_module import ProductModuleSerializers from src.auto_test.auto_system.views.project_product import ProjectProductSerializersC from src.enums.api_enum import MethodEnum @@ -148,3 +150,46 @@ class ApiInfoViews(ViewSet): result['json'] = json.dumps(parsed.json, indent=4, ensure_ascii=False) data = ApiInfoCRUD.inside_post(result) return ResponseData.success(RESPONSE_MSG_0069, data=data) + + @action(methods=['POST'], detail=False) + @error_response('ui') + def post_upload_api(self, request): + uploaded_file = request.FILES['file'] + df = pd.read_excel(uploaded_file, keep_default_na=False) + df = df.where(df.notna(), None) + df = df.replace('', None) + df['*请求方法'] = df['*请求方法'].map(MethodEnum.reversal_obj()) + + df = df.rename(columns={ + '*产品名称': 'project_product', + '*模块名称': 'module', + '*接口名称': 'name', + '*请求方法': 'method', + '*url': 'url', + '请求头': 'headers', + '参数': 'params', + '表单': 'data', + 'JSON': 'json', + '文件': 'file', + }) + for index, row in df.iterrows(): + record = row.to_dict() + record['type'] = request.data.get("type") + try: + record['project_product'] = ProjectProduct.objects.get(name=record['project_product']).id + record['module'] = ProductModule.objects.get(name=record['module'], + project_product=record['project_product']).id + except ( + ProductModule.MultipleObjectsReturned, ProjectProduct.MultipleObjectsReturned, ProductModule.DoesNotExist, + ProjectProduct.DoesNotExist): + return ResponseData.fail(RESPONSE_MSG_0138) + for i in ['headers', 'params', 'data', 'json', 'file']: + if record[i] == '' or record[i] is None: + record[i] = None + elif i == 'file': + try: + record[i] = json.loads(record[i]) + except json.decoder.JSONDecodeError: + return ResponseData.fail(RESPONSE_MSG_0137) + ApiInfoCRUD.inside_post(record) + return ResponseData.success(RESPONSE_MSG_0083) diff --git a/MangoServer/src/auto_test/auto_system/migrations/0011_alter_projectproduct_name.py b/MangoServer/src/auto_test/auto_system/migrations/0011_alter_projectproduct_name.py new file mode 100644 index 00000000..958db7b7 --- /dev/null +++ b/MangoServer/src/auto_test/auto_system/migrations/0011_alter_projectproduct_name.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.5 on 2025-10-20 07:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auto_system', '0010_testsuitedetails_case_sum_testsuitedetails_fail_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='projectproduct', + name='name', + field=models.CharField(max_length=64, unique=True, verbose_name='产品名称'), + ), + ] diff --git a/MangoServer/src/auto_test/auto_system/models.py b/MangoServer/src/auto_test/auto_system/models.py index caeb5147..5d55dfe5 100644 --- a/MangoServer/src/auto_test/auto_system/models.py +++ b/MangoServer/src/auto_test/auto_system/models.py @@ -31,7 +31,7 @@ class ProjectProduct(models.Model): create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True) update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True) project = models.ForeignKey(to=Project, to_field="id", on_delete=models.PROTECT) - name = models.CharField(verbose_name="产品名称", max_length=64) + name = models.CharField(verbose_name="产品名称", max_length=64, unique=True) ui_client_type = models.SmallIntegerField(verbose_name="UI客户端类型", default=0) api_client_type = models.SmallIntegerField(verbose_name="API客户端类型", default=0) diff --git a/MangoServer/src/tools/view/response_msg.py b/MangoServer/src/tools/view/response_msg.py index f276228f..6099d7d8 100644 --- a/MangoServer/src/tools/view/response_msg.py +++ b/MangoServer/src/tools/view/response_msg.py @@ -139,3 +139,5 @@ RESPONSE_MSG_0133 = (200, '测试子任务成功') RESPONSE_MSG_0134 = (300, '只支持cURL(base)的格式') RESPONSE_MSG_0135 = (200, '提取jsonpath预发成功') RESPONSE_MSG_0136 = (200, '设置日志状态成功') +RESPONSE_MSG_0137 = (300, 'file必须上传json格式,请参照webAPI新增模版') +RESPONSE_MSG_0138 = (300, '请确保上传的产品和模块没有重名,并且存在') diff --git a/MangoServer/upload_template/接口批量上传模版.xlsx b/MangoServer/upload_template/接口批量上传模版.xlsx new file mode 100644 index 00000000..87ad9b65 Binary files /dev/null and b/MangoServer/upload_template/接口批量上传模版.xlsx differ diff --git a/mango-console/src/api/apitest/info.ts b/mango-console/src/api/apitest/info.ts index 386c6933..33ee76c4 100644 --- a/mango-console/src/api/apitest/info.ts +++ b/mango-console/src/api/apitest/info.ts @@ -92,3 +92,19 @@ export function postApiCopyInfo(id: number) { }, }) } + +export function postApiUploadApi(type: number, file?: File) { + const formData = new FormData() + formData.append('type', type.toString()) + if (file) { + formData.append('file', file) + } + + return post({ + url: '/api/upload/api', + data: () => formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} diff --git a/mango-console/src/views/apitest/info/index.vue b/mango-console/src/views/apitest/info/index.vue index ef6e1301..fda0832f 100644 --- a/mango-console/src/views/apitest/info/index.vue +++ b/mango-console/src/views/apitest/info/index.vue @@ -11,7 +11,7 @@ + + + + 下载模板 + + + tips:如果需要直接上传到调试接口Tab里面,请点击开关打开 +
+ 选择文件 + 已选择: {{ selectedFile.name }} + +
+
+
+