From bbfaa3ed071ffc4e5e10636384fc88d7e707c7ed Mon Sep 17 00:00:00 2001 From: shijing Date: Sat, 18 Sep 2021 11:34:24 +0800 Subject: [PATCH 1/3] liuchengtu --- hb_client/package.json | 2 + hb_client/src/api/workflow.js | 10 +- hb_client/src/layout/components/Navbar.vue | 2 +- .../layout/components/Sidebar/SidebarItem.vue | 4 +- hb_client/src/router/index.js | 13 + hb_client/src/views/workflow/customfield.vue | 205 +++++++-------- hb_client/src/views/workflow/index.vue | 185 +++++++------- hb_client/src/views/workflow/test.vue | 133 ++++++++++ hb_client/src/views/workflow/ticket.vue | 238 ++++++++++++++++++ 9 files changed, 566 insertions(+), 226 deletions(-) create mode 100644 hb_client/src/views/workflow/test.vue create mode 100644 hb_client/src/views/workflow/ticket.vue diff --git a/hb_client/package.json b/hb_client/package.json index 4a4ab4c..21eedd0 100644 --- a/hb_client/package.json +++ b/hb_client/package.json @@ -19,6 +19,8 @@ "@riophae/vue-treeselect": "^0.4.0", "axios": "^0.21.1", "compression-webpack-plugin": "^5.0.1", + "d3": "^5.14.2", + "dagre-d3": "^0.6.4", "element-ui": "^2.15.5", "file-saver": "^2.0.2", "fuse.js": "^6.4.6", diff --git a/hb_client/src/api/workflow.js b/hb_client/src/api/workflow.js index 0b388a9..724227a 100644 --- a/hb_client/src/api/workflow.js +++ b/hb_client/src/api/workflow.js @@ -120,4 +120,12 @@ export function deleteWfTransition(id, data) { method: 'delete', data }) -} \ No newline at end of file +} +//工单详情 +export function getTickets(query) { + return request({ + url: `/wf/ticket/`, + method: 'get', + params:query + }) +} diff --git a/hb_client/src/layout/components/Navbar.vue b/hb_client/src/layout/components/Navbar.vue index ae69bc5..7cb30fd 100644 --- a/hb_client/src/layout/components/Navbar.vue +++ b/hb_client/src/layout/components/Navbar.vue @@ -7,7 +7,7 @@
diff --git a/hb_client/src/layout/components/Sidebar/SidebarItem.vue b/hb_client/src/layout/components/Sidebar/SidebarItem.vue index a418c3d..27feb9f 100644 --- a/hb_client/src/layout/components/Sidebar/SidebarItem.vue +++ b/hb_client/src/layout/components/Sidebar/SidebarItem.vue @@ -13,8 +13,8 @@ import('@/views/workflow/ticket'), + meta: { title: '工单列表', icon: 'example', perms: ['ticket_manage'] }, + hidden: true + },{ + path: 'test', + name: 'test', + component: () => import('@/views/workflow/test'), + meta: { title: '工单', icon: 'example', perms: ['test_manage'] }, + hidden: true + }, ] }, { diff --git a/hb_client/src/views/workflow/customfield.vue b/hb_client/src/views/workflow/customfield.vue index 78b579a..76b154f 100644 --- a/hb_client/src/views/workflow/customfield.vue +++ b/hb_client/src/views/workflow/customfield.vue @@ -1,7 +1,7 @@ diff --git a/hb_client/src/views/workflow/test.vue b/hb_client/src/views/workflow/test.vue new file mode 100644 index 0000000..fa06867 --- /dev/null +++ b/hb_client/src/views/workflow/test.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/hb_client/src/views/workflow/ticket.vue b/hb_client/src/views/workflow/ticket.vue new file mode 100644 index 0000000..7039ed0 --- /dev/null +++ b/hb_client/src/views/workflow/ticket.vue @@ -0,0 +1,238 @@ + + + + + From 737bb015fefc11f6a8ef1124960f2300574aebbb Mon Sep 17 00:00:00 2001 From: caoqianming Date: Sun, 19 Sep 2021 21:15:52 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=87=87=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_dcu/.gitignore | 3 + hb_dcu/default.aproj | 8 ++ hb_dcu/dlg/add.aardio | 24 +++++ hb_dcu/lib/config.aardio | 20 ++++ hb_dcu/main.aardio | 200 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 255 insertions(+) create mode 100644 hb_dcu/.gitignore create mode 100644 hb_dcu/default.aproj create mode 100644 hb_dcu/dlg/add.aardio create mode 100644 hb_dcu/lib/config.aardio create mode 100644 hb_dcu/main.aardio diff --git a/hb_dcu/.gitignore b/hb_dcu/.gitignore new file mode 100644 index 0000000..1f2de66 --- /dev/null +++ b/hb_dcu/.gitignore @@ -0,0 +1,3 @@ +dist/ +config/* +.build/ \ No newline at end of file diff --git a/hb_dcu/default.aproj b/hb_dcu/default.aproj new file mode 100644 index 0000000..17a8b81 --- /dev/null +++ b/hb_dcu/default.aproj @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/hb_dcu/dlg/add.aardio b/hb_dcu/dlg/add.aardio new file mode 100644 index 0000000..463f520 --- /dev/null +++ b/hb_dcu/dlg/add.aardio @@ -0,0 +1,24 @@ +import win.ui; +/*DSG{{*/ +var winform = win.form(text="新建采集内容";right=299;bottom=179;border="dialog frame";max=false;min=false) +winform.add( +button={cls="button";text="确定";left=90;top=119;right=196;bottom=154;z=5}; +edit={cls="edit";left=84;top=26;right=281;bottom=50;dl=1;dr=1;dt=1;edge=1;z=2}; +edit2={cls="edit";left=84;top=69;right=281;bottom=93;dl=1;dr=1;dt=1;edge=1;z=4}; +static={cls="static";text="设备编号";left=8;top=29;right=78;bottom=54;dl=1;dt=1;notify=1;transparent=1;z=1}; +static2={cls="static";text="文件夹地址";left=8;top=74;right=78;bottom=99;dl=1;dt=1;notify=1;transparent=1;z=3} +) +/*}}*/ + +winform.button.oncommand = function(id,event){ + if(winform.edit.text!="" && winform.edit2.text!=""){ + winform.parent.listview.addItem({winform.edit.text;winform.edit2.text}) + winform.close() + }else{ + winform.msgbox("请输入信息!")} + +} + +winform.show(); +win.loopMessage(); +return winform; \ No newline at end of file diff --git a/hb_dcu/lib/config.aardio b/hb_dcu/lib/config.aardio new file mode 100644 index 0000000..a1cbfc5 --- /dev/null +++ b/hb_dcu/lib/config.aardio @@ -0,0 +1,20 @@ +//config 配置文件 +import fsys.config; +config = fsys.config("/config/"); +//config = fsys.config( io.appData("/软件作者/应用程序名/") ); + +//不需要序列化的配置名字前请添加下划线 +namespace config { + __appName = "应用程序名"; + __appVersion = "1.0.0.01"; + __appDescription = "这是一个测试程序"; + __website = "http://www.aardio.com/"; +} + +/**intellisense(config) +__appName = 应用程序名 +__appVersion = 应用程序内部版本号 +__appDescription = 程序说明 +__website = 官方网站 +? = 配置文件名,\n读写配置并序列化为一个表对象,\n表的成员值可以是支持序列化的普通变量,支持table对象\n配置文件在首次使用时自动加载,退出程序时自动保存\n!fsys_table. +end intellisense**/ \ No newline at end of file diff --git a/hb_dcu/main.aardio b/hb_dcu/main.aardio new file mode 100644 index 0000000..cb5ac2e --- /dev/null +++ b/hb_dcu/main.aardio @@ -0,0 +1,200 @@ +import win.ui; +import win.inputBox; +import win.ui.menu; +import win.util.tray; +import win.ui.atom; +import win.timer; +import console; +import win.timer; +import fsys; +import web.multipartFormData; +import inet.http; +import fsys.config; +/*DSG{{*/ +mainForm = win.form(text="数据采集";right=799;bottom=399;border="dialog frame";max=false) +mainForm.add( +add={cls="button";text="新建";left=27;top=130;right=98;bottom=154;font=LOGFONT(h=-14;name='微软雅黑');z=6}; +backupPath={cls="edit";left=107;top=58;right=337;bottom=84;edge=1;font=LOGFONT(h=-14;name='微软雅黑');z=11}; +backupPathLabel={cls="static";text="备份文件夹";left=31;top=60;right=118;bottom=81;font=LOGFONT(h=-14;name='微软雅黑');notify=1;transparent=1;z=10}; +groupbox={cls="groupbox";text="采集内容";left=18;top=110;right=346;bottom=390;edge=1;z=5}; +groupbox2={cls="groupbox";text="采集日志";left=353;top=7;right=792;bottom=390;ah=1;aw=1;db=1;dr=1;edge=1;z=1}; +groupbox3={cls="groupbox";text="基础配置";left=18;top=7;right=346;bottom=102;edge=1;z=2}; +listbox={cls="listbox";left=360;top=24;right=785;bottom=387;edge=1;hscroll=1;items={};vscroll=1;z=12}; +listview={cls="listview";left=27;top=161;right=337;bottom=384;edge=1;fullRow=1;items={};msel=false;z=7}; +serverUrl={cls="edit";left=107;top=25;right=337;bottom=51;edge=1;font=LOGFONT(h=-14;name='微软雅黑');z=4}; +serverUrlLabel={cls="static";text="服务器地址";left=31;top=28;right=118;bottom=49;font=LOGFONT(h=-14;name='微软雅黑');notify=1;transparent=1;z=3}; +start={cls="button";text="开始采集";left=266;top=130;right=337;bottom=154;font=LOGFONT(h=-14;name='微软雅黑');z=8}; +statusLabel={cls="static";left=143;top=130;right=221;bottom=154;align="center";color=32768;font=LOGFONT(h=-16;name='微软雅黑';weight=700);transparent=1;z=9} +) +/*}}*/ + +/* +inputbox = win.inputBox(mainForm.hwnd) +inputbox.text = "输入框标题" +inputbox.info.text = "请在下面输入您的名字" +inputbox.input.text = "在这里输入您的名字" +name = inputbox.doModal(); + +if(name) + win.msgbox("您的名字是:"+name ) +else + win.msgbox("你拒绝输入名字") +*/ +mainForm.listview.adjust = function(cx,cy){ + mainForm.listview.fillParent(/*列序号*/); +} + +mainForm.listview.insertColumn("设备编号",100,,0x0/*_LVCFMT_LEFT*/) +mainForm.listview.insertColumn("文件夹地址",100,,0x0/*_LVCFMT_LEFT*/) //第二列开始可以使用_LVCFMT_CENTER居中 + +config = fsys.config("/config/") +mainForm.bindConfig( config.winform,{ + serverUrl = "text"; + backupPath = "text"; + listview = "items"; +} ); +if(mainForm.serverUrl.text==""){ + mainForm.serverUrl.text='https://testsearch.ctc.ac.cn' +} +if(mainForm.backupPath.text==""){ + mainForm.backupPath.text="\Backup" +} +/* +if(table.count(mainForm.listview.items)==0){ + mainForm.listview.items = {{"JN102";"D:\tmp"}}; +} +*/ + +var isWorking = false; +var atom,hwnd/*冲突窗口的句柄,该函数会自动激活此窗口*/ = mainForm.atom("33D501DF-BFC2-4283-8BBE-AF17AADB1C27"); +if(!atom){ + /*为窗口设置原子值可以避免一个程序重复运行多个实例*/ + win.quitMessage(); return; +} + + +mainForm.onMinimize = function(lParam){ + var tray = win.util.tray(mainForm) //创建托盘图标 + tray.tip = "数据采集"; + mainForm.show(false); //隐藏窗口 + return true;//阻击默认消息传递,取消最小化过程 +} +mainForm.wndproc = { + [0xACCF/*_WM_TRAYMESSAGE*/ ] = function(hwnd,message,wParam,lParam){ + if( lParam = 0x205/*_WM_RBUTTONUP*/ ){ + var pt = ::POINT(); + ::User32.GetCursorPos(pt); + //弹出托盘菜单以前,一定要前置主窗口中,不然不点击菜单不会消失 + win.setForeground(mainForm.hwnd) + mainForm.popmenu.popup(pt.x,pt.y,true ) + }elseif(lParam = 0x203/*_WM_LBUTTONDBLCLK*/){ + mainForm.show() + } + + + } +} + +mainForm.popmenu = win.ui.popmenu(mainForm);//创建弹出菜单 +mainForm.popmenu.add('&打开',function(id){ + //在下面输入菜单响应代码 + mainForm.show() +}); +mainForm.popmenu.add();//分隔线 +mainForm.popmenu.add('&退出',function(id){ mainForm.close() }) + +mainForm.start.oncommand = function(id,event){ + toggleWorking(); + +} +var timer = win.timer( mainForm ); +timer.setInterval(5000) +function toggleWorking(){ + if(isWorking == false){ + mainForm.serverUrl.disabled = true + mainForm.backupPath.disabled = true + mainForm.add.disabled = true + mainForm.statusLabel.text="采集中..." + mainForm.start.text="停止采集" + isWorking = true + timer.enable() + }else{ + mainForm.serverUrl.disabled = false + mainForm.backupPath.disabled = false + mainForm.add.disabled = false + mainForm.statusLabel.text="" + mainForm.start.text="开始采集" + isWorking=false + timer.disable() + } +} +if(mainForm.serverUrl && table.count(mainForm.listview.items)>0){ +toggleWorking(); +} + +timer.onTimer = function(hwnd,msg,id,tick){ + for itemIndex in mainForm.listview.each(){ + var number, dir = mainForm.listview.items[itemIndex][1], mainForm.listview.items[itemIndex][2] + //批量处理文件 + fsys.enum( dir, //指定要遍历的目录 + "*.*", //指定查询文件名,支持windows掩码 + function(dir,filename,fullpath,findData){ //指定触发器 + if(filename){ + mainForm.listbox.add(tostring(time.now(),"%Y-%m-%d %H:%M:%S","chs") + ":发现文件-"+filename, -1) + mainForm.listbox.add("正在上传并解析...") + var webData = web.multipartFormData(); + webData.add("equip_num", number) + webData.add("file", "@"+fullpath) + var http = inet.http(); + http.beginRequest( mainForm.serverUrl.text + "/api/file/", "POST" ); + //小数据一次性上传 + http.beginSendData(webData.size()); + http.writeData(webData.readAll()) + http.endSendData(); + var res = web.json.parse(http.readAll()) + if(res['code']==200){ + import fsys + var theDir = fsys.createDir(mainForm.backupPath.text+"\"+number, false) + fsys.move(fullpath, theDir) //移动到备份文件库 + mainForm.listbox.add("采集成功!") + }else{ + mainForm.listbox.add("失败:"+res['msg']) + } + http.close(); + + + } + }, false + ); + } +} + +mainForm.listview.onnotify = function(id,code,ptr){ + + select(code) { + case 0xFFFFFFFB/*_NM_RCLICK*/ { + var x,y = win.getCursorPos(); + var popmenu = win.ui.popmenu(mainForm);//创建弹出菜单 + popmenu.add('删除',function(id){ + //在下面输入菜单响应代码 + mainForm.listview.delItem( mainForm.listview.selIndex ) + }); + popmenu.popup(x,y,true);//弹出菜单 + } + } + +} + +mainForm.add.oncommand = function(id,event){ + +var frmChild = mainForm.loadForm("\dlg\add.aardio"); +frmChild.doModal(); + +} + + + + + +mainForm.show(); +return win.loopMessage(); \ No newline at end of file From da65c598937e8333e1569a22c6e5b5805471938e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 22 Sep 2021 09:08:23 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_client/package.json | 2 +- {hb_dcu => hb_daq}/.gitignore | 0 {hb_dcu => hb_daq}/default.aproj | 2 +- {hb_dcu => hb_daq}/dlg/add.aardio | 0 {hb_dcu => hb_daq}/lib/config.aardio | 0 {hb_dcu => hb_daq}/main.aardio | 32 +++++++++++++++++----------- hb_server/apps/em/serializers.py | 7 +++++- hb_server/apps/em/urls.py | 3 ++- hb_server/apps/em/views.py | 30 ++++++++++++++++++++++++-- 9 files changed, 58 insertions(+), 18 deletions(-) rename {hb_dcu => hb_daq}/.gitignore (100%) rename {hb_dcu => hb_daq}/default.aproj (54%) rename {hb_dcu => hb_daq}/dlg/add.aardio (100%) rename {hb_dcu => hb_daq}/lib/config.aardio (100%) rename {hb_dcu => hb_daq}/main.aardio (88%) diff --git a/hb_client/package.json b/hb_client/package.json index 1382831..2ba093d 100644 --- a/hb_client/package.json +++ b/hb_client/package.json @@ -20,7 +20,7 @@ "axios": "^0.21.1", "cache-loader": "^4.1.0", "compression-webpack-plugin": "^5.0.1", - "d3": "^5.14.2", + "d3": "^5.16.0", "dagre-d3": "^0.6.4", "element-ui": "^2.15.5", "file-saver": "^2.0.2", diff --git a/hb_dcu/.gitignore b/hb_daq/.gitignore similarity index 100% rename from hb_dcu/.gitignore rename to hb_daq/.gitignore diff --git a/hb_dcu/default.aproj b/hb_daq/default.aproj similarity index 54% rename from hb_dcu/default.aproj rename to hb_daq/default.aproj index 17a8b81..c3e936d 100644 --- a/hb_dcu/default.aproj +++ b/hb_daq/default.aproj @@ -1,5 +1,5 @@  - + diff --git a/hb_dcu/dlg/add.aardio b/hb_daq/dlg/add.aardio similarity index 100% rename from hb_dcu/dlg/add.aardio rename to hb_daq/dlg/add.aardio diff --git a/hb_dcu/lib/config.aardio b/hb_daq/lib/config.aardio similarity index 100% rename from hb_dcu/lib/config.aardio rename to hb_daq/lib/config.aardio diff --git a/hb_dcu/main.aardio b/hb_daq/main.aardio similarity index 88% rename from hb_dcu/main.aardio rename to hb_daq/main.aardio index cb5ac2e..ab39ff1 100644 --- a/hb_dcu/main.aardio +++ b/hb_daq/main.aardio @@ -54,10 +54,10 @@ mainForm.bindConfig( config.winform,{ listview = "items"; } ); if(mainForm.serverUrl.text==""){ - mainForm.serverUrl.text='https://testsearch.ctc.ac.cn' + mainForm.serverUrl.text='http://127.0.0.1:8000' } if(mainForm.backupPath.text==""){ - mainForm.backupPath.text="\Backup" + mainForm.backupPath.text="D:\Daq\Backup" } /* if(table.count(mainForm.listview.items)==0){ @@ -140,27 +140,35 @@ timer.onTimer = function(hwnd,msg,id,tick){ "*.*", //指定查询文件名,支持windows掩码 function(dir,filename,fullpath,findData){ //指定触发器 if(filename){ - mainForm.listbox.add(tostring(time.now(),"%Y-%m-%d %H:%M:%S","chs") + ":发现文件-"+filename, -1) + mainForm.listbox.add(tostring(time.now(),"%Y-%m-%d %H:%M:%S","chs") + ":新文件-"+filename, -1) mainForm.listbox.add("正在上传并解析...") var webData = web.multipartFormData(); webData.add("equip_num", number) webData.add("file", "@"+fullpath) + webData.contentHeader() var http = inet.http(); - http.beginRequest( mainForm.serverUrl.text + "/api/file/", "POST" ); + /* +http.beginRequest( mainForm.serverUrl.text + "/api/em/daq/", "POST" ); //小数据一次性上传 http.beginSendData(webData.size()); http.writeData(webData.readAll()) http.endSendData(); - var res = web.json.parse(http.readAll()) - if(res['code']==200){ - import fsys - var theDir = fsys.createDir(mainForm.backupPath.text+"\"+number, false) - fsys.move(fullpath, theDir) //移动到备份文件库 - mainForm.listbox.add("采集成功!") +*/ + var html,err,errCode = http.post( mainForm.serverUrl.text + "/api/em/daq/",webData.readAll(),webData.contentHeader()); + if(html){ + var res = web.json.parse(html) + if(res['code']==200){ + import fsys + var theDir = fsys.createDir(mainForm.backupPath.text+"\"+number, false) + fsys.move(fullpath, theDir) //移动到备份文件库 + mainForm.listbox.add("采集成功!") + }else{ + mainForm.listbox.add("失败:"+res['msg']) + } }else{ - mainForm.listbox.add("失败:"+res['msg']) + mainForm.listbox.add("失败:请求错误") } - http.close(); + } diff --git a/hb_server/apps/em/serializers.py b/hb_server/apps/em/serializers.py index b17e860..a200114 100644 --- a/hb_server/apps/em/serializers.py +++ b/hb_server/apps/em/serializers.py @@ -1,3 +1,4 @@ +from rest_framework import serializers from rest_framework.serializers import ModelSerializer from .models import Equipment,Equipmentrecord @@ -34,4 +35,8 @@ class EquipmentrecordSerializer(ModelSerializer): def setup_eager_loading(queryset): """ Perform necessary eager loading of data. """ queryset = queryset.select_related('equipment') - return queryset \ No newline at end of file + return queryset + +class DaqCreateSerializer(serializers.Serializer): + number = serializers.CharField() + file = serializers.FileField() \ No newline at end of file diff --git a/hb_server/apps/em/urls.py b/hb_server/apps/em/urls.py index a2f58d8..e2f7e91 100644 --- a/hb_server/apps/em/urls.py +++ b/hb_server/apps/em/urls.py @@ -1,6 +1,6 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.em.views import EquipmentViewSet,EquipmentrecordViewSet +from apps.em.views import DaqView, EquipmentViewSet,EquipmentrecordViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter @@ -8,6 +8,7 @@ router = DefaultRouter() router.register('equipment', EquipmentViewSet, basename='equipment') router.register('equipmentrecord', EquipmentrecordViewSet, basename='equipmentrecord') urlpatterns = [ + path('daq/', DaqView.as_view()), path('', include(router.urls)), ] diff --git a/hb_server/apps/em/views.py b/hb_server/apps/em/views.py index 64ad57d..00ae4b9 100644 --- a/hb_server/apps/em/views.py +++ b/hb_server/apps/em/views.py @@ -1,10 +1,12 @@ from django.shortcuts import render +from rest_framework.exceptions import APIException +from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet from rest_framework import serializers, status from rest_framework.response import Response from apps.em.models import Equipment,Equipmentrecord -from apps.em.serializers import EquipmentSerializer,EquipmentrecordSerializer +from apps.em.serializers import DaqCreateSerializer, EquipmentSerializer,EquipmentrecordSerializer from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin @@ -57,4 +59,28 @@ class EquipmentrecordViewSet(CreateUpdateModelAMixin, OptimizationMixin, ModelVi serializer = self.get_serializer(id, data=data) serializer.is_valid(raise_exception=True) serializer.save() - return Response(status=status.HTTP_200_OK) \ No newline at end of file + return Response(status=status.HTTP_200_OK) + +import uuid +import os +from django.conf import settings +from rest_framework.parsers import MultiPartParser +class DaqView(APIView): + """ + 数据采集 + """ + authentication_classes = [] + permission_classes = [] + parser_classes = [MultiPartParser] + + def post(self, request, format=None): + data = request.data + file = data.get('file', None) + equip_num = data.get('equip_num', None) + filename = str(uuid.uuid4()) + filepath = settings.BASE_DIR +'/temp/' + filename + os.path.splitext(file.name)[-1] + with open(filepath, 'wb') as f: + for chunk in file.chunks(): + f.write(chunk) + return Response() + # raise APIException('解析失败') \ No newline at end of file