From 44f87d3951278a0964739664cfdad90c8cdc444c Mon Sep 17 00:00:00 2001 From: Boshuang Zhao Date: Mon, 12 Jan 2026 11:13:01 +0800 Subject: [PATCH] bugfix --- server/__pycache__/main.cpython-310.pyc | Bin 3524 -> 3715 bytes .../endpoints_graph.cpython-310.pyc | Bin 11777 -> 14167 bytes .../endpoints_upload.cpython-310.pyc | Bin 4865 -> 4899 bytes server/app/api/endpoints_graph.py | 2 +- server/app/api/endpoints_upload.py | 2 + .../__pycache__/node_base.cpython-310.pyc | Bin 22065 -> 22169 bytes .../workflow_executor.cpython-310.pyc | Bin 18351 -> 21393 bytes .../trace_loader_nodes.cpython-310.pyc | Bin 6685 -> 6656 bytes server/app/nodes/trace_loader_nodes.py | 6 +- server/file_manager.py | 2 + server/main.py | 2 +- .../__pycache__/mock_schema.cpython-310.pyc | Bin .../__pycache__/mock_schema.cpython-312.pyc | Bin server/{ => tests}/api_spec/mock_schema.py | 0 web/src/core/api/dataAdapter.ts | 71 ++++++++++++------ web/src/core/model/GraphModel.ts | 7 +- web/src/core/model/PortModel.ts | 5 +- web/src/core/model/StudioRuntime.ts | 2 +- web/src/core/services/GraphService.ts | 5 +- 19 files changed, 68 insertions(+), 36 deletions(-) rename server/{ => tests}/api_spec/__pycache__/mock_schema.cpython-310.pyc (100%) rename server/{ => tests}/api_spec/__pycache__/mock_schema.cpython-312.pyc (100%) rename server/{ => tests}/api_spec/mock_schema.py (100%) diff --git a/server/__pycache__/main.cpython-310.pyc b/server/__pycache__/main.cpython-310.pyc index 8722869f2997269897a7a9916d42c37f5d763c2e..7f467cad46b7a8c8169f844b27aa20f6d9e9a1e8 100644 GIT binary patch delta 1070 zcmZ8g&2QsG9G!8T)bU4>Hc8v0O}~=urXRa2K(J^*P=U6b;Ii6XF^9EGe?L+O+p)$@ zyW2|-SxzX2)kqvbLd}tL1wtGV2hJS*XK;iIGv2CHcrd&d5KWzum*j$;ye zefJprKVLZ=`pc`mhv%WiEJ}dFTwsR|b8>D3m9WaHIWGsbaGuTQ+zb}NI;-bg4;ri? zb9&HZO|ZazN!TJTP6%5<4IHRI6>8H0TgIh}7R>u(rpa*u>H|8{SR3ltJ|X-Zl)&1! zJX}E?+t5(+yf>#sN~FGu=CA{cuq5^6Y2iwECIb0BAr{x zc}k+PPVn}N-zZV-a}v>0g2iDUws8q=w+QrG?2q4+harBV z&w5%`#R%e&AEk*q;9h*3)&3L4aWL}WazXo+(pB+e;VE4cR6n&EGS24}EQpDI*gezl zd9lxmpQr*mT2_iVe(67Fdg=`lRy_0ry!=D|reLkAOb(sPXGV)w>Po0c_?tf9Rq=Is z*D5P%Ux6WhEgw)*{8R4JJECX4-Mpvdy9#bp5|Q~)={+U(#n0wvrFBI&glTpAT}dbX~1`tO8LifIFptiJ@Dd~ zUq3ysN`u!FIBMmN_{;k6VN23%F80#n!2g2la>gnN@)P8DWm%KmccgUymcK4;j z)i=cNs5J#Xj{d)|ojm-0ID&D2A5b|~ CYyLO@ delta 874 zcmYk2yKfUg5XN`UXZvz5KjKIHN@6=NCs9CxC@3TlMIr?S4MoHWIGw$tq5Siukv>PdsJ>kV#aVs8Z*-KanepmLAR+6YhyFk_?O!knK z0*UCvASQ|RLslA6gA9qgXejYBL6Qe}C|OyOgzO2TPep8HA>Et;8M5SjQW(Kb^}`r} zI>R=7>V@+wecx}aI;FvkRp{FBGnxFuja1R zJogv+GM|Y2IM}sC_5(MrI?{WL^DH9o<05-5pK3`yX&MuVv+wfW)x+@Hkd_y5fWp-` zC5O#~Fm#STc#|3|qAqJuVbug8?5?_l74}+P!prP~x}IJY_KLt*C-zg_jocCDJloJ7 zMM^?Wvv*o`sm$d_cWC3#^`YS(Qy428Z}C-|!Q1SYwz0RwOKQ?cX*nCo%Hrv^_@Q$XXW&9Sb2e?H6QDB5xSL(i>KnMYQv3-ko&n$vOZ zZU-7P%zo~9EA?RrxhMrrbCF`atZO^)S)m^ zC>*$5AE>1qwQV?owoikpY>Q&Ww%bk%Z2RA6Z;7tA1#So|iz^{|+@|>;Gd3ELQMOt~ gNORB^fmoqFY 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 YQg_^EHpZKSSE~$PO?AP3zMe||22oZJrT_o{ delta 1246 zcmZWo&2Jk;6yG=d;q`jgvE8bwN@|jZxOM3VZJa)PHektdA*9`DyNk@-LxH3lHrffbrSuw~QpP3|{^+ z1_OWGq(J>SYCa(Mpl9?A)>G+WG`$KEY}$RBSNen&>DYaPmL3pVen>tv>J=f)d*T!8 z+wlq28ml6_s^C|n4idg#Q%Fn+(|!+T#T9!F4v6pUQ{ss|Wotk2)V>KP#JkS%=AJA1 zPb-jKJI;7(HEu^)S=rg!3dmQkW0@XU#4~+xNf9iQfDea=1r`t}!a*p3_qVmR~G-fh?C(NQ&H{^F4g%>ooE(ZC-<0HZpHoEOJq*|JJ@n?P(7DdT>4)ek;)E4Sk z#5sfXtD^6C^@5PV73@mRy3En60jwqJi8k@tYxsJNqa4ljd#r4wkYcIEl z`#OnqSd@e+@fBpQil0j7wsh%Op>(pl8$50+rw(UPB%O_<9Vef%B0A%^jLe2~x}l24 z*-f>lCgU2qTu0Dq>HD~W<^sYc1&v%1^>8X0{)!xbK<$#3F*xdlz} zSDC_Xu~?aahFGuE=5Jw4t@A~-l2$j(I9o(=31L~2G+yDXiT1vvdNnQnsLV{Bc8CY+ Zo7*Akiz0;VI;Owl&WwY5NWBvW;a}O08ub7G diff --git a/server/app/api/endpoints_graph.py b/server/app/api/endpoints_graph.py index 9533388..42a183e 100644 --- a/server/app/api/endpoints_graph.py +++ b/server/app/api/endpoints_graph.py @@ -313,7 +313,7 @@ async def ws_execute_graph(websocket: WebSocket): "source_port": s_handle, "target": edge.get("target"), "target_port": t_handle, - "dimension_mode": edge.get("dimension_mode"), + "dimension_mode": DimensionMode(edge.get("dimension_mode")), }) settings = init_msg.get("settings") or {} diff --git a/server/app/api/endpoints_upload.py b/server/app/api/endpoints_upload.py index d76e988..e1440f7 100644 --- a/server/app/api/endpoints_upload.py +++ b/server/app/api/endpoints_upload.py @@ -40,6 +40,8 @@ async def list_files( try: for item in target_path.iterdir(): # 统一使用正斜杠格式 + if item.name.startswith("__"): + continue # 跳过隐藏文件 relative_path = str(item.relative_to(CLOUD_ROOT)).replace('\\', '/') items.append({ "name": item.name, diff --git a/server/app/core/__pycache__/node_base.cpython-310.pyc b/server/app/core/__pycache__/node_base.cpython-310.pyc index c4148cc599d110fb5505c10ea0e04a51786f7823..5a00d917e321b245dc943f846637cf0d11efe9e5 100644 GIT binary patch delta 4421 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 aMK%0b>)Or58;aKyhkTXA4aN2JsrfGua8khl diff --git a/server/app/core/__pycache__/workflow_executor.cpython-310.pyc b/server/app/core/__pycache__/workflow_executor.cpython-310.pyc index 4d292be2179c083a8596e9c8ed5edde9eeb55ff6..64eea5d5f46b6e82d771627a902ce6a8b39fe437 100644 GIT binary patch delta 4285 zcmbVPeQ;D)6~FiHdvD*q>_^CVfR<$W%F>X6O$lTI+9pJtQJfmv*q!RSAUqYyYe8oQPIGv!0BSWZF${@ui0USkf#xlZG$GSSA(|mx=lt29FACks%-`jjs zXuC7-y!*~M_jk|vopbNLclsFq)=BJ*dprt)-%N9+CYWj%A%{Oq)Mu@7*S{D?p784+$>Qa&E78tJ#>*OP+66m1)4*1_X|O< zrO8vBpvk8Npz+Z{HJcWxPE}ABH4{K92DBWw%QL!WnJ%VFz&kgC_~f*^?Yxr!;8OYk zxa83X>9YMOm_M}?0A)i+CA1W*1st}SP(NJ`Pla>^T?xKLG^+sx%FZrZGcIMHB5X4- z!RkP4um9pHvta!IPMeq3zi2cGoTJRo2X}te5`e9>v4jNT-sTif4T9z*9PAV58kS-upIpRpkn!C^4k90ZY z>A@Xe@5qL5yxgy!dC{yvQU?!{PGlWm?B-aLM+y$8bsZ8xUiHQ&5177mcYG;db$bR3#hkOn9kW}duH$@ zn%zq>HUnjr0=hzlbWsKp^)2m3Q_~yK(~w8X^}MSQf{5nuTy~Kj%s&5N!qi2YQ-x9@ zASfLxftv?xZcF#a}po;E>MSO{g2(PE3o1{Fthh`-$n^vNG zx^YSY8r>Nh3o%p`>I(2rqZn>O3;BRqfY^f*t0Slz)4X0G<<%7n)4;4!S9CAUpGBy5 zDsx(p;X}0Bh!##02TL}>q7Bn`o1r!cU>-|G)lEdgZP>8FLzEnyA4AL}7O2|) z25DcHVZ*q8+mOVk7O+9s=RO`AZK!R|jx#=J%kkE-I-Im$;Rgkr6OZv`>>=#%oGokZ zZP0$lZq*p3S+vOB=`)9zy$W~@%O(YQQgrH zZ`!45C1XbiZgqCOV|4CQl#>*!v}8g}o294KQ7 zi`zpMpi1uxX*u&1BXl0#9Jr?V?nH~K-3!pj1UU<_oadz_Ay|KFvZ+aJZH0Jfl7)F@ z{_5w-{qdxhNNV7)x1ypV^#KtiSbQh5C*Ok~0|=T4vwBy#P1i!ArV>*bi?jO@v>O%< z?^ONOtr{y+1Lgkd{Nf3oMz|#twZTh2yQVY2+`FzNOijd@Hd9UZ2D~_=MXQ9ttXV}5 zIMSjOeOj`KNDI6*7`%(2py8ffcoqO1Tf;>;h*OSvitRzK#-^ROFdV;OuE?1eG+BZSWtuy9A7AZ`h?Fi)ID5WU3qm9gL; zV0B}~z&U(5EOdH7l1Y1cFP82o5HH5^Odl7B3qOpJVLBgAlMv>i5x6U6ih(C?{zF|jI&+ME%COk)+rrl z6;lO~?24Ry;uG5lVZSm@R+ftFw@@?lMrA&}X#S_Ns)SwR)#M#9udZwubbexf;nAeQ zH{&niYJCbs7yPgB&xU>sZ{c_wdWNJNDFJlY{*>UK0c@E@`rz{+D(Ir_(1m`%_H96x zUW{@ric0;CDSdz>KMUZay#wQem&OMUjh*SU|Lkslb6@lLzBl+^UDu`27mnQe?$Bue z_w0YP(TlH)A3Z&Kdidryep=GlP%?Vp{MbvcjSjtj^V0X<>D;$H;7t2MP4Si%wMm24 z=Vv>+3ag}@;nwz8QzV{tY4MQuHRxNKUTSu2DilN9VD8vZUBRw{=X_E)d-ePyiXSqh zGtcRUb}Pa~*zB*%GjDFlFSlm>iBC;~nDZ6p1qG+l0axqWAk2rVHe=b0R6Uxz1-?L( zVtCJnFDy}a)}TEB^GsE-Yh?tb+`5ZJ&9|x^ay_HF;p0zCHk!_j>q>!>(VoL&KRz*j z@W5E_tK;7u7#Tb|O&<_o{(EEG)6T<%3l+edj+xk0mdWvYX`cD&rseo;^V+5*S+l}6 z{|i3sGLLUX^_Jqlz<}|c&i)AENsh)3a=~S$ssniK4C2|}ReuuWE2ghTH9Kp{%yV#! z)*O^I!wzc%}dU%$RfV1TXJ)|se5>ALoID{t2BYdn( zA|oe{tRRHEPaLpKeSD-i$b=-2JBq0M&tGN+>bphu2f#7U)nCSyX2+)=5s=~j%Krf) C6oj<^ delta 1239 zcmYjPZA@EL7(VCp-rEn`!b%5a$m|$Gi%Vh5O*8pOX(44J6zO72<5HWR+XYA3c?yY} zmjDB%HB;ga`{SGe6WwBr%+xG=$#7!!)A-Azn)rtnh)eckiGSv(?*T+la-RF%=XvtJ z=RN2B_!gd>#MY$6VnVRCwxWF%uYGHM?6Ns9LMjSlio%5Au#Q&q5_dg*p8MRMVOpe0 z)Sw#T5-q0t#-*@jo3W{SU`nVR7%Sbc7SU2wuS#lhoRlM4rYh<__!|D>;s)xV<>0pM zX54e{c+U~YcYs!aql7+7E5}jT4$gXsLMcd86j$g$`W(pnMcO!_PI?IbN@*264CXTW zObEGaGVOKiO0k=;X6TXm0lGWRxOvmj+c?Z~N3UgWw*-j8tz&MX*9kbXYqGI#_}VKz zyu>};mukXB^&K@9=}W|u>|J52*@IdUEdWenKH(i4mLdERb}9fciZwKiG(3Yl5k&#? z1{u-~Nx)$ZYh;ED$(qC};h$)-rqiSu-HtDWGL~WBMCW4)odC6qpgfTX*;RUS`t7+_|ILAie<==f!9r$ zAs{1m#f&9l$5wo)hDX~E@L`|D^Aku+9G|TM#3X=!mlXm9_89C`7GMZTSu?Wp{7wH0#)%c9smDCd-0XaQc5-d*s~sty zzO^xPb>oA}>zC*EY%hA8`Kh~`H?HKaP55{*{py;fUI<0y_j-a*$Kh??+W?Dc9)Ws zXmlXT%R5>s9teGVV19sTMWh$=Mn_0iPDM655# PulKIvMjj3wBj(^g3#@AI diff --git a/server/app/nodes/__pycache__/trace_loader_nodes.cpython-310.pyc b/server/app/nodes/__pycache__/trace_loader_nodes.cpython-310.pyc index 953cd9f6f38523f652891e9107c27c0dadda5801..dfbfc94f8a93cb5b01e42db6ff37172c2edb82cd 100644 GIT binary patch delta 1293 zcmZ8h&5ImW5P#KQ(_e2sdU|HMXLk0>jk;<)NJI?cC73`qh!{w)iD0xA*~!di>1haV zUOTeA*JTq1M97YIgC|eQAb1fJyy?Yj$laSr{({u&8A0r(>;0-;{i^F#Rrl<|7Z>4rA;65Q8lWLYEf-ekLsn(7(P4=ua1H!DAmd^9Cf4aGDI)xp^4Tpi&l2KR~Xvp z95Zxwy-dv@>X$YbIobHqw)(^0I|_vJi|Usu98Lc;ewy5}SW?Yv!YTk*!bK$m^o03{ zVRNRUFDybWp_aP-shTiGmT{s0~3UL|(?_V9OSUjIblD}1;^Fts@Z#eo>XwHeA7DZv>&mVmcbDuPVUOQQd`)RnMIj3&Xlw&s@K`} z#(dwr0&sc$qjjnnZ&EwPA5E{i=QJB^V}9S=0N9+*_)~Qf(4K7GCF%2P!8VSW8_%FIypMRig(DF!sSN6#_v-R8nOs8@}?K)f{Kuv1&cpi;MCnW zg^ga135Oo7$7F#^?g4R|!u=0dUvlp!6J3y!@_kL%LMIXzd|(Z1^yzM$$PQ8}RNJ-; zfF0_3Aov1NzpIC5i96sJ=2Z6rN|rAS>|zgBPAX|l)CM)|Q;&beRf&nYMm??*uE#%% z`UKY{l)1gZ(t6Smb$LGQrwzf&?4O7RZrow<6Kafyn{p7zvPs_m^BDiWWc)?veNHC1 ztW`7j1*bvr7OfR(z|yAh=wLjX0B+IL_(@B68Av&3)7lYDJeMi>{F$1zMCAd*uO8YI zJ}BsGrMYk63vaQTY(Lak5&I3!^zz$ssN_^UXQSN_0e}T09d3#@9toPs^6Mote zotx}BBd&XK&?WjMps-Zx9&QVRO7zlLz{xjpxZCM zJ5Btj0P~Mq*MJA{4I1b86)Db7e`&u5kEe~!JI*(9$iF6G+Vf93mjO~8}$U!`buX{!irTOFJnkiJ-cCBalla_Ey1bhNJV-(w!li1H#vn>!9xsTO z_!8=995deAi?vt4}~W?vYeN!p8~%kcg2%l0{22NNVo1MP29nZ0MP1FX+JaURK| zm|`k5U#(()l1NBEHek6dM|8F@)3+#?=%!l9 zhF7TYwlMFr2}RQes!(Y~FIjqRZs*Q{E-dWyn6T-u_82wKsdF>R^@a1FT&)<*lSh=S z(f00vA}pa%5_Pk0^i7hE#5<{Ev#LX2SP@`EQpdubTO@Mx@HDgg4lYey(JU*$=@AX= z;WDnAH1d{c^_vJJ?2n`y*_63Px_TpWTIu(~!!wmto$UpddzmM^sy>9gE!_I_4@Dc- zZ?Nh=+`LDBz<82-G-_?_x~tUBbPSDmRZT)NGjxwJxwSU&PahbnWava@uD zx>;9r3aG|@KyxU3JXc6~{#4Ebq2Gb@!l6m@QAw{eRT$voFR`oaAXZow-+>RF1D1!t z4sGHL3!wEUs`Yp2^N@!hh6n0=z74mT=;o1#wyv@rM#*-6iPE=$XsOjb+!PIJ(UTK; zU5{WvzPBJ>)JuoiJ=BCde%6nhL|&0@KJ{h_bd$&L_>X39bYF*doL(V6eYzT+sfOe6 zgWzr8<3EB+&I1C5QyO$rhuJIPYXF~)KaMW=t0@xtn|ABw;95FNFO$Q^zeHbC-cigq cR>@bGuGkQP4mS937HmTYU6zbCNP__W0q<@^F#rGn diff --git a/server/app/nodes/trace_loader_nodes.py b/server/app/nodes/trace_loader_nodes.py index cdee411..a82fea8 100644 --- a/server/app/nodes/trace_loader_nodes.py +++ b/server/app/nodes/trace_loader_nodes.py @@ -65,9 +65,7 @@ class TraceLoader_Metadata(TraceNode): print("TraceLoader_Metadata: process called with utrace_file =", utrace_file, ", tokens =", tokens) if not utrace_file: - time.sleep(3.5) - return {} - #raise ValueError("必须指定 utrace_file 参数") + raise ValueError("必须指定 utrace_file 参数") # 加载系统配置 config = load_system_config() @@ -91,7 +89,7 @@ class TraceLoader_Metadata(TraceNode): # 确保输出目录存在 csv_full_path.parent.mkdir(parents=True, exist_ok=True) - if csv_full_path.exists(): + if csv_full_path.exists() and False: df = pl.read_csv(csv_full_path) return { "metadata": df, diff --git a/server/file_manager.py b/server/file_manager.py index aa8cec9..5f4e232 100644 --- a/server/file_manager.py +++ b/server/file_manager.py @@ -132,6 +132,8 @@ async def list_files( # 获取所有文件和文件夹 items: List[FileInfo] = [] for item in sorted(target_path.iterdir(), key=lambda x: (not x.is_dir(), x.name.lower())): + if item.name.startswith("__"): + continue # 跳过隐藏文件 try: items.append(get_file_info(item)) except Exception as e: diff --git a/server/main.py b/server/main.py index 12d330c..df1301f 100644 --- a/server/main.py +++ b/server/main.py @@ -9,7 +9,7 @@ import yaml from pathlib import Path from server.app.api import endpoints_graph, endpoints_upload -from server.api_spec import mock_schema +from server.tests.api_spec import mock_schema from server.app.core.user_manager import init_base_structure from server.app.core.node_loader import reload_custom_nodes from server.app.core.cache_manager import CacheManager diff --git a/server/api_spec/__pycache__/mock_schema.cpython-310.pyc b/server/tests/api_spec/__pycache__/mock_schema.cpython-310.pyc similarity index 100% rename from server/api_spec/__pycache__/mock_schema.cpython-310.pyc rename to server/tests/api_spec/__pycache__/mock_schema.cpython-310.pyc diff --git a/server/api_spec/__pycache__/mock_schema.cpython-312.pyc b/server/tests/api_spec/__pycache__/mock_schema.cpython-312.pyc similarity index 100% rename from server/api_spec/__pycache__/mock_schema.cpython-312.pyc rename to server/tests/api_spec/__pycache__/mock_schema.cpython-312.pyc diff --git a/server/api_spec/mock_schema.py b/server/tests/api_spec/mock_schema.py similarity index 100% rename from server/api_spec/mock_schema.py rename to server/tests/api_spec/mock_schema.py diff --git a/web/src/core/api/dataAdapter.ts b/web/src/core/api/dataAdapter.ts index cc98f4f..1ad7451 100644 --- a/web/src/core/api/dataAdapter.ts +++ b/web/src/core/api/dataAdapter.ts @@ -6,6 +6,8 @@ /** * 将旧版 nodes/edges 转换为后端执行器期望的格式 */ +import { PortModel } from '../model/PortModel' + export function toExecutorPayload(data: { nodes: any[] edges: any[] @@ -62,14 +64,52 @@ export function toExecutorPayload(data: { } }) - // 转换边 - const edgesOut = edges.map((e: any) => ({ - source: e.source, - source_port: e.source_port || e.sourceHandle?.replace(/^output-/, '') || 'output', - target: e.target, - target_port: e.target_port || e.targetHandle?.replace(/^input-/, '') || 'input', - dimension_mode: e.dimension_mode || 'none' - })) + // Helper: get port type from node meta + const findPortType = (node: any, portName: string, portSide: 'outputs' | 'inputs') => { + const meta = node?.meta || node?.data?.meta || {} + const ports = meta[portSide] || [] + if (!ports || !Array.isArray(ports)) return undefined + const p = ports.find((x: PortModel) => x && x.name === portName) + return PortModel.getTypeInfo(p.type || '') + } + + // 转换边并重新计算 dimension_mode + const edgesOut = edges.map((e: any) => { + const source = e.source + const target = e.target + const source_port = e.source_port + const target_port = e.target_port + + const srcNode = nodes.find((n: any) => n.id === source) || {} + const tgtNode = nodes.find((n: any) => n.id === target) || {} + + const srcInfo = findPortType(srcNode, source_port, 'outputs') + const tgtInfo = findPortType(tgtNode, target_port, 'inputs') + + const upDimension = srcNode.upDimension + const srcDim = (srcInfo.dim || 0) + (upDimension || 0) + const tgtDim = tgtInfo.dim || 0 + + // default to provided or 'none' + let dimension_mode = e.dimension_mode || 'none' + + // If multiple edges into same port, mark as 'up' (collapse/pack) + if (srcDim < tgtDim) { + dimension_mode = 'up' + }else if (srcDim > tgtDim) { + dimension_mode = 'down' + } else { + dimension_mode = 'none' + } + + return { + source, + source_port, + target, + target_port, + dimension_mode + } + }) const payload: any = { nodes: nodesOut, @@ -138,18 +178,3 @@ function normalizeOutputs(raw: any): Array { return [] } -/** - * 获取类型信息 - */ -export function getTypeInfo(type: string = 'any') { - const typeMap: Record = { - 'any': { dim: 1, color: '#8b5cf6' }, - 'number': { dim: 1, color: '#3b82f6' }, - 'string': { dim: 1, color: '#10b981' }, - 'array': { dim: 2, color: '#f59e0b' }, - 'dataframe': { dim: 2, color: '#f59e0b' }, - 'image': { dim: 2, color: '#ec4899' }, - 'tensor': { dim: 3, color: '#ef4444' }, - } - return typeMap[type] || { dim: 1, color: '#6b7280' } -} diff --git a/web/src/core/model/GraphModel.ts b/web/src/core/model/GraphModel.ts index 26c7d9c..13495b9 100644 --- a/web/src/core/model/GraphModel.ts +++ b/web/src/core/model/GraphModel.ts @@ -1,4 +1,5 @@ import NodeModel from './NodeModel' +import { PortModel } from '../model/PortModel' // 类型颜色映射 const TYPE_COLORS: Record = { DataTable: '#3b82f6', // 蓝色 @@ -80,9 +81,9 @@ export class GraphModel { if(!srcNode) continue const srcOutput = srcNode.outputs.find((o:any) => o.name === (e.source_port || 'output')) const tgtInput = node.inputs.find((i:any) => i.name === (e.target_port || 'input')) - const srcDimInfo = srcOutput?.getTypeInfo ? srcOutput.getTypeInfo() : { type: '', dim: 0 } - const tgtDimInfo = tgtInput?.getTypeInfo ? tgtInput.getTypeInfo() : { type: '', dim: 0 } - const srcDim = srcDimInfo.dim || 0 + const srcDimInfo = PortModel.getTypeInfo(srcOutput?.type || '') + const tgtDimInfo = PortModel.getTypeInfo(tgtInput?.type || '') + const srcDim = srcDimInfo.dim || 0 + (srcNode.upDimension || 0) const tgtDim = tgtDimInfo.dim || 0 const diff = srcDim - tgtDim if(diff > newUp) newUp = diff diff --git a/web/src/core/model/PortModel.ts b/web/src/core/model/PortModel.ts index c499981..75045e9 100644 --- a/web/src/core/model/PortModel.ts +++ b/web/src/core/model/PortModel.ts @@ -8,7 +8,10 @@ export class PortModel { } getTypeInfo(): {type: string; dim: number } { - const type = this.type + const result = PortModel.getTypeInfo(this.type || '') + return result + } + static getTypeInfo(type: string): {type: string; dim: number } { if (!type) return {type: '', dim: 0 } const str = String(type).trim() if (typeDimMap.has(str)) return typeDimMap.get(str)! diff --git a/web/src/core/model/StudioRuntime.ts b/web/src/core/model/StudioRuntime.ts index 8748ccb..aaf2995 100644 --- a/web/src/core/model/StudioRuntime.ts +++ b/web/src/core/model/StudioRuntime.ts @@ -119,7 +119,7 @@ export class StudioRuntime { } public exportWorkflow(){ if(!this.graph) return { nodes: [], edges: [] } - const nodes = Array.from(this.graph.nodes.values()).map(n => ({ id: n.id, schemaName: n.schemaName, position: n.position, params: n.params, meta: n.meta })) + const nodes = Array.from(this.graph.nodes.values()).map(n => ({ id: n.id, schemaName: n.schemaName, position: n.position, params: n.params, meta: n.meta , upDimension: n.upDimension } )) const edges = Array.from(this.graph.edges.values()).map((e:any) => ({ id: e.id, source: e.source, source_port: e.source_port, target: e.target, target_port: e.target_port, dimension_mode: e.dimension_mode, style: e.style, animated: !!e.animated })) const viewport = this.viewport || null return { nodes, edges, viewport } diff --git a/web/src/core/services/GraphService.ts b/web/src/core/services/GraphService.ts index b441563..f82ea45 100644 --- a/web/src/core/services/GraphService.ts +++ b/web/src/core/services/GraphService.ts @@ -1,5 +1,6 @@ import useRuntimeStore from '../store/runtimeStore' import { runtime } from '../model/StudioRuntime' +import { PortModel } from '../model/PortModel'; const GraphService = { // Graph mutations @@ -16,8 +17,8 @@ const GraphService = { const srcOutput = srcModel.outputs.find((o: any) => o.name === srcPort) const tgtInput = tgtModel.inputs.find((i: any) => i.name === tgtPort) - const srcTypeInfo = srcOutput?.getTypeInfo() || { type: '', dim: 0 } - const tgtTypeInfo = tgtInput?.getTypeInfo() || { type: '', dim: 0 } + const srcTypeInfo = PortModel.getTypeInfo(srcOutput?.type || '') + const tgtTypeInfo = PortModel.getTypeInfo(tgtInput?.type || '') if(srcTypeInfo.type != tgtTypeInfo.type){ console.warn('GraphService.createEdge: type mismatch'); return null } const srcDim = srcTypeInfo.dim + srcModel.upDimension