From 1e6f026be03bfd78023b65e663d99998599baa75 Mon Sep 17 00:00:00 2001 From: huyuyang Date: Wed, 12 Feb 2025 05:35:22 +0000 Subject: [PATCH 01/13] =?UTF-8?q?!1274=20=E4=BF=AE=E5=A4=8Dtree-view?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F=E6=B1=A1=E6=9F=93=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E5=88=86=E6=94=AF=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree-view?= =?UTF-8?q?=E8=BE=B9=E6=A1=86=E6=A0=B7=E5=BC=8F=E6=B1=A1=E6=9F=93=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E7=BB=84=E4=BB=B6treeview=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dtree-view=E6=BB=9A=E5=8A=A8=E6=9D=A1=E5=92=8C=E5=B1=95?= =?UTF-8?q?=E5=BC=80=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtree-view=E6=BB=9A=E5=8A=A8=E6=9D=A1=E5=92=8C?= =?UTF-8?q?=E5=B1=95=E5=BC=80=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9tree-view=E7=BB=84=E4=BB=B6=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1=20*=20fix:=20=E4=BF=AE=E6=94=B9tree-view?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=BB=9A=E5=8A=A8=E6=9D=A1=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E6=94=B9tree-view=E7=BB=84=E4=BB=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E6=8D=AE=E6=BA=90=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91=20*?= =?UTF-8?q?=20fix:=20=E8=BF=98=E5=8E=9F=E6=89=93=E5=8C=85=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E5=A4=8DpageSize=E5=AE=9E=E6=97=B6=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9tree-grid=E5=B8=AE=E5=8A=A9?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=BB=9A=E5=8A=A8=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E7=BB=93=E6=9D=9F=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E7=BC=96=E8=BE=91=E5=8F=82=E6=95=B0=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=E5=92=8C=E6=BB=9A=E5=8A=A8=E6=9D=A1=E8=B7=9F?= =?UTF-8?q?=E9=9A=8F=E6=B5=8F=E8=A7=88=E5=99=A8=E5=B0=BA=E5=AF=B8=E5=8F=98?= =?UTF-8?q?=E5=8C=96=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96=E5=85=A8?= =?UTF-8?q?=E9=80=89=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=A4=9A?= =?UTF-8?q?=E8=A1=8C=E6=96=87=E6=9C=AC=E6=A1=86;=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=BF=98=E5=8E=9F?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=BB=9A=E5=8A=A8=E8=AE=BE=E7=BD=AE=20*=20fi?= =?UTF-8?q?x:=20input-group=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E8=A1=8C=E6=96=87=E6=9C=AC=E6=A1=86=E7=B1=BB=E5=9E=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81hcm=E8=AF=95=E7=82=B9=20*=20fix:=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E7=BB=84=E4=BB=B6=E5=80=BC=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E5=A4=84=E7=90=86data-grid?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=20*=20fi?= =?UTF-8?q?x:=20=E7=82=B9=E5=87=BB=E5=85=A8=E9=80=89=E4=B8=8D=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=E9=80=89=E4=B8=AD=E8=A1=8C=20*=20fix:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=A4=9A=E4=BD=99=E4=BB=A3=E7=A0=81=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=95=B0=E6=8D=AE=E5=88=86=E7=BB=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E8=A7=A3=E5=86=B3=E6=A0=91=E8=A1=A8=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=94=B6=E6=8A=98=E6=BB=9A=E5=8A=A8=E6=9D=A1=E6=B6=88?= =?UTF-8?q?=E5=A4=B1=E6=95=B0=E6=8D=AE=E5=9B=9E=E5=BD=92=E5=88=B0=E7=AC=AC?= =?UTF-8?q?=E4=B8=80=E6=9D=A1=20*=20chore:=20=E5=88=A0=E9=99=A4=E5=89=A9?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96dataView=E6=95=B0=E6=8D=AEtop;=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=BB=9A=E5=8A=A8=E6=9D=A1=E9=AB=98=E5=BA=A6;?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=BB=9A=E5=8A=A8=E8=8A=82=E6=B5=81;=20*=20f?= =?UTF-8?q?ix:=20=E8=B0=83=E6=95=B4=E7=BA=A7=E8=81=94=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E9=80=89=E4=B8=AD=20*=20fix:=20=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E7=AA=97=E5=8F=A3=E5=8F=98=E5=8C=96=E5=90=8E?= =?UTF-8?q?data-grid=E5=B0=BA=E5=AF=B8=E5=93=8D=E5=BA=94=E5=BC=8F=E5=8F=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E5=88=87=E6=8D=A2listview=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E5=90=8E=E6=B8=85=E7=A9=BA=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E8=A1=8C=20*=20fix:=20=E5=AE=8C=E5=96=84tree?= =?UTF-8?q?-grid=E7=BB=84=E4=BB=B6=E7=BA=A7=E8=81=94=E9=80=89=E6=8B=A9=20*?= =?UTF-8?q?=20fix:=20=E4=BC=98=E5=8C=96=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E9=A6=96=E6=AC=A1=E5=8A=A0=E8=BD=BD=E5=8F=96?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=EF=BC=8CoriginalData=E4=BB=85=E5=9C=A8dataView=20*=20?= =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3=20*=20Merge=20bran?= =?UTF-8?q?ch=20'1.17'=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=EF=BC=8CoriginalData=E4=BB=85=E5=9C=A8dataView=20*=20?= =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=88=86=E9=A1=B5=EF=BC=8Corigin?= =?UTF-8?q?alData=E4=BB=85=E5=9C=A8dataView=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=A1=A8=E6=A0=BC=E7=AD=89=E5=86=B2=E5=87=BB=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E4=BD=8D=E7=BD=AE=E7=AD=89=20*=20fix:=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=B1=8F=E8=94=BD=E8=A1=A8=E6=A0=BC=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E7=89=B9=E6=80=A7;=E4=BF=AE=E5=A4=8D=E6=A0=91=E8=A1=A8?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E5=8F=96=E6=B6=88=E5=8B=BE=E9=80=89?= =?UTF-8?q?=E7=88=B6=E8=8A=82=E7=82=B9=E4=B8=AD=E9=97=B4=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8D=E5=B1=95=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=20*=20re?= =?UTF-8?q?factor:=20=E9=87=8D=E6=9E=84=E8=A1=A8=E6=A0=BC=E5=88=86?= =?UTF-8?q?=E9=A1=B5=20*=20Merge=20branch=20'1.16'=20*=20fix:=20data-grid?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BB=85=E5=8B=BE=E9=80=89=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E9=80=89=E4=B8=AD=E5=BD=93=E5=89=8D=E8=A1=8C=20*=20Me?= =?UTF-8?q?rge=20branch=20'1.16'=20*=20fix:=20=E7=A7=BB=E9=99=A4=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89class=E5=90=8Df-list-item-active=20*=20fix:?= =?UTF-8?q?=20=E8=A1=A8=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A1=A8=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E5=A4=84=E7=90=86tree-grid=E7=BB=84=E4=BB=B6=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4button-edit=E7=82=B9=E5=87=BB=E9=98=BB?= =?UTF-8?q?=E6=AD=A2=E5=86=92=E6=B3=A1=20*=20fix:=20=E4=BF=AE=E6=94=B9size?= =?UTF-8?q?Limits=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=E9=94=99=E8=AF=AF=20?= =?UTF-8?q?*=20fix:=20=E8=BF=98=E5=8E=9F=E5=A4=9A=E9=80=89=E5=92=8C?= =?UTF-8?q?=E8=A1=8C=E7=82=B9=E5=87=BB=E5=88=86=E7=A6=BB;=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=A6=81=E7=94=A8=E5=88=86=E9=A1=B5=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=20*=20fix:=20=E4=BF=AE=E6=94=B9getKey?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E5=8B=BE=E9=80=89=E9=80=89=E4=B8=AD=E8=A1=8C=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F;=E8=B0=83=E6=95=B4data-grid=E7=BB=84=E4=BB=B6demo=20*?= =?UTF-8?q?=20fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20Merge=20br?= =?UTF-8?q?anch=20'1.15'=20*=20fix:=20=E9=AA=8C=E8=AF=81=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'1.15'=20*?= =?UTF-8?q?=20fix:=20=E4=B8=8D=E5=87=BA=E7=8E=B0=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=9D=A1=E4=BC=9A=E6=BB=9A=E5=8A=A8=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?;=E4=BF=AE=E5=A4=8Dtextarea=E5=9C=A8=E8=A1=A8=E6=A0=BC=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E4=B8=AD=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'1.15'=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=A4=9A=E9=80=89=E6=A8=A1=E5=BC=8F=E5=92=8C?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4console.log=20*=20Merge=20branch=20'1.15'=20*?= =?UTF-8?q?=20fix:=20=E5=A4=84=E7=90=86combo-list=E4=BC=A0=E5=85=A5key?= =?UTF-8?q?=E6=98=AF=E5=B8=83=E5=B0=94=E5=92=8C=E6=95=B0=E5=AD=97=E7=9A=84?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=20*=20Merge=20branch=20'1.15'=20*=20fix:=20?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=E7=BB=93=E6=9D=9F=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=89=8D=E5=B8=AE=E5=8A=A9=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?;=E4=BF=AE=E6=94=B9=E8=A1=A8=E6=A0=BCschema=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F=EF=BC=8C=E8=B6=85?= =?UTF-8?q?=E5=87=BA=E5=A4=96=E9=83=A8=E5=85=83=E7=B4=A0=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E6=8A=98=E8=A1=8C=E5=B1=95=E7=A4=BA=E5=88=86=E9=A1=B5=20*=20fi?= =?UTF-8?q?x:=20=E7=A7=BB=E9=99=A4=E8=A1=A8=E6=A0=BC=E5=85=A8=E9=80=89?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E9=9A=90=E8=97=8F=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=92=8C=E5=8F=8C=E5=90=91=E7=BB=91=E5=AE=9A;?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A1=A8=E6=A0=BC=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E5=88=86=E9=A1=B5=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E4=BF=AE=E6=94=B9changed=E5=90=8D=E7=A7=B0=20*=20f?= =?UTF-8?q?ix:=20=E4=BF=AE=E6=94=B9=E8=B0=83=E7=94=A8useEdit=20*=20fix:=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9B=B4=E6=96=B0=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E5=92=8C=E8=A1=8C=E6=95=B0=E6=8D=AE=E7=BC=96=E8=BE=91=E6=97=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BB=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E4=B8=94=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=B8=8D=E8=A7=A6=E5=8F=91=E9=97=AE=E9=A2=98;=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=A1=A8=E6=A0=BC=E4=B8=8D=E8=83=BD=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=88=87=E6=8D=A2=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A7=A3=E5=86=B3=E5=88=86=E9=A1=B5=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E9=A1=B5=E7=A0=81=E5=92=8C=E6=AF=8F=E9=A1=B5?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E7=9A=84=E5=93=8D=E5=BA=94=E5=BC=8F=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'1.?= =?UTF-8?q?13'=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=8D=95=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E5=92=8C=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84?= =?UTF-8?q?=20*=20fix:=20=E9=87=8D=E6=9E=84=E5=8D=95=E9=80=89=E6=A1=86?= =?UTF-8?q?=E5=92=8C=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=E4=BB=B6=20*=20ch?= =?UTF-8?q?ore:=20merge=20remote=20branch=20and=20resolve=20conflict=20*?= =?UTF-8?q?=20fix:=20=E5=A4=84=E7=90=86listview=E9=80=89=E4=B8=AD=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E9=AB=98=E4=BA=AE=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=A4=84=E7=90=86listview=E9=80=89=E4=B8=AD=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E9=AB=98=E4=BA=AE=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=A4=8D=E9=80=89=E6=A1=86=E5=92=8C=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E7=BB=84=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E7=A6=81=E6=AD=A2=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0lock=20*?= =?UTF-8?q?=20feature:=20=E8=A1=A8=E6=A0=BC=E6=94=AF=E6=8C=81=E7=A6=81?= =?UTF-8?q?=E6=AD=A2=E6=93=8D=E4=BD=9C=E5=88=86=E9=A1=B5=E7=89=B9=E6=80=A7?= =?UTF-8?q?=20*=20Merge=20branch=20'1.10'=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=94=AF=E6=8C=81=E5=88=86=E9=A1=B5=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE;=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1=E6=95=B0=E5=9B=BA=E5=AE=9A=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.10'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8bug=20*=20Merge=20branch=20'1.10'=20?= =?UTF-8?q?*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=20pageList=E4=B8=8D?= =?UTF-8?q?=E5=8F=98=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E8=BF=9C=E7=AB=AF=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E9=80=89=E4=B8=AD=E8=A1=8Cemit?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=88=A4=E6=96=AD=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dtree-grid=E6=BB=9A=E5=8A=A8=E5=90=8E=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E6=94=B6=E6=8A=98=E6=8C=89=E9=92=AE=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E4=BF=AE=E5=A4=8D=E6=94=B6=E6=8A=98=E5=90=8E?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=9D=A1=E9=AB=98=E5=BA=A6=E4=B8=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4data-grid=E6=9A=82=E6=97=A0=E6=95=B0=E6=8D=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F;=E5=A4=84=E7=90=86=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=A0=91=E8=A1=A8=E8=AE=BE=E7=BD=AE=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E7=89=B9=E6=80=A7=EF=BC=8C=E6=BB=9A=E5=8A=A8=E5=90=8E=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E6=94=B6=E6=8A=98=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E7=BB=93=E6=9D=9F=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E7=BC=96=E8=BE=91=E5=8F=82=E6=95=B0=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=B5=8B=E5=80=BC=E4=B8=8D=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E5=88=86=E6=94=AF=20*=20chore:=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E6=9C=AC=E5=9C=B0=E5=88=86=E9=A1=B5=E5=88=86=E6=94=AF?= =?UTF-8?q?=20*=20fix:=20=E5=90=88=E5=B9=B6=E5=88=86=E9=A1=B5=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E5=8F=98=E6=9B=B4=E5=88=86=E6=94=AF=20*=20refactor:?= =?UTF-8?q?=20=E8=B0=83=E6=95=B4=E8=A1=A8=E6=A0=BC=E6=A0=91=E8=A1=A8?= =?UTF-8?q?=E7=AD=89=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.7'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=9B=B4=E6=94=B9=E5=80=BC=E5=90=8E?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.7'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=B8=85=E7=A9=BA=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'1.7'=20*=20?= =?UTF-8?q?fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=BB=84=E4=BB=B6data-grid?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=E5=8F=98=E6=9B=B4=E5=88=97=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=A7=A3=E6=9E=90=E5=85=B3=E8=81=94=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtree=E6=95=B0=E6=8D=AE=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=A2=AB=E8=A6=86=E7=9B=96=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E6=9B=B4=E6=94=B9=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1=E9=AA=8C=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20Merge=20branch=20'1.6'=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E8=A1=8C=E5=A2=9E=E5=8A=A0=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=97=E6=95=B0=E6=8D=AE=E6=96=B9=E6=B3=95=20*=20fix:=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1=E9=AA=8C=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E5=87=A0=E4=B8=AA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=20*=20docs:=20=E5=AE=8C=E5=96=84response-toolbar=E6=96=87?= =?UTF-8?q?=E6=A1=A3=20*=20build:=20=E7=BA=A0=E6=AD=A3=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BAindex?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BAindex?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20fix:=20=E5=AE=8C=E5=96=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=20*=20fix:=20=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=20*=20Merge=20branch=20'1.3'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E6=9C=9F=E5=A4=9A=E4=BD=99=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E9=97=AE=E9=A2=98=20*=20fix:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6=E6=8C=89=E9=9C=80=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=20*=20fix:=20tooltip=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8C=89=E9=9C=80=E5=8A=A0=E8=BD=BD=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E7=BC=96=E8=AF=91=E5=90=8E=E6=95=B4=E4=BD=93=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=BD=BF=E7=94=A8tree-shaking=20*=20fix:=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=AE=9E=E7=8E=B0=E5=AE=9E=E4=BD=93=E6=A0=91=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=AD=90=E8=A1=A8=E6=88=96=E8=80=85udt=E7=88=B6?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=B8=8D=E5=85=81=E8=AE=B8=E7=94=9F=E6=95=88?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farr?= =?UTF-8?q?is-vue=20*=20refactor:=20=E9=87=8D=E6=9E=84data-grid=E5=88=86?= =?UTF-8?q?=E9=A1=B5=20*=20Merge=20branch=20'1.2'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=A1=B5=E7=A0=81=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E9=94=99=E4=B9=B1=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E5=8F=8C=E5=87=BB=E5=AE=9E=E4=BD=93=E6=A0=91=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=80=BC=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=A2=9E=E5=8A=A0data-grid?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E7=BC=96=E8=BE=91=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E5=90=88=E5=B9=B6=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E6=9C=80=E6=96=B0=20*=20chore:=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E6=9C=80=E6=96=B0=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6=E6=96=B0=E5=A2=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=90=8Edom=E6=B2=A1=E6=9C=89=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98;=E4=BF=AE=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=B8=80=E8=A1=8C=E6=95=B0=E6=8D=AE=E5=90=8E=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E8=A7=A6=E5=8F=91=E8=A1=8C=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20*=20Merge=20branch=20'12.30'=20*=20feature:=20?= =?UTF-8?q?=E7=A9=BF=E6=A2=AD=E6=A1=86=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E6=A0=91=E7=BB=93=E6=9E=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?;=E4=BF=AE=E5=A4=8Ddata-grid=20tree=E7=AD=89=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E9=80=89=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'12.30'=20*=20Merge=20branch=20'main'?= =?UTF-8?q?=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84=E4=BB=B6=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E7=89=B9=E6=80=A7=20*=20fix:=20=E8=BF=98=E5=8E=9Fdata-area?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E7=BA=A0=E6=AD=A3=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=B8=8D=E6=AD=A3=E7=A1=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E4=B8=BB?= =?UTF-8?q?=E5=88=86=E6=94=AF=E4=BB=A3=E7=A0=81=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E6=A0=91=E5=8F=8C?= =?UTF-8?q?=E5=87=BB=E9=80=89=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98;?= =?UTF-8?q?=E4=BF=AE=E6=94=B9designer=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9data-grid=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E7=BB=84=E4=BB=B6;=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E4=B8=8D=E5=90=88=E7=90=86=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A7=A3=E5=86=B3data-grid=E9=A2=91=E7=B9=81?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=88=97=E5=B0=BA=E5=AF=B8=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3data-grid=E9=A2=91?= =?UTF-8?q?=E7=B9=81=E8=AE=A1=E7=AE=97=E5=88=97=E5=B0=BA=E5=AF=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81@/components=E5=AF=BC=E5=85=A5=E8=B7=AF=E5=BE=84=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farris-v?= =?UTF-8?q?ue=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E5=AD=97=E6=AE=B5=E6=A0=91?= =?UTF-8?q?;=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=B8=B2=E6=9F=93data-grid=20area=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=89=93=E5=8C=85@/componnets=E9=85=8D=E7=BD=AE=20*?= =?UTF-8?q?=20Merge=20branch=20'12.25'=20*=20fix:=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8;=E4=BF=AE=E6=94=B9=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8treeview=E5=AF=BC=E8=88=AA=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9totalItems=E7=B1=BB=E5=9E=8B=20*=20Merge?= =?UTF-8?q?=20branch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=97=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E6=9E=9A=E4=B8=BE=E5=B1=9E=E6=80=A7=E5=90=8D=20*=20Me?= =?UTF-8?q?rge=20branch=20'12.24'=20*=20fix:=20=E5=A4=84=E7=90=86=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=96=E6=B6=88=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=80=BC=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20?= =?UTF-8?q?*=20fix:=20=E8=A7=A3=E5=86=B3totalData=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E9=94=99=E8=AF=AF=E9=A1=B9?= =?UTF-8?q?;=E8=BF=98=E5=8E=9Fdata-grid=E7=BB=84=E4=BB=B6=E8=B5=8B?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E9=AA=8C=E8=AF=81=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8dom?= =?UTF-8?q?=E5=86=99=E5=80=BC=20*=20refactor:=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E4=BA=8B=E4=BB=B6=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=20*=20build:=20=E4=BF=AE=E5=A4=8Dnp?= =?UTF-8?q?m=E5=8C=85=E5=BC=95=E5=85=A5=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E8=B0=83=E6=95=B4bindingselector=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'designer-param'=20*?= =?UTF-8?q?=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=90=8E=E6=96=B9=E6=B3=95=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20*=20Merge=20branch=20'designer-param'=20*?= =?UTF-8?q?=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=90=8E=E4=B8=8B=E6=8B=89=E6=A0=91=E8=AE=BE=E7=BD=AE=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20fix:=20=E5=A4=84=E7=90=86const=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8F=98=E9=87=8F=E5=8F=8C=E5=90=91=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=90=88=E5=B9=B6=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E4=BB=A3=E7=A0=81=20*=20docs:=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=96=87=E6=A1=A3=20*=20fix:=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E5=8A=A8=E4=BD=9C=E8=AE=BE=E7=BD=AE;=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E9=80=9A=E7=94=A8=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=20*=20fix:=20=E8=8E=B7=E5=8F=96=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20fix:=20=E8=B0=83=E6=95=B4=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20*=20Merge=20branch=20'designer-param'=20*=20Merge=20branch?= =?UTF-8?q?=20'12.17'=20*=20fix:=20=E5=AE=9E=E7=8E=B0=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E8=B0=83=E6=95=B4data-grid=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=86=85=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=8C=96=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E4=B8=8D=E5=8F=98=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9data-grid=E5=88=97=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E8=BF=81=E7=A7=BB=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BB=84=E4=BB=B6=E5=92=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E7=BB=84=E4=BB=B6=20*=20Merge=20bra?= =?UTF-8?q?nch=20'12.16'=20into=2012.17=20*=20fix:=20=E8=B0=83=E6=95=B4bin?= =?UTF-8?q?ding-selector=E8=B7=AF=20*=20Merge=20branch=20'main'=20of=20git?= =?UTF-8?q?ee.com:hopefulman/farris-vue=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E6=9B=B4?= =?UTF-8?q?=E6=94=B9data-grid=E7=BB=84=E4=BB=B6=E6=9E=9A=E4=B8=BE=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=20*=20fix:=20=E8=B0=83=E6=95=B4data-grid=20?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=E4=B8=BA=E5=B0=8F?= =?UTF-8?q?=E9=A9=BC=E5=B3=B0=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E8=BF=98=E5=8E=9Fdata-gr?= =?UTF-8?q?id=E7=A9=BA=E6=95=B0=E6=8D=AE=E6=A0=B7=E5=BC=8F=E4=BD=BF?= =?UTF-8?q?=E5=BE=97=E8=A1=A8=E6=A0=BC=E5=B1=95=E7=A4=BA=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=20*=20fix:=20=E6=8B=89=E5=8F=96=E6=9C=80=E6=96=B0=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E4=BB=A3=E7=A0=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=89=93=E5=BC=80=E6=8A=A5=E9=94=99=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=B8=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E9=A1=B9=20*=20fix:=20=E8=B0=83=E6=95=B4import?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'12.12'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6import?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9data-grid=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98;=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6=E6=95=B0=E6=8D=AE=E4=B8=BA?= =?UTF-8?q?=E7=A9=BA=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81change?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6;data-grid=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=97field=E8=AE=BE=E7=BD=AE=E4=B8=BA=E5=85=B3?= =?UTF-8?q?=E8=81=94=E5=AD=97=E6=AE=B5=20*=20fix:=20data-grid=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E7=BA=A7field=E8=B5=8B=E5=80=BC=E5=92=8C?= =?UTF-8?q?=E5=8F=96=E5=80=BC=20*=20chore:=20=E5=90=88=E5=B9=B61209?= =?UTF-8?q?=E5=88=86=E6=94=AF=EF=BC=8C=E5=90=88=E5=B9=B6=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E4=B8=AD=E9=97=B4=E7=8A=B6=E6=80=81=E7=89=B9=E6=80=A7?= =?UTF-8?q?=20*=20docs:=20=E8=B0=83=E6=95=B4data-grid=E6=96=87=E6=A1=A3=20?= =?UTF-8?q?*=20fix:=20=E8=BF=98=E5=8E=9Fdata-grid=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E6=96=87=E6=A1=A3=20*=20fix:=20=E5=AE=8C=E5=96=84data-grid?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E5=92=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=8D=95=E5=85=83=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=89=B9?= =?UTF-8?q?=E6=80=A7;=E4=BF=AE=E6=94=B9listview=E7=A9=BA=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farr?= =?UTF-8?q?is-vue=20*=20fix:=20=E9=AA=8C=E8=AF=81=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20Merge=20branch=20'12.1?= =?UTF-8?q?1'=20*=20fix:=20=E9=AA=8C=E8=AF=81tree-grid=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E8=A1=8C=E7=89=B9=E6=80=A7=20*=20fix:=20=E6=9B=B4=E6=94=B9data?= =?UTF-8?q?-grid=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20fix:?= =?UTF-8?q?=20=E9=AA=8C=E8=AF=81data-grid=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=92=8C=E9=AA=8C=E8=AF=81data-grid=E6=95=B0=E6=8D=AE=E5=88=86?= =?UTF-8?q?=E7=BB=84=E7=89=B9=E6=80=A7=20*=20fix:=20=E8=BF=98=E5=8E=9F?= =?UTF-8?q?=E8=A1=A8=E5=A4=B4=E9=BB=98=E8=AE=A4=E4=BD=8D=E7=BD=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=89=93=E5=8C=85?= =?UTF-8?q?=E4=BA=A7=E7=89=A9=20*=20fix:=20=E5=AE=8C=E5=96=84=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE=E9=87=8F=E5=8F=98?= =?UTF-8?q?=E5=B0=91=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12?= =?UTF-8?q?.08'=20*=20Merge=20branch=20'12.06'=20*=20Merge=20branch=20'mai?= =?UTF-8?q?n'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20tree-gri?= =?UTF-8?q?d=E5=A2=9E=E5=8A=A0=E5=A4=8D=E9=80=89=E6=A1=86=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E7=8A=B6=E6=80=81;=E8=A7=A3=E5=86=B3=E5=8B=BE?= =?UTF-8?q?=E9=80=89tree-grid=E7=BB=84=E4=BB=B6=E5=8D=A1=E6=AD=BB=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=A2=9E=E5=8A=A0class?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0combo-list=E5=AE=9E=E7=8E=B0hover=E9=AB=98?= =?UTF-8?q?=E4=BA=AE=20*=20fix:=20=E7=A7=BB=E9=99=A4combo-list=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E5=B1=9E=E6=80=A7=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4combo-list=E7=BB=84=E4=BB=B6=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E5=B1=9E=E6=80=A7;=E8=BF=98=E5=8E=9Fdata-grid=E7=BB=84?= =?UTF-8?q?=E4=BB=B6mouse=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3lock=E6=96=87=E4=BB=B6=E5=86=B2=E7=AA=81=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96tree-grid=E5=92=8Cdata-grid=E7=A6=81=E7=94=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7;=E4=BF=AE=E5=A4=8D=E4=B8=A4=E4=B8=AA=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E6=97=B6=E4=BB=8D?= =?UTF-8?q?=E7=84=B6=E8=A7=A6=E5=8F=91=E6=BB=9A=E5=8A=A8=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20refactor:=20=E8=A1=A5?= =?UTF-8?q?=E5=85=85data-grid=E5=8D=95=E5=85=83=E6=A0=BC=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=92=8C=E5=8F=96=E6=B6=88=E7=BC=96=E8=BE=91=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E6=9C=AC=E6=98=BE=E7=A4=BA=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=8D=E7=BB=9F=E4=B8=80=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Ddata-grid=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E5=88=97=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12?= =?UTF-8?q?.05'=20*=20fix:=20=E5=A2=9E=E5=8A=A0data-grid=E5=92=8Ctree-grid?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E8=A1=8C=E7=89=B9=E6=80=A7=20*=20fix:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96tags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BA=20*?= =?UTF-8?q?=20fix:=20=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E5=88=86?= =?UTF-8?q?=E6=94=AF=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96tags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BA=20*?= =?UTF-8?q?=20fix:=20=E5=A2=9E=E5=8A=A0data-grid=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E4=BF=A1=E6=81=AF=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=20*=20feature:=20data-grid=E5=A2=9E=E5=8A=A0=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4combo-list=E9=80=89=E4=B8=AD=E9=A1=B9=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E8=89=B2=E7=AD=89=E6=A0=B7=E5=BC=8F=20*=20fix:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84combo-list=E5=A4=9A=E9=80=89=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BAdefau?= =?UTF-8?q?lt=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96combo-list=E4=BD=BF=E7=94=A8=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E5=A4=9A=E9=80=89=E7=89=B9=E6=80=A7=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcombo-list=E6=98=BE=E7=A4=BA=E5=80=BC?= =?UTF-8?q?=E5=92=8C=E5=80=BC=E9=A1=BA=E5=BA=8F=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83=E6=95=B4data?= =?UTF-8?q?-grid=E7=BB=84=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=87=BD?= =?UTF-8?q?=E6=95=B0=20*=20fix:=20=E8=BF=98=E5=8E=9Ftree-grid=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E8=AE=A1=E7=AE=97=E5=B0=BA=E5=AF=B8=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9data-grid=E5=88=86=E9=A1=B5=E6=80=BB=E6=95=B0?= =?UTF-8?q?=E8=B5=8B=E5=80=BC=E6=9C=BA=E5=88=B6=20*=20build:=20=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE;=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=8D=E5=90=88=E8=A7=84=E8=8C=83=E7=9A=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=20*=20build:=20=E6=9B=B4=E6=94=B9=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=8F=92=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fix:=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0data-grid=E9=BB=98=E8=AE=A4=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E5=88=97=20*=20fix:=20=E5=AE=8C=E5=96=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E5=90=88=E5=BC=8F=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E6=80=BB=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=20*=20Merge=20bra?= =?UTF-8?q?nch=20'12.03'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=9A=E8=A1=8C?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=A1=86=E8=BE=B9=E7=BA=BF=E8=BF=87=E7=B2=97?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3dependent-bas?= =?UTF-8?q?e=E6=89=93=E5=8C=85=E6=A0=B7=E5=BC=8F=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12.02'=20*?= =?UTF-8?q?=20config:=20=E4=BF=AE=E6=94=B9=E6=9E=84=E5=BB=BA=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E4=BD=BF=E6=89=93=E5=8C=85=E5=90=8E=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BC=95=E5=85=A5=E8=B7=AF=E5=BE=84=E4=B8=BA=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9=E8=B7=AF=E5=BE=84;=E6=94=AF=E6=8C=81=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E5=85=A5=E5=8F=A3tsx=E6=96=87=E4=BB=B6=20*=20Merge=20?= =?UTF-8?q?branch=20'12.02'=20*=20Merge=20branch=20'main'=20of=20gitee.com?= =?UTF-8?q?:hopefulman/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96tree-grid?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E8=A7=A3=E5=86=B3=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=8E=B7=E5=8F=96=E6=9C=80=E6=96=B0?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20textarea?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E6=B8=85=E7=A9=BA=E5=86=85?= =?UTF-8?q?=E5=AE=B9=20*=20docs:=20=E4=BF=AE=E6=94=B9textarea=E6=96=87?= =?UTF-8?q?=E6=A1=A3;=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E5=88=86?= =?UTF-8?q?=E6=94=AF=20*=20fix:=20textarea=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8F=AA=E8=AF=BB=E3=80=81=E7=A6=81=E7=94=A8=E3=80=81?= =?UTF-8?q?=E8=81=9A=E7=84=A6=E5=92=8C=E5=A4=B1=E5=8E=BB=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20Merge=20branch=20'11.29'=20*=20fix:=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=85=8D=E7=BD=AE=E5=85=BC=E5=AE=B9=E6=97=A7?= =?UTF-8?q?=E7=89=88=E6=9C=ACrollupOption=20*=20Merge=20branch=20'11.29'?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E5=85=A8=E9=80=89?= =?UTF-8?q?=E5=90=8E=E4=BC=9A=E9=80=89=E4=B8=AD=E6=9C=80=E5=90=8E=E4=B8=80?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'11?= =?UTF-8?q?.29'=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree-grid=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E8=A1=8C=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'11.29'=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?tree-grid=E6=9B=B4=E6=8D=A2checkbox=E5=90=8E=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=8D=95=E9=80=89=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=96=87=E6=A1=A3=E6=89=93=E5=8C=85=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20Merge?= =?UTF-8?q?=20branch=20'11.28'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E9=9D=A2=E6=9D=BF=E5=85=A8=E5=B1=80=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E5=92=8C=E5=85=A8=E9=83=A8=E5=B1=95=E5=BC=80=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'11.28'=20*=20fix:=20=E8=B0=83=E6=95=B4tree-grid=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=A4=8D=E9=80=89=E6=A1=86=E5=92=8C=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86=E6=A0=B7=E5=BC=8F=20*=20Merge=20bra?= =?UTF-8?q?nch=20'11.28'=20*=20fix:=20data-grid=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=94=AF=E6=8C=81=E6=97=A5=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E5=88=86=E7=A7=92=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20Merge=20branch=20'11.28'=20*=20f?= =?UTF-8?q?eature:=20combo-list=E6=94=AF=E6=8C=81=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E5=80=BC=E7=AD=9B=E9=80=89=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96tree-grid=E6=80=A7=E8=83=BD=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=BF=98=E5=8E=9F=E5=AE=9A=E4=B9=89cons?= =?UTF-8?q?t=E5=8F=98=E9=87=8F=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=A0=BC=E6=B0=B4=E5=B9=B3=E5=B1=85=E4=B8=AD=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E5=8F=8A=E7=BC=96=E8=AF=91=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=9E=84=E5=BB=BApackage.json=E6=96=87=E4=BB=B6=E5=BC=95?= =?UTF-8?q?=E7=94=A8css=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'11.27'?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6,?= =?UTF-8?q?=E6=A8=AA=E5=90=91=E6=BB=9A=E5=8A=A8=E6=9D=A1=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E4=B8=8D=E5=87=86=E7=A1=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20Merge=20branch=20'11.27'=20*=20config:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9E=84=E5=BB=BA=E5=90=8E=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=96=87=E4=BB=B6css=E5=90=8D=E7=A7=B0=20*=20fix:=20=E9=AA=8C?= =?UTF-8?q?=E8=AF=81data-grid=E6=8B=96=E6=8B=BD=E5=88=97=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui-vue/components/tree-view/src/tree-view.component.tsx | 1 + packages/ui-vue/components/tree-view/src/tree-view.css | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/ui-vue/components/tree-view/src/tree-view.component.tsx b/packages/ui-vue/components/tree-view/src/tree-view.component.tsx index 4e88db14163..ff4f621db20 100644 --- a/packages/ui-vue/components/tree-view/src/tree-view.component.tsx +++ b/packages/ui-vue/components/tree-view/src/tree-view.component.tsx @@ -35,6 +35,7 @@ export default defineComponent({ const classObject = { // 'fv-tree': true 'fv-grid': true, + 'fv-tree-view': true } as Record; return classObject; }); diff --git a/packages/ui-vue/components/tree-view/src/tree-view.css b/packages/ui-vue/components/tree-view/src/tree-view.css index ae2ed6c113e..c39325c2773 100644 --- a/packages/ui-vue/components/tree-view/src/tree-view.css +++ b/packages/ui-vue/components/tree-view/src/tree-view.css @@ -1,3 +1,3 @@ -.fv-grid .fv-grid-hierarchy-cell { - border:none; +.fv-tree-view .fv-grid-hierarchy-cell { + border: none; } \ No newline at end of file -- Gitee From de39f39c179285fe39dee8b39162beee47b1dda5 Mon Sep 17 00:00:00 2001 From: wang-xh Date: Wed, 12 Feb 2025 05:49:06 +0000 Subject: [PATCH 02/13] =?UTF-8?q?!1273=20fix:=20=E9=80=82=E9=85=8DTreeView?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84=E6=A0=B7=E5=BC=8F=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=20*=20fix:=20=E9=80=82=E9=85=8DTreeView=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=A0=B7=E5=BC=8F=E5=8F=98=E6=9B=B4=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20?= =?UTF-8?q?https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=90=8E=EF=BC=8C=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E9=A1=B5=E7=AD=BE=E5=86=85=E9=83=A8component?= =?UTF-8?q?=E5=92=8Cviewmodel=E5=88=A0=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merge=20branc?= =?UTF-8?q?h=20'main'=20of=20https://gitee.com/wang-xh-nancy/farris-vue=20?= =?UTF-8?q?*=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=A1=B5=EF=BC=9A=E5=AF=B9=E4=BA=8E=E4=B8=8D=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=EF=BC=8C=E5=81=9A?= =?UTF-8?q?=E7=BD=AE=E7=81=B0=E5=A4=84=E7=90=86=E3=80=82=20*=20fix:=20?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E7=9A=84?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E8=8C=83=E5=9B=B4=20*=20fix:=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=8D=95=E9=80=89=E7=BB=84=E5=92=8C=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E7=BB=84=E7=9A=84=E6=A8=AA=E5=90=91=E6=8E=92=E5=88=97=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E5=B9=B6=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?demo=E6=A0=B7=E4=BE=8B=E7=9A=84=E5=86=99=E6=B3=95=E3=80=82=20*?= =?UTF-8?q?=20fix:=20=E6=A8=A1=E5=9E=8B=E9=A1=B5=E9=9D=A2=E5=9C=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B9=E6=B3=95=E5=92=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=90=8E=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=B8=8A?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E7=9A=84=E6=A0=91=E8=8A=82=E7=82=B9=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E7=8A=B6=E6=80=81=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/?= =?UTF-8?q?wang-xh-nancy/farris-vue=20*=20Merge=20branch=20'main'=20into?= =?UTF-8?q?=20dev=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/w?= =?UTF-8?q?ang-xh-nancy/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=B7=B2=E9=80=89=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20https://g?= =?UTF-8?q?itee.com/wang-xh-nancy/farris-vue=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=EF=BC=9B=E4=BF=AE=E6=94=B9section=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20feature:=20=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=E5=B1=9E=E6=80=A7=E7=9A=84?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E4=BF=A1=E6=81=AF=EF=BC=9B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=90=9C=E7=B4=A2=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20?= =?UTF-8?q?https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E6=8E=A7=E4=BB=B6=E5=8D=95=E7=8B=AC=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=97=B6=E9=85=8D=E7=BD=AEclass=E6=A0=B7=E5=BC=8F=E6=97=A0?= =?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E9=80=89=E6=8B=A9=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E7=AA=97=E5=8F=A3=E4=B8=AD=EF=BC=8C=E5=B7=A6=E4=BE=A7?= =?UTF-8?q?listview=EF=BC=8C=E6=B2=A1=E6=9C=89=E9=80=89=E4=B8=AD=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E5=88=9B=E5=BB=BA=E8=A1=A8=E6=A0=BC=E5=92=8C=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E6=97=B6=E7=9A=84=E9=99=90=E5=88=B6=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E6=94=B9=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=9C=A8=E7=BB=91=E5=AE=9A=E5=80=BC=E4=B8=BA?= =?UTF-8?q?null=E6=97=B6=E7=9A=84=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE=E8=AE=A1=E6=97=B6datagrid?= =?UTF-8?q?=E8=A1=A8=E5=A4=B4=E6=A0=B7=E5=BC=8F=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20=E7=A7=BB=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E6=96=87=E4=BB=B6=EF=BC=9B=E4=BC=98=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=8E=A7=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20=E4=BC=98=E5=8C=96=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE=EF=BC=9A?= =?UTF-8?q?=E9=80=82=E5=BA=94=E6=8E=A7=E4=BB=B6=E5=86=85=E9=83=A8=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E5=BC=95=E8=B5=B7=E7=9A=84=E9=A1=B5=E9=9D=A2=E9=AB=98?= =?UTF-8?q?=E5=BA=A6=E5=8F=98=E5=8C=96=EF=BC=9B=E6=8B=96=E6=8B=BD=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E4=B8=AD=E6=94=AF=E6=8C=81=E9=A1=B5=E9=9D=A2=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=BB=9A=E5=8A=A8=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E4=B8=AD=E7=82=B9=E5=87=BB=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E7=9A=84=E5=85=B3=E9=97=AD=E6=8C=89=E9=92=AE=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BB=8D=E8=A2=AB=E5=88=9B=E5=BB=BA=E5=87=BA?= =?UTF-8?q?=E6=9D=A5=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8=E8=AE=BE=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E4=BB=A5=E5=8F=8A=E6=8C=89=E9=92=AE=E7=9A=84=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D=E7=BD=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9E=8B=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E6=9B=B4=E6=96=B0=E5=8F=82=E6=95=B0=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=B8=8D=E5=8F=8A=E6=97=B6=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=9A=84=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E4=BB=B6=E4=B8=8D=E5=BA=94=E7=94=A8=E9=A1=B5?= =?UTF-8?q?=E7=AD=BE=E6=98=AF=E5=90=A6=E5=8F=AF=E8=A7=81=E3=80=81=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=B8=8D=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E9=A1=B5=E7=AD=BE=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E6=8C=89=E9=92=AE=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E5=90=8E=EF=BC=8C=E5=B7=B2=E9=80=89=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=93=8D=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E4=B8=BA=E8=BE=93=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=A0=E4=BD=8D=E6=96=87=E6=9C=AC=20*=20fi?= =?UTF-8?q?x:=20=E4=BC=98=E5=8C=96=E6=8E=A7=E4=BB=B6=E5=BF=85=E5=A1=AB?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=8E=A7=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1?= =?UTF-8?q?=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/w?= =?UTF-8?q?ang-xh-nancy/farris-vue=20into=20dev=20*=20feature:=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=8F=AA=E5=B1=95=E7=A4=BA=E7=9B=AE=E5=89=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E6=8E=A7=E5=88=B6=E5=99=A8=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=8E=A7=E5=88=B6=E5=99=A8=E5=91=BD=E4=BB=A4=20*=20fi?= =?UTF-8?q?x:=20=E7=9B=91=E5=90=AC=E7=94=BB=E5=B8=83=E7=88=B6=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E6=A8=AA=E5=90=91=E6=BB=9A=E5=8A=A8=E6=9D=A1=E7=9A=84?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8B=96=E6=8B=BD=E8=B0=83=E6=95=B4=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E7=9A=84=E9=A1=B5=E7=AD=BE=E9=A1=BA=E5=BA=8F=20*=20fi?= =?UTF-8?q?x:=20=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=8C=89=E9=92=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8B=96=E6=8B=BD=E8=B0=83=E6=95=B4=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:ubml/farris-vue?= =?UTF-8?q?=20into=20dev=20*=20feature:=20=E5=88=86=E7=BB=84=E9=9D=A2?= =?UTF-8?q?=E6=9D=BFsection=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=A0=8F=EF=BC=9BResponseToolbar=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=97=B6=EF=BC=8C=E6=94=AF=E6=8C=81=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8C=89=E9=92=AE=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/wang-xh-?= =?UTF-8?q?nancy/farris-vue=20into=20dev=20*=20Merge=20branch=20'main'=20o?= =?UTF-8?q?f=20gitee.com:ubml/farris-vue=20into=20dev=20*=20Merge=20branch?= =?UTF-8?q?=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=8E?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=88=87=E6=8D=A2=E5=88=B0=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=90=8E=EF=BC=8C=E9=83=A8=E5=88=86=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E6=94=B9section=E6=8C=89=E9=92=AE=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=90=8E=E6=97=A0=E6=95=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=AE=B1=E5=88=9B=E5=BB=BA=E7=9A=84=E5=AD=90=E8=A1=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E7=BC=BA=E5=B0=91id=E7=9A=84=E9=97=AE=E9=A2=98=20*=20feature:?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=E4=BB=8E=E4=BA=A4=E4=BA=92=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=BC=B9=E5=87=BA=E9=80=89=E6=8B=A9=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E7=9A=84=E7=AA=97=E5=8F=A3=20*=20fix:=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E7=9A=84=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=B1=9E=E6=80=A7=EF=BC=8C=E5=8F=AA=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=89=E6=8B=A9=EF=BC=8C=E4=B8=8D=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=BE=93=E5=85=A5=EF=BC=9B=E4=BF=AE=E6=94=B9=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E9=83=A8=E5=88=86=E7=88=B6=E7=BA=A7=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E5=90=8E=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20dev=20*=20fix:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B7=A8=E7=BB=84=E4=BB=B6=E7=A7=BB=E5=8A=A8=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6=EF=BC=8C=E5=B9=B6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B=EF=BC=9B=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=90=8E=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6TreeGrid=E6=8E=A7=E4=BB=B6=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E9=AB=98=E5=BA=A6=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=A8=A1=E5=9E=8B=E9=A1=B5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=20*=20fix:=20=E6=94=AF=E6=8C=81=E5=B1=9E=E6=80=A7=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=B1=95=E7=A4=BA=E8=A1=A8=E5=8D=95=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BF=A1=E6=81=AF=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20fix:=20=E6=96=B0=E5=A2=9E=E5=A1=AB=E6=8A=A5?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9A=84=E6=8E=A7=E5=88=B6=E8=A7=84=E5=88=99?= =?UTF-8?q?=EF=BC=9B=E4=BC=98=E5=8C=96=E6=A0=87=E7=AD=BE=E9=A1=B5=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=A1=AB=E5=85=85=E7=89=B9=E6=80=A7=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'dev'=20of=20https://?= =?UTF-8?q?gitee.com/wang-xh-nancy/farris-vue=20into=20dev=20*=20Merge=20b?= =?UTF-8?q?ranch=20'main'=20into=20dev=20*=20feature:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1=E5=88=9B=E5=BB=BA=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E3=80=81=E6=94=AF=E6=8C=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=20*=20fix:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=8A=B6=E6=80=81=E6=9C=BA=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=8E=B7=E5=8F=96=E5=92=8C=E6=8F=90=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20Revert=20"fix:=20amdim=E6=A1=86=E6=9E=B6"=20*?= =?UTF-8?q?=20Revert=20"fix:=20admin=E5=AF=BC=E8=88=AA=E5=88=9D=E5=BB=BA"?= =?UTF-8?q?=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/wang-xh-?= =?UTF-8?q?nancy/farris-vue=20into=20dev=20*=20Revert=20"fix:=20amdim?= =?UTF-8?q?=E6=A1=86=E6=9E=B6"=20*=20fix:=20=E9=80=89=E6=8B=A9=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=97=B6=E6=94=AF=E6=8C=81=E7=A6=81=E7=94=A8=E4=B8=BB?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E5=9C=BA=E6=99=AF=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20admin=E5=AF=BC=E8=88=AA=E5=88=9D?= =?UTF-8?q?=E5=BB=BA=20*=20feature:=20=E7=B2=BE=E7=AE=80=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6schema=EF=BC=8C=E5=8F=AA=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=BF=85=E5=A1=AB=E7=9A=84=E5=B1=9E=E6=80=A7=20*=20feature:=20?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=AE=9E=E4=BD=93=E7=AA=97=E5=8F=A3=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=AE=9E=E4=BD=93=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E6=95=88=E6=9E=9C=20*=20fix:=20amdim=E6=A1=86=E6=9E=B6=20*=20f?= =?UTF-8?q?ix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E7=9A=84=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=88=E5=B9=B6=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merge=20branc?= =?UTF-8?q?h=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20feature:=20=E6=96=B0=E5=A2=9E=E5=8F=8C=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E3=80=81=E5=B7=A6=E6=A0=91=E5=8F=B3=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=A8=A1=E6=9D=BF=E7=9A=84=E6=8B=96=E6=8B=BD=E6=8E=A7?= =?UTF-8?q?=E5=88=B6json=E6=96=87=E4=BB=B6=20*=20Merge=20branch=20'grid-to?= =?UTF-8?q?olbar'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=86=E6=94=AF=E5=90=8E=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98=20*=20fix:=20=E9=80=82?= =?UTF-8?q?=E9=85=8D=E6=97=A0=E7=8A=B6=E6=80=81=E6=9C=BA=E7=9A=84=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=A8=A1=E6=9D=BF=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E7=9A=84=E9=94=99=E8=AF=AF=20*=20feature:=20?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=A1=A8=E6=A0=BC=E6=97=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E6=98=BE=E7=A4=BA=E5=AD=97=E6=AE=B5=20*=20Me?= =?UTF-8?q?rge=20branch=20'dev'=20into=20grid-toolbar=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F=E6=A3=80=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=91=BD=E5=90=8D=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=88=86=E7=BB=84?= =?UTF-8?q?=E9=9D=A2=E6=9D=BFSection=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E5=AE=9E=E4=BD=93=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E7=9A=84=E7=9B=AE=E5=BD=95=E7=BB=93?= =?UTF-8?q?=E6=9E=84=20*=20fix:=20=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E8=BE=93=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=BC=B9=E5=87=BA=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=9A=84=E7=AA=97=E5=8F=A3=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8B=96=E6=8B=BD=E6=99=AE=E9=80=9A=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E6=97=B6=E7=94=9F=E6=88=90schema=E7=9A=84=E5=88=86?= =?UTF-8?q?=E6=94=AF=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20fix:=20=E8=B0=83=E6=95=B4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=BB=93=E6=9E=84=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E9=9B=86=E5=90=88=E7=B1=BB=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E9=80=89=E6=8B=A9=E5=AE=9E=E4=BD=93=20*=20fe?= =?UTF-8?q?ature:=20=E6=8B=96=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=A2=9E=E5=8A=A0tab=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=20*=20feature:=20=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0tab=E6=96=B0=E5=A2=9E=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8C=89=E9=92=AE=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20Merge=20branch=20'main'=20into=20dev=20*=20feature?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20feature:=20=E6=A0=87=E7=AD=BE=E9=A1=B5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=EF=BC=9B=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E3=80=81=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8C=89=E9=92=AE=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E5=8F=91?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20merge=20dev=20*=20fix:=20merg?= =?UTF-8?q?e=20main=20*=20fix:=20=E6=96=B0=E5=A2=9E=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E4=B8=AD=E6=96=87=E5=90=8D=E7=A7=B0=E5=92=8C?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E5=88=A0=E9=99=A4=E5=90=8E=E4=BA=8B=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E6=8E=A7=E4=BB=B6=E5=90=8E?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B=E5=B9=B6?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99DOM=E8=8A=82=E7=82=B9=20*?= =?UTF-8?q?=20fix:=20=E4=BB=A3=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9B=91=E5=90=AC=E4=BB=A3=E7=A0=81=E7=9A=84?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E6=96=B0=E5=A2=9E=E7=BB=91=E5=AE=9A=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=EF=BC=8C=E6=94=AF=E6=8C=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=20*=20feature:=20=E6=8B=96=E6=8B=BD=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=97=B6=E6=B7=BB=E5=8A=A0=E6=96=B0=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8C=89=E9=92=AE=EF=BC=9BtabPage=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=85=B7=E6=A0=8F=20*=20fix:=20?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=88=9B=E5=BB=BA=E5=8F=AF=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C=E9=BB=98=E8=AE=A4=E4=B8=8D?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E5=88=86=E9=A1=B5=20*=20fix:=20=E5=B1=8F?= =?UTF-8?q?=E8=94=BD=E5=B7=A5=E5=85=B7=E7=AE=B1=E4=B8=AD=E7=9A=84=E6=99=AE?= =?UTF-8?q?=E9=80=9A=E5=AE=B9=E5=99=A8=20*=20fix:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=8F=AA=E8=AF=BB=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Dcombo-tree=20=E6=95=B0=E6=8D=AE=E6=BA=90?= =?UTF-8?q?=E4=B8=AD=E4=B8=8D=E5=B8=A6data=E7=9A=84=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E6=98=BE=E7=A4=BA=E5=B7=B2=E9=80=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E9=94=99=E8=AF=AF=E3=80=82=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20feature:=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E7=94=BB=E5=B8=83=E6=8B=96=E6=8B=BD=E6=8E=A7=E5=88=B6=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20feature:=20=E7=9B=91=E5=90=AC=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=E5=8F=98=E5=8C=96=EF=BC=8C=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=93=8D=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=E5=8D=A1=E7=89=87=E7=B1=BB=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=94=A8formColumns=E6=A0=87=E8=AF=86=E5=8C=BA?= =?UTF-8?q?=E5=9F=9F=E5=86=85=E6=AF=8F=E8=A1=8C=E6=94=BE=E5=87=A0=E5=88=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E5=88=A0=E9=99=A4=E6=A0=87=E7=AD=BE=E9=A1=B5?= =?UTF-8?q?=E9=A1=B9=E5=90=8E=EF=BC=8C=E8=A7=A6=E5=8F=91=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=A0=91=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20feature:=20=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=AD=E4=BF=AE=E6=94=B9=E6=8E=A7=E4=BB=B6=E7=9A=84=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E7=B1=BB=E5=B1=9E=E6=80=A7=E5=90=8E=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=8E=A7=E4=BB=B6=E6=A0=91=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=BB=8E=E6=9C=80=E8=BF=91=E5=88=97=E8=A1=A8=E4=B8=AD?= =?UTF-8?q?=E6=89=93=E4=B8=8D=E5=BC=80vue=E8=A1=A8=E5=8D=95=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E4=B8=8D=E6=94=AF=E6=8C=81=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E8=A7=86=E5=9B=BE=E4=B8=8E=E5=8F=98=E9=87=8F=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=97=B6=EF=BC=8C=E7=BB=99=E5=87=BA=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20*=20feature:=20=E6=94=AF=E6=8C=81=E4=BB=8E?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96=E6=8B=BD=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E9=9D=A2=E6=9D=BF=E5=92=8C=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E5=8C=BA=E5=9F=9F=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20into=20dev=20*=20featur?= =?UTF-8?q?e:=20=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=8E=A7=E4=BB=B6=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A1=A8=E6=A0=BC=E7=BB=91=E5=AE=9A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=BA=90=20*=20Merge=20branch=20'main'=20into=20dev=20*=20feat?= =?UTF-8?q?ure:=20=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E7=9A=84=E6=8E=A7=E4=BB=B6=E5=88=87=E6=8D=A2=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=20*=20fix:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=97=B6=EF=BC=8C=E6=B8=85=E7=A9=BA=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=20*=20fix:=20=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merg?= =?UTF-8?q?e=20branch=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=88=87=E6=8D=A2=E7=94=BB=E5=B8=83=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E7=9A=84?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E5=88=97=E8=A1=A8=E6=97=A0=E6=B3=95=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=8E=A7=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20dev=20*=20fix:=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E6=94=AF=E6=8C=81=E4=BF=9D=E5=AD=98=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E9=A1=B5=E9=9D=A2=E4=B8=AD=E6=96=B9=E6=B3=95=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=9A=84=E5=8F=98=E6=9B=B4=20*=20feature:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E5=9C=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E5=88=87=E6=8D=A2=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=EF=BC=9B=E6=94=AF=E6=8C=81=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E4=B8=AD=E6=96=87=E5=B1=95=E7=A4=BA=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E6=89=93=E5=BC=80=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=9A=84url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer-outline/src/designer-outline.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/ui-vue/components/designer-outline/src/designer-outline.css b/packages/ui-vue/components/designer-outline/src/designer-outline.css index b7ee0329992..d0883a8dc0f 100644 --- a/packages/ui-vue/components/designer-outline/src/designer-outline.css +++ b/packages/ui-vue/components/designer-outline/src/designer-outline.css @@ -5,39 +5,39 @@ background: #fcfdff; } -.designer-control-tree .fv-tree { +.designer-control-tree .fv-grid { height: 100% !important; overflow: hidden; } -.designer-control-tree .fv-tree .fv-tree-content { +.designer-control-tree .fv-grid .fv-grid-content { background: #fcfdff !important; } -.designer-control-tree .fv-tree .controlIcon { +.designer-control-tree .fv-grid .controlIcon { font-size: 20px; color: #7d86ab !important; margin: 0px 4px 0 0 !important; height: 1rem; } -.designer-control-tree .fv-tree .controlIcon.f-icon { +.designer-control-tree .fv-grid .controlIcon.f-icon { font-size: 18px; } -.designer-control-tree .fv-tree .fv-tree-data { +.designer-control-tree .fv-grid .fv-grid-data { overflow: auto; } -.designer-control-tree .fv-tree .fv-grid-row-selected { +.designer-control-tree .fv-grid .fv-grid-row-selected { border-radius: 10px; } -.designer-control-tree .fv-tree .fv-grid-row-hover { +.designer-control-tree .fv-grid .fv-grid-row-hover { border-radius: 10px; } -.designer-control-tree .fv-tree .fv-grid-hierarchy-cell{ +.designer-control-tree .fv-grid .fv-grid-hierarchy-cell{ padding: 0; } \ No newline at end of file -- Gitee From 1e9b6c6fb36878b3b0708fbbd465c76af3b7e33e Mon Sep 17 00:00:00 2001 From: XimenaFan Date: Thu, 13 Feb 2025 02:10:33 +0000 Subject: [PATCH 03/13] =?UTF-8?q?!1279=20feature:=20=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=8A=9F=E8=83=BD=20*=20feature:=20=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81=E5=8A=9F=E8=83=BD=20*=20Merge=20rem?= =?UTF-8?q?ote-tracking=20branch=20'refs/remotes/origin/main'=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*?= =?UTF-8?q?=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/main?= =?UTF-8?q?'=20*=20Merge=20remote-tracking=20branch=20'refs/remotes/origin?= =?UTF-8?q?/main'=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E9=A1=B9=E6=95=B0=E6=8D=AE=E5=8F=98=E6=9B=B4=EF=BC=8C?= =?UTF-8?q?=E4=B9=8B=E5=89=8D=E7=9A=84=E4=B8=8B=E6=8B=89=E7=AD=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=B6=88=E5=A4=B1=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E9=9A=90=E8=97=8F=E8=A1=A8=E6=A0=BC=E9=83=A8=E5=88=86=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E3=80=81=E4=BF=AE=E5=A4=8D=E5=B1=9E=E6=80=A7=E9=A1=B9?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E4=B8=8D=E5=8F=98=E6=9B=B4=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E5=88=97?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E5=88=87=E6=8D=A2=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BF=90=E8=A1=8C=E6=97=B6=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E5=BC=B9=E5=87=BA=E7=AA=97=E5=8F=A3?= =?UTF-8?q?=E3=80=81=E6=95=B0=E5=AD=97=E6=8E=A7=E4=BB=B6=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E7=BB=9F=E4=B8=80=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=8D=E6=98=BE=E7=A4=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=93=8D=E5=BA=94=E5=BC=8F?= =?UTF-8?q?=E5=88=97=E5=AE=BD=E7=A7=BB=E9=99=A4mock=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0schema=20*=20Merge=20remote-tracking=20branch=20'refs/?= =?UTF-8?q?remotes/origin/main'=20*=20fix:=20=E8=B0=83=E6=95=B4=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E5=92=8C=E5=93=8D=E5=BA=94=E5=BC=8F=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=B1=9E=E6=80=A7=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8=E3=80=81=E5=88=86?= =?UTF-8?q?=E6=A0=8F=E9=9D=A2=E6=9D=BF=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E9=AB=98=E5=BA=A6=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E8=B0=83=E6=95=B4=EF=BC=9B=E6=95=B0=E5=AD=97=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E5=9C=A8=E8=A1=8C=E7=BC=96=E8=BE=91=E6=97=B6=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E9=97=AE=E9=A2=98=EF=BC=9B=20*=20fix:=20=E6=A0=91?= =?UTF-8?q?=E8=A1=A8=E5=88=97=E9=85=8D=E7=BD=AE=E4=B8=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=94=BB=E5=B8=83=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E9=9D=9E?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E4=B8=8B=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=8F=B3=E4=BE=A7=E7=9A=84=E5=9C=86=E8=A7=92?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=8B=96=E6=8B=BD=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E5=A4=9A=E9=80=89=E7=BB=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=9E=9A=E4=B8=BE=E9=A1=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83=E6=95=B4=E4=B8=8B?= =?UTF-8?q?=E6=8B=89=E5=92=8C=E7=A9=BF=E6=A2=AD=E6=A1=86=E7=9A=84=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E7=A7=BB=E9=99=A4=E6=97=A7=E7=9A=84=E7=A9=BF?= =?UTF-8?q?=E6=A2=AD=E6=A1=86=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=A0=91=E9=85=8D=E7=BD=AE=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E8=A1=A8=E6=A0=BC=E5=A4=9A=E9=80=89=E5=92=8C=E5=A4=8D?= =?UTF-8?q?=E9=80=89=E6=A1=86=E5=9C=A8=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=8A=E7=9A=84=E4=BE=9D=E8=B5=96=E5=85=B3=E7=B3=BB=20*=20fi?= =?UTF-8?q?x:=20=E6=A0=B7=E5=BC=8F=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E6=8E=A7=E4=BB=B6=E5=B8=A6=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E5=B8=A6=E6=97=B6=E9=97=B4=E7=9A=84=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtab=E4=B8=ADtitle?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E5=90=8D=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=A4=9A=E9=80=89=E5=85=B3=E8=81=94=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=E6=90=9C=E7=B4=A2=E6=B8=85=E7=A9=BA=E8=BF=98?= =?UTF-8?q?=E4=BF=9D=E7=95=99=E4=B8=8A=E6=AC=A1=E6=96=87=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=A1=AB=E6=8A=A5=E6=A8=A1=E6=9D=BF=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=90=AF=E7=94=A8=E5=A4=9A=E9=80=89=EF=BC=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=98=BE=E7=A4=BA=E5=A4=9A=E9=80=89=E6=A1=86?= =?UTF-8?q?=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=88=86=E6=A0=8F=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=B1=9E=E6=80=A7=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E9=A1=B9=E6=9B=B4=E6=94=B9=E9=BB=98=E8=AE=A4=E5=80=BC=EF=BC=8C?= =?UTF-8?q?=E6=9A=B4=E9=9C=B2=E5=87=BA=E9=80=9A=E8=BF=87=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8=E4=BF=AE=E6=94=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=90=8E=EF=BC=8C=E4=B8=AD=E9=97=B4=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E8=B5=8B=E5=80=BC=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=A1=AB?= =?UTF-8?q?=E6=8A=A5=E6=A8=A1=E6=9D=BF=E5=B7=A5=E5=85=B7=E6=A0=8F=E7=9A=84?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E5=B1=85=E4=B8=AD=E5=AF=B9=E9=BD=90=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E4=B8=8D=E5=90=8C=E5=B1=82=E7=BA=A7=E4=B8=9A=E5=8A=A1=E5=85=B3?= =?UTF-8?q?=E8=81=94=E5=AD=97=E6=AE=B5=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E7=A7=BB=E9=99=A4=E9=A2=9D=E5=A4=96=E7=9A=84?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E6=96=87=E4=BB=B6=EF=BC=9B=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E6=96=87=E4=BB=B6=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E6=8B=89=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=BC=96=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=20*=20fi?= =?UTF-8?q?x:=20=E8=A7=A3=E5=86=B3=E6=8B=96=E6=8B=BD=E5=8D=95=E9=80=89?= =?UTF-8?q?=E7=BB=84=E3=80=81=E5=A4=9A=E9=80=89=E7=BB=84=E5=88=B0=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E4=B8=8A=EF=BC=8C=E5=88=9D=E5=A7=8B=E9=83=BD=E6=98=AF?= =?UTF-8?q?=E7=A9=BA=E7=99=BD=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E6=A0=B7=E5=BC=8F=E7=BB=9F=E4=B8=80=EF=BC=9B=E5=A4=9A?= =?UTF-8?q?=E8=A1=8C=E6=96=87=E6=9C=AC=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=20*=20fix:=20=E6=9B=B4=E6=94=B9=E8=A1=A8=E6=A0=BC=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20*=20Merge=20branch=20'xdev'=20*=20Merge=20remote-tr?= =?UTF-8?q?acking=20branch=20'refs/remotes/origin/main'=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=85=B3=E4=BA=8Erxjs=E7=9A=84=E5=BC=95?= =?UTF-8?q?=E7=94=A8=20*=20fix:=20checkbox=E7=BB=84=E4=BB=B6=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=86=E9=A1=B5=E6=A0=B7=E5=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E5=92=8C=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=88=97=E5=AF=B9=E9=BD=90=E6=96=B9=E5=BC=8F=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20xdev=20*=20Merge=20remo?= =?UTF-8?q?te-tracking=20branch=20'refs/remotes/origin/main'=20*=20feature?= =?UTF-8?q?:=20=E4=BA=8B=E4=BB=B6=E4=BA=A4=E4=BA=92=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=EF=BC=8C=E9=80=89=E6=8B=A9=E6=96=B0=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E5=90=8E=E8=BF=87=E6=BB=A4=E5=91=BD=E4=BB=A4=EF=BC=9B=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E4=B8=AD=E6=96=B0=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=EF=BC=8C=E7=82=B9=E5=87=BB=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=A1=A8=E6=A0=BC=E6=8B=96=E6=8B=BD=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20xdev=20*=20Merge=20remo?= =?UTF-8?q?te-tracking=20branch=20'refs/remotes/origin/main'=20*=20feature?= =?UTF-8?q?:=20=E4=BA=A4=E4=BA=92=E4=BA=8B=E4=BB=B6=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E5=A4=84=E7=90=86=E8=A2=AB=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=20*=20feature:=20=E5=88=97=E8=AE=BE=E7=BD=AE=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E6=A0=91=E5=9E=8B=E7=BB=93=E6=9E=84=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81UDT=E5=92=8C=E5=85=B3=E8=81=94=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E4=B8=8B=E5=88=97=E7=9A=84=E9=80=89=E6=8B=A9=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=88=97=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8B=96=E6=8B=BD=EF=BC=8C=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E9=BB=98=E8=AE=A4=E6=98=AF=E6=94=AF=E6=8C=81=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=20*=20feature:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81=E5=8A=9F=E8=83=BD=20*=20fix:=20?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=BA=A4=E4=BA=92=E9=9D=A2=E6=9D=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=89=E4=B8=AD=E6=8E=A7=E5=88=B6=E5=99=A8=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*?= =?UTF-8?q?=20fix:=20=E8=B0=83=E6=95=B4=E6=95=B0=E5=AD=97=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E6=94=AF=E6=8C=81=E6=8E=A7=E5=88=B6=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=96=B9=E6=B3=95=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=BF=90=E8=A1=8C=E6=97=B6=E8=A1=A8=E5=8D=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=93=8D=E5=BA=94=E5=BC=8F=E5=B1=9E=E6=80=A7=20*=20fe?= =?UTF-8?q?ature:=20=E4=BA=A4=E4=BA=92=E4=BA=8B=E4=BB=B6=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E7=9B=AE=E6=A0=87=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81=20*=20fix:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E6=A0=B7=E5=BC=8F=E6=96=87=E4=BB=B6=20*=20Me?= =?UTF-8?q?rge=20branch=20'xdev'=20*=20Merge=20remote-tracking=20branch=20?= =?UTF-8?q?'refs/remotes/origin/main'=20*=20fix:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E4=BA=A4=E4=BA=92=E9=9D=A2=E6=9D=BF=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=96=B9=E6=B3=95=E6=97=B6=EF=BC=8C=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=BE=97=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9E=9A=E4=B8=BE=E9=A1=B9=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E5=90=AF=E7=94=A8=E5=88=86=E9=A1=B5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=BC=96=E8=BE=91=E5=99=A8=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=B8=8B=E6=8B=89?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=9C=A8=E5=8D=95=E6=8D=AE=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=90=AF=E7=94=A8=E6=B8=85=E7=A9=BA=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=BA=94=E8=AF=A5=E4=B8=BA=E5=90=A6=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD?= =?UTF-8?q?=E5=B8=83=E5=B0=94=E5=92=8C=E4=B8=8B=E6=8B=89=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E8=A1=8C=E5=8F=B7=E5=B1=95=E7=A4=BA=E5=85=B3=E8=81=94?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=81=E5=A2=9E=E5=8A=A0=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20Merge=20remote-tracking=20branch?= =?UTF-8?q?=20'refs/remotes/origin/main'=20*=20Merge=20branch=20'main'=20o?= =?UTF-8?q?f=20https://gitee.com/ximenafan/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20feature:=20=E6=96=B0=E5=A2=9E=E6=96=B9=E6=B3=95=E5=90=8E?= =?UTF-8?q?=E8=83=BD=E7=9B=B4=E6=8E=A5=E6=89=93=E5=BC=80=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=E6=96=87=E4=BB=B6=20*=20Merge=20branch=20'co?= =?UTF-8?q?de-editor'=20*=20Merge=20remote-tracking=20branch=20'refs/remot?= =?UTF-8?q?es/origin/main'=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20*=20feature:=20=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BF=9D=E5=AD=98=E6=96=B9=E6=B3=95=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'code-editor'=20*=20M?= =?UTF-8?q?erge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20?= =?UTF-8?q?*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E9=97=AE=E9=A2=98=20*=20feature:=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=9B=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=20*=20feature:=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E8=A7=86=E5=9B=BE=E5=88=9D=E6=AD=A5=E7=BB=93=E6=9E=84?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E4=B8=8D?= =?UTF-8?q?=E8=A7=84=E8=8C=83=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=8E=A7=E4=BB=B6=E3=80=81=E5=A4=B4=E9=83=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE=E5=A4=8DHead?= =?UTF-8?q?er=E9=80=89=E4=B8=AD=E6=8C=89=E9=92=AE=E7=BB=84=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=A0=B7=E5=BC=8F=E4=B8=8D=E6=98=BE=E7=A4=BA=E4=B9=9F?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E4=B8=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B7=BB=E5=8A=A0=E4=BA=8B=E4=BB=B6=E5=90=8E?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=9C=8B=E4=B8=8D=E5=88=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20feature:=20=E8=A1=A8=E6=A0=BC=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E8=A1=8C=E5=8F=B7=E7=AD=89=E5=B1=9E=E6=80=A7=20*=20feature:=20?= =?UTF-8?q?=E5=A4=9A=E9=80=89=E7=BB=84=E3=80=81=E4=B8=8B=E6=8B=89=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=9E=9A=E4=B8=BE=E9=A1=B9=E4=BF=AE=E6=94=B9=20*=20fi?= =?UTF-8?q?x:=20check-box=E5=A2=9E=E5=8A=A0=E6=94=AF=E6=8C=81readonly?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20Merge=20branch=20'xdev'=20*=20Merge=20?= =?UTF-8?q?remote-tracking=20branch=20'refs/remotes/origin/main'=20*=20fea?= =?UTF-8?q?ture:=20=E5=A2=9E=E5=8A=A0=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=EF=BC=8C=E5=8D=95=E9=80=89=E7=BB=84=E5=B1=9E=E6=80=A7=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8=20*=20fix:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=89=93=E5=8C=85=E6=A0=B7=E5=BC=8F=E7=9A=84?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=EF=BC=9B=E8=B0=83=E6=95=B4=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=8E=A7=E4=BB=B6=E6=95=B0=E5=AD=97=E3=80=81=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=8E=A7=E4=BB=B6=E3=80=81=E5=A4=9A=E8=A1=8C=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E7=AD=89=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=8D=E6=AD=A3=E7=A1=AE=E4=BF=AE=E5=A4=8D=20*=20fi?= =?UTF-8?q?x:=20=E5=8D=95=E9=80=89=E3=80=81=E5=8D=95=E9=80=89=E7=BB=84?= =?UTF-8?q?=E3=80=81=E5=A4=9A=E9=80=89=E3=80=81=E5=A4=9A=E9=80=89=E7=BB=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6=E9=9C=80=E8=A6=81=E5=B1=9E=E6=80=A7?= =?UTF-8?q?readonly=E4=BD=86=E6=98=AF=E7=BB=84=E4=BB=B6=E5=8F=AA=E6=94=AF?= =?UTF-8?q?=E6=8C=81disabled=20*=20Merge=20remote-tracking=20branch=20'ref?= =?UTF-8?q?s/remotes/origin/main'=20*=20Merge=20remote-tracking=20branch?= =?UTF-8?q?=20'refs/remotes/origin/main'=20*=20fix:=20=E6=A0=B8=E5=AF=B9?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E6=94=B9=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcheckbox=E6=A8=AA=E5=90=91=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6disabled=E9=97=AE=E9=A2=98=EF=BC=9BS?= =?UTF-8?q?plitter=E8=AE=BE=E8=AE=A1=E6=97=B6=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E6=89=8B=E6=94=B9=E5=B8=83=E5=B0=94=E5=80=BC=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A6=E5=88=97=E5=8F=B3=E5=8D=A1=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=90=E8=A1=8C=E6=97=B6=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dsplitter=E5=B1=9E=E6=80=A7=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E5=B7=A6=E5=88=97=E5=8F=B3=E5=8D=A1=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E9=94=99=E4=B9=B1=EF=BC=8C=E5=A4=B4=E9=83=A8=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E4=B8=8D=E6=98=BE=E7=A4=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20rem?= =?UTF-8?q?ote-tracking=20branch=20'refs/remotes/origin/main'=20*=20Merge?= =?UTF-8?q?=20branch=20'xdev'=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20feature:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E5=93=8D=E5=BA=94=E6=8C=87=E4=BB=A4=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=AE=BE=E8=AE=A1=E6=97=B6=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E8=BE=93=E5=85=A5=E6=A0=B7=E5=BC=8F=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E9=97=AE=E9=A2=98=20*=20feature:=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?Splitter=E6=96=87=E6=A1=A3=E7=A4=BA=E4=BE=8B=20*=20Merge=20bran?= =?UTF-8?q?ch=20'main'=20into=20xdev=20*=20Merge=20remote-tracking=20branc?= =?UTF-8?q?h=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=96=B0=E5=BB=BA=E6=97=B6=E4=B8=8B=E6=8B=89=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E6=8C=87=E5=AE=9AidField=E9=97=AE=E9=A2=98=20*=20feature:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84splitter=E7=BB=84=E4=BB=B6=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E9=9C=80=E8=A6=81=E7=9A=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=8C=E8=B0=83=E6=95=B4=E6=9C=8D=E5=8A=A1=20*=20fe?= =?UTF-8?q?ature:=20=E6=8B=96=E6=8B=BD=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E5=BA=94=E7=94=A8=E7=BB=9F=E4=B8=80=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E9=85=8D=E7=BD=AE=E7=9A=84=E6=A0=B7=E5=BC=8F=20*=20fe?= =?UTF-8?q?ature:=20=E4=BF=AE=E5=A4=8D=E9=9B=86=E6=88=90=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E9=85=8D=E7=BD=AE=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20xdev=20*=20Merge=20remote-tracki?= =?UTF-8?q?ng=20branch=20'refs/remotes/origin/main'=20*=20feature:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=A7=E6=89=BF=E4=B8=AD=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=8F=E5=88=97=E5=AE=BD=E7=BC=96=E8=BE=91=E5=99=A8=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'main'=20into=20xdev=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E6=89=93=E5=8C=85=E8=BF=87=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20remote-track?= =?UTF-8?q?ing=20branch=20'refs/remotes/origin/main'=20*=20feature:=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=BB=84=E4=BB=B6=E5=AE=B9=E5=99=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=94=AF=E6=8C=81=E4=BA=8B=E4=BB=B6=20*=20fix:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=83=A8=E5=88=86=E6=8E=A7=E4=BB=B6=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E4=BA=8B=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E8=BF=90=E8=A1=8C=E6=97=B6=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=98=BE=E7=A4=BA=E4=B8=8D=E5=87=86=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20feature:=20Form=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=B8=83=E5=B1=80=E9=85=8D=E7=BD=AE=20*=20fe?= =?UTF-8?q?ature:=20Form=E6=94=AF=E6=8C=81=E7=BB=9F=E4=B8=80=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E9=85=8D=E7=BD=AE=20*=20feature:=20=E9=9B=86=E6=88=90?= =?UTF-8?q?=E5=88=97=E5=AE=BD=E7=BC=96=E8=BE=91=E5=99=A8=20*=20feature:=20?= =?UTF-8?q?schema=E4=B8=AD=E5=BF=BD=E7=95=A5=E5=85=83=E7=B4=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81ignore=E5=B1=9E=E6=80=A7=20*=20Merge=20remote-tracking?= =?UTF-8?q?=20branch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=90=8E=E5=88=97=E7=BC=96=E8=BE=91=E5=99=A8=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E6=97=B6=E9=97=B4=E7=BB=84=E4=BB=B6disable?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E4=B8=BAdisabled=20*=20Merge=20remote-tracki?= =?UTF-8?q?ng=20branch=20'refs/remotes/origin/main'=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3editor=E5=86=85=E9=83=A8=E5=8F=96=E4=B8=8D=E5=88=B0?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC=EF=BC=9B=E6=9B=BF=E6=8D=A2=E5=88=97?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E8=B0=83=E6=95=B4=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=96=B0=E6=97=A7=E5=88=97=E5=B1=9E=E6=80=A7=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=9D=A5=E5=9B=9E?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=8E=A7=E4=BB=B6=E5=90=8E=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E8=A2=AB=E9=80=89=E4=B8=AD=E9=97=AE=E9=A2=98=E3=80=81=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E9=83=A8=E5=88=86=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=A0=91=E8=A1=A8=E6=9A=82?= =?UTF-8?q?=E6=97=A0=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=88=97?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E9=80=89=E6=8B=A9=E5=88=97=E3=80=81?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=8E=A7=E4=BB=B6=E7=B1=BB=E5=9E=8B=E3=80=81?= =?UTF-8?q?=E5=88=97=E5=B1=95=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E5=A4=8DResponseToolbar=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E6=98=BE=E7=A4=BA=E4=B8=BA=E7=81=B0=E8=89=B2?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=BC=96=E8=BE=91=E5=99=A8=E4=B8=8D=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=A7=A3=E5=86=B3=E5=88=97=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E5=86=8D=E6=AC=A1=E6=89=93=E5=BC=80=E6=95=B0=E6=8D=AE=E4=B8=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98=20*=20Merge=20remote-track?= =?UTF-8?q?ing=20branch=20'refs/remotes/origin/main'=20*=20feature:=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA?= =?UTF-8?q?TreeGrid=E3=80=81=E5=88=97=E5=B1=9E=E6=80=A7=E3=80=81=E5=88=97?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E3=80=81=E7=BB=91=E5=AE=9A=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20*=20feature:=20=E8=B0=83=E6=95=B4Textarea=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=86=99=E6=B3=95=E5=92=8C=E7=A4=BA=E4=BE=8B=20*=20fe?= =?UTF-8?q?ature:=20=E5=A2=9E=E5=8A=A0=E9=99=84=E4=BB=B6=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=88=A0=E9=99=A4=E4=BF=A1=E6=81=AF=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=8F=AA?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=80=BC=E4=BD=86=E6=98=AF=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E6=B6=88=E6=81=AF=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=BC=96=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E3=80=81=E6=A0=87=E7=AD=BE=E9=A1=B5=E6=8C=89=E9=92=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=BA=8B=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/designer/src/components/designer.component.tsx | 9 ++++++--- .../command-source/command-source.component.tsx | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/designer/src/components/designer.component.tsx b/packages/designer/src/components/designer.component.tsx index 92b108c62c6..9fbe890b748 100644 --- a/packages/designer/src/components/designer.component.tsx +++ b/packages/designer/src/components/designer.component.tsx @@ -157,7 +157,10 @@ export default defineComponent({ * 切换设计器视图与代码视图 */ function onChangeDesignerView(viewType: string) { - currentViewType.value = viewType; + // currentViewType.value = viewType; + if (viewType === 'codeEditor') { + notifyService.warning('暂不支持'); + } } /** * 向自定义构件添加ts代码方法 @@ -257,9 +260,9 @@ export default defineComponent({ {/* */} -
+ {/*
onChangeDesignerView(type)} onSaveAll={()=>onCodeViewSaveAll()}> -
+
*/} : '' ); diff --git a/packages/ui-vue/components/events-editor/src/components/command-source/command-source.component.tsx b/packages/ui-vue/components/events-editor/src/components/command-source/command-source.component.tsx index dbb188ec0c1..ea80794e3a6 100644 --- a/packages/ui-vue/components/events-editor/src/components/command-source/command-source.component.tsx +++ b/packages/ui-vue/components/events-editor/src/components/command-source/command-source.component.tsx @@ -46,7 +46,8 @@ export default defineComponent({ const runtimeCustom = ref(props.canAddNewMethod); const shouldShowAddNewMethod = computed(() => { - return !runtimeCustom.value; + // return !runtimeCustom.value; + return false; }); const shouldShowBondEvents = computed(() => { -- Gitee From 7823266b30396de31eb63178127883a485b61e96 Mon Sep 17 00:00:00 2001 From: wang-xh Date: Thu, 13 Feb 2025 02:10:46 +0000 Subject: [PATCH 04/13] =?UTF-8?q?!1278=20=E4=B8=BB=E5=88=86=E6=94=AF?= =?UTF-8?q?=E5=B1=8F=E8=94=BD=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E6=A0=91=20*=20fix:=20=E4=B8=BB=E5=88=86=E6=94=AF=E5=B1=8F?= =?UTF-8?q?=E8=94=BD=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=AE=9E=E4=BD=93=E6=A0=91?= =?UTF-8?q?=20*=20fix:=20=E9=80=82=E9=85=8DTreeView=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=A0=B7=E5=BC=8F=E5=8F=98=E6=9B=B4=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20?= =?UTF-8?q?https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=90=8E=EF=BC=8C=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E9=A1=B5=E7=AD=BE=E5=86=85=E9=83=A8component?= =?UTF-8?q?=E5=92=8Cviewmodel=E5=88=A0=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merge=20branc?= =?UTF-8?q?h=20'main'=20of=20https://gitee.com/wang-xh-nancy/farris-vue=20?= =?UTF-8?q?*=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=A1=B5=EF=BC=9A=E5=AF=B9=E4=BA=8E=E4=B8=8D=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=EF=BC=8C=E5=81=9A?= =?UTF-8?q?=E7=BD=AE=E7=81=B0=E5=A4=84=E7=90=86=E3=80=82=20*=20fix:=20?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E7=9A=84?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E8=8C=83=E5=9B=B4=20*=20fix:=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=8D=95=E9=80=89=E7=BB=84=E5=92=8C=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E7=BB=84=E7=9A=84=E6=A8=AA=E5=90=91=E6=8E=92=E5=88=97=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E5=B9=B6=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?demo=E6=A0=B7=E4=BE=8B=E7=9A=84=E5=86=99=E6=B3=95=E3=80=82=20*?= =?UTF-8?q?=20fix:=20=E6=A8=A1=E5=9E=8B=E9=A1=B5=E9=9D=A2=E5=9C=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B9=E6=B3=95=E5=92=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=90=8E=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=B8=8A?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E7=9A=84=E6=A0=91=E8=8A=82=E7=82=B9=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E7=8A=B6=E6=80=81=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/?= =?UTF-8?q?wang-xh-nancy/farris-vue=20*=20Merge=20branch=20'main'=20into?= =?UTF-8?q?=20dev=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/w?= =?UTF-8?q?ang-xh-nancy/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=B7=B2=E9=80=89=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20https://g?= =?UTF-8?q?itee.com/wang-xh-nancy/farris-vue=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=EF=BC=9B=E4=BF=AE=E6=94=B9section=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20feature:=20=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=E5=B1=9E=E6=80=A7=E7=9A=84?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E4=BF=A1=E6=81=AF=EF=BC=9B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=90=9C=E7=B4=A2=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20Merge=20branch=20'main'=20of=20?= =?UTF-8?q?https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E6=8E=A7=E4=BB=B6=E5=8D=95=E7=8B=AC=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=97=B6=E9=85=8D=E7=BD=AEclass=E6=A0=B7=E5=BC=8F=E6=97=A0?= =?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/wang-xh-nancy/farris-vue=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E9=80=89=E6=8B=A9=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E7=AA=97=E5=8F=A3=E4=B8=AD=EF=BC=8C=E5=B7=A6=E4=BE=A7?= =?UTF-8?q?listview=EF=BC=8C=E6=B2=A1=E6=9C=89=E9=80=89=E4=B8=AD=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E5=88=9B=E5=BB=BA=E8=A1=A8=E6=A0=BC=E5=92=8C=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E6=97=B6=E7=9A=84=E9=99=90=E5=88=B6=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E6=94=B9=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=9C=A8=E7=BB=91=E5=AE=9A=E5=80=BC=E4=B8=BA?= =?UTF-8?q?null=E6=97=B6=E7=9A=84=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE=E8=AE=A1=E6=97=B6datagrid?= =?UTF-8?q?=E8=A1=A8=E5=A4=B4=E6=A0=B7=E5=BC=8F=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20=E7=A7=BB=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E6=96=87=E4=BB=B6=EF=BC=9B=E4=BC=98=E5=8C=96=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=8E=A7=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20=E4=BC=98=E5=8C=96=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E4=BD=8D=E7=BD=AE=EF=BC=9A?= =?UTF-8?q?=E9=80=82=E5=BA=94=E6=8E=A7=E4=BB=B6=E5=86=85=E9=83=A8=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E5=BC=95=E8=B5=B7=E7=9A=84=E9=A1=B5=E9=9D=A2=E9=AB=98?= =?UTF-8?q?=E5=BA=A6=E5=8F=98=E5=8C=96=EF=BC=9B=E6=8B=96=E6=8B=BD=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E4=B8=AD=E6=94=AF=E6=8C=81=E9=A1=B5=E9=9D=A2=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=BB=9A=E5=8A=A8=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E4=B8=AD=E7=82=B9=E5=87=BB=E5=BC=B9=E7=AA=97?= =?UTF-8?q?=E7=9A=84=E5=85=B3=E9=97=AD=E6=8C=89=E9=92=AE=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BB=8D=E8=A2=AB=E5=88=9B=E5=BB=BA=E5=87=BA?= =?UTF-8?q?=E6=9D=A5=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8=E8=AE=BE=E7=BD=AE=E4=B8=BA?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E4=BB=A5=E5=8F=8A=E6=8C=89=E9=92=AE=E7=9A=84=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D=E7=BD=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=A8=A1=E5=9E=8B=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E6=9B=B4=E6=96=B0=E5=8F=82=E6=95=B0=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=B8=8D=E5=8F=8A=E6=97=B6=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=9A=84=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E4=BB=B6=E4=B8=8D=E5=BA=94=E7=94=A8=E9=A1=B5?= =?UTF-8?q?=E7=AD=BE=E6=98=AF=E5=90=A6=E5=8F=AF=E8=A7=81=E3=80=81=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=B8=8D=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E9=A1=B5=E7=AD=BE=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E6=8C=89=E9=92=AE=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E5=90=8E=EF=BC=8C=E5=B7=B2=E9=80=89=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=93=8D=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E4=B8=BA=E8=BE=93=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=A0=E4=BD=8D=E6=96=87=E6=9C=AC=20*=20fi?= =?UTF-8?q?x:=20=E4=BC=98=E5=8C=96=E6=8E=A7=E4=BB=B6=E5=BF=85=E5=A1=AB?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=EF=BC=9B=E4=BF=AE=E6=94=B9=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=8E=A7=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E5=AE=A1?= =?UTF-8?q?=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/w?= =?UTF-8?q?ang-xh-nancy/farris-vue=20into=20dev=20*=20feature:=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=8F=AA=E5=B1=95=E7=A4=BA=E7=9B=AE=E5=89=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E6=8E=A7=E5=88=B6=E5=99=A8=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=8E=A7=E5=88=B6=E5=99=A8=E5=91=BD=E4=BB=A4=20*=20fi?= =?UTF-8?q?x:=20=E7=9B=91=E5=90=AC=E7=94=BB=E5=B8=83=E7=88=B6=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E6=A8=AA=E5=90=91=E6=BB=9A=E5=8A=A8=E6=9D=A1=E7=9A=84?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8B=96=E6=8B=BD=E8=B0=83=E6=95=B4=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E7=9A=84=E9=A1=B5=E7=AD=BE=E9=A1=BA=E5=BA=8F=20*=20fi?= =?UTF-8?q?x:=20=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=8C=89=E9=92=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8B=96=E6=8B=BD=E8=B0=83=E6=95=B4=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:ubml/farris-vue?= =?UTF-8?q?=20into=20dev=20*=20feature:=20=E5=88=86=E7=BB=84=E9=9D=A2?= =?UTF-8?q?=E6=9D=BFsection=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=A0=8F=EF=BC=9BResponseToolbar=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=97=B6=EF=BC=8C=E6=94=AF=E6=8C=81=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8C=89=E9=92=AE=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/wang-xh-?= =?UTF-8?q?nancy/farris-vue=20into=20dev=20*=20Merge=20branch=20'main'=20o?= =?UTF-8?q?f=20gitee.com:ubml/farris-vue=20into=20dev=20*=20Merge=20branch?= =?UTF-8?q?=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=BB=8E?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=88=87=E6=8D=A2=E5=88=B0=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=90=8E=EF=BC=8C=E9=83=A8=E5=88=86=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E6=94=B9section=E6=8C=89=E9=92=AE=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=90=8E=E6=97=A0=E6=95=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=AE=B1=E5=88=9B=E5=BB=BA=E7=9A=84=E5=AD=90=E8=A1=A8=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E7=BC=BA=E5=B0=91id=E7=9A=84=E9=97=AE=E9=A2=98=20*=20feature:?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=E4=BB=8E=E4=BA=A4=E4=BA=92=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=BC=B9=E5=87=BA=E9=80=89=E6=8B=A9=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E7=9A=84=E7=AA=97=E5=8F=A3=20*=20fix:=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E7=9A=84=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=B1=9E=E6=80=A7=EF=BC=8C=E5=8F=AA=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=89=E6=8B=A9=EF=BC=8C=E4=B8=8D=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=BE=93=E5=85=A5=EF=BC=9B=E4=BF=AE=E6=94=B9=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E9=83=A8=E5=88=86=E7=88=B6=E7=BA=A7=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E5=90=8E=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20dev=20*=20fix:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B7=A8=E7=BB=84=E4=BB=B6=E7=A7=BB=E5=8A=A8=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6=EF=BC=8C=E5=B9=B6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B=EF=BC=9B=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E5=90=8E=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=97=B6TreeGrid=E6=8E=A7=E4=BB=B6=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E9=AB=98=E5=BA=A6=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=A8=A1=E5=9E=8B=E9=A1=B5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=20*=20fix:=20=E6=94=AF=E6=8C=81=E5=B1=9E=E6=80=A7=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E5=B1=95=E7=A4=BA=E8=A1=A8=E5=8D=95=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BF=A1=E6=81=AF=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E7=9A=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20fix:=20=E6=96=B0=E5=A2=9E=E5=A1=AB=E6=8A=A5?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9A=84=E6=8E=A7=E5=88=B6=E8=A7=84=E5=88=99?= =?UTF-8?q?=EF=BC=9B=E4=BC=98=E5=8C=96=E6=A0=87=E7=AD=BE=E9=A1=B5=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=A1=AB=E5=85=85=E7=89=B9=E6=80=A7=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'dev'=20of=20https://?= =?UTF-8?q?gitee.com/wang-xh-nancy/farris-vue=20into=20dev=20*=20Merge=20b?= =?UTF-8?q?ranch=20'main'=20into=20dev=20*=20feature:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1=E5=88=9B=E5=BB=BA=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E3=80=81=E6=94=AF=E6=8C=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=20*=20fix:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=8A=B6=E6=80=81=E6=9C=BA=E5=85=83=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=8E=B7=E5=8F=96=E5=92=8C=E6=8F=90=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20Revert=20"fix:=20amdim=E6=A1=86=E6=9E=B6"=20*?= =?UTF-8?q?=20Revert=20"fix:=20admin=E5=AF=BC=E8=88=AA=E5=88=9D=E5=BB=BA"?= =?UTF-8?q?=20*=20Merge=20branch=20'dev'=20of=20https://gitee.com/wang-xh-?= =?UTF-8?q?nancy/farris-vue=20into=20dev=20*=20Revert=20"fix:=20amdim?= =?UTF-8?q?=E6=A1=86=E6=9E=B6"=20*=20fix:=20=E9=80=89=E6=8B=A9=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=97=B6=E6=94=AF=E6=8C=81=E7=A6=81=E7=94=A8=E4=B8=BB?= =?UTF-8?q?=E8=A1=A8=E7=9A=84=E5=9C=BA=E6=99=AF=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20dev=20*=20fix:=20admin=E5=AF=BC=E8=88=AA=E5=88=9D?= =?UTF-8?q?=E5=BB=BA=20*=20feature:=20=E7=B2=BE=E7=AE=80=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6schema=EF=BC=8C=E5=8F=AA=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=BF=85=E5=A1=AB=E7=9A=84=E5=B1=9E=E6=80=A7=20*=20feature:=20?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=AE=9E=E4=BD=93=E7=AA=97=E5=8F=A3=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=AE=9E=E4=BD=93=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E6=95=88=E6=9E=9C=20*=20fix:=20amdim=E6=A1=86=E6=9E=B6=20*=20f?= =?UTF-8?q?ix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E7=9A=84=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=88=E5=B9=B6=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merge=20branc?= =?UTF-8?q?h=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81=E7=9A=84=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20feature:=20=E6=96=B0=E5=A2=9E=E5=8F=8C=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E3=80=81=E5=B7=A6=E6=A0=91=E5=8F=B3=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=A8=A1=E6=9D=BF=E7=9A=84=E6=8B=96=E6=8B=BD=E6=8E=A7?= =?UTF-8?q?=E5=88=B6json=E6=96=87=E4=BB=B6=20*=20Merge=20branch=20'grid-to?= =?UTF-8?q?olbar'=20into=20dev=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=86=E6=94=AF=E5=90=8E=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98=20*=20fix:=20=E9=80=82?= =?UTF-8?q?=E9=85=8D=E6=97=A0=E7=8A=B6=E6=80=81=E6=9C=BA=E7=9A=84=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=A8=A1=E6=9D=BF=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E7=9A=84=E9=94=99=E8=AF=AF=20*=20feature:=20?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=A1=A8=E6=A0=BC=E6=97=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E6=98=BE=E7=A4=BA=E5=AD=97=E6=AE=B5=20*=20Me?= =?UTF-8?q?rge=20branch=20'dev'=20into=20grid-toolbar=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=BC=E5=BC=8F=E6=A3=80=E6=9F=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=91=BD=E5=90=8D=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E8=AE=BE=E8=AE=A1=E6=97=B6=E5=88=86=E7=BB=84?= =?UTF-8?q?=E9=9D=A2=E6=9D=BFSection=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E5=AE=9E=E4=BD=93=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E7=9A=84=E7=9B=AE=E5=BD=95=E7=BB=93?= =?UTF-8?q?=E6=9E=84=20*=20fix:=20=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E8=BE=93=E5=85=A5=E7=B1=BB=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E5=BC=B9=E5=87=BA=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=9A=84=E7=AA=97=E5=8F=A3=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8B=96=E6=8B=BD=E6=99=AE=E9=80=9A=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E6=97=B6=E7=94=9F=E6=88=90schema=E7=9A=84=E5=88=86?= =?UTF-8?q?=E6=94=AF=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20fix:=20=E8=B0=83=E6=95=B4=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=BB=93=E6=9E=84=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fe?= =?UTF-8?q?ature:=20=E4=BB=8E=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E9=9B=86=E5=90=88=E7=B1=BB=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E9=80=89=E6=8B=A9=E5=AE=9E=E4=BD=93=20*=20fe?= =?UTF-8?q?ature:=20=E6=8B=96=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=A2=9E=E5=8A=A0tab=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=20*=20feature:=20=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0tab=E6=96=B0=E5=A2=9E=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8C=89=E9=92=AE=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20Merge=20branch=20'main'=20into=20dev=20*=20feature?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20feature:=20=E6=A0=87=E7=AD=BE=E9=A1=B5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=EF=BC=9B=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=B7=A5=E5=85=B7=E6=A0=8F?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E3=80=81=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8C=89=E9=92=AE=20*=20Merge=20branch=20'dev'=20into=20grid-t?= =?UTF-8?q?oolbar=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E5=8F=91?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=A3=80=E6=9F=A5=E5=8F=91=E7=8E=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20merge=20dev=20*=20fix:=20merg?= =?UTF-8?q?e=20main=20*=20fix:=20=E6=96=B0=E5=A2=9E=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E4=B8=AD=E6=96=87=E5=90=8D=E7=A7=B0=E5=92=8C?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E5=88=A0=E9=99=A4=E5=90=8E=E4=BA=8B=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E6=8E=A7=E4=BB=B6=E5=90=8E?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E8=A7=86=E5=9B=BE=E6=A8=A1=E5=9E=8B=E5=B9=B6?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=86=97=E4=BD=99DOM=E8=8A=82=E7=82=B9=20*?= =?UTF-8?q?=20fix:=20=E4=BB=A3=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9B=91=E5=90=AC=E4=BB=A3=E7=A0=81=E7=9A=84?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E6=96=B0=E5=A2=9E=E7=BB=91=E5=AE=9A=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=EF=BC=8C=E6=94=AF=E6=8C=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=20*=20feature:=20=E6=8B=96=E6=8B=BD=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=97=B6=E6=B7=BB=E5=8A=A0=E6=96=B0=E5=A2=9E=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=8C=89=E9=92=AE=EF=BC=9BtabPage=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B7=A5=E5=85=B7=E6=A0=8F=20*=20fix:=20?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=88=9B=E5=BB=BA=E5=8F=AF=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=97=B6=EF=BC=8C=E9=BB=98=E8=AE=A4=E4=B8=8D?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E5=88=86=E9=A1=B5=20*=20fix:=20=E5=B1=8F?= =?UTF-8?q?=E8=94=BD=E5=B7=A5=E5=85=B7=E7=AE=B1=E4=B8=AD=E7=9A=84=E6=99=AE?= =?UTF-8?q?=E9=80=9A=E5=AE=B9=E5=99=A8=20*=20fix:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=8F=AA=E8=AF=BB=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Dcombo-tree=20=E6=95=B0=E6=8D=AE=E6=BA=90?= =?UTF-8?q?=E4=B8=AD=E4=B8=8D=E5=B8=A6data=E7=9A=84=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E6=98=BE=E7=A4=BA=E5=B7=B2=E9=80=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=9A=84=E9=94=99=E8=AF=AF=E3=80=82=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20into=20dev=20*=20feature:=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E7=94=BB=E5=B8=83=E6=8B=96=E6=8B=BD=E6=8E=A7=E5=88=B6=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20feature:=20=E7=9B=91=E5=90=AC=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=E5=8F=98=E5=8C=96=EF=BC=8C=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=93=8D=E4=BD=9C=E5=9B=BE=E6=A0=87=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=9B=E5=8D=A1=E7=89=87=E7=B1=BB=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=94=A8formColumns=E6=A0=87=E8=AF=86=E5=8C=BA?= =?UTF-8?q?=E5=9F=9F=E5=86=85=E6=AF=8F=E8=A1=8C=E6=94=BE=E5=87=A0=E5=88=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=20*=20Merge=20branch=20'main'=20into=20dev?= =?UTF-8?q?=20*=20fix:=20=E5=88=A0=E9=99=A4=E6=A0=87=E7=AD=BE=E9=A1=B5?= =?UTF-8?q?=E9=A1=B9=E5=90=8E=EF=BC=8C=E8=A7=A6=E5=8F=91=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=A0=91=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20feature:=20=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=AD=E4=BF=AE=E6=94=B9=E6=8E=A7=E4=BB=B6=E7=9A=84=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E7=B1=BB=E5=B1=9E=E6=80=A7=E5=90=8E=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=8E=A7=E4=BB=B6=E6=A0=91=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=BB=8E=E6=9C=80=E8=BF=91=E5=88=97=E8=A1=A8=E4=B8=AD?= =?UTF-8?q?=E6=89=93=E4=B8=8D=E5=BC=80vue=E8=A1=A8=E5=8D=95=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E4=B8=8D=E6=94=AF=E6=8C=81=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E8=A7=86=E5=9B=BE=E4=B8=8E=E5=8F=98=E9=87=8F=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E6=97=B6=EF=BC=8C=E7=BB=99=E5=87=BA=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20*=20feature:=20=E6=94=AF=E6=8C=81=E4=BB=8E?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96=E6=8B=BD=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E9=9D=A2=E6=9D=BF=E5=92=8C=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E5=8C=BA=E5=9F=9F=20*=20Merge=20branch=20'main'=20int?= =?UTF-8?q?o=20dev=20*=20Merge=20branch=20'main'=20into=20dev=20*=20featur?= =?UTF-8?q?e:=20=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E8=A1=A8=E6=A0=BC=E6=8E=A7=E4=BB=B6=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A1=A8=E6=A0=BC=E7=BB=91=E5=AE=9A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=BA=90=20*=20Merge=20branch=20'main'=20into=20dev=20*=20feat?= =?UTF-8?q?ure:=20=E6=94=AF=E6=8C=81=E5=B7=A5=E5=85=B7=E7=AE=B1=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E7=9A=84=E6=8E=A7=E4=BB=B6=E5=88=87=E6=8D=A2=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=20*=20fix:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=97=B6=EF=BC=8C=E6=B8=85=E7=A9=BA=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=20*=20fix:=20=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20Merge=20branch=20'main'=20into=20dev=20*=20Merg?= =?UTF-8?q?e=20branch=20'main'=20into=20dev=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=88=87=E6=8D=A2=E7=94=BB=E5=B8=83=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E7=9A=84?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E5=88=97=E8=A1=A8=E6=97=A0=E6=B3=95=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=8E=A7=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20into=20dev=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20dev=20*=20fix:=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E6=94=AF=E6=8C=81=E4=BF=9D=E5=AD=98=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E9=A1=B5=E9=9D=A2=E4=B8=AD=E6=96=B9=E6=B3=95=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=9A=84=E5=8F=98=E6=9B=B4=20*=20feature:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E5=9C=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E5=88=87=E6=8D=A2=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=EF=BC=9B=E6=94=AF=E6=8C=81=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E4=B8=AD=E6=96=87=E5=B1=95=E7=A4=BA=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E6=89=93=E5=BC=80=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=9A=84url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/form-designer/form-designer.component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index fce14c519a3..f39aa369534 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -132,9 +132,9 @@ export default defineComponent({ - + {/* - + */} -- Gitee From 7f38c87dea27ffa209b376327fbfa22d0f46d8ce Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Fri, 14 Feb 2025 15:59:40 +0000 Subject: [PATCH 05/13] =?UTF-8?q?!1281=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E9=80=9A=E8=BF=87props=E4=BF=AE=E6=94=B9=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=20*=20chore:=20=E4=BF=AE=E6=94=B9merge=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E8=A7=A3=E5=86=B3=E9=83=A8=E5=88=86=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=97=B6=E5=90=88=E5=B9=B6=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E9=80=9A=E8=BF=87props?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8schema=20*=20chore:=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=A2=9E=E5=8A=A0path=E5=B1=9E=E6=80=A7=20*?= =?UTF-8?q?=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0setSchema=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E4=BF=AE=E5=A4=8DsetProps=E6=97=A0?= =?UTF-8?q?=E6=95=88=E9=97=AE=E9=A2=98=20*=20chore:=20revert=20setProps=20?= =?UTF-8?q?*=20Merge=20branch=20'upstream-main'=20*=20chore:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4schema=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6=E6=9B=B4=E6=96=B0=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20*=20chore:=20=E4=BF=AE=E6=94=B9package=EF=BC=8C?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=89=93=E5=8C=85=E5=90=8E=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E7=A6=81=E7=94=A8rollup=E6=89=93=E5=8C=85=E6=B7=B7=E6=B7=86?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=BD=93=E5=89=8D=E8=A1=8C?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E4=BB=8E?= =?UTF-8?q?=E4=BB=8E=E8=A1=A8=E6=95=B0=E6=8D=AE=E4=B8=8D=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E6=A0=91=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=EF=BC=8C=E5=88=87=E6=8D=A2=E4=BB=8E=E8=A1=A8?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=A1=8C=E6=97=B6=E4=BB=8E=E4=BB=8E=E8=A1=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=88=B7=E6=96=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20Merge=20?= =?UTF-8?q?branch=20'upstream-main'=20*=20chore:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=BC=95=E7=94=A8ui-vue=E8=B7=AF=E5=BE=84=EF=BC=8Crollup?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20fix:=20=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=96=B0=E5=A2=9E=E5=9C=BA=E6=99=AF=E5=BC=80?= =?UTF-8?q?=E5=85=B3=E7=BB=84=E4=BB=B6=E8=A7=A6=E5=8F=91=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=8F=98=E6=9B=B4=E9=9B=86=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=85=B3=E8=81=94=E5=B5=8C=E5=A5=97udt=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E4=B8=ADudt=E5=8F=98=E6=9B=B4=E9=9B=86=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=93=E5=8C=85=E8=84=9A=E6=9C=AC=20*=20ch?= =?UTF-8?q?ore:=20=E8=A7=A3=E5=86=B3=E5=8E=8B=E7=BC=A9=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=90=8E=E8=BF=90=E8=A1=8C=E6=97=B6=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20ui-vue=E5=BC=80=E5=90=AF=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E6=89=93=E5=8C=85=20*=20fix:=20ui-vue=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=8E=8B=E7=BC=A9=E8=BF=90=E8=A1=8C=E6=97=B6=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20designer=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=8E=92=E9=99=A4vue=E7=AD=89=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=BC=95=E5=85=A5?= =?UTF-8?q?ui-vue=E6=96=B9=E5=BC=8F=EF=BC=8C=E8=A7=A3=E5=86=B3=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=97=A0=E6=B3=95=E5=89=94=E9=99=A4=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E7=A6=81=E7=94=A8=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=8E=8B=E7=BC=A9=20*=20chore:=20ui-vue=E5=BC=80?= =?UTF-8?q?=E5=90=AF=E5=8E=8B=E7=BC=A9=E6=89=93=E5=8C=85=20*=20Merge=20bra?= =?UTF-8?q?nch=20'upstream-main'=20*=20Merge=20branch=20'upstream-main'=20?= =?UTF-8?q?*=20Merge=20branch=20'upstream-main'=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=A4=9A=E8=AF=ADkey=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E4=BC=9A=E8=AF=9D=E5=88=9B=E5=BB=BA=E5=A4=9A=E6=AC=A1?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=A3=E5=86=B3iframe?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E6=89=93=E5=BC=80=E8=8F=9C=E5=8D=95=E6=97=B6?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E6=A1=86=E6=9E=B6=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=89=93=E5=8C=85=E5=8E=8B=E7=BC=A9?= =?UTF-8?q?=20*=20chore:=20renderer=E6=89=93=E5=8C=85=E5=8E=8B=E7=BC=A9=20?= =?UTF-8?q?*=20chore:=20=E6=89=93=E5=8C=85=E6=94=AF=E6=8C=81=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=20*=20chore:=20=E6=89=93=E5=8C=85=E5=8E=8B=E7=BC=A9?= =?UTF-8?q?=20*=20chore:=20=E6=89=93=E5=8C=85=E4=BF=9D=E7=95=99=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=90=8D=E7=A7=B0=20*=20chore:=20=E6=89=93=E5=8C=85?= =?UTF-8?q?=E6=97=B6=E4=BF=9D=E7=95=99=E5=87=BD=E6=95=B0=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=20*=20chore:=20devkit=E4=BA=A4=E4=BB=98=E7=89=A9=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=97=B6=E9=97=B4=E6=88=B3=20*=20chore:=20=E6=89=93?= =?UTF-8?q?=E5=8C=85=E8=84=9A=E6=9C=AC=E5=A2=9E=E5=8A=A0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=20*=20chore:=20=E5=8E=8B=E7=BC=A9bef=E6=89=93?= =?UTF-8?q?=E5=8C=85=E4=BA=A7=E7=89=A9=EF=BC=8C=E4=BC=98=E5=8C=96bef?= =?UTF-8?q?=E6=89=93=E5=8C=85=E4=BD=93=E7=A7=AF=20*=20chore:=20devkit?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=90=AF=E7=94=A8=E5=8E=8B=E7=BC=A9=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=AE=9A=E4=B9=89=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E4=B8=8Bloading=E6=97=A0=E6=B3=95=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20loading=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=BF=85=E9=A1=BB=E6=8C=87=E5=AE=9Aloadingid=E6=88=96?= =?UTF-8?q?timerid=20*=20chore:=20=E8=A7=A3=E5=86=B3=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E7=9C=8B=E3=80=81=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=89=8D=E7=9A=84=E6=A0=A1=E9=AA=8C=20*=20ch?= =?UTF-8?q?ore:=20=E5=90=8C=E6=AD=A5=E8=A1=A8=E6=A0=BC=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E5=B1=9E=E6=80=A7=E4=BF=AE=E6=94=B9=20*=20ch?= =?UTF-8?q?ore:=20=E6=9B=B4=E6=96=B0=E5=88=87=E6=8D=A2=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E3=80=81=E6=A0=91=E8=A1=A8=E5=BD=93=E5=89=8D=E8=A1=8C=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20*=20chore:=20=E7=BB=9F=E4=B8=80=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20*=20Merge=20branch=20'bugfix'=20*=20Merge=20branch=20'upstre?= =?UTF-8?q?am-main'=20*=20chore:=20update=20css=20*=20chore:=20=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E6=8B=A6=E6=88=AA=E5=BC=B9=E5=87=BA=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E5=90=8E=E7=BB=99=E5=87=BA=E6=8F=90=E7=A4=BA=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=A0=87=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=89=B9=E9=87=8F=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=88=97=E8=A1=A8=E5=88=A0=E9=99=A4=E5=90=8E=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E5=AF=BC=E8=87=B4=E6=95=B0=E6=8D=AE=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A4=E6=96=ADwindow=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E4=B8=BA=E6=A1=86=E6=9E=B6window=E7=9A=84=E6=96=B9=E5=BC=8F=20?= =?UTF-8?q?*=20Merge=20branch=20'upstream-main'=20*=20fix:=20=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=9C=AA=E5=90=AF=E7=94=A8=E5=88=86=E9=A1=B5=E6=97=B6?= =?UTF-8?q?=E6=89=93=E5=BC=80=E8=A1=A8=E5=8D=95=E6=8A=A5=E9=94=99=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E4=BF=AE=E5=A4=8Drenderer?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=A0=87=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=A1=A8=E6=A0=BC=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=94=81=E5=AE=9A=E5=B1=9E=E6=80=A7=E9=9B=86=E6=88=90?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=20*=20chore:=20=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=A0=91=E8=A1=A8=E6=A0=BC=E5=BD=93=E5=89=8D=E8=A1=8C=E5=89=8D?= =?UTF-8?q?=E5=85=88=E5=88=A4=E6=96=AD=E5=BD=93=E5=89=8D=E8=A1=8C=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E4=B8=80=E8=87=B4=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=96=E6=B6=88=E5=90=8E=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9C=AA=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E6=94=AF=E6=8C=81=E5=A2=9E=E9=87=8F?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20fix:=20=E6=9C=AA=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E6=95=B0=E6=8D=AE=E6=BA=90=E6=97=B6=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=8F=8C=E5=88=97=E8=A1=A8=E5=AD=90=E8=A1=A8=E6=97=A0?= =?UTF-8?q?=E7=84=A6=E7=82=B9=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=20*=20feature:=20=E8=A1=A8=E6=A0=BC=E5=88=97=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20*=20feature:=20=E5=8D=A1=E7=89=87=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=9C=BA=E7=AD=89=20*=20fix:=20=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=97=A0=E6=95=B0=E6=8D=AE=E6=97=B6=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=BD=93=E5=89=8D=E8=A1=8C=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E6=8E=A7=E4=BB=B6id=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=B8=AE=E5=8A=A9=E5=88=86=E9=9A=94=E7=AC=A6=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E4=BD=8D=E7=BD=AE=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20chore:=20=E6=9A=82=E6=97=B6=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=9B=B4=E6=96=B0=E8=A1=A8=E6=A0=BC=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8E=E5=86=8D=E5=90=AF=E7=94=A8=20*=20ch?= =?UTF-8?q?ore:=20=E6=89=93=E5=8C=85=E6=8E=92=E9=99=A4=E5=A4=A9=E6=B0=94?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20*=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E6=94=AF=E6=8C=81=E5=AD=90=E8=8A=82=E7=82=B9=E5=8F=8A?= =?UTF-8?q?slots=20*=20fix:=20=E5=8D=95=E9=80=89=E7=BB=84=E5=80=BC?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E5=80=BC=E5=8F=98=E5=8C=96=E5=9C=BA=E6=99=AF=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=A1=A8=E6=A0=BC=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE=20*=20fix:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'upstream-main'=20*=20feature:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83=20*=20ch?= =?UTF-8?q?ore:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20preview=E9=A1=B5=E9=9D=A2=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=9B=9E=E8=B0=83=20*=20chore:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20*=20chore:=20=E6=A0=91=E5=8A=A0=E8=BD=BD=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=94=AF=E6=8C=81=E8=BF=87=E6=BB=A4=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20checkbox?= =?UTF-8?q?=20checked=E5=B1=9E=E6=80=A7=E5=80=BC=E4=B8=8D=E6=98=AF?= =?UTF-8?q?=E5=B8=83=E5=B0=94=E7=B1=BB=E5=9E=8B=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20=E6=A0=91?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=96=B0=E5=A2=9E=E6=97=A0=E6=B3=95=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=B8=8A=E6=AC=A1=E5=BD=93=E5=89=8D=E8=A1=8C=E7=AD=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=B8=8A=E4=B8=8B=E6=96=87=20*=20chore:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=A0=91=E6=95=B0=E6=8D=AE=E6=BA=90=E7=BB=93?= =?UTF-8?q?=E6=9E=84=20*=20chore:=20=E6=A0=91=E8=A1=A8=E6=A0=BC=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81=E6=9C=BA=20*=20ch?= =?UTF-8?q?ore:=20section=E7=BB=84=E4=BB=B6=E5=A2=9E=E5=8A=A0=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=BA=94=E7=94=A8=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20feature:=20section=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=20*=20chore:=20=E6=A0=91=E8=8A=82=E7=82=B9=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=97=B6=E6=94=AF=E6=8C=81=E9=87=8D=E6=96=B0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=20*=20fix:=20=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E9=9A=90=E8=97=8F=E6=97=B6=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=AC=AC=E4=B8=80=E4=B8=AA=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E6=9D=A1=E4=BB=B6=E7=9A=84Relation=E4=B8=BA0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20fix:=20=E7=82=B9=E5=87=BB=E8=A1=8C=E6=97=B6=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E4=B8=A4=E6=AC=A1=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BB=8E=E8=A1=A8=E4=BB=8E=E4=BB=8E=E8=A1=A8?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=80=92=E5=BD=92=E6=96=B0=E5=A2=9E=E4=B8=BB=E4=BB=8E=E4=BB=8E?= =?UTF-8?q?=E8=A1=A8=E6=95=B0=E6=8D=AE=20*=20feature:=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E6=8C=89=E9=92=AE=E6=94=AF=E6=8C=81=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=8A=E4=BE=9D=E8=B5=96=E8=A7=A3=E6=9E=90=20*=20chore:=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=85=B7=E6=A0=8F=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=20*=20fix:=20=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E9=80=92=E5=BD=92=E5=AF=BC=E8=87=B4=E7=95=8C=E9=9D=A2=E5=8D=A1?= =?UTF-8?q?=E6=AD=BB=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20chore:=20=E4=BF=AE=E6=94=B9=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*=20ch?= =?UTF-8?q?ore:=20=E8=BF=90=E8=A1=8C=E6=97=B6=E6=94=AF=E6=8C=81=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A1=A8=E6=A0=BC=E8=BF=9B=E5=85=A5=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=80=81=E6=97=B6=E5=88=97=E6=97=A0=E6=B3=95=E4=B8=8E=E8=A1=A8?= =?UTF-8?q?=E5=A4=B4=E5=AF=B9=E9=BD=90=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E9=87=8D=E6=96=B0=E5=8A=A0=E8=BD=BD=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=B0=83=E7=94=A8setProps=E7=BB=84=E4=BB=B6=E4=B8=8D=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E6=B8=B2=E6=9F=93=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E6=9B=B4=E6=96=B0=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=B3=A8=E9=87=8A=20*=20feature:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=B1=9E=E6=80=A7=20*=20chore:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=85=BC=E5=AE=B9=E4=BB=A3=E7=A0=81=20*=20Merge=20bra?= =?UTF-8?q?nch=20'upstream-main'=20*=20chore:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E7=AD=9B=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E6=9C=80=E5=90=8E=E4=B8=80=E4=B8=AA=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?Relation=E4=BF=AE=E6=94=B9=E4=B8=BA0=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E5=91=BD=E4=BB=A4=E8=BD=AC?= =?UTF-8?q?=E8=B0=83=E6=94=AF=E6=8C=81=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=20*=20feature:=20=E6=94=AF=E6=8C=81=E8=A7=A3=E6=9E=90=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=E6=9C=8D=E5=8A=A1=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20chore:=20=E5=AD=90?= =?UTF-8?q?=E8=A1=A8=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E5=B9=B6=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=20*=20fix:=20=E5=8F=8C=E5=88=97=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E9=AB=98=E7=BA=A7=E5=88=97=E5=8D=A1=E5=AD=90=E8=A1=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E5=AF=B9=E9=BD=90=E8=A1=A8=E6=A0=BCschema=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E5=88=86=E9=A1=B5=E4=B8=8D=E5=8F=97=E6=8E=A7?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=AE=9E=E4=BD=93=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E6=95=B0=E6=8D=AE=E6=94=AF=E6=8C=81=E5=88=B7?= =?UTF-8?q?=E6=96=B0=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=AD=90=E8=A1=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8D=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E8=B7=AF=E5=BE=84=E8=A7=A3=E6=9E=90=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=88=9B=E5=BB=BA=20*=20fix:=20=E6=9C=AA?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E6=95=B0=E6=8D=AE=E5=88=B7=E6=96=B0=E6=97=B6?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=88=B0=E5=88=97=E8=A1=A8=E4=BB=8D=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E6=8D=AE=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20Merge=20branch=20'upstream?= =?UTF-8?q?-main'=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8A=A0=E8=BD=BD=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E6=9E=84=E4=BB=B6=E3=80=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89web=E6=9E=84=E4=BB=B6=E5=85=83=E6=95=B0=E6=8D=AE=20*?= =?UTF-8?q?=20refactor:=20=E4=BF=AE=E5=A4=8Dbinding=E6=89=93=E5=8C=85?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20refactor:=20=E4=BF=AE=E6=94=B9command-?= =?UTF-8?q?services=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bef=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*?= =?UTF-8?q?=20refactor:=20=E4=BF=AE=E6=94=B9devkit=E6=89=93=E5=8C=85?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20chore:=20=E5=AE=8C=E5=96=84=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E6=94=AF=E6=8C=81=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E6=9D=A1=E4=BB=B6=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20chore:=20=E4=BF=AE=E6=94=B9=E5=B1=9E=E6=80=A7=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=96=B9=E5=BC=8F=20*=20chore:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=98=A0=E5=B0=84=E5=AD=97=E6=AE=B5=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E5=A2=9E=E5=8A=A0=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E5=A3=B0=E6=98=8E=20*=20chore:=20=E6=B3=A8?= =?UTF-8?q?=E5=85=A5renderEngine=E5=88=B0=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=EF=BC=8C=E4=BF=9D=E8=AF=81=E5=BC=80=E5=8F=91=E8=80=85=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E5=9C=A8=E6=9E=84=E4=BB=B6=E4=B8=AD=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=88=B0=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=20*=20fix:=20?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E8=BF=9B=E5=85=A5=E8=8F=9C=E5=8D=95=E6=97=B6?= =?UTF-8?q?=E6=9C=AA=E9=87=8D=E6=96=B0=E5=88=9B=E5=BB=BA=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20feature:=20=E5=8F=AF=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E8=A1=A8=E6=A0=BC=E5=B8=AE=E5=8A=A9=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=97=B6=E6=9B=B4=E6=96=B0=E6=98=A0=E5=B0=84=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=80=BC=E5=88=B0=E8=A1=A8=E6=A0=BC=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9MODULE=5FCONFIG=5FID=20token=E7=BC=96=E5=8F=B7=20*=20f?= =?UTF-8?q?ix:=20=E8=BF=90=E8=A1=8C=E6=A1=86=E6=9E=B6tabid=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20chore:=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88=E4=BB=A3=E7=A0=81=20*=20ch?= =?UTF-8?q?ore:=20=E5=8F=82=E6=95=B0=E8=A7=A3=E6=9E=90=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84=20*=20chore:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A1=A8=E6=A0=BC=E5=88=86=E9=A1=B5=E5=A4=A7=E5=B0=8F?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=20*=20feature:=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E5=B9=B6?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=8E=A5=E5=8F=A3=20*=20fix:=20=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E7=BB=99=E7=BB=84=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=8E=E7=BB=84=E4=BB=B6=E6=9C=AC=E8=BA=AB=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E4=B8=8D=E4=B8=80=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E5=88=A0=E9=99=A4=E6=97=A5=E5=BF=97=20*=20fix:=20=E4=B8=8B?= =?UTF-8?q?=E6=8B=89=E6=A1=86=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20feature:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E9=9B=86=E6=88=90=E5=8F=98=E9=87=8F=20*=20fe?= =?UTF-8?q?ature:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=8F=98=E6=9B=B4=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=A1=A5=E5=85=85=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9command-services-vue=E7=9B=AE=E5=BD=95=E4=B8=BAcommand?= =?UTF-8?q?-services=20*=20chore:=20=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20chore:=20=E6=B8=B2=E6=9F=93=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E9=87=8D=E6=9E=84=20*=20chore:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E7=BC=96=E8=BE=91=E5=88=97=E8=A1=A8=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20fix:=20eslint?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=94=99=E8=AF=AF=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20update=20pnpm-lock.yaml=20*=20chore?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E5=8A=9F=E8=83=BD=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=BD=AC=E6=8D=A2=E6=97=B6=E5=BF=BD=E7=95=A5?= =?UTF-8?q?type=20*=20chore:=20=E4=BF=AE=E6=94=B9=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=B9=E5=BC=8F=20*=20chore:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E8=BE=93=E5=85=A5=E6=A1=86schema=E4=B8=ADrequired?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E6=B8=85=E7=A9=BA=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86undefined=E5=B1=9E=E6=80=A7=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=B8=8B=E6=8B=89=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=88=A0=E9=99=A4checkbox?= =?UTF-8?q?=E7=9A=84require=E5=B1=9E=E6=80=A7=EF=BC=8C=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=AF=A5=E5=B1=9E=E6=80=A7=20*=20chore:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=A7=A3=E6=9E=90=E5=BC=95=E6=93=8E=20*=20ch?= =?UTF-8?q?ore:=20=E9=80=82=E9=85=8D=E6=8E=A7=E5=88=B6=E5=99=A8=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20*=20chore:=20=E9=85=8D=E7=BD=AE=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E4=BF=AE=E6=94=B9=E4=B8=BA=E5=A4=96=E9=83=A8?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=20*=20chore:=20=E8=A1=A8=E6=A0=BCeditable?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9B=86=E6=88=90=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=20*=20chore:=20=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20*=20chore:=20=E9=80=82=E9=85=8D=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E4=BF=AE=E6=94=B9=20*=20fix:=20BorderEditor=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=B3=A8=E5=86=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E5=8D=A1=E7=89=87=E8=B7=B3=E5=9B=9E=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E6=97=B6=E5=BD=93=E5=89=8D=E8=A1=8C=E6=9C=AA?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E9=9B=86=E6=88=90=E7=8A=B6=E6=80=81=E6=9C=BA=20*=20chore:?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E7=8A=B6=E6=80=81=E6=9C=BA=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=20*=20fix:=20=E7=8A=B6=E6=80=81=E6=9C=BA=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=A4=9A=E4=B8=AA=E5=AE=9E=E4=BE=8B=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E5=B8=AE=E5=8A=A9=E6=94=AF=E6=8C=81=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E5=B7=B2=E9=80=89=E8=AE=B0=E5=BD=95=20*=20chore:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20*=20chore:=20=E5=90=8C=E6=AD=A5=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E4=BF=AE=E6=94=B9=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=BD=AC=E8=B0=83=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87=E7=BB=84=E4=BB=B6?= =?UTF-8?q?id=E6=89=A7=E8=A1=8C=E5=91=BD=E4=BB=A4=20*=20fix:=20=E5=AD=90?= =?UTF-8?q?=E8=A1=A8=E5=8F=98=E6=9B=B4=E9=9B=86=E7=BB=84=E8=A3=85=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=A2=9E=E5=8A=A0=E7=BB=84=E4=BB=B6id?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E6=94=AF=E6=8C=81=E5=B8=AE=E5=8A=A9=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E3=80=81=E8=A1=A8=E6=A0=BC=E5=80=BC=E5=8F=98=E5=8C=96=E3=80=81?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E9=A1=B5=E7=A0=81=E5=88=87=E6=8D=A2=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=A4=9A=E6=AC=A1=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=89=93=E5=8C=85?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E4=BF=AE=E6=94=B9=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91=E5=AE=9A=E4=B8=8E=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=88=86=E9=A1=B5=E6=89=A7=E8=A1=8C=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=20*=20chore:=20=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=86=E9=A1=B5=20*=20chore:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20ch?= =?UTF-8?q?ore:=20update=20lock=20file=20*=20chore:=20update=20gitignore?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E4=BD=BF=E7=94=A8=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E5=85=83=E6=95=B0=E6=8D=AE=20*=20chore:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4logger=20*=20fix:=20=E5=8A=9F=E8=83=BD=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E9=97=AE=E9=A2=98=20*=20chore:=20=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=97=B6=E5=A2=9E=E5=8A=A0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=20*=20chore:=20=E7=A7=BB=E9=99=A4lo?= =?UTF-8?q?gger=E3=80=81=E4=BD=BF=E7=94=A8=E9=80=9A=E7=94=A8=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86=E5=99=A8=20*=20chore:=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9Eevent-handler=E8=A7=A3=E6=9E=90=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4=E5=AD=90=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=97=B6=E6=9C=AA=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E7=A6=81=E7=94=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=B7=E6=96=B0=20*=20refactor:=20=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E5=99=A8=20*=20ch?= =?UTF-8?q?ore:=20=E5=A2=9E=E5=8A=A0=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=E8=A7=A3=E6=9E=90=E5=99=A8=20*=20chore:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=A0=91=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=20*=20fix:=20=E6=A0=91=E8=A1=A8=E6=A0=BC=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=A1=8C=E4=B8=8E=E6=8E=A7=E5=88=B6=E5=99=A8=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=A1=8C=E4=B8=8D=E4=B8=80=E8=87=B4=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E6=94=AF=E6=8C=81=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E5=AE=9E=E4=BD=93=E5=8F=98=E6=9B=B4=20*=20fi?= =?UTF-8?q?x:=20#IB8JC7=20=E5=8A=9F=E8=83=BD=E5=AE=A1=E6=9F=A5=EF=BC=9A?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=EF=BC=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=B8=BB=E8=A1=A8=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E6=8C=87=E5=AE=9A=E6=9C=89=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E4=BA=8B=E4=BB=B6=E6=89=A7=E8=A1=8C=E5=A4=9A=E6=AC=A1?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20refactor:=20=E9=87=8D=E6=9E=84render=20*=20chore:=20l?= =?UTF-8?q?ogger=E6=94=AF=E6=8C=81rollup=E6=89=93=E5=8C=85=20*=20chore:=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=BF=90=E8=A1=8C=E6=8C=89=E9=92=AE=E6=89=93?= =?UTF-8?q?=E5=BC=80=E9=A1=B5=E9=9D=A2=E5=9C=B0=E5=9D=80=E5=8F=8A=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20into=20dev=20*=20chor?= =?UTF-8?q?e:=20update=20gitignore=20*=20chore:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=A8=A1=E5=9D=97=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20feature:=20renderer=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=A1=B5=E7=AD=BE=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20*=20chore:=20viewmodel=E9=85=8D=E7=BD=AE=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=BB=91=E5=AE=9A=E8=B7=AF=E5=BE=84=20*=20chore:=20ta?= =?UTF-8?q?bs=E5=A2=9E=E5=8A=A0Click=E4=BA=8B=E4=BB=B6=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=20*=20chore:=20viewmodel=E6=94=AF=E6=8C=81=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20feature:=20=E6=94=AF=E6=8C=81=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=81=E5=88=A0=E9=99=A4=E5=AD=90=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20*=20chore:=20=E4=BF=AE=E6=94=B9schema=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=20*=20chore:=20=E6=8E=A7=E5=88=B6=E5=99=A8=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98=E6=97=B6=E4=B8=AD?= =?UTF-8?q?=E6=96=AD=E6=95=B4=E4=B8=AA=E5=91=BD=E4=BB=A4=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91=E5=AE=9A=E6=9C=AA?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E6=95=B0=E6=8D=AE=E6=BA=90=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A1=A8=E6=A0=BC=E7=BB=84=E4=BB=B6=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E8=A1=8C=E6=97=B6=E6=97=A0=E6=B3=95=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20tabs?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E6=8C=89=E9=92=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree-grid=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=91=E5=AE=9A=E4=B8=BAnull=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20refactor:=20=E9=87=8D=E6=9E=84=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change-resolver/change-resolve-service.ts | 19 +- .../src/change-resolver/change-resolver.ts | 3 +- .../entity-store-change-resolver.ts | 12 +- .../state-machine-change-resolver.ts | 12 +- .../ui-state-change-resolver.ts | 16 +- ...id-component-config-dependency-resolver.ts | 14 +- ...up-component-config-dependency-resolver.ts | 6 +- ...er-component-config-dependency-resolver.ts | 2 +- ...ar-component-config-dependency-resolver.ts | 2 +- ...on-component-config-dependency-resolver.ts | 2 +- ...ge-component-config-dependency-resolver.ts | 2 +- ...id-component-config-dependency-resolver.ts | 8 +- packages/renderer/src/config/types.ts | 1 + .../renderer/src/form-engine/form-engine.ts | 87 +++++++- .../src/render-engine/render-engine-impl.ts | 5 +- .../dynamic-resolver/src/props-resolver.ts | 7 +- .../dynamic-resolver/src/schema-resolver.ts | 2 +- .../src/dynamic-view.component.tsx | 204 +++++++++++++++--- 18 files changed, 320 insertions(+), 84 deletions(-) diff --git a/packages/renderer/src/change-resolver/change-resolve-service.ts b/packages/renderer/src/change-resolver/change-resolve-service.ts index a2281fad6e2..991fb03b391 100644 --- a/packages/renderer/src/change-resolver/change-resolve-service.ts +++ b/packages/renderer/src/change-resolver/change-resolve-service.ts @@ -1,17 +1,24 @@ - import { Change } from "../change-observer"; +import { Change } from "../change-observer"; +import { Config } from "../config"; import { ChangeResolver } from "./change-resolver"; import { ChangeResolverRegistry } from "./change-resolver-registry"; export class ChangeResolveService { constructor(private changeResolverRegistry: ChangeResolverRegistry) { } - public resolve(change: Change): string[] { - return this.changeResolverRegistry.registry.reduce((results: string[], resolver: ChangeResolver) => { + public resolve(change: Change): Map { + return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeResolver) => { const result = resolver.resolve(change); - if (result && result.length > 0) { - results.push(...result); + if (result && result.size > 0) { + result.keys().forEach((componentId: string)=>{ + if (results.has(componentId)) { + results.get(componentId)!.push(...result.get(componentId)!); + } else { + results.set(componentId, result.get(componentId)!); + } + }); } return results; - }, []); + }, new Map()); } } diff --git a/packages/renderer/src/change-resolver/change-resolver.ts b/packages/renderer/src/change-resolver/change-resolver.ts index 798c9f5910f..e39366bb141 100644 --- a/packages/renderer/src/change-resolver/change-resolver.ts +++ b/packages/renderer/src/change-resolver/change-resolver.ts @@ -1,5 +1,6 @@ import { Change } from "../change-observer"; +import { Config } from "../config"; export abstract class ChangeResolver { - public abstract resolve(change: Change): string[] | null; + public abstract resolve(change: Change): Map | null; } diff --git a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts index ac61aed36f1..39f13d95102 100644 --- a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts +++ b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts @@ -9,23 +9,23 @@ export class EntityStoreChangeResolver extends ChangeResolver>): string[] | null { + public resolve(change: Change>): Map | null { if (change.source !== ChangeSource.EntityState) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const components: string[] = []; + const result: Map = new Map(); registry.entries().forEach(([id, configs]) => { - const index = configs.findIndex((config: Config) => { + const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { return dependency.type === DependencyType.EntityState; }); return !!match; }); - if (index !== -1) { - components.push(id); + if (matchedConfigs && matchedConfigs.length > 0) { + result.set(id, matchedConfigs); } }); - return components; + return result; } } diff --git a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts index a953cad771a..d7a80d720a1 100644 --- a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts +++ b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts @@ -9,23 +9,23 @@ export class StateMachineChangeResolver extends ChangeResolver>) { + public resolve(change: Change>): Map | null{ if (change.source !== ChangeSource.StateMachine) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const components: string[] = []; + const result: Map = new Map(); registry.entries().forEach(([id, configs]) => { - const index = configs.findIndex((config: Config) => { + const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { return dependency.type === DependencyType.StateMachine; }); return !!match; }); - if (index !== -1) { - components.push(id); + if (matchedConfigs && matchedConfigs.length > 0) { + result.set(id, matchedConfigs); } }); - return components; + return result; } } diff --git a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts index bbbcef6f449..97ebea303a7 100644 --- a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts +++ b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts @@ -9,23 +9,23 @@ export class UIStateChangeResolver extends ChangeResolver { super(); } - public resolve(change: Change): string[] | null { + public resolve(change: Change): Map | null { if (change.source !== ChangeSource.UIState) { return null; } const registry = this.componentConfigDependencyRegistry.getComponents(); - const components: string[] = []; + const result: Map = new Map(); registry.entries().forEach(([id, configs]) => { - const index = configs.findIndex((config: Config) => { + const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { - return dependency.type === DependencyType.EntityState; + return dependency.type === DependencyType.UIState; }); - return !!match; + return !!match;; }); - if (index !== -1) { - components.push(id); + if (matchedConfigs && matchedConfigs.length > 0) { + result.set(id, matchedConfigs); } }); - return components; + return result; } } diff --git a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts index c7e80e51006..7ae74d01d8f 100644 --- a/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/data-grid-component-config-dependency-resolver.ts @@ -16,17 +16,17 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe const configs: Config[] = []; const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); if (editableConfigDeps) { - configs.push({ deps: editableConfigDeps, config: editable }); + configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); } const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (disabledConfigDeps) { - configs.push({ deps: disabledConfigDeps, config: disabled }); + configs.push({ deps: disabledConfigDeps, config: disabled, path: '/disabled' }); } if (pagination) { const { disabled = false } = pagination; const paginationDisabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (paginationDisabledConfigDeps) { - configs.push({ deps: paginationDisabledConfigDeps, config: disabled }); + configs.push({ deps: paginationDisabledConfigDeps, config: disabled, path: '/pagination/disabled' }); } } @@ -34,20 +34,20 @@ export class DataGridComponentConfigDependencyResolver extends ComponentConfigDe return configs && configs.length > 0 ? configs : null; } return fields.reduce((configs: Config[], field: Record) => { - const { visible, editor } = field; + const { visible, editor, id } = field; const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); if (visibleConfigDeps) { - configs.push({ deps: visibleConfigDeps, config: visible }); + configs.push({ deps: visibleConfigDeps, config: visible, path: `/columns/${id}:visible` }); } if (editor) { const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly); if (readonlyConfigDeps) { - configs.push({ deps: readonlyConfigDeps, config: editor?.readonly }); + configs.push({ deps: readonlyConfigDeps, config: editor?.readonly, path: `columns/${id}:editor/readonly` }); } const disabledConfigDeps = this.configDepencencyResolveService.resolve(editor?.disabled); if (disabledConfigDeps) { - configs.push({ deps: disabledConfigDeps, config: editor?.disabled }); + configs.push({ deps: disabledConfigDeps, config: editor?.disabled , path: `columns/${id}:editor/disabled`}); } } return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts index ffe97a4d486..ad786a97c3a 100644 --- a/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/form-group-component-config-dependency-resolver.ts @@ -20,15 +20,15 @@ export class FormGroupComponentConfigDependencyResolver extends ComponentConfigD const configs = []; const readonlyConfigDeps = this.configDepencencyResolveService.resolve(readonly); if (readonlyConfigDeps) { - configs.push({ deps: readonlyConfigDeps, config: readonly }); + configs.push({ deps: readonlyConfigDeps, config: readonly, path: '/editor/readonly' }); } const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (disabledConfigDeps) { - configs.push({ deps: disabledConfigDeps, config: disabled }); + configs.push({ deps: disabledConfigDeps, config: disabled, path: '/editor/disabled' }); } const requiredConfigDeps = this.configDepencencyResolveService.resolve(required); if (requiredConfigDeps) { - configs.push({ deps: requiredConfigDeps, config: required }); + configs.push({ deps: requiredConfigDeps, config: required, path: '/editor/required' }); } return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts index ce0917774a0..bb39af9d3da 100644 --- a/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/page-header-component-config-dependency-resolver.ts @@ -25,7 +25,7 @@ export class PageHeaderComponentConfigDependencyResolver extends ComponentConfig const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (diabledConfigDeps) { - configs.push({ deps: diabledConfigDeps, config: disabled }); + configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } }); return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts index cc1c90a7ac7..28085db3955 100644 --- a/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/response-toolbar-component-config-dependency-resolver.ts @@ -24,7 +24,7 @@ export class ResponseToolbarComponentConfigDependencyResolver extends ComponentC const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (diabledConfigDeps) { - configs.push({ deps: diabledConfigDeps, config: disabled }); + configs.push({ deps: diabledConfigDeps, config: disabled, path: `/buttons/${button.id}:disabled` }); } }); return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts index 7a183a00003..5c9aabe711e 100644 --- a/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/section-component-config-dependency-resolver.ts @@ -24,7 +24,7 @@ export class SectionComponentConfigDependencyResolver extends ComponentConfigDep const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (diabledConfigDeps) { - configs.push({ deps: diabledConfigDeps, config: disabled }); + configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } }); return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts index 24586160792..a3e36aca7e0 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tab-page-component-config-dependency-resolver.ts @@ -24,7 +24,7 @@ export class TabPageComponentConfigDependencyResolver extends ComponentConfigDep const { disabled, visible } = button; const diabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (diabledConfigDeps) { - configs.push({ deps: diabledConfigDeps, config: disabled }); + configs.push({ deps: diabledConfigDeps, config: disabled, path: `/toolbar/buttons/${button.id}:disabled` }); } }); return configs; diff --git a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts index d3aa9aa0ae7..6157aa7566a 100644 --- a/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts +++ b/packages/renderer/src/component-config-dependency-resolver/tree-grid-component-config-dependency-resolver.ts @@ -16,11 +16,11 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe const configs: Config[] = []; const editableConfigDeps = this.configDepencencyResolveService.resolve(editable); if (editableConfigDeps) { - configs.push({ deps: editableConfigDeps, config: editable }); + configs.push({ deps: editableConfigDeps, config: editable, path: '/editable' }); } const disabledConfigDeps = this.configDepencencyResolveService.resolve(disabled); if (disabledConfigDeps) { - configs.push({ deps: disabledConfigDeps, config: disabled }); + configs.push({ deps: disabledConfigDeps, config: disabled, path: '/disabled' }); } if (!id || !fields || !Array.isArray(fields) || fields.length < 1) { return configs && configs.length > 0 ? configs : null; @@ -29,12 +29,12 @@ export class TreeGridComponentConfigDependencyResolver extends ComponentConfigDe const { visible, editor } = field; const visibleConfigDeps = this.configDepencencyResolveService.resolve(visible); if (visibleConfigDeps) { - configs.push({ deps: visibleConfigDeps, config: visible }); + configs.push({ deps: visibleConfigDeps, config: visible, path: `/columns/${field.id}:visible` }); } if (editor) { const readonlyConfigDeps = this.configDepencencyResolveService.resolve(editor?.readonly); if (readonlyConfigDeps) { - configs.push({ deps: readonlyConfigDeps, config: editor?.readonly }); + configs.push({ deps: readonlyConfigDeps, config: editor?.readonly, path: `/columns/${field.id}:editor/readonly` }); } } return configs; diff --git a/packages/renderer/src/config/types.ts b/packages/renderer/src/config/types.ts index faf53f16ea0..2231120e8d2 100644 --- a/packages/renderer/src/config/types.ts +++ b/packages/renderer/src/config/types.ts @@ -13,4 +13,5 @@ export interface ConfigDependency { export interface Config { config: string | boolean; deps: ConfigDependency[]; + path: string; } diff --git a/packages/renderer/src/form-engine/form-engine.ts b/packages/renderer/src/form-engine/form-engine.ts index e880b56c226..bd45b32651b 100644 --- a/packages/renderer/src/form-engine/form-engine.ts +++ b/packages/renderer/src/form-engine/form-engine.ts @@ -1,9 +1,10 @@ - import { cloneDeep } from "lodash-es"; +import { cloneDeep, merge, mergeWith } from "lodash-es"; import { Change, ChangeObserver, ChangeObserverRegistry } from "../change-observer"; import { ChangeResolveService } from "../change-resolver"; import { ComponentConfigResolveService } from "../component-config-resolver"; import { RenderEngineImpl } from "../render-engine"; import { FormMetadataService } from "../service"; +import { Config } from "../config"; export class FormEngine { constructor( @@ -15,16 +16,22 @@ export class FormEngine { ) { this.changeObserverRegistry.observers.forEach((observer: ChangeObserver) => { observer.observe((change: Change) => { - const componentIds = this.changeResolveService.resolve(change); - if (componentIds && componentIds.length > 0) { - componentIds.forEach((id: string) => { - const metadata = this.formMetadataService.getMetadataById(id); + const results: Map = this.changeResolveService.resolve(change); + if (results && results.size > 0) { + results.forEach((configs: Config[], componentId: string) => { + const metadata = this.formMetadataService.getMetadataById(componentId); if (!metadata) { return; } const schema = cloneDeep(metadata); const resolvedSchema = this.componentConfigResolveService.resolve(schema); - this.renderEngineImpl.render(id, resolvedSchema); + // 过滤schema属性,仅解析发生变化的属性 + const changedSchema = {}; + configs.forEach((config: Config) => { + const filteredSchema = this.filterSchema(resolvedSchema, config); + mergeWith(changedSchema, filteredSchema, this.mergeArray); + }); + this.renderEngineImpl.render(componentId, resolvedSchema.type, changedSchema); }); } }); @@ -39,4 +46,72 @@ export class FormEngine { } }); } + filterSchema(schema: any, config: Config): Record { + const filteredSchema: Record = {}; + + // configs.forEach((config: Config) => { + const { path } = config; + const paths = path.split('/').filter((p: string) => p); + if (paths.length < 1) { + return {}; + } + let currentSchema = schema; + let currentFilteredSchema = filteredSchema; + + paths.forEach((pathSegment: string, index: number) => { + const [key, value] = pathSegment.split(':'); + const isLast = index === paths.length - 1; + if (value) { + if (!Array.isArray(currentSchema)) { + throw new Error(`Expected array at path ${pathSegment}`); + } + // eslint-disable-next-line eqeqeq + const itemIndex = currentSchema.findIndex((item) => item.id == key); + if (itemIndex === -1) { + throw new Error(`Item with id ${value} not found at path ${pathSegment}`); + } + currentSchema = currentSchema[itemIndex];// object + const item = { id: key, [value]: currentSchema[value] }; + currentFilteredSchema.push(item); + currentFilteredSchema = item[value]; + currentSchema = currentSchema[value]; + } else { + if (isLast) { + currentFilteredSchema[key] = currentSchema[key]; + } + else { + currentSchema = currentSchema[key]; + currentFilteredSchema[key] = currentFilteredSchema[key] || paths[index + 1].indexOf(':') !== -1 ? [] : {}; + currentFilteredSchema = currentFilteredSchema[key]; + } + } + }); + // }); + return filteredSchema; + } + private mergeArray(target: any, source: any) { + if (Array.isArray(target) && Array.isArray(source)) { + const mergedMap = new Map(); + target.forEach(item => { + if (item.id != null) { + mergedMap.set(item.id, cloneDeep(item)); + } + }); + + // 合并源数组元素到Map,存在则深度合并 + source.forEach(item => { + if (item.id != null) { + const existing = mergedMap.get(item.id); + if (existing) { + // 合并现有元素和当前元素 + mergedMap.set(item.id, merge(existing, item)); + } else { + mergedMap.set(item.id, cloneDeep(item)); + } + } + }); + const combined = Array.from(mergedMap.values()); + return combined; + } + } } diff --git a/packages/renderer/src/render-engine/render-engine-impl.ts b/packages/renderer/src/render-engine/render-engine-impl.ts index 1f88e19af90..8a55a7876e4 100644 --- a/packages/renderer/src/render-engine/render-engine-impl.ts +++ b/packages/renderer/src/render-engine/render-engine-impl.ts @@ -10,8 +10,9 @@ export class RenderEngineImpl implements RenderEngine { this.renderer = renderRef; } - public render(componentId: string, schema: Record) { - this.renderer.value.setSchema(componentId, schema); + public render(componentId: string, type: string,schema: Record) { + const props = this.renderer.value.convertPartialSchemaToProps(type,schema); + this.renderer.value.setProps(componentId, props); } public rerender(componentId: string) { diff --git a/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts index c1d99b457bf..8884abfc439 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -1,5 +1,5 @@ import { DesignerHostService } from './../../designer-canvas/src/composition/types'; -import { resolveSchemaToProps, schemaMap, schemaResolverMap } from './schema-resolver'; +import { mappingSchemaToProps, resolveSchemaToProps, schemaMap, schemaResolverMap } from './schema-resolver'; import { DynamicResolver, EffectFunction, MapperFunction, SchemaResolverFunction } from './types'; import { propertyConfigSchemaMap, propertyEffectMap } from './property-config-resolver'; @@ -20,7 +20,10 @@ export function createPropsResolver>( schemaResolverMap[defaultSchema.title] = schemaResolver; propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; propertyEffectMap[defaultSchema.title] = propertyEffect; - return (schemaValue: Record = {}) => { + return (schemaValue: Record = {}, mergeDefaults: boolean = true) => { + if (!mergeDefaults) { + return mappingSchemaToProps(schemaValue, schemaMapper); + } const resolvedPropsValue = resolveSchemaToProps(schemaValue, defaultSchema, schemaMapper); const defaultProps = Object.keys(componentPropsObject).reduce((propsObject: Record, propKey: string) => { propsObject[propKey] = componentPropsObject[propKey].default; diff --git a/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts b/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts index d2dada2e4dc..d9adc5dfc35 100644 --- a/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts +++ b/packages/ui-vue/components/dynamic-resolver/src/schema-resolver.ts @@ -131,4 +131,4 @@ function resolveSchemaWithDefaultValue(schemaValue: Record): Record return schemaValue; } -export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap }; +export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap, mappingSchemaToProps }; diff --git a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index 09c1a1466cf..df3e1792afa 100644 --- a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-function-type */ /* eslint-disable no-use-before-define */ import { SetupContext, defineComponent, ref, watch, inject, createVNode, VNode, reactive, Reactive } from 'vue'; -import { merge } from 'lodash-es'; +import { cloneDeep, merge, mergeWith } from 'lodash-es'; import { dynamicViewProps, DynamicViewProps } from './dynamic-view.props'; import { componentMap, componentPropsConverter, loadRegister, resolverMap } from './components/maps'; import { createEventsResolver, createFormBindingResolver, EditorResolver, SelectionItemResolver, UpdateColumnsResolver } from '../../dynamic-resolver'; @@ -26,7 +26,8 @@ const FDynamicView = defineComponent({ const bindingData = useBindingData(modelValue, setupContext); const entityState = useEntityState(schema.value); entityState.setup(); - const componentState = new Map>(); + // const componentState = new Map>(); + const state = new Map; }>>(); function resolveModels(viewSchema: Record) { const componentType = viewSchema.type; @@ -154,7 +155,7 @@ const FDynamicView = defineComponent({ if (!Component) { return null; } - const { props, eventProps } = resolveProps(viewSchema); + // const { props, eventProps } = resolveProps(viewSchema); const renderChildren = () => { if (!viewSchema.contents) { @@ -165,29 +166,30 @@ const FDynamicView = defineComponent({ } return viewSchema.contents.map((schema: Record) => render(schema)); }; - const resolver = resolverMap[componentKey]; - const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; - if (editorResolver) { - const editor = editorResolver.resolve(viewSchema); - Object.assign(editor, eventProps); - } else { - Object.assign(props, eventProps); - } - const createNode = (componentType: any, props: Record | undefined, children?: null | undefined | any[]) => { + // const resolver = resolverMap[componentKey]; + // const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; + // if (editorResolver) { + // const editor = editorResolver.resolve(viewSchema); + // Object.assign(editor, eventProps); + // } else { + // Object.assign(props, eventProps); + // } + const createNode = (componentType: any, props: Record, children?: null | undefined | any[]) => { if (children && children.length > 0) { return createVNode(componentType, { ...props }, children); } else { return createVNode(componentType, { ...props }, null); } }; - componentState.set(viewSchema.id, reactive({ props })); - const reactivedProps = componentState.get(viewSchema.id).props; + // componentState.set(viewSchema.id, reactive({ props })); + // const reactivedProps = componentState.get(viewSchema.id).props; + const props = state.get(viewSchema.id)?.props || {}; if (viewSchema.contents && viewSchema.contents.length > 0) { - return createNode(Component, reactivedProps, [renderChildren()]); + return createNode(Component, props, [renderChildren()]); } else if (viewSchema.slots) { - return createNode(Component, reactivedProps, [...Object.values(renderSlots(viewSchema.slots))]); + return createNode(Component, props, [...Object.values(renderSlots(viewSchema.slots))]); } else { - return createNode(Component, reactivedProps); + return createNode(Component, props); } } @@ -197,13 +199,40 @@ const FDynamicView = defineComponent({ } } - function getProps(id: string): Record | undefined { - return componentState.get(id); + function getSchema(id: string) { + return schemaMap.get(id); + } + + function setSchema(id: string, partialSchema: Record) { + const elementSchema = schemaMap.get(id); + if (!elementSchema) { + return; + } + // const componentInstance = componentManager.get(id); + // if (!componentInstance) { + // return; + // } + merge(elementSchema, partialSchema); + convertSchemaToProps(elementSchema); + // TODO: 此处不能再更新表格组件了,因为表格组件的列是动态的 + // const componentKey = elementSchema.type; + // const resolver = resolverMap[componentKey]; + // const updateColumnsResolver: UpdateColumnsResolver = resolver ? resolver.updateColumnsResolver : null; + // if (updateColumnsResolver) { + // updateColumnsResolver.updateColumns(componentInstance, elementSchema); + // } + // rerender(componentInstance); + } + + function getProps(id: string): Record { + const instance = componentManager.get(id); + return instance.$props || {}; } function setProps(id: string, props: Record) { - const currentProps = componentState.get(id); - merge(currentProps.props, props); + const currentState = state.get(id); + mergeWith(currentState?.props, props, mergeArray); + // state.set(id, reactive({ props: { ...currentProps, ...props } })); } function invoke(id: string, method: string, ...args: any[]): any { @@ -235,16 +264,135 @@ const FDynamicView = defineComponent({ selectionMethodResolver.selectItemById(Component, id); } } + function convertSchemaToProps(viewSchema: Record) { + const componentKey = viewSchema.type; + if (componentKey === 'component-ref') { + const componentSchema = schema.value?.module?.components + .find((component: any) => component.id === viewSchema.component); + if (componentSchema) { + return convertSchemaToProps(componentSchema); + } + } + const Component = componentMap[componentKey]; + if (!Component) { + return; + } + const { props, eventProps } = resolveProps(viewSchema); + const resolver = resolverMap[componentKey]; + const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; + if (editorResolver) { + const editor = editorResolver.resolve(viewSchema); + Object.assign(editor, eventProps); + } else { + Object.assign(props, eventProps); + } + if (props && Object.keys(props).length > 0) { + const currentState = state.get(viewSchema.id); + if (!currentState) { + state.set(viewSchema.id, reactive({ props })); + } else { + merge(currentState?.props, props); + } + + // state.set(viewSchema.id, reactive({ props: { ...currentProps, ...props } })); + } + if (!viewSchema.contents || !Array.isArray(viewSchema.contents)) { + return; + } + viewSchema.contents.forEach((schema: Record) => convertSchemaToProps(schema)); + } + + function convertPartialSchemaToProps(type: string, viewSchema: Record) { + const propsConverter = componentPropsConverter[type]; + const componentProps: Record = propsConverter ? propsConverter(viewSchema, false) : {}; + return componentProps; + } + + function convertModelValueToProps(viewSchema: Record) { + const componentKey = viewSchema.type; + if (componentKey === 'component-ref') { + const componentSchema = schema.value?.module?.components + .find((component: any) => component.id === viewSchema.component); + if (componentSchema) { + return convertModelValueToProps(componentSchema); + } + } + const Component = componentMap[componentKey]; + if (!Component) { + return; + } + const modelProps = resolveModels(viewSchema); + if (modelProps && Object.keys(modelProps).length > 0) { + const currentState = state.get(viewSchema.id); + if (!currentState) { + state.set(viewSchema.id, reactive({ props: modelProps })); + } else { + merge(currentState?.props, modelProps); + } + // state.set(viewSchema.id, reactive({ props: { ...currentProps, ...modelProps } })); + } + if (!viewSchema.contents || !Array.isArray(viewSchema.contents)) { + return; + } + viewSchema.contents.forEach((schema: Record) => convertModelValueToProps(schema)); + } + function getFrameComponentSchema(): Record | null { + const components: Record[] = schema.value?.module?.components; + if (!components || components.length < 1) { + return null; + } + const frameComponent = components.find((component: Record) => component.componentType && component.componentType.toLowerCase() === 'frame'); + if (!frameComponent) { + return null; + } + return frameComponent; + } + + function mergeArray(target: any, source: any) { + if (Array.isArray(target) && Array.isArray(source)) { + const mergedMap = new Map(); + target.forEach(item => { + if (item.id != null) { + mergedMap.set(item.id, cloneDeep(item)); + } + }); + + // 合并源数组元素到Map,存在则深度合并 + source.forEach(item => { + if (item.id != null) { + const existing = mergedMap.get(item.id); + if (existing) { + // 合并现有元素和当前元素 + mergedMap.set(item.id, merge(existing, item)); + } else { + mergedMap.set(item.id, cloneDeep(item)); + } + } + }); + const combined = Array.from(mergedMap.values()); + return combined; + } + } - watch( - [() => props.modelValue, () => props.schema], - ([newModelValue, newSchema]) => { - modelValue.value = newModelValue; - schema.value = newSchema; + watch(() => props.modelValue, (newModelValue) => { + modelValue.value = newModelValue; + const viewSchema = getFrameComponentSchema(); + if (!viewSchema) { + return; + } + convertModelValueToProps(viewSchema); + }); + + watch(() => props.schema, (newSchema) => { + schema.value = newSchema; + const viewSchema = getFrameComponentSchema(); + if (!viewSchema) { + return; } - ); + convertSchemaToProps(viewSchema); + }); - setupContext.expose({ componentManager, rerender, getProps, invoke, setProps, selectItemById }); + setupContext.expose({ componentManager, rerender, getProps, invoke, setProps, getSchema, setSchema, selectItemById, convertPartialSchemaToProps }); return () => { const components: Record[] = schema.value?.module?.components; -- Gitee From 90af042bcc047ad1612492d360e440de291adcc2 Mon Sep 17 00:00:00 2001 From: aalizzwell Date: Mon, 17 Feb 2025 11:53:57 +0000 Subject: [PATCH 06/13] =?UTF-8?q?!1285=20=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=9E=84=E4=BB=B6=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E8=A7=A3=E5=86=B3=E7=BC=93=E5=AD=98=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20chrome=2080=E5=80=BC=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E7=82=B9=E5=87=BB=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E5=9C=A8?= =?UTF-8?q?80=E7=89=88=E6=9C=AC=E6=B5=8F=E8=A7=88=E5=99=A8=E4=B8=AD?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=8E=A7=E5=88=B6=E5=8F=B0=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20chore:=20=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84?= =?UTF-8?q?=E4=BB=B6=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=E7=BC=93=E5=AD=98=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E7=BC=96=E8=BE=91=E6=80=81=E5=90=8E=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E9=A1=B5=E6=8C=89=E9=92=AE=E7=AD=89=E7=BB=84=E4=BB=B6=E6=9C=AA?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E4=BF=AE=E6=94=B9merge?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E8=A7=A3=E5=86=B3=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E5=90=88=E5=B9=B6=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E9=80=9A?= =?UTF-8?q?=E8=BF=87props=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E4=BD=BF=E7=94=A8schema=20*=20chore:=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E9=85=8D=E7=BD=AE=E5=A2=9E=E5=8A=A0path?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E5=A2=9E=E5=8A=A0setSchema=E6=96=B9=E6=B3=95=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DsetProps=E6=97=A0=E6=95=88=E9=97=AE=E9=A2=98=20*=20cho?= =?UTF-8?q?re:=20revert=20setProps=20*=20Merge=20branch=20'upstream-main'?= =?UTF-8?q?=20*=20chore:=20=E5=88=A0=E9=99=A4schema=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=9B=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9C=BA=E5=88=B6=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9package=EF=BC=8C=E8=A7=A3=E5=86=B3=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=90=8E=E5=A3=B0=E6=98=8E=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E7=A6=81=E7=94=A8rollup=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=B7=B7=E6=B7=86=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=A1=8C=E8=AE=A1=E7=AE=97=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E4=BB=8E=E4=BB=8E=E8=A1=A8=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E4=B8=8D=E9=80=89=E4=B8=AD=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E6=A0=91=E5=AD=97=E5=85=B8=E6=A8=A1=E6=9D=BF=EF=BC=8C=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E4=BB=8E=E8=A1=A8=E5=BD=93=E5=89=8D=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E4=BB=8E=E4=BB=8E=E8=A1=A8=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20Merge=20branch=20'upstream-main'=20*=20chore?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9=E5=BC=95=E7=94=A8ui-vue=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=EF=BC=8Crollup=E6=89=93=E5=8C=85=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20fix:=20=E5=8D=A1=E7=89=87=E5=8F=96=E6=B6=88=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=9C=BA=E6=99=AF=E5=BC=80=E5=85=B3=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E5=8F=98=E6=9B=B4=E5=AF=BC=E8=87=B4=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E9=9B=86=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=85=B3=E8=81=94=E5=B5=8C?= =?UTF-8?q?=E5=A5=97udt=E5=9C=BA=E6=99=AF=E4=B8=ADudt=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E9=9B=86=E6=9E=84=E9=80=A0=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E5=A2=9E=E5=8A=A0=E6=89=93=E5=8C=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E6=89=93=E5=8C=85=E5=90=8E=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20ui-vue?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E5=8E=8B=E7=BC=A9=E6=89=93=E5=8C=85=20*=20fi?= =?UTF-8?q?x:=20ui-vue=E6=89=93=E5=8C=85=E5=8E=8B=E7=BC=A9=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20designer=E6=89=93=E5=8C=85=E6=8E=92=E9=99=A4vue=E7=AD=89?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E6=94=B9=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E5=BC=95=E5=85=A5ui-vue=E6=96=B9=E5=BC=8F=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=89=93=E5=8C=85=E6=97=A0=E6=B3=95=E5=89=94=E9=99=A4?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E9=97=AE=E9=A2=98=20*=20chore:=20=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E6=89=93=E5=8C=85=E5=8E=8B=E7=BC=A9=20*=20chore:=20ui?= =?UTF-8?q?-vue=E5=BC=80=E5=90=AF=E5=8E=8B=E7=BC=A9=E6=89=93=E5=8C=85=20*?= =?UTF-8?q?=20Merge=20branch=20'upstream-main'=20*=20Merge=20branch=20'ups?= =?UTF-8?q?tream-main'=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E4=BF=AE=E6=94=B9=E5=A4=9A=E8=AF=ADkey=20*=20chore:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BC=9A=E8=AF=9D=E5=88=9B=E5=BB=BA=E5=A4=9A?= =?UTF-8?q?=E6=AC=A1=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=A3=E5=86=B3if?= =?UTF-8?q?rame=E6=A8=A1=E5=BC=8F=E6=89=93=E5=BC=80=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E6=97=B6=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=89=93=E5=8C=85=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=20*=20chore:=20renderer=E6=89=93=E5=8C=85=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=20*=20chore:=20=E6=89=93=E5=8C=85=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8E=8B=E7=BC=A9=20*=20chore:=20=E6=89=93=E5=8C=85=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=20*=20chore:=20=E6=89=93=E5=8C=85=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=90=8D=E7=A7=B0=20*=20chore:=20=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=97=B6=E4=BF=9D=E7=95=99=E5=87=BD=E6=95=B0=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20*=20chore:=20devkit=E4=BA=A4=E4=BB=98=E7=89=A9?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=B6=E9=97=B4=E6=88=B3=20*=20chore:=20?= =?UTF-8?q?=E6=89=93=E5=8C=85=E8=84=9A=E6=9C=AC=E5=A2=9E=E5=8A=A0=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=88=B3=20*=20chore:=20=E5=8E=8B=E7=BC=A9bef?= =?UTF-8?q?=E6=89=93=E5=8C=85=E4=BA=A7=E7=89=A9=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?bef=E6=89=93=E5=8C=85=E4=BD=93=E7=A7=AF=20*=20chore:=20devkit?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=90=AF=E7=94=A8=E5=8E=8B=E7=BC=A9=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=AE=9A=E4=B9=89=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E4=B8=8Bloading=E6=97=A0=E6=B3=95=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20loading=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=BF=85=E9=A1=BB=E6=8C=87=E5=AE=9Aloadingid=E6=88=96?= =?UTF-8?q?timerid=20*=20chore:=20=E8=A7=A3=E5=86=B3=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E7=9C=8B=E3=80=81=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=89=8D=E7=9A=84=E6=A0=A1=E9=AA=8C=20*=20ch?= =?UTF-8?q?ore:=20=E5=90=8C=E6=AD=A5=E8=A1=A8=E6=A0=BC=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E5=B1=9E=E6=80=A7=E4=BF=AE=E6=94=B9=20*=20ch?= =?UTF-8?q?ore:=20=E6=9B=B4=E6=96=B0=E5=88=87=E6=8D=A2=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E3=80=81=E6=A0=91=E8=A1=A8=E5=BD=93=E5=89=8D=E8=A1=8C=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20*=20chore:=20=E7=BB=9F=E4=B8=80=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20*=20Merge=20branch=20'bugfix'=20*=20Merge=20branch=20'upstre?= =?UTF-8?q?am-main'=20*=20chore:=20update=20css=20*=20chore:=20=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E6=8B=A6=E6=88=AA=E5=BC=B9=E5=87=BA=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E5=90=8E=E7=BB=99=E5=87=BA=E6=8F=90=E7=A4=BA=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=A0=87=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=89=B9=E9=87=8F=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=88=97=E8=A1=A8=E5=88=A0=E9=99=A4=E5=90=8E=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E5=AF=BC=E8=87=B4=E6=95=B0=E6=8D=AE=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A4=E6=96=ADwindow=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E4=B8=BA=E6=A1=86=E6=9E=B6window=E7=9A=84=E6=96=B9=E5=BC=8F=20?= =?UTF-8?q?*=20Merge=20branch=20'upstream-main'=20*=20fix:=20=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=9C=AA=E5=90=AF=E7=94=A8=E5=88=86=E9=A1=B5=E6=97=B6?= =?UTF-8?q?=E6=89=93=E5=BC=80=E8=A1=A8=E5=8D=95=E6=8A=A5=E9=94=99=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E4=BF=AE=E5=A4=8Drenderer?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=A0=87=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=A1=A8=E6=A0=BC=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=94=81=E5=AE=9A=E5=B1=9E=E6=80=A7=E9=9B=86=E6=88=90?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=20*=20chore:=20=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=A0=91=E8=A1=A8=E6=A0=BC=E5=BD=93=E5=89=8D=E8=A1=8C=E5=89=8D?= =?UTF-8?q?=E5=85=88=E5=88=A4=E6=96=AD=E5=BD=93=E5=89=8D=E8=A1=8C=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E4=B8=80=E8=87=B4=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=96=E6=B6=88=E5=90=8E=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9C=AA=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E6=94=AF=E6=8C=81=E5=A2=9E=E9=87=8F?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20fix:=20=E6=9C=AA=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E6=95=B0=E6=8D=AE=E6=BA=90=E6=97=B6=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=8F=8C=E5=88=97=E8=A1=A8=E5=AD=90=E8=A1=A8=E6=97=A0?= =?UTF-8?q?=E7=84=A6=E7=82=B9=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=20*=20feature:=20=E8=A1=A8=E6=A0=BC=E5=88=97=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20*=20feature:=20=E5=8D=A1=E7=89=87=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=9C=BA=E7=AD=89=20*=20fix:=20=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=97=A0=E6=95=B0=E6=8D=AE=E6=97=B6=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=BD=93=E5=89=8D=E8=A1=8C=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E6=8E=A7=E4=BB=B6id=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=B8=AE=E5=8A=A9=E5=88=86=E9=9A=94=E7=AC=A6=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E4=BD=8D=E7=BD=AE=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20chore:=20=E6=9A=82=E6=97=B6=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=9B=B4=E6=96=B0=E8=A1=A8=E6=A0=BC=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=90=8E=E7=BB=AD=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8E=E5=86=8D=E5=90=AF=E7=94=A8=20*=20ch?= =?UTF-8?q?ore:=20=E6=89=93=E5=8C=85=E6=8E=92=E9=99=A4=E5=A4=A9=E6=B0=94?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20*=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E6=94=AF=E6=8C=81=E5=AD=90=E8=8A=82=E7=82=B9=E5=8F=8A?= =?UTF-8?q?slots=20*=20fix:=20=E5=8D=95=E9=80=89=E7=BB=84=E5=80=BC?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E5=80=BC=E5=8F=98=E5=8C=96=E5=9C=BA=E6=99=AF=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=A1=A8=E6=A0=BC=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE=20*=20fix:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'upstream-main'=20*=20feature:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83=20*=20ch?= =?UTF-8?q?ore:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20preview=E9=A1=B5=E9=9D=A2=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=9B=9E=E8=B0=83=20*=20chore:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83=E6=96=B9?= =?UTF-8?q?=E6=B3=95=20*=20chore:=20=E6=A0=91=E5=8A=A0=E8=BD=BD=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=94=AF=E6=8C=81=E8=BF=87=E6=BB=A4=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20checkbox?= =?UTF-8?q?=20checked=E5=B1=9E=E6=80=A7=E5=80=BC=E4=B8=8D=E6=98=AF?= =?UTF-8?q?=E5=B8=83=E5=B0=94=E7=B1=BB=E5=9E=8B=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20=E6=A0=91?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=96=B0=E5=A2=9E=E6=97=A0=E6=B3=95=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=B8=8A=E6=AC=A1=E5=BD=93=E5=89=8D=E8=A1=8C=E7=AD=89?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=B8=8A=E4=B8=8B=E6=96=87=20*=20chore:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=A0=91=E6=95=B0=E6=8D=AE=E6=BA=90=E7=BB=93?= =?UTF-8?q?=E6=9E=84=20*=20chore:=20=E6=A0=91=E8=A1=A8=E6=A0=BC=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81=E6=9C=BA=20*=20ch?= =?UTF-8?q?ore:=20section=E7=BB=84=E4=BB=B6=E5=A2=9E=E5=8A=A0=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=BA=94=E7=94=A8=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20feature:=20section=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=20*=20chore:=20=E6=A0=91=E8=8A=82=E7=82=B9=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=97=B6=E6=94=AF=E6=8C=81=E9=87=8D=E6=96=B0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=BD=93=E5=89=8D=E8=A1=8C=20*=20fix:=20=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E9=9A=90=E8=97=8F=E6=97=B6=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=AC=AC=E4=B8=80=E4=B8=AA=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E6=9D=A1=E4=BB=B6=E7=9A=84Relation=E4=B8=BA0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20fix:=20=E7=82=B9=E5=87=BB=E8=A1=8C=E6=97=B6=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E4=B8=A4=E6=AC=A1=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BB=8E=E8=A1=A8=E4=BB=8E=E4=BB=8E=E8=A1=A8?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=80=92=E5=BD=92=E6=96=B0=E5=A2=9E=E4=B8=BB=E4=BB=8E=E4=BB=8E?= =?UTF-8?q?=E8=A1=A8=E6=95=B0=E6=8D=AE=20*=20feature:=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=A0=8F=E6=8C=89=E9=92=AE=E6=94=AF=E6=8C=81=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=8A=E4=BE=9D=E8=B5=96=E8=A7=A3=E6=9E=90=20*=20chore:=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B7=A5=E5=85=B7=E6=A0=8F=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=20*=20fix:=20=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E9=80=92=E5=BD=92=E5=AF=BC=E8=87=B4=E7=95=8C=E9=9D=A2=E5=8D=A1?= =?UTF-8?q?=E6=AD=BB=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20chore:=20=E4=BF=AE=E6=94=B9=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*=20ch?= =?UTF-8?q?ore:=20=E8=BF=90=E8=A1=8C=E6=97=B6=E6=94=AF=E6=8C=81=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A1=A8=E6=A0=BC=E8=BF=9B=E5=85=A5=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=80=81=E6=97=B6=E5=88=97=E6=97=A0=E6=B3=95=E4=B8=8E=E8=A1=A8?= =?UTF-8?q?=E5=A4=B4=E5=AF=B9=E9=BD=90=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E9=87=8D=E6=96=B0=E5=8A=A0=E8=BD=BD=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=B0=83=E7=94=A8setProps=E7=BB=84=E4=BB=B6=E4=B8=8D=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E6=B8=B2=E6=9F=93=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E6=9B=B4=E6=96=B0=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=B3=A8=E9=87=8A=20*=20feature:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=B1=9E=E6=80=A7=20*=20chore:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=85=BC=E5=AE=B9=E4=BB=A3=E7=A0=81=20*=20Merge=20bra?= =?UTF-8?q?nch=20'upstream-main'=20*=20chore:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E7=AD=9B=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E6=9C=80=E5=90=8E=E4=B8=80=E4=B8=AA=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?Relation=E4=BF=AE=E6=94=B9=E4=B8=BA0=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E5=91=BD=E4=BB=A4=E8=BD=AC?= =?UTF-8?q?=E8=B0=83=E6=94=AF=E6=8C=81=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=20*=20feature:=20=E6=94=AF=E6=8C=81=E8=A7=A3=E6=9E=90=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6=E6=9C=8D=E5=8A=A1=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20chore:=20=E5=AD=90?= =?UTF-8?q?=E8=A1=A8=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E5=B9=B6=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=20*=20fix:=20=E5=8F=8C=E5=88=97=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E9=AB=98=E7=BA=A7=E5=88=97=E5=8D=A1=E5=AD=90=E8=A1=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=20*=20ch?= =?UTF-8?q?ore:=20=E5=AF=B9=E9=BD=90=E8=A1=A8=E6=A0=BCschema=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20*=20Merge=20branch=20'upstream-main'=20*=20fix:=20?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E5=88=86=E9=A1=B5=E4=B8=8D=E5=8F=97=E6=8E=A7?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=AE=9E=E4=BD=93=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E5=AD=90=E8=A1=A8=E6=95=B0=E6=8D=AE=E6=94=AF=E6=8C=81=E5=88=B7?= =?UTF-8?q?=E6=96=B0=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=AD=90=E8=A1=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8D=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E8=B7=AF=E5=BE=84=E8=A7=A3=E6=9E=90=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E6=9E=84=E4=BB=B6?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=88=9B=E5=BB=BA=20*=20fix:=20=E6=9C=AA?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E6=95=B0=E6=8D=AE=E5=88=B7=E6=96=B0=E6=97=B6?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=88=B0=E5=88=97=E8=A1=A8=E4=BB=8D=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E6=95=B0=E6=8D=AE=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'upstream-main'=20*=20Merge=20branch=20'upstream?= =?UTF-8?q?-main'=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8A=A0=E8=BD=BD=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E6=9E=84=E4=BB=B6=E3=80=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89web=E6=9E=84=E4=BB=B6=E5=85=83=E6=95=B0=E6=8D=AE=20*?= =?UTF-8?q?=20refactor:=20=E4=BF=AE=E5=A4=8Dbinding=E6=89=93=E5=8C=85?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20refactor:=20=E4=BF=AE=E6=94=B9command-?= =?UTF-8?q?services=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bef=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE=20*?= =?UTF-8?q?=20refactor:=20=E4=BF=AE=E6=94=B9devkit=E6=89=93=E5=8C=85?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20chore:=20=E5=AE=8C=E5=96=84=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E6=94=AF=E6=8C=81=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E6=9D=A1=E4=BB=B6=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20Merge=20branch=20'upstream-main'=20*?= =?UTF-8?q?=20chore:=20=E4=BF=AE=E6=94=B9=E5=B1=9E=E6=80=A7=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=96=B9=E5=BC=8F=20*=20chore:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=98=A0=E5=B0=84=E5=AD=97=E6=AE=B5=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20chore:=20?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E5=A2=9E=E5=8A=A0=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E5=A3=B0=E6=98=8E=20*=20chore:=20=E6=B3=A8?= =?UTF-8?q?=E5=85=A5renderEngine=E5=88=B0=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=EF=BC=8C=E4=BF=9D=E8=AF=81=E5=BC=80=E5=8F=91=E8=80=85=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E5=9C=A8=E6=9E=84=E4=BB=B6=E4=B8=AD=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=88=B0=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=20*=20fix:=20?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E8=BF=9B=E5=85=A5=E8=8F=9C=E5=8D=95=E6=97=B6?= =?UTF-8?q?=E6=9C=AA=E9=87=8D=E6=96=B0=E5=88=9B=E5=BB=BA=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20feature:=20=E5=8F=AF=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E8=A1=A8=E6=A0=BC=E5=B8=AE=E5=8A=A9=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E6=97=B6=E6=9B=B4=E6=96=B0=E6=98=A0=E5=B0=84=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=80=BC=E5=88=B0=E8=A1=A8=E6=A0=BC=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9MODULE=5FCONFIG=5FID=20token=E7=BC=96=E5=8F=B7=20*=20f?= =?UTF-8?q?ix:=20=E8=BF=90=E8=A1=8C=E6=A1=86=E6=9E=B6tabid=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20chore:=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88=E4=BB=A3=E7=A0=81=20*=20ch?= =?UTF-8?q?ore:=20=E5=8F=82=E6=95=B0=E8=A7=A3=E6=9E=90=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=9B=B8=E5=AF=B9=E8=B7=AF=E5=BE=84=20*=20chore:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A1=A8=E6=A0=BC=E5=88=86=E9=A1=B5=E5=A4=A7=E5=B0=8F?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=8E=A7=E5=88=B6=E5=99=A8=E6=94=AF=E6=8C=81=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=20*=20feature:=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E5=B9=B6?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=8E=A5=E5=8F=A3=20*=20fix:=20=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E7=BB=99=E7=BB=84=E4=BB=B6=E7=9A=84=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=8E=E7=BB=84=E4=BB=B6=E6=9C=AC=E8=BA=AB=E7=9A=84=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E4=B8=8D=E4=B8=80=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E5=88=A0=E9=99=A4=E6=97=A5=E5=BF=97=20*=20fix:=20=E4=B8=8B?= =?UTF-8?q?=E6=8B=89=E6=A1=86=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20feature:=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E9=9B=86=E6=88=90=E5=8F=98=E9=87=8F=20*=20fe?= =?UTF-8?q?ature:=20=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=8F=98=E6=9B=B4=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=A1=A5=E5=85=85=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20chore:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9command-services-vue=E7=9B=AE=E5=BD=95=E4=B8=BAcommand?= =?UTF-8?q?-services=20*=20chore:=20=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20chore:=20=E6=B8=B2=E6=9F=93=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E9=87=8D=E6=9E=84=20*=20chore:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E7=BC=96=E8=BE=91=E5=88=97=E8=A1=A8=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=96=B9=E6=B3=95=20*=20fix:=20eslint?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=94=99=E8=AF=AF=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20update=20pnpm-lock.yaml=20*=20chore?= =?UTF-8?q?:=20=E4=BF=AE=E5=A4=8D=E5=8A=9F=E8=83=BD=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=BD=AC=E6=8D=A2=E6=97=B6=E5=BF=BD=E7=95=A5?= =?UTF-8?q?type=20*=20chore:=20=E4=BF=AE=E6=94=B9=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=B9=E5=BC=8F=20*=20chore:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E8=BE=93=E5=85=A5=E6=A1=86schema=E4=B8=ADrequired?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E6=B8=85=E7=A9=BA=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=97=B6=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86undefined=E5=B1=9E=E6=80=A7=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=B8=8B=E6=8B=89=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=B1=9E=E6=80=A7=E7=B1=BB=E5=9E=8B=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=88=A0=E9=99=A4checkbox?= =?UTF-8?q?=E7=9A=84require=E5=B1=9E=E6=80=A7=EF=BC=8C=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=AF=A5=E5=B1=9E=E6=80=A7=20*=20chore:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=A7=A3=E6=9E=90=E5=BC=95=E6=93=8E=20*=20ch?= =?UTF-8?q?ore:=20=E9=80=82=E9=85=8D=E6=8E=A7=E5=88=B6=E5=99=A8=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20*=20chore:=20=E9=85=8D=E7=BD=AE=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E4=BF=AE=E6=94=B9=E4=B8=BA=E5=A4=96=E9=83=A8?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=20*=20chore:=20=E8=A1=A8=E6=A0=BCeditable?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9B=86=E6=88=90=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=20*=20chore:=20=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20*=20chore:=20=E9=80=82=E9=85=8D=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=99=A8=E4=BF=AE=E6=94=B9=20*=20fix:=20BorderEditor=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=B3=A8=E5=86=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E5=8D=A1=E7=89=87=E8=B7=B3=E5=9B=9E=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E6=97=B6=E5=BD=93=E5=89=8D=E8=A1=8C=E6=9C=AA?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E9=9B=86=E6=88=90=E7=8A=B6=E6=80=81=E6=9C=BA=20*=20chore:?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E7=8A=B6=E6=80=81=E6=9C=BA=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=20*=20fix:=20=E7=8A=B6=E6=80=81=E6=9C=BA=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=A4=9A=E4=B8=AA=E5=AE=9E=E4=BE=8B=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'upstream-main'=20*=20chore:?= =?UTF-8?q?=20=E5=B8=AE=E5=8A=A9=E6=94=AF=E6=8C=81=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E5=B7=B2=E9=80=89=E8=AE=B0=E5=BD=95=20*=20chore:=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E=E6=94=AF=E6=8C=81=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=20*=20chore:=20=E5=90=8C=E6=AD=A5=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E4=BF=AE=E6=94=B9=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E8=BD=AC=E8=B0=83=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87=E7=BB=84=E4=BB=B6?= =?UTF-8?q?id=E6=89=A7=E8=A1=8C=E5=91=BD=E4=BB=A4=20*=20fix:=20=E5=AD=90?= =?UTF-8?q?=E8=A1=A8=E5=8F=98=E6=9B=B4=E9=9B=86=E7=BB=84=E8=A3=85=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=A2=9E=E5=8A=A0=E7=BB=84=E4=BB=B6id?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20chore:=20=E6=B8=B2=E6=9F=93=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E6=94=AF=E6=8C=81=E5=B8=AE=E5=8A=A9=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E3=80=81=E8=A1=A8=E6=A0=BC=E5=80=BC=E5=8F=98=E5=8C=96=E3=80=81?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E9=A1=B5=E7=A0=81=E5=88=87=E6=8D=A2=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=A4=9A=E6=AC=A1=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=89=93=E5=8C=85?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E4=BF=AE=E6=94=B9=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91=E5=AE=9A=E4=B8=8E=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=88=86=E9=A1=B5=E6=89=A7=E8=A1=8C=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=20*=20chore:=20=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=86=E9=A1=B5=20*=20chore:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20ch?= =?UTF-8?q?ore:=20update=20lock=20file=20*=20chore:=20update=20gitignore?= =?UTF-8?q?=20*=20Merge=20branch=20'upstream-main'=20*=20chore:=20?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E4=BD=BF=E7=94=A8=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E5=85=83=E6=95=B0=E6=8D=AE=20*=20chore:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4logger=20*=20fix:=20=E5=8A=9F=E8=83=BD=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E9=97=AE=E9=A2=98=20*=20chore:=20=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=97=B6=E5=A2=9E=E5=8A=A0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=20*=20chore:=20=E7=A7=BB=E9=99=A4lo?= =?UTF-8?q?gger=E3=80=81=E4=BD=BF=E7=94=A8=E9=80=9A=E7=94=A8=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86=E5=99=A8=20*=20chore:=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9Eevent-handler=E8=A7=A3=E6=9E=90=20*=20chore:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4=E5=AD=90=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=97=B6=E6=9C=AA=E8=AE=BE=E7=BD=AE=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20chore:=20=E7=A6=81=E7=94=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=B7=E6=96=B0=20*=20refactor:=20=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E5=99=A8=20*=20ch?= =?UTF-8?q?ore:=20=E5=A2=9E=E5=8A=A0=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=E8=A7=A3=E6=9E=90=E5=99=A8=20*=20chore:=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=A0=91=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=20*=20fix:=20=E6=A0=91=E8=A1=A8=E6=A0=BC=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=A1=8C=E4=B8=8E=E6=8E=A7=E5=88=B6=E5=99=A8=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E8=A1=8C=E4=B8=8D=E4=B8=80=E8=87=B4=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20chore:=20=E6=94=AF=E6=8C=81=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E5=AE=9E=E4=BD=93=E5=8F=98=E6=9B=B4=20*=20fi?= =?UTF-8?q?x:=20#IB8JC7=20=E5=8A=9F=E8=83=BD=E5=AE=A1=E6=9F=A5=EF=BC=9A?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=EF=BC=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=B8=BB=E8=A1=A8=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E6=8C=87=E5=AE=9A=E6=9C=89=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E4=BA=8B=E4=BB=B6=E6=89=A7=E8=A1=8C=E5=A4=9A=E6=AC=A1?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'upstream-ma?= =?UTF-8?q?in'=20*=20refactor:=20=E9=87=8D=E6=9E=84render=20*=20chore:=20l?= =?UTF-8?q?ogger=E6=94=AF=E6=8C=81rollup=E6=89=93=E5=8C=85=20*=20chore:=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=BF=90=E8=A1=8C=E6=8C=89=E9=92=AE=E6=89=93?= =?UTF-8?q?=E5=BC=80=E9=A1=B5=E9=9D=A2=E5=9C=B0=E5=9D=80=E5=8F=8A=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20into=20dev=20*=20chor?= =?UTF-8?q?e:=20update=20gitignore=20*=20chore:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=A8=A1=E5=9D=97=20*=20Merge=20branch=20'up?= =?UTF-8?q?stream-main'=20*=20feature:=20renderer=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=A1=B5=E7=AD=BE=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20*=20chore:=20viewmodel=E9=85=8D=E7=BD=AE=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=BB=91=E5=AE=9A=E8=B7=AF=E5=BE=84=20*=20chore:=20ta?= =?UTF-8?q?bs=E5=A2=9E=E5=8A=A0Click=E4=BA=8B=E4=BB=B6=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=20*=20chore:=20viewmodel=E6=94=AF=E6=8C=81=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20feature:=20=E6=94=AF=E6=8C=81=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=81=E5=88=A0=E9=99=A4=E5=AD=90=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20*=20chore:=20=E4=BF=AE=E6=94=B9schema=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=20*=20chore:=20=E6=8E=A7=E5=88=B6=E5=99=A8=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98=E6=97=B6=E4=B8=AD?= =?UTF-8?q?=E6=96=AD=E6=95=B4=E4=B8=AA=E5=91=BD=E4=BB=A4=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=BB=91=E5=AE=9A=E6=9C=AA?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E6=95=B0=E6=8D=AE=E6=BA=90=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A1=A8=E6=A0=BC=E7=BB=84=E4=BB=B6=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E8=A1=8C=E6=97=B6=E6=97=A0=E6=B3=95=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20tabs?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E6=8C=89=E9=92=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree-grid=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=91=E5=AE=9A=E4=B8=BAnull=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20refactor:=20=E9=87=8D=E6=9E=84=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../callback-handler/before-edit-cell-callback-handler.ts | 2 +- .../renderer/src/change-resolver/change-resolve-service.ts | 2 +- .../src/change-resolver/entity-store-change-resolver.ts | 2 +- .../src/change-resolver/state-machine-change-resolver.ts | 2 +- .../src/change-resolver/ui-state-change-resolver.ts | 2 +- packages/renderer/src/composition/use-metadata-refine.ts | 2 +- .../renderer/src/config-builders/command-handler-builder.ts | 2 +- .../ui-binding/lib/compositions/use-data-grid-binding.ts | 6 +++--- .../components/dynamic-view/src/dynamic-view.component.tsx | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts index b1fc654abb4..c83d39ef332 100644 --- a/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts +++ b/packages/renderer/src/callback-handler/before-edit-cell-callback-handler.ts @@ -16,7 +16,7 @@ export class BeforeEditCallCallbackHandler extends CallbackHandler { super(); } public handle(callbackType: string, args: any[]): undefined | boolean | Promise { - const { column, rawData } = args.at(0); + const { column, rawData } = args[0]; const { editor, binding } = column || {}; if (!editor || !binding) { return true; diff --git a/packages/renderer/src/change-resolver/change-resolve-service.ts b/packages/renderer/src/change-resolver/change-resolve-service.ts index 991fb03b391..3fabfb4e8de 100644 --- a/packages/renderer/src/change-resolver/change-resolve-service.ts +++ b/packages/renderer/src/change-resolver/change-resolve-service.ts @@ -10,7 +10,7 @@ export class ChangeResolveService { return this.changeResolverRegistry.registry.reduce((results: Map, resolver: ChangeResolver) => { const result = resolver.resolve(change); if (result && result.size > 0) { - result.keys().forEach((componentId: string)=>{ + Array.from(result.keys()).forEach((componentId: string)=>{ if (results.has(componentId)) { results.get(componentId)!.push(...result.get(componentId)!); } else { diff --git a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts index 39f13d95102..182d731c29a 100644 --- a/packages/renderer/src/change-resolver/entity-store-change-resolver.ts +++ b/packages/renderer/src/change-resolver/entity-store-change-resolver.ts @@ -15,7 +15,7 @@ export class EntityStoreChangeResolver extends ChangeResolver = new Map(); - registry.entries().forEach(([id, configs]) => { + Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { return dependency.type === DependencyType.EntityState; diff --git a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts index d7a80d720a1..5df37f6db3d 100644 --- a/packages/renderer/src/change-resolver/state-machine-change-resolver.ts +++ b/packages/renderer/src/change-resolver/state-machine-change-resolver.ts @@ -15,7 +15,7 @@ export class StateMachineChangeResolver extends ChangeResolver = new Map(); - registry.entries().forEach(([id, configs]) => { + Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { return dependency.type === DependencyType.StateMachine; diff --git a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts index 97ebea303a7..f33a9167360 100644 --- a/packages/renderer/src/change-resolver/ui-state-change-resolver.ts +++ b/packages/renderer/src/change-resolver/ui-state-change-resolver.ts @@ -15,7 +15,7 @@ export class UIStateChangeResolver extends ChangeResolver { } const registry = this.componentConfigDependencyRegistry.getComponents(); const result: Map = new Map(); - registry.entries().forEach(([id, configs]) => { + Array.from(registry.entries()).forEach(([id, configs]) => { const matchedConfigs = configs.filter((config: Config) => { const match = config.deps.find((dependency: ConfigDependency) => { return dependency.type === DependencyType.UIState; diff --git a/packages/renderer/src/composition/use-metadata-refine.ts b/packages/renderer/src/composition/use-metadata-refine.ts index b9bcfd56948..669bf30b155 100644 --- a/packages/renderer/src/composition/use-metadata-refine.ts +++ b/packages/renderer/src/composition/use-metadata-refine.ts @@ -13,7 +13,7 @@ export function useMetadataRefine(metadata: any) { if (!stateMachines || !viewModels || !Array.isArray(stateMachines) || stateMachines.length < 1 || !Array.isArray(viewModels) || viewModels.length < 1) { return; } - const { id } = stateMachines.at(0); + const { id } = stateMachines[0]; viewModels.forEach((viewModel: ViewModelMeta) => { viewModel.stateMachine = id; }); diff --git a/packages/renderer/src/config-builders/command-handler-builder.ts b/packages/renderer/src/config-builders/command-handler-builder.ts index a58a772993e..4a508e2a4a6 100644 --- a/packages/renderer/src/config-builders/command-handler-builder.ts +++ b/packages/renderer/src/config-builders/command-handler-builder.ts @@ -136,7 +136,7 @@ class CommandHandlerConfigBuilder { throw new Error(`WebComponentMetadata(Id=${componentId}) does not exist`); } const fileName = fullFileName.split('/').pop().split('.')[0].toLowerCase(); - const serviceUrl = `/apps/${app}/${su}/web/${proj}/${fileName}.js`; + const serviceUrl = `/apps/${app}/${su}/web/${proj}/${fileName}.js?version=${new Date().valueOf()}`; return serviceUrl; } diff --git a/packages/ui-binding/lib/compositions/use-data-grid-binding.ts b/packages/ui-binding/lib/compositions/use-data-grid-binding.ts index 09801c12c82..45cb2626e8b 100644 --- a/packages/ui-binding/lib/compositions/use-data-grid-binding.ts +++ b/packages/ui-binding/lib/compositions/use-data-grid-binding.ts @@ -95,13 +95,13 @@ export function useDataGridBinding(elementRef: ElementRef, options: BindingOptio let idValue: string | undefined | null = null; let index = -1; if (!entityPath || entityPath.length < 1) { - idValue = nodes.at(0)?.getNodeValue(); + idValue = nodes[0]?.getNodeValue(); } else { index = nodes.findIndex((node: EntityPathNode) => node.getNodeType() === EntityPathNodeType.PropName && node.getNodeValue() === entityPath[entityPath.length - 1]); if (index === -1) { return; } - idValue = nodes.at(index + 1)?.getNodeValue(); + idValue = nodes[index + 1]?.getNodeValue(); } if (!idValue) { return; @@ -110,7 +110,7 @@ export function useDataGridBinding(elementRef: ElementRef, options: BindingOptio if (!rows || rows.length < 1) { return; } - const row = rows.at(0); + const row = rows[0]; const propertyNames = changePath.getNodes().slice(index + 1 + 1); const propertyName = propertyNames.map((node: EntityPathNode) => node.getNodeValue()).join('.'); diff --git a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index df3e1792afa..a2b6b6ee049 100644 --- a/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -353,7 +353,7 @@ const FDynamicView = defineComponent({ const mergedMap = new Map(); target.forEach(item => { if (item.id != null) { - mergedMap.set(item.id, cloneDeep(item)); + mergedMap.set(item.id, item); } }); -- Gitee From a907472db64d4ee445b8107591ab1c799ab01bc3 Mon Sep 17 00:00:00 2001 From: wangjinzhe77 <464984407@qq.com> Date: Mon, 17 Feb 2025 11:55:22 +0000 Subject: [PATCH 07/13] =?UTF-8?q?!1287=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E7=AD=9B=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E4=B8=8B=E6=8B=89=E9=9D=A2=E6=9D=BF=E5=80=BC=E4=B8=BA?= =?UTF-8?q?boolean=E6=88=96=E8=80=85number=E6=97=B6=E7=9A=84=E4=B8=8E?= =?UTF-8?q?=E6=88=96=E5=85=B3=E7=B3=BB=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E7=AD=9B=E9=80=89=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E4=B8=8B=E6=8B=89=E9=9D=A2=E6=9D=BF=E5=80=BC=E4=B8=BA?= =?UTF-8?q?boolean=E6=88=96=E8=80=85number=E6=97=B6=E7=9A=84=E4=B8=8E?= =?UTF-8?q?=E6=88=96=E5=85=B3=E7=B3=BB=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/ubml/farris-vue=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/ubml/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=8F=90=E7=A4=BA=E6=A1=86tooltip=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/ubml/farris-vue=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8D=95=E9=80=89=E6=A1=86=E5=B1=95=E7=A4=BA=E6=96=B9=E5=90=91?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E7=AD=9B=E9=80=89=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E5=88=A0=E9=99=A4=E6=97=A0=E6=95=88=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=E5=B1=9E=E6=80=A7=E3=80=81=E4=BF=AE=E6=94=B9=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=AE=A1=E7=90=86=E7=95=8C=E9=9D=A2?= =?UTF-8?q?datagrid=E7=BB=84=E4=BB=B6=E5=AE=BD=E5=BA=A6=E4=B8=BA=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=A1=AB=E5=85=85=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/ubml/farris-vue=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/ubml/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E7=AE=A1=E7=90=86=E7=95=8C=E9=9D=A2=E7=82=B9=E5=87=BB?= =?UTF-8?q?datagrid=E5=8D=A1=E6=AD=BB=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF=E6=8F=90=E7=A4=BA=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/ubml/farris-vue=20*=20fix:=20=E7=A7=BB=E9=99=A4=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E4=B8=ADcombolist=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E4=B8=8D=E7=94=A8=E7=9A=84=E5=B1=9E=E6=80=A7=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20https://gitee.com/ubml/farris-vue=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=96=B9=E6=A1=88=E5=90=8D=E7=A7=B0=E5=8F=96?= =?UTF-8?q?=E5=80=BC=E4=B8=8E=E4=BF=A1=E6=81=AF=E6=8F=90=E7=A4=BA=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E4=BC=98=E5=8C=96=20*=20fix:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E4=B8=AD=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E4=B8=8D=E6=94=AF=E6=8C=81=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=A0=BC=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E6=8E=A7=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E6=9C=AA=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E5=9B=9E=E9=80=80condition=E7=BB=84=E4=BB=B6comb?= =?UTF-8?q?olistvalue=E7=BB=84=E4=BB=B6=E6=9E=84=E9=80=A0=E5=99=A8=20*=20f?= =?UTF-8?q?ix:=20=E4=BF=AE=E6=94=B9=E8=A1=A8=E5=8D=95=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E6=8E=A5=E5=8F=A3=E6=8A=A5=E9=94=99=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=96=87=E6=A1=88=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/ubml/farris-vue=20*=20fix:=20handle=20confilct=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E5=B8=AE=E5=8A=A9=E6=8E=A7=E4=BB=B6=E5=80=BC=E5=80=BC?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=9C=AA=E7=94=9F=E6=95=88=E4=B8=8E=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E5=B8=AE=E5=8A=A9=E6=8E=A7=E4=BB=B6=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=97=B6=E5=80=BC=E4=B8=BA=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E4=B8=8B=E6=8B=89=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E6=98=AF=E5=90=A6=E4=B8=BA=E7=A9=BA=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E6=9D=A1=E4=BB=B6=20*=20fix:=20=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E6=97=A5=E6=9C=9F=E7=B1=BB=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=89=E6=8B=A9=E6=97=A5=E6=9C=9F=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E3=80=81=E6=95=B0=E5=AD=97=E5=8C=BA=E9=97=B4=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E6=9C=80=E5=B0=8F=E5=80=BC=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E3=80=81=E4=B8=8B=E6=8B=89=E9=9D=A2=E6=9D=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=B8=85=E7=A9=BA=E6=8C=89=E9=92=AE=20*=20fix:=20?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=AE=BE=E8=AE=A1=E5=99=A8=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E8=A7=A6=E5=8F=91=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=9E=84=E4=BB=B6=E9=83=A8=E5=88=86=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/ubml/fa?= =?UTF-8?q?rris-vue=20*=20fix:=20=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=B8=8E=E8=87=AA=E9=80=82=E5=BA=94=E6=A0=B7=E5=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E6=94=B9=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/ubml/farris-vue=20*=20fix:=20=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/ubml/farris-vue=20*=20fix:=20handle=20conflict=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E6=95=B0=E5=AD=97=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=E6=9C=80=E5=A4=A7=E6=9C=80=E5=B0=8F=E5=80=BC=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E6=9C=80=E5=A4=A7=E6=9C=80=E5=B0=8F=E5=80=BC?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9canNull=E5=B1=9E=E6=80=A7=E4=B8=BAnullable=20*=20fix:?= =?UTF-8?q?=20response-toolbar=20=E7=BB=84=E4=BB=B6=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E6=94=B6=E6=8A=98=E6=97=B6=E7=82=B9=E5=87=BB=E6=8A=A5=E9=94=99?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/ubml/fa?= =?UTF-8?q?rris-vue=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E5=80=BC?= =?UTF-8?q?=E4=B8=8E=E6=95=B0=E5=80=BC=E5=8C=BA=E9=97=B4=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=9C=80=E5=A4=A7=E6=9C=80=E5=B0=8F=E5=80=BC=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E6=95=B0?= =?UTF-8?q?=E5=80=BC=E5=8C=BA=E9=97=B4=E6=97=A0=E6=B3=95=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E5=80=BC=E5=8F=98=E5=8C=96=E4=BA=8B=E4=BB=B6=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/ubml/farris-vue=20*=20fix:=20=E6=96=B0=E5=A2=9E=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E6=96=B9=E6=A1=88=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E5=88=A0=E9=99=A4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/ubml/farris-vue=20*=20fix:=20update=20conflict=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9dynamic-form-group=E7=BB=84=E4=BB=B6=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=8A=A5=E9=94=99=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/ubml/farris-vue=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E5=8C=BA=E9=97=B4=E4=B8=8E=E5=B8=AE=E5=8A=A9=E6=9C=AA=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=80=BC=E5=8F=98=E5=8C=96=E4=BA=8B=E4=BB=B6=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20of=20https://gitee.com/ubml/farris-vue?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E6=95=B0=E5=AD=97=E6=8E=A7=E4=BB=B6=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E5=80=BC=E5=AD=97=E6=AE=B5=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E6=9F=A5=E8=AF=A2=E5=BC=82=E5=B8=B8=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=B8=8E=E4=BC=98=E5=8C=96ui=E5=B1=95=E7=A4=BA=20*=20?= =?UTF-8?q?Merge=20branch=20'main'=20of=20https://gitee.com/ubml/farris-vu?= =?UTF-8?q?e=20*=20fix:=20solution=E7=BB=84=E4=BB=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E9=A2=84=E7=BD=AE=E6=96=B9=E6=A1=88=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BF=90=E8=A1=8C=E6=97=B6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20handle=20conflict=20*=20Merge=20branch=20'main'?= =?UTF-8?q?=20of=20https://gitee.com/ubml/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF=E5=B1=9E=E6=80=A7=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20*=20fix:=20=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88?= =?UTF-8?q?=E5=B8=AE=E5=8A=A9=E5=80=BC=E7=BB=91=E5=AE=9A=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9=E7=AD=9B=E9=80=89=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E5=B8=AE=E5=8A=A9=E4=B8=8E=E4=B8=8B=E6=8B=89=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E7=BB=91=E5=AE=9A=E5=80=BC=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/ubml/farris-vue=20*=20Merge=20bran?= =?UTF-8?q?ch=20'main'=20of=20https://gitee.com/ubml/farris-vue=20*=20fix:?= =?UTF-8?q?=20hanlde=20conflict=20*=20fix:=20=E4=BF=AE=E6=94=B9=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=AD=9B=E9=80=89=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=80=BC=E7=B1=BB=E5=9E=8B=20*=20fix:=20handle=20conflict=20*?= =?UTF-8?q?=20fix:=20=E7=AD=9B=E9=80=89=E6=96=B9=E6=A1=88=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8E=A5=E5=8F=A3=E6=9F=A5=E8=AF=A2=20*=20feature:=20?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E8=BF=90=E8=A1=8C=E5=89=8D=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E5=89=8D=E7=AB=AF=E8=84=9A=E6=9C=AC=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/ubml/farris-vue=20*=20Merge=20branch=20'main'=20of=20https://?= =?UTF-8?q?gitee.com/ubml/farris-vue=20*=20Merge=20branch=20'main'=20of=20?= =?UTF-8?q?https://gitee.com/ubml/farris-vue=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9eslint=E9=97=AE=E9=A2=98=20*=20feature:=20=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=8A=A0=E8=BD=BD=E7=AD=89=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/ubml/fa?= =?UTF-8?q?rris-vue=20*=20Merge=20branch=20'main'=20of=20https://gitee.com?= =?UTF-8?q?/ubml/farris-vue=20*=20fix:=20fix=20the=20ts=20error=20*=20fix:?= =?UTF-8?q?=20handle=20conflict=20*=20fix:=20=E7=AD=9B=E9=80=89=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E8=AE=BE=E8=AE=A1=E6=97=B6=E4=BA=A4=E4=BA=92=E4=B8=8E?= =?UTF-8?q?UI=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=20*=20fix:=20=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=96=B9=E6=A1=88=E8=AE=BE=E8=AE=A1=E6=97=B6=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=B8=8EUI=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9=20*=20?= =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E7=BB=84=E4=BB=B6porps=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=20*=20refactor:=20=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E7=BB=84=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/query-solution/src/composition/use-condition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui-vue/components/query-solution/src/composition/use-condition.ts b/packages/ui-vue/components/query-solution/src/composition/use-condition.ts index 4f7b941ea9c..295bbb9f680 100644 --- a/packages/ui-vue/components/query-solution/src/composition/use-condition.ts +++ b/packages/ui-vue/components/query-solution/src/composition/use-condition.ts @@ -132,7 +132,7 @@ export function useCondition(props: QuerySolutionProps, context: SetupContext): 'FilterField' : condition.fieldCode, 'Compare' : (condition.compareType || condition.compareType === 0) ? condition.compareType : CompareType.Equal, 'Value' : comboListValue, - 'Relation' : condition.compareType === CompareType.NotEqual ? RelationType.And : RelationType.Or, + 'Relation' : RelationType.And, 'Expresstype':ValueType.Value }); } -- Gitee From e8be7c3683efb74df8a829f6c628cd4293b13d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=B1=9F=E5=9D=A4?= <5364197@qq.com> Date: Mon, 17 Feb 2025 12:00:11 +0000 Subject: [PATCH 08/13] =?UTF-8?q?!1288=20=E5=90=8C=E6=AD=A5dynamic-canvas?= =?UTF-8?q?=E3=80=81dynamic-form=E3=80=81dynamic-resolver=E3=80=81dynamic-?= =?UTF-8?q?view=E7=AD=89=E6=9C=80=E6=96=B0=E4=BB=A3=E7=A0=81=E5=88=B0?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6=E5=BA=93=20*=20chore:?= =?UTF-8?q?=E5=90=88=E5=B9=B6main-designer=E4=BB=A3=E7=A0=81=20*=20chore:?= =?UTF-8?q?=E5=90=8C=E6=AD=A5dynamic-canvas=E3=80=81dynamic-form=E3=80=81d?= =?UTF-8?q?ynamic-resolver=E3=80=81dynamic-view=E7=AD=89=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=88=B0=E7=A7=BB=E5=8A=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/common/date/date-converter.ts | 204 +++ .../components/common/date/use-date-format.ts | 54 + .../components/common/date/use-time-ago.ts | 65 + .../common/directive/area-response.ts | 136 ++ .../common/editor/binding-selector/style.ts | 6 + .../components/common/entity/entity-schema.ts | 274 ++++ .../mobile-ui-vue/components/common/index.ts | 34 + .../common/number/use-number-format.ts | 278 ++++ .../radio-checkbox/radio-checkbox.props.ts | 45 + .../common/radio-checkbox/use-check.ts | 100 ++ .../common/src/entity/base-property.ts | 129 ++ .../common/src/entity/entity-schema.ts | 274 ++++ .../common/src/entity/input-base-property.ts | 282 +++++ .../common/text-box/composition/use-clear.ts | 61 + .../composition/use-text-box-design.ts | 96 ++ .../text-box/composition/use-text-box.ts | 181 +++ .../mobile-ui-vue/components/common/types.ts | 131 ++ .../components/common/utils/encrypt.ts | 246 ++++ .../components/common/utils/resolve-field.ts | 29 + .../components/common/utils/symbol-key.ts | 6 + .../components/common/utils/use-appearance.ts | 33 + .../components/common/utils/use-class.ts | 33 + .../components/common/utils/use-guid.ts | 43 + .../common/utils/use-request-animation.ts | 46 + .../components/common/utils/with-install.ts | 10 + .../components/designer-canvas/index.ts | 24 +- .../control-tree-view.component.tsx | 124 -- .../designer-inner-item.component.tsx | 436 ++++--- .../components/designer-item.component.tsx | 569 +++++---- .../designer-placeholder.component.tsx | 74 +- .../designer-template-item.component.tsx | 93 +- .../src/components/iconfont.css | 490 -------- .../src/components/iconfont.ttf | Bin 35356 -> 0 bytes .../designer-canvas/src/components/maps.ts | 37 +- .../src/components/toolbox.component.tsx | 130 -- .../src/components/toolbox.json | 34 - .../src/composition/class/control.css | 535 +------- .../src/composition/class/designer-canvas.css | 354 ++---- .../src/composition/class/toolbox.css | 69 - .../composition/designer-canvas-changed.ts | 120 +- .../src/composition/dg-control.ts | 214 +--- .../src/composition/entity/builder-element.ts | 12 +- .../entity/control-tree-node-entity.ts | 64 - .../src/composition/entity/property-entity.ts | 211 ---- .../function/change-control-tree-node.ts | 53 - .../function/create-design-builder.ts | 59 +- .../src/composition/function/drag-resolve.tsx | 228 ++++ .../function/use-designer-component.ts | 418 +++--- .../function/use-designer-inner-component.ts | 364 +++--- .../src/composition/function/use-dragula.ts | 697 +++++------ .../props/control-tree-view.props.ts | 26 - .../props/designer-canvas.props.ts | 11 +- .../props/designer-inner-item.props.ts | 23 +- .../composition/props/designer-item.props.ts | 28 +- .../props/designer-placeholder.props.ts | 2 +- .../src/composition/props/toolbox.props.ts | 8 - .../rule/drag-drop-rules.schema.json | 1115 +++++++++-------- .../composition/rule/use-drag-drop-rules.ts | 308 ++--- .../rule/use-dragula-common-rule.ts | 51 + .../src/composition/rule/use-template-rule.ts | 151 +++ .../designer-canvas/src/composition/types.ts | 242 ++-- .../composition/use-dragula-common-rule.ts | 43 - .../src/designer-canvas.component.tsx | 185 ++- .../components/designer-canvas/src/types.ts | 131 +- packages/mobile-ui-vue/components/designer.ts | 3 + .../components/dynamic-form/index.ts | 4 + ...response-form-component-creator.service.ts | 196 +++ .../dynamic-form/src/composition/types.ts | 12 + .../use-response-form-layout-setting.ts | 128 ++ .../composition/use-type-resolver-design.ts | 25 + .../src/composition/use-type-resolver.ts | 109 ++ .../components/dynamic-form/src/types.ts | 33 + .../components/dynamic-resolver/index.ts | 9 + .../dynamic-resolver/src/binding-resolver.ts | 68 + .../src/common/appearance-resolver.ts | 2 +- .../src/common/toolbar-resolver.ts | 16 +- .../src/converter/appearance.converter.ts | 14 + .../src/converter/buttons.converter.ts | 8 +- .../src/converter/change-editor.converter.ts | 15 + .../src/converter/enum-data.converter.ts | 11 + .../src/converter/field-selector.converter.ts | 24 + .../converter/form-group-label.converter.ts | 10 + .../src/converter/grid-selection.converter.ts | 13 + .../src/converter/items-count.converter.ts | 8 + .../src/converter/pagination.converter.ts | 16 + .../converter/property-editor.converter.ts | 17 +- .../src/converter/row-number.converter.ts | 13 + .../src/converter/type.converter.ts | 10 + .../dynamic-resolver/src/editor-resolver.ts | 10 + .../src/event-handler-resolver.ts | 90 ++ .../dynamic-resolver/src/events-resolver.ts | 20 + .../dynamic-resolver/src/object-expression.ts | 170 +-- .../src/property-config-resolver.ts | 342 +++-- .../dynamic-resolver/src/props-resolver.ts | 49 +- .../dynamic-resolver/src/schema-resolver.ts | 161 ++- .../src/selection-item-resolver.ts | 19 + .../components/dynamic-resolver/src/types.ts | 93 +- .../src/update-columns-resolver.ts | 11 + .../src/visible-prop-resolver.ts | 8 + .../components/dynamic-view/index.ts | 10 +- .../dynamic-view/src/callback-deliver.ts | 10 + .../dynamic-view/src/components/maps.ts | 24 +- .../dynamic-view/src/composition/index.ts | 3 + .../src/composition/use-binding-data.ts | 20 + .../src/composition/use-component-manager.ts | 51 + .../src/composition/use-entity-resolver.ts | 69 + .../src/composition/use-entity-state.ts | 32 + .../src/composition/use-entity.ts | 34 + .../src/composition/use-field-resolver.ts | 50 + .../src/composition/use-form-schema.ts | 11 + .../src/dynamic-view.component.tsx | 332 ++++- .../dynamic-view/src/dynamic-view.props.ts | 19 +- .../dynamic-view/src/event-dispatcher.ts | 16 + .../components/dynamic-view/src/types.ts | 83 ++ packages/mobile-ui-vue/components/index.ts | 35 +- .../mobile-ui-vue/components/modal/index.ts | 32 + .../modal-context-holder.component.tsx | 23 + .../modal/src/composition/destroy.ts | 1 + .../modal/src/composition/modal.service.tsx | 263 ++++ .../src/composition/resizeable/position.ts | 104 ++ .../composition/resizeable/resize-event.ts | 11 + .../modal/src/composition/resizeable/size.ts | 33 + .../components/modal/src/composition/type.ts | 49 + .../modal/src/composition/use-draggable.ts | 222 ++++ .../modal/src/composition/use-resizeable.tsx | 390 ++++++ .../modal/src/composition/use-shortcut.ts | 56 + .../components/modal/src/modal.component.tsx | 375 ++++++ .../components/modal/src/modal.css | 84 ++ .../components/modal/src/modal.props.ts | 83 ++ .../mobile-ui-vue/components/modal/style.ts | 3 + .../components/property-panel/index.ts | 12 +- .../property-panel-item-list.component.tsx | 143 --- .../property-panel-item.component.tsx | 58 - .../class/property-panel-item-list.css | 72 +- .../src/composition/class/property-panel.css | 5 +- .../src/composition/entity/base-property.ts | 130 ++ .../composition/entity/input-base-property.ts | 390 ++++++ .../src/composition/entity/property-entity.ts | 414 +++--- .../composition/entity/schema-dom-mapping.ts | 79 ++ .../src/composition/entity/use-input-rules.ts | 62 + .../props/property-panel-item-list.props.ts | 21 +- .../props/property-panel-item.props.ts | 4 +- .../composition/props/property-panel.props.ts | 52 +- .../property-panel/src/composition/type.ts | 94 +- .../components/property-panel/src/mock.ts | 318 ++--- .../src/property-panel.component.tsx | 456 ------- packages/mobile-ui-vue/package.json | 2 + 147 files changed, 11057 insertions(+), 6049 deletions(-) create mode 100644 packages/mobile-ui-vue/components/common/date/date-converter.ts create mode 100644 packages/mobile-ui-vue/components/common/date/use-date-format.ts create mode 100644 packages/mobile-ui-vue/components/common/date/use-time-ago.ts create mode 100644 packages/mobile-ui-vue/components/common/directive/area-response.ts create mode 100644 packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts create mode 100644 packages/mobile-ui-vue/components/common/entity/entity-schema.ts create mode 100644 packages/mobile-ui-vue/components/common/number/use-number-format.ts create mode 100644 packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts create mode 100644 packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts create mode 100644 packages/mobile-ui-vue/components/common/src/entity/base-property.ts create mode 100644 packages/mobile-ui-vue/components/common/src/entity/entity-schema.ts create mode 100644 packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts create mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts create mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts create mode 100644 packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts create mode 100644 packages/mobile-ui-vue/components/common/types.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/encrypt.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/resolve-field.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/symbol-key.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/use-appearance.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/use-class.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/use-guid.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/use-request-animation.ts create mode 100644 packages/mobile-ui-vue/components/common/utils/with-install.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/control-tree-view.component.tsx delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.css delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.ttf delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.component.tsx delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.json delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/class/toolbox.css delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/control-tree-node-entity.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/property-entity.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/function/change-control-tree-node.ts create mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/props/control-tree-view.props.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/props/toolbox.props.ts create mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-dragula-common-rule.ts create mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-template-rule.ts delete mode 100644 packages/mobile-ui-vue/components/designer-canvas/src/composition/use-dragula-common-rule.ts create mode 100644 packages/mobile-ui-vue/components/designer.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/index.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/response-form-component-creator.service.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/types.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-form/src/types.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/binding-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/field-selector.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/form-group-label.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/editor-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/event-handler-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/events-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/selection-item-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/update-columns-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-resolver/src/visible-prop-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts create mode 100644 packages/mobile-ui-vue/components/dynamic-view/src/types.ts create mode 100644 packages/mobile-ui-vue/components/modal/index.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/components/modal-context-holder.component.tsx create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/destroy.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/modal.service.tsx create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/resizeable/position.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/resizeable/resize-event.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/resizeable/size.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/type.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/use-draggable.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/use-resizeable.tsx create mode 100644 packages/mobile-ui-vue/components/modal/src/composition/use-shortcut.ts create mode 100644 packages/mobile-ui-vue/components/modal/src/modal.component.tsx create mode 100644 packages/mobile-ui-vue/components/modal/src/modal.css create mode 100644 packages/mobile-ui-vue/components/modal/src/modal.props.ts create mode 100644 packages/mobile-ui-vue/components/modal/style.ts delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item-list.component.tsx delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item.component.tsx create mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts create mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts create mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts create mode 100644 packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts delete mode 100644 packages/mobile-ui-vue/components/property-panel/src/property-panel.component.tsx diff --git a/packages/mobile-ui-vue/components/common/date/date-converter.ts b/packages/mobile-ui-vue/components/common/date/date-converter.ts new file mode 100644 index 00000000000..d58257fe8d9 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/date/date-converter.ts @@ -0,0 +1,204 @@ + +const MONTHNAMES_LOOKUP: Record = + { jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6, jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12 }; +const DAYNAMES_LOOKUP: Record = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 }; + +export class DateConverter { + regexes: Record = { + YEAR: '[1-9]\\d{3}', + MONTH: '1[0-2]|0?[1-9]', + MONTH2: '1[0-2]|0[1-9]', + MONTHNAME: + 'jan|january|feb|february|mar|march|apr|april|may|jun|june|jul|july|aug|august|sep|september|oct|october|nov|november|dec|december', + DAYNAME: 'mon|monday|tue|tuesday|wed|wednesday|thu|thursday|fri|friday|sat|saturday|sun|sunday', + DAY: '3[01]|[12]\\d|0?[1-9]', + DAY2: '3[01]|[12]\\d|0[1-9]', + TIMEZONE: '[+-][01]\\d\\:?[0-5]\\d', + H24: '[01]\\d|2[0-3]', + MIN: '[0-5]\\d', + SEC: '[0-5]\\d', + MS: '\\d{3,}', + H12: '0?[1-9]|1[012]', + AMPM: 'am|pm', + UNIT: 'year|month|week|day|hour|minute|second|millisecond' + }; + + patterns = [ + // 2010-03-15 + ['iso_8601', this.makePattern('^(_YEAR_)-(_MONTH_)-(_DAY_)$'), '$2/$3/$1'], + + // 3-15-2010 + ['us', this.makePattern('^(_MONTH_)([\\/-])(_DAY_)\\2(_YEAR_)$'), '$1/$3/$4'], + + // 15.03.2010 + ['world', this.makePattern('^(_DAY_)([\\/\\.])(_MONTH_)\\2(_YEAR_)$'), '$3/$1/$4'], + + // 15-Mar-2010, 8 Dec 2011, "Thu, 8 Dec 2011" + ['chicago', this.makePattern('^(?:(?:_DAYNAME_),? )?(_DAY_)([ -])(_MONTHNAME_)\\2(_YEAR_)$'), '$3 $1, $4'], + + // "March 4, 2012", "Mar 4 2012", "Sun Mar 4 2012" + ['conversational', this.makePattern('^(?:(?:_DAYNAME_),? )?(_MONTHNAME_) (_DAY_),? (_YEAR_)$'), '$1 $2, $3'], + + // Tue Jun 22 17:47:27 +0000 2010 + [ + 'month_day_time_year', + this.makePattern('^(?:_DAYNAME_) (_MONTHNAME_) (_DAY_) ((?:_H24_)\\:(?:_MIN_)(?:\\:_SEC_)?) (_TIMEZONE_) (_YEAR_)$'), + (dateInfoList: Array) => { + const month = (''+this.getMonthByName(dateInfoList[1])).padStart(2, '0'); + const day = (''+dateInfoList[2]).padStart(2, '0'); + const year = dateInfoList[5]; + const time = dateInfoList[3]; + const timezone = dateInfoList[4]; + const date: any = year + '-' + month + '-' + day + 'T' + time + timezone; + if (isNaN(date)) { + return false; + } + return date; + } + ], + + // @123456789 + [ + 'unix', + /^@(-?\d+)$/, + (match: Array) => { + return this.create(parseInt(match[1], 10) * 1000); + } + ], + + // 24-hour time (This will help catch Date objects that are casted to a string) + [ + '24_hour', + this.makePattern('^(?:(.+?)(?: |T))?(_H24_)\\:(_MIN_)(?:\\:(_SEC_)(?:\\.(_MS_))?)? ?(?:GMT)?(_TIMEZONE_)?(?: \\([A-Z]+\\))?$'), + (match: Array) => { + let date: any; + const datePart = match[1]; + if (datePart) { + date = this.create(datePart); + if (isNaN(date)) { + return false; + } + } else { + date = new Date(); + date.setMilliseconds(0); + } + const hour = match[2]; + const minute = match[3]; + const second = match[4]; + const milliseconds = match[5]; + (date as Date).setHours(parseFloat(hour), parseFloat(minute), parseFloat(second || 0)); + + if (milliseconds) { + (date as Date).setMilliseconds(+String(milliseconds).slice(0, 3)); + } + + return date; + } + ], + + // 12-hour time + [ + '12_hour', + this.makePattern('^(?:(.+) )?(_H12_)(?:\\:(_MIN_)(?:\\:(_SEC_))?)? ?(_AMPM_)$'), + (match: Array) => { + let date: any; + const datePart = match[1]; + if (datePart) { + date = this.create(datePart); + if (isNaN(date)) { + return false; + } + } else { + date = new Date(); + date.setMilliseconds(0); + } + let hour = parseFloat(match[2]); + hour = match[5].toLowerCase() === 'am' ? (hour === 12 ? 0 : hour) : hour === 12 ? 12 : hour + 12; + const minute = match[3]; + const second = match[4]; + date.setHours(hour, parseFloat(minute || 0), parseFloat(second || 0)); + return date; + } + ] + ]; + + makePattern(code: string) { + code = code.replace(/_([A-Z][A-Z0-9]+)_/g, ($0, $1) => { + return this.regexes[$1]; + }); + return new RegExp(code, 'i'); + } + + getMonthByName(monthname: string) { + return MONTHNAMES_LOOKUP[String(monthname).slice(0, 3).toLowerCase()]; + } + + getWeekdayByName(dayname: string) { + return DAYNAMES_LOOKUP[String(dayname).slice(0, 3).toLowerCase()]; + } + + private parse(date: number|string) { + // If the passed value is an integer, interpret it as ms past epoch + if (!isNaN(Number(date))) { + return new Date(date); + } + + // trim the date + date = String(date).replace(/^\s*(.*)\s*$/, '$1'); + // normalize whitespace + date = date.replace(/\s{2,}/g, ' '); + if (date === '') { + return Date.now(); + } + + let i = 0; + // try each of our patterns + while(i < this.patterns.length) { + const pattern = this.patterns[i]; + let callback; + let regex: string| RegExp; + if (typeof pattern[0] == 'string') { + // pattern[0] is the name of the pattern + regex = pattern[1] as RegExp; + callback = pattern[2]; + } else { + // backwards compatibility with version 3.1 + regex = pattern[0] as RegExp; + callback = pattern[1]; + } + const match = date.match(regex); + if (!match) { + i++; + continue; + } + + if (typeof callback == 'function') { + const result = callback(match); + if (result instanceof Date) { + return result; + } + } else { + // fn is not a function but a string replace command + const milliseconds = Date.parse(date.replace(regex, callback as string)); + if (!isNaN(milliseconds)) { + return new Date(milliseconds); + } + } + i++; + } + return NaN; + } + + create(date?: Date | string | number) { + // 0 arguments or date is undefined + if (date == null) { + return Date.now(); + } + // If the passed value is already a date object, return it + if (date instanceof Date) { + return date; + } + + return this.parse(date); + } +} diff --git a/packages/mobile-ui-vue/components/common/date/use-date-format.ts b/packages/mobile-ui-vue/components/common/date/use-date-format.ts new file mode 100644 index 00000000000..05a937d8616 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/date/use-date-format.ts @@ -0,0 +1,54 @@ +/* eslint-disable eqeqeq */ +import { format, isValid, parseISO } from "date-fns"; + +import { UseDateFormat } from "../types"; +import { DateConverter } from "./date-converter"; + +export function useDateFormat(): UseDateFormat { + + const dateConverter = new DateConverter(); + + function formatTo(dateValue: string | Date, dateFormat: string): string { + if (!dateValue) { + return ""; + } + + if (typeof dateValue === "string" && dateValue.indexOf("0001") === 0) { + return ""; + } + + if (dateValue instanceof Date) { + return format(dateValue, dateFormat); + } + + let dateObject: any = parseISO(dateValue); + + if (dateObject == "Invalid Date") { + dateObject = dateConverter.create(dateValue) || new Date(dateValue); + } + + // const d = parseISO(value); + if (isValid(dateObject)) { + dateObject = parseISO(format(dateObject, "yyyy-MM-dd HH:mm:ss")); + return format(dateObject, dateFormat); + } + if (dateFormat.indexOf("HH") === 0 || dateFormat.indexOf("hh") === 0) { + // 仅有时间部分 + // 提取时间 + const _time = dateValue.match(/\d*/g)?.filter((n) => n !== "").join(":"); + + if (dateFormat === "HH" || dateFormat === "hh") { + dateFormat += ":mm"; + } + + const fullDateTime = parseISO("2024-06-05 " + _time); + return format(fullDateTime, dateFormat); + } + return ""; + + } + + return { + formatTo + }; +} diff --git a/packages/mobile-ui-vue/components/common/date/use-time-ago.ts b/packages/mobile-ui-vue/components/common/date/use-time-ago.ts new file mode 100644 index 00000000000..cc251eb044d --- /dev/null +++ b/packages/mobile-ui-vue/components/common/date/use-time-ago.ts @@ -0,0 +1,65 @@ +import { TimeAgoDate, TimeAgoOptions, UseTimeAgoFormat } from "../types"; +import { DateConverter } from "./date-converter"; + +const TEXTZH_CN = ['秒', '分钟', '小时', '天', '周', '个月', '年']; + +const SECONDS_ARRAY = [ + 60, // 60 seconds in 1 min + 60, // 60 mins in 1 hour + 24, // 24 hours in 1 day + 7, // 7 days in 1 week + 365 / 7 / 12, // 4.345238095238096 weeks in 1 month + 12, // 12 months in 1 year +]; + +export function useTimeAgo(): UseTimeAgoFormat { + + const dateConverter = new DateConverter(); + + + function timeAgoText(second: number, index: number): [string, string] { + if (index === 0) {return ['刚刚', '片刻后'];} + const unit = TEXTZH_CN[~~(index / 2)]; + return [`${second} ${unit}前`, `${second} ${unit}后`]; + } + + function toDate(date: TimeAgoDate): Date { + if (typeof date == 'object') { + return date; + } else { + const result = dateConverter.create(date); + return typeof result == 'object' ? result : new Date(); + } + + } + function secondDifference(date: TimeAgoDate, relativeDate: TimeAgoDate | undefined): number { + const relDate = relativeDate ? toDate(relativeDate) : new Date(); + return (+relDate - +toDate(date)) / 1000; + } + + + function formatDifferent(second: number): string { + const agoIn = second < 0 ? 1 : 0; + second = Math.abs(second); + // const totalSec = diff; + let index = 0; + for (; second >= SECONDS_ARRAY[index] && index < SECONDS_ARRAY.length; index++) { + second /= SECONDS_ARRAY[index]; + } + second = Math.floor(second); + + index *= 2; + + if (second > (index === 0 ? 9 : 1)) {index += 1;} + + return timeAgoText(second, index)[agoIn].replace('%s', second.toString()); + } + function formatTo(date: TimeAgoDate, options?: TimeAgoOptions): string { + // 计算差异秒 + const second = secondDifference(date, options && options.relativeDate); + return formatDifferent(second); + }; + return { + formatTo + }; +} diff --git a/packages/mobile-ui-vue/components/common/directive/area-response.ts b/packages/mobile-ui-vue/components/common/directive/area-response.ts new file mode 100644 index 00000000000..c3cf63e64cd --- /dev/null +++ b/packages/mobile-ui-vue/components/common/directive/area-response.ts @@ -0,0 +1,136 @@ +import { addClass, removeClass } from "../utils/use-class"; + +const breakPoints = [ + { size: 'sm', width: 576 }, + { size: 'md', width: 768 }, + { size: 'lg', width: 888 }, + { size: 'xl', width: 1200 }, + { size: 'el', width: 1690 } +]; + +/** + * 移除绑定 + * @param sharedObject + */ +function deleteObserver(sharedObject) { + if (sharedObject.resizeObserver) { + sharedObject.resizeObserver.disconnect(); + sharedObject.sharedObject = null; + } +} +/** + * 宽度变更后,执行事件 + * @param sharedObject + * @param bindElement + * @param newWidth + * @returns + */ +function afterWidthChange(sharedObject, bindElement, newWidth = 0) { + const result = [] as any; + if (!bindElement) { + return; + } + const areaWidth = newWidth ? newWidth : bindElement.getBoundingClientRect().width; + const width = parseFloat(areaWidth); + for (let k = 0; k < breakPoints.length; k++) { + if (breakPoints[k]['width'] <= width) { + result.push(breakPoints[k]['size']); + } + } + if (sharedObject.className.join(',') !== result.join(',')) { + // 旧的比新的多,应该移除class + const distance = sharedObject.className.length - result.length; + if (distance > 0) { + for (let m = result.length; m < sharedObject.className.length; m++) { + removeClass(bindElement, 'f-area-response--' + sharedObject.className[m]); + } + } else { + for (let m = sharedObject.className.length; m < result.length; m++) { + addClass(bindElement, 'f-area-response--' + result[m]); + } + } + sharedObject.className = [...result]; + } +} + +/** + * 绑定监听宽度变化事件 + * @param sharedObject + * @param bindElement + */ +function bindObserver(sharedObject, bindElement) { + if (sharedObject.enable && sharedObject.autoWidth) { + if (!sharedObject.resizeObserver) { + sharedObject.resizeObserver = new ResizeObserver(entries => { + if (!entries || entries.length < 1 || !entries[0].contentRect) { + return; + } + const rect = entries[0].contentRect; + if (Math.abs(parseInt(rect.width + '') - sharedObject.width) > sharedObject.threshold) { + afterWidthChange(sharedObject, bindElement, rect.width); + sharedObject.width = parseInt(rect.width + ''); + } + }); + sharedObject.resizeObserver.observe(bindElement); + } + } else { + deleteObserver(sharedObject); + } +} + +function supportResponse(sharedObject, bindElement) { + // 启用响应 + if (sharedObject.enable) { + addClass(bindElement, 'f-area-response'); + afterWidthChange(sharedObject, bindElement); + } else { + // 移除对应的样式 + removeClass(bindElement, 'f-area-response'); + for (let m = sharedObject.className.length; m > 0; m--) { + addClass(bindElement, 'f-area-response--' + sharedObject.className[m]); + } + sharedObject.className = []; + } + bindObserver(sharedObject, bindElement); +} +function updateSharedObject(sharedObject, binding) { + if (binding.value && Object.prototype.hasOwnProperty.call(binding.value, 'enable')) { + sharedObject.enable = binding.value.enable; + } + if (binding.value && Object.prototype.hasOwnProperty.call(binding.value, 'autoWidth')) { + sharedObject.autoWidth = binding.value.autoWidth; + } +} + +/** + * enable:启用 + * autoWidth:自动宽度 + */ +const areaResponseDirective = { + // 在绑定元素的父组件 + // 及他自己的所有子节点都挂载完成后调用 + mounted: (bindElement, binding, vnode) => { + vnode.sharedObject = { + className: [], + resizeObserver: null, + enable: true, + autoWidth: true, + threshold: 10, + width: 0 + }; + updateSharedObject(vnode.sharedObject, binding); + supportResponse(vnode.sharedObject, bindElement); + }, + // 在绑定元素的父组件 + // 及他自己的所有子节点都更新后调用 + updated: function (bindElement, binding, vnode, prevVnode) { + vnode.sharedObject = prevVnode.sharedObject; + updateSharedObject(vnode.sharedObject, binding); + supportResponse(vnode.sharedObject, bindElement); + }, + // 绑定元素的父组件卸载前调用 + beforeUnmount(bindElement, binding, vnode) { + deleteObserver(vnode.sharedObject); + } +}; +export default areaResponseDirective; diff --git a/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts b/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts new file mode 100644 index 00000000000..9ca3d1dda47 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/editor/binding-selector/style.ts @@ -0,0 +1,6 @@ +import "@/components/dependent-base/style"; +import "@/components/dependent-icon/style"; +import "@/components/tree-grid/style"; +import "@/components/button-edit/style"; +import "@/components/radio/style"; +import "@/components/modal/style"; diff --git a/packages/mobile-ui-vue/components/common/entity/entity-schema.ts b/packages/mobile-ui-vue/components/common/entity/entity-schema.ts new file mode 100644 index 00000000000..30e62037ec6 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/entity/entity-schema.ts @@ -0,0 +1,274 @@ +/* eslint-disable no-use-before-define */ +export interface FormSchema { + sourceUri: string; + id: string; + code: string; + name: string; + entities: FormSchemaEntity[]; + variables: FormSchemaEntityField[]; + eapiId: string; + extendProperties: { enableStdTimeFormat: boolean }; + eapiCode?: string; + eapiName?: string; + eapiNameSpace?: string; + voPath?: string; + voNameSpace?: string; +} + +/** + * 实体 + */ +export interface FormSchemaEntity { + id: string; + code: string; + name: string; + label: string; + type: FormSchemaEntityType; +} + +/** + * 字段类型枚举 + */ +export enum FormSchemaEntityField$Type { + /** + * 简单类型字段 + */ + SimpleField = "SimpleField", + /** + * 关联/UDT类型字段 + */ + ComplexField = "ComplexField" +} +/** + * 字段编辑器对象 + */ +export interface FormSchemaEntityFieldEditor { + $type: string; + [propName: string]: any; +} +export interface DesignViewModelField extends FormSchemaEntityField { + valueChanging: string; + valueChanged: string; + groupId: string; + groupName: string; + isSchemaRemoved?: boolean; + updateOn?: string; +} +/** + * 字段 + */ +export interface FormSchemaEntityField { + $type: FormSchemaEntityField$Type; + id: string; + originalId: string; + code: string; + label: string; + bindingField: string; + name: string; + defaultValue?: any; + require?: boolean; + readonly?: boolean; + type: FormSchemaEntityFieldType; + editor?: FormSchemaEntityFieldEditor; + path?: string; + bindingPath?: string; + multiLanguage?: boolean; + expression?: any; +} +/** + * 字段类型对象中的类型枚举 + */ +export enum FormSchemaEntityFieldType$Type { + /** + * 字符串 + */ + StringType = "StringType", + /** + * 备注 + */ + TextType = "TextType", + /** + * 数字(整数、浮点数) + */ + NumericType = "NumericType", + /** + * 布尔 + */ + BooleanType = "BooleanType", + /** + * 日期 + */ + DateType = "DateType", + /** + * 日期时间 + */ + DateTimeType = "DateTimeType", + /** + * 枚举 + */ + EnumType = "EnumType", + /** + * 实体类 + */ + EntityType = "EntityType", + /** + * 分级码 + */ + HierarchyType = "HierarchyType", + /** + * 对象 + */ + ObjectType = "ObjectType", + /** + * 数字(大数据) + */ + BigNumericType = "BigNumericType" +} +/** + * 字段类型中的名称 + */ +export enum FormSchemaEntityFieldTypeName { + /** + * 简单类型字段 + */ + String = "String", + /** + * 日期时间 + */ + DateTime = "DateTime", + /** + * 日期 + */ + Date = "Date", + /** + * 枚举 + */ + Enum = "Enum", + /** + * 布尔 + */ + Boolean = "Boolean", + /** + * 数字 + */ + Number = "Number", + /** + * 备注 + */ + Text = "Text", + /** + * 大数字 + */ + BigNumber = "BigNumber" + /** + * 人员 + */ +} +/** + * 枚举类型 + */ +export interface EnumData { + value: string; + name: string; +} +/** + * 实体 + */ +export interface FormSchemaEntity { + id: string; + code: string; + name: string; + label: string; + type: FormSchemaEntityType; +} +/** + * 实体类型对象 + */ +export interface FormSchemaEntityType { + $type: string; + name: string; + primary: string; + fields: FormSchemaEntityField[]; + entities?: FormSchemaEntity[]; + displayName?: string; +} +/** + * 字段类型对象 + */ +export interface FormSchemaEntityFieldType { + $type: FormSchemaEntityFieldType$Type; + name: FormSchemaEntityFieldTypeName | any; + length?: number; + precision?: number; + valueType?: FormSchemaEntityFieldType; + enumValues?: EnumData[]; + fields?: FormSchemaEntityField[]; + displayName?: string; + primary?: string; + entities?: FormSchemaEntity[]; + elementType?: GSPElementDataType; + extendProperty?: any; +} +/** + * 字段数据类型 + */ +export enum GSPElementDataType { + /** + * 文本 + */ + String = "String", + /** + * 备注 + */ + Text = "Text", + /** + * 整数 + */ + Integer = "Integer", + /** + * 浮点数 + */ + Decimal = "Decimal", + /** + * 布尔型 + */ + Boolean = "Boolean", + /** + * 日期型 + */ + Date = "Date", + /** + * 日期时间型 + */ + DateTime = "DateTime", + /** + * 二进制 + */ + Binary = "Binary" +} +/** + * dom Json ViewModel 节点中states实体 + */ +export interface FormVariable { + id: string; + code: string; + name: string; + value?: any; + type: string; + category: string; + fields?: any[]; + defaultValue?: any; +} +/** + * 表单变量 + */ +export interface DesignFormVariable extends FormVariable { + /** + * 分组ID + */ + groupId: string; + /** + * 分组名称 + */ + groupName: string; +} diff --git a/packages/mobile-ui-vue/components/common/index.ts b/packages/mobile-ui-vue/components/common/index.ts index 79f1d765672..279f22b74ef 100644 --- a/packages/mobile-ui-vue/components/common/index.ts +++ b/packages/mobile-ui-vue/components/common/index.ts @@ -1,2 +1,36 @@ +import { App } from 'vue'; +import areaResponseDirective from './directive/area-response'; + export * from './src/compositions'; +export * from './types'; +export * from './text-box/composition/use-text-box'; +export * from './text-box/composition/use-text-box-design'; +export * from './text-box/composition/use-clear'; +export * from './date/date-converter'; +export * from './date/use-date-format'; +export * from './number/use-number-format'; +export * from './date/use-time-ago'; +export * from './utils/use-request-animation'; +export * from './utils/use-appearance'; +export * from './utils/symbol-key'; +export * from './radio-checkbox/use-check'; +export * from './radio-checkbox/radio-checkbox.props'; +export * from './utils/encrypt'; +export * from './utils/resolve-field'; +export * from './utils/use-guid'; +export * from './entity/entity-schema'; export * from './src/utils'; + +export default { + install(app: App): void { + app.directive('area-response', areaResponseDirective); + }, + register(componentMap: Record, propsResolverMap: Record, + configResolverMap: Record, resolverMap: Record): void { + componentMap['area-response'] = areaResponseDirective; + }, + registerDesigner(componentMap: Record, propsResolverMap: Record): void { + componentMap['area-response'] = areaResponseDirective; + } +}; + diff --git a/packages/mobile-ui-vue/components/common/number/use-number-format.ts b/packages/mobile-ui-vue/components/common/number/use-number-format.ts new file mode 100644 index 00000000000..76f430ea334 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/number/use-number-format.ts @@ -0,0 +1,278 @@ +import BigNumber from "bignumber.js"; +import { NumberOption, NumberType, UseNumberFormat } from "../types"; + +export function useNumberFormat(): UseNumberFormat { + /** + * 获取最大值 + * @param n1 + * @param n2 + * @returns + */ + function max(firstValue: Array | NumberType, secondValue: NumberType | null = null): string { + if (Array.isArray(firstValue)) { + return BigNumber.max.apply(null, firstValue).toFixed(); + } else { + if (firstValue && secondValue) { + return BigNumber.maximum(firstValue, secondValue).toFixed(); + } else { + console.error(`请提供比较的值firstValue、secondValue.`); + return ''; + } + } + } + + /** + * 最小值 + * @param firstValue + * @param secondValue + * @returns + */ + function min(firstValue: Array | NumberType, secondValue: NumberType | null = null): string { + if (Array.isArray(firstValue)) { + return BigNumber.min.apply(null, firstValue).toFixed(); + } else { + if (firstValue && secondValue) { + return BigNumber.minimum(firstValue, secondValue).toFixed(); + } else { + console.error(`请提供比较的值firstValue、secondValue.`); + return ''; + } + } + } + + /** + * 求和 + * @param numberArray + * @returns + */ + function sum(numberArray: NumberType[]): string { + return BigNumber.sum.apply(null, numberArray).toFixed(); + } + + /** + * 平均数 + * @param total + * @param len + * @returns + */ + function average(total: NumberType, len: number): string { + return new BigNumber(total).div(len).toFixed(); + } + + /** + * 加法 + * @param firstValue + * @param secondValue + * @returns + */ + function plus(firstValue: NumberType, secondValue: NumberType): string { + return new BigNumber(firstValue).plus(secondValue).toFixed(); + } + + /** + * 乘法 + * @param firstValue + * @param secondValue + * @returns + */ + function multiplied(firstValue: NumberType, secondValue: NumberType): string { + return new BigNumber(firstValue).times(secondValue).toFixed(); + } + + /** + * 减法 + * @param firstValue + * @param secondValue + * @returns + */ + function minus(firstValue: NumberType, secondValue: NumberType): string { + return new BigNumber(firstValue).minus(secondValue).toFixed(); + } + + /** + * 是否相等 + * @param firstValue + * @param secondValue + * @returns + */ + function equal(firstValue: NumberType, secondValue: NumberType): boolean { + return new BigNumber(firstValue).eq(secondValue); + } + /** + * 是否小于 + * @param firstValue + * @param secondValue + * @returns + */ + function lessThan(firstValue: NumberType, secondValue: NumberType): boolean { + return new BigNumber(firstValue).lt(secondValue); + } + /** + * 是否大于 + * @param firstValue + * @param secondValue + * @returns + */ + function greaterThan(firstValue: NumberType, secondValue: NumberType): boolean { + return new BigNumber(firstValue).gt(secondValue); + } + /** + * 转成数字 + */ + /** */ + function toNumber(value: string): number { + return new BigNumber(value).toNumber(); + } + /** + * 精度 + * @param value + * @param precision + * @returns + */ + function toFixed(value: string, precision: number = 0): string { + return new BigNumber(value).toFixed(precision); + } + /** + * 转换金额 + * @param money + * @returns + */ + function convertCurrency(money: string): string { + // 汉字的数字 + const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; + // 基本单位 + const cnIntRadice = ['', '拾', '佰', '仟']; + // 对应整数部分扩展单位 + const cnIntUnits = ['', '万', '亿', '兆']; + // 对应小数部分单位 + const cnDecUnits = ['角', '分', '毫', '厘']; + // 整数金额时后面跟的字符 + const cnInteger = '整'; + // 整型完以后的单位 + const cnIntLast = '元'; + // 最大处理的数字 + // eslint-disable-next-line no-loss-of-precision + const maxNum = 999999999999999.9999; + // 金额整数部分 + let intPart; + // 金额小数部分 + let decimalNum; + // 输出的中文金额字符串 + let chineseStr = ''; + // 分离金额后用的数组,预定义 + let parts; + if (money === '') { return ''; } + const moneyNum = parseFloat(money); + if (moneyNum >= maxNum) { + // 超出最大处理数字 + return ''; + } + if (moneyNum === 0) { + chineseStr = cnNums[0] + cnIntLast + cnInteger; + return chineseStr; + } + // 转换为字符串 + money = moneyNum.toString(); + if (money.indexOf('.') === -1) { + intPart = money; + decimalNum = ''; + } else { + parts = money.split('.'); + intPart = parts[0]; + decimalNum = parts[1].substr(0, 4); + } + // 获取整型部分转换 + if (parseInt(intPart, 10) > 0) { + let zeroCount = 0; + const intPartLength = intPart.length; + for (let i = 0; i < intPartLength; i++) { + const intNumSub = intPart.substr(i, 1); + const leftLength = intPartLength - i - 1; + const divisionInt = leftLength / 4; + const remainder = leftLength % 4; + if (intNumSub === '0') { + zeroCount++; + } else { + if (zeroCount > 0) { + chineseStr += cnNums[0]; + } + // 归零 + zeroCount = 0; + chineseStr += cnNums[parseInt(intNumSub, 10)] + cnIntRadice[remainder]; + } + if (remainder === 0 && zeroCount < 4) { + chineseStr += cnIntUnits[divisionInt]; + } + } + chineseStr += cnIntLast; + } + // 小数部分 + if (decimalNum !== '') { + const decLen = decimalNum.length; + for (let i = 0; i < decLen; i++) { + const n = decimalNum.substr(i, 1); + if (n !== '0') { + chineseStr += cnNums[Number(n)] + cnDecUnits[i]; + } + } + } + if (chineseStr === '') { + chineseStr += cnNums[0] + cnIntLast + cnInteger; + } else if (decimalNum === '') { + chineseStr += cnInteger; + } + return chineseStr; + } + /** + * 去除格式化 + * @param value + * @param options + * @returns + */ + function removeFormat(value: NumberType | null | undefined, options: NumberOption): string { + let newValue = (value === null || value === undefined || typeof value == 'number' && isNaN(value)) ? '' : String(value); + if (options) { + // 去前缀 + if (options.prefix) { + newValue = newValue.replace(new RegExp(options.prefix, 'g'), ''); + } + + // 去后缀 + if (options.suffix) { + newValue = newValue.replace(new RegExp(options.suffix, 'g'), ''); + } + + // 去掉千分位分隔符 + newValue = newValue.replace(/\\,/g, ''); + } + return newValue; + } + /** + * 格式化数据 + * @param value + * @param options + * @returns + */ + function formatTo(value: NumberType, options: NumberOption): string { + const bignum = new BigNumber(value); + const fmt = { + prefix: options.prefix || '', + suffix: options.suffix || '', + decimalSeparator: options.decimalSeparator || '.', + groupSeparator: options.groupSeparator || '', + groupSize: 3 + }; + + if (bignum.isNaN()) { + return ''; + } + + let precision = options.precision || 0; + precision = Number(precision); + + return bignum.toFormat(precision, fmt); + } + return { + formatTo, removeFormat, convertCurrency, toFixed, toNumber, greaterThan, lessThan, equal, minus, multiplied, plus, average, sum, min, max + }; +} diff --git a/packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts b/packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts new file mode 100644 index 00000000000..24f1312634c --- /dev/null +++ b/packages/mobile-ui-vue/components/common/radio-checkbox/radio-checkbox.props.ts @@ -0,0 +1,45 @@ + +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { PropType } from 'vue'; +export type RadioCheckboxType = 'default' | 'button'; +export const radioCheckboxCommonProps = { + /** + * 是否被选中 + */ + checked: { type: Boolean, default: false }, + /** + * 展示方向 水平或者垂直 + */ + direction: { type: String as PropType<'vertical' | 'horizontal'>, default: 'vertical' }, + /** + * 单选组类型 + */ + // mode: { type: String as PropType<'default' | 'button' | 'tag'>, default: 'default' }, + /** + * type为button或者tag时的颜色 + */ + type: { type: String as PropType, default: 'default' }, + /** + * type为button或者tag时的尺寸 + * 应该要弃用 + */ + size: { type: String as PropType<'small' | 'middle' | 'large'>, default: 'middle' }, + /** + * 选项列表 + */ + options: { type: Object, default: []} +}; diff --git a/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts b/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts new file mode 100644 index 00000000000..0c67b4d7e26 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/radio-checkbox/use-check.ts @@ -0,0 +1,100 @@ +import { computed, ref, SetupContext, watch } from 'vue'; +import { isUndefined } from 'lodash-es'; +import { CheckBoxProps, CheckboxGroupProps } from '@/components/checkbox'; +import { RadioProps, RadioGroupProps } from '@/components/radio-group'; + +export function useCheck( + props: CheckBoxProps | RadioProps, + context: SetupContext, + parentProps: CheckboxGroupProps | RadioGroupProps, + parentContext: SetupContext, +) { + // name,如果相同,可以作为一组 + const name = computed(() => parentProps?.name); + // 禁用 + const disabled = computed(() => props.readonly || props.disabled || parentProps?.readonly || parentProps?.disabled); + // 展示按钮样式 + const shouldRenderButton = computed(() => parentProps?.type === 'button'); + // 展示原生单选框或者复选框 + const shouldRenderNative = computed(() => parentProps?.type === 'default' || isUndefined(parentProps?.type)); + + // 如果是group + const checked = computed(() => parentProps ? + parentProps.modelValue === props.value || parentProps.modelValue.includes(props.value) : + !!props.checked || !!props.modelValue); + + // 按钮样式 + const buttonClass = computed(() => { + return { + btn: true, + 'f-radio-button': true, + active: checked.value, + 'f-radio-button-primary': true, + }; + }); + + + const modelValue = ref(props.modelValue); + const indeterminate = ref(props.indeterminate); + watch(() => props.modelValue, (newValue: boolean) => { + modelValue.value = newValue; + }); + watch(() => props.indeterminate, (newValue: boolean) => { + indeterminate.value = newValue; + }); + + // 点击单选框事件 + const onClickRadio = (e: MouseEvent) => { + e.stopPropagation(); + if (disabled.value) { + return; + } + if (parentProps) { + // 父组件双向绑定 + if (!checked.value) { + parentContext.emit('update:modelValue', props.value); + // 值变化事件 + parentContext.emit('changeValue', props.value); + } + } else { + context.emit('update:checked', !checked.value); + } + }; + + // 点击复选框事件 + const onClickCheckBox = (e: MouseEvent) => { + e.stopPropagation(); + if (disabled.value) { + return; + } + if (parentProps) { + // 父组件双向绑定 + if (!checked.value) { + parentContext.emit('update:modelValue', [...parentProps.modelValue, props.value]); + // 值变化事件 + parentContext.emit('changeValue', [...parentProps.modelValue, props.value]); + } else { + const valuesWithoutSelf = parentProps.modelValue?.filter(value => value !== props.value); + parentContext.emit('update:modelValue', valuesWithoutSelf); + // 值变化事件 + parentContext.emit('changeValue', valuesWithoutSelf); + } + } else { + context.emit('update:checked', !checked.value); + context.emit('update:modelValue', !checked.value); + context.emit('changeValue', !checked.value); + context.emit('change', { originalEvent: e, checked: !checked.value }); + } + }; + return { + disabled, + name, + indeterminate, + shouldRenderButton, + shouldRenderNative, + buttonClass, + checked, + onClickRadio, + onClickCheckBox + }; +} diff --git a/packages/mobile-ui-vue/components/common/src/entity/base-property.ts b/packages/mobile-ui-vue/components/common/src/entity/base-property.ts new file mode 100644 index 00000000000..8c9c9eb2c67 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/entity/base-property.ts @@ -0,0 +1,129 @@ +import { DesignerComponentInstance, DgControl } from "@/components/designer-canvas"; +import { cloneDeep } from "lodash-es"; + +/** + * 控件属性基类 + */ +export class BaseControlProperty { + public componentId: string; + + public viewModelId: string; + + public eventsEditorUtils: any; + + public formSchemaUtils: any; + public formMetadataConverter: any; + public designViewModelUtils: any; + public designViewModelField: any; + public controlCreatorUtils: any; + public designerHostService: any; + + schemaService: any = null; + + metadataService: any = null; + + protected propertyConfig = { + type: 'object', + categories: {} + }; + + constructor(componentId: string, designerHostService: any) { + this.componentId = componentId; + this.designerHostService = designerHostService; + this.eventsEditorUtils = designerHostService['eventsEditorUtils']; + this.formSchemaUtils = designerHostService['formSchemaUtils']; + this.formMetadataConverter = designerHostService['formMetadataConverter']; + this.viewModelId = this.formSchemaUtils?.getViewModelIdByComponentId(componentId) || ''; + this.designViewModelUtils = designerHostService['designViewModelUtils']; + this.controlCreatorUtils = designerHostService['controlCreatorUtils']; + this.metadataService = designerHostService['metadataService']; + this.schemaService = designerHostService['schemaService']; + } + + getTableInfo() { + return this.schemaService?.getTableInfoByViewModelId(this.viewModelId); + } + + setDesignViewModelField(propertyData: any) { + const bindingFieldId = propertyData.binding && propertyData.binding.type === 'Form' && propertyData.binding.field; + // 视图模型中[字段更新时机]属性现在要在控件上维护,所以在控件上复制一份属性值 + if (bindingFieldId) { + if (!this.designViewModelField) { + const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); + this.designViewModelField = dgViewModel.fields.find(f => f.id === bindingFieldId); + } + propertyData.updateOn = this.designViewModelField?.updateOn; + } + } + + getBasicPropConfig(propertyData: any): any { + return { + description: 'Basic Information', + title: '基本信息', + properties: { + id: { + description: '组件标识', + title: '标识', + type: 'string', + readonly: true + }, + type: { + description: '组件类型', + title: '控件类型', + type: 'select', + editor: { + type: 'combo-list', + textField: 'name', + valueField: 'value', + editable: false, + data: [{ value: propertyData.type, name: DgControl[propertyData.type] && DgControl[propertyData.type].name }] + } + } + } + }; + + } + + + protected getAppearanceConfig(propertyData = null): any { + return { + title: "外观", + description: "Appearance", + properties: { + class: { + title: "class样式", + type: "string", + description: "组件的CSS样式", + $converter: "/converter/appearance.converter" + }, + style: { + title: "style样式", + type: "string", + description: "组件的样式", + $converter: "/converter/appearance.converter" + } + } + }; + } + + /** + * + * @param propertyId + * @param componentInstance + * @returns + */ + public updateElementByParentContainer(propertyId: string, componentInstance: DesignerComponentInstance) { + // 1、定位控件父容器 + const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; + if (!parentContainer) { + return; + } + const index = parentContainer.contents.findIndex(c => c.id === propertyId); + // 通过cloneDeep方式的触发更新 + const controlSchema = cloneDeep(parentContainer.contents[index]); + // 5、替换控件 + parentContainer.contents.splice(index, 1); + parentContainer.contents.splice(index, 0, controlSchema); + } + +} diff --git a/packages/mobile-ui-vue/components/common/src/entity/entity-schema.ts b/packages/mobile-ui-vue/components/common/src/entity/entity-schema.ts new file mode 100644 index 00000000000..30e62037ec6 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/entity/entity-schema.ts @@ -0,0 +1,274 @@ +/* eslint-disable no-use-before-define */ +export interface FormSchema { + sourceUri: string; + id: string; + code: string; + name: string; + entities: FormSchemaEntity[]; + variables: FormSchemaEntityField[]; + eapiId: string; + extendProperties: { enableStdTimeFormat: boolean }; + eapiCode?: string; + eapiName?: string; + eapiNameSpace?: string; + voPath?: string; + voNameSpace?: string; +} + +/** + * 实体 + */ +export interface FormSchemaEntity { + id: string; + code: string; + name: string; + label: string; + type: FormSchemaEntityType; +} + +/** + * 字段类型枚举 + */ +export enum FormSchemaEntityField$Type { + /** + * 简单类型字段 + */ + SimpleField = "SimpleField", + /** + * 关联/UDT类型字段 + */ + ComplexField = "ComplexField" +} +/** + * 字段编辑器对象 + */ +export interface FormSchemaEntityFieldEditor { + $type: string; + [propName: string]: any; +} +export interface DesignViewModelField extends FormSchemaEntityField { + valueChanging: string; + valueChanged: string; + groupId: string; + groupName: string; + isSchemaRemoved?: boolean; + updateOn?: string; +} +/** + * 字段 + */ +export interface FormSchemaEntityField { + $type: FormSchemaEntityField$Type; + id: string; + originalId: string; + code: string; + label: string; + bindingField: string; + name: string; + defaultValue?: any; + require?: boolean; + readonly?: boolean; + type: FormSchemaEntityFieldType; + editor?: FormSchemaEntityFieldEditor; + path?: string; + bindingPath?: string; + multiLanguage?: boolean; + expression?: any; +} +/** + * 字段类型对象中的类型枚举 + */ +export enum FormSchemaEntityFieldType$Type { + /** + * 字符串 + */ + StringType = "StringType", + /** + * 备注 + */ + TextType = "TextType", + /** + * 数字(整数、浮点数) + */ + NumericType = "NumericType", + /** + * 布尔 + */ + BooleanType = "BooleanType", + /** + * 日期 + */ + DateType = "DateType", + /** + * 日期时间 + */ + DateTimeType = "DateTimeType", + /** + * 枚举 + */ + EnumType = "EnumType", + /** + * 实体类 + */ + EntityType = "EntityType", + /** + * 分级码 + */ + HierarchyType = "HierarchyType", + /** + * 对象 + */ + ObjectType = "ObjectType", + /** + * 数字(大数据) + */ + BigNumericType = "BigNumericType" +} +/** + * 字段类型中的名称 + */ +export enum FormSchemaEntityFieldTypeName { + /** + * 简单类型字段 + */ + String = "String", + /** + * 日期时间 + */ + DateTime = "DateTime", + /** + * 日期 + */ + Date = "Date", + /** + * 枚举 + */ + Enum = "Enum", + /** + * 布尔 + */ + Boolean = "Boolean", + /** + * 数字 + */ + Number = "Number", + /** + * 备注 + */ + Text = "Text", + /** + * 大数字 + */ + BigNumber = "BigNumber" + /** + * 人员 + */ +} +/** + * 枚举类型 + */ +export interface EnumData { + value: string; + name: string; +} +/** + * 实体 + */ +export interface FormSchemaEntity { + id: string; + code: string; + name: string; + label: string; + type: FormSchemaEntityType; +} +/** + * 实体类型对象 + */ +export interface FormSchemaEntityType { + $type: string; + name: string; + primary: string; + fields: FormSchemaEntityField[]; + entities?: FormSchemaEntity[]; + displayName?: string; +} +/** + * 字段类型对象 + */ +export interface FormSchemaEntityFieldType { + $type: FormSchemaEntityFieldType$Type; + name: FormSchemaEntityFieldTypeName | any; + length?: number; + precision?: number; + valueType?: FormSchemaEntityFieldType; + enumValues?: EnumData[]; + fields?: FormSchemaEntityField[]; + displayName?: string; + primary?: string; + entities?: FormSchemaEntity[]; + elementType?: GSPElementDataType; + extendProperty?: any; +} +/** + * 字段数据类型 + */ +export enum GSPElementDataType { + /** + * 文本 + */ + String = "String", + /** + * 备注 + */ + Text = "Text", + /** + * 整数 + */ + Integer = "Integer", + /** + * 浮点数 + */ + Decimal = "Decimal", + /** + * 布尔型 + */ + Boolean = "Boolean", + /** + * 日期型 + */ + Date = "Date", + /** + * 日期时间型 + */ + DateTime = "DateTime", + /** + * 二进制 + */ + Binary = "Binary" +} +/** + * dom Json ViewModel 节点中states实体 + */ +export interface FormVariable { + id: string; + code: string; + name: string; + value?: any; + type: string; + category: string; + fields?: any[]; + defaultValue?: any; +} +/** + * 表单变量 + */ +export interface DesignFormVariable extends FormVariable { + /** + * 分组ID + */ + groupId: string; + /** + * 分组名称 + */ + groupName: string; +} diff --git a/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts b/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts new file mode 100644 index 00000000000..fb43a637e9a --- /dev/null +++ b/packages/mobile-ui-vue/components/common/src/entity/input-base-property.ts @@ -0,0 +1,282 @@ +import { BaseControlProperty } from './base-property'; +import { DesignerComponentInstance } from "@/components/designer-canvas"; +import { SchemaDOMMapping } from "@/components/property-panel"; +import { canvasChanged } from "@/components/designer-canvas/src/composition/designer-canvas-changed"; +import { FormSchemaEntityFieldType$Type } from './entity-schema'; + +export class InputBaseProperty extends BaseControlProperty { + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + } + + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicProperties(propertyData, componentInstance); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceProperties(propertyData, componentInstance); + // 编辑器 + this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); + return this.propertyConfig; + } + + public getBasicProperties(propertyData, componentInstance): any { + const self = this; + this.setDesignViewModelField(propertyData); + return { + description: 'Basic Information', + title: '基本信息', + properties: { + id: { + description: '组件标识', + title: '标识', + type: 'string', + readonly: true + }, + type: { + description: '编辑器类型', + title: '编辑器类型', + type: 'string', + refreshPanelAfterChanged: true, + $converter: '/converter/change-editor.converter', + editor: { + type: 'combo-list', + textField: 'value', + valueField: 'key', + editable: false, + data: self.designViewModelField ? SchemaDOMMapping.getEditorTypesByMDataType(self.designViewModelField.type?.name) : SchemaDOMMapping.getAllInputTypes() + } + }, + label: { + title: "标签", + type: "string", + $converter: '/converter/form-group-label.converter' + }, + binding: { + description: "绑定的表单字段", + title: "绑定", + editor: { + type: "binding-selector", + bindingType: { "enable": false }, + editorParams: { + componentSchema: propertyData, + needSyncToViewModel: true, + viewModelId: this.viewModelId, + designerHostService: this.designerHostService, + disableOccupiedFields: true + }, + textField: 'bindingField' + } + } + }, + setPropertyRelates(changeObject, prop) { + if (!changeObject) { + return; + } + switch (changeObject && changeObject.propertyID) { + case 'type': { + self.changeControlType(propertyData, changeObject, componentInstance); + break; + } + case 'label': { + changeObject.needRefreshControlTree = true; + break; + } + } + } + }; + } + public getAppearanceProperties(propertyData, componentInstance): any { + + const self = this; + return { + title: "外观", + description: "Appearance", + properties: { + class: { + title: "class样式", + type: "string", + description: "组件的CSS样式", + $converter: "/converter/appearance.converter" + }, + style: { + title: "style样式", + type: "string", + description: "组件的样式", + $converter: "/converter/appearance.converter" + } + }, + setPropertyRelates(changeObject, prop) { + if (!changeObject) { + return; + } + switch (changeObject && changeObject.propertyID) { + case 'class': + self.updateElementByParentContainer(propertyData.id, componentInstance); + break; + } + + } + }; + }; + + public getEditorProperties(propertyData): any { + return this.getComponentConfig(propertyData); + } + + + /** + * 卡片控件:切换控件类型后事件 + * @param propertyData 控件DOM属性 + * @param newControlType 新控件类型 + */ + private changeControlType(propertyData, changeObject, componentInstance: DesignerComponentInstance) { + const newControlType = changeObject.propertyValue; + + // 1、定位控件父容器 + const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; + if (!parentContainer) { + return; + } + + const index = parentContainer.contents.findIndex(c => c.id === propertyData.id); + const oldControl = parentContainer.contents[index]; + + let newControl; + // 2、记录绑定字段viewModel的变更 + if (this.designViewModelField) { + const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); + dgViewModel.changeField(this.designViewModelField.id, { + editor: { + $type: newControlType + }, + name: this.designViewModelField.name, + require: this.designViewModelField.require, + readonly: this.designViewModelField.readonly + }, false); + // 3、创建新控件 + newControl = this.controlCreatorUtils.setFormFieldProperty(this.designViewModelField, newControlType); + } + if (!newControl) { + newControl = this.controlCreatorUtils.createFormGroupWithoutField(newControlType); + } + // 4、保留原id样式等属性 + Object.assign(newControl, { + id: oldControl.id, + appearance: oldControl.appearance, + size: oldControl.size, + label: oldControl.label, + binding: oldControl.binding, + visible: oldControl.visible + }); + Object.assign(newControl.editor, { + isTextArea: newControl.isTextArea && oldControl.isTextArea, + placeholder: oldControl.editor?.placeholder, + holdPlace: oldControl.editor?.holdPlace, + readonly: oldControl.editor?.readonly, + required: oldControl.editor?.required, + }); + + // 5、替换控件 + parentContainer.contents.splice(index, 1); + parentContainer.contents.splice(index, 0, newControl); + componentInstance.schema = Object.assign(oldControl, newControl); + + // 6、暂时移除旧控件的选中样式(后续考虑更好的方式) + Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentSelected') + ); + + Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentFocused') + ); + // 7、触发刷新 + canvasChanged.value++; + + } + + public getComponentConfig(propertyData, info = {}, properties = {}, setPropertyRelates?: any) { + const editorBasic = Object.assign({ + description: "编辑器", + title: "编辑器", + type: "input-group", + $converter: "/converter/property-editor.converter" + }, info); + + const editorProperties = Object.assign({ + readonly: { + description: "", + title: "只读", + type: "boolean", + editor: { + enableClear: true, + editable: true + } + }, + disabled: { + description: "", + title: "禁用", + type: "boolean", + visible: false + }, + // required: { + // description: "", + // title: "必填", + // type: "boolean" + // }, + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + } + }, properties); + + return { ...editorBasic, properties: { ...editorProperties }, setPropertyRelates }; + + } + + + /** + * 枚举项编辑器 + * @param propertyData + * @param valueField + * @param textField + * @returns + */ + protected getItemCollectionEditor(propertyData, valueField, textField) { + valueField = valueField || 'value'; + textField = textField || 'name'; + return { + editor: { + columns: [ + { field: valueField, title: '值', dataType: 'string' }, + { field: textField, title: '名称', dataType: 'string' }, + { field: 'disabled', title: '禁用', visible: false, dataType: 'boolean', editor: { type: 'switch' } }, + ], + type: "item-collection-editor", + valueField: valueField, + nameField: textField, + requiredFields: [valueField, textField], + uniqueFields: [valueField, textField], + readonly: this.checkEnumDataReadonly(propertyData) + } + }; + } + /** + * 判断枚举数据是否只读 + * 1、没有绑定信息或者绑定变量,可以新增、删除、修改 + * 2、绑定类型为字段,且字段为枚举字段,则不可新增、删除、修改枚举值。只能从be修改然后同步到表单上。 + * @param propertyData 下拉框控件属性值 + */ + private checkEnumDataReadonly(propertyData: any): boolean { + // 没有绑定信息或者绑定变量 + if (!propertyData.binding || propertyData.binding.type !== 'Form') { + return false; + } + if (this.designViewModelField && this.designViewModelField.type && + this.designViewModelField.type.$type === FormSchemaEntityFieldType$Type.EnumType) { + // 低代码、零代码,枚举字段均不可以改 + return true; + } + return false; + } +} diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts new file mode 100644 index 00000000000..74957c969a7 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/text-box/composition/use-clear.ts @@ -0,0 +1,61 @@ +import { Ref, SetupContext, WatchSource, computed, ref, watch } from "vue"; +import { TextBoxProps, UseClear, UseTextBox } from "../../types"; + +export function useClear( + props: TextBoxProps, + context: SetupContext, + useTextBoxComposition: UseTextBox +): UseClear { + const hasShownClearButton = ref(false); + const shouldShowClearButton = computed(() => props.enableClear && !props.readonly && !props.disabled); + const { changeTextBoxValue, displayText, hasFocused, isEmpty } = useTextBoxComposition; + + function toggleClearIcon(isShow: boolean) { + hasShownClearButton.value = isShow; + } + + watch(displayText as WatchSource, () => { + if (hasFocused?.value) { + toggleClearIcon(!!displayText?.value); + } else { + toggleClearIcon(false); + } + }); + + const clearButtonClass = computed(() => ({ + 'input-group-text': true, + 'input-group-clear': true + })); + + const clearButtonStyle = computed(() => { + const styleObject = { + width: '24px', + display: hasShownClearButton.value ? 'flex' : 'none' + } as Record; + return styleObject; + }); + + /** 清空输入框中的值 */ + function onClearValue($event: MouseEvent) { + $event.stopPropagation(); + if (shouldShowClearButton.value) { + changeTextBoxValue('', true); + toggleClearIcon(!hasShownClearButton.value); + context.emit('clear'); + } + } + + function onMouseEnter(event: MouseEvent) { + if (shouldShowClearButton.value && !isEmpty.value) { + toggleClearIcon(true); + } + } + + function onMouseLeave(event: MouseEvent) { + if (shouldShowClearButton.value) { + toggleClearIcon(false); + } + } + + return { clearButtonClass, clearButtonStyle, hasShownClearButton, onClearValue, onMouseEnter, onMouseLeave, shouldShowClearButton }; +} diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts new file mode 100644 index 00000000000..b4957d96db9 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box-design.ts @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { computed, ref, Ref, SetupContext, watch } from 'vue'; +import { TextBoxProps, UseTextBox } from '../../types'; + +export function useTextBoxDesign( + props: TextBoxProps, + context: SetupContext, + modelValue: Ref, + displayText: Ref +): UseTextBox { + const disabled = ref(props.disabled); + const focusStatus = ref(false); + const inputType = ref('text'); + const showBorder = ref(props.showBorder); + const textAlign = ref(props.textAlign); + + const canFocus = computed(() => props.editable || !props.readonly); + const editable = computed(() => props.editable && !props.disabled && !props.readonly); + const hasFocused = computed(() => !props.disabled && focusStatus.value); + const isEmpty = computed(() => modelValue.value === '' || modelValue.value === null || modelValue.value === undefined); + const placeholder = computed(() => (props.placeholder)); + const readonly = computed(() => props.readonly || !props.editable); + const textBoxTitle = computed(() => (props.enableTitle ? modelValue.value : '')); + + const textBoxClass = computed(() => ({ + 'form-control': true, + // 'f-utils-fill': true, + 'text-left': textAlign.value === 'left', + 'text-center': textAlign.value === 'center', + 'text-right': textAlign.value === 'right', + })); + + const inputGroupClass = computed(() => { + const classObject = { + 'f-cmp-inputgroup': true, + 'input-group': true, + 'f-state-disabled': true, + 'f-state-editable': false, + 'f-state-readonly': true, + // 'f-state-focus': hasFocused.value + }; + // const customClassArray = (props.customClass || '').split(' '); + // customClassArray.reduce>((classObject, classString) => { + // classObject[classString] = true; + // return classObject; + // }, classObject); + return classObject; + }); + + const inputGroupStyle = computed(() => { + return !showBorder.value ? 'border-width : 0 ' : ''; + }); + + function changeTextBoxValue(newValue: string, shouldEmitChangeEvent = true) { + } + + + return { + changeTextBoxValue, + disabled, + displayText, + editable, + hasFocused, + inputGroupClass, + inputType, + isEmpty, + modelValue, + readonly, + // onBlur, + // onClick, + // onFocus, + // onInput, + // onKeydown, + // onKeyup, + // onMousedown, + // onTextBoxValueChange, + placeholder, + textBoxClass, + textBoxTitle, + inputGroupStyle + }; +} diff --git a/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts new file mode 100644 index 00000000000..572b66def91 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/text-box/composition/use-text-box.ts @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { computed, ref, Ref, SetupContext, watch } from 'vue'; +import { TextBoxProps, UseTextBox } from '../../types'; + +export function useTextBox( + props: TextBoxProps, + context: SetupContext, + modelValue: Ref, + displayText: Ref +): UseTextBox { + const disabled = ref(props.disabled); + const focusStatus = ref(false); + const inputType = ref('text'); + const showBorder = ref(props.showBorder); + const textAlign = ref(props.textAlign); + const updateOn = ref(props.updateOn); + + const canFocus = computed(() => props.editable || !props.readonly); + const editable = computed(() => props.editable && !props.disabled && !props.readonly); + const hasFocused = computed(() => !props.disabled && focusStatus.value); + const isEmpty = computed(() => modelValue.value === '' || modelValue.value === null || modelValue.value === undefined); + const placeholder = computed(() => ((props.disabled || props.readonly) && !props.forcePlaceholder ? '' : props.placeholder)); + const readonly = computed(() => props.readonly || !props.editable); + const textBoxTitle = computed(() => (props.enableTitle ? modelValue.value : '')); + + const textBoxClass = computed(() => ({ + 'form-control': true, + 'f-utils-fill': true, + 'text-left': textAlign.value === 'left', + 'text-center': textAlign.value === 'center', + 'text-right': textAlign.value === 'right', + })); + + const inputGroupClass = computed(() => { + const classObject = { + 'f-cmp-inputgroup': true, + 'input-group': true, + 'f-state-disabled': disabled.value, + 'f-state-editable': editable.value, + 'f-state-readonly': readonly.value, + 'f-state-focus': hasFocused.value + }; + const customClassArray = (props.customClass || '').split(' '); + customClassArray.reduce>((classObject, classString) => { + classObject[classString] = true; + return classObject; + }, classObject); + return classObject; + }); + + const inputGroupStyle = computed(() => { + return !showBorder.value ? 'border-width : 0 ' : ''; + }); + + function changeTextBoxValue(newValue: string, shouldEmitChangeEvent = true) { + // if (modelValue.value !== newValue) { + modelValue.value = newValue; + if (displayText.value !== newValue) { + displayText.value = newValue; + } + if (shouldEmitChangeEvent) { + context.emit('change', newValue); + } + context.emit('update:modelValue', newValue); + context.emit('update:value', newValue); + // } + } + + watch( + () => props.modelValue, + (newValue: string, oldValue: string) => { + if (newValue !== oldValue) { + modelValue.value = newValue; + displayText.value = newValue; + } + } + ); + + watch(() => props.disabled, (newValue, oldValue) => { + if (newValue !== oldValue) { + disabled.value = newValue; + } + }); + + function onBlur(payload: FocusEvent) { + focusStatus.value = false; + context.emit('blur', payload); + payload.stopPropagation(); + return false; + } + + function onClick(payload: MouseEvent) { + context.emit('click', payload); + } + + function onFocus(payload: FocusEvent) { + if (props.disabled) { + return; + } + if (showBorder.value) { + focusStatus.value = true; + } + if (canFocus.value) { + context.emit('focus', payload); + + } + } + + function onInput(payload: Event) { + context.emit('input', (payload.target as HTMLInputElement).value); + const newValue = (payload.target as HTMLInputElement).value; + displayText.value = newValue; + if (updateOn.value === 'change') { + context.emit('update:modelValue', newValue); + context.emit('update:value', newValue); + } + } + + function onKeydown(payload: KeyboardEvent) { + context.emit('keydown', payload); + } + + function onKeyup(payload: KeyboardEvent) { + context.emit('keyup', payload); + } + + function onMousedown(payload: MouseEvent) { + const target = payload.target as HTMLElement; + if (target.tagName !== 'INPUT') { + payload.preventDefault(); + } + payload.stopPropagation(); + } + + function onTextBoxValueChange(payload: Event) { + if (updateOn.value === 'blur') { + const newValue = (payload.target as HTMLInputElement).value; + payload.stopPropagation(); + changeTextBoxValue(newValue); + } + } + + return { + changeTextBoxValue, + disabled, + displayText, + editable, + hasFocused, + inputGroupClass, + inputType, + isEmpty, + modelValue, + readonly, + onBlur, + onClick, + onFocus, + onInput, + onKeydown, + onKeyup, + onMousedown, + onTextBoxValueChange, + placeholder, + textBoxClass, + textBoxTitle, + inputGroupStyle + }; +} diff --git a/packages/mobile-ui-vue/components/common/types.ts b/packages/mobile-ui-vue/components/common/types.ts new file mode 100644 index 00000000000..317a5cf3020 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/types.ts @@ -0,0 +1,131 @@ +import { ComputedRef, Ref } from "vue"; + +export interface TextBoxProps { + + customClass: string; + + disabled: boolean; + + editable: boolean; + + enableClear: boolean; + + enableTitle: boolean; + + forcePlaceholder: boolean; + + modelValue: string; + + placeholder: string; + + readonly: boolean; + + textAlign: string; + + showBorder: boolean; + + updateOn: 'blur' | 'change'; +} + +export interface UseClear { + + clearButtonClass: ComputedRef>; + + clearButtonStyle: ComputedRef>; + + hasShownClearButton: Ref; + + onClearValue: ($event: MouseEvent) => void; + + onMouseEnter: ($event: MouseEvent) => void; + + onMouseLeave: ($event: MouseEvent) => void; + + shouldShowClearButton: ComputedRef; +} + +export interface UseTextBox { + + changeTextBoxValue: (newValue: string, shouldEmitChangeEvent: boolean) => void; + + disabled?: Ref; + + displayText?: Ref; + + editable?: Ref; + + hasFocused?: ComputedRef; + + inputGroupClass: ComputedRef>; + + inputType: Ref; + + isEmpty: ComputedRef; + + modelValue?: Ref; + + readonly?: ComputedRef; + + onBlur?: (payload: FocusEvent) => boolean; + + onClick?: (payload: MouseEvent) => void; + + onFocus?: (payload: FocusEvent) => void; + + onInput?: (payload: Event) => void; + + onKeydown?: (payload: KeyboardEvent) => void; + + onKeyup?: (payload: KeyboardEvent) => void; + + onMousedown?: (payload: MouseEvent) => void; + + onTextBoxValueChange?: (payload: Event) => void; + + placeholder: ComputedRef; + + textBoxClass: ComputedRef>; + + textBoxTitle: ComputedRef; + + inputGroupStyle: ComputedRef; +} + +export interface UseDateFormat { + formatTo: (date: string | Date, format: string) => string; +} +export type NumberType = string | number; +export interface NumberOption { + prefix?: string; + suffix?: string; + decimalSeparator?: string; + groupSeparator?: string; + [key: string]: any; +} +export interface UseNumberFormat { + formatTo: (value: NumberType, opts: any) => string; + removeFormat: (value: NumberType | null | undefined, opts: any) => string; + convertCurrency: (money: string) => string; + toFixed: (value: string, precision: number) => string; + toNumber: (value: string) => number; + greaterThan: (firstValue: NumberType, secondValue: NumberType) => boolean; + lessThan: (firstValue: NumberType, secondValue: NumberType) => boolean; + equal: (firstValue: NumberType, secondValue: NumberType) => boolean; + minus: (firstValue: NumberType, secondValue: NumberType) => string; + multiplied: (firstValue: NumberType, secondValue: NumberType) => string; + plus: (firstValue: NumberType, secondValue: NumberType) => string; + average: (total: NumberType, len: number) => string; + sum: (numberArray: NumberType[]) => string; + min: (firstValue: Array | NumberType, secondValue: NumberType | null) => string; + max: (firstValue: Array | NumberType, secondValue: NumberType | null) => string; +} + +export type TimeAgoDate = Date | string | number; +export type TimeAgoOptions = { + // 可能后期有其他属性 + /** 相对的日期 */ + readonly relativeDate?: TimeAgoDate; +}; +export interface UseTimeAgoFormat { + formatTo(date: TimeAgoDate, opts?: TimeAgoOptions): string +} diff --git a/packages/mobile-ui-vue/components/common/utils/encrypt.ts b/packages/mobile-ui-vue/components/common/utils/encrypt.ts new file mode 100644 index 00000000000..8b0920d4682 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/encrypt.ts @@ -0,0 +1,246 @@ +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +const hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +const b64pad = ''; /* base-64 pad character. "=" for strict RFC compliance */ +const chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safeAdd(x, y) { + const lsw = (x & 0xffff) + (y & 0xffff); + const msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bitRol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function encryptCmn(q, a, b, x, s, t) { + return safeAdd(bitRol(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} + +function encryptFf(a, b, c, d, x, s, t) { + return encryptCmn((b & c) | (~b & d), a, b, x, s, t); +} + +function encryptGg(a, b, c, d, x, s, t) { + return encryptCmn((b & d) | (c & ~d), a, b, x, s, t); +} + +function encryptHh(a, b, c, d, x, s, t) { + return encryptCmn(b ^ c ^ d, a, b, x, s, t); +} + +function encryptIi(a, b, c, d, x, s, t) { + return encryptCmn(c ^ (b | ~d), a, b, x, s, t); +} + +/* + * Convert a string to an array of little-endian words + * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. + */ +function str2binl(str: string): any[] { + const bin: any = []; + const mask = (1 << chrsz) - 1; + for (let i = 0; i < str.length * chrsz; i += chrsz) { + bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << i % 32; + } + return bin; +} + +/* + * Convert an array of little-endian words to a string + */ +function binl2str(bin) { + let str = ''; + const mask = (1 << chrsz) - 1; + for (let i = 0; i < bin.length * 32; i += chrsz) { + str += String.fromCharCode((bin[i >> 5] >>> i % 32) & mask); + } + return str; +} + +/* + * Convert an array of little-endian words to a hex string. + */ +function binl2hex(binarray) { + // tslint:disable-next-line: variable-name + const hexTab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef'; + let str = ''; + for (let i = 0; i < binarray.length * 4; i++) { + str += + hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xf) + + hexTab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xf); + } + return str; +} + +/* + * Convert an array of little-endian words to a base-64 string + */ +function binl2b64(binarray) { + const tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + let str = ''; + for (let i = 0; i < binarray.length * 4; i += 3) { + const triplet = + (((binarray[i >> 2] >> (8 * (i % 4))) & 0xff) << 16) | + (((binarray[(i + 1) >> 2] >> (8 * ((i + 1) % 4))) & 0xff) << 8) | + ((binarray[(i + 2) >> 2] >> (8 * ((i + 2) % 4))) & 0xff); + for (let j = 0; j < 4; j++) { + if (i * 8 + j * 6 > binarray.length * 32) { + str += b64pad; + } else { + str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f); + } + } + } + return str; +} + +/* + * Calculate the encrypt of an array of little-endian words, and a bit length + */ +function coreEncrypt(x: any, len: number) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(((len + 64) >>> 9) << 4) + 14] = len; + + let a = 1732584193; + let b = -271733879; + let c = -1732584194; + let d = 271733878; + + for (let i = 0; i < x.length; i += 16) { + const olda = a; + const oldb = b; + const oldc = c; + const oldd = d; + + a = encryptFf(a, b, c, d, x[i + 0], 7, -680876936); + d = encryptFf(d, a, b, c, x[i + 1], 12, -389564586); + c = encryptFf(c, d, a, b, x[i + 2], 17, 606105819); + b = encryptFf(b, c, d, a, x[i + 3], 22, -1044525330); + a = encryptFf(a, b, c, d, x[i + 4], 7, -176418897); + d = encryptFf(d, a, b, c, x[i + 5], 12, 1200080426); + c = encryptFf(c, d, a, b, x[i + 6], 17, -1473231341); + b = encryptFf(b, c, d, a, x[i + 7], 22, -45705983); + a = encryptFf(a, b, c, d, x[i + 8], 7, 1770035416); + d = encryptFf(d, a, b, c, x[i + 9], 12, -1958414417); + c = encryptFf(c, d, a, b, x[i + 10], 17, -42063); + b = encryptFf(b, c, d, a, x[i + 11], 22, -1990404162); + a = encryptFf(a, b, c, d, x[i + 12], 7, 1804603682); + d = encryptFf(d, a, b, c, x[i + 13], 12, -40341101); + c = encryptFf(c, d, a, b, x[i + 14], 17, -1502002290); + b = encryptFf(b, c, d, a, x[i + 15], 22, 1236535329); + + a = encryptGg(a, b, c, d, x[i + 1], 5, -165796510); + d = encryptGg(d, a, b, c, x[i + 6], 9, -1069501632); + c = encryptGg(c, d, a, b, x[i + 11], 14, 643717713); + b = encryptGg(b, c, d, a, x[i + 0], 20, -373897302); + a = encryptGg(a, b, c, d, x[i + 5], 5, -701558691); + d = encryptGg(d, a, b, c, x[i + 10], 9, 38016083); + c = encryptGg(c, d, a, b, x[i + 15], 14, -660478335); + b = encryptGg(b, c, d, a, x[i + 4], 20, -405537848); + a = encryptGg(a, b, c, d, x[i + 9], 5, 568446438); + d = encryptGg(d, a, b, c, x[i + 14], 9, -1019803690); + c = encryptGg(c, d, a, b, x[i + 3], 14, -187363961); + b = encryptGg(b, c, d, a, x[i + 8], 20, 1163531501); + a = encryptGg(a, b, c, d, x[i + 13], 5, -1444681467); + d = encryptGg(d, a, b, c, x[i + 2], 9, -51403784); + c = encryptGg(c, d, a, b, x[i + 7], 14, 1735328473); + b = encryptGg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = encryptHh(a, b, c, d, x[i + 5], 4, -378558); + d = encryptHh(d, a, b, c, x[i + 8], 11, -2022574463); + c = encryptHh(c, d, a, b, x[i + 11], 16, 1839030562); + b = encryptHh(b, c, d, a, x[i + 14], 23, -35309556); + a = encryptHh(a, b, c, d, x[i + 1], 4, -1530992060); + d = encryptHh(d, a, b, c, x[i + 4], 11, 1272893353); + c = encryptHh(c, d, a, b, x[i + 7], 16, -155497632); + b = encryptHh(b, c, d, a, x[i + 10], 23, -1094730640); + a = encryptHh(a, b, c, d, x[i + 13], 4, 681279174); + d = encryptHh(d, a, b, c, x[i + 0], 11, -358537222); + c = encryptHh(c, d, a, b, x[i + 3], 16, -722521979); + b = encryptHh(b, c, d, a, x[i + 6], 23, 76029189); + a = encryptHh(a, b, c, d, x[i + 9], 4, -640364487); + d = encryptHh(d, a, b, c, x[i + 12], 11, -421815835); + c = encryptHh(c, d, a, b, x[i + 15], 16, 530742520); + b = encryptHh(b, c, d, a, x[i + 2], 23, -995338651); + + a = encryptIi(a, b, c, d, x[i + 0], 6, -198630844); + d = encryptIi(d, a, b, c, x[i + 7], 10, 1126891415); + c = encryptIi(c, d, a, b, x[i + 14], 15, -1416354905); + b = encryptIi(b, c, d, a, x[i + 5], 21, -57434055); + a = encryptIi(a, b, c, d, x[i + 12], 6, 1700485571); + d = encryptIi(d, a, b, c, x[i + 3], 10, -1894986606); + c = encryptIi(c, d, a, b, x[i + 10], 15, -1051523); + b = encryptIi(b, c, d, a, x[i + 1], 21, -2054922799); + a = encryptIi(a, b, c, d, x[i + 8], 6, 1873313359); + d = encryptIi(d, a, b, c, x[i + 15], 10, -30611744); + c = encryptIi(c, d, a, b, x[i + 6], 15, -1560198380); + b = encryptIi(b, c, d, a, x[i + 13], 21, 1309151649); + a = encryptIi(a, b, c, d, x[i + 4], 6, -145523070); + d = encryptIi(d, a, b, c, x[i + 11], 10, -1120210379); + c = encryptIi(c, d, a, b, x[i + 2], 15, 718787259); + b = encryptIi(b, c, d, a, x[i + 9], 21, -343485551); + + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + return [a, b, c, d]; +} + +/* + * Calculate the HMAC-encrypt, of a key and some data + */ +function coreHmacEncrypt(key, data) { + let bkey = str2binl(key); + if (bkey.length > 16) { + bkey = coreEncrypt(bkey, key.length * chrsz); + } + + const ipad = Array(16); + const opad = Array(16); + for (let i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5c5c5c5c; + } + + const hash = coreEncrypt(ipad.concat(str2binl(data)), 512 + data.length * chrsz); + return coreEncrypt(opad.concat(hash), 512 + 128); +} + +export function encrypt(s: string, type = 'hex') { + if (type === 'hex') { + return binl2hex(coreEncrypt(str2binl(s), s.length * chrsz)); + } + + if (type === 'b64') { + return binl2b64(coreEncrypt(str2binl(s), s.length * chrsz)); + } + + return binl2str(coreEncrypt(str2binl(s), s.length * chrsz)); +} + +export function hmacEncrypt(key, data, type = 'hex') { + if (type === 'hex') { + return binl2hex(coreHmacEncrypt(key, data)); + } + if (type === 'b64') { + return binl2b64(coreHmacEncrypt(key, data)); + } + return binl2str(coreHmacEncrypt(key, data)); +} diff --git a/packages/mobile-ui-vue/components/common/utils/resolve-field.ts b/packages/mobile-ui-vue/components/common/utils/resolve-field.ts new file mode 100644 index 00000000000..55530326bc7 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/resolve-field.ts @@ -0,0 +1,29 @@ +export const resolveField = (dataItem: any, field: Array | string) => { + if (!field) { + // 空字符串或者undefined + return ''; + } + if (!dataItem) { + return ''; + } + const fieldList = typeof field === 'string' ? field.split('.') : field; + const result = fieldList.reduce((total: any, next: string) => { + return total[next]; + }, dataItem); + return result; +}; + +export const setFieldValue = (newValue: any, dataItem: any, field: Array | string) => { + let fieldList: string[] = []; + if (typeof field === 'string') { + fieldList = [...field.split('.')]; + } + if (Array.isArray(field)) { + fieldList = field; + } + let value = dataItem; + while (fieldList && fieldList.length > 1) { + value = value[fieldList.shift()!]; + } + value[fieldList.shift()!] = newValue; +}; diff --git a/packages/mobile-ui-vue/components/common/utils/symbol-key.ts b/packages/mobile-ui-vue/components/common/utils/symbol-key.ts new file mode 100644 index 00000000000..8c3db5ff8c0 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/symbol-key.ts @@ -0,0 +1,6 @@ +import { InjectionKey } from "vue"; + +export const CHECKBOX_CONTEXT: InjectionKey<{ [key: string]: any }> = Symbol('checkboxGroupContext'); + +/** 选择控制器 */ +export const ControllerSchemaRepositorySymbol = Symbol('controller schema repository inject token'); diff --git a/packages/mobile-ui-vue/components/common/utils/use-appearance.ts b/packages/mobile-ui-vue/components/common/utils/use-appearance.ts new file mode 100644 index 00000000000..74038b3cfa0 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/use-appearance.ts @@ -0,0 +1,33 @@ +/** + * 根据传递过来已有的类对象和自定义类名,构造新的样式对象 + * @param classObject + * @param customClass + * @returns + */ +export function getCustomClass(classObject: Record, customClass: string) { + const customClassArray = customClass?.split(' ') || []; + customClassArray.reduce((result: Record, classString: string) => { + if (classString) { + result[classString] = true; + } + return result; + }, classObject); + return classObject; +} +/** + * 根据传递过来已有的style对象和自定义style,构造新的style对象 + * @param styleObject + * @param customStyle + * @returns + */ +export function getCustomStyle(styleObject: Record, customStyle: string) { + const styleArray = customStyle?.split(';') || []; + styleArray.reduce((result: Record, styleString: string) => { + if (styleString) { + const styles = styleString.split(':'); + result[styles[0]] = styles[1]; + } + return result; + }, styleObject); + return styleObject; +} diff --git a/packages/mobile-ui-vue/components/common/utils/use-class.ts b/packages/mobile-ui-vue/components/common/utils/use-class.ts new file mode 100644 index 00000000000..578e29c9466 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/use-class.ts @@ -0,0 +1,33 @@ +interface ElementRef { + nativeElement?: any; +} +export function getElementWithClassList(elementRef: ElementRef) { + const element = elementRef.nativeElement ? elementRef.nativeElement : elementRef; + + if (element.classList !== undefined && element.classList !== null) { + return element; + } + + return null; +} + +export function removeClass(elementRef: ElementRef | any, className: string) { + if (className === undefined) { + return; + } + const element = getElementWithClassList(elementRef); + + if (element) { + element.classList.remove(className); + } +} +export function addClass(elementRef: ElementRef | any, className: string) { + if (className === undefined) { + return; + } + const element = getElementWithClassList(elementRef); + + if (element) { + element.classList.add(className); + } +} diff --git a/packages/mobile-ui-vue/components/common/utils/use-guid.ts b/packages/mobile-ui-vue/components/common/utils/use-guid.ts new file mode 100644 index 00000000000..afc1786306f --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/use-guid.ts @@ -0,0 +1,43 @@ +export function useGuid() { + function guid() { + const replaceCallback = (replaceChar: string) => { + const randomValue = (Math.random() * 16) | 0; + const result = replaceChar === 'x' ? randomValue : (randomValue & 0x3) | 0x8; + return result.toString(16); + }; + + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, replaceCallback); + } + + function uuid(uuidLength: number, radix?: number) { + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); + const uuid: string[] = []; + let charIndex; + radix = radix || chars.length; + + if (uuidLength) { + // Compact form + for (charIndex = 0; charIndex < uuidLength; charIndex++) {uuid[charIndex] = chars[0 | (Math.random() * radix)];} + } else { + // rfc4122, version 4 form + let randomValue; + + // rfc4122 requires these characters + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; + uuid[14] = '4'; + + // Fill in random data. At i==19 set the high bits of clock sequence as + // per rfc4122, sec. 4.1.5 + for (charIndex = 0; charIndex < 36; charIndex++) { + if (!uuid[charIndex]) { + randomValue = 0 | (Math.random() * 16); + uuid[charIndex] = chars[charIndex === 19 ? (randomValue & 0x3) | 0x8 : randomValue]; + } + } + } + + return uuid.join(''); + } + + return { guid, uuid }; +} diff --git a/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts b/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts new file mode 100644 index 00000000000..67f7be8999e --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/use-request-animation.ts @@ -0,0 +1,46 @@ +// tslint:disable:no-any typedef no-invalid-this +const availablePrefixes = ['moz', 'ms', 'webkit']; +function requestAnimationFramePolyfill(): typeof requestAnimationFrame { + let lastTime = 0; + return (callback: FrameRequestCallback): any => { + const currTime = new Date().getTime(); + const timeToCall = Math.max(0, 16 - (currTime - lastTime)); + const id = setTimeout(() => { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; +} + +function getRequestAnimationFrame(): typeof requestAnimationFrame { + if (typeof window === 'undefined') { + return () => 0; + } + if (window.requestAnimationFrame) { + return window.requestAnimationFrame.bind(window); + } + + const prefix = availablePrefixes.filter(key => `${key}RequestAnimationFrame` in window)[0]; + + return prefix ? (window as any)[`${prefix}RequestAnimationFrame`] : requestAnimationFramePolyfill(); +} +export function cancelRequestAnimationFrame(id: number): any { + if (typeof window === 'undefined') { + return null; + } + if (window.cancelAnimationFrame) { + return window.cancelAnimationFrame(id); + } + const prefix = availablePrefixes.filter( + key => `${key}CancelAnimationFrame` in window || `${key}CancelRequestAnimationFrame` in window + )[0]; + + return prefix + ? ((window as any)[`${prefix}CancelAnimationFrame`] || (window as any)[`${prefix}CancelRequestAnimationFrame`]) + // @ts-ignore + .call(this, id) + : clearTimeout(id); +} + +export const useReqAnimationFrame = getRequestAnimationFrame(); diff --git a/packages/mobile-ui-vue/components/common/utils/with-install.ts b/packages/mobile-ui-vue/components/common/utils/with-install.ts new file mode 100644 index 00000000000..3bce8e707a3 --- /dev/null +++ b/packages/mobile-ui-vue/components/common/utils/with-install.ts @@ -0,0 +1,10 @@ +import type { App, Component, Plugin } from 'vue'; + +export const withInstall = (component: T) => { + const c = component as any; + c.install = function (app: App) { + app.component(c.name, component); + }; + + return component as T & Plugin; +}; diff --git a/packages/mobile-ui-vue/components/designer-canvas/index.ts b/packages/mobile-ui-vue/components/designer-canvas/index.ts index fb72a072207..6ce6546f37b 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/index.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/index.ts @@ -1,16 +1,14 @@ -import type { App } from 'vue'; -import FDesignerCanvas from './src/designer-canvas.component'; -import FToolbox from './src/components/toolbox.component'; -import FControlTreeView from './src/components/control-tree-view.component'; +import FDesignerCanvasInstallless from './src/designer-canvas.component'; +import FDesignerItem from './src/components/designer-item.component'; +import { DgControl } from './src/composition/dg-control'; +import type { DesignerHostService, UseDesignerRules } from './src/composition/types'; +import { withInstall } from '../common'; export * from './src/composition/props/designer-canvas.props'; +export * from './src/composition/function/use-designer-component'; +export * from './src/composition/function/use-designer-inner-component'; +export * from './src/types'; +const FDesignerCanvas = withInstall(FDesignerCanvasInstallless); -export { FDesignerCanvas }; - -export default { - install(app: App): void { - app.component(FDesignerCanvas.name as string, FDesignerCanvas); - app.component(FToolbox.name as string, FToolbox); - app.component(FControlTreeView.name as string, FControlTreeView); - } -}; +export { FDesignerCanvas, FDesignerItem, DgControl, UseDesignerRules, DesignerHostService }; +export default FDesignerCanvas; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/control-tree-view.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/control-tree-view.component.tsx deleted file mode 100644 index 8d2635389b7..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/control-tree-view.component.tsx +++ /dev/null @@ -1,124 +0,0 @@ - - -import { SetupContext, defineComponent, ref } from 'vue'; -// FTreeView from `../../../../../ui-vue/components/tree-view/src/tree-view.component` -import { controlTreeViewProps, ControlTreeViewProps } from '../composition/props/control-tree-view.props'; -import { cloneDeep } from 'lodash-es'; -import { changeTreeNode } from '../composition/function/change-control-tree-node'; - -export default defineComponent({ - name: 'FControlTreeView', - props: controlTreeViewProps, - emits: ['outputValue', 'currentEvent', 'selectionChanged'] as string[] | undefined, - setup(props: ControlTreeViewProps, context: SetupContext) { - /** 树表数据 */ - const domJsonComponents = ref(props.data); - /** 树节点图标数据 */ - const treeNodeIconsData = ref(props.treeNodeIconsData); - /** 树表是否支持可选状态 */ - const selectable = ref(props.selectable); - /** 选中父节点会自动选中子节点 */ - const autoCheckChildren = ref(props.autoCheckChildren); - /** 返回值展示父节点和子节点 */ - const cascade = ref(props.cascade); - /** 是否显示图标集 */ - const showTreeNodeIcons = ref(props.showTreeNodeIcons); - /** 是否显示连接线 */ - const showLines = ref(props.showLines); - /** 新增值 */ - const newDataItem = ref(props.newDataItem); - /** 连接线颜色 */ - const lineColor = ref(props.lineColor); - /** 单元格高度 */ - const cellHeight = ref(props.cellHeight); - - const { onComponentClicked } = changeTreeNode(props, context); - - /** 处理数据 */ - function handleInputData(components: any, findComponents: any, number: number, parentId: string) { - components.forEach((componentsItem: any) => { - const findComponentsItem = { - oldId: componentsItem.id, - layer: number, - oldParent: parentId, - name: componentsItem.name || componentsItem.text || componentsItem.id, - type: componentsItem.type, - class: componentsItem.appearance?.class || '' - }; - findComponents.push(cloneDeep(findComponentsItem)); - if (componentsItem.contents || componentsItem.buttons) { - handleInputData(componentsItem.contents || componentsItem.buttons, findComponents, number + 1, componentsItem.id); - } - }); - const findComponentsReverse = findComponents.reverse(); - return findComponentsReverse; - } - - /** 按照treeview输入值排序 */ - function getSortedData(flatData: any) { - const sortedData: any = []; - const rootComponent = flatData.find((flatDataItem: any) => flatDataItem.layer === 0); - flatData = flatData.filter((flatDataItem: any) => flatDataItem.layer !== 0); - sortedData.push(rootComponent); - let neededId = rootComponent.oldId; - let back = 0; - // 死循环时跳出 - let lock = 1000; - while (flatData.length !== 0 || lock === 0) { - const result = flatData.find((flatDataItem: any) => flatDataItem.oldParent === neededId); - if (result) { - sortedData.push(result); - neededId = result.oldId; - flatData = flatData.filter((flatDataItem: any) => flatDataItem.oldId !== neededId); - back = 0; - } else { - // 若非同层级,则找其父级的子 - back -= 1; - neededId = sortedData.slice(back)[0].oldId; - } - lock -= 1; - } - return sortedData; - } - - function formTreeViewFrame(originData: any) { - originData.forEach((originDataItem: any, index: number) => { - originDataItem.id = (index + 1).toString(); - }); - originData.forEach((originDataItem: any) => { - originDataItem.parent = originData.find((item: any) => item.oldId === originDataItem.oldParent)?.id || ''; - }); - return originData; - } - - /** 获取treeview所需数据 */ - function getTreeViewData() { - let outputDataWithTreeViewFrame: any; - if (domJsonComponents.value.length !== 0) { - const components = []; - components.push(domJsonComponents.value); - const findComponents: any = []; - const number = 0; - const outputData = getSortedData(handleInputData(components, findComponents, number, '')); - outputDataWithTreeViewFrame = formTreeViewFrame(outputData); - } - return outputDataWithTreeViewFrame; - } - - function emitOutputValue(value: any) { - context.emit('outputValue', value); - const propertyId = value.data.displayText.data; - const componentType = value.raw.type; - const config = onComponentClicked(propertyId); - context.emit('propertyConfig', config); - } - - function returnTreeView() { - const treeViewData = getTreeViewData(); - return (); - } - return () => { - return <>{returnTreeView()}; - }; - } -}); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-inner-item.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-inner-item.component.tsx index 2fe158a607b..9225b195cbf 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-inner-item.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-inner-item.component.tsx @@ -1,225 +1,257 @@ -import { Ref, SetupContext, computed, defineComponent, inject, onMounted, provide, ref, watch, onBeforeUnmount } from 'vue'; +import { Ref, SetupContext, computed, defineComponent, inject, onMounted, provide, ref, watch, onBeforeUnmount, withModifiers } from 'vue'; import { DesignerInnerItemPropsType, designerInnerItemProps } from '../composition/props/designer-inner-item.props'; -import { UseDragula } from '../composition/types'; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, ResolveComponentContext } from '../types'; -import { canvasChanged, setPositionOfBtnGroup } from '../composition/designer-canvas-changed'; +import { DraggingResolveContext, UseDragula } from '../composition/types'; +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from '../types'; +import { canvasChanged, setPositionOfButtonGroup } from '../composition/designer-canvas-changed'; import { useDesignerInnerComponent } from '../composition/function/use-designer-inner-component'; const FDesignerInnerItem = defineComponent({ - name: 'FDesignerInnerItem', - props: designerInnerItemProps, - emits: ['selectionChange'], - setup(props: DesignerInnerItemPropsType, context: SetupContext) { - const canMove = ref(props.canMove); - const canAdd = ref(props.canAdd); - const canDelete = ref(props.canDelete); - const canNested = ref(false); - const contentKey = ref(props.contentKey); - const childType = ref(props.childType); - const childLabel = ref(props.childLabel); - const schema = ref(props.modelValue); - const designComponentStyle = ref(''); - const designerItemElementRef = ref(); - const useDragulaComposition = inject('canvas-dragula'); - const componentInstance = ref() as Ref; - const parent = inject('design-item-context'); - const designItemContext = { designerItemElementRef, componentInstance, schema: schema.value, parent, setupContext: context }; - provide('design-item-context', designItemContext); - - const designerItemClass = computed(() => { - const classObject = { - 'farris-component': true, - 'position-relative': canMove.value || canDelete.value, - 'farris-nested': canNested.value, - 'can-move': canMove.value, - 'd-none': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('d-none') - } as Record; - return classObject; - }); - - const desginerItemStyle = computed(() => { - const styleObject = {} as Record; - if (designComponentStyle.value) { - designComponentStyle.value.split(';').reduce((result: Record, styleString: string) => { - const [styleKey, styleValue] = styleString.split(':'); - if (styleKey) { - result[styleKey] = styleValue; - } - return result; - }, styleObject); - } - return styleObject; - }); - - function onClickDeleteButtom(payload: MouseEvent, schemaToRemove: ComponentSchema) { - if (parent && parent.schema[contentKey.value]) { - const indexToRemove = parent.schema[contentKey.value].findIndex( - (contentItem: ComponentSchema) => contentItem.id === schemaToRemove.id - ); - parent.schema[contentKey.value].splice(indexToRemove, 1); - parent.componentInstance.value.updateDragAndDropRules(); - } + name: 'FDesignerInnerItem', + props: designerInnerItemProps, + emits: ['selectionChange', 'addComponent', 'removeComponent'], + setup(props: DesignerInnerItemPropsType, context) { + const canMove = ref(props.canMove); + const canAdd = ref(props.canAdd); + const canDelete = ref(props.canDelete); + const canNested = ref(false); + const contentKey = ref(props.contentKey); + const childType = ref(props.childType); + const childLabel = ref(props.childLabel); + const schema = ref(props.modelValue); + const designComponentStyle = ref(''); + const designerItemElementRef = ref(); + const useDragulaComposition = inject('canvas-dragula'); + const componentInstance = ref() as Ref; + const parent = inject('design-item-context'); + const designItemContext = { designerItemElementRef, componentInstance, schema: schema.value, parent, setupContext: context as SetupContext }; + provide('design-item-context', designItemContext); - } + const designerItemClass = computed(() => { + const classObject = { + 'farris-component': true, + // 受position-relative影响,整个容器的高度不能被撑起 + 'flex-fill': props.id === 'root-component', + 'position-relative': canMove.value || canDelete.value, + 'farris-nested': canNested.value, + 'can-move': canMove.value, + 'd-none': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('d-none') + } as Record; + return classObject; + }); - function onClickAddButton(payload: MouseEvent) { - if (componentInstance.value.addNewChildComponentSchema) { - const resolveContext = { - componentType: childType.value, - label: childLabel.value, - parentComponentInstance: componentInstance.value, - targetPosition: -1 - } as ResolveComponentContext; - const childComponentSchema = componentInstance.value.addNewChildComponentSchema(resolveContext); - componentInstance.value.schema[contentKey.value].push(childComponentSchema); - } - } + const desginerItemStyle = computed(() => { + const styleObject = {} as Record; + if (designComponentStyle.value) { + designComponentStyle.value.split(';').reduce((result: Record, styleString: string) => { + const [styleKey, styleValue] = styleString.split(':'); + if (styleKey) { + result[styleKey] = styleValue; + } + return result; + }, styleObject); + } + return styleObject; + }); - function renderAddButton() { - return ( - canAdd.value && ( -
{ - onClickAddButton(payload); - }}> - -
- ) - ); - } + function onClickDeleteButton(payload: MouseEvent, schemaToRemove: ComponentSchema) { + if (parent && parent.schema[contentKey.value]) { + const indexToRemove = parent.schema[contentKey.value].findIndex( + (contentItem: ComponentSchema) => contentItem.id === schemaToRemove.id + ); + // 如果仍然存在子级,点击子级事件,展示属性面板 + if (indexToRemove > -1) { + const childrenSize = parent.schema[contentKey.value].length; + const nextSchema = parent.schema[contentKey.value][indexToRemove % childrenSize]; + const designerItem = parent.designerItemElementRef.value.querySelector( + `#${nextSchema.id}-design-item` + ); + parent.schema[contentKey.value].splice(indexToRemove, 1); - function renderDeleteButton(componentSchema: ComponentSchema) { - return ( - canDelete.value && ( -
{ - onClickDeleteButtom(payload, componentSchema); - }}> - -
- ) - ); - } + // 此处删除子组件schame后,会自动选中第一个元素但属性面板不更新,暂时绕过此问题,使用emit removeComponent方式来解决 + canvasChanged.value++; + context.emit('removeComponent'); + context.emit('selectionChange'); + } + } - function renderIconPanel(componentSchema: ComponentSchema) { - return ( -
-
- {renderAddButton()} - {renderDeleteButton(componentSchema)} -
-
- ); - } + } - watch( - () => props.modelValue, - (value: any) => { - schema.value = value; - } - ); + function onClickAddButton(payload: MouseEvent) { + if (componentInstance.value.addNewChildComponentSchema) { + const resolveContext = { + componentType: childType.value, + label: childLabel.value, + parentComponentInstance: componentInstance.value, + targetPosition: -1 + } as DraggingResolveContext; + const childComponentSchema = componentInstance.value.addNewChildComponentSchema(resolveContext); + schema.value[contentKey.value].push(childComponentSchema); + context.emit('addComponent'); + } + } - function updatePositionOfBtnGroup(e: Event) { - const targetEl = e.target as any; - setPositionOfBtnGroup(targetEl); - } + function renderAddButton() { + return ( + canAdd.value && ( +
{ + onClickAddButton(payload); + }}> + +
+ ) + ); + } - function bindingScrollEvent() { - if (schema.value?.contents?.length && designerItemElementRef.value) { - designerItemElementRef.value.addEventListener('scroll', updatePositionOfBtnGroup); - } - } + function renderDeleteButton(componentSchema: ComponentSchema) { + return ( + canDelete.value && ( +
+ onClickDeleteButton(payload as MouseEvent, componentSchema), + ['stop'])}> + +
+ ) + ); + } + function renderMoveButton() { + return ( + canMove.value && ( +
+ +
+ ) + ); + } - function createDefaultComponentInstance() { - const designerItemElement = designerItemElementRef.value as HTMLElement; - const innerComponentElementRef = ref(designerItemElement.children[1] as HTMLElement); - const innerComponentInstance = useDesignerInnerComponent(innerComponentElementRef, designItemContext); - return innerComponentInstance.value; - } + function renderIconPanel(componentSchema: ComponentSchema) { + return ( +
+
+ {renderAddButton()} + {renderMoveButton()} + {renderDeleteButton(componentSchema)} +
+
+ ); + } - onMounted(() => { - if (designerItemElementRef.value) { - const draggableContainer = designerItemElementRef.value.querySelector( - `[data-dragref='${schema.value.id}-container']` + watch( + () => props.modelValue, + (value: any) => { + schema.value = value; + designItemContext.schema = value; + } ); - componentInstance.value = (draggableContainer && draggableContainer.componentInstance) ? - draggableContainer.componentInstance.value : createDefaultComponentInstance(); - if (useDragulaComposition && draggableContainer) { - useDragulaComposition.attachComponents(draggableContainer, schema.value); + function updatePositionOfButtonGroup(e: Event | any) { + const targetEl = e.target as any; + setPositionOfButtonGroup(targetEl); } - canNested.value = componentInstance.value.canNested !== undefined ? componentInstance.value.canNested : canNested.value; - // canDelete.value = componentInstance.value.canDelete !== undefined ? componentInstance.value.canDelete : canDelete.value; - canMove.value = componentInstance.value.canMove !== undefined ? componentInstance.value.canMove : canMove.value; - designComponentStyle.value = componentInstance.value.styles || ''; - if (designerItemElementRef.value) { - designerItemElementRef.value.componentInstance = componentInstance; - designerItemElementRef.value.designItemContext = designItemContext; + + function bindingScrollEvent() { + if (schema.value?.contents?.length && designerItemElementRef.value) { + designerItemElementRef.value.addEventListener('scroll', updatePositionOfButtonGroup); + } } - } - bindingScrollEvent(); - - canvasChanged.value++; - }); - - onBeforeUnmount(() => { - if (designerItemElementRef.value) { - designerItemElementRef.value.removeEventListener('scroll', updatePositionOfBtnGroup); - } - }); - - function onClickDesignerItem(payload: MouseEvent) { - Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentFocused') - ); - if (payload) { - payload.preventDefault(); - payload.stopPropagation(); - } - const designerItemElement = designerItemElementRef.value as HTMLElement; - if (designerItemElement) { - const currentSelectedElements = document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf; - // 重复点击 - const duplicateClick = - currentSelectedElements && - currentSelectedElements.length === 1 && - currentSelectedElements[0] === designerItemElementRef.value; - if (!duplicateClick) { - Array.from(currentSelectedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentSelected')); - - designerItemElement.classList.add('dgComponentFocused'); - context.emit('selectionChange', schema.value.type, schema.value); - const draggabledesignerItemElementRef = componentInstance.value.getDraggableDesignItemElement(designItemContext); - if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { - draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); - } + + function createDefaultComponentInstance() { + const designerItemElement = designerItemElementRef.value as HTMLElement; + const innerComponentElementRef = ref(designerItemElement.children[1] as HTMLElement); + const innerComponentInstance = useDesignerInnerComponent(innerComponentElementRef, designItemContext); + return innerComponentInstance.value; } - } - canvasChanged.value++; - } + onMounted(() => { + if (designerItemElementRef.value) { + const draggableContainer = designerItemElementRef.value.querySelector( + `[data-dragref='${schema.value.id}-container']` + ); + componentInstance.value = (draggableContainer && draggableContainer.componentInstance) ? + draggableContainer.componentInstance.value : createDefaultComponentInstance(); + + if (useDragulaComposition && draggableContainer) { + useDragulaComposition.attachComponents(draggableContainer, schema.value); + } + canNested.value = componentInstance.value.canNested !== undefined ? componentInstance.value.canNested : canNested.value; + canAdd.value = componentInstance.value.canAdd !== undefined ? componentInstance.value.canAdd : canAdd.value; + canDelete.value = componentInstance.value.canDelete !== undefined ? componentInstance.value.canDelete : canDelete.value; + canMove.value = componentInstance.value.canMove !== undefined ? componentInstance.value.canMove : canMove.value; + designComponentStyle.value = componentInstance.value.styles || ''; + if (designerItemElementRef.value) { + designerItemElementRef.value.componentInstance = componentInstance; + designerItemElementRef.value.designItemContext = designItemContext; + } + } + bindingScrollEvent(); + + canvasChanged.value++; + }); + + onBeforeUnmount(() => { + if (designerItemElementRef.value) { + designerItemElementRef.value.removeEventListener('scroll', updatePositionOfButtonGroup); + } + }); - return () => { - return ( -
- {renderIconPanel(schema.value)} - {context.slots.default && context.slots.default()} -
- ); - }; - } + function onClickDesignerItem(payload: MouseEvent) { + + if (payload) { + payload.preventDefault(); + payload.stopPropagation(); + } + let draggabledesignerItemElementRef: any = designItemContext.designerItemElementRef; + const designerItemElement = designerItemElementRef.value as HTMLElement; + if (designerItemElement) { + const currentFocusedElements = document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf; + // 重复点击 + const duplicateClick = + currentFocusedElements && + currentFocusedElements.length === 1 && + currentFocusedElements[0] === designerItemElementRef.value; + if (!duplicateClick) { + Array.from(currentFocusedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentFocused')); + Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentSelected') + ); + + designerItemElement.classList.add('dgComponentFocused'); + context.emit('selectionChange', schema.value.type, schema.value, props.componentId, componentInstance.value); + if (componentInstance.value.getDraggableDesignItemElement) { + draggabledesignerItemElementRef = componentInstance.value.getDraggableDesignItemElement(designItemContext); + if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { + draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); + + } + } + } + } + + updatePositionOfButtonGroup({ target: draggabledesignerItemElementRef?.value }); + } + + return () => { + return ( +
+ {renderIconPanel(schema.value)} + {context.slots.default && context.slots.default()} +
+ ); + }; + } }); export default FDesignerInnerItem; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx index 48ec670430e..04e84744927 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-item.component.tsx @@ -1,281 +1,340 @@ + import { Ref, SetupContext, computed, defineComponent, inject, onMounted, provide, ref, watch, onBeforeUnmount } from 'vue'; import { DesignerItemPropsType, designerItemProps } from '../composition/props/designer-item.props'; import { componentMap, componentPropsConverter } from './maps'; import { UseDragula } from '../composition/types'; import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from '../types'; import FDesignerPlaceholder from './designer-placeholder.component'; -import { canvasChanged, setPositionOfBtnGroup } from '../composition/designer-canvas-changed'; +import { canvasChanged, setPositionOfButtonGroup } from '../composition/designer-canvas-changed'; +import { getCustomClass } from '@/components/common'; const FDesignerItem = defineComponent({ - name: 'FDesignerItem', - props: designerItemProps, - emits: ['selectionChange'], - setup(props: DesignerItemPropsType, context: SetupContext) { - const id = ref(`${props.modelValue.id}-component`); - const canMove = ref(props.canMove); - const canDelete = ref(props.canDelete); - const canNested = ref(false); - const schema = ref(props.modelValue); - const designComponentStyle = ref(''); - const designComponentClass = ref(''); - const designerItemElementRef = ref(); - const useDragulaComposition = inject('canvas-dragula'); - const componentInstance = ref() as Ref; - const parent = inject('design-item-context'); - const designItemContext = { designerItemElementRef, componentInstance, schema: schema.value, parent, setupContext: context }; - provide('design-item-context', designItemContext); - - const designerItemClass = computed(() => { - const componentClass = props.modelValue.appearance ? (props.modelValue.appearance.class as string) || '' : ''; - const classObject = { - 'farris-component': true, - 'position-relative': canMove.value || canDelete.value, - 'farris-nested': canNested.value, - 'can-move': canMove.value, - 'd-none': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('d-none') - } as Record; - classObject[`farris-component-${schema.value.type}`] = true; - if (componentClass) { - componentClass.split(' ').reduce((result: Record, classString: string) => { - result[classString] = true; - return result; - }, classObject); - } - if (designComponentClass.value) { - designComponentClass.value.split(' ').reduce((result: Record, classString: string) => { - result[classString] = true; - return result; - }, classObject); - } - return classObject; - }); - - const desginerItemStyle = computed(() => { - const styleObject = {} as Record; - const componentStyle = props.modelValue.appearance ? (props.modelValue.appearance.style as string) || '' : ''; - if (componentStyle) { - componentStyle.split(';').reduce((result: Record, styleString: string) => { - const [styleKey, styleValue] = styleString.split(':'); - result[styleKey] = styleValue; - return result; - }, styleObject); - } - if (designComponentStyle.value) { - designComponentStyle.value.split(';').reduce((result: Record, styleString: string) => { - const [styleKey, styleValue] = styleString.split(':'); - if (styleKey) { - result[styleKey] = styleValue; - } - return result; - }, styleObject); - } - return styleObject; - }); - - function onClickDeleteButtom(payload: MouseEvent, schemaToRemove: ComponentSchema) { - // 连同所属组件一起删除,使用场景如data-grid、form控件等。 - if (componentInstance.value.triggerBelongedComponentToDeleteWhenDeleted) { - const cmpInstance = componentInstance.value.getBelongedComponentInstance(componentInstance); - if (cmpInstance && cmpInstance.parent) { - const cmpInstanceParent = ref(cmpInstance?.parent) as any; - const indexToRemove = cmpInstanceParent.value.contents.findIndex( - (contentItem: ComponentSchema) => contentItem.id === cmpInstance.schema.id - ); - cmpInstanceParent.value?.contents?.splice(indexToRemove, 1); - cmpInstanceParent.value?.updateDragAndDropRules(); - } - return; - } - if (parent && parent.schema.contents) { - const indexToRemove = parent.schema.contents.findIndex( - (contentItem: ComponentSchema) => contentItem.id === schemaToRemove.id - ); - parent.schema.contents.splice(indexToRemove, 1); - parent.componentInstance.value.updateDragAndDropRules(); - } + name: 'FDesignerItem', + props: designerItemProps, + emits: ['selectionChange'], + setup(props: DesignerItemPropsType, context) { + const id = ref(`${props.modelValue.id}-component`); + const canMove = ref(props.canMove); + const canDelete = ref(props.canDelete); + const canNested = ref(false); + const schema = ref(props.modelValue); + const componentId = ref(props.componentId || ''); + const designComponentStyle = ref(''); + const designComponentClass = ref(''); + const designCustomClass = ref(props.customClass); + const designerItemElementRef = ref(); + const useDragulaComposition = inject('canvas-dragula'); + const componentInstance = ref() as Ref; + const parent = inject('design-item-context'); + const designItemContext = { designerItemElementRef, componentInstance, schema: schema.value, parent, setupContext: context as SetupContext }; + provide('design-item-context', designItemContext); + const useFormSchema = inject('useFormSchema'); - } + const designerItemClass = computed(() => { + const componentClass = props.modelValue.appearance ? (props.modelValue.appearance.class as string) || '' : ''; + const customButtons = componentInstance.value?.getCustomButtons && componentInstance.value.getCustomButtons(); + let classObject = { + 'farris-component': true, + // 受position-relative影响,整个容器的高度不能被撑起 + 'flex-fill': schema.value.id === 'root-component', + 'position-relative': canMove.value && canDelete.value || (customButtons?.length), + 'farris-nested': canNested.value, + 'can-move': canMove.value, + 'd-none': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('d-none'), + 'dgComponentSelected': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('dgComponentSelected'), + 'dgComponentFocused': designerItemElementRef.value && (designerItemElementRef.value as HTMLElement).classList.contains('dgComponentFocused'), + } as Record; + classObject[`farris-component-${schema.value.type}`] = true; + classObject = getCustomClass(classObject, componentClass); + classObject = getCustomClass(classObject, designComponentClass.value); + classObject = getCustomClass(classObject, designCustomClass.value); + return classObject; + }); - function renderDeleteButton(componentSchema: ComponentSchema) { - return ( - canDelete.value && ( -
{ - onClickDeleteButtom(payload, componentSchema); - }}> - -
- ) - ); - } + const desginerItemStyle = computed(() => { + const styleObject = {} as Record; + const componentStyle = props.modelValue.appearance ? (props.modelValue.appearance.style as string) || '' : ''; + if (componentStyle) { + componentStyle.split(';').reduce((result: Record, styleString: string) => { + const [styleKey, styleValue] = styleString.split(':'); + result[styleKey] = styleValue; + return result; + }, styleObject); + } + if (designComponentStyle.value) { + designComponentStyle.value.split(';').reduce((result: Record, styleString: string) => { + const [styleKey, styleValue] = styleString.split(':'); + if (styleKey) { + result[styleKey] = styleValue; + } + return result; + }, styleObject); + } + return styleObject; + }); - function renderMoveButton() { - return ( - canMove.value && ( -
- -
- ) - ); - } + function onClickDeleteButton(payload: MouseEvent, schemaToRemove: ComponentSchema) { + if (payload) { + payload.preventDefault(); + payload.stopPropagation(); + } - function renderCustomButtons() { - return ( - props.customButtons && - !!props.customButtons.length && - props.customButtons.map((buttonConfig: any) => { - return ( -
- -
- ); - }) - ); - } + // 连同所属组件一起删除,使用场景如data-grid、form控件等。 + if (componentInstance.value.triggerBelongedComponentToDeleteWhenDeleted) { + const belongedComponentInstance = componentInstance.value.getBelongedComponentInstance(componentInstance); + if (belongedComponentInstance && belongedComponentInstance.parent) { + const belongedComponentInstanceParent = ref(belongedComponentInstance?.parent) as any; + const indexToRemove = belongedComponentInstanceParent.value.contents.findIndex( + (contentItem: ComponentSchema) => contentItem.id === belongedComponentInstance.schema.id + ); + belongedComponentInstanceParent.value?.contents?.splice(indexToRemove, 1); - function renderIconPanel(componentSchema: ComponentSchema) { - return ( -
-
- {renderDeleteButton(componentSchema)} - {renderMoveButton()} - {renderCustomButtons()} -
-
- ); - } + canvasChanged.value++; + } + return; + } + componentInstance.value.onRemoveComponent(); + let parentContext = parent; + let locatePredicate: any = (contentItem: ComponentSchema) => contentItem.id === schemaToRemove.id; + if (schemaToRemove.type === 'component') { + parentContext = parent?.parent; + locatePredicate = (contentItem: ComponentSchema) => contentItem.component === schemaToRemove.id; - function onSelectionChange(schemaType: string, schemaValue: ComponentSchema) { - context.emit('selectionChange', schemaType, schemaValue); - } + } + if (parentContext && parentContext.schema.contents) { + const indexToRemove = parentContext.schema.contents.findIndex(locatePredicate); + parentContext.schema.contents.splice(indexToRemove, 1); - function renderContent(viewSchema: ComponentSchema) { - const componentKey = viewSchema.type; - const Component = componentMap[componentKey]; - const propsConverter = componentPropsConverter[componentKey]; - const viewProps = propsConverter ? propsConverter(viewSchema) : {}; - viewProps.customClass = props.ignore ? viewProps.customClass : ''; - const shouldShowPlaceholder = viewSchema.contents && viewSchema.contents.length === 0; - const hasContent = viewSchema.contents && !!viewSchema.contents.length; - return hasContent && Component ? ( - - {(viewSchema.contents as ComponentSchema[]).map((contentSchema: any) => ( - - ))} - - ) : Component ? ( - shouldShowPlaceholder ? ( - - - - ) : ( - - ) - ) : ( -
- ); - } + canvasChanged.value++; + context.emit('selectionChange'); - watch( - () => props.modelValue, - (value: any) => { - schema.value = value; - id.value = `${value.id}-component`; - } - ); - - function updatePositionOfBtnGroup(e: Event) { - const targetEl = e.target as any; - setPositionOfBtnGroup(targetEl); - } + } - function bindingScrollEvent() { - if (schema.value?.contents?.length && designerItemElementRef.value) { - designerItemElementRef.value.addEventListener('scroll', updatePositionOfBtnGroup); - } - } + } + + function renderDeleteButton(componentSchema: ComponentSchema) { + return ( + canDelete.value && ( +
{ + onClickDeleteButton(payload, componentSchema); + }}> + +
+ ) + ); + } + + function renderMoveButton() { + return ( + canMove.value && ( +
+ +
+ ) + ); + } + + function renderCustomButtons() { + const customButtons = componentInstance.value?.getCustomButtons && componentInstance.value.getCustomButtons(); + + return ( + customButtons && + !!customButtons.length && + customButtons.map((buttonConfig: any) => { + return ( +
buttonConfig.onClick && buttonConfig.onClick(payload)}> + +
+ ); + }) + ); + } + + function renderIconPanel(componentSchema: ComponentSchema) { + return ( +
+
+ {renderDeleteButton(componentSchema)} + {renderMoveButton()} + {renderCustomButtons()} +
+
+ ); + } - onMounted(() => { - if (designerItemElementRef.value && componentInstance.value) { - const draggableContainer = designerItemElementRef.value.querySelector( - `[data-dragref='${componentInstance.value.schema.id}-container']` + function onSelectionChange(schemaType: string, schemaValue: ComponentSchema, componentId: string, componentInstance: DesignerComponentInstance) { + context.emit('selectionChange', schemaType, schemaValue, componentId, componentInstance); + } + + function renderContent(viewSchema: ComponentSchema) { + const componentKey = viewSchema.type; + const Component = componentMap[componentKey]; + const propsConverter = componentPropsConverter[componentKey]; + const viewProps = propsConverter ? propsConverter(viewSchema) : {}; + viewProps.customClass = props.ignore ? viewProps.customClass : ''; + viewProps.componentId = componentId.value; + viewProps.id = viewSchema.id; + const shouldShowPlaceholder = viewSchema.contents && viewSchema.contents.length === 0; + const hasContent = viewSchema.contents && !!viewSchema.contents.length; + return hasContent && Component ? ( + + {(viewSchema.contents as ComponentSchema[]).map((contentSchema: any) => ( + + ))} + + ) : Component ? ( + shouldShowPlaceholder ? ( + + + + ) : ( + + ) + ) : ( +
+ ); + } + + function renderChildComponentContent(viewSchema: ComponentSchema) { + const componentKey = viewSchema.type; + if (componentKey === 'component-ref') { + // eslint-disable-next-line prefer-const + let componentSchema = useFormSchema?.getFormSchema().module.components + .find((component: any) => component.id === viewSchema.component); + if (componentSchema) { + + return ; + } + } + } + watch( + () => props.modelValue, + (value: any) => { + schema.value = value; + id.value = `${value.id}-component`; + componentId.value = value.id; + } ); - if (useDragulaComposition && draggableContainer) { - useDragulaComposition.attachComponents(draggableContainer, schema.value); + + function updatePositionOfButtonGroup(event: Event | any) { + const targetElement = event?.target as any; + setPositionOfButtonGroup(targetElement); } - canNested.value = componentInstance.value.canNested !== undefined ? componentInstance.value.canNested : canNested.value; - canDelete.value = componentInstance.value.canDelete !== undefined ? componentInstance.value.canDelete : canDelete.value; - canMove.value = componentInstance.value.canMove !== undefined ? componentInstance.value.canMove : canMove.value; - designComponentStyle.value = componentInstance.value.styles || ''; - designComponentClass.value = componentInstance.value.designerClass || ''; - if (designerItemElementRef.value) { - designerItemElementRef.value.componentInstance = componentInstance; - designerItemElementRef.value.designItemContext = designItemContext; + /** + * 记录滚动区域 + */ + function recordScrollContainer(element: HTMLElement) { + if (!window['scrollContainerList']) { window['scrollContainerList'] = new Set(); } + + const id = element.getAttribute('id'); + if (id) { + window['scrollContainerList'].add(id); + } } - } - bindingScrollEvent(); - - canvasChanged.value++; - }); - - onBeforeUnmount(() => { - if (designerItemElementRef.value) { - designerItemElementRef.value.removeEventListener('scroll', updatePositionOfBtnGroup); - } - }); - - function onClickDesignerItem(payload: MouseEvent) { - Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentFocused') - ); - if (payload) { - payload.preventDefault(); - payload.stopPropagation(); - } - const designerItemElement = designerItemElementRef.value as HTMLElement; - if (designerItemElement) { - const currentSelectedElements = document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf; - // 重复点击 - const duplicateClick = - currentSelectedElements && - currentSelectedElements.length === 1 && - currentSelectedElements[0] === designerItemElementRef.value; - if (!duplicateClick) { - Array.from(currentSelectedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentSelected')); - - designerItemElement.classList.add('dgComponentFocused'); - context.emit('selectionChange', schema.value.type, schema.value); - const draggabledesignerItemElementRef = componentInstance.value.getDraggableDesignItemElement(designItemContext); - if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { - draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); - } + + function updatePositionOfBtnGroupWhenScroll(event: Event | any) { + const targetElement = event?.target as any; + recordScrollContainer(targetElement); + updatePositionOfButtonGroup(event); + } + function bindingScrollEvent() { + if (schema.value?.contents?.length && designerItemElementRef.value) { + designerItemElementRef.value.addEventListener('scroll', updatePositionOfBtnGroupWhenScroll); + } } - } - canvasChanged.value++; - } + onMounted(() => { + if (designerItemElementRef.value && componentInstance.value && componentInstance.value.schema) { + const draggableContainer = designerItemElementRef.value.querySelector( + `[data-dragref='${componentInstance.value.schema.id}-container']` + ); + if (useDragulaComposition && draggableContainer) { + useDragulaComposition.attachComponents(draggableContainer, schema.value); + } + canNested.value = componentInstance.value.canNested !== undefined ? componentInstance.value.canNested : canNested.value; + canDelete.value = componentInstance.value.canDelete !== undefined ? componentInstance.value.canDelete : canDelete.value; + canMove.value = componentInstance.value.canMove !== undefined ? componentInstance.value.canMove : canMove.value; + designComponentStyle.value = componentInstance.value.styles || ''; + designComponentClass.value = componentInstance.value.designerClass || ''; + if (designerItemElementRef.value) { + designerItemElementRef.value.componentInstance = componentInstance; + designerItemElementRef.value.designItemContext = designItemContext; + } + componentInstance.value.belongedComponentId = componentId.value; - return () => { - return ( -
- {renderIconPanel(schema.value)} - {renderContent(schema.value)} -
- ); - }; - } + } + bindingScrollEvent(); + + canvasChanged.value++; + }); + + onBeforeUnmount(() => { + if (designerItemElementRef.value) { + designerItemElementRef.value.removeEventListener('scroll', updatePositionOfButtonGroup); + } + }); + + function onClickDesignerItem(payload: MouseEvent) { + if (payload) { + payload.preventDefault(); + payload.stopPropagation(); + } + let draggabledesignerItemElementRef: any = designItemContext.designerItemElementRef; + const designerItemElement = designerItemElementRef.value as HTMLElement; + if (designerItemElement) { + const currentFocusedElements = document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf; + // 重复点击 + const duplicateClick = + currentFocusedElements && + currentFocusedElements.length === 1 && + currentFocusedElements[0] === designerItemElementRef.value; + if (!duplicateClick) { + Array.from(currentFocusedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentFocused')); + Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentSelected') + ); + + designerItemElement.classList.add('dgComponentFocused'); + context.emit('selectionChange', schema.value.type, schema.value, componentId.value, componentInstance.value); + if (componentInstance.value.getDraggableDesignItemElement) { + draggabledesignerItemElementRef = componentInstance.value.getDraggableDesignItemElement(designItemContext); + if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { + draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); + + } + } + + } + } + + updatePositionOfButtonGroup({ target: draggabledesignerItemElementRef?.value }); + } + + return () => { + return ( + schema.value.type === 'component-ref' ? + renderChildComponentContent(schema.value) : +
+ {renderIconPanel(schema.value)} + {renderContent(schema.value)} +
+ ); + }; + } }); export default FDesignerItem; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-placeholder.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-placeholder.component.tsx index 5dc1be4ab5c..5dd90cb489a 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-placeholder.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-placeholder.component.tsx @@ -2,41 +2,45 @@ import { SetupContext, computed, defineComponent } from 'vue'; import { DesignerPlaceholderPropsType, designerPlaceholderProps } from '../composition/props/designer-placeholder.props'; export default defineComponent({ - name: 'FDesignerPlaceholder', - props: designerPlaceholderProps, - emits: [], - setup(props: DesignerPlaceholderPropsType, context: SetupContext) { - const designerPlaceholderClass = computed(() => { - const classObject = { - 'drag-and-drop-alert': true, - 'alert': true, - 'alert-info': true, - 'no-drag': true, - 'w-100': true - } as Record; - return classObject; - }); + name: 'FDesignerPlaceholder', + props: designerPlaceholderProps, + emits: [], + setup(props: DesignerPlaceholderPropsType) { + const designerPlaceholderClass = computed(() => { + const classObject = { + 'drag-and-drop-alert': true, + 'no-drag': true, + 'w-100': true + } as Record; + return classObject; + }); - const designerPlaceholderStyle = computed(() => { - const styleObject = { - 'height': '60px', - 'display': 'flex', - 'justify-content': 'center', - 'align-items': 'center', - 'margin': 0 - } as Record; - return styleObject; - }); + const designerPlaceholderStyle = computed(() => { + const styleObject = { + 'height': '60px', + 'display': 'flex', + 'justify-content': 'center', + 'align-items': 'center', + 'margin': 0, + 'padding': '.75rem 1.25rem', + 'border': '1px solid transparent', + 'border-radius': '3px', + 'color': '#315585', + 'background-color': '#dfedff', + 'border-color': '#d2e6ff', + } as Record; + return styleObject; + }); - return () => ( - - ); - } + return () => ( + + ); + } }); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-template-item.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-template-item.component.tsx index 86469e409d6..9df082c1b83 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-template-item.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/designer-template-item.component.tsx @@ -1,56 +1,57 @@ -import { SetupContext, computed, defineComponent, ref } from 'vue'; +import { computed, defineComponent, ref } from 'vue'; import { DesignerItemPropsType, designerItemProps } from '../composition/props/designer-item.props'; import { canvasChanged } from '../composition/designer-canvas-changed'; const FDesignerTemplateItem = defineComponent({ - name: 'FDesignerTemplateItem', - props: designerItemProps, - emits: ['selectionChange'], - setup(props: DesignerItemPropsType, context: SetupContext) { - const designerItemElementRef = ref(); + name: 'FDesignerTemplateItem', + props: designerItemProps, + emits: ['selectionChange'], + setup(props: DesignerItemPropsType, context) { + const designerItemElementRef = ref(); - const designerItemClass = computed(() => { - const classObject = { - 'farris-component': true - } as Record; - return classObject; - }); + const designerItemClass = computed(() => { + const classObject = { + 'farris-component': true + } as Record; + return classObject; + }); - function onClickDesignerItem(payload: MouseEvent) { - Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentFocused') - ); - if (payload) { - payload.preventDefault(); - payload.stopPropagation(); - } - const designerItemElement = designerItemElementRef.value as HTMLElement; - if (designerItemElement) { - const currentSelectedElements = document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf; - // 重复点击 - const duplicateClick = - currentSelectedElements && - currentSelectedElements.length === 1 && - currentSelectedElements[0] === designerItemElementRef.value; - if (!duplicateClick) { - Array.from(currentSelectedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentSelected')); - designerItemElement.classList.add('dgComponentFocused'); + function onClickDesignerItem(payload: MouseEvent) { + + if (payload) { + payload.preventDefault(); + payload.stopPropagation(); + } + const designerItemElement = designerItemElementRef.value as HTMLElement; + if (designerItemElement) { + const currentSelectedElements = document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf; + + // 重复点击 + const duplicateClick = + currentSelectedElements && + currentSelectedElements.length === 1 && + currentSelectedElements[0] === designerItemElementRef.value; + if (!duplicateClick) { + Array.from(currentSelectedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentSelected')); + Array.from(currentSelectedElements).forEach((element: HTMLElement) => element.classList.remove('dgComponentFocused')); + + designerItemElement.classList.add('dgComponentFocused'); + } + } + canvasChanged.value++; } - } - canvasChanged.value++; - } - return () => { - return ( -
- {context.slots.default && context.slots.default()} -
- ); - }; - } + return () => { + return ( +
+ {context.slots.default && context.slots.default()} +
+ ); + }; + } }); export default FDesignerTemplateItem; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.css b/packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.css deleted file mode 100644 index 07d31e8701a..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.css +++ /dev/null @@ -1,490 +0,0 @@ -@font-face { - font-family: 'fd-i-Family'; - src: url('iconfont.ttf?t=1640255080725') format('truetype'); -} - -.fd-i-Family { - font-family: 'fd-i-Family' !important; - font-size: 16px; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.fd_pc-response-layout-4:before { - content: '\e601'; -} - -.fd_pc-response-layout-3:before { - content: '\e602'; -} - -.fd_pc-response-layout-2:before { - content: '\e603'; -} - -.fd_pc-response-layout-1:before { - content: '\e604'; -} -.fd_pc-city-selector:before { - content: '\e600'; -} -.fd_pc-shenpiyijian:before { - content: '\e073'; -} - -.fd_pc-eventCode:before { - content: '\e071'; -} - -.fd_pc-delete-element:before { - content: '\e070'; -} - -.fd_pc-enable-function:before { - content: '\e06f'; -} - -.fd_pc-dragHandler:before { - content: '\e06e'; -} - -.fd_pc-editEvent:before { - content: '\e06d'; -} - -.fd_pc-extend-setting:before { - content: '\e06c'; -} - -.fd_pc-variable-setting:before { - content: '\e06b'; -} - -.fd_pc-leaf-node:before { - content: '\e06a'; -} - -.fd_pc-import-from-cdm:before { - content: '\e069'; -} - -.fd_pc-root-node:before { - content: '\e068'; -} - -.fd_pc-push:before { - content: '\e6067'; -} - -.fd_pc-save-sync:before { - content: '\e066'; -} - -.fd_pc-delete-obj:before { - content: '\e065'; -} - -.fd_pc-sync-bizelements:before { - content: '\e064'; -} - -.fd_pc-basic-info:before { - content: '\e063'; -} - -.fd_pc-advanced-setting:before { - content: '\e062'; -} - -.fd_pc-add-new-element:before { - content: '\e061'; -} - -.fd_pc-corner-marks-right-bottom:before { - content: '\e060'; -} - -.fd_pc-add-virtual-element:before { - content: '\e05f'; -} - -.fd_pc-cancel:before { - content: '\e05e'; -} - -.fd_pc-add-child-obj:before { - content: '\e05d'; -} - -.fd_pc-add-same-obj:before, -.fd_pc-imageupload:before { - content: '\e05c'; -} - -.fd_pc-yilaiguanxi:before { - content: '\e05b'; -} - -.fd_pc-shanchu:before { - content: '\e05a'; -} - -.fd_pc-gengduo:before { - content: '\e059'; -} - -.fd_pc-git:before { - content: '\e058'; -} - -.fd_pc-shouji:before { - content: '\e057'; -} - -.fd_pc-diannao:before { - content: '\e056'; -} - -.fd_pc-quanxian:before { - content: '\e055'; -} - -.fd_pc-daorudaochu:before { - content: '\e054'; -} - -.fd_pc-dayinshezhi:before { - content: '\e053'; -} - -.fd_pc-yewuliu:before { - content: '\e052'; -} - -.fd_pc-shujuzhuanhuanguize:before { - content: '\e051'; -} - -.fd_pc-shenjirizhi:before { - content: '\e050'; -} - -.fd_pc-bianmaguize:before { - content: '\e04f'; -} - -.fd_pc-zhuanyebanshejiqi:before { - content: '\e04e'; -} - -.fd_pc-lingdaimashejiqi:before { - content: '\e04d'; -} - -.fd_pc-didaimashejiqi:before { - content: '\e04c'; -} - -.fd_pc-geshidingzhi:before { - content: '\e04b'; -} - -.fd_pc-kuozhankaifa:before { - content: '\e04a'; -} - -.fd_pc-dingzhi:before { - content: '\e049'; -} - -.fd_pc-ziyuanguanliqi:before { - content: '\e048'; -} - -.fd_pc-zhedieshouqi:before { - content: '\e047'; -} - -.fd_pc-zhediezhankai:before { - content: '\e046'; -} - -.fd_pc-xianshiID:before { - content: '\e045'; -} - -.fd_pc-sousuo:before { - content: '\e044'; -} - -.fd_pc-shuaxin:before { - content: '\e043'; -} - -.fd_pc-anheimoshiqidongtai:before { - content: '\e042'; -} - -.fd_pc-anheimoshi:before { - content: '\e041'; -} -.fd_pc-tag:before { - content: '\e040'; -} - -.fd_pc-html-template:before { - content: '\e03f'; -} - -.fd_pc-button-group:before { - content: '\e03e'; -} - -.fd_pc-display-field:before, -.fd_pc-static-text:before { - content: '\e03d'; -} - -.fd_pc-QdpFramework:before { - content: '\e03c'; -} - -.fd_pc-check-group:before { - content: '\e03b'; -} - -.fd_pc-list-nav:before { - content: '\e03a'; -} - -.fd_pc-nav-tab:before { - content: '\e039'; -} - -.fd_pc-file-upload:before { - content: '\e038'; -} - -.fd_pc-section:before { - content: '\e037'; -} - -.fd_pc-jingtaiwenben:before { - content: '\e036'; -} - -.fd_pc-discussion-list:before { - content: '\e035'; -} - -.fd_pc-personnel-selector:before { - content: '\e034'; -} - -.fd_pc-gags:before { - content: '\e033'; -} - -.fd_pc-module:before { - content: '\e032'; -} - -.fd_pc-multi-select:before { - content: '\e031'; -} - -.fd_pc-sidebar:before { - content: '\e030'; -} - -.fd_pc-steps:before { - content: '\e02f'; -} - -.fd_pc-splitter:before { - content: '\e02e'; -} - -.fd_pc-scrollspy:before { - content: '\e02d'; -} - -.fd_pc-multi-view-container:before { - content: '\e02c'; -} - -.fd_pc-list-view:before { - content: '\e02b'; -} - -.fd_pc-charts:before { - content: '\e02a'; -} - -.fd_pc-image:before { - content: '\e029'; -} - -.fd_pc-scroll-collapsible-area:before { - content: '\e028'; -} - -.fd_pc-modal-footer:before { - content: '\e027'; -} - -.fd_pc-wizard:before { - content: '\e026'; -} - -.fd_pc-header:before { - content: '\e025'; -} - -.fd_pc-component:before { - content: '\e024'; -} - -.fd_pc-data-grid:before { - content: '\e023'; -} - -.fd_pc-mingxibiao2:before { - content: '\e022'; -} - -.fd_pc-tubiao:before { - content: '\e021'; -} - -.fd_pc-query-scheme:before { - content: '\e020'; -} - -.fd_pc-liushuihao:before { - content: '\e01f'; -} - -.fd_pc-switch:before { - content: '\e01e'; -} - -.fd_pc-lookup:before { - content: '\e01d'; -} - -.fd_pc-erweima:before { - content: '\e01c'; -} - -.fd_pc-radio-group:before { - content: '\e01b'; -} - -.fd_pc-organization-selector:before { - content: '\e01a'; -} - -.fd_pc-approval-logs:before { - content: '\e019'; -} - -.fd_pc-combo-list:before { - content: '\e018'; -} - -.fd_pc-input-group:before { - content: '\e017'; -} - -.fd_pc-multi-text-box:before { - content: '\e016'; -} - -.fd_pc-tabs:before { - content: '\e015'; -} - -.fd_pc-OCR:before { - content: '\e014'; -} - -.fd_pc-number-spinner:before { - content: '\e013'; -} - -.fd_pc-field-set:before { - content: '\e012'; -} - -.fd_pc-list-filter:before { - content: '\e011'; -} - -.fd_pc-avatar:before { - content: '\e010'; -} - -.fd_pc-date-picker:before { - content: '\e00f'; -} - -.fd_pc-language-text-box:before { - content: '\e00e'; -} - -.fd_pc-discussion-editor:before { - content: '\e00d'; -} - -.fd_pc-button:before { - content: '\e00c'; -} - -.fd_pc-yuyinshuru:before { - content: '\e00b'; -} - -.fd_pc-rich-text-box:before { - content: '\e00a'; -} - -.fd_pc-dizhi:before { - content: '\e009'; -} - -.fd_pc-time-picker:before { - content: '\e008'; -} - -.fd_pc-input-group:before { - content: '\e007'; -} - -.fd_pc-view-model:before { - content: '\e006'; -} - -.fd_pc-check-box:before { - content: '\e005'; -} - -.fd_pc-file-upload:before { - content: '\e004'; -} - -.fd_pc-tree-grid:before { - content: '\e003'; -} - -.fd_pc-response-form:before { - content: '\e002'; -} - -.fd_pc-content-container:before { - content: '\e001'; -} - -.fd_pc-fenlanmianban:before { - content: '\e000'; -} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.ttf b/packages/mobile-ui-vue/components/designer-canvas/src/components/iconfont.ttf deleted file mode 100644 index d30de0f48c4d33baa082d126edacd6a4aa9a6687..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35356 zcmd?ScibFRy+1zZ%+Ai%nVp^Oz3aoT9BebB3v8Nq={ZI z7kdJNA}C(*22rpeO+l}s?o}=-DqckaH9PsfKQsG0Nf43yeSQD=y?#&j)H&zO%$d*m z^m8IGK@i-+enAxa=C52mD|1!xQbAzTP`hgB%HDxmXv?or{s79G&fK&4T*pVgx>OLv z#{|Kl?AU$D_Sb&*U|bM9PYS}m!p?1*x0arJ+uzW(fl%9t3ir7DVdTGpP}sR=-^IU` zkNpMX{T89I`eMoo$*CHrq_HN#@?VIzT-Yp3G|0D?f zs&mh|VBd2K?s%slT(Mse?6(Sdc5(l){lW(Mj$`*6`N#6Z35MSvxjkeCrBBJG#nH!vxHLc|V&i#;y}2yzBcoW>~n^O4)CO z0fwGjkVMqJ!QZm&bGHgd8p5$-=6nd^a{|2$y~FW8PB;9A;Sgr@2(DM&pv|0P$4>4? z<;l9q^bPu*ct3Ltw8fV{X)LVAz_+O7ivOP7!)ePfY6V%*DLf0-FT-?p+jgF+Jv%D5{g1W z$O}0kD`bSUkP?zYLWpBsMumtF#%c}<0YMiu!6&GKB6tN4u%AnC;yq>DMZz0%%n?A8 z(W?Ca`=5s@1*~_W(QgH; ze4#O51>gXo0eV0I*g$9uS^;=LXjH8L3?VdXRsgOL8g(lGYY2^LRuIOK4p{-1L}*O6 z0&t4Z7`6hii_n;11>hN>L1hGB9HBw&5P*Ax2K7e(eh?ZoE&}k8(4hMv05b^0+#>)_3yssQ0E{g(&aeV-x6s&V1z>TZvB?U+=R#w%6@b}=#uh68 z#|w=!tw6k6W2+T__l3qbD}VwBjqO$dEda%{0;qz}ILiv44?^Q?D}Yi6ja^m%%@7*9 ztpMsFH1=2lbVO+EwE`%L&^X5mL~R@AS^-o>Xq;yS&>Nv~z7+%+=>=9G7<&QJL4m0G z3(N|jOTr7>3ZPKJ3!)W3tArP9RshvfHtjHjAoytj{B07x%oMhPFXCSlw~ODlooahh zx>)+Q-DQ7L-sc!_JnmfOe9X1U?Q>t_;hxJphrFLvO3L%)2`N=?XU&@#IK$th2(Ye2CUf1p2J>Adu6nbv%dA@g6@0ES?`o7;ktN;0dn=5N7KODSq@UPVm)z;L$ zR6AOKTm9S97EF77==|yQ&X_;2KzH*W;j5(q<}Iu-~8{M|NrXg*;{<_{l|p;=98~Jbm;%)x$(Gwzt=tU|Kf?o?BsO6 zm3e-q^O#^ht?<8nR(iyfp0oF#Lxq&Jz#`vz#((mJ&5v;N;S7r3+Vff8AI}BcfCqd^ z>;x592X14paGCI4;e*2M!lyx025JP6!+>HyX$XZ{{lwB>sgvd8>R=B;sxWF(EGaA$ z4u$P9{$T!2k~Ec*^B5$MVyGTv7!>7Jo8nZi zj9kF%I9L*=Y9Df|iNH4liC9dsxzszAKrCJ<+^PBEJ&A9|d*UkpFIT|jaE2sXBscU9 zvSRLqo4&j8ZF5(!=5KHDsj816W}i^;H$mkI*(>8W;qW-{o2oZ{ zG}YR7i`(aOThZhQyL~P`9!Mkt%_B4t`>tqn2NYweS@>LGz+SD7Q^2KvPbpEX0(qg_fT||8dC8y zUW~_LpkK76kNrg45AaKYMwUQ_L8UR>Jq%xUlvT0=DVAjU>R<_gW)EvL*fu((q4o}n;h$dzzUD|M7s7%zF|f3EliC7tL`@Fj@wd-&mC zDiv&gA(-L=wT;zHRpU?0F9wul?vR6dz0A8sDSK-!*R)b+;WXpueBY{;c4QfH4>1=h7 z%0S^k!WQK!kaWOaw1Cru!|XrEi#N0l+tz3MMb@2h9(^8}wWz4KImB-ea1LV(Qosma!IW?SbTj- z`0Cgp=?Q+n2{j8%m?@1gfJt?rh7>3uh}Tat5H^A!T8~bacQUK4lT|BLyLu0!Ze~S@ z+Ev&+xv^=Ty}g~&#&X{Fbmu^&Bi-)hgT|l6nVWa^cGk!8-u6t#z(7Z)-J2h)mj);1 zZ0J}qK7Zzlj`eef^0N}_Cj!BVb%|Md{#5gFe!y5hzM^Bpoawl-ZXy_5y&hMFW^d?N zw4jA|?+|wY_IpTjsRQ&uhDTYQKtCJ|D6CYbC$vCpm`YH$b1G9y3 z0l=SPl{!EIOJS5%%cWj6#%fqTH>7Jho*GQ^1({k_RCFIN#^vUbc$-*^$!yt|A6fng ze@y1Gw(BgLE21;zIO{A?X1Z5$BX>fTvqGaROxHp92h-2G6z*}^9=FD69!a!uR^hkK zYyOqn=NSiWjLT=AB|7-uk25v2)9vt>-}64;_;uhAM@aJ0Ej$anJXoqLJjLs^P&maD z5z_;VU9a^pU~kmmhfi4_<)t!Rl64a!jB?C|KFU%|7VYwjYTW0GtKm%McDE)=YRJ9) z8?*bnmAU6%d(*%4%~sW--J40v-F{c4ZPu5zFTZ7U-YQ>xdiz;3E_(Y6#r;{kBq@Hs zeC?yo1gJ*Csqx>dv2RczqXKI(mNJ zsT1|V;eWgTvvd3B2ioGzUG97By5DP)>^HKqTk<75#{CKySMb%xF6Ymg+Ex!Z=omQs zG9-{Hq@`Jq?3O_aJsnaq_-&RCgh2Q}fG|x`9t6o+NoUjE+d zOfOGau)@%h@DZ9IZ^vq- zaR+c27;21_i&&@%TaihI7}tT{oPmg%ilp3|_66SV=`7D1nVXE_l1C5avvNRIqmH0A z&bp#LkJBDZF6|HLswykJnQ&(&?&?%sc2VZ`n9pvvIb2@9Pb~*iL!rU294rm^%7LV= zOPb`g$3n8K1meMwxbgeN>D8TQ?Z+LGQO(0eo22*E*;PxFHK)$WXI#vyCqn@b=N?(~ zD+ASaGS}mYM4~+6;vR2@f`<>b4Jg-l%(aOgE~_CM=Qg`q&bky_35+gD1cxiC!dS@H z?{|va?Na1mG_~#u+4$BKJ4+oVZ*WBXSHNo+t9}~vLle-U(Q4O1H1nA(5S#{1rv}js zGaeMRLBKAN1VA%5Rt=0(i6$Nb8s^%Y zD^U`#iyvX-jOsJKX?(MNnDKNxlHglQ)12bma`U#b?&mvXd&KzUOL|Ze6_;dZKgda# z4C6n)>h!r}MU~kum(%05>7Ms^qsfSuv2=UVn59G#5pSw9b!RA*?ntHBe&bMXnoDAA zsGWZY%>_4{0miMC)wV@!=I6oLts z3@8z=5>bMw^a6~JA7I*&b8i+GW7YRU!krJz<&~Jl0iy5roW&-9zoLmFxq)QcmY}6i zmLTKSC-Y!KifvQ~jI!ftYI zfMak+kPdGcB;r)5kZ*=*iH!dsaQT|hrKd&v{vBLM?Tx2%>CyDoA^h6+VfTBd;M_(gq z^))|G#Jkd!RJH@78x>cEy=shUUMFy$Y!5iS8hc2OM$a(b&+dpBeO%18wPi*AHOW+K zz`}Iw3ef=VFG0#3C7rjF?E!(pl$g`;_n>P{sBQtJIk^xv0iYI0kMU8K=CtU0xn?qv zAa*DKGT9O1k-}&JKmOg~XdzaL#q?&yAB*|fbUhZEVLXLcXT5qXzWW)K21}62ix|PgmMDr({KVfIZGJJ^(~}ifXM1$x zHsi0pP*8>RriYH*6!sabec`JWoi7Y14VT)CLK#-97TM2_3FZU|cvt@RpZNnl*`tSP z6h1H7+dMzy`?(s_y}yJ8Y^^VhQ9h+B;-K;iudn&EOXa(Cj8Ux4kI}S1ZA+F$@O|I` z4uIn;Kzlw97;7c05}UvW;0+w?E8p)bj@ps@_N9`qL!!k#1Ec#!C7 z7_Fz+LK*WQ_uC;S)cb1^2z9x?1fm=653zm5QD2Dv8X()e3&4w%*?hsE@ms#q7iw;1 zLB8p<#S1#Rx;hpt{_JGtw0RfKoqOR2DEeaP7a`o8BBmkS;Lz&jx{3by43ENg#ci6T%6`<}eE#%{D zh8)1M<3{1{E{(_m;CBwi1o5Irpo%R#V z#?@XwU-Mqj!28*3lNLT`(!%5UGnP{YMc)wZ4(^I|#qev6BLbRU%a3?<-D^gK%_1nNOes-hJBT_c5itNj ztH3i@RfL3Qy2C zgexcL8}cd-c7mz|fKrC>(II&PlZ=>jdk|C633W;j|44SIz@cd1J90yLt^@&rrKH@v zBiSJ$Wm_J8a`lruz&Ur`CV4fN z%#mvR-xoC-JhRAnj@beqJ#hf1HJ&KnCZS*J`&x3AM7FXZpt7ooK$yLpSYNyhy#_cG z@u67pk{{Ru_Us;4An7_Cxlg!Kf&JyU_|@i>Ka=I$UUw?!I$f6Ubca%8=Q`F9{|EEw z2G?GOO=S!=-qT@EzfkxW;dAukuT(X{m-4!0@N{(torSuFZ9sy&bvIS>Y?Zty%F6R^4gr)_FlBT z(i-Cm0+1dy2_UxC2We1*@wS zdu5v*vWHPvV?7-nC-W8|jP%%-+ZcEjAMCa5u*t*13=*P z&?FGg8te~%3Rn9F>tMn1{W)-KmHq({C>6XKw3;TC=>^q*97QT_z%FDenPf4ju^|pr z*vTfQij>u|W+N5o)|9Qn)a4(PSR=#6Ga2JZrjfzlx_rf^MFO08oKo{oPQ}c;4a#h2 zo8N|Oy?KYYJzgxr*g-KLZyrIIXf?2sO(!K8tJF#u-6V66?nn1!M|!f(omPvTP6)zo zhtz!1>E&8f7jcRAm%yNmI(TraEm>FLU0ksWvSL#3);A6R4Is)hAD&ks*5e?zcE|4AXGpbY%3n-|e&= z{e!~`Eq@f>p(p1M)!cx{it(f7l#An-gQG`G8uftqs5l>7$S`>z;px)=5j-%~N-sn} zQdy870Llb`hMvRcVu z%%DslrE{-aVqf=wmv!4`ssW$Zez_y;uo?gD)?;Abf-Wx4FT$eHYHG|lvFXg#XngL} zkjOCZ(^bW87*gu0g>!ei!?`dEXW0QyBpZp~Da#3dUGv;TSvjc77dNHqZ3<*m>qq*ZCvNGgZ1)dwt20BQ3cq0w16nDDwh>B~zae0E0&2 z5^fB6iBx9c90^dz?Z1O0N|_)+fQ6|e)zJwVF6`X6;hJ(=Tlty|8=pL$-MMe;=Aq%? zq0L)=HJLF!fF)jobu4~zD(-)MXKS3*!_ziz{qaJS+!YME;%cU&c^CILUs}gJt{@v+cewkqb;e_3*#hbDVgK*v&%$pdinl!O zoiK^6>ad7`o)S}6u9*~p$OCF~auCozSmv*VGCUhL#>3fUkUehnNg_KUO5b#mn8|LHaW%PX-t5OnoLjMbcj~O*2(fAPCY3HqH+lyyQLsvoE zpHMXKjVZ*OPf19GeS@abP%dL$p|v?#lVOrRlc?3%xZB4R*PJ8Kf(SaaH&!aej*Nqi zRos{E-~Vd!gEmRB@x3q~884!x*L{k4ZMGWJ_}*-U?IU_(+z>DBrJ7Id1XmDPp5P}tw^%UwLJ0mt5XQJIDxx8Mx+bK#A9VD2J z-ClSYNFx92u3e(fWvmIrE1lJiKAX)EF2nF%i3ixHUB2cL_SzDX6(1FC%8YzD71KT5 zbUZH=M_ki%FH`jINNy@tR)x{*hAh%OYN#TQKwBpLAm@#C1U0Qn1osV0(XYK}?8 zUJc7t$*Rj|t8%z%S(w23bwFEIjA`li5Zn6HQw+2t6E+?}Zhfddt;P5nK;~CW{o8h` z*m>1et7k$yeK4Hebk$X-oBg)wt^E_?U-2+HWQ{!eGQu;0v>zoHx=8^FSg)0eaE>5C zIVpSADNE=}{PLw@K5X0&DO{Ss9Iq4$&4<_?;|BHtW5TOJ<$TEFhc38K7$_9jUmuTT z#9Z|8&V+FayEoDK_~XVrOI-eIv05rsVWc8`!5_qH_!rAVxOZ!UroHgn_FS_$$qi1ydgiCQ|{{i#T{oDqxnr9ZV&IytDbS zZQE{Pn~jfJK}`j}mF!63_pM-x^`_cW_^}&|J#2GjU|?&dvaM1fv_UZbOYtT#YRYHR zNv{etK@2HaQ*H3XeBBfQEg2T<1Bp^3gn_ZZlECc3H%KbwpgaqN2O;``g(bNPyetY( z55S?I3Pdx^y1KiK?{^#TX5C#~#`n6n+kN(RBEeC2d1lGy^mv@U@!jK9NoM@3l4f5k zigw;rnuSYlw{;12L|>Qjv+iz|?K0MN8$avnV%hGwcKbG)(`K`kW|rN~s?$BTd)y_9 z>^oMyD4O*{X1&J-rodDzi(fa_cNt%1HfaDs zCX`NxFr-N{|5Mx~md#aEhTp{i<|S_#(}Q_a%WA$3F+oL3Vl!uh9FM?V*28ry?rK(y zU0s^FWM=8=WP5v(4Zi!)2CJ=y%O z*`tzdpRZ?&S-pL@-8eYUcp>_ZfioW+xNAOshlq8aQZgu3~9t=DIqscGzbtvBa4Ze!;-*$n}ISboBxc;ivO z=6u|lLT$I_^Q7bo!oFav3iSg=aA0#Z@cM!{oY zJt`b4a?;>YBtg(LG55>$APmp|&=82POc~RJ@nc^k;xnGJD*@05K&YM1N1n4tHmc`) zqRj`QJ$XGlJ;#3&(X@zhyXbJeV`))zu+5Q~Ra2w*@yKR1-?MPC}r&O^%M@LYl-3!^U+jZZJ|Vzi70-cl``^L6Z+ zyBMCv{jlZ0ZyMe#aIK-wf_DZ#(!(T^#=?k;)g>#u6YGf>&N}7;=G!o^BXA0Ax`4_e zmMlIscri>HR#~}5Y%5UcR2HPhsy)M>4!e2Z;)vVLBc3epon9`aX4kGs%;?RpJ#+k( zWY!&qgB$a>qeG9p`_`Um!;#Gsm)nL7rPS+o@~FF%<*dD(v7j>%F-F-3+lq__9Px;8 z4*Nnoe0u_pgm{rRT1+=#l!$tY8UE9H)a&&z$>z}dF8%Au_wMP;v;#@X-e|tS@643l z(JPw!VCGx-tq)vVz9JabyPC6yqHYf_!SB%FfWT9T$NaK`zgCDR{0obtpb{+i!kUCSeY#$>%DFq zF!)5xCpk(8z>|2=8mgV0TxR>zU0vy80>xsdM~CN{%{T;k-{*bmm|&A-U|__&Y+X7G zWwy_2J8U*EK511xbHWhjK-O@_u#<9X0Cx1m!s5wWGPEa0X@I{LgY7aTLzytyX&36D zX9)1abj@tUg%f+8m>)l}=ZSffzVA16S~_%E9pG(O(H76!7c!kWMQ<}RIF6& zIeJqe%KsQG80V^fag;~Xh{fm+-YIkEWs)B7IYj&3b7U!!bQ%*L$+>s0oxA)l-F=zN z9G5v$e0Ecb=9#!FFYZ5KT>eLlZ#>xiHu#+=drFL|#_g)#9#z?9pQashxmEXJK&MC7 z9XH?XN&3n2HSM|iW=BwWtB0K)1=|5^Yy-L`QO2nNYf!&9t32u1%e=wW9lVLs5MJ4J`oH9Z1;ydvYM9d2sedvHBA{&XbL`f zpotV;?3QHlyUv71+V8PxNyWD1K3B$gNDXmamA;0Z;5(eDC^+M#Klh3Q!4$0Ji1>FYGE2aJq#OJn@mu@_bC*Fkb{R~A zK9sDuD`>yhaSnvIsuq(7Hj9v$xoFL$2&oM`NENmu;wB;90VP}ZOjAh?pEqbv-`D}} z!lpmp*OzC$Wu$v%yWN`RUdH^n{{Ex?!(Vc%M}OjDcW>Ch7B&5DpO{yh_g0iJIjD4` zm{38CQdmLO8$oJb;xF{)jC`(tx)#!W5#RLw9D6R`Kcu>iPq8%~wfT(R@owN zM1fBVaW3Q^4Br&|%(^&bF+C=%{8{`A|07_9G+c{m_gWEa1#7C8gF;%iNAP4iSszb; zjoLtqA2U%Jn76PFSeaakC_`mxmWiA|gUTY(&E9B9v7di|r=ZxqqD#8TomD>SwYhCK zdy1-blb1zHs&v8mN*jApp_f&D>ZQc{Ushtg-y8Ab$1Z4H)e{N*Md>zgDIvP0i!a8I zHg8^)Zu3YE_GdHa6+O18>uU2_<_*Wg9uFdDL5IBISlDYutvpM#C0J`t{sVKO3t33` zBd~xAz$GB}yoZdm`1WJmWFk75-7?N$b_ij&N+(}Ki98^vD~KhbAgBZ1>n$ZEH(t7+ zPRXiwhED83vnbIAvS8y|rq5y!GF1($2G&TzBT&Uz7`NpU@_PD2qz*0U!($QE z>izkeMbPm2RXB}F7DoYgLR=K?$Y=~Jy?IuMmOR{fuWnuzOhU|hS0I@*UK(6Gh~HAO z(0mb`I-EQd=4bw%p2A3>Fd~j?8K9p%scH(D5WfKfEKUZR)HlE{3ncFuT)T7aAlKZm zC%}Qo?=c?m_@VYh+2fyKyqX_bFjBxeAYMs;z1a=@17z7Ec43&DO$kfDa_uF?7QR2= zbxk)mOaqWv25j~p^&ccTd{QI>N&T2pdtK7zFeAr`nC=8%jNkS zww=E4qjOiUT)N^sKa_^=Shak`sso9*qSSAP-tpnQ*{rkx&E}U%t>?Lw{|YobqZKqpK#sRQ7nvd~S<#+urO zUC8e?A&Q*hO%ayhBTvvprWY`lrc{WH6R05bF6=U3L`OjFq5LteG_+9x8h48iAi8As zfc%HX=Abf=H~N5!HOHu!{V_6zz?_n>h(UqI%i{k0a4t8Te-z32=~~wHXm%(sBIA{{ zhzOZf{*D&qf8xzoBbxlEKQ4y-%_C@QJYe+`g;smxZt5+{X#KZV&*r1l0sUSL``P@~ zO^~qp#sjTh*6o&JqndRiN?(1|pWtCX?v~*EeQ0ky(CRz&d~81TUuL$px<>F|W{+2K zOVgL&G4XcsR7h?^SkicNQ^JNO77$MFO~r~S0KkzIyghiL$%`Zelpz&RHT%ilua8O) zW*y4e>(&fb3ppEeD9($vLBY&MhPUrDcGquMcGmhem0CyJ{6*{gYJ=-fA7tCt$(rhf zLSoJOvu2#vkAlNCI&$WYi!R-{eR%Z#>EqSGHS5mauwr>_ns4K-^UvHoGS<>#J_|i& z1Z!~!{^pY&SC+pt^joww1@=l>15;cwNHx)|vgP~$J7*7*r_@akf6xaU^Sy8<$;6#u z-kq-cKIr%N-{6R=&F@9>`3Ud!#T+*{kHHtBFt%t$p)jME>FJr-)5GrlO)N>BjLrzU zr(!QAXD82i(W~a7?3qYj_5Mc5-dY@8JXT=E(S@VMXQ|W79?O^NWs%+^3XRkdwBc)^ z*F2l{*h9i6yN9X$2!r*2p4(E91*KLx$^Yw<%q&C*>H)7=2xySVz_!w|0Gx+p(hNcA zIm*keT&*6=LvLOQhRd+7SHjhbCict@D9uL{T~}Zzfr;at@wVm_NN=Z7b4#K;8`~Z? z(DmlW75%^6p@eVs60au)Bp^$&V)s-7-dN1;aoPPUY}+pNv$eTL4z8?qEv@tO6g}WI zmMA)#-4=cZpna2Ev*)$L3J>sh+B* z`0TTTga3KUjm-7#cN;I0><+wq7#sM#PL63=-3>;0Y)k6-hqjHi8ZY@*XxPm0Q@B)J98e?EW2^g%5`Zdp!e z9q1;af+m!n6+$?2B=O}+k|p+8K!CLg%+AT{)Gk|I?GRI7t_HfNg^SNmy9bFgfxvPc zh@gP24gy#(WW@mAiEVBp)?PREd7smAfT8c*sv3aM=kLQx!*aFCjc3oaj zJbm3aV}AIO4o<5CV*X$pnZYNFFJs3_m~Rhf2F2!wMUiEh>i!~)gebTP4y#8*gWKlm-V&#u*fwTIo9|e)ThU)#tX^>|b?8o%@{r zsDuCVUb^s<$L~;lilaF&S;S!cgOelBXfrVE8Iwa94}ZpPv$=gLM#4Z5zq5t=F66hE zI%4t}7a*h1i{ZWC2-MPqQXY^$RS!+VR35gC9VCOXTh&mg`S7`jRf>4JxrOrlc8X8P z^Ch8lXzFLcI}*QRRt15trMo2-PtF5sO#*CZnjG$zi58PC1J&YU z1D>3Cw7V!iA@6VQ#YXFh#y{wbvT*aIuYBbOE2~)-mEeTqN>A0`C~O4OaxeRfM1^+NS)MY&t&5;njK?-L@=xxMUzbY7~|r3 zEuMT1zGsMd7t%~%%FBaQ_-;-?dtQg$GGs5?X)_OY@{|Tixl=9G!ZmCMs)YxzGnKva zv>5UEhZH%y_f zXfj=U(RjqfPtyU&!^WR2vuzZ`GHet#Fiwf&wr<7XqmeAE zzR5CFyDpd8r{^NZ!)nYSM}m@F8%(ni^f2!66GZy2HF2dGS@`}b%-ags7*awV^1(99 z8@@I^H2DaSPdPrnX1y#X53h>L!2ZO?nkqbOlp{tJYZhCL(9K$zU;&9>5T#WZ_YUt! zrG^IvFWHeyr;|How9o74n73knN5_2Q?P_S%(q*S@obW1gQdxM*`1E{H=MVl!4Fxnr z`a6|yFc+`|*p03JNZvj;FoW%*5!&15ub9_y^xHw->7O1LwyRlNBHgjwCoOyr^abG(wwi($uYsu(Ee@SHafNjA zro|ibXjv|!0y<0?Q$SnH0V06^IvQ{xR8ISfBQtwF(P=ebE+Q*QEs|w=(Yv~^Fdhd{t9mDARKZ~a13Yv=T7Fy4^_+tQqbuKjF6SG7mPgn$>~&(jAgdX$7|boh3(g0_V|3Bmx+^k zgB<@@JkY!kJM7~Dz63ponh*0I!~@%<=I?FCtJw4XpV1;dsOGNM!a(C;q$q~5pSHyd z9x#1J(&k%}EdjEC#i9USO`W57oL&(K2SI11-W0oPrt<%+A6x%%V%f|{bL}OT9no`j z511ETnd8P{-5@dUtVZl;`>F`xKA+KjkQw_y;Hha7hT~CBm?aF{i1Z>P^&aq*~RpPc^Tiw;&V3f zpFrcX2>OW)&`=0^g%%cg7;bXgHq`^0KVHm-2hW|V9=y@qK%pGGW%fXvSp8k<8 zv3XxI;frXtXaplNw~AqrVpAJZ1=H4&(I&uN(0UFN7MqgMOrmBwaAJ>~Xqvs7N67fi zr;{PtsLz}!3h8k3p-?6h;$z|TjOOEfQS(|F7x)o_FA-J9PC(Zpp&x(YD;aS}mjP|czSmvd|y@%U7Slfd2d|RvE^0{qusN?LumwGy8oVIde&8#o0 zqGJ2}thJ|2tQqa-nNygv;jC@tdk?jpH8i+k4it;lJFEq+)3D-u$tQ~eqVS|}ZYo2S zIL0NBj8kNT4X7NofF2@yW4!2P#jsSA?Ep3q{~`%};#`|Uw!!Q39?54n?(&EZQDSF= zond%@&ca?_k7zRYLk zC@CVlkKcryK`;l{+*yyv57|-pq$qkaC|r2+^*3Jf#rv42(|H%R9^NCx;^22I`Su2W zCr;donK*3$EOUZxtr6mKK&bO4?y>}eHW?P+HtQl;Gbgzj;Iw~y@uL~CgJ(Sfw>#i@ zh$~p>YV(h3FnDhU6{v1q!qHDu3u^^hG_!AVksoI8>Vy+iIN)9t%|-FM*DSaLVcl(2 z7=JYjX0=sAU`g_6Q(VhG2Z+xAHmB2h8TtvbCMa+os>hNJ*wjKm6XtnVDA2a&sRF4w ztwN1}0{g#UbeXibS=%PRVX7wfVIwZ{yPJpnhanw+z1Nxcbt~uR{;xx~?ThH#zYu%6 zn8Wsz1N*2}eHG4ml2esMSu`t7<9GW#&8tXEvB7_L!s9pYR6WKk9{AuvA>;L*N;V{` zwASOVLZH9EDq;K6cVzC5IK|uSc5&irku#TuT@<&;a7Lu#NmT{FPhAgx4*3@w99oXWiN6 zf^47Io#j%Ytu(K5ZlP2h9T8m)8~?n+%hW)4;hyHH$nj(vt~}GL)ur8iecLwKTn|mtME2#{}n2z8AD0AV`(UGThHt zHIHpf_8^4ia1aPUDu;V~FkFS}(+Df$1eLP5uDQgmF~!ZlWG1=hd)aBV z#T=*CY-9K=Ts)KUB{5Oj0w2XCbm2@?@>dmibHVX`!_D{di;dga7F-f{Fmx7eTO~>l zFnKHd!#1-ma5db9BXJ;vk=*z!qgHc}v|%iaJvXOJ|7aczu9_WLD7E{DTkn ze;-$oJRkKxLwgkwjUQ$=S$zm!!LN@9ijl0&;&gQKLp?rj?f=FZ2qzRH{ns>r|=J+ zrx(_;|J5@|crFTW@!5_ZVes*RO`+3x=AS%g=QEwp;4!Va+s~h!(oxd67Awi0q6kHX zNx(td>r;%{FoOXC>NKmOJf(B%WUx+Hh#gnM;1njQf1Ruu#5$ltwsdjm+{xItE`WtM zJvcU)9_m?o`qG}Br9F3UIv@7qbak|vn%-;G_1?MhEw;P!{1iH(cexi9jE?~jfXu7SN4aat9MqD(R{p|bJ~lE`pvVa&yoMozp}r7<(8Fw zeJhQRUJqGIx!KO@-!?m`?atp*=7G@vBs+AkUC|vlaZ9v?J=a5nL}}ivh5w>gXaCth z9`?vyf1-W&w9>rzU?`v5efh8ZSDr~XK=ds@gscRU3A^VZvs;RN!A#p)eC5aa@4@>= zf!{08=B~#&usAGBP?jePV6940$=o4iT?v;=%NkTC@IkL<6%ne-6qya_n599?@9P8< zb{7yiJW#&?2?`#&8XLz68KgJ;uvrhztJpjg>BPZL+3ql(h;(I<>x#s3`DpV{G@py{ zIy?&=_iBC*8-PFENd=~#ct zPxE(}__iCfkXJYsQ8;TFImAPdaRYt#-~L)$lBKgO$3f>#MAPV$j%I znHU(Ds5m=F`L&uN{tj{O`Tug>T(Ol*tFAk1O^u7yH9L{Cbu3u5pu>#laUj>U>@xw_ zHb=>(Mcm!rZCaAw=sXBLZ|dnnX-@iN*l}T%2JcMFA;dL0;|Z#Haz`bHBjSO~I-Gz| zt(8k$IB&}t(}sqoow4QTlbQ3*Sh2LXudjFMimyy&*2zA&(Ag!AH|lf2Nmy|?+NOuf z5Nj8STn)DeV@}O$^N-+YSgHck>`NA6QddsQoiwz0k2xm|ZQjGs;Mo^+!<_AON)D}4 zbINe)353eCJR)Pxaxf{ov|P+5`KEQ{u{1b`CzD4@Kr`Fjl{5X)o`B@l2l;{g;pwD} zmGCQlyKuR=XO(Cv>Dy1(Rfzo@G8h(ML{n2z2f-{^b%2FhooxAFCZ)*+BrU>K-qN2? z!KBYqV_HW$lI(T-K31JXJ0gfJy~j8LUl|qt`{QQHo3^~7XFJfO5V#i~K z!QZ#cys`=>C;B`~j9-~01`7t78*@$?3f2ww-0N$aO$_pL!(dBs$CEA|M8yHR57L8P z|1u=4dwKnzM+d%zE&v6mk;3Hq+Q^z{p zudmLUT=B`(5^cvr5UV(R0akVKaHczDH0~pY#xU8M`;11aJ40O1eyYsaC2T>aoK<8Q z$!-H7FF zfw&hYu>BJg&HdPDfDWyVBhxpC1gk3LAk2V( z!XRUEs4#1iqdRcXWTmOiBK;qP*R;72XHo@S&R0p#M0+%*TANI6tBmhqF}?h=d7P1f z!&%EiJk}F?Hr5@-CK6rDlB-c5Ubb;y3E6Pt6qFZ4o921kbfEZ^lqe}4?;_fmWlqjw z#iMi>zZ6By^EQrVEJ?BP3p4-u?6h2@TN9&%Ae<=jAxILArK9F#>}touQUc6K&IMBAyEkJ^riBM>M0!wR4Us z_ov|{Xv+MMyG$MalstHX#4CqI*x*H>Yh0Ys)qLJec%u0mJ;A{p$B`r#iqFW;V3*Pf z*U@YgEcAa`rk_zq$b zK)&wbSiGh>!aR&(jN!PU6ffuNVQUFl%#^slDbTJ*(Tx2{a~!8{D*TAzCqD|uDWc04 z@HuUZMUneLE{AuQ*KV^r2bY!~f{Hz?s{CLnW{lGa>`1I+WT-dWPqA^>7YIHD!sJrj zPdH(Lbota^si-;~(uEiQPV+wx5!C;@=5Of{j_`*0j$P&sp?~s**4{r*S9*QC?g%!Y z|HBt)Zo=av{C>Vd@gL-kQmlz5EyXyVx_Qv6<81|sGk)cmnPG?xl=dH-Tx)-8$x$6G zN$`XvLyI6BtW>3P%dia9#|heD+9pV!rkoAq>=3LoOA=%cJx2;*in5P1Kf=JTo&koE zy+-DUqqm1LGsRPye}ub{@e8*3f>7v!kSJtAhp7*unK#|^`KO6Zy)PX$mQWY=h}~Gk zK8l(zO$0;u3tD*M*poParqA4`9)@3H2PBw0?KLJH6mqo6v3ZvC3M2*MH9%xxtN_id zR4d{$V+U`EmnC-ey0L7`e)~Z&bMz0Q>bT|LST5S!^`S&NA3J#W!O?6~zU`J+n+@Fl zb))R@(Sv58n7D0f{+{KB&2QTcFPHaY4gIsPOX5KgK3>plz(Ijbpk(?gW0y5CRu$Sr zj!yu`y?$zmnra@6pg_j+V`-oP45EbR@TQP3&`<$mL3+4y-c-R^xC{<5;s=jDM;J&f zQ0!NmDb?>+`Oj5<^F21Z<|+o-Qj+?J2wvRdc6*|QK-Lv$_ey?OB!Kfz(y_?h@347Y z%n=Oq&#Sh3UA+Nv_X_%CyVs$4qE6W+ifvLfR_Y3S-FAm9$PdG9tk1-HPXZq)bU$_t z#hbY36g%De4rd_X5BYGGd9qk=x}Edocqm_LF9#G? zpe>McNvb#K#9d{VLv4@gVNYE1V!s9~7|>xK`-}Kt{zKTOy1|Lj?f{%u!1^&YNmEb@ zYM37=>uHDB7^{L(NLi9Tbh5jXQ68SmG@*oL0OmNYvE^Tc!z)hk7-88w1hjA#tXoO! zwTBX-T@Q<$$>z>vnMVU6Plx$M&7C-@lQFxEf5av+`CX*`H8#_67waTRoWY%ZhKL3a zkUz*@ur9r9DNYB0LT9dx^B-_~F}&QyorRz=JBi~EI+E~(z!zUf|9eppUys&+ z>6~XS0a_9!Gf3KMldzkDIk6AWTafnw#aK-wt?uWusk@)v+g?W#B9b<(a^ zXa6E!e#f*chP%6mub8$Y?_1Qb=x5W&FQ0TTarC5nm^UL`EGF_Q>}jSG^D8F(ouL1L zij)!N|J*@DnEvaIUPek|(r0IhNyS7n5;6#vk`-?Z2n=Y?Dv&T^nZ2P6r>0^ROc#(Y z`VuBH4FvFqrB73_#6|K_Hi^0X^A#>S8^LAcI4F@a6K)?$_2xvKGW?w81Um*>aWE0Y zh9TqjRyO$bUb=ifMYjf}aH5|LpKpV^GtL6@=ki^elf{|jit8bd0~=3VF25xy-=<*)AQ=?yOD6?H^v9qUba4Df5w94y5$6Uw;7H{1 z_m@-tc)%45`Bks%_JN0qPTJTed7LiT*ES39`{z`Gg-l7Hr5*w+Fj%VAp;99Ok)|By z1VGBhq|uQZa7wDxQ#cA4_={$jAY3vBFxLYn-#qt`Huuxl0#&zY3>Dvmv$z%ZXl&v6 zn^Sc$t&~l->0ZC2>H*+KpE4AQGheDbr#sctuRlxG#J!$*`dhHr~a$z*L-ub9#u=k*Qun!H}T+6@gRJ4(x4EtppAl+ zlhsITPbOy*^2nhS>O4DUOao4+OF(*5+p*A|GSJBnK_4N zhD(ksec5c*llN@E=GiO8O9fuY4f7dN^C=&EWm#M5j*D&m6{qVXv2M<6h2+jqGTE6- zej=1i;UEGeR1$4sy=Gioo>_p3Ln{=EigydnLw1+)bJ*@#r92-F=l#absUFVvOZ7pg zqdUQN<-6Il>F!LXJAGo@TIa;4bYchHV#uB6KvO|`U`u73ol>rk;$DCX9Oj8xKy3P` z{G$X7@Q1XGPg_k-$%4lR^k6JQQWXsa&bEjgqCo{A^V1KmbNU4k}Vd)p_e#Kg?-s( zw~0>oDP1+N3a7s$8P9aR7Ta!4GXSUj1|`;JSc$54XjQj(8iq=AVtX8BWt{ z@`Ds#_=6wdC;%|l$KDILI|Y`vKG;=(SHmf2#PH_O3y-lp_Wa0sJ7(8h*Fc|;Zb^3z z6pBhx4VuC(tnMh9Lhjv5S$ON!%d?9dt8d&L6Hn!l)89EavgkeAVr;c*{v`{=xfjg~ zv{F~)v_Y|d^?=?=S%xh;u*z%Ow23*E9$4;`W^J1xvEj4l@xFO)oByQ+mn`CQFPi_Q z`Ijyf7Z0o+_+sU>D!NxFyi(qimTu-)4E_UpQGZZJ(#8 zt}j~kU!oq-R%GFy!{QgftMtLDa3=PU96%*p;;a*P!JJr}KAjn5;&LoJ5>~AJJ>(rj zJboFCs1N-!VF8Q_IUEviLaHp2%RysWwInQnt;IPAIJDi`?bg~_V_9anaOtDdh6j4q zc|%-Ol<94SK%&2T-R;-b`jc8AlkZeiDdgQaP#vE3Xm>=9=PRAlM(137N@jXjB+@l~Y@C!Rf<;UGuhRt zq%JDhv&nIazFYG66;;zz1^PfY<8o#C>kHrAzxv8W#>PnJ^wA-@`w%6~SodIe%#6%+ zi0F1PW$Fk=0JCpdM_9+Qn}j-SP$KeL;=!{wtQoA;2G_2CX8qd1Y89DXYnCkP?CR=V zwB&P37It=bcP?Bq{!SZ=hc@wgAe<-+`blc{jMa0^2D4|ga#D}a(HK8i_e0TU6aOIc zv(YKXA>ddxgyTHKKV5StX%OCo!cXcB{-K)VB((uFb;K{e!k>bSB``XssGOAvWC3+` zTC}8#0~r9a>VbyNluNB0wzRv8pwjx0=?v@(L@x5kqhrGW!~dtRtNU#utKvOl&$!Mw z&ZnI=b`qztohGf5INdI^+w?2lWZNz6_G4RE1Y&HD?VF5eobgN=n?8Vq#KVFRZ}6}@ zAtZ!&0Er^RpTNT+EuRAQrEiPGhYN3xUHnM6N6e&hOFG&XrEm+u=?qS>!ZM3vOos-8dDkC~m~!t|Ld zXQodbj~pIJp3E1QlX@RTMvp99UN|xu8P@Z;r5ulsgR*zApP1Lnc{La9+4EW;2Ug1E zq#4`x!J7vg=Hz8UERjUi-4C8EbDupClZ)KpS~vYhpVEKfvhB@p>N)*A3>yCNiRZRRAfI80^557FY&e;15ng z@mhtFniOsMIAGsw5rdxdr2INJ6-OJx=Wy*k8NV@Ky8rrwIy9KwRmXHq{ckE8Nl#`j zT|AqjY-$+h9H#Hg?|nE-$>D|M`)WF&Mc*G^n#&JjB>~ps=O1UzDL;U@t@u#v=!Gj6 zkM8|td?un~uibsKn9qEmYI<7zSL##eS0=~P(IcajN}VXp4d$Z9|1*4YU`R_oQPo6R zeF9q)BLjMVbZkC-;t%5!JiY^?c&{FxcX1w?`z`PZ%^n80p*a|gZZKq)`Yqf}@@oyZ zun}~z&m+-Ck%Bj7ekJ0m(7^VZ?2+Z>)X0rYd3JPkww&2}m{~5Sa4JZKzP9%;I~OTt z=xxj+6*F4?LjD;BY&O4$u=|M3dL;4_CnCou3V6c<-*U+8ej*aMSj-%g z5%YELCx!Ec%zn}tI4%~m)117#(wEtQM}BqN)B@; ztp68FajoS1@_AyIhg^hO6DsT20bz%hHzwMa$0jH?jb;*NR%KVug^QvsaQDs-7PSDO z+yF1qV;Y-MBBMu@*$L%4$nMyP7Rjcy0#1fdqq}A}d!ksX65ahJ5ApuW^C#Hy{r&!7 z%r0z?PEPQ_ANIe|ha`3rc%mx5SC5U|kH(Jiw8^|evpj8*k1NqzV+Bol7e?#WW$c(Y z!Q9NZRfQ)=RAuiiY-K=+3@JYi41lHC;1f1|5!WT0Yx?2uFu!mDEkF#q5`lK?GfflL z?BG)`FF+e;9b@X77**r+wE|kf*%$spaF2w3vXunPcf3u@`$4}K!?L#4C(VWrMTS>a zdi%eBuHX~67+P6TjNs1Kr&wM1U*0Xq?T~-srRt&n-AZx@D%aoZAF|Kwf0TDtcK>|t z(aO)|ckkU0c=R;J?_v{Xfx|0^Wmm&$ds2CagY zlOY^|e<6gUfR{p81^h|~Yk=26xDW3#w?dd>d!slN!Pr;7kbj9lA&55Y`VB>FcYmX?SKWSLx!7-h zI2}-z1C>lY=gGp?flpgL+kg)bq8D($IEQLOfp-z#{e14@FUb6(E5I_b{K$?ngb&_! zpgak!Xi`Zd*!satWFMhxg}ODbF%3ecWSB+>-4UgsjeUfU(m1A*aA**E*eS|kH|;TO zX2lM2f^ADW4$HXn82+5361vhwTB0&7!=TDbbedj9uls2_Luaw|@Ept?@Qn0DxpQ~MGb z&;_kh4N9bSYEY8|ZO|rJ)FPW4YSR|E)FF?2+NKAzL)}9$*RdO0;-&C@D!ea;_i|!Y zc-=du1%Y$iM5k%mZP67Q!mu@?RK_Q6Zkx8Z>eS3+4QQTO!nFmj0n;`rmRYL%cGZKR z>owPCyk^)n%XH&rO?a8ltWQ7sA7)Ip=RZP-=w zY1#uutyZ$l2m2W~T6J7h#!}00H#;R)G@4$i;&`6Z8ezokGh^kWUvZq$4y(h#23X*&Lfh}BTIw&5J!l9&bx z&Tw2G7vKZ#3L9+bHASpzKJYE!k93;;hTm%fo&OCV+0~g-8^RU9(<_LuWk~-aiPkkM z21l|Xw#1-?Vy_vZWrQBdnmFi8G|Wy@)PRJj5}Ur$1Ld2Bs2d3lS!I zO>h^19Dhsn2aYgIduwyRgPj^lTH2gTqUJHj3T>85Boc(x^KkVwxEeb4+Np3#V* zP=w#}lN(4Cj~|$J#k9-mYSY;9kySLcPS@OILLi+ZDAOIlJ%6=nRyWsO$8V=BVWKD; zlq9myxGp;04P*NVdu@R(%S68A6ZqaWD#LX!!?3$(!I3W+GI0mh0HRzs5pn->giNkOah0r zE<^zmC!e7Z)UN3{zSffkpmE5Cske~Kj$p^K7DShX5DU&u9Z`Z($RhYDnuZgDfUuy) zKqutJkC`qgY(Zp#{3BCnB6>($NJ(vnk_rMWu#*c2VkB%-4#epC{m2{hEMU6M7?Rda zBXV=~_5g5tLL$n-OKuu%#b|Mq1?38&_kY>}i1j#Sv{#go8#Y;7vtRwtQL( IoU#Y{A3c~{t^fc4 diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts index 5b6eb68c3ae..bf45989af28 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/components/maps.ts @@ -1,17 +1,32 @@ -import PageContainer from '../../../page-container'; -import PageBodyContainer from '../../../page-body-container'; -import PageHeaderContainer from '../../../page-header-container'; -import PageFooterContainer from '../../../page-footer-container'; -import ListView from '../../../list-view'; + const componentMap: Record = {}; const componentPropsConverter: Record = {}; const componentPropertyConfigConverter: Record = {}; -PageContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); -PageBodyContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); -PageHeaderContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); -PageFooterContainer.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); -ListView.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); -export { componentMap, componentPropsConverter, componentPropertyConfigConverter }; +let hasLoaded = false; +/** + * 加载设计时组件 + */ +function loadDesignerRegister() { + if (!hasLoaded) { + hasLoaded = true; + // FAvatar.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter); + + } +} +/** + * 加载设计时组件 + */ +function loadDesignerRegisterByComponents(components:any[]) { + if (!hasLoaded) { + hasLoaded = true; + components.forEach(component => { + component.registerDesigner(componentMap, componentPropsConverter, componentPropertyConfigConverter) + }) + + } +} + +export { componentMap, componentPropsConverter, componentPropertyConfigConverter, loadDesignerRegister, loadDesignerRegisterByComponents }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.component.tsx deleted file mode 100644 index 9075044506c..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.component.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { SetupContext, defineComponent, ref, watch } from 'vue'; -import { ToolboxPropsType, toolboxProps } from '../composition/props/toolbox.props'; -import toolboxItems from './toolbox.json'; -import { ToolboxCategory, ToolboxItem } from '../types'; - -import '../composition/class/toolbox.css'; -import './iconfont.css'; - -export default defineComponent({ - name: 'FDesignerToolbox', - props: toolboxProps, - emits: [], - setup(props: ToolboxPropsType, context: SetupContext) { - const controlCategoryList = ref(toolboxItems); - const dragularCompostion = ref(props.dragula); - - function onClickCardHeader(payload: MouseEvent, category: any) { - category.isHide = !category.isHide; - } - - function getCardHeaderIconClass(category: any) { - const classObject = { - 'f-icon': true, - 'f-icon-arrow-60-down': !category.isHide, - 'f-icon-arrow-e': category.isHide - } as Record; - return classObject; - } - - function renderCategoryCardHeader(category: ToolboxCategory) { - return ( -
onClickCardHeader(payload, category)}> -
-
-
-
- -
-
- {category.name} -
-
-
-
-
- ); - } - - function getControlTileClass(toolboxItem: ToolboxItem) { - const classObject = { - 'd-none': toolboxItem.dependentParent || toolboxItem.hideInControlBox, - controlPanel: true, - 'drag-copy': true, - 'no-drag': toolboxItem.disable, - 'updating': toolboxItem.updating - } as Record; - return classObject; - } - - function getToolboxItemClass(toolboxItem: ToolboxItem) { - const classObject = { - farrisControlIcon: true, - 'fd-i-Family': true - } as Record; - const toolboxItemTypicalClassName = `fd_pc-${toolboxItem.icon || toolboxItem.type}`; - classObject[toolboxItemTypicalClassName] = true; - return classObject; - } - - function renderControlTile(toolboxItem: ToolboxItem, category: ToolboxCategory) { - return ( - - ); - } - - function renderCategoryCardBody(category: ToolboxCategory) { - return ( -
- {category.items.map((toolboxItem: any) => renderControlTile(toolboxItem, category))} -
- ); - } - - function renderCategoryCard(category: ToolboxCategory) { - return ( - !category.hideInControlBox && ( -
- {renderCategoryCardHeader(category)} - {renderCategoryCardBody(category)} -
- ) - ); - } - - watch( - () => props.dragula, - (newValue: any) => { - dragularCompostion.value = newValue; - dragularCompostion.value?.attachToolbox(); - } - ); - - return () => { - return ( -
-
- {controlCategoryList.value.map((category: any) => { - return renderCategoryCard(category); - })} -
-
- ); - }; - } -}); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.json b/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.json deleted file mode 100644 index c2de0dc4e8b..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/components/toolbox.json +++ /dev/null @@ -1,34 +0,0 @@ -[ - { - "type": "dataCollection", - "name": "数据集合类控件", - "items": [ - { - "id": "ListView", - "type": "list-view", - "name": "列表", - "category": "dataCollection" - } - ] - }, - { - "type": "container", - "name": "容器类控件", - "items": [ - { - "id": "PageHeaderContainer", - "type": "page-header-container", - "name": "页头容器", - "category": "container", - "icon": "header" - }, - { - "id": "PageFooterContainer", - "type": "page-footer-container", - "name": "页尾容器", - "category": "container", - "icon": "modal-footer" - } - ] - } -] \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/control.css b/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/control.css index 57960b5b629..9044cd61f76 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/control.css +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/control.css @@ -1,539 +1,30 @@ -/*avatar*/ -.f-avatar.f-avatar-circle { - border-radius: 100%; - overflow: hidden; - width: 100px; - height: 100px; - margin: 0 auto; -} - -.f-avatar.f-avatar-circle .f-avatar-image { - display: inline-block; - width: 100%; - height: 100%; -} - -/*image 图像*/ -.ide-image img { - width: inherit; - height: 100px; - max-width: inherit; - max-height: inherit; -} - -/*数值控件*/ -.ide-numeric-box .input-group .btn-group-number { - height: 1.50003rem; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - flex-direction: column; - background-color: #fff; - border-left: 1px solid #d9d9d9; -} - -.ide-numeric-box .input-group .btn-group-number .btn-number-flag { - height: 50%; - display: -webkit-box; - display: flex; - box-shadow: none; - padding: 0 5px; - margin-left: 1px; - - overflow: hidden; - -webkit-transition: 0.1s linear; - transition: 0.1s linear; -} - -.ide-numeric-box .input-group .btn-group-number .btn-number-flag .number-arrow-chevron { - -webkit-box-flex: 1; - flex: 1; - line-height: 1; -} - -.ide-numeric-box .input-group .btn-group-number .btn-number-flag:hover { - height: 60% !important; -} - -.ide-numeric-box .input-group .btn-group-number .btn-number-flag:nth-child(2) { - border-top: 1px solid #d9d9d9; -} - -.ide-numeric-box input::-webkit-inner-spin-button, -.ide-numeric-box input::-webkit-outer-spin-button { - -webkit-appearance: none !important; - margin: 0; -} - -.ide-numeric-box .input-group .btn-group-number .number-arrow-chevron { - height: unset; -} - -/*富文本*/ -.ide-rich-text-box .f-form-control-textarea { - padding: 0; - border: 0; - max-width: 100%; - width: 100%; - height: auto; -} - -/*数值区间*/ -.ide-number-range .number-range { - position: relative; -} - -.ide-number-range .number-range .input-container { - display: flex; - padding: 0; - align-items: center; -} - -.ide-number-range .number-range .input-container .sub-input-group { - -webkit-box-flex: 1; - flex: 1; - position: relative; - display: -webkit-box; - display: flex; - -webkit-transition: 0.3s ease-out; - transition: 0.3s ease-out; -} - -.ide-number-range .number-range .input-container .sub-input-group .sub-input { - width: 100%; - border: none; - outline: 0; - background-color: rgba(0, 0, 0, 0); - min-width: 2px; - padding: 0.125rem 4px 0.125rem 0.5rem; -} - -.ide-number-range .number-range .input-container .spliter { - width: 15px; - text-align: center; -} - -.f-table-has-form .ide-number-range { - height: 100%; -} - -/** 智能输入框 */ -.f-cmp-inputgroup.ide-input-group .f-state-disabled .input-group-append { - display: flex; -} - -/*external-container 引入外部组件的容器*/ -.ide-external-container, -.ide-cmp-route-container { - min-height: 100px; - background: #fafafa; - height: 100%; - width: 100%; - display: inline-block; -} - -.ide-external-container::before, -.ide-cmp-route-container::before { - content: "\e136"; - width: 2em; - height: 2em; - -webkit-font-smoothing: antialiased; - font-size: 2rem; - font-weight: 400; - line-height: 1; - display: inline-block; - color: #ccc; - position: absolute; - left: 50%; - top: 50%; - margin-left: -1rem; - margin-top: -1rem; -} - -.ide-external-container::before { - content: "\e136"; - font-family: FarrisExtend; -} - -.ide-cmp-route-container::before { - content: "\eb79"; - font-family: FarrisIcons; -} - -.farris-component-ModalContainer .ide-external-container { - min-height: 70px; -} - -/* 复写 侧边栏 父级样式 */ -.farris-component-Sidebar { - position: initial !important; - min-height: auto; - margin-bottom: 0; -} - -.farris-component-Sidebar.farris-nested { - padding: 0 !important; - border: none !important; -} - -.f-sidebar-pos-right.f-sidebar-show .f-sidebar-main, -.f-sidebar-pos-left.f-sidebar-show .f-sidebar-main { - transform: None !important; -} - -/*viewChange*/ -.f-viewchange-view-none { - display: none !important; -} - -/*Section */ -.ide-cmp-section .f-section-header .f-section-header--btn-placeholder { - position: absolute; - display: -webkit-inline-box; - display: inline-flex; - top: -30px; - left: 0; - opacity: 0; - overflow: hidden; - z-index: -90; -} - -.ide-cmp-section .f-section-content .toolbar-btn-inline-flex, -.ide-cmp-section .f-section-header .toolbar-btn-inline-flex { - display: -webkit-inline-box; - display: inline-flex; - overflow: hidden; -} - -.ide-cmp-section .f-section-header--toolbar { - -webkit-box-flex: 1; - flex: 1; - -webkit-box-align: center; - align-items: center; - width: 30%; - display: -webkit-box; - display: flex; - -webkit-box-pack: end; - justify-content: flex-end; - margin-left: 0.875rem; -} - -.ide-cmp-section .f-section-content--toolbar { - display: -webkit-box; - display: flex; - -webkit-box-align: center; - align-items: center; - overflow: auto; -} - -.ide-cmp-modal-footer .f-toolbar, -.ide-cmp-header .f-toolbar, -.ide-cmp-section .f-section-header .f-toolbar { - justify-content: normal; -} - -.ide-cmp-section.f-section-accordion.f-state-collapse>.f-section-content { - display: none; -} - -/* 小分组 fieldSet */ -.ide-cmp-fieldSet .f-section-formgroup-inputs.drag-container { - display: flex; - flex-wrap: wrap; -} - -.ide-cmp-fieldSet.f-section-formgroup.f-state-collapse .f-section-formgroup-inputs { - display: none; -} - -/* 若小分组没有间距,拖拽时会有控件位置晃动的情况 */ -.farris-component-Form>.drag-container>.farris-component-FieldSet { - margin-top: 10px; - margin-bottom: 10px; -} - -/** 列表 */ -.ide-dataGrid .header-cell { - height: 2.1875rem; - overflow: hidden; - padding: 0.4375rem 0; - white-space: nowrap; - width: 120px; - flex-shrink: 0; - background-color: #F4F5F9; -} - -.ide-dataGrid .header-cell:hover { - border-right: 2px solid #388FFF; - background: #EDF5FF; -} - -.ide-dataGrid .header-cell .caption { - border-right: 1px solid #E6E9F0 !important; - padding: 0 0.75rem; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.farris-component-DataGrid .cardViewPanel .farris-component-Component { - flex-grow: 1 !important; - flex-shrink: 1 !important; - flex-basis: auto !important; -} - -.farris-component-DataGrid .cardViewPanel .farris-component-Component .f-page { - position: absolute !important; -} - -.farris-component-ModalFooter .ide-cmp-modal-footer.showtype-sidebar .fe-modal-footer-base { - display: flex; - align-items: center; - justify-content: flex-end; - flex-shrink: 0; - background: #fff; - padding: 0.875rem 1.5rem; - box-shadow: none; -} - /** 筛选方案 **/ .f-section-scheme { - background: #fff; - margin: 0.5625rem 0.5rem 0; -} - -/*Tag*/ -.ide-cmp-tag .k-icon.k-i-close { - font-size: 12px; -} - -.ide-cmp-tag .k-icon.k-i-close:hover { - cursor: pointer; -} - -.ide-cmp-tag .btn { - margin-left: 5px -} - -.ide-cmp-tag .farris-tag-disabled { - cursor: text; -} - -/*穿梭框*/ -.ide-cmp-multi-select { - min-height: 200px; -} - -.f-multi-select-list .search { - position: relative; -} - -.f-multi-select-list .search .form-control { - line-height: 1.875; - height: 1.875; - outline: none; -} - -/* .f-multi-select-list .f-table-norecords-content { - margin: -10.0625rem 0 0 -0.225rem; - } */ - -/*scroll-collapse-area 滚动収折组件,収折实现变动*/ -.ide-cmp-collapsible-area.f-state-expand .fe-collapsible-container { - height: auto; -} - -.ide-cmp-collapsible-area.f-state-collapse .fe-collapsible-container { - height: 0; -} - -.ide-cmp-collapsible-area .fe-collapsible-icon-container { - cursor: pointer; -} - -/* 动态区域相关 */ -.ide-cmp-dynamic-area.f-component-tabs .farris-tabs-title { - align-items: center; -} - -.ide-cmp-dynamic-area.f-component-tabs .addPanel span { - font-size: 18px; - text-align: center; - width: 1.875rem; - height: 1.875rem; - line-height: 1.875rem; - background-color: #fff; - color: #85888e; - border: 1px solid #85888e; -} - -.ide-cmp-dynamic-area .farris-nav-tabs .nav-item .st-drop-close { - opacity: 0; -} - -.ide-cmp-dynamic-area .farris-nav-tabs .nav-item:hover .st-drop-close { - opacity: .6; -} - -.ide-cmp-dynamic-area .ide-external-container.add-dynamic::before { - content: '\e11e'; -} - -/* table表格 */ -.ide-cmp-table.table .widget-panel { - position: absolute; - bottom: 0; - right: 0; - color: #fff; - background: #388FFF !important; - padding: 3px 1px 1px 4px; - z-index: 300; - display: none; -} - -.ide-cmp-table.table td { - position: relative; -} - -.ide-cmp-table.table td.dgComponentSelected .widget-panel { - display: block; -} - -/*查询*/ -.ide-cmp-spreadsheet, -.ide-cmp-charts { - display: flex; - align-items: center; - justify-content: center; -} - -.ide-cmp-spreadsheet img { - width: 100%; - height: 100%; - max-width: 178px; - max-height: 132px; + background: #fff; + margin: 0.5625rem 0.5rem 0; } -.ide-cmp-charts img { - width: 100%; - height: 100%; - max-width: 780px; - max-height: 271px; -} - -/** toolbar工具栏**/ -.f-toolbar.farris-component-ToolBar { - min-height: 20px; -} - -.toolbar-drag.sortable-toolbar-container .component-btn-group { - display: none !important; -} - -.toolbar-drag .sortable-mirror { - width: 0 !important; -} - -.toolbar-drag .sortable-mirror.sortable-chosen .btn.dropdown-toggle.dropdown-toggle-split { - display: none; -} - -.toolbar-drag .btn-primary.disabled+.dropdown-toggle, -.toolbar-drag .btn-secondary.disabled+.dropdown-toggle { - color: #878D99; - background: #EAECF3; - border-color: #DEE1EA; -} - - -.ide-header-toolbar-lg .toolbar-drag .btn:not(.component-settings-button):not(.dropdown-toggle) { - padding: 0.25rem 1.125rem; - font-size: .875rem; - line-height: 1.4286; - border-radius: 3px; -} - -.ide-header-toolbar-lg .toolbar-drag .btn.dropdown-toggle.dropdown-toggle-split { - padding-top: 0.25rem; - padding-bottom: 0.25rem; - font-size: .875rem; -} - -.toolbar-drag .cascadeToolbar .btn:not(.component-settings-button) { - padding-right: 30px; -} - -/** 标签页Tab **/ -.farris-component-Tab .farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .nav-item { - background-color: white; -} - -.farris-component-Tab .farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .nav-item.gu-mirror { - position: fixed !important; -} - -.farris-component-Tab .farris-tabs .farris-tabs-header .farris-tabs-title.scroll-tabs .farris-nav-tabs.gu-unselectable .component-btn-group { - display: none; -} - -.farris-component-Tab .farris-tabs .farris-tabs-header.farris-tabs-inContent.hasToolbar .farris-tabs-toolbar { - width: 100%; -} - -.farris-component-Tab .farris-tabs .farris-tabs-header.farris-tabs-inContent .farris-tabs-toolbar .farris-tabs-inline-flex { - display: flex; -} - -/** 为了方便拖拽,区块上下增加间距 */ -.f-page.f-page-card .f-struct-like-card>.drag-container, -.f-component-splitter-pane.f-page-content-main { - padding-top: 10px; - padding-bottom: 10px; +/** 标签页tabs **/ +.farris-component-tabs .farris-tabs-content.f-utils-fill-flex-column .farris-component-tab-page:has(.farris-tab-page-active) { + display: flex !important; + overflow: hidden; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + flex-direction: column !important; } /** 布局容器 ResponseLayout **/ .response-layout { - border: dotted 2px #e8e8e8; + border: dotted 2px #e8e8e8; } .response-layout .response-layout-item { - border-right: dotted 2px #e8e8e8; + border-right: dotted 2px #e8e8e8; } .response-layout .response-layout-item:not(:last-child) { - padding-right: 8px !important; + padding-right: 8px !important; } - -/** 子列表填充布局:若没有这个,struct-wrapper内部放任意容器的时候,无法出现滚动条 **/ -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child { - overflow: hidden; -} - -/** 子列表填充布局:设计器section的适配样式 **/ -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section-in-mainsubcard { - height: 100% -} - -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section-in-main { - height: 100% -} - -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section.f-section-fill>.f-section-content { - flex-basis: 0%; -} - -/** 子列表填充布局:标签页的滚动条要放到tab-body上,所以整个tab上设置overflow:hidden **/ -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-component-tabs .f-tabs-content-fill { - overflow: hidden; -} - -/** 子列表填充布局:标签页下直接放组件节点(附件组件、卡片组件)的场景要设置组件填充,否则组件无法显示 **/ -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-component-tabs .f-tabs-content-fill .farris-tabs-body>.farris-component-Component { - flex: 1; -} - -/** 子列表填充布局:目的是为了让标签页tab-body出现滚动条。因为设计时的section强制添加了f-utils-fill 样式,所以要覆盖掉他的overflow:hidden,否则无法出现滚动条 **/ -.f-page-child-fill .f-struct-wrapper.f-struct-wrapper-child .f-section .f-component-tabs .f-tabs-content-fill .farris-tabs-body .f-section.ide-cmp-section { - overflow: unset; -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css b/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css index 563e4af0e1c..d92b16e7338 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/designer-canvas.css @@ -1,376 +1,284 @@ -.formEditor { - width: 100%; - height: 100%; - overflow: hidden; +.form-group-in-canvas .f-cmp-inputgroup .f-state-readonly .input-group-append{ + display: flex !important; } - -.formEditor .mainContent { - overflow: auto; -} - -.formEditor .toolbar { - font-size: 13px; - background: #fff; - display: flex; - min-height: 40px; - align-items: center; -} - -.formEditor .toolbar .disable { - color: #9ca5ad; -} - -.formEditor .viewTypePanel { - padding: 2px; - background: #f0f3f9; - border-radius: 5px; - margin-right: 15px; - margin-top: 5px; - margin-bottom: 5px; - display: flex; - margin-left: 17px; - height: 28px; - min-width: 145px; - cursor: pointer; - color: #8da3ce; - align-self: center; -} - -.formEditor .viewTypePanel>div { - background: #f4f5f9; - display: flex; - text-align: center; - align-items: center; - padding: 0 8px; - border-radius: 4px; -} - -.formEditor .viewTypePanel>div.active { - color: #5b89fe; - background: #fff; - box-shadow: 0 0 4px 0 rgb(161 179 255 / 37%); -} - -.formEditor .viewTypePanel>div>div { - margin: 0 auto; - display: flex; -} - -.formEditor .viewTypePanel>div>div span { - width: 18px; - height: 15px; - margin-right: 4px; -} - -.formEditor .showTypePanel { - padding: 0px 20px; - height: 30px; - align-self: center; - font-size: 14px; - color: #000; - min-width: 210px; -} - -.formEditor .showTypePanel .showTypeItem { - padding: 0 10px; - cursor: pointer; -} - -.formEditor .showTypePanel .showTypeItem>div { - padding: 4px 4px 9px 4px; -} - -.formEditor .showTypePanel .showTypeItem>div.active { - border-bottom: 2px solid #2a87ff; - color: #5b89fe; -} - -.formEditor>>>.dropdown-menu.show { - z-index: 1000; -} - .component-btn-group { - flex-direction: row-reverse; - position: absolute; - z-index: 800; - background: #fff; - display: none; - top: -26px; - right: 0; + flex-direction: row-reverse; + position: absolute; + z-index: 800; + background: #fff; + display: none; + top: -26px; + right: 0; } -.component-btn-group>div { - position: fixed; +.component-btn-group > div { + position: fixed; } .farris-component { - border: dotted 2px transparent; + /* border: dotted 2px transparent; */ } .farris-component.farris-nested { - padding: 10px !important; - border: dotted 2px #e8e8e8; + padding: 10px !important; + border: dotted 2px #e8e8e8; } .farris-component.farris-nested.dgComponentFocused { - border: dotted 2px #388fff; + /* padding: 10px; */ + border: dotted 2px #388fff; } .farris-component.can-move { - padding: 2px; + padding: 2px; } -.farris-component.dgComponentSelected>.component-btn-group { - display: flex; +.farris-component.dgComponentSelected > .component-btn-group { + display: flex; } .component-btn-group .component-settings-button { - display: flex; - cursor: pointer; - float: right; - margin-left: 4px; - padding: 0; - font-size: 10px; - line-height: 1.2em; - border-radius: 2px 2px 0px 0px; - width: 24px !important; - height: 24px !important; - color: #fff !important; - background: #388fff !important; + display: flex; + cursor: pointer; + float: right; + margin-left: 4px; + padding: 0; + font-size: 10px; + line-height: 1.2em; + border-radius: 2px 2px 0px 0px; + width: 24px !important; + height: 24px !important; + color: #fff !important; + background: #388fff !important; } .component-btn-group .component-settings-button .f-icon { - font-size: 18px; - margin: 0 auto; - line-height: 20px; + font-size: 18px; + margin: 0 auto; + line-height: 20px; } .component-btn-group .component-settings-button .f-icon.f-icon-yxs_move { - cursor: move; + cursor: move; } -.farris-component-page-container .drag-container, -.farris-component-page-body-container .drag-container, .farris-component-content-container .drag-container { - display: inherit; - flex-direction: inherit; - flex-shrink: 1; - flex-grow: 1; - flex-basis: 0%; - flex-wrap: inherit; - justify-content: inherit; - align-items: inherit; - width: 100%; - overflow: inherit; - height: inherit; -} - -.farris-component-list-view>.drag-container { - height: 100%; + display: inherit; + flex-direction: inherit; + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0%; + flex-wrap: inherit; + justify-content: inherit; + align-items: inherit; + width: 100%; + overflow: inherit; + height: inherit; } /* gu-mirror被添加到镜像中 */ .gu-mirror { - position: fixed !important; - margin: 0 !important; - z-index: 9999 !important; - opacity: 0.8; - -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; - filter: alpha(opacity=80); + position: fixed !important; + margin: 0 !important; + z-index: 9999 !important; + opacity: 0.8; + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; + filter: alpha(opacity=80); } .gu-mirror.undroppable .component-settings-button .f-icon-yxs_move { - cursor: no-drop; + cursor: no-drop; +} + +.component-btn-group .component-settings-button .f-icon.f-icon-yxs_delete { + color: #fff !important; + background: #388fff !important; } .gu-hide { - display: none !important; + display: none !important; } /** 拖拽时镜像元素的父级元素 */ .gu-unselectable { - -webkit-user-select: none !important; - -moz-user-select: none !important; - -ms-user-select: none !important; - user-select: none !important; + -webkit-user-select: none !important; + -moz-user-select: none !important; + -ms-user-select: none !important; + user-select: none !important; } /* 当拖动源元素的镜像时,gu-transit被添加到源元素中。只是增加了透明度。 */ .gu-transit { - opacity: 0.2; - -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=20)'; - filter: alpha(opacity=20); + opacity: 0.2; + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=20)'; + filter: alpha(opacity=20); } /* 拖拽经过某区域时,为区域增加底色 */ .drag-over:not(.no-drop) { - background-color: #f3f8ff !important; + background-color: #f3f8ff !important; } /** 拖拽区域内的元素不显示按钮区域 */ -.gu-unselectable .farris-component.dgComponentSelected>.component-btn-group { - display: none; +.gu-unselectable .farris-component.dgComponentSelected > .component-btn-group { + display: none; } /** 拖拽区域内的镜像元素显示按钮区域 */ -.gu-unselectable .gu-mirror.farris-component.dgComponentSelected>.component-btn-group { - display: flex; +.gu-unselectable .gu-mirror.farris-component.dgComponentSelected > .component-btn-group { + display: flex; } /** 拖拽过程中的源元素不显示按钮区域 */ -.gu-transit.farris-component.dgComponentSelected>.component-btn-group { - display: none; +.gu-transit.farris-component.dgComponentSelected > .component-btn-group { + display: none; } /* 镜像元素为fixed定位 */ .gu-mirror.farris-component.dgComponentSelected { - position: fixed !important; + position: fixed !important; } /* 镜像元素的按钮区域定位 */ -.gu-mirror.farris-component.dgComponentSelected>.component-btn-group>div { - position: relative; - top: 0 !important; - left: 0 !important; +.gu-mirror.farris-component.dgComponentSelected > .component-btn-group > div { + position: relative; + top: 0 !important; + left: 0 !important; } /** 镜像元素的按钮区域设置宽度。是为了适配控件本身宽度比较小,但是操作按钮比较多时,按钮被换行的问题 */ -.gu-mirror.farris-component.dgComponentSelected>.component-btn-group { - width: max-content; +.gu-mirror.farris-component.dgComponentSelected > .component-btn-group { + width: max-content; } .dgComponentFocused { - border-top: 2px dotted #388fff !important; - border-left: 2px dotted #388fff !important; - border-right: 2px dotted #388fff !important; - border-bottom: 2px dotted #388fff !important; + border-top: 2px dotted #388fff !important; + border-left: 2px dotted #388fff !important; + border-right: 2px dotted #388fff !important; + border-bottom: 2px dotted #388fff !important; } .dgComponentSelected { - border-top: 2px solid #388fff !important; - border-left: 2px solid #388fff !important; - border-right: 2px solid #388fff !important; - border-bottom: 2px solid #388fff !important; + border-top: 2px solid #388fff !important; + border-left: 2px solid #388fff !important; + border-right: 2px solid #388fff !important; + border-bottom: 2px solid #388fff !important; } .editorDiv { - background-color: #dbe6f7; - overflow-x: auto; + background-color: #dbe6f7; + overflow-x: auto; } .editorPanel { - position: relative; - height: 100%; - min-width: 900px; -} - -.editorPanel.Mobile { - min-width: 414px; - width: 414px; - margin: 20px auto; - height: calc(100% - 40px); + position: relative; + height: 100%; + min-width: 900px; } /** 卡片区块 **/ .editorDiv .f-struct-like-card { - display: block; + display: block; } /** 解决farristab 开启内容填充后切换标签页导致内部列表不显示的问题**/ .editorDiv .farris-tabs.f-tabs-content-fill .f-struct-is-subgrid .f-grid-is-sub { - width: 100%; + width: 100%; } /** 解决在模态框中弹出右键菜单 菜单不显示的问题**/ .ide-framework .cdk-overlay-container { - z-index: 1100; + z-index: 1100; } - .editorDiv .f-struct-wrapper { - margin-bottom: 15px; + margin-bottom: 15px; } -.f-struct-wrapper+.f-struct-wrapper { - position: relative; - display: inherit; - margin-bottom: 15px; +.f-struct-wrapper + .f-struct-wrapper { + position: relative; + display: inherit; + margin-bottom: 15px; } .f-page-is-mainsubcard .f-page-main .f-struct-wrapper { - background: #fff; + background: #fff; } /** 解决带导航的列表和带导航的卡片模板中,不显示右侧区域的问题 */ .editorDiv .f-page-navigate .f-page { - position: absolute !important; + position: absolute !important; } /** 解决带导航的列表和带导航的卡片模板中,右侧区域滚动条位置问题 */ -.editorDiv .f-page-navigate .f-page.f-page-card .f-page-main>.drag-container { - display: block; - overflow: unset; +.editorDiv .f-page-navigate .f-page.f-page-card .f-page-main > .drag-container { + display: block; + overflow: unset; } /* 解决OA模板(带页头的导航类模板) 中,右侧滚动条位置问题 */ .editorDiv .f-page.f-page-navigate.f-page-is-listnav-with-header .f-page-main .f-page-content-main { - display: block; + display: block; } /** 解决在弹窗中使用smoothDnd时不显示镜像元素的问题 */ .smooth-dnd-ghost { - z-index: 1100 !important; + z-index: 1100 !important; } /** 解决零代码设计器中OA类卡片表单滚动条位置问题 */ .editorDiv .farris-oa-page.f-page-card .f-page-main { - display: block !important; - overflow: auto !important; + display: block !important; + overflow: auto !important; } /** 解决带筛选方案的列表表单中,选中表格组件后没有上边线的问题 */ .editorDiv .f-page-has-scheme .f-page-main.farris-component { - margin-top: 0; + margin-top: 0; } /** 解决表单设计器中顶层工具栏的下拉面板被属性面板(z-index:850)遮挡的问题 */ .dropdown-menu.show { - z-index: 860; + z-index: 860; } /** 解决拟物风下从从表区域的下拉箭头错位的问题 */ .f-struct-subsub-wrapper { - padding-top: 0 !important; + padding-top: 0 !important; } /** 新拖拽 */ .gu-mirror.undroppable { - cursor: no-drop; + cursor: no-drop; } .gu-insertion { - position: fixed; - z-index: 840 !important; - pointer-events: none !important; - background-color: #388fff; - height: 4px; - overflow: hidden; + position: fixed; + z-index: 840 !important; + pointer-events: none !important; + background-color: #388fff; + height: 4px; + overflow: hidden; } /* 在designer canvas中还原嵌套页面样式,解决desinger和canvas各自f-page样式冲突 */ .editorPanel .f-page::before { - display: initial !important; + display: initial !important; } .editorPanel .f-page .f-page-main { - margin-right: 0.5rem !important; - margin-left: 0.5rem !important; - margin-bottom: 0.5rem !important; + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + margin-bottom: 0.5rem !important; } .editorPanel .f-page.f-page-is-listnav .f-page-main { - margin-top: 0.5rem !important; + margin-top: 0.5rem !important; } .editorPanel .f-page .f-page-main .f-page-main { - margin: 0 !important; -} \ No newline at end of file + margin: 0 !important; +} + +.editorPanel .f-page.f-page-has-scheme .f-page-header{ + margin: 0 .5rem; +} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/toolbox.css b/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/toolbox.css deleted file mode 100644 index c4f451fdcf0..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/class/toolbox.css +++ /dev/null @@ -1,69 +0,0 @@ -.controlBox { - font-size: 13px !important; -} - -.controlBox .farris-panel .card-header { - padding: 10px 0px; - background-color: #fcfdff; -} - -.controlBox .farris-panel .card-header .col-form-label { - font-size: 13px; - margin-bottom: 0px; - color: #3f4764; - opacity: 0.65; -} - -.controlBox .farris-panel .card-header .col-form-label .f-icon { - font-size: 10.8px; - color: #3f4764; -} - -.controlBox .farris-panel .card-body { - display: flex; - flex-wrap: wrap; - background: #fcfdff !important; -} - -.controlPanel:nth-child(-n + 3) { - margin-top: 0 !important; -} - -.controlPanel .farrisControlIcon { - font-size: 27px; -} - -.controlPanel { - font-size: 13px; - cursor: grab; - display: flex; - background: #fff; - align-items: center; - width: 33.333%; - background-color: #fcfdff; - border: 1px solid #edf1f5; - height: 76px !important; - text-align: center; - margin: -1px 0 0 -1px !important; - color: #6080ad; - text-overflow: ellipsis; - word-break: keep-all; - user-select: none; -} - -.controlPanel.updating { - color: #707070; -} - -.controlPanel>div { - margin: auto; - overflow: hidden; -} - -.gu-mirror.undroppable.controlPanel { - cursor: no-drop; -} - -.controlBox .farris-panel .card-header .col-form-label .icon-panel .f-icon { - font-size: 16px; -} \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts index f8c28c316c8..11ada793acc 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/designer-canvas-changed.ts @@ -9,46 +9,96 @@ export const canvasChanged = ref(0); * @param containerEl 容器 */ function isElementInViewport(el: HTMLElement, containerEl: HTMLElement) { - const container = containerEl.getBoundingClientRect(); - const box = el.getBoundingClientRect(); - const top = box.top >= container.top; - const bottom = box.top <= container.bottom; - return (top && bottom); + const container = containerEl.getBoundingClientRect(); + const box = el.getBoundingClientRect(); + const top = box.top >= container.top; + const bottom = box.top <= container.bottom; + return (top && bottom); } -/** - * 定位画布中已选控件的操作按钮的位置 - * @param canvasElement 画布父容器 - */ -export function setPositionOfBtnGroup(canvasElement: HTMLElement) { - if (!canvasElement) { - return; - } - const selectDom = canvasElement.querySelector('.dgComponentSelected') as HTMLElement; - if (!selectDom) { - return; - } - - const selectDomRect = selectDom.getBoundingClientRect(); - if (selectDomRect.width === 0 && selectDomRect.height === 0) { - return; - } - const toolbar = selectDom.querySelector('.component-btn-group') as HTMLElement; - if (toolbar) { - - const isInView = isElementInViewport(selectDom, canvasElement); - if (!isInView) { - toolbar.style.display = 'none'; - return; - } - // 计算位置 +function setPositionForSelectedElement(selectElement: HTMLElement) { + const toolbar = selectElement.querySelector('.component-btn-group') as HTMLElement; + if (!toolbar) { + return; + } toolbar.style.display = ''; const toolbarRect = toolbar.getBoundingClientRect(); const divPanel = toolbar.querySelector('div') as HTMLElement; if (divPanel) { - const divPanelRect = divPanel.getBoundingClientRect(); - divPanel.style.top = toolbarRect.top + 'px'; - divPanel.style.left = toolbarRect.left - divPanelRect.width + 'px'; + const divPanelRect = divPanel.getBoundingClientRect(); + divPanel.style.top = toolbarRect.top + 'px'; + + // 若操作按钮的最左边比画布最左边还要靠左,那么操作按钮就以控件的最左边为界 + let left = toolbarRect.left - divPanelRect.width; + const editorDiv = document.querySelector('.editorDiv'); + if (editorDiv) { + const editorDivRect = editorDiv.getBoundingClientRect(); + if (left < editorDivRect.left) { + const elementRect = selectElement.getBoundingClientRect(); + ({ left } = elementRect); + } + } + divPanel.style.left = left + 'px'; + } +} + +/** + * 定位画布中已选控件的操作按钮的位置 + * @param canvasElement 画布父容器 + */ +export function setPositionOfButtonGroup(canvasElement: HTMLElement) { + if (!canvasElement) { + return; + } + let selectElement: HTMLElement; + if (canvasElement.className.includes('dgComponentSelected')) { + selectElement = canvasElement; + } else { + selectElement = canvasElement.querySelector('.dgComponentSelected') as HTMLElement; + } + if (!selectElement) { + return; + } + + const selectDomRect = selectElement.getBoundingClientRect(); + if (selectDomRect.width === 0 && selectDomRect.height === 0) { + return; + } + const toolbar = selectElement.querySelector('.component-btn-group') as HTMLElement; + if (toolbar) { + + const isInView = isElementInViewport(selectElement, canvasElement); + if (!isInView) { + toolbar.style.display = 'none'; + return; + } + // 计算位置 + setPositionForSelectedElement(selectElement); + } +} + + +/** + * 定位页面中选中控件的操作按钮位置。 + * 场景:控件内部点击收折或者切换显示内容后,需要重新计算页面中下方选中控件的按钮位置。 + * 例如点击section控件的收折图标后,需要重新计算section下方已选控件的操作按钮位置 + */ +export function setPositionOfSelectedComponentBtnGroup(canvasElement: HTMLElement) { + const selectElement = document.querySelector('.dgComponentSelected') as HTMLElement; + if (!selectElement) { + return; + } + const selectedElementRect = selectElement.getBoundingClientRect(); + const elementRect = canvasElement.getBoundingClientRect(); + + const toolbar = selectElement.querySelector('.component-btn-group') as HTMLElement; + if (toolbar) { + const toolbarRect = toolbar.getBoundingClientRect(); + const isBelow = elementRect.top < selectedElementRect.top; + + // 选中控件已显示并且在基准位置的下方 + if (toolbarRect.top !== 0 && isBelow) { + setPositionForSelectedElement(selectElement); + } } - } } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts index ebbc84f1f77..3e00a135b84 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/dg-control.ts @@ -1,215 +1,79 @@ export const DgControl = { - Button: { type: 'Button', name: '按钮', icon: 'Button' }, + 'button': { type: 'button', name: '按钮', icon: 'Button' }, - ButtonGroup: { type: 'ButtonGroup', name: '按钮组', icon: 'ButtonGroup' }, + 'response-toolbar': { type: 'response-toolbar', name: '工具栏', icon: 'ButtonGroup' }, - ToolBar: { type: 'ToolBar', name: '工具栏', icon: 'ButtonGroup' }, + 'response-toolbar-item': { type: 'response-toolbar-item', name: '按钮', icon: 'Button' }, - ToolBarItem: { type: 'ToolBarItem', name: '工具栏项', icon: 'Button' }, + 'content-container': { type: 'content-container', name: '容器', icon: 'ContentContainer' }, - ContentContainer: { type: 'ContentContainer', name: '容器', icon: 'ContentContainer' }, + 'input-group': { type: 'input-group', name: '文本', icon: 'TextBox' }, - DisplayField: { type: 'DisplayField', name: '标签', icon: 'DisplayField' }, + 'textarea': { type: 'textarea', name: '多行文本', icon: 'MultiTextBox' }, - TextBox: { type: 'TextBox', name: '文本', icon: 'TextBox' }, + 'lookup': { type: 'lookup', name: '帮助', icon: 'LookupEdit' }, - MultiTextBox: { type: 'MultiTextBox', name: '多行文本', icon: 'MultiTextBox' }, + 'number-spinner': { type: 'number-spinner', name: '数值', icon: 'NumericBox' }, - LookupEdit: { type: 'LookupEdit', name: '帮助', icon: 'LookupEdit' }, + 'date-picker': { type: 'date-picker', name: '日期', icon: 'DateBox' }, - NumericBox: { type: 'NumericBox', name: '数值', icon: 'NumericBox' }, + 'switch': { type: 'switch', name: '开关', icon: 'SwitchField' }, - DateBox: { type: 'DateBox', name: '日期', icon: 'DateBox' }, + 'radio-group': { type: 'radio-group', name: '单选组', icon: 'RadioGroup' }, - SwitchField: { type: 'SwitchField', name: '开关', icon: 'SwitchField' }, + 'check-box': { type: 'check-box', name: '复选框', icon: 'CheckBox' }, - RadioGroup: { type: 'RadioGroup', name: '单选组', icon: 'RadioGroup' }, + 'check-group': { type: 'check-group', name: '复选框组', icon: 'CheckGroup' }, - CheckBox: { type: 'CheckBox', name: '复选框', icon: 'CheckBox' }, + 'combo-list': { type: 'combo-list', name: '下拉列表', icon: 'EnumField' }, - CheckGroup: { type: 'CheckGroup', name: '复选框组', icon: 'CheckGroup' }, + 'response-form': { type: 'response-form', name: '卡片面板', icon: 'Form' }, - EnumField: { type: 'EnumField', name: '下拉列表', icon: 'EnumField' }, - /** 暂时没用 */ - FlexLayout: { type: 'FlexLayout', name: '弹性布局' }, - /** 暂时没用 */ - FlowLayout: { type: 'FlowLayout', name: '流布局' }, + 'response-layout': { type: 'response-layout', name: '布局容器', icon: 'ResponseLayout3' }, - ResponseLayout: { type: 'ResponseLayout', name: '布局容器', icon: 'ResponseLayout3' }, + 'response-layout-item': { type: 'response-layout-item', name: '布局', icon: 'ResponseLayout1' }, - ResponseLayoutItem: { type: 'ResponseLayoutItem', name: '布局', icon: 'ResponseLayout1' }, + 'tree-grid': { type: 'tree-grid', name: '树表格', icon: 'TreeGrid' }, - TreeGrid: { type: 'TreeGrid', name: '树表格', icon: 'TreeGrid' }, + 'tree-grid-column': { type: 'tree-grid-column', name: '树表格列' }, - TreeGridField: { type: 'TreeGridField', name: '树表格列' }, + 'data-grid': { type: 'data-grid', name: '表格', icon: 'DataGrid' }, - FieldSet: { type: 'FieldSet', name: '分组', icon: 'FieldSet' }, + 'data-grid-column': { type: 'data-grid-column', name: '表格列' }, - Form: { type: 'Form', name: '卡片面板', icon: 'Form' }, + 'module': { type: 'Module', name: '模块', icon: 'Module' }, - QueryForm: { type: 'QueryForm', name: '查询面板', icon: 'Form' }, + 'component': { type: 'component', name: '组件', icon: 'Component' }, - DataGrid: { type: 'DataGrid', name: '表格', icon: 'DataGrid' }, + 'tabs': { type: 'tabs', name: '标签页', icon: 'Tab' }, - GridField: { type: 'GridField', name: '表格列' }, + 'tab-page': { type: 'tab-page', name: '标签页项', dependentParentControl: 'Tab' }, - Panel: { type: 'Panel', name: '面板', icon: 'ContentContainer' }, + 'tab-toolbar-item': { type: 'tab-toolbar-item', name: '标签页工具栏按钮', icon: 'Button' }, - Module: { type: 'Module', name: '模块', icon: 'Module' }, + 'time-picker': { type: 'time-picker', name: '时间选择', icon: 'TimePicker' }, - Component: { type: 'Component', name: '组件', icon: 'Component' }, + 'section': { type: 'section', name: '分组面板', icon: 'Section' }, - ExternalContainer: { type: 'ExternalContainer', name: '外部容器', icon: 'ContentContainer' }, + 'section-toolbar': { type: 'section-toolbar', name: '分组面板工具栏' }, - Image: { type: 'Image', name: '图像', icon: 'Image' }, + 'section-toolbar-item': { type: 'section-toolbar-item', name: '分组面板按钮' }, - ImageUpload: { type: 'ImageUpload', name: '图片上传', icon: 'imageupload' }, + 'splitter': { type: 'splitter', name: '分栏面板', icon: 'Splitter' }, - HiddenContainer: { type: 'HiddenContainer', name: '隐藏区域', icon: 'ContentContainer' }, + 'splitter-pane': { type: 'splitter-pane', name: '分栏面板项', dependentParentControl: 'Splitter' }, - ModalContainer: { type: 'ModalContainer', name: '弹窗容器', icon: 'ContentContainer' }, + 'component-ref': { type: 'component-ref', name: '组件引用节点' }, - RouteContainer: { type: 'RouteContainer', name: '路由区域', icon: 'ContentContainer' }, + 'uploader': { type: 'uploader', name: '附件上传', icon: 'FileUpload' }, - Tab: { type: 'Tab', name: '标签页', icon: 'Tab' }, + 'page-header': { type: 'page-header', name: '页头', icon: 'Header' }, - TabPage: { type: 'TabPage', name: '标签页项', dependentParentControl: 'Tab' }, + 'page-footer': { type: 'page-footer', name: '页脚', icon: 'ModalFooter' }, - TabToolbarItem: { type: 'TabToolbarItem', name: '标签页工具栏按钮', icon: 'Button' }, + 'tab-toolbar': { type: 'tab-toolbar', name: '标签页工具栏', icon: 'TabToolbar' }, - Tag: { type: 'Tag', name: 'Tag', icon: 'Tag' }, + 'fieldset': { type: 'fieldset', name: '分组', icon: 'fieldset' }, - Sidebar: { type: 'Sidebar', name: '侧边栏', icon: 'Sidebar' }, - - HtmlTemplate: { type: 'HtmlTemplate', name: '模版容器', icon: 'HtmlTemplate' }, - - ListView: { type: 'ListView', name: '列表', icon: 'ListView' }, - - RichTextBox: { type: 'RichTextBox', name: '富文本', icon: 'RichTextBox' }, - - TimeSpinner: { type: 'TimeSpinner', name: '时间调节器', icon: 'TimePicker' }, - - TimePicker: { type: 'TimePicker', name: '时间选择', icon: 'TimePicker' }, - - Section: { type: 'Section', name: '分组面板', icon: 'Section' }, - - SectionToolbar: { type: 'SectionToolbar', name: '分组面板工具栏' }, - - SectionToolbarItem: { type: 'SectionToolbarItem', name: '分组面板按钮' }, - - QueryScheme: { type: 'QueryScheme', name: '筛选方案', icon: 'QueryScheme' }, - - FormHeader: { type: 'FormHeader', name: '翻页' }, - - Splitter: { type: 'Splitter', name: '分栏面板', icon: 'Splitter' }, - - SplitterPane: { type: 'SplitterPane', name: '分栏面板项', dependentParentControl: 'Splitter' }, - - WizardDetail: { type: 'WizardDetail', name: '向导详情页' }, - - WizardDetailContainer: { type: 'WizardDetailContainer', name: '向导详情容器' }, - - Wizard: { type: 'Wizard', name: '向导', icon: 'Wizard' }, - - MultiSelect: { type: 'MultiSelect', name: '数据分配', icon: 'MultiSelect' }, - - InputGroup: { type: 'InputGroup', name: '智能输入框', icon: 'InputGroup' }, - - Steps: { type: 'Steps', name: '步骤条', icon: 'Steps' }, - - Avatar: { type: 'Avatar', name: '头像', icon: 'Avatar' }, - - ListFilter: { type: 'ListFilter', name: '筛选条', icon: 'ListFilter' }, - - ListNav: { type: 'ListNav', name: '列表导航', icon: 'ListNav' }, - - NumberRange: { type: 'NumberRange', name: '数字区间选择', icon: 'NumericBox' }, - - Scrollspy: { type: 'Scrollspy', name: '滚动监听', icon: 'Scrollspy' }, - - LanguageTextBox: { type: 'LanguageTextBox', name: '多语言输入框', icon: 'LanguageTextBox' }, - - ComponentRef: { type: 'ComponentRef', name: '组件引用节点' }, - - FileUpload: { type: 'FileUpload', name: '附件上传', icon: 'FileUpload' }, - - FilePreview: { type: 'FilePreview', name: '附件预览', icon: 'FilePreview' }, - - ViewChange: { type: 'ViewChange', name: '多视图切换', icon: 'Button' }, - - MultiViewContainer: { type: 'MultiViewContainer', name: '多视图', icon: 'MultiViewContainer' }, - - MultiViewItem: { type: 'MultiViewItem', name: '多视图项', dependentParentControl: 'MultiViewContainer' }, - - Footer: { type: 'Footer', name: '页脚' }, - - DiscussionEditor: { type: 'DiscussionEditor', name: '评论编辑区', icon: 'DiscussionEditor' }, - - DiscussionList: { type: 'DiscussionList', name: '评论列表', icon: 'DiscussionList' }, - - NavTab: { type: 'NavTab', name: '标签类导航', icon: 'NavTab' }, - - Tags: { type: 'Tags', name: '标记组', icon: 'Tags' }, - - Portlet: { type: 'Portlet', name: '小部件', icon: 'dingzhi' }, - - Header: { type: 'Header', name: '页头', icon: 'Header' }, - - ModalFooter: { type: 'ModalFooter', name: '弹窗页脚', icon: 'ModalFooter' }, - - ScrollCollapsibleArea: { type: 'ScrollCollapsibleArea', name: '滚动收折区域', icon: 'ScrollCollapsibleArea' }, - - PersonnelSelector: { type: 'PersonnelSelector', name: '人员选择', icon: 'PersonnelSelector' }, - - Table: { type: 'Table', name: '表格', icon: 'DataGrid' }, - - LoopContainer: { type: 'LoopContainer', name: '循环容器', icon: 'ContentContainer' }, - - FileUploadPreview: { type: 'FileUploadPreview', name: '附件上传预览', icon: 'FileUpload' }, - - DynamicArea: { type: 'DynamicArea', name: '动态区域', icon: 'ContentContainer' }, - - DynamicAreaItem: { type: 'DynamicAreaItem', name: '动态区域项', icon: 'ContentContainer' }, - - TabToolbar: { type: 'TabToolbar', name: '标签页工具栏', icon: 'TabToolbar' }, - - HeaderToolBar: { type: 'HeaderToolBar', name: '头部组件工具栏', icon: 'HeaderToolBar' }, - - ModalFooterToolBar: { type: 'ModalFooterToolBar', name: '底部组件工具栏', icon: 'ModalFooterToolBar' }, - - HeaderToolBarItem: { type: 'HeaderToolBarItem', name: '头部组件工具栏按钮', icon: 'HeaderToolBarItem' }, - - ModalFooterToolBarItem: { type: 'ModalFooterToolBarItem', name: '底部组件工具栏按钮', icon: 'ModalFooterToolBarItem' }, - - OrganizationSelector: { type: 'OrganizationSelector', name: '组织选择', icon: 'OrganizationSelector' }, - - AdminOrganizationSelector: { type: 'AdminOrganizationSelector', name: '组织选择', icon: 'OrganizationSelector' }, - - EmployeeSelector: { type: 'EmployeeSelector', name: '人员选择', icon: 'PersonnelSelector' }, - - OaRelation: { type: 'OaRelation', name: '关联行政审批', icon: 'TextBox' }, - - CitySelector: { type: 'CitySelector', name: '城市选择', icon: 'CitySelector' }, - - ExtIntergration: { type: 'ExtIntergration', name: '外部服务集成', icon: 'ViewModel' }, - - AppointmentCalendar: { type: 'AppointmentCalendar', name: '预约日历', icon: 'DateBox' }, - - /** 查询类 start */ - Charts: { type: 'Charts', name: '图表', icon: 'Charts' }, - - QdpFramework: { type: 'QdpFramework', name: '查询结果工具栏', icon: 'QdpFramework' }, - - SpreadSheet: { type: 'SpreadSheet', name: '查询表格控件', icon: 'Charts' }, - - QdpConditionDialog: { type: 'QdpConditionDialog', name: '查询筛选对话框', icon: 'ContentContainer' }, - - QdpConditionDialogTab: { type: 'QdpConditionDialogTab', name: '查询筛选标签页', icon: 'Tab' }, - /** 查询类 end */ - - /** 审批类 start */ - ApprovalLogs: { type: 'ApprovalLogs', name: '审批记录', icon: 'ApprovalLogs' }, - - ApprovalComments: { type: 'ApprovalComments', name: '审批意见', icon: 'shenpiyijian' }, - /** 审批类 end */ + 'query-solution': { type: 'query-solution', name: '筛选方案', icon: 'QueryScheme'} }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/builder-element.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/builder-element.ts index e23d954b45d..b071db88587 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/builder-element.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/builder-element.ts @@ -1,12 +1,12 @@ /** * 设计器DOM元素结构 */ -export interface BuilderHTMLElement extends Element { - /** 记录各子元素对应的控件schema json的集合,用于container类dom节点 */ - childrenContents?: any[]; +export interface BuilderHTMLElement extends Element{ + /** 记录各子元素对应的控件schema json的集合,用于container类dom节点 */ + childrenContents?: any[]; - /** 记录element对应的component实例,用于单个component节点 */ - componentInstance?: any; + /** 记录element对应的component实例,用于单个component节点 */ + componentInstance?: any; - component?: any; + component?: any; }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/control-tree-node-entity.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/control-tree-node-entity.ts deleted file mode 100644 index eb852d2634e..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/control-tree-node-entity.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 控件树节点 - */ -export interface ControlTreeNode { - id?: string; - data: { - /** 节点标识 */ - id: string; - /** 节点名称 */ - name?: string; - /** 隶属组件节点标识 */ - componentId?: string; - }; - /** - * 在节点中保存的表单原始DOM对象(注意:在收折起来的控件树上rawElement并非原始DOM对象,所以针对这个属性的修改不会映射到DOM中。) - */ - rawElement?: any; - /** - * 子节点集合 - */ - children?: ControlTreeNode[]; - /** - * 节点类型,包括:组件、视图模型、控件集合、控件四种类型。 - */ - type?: string; - /** 是否展开 */ - expanded?: boolean; - /** 叶子节点图标 */ - icon?: any; - /** 节点展开图标 */ - expandedIcon?: any; - /** 节点折叠图标 */ - collapsedIcon?: any; - /** 树节点在其父节点下的索引号 */ - index?: number; - /** 父节点标识 */ - parentNodeId?: string; - /** 父节点 */ - parent?: ControlTreeNode; - controlIcon?: string; - hideContextMenuIcon?: boolean; - dependentParentControl?: string; - tips?: string; - rawParentNodeId?: string; -} - -/** - * 控件树右键菜单配置 - */ -export declare class ControlTreeContextMenuConfig { - command?: string; - - name: string; - - controlType?: string; - - isUnique?: boolean; - - subMenus?: any; - - divider?: boolean; - - [propName: string]: any; -}; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/property-entity.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/property-entity.ts deleted file mode 100644 index 30aa1b1f4e6..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/entity/property-entity.ts +++ /dev/null @@ -1,211 +0,0 @@ -import { Ref } from "vue"; -import { EditorConfig } from "../../../../dynamic-resolver"; - -export interface KeyMap { - key: any; - value: any; -} - -/** 属性实体 */ -export interface PropertyEntity { - /** - * 属性ID - */ - propertyID: string; - - /** - * 属性显示的名称 - */ - propertyName?: string; - - /** - * 属性的类型 - */ - propertyType: any; - - /** - * 属性描述 - */ - description?: string; - - /** - * 属性的默认值 - */ - defaultValue?: any; - - propertyValue: Ref; - - /** - * 是否只读,默认false - */ - readonly: () => boolean; - - /** - * 是否可见,默认true - */ - visible: () => boolean; - - /** - * 最小值 - */ - min?: any; - - /** - * 最大值 - */ - max?: any; - - /** - * 数字类型属性的小数位数 - */ - decimals?: number; - - /** - * 是否大数字 - */ - isBigNumber?: boolean; - - /** - * 属性改变后是否需要刷新整个面板:用于更改其他分类下的属性 - */ - refreshPanelAfterChanged?: boolean; - - /** - * 下拉框的枚举值 - */ - iterator?: KeyMap[]; - - /** - * 下拉多选类型:属性值的类型:string(多值以逗号分隔)/array(多值组装成数组) - */ - multiSelectDataType?: string; - - /** - * 文本控件限制输入的字符,支持字符和正则表达式 - */ - notAllowedChars?: any[]; - - /** - * 级联属性配置 - */ - cascadeConfig?: PropertyEntity[]; - - /** - * 级联属性是否默认收起 - */ - isExpand?: boolean; - - /** - * 是否隐藏级联属性的头部 - */ - hideCascadeTitle?: boolean; - - /** - * 模态框属性自定义编辑器参数 - */ - editorParams?: any; - - /** 模态框属性是否展示清除图标 */ - showClearButton?: boolean; - - /** 点击清除按钮后的方法,参数为清除前的属性值 */ - afterClickClearButton?(value: any): void; - - /** 点击清除按钮时是否需要弹窗确认 */ - showQuestionBeforeClear?: boolean; - - /** 点击清除按钮时弹窗确认的文案 */ - questionMessage?: string; - - editor: EditorConfig; -} - -export interface ElementPropertyConfig { - /** - * 分类ID - */ - categoryId: string; - - /** - * 分类显示的名称 - */ - categoryName: string; - - /** - * 分类是否隐藏,默认false - */ - hide?: boolean; - - /** - * 是否隐藏分类标题 - */ - hideTitle?: boolean; - - /** - * 分类下的属性配置 - */ - properties: PropertyEntity[]; - - /** - * 是否启用级联特性,默认false - */ - enableCascade?: boolean; - - /** - * 属性值:分类启用级联特性时必填 - */ - propertyData?: any; - - /** - * 父级属性ID:分类启用级联特性时必填 - */ - parentPropertyID?: string; - - /** - * 属性关联关系,用于属性变更后修改其他属性配置或属性值 - */ - setPropertyRelates?: (changeObject: any, propertyData: any, parameters?: any) => void; - - /** - * 分类以标签页展示时,标签页的ID。若只需平铺展示,则不需要传入。 - */ - tabId?: string; - - /** - * 分类以标签页展示时,标签页的名称。若只需平铺展示,则不需要传入。 - */ - tabName?: string; - - status?: string; -} - -/** - * 属性变更集 - */ -export interface PropertyChangeObject { - /** - * 属性ID - */ - propertyID: string; - - /** - * 变更后的属性值 - */ - propertyValue: any; - - /** - * 属性所在分类ID - */ - categoryId: string; - - /** - * 级联属性的父路径,以.分隔 - */ - propertyPath: string; - - /** - * 级联属性的父属性ID - */ - parentPropertyID: string; - -}; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/change-control-tree-node.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/change-control-tree-node.ts deleted file mode 100644 index c57fd4515a8..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/change-control-tree-node.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { SetupContext } from 'vue'; -import { ControlTreeViewProps } from '../props/control-tree-view.props'; -import { BuilderHTMLElement } from '../entity/builder-element'; -import { DesignerItemContext } from '../../types'; - -/** 变更控件树节点后的操作 */ -export function changeTreeNode(props: ControlTreeViewProps, context: SetupContext) { - - /** 点击左侧控件树 */ - function onComponentClicked(e?: PointerEvent) { - Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( - (element: HTMLElement) => element.classList.remove('dgComponentFocused') - ); - const designId = `${e}-design-item`; - const curSelectedElement = document.getElementById(designId) as any; - - if (designId) { - const currentSelectedElements = document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf; - const returnValue = curSelectedElement?.componentInstance.value.getPropConfig(); - - // 重复点击 - const duplicateClick = currentSelectedElements && - currentSelectedElements.length === 1 && - currentSelectedElements[0] === curSelectedElement; - if (!duplicateClick) { - const array = Array.from(currentSelectedElements); - array.map((element) => { - element?.classList.remove('dgComponentSelected'); - if (element.componentInstance && element.componentInstance.afterComponentCancelClicked) { - element.componentInstance.afterComponentCancelClicked(e); - } - }); - curSelectedElement?.classList.add('dgComponentFocused'); - const { designItemContext } = curSelectedElement; - if (designItemContext) { - const { schema } = (designItemContext as DesignerItemContext).componentInstance.value; - context.emit('selectionChanged', schema); - const draggabledesignerItemElementRef = - designItemContext.componentInstance.value.getDraggableDesignItemElement(designItemContext); - if (draggabledesignerItemElementRef && draggabledesignerItemElementRef.value) { - draggabledesignerItemElementRef.value.classList.add('dgComponentSelected'); - } - } else { - curSelectedElement?.classList.add('dgComponentSelected'); - } - } - return returnValue; - } - } - return { - onComponentClicked - }; -} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts index 1ea2e3179e7..7d950952527 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/create-design-builder.ts @@ -1,27 +1,52 @@ - - import { SetupContext } from 'vue'; -import { ControlTreeViewProps } from '../props/control-tree-view.props'; +import { DesignerOutlineProps } from '../../../../designer-outline/src/designer-outline.props'; /** 创建设计器 */ -export function createDesigner(props: ControlTreeViewProps, context: SetupContext) { +export function createDesigner(props: DesignerOutlineProps, context: SetupContext) { - function createDesignBuilder(domJson: any) { - // 画布渲染过程中,可能会在控件上补充属性,这种变更用户不感知,所以不需要通知IDE框架 + function createDesignBuilder(domJson: any) { + // 画布渲染过程中,可能会在控件上补充属性,这种变更用户不感知,所以不需要通知IDE框架 + // window.suspendChangesOnForm = true; - const elements = document.getElementsByClassName('editorPanel'); - let rootElement: Element; - if (elements && elements.length) { - rootElement = elements[0]; + const elements = document.getElementsByClassName('editorPanel'); + let rootElement; + if (elements && elements.length) { + rootElement = elements[0]; + } + + // if (!DesignerBuilder) { + // return; + // } + + // addServiceToDevkit(); + // const designerHost = addServiceToUI(); + + const childComponents = domJson.module.components.slice(1); + const rootComponent = domJson.module.components[0]; + const designerSchema = { + contents: [rootComponent] + }; + // designBuilder = new DesignerBuilder(rootElement, designerSchema, childComponents, AllComponents, designerHost); + // designBuilder.instance.ready.then(() => { + // onBuilderReady(); + + // 加载控件工具箱 + // controlBox.getDisplayedControls(); + + // 设计器渲染完毕,开始监听DOM变更 + // window.suspendChangesOnForm = false; + // }); + + // designBuilder.instance.on('change', () => { + // onComponentChanged(); + // }); + // designBuilder.instance.on('removeComponent', () => { + // updatePropertyPanel(null); + // onComponentChanged(); + // }); } - const childComponents = domJson.module.components.slice(1); - const rootComponent = domJson.module.components[0]; - const designerSchema = { - contents: [rootComponent] + return { }; - } - - return {}; }; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx new file mode 100644 index 00000000000..8bdd337b123 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/drag-resolve.tsx @@ -0,0 +1,228 @@ +import { ModalFunctions } from "../../../../modal/src/composition/type"; +import { ComponentBindingSourceContext, DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "../types"; +// import EntityBindingSelectorComponent from '../../../../entity-binding-selector/entity-binding-selector.component'; +// import { FBindingSelectorContainer as BindingSelectorComponent } from "@/components/binding-selector"; +import { DesignViewModelField, FormVariable } from "../../../../common/entity/entity-schema"; +import { merge } from "lodash-es"; +import { DesignerComponentInstance } from "../../types"; +import { DgControl } from "../dg-control"; + +export function dragResolveService(designerHostService: DesignerHostService) { + /** 弹窗实例 */ + let modalEditorRef: ModalFunctions; + /** 拖拽上下文 */ + let componentResolveContext: DraggingResolveContext; + + /** + * 获取拖拽上下文信息 + */ + function getComponentResolveContext(sourceElement: DesignerHTMLElement, sourceContainer: DesignerHTMLElement, targetContainer: DesignerHTMLElement) + : DraggingResolveContext { + + const resolveContext: DraggingResolveContext = { + componentType: String(sourceElement.getAttribute('data-controltype')), + componentFeature: String(sourceElement.getAttribute('data-feature')), + componentCategory: String(sourceElement.getAttribute('data-category')), + label: String(sourceElement.getAttribute('data-controlTypeName')), + sourceType: String(sourceElement.getAttribute('data-sourceType') || 'move'), + parentComponentInstance: targetContainer.componentInstance.value, + sourceElement, + sourceContainer, + targetContainer, + bindingSourceContext: null + }; + + // 现有控件移动位置:从控件实例上获取控件类型 + if (sourceElement.componentInstance) { + resolveContext.componentType = sourceElement.componentInstance.value.schema?.type; + // resolveContext.componentCategory = sourceElement.componentInstance.value.category; + } + + return resolveContext; + } + /** + * 选择绑定实体后事件 + */ + function onSubmitEntitySelctor(bindingSourceContext: ComponentBindingSourceContext) { + componentResolveContext.bindingSourceContext = bindingSourceContext; + + if (modalEditorRef?.modalRef?.value.close) { + modalEditorRef?.modalRef?.value.close(); + } + } + /** + * 取消绑定实体 + */ + function onCancelEntitySelector() { + componentResolveContext.bindingSourceContext = undefined; + if (modalEditorRef?.modalRef?.value.close) { + modalEditorRef?.modalRef?.value.close(); + } + } + /** + * 选择绑定实体窗口 + */ + function renderEntityComponent() { + const { componentType } = componentResolveContext; + // return () => (<> ); + } + /** + * 弹出实体绑定窗口 + */ + function triggerBindingEntity() { + return new Promise((resolve, reject) => { + modalEditorRef = designerHostService.modalService.open({ + title: '选择绑定', + width: 800, + height: 600, + fitContent: false, + showButtons: false, + render: renderEntityComponent(), + rejectCallback:()=>{ + componentResolveContext.bindingSourceContext = undefined; + }, + closedCallback: () => { + resolve(componentResolveContext); + }, + draggable: true + }); + }); + } + /** + * 取消绑定字段后事件 + */ + function onCancelFieldSelector() { + componentResolveContext.bindingSourceContext = undefined; + if (modalEditorRef?.modalRef?.value.close) { + modalEditorRef?.modalRef?.value.close(); + } + } + /** + * 获取控件拖拽后的分组信息,以便于后续记录到视图模型 + */ + function getFieldGroupInfo(parentComponentInstance: DesignerComponentInstance) { + let groupId = ''; + let groupName = ''; + if (DgControl['field-set'] && parentComponentInstance.schema.type === DgControl['field-set'].type) { + groupId = parentComponentInstance.schema.id; + groupName = parentComponentInstance.schema.title; + } + return { groupId, groupName }; + } + /** + * 选择绑定字段后事件 + */ + function onSubmitFieldSelctor(data: { selectedData: any, bindingType: any }) { + if (!data || !data.selectedData || !data.bindingType) { + return; + } + const { selectedData, bindingType } = data; + // 若添加到小分组内,需要向vm保存groupId和groupName + const { groupId, groupName } = getFieldGroupInfo(componentResolveContext.parentComponentInstance); + const bindingSourceContext: ComponentBindingSourceContext = { bindingType: 'field' }; + + if (bindingType === 'Form') { + // 绑定字段 + const entityField = selectedData as DesignViewModelField; + bindingSourceContext.entityFieldNode = entityField; + + bindingSourceContext.designViewModelField = merge({}, entityField, { groupId, groupName }); + + componentResolveContext.bindingSourceContext = bindingSourceContext; + } else { + // 绑定变量 + const varibleField = selectedData as FormVariable; + bindingSourceContext.variableFieldNode = merge({}, varibleField, { groupId, groupName }); + componentResolveContext.bindingSourceContext = bindingSourceContext; + } + + if (modalEditorRef?.modalRef?.value.close) { + modalEditorRef?.modalRef?.value.close(); + } + } + /** + * 绑定字段弹窗 + */ + function renderFieldComponent() { + const { parentComponentInstance } = componentResolveContext; + const viewModelId = designerHostService.formSchemaUtils.getViewModelIdByComponentId(parentComponentInstance?.belongedComponentId); + const editorParams = { + viewModelId, + designerHostService, + disableOccupiedFields: true, + componentSchema: { editor: { type: componentResolveContext.componentType } } + }; + const bindingSettings = { enable: false }; + // return () => (<> ); + } + /** + * 弹出绑定字段的窗口 + */ + function triggerBindingField() { + return new Promise((resolve, reject) => { + modalEditorRef = designerHostService.modalService.open({ + title: '选择绑定', + width: 800, + height: 600, + fitContent: false, + showButtons: false, + render: renderFieldComponent(), + rejectCallback:()=>{ + componentResolveContext.bindingSourceContext = undefined; + }, + closedCallback: () => { + resolve(componentResolveContext); + }, + draggable: true + }); + }); + } + /** + * 生成控件schema结构 + */ + function resolveComponentSchema() { + const { parentComponentInstance } = componentResolveContext; + const componentSchema = parentComponentInstance.addNewChildComponentSchema(componentResolveContext, designerHostService); + componentResolveContext.componentSchema = componentSchema; + } + /** + * 解析拖拽元素,并根据场景展示不同的绑定窗口 + */ + async function resolveBindingSource() { + const { componentCategory } = componentResolveContext; + + switch (componentCategory) { + case 'input': { + await triggerBindingField(); + break; + } + case 'dataCollection': { + await triggerBindingEntity(); + break; + } + + } + } + /** + * 根据拖拽元素解析并创建控件 + */ + async function resolveComponentCreationContextByDrop(sourceElement: DesignerHTMLElement, sourceContainer: DesignerHTMLElement, targetContainer: DesignerHTMLElement): Promise { + componentResolveContext = getComponentResolveContext(sourceElement, sourceContainer, targetContainer); + + await resolveBindingSource(); + + // 若返回 undefined 代表终止后续生成 + if (componentResolveContext.bindingSourceContext === undefined) { + return null; + } else { + resolveComponentSchema(); + return componentResolveContext; + } + + } + + return { + getComponentResolveContext, + resolveComponentCreationContextByDrop + }; +} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts index bcbc0270d6b..fe7cd6300d1 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-component.ts @@ -1,208 +1,226 @@ - import { Ref, ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, ResolveComponentContext } from "../../types"; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; export function useDesignerComponent( - elementRef: Ref, - designItemContext?: DesignerItemContext, - designerRules?: UseDesignerRules + elementRef: Ref, + designItemContext?: DesignerItemContext, + designerRules?: UseDesignerRules ): Ref { - function updateDragAndDropRules() { - designerRules?.resolveComponentContext && designerRules.resolveComponentContext(); - } - updateDragAndDropRules(); - - const styles = (designerRules && designerRules.getStyles && designerRules.getStyles()) || ''; - const designerClass = (designerRules && designerRules.getDesignerClass && designerRules.getDesignerClass()) || ''; - const componentInstance = ref(); - /** - * 校验组件是否支持移动 - */ - function checkCanMoveComponent(): boolean { - if (designItemContext?.schema.componentType === 'frame') { - return false; - } - if (designerRules && designerRules.checkCanMoveComponent) { - return designerRules.checkCanMoveComponent(); - } - return true; - } - - /** - * 校验组件是否支持选中父级 - */ - function checkCanSelectParentComponent(): boolean { - return false; - } - - /** - * 校验组件是否支持删除 - */ - function checkCanDeleteComponent() { - if (designItemContext?.schema.componentType === 'frame') { - return false; - } - if (designerRules && designerRules.checkCanDeleteComponent) { - return designerRules.checkCanDeleteComponent(); - } - return true; - } - - /** - * 判断在可视化区域中是否隐藏容器间距和线条 - */ - function hideNestedPaddingInDesginerView() { - if (designItemContext?.schema.componentType === 'frame') { - return true; - } - if (designerRules && designerRules.hideNestedPaddingInDesginerView) { - return designerRules.hideNestedPaddingInDesginerView(); - } - return false; - } - - /** - * 获取组件在表单DOM中所属的Component的实例 - * @param componentInstance 组件实例 - */ - function getBelongedComponentInstance(componentInstance?: Ref): DesignerComponentInstance | null { - if (!componentInstance || !componentInstance.value) { - return null; - } - if (componentInstance.value.schema && componentInstance.value.schema.type === 'component') { - return componentInstance.value; - } - const parent = ref(componentInstance?.value.parent) as Ref; - const grandParent = getBelongedComponentInstance(parent); - if (grandParent) { - return grandParent; - } - return null; - } - - function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext as DesignerItemContext): Ref | null { - const { componentInstance, designerItemElementRef } = context; - if (!componentInstance || !componentInstance.value) { - return null; - } - if (componentInstance.value.canMove || componentInstance.value.canDelete) { - return designerItemElementRef; - } - return getDraggableDesignItemElement(context.parent); - } - - /** - * 判断是否可以接收拖拽新增的子级控件 - * @param data 新控件的类型、所属分类 - * @returns boolean - */ - function canAccepts(draggingContext: DraggingResolveContext) { - return !!designerRules && designerRules.canAccepts(draggingContext); - } - - function getDraggingDisplayText() { - return designItemContext?.schema.label || designItemContext?.schema.title || designItemContext?.schema.name; - } - - /** - * 控件可以拖拽到的最外层容器,用于限制控件向外层容器拖拽的范围。不写则不限制 - */ - function getDragScopeElement(): HTMLElement | undefined { - return undefined; - } - - /** - * 移动控件后事件:在可视化设计器中,将现有的控件移动到容器中 - * @param element 移动的源DOM结构 - */ - function onAcceptMovedChildElement(element: DesignerHTMLElement, soureeElement?: DesignerHTMLElement) { - if (!soureeElement) { - return; - } - if (designerRules?.onAcceptMovedChildElement) { - designerRules.onAcceptMovedChildElement(soureeElement); - } - } - - function addNewChildComponentSchema(resolveContext: ResolveComponentContext) { - const { componentType } = resolveContext; - let componentSchema = getSchemaByType(componentType, resolveContext) as ComponentSchema; - if (designerRules && designerRules.onResolveNewComponentSchema) { - componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); - } - - const typePrefix = componentType.toLowerCase().replace('-', '_'); - if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { - componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return componentSchema; - } - - /** - * 当前容器接收新创建的子控件 - */ - function onAcceptNewChildElement(element: DesignerHTMLElement, targetPosition: number): ComponentSchema { - const componentType = String(element.getAttribute('data-controltype')); - const featureString = element.getAttribute('data-feature'); - const resolveContext = featureString ? JSON.parse(featureString) : {}; - resolveContext.parentComponentInstance = componentInstance.value; - let componentSchema = getSchemaByType(componentType, resolveContext) as ComponentSchema; - if (designerRules && designerRules.onAcceptNewChildElement) { - componentSchema = designerRules.onAcceptNewChildElement(element, targetPosition, componentSchema); - } - - const typePrefix = componentType.toLowerCase().replace('-', '_'); - if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { - componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return componentSchema; - } - - /** - * 移动内部控件后事件:在可视化设计器中,将现有的控件移动到容器中 - * @param element 移动的源DOM结构 - */ - function onChildElementMovedOut(element: HTMLElement) { - - } - - /** 属性面板属性 */ - function getPropConfig() { - if (designerRules && designerRules.getPropsConfig) { - return designerRules.getPropsConfig(); - } - return []; - } - - componentInstance.value = { - canMove: checkCanMoveComponent(), - canSelectParent: checkCanSelectParentComponent(), - canDelete: checkCanDeleteComponent(), - canNested: !hideNestedPaddingInDesginerView(), - contents: designItemContext?.schema.contents, - elementRef, - parent: designItemContext?.parent?.componentInstance, - schema: designItemContext?.schema, - styles, - designerClass, - canAccepts, - getBelongedComponentInstance, - getDraggableDesignItemElement, - getDraggingDisplayText, - getPropConfig, - getDragScopeElement, - onAcceptMovedChildElement, - onAcceptNewChildElement, - onChildElementMovedOut, - addNewChildComponentSchema, - updateDragAndDropRules, - triggerBelongedComponentToMoveWhenMoved: !!designerRules && designerRules.triggerBelongedComponentToMoveWhenMoved || ref(false), - triggerBelongedComponentToDeleteWhenDeleted: !!designerRules && designerRules.triggerBelongedComponentToDeleteWhenDeleted || ref(false) - } as DesignerComponentInstance; - - return componentInstance as any; + const styles = (designerRules && designerRules.getStyles && designerRules.getStyles()) || ''; + const designerClass = (designerRules && designerRules.getDesignerClass && designerRules.getDesignerClass()) || ''; + const componentInstance = ref(); + /** + * 校验组件是否支持移动 + */ + function checkCanMoveComponent(): boolean { + if (designItemContext?.schema.componentType === 'frame') { + return false; + } + if (designerRules && designerRules.checkCanMoveComponent) { + return designerRules.checkCanMoveComponent(); + } + return true; + } + + /** + * 校验组件是否支持选中父级 + */ + function checkCanSelectParentComponent(): boolean { + return false; + } + + /** + * 校验组件是否支持删除 + */ + function checkCanDeleteComponent() { + if (designItemContext?.schema.componentType === 'frame') { + return false; + } + if (designerRules && designerRules.checkCanDeleteComponent) { + return designerRules.checkCanDeleteComponent(); + } + return true; + } + + /** + * 判断在可视化区域中是否隐藏容器间距和线条 + */ + function hideNestedPaddingInDesginerView() { + if (designItemContext?.schema.componentType === 'frame') { + return true; + } + if (designerRules && designerRules.hideNestedPaddingInDesginerView) { + return designerRules.hideNestedPaddingInDesginerView(); + } + return false; + } + + /** + * 获取组件在表单DOM中所属的Component的实例 + * @param componentInstance 组件实例 + */ + function getBelongedComponentInstance(currentComponentInstance?: Ref): DesignerComponentInstance | null { + if (!currentComponentInstance || !currentComponentInstance.value) { + return null; + } + if (currentComponentInstance.value.schema && currentComponentInstance.value.schema.type === 'component') { + return currentComponentInstance.value; + } + const parent = ref(currentComponentInstance?.value.parent) as Ref; + const grandParent = getBelongedComponentInstance(parent); + if (grandParent) { + return grandParent; + } + return null; + } + + function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext as DesignerItemContext): Ref | null { + const { componentInstance, designerItemElementRef } = context; + if (!componentInstance || !componentInstance.value) { + return null; + } + const { getCustomButtons } = componentInstance.value; + if (componentInstance.value.canMove || (getCustomButtons && getCustomButtons()?.length)) { + return designerItemElementRef; + } + return getDraggableDesignItemElement(context.parent); + } + + /** + * 判断是否可以接收拖拽新增的子级控件 + * @param data 新控件的类型、所属分类 + * @returns boolean + */ + function canAccepts(draggingContext: DraggingResolveContext) { + return !!designerRules && designerRules.canAccepts(draggingContext); + } + + function getDraggingDisplayText() { + return designItemContext?.schema.label || designItemContext?.schema.title || designItemContext?.schema.name; + } + + /** + * 控件可以拖拽到的最外层容器,用于限制控件向外层容器拖拽的范围。不写则不限制 + */ + function getDragScopeElement(): HTMLElement | undefined { + return undefined; + } + + /** + * 移动控件后事件:在可视化设计器中,将现有的控件移动到容器中 + * @param element 移动的源DOM结构 + */ + function onAcceptMovedChildElement(element: DesignerHTMLElement, sourceContainer?: DesignerHTMLElement) { + if (!element || !sourceContainer) { + return; + } + if (designerRules?.onAcceptMovedChildElement) { + designerRules.onAcceptMovedChildElement(element, sourceContainer); + } + } + /** + * 当前容器接收新创建的子控件,返回子控件schema结构 + */ + function addNewChildComponentSchema(resolveContext: DraggingResolveContext, designerHostService: DesignerHostService) { + const { componentType } = resolveContext; + let componentSchema = getSchemaByType(componentType, resolveContext, designerHostService) as ComponentSchema; + if (designerRules && designerRules.onResolveNewComponentSchema) { + componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); + } + + const typePrefix = componentType.toLowerCase().replace(/-/g, '_'); + if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { + componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return componentSchema; + } + + /** + * 移动内部控件后事件:在可视化设计器中,将现有的控件移动到容器中 + * @param element 移动的源DOM结构 + */ + function onChildElementMovedOut(element: HTMLElement) { + + } + + /** + * 获取控件属性配置 + */ + function getPropConfig(...args) { + if (designerRules && designerRules.getPropsConfig) { + return designerRules.getPropsConfig(...args); + } + } + /** + * 控件删除后事件 + */ + function onRemoveComponent() { + // 调用当前控件的删除后事件 + if (designerRules && designerRules.onRemoveComponent) { + designerRules.onRemoveComponent(); + } + // 递归触发子级控件的删除后事件 + if (designItemContext?.schema.contents) { + designItemContext.schema.contents.map(content => { + let contentSchemaId = content.id; + if (content.type === 'component-ref') { + contentSchemaId = content.component; + } + const contentElement: any = elementRef.value.querySelector(`#${contentSchemaId}-design-item`); + if (contentElement?.componentInstance?.value.onRemoveComponent) { + contentElement.componentInstance.value.onRemoveComponent(); + } + }); + } + } + /** + * 校验组件是否支持删除 + */ + function getCustomButtons() { + if (designerRules && designerRules.getCustomButtons) { + return designerRules.getCustomButtons(); + } + + } + + /** + * 控件属性变更后事件 + */ + function onPropertyChanged(event: any) { + if (designerRules && designerRules.onPropertyChanged) { + return designerRules.onPropertyChanged(event); + } + } + componentInstance.value = { + canMove: checkCanMoveComponent(), + canSelectParent: checkCanSelectParentComponent(), + canDelete: checkCanDeleteComponent(), + canNested: !hideNestedPaddingInDesginerView(), + contents: designItemContext?.schema.contents, + elementRef, + parent: designItemContext?.parent?.componentInstance, + schema: designItemContext?.schema, + styles, + designerClass, + canAccepts, + getBelongedComponentInstance, + getDraggableDesignItemElement, + getDraggingDisplayText, + getPropConfig, + getDragScopeElement, + onAcceptMovedChildElement, + onChildElementMovedOut, + addNewChildComponentSchema, + triggerBelongedComponentToMoveWhenMoved: !!designerRules && designerRules.triggerBelongedComponentToMoveWhenMoved || ref(false), + triggerBelongedComponentToDeleteWhenDeleted: !!designerRules && designerRules.triggerBelongedComponentToDeleteWhenDeleted || ref(false), + onRemoveComponent, + getCustomButtons, + onPropertyChanged + } as DesignerComponentInstance; + + return componentInstance as any; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts index cf6aa6a65c8..d0858e64716 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-designer-inner-component.ts @@ -1,190 +1,186 @@ - -import { Ref, ref } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; -import { ComponentSchema, DesignerComponentInstance, DesignerItemContext, ResolveComponentContext } from "../../types"; +import { inject, Ref, ref } from "vue"; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types"; +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types"; import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver'; export function useDesignerInnerComponent( - elementRef: Ref, - designItemContext: DesignerItemContext, - designerRules?: UseDesignerRules + elementRef: Ref, + designItemContext: DesignerItemContext, + designerRules?: UseDesignerRules ): Ref { - function updateDragAndDropRules() { - designerRules?.resolveComponentContext && designerRules.resolveComponentContext(); - } - updateDragAndDropRules(); - - const styles = (designerRules && designerRules.getStyles && designerRules.getStyles()) || ''; - const componentInstance = ref(); - /** - * 校验组件是否支持移动 - */ - function checkCanMoveComponent(): boolean { - if (designerRules && designerRules.checkCanMoveComponent) { - return designerRules.checkCanMoveComponent(); - } - return true; - } - - /** - * 校验组件是否支持选中父级 - */ - function checkCanSelectParentComponent(): boolean { - return false; - } - - /** - * 校验组件是否支持删除 - */ - function checkCanDeleteComponent() { - if (designerRules && designerRules.checkCanDeleteComponent) { - return designerRules.checkCanDeleteComponent(); - } - return true; - } - - /** - * 判断在可视化区域中是否隐藏容器间距和线条 - */ - function hideNestedPaddingInDesginerView() { - return true; - } - - /** - * 获取组件在表单DOM中所属的Component的实例 - * @param componentInstance 组件实例 - */ - function getBelongedComponentInstance(componentInstance?: Ref): DesignerComponentInstance | null { - if (!componentInstance || !componentInstance.value) { - return null; - } - const parent = ref(componentInstance?.value.parent) as Ref; - const grandParent = getBelongedComponentInstance(parent); - if (grandParent) { - return grandParent; - } - return null; - } - - function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext): Ref | null { - const { componentInstance, designerItemElementRef } = context; - if (!componentInstance || !componentInstance.value) { - return null; - } - if (componentInstance.value.canMove || componentInstance.value.canDelete) { - return designerItemElementRef; - } - return getDraggableDesignItemElement(context.parent); - } - - /** - * 判断是否可以接收拖拽新增的子级控件 - * @param data 新控件的类型、所属分类 - * @returns boolean - */ - function canAccepts(draggingContext: DraggingResolveContext) { - return !!designerRules && designerRules.canAccepts(draggingContext); - } - - function getDraggingDisplayText() { - return designItemContext?.schema.label || designItemContext?.schema.title || designItemContext?.schema.name; - } - - /** - * 控件可以拖拽到的最外层容器,用于限制控件向外层容器拖拽的范围。不写则不限制 - */ - function getDragScopeElement(): HTMLElement | undefined { - return undefined; - } - - /** - * 移动控件后事件:在可视化设计器中,将现有的控件移动到容器中 - * @param element 移动的源DOM结构 - */ - function onAcceptMovedChildElement(element: DesignerHTMLElement, soureeElement?: DesignerHTMLElement) { - if (!soureeElement) { - return; - } - if (designerRules?.onAcceptMovedChildElement) { - designerRules.onAcceptMovedChildElement(soureeElement); - } - } - - function addNewChildComponentSchema(resolveContext: ResolveComponentContext) { - const { componentType } = resolveContext; - let componentSchema = getSchemaByType(componentType, resolveContext) as ComponentSchema; - if (designerRules && designerRules.onResolveNewComponentSchema) { - componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); - } - - const typePrefix = componentType.toLowerCase().replace('-', '_'); - if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { - componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return componentSchema; - } - - /** - * 当前容器接收新创建的子控件 - */ - function onAcceptNewChildElement(element: DesignerHTMLElement, targetPosition: number): ComponentSchema { - const componentType = String(element.getAttribute('data-controltype')); - const featureString = element.getAttribute('data-feature'); - const resolveContext = featureString ? JSON.parse(featureString) : {}; - resolveContext.parentComponentInstance = componentInstance.value; - let componentSchema = getSchemaByType(componentType, resolveContext) as ComponentSchema; - if (designerRules && designerRules.onAcceptNewChildElement) { - componentSchema = designerRules.onAcceptNewChildElement(element, targetPosition, componentSchema); - } - - const typePrefix = componentType.toLowerCase().replace('-', '_'); - if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { - componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; - } - return componentSchema; - } - - /** - * 移动内部控件后事件:在可视化设计器中,将现有的控件移动到容器中 - * @param element 移动的源DOM结构 - */ - function onChildElementMovedOut(element: HTMLElement) { - - } - - /** 属性面板属性 */ - function getPropConfig() { - if (designerRules && designerRules.getPropsConfig) { - return designerRules.getPropsConfig(); - } - return []; - } - - componentInstance.value = { - canMove: checkCanMoveComponent(), - canSelectParent: checkCanSelectParentComponent(), - canDelete: checkCanDeleteComponent(), - canNested: !hideNestedPaddingInDesginerView(), - contents: [], - elementRef, - parent: designItemContext.parent?.componentInstance, - schema: designItemContext.schema, - styles, - canAccepts, - getBelongedComponentInstance, - getDraggableDesignItemElement, - getDraggingDisplayText, - getPropConfig, - getDragScopeElement, - onAcceptMovedChildElement, - onAcceptNewChildElement, - onChildElementMovedOut, - addNewChildComponentSchema, - updateDragAndDropRules, - triggerBelongedComponentToMoveWhenMoved: !!designerRules && designerRules.triggerBelongedComponentToMoveWhenMoved || ref(false), - triggerBelongedComponentToDeleteWhenDeleted: !!designerRules && designerRules.triggerBelongedComponentToDeleteWhenDeleted || ref(false) - } as DesignerComponentInstance; - - return componentInstance; + const styles = (designerRules && designerRules.getStyles && designerRules.getStyles()) || ''; + const componentInstance = ref(); + /** + * 校验组件是否支持移动 + */ + function checkCanMoveComponent(): boolean { + if (designerRules && designerRules.checkCanMoveComponent) { + return designerRules.checkCanMoveComponent(); + } + return true; + } + + /** + * 校验组件是否支持选中父级 + */ + function checkCanSelectParentComponent(): boolean { + return false; + } + + /** + * 校验组件是否支持删除 + */ + function checkCanDeleteComponent() { + if (designerRules && designerRules.checkCanDeleteComponent) { + return designerRules.checkCanDeleteComponent(); + } + return true; + } + + /** + * 校验组件是否支持添加子元素 + */ + function checkCanAddComponent() { + if (designerRules && designerRules.checkCanAddComponent) { + return designerRules.checkCanAddComponent(); + } + return true; + } + + /** + * 判断在可视化区域中是否隐藏容器间距和线条 + */ + function hideNestedPaddingInDesginerView() { + return true; + } + + /** + * 获取组件在表单DOM中所属的Component的实例 + * @param componentInstance 组件实例 + */ + function getBelongedComponentInstance(componentInstance?: Ref): DesignerComponentInstance | null { + if (!componentInstance || !componentInstance.value) { + return null; + } + const parent = ref(componentInstance?.value.parent) as Ref; + const grandParent = getBelongedComponentInstance(parent); + if (grandParent) { + return grandParent; + } + return null; + } + + function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext): Ref | null { + const { componentInstance, designerItemElementRef } = context; + if (!componentInstance || !componentInstance.value) { + return null; + } + if (componentInstance.value.canMove || componentInstance.value.canAdd || componentInstance.value.canDelete) { + return designerItemElementRef; + } + return getDraggableDesignItemElement(context.parent); + } + + /** + * 判断是否可以接收拖拽新增的子级控件 + * @param data 新控件的类型、所属分类 + * @returns boolean + */ + function canAccepts(draggingContext: DraggingResolveContext) { + return !!designerRules && designerRules.canAccepts(draggingContext); + } + + function getDraggingDisplayText() { + return designItemContext?.schema.label || designItemContext?.schema.title || designItemContext?.schema.name; + } + + /** + * 控件可以拖拽到的最外层容器,用于限制控件向外层容器拖拽的范围。不写则不限制 + */ + function getDragScopeElement(): HTMLElement | undefined { + return undefined; + } + + /** + * 移动控件后事件:在可视化设计器中,将现有的控件移动到容器中 + * @param element 移动的源DOM结构 + */ + function onAcceptMovedChildElement(element: DesignerHTMLElement, sourceContainer?: DesignerHTMLElement) { + if (!element || !sourceContainer) { + return; + } + if (designerRules?.onAcceptMovedChildElement) { + designerRules.onAcceptMovedChildElement(element, sourceContainer); + } + } + + function addNewChildComponentSchema(resolveContext: DraggingResolveContext) { + const { componentType } = resolveContext; + const designerHostServer = inject('designer-host-service') as DesignerHostService; + let componentSchema = getSchemaByType(componentType, resolveContext, designerHostServer) as ComponentSchema; + if (designerRules && designerRules.onResolveNewComponentSchema) { + componentSchema = designerRules.onResolveNewComponentSchema(resolveContext, componentSchema); + } + + const typePrefix = componentType.toLowerCase().replace(/-/g, '_'); + if (componentSchema && !componentSchema.id && componentSchema.type === componentType) { + componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return componentSchema; + } + + /** + * 移动内部控件后事件:在可视化设计器中,将现有的控件移动到容器中 + * @param element 移动的源DOM结构 + */ + function onChildElementMovedOut(element: HTMLElement) { + + } + + /** 属性面板属性 */ + function getPropConfig(...args) { + if (designerRules && designerRules.getPropsConfig) { + return designerRules.getPropsConfig(...args); + } + return []; + } + function onRemoveComponent() { + + } + /** + * 控件属性变更后事件 + */ + function onPropertyChanged(event: any) { + if (designerRules && designerRules.onPropertyChanged) { + return designerRules.onPropertyChanged(event); + } + } + componentInstance.value = { + canMove: checkCanMoveComponent(), + canSelectParent: checkCanSelectParentComponent(), + canAdd: checkCanAddComponent(), + canDelete: checkCanDeleteComponent(), + canNested: !hideNestedPaddingInDesginerView(), + contents: [], + elementRef, + parent: designItemContext.parent?.componentInstance, + schema: designItemContext.schema, + styles, + canAccepts, + getBelongedComponentInstance, + getDraggableDesignItemElement, + getDraggingDisplayText, + getPropConfig, + getDragScopeElement, + onAcceptMovedChildElement, + onChildElementMovedOut, + addNewChildComponentSchema, + onRemoveComponent, + triggerBelongedComponentToMoveWhenMoved: !!designerRules && designerRules.triggerBelongedComponentToMoveWhenMoved || ref(false), + triggerBelongedComponentToDeleteWhenDeleted: !!designerRules && designerRules.triggerBelongedComponentToDeleteWhenDeleted || ref(false), + onPropertyChanged + } as DesignerComponentInstance; + + return componentInstance as Ref; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts index 9f839e9308b..a7be4974f63 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/function/use-dragula.ts @@ -1,431 +1,354 @@ import dragula from '@farris/designer-dragula'; -import { DesignerHTMLElement, DraggingResolveContext, UseDragula } from '../types'; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext, UseDragula } from '../types'; import { findIndex } from 'lodash-es'; import { ref } from 'vue'; import { canvasChanged } from '../designer-canvas-changed'; -import { ComponentSchema, ResolveComponentContext } from '../../types'; - -export function useDragula(): UseDragula { - - let dragulaInstance: any; - - /** - * 获取拖拽上下文信息 - * @param sourceEl 拖拽源HTML节点 - * @param targetComponentInstance 目标组件实例 - */ - function getComponentResolveContext( - sourceElement: DesignerHTMLElement, - targetContainer: DesignerHTMLElement, - sourceContainer: DesignerHTMLElement - ): DraggingResolveContext { - - const resolveContext: DraggingResolveContext = {}; - - resolveContext.sourceElement = sourceElement; - resolveContext.sourceContainer = sourceContainer; - resolveContext.targetContainer = targetContainer; - - resolveContext.sourceType = sourceElement.getAttribute('data-sourceType') || 'move' as any; - resolveContext.controlType = sourceElement.getAttribute('data-controlType'); - resolveContext.controlTypeName = sourceElement.getAttribute('data-controlTypeName'); - resolveContext.controlCategory = sourceElement.getAttribute('data-category'); - resolveContext.controlFeature = sourceElement.getAttribute('data-feature'); - resolveContext.parentComponentInstance = targetContainer.componentInstance; - - if (resolveContext.controlCategory === 'input') { - resolveContext.bindingType = 'field'; - } else if (resolveContext.controlCategory === 'dataCollection') { - resolveContext.bindingType = 'entity'; - } - - // 现有控件移动位置:从控件实例上获取控件类型 - if (sourceElement.componentInstance) { - resolveContext.controlType = sourceElement.componentInstance.value.schema.type; - resolveContext.controlCategory = sourceElement.componentInstance.value.schema.category; - } - return resolveContext; - } - - /** - * 判断是否可以接收拖拽的新控件 - * @param el 拖拽的新控件元素 - * @param target 目标位置 - * @returns boolean - */ - function checkCanAcceptDrops( - element: DesignerHTMLElement, - target: DesignerHTMLElement, - sourceContainer: DesignerHTMLElement - ): boolean { - if (!!element.contains(target) || target.classList.contains('no-drop')) { - return false; - } - const result = true; - if (element.componentInstance && element.componentInstance.value.getDragScopeElement) { - const dragScopEle = element.componentInstance.value.getDragScopeElement(); - if (dragScopEle) { - if (!dragScopEle.contains(target)) { - return false; +import { ComponentSchema } from '../../types'; +import { dragResolveService } from './drag-resolve'; + +export function useDragula(designerHostService: DesignerHostService): UseDragula { + + let dragulaInstance: any; + + /** + * 判断是否可以接收拖拽的新控件 + * @param el 拖拽的新控件元素 + * @param target 目标位置 + * @returns boolean + */ + function checkCanAcceptDrops( + element: DesignerHTMLElement, + target: DesignerHTMLElement, + sourceContainer: DesignerHTMLElement + ): boolean { + if (!!element.contains(target) || target.classList.contains('no-drop')) { + return false; } - } - } - if (target.componentInstance && target.componentInstance.value.canAccepts) { - const draggingContext = getComponentResolveContext(element, target, sourceContainer); + const result = true; + if (element.componentInstance && element.componentInstance.value.getDragScopeElement) { + const dragScopEle = element.componentInstance.value.getDragScopeElement(); + if (dragScopEle) { + if (!dragScopEle.contains(target)) { + return false; + } + } + } + if (target.componentInstance && target.componentInstance.value.canAccepts) { + const dragResolveUtil = dragResolveService(designerHostService); + const draggingContext = dragResolveUtil.getComponentResolveContext(element, sourceContainer, target); - return target.componentInstance.value.canAccepts(draggingContext); - } - return result; - } - - /** - * 判断DOM 是否在可视区域内 - * @param el 元素 - * @param containerEl 容器 - */ - function isElementInViewport(element: HTMLElement, sourceContainer: HTMLElement) { - const container = sourceContainer.getBoundingClientRect(); - const box = element.getBoundingClientRect(); - const top = box.top >= container.top; - const bottom = box.top < container.bottom; - return (top && bottom); - } - - /** - * 拖拽过程若中产生了页面的上下滚动,需要将已选控件的操作按钮上下移动相等的距离。 - * @param formElement 滚动父容器 - * @param scrollDirection 滚动方向 - * @param scrollHeight 滚动距离 - */ - function scrollInDragging(formElement: HTMLElement, scrollHeight: number) { - const selectedDom = formElement.querySelector('.dgComponentSelected') as HTMLElement; - if (!selectedDom || scrollHeight === 0) { - return; - } - if (isElementInViewport(selectedDom, formElement)) { - const toolbar = selectedDom.querySelector('.component-btn-group'); - if (toolbar) { - const divPanel = toolbar.querySelector('div'); - if (divPanel && divPanel.style.top) { - const top = Number.parseFloat(divPanel.style.top); - divPanel.style.top = (top - scrollHeight) + 'px'; + return target.componentInstance.value.canAccepts(draggingContext); } - } + return result; } - } - - /** - * 将新控件json添加到新容器schema json中 - * @param target 目标容器元素 - * @param sourceControlSchema 新控件的JSON schema结构 - * @param sibling 目标位置的下一个同级元素 - */ - function addNewControlToTarget( - target: DesignerHTMLElement, - sourceControlSchema: ComponentSchema | null, - sibling: DesignerHTMLElement - ): number { - const parent = target.componentInstance; - let index = -1; - if (!sourceControlSchema) { - return -1; + + /** + * 判断DOM 是否在可视区域内 + * @param el 元素 + * @param containerEl 容器 + */ + function isElementInViewport(element: HTMLElement, sourceContainer: HTMLElement) { + const container = sourceContainer.getBoundingClientRect(); + const box = element.getBoundingClientRect(); + const top = box.top >= container.top; + const bottom = box.top < container.bottom; + return (top && bottom); } - if (target.componentInstance.value.contents) { - if (sibling && sibling.componentInstance) { - if (!sibling.getAttribute('data-noattach')) { - // 定位目标位置 - const siblingComponentSchema = sibling.componentInstance.value.schema; - let locatePredicate: any = { id: siblingComponentSchema.id }; - if (siblingComponentSchema.type === 'Component') { - locatePredicate = { component: siblingComponentSchema.id }; - } - - index = findIndex(target.componentInstance.value.contents, locatePredicate); - index = (index === -1) ? 0 : index; - } else { - index = Number(sibling.getAttribute('data-position')); + + /** + * 拖拽过程若中产生了页面的上下滚动,需要将已选控件的操作按钮上下移动相等的距离。 + * @param formElement 滚动父容器 + * @param scrollDirection 滚动方向 + * @param scrollHeight 滚动距离 + */ + function scrollInDragging(formElement: HTMLElement, scrollHeight: number) { + const selectedDom = formElement.querySelector('.dgComponentSelected') as HTMLElement; + if (!selectedDom || scrollHeight === 0) { + return; } - if (index !== -1) { - target.componentInstance.value.contents.splice(index, 0, sourceControlSchema); + if (isElementInViewport(selectedDom, formElement)) { + const toolbar = selectedDom.querySelector('.component-btn-group'); + if (toolbar) { + const divPanel = toolbar.querySelector('div'); + if (divPanel && divPanel.style.top) { + const top = Number.parseFloat(divPanel.style.top); + divPanel.style.top = (top - scrollHeight) + 'px'; + } + } } - } else { - target.componentInstance.value.contents.push(sourceControlSchema); - } - target.componentInstance.value.updateDragAndDropRules(); } - return index; - } - - /** - * 获取新控件的目标位置 - */ - function getNewControlTargetPosition(target: DesignerHTMLElement, sibling: DesignerHTMLElement): number { - // 不允许放置 - if (!target.componentInstance.value.contents) { - return -1; + /** + * 将新控件json添加到新容器schema json中 + * @param target 目标容器元素 + * @param sourceControlSchema 新控件的JSON schema结构 + * @param sibling 目标位置的下一个同级元素 + */ + function addNewControlToTarget( + target: DesignerHTMLElement, + sourceControlSchema: ComponentSchema | null, + sibling: DesignerHTMLElement + ): number { + let index = -1; + if (!sourceControlSchema) { + return -1; + } + if (target.componentInstance.value.contents) { + if (sibling && sibling.componentInstance) { + if (!sibling.getAttribute('data-noattach')) { + // 定位目标位置 + const siblingComponentSchema = sibling.componentInstance.value.schema; + let locatePredicate: any = { id: siblingComponentSchema.id }; + if (siblingComponentSchema.type === 'component') { + locatePredicate = { component: siblingComponentSchema.id }; + } + + index = findIndex(target.componentInstance.value.contents, locatePredicate); + index = (index === -1) ? 0 : index; + } else { + index = Number(sibling.getAttribute('data-position')); + } + if (index !== -1) { + target.componentInstance.value.contents.splice(index, 0, sourceControlSchema); + } + } else { + target.componentInstance.value.contents.push(sourceControlSchema); + } + } + return index; } - // 空容器:放置第1个位置 - if (target.componentInstance.value.contents.length === 0) { - return 0; + /** + * 从控件工具箱中拖拽新建控件 + * @param element 拖拽的元素 + * @param target 目标容器元素 + * @param source 原容器元素 + * @param sibling 目标位置的下一个同级元素 + */ + function createControlFromOutside( + element: DesignerHTMLElement, + target: DesignerHTMLElement, + source: DesignerHTMLElement, + sibling: DesignerHTMLElement + ) { + const dragResolveUtil = dragResolveService(designerHostService); + dragResolveUtil.resolveComponentCreationContextByDrop(element, source, target).then(componentResolveContext => { + if (!componentResolveContext) { + return; + } + const sourceControlSchema = componentResolveContext.componentSchema; + if (sourceControlSchema) { + addNewControlToTarget(target, sourceControlSchema, sibling); + } + }); + // 移除拷贝生成的源DOM + if (target.contains(element)) { + target.removeChild(element); + } } + /** + * 在现有的表单中拖拽移动控件位置 + * @param element 拖拽的元素 + * @param target 目标容器元素 + * @param source 源容器元素 + * @param sibling 目标位置的下一个同级元素 + */ + function dragBetweenCurrentForm( + element: DesignerHTMLElement, + target: DesignerHTMLElement, + source: DesignerHTMLElement, + sibling: DesignerHTMLElement + ) { + let sourceControlSchema; + let index = -1; + // Form、DataGrid等控件在拖拽时,需要连同所属Component一起拖拽。 + if (element.componentInstance && element.componentInstance.value.triggerBelongedComponentToMoveWhenMoved) { + const cmpInstance = element.componentInstance.value.getBelongedComponentInstance(element.componentInstance); + if (cmpInstance) { + // 将拖拽元素替换为所属Component + element = ref(cmpInstance.elementRef).value.parentElement as DesignerHTMLElement; + // 将源容器元素替换为所属Component的父级元素 + source = element.parentElement as DesignerHTMLElement; + } - // 后面没有兄弟控件:放置到最后 - if (!sibling || !sibling.componentInstance) { - return target.componentInstance.value.contents.length; - } + } + const elementComponentSchema = element.componentInstance && element.componentInstance.value.schema; - // noattach??? - if (sibling.getAttribute('data-noattach')) { - return Number(sibling.getAttribute('data-position')); - } + let locatePredicate: any = { id: elementComponentSchema && elementComponentSchema.id }; + if (elementComponentSchema.type === 'component') { + locatePredicate = { component: elementComponentSchema && elementComponentSchema.id }; + } - const siblingComponentSchema = sibling.componentInstance.value.schema; - let locatePredicate: any; - if (siblingComponentSchema.type === 'Component') { - locatePredicate = { component: siblingComponentSchema.id }; - } else { - locatePredicate = { id: siblingComponentSchema.id }; - } - let position = findIndex(target.componentInstance.value.contents, locatePredicate); - position = (position === -1) ? 0 : position; - - return position; - } - - /** - * 从控件工具箱中拖拽新建控件 - * @param element 拖拽的元素 - * @param target 目标容器元素 - * @param source 原容器元素 - * @param sibling 目标位置的下一个同级元素 - */ - function createControlFromOutside( - element: DesignerHTMLElement, - target: DesignerHTMLElement, - source: HTMLElement, - sibling: DesignerHTMLElement - ) { - if (target.componentInstance.value.addNewChildComponentSchema) { - const targetPosition = getNewControlTargetPosition(target, sibling); - const componentType = String(element.getAttribute('data-controltype')); - const featureString = element.getAttribute('data-feature'); - const label = String(element.innerText); - const parentComponentInstance = target.componentInstance.value; - const baseContext = { componentType, label, parentComponentInstance, targetPosition } as ResolveComponentContext; - const extendContext = featureString ? JSON.parse(featureString) : {}; - const resolveContext = Object.assign(baseContext, extendContext) as ResolveComponentContext; - const newComponentSchema = target.componentInstance.value.addNewChildComponentSchema(resolveContext); - addNewControlToTarget(target, newComponentSchema, sibling); - } - // 移除拷贝生成的源DOM - if (target.contains(element)) { - target.removeChild(element); - } - } - - /** - * 在现有的表单中拖拽移动控件位置 - * @param element 拖拽的元素 - * @param target 目标容器元素 - * @param source 源容器元素 - * @param sibling 目标位置的下一个同级元素 - */ - function dragBetweenCurrentForm( - element: DesignerHTMLElement, - target: DesignerHTMLElement, - source: DesignerHTMLElement, - sibling: DesignerHTMLElement - ) { - let sourceControlSchema: any; - let index = -1; - // Form、DataGrid等控件在拖拽时,需要连同所属Component一起拖拽。 - if (element.componentInstance && element.componentInstance.value.triggerBelongedComponentToMoveWhenMoved) { - const cmpInstance = element.componentInstance.value.getBelongedComponentInstance(element.componentInstance); - if (cmpInstance) { - // 将拖拽元素替换为所属Component - element = ref(cmpInstance.elementRef).value.parentElement as DesignerHTMLElement; - // 将源容器元素替换为所属Component的父级元素 - source = element.parentElement as DesignerHTMLElement; - } + index = findIndex(source.componentInstance.value.contents, locatePredicate); - } - const elementComponentSchema = element.componentInstance && element.componentInstance.value.schema; + // 从源容器schema json中移除 + if (index !== -1 && source.componentInstance.value.contents) { + sourceControlSchema = source.componentInstance.value.contents.splice(index, 1); + sourceControlSchema = sourceControlSchema[0]; + } - const locatePredicate: any = { id: elementComponentSchema && elementComponentSchema.id }; - index = findIndex(source.componentInstance.value.contents, locatePredicate); + addNewControlToTarget(target, sourceControlSchema as ComponentSchema, sibling); - if (index !== -1 && source.componentInstance.value.contents) { - // 从源容器schema json中移除 - sourceControlSchema = source.componentInstance.value.contents.splice(index, 1); + // 源容器的控件被移除掉 + if (source.componentInstance && source.componentInstance.value.onChildElementMovedOut) { + source.componentInstance.value.onChildElementMovedOut(element); + } - sourceControlSchema = sourceControlSchema[0]; + // 目标容器接收新控件 + if (target.componentInstance && target.componentInstance.value.onAcceptMovedChildElement) { + target.componentInstance.value.onAcceptMovedChildElement(element, source); + } } - addNewControlToTarget(target, sourceControlSchema as ComponentSchema, sibling); + /** + * 拖拽结束 + * @param element 拖拽的元素 + * @param target 目标容器元素 + * @param source 原容器元素 + * @param sibling 目标位置的下一个同级元素 + */ + function onDrop(element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement) { + if (!target) { + return; + } + if (element.contains(target)) { + return; + } + const sourceType = element.getAttribute('data-sourceType'); + + switch (sourceType) { + case 'control': case 'field': case 'entity': { + createControlFromOutside(element, target, source, sibling); + break; + } + default: { + if (source.componentInstance.value.contents) { + dragBetweenCurrentForm(element, target, source, sibling); + } else { + // 移除拷贝生成的源DOM + if (target.contains(element)) { + target.removeChild(element); + } + } + } + } + canvasChanged.value++; - // 源容器的控件被移除掉 - if (source.componentInstance && source.componentInstance.value.onChildElementMovedOut) { - source.componentInstance.value.onChildElementMovedOut(element); } - // 目标容器接收新控件 - if (target.componentInstance && target.componentInstance.value.onAcceptMovedChildElement) { - target.componentInstance.value.onAcceptMovedChildElement(element, source); - } - } - - /** - * 拖拽结束 - * @param element 拖拽的元素 - * @param target 目标容器元素 - * @param source 原容器元素 - * @param sibling 目标位置的下一个同级元素 - */ - function onDrop(element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement) { - if (!target) { - return; - } - // If you try to drop within itself. - if (element.contains(target)) { - return; - } - const sourceType = element.getAttribute('data-sourceType'); - - switch (sourceType) { - case 'control': case 'field': case 'entity': { - createControlFromOutside(element, target, source, sibling); - break; - } - default: { - if (source.componentInstance.value.contents) { - dragBetweenCurrentForm(element, target, source, sibling); - } else { - // 移除拷贝生成的源DOM - - if (target.contains(element)) { - target.removeChild(element); - } + function initializeDragula(containerElement: DesignerHTMLElement) { + if (dragulaInstance) { + dragulaInstance.destroy(); } - } - } - canvasChanged.value++; - } - function initializeDragula(containerElement: DesignerHTMLElement) { - if (dragulaInstance) { - dragulaInstance.destroy(); - } + if (!dragula) { + return; + } - if (!dragula) { - return; + dragulaInstance = dragula([], { + // 镜像容器 + mirrorContainer: containerElement, + direction: 'mixed', + revertOnSpill: true, + // 判断是否可移动 + moves(element: DesignerHTMLElement, container: DesignerHTMLElement, handle: DesignerHTMLElement): boolean { + let moves = true; + + // 包含no-drag样式的元素不允许拖动 + if (element.classList.contains('no-drag')) { + moves = false; + } + // 为防止误操作,可视化区域的控件只能通过移动图标来拖拽 + if (element.componentInstance) { + moves = !!handle.getAttribute('data-dragging-icon'); + } + return moves; + }, + // 判断是否可拷贝 + copy(element: HTMLElement): boolean { + // 工具箱里的div需要配置drag-copy + return element.classList.contains('drag-copy'); + }, + // 获取镜像元素的文本内容 + getMirrorText(element: DesignerHTMLElement): string { + if (element.componentInstance && element.componentInstance.value.getDraggingDisplayText) { + return element.componentInstance.value.getDraggingDisplayText(); + } + return element.innerText || '控件'; + }, + // 判断目标区域是否可接收拖拽的控件 + accepts(element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement): boolean { + const canAccept = checkCanAcceptDrops(element, target, source); + const guMirrotElement = containerElement.lastElementChild as Element; + if (canAccept) { + guMirrotElement.className = guMirrotElement.className.replace('undroppable', ''); + } else if (!guMirrotElement.className.includes('undroppable')) { + guMirrotElement.className += ' undroppable'; + } + return canAccept; + } + }).on('over', (el: DesignerHTMLElement, container: DesignerHTMLElement) => { + container.className += ' drag-over'; + }).on('out', (el: DesignerHTMLElement, container: DesignerHTMLElement) => { + container.className = container.className.replace('drag-over', '').replace(' ', ''); + }).on('drop', ( + element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement + ) => { + onDrop(element, target, source, sibling); + }).on('dragend', (element: HTMLElement, scrollHeight: number) => { + scrollInDragging(element, scrollHeight); + }); } - dragulaInstance = dragula([], { - // 镜像容器 - mirrorContainer: containerElement, - direction: 'mixed', - revertOnSpill: true, - // 判断是否可移动 - moves(element: DesignerHTMLElement, container: DesignerHTMLElement, handle: DesignerHTMLElement): boolean { - let moves = true; - - // 包含no-drag样式的元素不允许拖动 - if (element.classList.contains('no-drag')) { - moves = false; - } - // 为防止误操作,可视化区域的控件只能通过移动图标来拖拽 - if (element.componentInstance) { - moves = !!handle.getAttribute('data-dragging-icon'); + /** + * 子组件JSON结构和当前组件的实例添加到DOM中并注册拖拽容器。节点class= 'builder-components...' + * @param element dom元素 + * @param childrenComponents 容器内的子组件实例集合 + * @param childrenContents 子组件JSON schema集合 + * @param component 容器组件实例 + * @returns 容器类组件的子组件集合 + */ + function attachComponents(element: HTMLElement, component: Record) { + + // don't attach if no element was found or component doesn't participate in drag'n'drop. + if (!element) { + return; } - return moves; - }, - // 判断是否可拷贝 - copy(element: HTMLElement): boolean { - // 工具箱里的div需要配置drag-copy - return element.classList.contains('drag-copy'); - }, - // 获取镜像元素的文本内容 - getMirrorText(element: DesignerHTMLElement): string { - if (element.componentInstance && element.componentInstance.value.getDraggingDisplayText) { - return element.componentInstance.value.getDraggingDisplayText(); + if (component.noDragDrop) { + return element; } - return element.innerText || '控件'; - }, - // 判断目标区域是否可接收拖拽的控件 - accepts(element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement): boolean { - const canAccept = checkCanAcceptDrops(element, target, source); - const guMirrotElement = containerElement.lastElementChild as Element; - if (canAccept) { - guMirrotElement.className = guMirrotElement.className.replace('undroppable', ''); - } else if (!guMirrotElement.className.includes('undroppable')) { - guMirrotElement.className += ' undroppable'; + // 获取容器中的子组件集合节点 + const containerElement: HTMLElement = element.querySelector(`[data-dragref='${component.id}-container']`) || element; + + // 将容器添加到拖拽列表中,dragula控件会监听容器中元素的拖动事件 + if (dragulaInstance && containerElement) { + // containerElement 为页面中的容器节点的builder-components层级 + dragulaInstance.containers.push(containerElement); } - return canAccept; - } - }).on('over', (el: DesignerHTMLElement, container: DesignerHTMLElement) => { - container.className += ' drag-over'; - }).on('out', (el: DesignerHTMLElement, container: DesignerHTMLElement) => { - container.className = container.className.replace('drag-over', '').replace(' ', ''); - }).on('drop', ( - element: DesignerHTMLElement, target: DesignerHTMLElement, source: DesignerHTMLElement, sibling: DesignerHTMLElement - ) => { - onDrop(element, target, source, sibling); - }).on('dragend', (element: HTMLElement, scrollHeight: number) => { - scrollInDragging(element, scrollHeight); - }); - } - - /** - * 子组件JSON结构和当前组件的实例添加到DOM中并注册拖拽容器。节点class= 'builder-components...' - * @param element dom元素 - * @param childrenComponents 容器内的子组件实例集合 - * @param childrenContents 子组件JSON schema集合 - * @param component 容器组件实例 - * @returns 容器类组件的子组件集合 - */ - function attachComponents(element: HTMLElement, component: Record) { - - // don't attach if no element was found or component doesn't participate in drag'n'drop. - if (!element) { - return; - } - if (component.noDragDrop) { - return element; } - // 获取容器中的子组件集合节点 - const containerElement: HTMLElement = element.querySelector(`[data-dragref='${component.id}-container']`) || element; - // 将容器添加到拖拽列表中,dragula控件会监听容器中元素的拖动事件 - if (dragulaInstance && containerElement) { - // containerElement 为页面中的容器节点的builder-components层级 - dragulaInstance.containers.push(containerElement); - } - } - - /** - * 将工具箱各容器添加到dragula的拖拽列表中 - */ - function attachToolbox() { - if (!dragulaInstance) { - return; - } - const controlPanels = document.getElementsByClassName('controlCategory'); - if (!controlPanels) { - return; - } + /** + * 将工具箱各容器添加到dragula的拖拽列表中 + */ + function attachToolbox() { + if (!dragulaInstance) { + return; + } + const controlPanels = document.getElementsByClassName('controlCategory'); + if (!controlPanels) { + return; + } - dragulaInstance.containers = dragulaInstance.containers.filter( - (element: HTMLElement) => !element.className.includes('controlCategory') - ); + dragulaInstance.containers = dragulaInstance.containers.filter( + (element: HTMLElement) => !element.className.includes('controlCategory') + ); - Array.from(controlPanels).forEach((panelElement) => { - dragulaInstance.containers.push(panelElement); - }); + Array.from(controlPanels).forEach((panelElement) => { + dragulaInstance.containers.push(panelElement); + }); - } + } - return { attachComponents, attachToolbox, initializeDragula }; + return { attachComponents, attachToolbox, initializeDragula }; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/control-tree-view.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/control-tree-view.props.ts deleted file mode 100644 index 8fdb2cfec83..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/control-tree-view.props.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ExtractPropTypes } from 'vue'; - -export const controlTreeViewProps = { - /** 树表数据 */ - data: { type: Object, default: [] }, - /** 树节点图标数据 */ - treeNodeIconsData: { type: [Object, String], default: {} }, - /** 树表是否支持可选状态 */ - selectable: { type: Boolean, default: false }, - /** 选中父节点会自动选中子节点 */ - autoCheckChildren: { type: Boolean, default: true }, - /** 返回值展示父节点和子节点 */ - cascade: { type: Boolean, default: true }, - /** 是否显示图标集 */ - showTreeNodeIcons: { type: Boolean, default: false }, - /** 是否显示连接线 */ - showLines: { type: Boolean, default: false }, - /** 新增值 */ - newDataItem: { type: Object, default: {} }, - /** 连接线颜色 */ - lineColor: { type: String, default: '#9399a0' }, - /** 单元格高度 */ - cellHeight: { type: Number, default: 28 }, -}; - -export type ControlTreeViewProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts index 1b6b5feba1e..e07d95a7ac9 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-canvas.props.ts @@ -1,10 +1,13 @@ import { ExtractPropTypes } from 'vue'; export const designerCanvasProps = { - /** - * 组件值 - */ - modelValue: { type: Object, default: {} }, + /** + * 组件值 + */ + modelValue: { type: Object, default: {} }, + componentId: { type: String, default: '' }, + components: { type: Array, default: null }, + } as Record; export type DesignerCanvasPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-inner-item.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-inner-item.props.ts index 5dfd4dc5a94..9c449ec8854 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-inner-item.props.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-inner-item.props.ts @@ -1,17 +1,18 @@ import { ExtractPropTypes } from "vue"; export const designerInnerItemProps = { - id: { type: String, default: '' }, - canAdd: { type: Boolean, default: false }, - canDelete: { type: Boolean, default: false }, - canMove: { type: Boolean, default: false }, - contentKey: { type: String, default: 'contents' }, - childLabel: { type: String, default: '' }, - childType: { type: String, default: '' }, - /** - * 组件值 - */ - modelValue: { type: Object }, + id: { type: String, default: '' }, + componentId: { type: String, default: '' }, + canAdd: { type: Boolean, default: false }, + canDelete: { type: Boolean, default: false }, + canMove: { type: Boolean, default: false }, + contentKey: { type: String, default: 'contents' }, + childLabel: { type: String, default: '' }, + childType: { type: String, default: '' }, + /** + * 组件值 + */ + modelValue: { type: Object }, } as Record; export type DesignerInnerItemPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-item.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-item.props.ts index 8df41e9b8a9..a674600f00b 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-item.props.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-item.props.ts @@ -1,20 +1,20 @@ import { ExtractPropTypes } from "vue"; export const designerItemProps = { - id: { type: String, default: '' }, - componentId: { type: String, default: '' }, - type: { type: String, default: '' }, - canDelete: { type: Boolean, default: true }, - canMove: { type: Boolean, default: true }, - canSelectParent: { type: Boolean, default: true }, - customButtons: { type: Array, default: [] }, - customClass: { type: String, default: '' }, - customStyle: { type: String, default: '' }, - /** - * 组件值 - */ - modelValue: { type: Object }, - ignore: { type: Boolean, default: false } + id: { type: String, default: '' }, + componentId: { type: String, default: '' }, + type: { type: String, default: '' }, + canDelete: { type: Boolean, default: true }, + canMove: { type: Boolean, default: true }, + canSelectParent: { type: Boolean, default: true }, + customButtons: { type: Array, default: [] }, + customClass: { type: String, default: '' }, + customStyle: { type: String, default: '' }, + /** + * 组件值 + */ + modelValue: { type: Object }, + ignore: { type: Boolean, default: false } } as Record; export type DesignerItemPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-placeholder.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-placeholder.props.ts index 0c94cad7b00..3bde9b168af 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-placeholder.props.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/designer-placeholder.props.ts @@ -1,7 +1,7 @@ import { ExtractPropTypes } from "vue"; export const designerPlaceholderProps = { - id: { type: String } + id: { type: String } }; export type DesignerPlaceholderPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/toolbox.props.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/toolbox.props.ts deleted file mode 100644 index f2037941f79..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/props/toolbox.props.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ExtractPropTypes } from 'vue'; - -export const toolboxProps = { - id: { type: String, default: '' }, - dragula: { type: Object } -}; - -export type ToolboxPropsType = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/drag-drop-rules.schema.json b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/drag-drop-rules.schema.json index 682d89ed866..f524134d361 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/drag-drop-rules.schema.json +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/drag-drop-rules.schema.json @@ -1,573 +1,646 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://farris-design.gitee.io/dragging-rules.schema.json", - "title": "Dragging Rules", - "description": "The rules of designer canvas", - "type": "object", - "properties": { - "f-page": { - "description": "The root class of page designed by farris.", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-page-header": { - "description": "The class of page header designed by farris.", - "type": "string" - }, - "f-page-main": { - "description": "The class of page body designed by farris.", - "type": "object", - "properties": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://farris-design.gitee.io/dragging-rules.schema.json", + "title": "Dragging Rules", + "description": "The rules of designer canvas", + "type": "object", + "properties": { + "f-page": { + "description": "The root class of page designed by farris.", + "type": "object", + "properties": { "contents": { - "type": "object", - "properties": { - "f-struct-like-card": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-struct-form": { - "description": "The class of form component which has a hierarchical structure of component -> section -> respnse-form.", - "type": "object", - "properties": { + "type": "object", + "properties": { + "f-page-header": { + "description": "The class of page header designed by farris.", + "type": "string" + }, + "f-page-main": { + "description": "The class of page body designed by farris.", + "type": "object", + "properties": { "contents": { - "type": "object", - "properties": { - "f-section-form": { - "description": "The class of section which has wrapped a reponse-form component.", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-form-layout": { - "description": "The class of reponse form", - "type": "object", - "properties": { + "type": "object", + "properties": { + "f-struct-like-card": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-struct-form": { + "description": "The class of form component which has a hierarchical structure of component -> section -> respnse-form.", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-section-form": { + "description": "The class of section which has wrapped a reponse-form component.", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-form-layout": { + "description": "The class of reponse form", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": true + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": false + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": false + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + }, + "f-struct-wrapper": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-section-tabs": { + "description": "The class of section which has wrapped sub-grid tabs.", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-tabs-in-card": { + "description": "The class of tabs which contains sub-grid.", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-struct-data-grid-in-card": { + "description": "The class of sub-grid component", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-grid-is-sub": { + "description": "The class of sub-grid", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": true + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": false + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": false + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + }, + "f-section-in-main": { + "description": "The class of section which has wrapped a reponse-form component.", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": true + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": false + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": false + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + }, "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": true - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": false + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": true + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "object", + "const": { + "allOf": [ + { + "sibling": 0, + "parent": { + "f-page-main": true + } + } + ] + } + } + } + } + } + }, + "f-struct-data-grid": { + "description": "", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "object", + "const": true + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } } - } } - } } - } }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true + "f-page-main-content": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-page-content-nav": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-struct-data-grid-in-nav": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-page-content-nav-extend": { + "description": "", + "type": "object" + }, + "f-section-in-nav": { + "description": "", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": false + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": true + }, + "fixed": { + "type": "boolean", + "const": false + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + } + } + }, + "f-page-content-main": { + "description": "", + "type": "object", + "properties": {} + } + } + } } - } - } - } - } - } - }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": false - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } - } - } - }, - "f-struct-wrapper": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-section-tabs": { - "description": "The class of section which has wrapped sub-grid tabs.", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-tabs-in-card": { - "description": "The class of tabs which contains sub-grid.", - "type": "object", - "properties": { + }, + "f-page-content": { + "description": "", + "type": "object", + "properties": { "contents": { - "type": "object", - "properties": { - "f-struct-data-grid-in-card": { - "description": "The class of sub-grid component", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-grid-is-sub": { - "description": "The class of sub-grid", - "type": "object", - "properties": { - "rules": { - "type": "object", - "properties": { + "type": "object", + "properties": { + "f-page-content-nav": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-list-nav": { + "description": "", + "type": "object" + }, + "f-list-nav-left": { + "description": "", + "type": "object" + }, + "f-struct-data-grid-in-nav": { + "description": "", + "type": "object", + "properties": { + "contents": { + "type": "object", + "properties": { + "f-section-form": { + "description": "", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + }, + "f-section-grid": { + "description": "", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } + } + } + } + } + }, + "rules": { + "type": "object", + "properties": { "canAccept": { - "type": "boolean", - "const": true + "type": "boolean", + "const": false }, "fixed": { - "type": "boolean", - "const": true + "type": "boolean", + "const": true }, "hidePadding": { - "type": "boolean", - "const": false + "type": "boolean", + "const": true } - } } - } } - } }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": false - }, - "hidePadding": { - "type": "boolean", - "const": true + "f-page-content-main": { + "description": "", + "type": "object", + "properties": { + "rules": { + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": false + }, + "hidePadding": { + "type": "boolean", + "const": true + } + } + } } - } } - } } - } }, "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } } - } } - } - } - } - }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true } - } } - } - }, - "f-section-in-main": { - "description": "The class of section which has wrapped a reponse-form component.", - "type": "object", - "properties": { - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": true - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": false - } - } - } - } } - } }, "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": false - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } - } - } - } - } - }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": true - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "object", - "const": { - "allOf": [ - { - "sibling": 0, - "parent": { - "f-page-main": true - } - } - ] - } - } - } - } - } - }, - "f-struct-data-grid": { - "description": "", - "type": "object", - "properties": { - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "object", - "const": true - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } - } - } - }, - "f-page-main-content": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-page-content-nav": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-struct-data-grid-in-nav": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-page-content-nav-extend": { - "description": "", - "type": "object" - }, - "f-section-in-nav": { - "description": "", - "type": "object", - "properties": { - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false + "type": "object", + "properties": { + "canAccept": { + "type": "object", + "const": { + "anyOf": [ + { + "children": 0 }, - "fixed": { - "type": "boolean", - "const": true + { + "children": { + "length": { + "not": 1 + }, + "f-struct-like-card": true + } }, - "hidePadding": { - "type": "boolean", - "const": false + { + "children": { + "scroll-spy": false, + "f-page-content": false, + "f-struct-like-card": false + } } - } - } - } + ] } - } }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": true - }, - "fixed": { - "type": "boolean", - "const": false - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true } - } } - } } - } - }, - "f-page-content-main": { - "description": "", - "type": "object", - "properties": {} } - } - } - } - }, - "f-page-content": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-page-content-nav": { - "description": "", - "type": "object", - "properties": { - "contents": { - "type": "object", - "properties": { - "f-list-nav": { - "description": "", - "type": "object" - }, - "f-list-nav-left": { - "description": "", - "type": "object" - } - } - } - }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } - } - }, - "f-page-content-main": { - "description": "", - "type": "object", - "properties": { - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": false - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } - } - } - } - } }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } + "f-page-footer": { + "description": "The class of page footer designed by farris.", + "type": "string" } - } } - } }, "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "object", - "const": { - "anyOf": [ - { - "children": 0 - }, - { - "children": { - "length": { - "not": 1 - }, - "f-struct-like-card": true - } - }, - { - "children": { - "scroll-spy": false, - "f-page-content": false, - "f-struct-like-card": false - } - } - ] - } - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true + "type": "object", + "properties": { + "canAccept": { + "type": "boolean", + "const": false + }, + "fixed": { + "type": "boolean", + "const": true + }, + "hidePadding": { + "type": "boolean", + "const": true + } } - } } - } - }, - "f-page-footer": { - "description": "The class of page footer designed by farris.", - "type": "string" } - } }, - "rules": { - "type": "object", - "properties": { - "canAccept": { - "type": "boolean", - "const": false - }, - "fixed": { - "type": "boolean", - "const": true - }, - "hidePadding": { - "type": "boolean", - "const": true - } - } + "f-page-is-managelist": { + "description": "The root class of mangement list page.", + "type": "string" + }, + "f-page-card": { + "description": "", + "type": "object" + }, + "f-page-is-mainsubcard": { + "description": "", + "type": "object" } - } - }, - "f-page-is-managelist": { - "description": "The root class of mangement list page.", - "type": "string" - }, - "f-page-card": { - "description": "", - "type": "object" - }, - "f-page-is-mainsubcard": { - "description": "", - "type": "object" } - }, - "required": [] } \ No newline at end of file diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-drag-drop-rules.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-drag-drop-rules.ts index b7e679aaae4..7af83dea3ad 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-drag-drop-rules.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-drag-drop-rules.ts @@ -1,24 +1,24 @@ import dragAndDropRules from './drag-drop-rules.schema.json'; interface DragDropRule { - canAccept: boolean; - fixed: boolean; - hidePadding: boolean; - [index: string]: boolean; + canAccept: boolean; + fixed: boolean; + hidePadding: boolean; + [index: string]: boolean; } interface Expression { - target: string; - operator: string; - param: any; - value: any; + target: string; + operator: string; + param: any; + value: any; } interface DragAndDropContext { - children: any; - parent: any; - slibing: any; - [index: string]: any; + children: any; + parent: any; + slibing: any; + [index: string]: any; } export type CalculateFunction = (target: string, param: any, value: any, context: DragAndDropContext) => boolean; @@ -26,171 +26,171 @@ export type CalculateFunction = (target: string, param: any, value: any, context export type RuleFunction = (context: DragAndDropContext) => DragDropRule; export interface UseDragAndDropRule { - getRuleValue: (componentToken: string, context: DragAndDropContext) => DragDropRule; + getRuleValue: (componentToken: string, context: DragAndDropContext) => DragDropRule; } const ruleMap = new Map(); export function useDragAndDropRules(): UseDragAndDropRule { - function judgingElementCount(target: string, param: any, value: any, context: DragAndDropContext) { - if (typeof value === 'number') { - return context[target].length === value; - } - if (typeof value === 'object') { - const compare = Object.keys(value)[0]; - const targetValue = value[compare]; - if (compare === 'not') { - return Number(context[target].length) !== Number(targetValue); - } - if (compare === 'moreThan') { - return Number(context[target].length) >= Number(targetValue); - } - if (compare === 'lessThan') { - return Number(context[target].length) <= Number(targetValue); - } + function judgingElementCount(target: string, param: any, value: any, context: DragAndDropContext) { + if (typeof value === 'number') { + return context[target]?.length === value; + } + if (typeof value === 'object') { + const compare = Object.keys(value)[0]; + const targetValue = value[compare]; + if (compare === 'not') { + return Number(context[target].length) !== Number(targetValue); + } + if (compare === 'moreThan') { + return Number(context[target].length) >= Number(targetValue); + } + if (compare === 'lessThan') { + return Number(context[target].length) <= Number(targetValue); + } + } + return false; } - return false; - } - function hasChildren(target: string, param: any, value: any, context: DragAndDropContext) { - if (typeof value === 'boolean') { - return context.childrenClassList.includes(param) === Boolean(value); + function hasChildren(target: string, param: any, value: any, context: DragAndDropContext) { + if (typeof value === 'boolean') { + return context.childrenClassList.includes(param) === Boolean(value); + } + return false; } - return false; - } - function hasParent(target: string, param: any, value: any, context: DragAndDropContext) { - if (typeof value === 'boolean') { - return context.parentClassList.includes(param) === Boolean(value); + function hasParent(target: string, param: any, value: any, context: DragAndDropContext) { + if (typeof value === 'boolean') { + return context.parentClassList.includes(param) === Boolean(value); + } + return false; } - return false; - } - function hasSibling(target: string, param: any, value: any, context: DragAndDropContext) { - if (typeof value === 'boolean') { - return context.parentClassList.includes(param) === Boolean(value); + function hasSibling(target: string, param: any, value: any, context: DragAndDropContext) { + if (typeof value === 'boolean') { + return context.parentClassList.includes(param) === Boolean(value); + } + return false; } - return false; - } - - const expressionCalculateFunctions = new Map([ - ['length', judgingElementCount], - ['hasChildren', hasChildren], - ['hasSibling', hasSibling], - ['hasParent', hasParent] - ]); - - function parseExpression(token: string, expression: Record): Expression[] { - const target = token; - if (typeof expression === 'number') { - return [{ target, operator: 'length', param: null, value: Number(expression) }]; + + const expressionCalculateFunctions = new Map([ + ['length', judgingElementCount], + ['hasChildren', hasChildren], + ['hasSibling', hasSibling], + ['hasParent', hasParent] + ]); + + function parseExpression(token: string, expression: Record): Expression[] { + const target = token; + if (typeof expression === 'number') { + return [{ target, operator: 'length', param: null, value: Number(expression) }]; + } + if (typeof expression === 'object') { + return Object.keys(expression).map((key: string) => { + if (key === 'length') { + return { target, operator: 'length', param: null, value: expression[key] }; + } + const param = key; + const value = expression[key]; + const operator = token === 'children' ? 'hasChildren' : (token === 'parent' ? 'hasParent' : 'hasSibling'); + return { target, operator, param, value }; + }); + } + return []; } - if (typeof expression === 'object') { - return Object.keys(expression).map((key: string) => { - if (key === 'length') { - return { target, operator: 'length', param: null, value: expression[key] }; + + function calculateExpression(expression: Expression, context: DragAndDropContext) { + if (expressionCalculateFunctions.has(expression.operator)) { + const calculateFunction = expressionCalculateFunctions.get(expression.operator); + return calculateFunction && calculateFunction(expression.target, expression.param, expression.value, context) || false; } - const param = key; - const value = expression[key]; - const operator = token === 'children' ? 'hasChildren' : (token === 'parent' ? 'hasParent' : 'hasSibling'); - return { target, operator, param, value }; - }); + return false; + } + + function calculate(expression: Record, context: DragAndDropContext): boolean { + const expressionTokens = Object.keys(expression); + + const parsedExpression = expressionTokens.reduce((expressions: Expression[], token: string) => { + const result = parseExpression(token, expression[token]); + expressions.push(...result); + return expressions; + }, []); + const result = parsedExpression.reduce((parsingResult: boolean, expression: Expression) => { + return parsingResult && calculateExpression(expression, context); + }, true); + + return result; } - return []; - } - function calculateExpression(expression: Expression, context: DragAndDropContext) { - if (expressionCalculateFunctions.has(expression.operator)) { - const calculateFunction = expressionCalculateFunctions.get(expression.operator); - return calculateFunction && calculateFunction(expression.target, expression.param, expression.value, context) || false; + function parseValueSchema(valueSchema: Record, context: DragAndDropContext): boolean { + const schemaKeys = Object.keys(valueSchema); + const allOf = schemaKeys.includes('allOf'); + const anyOf = schemaKeys.includes('anyOf'); + const hasLogicalOperatorsInSchemaKey = allOf || anyOf; + const logicalOperator = hasLogicalOperatorsInSchemaKey ? (allOf ? 'allOf' : 'anyOf') : 'allOf'; + const expressions = (hasLogicalOperatorsInSchemaKey ? valueSchema[logicalOperator] : [valueSchema]) as Record[]; + const expressionValues = expressions.map((expression: Record) => calculate(expression, context)); + const result = allOf ? !expressionValues.includes(false) : expressionValues.includes(true); + return result; } - return false; - } - - function calculate(expression: Record, context: DragAndDropContext): boolean { - const expressionTokens = Object.keys(expression); - - const parsedExpression = expressionTokens.reduce((expressions: Expression[], token: string) => { - const result = parseExpression(token, expression[token]); - expressions.push(...result); - return expressions; - }, []); - const result = parsedExpression.reduce((parsingResult: boolean, expression: Expression) => { - return parsingResult && calculateExpression(expression, context); - }, true); - - return result; - } - - function parseValueSchema(valueSchema: Record, context: DragAndDropContext): boolean { - const schemaKeys = Object.keys(valueSchema); - const allOf = schemaKeys.includes('allOf'); - const anyOf = schemaKeys.includes('anyOf'); - const hasLogicalOperatorsInSchemaKey = allOf || anyOf; - const logicalOperator = hasLogicalOperatorsInSchemaKey ? (allOf ? 'allOf' : 'anyOf') : 'allOf'; - const expressions = (hasLogicalOperatorsInSchemaKey ? valueSchema[logicalOperator] : [valueSchema]) as Record[]; - const expressionValues = expressions.map((expression: Record) => calculate(expression, context)); - const result = allOf ? !expressionValues.includes(false) : expressionValues.includes(true); - return result; - } - - function resolveRuleValue(ruleValueSchema: Record, context: DragAndDropContext): boolean { - const valueSchema = ruleValueSchema.const; - if (!valueSchema) { - return false; + + function resolveRuleValue(ruleValueSchema: Record, context: DragAndDropContext): boolean { + const valueSchema = ruleValueSchema.const; + if (!valueSchema) { + return false; + } + if (typeof valueSchema === 'boolean') { + return valueSchema; + } + if (typeof valueSchema === 'object') { + return parseValueSchema(valueSchema, context); + } + return false; } - if (typeof valueSchema === 'boolean') { - return valueSchema; + + function generateRuleFunction(rulesSchema: Record): RuleFunction { + return (context: DragAndDropContext) => { + const rulesInstance = { canAccept: true, fixed: false, hidePadding: false } as DragDropRule; + rulesSchema && rulesSchema.properties && + Object.keys(rulesSchema.properties).reduce((compoentRulesMap: DragDropRule, ruleItemKey: string) => { + const ruleItemSchema = rulesSchema.properties[ruleItemKey]; + compoentRulesMap[ruleItemKey] = resolveRuleValue(ruleItemSchema, context); + return compoentRulesMap; + }, rulesInstance); + return rulesInstance; + }; } - if (typeof valueSchema === 'object') { - return parseValueSchema(valueSchema, context); + + function resolveComponentRule(componentToken: string, componentSchema: Record, ruleMap: Map) { + if (componentSchema.type === 'object' && componentSchema.properties) { + const { rules: rulesSchema, contents } = componentSchema.properties; + ruleMap.set(componentToken, generateRuleFunction(rulesSchema)); + if (contents) { + Object.keys(contents.properties).forEach((subComponentToken: string) => + resolveComponentRule(subComponentToken, contents.properties[subComponentToken], ruleMap) + ); + } + } } - return false; - } - - function generateRuleFunction(rulesSchema: Record): RuleFunction { - return (context: DragAndDropContext) => { - const rulesInstance = { canAccept: true, fixed: false, hidePadding: false } as DragDropRule; - rulesSchema && rulesSchema.properties && - Object.keys(rulesSchema.properties).reduce((compoentRulesMap: DragDropRule, ruleItemKey: string) => { - const ruleItemSchema = rulesSchema.properties[ruleItemKey]; - compoentRulesMap[ruleItemKey] = resolveRuleValue(ruleItemSchema, context); - return compoentRulesMap; - }, rulesInstance); - return rulesInstance; - }; - } - - function resolveComponentRule(componentToken: string, componentSchema: Record, ruleMap: Map) { - if (componentSchema.type === 'object' && componentSchema.properties) { - const { rules: rulesSchema, contents } = componentSchema.properties; - ruleMap.set(componentToken, generateRuleFunction(rulesSchema)); - if (contents) { - Object.keys(contents.properties).forEach((subComponentToken: string) => - resolveComponentRule(subComponentToken, contents.properties[subComponentToken], ruleMap) - ); - } + + function resolveRuleSchema() { + const { properties: componentsSchema } = dragAndDropRules as Record; + Object.keys(componentsSchema).forEach((componentToken: string) => { + resolveComponentRule(componentToken, componentsSchema[componentToken], ruleMap); + }); } - } - - function resolveRuleSchema() { - const { properties: componentsSchema } = dragAndDropRules as Record; - Object.keys(componentsSchema).forEach((componentToken: string) => { - resolveComponentRule(componentToken, componentsSchema[componentToken], ruleMap); - }); - } - - function getRuleValue(componentToken: string, context: DragAndDropContext): DragDropRule { - const rulesInstance = { canAccept: true, fixed: false, hidePadding: true } as DragDropRule; - if (ruleMap.has(componentToken)) { - const ruleFuntions = ruleMap.get(componentToken) as RuleFunction; - return ruleFuntions(context); + + function getRuleValue(componentToken: string, context: DragAndDropContext): DragDropRule { + const rulesInstance = { canAccept: true, fixed: false, hidePadding: true } as DragDropRule; + if (ruleMap.has(componentToken)) { + const ruleFuntions = ruleMap.get(componentToken) as RuleFunction; + return ruleFuntions(context); + } + return rulesInstance; } - return rulesInstance; - } - resolveRuleSchema(); + resolveRuleSchema(); - return { getRuleValue }; + return { getRuleValue }; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-dragula-common-rule.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-dragula-common-rule.ts new file mode 100644 index 00000000000..7f6131d6913 --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-dragula-common-rule.ts @@ -0,0 +1,51 @@ +import { DgControl } from "../dg-control"; +import { DesignerHostService, DraggingResolveContext } from "../types"; + +export function useDragulaCommonRule() { + + /** + * 容器类控件的基础控制规则 + */ + function basalDragulaRuleForContainer(draggingContext: DraggingResolveContext, designerHostService?: DesignerHostService): boolean { + if (!draggingContext) { + return false; + } + + /** 目标容器的组件实例 */ + const targetCmpInstance = draggingContext.targetContainer?.componentInstance && + draggingContext.targetContainer.componentInstance.value; + + if (!targetCmpInstance) { + return false; + } + const targetContainerType = targetCmpInstance.schema.type; + const belongedComponent = designerHostService?.formSchemaUtils.getComponentById(targetCmpInstance.belongedComponentId); + + // 限制输入类控件的可接收容器 + if (draggingContext.componentCategory === 'input' || draggingContext.componentType === 'form-group') { + if (![DgControl['response-layout-item'].type, DgControl['response-form'].type].includes(targetContainerType)) { + return false; + } + } + + // 限制标签页区域、分组面板的可接收容器 + if (draggingContext.componentType === DgControl.tabs.type || draggingContext.componentType === DgControl.section.type) { + const belongedComponentType = belongedComponent?.componentType; + if (belongedComponentType !== 'frame') { + return false; + } + if (![DgControl['content-container'].type, DgControl['splitter-pane'].type, DgControl['response-layout-item'].type].includes(targetContainerType)) { + return false; + } + } + // 限制筛选方案 + if (draggingContext.componentType === DgControl['query-solution'].type) { + return false; + } + return true; + } + + return { + basalDragulaRuleForContainer + }; +} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-template-rule.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-template-rule.ts new file mode 100644 index 00000000000..93c1c87835d --- /dev/null +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/rule/use-template-rule.ts @@ -0,0 +1,151 @@ +import { DesignerItemContext } from "../../types"; +import { DesignerHostService } from "../types"; + +export interface DragDropRule { + canAccept: boolean; + canMove: boolean; + canDelete: boolean; + [index: string]: boolean; +} + +/** + * 解析模板拖拽控制规则 + */ +export class UseTemplateDragAndDropRules { + public getTemplateRule(designItemContext: DesignerItemContext, designerHostService?: DesignerHostService): DragDropRule { + + const formSchemaUtils = designerHostService?.formSchemaUtils; + const dragTemplateRules = formSchemaUtils?.getFormTemplateRule(); + const dragDropRule = { canAccept: true, canDelete: true, canMove: true }; + if (!dragTemplateRules) { + return dragDropRule; + } + const componentContext = this.getComponentContext(designItemContext); + const { componentClassList } = componentContext; + + componentClassList.forEach(componentClass => { + if (!componentClass || !dragTemplateRules[componentClass]) { + return; + } + + const { canMove: moveRule, canDelete: deleteRule, canAccept: acceptRule } = dragTemplateRules[componentClass]; + dragDropRule.canMove = dragDropRule.canMove && this.resolveRuleValue(moveRule, componentContext); + dragDropRule.canDelete = dragDropRule.canDelete && this.resolveRuleValue(deleteRule, componentContext); + dragDropRule.canAccept = dragDropRule.canAccept && this.resolveRuleValue(acceptRule, componentContext); + }); + + return dragDropRule; + } + + private resolveRuleValue(ruleSchema: any, componentContext: any): boolean { + + if (typeof ruleSchema === 'boolean') { + return ruleSchema; + } else { + return this.parseRuleValueSchema(ruleSchema, componentContext); + } + } + + private parseRuleValueSchema(ruleSchema: any, componentContext: any) { + const invalidContext = ruleSchema.invalidContext || []; + let isMatched = true; + for (const ruleContext of invalidContext) { + + // 判断子级节点是否匹配 + if (ruleContext.firstLevelChild) { + if (ruleContext.firstLevelChild.class) { + const { firstLevelChildClassList } = componentContext; + if (firstLevelChildClassList && !firstLevelChildClassList.includes(ruleContext.firstLevelChild.class)) { + isMatched = false; + continue; + } + } + if (ruleContext.firstLevelChild.type) { + const { firstLevelChildSchema } = componentContext; + if (!firstLevelChildSchema || firstLevelChildSchema.type !== ruleContext.firstLevelChild.type) { + isMatched = false; + continue; + } + } + + } + // 判断孙子节点是否匹配 + if (ruleContext.secondLevelChild) { + if (ruleContext.secondLevelChild.class) { + const { secondLevelChildClassList } = componentContext; + if (secondLevelChildClassList && !secondLevelChildClassList.includes(ruleContext.secondLevelChild.class)) { + isMatched = false; + continue; + } + } + if (ruleContext.secondLevelChild.type) { + const { secondLevelChildSchema } = componentContext; + if (!secondLevelChildSchema || secondLevelChildSchema.type !== ruleContext.secondLevelChild.type) { + isMatched = false; + continue; + } + } + + } + // 判断父级节点是否匹配 + if (ruleContext.parent) { + if (ruleContext.parent.class) { + const { parentClassList } = componentContext; + if (parentClassList && !parentClassList.includes(ruleContext.parent.class)) { + isMatched = false; + continue; + } + } + if (ruleContext.parent.type) { + const { parentSchema } = componentContext; + if (parentSchema && parentSchema.type !== ruleContext.parent.type) { + isMatched = false; + continue; + } + } + } + isMatched = true; + break; + } + return !isMatched; + + } + public getComponentContext(designItemContext: DesignerItemContext) { + const component = designItemContext.schema; + + // 控件本身 + const componentClass = component.appearance && component.appearance.class || ''; + const componentClassList = componentClass.split(' ') || []; + + // 控件子级节点 + const childContents = component.contents || []; + const firstLevelChildSchema = childContents.length ? childContents[0] : null; + const firstLevelChildClass = firstLevelChildSchema && firstLevelChildSchema.appearance ? firstLevelChildSchema.appearance.class : ''; + const firstLevelChildClassList = firstLevelChildClass ? firstLevelChildClass.split(' ') : []; + + // 控件孙子级节点 + const secondLevelChildSchema = firstLevelChildSchema?.contents?.length ? firstLevelChildSchema?.contents[0] : null; + const secondLevelChildClass = secondLevelChildSchema && secondLevelChildSchema.appearance ? secondLevelChildSchema.appearance.class : ''; + const secondLevelChildClassList = secondLevelChildClass ? secondLevelChildClass.split(' ') : []; + + // 控件父级节点 + const parentSchema = component.type === 'component' ? designItemContext.parent?.parent?.schema : designItemContext.parent?.schema; + const parentClass = parentSchema && parentSchema.appearance && parentSchema.appearance.class || ''; + const parentClassList = parentClass ? parentClass.split(' ') : []; + + return { + componentClass, + componentClassList, + childContents, + firstLevelChildSchema, + firstLevelChildClass, + firstLevelChildClassList, + secondLevelChildSchema, + secondLevelChildClass, + secondLevelChildClassList, + parentSchema, + parentClass, + parentClassList + }; + } +} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts index 4a8b8103b7e..e256c20caa3 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/composition/types.ts @@ -1,22 +1,54 @@ +import { DesignFormVariable, DesignViewModelField, FormSchemaEntity, FormSchemaEntityField } from "../../../common/entity/entity-schema"; import { Ref } from "vue"; -import { ComponentSchema, DesignerComponentInstance, ResolveComponentContext } from "../types"; +import { ComponentSchema, DesignerComponentButton, DesignerComponentInstance } from "../types"; export interface DesignerHTMLElement extends HTMLElement { - /** 记录各子元素对应的控件schema json的集合,用于container类dom节点 */ - contents?: ComponentSchema[]; + /** 记录各子元素对应的控件schema json的集合,用于container类dom节点 */ + contents?: ComponentSchema[]; - /** 记录element对应的component实例,用于单个component节点 */ - componentInstance: Ref; + /** 记录element对应的component实例,用于单个component节点 */ + componentInstance: Ref; - schema: ComponentSchema; + schema: ComponentSchema; } export interface UseDragula { - attachComponents: (element: HTMLElement, component: ComponentSchema) => void; + attachComponents: (element: HTMLElement, component: ComponentSchema) => void; - attachToolbox: () => void; + attachToolbox: () => void; - initializeDragula: (containerElement: DesignerHTMLElement) => void; + initializeDragula: (containerElement: DesignerHTMLElement) => void; +} +export interface DesignerHostService { + eventsEditorUtils: any; + formSchemaUtils: any; + formMetadataConverter: any; + designViewModelUtils: any; + controlCreatorUtils: any; + metadataService?: any; + formStateMachineUtils: any; + [key: string]: any; +} +/** + * 绑定上下文 + */ +export interface ComponentBindingSourceContext { + /** 控件绑定类型:字段|实体 */ + bindingType: 'field' | 'entity'; + /** 控件绑定的实体schema字段 */ + entityFieldNode?: FormSchemaEntityField; + /** 控件绑定的实体schema字段若是关联带出字段,此属性记录关联字段所属的根字段 */ + entityRootFieldNode?: FormSchemaEntityField; + /** 实体schema字段对应的DesignViewModel结构 */ + designViewModelField?: DesignViewModelField; + /** 变量字段节点 */ + variableFieldNode?: DesignFormVariable; + /** 要绑定的实体 */ + bindingEntity?: FormSchemaEntity; + /** 要绑定的字段集合 */ + bindingEntityFields?: FormSchemaEntityField[]; + /** 实体在视图模型中的绑定信息 */ + bindTo?: string } /** @@ -24,108 +56,98 @@ export interface UseDragula { */ export interface DraggingResolveContext { - sourceElement?: DesignerHTMLElement; - sourceContainer?: DesignerHTMLElement; - targetContainer?: DesignerHTMLElement; - - /** - * 拖拽来源 - * @summary - * 控件工具箱control/实体树字段field/实体树实体entity/ 现有控件移动位置move - */ - sourceType?: 'control' | 'field' | 'entity' | 'move'; - - /** - * 拖拽控件类型 - */ - controlType?: string | null; - - /** - * 拖拽控件的中文类型名称 - */ - controlTypeName?: string | null; - /** - * 拖拽控件分类 - */ - controlCategory?: string | null; - - /** - * 绑定对象类型(字段/实体/小部件) - */ - bindingType?: 'field' | 'entity' | 'widget'; - - /** - * 目标容器的组件实例 - */ - parentComponentInstance?: any; - - /** - * 要添加的控件Schema - */ - componentSchema?: any; - - /** 工具箱中的控件,启用的特性 */ - controlFeature?: any; - + /** 拖拽的源元素 */ + sourceElement: DesignerHTMLElement; + /** 拖拽的源元素父容器 */ + sourceContainer: DesignerHTMLElement; + /** 拖拽的目标容器 */ + targetContainer: DesignerHTMLElement; + + /** 拖拽的控件类型 */ + componentType: string; + /** 拖拽的控件名称 */ + label: string; + /** 拖拽目标区域的组件实例 */ + parentComponentInstance: DesignerComponentInstance; + /** 拖拽位置在目标区域的索引值 */ + targetPosition?: number; + /** 拖拽控件的类别 */ + componentCategory?: string; + /** 拖拽来源:控件工具箱control / 实体树字段field / 实体树实体entity / 现有控件移动位置move */ + sourceType: string; + /** 工具箱中的控件,启用的特性 */ + componentFeature?: string; + /** 要添加的控件Schema */ + componentSchema?: any; + + /** 绑定信息 */ + bindingSourceContext?: ComponentBindingSourceContext | null; + + // [propName: string]: any; } export interface UseDesignerRules { - /** - * 判断是否可以接收拖拽新增的子级控件 - */ - canAccepts(draggingContext: DraggingResolveContext): boolean; - - /** - * 判断当前容器是否是固定的上下文的中间层级 - */ - checkIsInFixedContextRules?(): boolean; - - /** - * 判断控件上下文环境,用于后续判断控件是否可移动、可删除、是否有默认间距、线条 - */ - resolveComponentContext?(): void; - - getStyles?(): string; - - getDesignerClass?(): string; - - onResolveNewComponentSchema?: (resolveContext: ResolveComponentContext, compnentSchema: ComponentSchema) => ComponentSchema; - - /** - * 容器接收新创建的子控件 - */ - onAcceptNewChildElement?: (element: DesignerHTMLElement, targetPosition: number, compnentSchema: ComponentSchema) => ComponentSchema; - - /** - * 移动控件后事件:在可视化设计器中,容器接收控件后调用此事件 - */ - onAcceptMovedChildElement?: (sourceElement: DesignerHTMLElement) => void; - - /** - * 判断是否支持移动组件 - */ - checkCanMoveComponent?(): boolean; - - /** - * 判断是否支持删除组件 - */ - checkCanDeleteComponent?(): boolean; - - /** - * 判断是否隐藏组件间距和线条 - */ - hideNestedPaddingInDesginerView?(): boolean; - - /** 接收控件属性信息 */ - - getPropsConfig?(schema?: any): any; - - /** - * 组件在拖拽时是否需要将所属的Component一起拖拽,用于form、data-grid等控件的拖拽 - */ - triggerBelongedComponentToMoveWhenMoved?: Ref; - /** - * 组件在被移除时是否需要将所属的Component一起移除,用于form、data-grid等控件的拖拽 - */ - triggerBelongedComponentToDeleteWhenDeleted?: Ref; + /** + * 判断是否可以接收拖拽新增的子级控件 + */ + canAccepts(draggingContext: DraggingResolveContext): boolean; + + /** + * 判断当前容器是否是固定的上下文的中间层级 + */ + checkIsInFixedContextRules?(): boolean; + + getStyles?(): string; + + getDesignerClass?(): string; + /** + * 容器接收新创建的子控件 + */ + onResolveNewComponentSchema?: (resolveContext: DraggingResolveContext, componentSchema: ComponentSchema) => ComponentSchema; + + /** + * 移动控件后事件:在可视化设计器中,容器接收控件后调用此事件 + */ + onAcceptMovedChildElement?: (sourceElement: DesignerHTMLElement, sourceContainer: DesignerHTMLElement) => void; + + /** + * 判断是否支持移动组件 + */ + checkCanMoveComponent?(): boolean; + + /** + * 判断是否支持删除组件 + */ + checkCanDeleteComponent?(): boolean; + + /** + * 判断是否支持增加组件 + */ + checkCanAddComponent?(): boolean; + + /** + * 判断是否隐藏组件间距和线条 + */ + hideNestedPaddingInDesginerView?(): boolean; + + /** 接收控件属性信息 */ + getPropsConfig?(schema?: any, componentInstance?: any): any; + + /** + * 组件在拖拽时是否需要将所属的Component一起拖拽,用于form、data-grid等控件的拖拽 + */ + triggerBelongedComponentToMoveWhenMoved?: Ref; + /** + * 组件在被移除时是否需要将所属的Component一起移除,用于form、data-grid等控件的拖拽 + */ + triggerBelongedComponentToDeleteWhenDeleted?: Ref; + + /** 组件删除后事件 */ + onRemoveComponent?(): void; + + /** 获取控件自定义操作按钮 */ + getCustomButtons?: () => DesignerComponentButton[]; + + /** 控件属性变更后事件 */ + onPropertyChanged?: (event:any) => void; } diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/composition/use-dragula-common-rule.ts b/packages/mobile-ui-vue/components/designer-canvas/src/composition/use-dragula-common-rule.ts deleted file mode 100644 index 9d8c585e349..00000000000 --- a/packages/mobile-ui-vue/components/designer-canvas/src/composition/use-dragula-common-rule.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { DraggingResolveContext } from "./types"; - -export function useDragulaCommonRule() { - - /** - * 容器类控件的基础控制规则 - */ - function basalDragulaRuleForContainer(draggingContext: DraggingResolveContext): boolean { - if (!draggingContext) { - return false; - } - - /** 目标容器的组件实例 */ - const targetCmpInstance = draggingContext.targetContainer?.componentInstance && - draggingContext.targetContainer.componentInstance.value; - if (!targetCmpInstance) { - return false; - } - - const targetCmpInstanceClass = targetCmpInstance.schema.appearance?.class; - - // 能够接收输入类控件的只有Form控件和布局容器 - if (draggingContext.controlCategory === 'input' || draggingContext.controlType === 'form-group') { - const targetContainerType = targetCmpInstance.schema.type; - const isFormContainer = (targetContainerType === 'response-form' || targetContainerType === 'content-container') - && targetCmpInstanceClass && targetCmpInstanceClass.includes('farris-form'); - if (targetCmpInstance.schema.type !== 'response-layout-item' && !isFormContainer) { - return false; - } - } - - // 不接收卡片内小分组 - if (draggingContext.controlType === 'field-set') { - return false; - } - - return true; - } - - return { - basalDragulaRuleForContainer - }; -} diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index 37e31bc7f0c..569b057e421 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/mobile-ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -1,69 +1,144 @@ - -import { SetupContext, computed, defineComponent, onMounted, provide, ref, watch } from 'vue'; -import { ComponentSchema, DesignerItemContext } from './types'; -import { canvasChanged, setPositionOfBtnGroup } from './composition/designer-canvas-changed'; + +import { computed, defineComponent, inject, onMounted, onUnmounted, provide, ref, watch } from 'vue'; +import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from './types'; +import { canvasChanged, setPositionOfButtonGroup } from './composition/designer-canvas-changed'; import { designerCanvasProps, DesignerCanvasPropsType } from './composition/props/designer-canvas.props'; import { useDragula } from './composition/function/use-dragula'; -import { UseDragula } from './composition/types'; +import { DesignerHostService, UseDragula } from './composition/types'; import FDesignerItem from './components/designer-item.component'; import './composition/class/designer-canvas.css'; import './composition/class/control.css'; +import { loadDesignerRegister, loadDesignerRegisterByComponents } from './components/maps'; +import { F_MODAL_SERVICE_TOKEN } from '../../modal'; export default defineComponent({ - name: 'FDesignerCanvas', - props: designerCanvasProps, - emits: ['init', 'selectionChange'], - setup(props: DesignerCanvasPropsType, context: SetupContext) { - const schema = ref(); - const designerCanvasElementRef = ref(); - const designerItemElementRef = ref(); - const componentInstance = ref(); - const useDragulaComposition = useDragula(); + name: 'FDesignerCanvas', + props: designerCanvasProps, + emits: ['init', 'selectionChange', 'canvasChanged'], + setup(props: DesignerCanvasPropsType, context) { + const schema = ref(); + const componentSchema = ref(); + const designerCanvasElementRef = ref(); + const designerCanvasContainerElementRef = ref(); + const designerItemElementRef = ref(); + const componentInstance = ref(); + const componentId = ref(props.componentId); + let resizeObserver: ResizeObserver | null; + let resizeObserverTimer; - provide('canvas-dragula', useDragulaComposition); - provide('design-item-context', { - designerItemElementRef, - componentInstance, - schema: schema.value, - parent: undefined, - setupContext: context, - }); + const designerHostService = { + eventsEditorUtils: inject('eventsEditorUtils'), + formSchemaUtils: inject('useFormSchema'), + formMetadataConverter: inject('formMetadataConverter'), + designViewModelUtils: inject('designViewModelUtils'), + controlCreatorUtils: inject('controlCreatorUtils'), + metadataService: inject('Meatdata_Http_Service_Token'), + schemaService: inject('schemaService'), + useFormCommand: inject('useFormCommand'), + modalService: inject(F_MODAL_SERVICE_TOKEN), + formStateMachineUtils: inject('useFormStateMachine') + }; + provide('designer-host-service', designerHostService); - const designerCanvasClass = computed(() => { - const classObject = { - 'd-flex': true, - 'flex-fill': true, - 'flex-column': true - } as Record; - return classObject; - }); + const useDragulaComposition = useDragula(designerHostService); + if(props.components){ + loadDesignerRegisterByComponents(props.components); + }else{ + loadDesignerRegister(); + } - onMounted(() => { - if (designerCanvasElementRef.value) { - useDragulaComposition.initializeDragula(designerCanvasElementRef.value); - } - schema.value = props.modelValue; - context.emit('init', useDragulaComposition); - }); + provide('canvas-dragula', useDragulaComposition); + provide('design-item-context', { + designerItemElementRef, + componentInstance, + schema: componentSchema.value, + parent: undefined + }); - watch(canvasChanged, () => { - setPositionOfBtnGroup(designerCanvasElementRef.value); - }, { flush: 'post' }); + const designerCanvasClass = computed(() => { + const classObject = { + 'd-flex': true, + 'flex-fill': true, + 'flex-column': true + } as Record; + return classObject; + }); - function onSelectionChange(schemaType: string, schemaValue: ComponentSchema) { - context.emit('selectionChange', schemaType, schemaValue); - } + /** + * 用于在设计器里 + * @param designerItem + */ + function updateDesignerItem(item: any, compId: string) { + schema.value = item; + componentId.value = compId; + } + + watch(canvasChanged, () => { + setPositionOfButtonGroup(designerCanvasElementRef.value); + + context.emit('canvasChanged'); + }, { flush: 'post' }); + + /** + * 监听画布尺寸变化,重新计算操作图标位置 + */ + function registerResizeListenner() { + resizeObserver = new ResizeObserver(() => { + if (resizeObserverTimer) { + clearTimeout(resizeObserverTimer); + } - return () => { - return ( -
-
-
- {schema.value && } -
-
-
- ); - }; - } + resizeObserverTimer = setTimeout(() => { + setPositionOfButtonGroup(designerCanvasElementRef.value); + }); + }); + resizeObserver.observe(designerCanvasElementRef.value); + } + + function onSelectionChange(schemaType: string, schemaValue: ComponentSchema, cmpId: string, componentInst: DesignerComponentInstance) { + context.emit('selectionChange', schemaType, schemaValue, cmpId, componentInst); + } + + /** + * 监听画布父容器横向滚动条的滚动,重新计算操作图标位置 + */ + function registerEditorPanelScrollEvent() { + designerCanvasContainerElementRef.value.addEventListener('scroll', (e) => { + setPositionOfButtonGroup(designerCanvasElementRef.value); + }); + } + onMounted(() => { + if (designerCanvasElementRef.value) { + useDragulaComposition.initializeDragula(designerCanvasElementRef.value); + } + schema.value = props.modelValue; + context.emit('init', useDragulaComposition); + registerResizeListenner(); + registerEditorPanelScrollEvent(); + }); + + onUnmounted(() => { + if (resizeObserver) { + resizeObserver.unobserve(designerCanvasElementRef.value); + resizeObserver.disconnect(); + resizeObserver = null; + } + }); + + context.expose({ + updateDesignerItem + }); + + return () => { + return ( +
+
+
+ {schema.value && } +
+
+
+ ); + }; + } }); diff --git a/packages/mobile-ui-vue/components/designer-canvas/src/types.ts b/packages/mobile-ui-vue/components/designer-canvas/src/types.ts index 312f15c17e3..c63ceb11c79 100644 --- a/packages/mobile-ui-vue/components/designer-canvas/src/types.ts +++ b/packages/mobile-ui-vue/components/designer-canvas/src/types.ts @@ -1,124 +1,107 @@ /* eslint-disable no-use-before-define */ import { Ref, SetupContext } from "vue"; -import { DesignerHTMLElement, DraggingResolveContext } from "./composition/types"; +import { DesignerHostService, DesignerHTMLElement, DraggingResolveContext } from "./composition/types"; export interface ComponentSchema { - /** 设计时使用 */ - key?: string; + /** 设计时使用 */ + key?: string; - id: string; + id: string; - type: string; + type: string; - contents?: ComponentSchema[]; + contents?: ComponentSchema[]; - // 其他属性 - [propName: string]: any; + // 其他属性 + [propName: string]: any; } export interface DesignerComponentInstance { - canMove: boolean; + canAdd?: boolean; - canSelectParent: boolean; + canMove: boolean; - canDelete: boolean; + canSelectParent: boolean; - canNested: boolean; + canDelete: boolean; - contents?: ComponentSchema[]; + canNested: boolean; - elementRef: Ref; + contents?: ComponentSchema[]; - parent: Ref | undefined; + elementRef: Ref; - schema: ComponentSchema; + parent: Ref | undefined; - styles?: string; + schema: ComponentSchema; - designerClass?: string; + styles?: string; - canAccepts: (draggingContext: DraggingResolveContext) => boolean; + designerClass?: string; - getBelongedComponentInstance: (componentInstance: Ref) => DesignerComponentInstance | null; + canAccepts: (draggingContext: DraggingResolveContext) => boolean; - getDraggableDesignItemElement: (context: DesignerItemContext) => Ref | null; + getBelongedComponentInstance: (componentInstance: Ref) => DesignerComponentInstance | null; - getDraggingDisplayText: () => string; + /** 获取可拖拽的上层容器 */ + getDraggableDesignItemElement: (context: DesignerItemContext) => Ref | null; - getDragScopeElement: () => HTMLElement | undefined; + getDraggingDisplayText: () => string; - /** - * 移动内部控件后事件:在可视化设计器中,容器接收控件后事件 - * @param element 移动的源DOM结构 - */ - onAcceptMovedChildElement: (element: DesignerHTMLElement, soureElement?: DesignerHTMLElement) => void; + getDragScopeElement: () => HTMLElement | undefined; - onAcceptNewChildElement: (element: DesignerHTMLElement, targetPosition: number) => ComponentSchema; + /** 移动内部控件后事件:在可视化设计器中,容器接收控件后事件 */ + onAcceptMovedChildElement: (element: DesignerHTMLElement, soureElement?: DesignerHTMLElement) => void; - onChildElementMovedOut: (element: HTMLElement) => void; + onChildElementMovedOut: (element: HTMLElement) => void; - addNewChildComponentSchema: (resolveContext: ResolveComponentContext) => ComponentSchema; + addNewChildComponentSchema: (resolveContext: DraggingResolveContext, designerHostService?: DesignerHostService) => ComponentSchema; - updateDragAndDropRules: () => void; + /** 组件在拖拽时是否需要将所属的Component一起拖拽,用于form、data-grid等控件的拖拽 */ + triggerBelongedComponentToMoveWhenMoved?: Ref; - /** - * 组件在拖拽时是否需要将所属的Component一起拖拽,用于form、data-grid等控件的拖拽 - */ - triggerBelongedComponentToMoveWhenMoved?: Ref; + /** 组件在被移除时是否需要将所属的Component一起移除,用于form、data-grid等控件的拖拽 */ + triggerBelongedComponentToDeleteWhenDeleted?: Ref; - /** - * 组件在被移除时是否需要将所属的Component一起移除,用于form、data-grid等控件的拖拽 - */ - triggerBelongedComponentToDeleteWhenDeleted?: Ref; -} - -export interface ResolveComponentContext { + /** 获取属性配置 */ + getPropConfig: (...args) => any; - componentType: string; + /** 控件所属Component的标识*/ + belongedComponentId?: string; - label: string; + /** 控件删除后事件 */ + onRemoveComponent: () => void; - parentComponentInstance: DesignerComponentInstance; + /** 获取控件自定义操作按钮 */ + getCustomButtons?: () => DesignerComponentButton[]; - targetPosition: number; - - [propName: string]: any; + /** 控件属性变更后事件 */ + onPropertyChanged?: (event:any) => void; } export interface DesignerItemContext { - designerItemElementRef: Ref; + designerItemElementRef: Ref; - componentInstance: Ref; + componentInstance: Ref; - schema: ComponentSchema; + schema: ComponentSchema; - parent?: DesignerItemContext; + parent?: DesignerItemContext; - setupContext: SetupContext; -} + setupContext?: SetupContext; -export interface ToolboxItem { - id: string; - type: string; - name: string; - category: string; - icon?: string; - feature?: any; - dependentParent?: boolean; - hideInControlBox?: boolean; - disable?: boolean; - fieldType?: string; - templateCategory?: string; - updating?: boolean; } -export interface ToolboxCategory { - type: string; - name: string; - items: ToolboxItem[]; - hideInControlBox?: boolean; - isHide?: boolean; +/** + * 控件自定义操作按钮 + */ +export interface DesignerComponentButton { + id: string; + title: string; + icon: string; + class?: string; + onClick: (payload: MouseEvent) => void; } diff --git a/packages/mobile-ui-vue/components/designer.ts b/packages/mobile-ui-vue/components/designer.ts new file mode 100644 index 00000000000..3aaf39102fc --- /dev/null +++ b/packages/mobile-ui-vue/components/designer.ts @@ -0,0 +1,3 @@ +export * from './designer-canvas'; +export * from './dynamic-resolver'; + diff --git a/packages/mobile-ui-vue/components/dynamic-form/index.ts b/packages/mobile-ui-vue/components/dynamic-form/index.ts new file mode 100644 index 00000000000..4eee3a79648 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/index.ts @@ -0,0 +1,4 @@ + + +export * from './src/types'; +export * from './src/composition/types'; diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/response-form-component-creator.service.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/response-form-component-creator.service.ts new file mode 100644 index 00000000000..296ef9ed765 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/response-form-component-creator.service.ts @@ -0,0 +1,196 @@ +import { inject } from 'vue'; +import { DesignerHostService } from '../../../designer-canvas/src/composition/types'; +import { DynamicResolver } from '../../../../components/dynamic-resolver'; +import { ComponentBuildInfo } from '../../../component/src/composition/inner-component-build-info'; +import { ComponentSchema } from '../../../../components/designer-canvas'; +import { FormSchemaEntityFieldTypeName } from '../../../common/entity/entity-schema'; +import { cloneDeep } from 'lodash-es'; + +const ROOT_VIEW_MODEL_ID = 'root-viewmodel'; +/** + * 创建卡片类组件服务类 + */ +export class ResponseFormComponentCreatorService { + + private formSchemaUtils: any; + private controlCreatorUtils: any; + private designViewModelUtils: any; + + constructor( + private resolver: DynamicResolver, + private designerHostService: DesignerHostService + ) { + this.formSchemaUtils = this.designerHostService.formSchemaUtils; + this.controlCreatorUtils = this.designerHostService.controlCreatorUtils; + this.designViewModelUtils = this.designerHostService.designViewModelUtils; + } + + public createComponent(buildInfo: ComponentBuildInfo) { + const componentRefNode = this.createComponentRefNode(buildInfo); + + const componentNode = this.createComponentNode(buildInfo); + + const viewModelNode = this.createViewModeNode(buildInfo); + + const formSchema = this.formSchemaUtils.getFormSchema(); + formSchema.module.viewmodels.push(viewModelNode); + formSchema.module.components.push(componentNode); + + this.designViewModelUtils.assembleDesignViewModel(); + + return componentRefNode; + } + createComponentRefNode(buildInfo: ComponentBuildInfo): any { + const componentRefNode = this.resolver.getSchemaByType('component-ref') as ComponentSchema; + Object.assign(componentRefNode, { + id: `${buildInfo.componentId}-component-ref`, + component: `${buildInfo.componentId}-component`, + }); + return componentRefNode; + } + + createComponentNode(buildInfo: ComponentBuildInfo): any { + const componentNode = this.resolver.getSchemaByType('component') as ComponentSchema; + const contents = this.createFormComponentContents(buildInfo); + Object.assign(componentNode, { + id: `${buildInfo.componentId}-component`, + viewModel: `${buildInfo.componentId}-component-viewmodel`, + componentType: buildInfo.componentType, + appearance: { + class: this.getFormComponentClass() + }, + formColumns: buildInfo.formColumns, + contents + }); + return componentNode; + } + + + /** + * 获取卡片组件层级的class样式 + */ + private getFormComponentClass(): string { + const {templateId} = this.formSchemaUtils.getFormSchema().module; + + // 双列表标签页模板中拖入卡片 + if (templateId === 'double-list-in-tab-template') { + return 'f-struct-wrapper f-utils-fill-flex-column'; + } + return 'f-struct-wrapper'; + + } + + private createFormComponentContents(buildInfo: ComponentBuildInfo) { + // 1、创建section + const section = this.resolver.getSchemaByType('section') as ComponentSchema; + Object.assign(section, { + id: buildInfo.componentId + '-form-section', + appearance: { + class: 'f-section-form f-section-in-mainsubcard' + }, + mainTitle: buildInfo.componentName + }); + + // 2、创建form(默认控件标签独占一列) + const responseForm = this.resolver.getSchemaByType('response-form') as ComponentSchema; + const controls: any[] = []; + Object.assign(responseForm, { + id: buildInfo.componentId + '-form', + appearance: { + class: 'f-form-layout farris-form farris-form-controls-inline' + }, + contents: controls + }); + section.contents = [responseForm]; + + // 3、创建字段 + const { selectedFields } = buildInfo; + selectedFields?.forEach(field => { + const dgVMField = cloneDeep(field); + const resolvedControlClass = this.resolveControlClassByFormColumns(buildInfo); + const fieldMetadata = this.controlCreatorUtils.setFormFieldProperty(dgVMField, '', resolvedControlClass); + + if (fieldMetadata) { + controls.push(fieldMetadata); + } + }); + + // 双列表标签页模板中拖入卡片,要求卡片要填充 + const {templateId} = this.formSchemaUtils.getFormSchema().module; + if (templateId === 'double-list-in-tab-template') { + section.appearance.class = 'f-section-grid f-section-in-main px-0 pt-0'; + section.fill = true; + } + + return [section]; + } + + private resolveControlClassByFormColumns(buildInfo: ComponentBuildInfo) { + let className = ''; + switch (buildInfo.formColumns) { + case 1: { + className = 'col-12'; + break; + } + case 2: { + className = 'col-12 col-md-6 col-xl-6 col-el-6'; + break; + } + case 3: { + className = 'col-12 col-md-6 col-xl-4 col-el-4'; + break; + } + case 4: { + className = 'col-12 col-md-6 col-xl-3 col-el-2'; + break; + } + } + + return className; + } + /** + * 添加viewModel节点 + */ + createViewModeNode(buildInfo: ComponentBuildInfo): any { + const viewModelNode = { + id: `${buildInfo.componentId}-component-viewmodel`, + code: `${buildInfo.componentId}-component-viewmodel`, + name: buildInfo.componentName, + bindTo: buildInfo.bindTo, + parent: ROOT_VIEW_MODEL_ID, + fields: this.assembleViewModelFields(buildInfo), + commands: [], + states: [], + enableValidation: true + }; + return viewModelNode; + } + + /** + * 组装viewModel fields 节点 + */ + private assembleViewModelFields(buildInfo: ComponentBuildInfo) { + + const vmFields: any[] = []; + const { selectedFields } = buildInfo; + selectedFields?.forEach(field => { + let updateOn = 'blur'; + const type = field.type.name; + if (type === FormSchemaEntityFieldTypeName.Enum || type === FormSchemaEntityFieldTypeName.Boolean) { + updateOn = 'change'; + } + + vmFields.push({ + type: 'Form', + id: field.id, + fieldName: field.bindingField, + groupId: null, + groupName: null, + updateOn, + fieldSchema: {} + }); + }); + return vmFields; + } + +} diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/types.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/types.ts new file mode 100644 index 00000000000..6963eb18697 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/types.ts @@ -0,0 +1,12 @@ +import { EditorConfig } from "../types"; + +export interface UseTypeResolver { + + resolveEditorProps(type: string, config: EditorConfig): Record; + + resolveEditorType(type: string): any; + + getChangeFunctionName(type: string): any; + + getClearFunctionName(type: string): any; +} diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts new file mode 100644 index 00000000000..b562cf68f49 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-response-form-layout-setting.ts @@ -0,0 +1,128 @@ +import { ResponseFormLayoutContext } from "@/components/response-layout-editor"; +import { FormUnifiedColumnLayout, UseResponseFormLayoutSetting } from "../types"; +import { DgControl } from "@/components/designer-canvas"; +import { useResponseLayoutEditorSetting } from + "../../../response-layout-editor/src/composition/converter/use-response-layout-editor-setting"; + +export function useResponseFormLayoutSetting(formShemaService, componentId: string): UseResponseFormLayoutSetting { + function getFormNode(formSchemaId, formNode = null): any { + if (formNode) { return formNode; } + const componentNode = formShemaService.getComponentById(componentId); + return formShemaService.selectNode(componentNode, item => item.id === formSchemaId); + } + function checkIsInFormComponent(componentId: string): boolean { + const componentNode = formShemaService.getComponentById(componentId); + if (!componentNode || !componentNode.componentType || !componentNode.componentType.startsWith('form')) { + return false; + } + return true; + + } + /** + * 组装每种屏幕下的宽度样式值,例如col-md-6,则uniqueColClassInMD为6 + */ + function assembleUnifiedLayoutContext(propertyData: any): FormUnifiedColumnLayout { + + const formNode = getFormNode(propertyData.id); + const responseLayoutService = useResponseLayoutEditorSetting(formShemaService); + const responseLayoutConfig: ResponseFormLayoutContext[] = []; + responseLayoutService.getResonseFormLayoutConfig(formNode, responseLayoutConfig, 1); + + + // 收集每种屏幕下的列数 + const columnInSMArray = responseLayoutConfig.map(config => config.columnInSM); + const columnInMDArray = responseLayoutConfig.map(config => config.columnInMD); + const columnInLGArray = responseLayoutConfig.map(config => config.columnInLG); + const columnInELArray = responseLayoutConfig.map(config => config.columnInEL); + + /** + * 校验宽度样式值是否一致 + */ + function checkIsUniqueColumn(columnsInScreen: number[]) { + const keySet = new Set(columnsInScreen); + const exclusiveKeys = Array.from(keySet); + + if (exclusiveKeys.length === 1) { + return true; + } + return false; + } + + // 只有每个控件的宽度都一样时,才认为form上有统一宽度,否则认为是自定义的控件宽度,此处传递null + const uniqueColClassInSM = checkIsUniqueColumn(columnInSMArray) ? columnInSMArray[0] : 0; + const uniqueColClassInMD = checkIsUniqueColumn(columnInMDArray) ? columnInMDArray[0] : 0; + const uniqueColClassInLG = checkIsUniqueColumn(columnInLGArray) ? columnInLGArray[0] : 0; + const uniqueColClassInEL = checkIsUniqueColumn(columnInELArray) ? columnInELArray[0] : 0; + + return { + uniqueColClassInSM, + uniqueColClassInMD, + uniqueColClassInLG, + uniqueColClassInEL + }; + } + + /** + * 校验宽度样式值是否一致 + */ + function checkIsUniqueColumn(columnsInScreen: number[]) { + const keySet = new Set(columnsInScreen); + const exclusiveKeys = Array.from(keySet); + + if (exclusiveKeys.length === 1) { + return true; + } + return false; + } + + /** + * 根据统一配置值,修改某一个控件的class样式 + */ + function changeControlClassInByColumn(controlClass: string, unifiedLayout: FormUnifiedColumnLayout) { + let originColClass; + let originColMDClass; + let originColXLClass; + let originColELClass; + let otherClassItems = [] as any; + if (controlClass) { + const controlClassArray = controlClass.split(' '); + const colClassItems = controlClassArray.filter(classItem => classItem.startsWith('col-')); + originColClass = colClassItems.find(item => /^col-([1-9]|10|11|12)$/.test(item)); + originColMDClass = colClassItems.find(item => /^col-md-([1-9]|10|11|12)$/.test(item)); + originColXLClass = colClassItems.find(item => /^col-xl-([1-9]|10|11|12)$/.test(item)); + originColELClass = colClassItems.find(item => /^col-el-([1-9]|10|11|12)$/.test(item)); + otherClassItems = controlClassArray.filter(classItem => !classItem.startsWith('col-')); + } + const colClass = unifiedLayout.uniqueColClassInSM ? 'col-' + unifiedLayout.uniqueColClassInSM : originColClass; + const colMDClass = unifiedLayout.uniqueColClassInMD ? 'col-md-' + unifiedLayout.uniqueColClassInMD : originColMDClass; + const colXLClass = unifiedLayout.uniqueColClassInLG ? 'col-xl-' + unifiedLayout.uniqueColClassInLG : originColXLClass; + const colELClass = unifiedLayout.uniqueColClassInEL ? 'col-el-' + unifiedLayout.uniqueColClassInEL : originColELClass; + + const newClassItems = [colClass, colMDClass, colXLClass, colELClass].concat(otherClassItems); + + return newClassItems.join(' '); + } + + /** + * 根据统一配置值,修改卡片区域内所有控件的class样式 + * @param formNode dom节点 + * @param unifiedLayout 统一配置值 + */ + function changeFormControlsByUnifiedLayoutConfig(formNode: any, unifiedLayout: FormUnifiedColumnLayout, formSchemaId) { + formNode = getFormNode(formSchemaId, formNode); + formNode.contents.forEach(control => { + if (control.type === DgControl['fieldset'].type) { + changeFormControlsByUnifiedLayoutConfig(control, unifiedLayout, control.id); + return; + } + if (!control.appearance) { + control.appearance = {}; + } + const controlClass = control.appearance.class; + control.appearance.class = changeControlClassInByColumn(controlClass, unifiedLayout); + + }); + } + + return { checkIsInFormComponent, assembleUnifiedLayoutContext, changeFormControlsByUnifiedLayoutConfig }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts new file mode 100644 index 00000000000..9777e1d6971 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver-design.ts @@ -0,0 +1,25 @@ +import { componentMap, componentPropsConverter } from '../../../../components/designer-canvas/src/components/maps'; +import FInputGroupDesign from '../../../input-group/src/designer/input-group.design.component'; +import { EditorType, EditorConfig } from "../types"; +import { UseTypeResolver } from "./types"; + +export function useTypeResolverDesign(): UseTypeResolver { + + function resolveEditorProps(type: EditorType, config: EditorConfig): Record { + const propsConverter = componentPropsConverter[type]; + const viewProps = propsConverter ? propsConverter(config) : {}; + return viewProps; + } + + function resolveEditorType(type: EditorType) { + return componentMap[type] || FInputGroupDesign; + } + + function getChangeFunctionName(type: EditorType) { + } + + function getClearFunctionName(type: EditorType) { + } + + return { getChangeFunctionName, getClearFunctionName, resolveEditorProps, resolveEditorType }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts new file mode 100644 index 00000000000..a76465116e5 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/composition/use-type-resolver.ts @@ -0,0 +1,109 @@ +import FInputGroup from '../../../input-group/src/input-group.component'; +import { EditorType, EditorConfig } from "../types"; +import { UseTypeResolver } from "./types"; +import { componentMap, componentPropsConverter, loadRegister } from '../../../dynamic-view/src/components/maps'; + +export function useTypeResolver(): UseTypeResolver { + + loadRegister(); + + function resolveEditorType(type: EditorType) { + return componentMap[type] || FInputGroup; + } + + function resolveEditorProps(type: EditorType, config: EditorConfig): Record { + const propsConverter = componentPropsConverter[type]; + const viewProps = propsConverter ? propsConverter(config) : {}; + // const Component = resolveEditorType(type); + // const componentPropertyProps = Object.keys(Component?.props || {}); + // const componentEventProps = (Component?.emits as string[] || []).map((eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`); + // const currentComponentProps = componentPropertyProps.concat(componentEventProps); + // const componentProps = Object.keys(viewProps).reduce((props: Record, propertyName: string) => { + // if (currentComponentProps.indexOf(propertyName) !== -1) { + // props[propertyName] = viewProps[propertyName]; + // } + // return props; + // }, {}); + return viewProps; + } + + // jumphere + function getChangeFunctionName(type: EditorType) { + + switch (type) { + case 'check-box': + return 'onChangeValue'; + case 'switch': + return 'onModelValueChanged'; + case 'check-group': + return 'onChangeValue'; + case 'combo-list': + case 'combo-tree': + return 'onChange'; + case 'combo-lookup': + return ''; + case 'date-picker': + return 'onDatePicked'; + case 'date-range': + return ''; + case 'datetime-picker': + return ''; + case 'datetime-range': + return ''; + case 'month-picker': + return ''; + case 'month-range': + return ''; + case 'year-picker': + return ''; + case 'year-range': + return ''; + case 'input-group': + return 'onChange'; + case 'lookup': + return 'onUpdate:modelValue'; + case 'number-range': + return 'onValueChange'; + case 'number-spinner': + return 'onValueChange'; + case 'radio-group': + return 'onChangeValue'; + case 'text': + return ''; + case 'response-layout-editor-setting': + return 'onChange'; + case 'events-editor': + return 'onSavedCommandListChanged'; + case 'grid-field-editor': + return 'onChange'; + case 'item-collection-editor': + return 'onChange'; + case 'response-form-layout-setting': + return 'onChange'; + case 'field-selector': case 'binding-selector': + return 'onFieldSelected'; + case 'schema-selector': + return 'onSchemaSelected'; + case 'mapping-editor': + return 'onMappingFieldsChanged'; + case 'textarea': + return 'onValueChange'; + case 'query-solution-config': + case 'solution-preset': + return 'onFieldsChanged'; + + + } + } + + function getClearFunctionName(type: EditorType) { + switch (type) { + case 'combo-list': + case 'input-group': + case 'textarea': + return 'onClear'; + } + } + + return { resolveEditorProps, resolveEditorType, getChangeFunctionName, getClearFunctionName }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-form/src/types.ts b/packages/mobile-ui-vue/components/dynamic-form/src/types.ts new file mode 100644 index 00000000000..e5029eeff4c --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-form/src/types.ts @@ -0,0 +1,33 @@ +export type EditorType = 'button-edit' | 'check-box' | 'check-group' | 'combo-list' | 'combo-lookup' | 'combo-tree' | + 'date-picker' | 'date-range' | 'datetime-picker' | 'datetime-range' | 'events-editor' | 'month-picker' | 'month-range' | + 'year-picker' | 'year-range' | 'input-group' | 'lookup' | 'number-range' | 'number-spinner' | 'radio-group' | 'text' | + 'response-layout-editor-setting' | 'switch' | 'grid-field-editor' | 'field-selector' | 'schema-selector' | 'mapping-editor' | + 'textarea' | 'response-form-layout-setting'|'binding-selector' | 'query-solution-config' | 'solution-preset' | 'item-collection-editor'; + +export interface EditorConfig { + /** 编辑器类型 */ + type: EditorType; + /** 自定义样式 */ + customClass?: string; + /** 禁用 */ + disabled?: boolean; + /** 只读 */ + readonly?: boolean; + /** 必填 */ + required?: boolean; + /** 提示文本 */ + placeholder?: string; + /** 其他属性 */ + [key: string]: any; +} +export interface FormUnifiedColumnLayout { + uniqueColClassInSM: number; + uniqueColClassInMD: number; + uniqueColClassInLG: number; + uniqueColClassInEL: number; +} +export interface UseResponseFormLayoutSetting { + checkIsInFormComponent: (componentId: string) => boolean; + assembleUnifiedLayoutContext: (propertyData: any) => FormUnifiedColumnLayout; + changeFormControlsByUnifiedLayoutConfig: (formNode: any, unifiedLayout: FormUnifiedColumnLayout, formSchemaId: string) => void; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts index 0b17160f466..5ee690b0cd7 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/index.ts @@ -2,3 +2,12 @@ export * from './src/types'; export * from './src/props-resolver'; export * from './src/common/appearance-resolver'; export * from './src/common/toolbar-resolver'; +export * from './src/binding-resolver'; +export * from './src/events-resolver'; +export * from './src/selection-item-resolver'; +export * from './src/editor-resolver'; +export * from './src/visible-prop-resolver'; +export * from './src/event-handler-resolver'; +export * from './src/schema-resolver'; +export * from './src/update-columns-resolver'; +export { propertyConfigSchemaMap,getPropertyConfigBySchema } from './src/property-config-resolver'; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/binding-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/binding-resolver.ts new file mode 100644 index 00000000000..9428dca63fb --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/binding-resolver.ts @@ -0,0 +1,68 @@ +import { BindingData, BindingResolver } from "./types"; + +export function createFormBindingResolver(): BindingResolver { + function resolve(schema: Record, bindingData: BindingData) { + const { id } = schema || {}; + const { field } = schema.binding || {}; + return { + 'modelValue': bindingData.getValue(id), + 'onUpdate:modelValue': (value: any) => { + bindingData.setValue(id, field, value); + } + }; + }; + return { + resolve + }; +} + +export function createCollectionBindingResolver(): BindingResolver { + function resolve(schema: Record, bindingData: BindingData) { + const { id } = schema || {}; + const { dataSource } = schema || {}; + if (dataSource === undefined) { + return {}; + } + return { + 'data': bindingData.getValue(id), + 'onUpdate:data': (...payload: any[]) => { + // bindingData.updateData(...payload); + } + }; + }; + return { + resolve + }; +} + +export function createTreeGridBindingResolver(): BindingResolver{ + function resolve(schema: Record, bindingData: BindingData) { + const { id } = schema || {}; + const { dataSource } = schema || {}; + if (dataSource === undefined) { + return {}; + } + return { + }; + }; + return { + resolve + }; +} + +export function createDataMappingBindingResolver(): BindingResolver { + function resolve(schema: Record, bindingData: BindingData) { + const { path } = schema.binding || {}; + if (!path) { + return {}; + } + return { + 'onUpdate:dataMapping': (...payloads: any[]) => { + // bindingModel.dataMapping(...payloads); + } + }; + }; + return { + resolve + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts index 1ddf2f0b20a..c5a7cbd2e5b 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/appearance-resolver.ts @@ -1,3 +1,3 @@ export function resolveAppearance(key: string, appearanceObject: { class: string; style: string }) { - return { customClass: appearanceObject.class }; + return { customClass: appearanceObject.class,customStyle:appearanceObject.style }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts index d8d6c955507..08ebea5f43f 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/common/toolbar-resolver.ts @@ -1,3 +1,15 @@ -export function resolveToolbar(key: string, toolbarObject: { buttons: any[] }) { - return { buttons: toolbarObject.buttons }; +export function resolveToolbar(key: string, toolbarObject: { buttons: any[],appearance:any }) { + const result = [] as any; + toolbarObject?.buttons.map(button => { + const newButton = {}; + Object.keys(button).map(key => { + if (key === 'appearance') { + newButton['class']=button[key]?.class||''; + }else{ + newButton[key] = button[key]; + } + }); + result.push(newButton); + }); + return { buttons: result }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts new file mode 100644 index 00000000000..b6ca97b8dff --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/appearance.converter.ts @@ -0,0 +1,14 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; + +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.appearance) { + schema.appearance={}; + } + schema.appearance[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.appearance ? schema.appearance[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts index 79e422c565c..abfb60a4d29 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/buttons.converter.ts @@ -1,8 +1,8 @@ import { ComponentSchema } from "../../../designer-canvas/src/types"; -import { PropertyConverter } from "../types"; +import { PropertyConverter, SchemaService } from "../types"; export default { - convertFrom: (schema: ComponentSchema, propertyKey: string) => { - return (schema.buttons && schema.buttons.length) ? `共 ${schema.buttons.length} 项` : '无'; - } + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return (schema.buttons && schema.buttons.length) ? `共 ${schema.buttons.length} 项` : '无'; + } } as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts new file mode 100644 index 00000000000..61e5ef06b48 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/change-editor.converter.ts @@ -0,0 +1,15 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; + +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + // eslint-disable-next-line no-self-assign + schema[propertyKey] = schema[propertyKey]; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + if (schema.editor) { + return schemaService.getRealEditorType(schema.editor.type); + } + return ''; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts new file mode 100644 index 00000000000..3b1a445ef2f --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/enum-data.converter.ts @@ -0,0 +1,11 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + schema.editor[propertyKey] = propertyValue.value; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.editor && Object.prototype.hasOwnProperty.call(schema.editor, propertyKey) ? + schema.editor[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/field-selector.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/field-selector.converter.ts new file mode 100644 index 00000000000..a9e96534d00 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/field-selector.converter.ts @@ -0,0 +1,24 @@ +import { PropertyConverter } from "../types"; + +export default { + convertFrom: (schema: Record, propertyKey: string) => { + // return schema['binding'] ? schema['binding']['type'] + ":" + schema['binding']['path'] : ''; + return schema['binding'] ? schema['binding']['path'] : ''; + + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + if (propertyValue && propertyValue.length > 0) { + const bindingData = propertyValue[0]; + + if (!schema.binding) { + schema.binding = {}; + } + + schema.binding.type = 'Form'; + schema.binding.path = bindingData.bindingField; + schema.binding.field = bindingData.id; + schema.binding.fullPath = bindingData.path; + schema.path = bindingData.bindingPath; + } + } +} as PropertyConverter;; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/form-group-label.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/form-group-label.converter.ts new file mode 100644 index 00000000000..ac8aec8d00a --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/form-group-label.converter.ts @@ -0,0 +1,10 @@ +import { PropertyConverter } from "../types"; + +export default { + convertFrom: (schema: Record, propertyKey: string) => { + return schema[propertyKey] || ''; + }, + convertTo: (schema: Record, propertyKey: string, propertyValue: any) => { + schema[propertyKey] = propertyValue; + } +} as PropertyConverter;; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts new file mode 100644 index 00000000000..b37faa1b46e --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/grid-selection.converter.ts @@ -0,0 +1,13 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.selection) { + schema.selection = {}; + } + schema.selection[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.selection ? schema.selection[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts new file mode 100644 index 00000000000..288438ef0f2 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/items-count.converter.ts @@ -0,0 +1,8 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; + +export default { + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return (schema[propertyKey] && schema[propertyKey].length) ? `共 ${schema[propertyKey].length} 项` : ''; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts new file mode 100644 index 00000000000..ebf0e2bb56a --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/pagination.converter.ts @@ -0,0 +1,16 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; +/** + * NG版,此处pagination类型是布尔 + */ +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.pagination) { + schema.pagination = {}; + } + schema.pagination[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.pagination ? schema.pagination[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts index b39572b66af..e6e83cae987 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/property-editor.converter.ts @@ -1,13 +1,14 @@ import { ComponentSchema } from "../../../designer-canvas/src/types"; -import { PropertyConverter } from "../types"; +import { PropertyConverter, SchemaService } from "../types"; export default { - convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any) => { - if (schema.editor) { - schema.editor[propertyKey] = propertyValue; + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (schema.editor) { + schema.editor[propertyKey] = propertyValue; + } + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.editor && Object.prototype.hasOwnProperty.call(schema.editor, propertyKey) ? + schema.editor[propertyKey] : schema[propertyKey]; } - }, - convertFrom: (schema: ComponentSchema, propertyKey: string) => { - return schema.editor ? schema.editor[propertyKey] : schema[propertyKey]; - } } as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts new file mode 100644 index 00000000000..929fb4e037a --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/row-number.converter.ts @@ -0,0 +1,13 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { PropertyConverter, SchemaService } from "../types"; +export default { + convertTo: (schema: ComponentSchema, propertyKey: string, propertyValue: any, schemaService: SchemaService) => { + if (!schema.rowNumber) { + schema.rowNumber = {}; + } + schema.rowNumber[propertyKey] = propertyValue; + }, + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + return schema.rowNumber ? schema.rowNumber[propertyKey] : schema[propertyKey]; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts new file mode 100644 index 00000000000..f3e2f4c71f0 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/converter/type.converter.ts @@ -0,0 +1,10 @@ +import { ComponentSchema } from "../../../designer-canvas/src/types"; +import { DgControl } from "../../../designer-canvas/src/composition/dg-control"; +import { PropertyConverter, SchemaService } from "../types"; + +export default { + convertFrom: (schema: ComponentSchema, propertyKey: string, schemaService: SchemaService) => { + const foundValue=schema.editor&&schema.editor[propertyKey]?schema.editor[propertyKey]:schema[propertyKey]; + return DgControl[foundValue]?.name||foundValue; + } +} as PropertyConverter; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/editor-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/editor-resolver.ts new file mode 100644 index 00000000000..6a539482064 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/editor-resolver.ts @@ -0,0 +1,10 @@ +import { EditorResolver } from "./types"; + +export function createFormGroupEditorResolver(): EditorResolver { + function resolve(viewSchema: Record) { + return viewSchema.editor; + } + return { + resolve + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/event-handler-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/event-handler-resolver.ts new file mode 100644 index 00000000000..9d9954e304f --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/event-handler-resolver.ts @@ -0,0 +1,90 @@ +import { EventHandlerResolver, ViewEvent } from "./types"; + +export function createEventHandlerResolver(): EventHandlerResolver { + function resolve(schema: Record, event: ViewEvent) { + const { name } = event; + return schema[`on${name.charAt(0).toUpperCase()}${name.slice(1)}`] || schema[name]; + }; + return { + resolve + }; +} + +export function createPageHeaderEventHandlerResolver(): EventHandlerResolver { + function resolve(schema: Record, event: ViewEvent) { + const buttons = schema.toolbar?.buttons as any[]; + if (!buttons || buttons.length < 1) { + return null; + } + const [payload, buttonId] = event.payloads; + const button = buttons.find((button: Record) => button.id === buttonId); + if (!button) { + return null; + } + return button.onClick || button.click; + }; + return { + resolve + }; +} + +export function createTabsEventHandlerResolver(): EventHandlerResolver { + function resolve(schema: Record, event: ViewEvent) { + const tabPages = schema.contents; + if (!tabPages || tabPages.length < 1) { + return null; + } + + const buttons = tabPages.reduce((tabsButtons: any[], tabPage: any) => { + const tabPageButtons = tabPage.toolbar && tabPage.toolbar.buttons || []; + tabsButtons.push(...tabPageButtons); + return tabsButtons; + }, []); + if (!buttons || buttons.length < 1) { + return; + } + const [payload, buttonId] = event.payloads; + const button = buttons.find((button: Record) => button.id === buttonId); + if (!button) { + return null; + } + return button.onClick || button.click; + }; + return { + resolve + }; +} +export function createResponseToolbarEventHandlerResolver(): EventHandlerResolver { + function resolve(schema: Record, event: ViewEvent) { + const buttons = schema.buttons as any[]; + if (!buttons || buttons.length < 1) { + return null; + } + const [payload, buttonId] = event.payloads; + const button = buttons.find((button: Record) => button.id === buttonId); + if (!button) { + return null; + } + return button.onClick || button.click; + }; + return { + resolve + }; +} +export function createSectionEventHandlerResolver(): EventHandlerResolver { + function resolve(schema: Record, event: ViewEvent) { + const buttons = schema.toolbar?.buttons as any[]; + if (!buttons || buttons.length < 1) { + return null; + } + const [payload, buttonId] = event.payloads; + const button = buttons.find((button: Record) => button.id === buttonId); + if (!button) { + return null; + } + return button.onClick || button.click; + }; + return { + resolve + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/events-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/events-resolver.ts new file mode 100644 index 00000000000..fd66d0c5d42 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/events-resolver.ts @@ -0,0 +1,20 @@ + +import { EventDispatcher } from "./types"; + +export function createEventsResolver() { + return (component: any, schema: Record, dispatcher: EventDispatcher) => { + const token = schema.id; + const { type } = schema; + const events = component.emits as any[]; + if (!events) { + return {}; + } + return events.filter((eventName: string) => eventName !== 'update:modelValue').reduce((mergedEvents: Record, eventName: string) => { + const eventNameProp = `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`; + mergedEvents[eventNameProp] = (...payloads) => { + dispatcher.dispatch(token, eventName, type, payloads); + }; + return mergedEvents; + }, {}); + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/object-expression.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/object-expression.ts index e0dcb54de65..e4104b316de 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/object-expression.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/object-expression.ts @@ -1,10 +1,10 @@ export type ObjectExpressionFunction = (target: string, param: any, value: any, context: Record) => boolean; interface Expression { - target: string; - operator: string; - param: any; - value: any; + target: string; + operator: string; + param: any; + value: any; } /** @@ -71,99 +71,99 @@ interface Expression { */ export function useObjectExpression(extendFunctions: Record = {}) { - function judgingElementCount(target: string, param: any, value: any, context: Record) { - if (typeof value === 'number') { - return context[target].length === value; - } - if (typeof value === 'object') { - const compare = Object.keys(value)[0]; - const targetValue = value[compare]; - if (compare === 'not') { - return Number(context[target].length) !== Number(targetValue); - } - if (compare === 'moreThan') { - return Number(context[target].length) >= Number(targetValue); - } - if (compare === 'lessThan') { - return Number(context[target].length) <= Number(targetValue); - } + function judgingElementCount(target: string, param: any, value: any, context: Record) { + if (typeof value === 'number') { + return context[target].length === value; + } + if (typeof value === 'object') { + const compare = Object.keys(value)[0]; + const targetValue = value[compare]; + if (compare === 'not') { + return Number(context[target].length) !== Number(targetValue); + } + if (compare === 'moreThan') { + return Number(context[target].length) >= Number(targetValue); + } + if (compare === 'lessThan') { + return Number(context[target].length) <= Number(targetValue); + } + } + return false; } - return false; - } - function getProperty(target: string, param: any, value: any, context: Record) { - return context[param] && context[param].propertyValue && String(context[param].propertyValue.value) === String(value); - } + function getProperty(target: string, param: any, value: any, context: Record) { + return context[target] && context[target].propertyValue && String(context[target].propertyValue.value) === String(value); + } - const expressionCalculateFunctions = new Map([ - ['length', judgingElementCount], - ['getProperty', getProperty] - ]); + const expressionCalculateFunctions = new Map([ + ['length', judgingElementCount], + ['getProperty', getProperty] + ]); - Object.keys(extendFunctions).reduce((functionMaps: Map, operator: string) => { - functionMaps.set(operator, extendFunctions[operator]); - return functionMaps; - }, expressionCalculateFunctions); + Object.keys(extendFunctions).reduce((functionMaps: Map, operator: string) => { + functionMaps.set(operator, extendFunctions[operator]); + return functionMaps; + }, expressionCalculateFunctions); - function generateExpressions(token: string, valueObject: any): Expression[] { - const target = token; - if (typeof valueObject === 'number') { - return [{ target, operator: 'length', param: null, value: Number(valueObject) }]; - } - if (typeof valueObject === 'boolean') { - return [{ target, operator: 'getProperty', param: token, value: Boolean(valueObject) }]; - } - if (typeof valueObject === 'object') { - return Object.keys(valueObject).map((key: string) => { - if (key === 'length') { - return { target, operator: 'length', param: null, value: valueObject[key] }; + function generateExpressions(token: string, valueObject: any): Expression[] { + const target = token; + if (typeof valueObject === 'number') { + return [{ target, operator: 'length', param: null, value: Number(valueObject) }]; } - const param = key; - const value = valueObject[key]; - const operator = token; - return { target, operator, param, value }; - }); + if (typeof valueObject === 'boolean') { + return [{ target, operator: 'getProperty', param: token, value: Boolean(valueObject) }]; + } + if (typeof valueObject === 'object') { + return Object.keys(valueObject).map((key: string) => { + if (key === 'length') { + return { target, operator: 'length', param: null, value: valueObject[key] }; + } + const param = key; + const value = valueObject[key]; + const operator = 'getProperty'; + return { target, operator, param, value }; + }); + } + return []; } - return []; - } - function parseValueObjectToExpression(valueObject: Record): Expression[] { - const parsedExpression = Object.keys(valueObject).reduce((result: Expression[], token: string) => { - const expressions = generateExpressions(token, valueObject[token]); - result.push(...expressions); - return result; - }, []); - return parsedExpression; - } + function parseValueObjectToExpression(valueObject: Record): Expression[] { + const parsedExpression = Object.keys(valueObject).reduce((result: Expression[], token: string) => { + const expressions = generateExpressions(token, valueObject[token]); + result.push(...expressions); + return result; + }, []); + return parsedExpression; + } - function calculateExpression(expression: Expression, context: Record) { - if (expressionCalculateFunctions.has(expression.operator)) { - const calculateFunction = expressionCalculateFunctions.get(expression.operator); - return calculateFunction && calculateFunction(expression.target, expression.param, expression.value, context) || false; + function calculateExpression(expression: Expression, context: Record) { + if (expressionCalculateFunctions.has(expression.operator)) { + const calculateFunction = expressionCalculateFunctions.get(expression.operator); + return calculateFunction && calculateFunction(expression.target, expression.param, expression.value, context) || false; + } + return false; } - return false; - } - function calculate(valueObject: Record, context: Record): boolean { - const parsedExpression = parseValueObjectToExpression(valueObject); - const result = parsedExpression.reduce((parsingResult: boolean, expression: Expression) => { - return parsingResult && calculateExpression(expression, context); - }, true); + function calculate(valueObject: Record, context: Record): boolean { + const parsedExpression = parseValueObjectToExpression(valueObject); + const result = parsedExpression.reduce((parsingResult: boolean, expression: Expression) => { + return parsingResult && calculateExpression(expression, context); + }, true); - return result; - } + return result; + } - function parseValueSchema(valueSchema: Record, context: Record): boolean { - const schemaKeys = Object.keys(valueSchema); - const allOf = schemaKeys.includes('allOf'); - const anyOf = schemaKeys.includes('anyOf'); - const hasLogicalOperatorsInSchemaKey = allOf || anyOf; - const logicalOperator = hasLogicalOperatorsInSchemaKey ? (allOf ? 'allOf' : 'anyOf') : 'allOf'; - const valueObjects = (hasLogicalOperatorsInSchemaKey ? valueSchema[logicalOperator] : [valueSchema]) as Record[]; - const expressionValues = valueObjects.map((valueObject: Record) => calculate(valueObject, context)); - const result = allOf ? !expressionValues.includes(false) : expressionValues.includes(true); - return result; - } + function parseValueSchema(valueSchema: Record, context: Record): boolean { + const schemaKeys = Object.keys(valueSchema); + const allOf = schemaKeys.includes('allOf'); + const anyOf = schemaKeys.includes('anyOf'); + const hasLogicalOperatorsInSchemaKey = allOf || anyOf; + const logicalOperator = hasLogicalOperatorsInSchemaKey ? (allOf ? 'allOf' : 'anyOf') : 'allOf'; + const valueObjects = (hasLogicalOperatorsInSchemaKey ? valueSchema[logicalOperator] : [valueSchema]) as Record[]; + const expressionValues = valueObjects.map((valueObject: Record) => calculate(valueObject, context)); + const result = allOf ? !expressionValues.includes(false) : expressionValues.includes(true); + return result; + } - return { parseValueSchema }; + return { parseValueSchema }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts index e6c0ae88d0c..e28ab5abe92 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/property-config-resolver.ts @@ -1,170 +1,248 @@ -import { computed } from "vue"; -import { ElementPropertyConfig, PropertyEntity } from "../../designer-canvas/src/composition/entity/property-entity"; -import { EffectFunction, PropertyConverter, EditorConfig } from './types'; +import { computed, ref } from "vue"; +import { EffectFunction, PropertyConverter, SchemaService } from './types'; +import { EditorConfig } from "../../dynamic-form"; import { useObjectExpression } from './object-expression'; import { ComponentSchema } from "../../designer-canvas/src/types"; import { resolveSchemaWithDefaultValue } from "./schema-resolver"; -import propertyEditorConverter from "./converter/property-editor.converter"; +import appearanceConverter from './converter/appearance.converter'; import buttonsConverter from "./converter/buttons.converter"; +import propertyEditorConverter from "./converter/property-editor.converter"; +import typeConverter from "./converter/type.converter"; +import changeEditorConverter from "./converter/change-editor.converter"; +import fieldSelectorConverter from "./converter/field-selector.converter"; +import paginationConverter from "./converter/pagination.converter"; +import rowNumberConverter from "./converter/row-number.converter"; +import gridSelectionConverter from "./converter/grid-selection.converter"; +import itemsCountConverter from "./converter/items-count.converter"; +import enumDataConverter from "./converter/enum-data.converter"; +import formGroupLabelConverter from "./converter/form-group-label.converter"; +import { ElementPropertyConfig, PropertyEntity } from "@/components/property-panel"; const propertyConfigSchemaMap = {} as Record; const propertyConverterMap = new Map([ - ['/converter/property-editor.converter', propertyEditorConverter], - ['/converter/buttons.converter', buttonsConverter] + ['/converter/appearance.converter', appearanceConverter], + ['/converter/buttons.converter', buttonsConverter], + ['/converter/property-editor.converter', propertyEditorConverter], + ['/converter/items-count.converter', itemsCountConverter], + ['/converter/type.converter', typeConverter], + ['/converter/change-editor.converter', changeEditorConverter], + ['/converter/form-group-label.converter', formGroupLabelConverter], + ['/converter/field-selector.converter', fieldSelectorConverter], + ['/converter/pagination.converter', paginationConverter], + ['/converter/row-number.converter', rowNumberConverter], + ['/converter/grid-selection.converter', gridSelectionConverter], + ['/converter/enum-data.converter',enumDataConverter] ]); const propertyEffectMap = {} as Record; const propertyEditorMap = new Map([ - ['string', { type: 'input-group', enableClear: false }], - ['boolean', { - "type": "combo-list", - "textField": "name", - "valueField": "value", - "maxHeight": 64, - "data": [ - { - "value": true, - "name": "是" - }, - { - "value": false, - "name": "否" - } - ] - }], - ['enum', { "type": "combo-list", "maxHeight": 128, enableClear: false }], - ['array', { "type": "button-edit" }], - ['number', { "type": "number-spinner" }] + ['string', { type: 'input-group', enableClear: false }], + ['boolean', { + "type": "combo-list", + "textField": "name", + "valueField": "value", + "idField": "value", + "enableClear": false, + "editable": false, + "maxHeight": 64, + "data": [ + { + "value": true, + "name": "是" + }, + { + "value": false, + "name": "否" + } + ] + }], + ['enum', { "type": "combo-list", "maxHeight": 128, "enableClear": false, "editable": false }], + ['array', { "type": "button-edit" }], + ['number', { "type": "number-spinner","placeholder":"" }], + ['events-editor', { "type": "events-editor", hide: true }] ]); const useObjectExpressionComponstion = useObjectExpression(); function generateBooleanValue(pvalueSchema: Record, propertyConfigMap: Record) { - return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); + return () => useObjectExpressionComponstion.parseValueSchema(pvalueSchema, propertyConfigMap); } -function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { - if (propertySchemaKeys.includes('visible')) { - return typeof propertySchema.visible === 'boolean' ? - () => Boolean(propertySchema.visible) : - generateBooleanValue(propertySchema.visible, propertyConfigMap); - } - return () => true; +function isVisible(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) + : boolean | (() => boolean) { + if (propertySchemaKeys.includes('visible') && propertySchema.visible !== undefined) { + return typeof propertySchema.visible === 'boolean' ? + () => Boolean(propertySchema.visible) : + propertySchema.visible === undefined ? true : generateBooleanValue(propertySchema.visible, propertyConfigMap); + } + return () => true; } function isReadonly(propertySchemaKeys: string[], propertySchema: Record, propertyConfigMap: Record) { - if (propertySchemaKeys.includes('readonly')) { - return typeof propertySchema.visible === 'boolean' ? - () => Boolean(propertySchema.visible) : - generateBooleanValue(propertySchema.readonly, propertyConfigMap); - } - return () => false; + if (propertySchemaKeys.includes('readonly') && propertySchema.readonly !== undefined) { + return typeof propertySchema.readonly === 'boolean' ? + () => Boolean(propertySchema.readonly) : + generateBooleanValue(propertySchema.readonly, propertyConfigMap); + } + return () => false; } -function tryGetPropertyConverter(propertySchema: Record): PropertyConverter | null { - const { $converter } = propertySchema; - if ($converter && propertyConverterMap.has($converter)) { - return propertyConverterMap.get($converter) || null; - } - return null; +function tryGetPropertyConverter(propertySchema: Record, categoryConverter): PropertyConverter | null { + const $converter = propertySchema['$converter'] || categoryConverter; + if (typeof $converter === 'string') { + if ($converter && propertyConverterMap.has($converter)) { + return propertyConverterMap.get($converter) || null; + } + } + return $converter || null; } +/** + * + * @param propertiesInCategory + * 举例: + * visible: { + description: "运行时组件是否可见", + title: "是否可见", + type: "boolean" + } + 其中type属性 这个属性用来控制编辑器是哪一种,对应关系在propertyEditorMap中定义,boolean指定了下拉 + * @param propertyConfigMap + * @param editingSchema + * @param rawSchema + * @param schemaService + * @returns + */ function getPropertyEntities( - propertiesInCategory: Record, propertyConfigMap: Record, editingSchema: ComponentSchema, rawSchema: ComponentSchema + propertiesInCategory: Record, + propertyConfigMap: Record, + editingSchema: ComponentSchema, + rawSchema: ComponentSchema, + schemaService: SchemaService, + componentId = '', + categoryConverter: any = '' ): PropertyEntity[] { - const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { - const propertyID = propertyKey; - const propertySchema = propertiesInCategory[propertyKey]; - const propertySchemaKeys = Object.keys(propertySchema); - const propertyName = propertySchema.title; - const propertyType = propertySchema.type; - const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; - const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : defaultEditor; - const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); - const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); - const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema) : []; - const hideCascadeTitle = true; - const converter = tryGetPropertyConverter(propertySchema); - const propertyValue = computed({ - get() { - return (converter && converter.convertFrom) ? converter.convertFrom(editingSchema, propertyKey) : editingSchema[propertyKey]; - }, - set(newValue) { - if (converter && converter.convertTo) { - converter.convertTo(rawSchema, propertyKey, newValue); - converter.convertTo(editingSchema, propertyKey, newValue); - } else { - rawSchema[propertyKey] = newValue; - editingSchema[propertyKey] = newValue; - } - } - }); - const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle }; - propertyConfigMap[propertyID] = propertyEntity; - return propertyEntity; - }); - return propertyEntities; -} - -function getPropertyConfigByType(schemaType: string, schema = {} as ComponentSchema): ElementPropertyConfig[] { - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema); - return { categoryId, categoryName, properties }; + const propertyEntities = Object.keys(propertiesInCategory).map((propertyKey: string) => { + const updateCount = ref(1); + const propertyID = propertyKey; + const propertySchema = propertiesInCategory[propertyKey]; + const propertySchemaKeys = Object.keys(propertySchema); + const propertyName = propertySchema.title; + const propertyType = propertySchema.type; + const defaultEditor = propertyEditorMap.get(propertyType) || { type: 'input-group', enableClear: false }; + const editor = propertySchema.editor ? Object.assign({}, defaultEditor, propertySchema.editor) as EditorConfig : Object.assign({}, defaultEditor); + const visible = isVisible(propertySchemaKeys, propertySchema, propertyConfigMap); + const readonly = isReadonly(propertySchemaKeys, propertySchema, propertyConfigMap); + editor.readonly = editor.readonly===undefined?readonly():editor.readonly; + const cascadeConfig = propertySchema.type === 'cascade' ? getPropertyEntities(propertySchema.properties, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, categoryConverter) : []; + const hideCascadeTitle = true; + let converter = tryGetPropertyConverter(propertySchema, categoryConverter); + // const propertyValue = ref(converter ? converter.convertFrom(schema, propertyKey) : schema[propertyKey]); + const propertyValue = computed({ + get() { + if (updateCount.value) { + // class、style 统一处理 + if (['class', 'style'].find(id => id === propertyID) && !converter) { + converter = propertyConverterMap.get('/converter/appearance.converter') || null; + } + if (converter && converter.convertFrom) { + return converter.convertFrom(editingSchema, propertyKey, schemaService, componentId); + } + // 获取属性时,如果没有convertForm,并且通过在Schema上获取得值是空,那就获取defaultValue属性值或者是空 + const editingSchemaValue = editingSchema[propertyKey]; + return typeof editingSchemaValue == 'string' && editingSchemaValue === '' ? propertySchema['defaultValue'] || '' : editingSchemaValue; + } + return null; + }, + set(newValue) { + updateCount.value += 1; + if (converter && converter.convertTo) { + converter.convertTo(rawSchema, propertyKey, newValue, schemaService, componentId); + converter.convertTo(editingSchema, propertyKey, newValue, schemaService, componentId); + } else { + rawSchema[propertyKey] = newValue; + editingSchema[propertyKey] = newValue; + } + } + }); + const { refreshPanelAfterChanged } = propertySchema; + const propertyEntity = { propertyID, propertyName, propertyType, propertyValue, editor, visible, readonly, cascadeConfig, hideCascadeTitle, refreshPanelAfterChanged }; + propertyConfigMap[propertyID] = propertyEntity; + return propertyEntity; }); - return propertyConfigs; - } - return []; + return propertyEntities; } -function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema) { - const refSchemaPath = propertyCategory.$ref.schema; - const $converter = propertyCategory.$ref.converter; - const refSchema = rawSchema[refSchemaPath]; - - const schemaType = refSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyCategory = propertyConfigSchema.categories[categoryId]; - const categoryName = propertyCategory?.title; - if ($converter) { - Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { - propertyCategory.properties[propertyKey].$converter = $converter; - }); +function getPropertyConfigByType(schemaType: string, schemaService: SchemaService, schema = {} as ComponentSchema): ElementPropertyConfig[] { + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + const categoryName = propertyCategory?.title; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, {} as ComponentSchema, schema, schemaService); + return { categoryId, categoryName, properties }; + }); + return propertyConfigs; } - const propertiesInCategory = propertyCategory?.properties || {}; - const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema); - return { categoryId, categoryName, properties }; - - } - return { categoryId, categoryName: '', properties: [] }; + return []; } -function getPropertyConfigBySchema(rawSchema: ComponentSchema): ElementPropertyConfig[] { - const schemaType = rawSchema.type; - const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; - const propertyConfigMap = {} as Record; - const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; - if (propertyConfigSchema && propertyConfigSchema.categories) { - const propertyConfigs = Object.keys(propertyConfigSchema.categories) - .map((categoryId: string) => { +function tryToResolveReference(categoryId: string, propertyCategory: Record, rawSchema: ComponentSchema, schemaService: SchemaService, componentId = '') { + const refSchemaPath = propertyCategory.$ref.schema; + const $converter = propertyCategory.$ref.converter; + const refSchema = rawSchema[refSchemaPath]; + + const schemaType = refSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(refSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + const propertyConfigSchema = propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && propertyConfigSchema.categories) { const propertyCategory = propertyConfigSchema.categories[categoryId]; - if (propertyCategory.$ref) { - return tryToResolveReference(categoryId, propertyCategory, rawSchema) as ElementPropertyConfig; - } const categoryName = propertyCategory?.title; - const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema); + if ($converter) { + Object.keys(propertyCategory.properties).forEach((propertyKey: any) => { + propertyCategory.properties[propertyKey].$converter = $converter; + }); + } + const propertiesInCategory = propertyCategory?.properties || {}; + const properties = getPropertyEntities(propertiesInCategory, propertyConfigMap, editingSchema, refSchema, schemaService, componentId); return { categoryId, categoryName, properties }; - }) - .filter((propertyConfig: ElementPropertyConfig) => !!propertyConfig);; - return propertyConfigs; - } - return []; + + } + return { categoryId, categoryName: '', properties: [] }; +} + +// jumphere +function getPropertyConfigBySchema(rawSchema: ComponentSchema, schemaService: SchemaService, designerItem: any, componentId: string, propertyConfig?: Record): ElementPropertyConfig[] { + const schemaType = rawSchema.type; + const editingSchema = resolveSchemaWithDefaultValue(rawSchema) as ComponentSchema; + const propertyConfigMap = {} as Record; + + // 先从ConfigMap中取简单类属性,若找不到,则在控件实例中取复杂属性 + let propertyConfigSchema = propertyConfig || propertyConfigSchemaMap[schemaType]; + if (propertyConfigSchema && Object.keys(propertyConfigSchema).length === 0 && designerItem && designerItem.getPropConfig) { + propertyConfigSchema = designerItem.getPropConfig(componentId); + } + if (propertyConfigSchema && propertyConfigSchema.categories) { + const propertyConfigs = [] as Array; + Object.keys(propertyConfigSchema.categories).map((categoryId: string) => { + const propertyCategory = propertyConfigSchema.categories[categoryId]; + if (propertyCategory.$ref) { + propertyConfigs.push(tryToResolveReference(categoryId, propertyCategory, rawSchema, schemaService, componentId) as ElementPropertyConfig); + return; + } + const categoryName = propertyCategory?.title; + const tabId = propertyCategory?.tabId; + const tabName = propertyCategory?.tabName; + const hide = propertyCategory?.hide; + const hideTitle = propertyCategory?.hideTitle; + const properties = getPropertyEntities(propertyCategory.properties || {}, propertyConfigMap, editingSchema, rawSchema, schemaService, componentId, propertyCategory['$converter']); + const { setPropertyRelates } = propertyCategory; + propertyConfigs.push({ categoryId, categoryName, tabId, tabName, hide, properties, hideTitle, setPropertyRelates }); + }); + return propertyConfigs; + } + return []; } export { getPropertyConfigBySchema, getPropertyConfigByType, propertyConfigSchemaMap, propertyConverterMap, propertyEffectMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts index 0b08bc3244f..c1d99b457bf 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/props-resolver.ts @@ -1,30 +1,31 @@ +import { DesignerHostService } from './../../designer-canvas/src/composition/types'; import { resolveSchemaToProps, schemaMap, schemaResolverMap } from './schema-resolver'; import { DynamicResolver, EffectFunction, MapperFunction, SchemaResolverFunction } from './types'; import { propertyConfigSchemaMap, propertyEffectMap } from './property-config-resolver'; -export function createPropsResolver( - componentPropsObject: Record, - defaultSchema: Record, - schemaMapper: Map = new Map(), - schemaResolver: SchemaResolverFunction = ( - dynamicResolver: DynamicResolver, - schema: Record, - resolveContext: Record - ) => schema, - propertyConfig: Record = {}, - propertyEffect: EffectFunction = (properties: Record) => properties +export function createPropsResolver>( + componentPropsObject: T, + defaultSchema: Record, + schemaMapper: Map = new Map(), + schemaResolver: SchemaResolverFunction = ( + dynamicResolver: DynamicResolver, + schema: Record, + resolveContext: Record, + designerHostService?: DesignerHostService + ) => schema, + propertyConfig: Record = {}, + propertyEffect: EffectFunction = (properties: Record) => properties ) { - schemaMap[defaultSchema.title] = defaultSchema; - schemaResolverMap[defaultSchema.title] = schemaResolver; - propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; - propertyEffectMap[defaultSchema.title] = propertyEffect; - return (schemaValue: Record = {}) => { - const resolvedPropsValue = resolveSchemaToProps(schemaValue, defaultSchema, schemaMapper); - const defaultProps = Object.keys(componentPropsObject).reduce((propsObject: Record, propKey: string) => { - propsObject[propKey] = componentPropsObject[propKey].default; - return propsObject; - }, {}); - - return Object.assign(defaultProps, resolvedPropsValue); - }; + schemaMap[defaultSchema.title] = defaultSchema; + schemaResolverMap[defaultSchema.title] = schemaResolver; + propertyConfigSchemaMap[defaultSchema.title] = propertyConfig; + propertyEffectMap[defaultSchema.title] = propertyEffect; + return (schemaValue: Record = {}) => { + const resolvedPropsValue = resolveSchemaToProps(schemaValue, defaultSchema, schemaMapper); + const defaultProps = Object.keys(componentPropsObject).reduce((propsObject: Record, propKey: string) => { + propsObject[propKey] = componentPropsObject[propKey].default; + return propsObject; + }, {}); + return Object.assign(defaultProps, resolvedPropsValue); + }; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts index c7a46a9ef57..d2dada2e4dc 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/schema-resolver.ts @@ -1,81 +1,134 @@ -import { cloneDeep } from "lodash-es"; +import { cloneDeep, isPlainObject } from "lodash-es"; +import { DesignerHostService } from "../../designer-canvas/src/composition/types"; import { MapperFunction, SchemaResolverFunction } from "./types"; const schemaMap = {} as Record; const schemaResolverMap = {} as Record; function getSchemaValueByDefault(defaultSchema: Record): Record { - const { properties, title } = defaultSchema as Record; - const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { - propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? - getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); - return propsObject; - }, {}); - resolvedSchema.id = `${title}-${Date.now()}`; - return resolvedSchema; + const { properties, title, ignore: ignoreList } = defaultSchema as Record; + const canIgnoreProperty = ignoreList && Array.isArray(ignoreList); + const resolvedSchema = Object.keys(properties).reduce((propsObject: Record, propKey: string) => { + if (!canIgnoreProperty || !ignoreList.find(item => item === propKey)) { + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + } + return propsObject; + }, {}); + if (title && (!canIgnoreProperty || !ignoreList.find(item => item === 'id'))) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; } +/** + * 获取控件元数据,只组装必填的字段 + */ +function getRequiredSchemaValueByDefault(defaultSchema: Record): Record { + const { properties, title, required: requiredProperty } = defaultSchema as Record; + if (requiredProperty && Array.isArray(requiredProperty)) { + const resolvedSchema = requiredProperty.reduce((propsObject: Record, propKey: string) => { + + propsObject[propKey] = (properties[propKey].type === 'object' && !!properties[propKey].properties) ? + getSchemaValueByDefault(properties[propKey]) : cloneDeep(properties[propKey].default); + + return propsObject; + }, {}); + if (title && requiredProperty.find(item => item === 'id')) { + const typePrefix = title.toLowerCase().replace(/-/g, '_'); + resolvedSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`; + } + return resolvedSchema; + } + return { + type: title + }; -function getSchemaByType(componentType: string, resolveContext: Record = {}): Record | null { - const defaulSchema = schemaMap[componentType]; - if (defaulSchema) { - let componentSchema = getSchemaValueByDefault(defaulSchema); - const schemaResolver = schemaResolverMap[componentType]; - componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext) : componentSchema; - return componentSchema; - } - return null; +} +function getSchemaByType(componentType: string, resolveContext: Record = {}, designerHostService?: DesignerHostService) + : Record | null { + const defaultSchema = schemaMap[componentType]; + if (defaultSchema) { + let componentSchema = getRequiredSchemaValueByDefault(defaultSchema); + const schemaResolver = schemaResolverMap[componentType]; + componentSchema = schemaResolver ? schemaResolver({ getSchemaByType }, componentSchema, resolveContext, designerHostService) + : componentSchema; + return componentSchema; + } + return null; } function resolveSchema(schemaValue: Record, defaultSchema: Record): Record { - const resolvedSchema = getSchemaValueByDefault(defaultSchema); + const resolvedSchema = getSchemaValueByDefault(defaultSchema); - Object.keys(schemaValue).reduce((resolvedSchema: Record, propKey: string) => { - resolvedSchema[propKey] = schemaValue[propKey]; - return resolvedSchema; - }, resolvedSchema); + Object.keys(resolvedSchema).reduce((resolvedSchema: Record, propKey: string) => { + if (Object.prototype.hasOwnProperty.call(schemaValue, propKey)) { + // 解决属性是对象类型,默认值被冲掉的情况 + // 增加非判断,解决针对属性时对象,但是schemaValue=null或者undefined情况 + if (resolvedSchema[propKey] && isPlainObject(resolvedSchema[propKey]) && (isPlainObject(schemaValue[propKey] || !schemaValue[propKey]))) { + Object.assign(resolvedSchema[propKey], schemaValue[propKey] || {}); + } else { + resolvedSchema[propKey] = schemaValue[propKey]; + } + } + + return resolvedSchema; + }, resolvedSchema); - return resolvedSchema; + return resolvedSchema; }; function mappingSchemaToProps(resolvedSchema: Record, schemaMapper: Map) { - const props = Object.keys(resolvedSchema) - .filter((propKey: string) => resolvedSchema[propKey] != null) - .reduce((resolvedProps: Record, propKey: string) => { - if (schemaMapper.has(propKey)) { - const mapper = schemaMapper.get(propKey) as string | MapperFunction; - if (typeof mapper === 'string') { - resolvedProps[mapper] = resolvedSchema[propKey]; - } else { - const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); - Object.assign(resolvedProps, mapperResult); - } - } else { - resolvedProps[propKey] = resolvedSchema[propKey]; - } - return resolvedProps; - }, {}); - return props; + const props = Object.keys(resolvedSchema) + .filter((propKey: string) => resolvedSchema[propKey] != null) + .reduce((resolvedProps: Record, propKey: string) => { + if (schemaMapper.has(propKey)) { + const mapper = schemaMapper.get(propKey) as string | MapperFunction; + if (typeof mapper === 'string') { + resolvedProps[mapper] = resolvedSchema[propKey]; + } else { + const mapperResult = (mapper as MapperFunction)(propKey, resolvedSchema[propKey], resolvedSchema); + Object.assign(resolvedProps, mapperResult); + } + } else { + resolvedProps[propKey] = resolvedSchema[propKey]; + } + return resolvedProps; + }, {}); + return props; } function resolveSchemaToProps( - schemaValue: Record, - defaultSchema: Record, - schemaMapper: Map = new Map() + schemaValue: Record, + defaultSchema: Record, + schemaMapper: Map = new Map() ): Record { - const resolvedSchema = resolveSchema(schemaValue, defaultSchema); - const props = mappingSchemaToProps(resolvedSchema, schemaMapper); - return props; + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const props = mappingSchemaToProps(resolvedSchema, schemaMapper); + return props; } function resolveSchemaWithDefaultValue(schemaValue: Record): Record { - const componentType = schemaValue.type; - if (componentType) { - const defaulSchema = schemaMap[componentType]; - const resolvedSchema = resolveSchema(schemaValue, defaulSchema); - return resolvedSchema; - } - return schemaValue; + const componentType = schemaValue.type; + if (componentType) { + const defaultSchema = schemaMap[componentType]; + if (!defaultSchema) { + return schemaValue; + } + const resolvedSchema = resolveSchema(schemaValue, defaultSchema); + const editorType = schemaValue.editor?.type || ''; + /* 解决schemeValue结构如下图场景,在editor下,获取不到date-picker类型的默认值的问题 + * {type:'input-group',...,editor:{type:'date-picker',...}} + */ + if (editorType) { + const defaulEditorSchema = schemaMap[editorType]; + const resolvedEditorSchema = resolveSchema(schemaValue.editor, defaulEditorSchema); + resolvedSchema.editor = resolvedEditorSchema; + } + return resolvedSchema; + } + return schemaValue; } export { getSchemaByType, resolveSchemaWithDefaultValue, resolveSchemaToProps, schemaMap, schemaResolverMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/selection-item-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/selection-item-resolver.ts new file mode 100644 index 00000000000..6b946eae93f --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/selection-item-resolver.ts @@ -0,0 +1,19 @@ +import { SelectionItemResolver } from "./types"; + +export function createDataGridSelectionItemResolver(): SelectionItemResolver { + function selectItemById(component: any, id: string) { + return component.selectItemById(id); + } + return { + selectItemById + }; +} + +export function createTreeGridSelectionItemResolver(): SelectionItemResolver { + function selectItemById(component: any, id: string) { + return component.selectItemById(id); + } + return { + selectItemById + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/types.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/types.ts index 5182a1bd958..c82d887f402 100644 --- a/packages/mobile-ui-vue/components/dynamic-resolver/src/types.ts +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/types.ts @@ -1,42 +1,83 @@ + +import { DesignerHostService } from "../../designer-canvas/src/composition/types"; + export type MapperFunction = (key: string, value: any, resolvedSchema?: any) => Record; +export interface SchemaService { + + closest: (componentId: string, componentType: string) => Record | null; + + getSchemaById: (string) => Record; + + load: (componentSchema: Record) => void; + + select: (root: Record, predicate: (child: Record) => boolean) => Record; + + getRealEditorType: (editorType: string) => string; +} + export interface PropertyConverter { - convertTo: (schema: Record, propertyKey: string, propertyValue: any) => void; + convertTo: (schema: Record, propertyKey: string, propertyValue: any, schemaService: SchemaService, componentId?: string) => void; - convertFrom: (schema: Record, propertyKey: string) => any; + convertFrom: (schema: Record, propertyKey: string, schemaService: SchemaService, componentId?: string) => any; } export interface DynamicResolver { - getSchemaByType: (componentType: string) => Record | null; - getPropertyConfigByType?: (componentType: string) => Record | null; + getSchemaByType: (componentType: string, resolveContext?: Record, designerHostService?: DesignerHostService) => Record | null; + getPropertyConfigByType?: (componentType: string) => Record | null; }; export type SchemaResolverFunction = ( - dynamicResolver: DynamicResolver, - schema: Record, - resolveContext: Record + dynamicResolver: DynamicResolver, + schema: Record, + resolveContext: Record, + designerHostService?: DesignerHostService ) => Record; export type EffectFunction = (source: Record) => Record; -export type EditorType = 'button-edit' | 'check-box' | 'combo-list' | 'combo-lookup' - | 'date-picker' | 'date-range' | 'datetime-picker' | 'datetime-range' | 'month-picker' | 'month-range' | 'year-picker' | 'year-range' - | 'input-group' | 'lookup' | 'number-range' | 'number-spinner' | 'radio-group' | 'text'; - -export interface EditorConfig { - /** 编辑器类型 */ - type: EditorType; - /** 自定义样式 */ - customClass?: string; - /** 禁用 */ - disable?: boolean; - /** 只读 */ - readonly?: boolean; - /** 必填 */ - required?: boolean; - /** 提示文本 */ - placeholder?: string; - /** 其他属性 */ - [key: string]: any; +export interface EventDispatcher { + dispatch(token: string, eventName: string, ...payloads); +} + +export interface BindingModel { + getValue(field: string); + setValue(field: string, value: any); + getList(dataSource: string); + updateData(...payloads); + dataMapping(...payloads); +} + +export interface BindingData { + getValue(elementId: string); + setValue(elementId: string, field: string, value: any); +} +export interface BindingResolver { + resolve(schema: Record, bindingData: BindingData); +} + +export interface SelectionItemResolver { + selectItemById(component: any, id: string); +} + +export interface EditorResolver { + resolve(schema: Record); +} + +export interface UpdateColumnsResolver { + updateColumns(component: any ,schema: Record); +} + +export interface ViewEvent { + token: string; + type: string; + name: string; + payloads: any[]; +} +export interface EventHandlerResolver { + resolve(schema: Record, event: ViewEvent); +} +export interface Caller { + call: (methodName: string, ...payloads: any[]) => any; } diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/update-columns-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/update-columns-resolver.ts new file mode 100644 index 00000000000..a6556e0fc80 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/update-columns-resolver.ts @@ -0,0 +1,11 @@ +import { UpdateColumnsResolver } from "./types"; + +export function createDataViewUpdateColumnsResolver(): UpdateColumnsResolver { + function updateColumns(component: any, schema: Record) { + const { columns } = schema; + return component.updateColumns(columns); + } + return { + updateColumns + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-resolver/src/visible-prop-resolver.ts b/packages/mobile-ui-vue/components/dynamic-resolver/src/visible-prop-resolver.ts new file mode 100644 index 00000000000..94a6e09666e --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-resolver/src/visible-prop-resolver.ts @@ -0,0 +1,8 @@ +export function createVisiblePropResolver() { + function resolve(schema: Record) { + return Object.prototype.hasOwnProperty.call(schema, 'visible') ? schema.visible : null; + } + return { + resolve + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/index.ts b/packages/mobile-ui-vue/components/dynamic-view/index.ts index 8aaf1dfb4e1..7b3e294e2e8 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/index.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/index.ts @@ -1,12 +1,12 @@ import type { App } from 'vue'; -import DynamicView from './src/dynamic-view.component'; +import FDynamicView from './src/dynamic-view.component'; export * from './src/dynamic-view.props'; -export { DynamicView }; +export { FDynamicView }; export default { - install(app: App): void { - app.component(DynamicView.name, DynamicView); - } + install(app: App): void { + app.component(FDynamicView.name as string, FDynamicView); + } }; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts new file mode 100644 index 00000000000..77070fdc522 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/callback-deliver.ts @@ -0,0 +1,10 @@ +import { Caller } from "../../dynamic-resolver"; + +export function createCallbackDeliver(callback: (type: string, args: any[]) => any): Caller { + function call(methodName: string, payloads: any[]): any { + return callback(methodName, payloads); + } + return { + call + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts b/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts index b7768c77cba..d053ec61421 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/src/components/maps.ts @@ -1,24 +1,20 @@ -import PageContainer from '../../../page-container'; -import PageBodyContainer from '../../../page-body-container'; -import PageHeaderContainer from '../../../page-header-container'; -import PageFooterContainer from '../../../page-footer-container'; -import ListView from '../../../list-view'; + +// import FExternalContainer from '@/components/external-container'; const componentMap: Record = {}; const componentPropsConverter: Record = {}; const componentPropertyConfigConverter: Record = {}; +const resolverMap: Record = {}; let hasLoaded = false; +// jumphere function loadRegister() { - if (!hasLoaded) { - hasLoaded = true; - PageContainer.register(componentMap, componentPropsConverter, componentPropertyConfigConverter); - PageBodyContainer.register(componentMap, componentPropsConverter, componentPropertyConfigConverter); - PageHeaderContainer.register(componentMap, componentPropsConverter, componentPropertyConfigConverter); - PageFooterContainer.register(componentMap, componentPropsConverter, componentPropertyConfigConverter); - ListView.register(componentMap, componentPropsConverter, componentPropertyConfigConverter); - } + if (!hasLoaded) { + hasLoaded = true; + // FAvatar.register(componentMap, componentPropsConverter, componentPropertyConfigConverter, resolverMap); + + } } -export { componentMap, componentPropsConverter, loadRegister }; +export { componentMap, componentPropsConverter, loadRegister, resolverMap }; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts new file mode 100644 index 00000000000..9828d143ccb --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/index.ts @@ -0,0 +1,3 @@ +export * from './use-form-schema'; +export * from './use-binding-data'; +export * from './use-component-manager'; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts new file mode 100644 index 00000000000..f569b2703ee --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-binding-data.ts @@ -0,0 +1,20 @@ +import { BindingData } from "../../../dynamic-resolver"; +import { Ref, SetupContext } from "vue"; + +export function useBindingData(modelValue: Ref>, setupContext: SetupContext): BindingData { + function getValue(elementId: string) { + return modelValue.value && modelValue.value[elementId]; + } + + function setValue(elementId: string, field: string, value: any) { + if (modelValue.value) { + modelValue.value[elementId] = value; + } + setupContext.emit('update:modelValue', { elementId, field, value, modelValue: modelValue.value }); + } + + return { + getValue, + setValue + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts new file mode 100644 index 00000000000..620a2057382 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-component-manager.ts @@ -0,0 +1,51 @@ +import { UseComponentInstanceManager } from "../types"; + +export function useComponentManager(): UseComponentInstanceManager { + const instances: Map = new Map(); + + function register(id: string, instance: any) { + instances.set(id, instance); + } + + function get(id: string) { + const instance = instances.get(id); + if (!instance) { + console.warn(`Instance with id ${id} not found`); + return null; + } + return instance; + } + + function remove(id: string) { + instances.delete(id); + } + + function update(id: string, instance: any) { + if (!instances.has(id)) { + console.warn(`Instance with id ${id} not found`); + return; + } + instances.set(id, instance); + } + + function has(id: string): boolean { + return instances.has(id); + } + + function getAll(): Map { + return new Map(instances); + } + + function clear() { + instances.clear(); + } + return { + register, + get, + remove, + update, + has, + getAll, + clear + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts new file mode 100644 index 00000000000..95169ec23fe --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-resolver.ts @@ -0,0 +1,69 @@ +/* eslint-disable no-use-before-define */ +import { ResolvedEntity, EntitySchema, UseEntityResolver } from "../types"; +import { useFormSchema } from "./use-form-schema"; + +export function useEntityResolver(schema: Record): UseEntityResolver { + const { getSchemaEntity } = useFormSchema(schema); + function resolveEntityByDataSource(dataSource: string): ResolvedEntity | null { + const entity = getSchemaEntity(); + const entityInfo = resolveEntity(entity, dataSource); + return entityInfo; + } + function resolveEntities(entitySchema: EntitySchema): ResolvedEntity[] { + const result: ResolvedEntity[] = []; + function traverse(entity: EntitySchema, path: string[]) { + const currentPath = [...path, entity.label]; + const primary = entitySchema?.type?.primary || null; + if (primary) { + result.push({ + bindingPaths: currentPath, + primaryKey: entity.type.primary, + label: entity.label + }); + } + entity.type.entities.forEach(childEntity => { + traverse(childEntity, currentPath); + }); + } + const primary = entitySchema?.type?.primary || null; + if (!primary) { + return result; + } + result.push({ + bindingPaths: [], + primaryKey: entitySchema.type.primary, + label: entitySchema.label + }); + const childEntities = entitySchema?.type?.entities || []; + childEntities.forEach((entity) => { + traverse(entity, []); + }); + return result; + } + function resolveEntity(entity: Record, entityLabel: string, isRoot: boolean = true): ResolvedEntity | null { + const currentPath = isRoot ? [] : [entity.label]; + if (entity.label === entityLabel) { + return { + bindingPaths: currentPath, + primaryKey: entity.type.primary, + label: entity.label + }; + } + for (const childEntity of entity.type.entities) { + const result = resolveEntity(childEntity, entityLabel, false); + if (result) { + return { + bindingPaths: [...currentPath, ...result.bindingPaths], + primaryKey: result.primaryKey, + label: result.label + }; + } + } + return null; + } + return { + resolveEntityByDataSource, + resolveEntity, + resolveEntities + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts new file mode 100644 index 00000000000..1255c85431e --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity-state.ts @@ -0,0 +1,32 @@ +import { EntityState, ResolvedEntity } from "../types"; +import { useEntityResolver } from "./use-entity-resolver"; +import { useFormSchema } from "./use-form-schema"; + +export function useEntityState(schema: Record) { + const bindingContexts: Record = {}; + const { getSchemaEntity } = useFormSchema(schema); + const { resolveEntities } = useEntityResolver(schema); + + function setup() { + const schemaEntity = getSchemaEntity(); + const entities = resolveEntities(schemaEntity); + entities.forEach((entity: ResolvedEntity) => { + const bindingPath = '/' + entity.bindingPaths.join('/'); + const { primaryKey } = entity; + const bindingContext: EntityState = { primaryKey, bindingPath, label: entity.label, currentId: null }; + bindingContexts[bindingPath] = bindingContext; + }); + } + function get(bindingPath: string | string[]): EntityState { + if (Array.isArray(bindingPath)) { + bindingPath = '/' + bindingPath.join('/'); + } else { + bindingPath = '/' + bindingPath.split('/').filter((item: any) => item).join('/'); + } + return bindingContexts[bindingPath]; + } + return { + setup, + get + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts new file mode 100644 index 00000000000..bb3ba43b275 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-entity.ts @@ -0,0 +1,34 @@ +import { EntityState, ResolvedEntity } from "../types"; +import { useEntityResolver } from "./use-entity-resolver"; +import { useFormSchema } from "./use-form-schema"; + +export function useEntity(schema: Record) { + const bindingDataContexts: Record = {}; + const { getSchemaEntity } = useFormSchema(schema); + const { resolveEntities } = useEntityResolver(schema); + + function setup() { + const schemaEntity = getSchemaEntity(); + const entities = resolveEntities(schemaEntity); + entities.forEach((entity: ResolvedEntity) => { + const bindingPath = '/' + entity.bindingPaths.join('/'); + const { primaryKey } = entity; + const bindingContext: EntityState = { primaryKey, bindingPath, currentId: null, label: entity.label }; + // jumphere by sagi + bindingContext['dataSource'] = entity.label; + bindingDataContexts[bindingPath] = bindingContext; + }); + } + function get(bindingPath: string | string[]): EntityState { + if (Array.isArray(bindingPath)) { + bindingPath = '/' + bindingPath.join('/'); + } else { + bindingPath = '/' + bindingPath.split('/').filter((item: any) => item).join('/'); + } + return bindingDataContexts[bindingPath]; + } + return { + setup, + get + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts new file mode 100644 index 00000000000..29206d38d88 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-field-resolver.ts @@ -0,0 +1,50 @@ +/* eslint-disable no-use-before-define */ + +import { ResolvedEntityField, UseFieldResolver } from "../types"; +import { useFormSchema } from "./use-form-schema"; + +export function useFieldResolver(schema: Record): UseFieldResolver { + const { getSchemaEntity } = useFormSchema(schema); + function resolveFieldById(fieldId: string): ResolvedEntityField | null { + const entity = getSchemaEntity(); + const fieldInfo = resolveField(entity, fieldId); + return fieldInfo; + } + + function resolveField(entitySchema: Record, fieldId: string): ResolvedEntityField | null { + const { fields } = entitySchema.type; + for (const field of fields) { + if (field.id === fieldId) { + return { + id: field.id, + bindingPath: field.bindingPath, + require: field.require, + readonly: field.readonly, + multiLanguage: field.multiLanguage, + label: field.label, + dataSource: entitySchema.label + }; + } + if (field.type && field.type.fields) { + const result = resolveField({ type: field.type, label: entitySchema.label }, fieldId); + if (result) { + return result; + } + } + } + const { entities } = entitySchema.type; + if (!entities || entities.length < 1) { + return null; + } + for (const entity of entities) { + const result = resolveField(entity, fieldId); + if (result) { + return result; + } + } + return null; + } + return { + resolveFieldById + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts new file mode 100644 index 00000000000..f39c41aef55 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/composition/use-form-schema.ts @@ -0,0 +1,11 @@ +import { EntitySchema } from "../types"; + +export function useFormSchema(schema: Record) { + function getSchemaEntity(): EntitySchema { + return schema?.module?.entity[0]?.entities[0] || {}; + } + + return { + getSchemaEntity + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx index f43f3fbc3c4..2bf3634cc82 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.component.tsx @@ -1,55 +1,291 @@ -import { SetupContext, defineComponent, toRef } from 'vue'; +/* eslint-disable @typescript-eslint/no-unsafe-function-type */ +/* eslint-disable no-use-before-define */ +import { SetupContext, defineComponent, ref, watch, inject, createVNode, VNode } from 'vue'; +import { merge } from 'lodash-es'; import { dynamicViewProps, DynamicViewProps } from './dynamic-view.props'; -import { componentMap, componentPropsConverter, loadRegister } from './components/maps'; +import { componentMap, componentPropsConverter, loadRegister, resolverMap } from './components/maps'; +import { createEventsResolver, createFormBindingResolver, EditorResolver, SelectionItemResolver, UpdateColumnsResolver } from '../../dynamic-resolver'; +import { createEventDispatcher } from './event-dispatcher'; +import { useComponentManager } from './composition/use-component-manager'; +import { useBindingData } from './composition/use-binding-data'; +import { useEntityState } from './composition/use-entity-state'; +import { createCallbackDeliver } from './callback-deliver'; const FDynamicView = defineComponent({ - name: 'FDynamicView', - props: dynamicViewProps, - emits: ['update:modelValue'], - setup(props: DynamicViewProps, context: SetupContext) { - const modelValue = toRef(props, 'modelValue'); - loadRegister(); - - function renderContent(contents: any[]) { - return contents.map((contentSchema: any) => { - return ; - }); - } + name: 'FDynamicView', + props: dynamicViewProps, + emits: ['update:modelValue', 'event', 'componentReady'], + setup(props: DynamicViewProps, setupContext: SetupContext) { + const schema = ref(props.schema); + const modelValue = ref(props.modelValue); + const callback = ref(props.callback); + const schemaMap: Map = new Map(); + const dataSourceMap: Map = new Map(); + loadRegister(); + const componentManager = useComponentManager(); + const bindingData = useBindingData(modelValue, setupContext); + const entityState = useEntityState(schema.value); + entityState.setup(); - function render(viewSchema: any) { - const componentKey = viewSchema.type; - if (componentKey === 'ContentContainer') { - return
{renderContent(viewSchema.contents)}
; - } - const Component = componentMap[componentKey]; - - const propsConverter = componentPropsConverter[componentKey]; - const viewProps = propsConverter ? propsConverter(viewSchema) : {}; - - const hasContent = viewSchema.contents && !!viewSchema.contents.length; - const contentMap = hasContent - ? (viewSchema.contents as Record[]).reduce((mapResult: Record, content: Record) => { - const slot = content.slot || 'default'; - mapResult[slot] = [...(mapResult[slot] || []), content]; - return mapResult; - }, {}) - : {}; - const contentsRender = Object.keys(contentMap).reduce((render: Record, slot: string) => { - render[slot] = () => renderContent(contentMap[slot]); - return render; - }, {}); - return hasContent && Component ? ( - {contentsRender} - ) : Component ? ( - - ) : ( -
- ); - } + function resolveModels(viewSchema: Record) { + const componentType = viewSchema.type; + const { dataSource, binding } = viewSchema; + if (!dataSource && !binding) { + return {}; + } + if (dataSource) { + dataSourceMap.set(dataSource, viewSchema); + } + const resolver = resolverMap[componentType]; + const bindingResolver = resolver && resolver.bindingResolver ? resolver.bindingResolver : createFormBindingResolver(); + return bindingResolver.resolve(viewSchema, bindingData); + } + + function renderSlots(slots?: Record) { + const result: Record = {}; + if (!slots) { + return result; + } + Object.entries(slots).forEach(([name, schema]) => { + result[name] = () => { + if (Array.isArray(schema)) { + return schema.map((schema: Record) => render(schema)); + } + return render(schema); + }; + }); + return result; + } + + function resolveCallbacks(viewSchema: Record) { + const componentKey = viewSchema.type; + const resolvers = resolverMap[componentKey]; + if (!resolvers || Object.keys(resolvers).length < 1) { + return {}; + } + const { callbackResolver } = resolvers; + if (!callbackResolver) { + return {}; + } + const callbackDeliver = createCallbackDeliver(callback.value); + return callbackResolver.resolve(viewSchema, callbackDeliver); + } + function resolveEvents(viewSchema: Record) { + const componentKey = viewSchema.type; + const eventDispatcher = createEventDispatcher(setupContext, viewSchema); + const Component = componentMap[componentKey]; + const eventResolver = createEventsResolver(); + const resolver = resolverMap[componentKey]; + const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; + if (editorResolver) { + const editor = editorResolver.resolve(viewSchema); + const componentType = editor.type; + const Editor = componentMap[componentType]; + const eventProps = eventResolver ? eventResolver(Editor, viewSchema, eventDispatcher) : {}; + return eventProps; + } + const eventProps = eventResolver ? eventResolver(Component, viewSchema, eventDispatcher) : {}; + return eventProps; + } + + function resolveExtraProps(viewSchema: Record) { + // const componentKey = viewSchema.type; + // const resolver = resolverMap[componentKey]; + // const extraPropsResolver: ExtraPropsResolver | null = resolver ? resolver.extraPropsResolver : null; + // if (!extraPropsResolver) { + // return {}; + // } + // return extraPropsResolver.resolve(viewSchema); + return {}; + } + + function resolveProps(viewSchema: Record) { + const componentKey = viewSchema.type; + const propsConverter = componentPropsConverter[componentKey]; + const componentProps: Record = propsConverter ? propsConverter(viewSchema) : {}; + // const Component = componentMap[componentKey]; + // const componentPropertyProps = Object.keys(Component?.props || {}); + // const componentEventProps = (Component?.emits as string[] || []).map((eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`); + // const currentComponentProps = componentPropertyProps.concat(componentEventProps); + // const componentProps = Object.keys(componentSchema).reduce((props: Record, propertyName: string) => { + // if (currentComponentProps.indexOf(propertyName) !== -1) { + // props[propertyName] = componentSchema[propertyName]; + // } + // return props; + // }, {}); + const eventProps = { + ...resolveEvents(viewSchema) + }; + const viewProps = { + ...componentProps, + ...resolveModels(viewSchema), + ...resolveExtraProps(viewSchema), + ...resolveCallbacks(viewSchema) + }; + const props = { + ...viewProps, + key: viewSchema.id, + ref: (componentRef: any) => { + if (componentRef && viewSchema.id && !componentManager.has(viewSchema.id)) { + componentManager.register(viewSchema.id, componentRef); + setupContext.emit('componentReady', { ref: ref(componentRef), id: viewSchema.id, type: viewSchema.type }); + } + } + }; + return { props, eventProps }; + } + + function render(viewSchema: Record) { + const componentKey = viewSchema.type; + + if (componentKey === 'component-ref') { + const componentSchema = schema.value?.module?.components + .find((component: any) => component.id === viewSchema.component); + if (componentSchema) { + return render(componentSchema); + } + } + + if (viewSchema.id) { + schemaMap.set(viewSchema.id, viewSchema); + } + const Component = componentMap[componentKey]; + if (!Component) { + return null; + } + const { props, eventProps } = resolveProps(viewSchema); + + const renderChildren = () => { + if (!viewSchema.contents) { + return null; + } + if (typeof viewSchema.contents === 'string') { + return viewSchema.contents; + } + return viewSchema.contents.map((schema: Record) => render(schema)); + }; + const resolver = resolverMap[componentKey]; + const editorResolver: EditorResolver = resolver ? resolver.editorResolver : null; + if (editorResolver) { + const editor = editorResolver.resolve(viewSchema); + Object.assign(editor, eventProps); + } else { + Object.assign(props, eventProps); + } + const createNode = (componentType: any, props: Record, children?: null | undefined | any[]) => { + if (children && children.length > 0) { + return createVNode(componentType, { ...props }, children); + } else { + return createVNode(componentType, { ...props }, null); + } + }; + if (viewSchema.contents && viewSchema.contents.length > 0) { + return createNode(Component, props, [renderChildren()]); + } else if (viewSchema.slots) { + return createNode(Component, props, [...Object.values(renderSlots(viewSchema.slots))]); + } else { + return createNode(Component, props); + } + } - return () => { - return render(modelValue.value); - }; - } + function rerender(component: any) { + if (component.$forceUpdate) { + component.$forceUpdate(); + } + } + + function getSchema(id: string) { + return schemaMap.get(id); + } + + function setSchema(id: string, partialSchema: Record) { + const elementSchema = schemaMap.get(id); + if (!elementSchema) { + return; + } + const componentInstance = componentManager.get(id); + if (!componentInstance) { + return; + } + merge(elementSchema, partialSchema); + const componentKey = elementSchema.type; + const resolver = resolverMap[componentKey]; + const updateColumnsResolver: UpdateColumnsResolver = resolver ? resolver.updateColumnsResolver : null; + if (updateColumnsResolver) { + updateColumnsResolver.updateColumns(componentInstance, elementSchema); + } + rerender(componentInstance); + } + + function getProps(id: string): Record { + const instance = componentManager.get(id); + return instance.$props || {}; + } + + function setProps(id: string, props: Record) { + const componentInstance = componentManager.get(id); + if (!componentInstance) { + return; + } + const elementSchema = schemaMap.get(id); + if (!elementSchema) { + return; + } + merge(elementSchema, props); + rerender(componentInstance); + } + + function invoke(id: string, method: string, ...args: any[]): any { + const componentInstance = componentManager.get(id); + if (!componentInstance) { + return; + } + if (!componentInstance || typeof componentInstance[method] !== 'function') { + throw new Error(`Method ${method} not found on instance ${id}`); + } + return componentInstance[method](...args); + } + + function selectItemById(bindingPath: string, id: string) { + const bindingEntityState = entityState.get(bindingPath); + if (!bindingEntityState) { + return; + } + const entityLabel = bindingEntityState.label; + const viewSchema = dataSourceMap.get(entityLabel); + if (!viewSchema) { + return; + } + const componentType = viewSchema.type; + const resolver = resolverMap[componentType]; + const selectionMethodResolver: SelectionItemResolver | null = resolver ? resolver.selectionItemResolver : null; + if (selectionMethodResolver) { + const Component = componentManager.get(viewSchema.id); + selectionMethodResolver.selectItemById(Component, id); + } + } + + watch( + [() => props.modelValue, () => props.schema], + ([newModelValue, newSchema]) => { + modelValue.value = newModelValue; + schema.value = newSchema; + } + ); + + setupContext.expose({ componentManager, rerender, getProps, invoke, setProps, getSchema, setSchema, selectItemById }); + + return () => { + const components: Record[] = schema.value?.module?.components; + if (!components || components.length < 1) { + return null; + } + const frameComponent = components.find((component: Record) => component.componentType && component.componentType.toLowerCase() === 'frame'); + if (!frameComponent) { + return null; + } + return render(frameComponent); + }; + } }); export default FDynamicView; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts index a08158711f0..116990adad7 100644 --- a/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts +++ b/packages/mobile-ui-vue/components/dynamic-view/src/dynamic-view.props.ts @@ -1,10 +1,17 @@ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; export const dynamicViewProps = { - schema: { type: Object, default: {} }, - /** - * 组件值 - */ - modelValue: { type: Object, default: {} }, + /** + * schema + */ + schema: { type: Object, default: null }, + /** + * 组件值 + */ + modelValue: { type: Object as PropType>, default: null }, + /** + * 回调 + */ + callback: { type: Function as PropType<(type: string, ...args: unknown[]) => any>, default: () => { } } }; export type DynamicViewProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts b/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts new file mode 100644 index 00000000000..37b0c47fa49 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/event-dispatcher.ts @@ -0,0 +1,16 @@ + +import { SetupContext } from "vue"; +import { createEventHandlerResolver, EventDispatcher } from "../../dynamic-resolver"; +import { resolverMap } from "./components/maps"; + +export function createEventDispatcher(context: SetupContext, schema: Record): EventDispatcher { + function dispatch(token: string, eventName: string, type: string, payloads: any[]) { + const resolver = resolverMap[type]; + const eventHandlerResolver = resolver && resolver.eventHandlerResolver ? resolver.eventHandlerResolver : createEventHandlerResolver(); + const eventHandler = eventHandlerResolver.resolve(schema, { token, name: eventName, type, payloads }); + context.emit('event', { token, name: eventName, type, payloads, handler: eventHandler, schema }); + } + return { + dispatch + }; +} diff --git a/packages/mobile-ui-vue/components/dynamic-view/src/types.ts b/packages/mobile-ui-vue/components/dynamic-view/src/types.ts new file mode 100644 index 00000000000..07c3f181906 --- /dev/null +++ b/packages/mobile-ui-vue/components/dynamic-view/src/types.ts @@ -0,0 +1,83 @@ +/* eslint-disable no-use-before-define */ +export interface EntityState { + primaryKey: string; + bindingPath: string; + currentId: string | null; + label: string; +} + +export interface UseBindingContext { + setup(); + get(bindingPath: string | string[]): EntityState; +} + +export interface EntityFieldSchema { + id: string; + require: any; + multiLanguage: boolean; + defaultValue: any; + readonly: any; + bindingPath: string; + label: string; + type: Record; + name: string; +} + +export interface EntityTypeSchema { + entities: EntitySchema[]; + primary: string; + displayName: string; + fields: EntityFieldSchema[]; + name: string; +} +export interface EntitySchema { + id: string; + label: string; + code: string; + type: EntityTypeSchema; + name: string; +} + +export interface ResolvedEntity { + bindingPaths: string[]; + primaryKey: string; + label: string; +} + +export interface ResolvedEntityField { + id: string; + bindingPath: string; + require: any; + readonly: any; + multiLanguage: boolean; + label: string; + dataSource: string; +} + +export interface UseEntityResolver { + resolveEntityByDataSource(dataSource: string): ResolvedEntity | null; + resolveEntities(entitySchema: EntitySchema): ResolvedEntity[]; + resolveEntity(entity: Record, entityLabel: string, isRoot?: boolean): ResolvedEntity | null; +} + +export interface UseFieldResolver { + resolveFieldById(fieldId: string): ResolvedEntityField | null; +} + +// export interface UseBindingData { +// currentId: ComputedRef; +// primaryKey: ComputedRef; +// bindingList: ComputedRef; +// currentItem: ComputedRef; +// setValueByPath(bindingPath: string, value: any); +// } + +export interface UseComponentInstanceManager { + register(id: string, instance: any): void; + get(id: string): any | null; + remove(id: string): void; + update(id: string, instance: any): void; + has(id: string): boolean; + getAll(): Map; + clear(): void; +} diff --git a/packages/mobile-ui-vue/components/index.ts b/packages/mobile-ui-vue/components/index.ts index df0d1934731..657cb330b5c 100644 --- a/packages/mobile-ui-vue/components/index.ts +++ b/packages/mobile-ui-vue/components/index.ts @@ -55,10 +55,19 @@ import Tab from './tab'; import Tabs from './tabs'; import Tag from './tag'; import * as Utils from './common/src/utils'; -// import { PageContainer } from './page-container'; -// import { PageBodyContainer } from './page-body-container'; -// import { PageHeaderContainer } from './page-header-container'; -// import { PageFooterContainer } from './page-footer-container'; +// import PageContainer from './page-container'; +// import PageBodyContainer from './page-body-container'; +// import PageHeaderContainer from './page-header-container'; +// import PageFooterContainer from './page-footer-container'; +// import Component from './component'; +// import ContentContainerfrom './content-container'; +// import FloatContainer from './float-container'; + +import Common from './common'; +import Modal from './modal'; +import DynamicView from './dynamic-view'; +import FDesignerCanvas from './designer-canvas'; +export * from './designer'; const components = [ Button, @@ -103,7 +112,14 @@ const components = [ // PageBodyContainer, // PageHeaderContainer, // PageFooterContainer, - Overlay + Overlay, + // Component, + // ContentContainer, + // FloatContainer, + Common, + Modal, + DynamicView, + FDesignerCanvas ]; const install = (app: App): void => { @@ -155,7 +171,14 @@ export { // PageBodyContainer, // PageHeaderContainer, // PageFooterContainer, - Utils + Utils, + // Component, + // ContentContainer, + // FloatContainer, + Common, + Modal, + DynamicView, + FDesignerCanvas }; export default { diff --git a/packages/mobile-ui-vue/components/modal/index.ts b/packages/mobile-ui-vue/components/modal/index.ts new file mode 100644 index 00000000000..cea142d232b --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/index.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import type { App, Plugin } from 'vue'; +import FModal from './src/modal.component'; +import FModalService from './src/composition/modal.service'; + +export * from './src/modal.props'; + +export const F_MODAL_SERVICE_TOKEN = Symbol('FModalService'); + +FModal.install = (app: App) => { + app.component(FModal.name as string, FModal); + const modalInstance = new FModalService(app); + app.provide(F_MODAL_SERVICE_TOKEN, modalInstance); + app.provide('FModalService', modalInstance); +}; + +export { FModal, FModalService }; +export default FModal as typeof FModal & Plugin; diff --git a/packages/mobile-ui-vue/components/modal/src/components/modal-context-holder.component.tsx b/packages/mobile-ui-vue/components/modal/src/components/modal-context-holder.component.tsx new file mode 100644 index 00000000000..4f24d447152 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/components/modal-context-holder.component.tsx @@ -0,0 +1,23 @@ +import { defineComponent, SetupContext, shallowRef, VNode } from "vue"; + +export interface ContextHolder { + addModal: (modal: () => VNode) => () => void; +} +export default defineComponent({ + name: 'FModalContextHolder', + setup(props: any, context: SetupContext) { + const modals = shallowRef<(() => VNode)[]>([]); + const addModal = (modal: () => VNode) => { + modals.value.push(modal); + modals.value = modals.value.slice(); + return () => { + // 删除当前模态框 + modals.value = modals.value.filter(currentModal => currentModal !== modal); + }; + }; + context.expose({ addModal }); + return () => { + return modals.value.map(modal => modal()); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/modal/src/composition/destroy.ts b/packages/mobile-ui-vue/components/modal/src/composition/destroy.ts new file mode 100644 index 00000000000..e68523fb9e0 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/destroy.ts @@ -0,0 +1 @@ +export const destroyFunctionList: any[] = []; diff --git a/packages/mobile-ui-vue/components/modal/src/composition/modal.service.tsx b/packages/mobile-ui-vue/components/modal/src/composition/modal.service.tsx new file mode 100644 index 00000000000..ff8a7dc10cf --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/modal.service.tsx @@ -0,0 +1,263 @@ +import { ref, h, render, VNode, cloneVNode, shallowRef, nextTick, App, AppContext, createApp, onUnmounted, onMounted, computed } from "vue"; +import { ModalFunctions, ModalOptions } from "./type"; +import FModal from '../modal.component'; +// import FarrisPlugin from '../../../plugin'; + +function getContentRender(props: ModalOptions) { + if (props.content && props.content.render) { + return props.content.render; + } + if (props.render && typeof props.render === 'function') { + return props.render; + } +} + +function createModalInstance(options: ModalOptions) { + const container = document.createElement('div'); + container.style.display = 'contents'; + + const app: App = createApp({ + setup(props, context) { + + onUnmounted(() => { + document.body.removeChild(container); + }); + + const modalRef = ref(); + + const customClass = ref(options.class || ''); + const showButtons = ref(!!options.showButtons); + const showHeader = ref(!!options.showHeader); + const showCloseButton = ref(options.showCloseButton == null ? true : options.showCloseButton); + const showModal = ref(true); + const modalTitle = ref(options.title || ''); + const acceptCallback = options.acceptCallback || (() => { }); + const rejectCallback = options.rejectCallback || (() => { }); + + const modalClosedCallback = options.closedCallback || (($event: Event) => { }); + const modalResizedCallback = options.resizeHandle || (($event: Event) => { }); + + const contentRender = getContentRender(options); + + const onClosed = ($event: Event) => { + showModal.value = false; + app.unmount(); + modalClosedCallback($event); + }; + + onMounted(() => { + // console.log(modalRef); + }); + + context.expose({ + modalRef + }); + + return () => ( + + {contentRender && contentRender(app)} + + ); + } + }); + document.body.appendChild(container); + // if (FarrisPlugin && !!FarrisPlugin.install) { + // app.use(FarrisPlugin); + // } + + app.mount(container); + + return app; +} + +export default class ModalService { + private appContext: AppContext | null = null; + + private modalRef = ref(); + + private activeModalIndex = ref(0); + + private modalRefs: Record = {}; + + private isUseEscCloseModal = ref(false); + + private activeModalInstance = computed(() => { + return this.modalRefs[this.activeModalIndex.value]; + }); + + private app: App; + + constructor(currentApp: App) { + this.app = currentApp; + this.appContext = currentApp ? currentApp._context : null; + } + + getCurrentModal() { + return this.activeModalInstance.value; + } + + private adaptToWindow(width: number, height: number) { + // 可视区域尺寸 + const { width: winWidth, height: winHeight } = { + width: window.innerWidth, + height: window.innerHeight + }; + + if (winWidth < width) { + width = winWidth; + } + + if (winHeight < height) { + height = winHeight; + } + + return { + width, + height + }; + } + + static show(options: ModalOptions) { + const modalOptions = Object.assign({ + title: '', + showButtons: true, + showHeader: true + }, options); + const app: App = createModalInstance(modalOptions); + return app; + } + + open(options: ModalOptions): ModalFunctions { + // 创建一个空白文档作为模态框容器,空白文档不属于DOM树,比创建一般节点性能较好,且仅渲染子元素 + const container = document.createDocumentFragment(); + + if (options.showMaxButton && options.fitContent) { + options.showMaxButton = false; + } + + const modalOptions = shallowRef(Object.assign({ + title: '', + showButtons: true, + showHeader: true, + }, options)); + + const showModal = ref(true); + const acceptCallback = modalOptions.value.acceptCallback || (() => { }); + const rejectCallback = modalOptions.value.rejectCallback || (() => { }); + + const modalClosedCallback = modalOptions.value.closedCallback || (($event?: Event, from?: string) => { }); + const modalResizedCallback = modalOptions.value.resizeHandle || (($event: Event) => { }); + let modalInstance: VNode | null; + + const contentRender = getContentRender(modalOptions.value); + + const onClosed = ($event?: Event) => { + showModal.value = false; + + const isCloseIconClick = ($event?.target as any)?.classList.contains('modal_close'); + + modalClosedCallback($event, this.isUseEscCloseModal.value ? 'esc' : isCloseIconClick ? 'icon' : 'button'); + + }; + + const destroy = ($event?: Event) => { + onClosed($event); + if (modalInstance) { + nextTick(() => { + if (this.modalRefs[this.activeModalIndex.value]) { + delete this.modalRefs[this.activeModalIndex.value]; + } + render(null, container as any); + modalInstance = null; + this.modalRef.value = null; + + if (this.modalRefs) { + const modals = Object.keys(this.modalRefs).map((key: string) => Number(key)); + if (modals.length > 0) { + this.activeModalIndex.value = Math.max(...modals); + } else { + this.activeModalIndex.value = 0; + } + } + + this.isUseEscCloseModal.value = false; + }); + } + + }; + + const onEsc = (payload: any) => { + this.isUseEscCloseModal.value = true; + this.activeModalInstance && this.activeModalInstance.value?.close(payload?.event); + }; + + const { width: modalWidth, height: modalHeight } = modalOptions.value; + const adaptedSize = this.adaptToWindow(modalWidth || 500, modalHeight || 320); + Object.assign(modalOptions.value, adaptedSize); + + const ModalWrapper = () => ( + + {contentRender && contentRender(this.app)} + + ); + + const renderModal = (props: Partial): VNode => { + const vnode = h(ModalWrapper, props); + vnode.appContext = this.appContext; + // if (FarrisPlugin && !!FarrisPlugin.install) { + // vnode.appContext?.app.use(FarrisPlugin); + // } + render(vnode, container as any); + return vnode; + }; + modalInstance = renderModal( + { + ...modalOptions.value, + // 'onUpdate:modelValue': onUpdateModelValue, + } + ); + + this.activeModalIndex.value++; + this.modalRefs[this.activeModalIndex.value] = this.modalRef.value; + + const update = (updateConfig: ModalOptions) => { + modalOptions.value = { + ...modalOptions.value, + ...updateConfig + }; + if (modalInstance) { + render(cloneVNode(modalInstance, { ...modalOptions }), container as any); + } + }; + + return { + update, + destroy, + modalRef: this.activeModalInstance + }; + } +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/resizeable/position.ts b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/position.ts new file mode 100644 index 00000000000..8aa65d4a5cd --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/position.ts @@ -0,0 +1,104 @@ +export interface IPosition { + x: number; + y: number; +} + +export class Position implements IPosition { + constructor(public x: number, public y: number) { } + + static getTransformInfo(target: Element) { + const styleInfo = window.getComputedStyle(target); + const transforms = styleInfo.getPropertyValue('transform').replace(/[^-\d,]/g, '').split(','); + if (transforms.length >= 6) { + const translateX = parseInt(transforms[4], 10); + const translateY = parseInt(transforms[5], 10); + return {x: translateX, y: translateY }; + } + + return {x: 0, y: 0 }; + } + + static fromEvent(e: MouseEvent | TouchEvent, el: any = null) { + + if (this.isMouseEvent(e)) { + return new Position(e.clientX, e.clientY); + } + + if (el === null || e.changedTouches.length === 1) { + return new Position(e.changedTouches[0].clientX, e.changedTouches[0].clientY); + } + + for (let i = 0; i < e.changedTouches.length; i++) { + if (e.changedTouches[i].target === el) { + return new Position(e.changedTouches[i].clientX, e.changedTouches[i].clientY); + } + } + } + + static isMouseEvent(e: MouseEvent | TouchEvent): e is MouseEvent { + return Object.prototype.toString.apply(e).indexOf('MouseEvent') === 8; + } + + static isIPosition(obj): obj is IPosition { + return !!obj && ('x' in obj) && ('y' in obj); + } + + static getCurrent(el: Element) { + const pos = new Position(0, 0); + + if (window) { + const computed = window.getComputedStyle(el); + if (computed) { + const x = parseInt(computed.getPropertyValue('left'), 10); + const y = parseInt(computed.getPropertyValue('top'), 10); + pos.x = isNaN(x) ? 0 : x; + pos.y = isNaN(y) ? 0 : y; + } + return pos; + } + + return null; + } + + static copy(p: IPosition) { + return new Position(0, 0).set(p); + } + + get value(): IPosition { + return { x: this.x, y: this.y }; + } + + add(p: IPosition) { + this.x += p.x; + this.y += p.y; + return this; + } + + subtract(p: IPosition) { + this.x -= p.x; + this.y -= p.y; + return this; + } + + multiply(n: number) { + this.x *= n; + this.y *= n; + } + + divide(n: number) { + this.x /= n; + this.y /= n; + } + + reset() { + this.x = 0; + this.y = 0; + return this; + } + + set(p: IPosition) { + this.x = p.x; + this.y = p.y; + return this; + } +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/resizeable/resize-event.ts b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/resize-event.ts new file mode 100644 index 00000000000..6f3828a241b --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/resize-event.ts @@ -0,0 +1,11 @@ +export interface IResizeEvent { + size: { + width?: number; + height?: number; + }; + position: { + x?: number; + y?: number; + }; + transform?: string; +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/resizeable/size.ts b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/size.ts new file mode 100644 index 00000000000..10f028b9fab --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/resizeable/size.ts @@ -0,0 +1,33 @@ +export interface ISize { + width: number; + height: number; +} + +export class Size implements ISize { + constructor(public width: number, public height: number) {} + + static getCurrent(el: Element) { + const size = new Size(0, 0); + + if (window) { + const computed = window.getComputedStyle(el); + if (computed) { + size.width = parseInt(computed.getPropertyValue('width'), 10); + size.height = parseInt(computed.getPropertyValue('height'), 10); + } + return size; + } + + return null; + } + + static copy(s: Size) { + return new Size(0, 0).set(s); + } + + set(s: ISize) { + this.width = s.width; + this.height = s.height; + return this; + } +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/type.ts b/packages/mobile-ui-vue/components/modal/src/composition/type.ts new file mode 100644 index 00000000000..e39156ec691 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/type.ts @@ -0,0 +1,49 @@ +import { App, VNode } from "vue"; +import { JSX } from "vue/jsx-runtime"; +import { IResizeEvent } from "./resizeable/resize-event"; + +/** 自定义按钮结构 */ +export interface ModalButton { + name?: string; + class: string; + focusedByDefault?: boolean; + disable?: boolean; + iconClass?: string; + handle: ($event: MouseEvent, context: any) => any; + text: string; +} + +export interface ModalOptions { + class?: string; + title?: string; + width?: number; + height?: number; + minWidth?: number; + minHeight?: number; + showButtons?: boolean; + showHeader?: boolean; + showFloatingClose?: boolean; + content?: { render(): JSX.Element }; + render?: (app: App) => JSX.Element; + fitContent?: boolean; + buttons?: ModalButton[]; + draggable?: boolean; + showMaxButton?: boolean; + showCloseButton?: boolean; + acceptCallback?: () => void; + rejectCallback?: () => void; + closedCallback?: ($event?: Event, from?: 'esc' | 'icon' | 'button') => void; + resizeHandle?: (event: IResizeEvent) => void; + enableEsc?: boolean; +} + +export interface ModalFunctions { + update: (options: ModalOptions) => void; + destroy: () => void; + modalRef: any; +} + +export interface UseModal { + FModalContextHolder: () => VNode; + +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/use-draggable.ts b/packages/mobile-ui-vue/components/modal/src/composition/use-draggable.ts new file mode 100644 index 00000000000..2a239d952c9 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/use-draggable.ts @@ -0,0 +1,222 @@ +import { Ref, ref, watch } from "vue"; +import { Position } from "./resizeable/position"; + +export function useDraggable(props: any, context: any, canMove: Ref) { + + const dragTarget = ref(); + const allowDrag = ref(props.draggable); + const lockAxis = ref(props.lockAxis); + + const dragHandle = ref(); + const boundingElement = ref(); + const moving = ref(false); + + const origPos = ref(new Position(0, 0)); + const oldTranslate = ref(new Position(0, 0)); + const movingPos= ref(new Position(0, 0)); + const currentPos= ref(new Position(0, 0)); + + watch(() => canMove.value, (move) => { + dragHandle.value.style.cursor = move ? 'move' : 'default'; + }); + + function checkHandleTarget(target: EventTarget, element: Element) { + // Checks if the target is the element clicked, then checks each child element of element as well + // Ignores button clicks + + // Ignore elements of type button + if (element.tagName === 'BUTTON') { + return false; + } + + // If the target was found, return true (handle was found) + if (element === target) { + return true; + } + + // Recursively iterate this elements children + + for (const child in element.children) { + if (Object.prototype.hasOwnProperty.call(element.children, child)) { + if (checkHandleTarget(target, element.children[child])) { + return true; + } + } + } + + // Handle was not found in this lineage + // Note: return false is ignore unless it is the parent element + return false; + } + + function transform() { + let translateX = movingPos.value.x + oldTranslate.value.x; + let translateY = movingPos.value.y + oldTranslate.value.y; + + if (lockAxis.value === 'x') { + translateX = origPos.value?.x || 0; + movingPos.value.x = 0; + } else if (lockAxis.value === 'y') { + translateY = origPos.value?.y || 0; + movingPos.value.y = 0; + } + + const value = `translate3d(${Math.round(translateX)}px, ${Math.round(translateY)}px, 0px)`; + if (dragTarget.value) { + dragTarget.value.style.transform = value; + } + + // save current position + currentPos.value.x = translateX; + currentPos.value.y = translateY; + } + + function checkBounds(){ + if(!boundingElement.value || !dragTarget.value){ return null; } + const boundary = boundingElement.value.getBoundingClientRect(); + const targetRect = dragTarget.value.getBoundingClientRect(); + const result = { + 'top': boundary.top < targetRect.top, + 'right': boundary.right > targetRect.right, + 'bottom': boundary.bottom > targetRect.bottom, + 'left': boundary.left < targetRect.left + }; + + if (!result.top) { + movingPos.value.y -= targetRect.top - boundary.top; + } + + if (!result.bottom) { + movingPos.value.y -= targetRect.bottom - boundary.bottom; + } + + if (!result.right) { + movingPos.value.x -= targetRect.right - boundary.right; + } + + if (!result.left) { + movingPos.value.x -= targetRect.left - boundary.left; + } + + transform(); + return result; + } + + function moveTo(p?: Position) { + if (p) { + if (origPos.value) { + p.subtract(origPos.value); + } + + movingPos.value.set(p); + transform(); + checkBounds(); + } + } + + function onMouseMove(event: MouseEvent) { + if (moving.value && allowDrag.value) { + event.stopPropagation(); + event.preventDefault(); + + // Add a transparent helper div: + // helperBlock.add(); + moveTo(Position.fromEvent(event, dragHandle.value)); + } + } + + function stopMove() { + if (moving.value) { + + moving.value = false; + + oldTranslate.value.add(movingPos.value); + movingPos.value.reset(); + + dragTarget.value?.classList.remove('ng-dragging'); + + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', stopMove); + } + } + + function startMove() { + if (!moving.value && dragHandle.value) { + moving.value = true; + dragHandle.value.classList.add('ng-dragging'); + + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', stopMove); + } + } + + function resetTranslate() { + if (dragTarget.value) { + const pos = Position.getTransformInfo(dragTarget.value); + oldTranslate.value.set(pos); + return; + } + + oldTranslate.value.reset(); + } + + function onMouseDown(event: MouseEvent) { + if (!canMove.value) { + return; + } + // 1. skip right click; + if (event instanceof MouseEvent && event.button === 2) { + return; + } + // 2. if handle is set, the element can only be moved by handle + const target = event.target || event.srcElement; + if (dragHandle.value !== undefined && target && !checkHandleTarget(target, dragHandle.value)) { + return; + } + + // 3. if allow drag is set to false, ignore the mousedown + if (allowDrag.value === false) { + return; + } + + // 隐藏其他浮动层 + document.body.click(); + + event.stopPropagation(); + event.preventDefault(); + + origPos.value = Position.fromEvent(event, dragTarget.value); + resetTranslate(); + startMove(); + } + + function registerDraggle(handle: HTMLElement, hostElement: HTMLElement, boundingHost: HTMLElement | null) { + if (allowDrag.value && hostElement) { + if (handle) { + dragHandle.value = handle; + } else if (props.dragHandle) { + if (props.dragHandle instanceof HTMLElement) { + dragHandle.value = props.dragHandle; + } else if (typeof props.dragHandle === 'string') { + const element = hostElement.querySelector(props.dragHandle); + if(element) { + dragHandle.value = element as HTMLElement; + } + } + } + + dragTarget.value = hostElement; + boundingElement.value = boundingHost; + if (dragHandle.value) { + dragHandle.value.classList.add('ng-draggable'); + dragHandle.value.addEventListener('mousedown', onMouseDown); + } else { + allowDrag.value = false; + } + } + } + + return { + registerDraggle, resetTranslate + }; +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/use-resizeable.tsx b/packages/mobile-ui-vue/components/modal/src/composition/use-resizeable.tsx new file mode 100644 index 00000000000..e23782f5926 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/use-resizeable.tsx @@ -0,0 +1,390 @@ +import { ref } from "vue"; +import { Position } from "./resizeable/position"; +import { Size } from "./resizeable/size"; +import { IResizeEvent } from "./resizeable/resize-event"; + +export function useResizeable(props: any, context: any) { + + const resizedTarget = ref(); + const boundingElement = ref(); + + const origMousePos = ref(); + const origSize = ref(); + const origPos = ref(); + const currSize = ref(); + const currPos = ref(); + const direction = ref<{ 'n': boolean; 's': boolean; 'w': boolean; 'e': boolean } | null>(); + const resizeHandlerElement = ref(); + const modalBounding = ref(); + const resizedEventParam = ref(); + + const lastSize = ref(); + + const allowDrag = ref(props.draggable); + + const isMaximized = ref(false); + + function initBounding() { + const el = boundingElement.value || document.body; + const computed = window.getComputedStyle(el); + if(!computed){ + return; + } + + if (!resizedTarget.value) { + return; + } + + const transforms = Position.getTransformInfo(resizedTarget.value); + + + const bounding: any = {}; + + if (currPos.value) { + bounding.deltaL = resizedTarget.value.offsetLeft - currPos.value.x; + bounding.deltaT = resizedTarget.value.offsetTop - currPos.value.y; + } + + const p = computed.getPropertyValue('position'); + bounding.width = el.clientWidth; + bounding.height = el.clientHeight; + bounding.pr = parseInt(computed.getPropertyValue('padding-right'), 10); + bounding.pb = parseInt(computed.getPropertyValue('padding-bottom'), 10); + bounding.position = computed.getPropertyValue('position'); + + if (p === 'static') { + el.style.position = 'relative'; + } + + bounding.translateX = transforms.x; + bounding.translateY = transforms.y; + + modalBounding.value = bounding; + } + + function startResize(event: MouseEvent) { + + if (resizedTarget.value) { + origSize.value = Size.getCurrent(resizedTarget.value); + origPos.value = Position.getCurrent(resizedTarget.value); + currSize.value = origSize.value ? Size.copy(origSize.value) : null; + currPos.value = origPos.value ? Position.copy(origPos.value) : null; + + initBounding(); + + const directionType = (event.target as HTMLElement).getAttribute('type') || ''; + direction.value = { + n: !!directionType.match(/n/), + s: !!directionType.match(/s/), + w: !!directionType.match(/w/), + e: !!directionType.match(/e/) + }; + + } + } + + function doResize() { + if (resizedTarget.value) { + const container = resizedTarget.value as HTMLElement; + if (direction.value) { + if ((direction.value.n || direction.value.s) && currSize.value?.height) { + container.style.height = currSize.value.height + 'px'; + } + if ((direction.value.w || direction.value.e) && currSize.value?.width) { + container.style.width = currSize.value.width + 'px'; + } + + if (currPos.value) { + if (currPos.value?.x) { + container.style.left = currPos.value.x + 'px'; + } + if (currPos.value?.y) { + container.style.top = currPos.value.y + 'px'; + } + } + } + } + } + + function checkSize() { + + const minHeight = !props.minHeight ? 1 : props.minHeight; + const minWidth = !props.minWidth ? 1 : props.minWidth; + + if (currSize.value && currPos.value && direction.value && origSize.value) { + if (currSize.value.height < minHeight) { + currSize.value.height = minHeight; + + if (direction.value.n && origPos.value) { + currPos.value.y = origPos.value.y + (origSize.value.height - minHeight); + } + } + + if (currSize.value.width < minWidth) { + currSize.value.width = minWidth; + + if (direction.value.w && origPos.value) { + currPos.value.x = origPos.value.x + (origSize.value.width - minWidth); + } + } + + if (props.maxHeight && currSize.value.height > props.maxHeight) { + currSize.value.height = props.maxHeight; + + if (origPos.value && direction.value.n) { + currPos.value.y = origPos.value.y + (origSize.value.height - props.maxHeight); + } + } + + if (props.maxWidth && currSize.value.width > props.maxWidth) { + currSize.value.width = props.maxWidth; + + if (direction.value.w && origPos.value) { + currPos.value.x = origPos.value.x + (origSize.value.width - props.maxWidth); + } + } + } + + } + + function checkBounds(){ + if (boundingElement.value) { + const bounding = modalBounding.value; + + if (currPos.value && currSize.value && direction.value && origSize.value) { + const maxWidth = bounding.width - bounding.pr - bounding.deltaL - bounding.translateX - currPos.value.x; + const maxHeight = bounding.height - bounding.pb - bounding.deltaT - bounding.translateY - currPos.value.y; + + if (direction.value.n && (currPos.value.y + bounding.translateY < 0) && origPos.value) { + currPos.value.y = -bounding.translateY; + currSize.value.height = origSize.value.height + origPos.value.y + bounding.translateY; + } + + if (direction.value.w && (currPos.value.x + bounding.translateX) < 0 && origPos.value) { + currPos.value.x = -bounding.translateX; + currSize.value.width = origSize.value.width + origPos.value.x + bounding.translateX; + } + + if (currSize.value.width > maxWidth) { + currSize.value.width = maxWidth; + } + + if (currSize.value.height > maxHeight) { + currSize.value.height = maxHeight; + } + } + } + } + + function resizeTo(p: Position) { + + if (!origMousePos.value || !origSize.value || !origPos.value || !direction.value) { + return; + } + + p.subtract(origMousePos.value); + + const tmpX = p.x; + const tmpY = p.y; + + if (direction.value.n) { + // n, ne, nw + currPos.value!.y = origPos.value.y + tmpY; + currSize.value!.height = origSize.value.height - tmpY; + } else if (direction.value.s) { + // s, se, sw + currSize.value!.height = origSize.value.height + tmpY; + } + + if (direction.value.e) { + // e, ne, se + currSize.value!.width = origSize.value.width + tmpX; + } else if (direction.value.w) { + // w, nw, sw + currSize.value!.width = origSize.value.width - tmpX; + currPos.value!.x = origPos.value.x + tmpX; + } + + checkBounds(); + checkSize(); + doResize(); + } + + function onMouseMove(event: MouseEvent) { + if (!resizeHandlerElement.value) { + return; + } + + const pos = Position.fromEvent(event); + if (pos) { + resizeTo(pos); + } + } + + function getResizedEventParam(): IResizeEvent | null { + if (resizedTarget.value) { + const { width, height, x, y } = resizedTarget.value.getBoundingClientRect(); + const transforms = Position.getTransformInfo(resizedTarget.value); + + return { + size: { width, height }, + position: {x: x - transforms.x, y: y - transforms.y } + }; + } + return null; + } + + function onMouseLeave(event: MouseEvent) { + if (resizedTarget.value) { + const resizedParam = getResizedEventParam(); + resizedEventParam.value = resizedParam; + } + + origMousePos.value = undefined; + origSize.value = null; + origPos.value = null; + currSize.value = null; + currPos.value = null; + direction.value = null; + resizeHandlerElement.value = null; + + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseLeave); + } + + function registerMouseEvent() { + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', onMouseLeave); + } + + function onMouseDown(event: MouseEvent) { + // skip right click; + if (event instanceof MouseEvent && event.button === 2) { + return; + } + + if (!allowDrag.value) { + return; + } + // 隐藏其他浮动层 + document.body.click(); + // prevent default events + event.stopPropagation(); + event.preventDefault(); + + origMousePos.value = Position.fromEvent(event); + resizeHandlerElement.value = event.target; + startResize(event); + registerMouseEvent(); + } + + function renderResizeBar(hostElement: any) { + resizedTarget.value = hostElement; + return <> +
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+
onMouseDown(e)}>
+ ; + } + + function maximize(updateLastSize = true) { + // 隐藏其他浮动层 + document.body.click(); + + const container = boundingElement.value || document.body; + const maxSize = Size.getCurrent(container); + const target = resizedTarget.value as HTMLElement; + + if (updateLastSize && target) { + lastSize.value = getResizedEventParam(); + lastSize.value!.transform = target.style.transform; + } + + if (maxSize && target) { + currSize.value = maxSize; + + target.style.height = (currSize.value.height - 14) + 'px'; + target.style.width = (currSize.value.width - 14) + 'px'; + target.style.left = '7px'; + target.style.top = '7px'; + target.style.transform = ''; + + resizedEventParam.value = { + size: currSize.value, + position: {x: 0, y: 0} + }; + + allowDrag.value = false; + isMaximized.value = true; + } + } + + function restore() { + // 隐藏其他浮动层 + document.body.click(); + + if (lastSize.value) { + const size = { width: lastSize.value.size.width || 0, height: lastSize.value.size.height || 0 }; + const position = { x: (window.innerWidth - size.width) / 2, y: (window.innerHeight - size.height) / 2}; + + currSize.value?.set(size); + currPos.value?.set(position); + + const target = resizedTarget.value as HTMLElement; + target.style.height = size.height + 'px'; + target.style.width = size.width + 'px'; + target.style.left = `${position.x}px`; + target.style.top = `${position.y}px`; + target.style.transform = ''; + resizedEventParam.value = { + size, + position + }; + + allowDrag.value = props.draggable; + + isMaximized.value = false; + } + } + + function moveToCenter() { + if (resizedTarget.value) { + const modalSize = Size.getCurrent(resizedTarget.value); + if (modalSize) { + const { width, height } = modalSize; + resizedTarget.value.style.left = `${(window.innerWidth - width) / 2}px`; + resizedTarget.value.style.top = `${(window.innerHeight - height) / 2}px`; + resizedTarget.value.style.transform = ''; + + } + } + } + + function onWindowResize() { + const windowResizeHandle = () => { + if (isMaximized.value) { + maximize(false); + } else { + moveToCenter(); + } + // 隐藏其他浮动层 + document.body.click(); + }; + + window.addEventListener('resize', windowResizeHandle); + return () => { + window.removeEventListener('resize', windowResizeHandle); + }; + } + + const unWindowResizeHandle = onWindowResize(); + + return { + renderResizeBar, boundingElement, resizedEventParam, maximize, restore, allowDrag, isMaximized, unWindowResizeHandle + }; +} diff --git a/packages/mobile-ui-vue/components/modal/src/composition/use-shortcut.ts b/packages/mobile-ui-vue/components/modal/src/composition/use-shortcut.ts new file mode 100644 index 00000000000..52e510aec03 --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/composition/use-shortcut.ts @@ -0,0 +1,56 @@ +import { ref } from "vue"; + + +function registrationShortcutKeyEvent(keyCode: string, callBack: (...args) => void) { + if (keyCode) { + const registerKeyDown =(event: KeyboardEvent) =>{ + if (event.key.toLowerCase() === keyCode.toLowerCase()) { + callBack({ event, key: keyCode }); + } + }; + + document.addEventListener('keydown', registerKeyDown); + + return () => { + document.removeEventListener('keydown', registerKeyDown); + }; + } + +} + +export function useEsc(props: any, context: any) { + const enableEsc = ref(props.enableEsc); + + let removeEventListener: any = null; + + if (enableEsc.value) { + removeEventListener = registrationShortcutKeyEvent('Escape', ($event: any) => { + context.emit('esc', { event: $event.event, type: 'esc' }); + }); + + return { + remove: removeEventListener + }; + } + + return null; +} + +export function useEnter(props: any, context: any) { + const enableEnter = ref(props.enableEnter); + + let removeEventListener: any = null; + + if (enableEnter.value) { + removeEventListener = registrationShortcutKeyEvent('Enter', ($event: any) => { + context.emit('enter', { event: $event.event, type: 'enter' }); + }); + + return { + remove: removeEventListener + }; + } + + return null; + +} diff --git a/packages/mobile-ui-vue/components/modal/src/modal.component.tsx b/packages/mobile-ui-vue/components/modal/src/modal.component.tsx new file mode 100644 index 00000000000..31b1e0a72ae --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/modal.component.tsx @@ -0,0 +1,375 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { computed, defineComponent, ref, SetupContext, Teleport, watch, Transition, onMounted, onUnmounted, provide, nextTick } from 'vue'; +import { ModalButton, ModalOptions } from './composition/type'; +import { ModalProps, modalProps } from './modal.props'; +import { useResizeable } from './composition/use-resizeable'; +import { useDraggable } from './composition/use-draggable'; +import './modal.css'; +import { useEnter, useEsc } from './composition/use-shortcut'; + +export default defineComponent({ + name: 'FModal', + props: modalProps, + emits: ['update:modelValue', 'accept', 'cancel', 'closed', 'resize', 'esc', 'enter'] as (string[] & ThisType) | undefined, + setup(props: ModalProps, context: SetupContext) { + const width = ref(props.width || 300); + const height = ref(props.height || 200); + const modelValue = ref(props.modelValue); + const modalId = ref(''); + const customClass = ref(props.class); + const fitContent = ref(props.fitContent); + const showHeader = ref(props.showHeader); + const headerIconClass = ref(''); + const enableClose = ref(props.showCloseButton); + const enableMaximize = ref(props.showMaxButton); + const enableMinimize = ref(false); + const dialogType = ref(''); + const iframeSrc = ref(''); + const buttonAlignment = ref(''); + const showButtons = ref(props.showButtons); + const title = ref(props.title); + const resizeable = ref(props.reiszeable); + const containment = ref(props.containment || null); + const modalContainerRef = ref(); + + + function close($event: MouseEvent, accept?: boolean) { + modelValue.value = false; + context.emit('update:modelValue', false); + if (accept != null) { + context.emit(accept ? 'accept' : 'cancel'); + } + + context.emit('closed', $event); + } + const defaultButtons: ModalButton[] = [ + { + name: 'cancel', + text: '取消', + class: 'btn btn-secondary', + handle: ($event: MouseEvent) => { + close($event, false); + } + }, + { + name: 'accept', + text: '确定', + class: 'btn btn-primary', + handle: ($event: MouseEvent) => { + close($event, true); + } + } + ]; + const buttons = ref(props.buttons && props.buttons.length ? props.buttons : defaultButtons); + + const showHeaderIcon = computed(() => !!headerIconClass.value); + const showFooter = computed(() => !!showButtons.value && !!buttons.value); + + const modalHeaderRef = ref(); + const modalElementRef = ref(); + const maximized = ref(false); + + const { renderResizeBar, maximize, restore, boundingElement, + resizedEventParam, allowDrag, unWindowResizeHandle } = useResizeable(props, context); + const { registerDraggle } = useDraggable(props, context, allowDrag); + + // 监听modal 标题变化 + watch(() => props.title, (newValue, oldValue) => { + if (newValue !== oldValue) { + title.value = newValue; + } + }); + + // 监听打开关闭状态变化 + watch(() => props.modelValue, (newValue, oldValue) => { + if (newValue !== oldValue) { + modelValue.value = newValue; + } + }); + // 监听是否展示标题变化 + watch(() => props.showHeader, (newValue, oldValue) => { + if (newValue !== oldValue) { + showHeader.value = newValue; + } + }); + // 监听是否展示按钮变化 + // todo: 可以抽出公共方法 + watch(() => props.showButtons, (newValue, oldValue) => { + if (newValue !== oldValue) { + showButtons.value = newValue; + } + }); + + watch(() => resizedEventParam.value, (newSize, oldSize) => { + const newSizeValue = newSize || {}; + const oldSizeValue = oldSize || {}; + + if (JSON.stringify(newSizeValue) !== JSON.stringify(oldSizeValue)) { + context.emit('resize', { newSize, oldSize }); + } + }); + + function removeModalOpenStyle() { + const modalTotal = document.querySelectorAll('.farris-modal').length; + if (!modalTotal || modalTotal - 1 <= 0) { + document.body.classList.remove('modal-open'); + } + + if (modalContainerRef.value) { + modalContainerRef.value.classList.remove('show'); + } + } + + const showModal = computed(() => { + if (modelValue.value) { + document.body.classList.add('modal-open'); + } else { + removeModalOpenStyle(); + } + + return modelValue.value; + }); + + const modalContainerClass = computed(() => { + const classObject = { + modal: true, + 'farris-modal': true, + 'fade': true, + } as Record; + classObject['f-modal-fitContent'] = !!fitContent.value; + classObject.show = !!showModal.value; + return classObject; + }); + + const modalDialogClass = computed(() => { + const classObject = { 'modal-dialog': true }; + const customClassArray = customClass.value?.split(' '); + customClassArray?.reduce((target: any, className: string) => { + target[className] = true; + return target; + }, classObject); + return classObject; + }); + + const modalDialogStyle = computed(() => { + const styleObject = { + position: 'absolute', + top: `${(window.innerHeight - height.value) / 2}px`, + left: `${(window.innerWidth - width.value) / 2}px`, + width: `${width.value}px`, + height: fitContent.value ? 'auto' : `${height.value}px` + }; + return styleObject; + }); + + const modalContentClass = computed(() => { + const classObject = { + 'modal-content': true, + 'modal-content-has-header': showHeader.value + }; + return classObject; + }); + + const modalHeaderStyle = computed(() => { + const styleObject = { display: showHeader.value ? '' : 'none' }; + styleObject['pointer-events'] = allowDrag.value ? 'auto': 'none'; + return styleObject; + }); + + const headerMaxButtonClass = computed(() => { + const classObject = { 'f-icon': true, modal_maximize: true, modalrevert: maximized.value }; + return classObject; + }); + + const modalBodyClass = computed(() => { + const classObject = { 'modal-body': true, 'f-utils-flex-column': dialogType.value === 'iframe' }; + return classObject; + }); + + function buildFooterStyles(): Record { + return {}; + } + + const modalFooterStyle = computed(() => { + const styleObject = { textAlgin: buttonAlignment.value }; + const footerSytles = buildFooterStyles(); + return Object.assign(styleObject, footerSytles); + }); + + function maxDialog($event: MouseEvent) { + $event.stopPropagation(); + if (maximized.value) { + maximized.value = false; + restore(); + return; + } + maximize(); + maximized.value = true; + } + + async function customButtonClick(button: ModalButton, $event: MouseEvent) { + if (button.handle) { + const result = await button.handle($event, button); + if (result) { + context.emit('closed', $event); + } + } + } + + function updateModalOptions(options: ModalOptions) { + if (options.width) { + width.value = options.width; + } + if (options.height) { + height.value = options.height; + } + if (options.buttons) { + buttons.value = options.buttons; + } + if (options.title) { + title.value = options.title; + } + } + + let escEventHandler: any = null; + let enterEventHandler: any = null; + + onMounted(() => { + if (modalElementRef.value && !containment.value) { + containment.value = (modalElementRef.value as HTMLElement).parentElement; + boundingElement.value = containment.value; + registerDraggle(modalHeaderRef.value, modalElementRef.value, boundingElement.value); + } + if (showModal.value) { + document.body.classList.add('modal-open'); + } + + escEventHandler = useEsc(props, context); + enterEventHandler = useEnter(props, context); + + }); + + onUnmounted(() => { + removeModalOpenStyle(); + if (unWindowResizeHandle) { + unWindowResizeHandle(); + } + + if (escEventHandler) { + escEventHandler.remove(); + } + + if (enterEventHandler) { + enterEventHandler.remove(); + } + }); + + context.expose({ + modalElementRef, + updateModalOptions, + close, + maxDialog + }); + + function renderFloatingCloseButton() { + return
    + {enableMinimize.value && ( +
  • + +
  • + )} + {enableMaximize.value && ( +
  • + +
  • + )} + {enableClose.value && ( +
  • close(payload, false)} style="pointer-events: auto;"> + +
  • + )} +
; + } + + function renderFooterButtons() { + return ; + } + + function renderModalHeader() { + return ; + } + + function onClickModalBackdrop($event) { + $event.stopPropagation(); + } + + return () => { + return ( + + {showModal.value && + +
+
+
+ { showHeader.value && renderModalHeader() } + +
+ {context.slots.default?.()} + {dialogType.value === 'iframe' && ( + + )} +
+ {showFooter.value && renderFooterButtons()} +
+ {!fitContent.value && resizeable.value && modalElementRef.value && !maximized.value && renderResizeBar(modalElementRef.value)} +
+
+
} +
+ ); + }; + } +}); diff --git a/packages/mobile-ui-vue/components/modal/src/modal.css b/packages/mobile-ui-vue/components/modal/src/modal.css new file mode 100644 index 00000000000..080d52aa71e --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/modal.css @@ -0,0 +1,84 @@ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.5s ease; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +.fv-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + touch-action: none; + + &:hover { + background: rgba(42, 135, 255, .07); + } + + &.fv-resizable-n { + cursor: n-resize; + height: 0.4375rem; + width: 100%; + top: -0.3125rem; + left: 0; + } + + &.fv-resizable-e { + cursor: e-resize; + width: 0.4375rem; + right: -0.3125rem; + height: 100%; + top: 0; + } + + &.fv-resizable-s { + cursor: s-resize; + height: 0.4375rem; + width: 100%; + bottom: -0.3125rem; + left: 0; + } + + &.fv-resizable-w { + cursor: w-resize; + height: 100%; + width: 0.4375rem; + left: -0.3125rem; + top: 0; + } + + &.fv-resizable-ne { + cursor: ne-resize; + width: .75rem; + height: .75rem; + right: 1px; + top: 1px; + } + + &.fv-resizable-se { + cursor: se-resize; + width: .75rem; + height: .75rem; + right: 1px; + bottom: 1px; + } + + &.fv-resizable-nw { + cursor: nw-resize; + width: .75rem; + height: .75rem; + left: 1px; + top: 1px; + } + + &.fv-resizable-sw { + cursor: sw-resize; + width: .75rem; + height: .75rem; + left: 1px; + bottom: 1px; + } +} diff --git a/packages/mobile-ui-vue/components/modal/src/modal.props.ts b/packages/mobile-ui-vue/components/modal/src/modal.props.ts new file mode 100644 index 00000000000..19fa251526c --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/src/modal.props.ts @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ExtractPropTypes, PropType } from 'vue'; +import { ModalButton } from './composition/type'; + +export type DragHandleType = HTMLElement | string; + +export const modalProps = { + /** + * 自定义类 + */ + class: { type: String, default: '' }, + /** + * 模态框标题 + */ + title: { type: String, default: '' }, + /** + * 模态框宽度 + */ + width: { type: Number, default: 500 }, + /** + * 模态框高度 + */ + height: { type: Number, default: 320 }, + /** + * 自定义按钮列表 + */ + buttons: { + type: Array, + default: [] + }, + /** + * 是否展示模态框 + */ + modelValue: { type: Boolean, default: false }, + /** + * 是否展示头部 + */ + showHeader: { type: Boolean, default: true }, + /** + * 是否展示默认按钮 + */ + showButtons: { type: Boolean, default: true }, + /** + * 是否启用自适应样式 + */ + fitContent: { type: Boolean, default: true }, + /** + * 是否展示右上角按钮 + */ + showCloseButton: { type: Boolean, default: true }, + showMaxButton: { type: Boolean, default: false }, + minHeight: {type: Number}, + maxHeight: {type: Number}, + minWidth: {type: Number}, + maxWidth: {type: Number}, + containment: {type: Object as PropType, default: null}, + reiszeable: { type: Boolean, default: false }, + draggable: { type: Boolean, default: false}, + dragHandle: { type: Object as PropType, default: null}, + closedCallback: { type: Function, default: null}, + resizeHandle: { type: Function, default: null}, + render: { type: Function, default: null}, + acceptCallback: { type: Function, default: null}, + rejectCallback: { type: Function, default: null}, + enableEsc: { type: Boolean, default: true }, + enableEnter: { type: Boolean, default: false } +}; + +export type ModalProps = Partial>; diff --git a/packages/mobile-ui-vue/components/modal/style.ts b/packages/mobile-ui-vue/components/modal/style.ts new file mode 100644 index 00000000000..ecfe335ae4d --- /dev/null +++ b/packages/mobile-ui-vue/components/modal/style.ts @@ -0,0 +1,3 @@ +import "@/components/dependent-base/style"; +import "@components/button/style"; +import "@theme-default/components/modal.css"; diff --git a/packages/mobile-ui-vue/components/property-panel/index.ts b/packages/mobile-ui-vue/components/property-panel/index.ts index 43370695937..7963be09873 100644 --- a/packages/mobile-ui-vue/components/property-panel/index.ts +++ b/packages/mobile-ui-vue/components/property-panel/index.ts @@ -13,16 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import type { App } from 'vue'; -import PropertyPanel from './src/property-panel.component'; +import { BaseControlProperty } from './src/composition/entity/base-property'; +import { SchemaDOMMapping } from './src/composition/entity/schema-dom-mapping'; export * from './src/composition/props/property-panel-item.props'; export * from './src/composition/props/property-panel.props'; -export { PropertyPanel }; +export * from './src/composition/type'; -export default { - install(app: App): void { - app.component(PropertyPanel.name as string, PropertyPanel); - } -}; +export { BaseControlProperty, SchemaDOMMapping }; diff --git a/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item-list.component.tsx b/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item-list.component.tsx deleted file mode 100644 index 0f1a873c936..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item-list.component.tsx +++ /dev/null @@ -1,143 +0,0 @@ - - -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { defineComponent, SetupContext, ref, watch } from 'vue'; -import { propertyPanelItemListProps, PropertyPanelItemListProps } from '../composition/props/property-panel-item-list.props'; -import FPropertyPanelItem from '../component/property-panel-item.component'; - -import '../composition/class/property-panel-item-list.css'; -import { ElementPropertyConfig, PropertyEntity } from '../../../designer-canvas/src/composition/entity/property-entity'; - -export default defineComponent({ - name: 'FPropertyPanelItemList', - props: propertyPanelItemListProps, - emits: ['valueChanged', 'submitModal', 'triggerRefreshPanel'] as (string[] & ThisType) | undefined, - setup(props: PropertyPanelItemListProps, context: SetupContext) { - /** 某一分类下的属性配置 */ - const category = ref(props.category as ElementPropertyConfig); - - function hideCascadeTitle(propItem: any) { - if (!propItem.hideCascadeTitle) { - return ( -
- - -
- ); - } - } - - function onClickExpandButton(payload: MouseEvent, propertyItem: PropertyEntity) { - propertyItem.isExpand = !propertyItem.isExpand; - } - function renderExpandButton(propertyItem: PropertyEntity) { - return ( -
- -
- ); - } - - function formgroup(propertyItem: PropertyEntity) { - return ( -
-
-
- - {propertyItem.propertyName} -
-
-
- ); - } - - // f-icon-arrow-60-down - function getPropertyItemKey(propertyItem: PropertyEntity) { - return `${props.categoryKey}_${propertyItem.propertyID}`; - } - - function renderPropertyPanelItem(propertyItem: PropertyEntity) { - return ( -
- -
- ); - } - - /** 带级联属性的类型 */ - function renderCascadePropertyPanelItem(propertyItem: PropertyEntity) { - return ( -
-
-
onClickExpandButton(payload, propertyItem)}> -
-
- {formgroup(propertyItem)} - {hideCascadeTitle(propertyItem)} - {renderExpandButton(propertyItem)} -
-
-
-
- {propertyItem.cascadeConfig?.map((cascadeItem: any) => renderPropertyPanelItem(cascadeItem))} -
-
-
- ); - } - - function renderCascade(propertyItem: PropertyEntity) { - return ( -
-
- -
-
- -
-
-
-
- ); - } - - watch(() => props.category, () => { - category.value = props.category as ElementPropertyConfig; - }); - - function getPropertyPanelItemRender(propertyItem: PropertyEntity) { - return propertyItem.propertyType === 'cascade' ? renderCascadePropertyPanelItem : renderPropertyPanelItem; - } - - return () => { - return <> - {category.value.properties.map((propertyItem: PropertyEntity) => { - const renderPropertyItem = getPropertyPanelItemRender(propertyItem); - return renderPropertyItem(propertyItem); - })} - ; - }; - } -}); diff --git a/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item.component.tsx b/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item.component.tsx deleted file mode 100644 index 9e8e444b415..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/component/property-panel-item.component.tsx +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { defineComponent, SetupContext, ref, computed } from 'vue'; -import { propertyPanelItemProps, PropertyPanelItemProps } from '../composition/props/property-panel-item.props'; -import { PropertyEntity } from '../../../designer-canvas/src/composition/entity/property-entity'; -import FDynamicFormGroup from '../../../../../ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.component'; -import '../composition/class/property-panel-item.css'; - -export default defineComponent({ - name: 'FPropertyPanelItem', - props: propertyPanelItemProps, - emits: ['PropertyChange'] as (string[] & ThisType) | undefined, - setup(props: PropertyPanelItemProps, context: SetupContext) { - const categoryId = ref(props.category?.categoryId); - const propertyID = ref(props.elementConfig.propertyID); - const propertyName = ref(props.elementConfig.propertyName); - const editor = ref(props.elementConfig.editor); - const propertyValue = ref(props.elementConfig.propertyValue); - const propertyItemClass = computed(() => ({ - 'farris-group-wrap': true, - 'property-item': true, - 'd-none': !(props.elementConfig as PropertyEntity).visible() - })); - - function onPropertyChange(newValue: any) { - (props.elementConfig as PropertyEntity).propertyValue = newValue; - context.emit('PropertyChange', (props.elementConfig as PropertyEntity).propertyID, newValue); - } - - return () => { - return ( -
- -
- ); - }; - } -}); diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel-item-list.css b/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel-item-list.css index 030f153bdc2..1df3d4efa1d 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel-item-list.css +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel-item-list.css @@ -1,80 +1,80 @@ .propertyCascadeItem { - background-color: transparent !important; - border: none !important; + background-color: transparent !important; + border: none !important; } .propertyCascadeItem .card-header { - background-color: transparent !important; - padding: 4px 0px !important; - color: inherit !important; + background-color: transparent !important; + padding: 4px 0px !important; + color: inherit !important; } .propertyCascadeItem .card-header .panel-item-title { - width: 100%; - position: relative; - font-size: inherit !important; + width: 100%; + position: relative; + font-size: inherit !important; } .propertyCascadeItem .card-header .panel-item-title .farris-input-wrap { - margin-left: -5px; - margin-right: -5px; + margin-left: -5px; + margin-right: -5px; } .propertyCascadeItem .form-group .col-form-label .f-icon { - color: #a3a3a3 !important; + color: #a3a3a3 !important; } .propertyCascadeItem .f-accordion-collapse, .propertyCascadeItem .f-accordion-expand { - right: 0; - left: auto !important; - top: 6px; - color: #6b94ec !important; - position: absolute; + right: 0; + left: auto !important; + top: 6px; + color: #6b94ec !important; + position: absolute; } .propertyCascadeItem .card-body { - padding: 3px 12px !important; - background: rgba(255, 255, 255, 0.8); - border-radius: 8px; - margin: 4px 0px; + padding: 3px 12px !important; + background: rgba(255, 255, 255, 0.8); + border-radius: 8px; + margin: 4px 0px; } .propertyCascadeItem .card-body.hidden { - display: none; + display: none; } .landscape { - display: none; - flex-shrink: 0; - align-items: center; - justify-content: flex-end; + display: none; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; } .wide-panel .vertical { - display: none; + display: none; } .wide-panel .landscape { - display: block; - padding: 0px; - overflow: hidden; + display: block; + padding: 0px; + overflow: hidden; } .wide-panel .line-item { - display: flex; + display: flex; } .wide-panel .line-item .f-header { - margin-bottom: 0; + margin-bottom: 0; } .wide-panel .line-item .f-section-formgroup-legend { - width: 89px; - text-align: right; - padding-right: 13px; + width: 89px; + text-align: right; + padding-right: 13px; } .wide-panel .line-item .farris-input-wrap { - flex: 1 1 0; -} \ No newline at end of file + flex: 1 1 0; +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel.css b/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel.css index ac1739e8e74..a83de6b5095 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel.css +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/class/property-panel.css @@ -5,7 +5,6 @@ .property-panel { position: relative; - z-index: 801; } .property-panel .switcher { @@ -151,6 +150,10 @@ font-weight: 600; } +.propertyPanel .search .input-group-clear { + border-radius: 0 !important; +} + /***************************白色主题******************************/ .white-theme .propertyPanel { diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts new file mode 100644 index 00000000000..c07677ccf58 --- /dev/null +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/base-property.ts @@ -0,0 +1,130 @@ +import { DesignerComponentInstance } from "@/components/designer-canvas"; +import { DgControl } from "../../../../designer-canvas/src/composition/dg-control"; +import { cloneDeep } from "lodash-es"; + +/** + * 控件属性基类 + */ +export class BaseControlProperty { + public componentId: string; + + public viewModelId: string; + + public eventsEditorUtils: any; + + public formSchemaUtils: any; + public formMetadataConverter: any; + public designViewModelUtils: any; + public designViewModelField: any; + public controlCreatorUtils: any; + public designerHostService: any; + + schemaService: any = null; + + metadataService: any = null; + + protected propertyConfig = { + type: 'object', + categories: {} + }; + + constructor(componentId: string, designerHostService: any) { + this.componentId = componentId; + this.designerHostService = designerHostService; + this.eventsEditorUtils = designerHostService['eventsEditorUtils']; + this.formSchemaUtils = designerHostService['formSchemaUtils']; + this.formMetadataConverter = designerHostService['formMetadataConverter']; + this.viewModelId = this.formSchemaUtils?.getViewModelIdByComponentId(componentId) || ''; + this.designViewModelUtils = designerHostService['designViewModelUtils']; + this.controlCreatorUtils = designerHostService['controlCreatorUtils']; + this.metadataService = designerHostService['metadataService']; + this.schemaService = designerHostService['schemaService']; + } + + getTableInfo() { + return this.schemaService?.getTableInfoByViewModelId(this.viewModelId); + } + + setDesignViewModelField(propertyData: any) { + const bindingFieldId = propertyData.binding && propertyData.binding.type === 'Form' && propertyData.binding.field; + // 视图模型中[字段更新时机]属性现在要在控件上维护,所以在控件上复制一份属性值 + if (bindingFieldId) { + if (!this.designViewModelField) { + const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); + this.designViewModelField = dgViewModel.fields.find(f => f.id === bindingFieldId); + } + propertyData.updateOn = this.designViewModelField?.updateOn; + } + } + + getBasicPropConfig(propertyData: any): any { + return { + description: 'Basic Information', + title: '基本信息', + properties: { + id: { + description: '组件标识', + title: '标识', + type: 'string', + readonly: true + }, + type: { + description: '组件类型', + title: '控件类型', + type: 'select', + editor: { + type: 'combo-list', + textField: 'name', + valueField: 'value', + editable: false, + data: [{ value: propertyData.type, name: DgControl[propertyData.type] && DgControl[propertyData.type].name }] + } + } + } + }; + + } + + + protected getAppearanceConfig(propertyData = null): any { + return { + title: "外观", + description: "Appearance", + properties: { + class: { + title: "class样式", + type: "string", + description: "组件的CSS样式", + $converter: "/converter/appearance.converter" + }, + style: { + title: "style样式", + type: "string", + description: "组件的样式", + $converter: "/converter/appearance.converter" + } + } + }; + } + + /** + * + * @param propertyId + * @param componentInstance + * @returns + */ + public updateElementByParentContainer(propertyId:string, componentInstance: DesignerComponentInstance){ + // 1、定位控件父容器 + const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; + if (!parentContainer) { + return; + } + const index = parentContainer.contents.findIndex(c => c.id === propertyId); + // 通过cloneDeep方式的触发更新 + const controlSchema = cloneDeep(parentContainer.contents[index]); + // 5、替换控件 + parentContainer.contents.splice(index, 1); + parentContainer.contents.splice(index, 0, controlSchema); + } + +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts new file mode 100644 index 00000000000..32aad5db258 --- /dev/null +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/input-base-property.ts @@ -0,0 +1,390 @@ + +import { BaseControlProperty } from "./base-property"; +import { SchemaDOMMapping } from './schema-dom-mapping'; +import { canvasChanged } from '../../../../designer-canvas/src/composition/designer-canvas-changed'; +import { DesignerComponentInstance } from "../../../../designer-canvas/src/types"; +import { FormUnifiedColumnLayout } from "../type"; +import { + ResponseFormLayoutContext, + UseResponseLayoutEditorSetting, +} from "@/components/response-layout-editor"; +import { useResponseLayoutEditorSetting } from "../../../../response-layout-editor/src/composition/converter/use-response-layout-editor-setting"; +import { FormSchemaEntityFieldType$Type } from "@/components/common"; + +export class InputBaseProperty extends BaseControlProperty { + public responseLayoutEditorFunction: UseResponseLayoutEditorSetting; + constructor(componentId: string, designerHostService: any) { + super(componentId, designerHostService); + this.responseLayoutEditorFunction = useResponseLayoutEditorSetting(this.formSchemaUtils); + } + + public getPropertyConfig(propertyData: any, componentInstance: DesignerComponentInstance) { + // 基本信息 + this.propertyConfig.categories['basic'] = this.getBasicProperties(propertyData, componentInstance); + // 外观 + this.propertyConfig.categories['appearance'] = this.getAppearanceProperties(propertyData, componentInstance); + // 编辑器 + this.propertyConfig.categories['editor'] = this.getEditorProperties(propertyData); + return this.propertyConfig; + } + + public getBasicProperties(propertyData, componentInstance): any { + const self = this; + this.setDesignViewModelField(propertyData); + return { + description: 'Basic Information', + title: '基本信息', + properties: { + id: { + description: '组件标识', + title: '标识', + type: 'string', + readonly: true + }, + type: { + description: '编辑器类型', + title: '编辑器类型', + type: 'string', + refreshPanelAfterChanged: true, + $converter: '/converter/change-editor.converter', + editor: { + type: 'combo-list', + textField: 'value', + valueField: 'key', + editable: false, + data: self.designViewModelField ? SchemaDOMMapping.getEditorTypesByMDataType(self.designViewModelField.type?.name) : SchemaDOMMapping.getAllInputTypes() + } + }, + label: { + title: "标签", + type: "string", + $converter: '/converter/form-group-label.converter' + }, + binding: { + description: "绑定的表单字段", + title: "绑定", + editor: { + type: "binding-selector", + bindingType: { "enable": false }, + editorParams: { + componentSchema: propertyData, + needSyncToViewModel: true, + viewModelId: this.viewModelId, + designerHostService: this.designerHostService, + disableOccupiedFields: true + }, + textField: 'bindingField' + } + } + }, + setPropertyRelates(changeObject, prop) { + if (!changeObject) { + return; + } + switch (changeObject && changeObject.propertyID) { + case 'type': { + self.changeControlType(propertyData, changeObject, componentInstance); + break; + } + case 'label': { + changeObject.needRefreshControlTree = true; + break; + } + } + } + }; + } + public getAppearanceProperties(propertyData, componentInstance): any { + + const self = this; + return { + title: "外观", + description: "Appearance", + properties: { + class: { + title: "class样式", + type: "string", + description: "组件的CSS样式", + $converter: "/converter/appearance.converter" + }, + style: { + title: "style样式", + type: "string", + description: "组件的样式", + $converter: "/converter/appearance.converter" + }, + responseLayout: { + description: "响应式列宽", + title: "响应式列宽", + type: "boolean", + visible: true, + // 这个属性,标记当属性变更得时候触发重新更新属性 + refreshPanelAfterChanged: true, + editor: { + type: "response-layout-editor-setting", + initialState: self.responseLayoutEditorFunction.checkCanOpenLayoutEditor(propertyData, self.componentId) + } + } + }, + setPropertyRelates(changeObject, prop) { + if (!changeObject) { + return; + } + switch (changeObject && changeObject.propertyID) { + case 'responseLayout': + self.responseLayoutEditorFunction.changeFormControlsByResponseLayoutConfig(changeObject.propertyValue, self.componentId || propertyData.id); + self.updateUnifiedLayoutAfterResponseLayoutChanged(self.componentId); + self.updateElementByParentContainer(propertyData.id, componentInstance); + delete propertyData.responseLayout; + break; + case 'class': + self.updateUnifiedLayoutAfterControlChanged(changeObject.propertyValue, propertyData.id, this.componentId); + self.updateElementByParentContainer(propertyData.id, componentInstance); + break; + } + + } + }; + }; + + public getEditorProperties(propertyData): any { + return this.getComponentConfig(propertyData); + } + + + /** + * 卡片控件:切换控件类型后事件 + * @param propertyData 控件DOM属性 + * @param newControlType 新控件类型 + */ + private changeControlType(propertyData, changeObject, componentInstance: DesignerComponentInstance) { + const newControlType = changeObject.propertyValue; + + // 1、定位控件父容器 + const parentContainer = componentInstance && componentInstance.parent && componentInstance.parent['schema']; + if (!parentContainer) { + return; + } + + const index = parentContainer.contents.findIndex(c => c.id === propertyData.id); + const oldControl = parentContainer.contents[index]; + + let newControl; + // 2、记录绑定字段viewModel的变更 + if (this.designViewModelField) { + const dgViewModel = this.designViewModelUtils.getDgViewModel(this.viewModelId); + dgViewModel.changeField(this.designViewModelField.id, { + editor: { + $type: newControlType + }, + name: this.designViewModelField.name, + require: this.designViewModelField.require, + readonly: this.designViewModelField.readonly + }, false); + // 3、创建新控件 + newControl = this.controlCreatorUtils.setFormFieldProperty(this.designViewModelField, newControlType); + } + if (!newControl) { + newControl = this.controlCreatorUtils.createFormGroupWithoutField(newControlType); + } + // 4、保留原id样式等属性 + Object.assign(newControl, { + id: oldControl.id, + appearance: oldControl.appearance, + size: oldControl.size, + label: oldControl.label, + binding: oldControl.binding, + visible: oldControl.visible + }); + Object.assign(newControl.editor, { + isTextArea: newControl.isTextArea && oldControl.isTextArea, + placeholder: oldControl.editor?.placeholder, + holdPlace: oldControl.editor?.holdPlace, + readonly: oldControl.editor?.readonly, + required: oldControl.editor?.required, + }); + + // 5、替换控件 + parentContainer.contents.splice(index, 1); + parentContainer.contents.splice(index, 0, newControl); + componentInstance.schema = Object.assign(oldControl, newControl); + + // 6、暂时移除旧控件的选中样式(后续考虑更好的方式) + Array.from(document.getElementsByClassName('dgComponentSelected') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentSelected') + ); + + Array.from(document.getElementsByClassName('dgComponentFocused') as HTMLCollectionOf).forEach( + (element: HTMLElement) => element.classList.remove('dgComponentFocused') + ); + // 7、触发刷新 + canvasChanged.value++; + + } + + public getComponentConfig(propertyData, info = {}, properties = {}, setPropertyRelates?: any) { + const editorBasic = Object.assign({ + description: "编辑器", + title: "编辑器", + type: "input-group", + $converter: "/converter/property-editor.converter" + }, info); + + const editorProperties = Object.assign({ + readonly: { + description: "", + title: "只读", + type: "boolean", + editor: { + enableClear: true, + editable: true + } + }, + disabled: { + description: "", + title: "禁用", + type: "boolean", + visible: false + }, + // required: { + // description: "", + // title: "必填", + // type: "boolean" + // }, + placeholder: { + description: "空值时,输入控件内的占位文本", + title: "提示文本", + type: "string" + } + }, properties); + + return { ...editorBasic, properties: { ...editorProperties }, setPropertyRelates }; + + } + + + /** + * 修改某一输入控件的样式后更新Form的统一布局配置 + * @param controlClass 控件样式 + * @param controlId 控件Id + * @param componentId 控件所在组件id + */ + private updateUnifiedLayoutAfterControlChanged(controlClass: string, controlId: string, componentId: string) { + const controlClassArray = controlClass.split(' '); + + let colClass = controlClassArray.find(item => /^col-([1-9]|10|11|12)$/.test(item)); + let colMDClass = controlClassArray.find(item => /^col-md-([1-9]|10|11|12)$/.test(item)); + let colXLClass = controlClassArray.find(item => /^col-xl-([1-9]|10|11|12)$/.test(item)); + let colELClass = controlClassArray.find(item => /^col-el-([1-9]|10|11|12)$/.test(item)); + + colClass = colClass || 'col-12'; + colMDClass = colMDClass || 'col-md-' + colClass.replace('col-', ''); + colXLClass = colXLClass || 'col-xl-' + colMDClass.replace('col-md-', ''); + colELClass = colELClass || 'col-el-' + colXLClass.replace('col-xl-', ''); + + const latestControlLayoutConfig = { + id: controlId, + columnInSM: parseInt(colClass.replace('col-', ''), 10), + columnInMD: parseInt(colMDClass.replace('col-md-', ''), 10), + columnInLG: parseInt(colXLClass.replace('col-xl-', ''), 10), + columnInEL: parseInt(colELClass.replace('col-el-', ''), 10), + }; + + this.updateUnifiedLayoutAfterResponseLayoutChanged(componentId, latestControlLayoutConfig); + } + + /** + * 修改控件布局配置后更新Form统一布局配置 + * @param componentId 组件Id + * @param controlLayoutConfig 某单独变动的控件配置项,FormResponseLayoutContext类型 + */ + private updateUnifiedLayoutAfterResponseLayoutChanged(componentId: string, controlLayoutConfig?: any): FormUnifiedColumnLayout | undefined { + const { formNode } = this.responseLayoutEditorFunction.checkCanFindFormNode(componentId); + // 更改form上的统一配置 + if (!formNode || !formNode.unifiedLayout) { + return; + } + const responseLayoutConfig: ResponseFormLayoutContext[] = []; + this.responseLayoutEditorFunction.getResonseFormLayoutConfig(formNode, responseLayoutConfig, 1); + if (controlLayoutConfig) { + const changedControl = responseLayoutConfig.find(c => c.id === controlLayoutConfig.id); + Object.assign(changedControl || {}, controlLayoutConfig); + } + + // 收集每种屏幕下的列数 + const columnInSMArray = responseLayoutConfig.map(config => config.columnInSM); + const columnInMDArray = responseLayoutConfig.map(config => config.columnInMD); + const columnInLGArray = responseLayoutConfig.map(config => config.columnInLG); + const columnInELArray = responseLayoutConfig.map(config => config.columnInEL); + + // 只有每个控件的宽度都一样时,才认为form上有统一宽度,否则认为是自定义的控件宽度,此处传递null + const uniqueColClassInSM = this.checkIsUniqueColumn(columnInSMArray) ? columnInSMArray[0] : null; + const uniqueColClassInMD = this.checkIsUniqueColumn(columnInMDArray) ? columnInMDArray[0] : null; + const uniqueColClassInLG = this.checkIsUniqueColumn(columnInLGArray) ? columnInLGArray[0] : null; + const uniqueColClassInEL = this.checkIsUniqueColumn(columnInELArray) ? columnInELArray[0] : null; + + + Object.assign(formNode.unifiedLayout, { + uniqueColClassInSM, + uniqueColClassInMD, + uniqueColClassInLG, + uniqueColClassInEL + }); + } + /** + * 校验宽度样式值是否一致 + */ + private checkIsUniqueColumn(columnsInScreen: number[]) { + const keySet = new Set(columnsInScreen); + const exclusiveKeys = Array.from(keySet); + + if (exclusiveKeys.length === 1) { + return true; + } + return false; + } + /** + * 枚举项编辑器 + * @param propertyData + * @param valueField + * @param textField + * @returns + */ + protected getItemCollectionEditor(propertyData, valueField, textField) { + valueField = valueField || 'value'; + textField = textField || 'name'; + return { + editor: { + columns: [ + { field: valueField, title: '值', dataType: 'string' }, + { field: textField, title: '名称', dataType: 'string' }, + { field: 'disabled', title: '禁用', visible: false, dataType: 'boolean', editor: { type: 'switch' } }, + ], + type: "item-collection-editor", + valueField: valueField, + nameField: textField, + requiredFields: [valueField, textField], + uniqueFields: [valueField, textField], + readonly: this.checkEnumDataReadonly(propertyData) + } + }; + } + /** + * 判断枚举数据是否只读 + * 1、没有绑定信息或者绑定变量,可以新增、删除、修改 + * 2、绑定类型为字段,且字段为枚举字段,则不可新增、删除、修改枚举值。只能从be修改然后同步到表单上。 + * @param propertyData 下拉框控件属性值 + */ + private checkEnumDataReadonly(propertyData: any): boolean { + // 没有绑定信息或者绑定变量 + if (!propertyData.binding || propertyData.binding.type !== 'Form') { + return false; + } + if (this.designViewModelField && this.designViewModelField.type && + this.designViewModelField.type.$type === FormSchemaEntityFieldType$Type.EnumType) { + // 低代码、零代码,枚举字段均不可以改 + return true; + } + return false; + } +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/property-entity.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/property-entity.ts index de97d6be5f6..2a8f1dcd855 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/property-entity.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/property-entity.ts @@ -1,208 +1,240 @@ -import { Ref } from 'vue'; -import { PropertyType } from '../type'; +import { EditorConfig } from "@/components/dynamic-form"; +import { Ref } from "vue"; export interface KeyMap { - key: any; - value: any; + key: any; + value: any; } /** 属性实体 */ export interface PropertyEntity { - /** - * 属性ID - */ - propertyID: string; - - /** - * 属性显示的名称 - */ - propertyName?: string; - - /** - * 属性的类型 - */ - propertyType: PropertyType | any; - - /** - * 属性描述 - */ - description?: string; - - /** - * 属性的默认值 - */ - defaultValue?: any; - - propertyValue: Ref; - - /** - * 是否只读,默认false - */ - readonly?: boolean; - - /** - * 是否可见,默认true - */ - visible?: boolean; - - /** - * 最小值 - */ - min?: any; - - /** - * 最大值 - */ - max?: any; - - /** - * 数字类型属性的小数位数 - */ - decimals?: number; - - /** - * 是否大数字 - */ - isBigNumber?: boolean; - - /** - * 属性改变后是否需要刷新整个面板:用于更改其他分类下的属性 - */ - refreshPanelAfterChanged?: boolean; - - /** - * 下拉框的枚举值 - */ - iterator?: KeyMap[]; - - /** - * 下拉多选类型:属性值的类型:string(多值以逗号分隔)/array(多值组装成数组) - */ - multiSelectDataType?: string; - - /** - * 文本控件限制输入的字符,支持字符和正则表达式 - */ - notAllowedChars?: any[]; - - /** - * 级联属性配置 - */ - cascadeConfig?: PropertyEntity[]; - - /** - * 级联属性是否默认收起 - */ - isExpand?: boolean; - - /** - * 是否隐藏级联属性的头部 - */ - hideCascadeTitle?: boolean; - - /** - * 模态框属性自定义编辑器参数 - */ - editorParams?: any; - - /** 模态框属性是否展示清除图标 */ - showClearButton?: boolean; - - /** 点击清除按钮后的方法,参数为清除前的属性值 */ - afterClickClearButton?(value: any): void; - - /** 点击清除按钮时是否需要弹窗确认 */ - showQuestionBeforeClear?: boolean; - - /** 点击清除按钮时弹窗确认的文案 */ - questionMessage?: string; - + /** + * 属性ID + */ + propertyID: string; + + /** + * 属性显示的名称 + */ + propertyName?: string; + + /** + * 属性的类型 + */ + propertyType: any; + + /** + * 属性描述 + */ + description?: string; + + /** + * 属性的默认值 + */ + defaultValue?: any; + + propertyValue?: Ref; + + /** + * 是否只读,默认false + */ + readonly?: () => boolean; + + /** + * 是否可见,默认true + */ + visible: boolean | (() => boolean); + + /** + * 最小值 + */ + min?: any; + + /** + * 最大值 + */ + max?: any; + + /** + * 数字类型属性的小数位数 + */ + decimals?: number; + + /** + * 是否大数字 + */ + isBigNumber?: boolean; + + /** + * 属性改变后是否需要刷新整个面板:用于属性有联动修改的场景 + */ + refreshPanelAfterChanged?: boolean; + + /** + * 下拉框的枚举值 + */ + iterator?: KeyMap[]; + + /** + * 下拉多选类型:属性值的类型:string(多值以逗号分隔)/array(多值组装成数组) + */ + multiSelectDataType?: string; + + /** + * 文本控件限制输入的字符,支持字符和正则表达式 + */ + notAllowedChars?: any[]; + + /** + * 级联属性配置 + */ + cascadeConfig?: PropertyEntity[]; + + /** + * 级联属性是否默认收起 + */ + isExpand?: boolean; + + /** + * 是否隐藏级联属性的头部 + */ + hideCascadeTitle?: boolean; + + /** + * 模态框属性自定义编辑器参数 + */ + editorParams?: any; + + /** 模态框属性是否展示清除图标 */ + showClearButton?: boolean; + + /** 点击清除按钮后的方法,参数为清除前的属性值 */ + afterClickClearButton?(value: any): void; + + /** 点击清除按钮时是否需要弹窗确认 */ + showQuestionBeforeClear?: boolean; + + /** 点击清除按钮时弹窗确认的文案 */ + questionMessage?: string; + + editor?: EditorConfig; } export interface ElementPropertyConfig { - /** - * 分类ID - */ - categoryId: string; - - /** - * 分类显示的名称 - */ - categoryName: string; - - /** - * 分类是否隐藏,默认false - */ - hide?: boolean; - - /** - * 是否隐藏分类标题 - */ - hideTitle?: boolean; - - /** - * 分类下的属性配置 - */ - properties: PropertyEntity[]; - - /** - * 是否启用级联特性,默认false - */ - enableCascade?: boolean; - - /** - * 属性值:分类启用级联特性时必填 - */ - propertyData?: any; - - /** - * 父级属性ID:分类启用级联特性时必填 - */ - parentPropertyID?: string; - - /** - * 属性关联关系,用于属性变更后修改其他属性配置或属性值 - */ - setPropertyRelates?: (changeObject: any, propertyData: any, parameters?: any) => void; - - /** - * 分类以标签页展示时,标签页的ID。若只需平铺展示,则不需要传入。 - */ - tabId?: string; - - /** - * 分类以标签页展示时,标签页的名称。若只需平铺展示,则不需要传入。 - */ - tabName?: string; + /** + * 分类ID + */ + categoryId: string; + + /** + * 分类显示的名称 + */ + categoryName: string; + + /** + * 分类是否隐藏,默认false + */ + hide?: boolean; + + /** + * 是否隐藏分类标题 + */ + hideTitle?: boolean; + + /** + * 分类下的属性配置 + */ + properties: PropertyEntity[]; + + /** + * 是否启用级联特性,默认false + */ + enableCascade?: boolean; + + /** + * 属性值:分类启用级联特性时必填 + */ + propertyData?: any; + + /** + * 父级属性ID:分类启用级联特性时必填 + */ + parentPropertyID?: string; + + /** + * 属性关联关系,用于属性变更后修改其他属性配置或属性值 + */ + setPropertyRelates?: (changeObject: any, propertyData: any, parameters?: any) => void; + + /** + * 分类以标签页展示时,标签页的ID。若只需平铺展示,则不需要传入。 + */ + tabId?: string; + + /** + * 分类以标签页展示时,标签页的名称。若只需平铺展示,则不需要传入。 + */ + tabName?: string; + + status?: string; } /** * 属性变更集 */ export interface PropertyChangeObject { - /** - * 属性ID - */ - propertyID: string; - - /** - * 变更后的属性值 - */ - propertyValue: any; - - /** - * 属性所在分类ID - */ - categoryId: string; - - /** - * 级联属性的父路径,以.分隔 - */ - propertyPath: string; - - /** - * 级联属性的父属性ID - */ - parentPropertyID: string; + /** + * 属性ID + */ + propertyID: string; + + /** + * 变更后的属性值 + */ + propertyValue: any; + + /** + * 属性所在分类ID + */ + categoryId?: string; + + /** + * 级联属性的父路径,以.分隔 + */ + propertyPath?: string; + + /** + * 级联属性的父属性ID + */ + parentPropertyID?: string; }; +/** + * 属性变更实体类 + */ +export interface FormPropertyChangeObject extends PropertyChangeObject { + + /** 属性变更后是否需要整体刷新表单 */ + needRefreshForm?: boolean; + + /** 属性变更后需要局部刷新的组件id */ + needRefreshedComponentId?: string; + + /** 是否需要刷新控件树 */ + needRefreshControlTree?: boolean; + + /** 是否需要更新控件树节点名称 */ + needUpdateControlTreeNodeName?: boolean; + + /** 关联变更的属性集合,用于更新表单DOM属性 */ + relateChangeProps?: Array<{ + propertyID: string, + propertyValue: any + }>; + + /** 属性变更后是否需要向schema字段同步 */ + needSyncToSchemaField?: boolean; + + /** 强关联的属性id:在当前属性变更后,页面自动定位到强关联的属性 */ + autoLocatedPropertyId?: string; +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts new file mode 100644 index 00000000000..fe8b7152564 --- /dev/null +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/schema-dom-mapping.ts @@ -0,0 +1,79 @@ + +import { DgControl } from "../../../../designer-canvas/src/composition/dg-control"; + +export class SchemaDOMMapping { + + /** + * <字段类型,可配置的控件类型列表>的映射 + */ + static fieldControlTypeMapping = { + String: [ + { key: DgControl['input-group'].type, value: DgControl['input-group'].name }, + { key: DgControl['lookup'].type, value: DgControl['lookup'].name }, + { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name }, + { key: DgControl['check-group'].type, value: DgControl['check-group'].name }, + { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, + { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, + ], + Text: [ + { key: DgControl['textarea'].type, value: DgControl['textarea'].name }, + { key: DgControl['lookup'].type, value: DgControl['lookup'].name } + ], + Decimal: [ + { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + ], + Integer: [ + { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + ], + Number: [ + { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + ], + BigNumber: [ + { key: DgControl['number-spinner'].type, value: DgControl['number-spinner'].name } + ], + Date: [ + { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } + ], + DateTime: [ + { key: DgControl['date-picker'].type, value: DgControl['date-picker'].name } + ], + Boolean: [ + { key: DgControl['switch'].type, value: DgControl['switch'].name }, + { key: DgControl['check-box'].type, value: DgControl['check-box'].name }, + ], + Enum: [ + { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, + ], + Object: [ + { key: DgControl['lookup'].type, value: DgControl['lookup'].name }, + { key: DgControl['combo-list'].type, value: DgControl['combo-list'].name }, + { key: DgControl['radio-group'].type, value: DgControl['radio-group'].name }, + ] + }; + /** + * 根据绑定字段类型获取可用的输入类控件 + */ + static getEditorTypesByMDataType(fieldType: string) { + const foundTypes = SchemaDOMMapping.fieldControlTypeMapping[fieldType]; + return foundTypes ? foundTypes : [{ key: "", value: "" }]; + + } + /** + * 获取所有输入类控件 + */ + static getAllInputTypes() { + const allControlTypes: Array<{ key: string, value: string }> = []; + for (const fieldType in SchemaDOMMapping.fieldControlTypeMapping) { + SchemaDOMMapping.fieldControlTypeMapping[fieldType].forEach(control => { + if (!allControlTypes.find(controlKeyValue => controlKeyValue.key === control.key && controlKeyValue.value === control.value)) { + allControlTypes.push({ key: control.key, value: control.value }); + } + }); + } + + return allControlTypes; + } + +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts new file mode 100644 index 00000000000..111c3ced7a7 --- /dev/null +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/entity/use-input-rules.ts @@ -0,0 +1,62 @@ + +import { ref } from "vue"; +import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from '../../../../designer-canvas/src/composition/types'; +import { ComponentSchema, DesignerItemContext } from "@/components/designer-canvas"; + +export function useInputDesignerRules(designItemContext: DesignerItemContext, designerHostService): UseDesignerRules { + const schema = designItemContext.schema as ComponentSchema; + /** 组件在拖拽时需要将所属的Component一起拖拽 */ + const triggerBelongedComponentToMoveWhenMoved = ref(true); + /** 组件在删除时需要将所属的Component一起拖拽 */ + const triggerBelongedComponentToDeleteWhenDeleted = ref(true); + /** data-grid所属的上级组件控制规则 */ + /** + * 判断是否可以接收拖拽新增的子级控件 + */ + function canAccepts(draggingContext: DraggingResolveContext): boolean { + return false; + } + + /** + * data-grid是否支持删除,取决于所属组件是否支持删除 + */ + function checkCanDeleteComponent() { + return false; + } + /** + * data-grid是否支持移动,取决于所属组件是否支持移动 + */ + function checkCanMoveComponent() { + return false; + } + + function hideNestedPaddingInDesginerView() { + return true; + } + + function onAcceptMovedChildElement(sourceElement: DesignerHTMLElement) { + } + /** + * 判断data-grid上下文 + */ + function resolveComponentContext() { + + } + // 构造属性配置方法 + function getPropsConfig(componentId: string) { + return null; + } + + return { + canAccepts, + checkCanDeleteComponent, + checkCanMoveComponent, + hideNestedPaddingInDesginerView, + onAcceptMovedChildElement, + resolveComponentContext, + triggerBelongedComponentToMoveWhenMoved, + triggerBelongedComponentToDeleteWhenDeleted, + getPropsConfig + } as UseDesignerRules; + +} diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item-list.props.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item-list.props.ts index 62d1f567314..40bf0ca77a9 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item-list.props.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item-list.props.ts @@ -13,21 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; +import { ElementPropertyConfig } from '../entity/property-entity'; export const propertyPanelItemListProps = { + /** 某一分类下的属性配置 */ + // as PropType + category: { type: Object, default: {} }, - /** 某一分类下的属性配置 */ - category: { type: Object, default: {} }, + categoryKey: { type: String }, + /** 属性值 */ + propertyData: { type: Object, default: {} }, - categoryKey: { type: String }, + valueChanged: { type: Function }, - /** 属性值 */ - propertyData: { type: Object, default: {} }, - - valueChanged: { type: Function }, - - triggerRefreshPanel: { type: Function } + triggerRefreshPanel: { type: Function } }; - export type PropertyPanelItemListProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item.props.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item.props.ts index c9fcb73588c..c87c39e87b0 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item.props.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel-item.props.ts @@ -16,7 +16,7 @@ import { ExtractPropTypes, PropType } from 'vue'; export const propertyPanelItemProps = { - elementConfig: { type: Object, default: {} }, - category: { type: Object, default: {} } + elementConfig: { type: Object, default: {} }, + category: { type: Object, default: {} } }; export type PropertyPanelItemProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel.props.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel.props.ts index bd5dfda01c1..456a906bfad 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel.props.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/props/property-panel.props.ts @@ -19,44 +19,46 @@ type ShowMode = 'panel' | 'sidebar'; export const propertyPanelProps = { - width: { type: String, default: '300px' }, + width: { type: String, default: '300px' }, - height: { type: Number, default: 10 }, + height: { type: Number, default: 10 }, - isWidePanel: { type: Boolean, default: false }, + isWidePanel: { type: Boolean, default: false }, - /** 是否启用搜索 */ - enableSearch: { type: Boolean, default: true }, + /** 是否启用搜索 */ + enableSearch: { type: Boolean, default: true }, - /** 使用模式 */ - mode: { type: String as PropType, default: 'panel' }, + /** 使用模式 */ + mode: { type: String as PropType, default: 'panel' }, - /** 是否持有面板的隐藏显示状态 */ - isPersitOpenState: { type: Boolean, default: false }, + /** 是否持有面板的隐藏显示状态 */ + isPersitOpenState: { type: Boolean, default: false }, - /** isPersitOpenState=true时,控制面板是否隐藏显示 */ - isShowPanel: { type: Boolean, default: false }, + /** isPersitOpenState=true时,控制面板是否隐藏显示 */ + isShowPanel: { type: Boolean, default: false }, - /** 属性名 */ - propertyName: { type: String, default: '' }, + /** 属性名 */ + propertyName: { type: String, default: '' }, - /** 属性类型 */ - propertyConfig: { type: Array }, + /** 属性类型 */ + propertyConfig: { type: Array }, - /** 属性值 */ - propertyData: { type: Object, default: {} }, + /** 属性值 */ + propertyData: { type: Object, default: {} }, - /** 是否展示关闭按钮 */ - showCloseBtn: { type: Boolean, default: false }, + /** 是否展示关闭按钮 */ + showCloseBtn: { type: Boolean, default: false }, - /** 当前选中的标签页id */ - selectedTabId: { type: String, default: '' }, + /** 当前选中的标签页id */ + selectedTabId: { type: String, default: '' }, - /** 是否是白色主题 */ - isWhiteTheme: { type: Boolean, default: true }, + /** 是否是白色主题 */ + isWhiteTheme: { type: Boolean, default: true }, - /** dom结构 */ - schema: { type: Object, default: {} } + /** dom结构 */ + schema: { type: Object, default: {} }, + /** 属性变更后事件 */ + propertyChanged: { type: Function } }; export type PropertyPanelProps = ExtractPropTypes; diff --git a/packages/mobile-ui-vue/components/property-panel/src/composition/type.ts b/packages/mobile-ui-vue/components/property-panel/src/composition/type.ts index 7c86322dd68..f6727192b3f 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/composition/type.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/composition/type.ts @@ -2,63 +2,83 @@ * 属性类型 */ export enum PropertyType { + /** 字符串 */ + string = 'string', - /** 字符串 */ - string = 'string', + /** 布尔,下拉选择 */ + boolean = 'boolean', - /** 布尔,下拉选择 */ - boolean = 'boolean', + /** 数字 */ + number = 'number', - /** 数字 */ - number = 'number', + /** 下拉选择:单选 */ + select = 'select', - /** 下拉选择:单选 */ - select = 'select', + /** 已废弃,请使用editableSelect */ + boolOrExp = 'boolOrExp', - /** 已废弃,请使用editableSelect */ - boolOrExp = 'boolOrExp', + /** 可编辑的下拉选择:单选,并且可编辑 */ + editableSelect = 'editableSelect', - /** 可编辑的下拉选择:单选,并且可编辑 */ - editableSelect = 'editableSelect', + /** 下拉多选 */ + multiSelect = 'multiSelect', - /** 下拉多选 */ - multiSelect = 'multiSelect', + /** 日期 */ + date = 'date', - /** 日期 */ - date = 'date', + /** 日期时间 */ + datetime = 'datetime', - /** 日期时间 */ - datetime = 'datetime', + /** 模态窗,自定义组件 */ + modal = 'modal', - /** 模态窗,自定义组件 */ - modal = 'modal', + /** 级联 */ + cascade = 'cascade', - /** 级联 */ - cascade = 'cascade', + /** 自定义组件 */ + custom = 'custom', - /** 自定义组件 */ - custom = 'custom', + /** 多功能属性编辑器,支持常量、变量、自定义、表达式等场景 */ + unity = 'unity', - /** 多功能属性编辑器,支持常量、变量、自定义、表达式等场景 */ - unity = 'unity', + /** 事件编辑器集成,支持导入命令、参数编辑等场景 */ + events = 'events', - /** 事件编辑器集成,支持导入命令、参数编辑等场景 */ - events = 'events', + /** 开关类编辑器,适用于布尔值属性 */ + switch = 'switch', - /** 开关类编辑器,适用于布尔值属性 */ - switch = 'switch', - - /** 多语言输入框 */ - multiLanguage = 'multiLanguage' + /** 多语言输入框 */ + multiLanguage = 'multiLanguage' } /** 属性值转换器,返回模态框类属性文本框内的显示内容 */ export interface TypeConverter { - // 由模态框转为属性框中展示的值 - convertTo(data: any, params?: any): string; + // 由模态框转为属性框中展示的值 + convertTo(data: any, params?: any): string; } export interface KeyMap { - key: any; - value: any; + key: any; + value: any; +} + +/** + * binding 类型 + */ +export enum FormBindingType { + Form = "Form", + Variable = "Variable" } + +export interface FormUnifiedColumnLayout { + uniqueColClassInSM: number; + uniqueColClassInMD: number; + uniqueColClassInLG: number; + uniqueColClassInEL: number; +} + +export interface IPropertyConfig { + getPropertyConfig(propertyData: any, eventsEditorUtils: any); +} + +export * from './entity/property-entity'; diff --git a/packages/mobile-ui-vue/components/property-panel/src/mock.ts b/packages/mobile-ui-vue/components/property-panel/src/mock.ts index 2c221ca6959..8266d0cfe1d 100644 --- a/packages/mobile-ui-vue/components/property-panel/src/mock.ts +++ b/packages/mobile-ui-vue/components/property-panel/src/mock.ts @@ -1,174 +1,174 @@ export const propertyConfigTemp = [ - { - categoryId: 'basic', - categoryName: '基本信息', - properties: [ - { - propertyID: 'id', - propertyName: '标识', - propertyType: 'string', - description: '组件的id', - readonly: true - }, - { - propertyID: 'type', - propertyName: '控件类型', - propertyType: 'select', - description: '组件的类型', - } - ] - }, - { - categoryId: 'appearance', - categoryName: '样式', - properties: [ - { - propertyID: 'fill', - propertyName: '填充', - propertyType: 'datetime', - description: 'flex布局下,填充满剩余部分', - modelValue: '2023-4-9', - editor: { - id: 'd152e48d-13d1-4553-94fa-525fa67d4f2b', - type: 'date-picker', - require: false, - format: 'yyyy-MM-dd', - weekSelect: false, - startFieldCode: 'BillDate', - endFieldCode: 'BillDate' - }, - }, - { - propertyID: 'expanded', - propertyName: '展开', - propertyType: 'boolean', - description: '是否展开', - modelValue: 'false', - editor: { - type: 'combo-list', - require: false, - valueType: '1', - multiSelect: false, - data: [ + { + categoryId: 'basic', + categoryName: '基本信息', + properties: [ { - value: 'true', - name: 'true' + propertyID: 'id', + propertyName: '标识', + propertyType: 'string', + description: '组件的id', + readonly: true }, { - value: 'false', - name: 'false' + propertyID: 'type', + propertyName: '控件类型', + propertyType: 'select', + description: '组件的类型', } - ] - } - }, - { - propertyID: 'showHeader', - propertyName: '显示头部区域', - propertyType: 'boolean', - description: '是否显示头部区域', - modelValue: 'true', - editor: { - type: 'combo-list', - require: false, - valueType: '1', - multiSelect: false, - data: [ + ] + }, + { + categoryId: 'appearance', + categoryName: '样式', + properties: [ + { + propertyID: 'fill', + propertyName: '填充', + propertyType: 'datetime', + description: 'flex布局下,填充满剩余部分', + modelValue: '2023-4-9', + editor: { + id: 'd152e48d-13d1-4553-94fa-525fa67d4f2b', + type: 'date-picker', + require: false, + format: 'yyyy-MM-dd', + weekSelect: false, + startFieldCode: 'BillDate', + endFieldCode: 'BillDate' + }, + }, + { + propertyID: 'expanded', + propertyName: '展开', + propertyType: 'boolean', + description: '是否展开', + modelValue: 'false', + editor: { + type: 'combo-list', + require: false, + valueType: '1', + multiSelect: false, + data: [ + { + value: 'true', + name: 'true' + }, + { + value: 'false', + name: 'false' + } + ] + } + }, { - value: 'true', - name: 'true' + propertyID: 'showHeader', + propertyName: '显示头部区域', + propertyType: 'boolean', + description: '是否显示头部区域', + modelValue: 'true', + editor: { + type: 'combo-list', + require: false, + valueType: '1', + multiSelect: false, + data: [ + { + value: 'true', + name: 'true' + }, + { + value: 'false', + name: 'false' + } + ] + } }, { - value: 'false', - name: 'false' + propertyID: 'mainTitle', + propertyName: '主标题', + propertyType: 'string', + description: '主标题名称', + group: 'header' + }, + { + propertyID: 'subTitle', + propertyName: '副标题', + propertyType: 'string', + description: '副标题名称', + group: 'header' + }, + { + propertyID: 'enableMaximize', + propertyName: '显示最大化', + propertyType: 'boolean', + description: '是否显示最大化', + group: 'header' + }, + { + propertyID: 'enableAccordion', + propertyName: '启用收折功能', + propertyType: 'boolean', + description: '是否启用收折功能', + group: 'header' + }, + { + propertyID: 'accordionMode', + propertyName: '收折模式', + propertyType: 'select', + description: '收折模式选择', + iterator: [{ key: 'default', value: '默认收折' }, { key: 'custom', value: '自定义收折' }], + group: 'header' } - ] - } - }, - { - propertyID: 'mainTitle', - propertyName: '主标题', - propertyType: 'string', - description: '主标题名称', - group: 'header' - }, - { - propertyID: 'subTitle', - propertyName: '副标题', - propertyType: 'string', - description: '副标题名称', - group: 'header' - }, - { - propertyID: 'enableMaximize', - propertyName: '显示最大化', - propertyType: 'boolean', - description: '是否显示最大化', - group: 'header' - }, - { - propertyID: 'enableAccordion', - propertyName: '启用收折功能', - propertyType: 'boolean', - description: '是否启用收折功能', - group: 'header' - }, - { - propertyID: 'accordionMode', - propertyName: '收折模式', - propertyType: 'select', - description: '收折模式选择', - iterator: [{ key: 'default', value: '默认收折' }, { key: 'custom', value: '自定义收折' }], - group: 'header' - } - ] - }, - { - categoryId: 'toolbar', - categoryName: '工具栏', - properties: [ - { - propertyID: 'toolbarCls', - propertyName: '工具栏样式', - propertyType: 'string' - }, - { - propertyID: 'toolbarBtnSize', - propertyName: '按钮尺寸', - propertyType: 'select', - iterator: [ - { key: 'default', value: '标准' }, - { key: 'lg', value: '大号' } ] - }, - { - propertyID: 'toolbarPopDirection', - propertyName: '弹出方向', - propertyType: 'select', - iterator: [ - { key: 'default', value: '自动' }, - { key: 'top', value: '向上' }, - { key: 'bottom', value: '向下' } + }, + { + categoryId: 'toolbar', + categoryName: '工具栏', + properties: [ + { + propertyID: 'toolbarCls', + propertyName: '工具栏样式', + propertyType: 'string' + }, + { + propertyID: 'toolbarBtnSize', + propertyName: '按钮尺寸', + propertyType: 'select', + iterator: [ + { key: 'default', value: '标准' }, + { key: 'lg', value: '大号' } + ] + }, + { + propertyID: 'toolbarPopDirection', + propertyName: '弹出方向', + propertyType: 'select', + iterator: [ + { key: 'default', value: '自动' }, + { key: 'top', value: '向上' }, + { key: 'bottom', value: '向下' } + ] + } ] - } - ] - } + } ]; export const propertyDataTemp = { - id: 'dataGrid', - testCategoryCascade: { - showSize2: false - }, - language1: { - 'zh-CHS': 'check1', - 'en': 'hhhh' - }, - language2: { - 'en': 'hhhh2', - 'zh-CHS': 'check2', - }, - language3: { - 'en': 'hhhh3', - 'zh-CHS': 'check3', - } + id: 'dataGrid', + testCategoryCascade: { + showSize2: false + }, + language1: { + 'zh-CHS': 'check1', + 'en': 'hhhh' + }, + language2: { + 'en': 'hhhh2', + 'zh-CHS': 'check2', + }, + language3: { + 'en': 'hhhh3', + 'zh-CHS': 'check3', + } }; diff --git a/packages/mobile-ui-vue/components/property-panel/src/property-panel.component.tsx b/packages/mobile-ui-vue/components/property-panel/src/property-panel.component.tsx deleted file mode 100644 index 82ada996560..00000000000 --- a/packages/mobile-ui-vue/components/property-panel/src/property-panel.component.tsx +++ /dev/null @@ -1,456 +0,0 @@ - - -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by ,applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { defineComponent, SetupContext, ref, watch, onMounted, onBeforeMount } from 'vue'; -import { PropertyPanelProps, propertyPanelProps } from './composition/props/property-panel.props'; -import { getPropertyConfigBySchema } from '../../dynamic-resolver/src/property-config-resolver'; -import FPropertyPanelItemList from '../src/component/property-panel-item-list.component'; - -import './composition/class/property-panel.css'; -import { ElementPropertyConfig } from '../../designer-canvas/src/composition/entity/property-entity'; - -export default defineComponent({ - name: 'FPropertyPanel', - props: propertyPanelProps, - emits: [] as (string[] & ThisType) | undefined, - setup(props: PropertyPanelProps, context: SetupContext) { - const width = ref(props.width); - const isWidePanel = ref(props.isWidePanel); - /** 是否启用搜索 */ - const enableSearch = ref(props.enableSearch); - /** 使用模式 */ - const mode = ref(props.mode); - /** 是否持有面板的隐藏显示状态 */ - const isPersitOpenState = ref(props.isPersitOpenState); - /** isPersitOpenState=true时,控制面板是否隐藏显示 */ - const isShowPanel = ref(props.isShowPanel); - /** 属性类型 */ - const propertyConfig = ref(); - /** 属性值 */ - const propertyData = ref(); - /** 是否展示关闭按钮 */ - const showCloseBtn = ref(props.showCloseBtn); - /** 当前选中的标签页id */ - const selectedTabId = ref(props.selectedTabId); - /** 当前显示状态 */ - const isOpen = ref(true); - /** 是否是白色主题 */ - const isWhiteTheme = ref(props.isWhiteTheme); - /** 外层分类,以标签页形式展示 */ - let categoryTabs: any = []; - let properties: any = []; - const keyword = ref(''); - const fPropertyPanel = ref(); - const propertyPanel = ref(); - - let matchedElementRefs: Array = []; - - /** 当前选中的标签页 */ - let selectedTab: any; - - function collectProperties() { - properties = []; - if (selectedTab && selectedTab.categoryList && Array.isArray(selectedTab.categoryList) && selectedTab.categoryList.length > 0) { - const categoryLists = selectedTab.categoryList; - categoryLists.forEach((category: any) => { - category.properties.forEach((item: any) => item.categoryId = category.categoryId); - if (category.properties && Array.isArray(category.properties) && category.properties.length > 0) { - const props = category.properties.map((item: any) => { - item.category = category; - return item; - }); - properties = properties.concat(props); - } - }); - } - } - - function getElementTop(element: any) { - let actualTop = element.offsetTop; - let current = element.offsetParent; - while (current !== null) { - actualTop += current.offsetTop; - current = current.offsetParent; - } - return actualTop; - } - function setElementStyle(element: any, styles: any) { - if (element && styles && Object.keys(styles).length > 0) { - Object.keys(styles).forEach((style: string) => { - const value = styles[style]; - element.style?.setProperty(style, value); - }); - } - } - - /** 比较搜索值与属性面板 */ - function compareSearchValue() { - const items = properties.filter((item: any) => { - if (!item.visible) { - return false; - } - if (item.propertyID && item.propertyID.startsWith(keyword.value)) { - return true; - } - if (item.propertyName && (item.propertyName.startsWith(keyword.value) || item.propertyName.includes(keyword.value))) { - return true; - } - return false; - }); - return items; - } - - function scrollPanel(index: number, panelElement: HTMLElement, element: HTMLElement) { - if (index === 0) { - const panelBodyTop = getElementTop(panelElement); - const elementTop = getElementTop(element); - const offsetTop = elementTop - panelBodyTop - 5; - panelElement?.scroll({ - top: offsetTop, - behavior: 'smooth' - }); - } - } - - /** 搜索框属性值变化 */ - function onValueChangeEvent(searchKey?: string) { - if (matchedElementRefs && matchedElementRefs.length > 0) { - matchedElementRefs.forEach((element: any) => { - element.style.cssText = ''; - }); - matchedElementRefs = []; - } - keyword.value = searchKey || keyword.value; - const panelElement = document.querySelector(".panel-body") as HTMLElement; - if (!keyword.value) { - if (fPropertyPanel.value && panelElement) { - panelElement.scrollTop = 0; - } - - } else { - collectProperties(); - if (properties && properties.length > 0) { - const items = compareSearchValue(); - if (items && items.length > 0) { - if (items[0].category.status === 'closed') { - items[0].category.status = 'open'; - } - setTimeout(() => { - items.forEach((item: any, index: number) => { - const selector = item.propertyType === 'cascade' ? `.${item.categoryId}-${item.propertyID} div.col-form-label` : - `.property-item .${item.categoryId}-${item.propertyID} label.col-form-label`; - const element = document.querySelector(selector) as HTMLElement; - if (element) { - scrollPanel(index, panelElement, element); - setElementStyle(element, { color: '#5B89FE' }); - matchedElementRefs.push(element); - } - }); - }, 50); - } - } - } - } - - function search(searchKey?: string) { - onValueChangeEvent(searchKey); - } - /** - * 回车搜索事件 - * @param event - */ - function onSearchBoxKeyUpEvent(event: KeyboardEvent) { - const { value } = event.target as any; - if (event.key === 'Enter') { - search(value); - } - } - function onSearchEvent(event: any) { - const { value } = event.target; - search(value); - } - - /** - * 隐藏面板 - */ - function collapse() { - // isPersitOpenState=true时,由外部确定状态 - if (!isPersitOpenState.value) { - isOpen.value = false; - } - context.emit('closePropertyPanel'); - } - - function onClearEvent(event: any) { - keyword.value = ''; - onValueChangeEvent(); - } - /** 收折 */ - function changeStatus(item: any) { - if (!item.status || item.status === 'open') { - item.status = 'closed'; - } else { - item.status = 'open'; - } - } - - /** - * 将属性分类按照标签页进行归类 - */ - function checkShowTabCategory() { - categoryTabs = []; - if (!propertyConfig.value || propertyConfig.value.length === 0) { - categoryTabs = [ - { - tabId: 'default', - tabName: '属性', - categoryList: [] - } - ]; - selectedTab = null; - return; - } - propertyConfig?.value?.forEach((config: any) => { - if (config.tabId) { - const propTab = categoryTabs.find((t: any) => t.tabId === config.tabId) as any; - if (!propTab) { - categoryTabs.push({ - tabId: config.tabId, - tabName: config.tabName, - categoryList: [config], - hide: config.hide || config.properties.length === 0 - }); - } else { - propTab.categoryList.push(config); - if (propTab.hide) { - propTab.hide = config.hide || config.properties.length === 0; - } - } - } else { - const defaultTab = categoryTabs.find((t: any) => t.tabId === 'default') as any; - if (!defaultTab) { - categoryTabs.push({ - tabId: 'default', - tabName: '属性', - categoryList: [config] - }); - } else { - defaultTab.categoryList.push(config); - } - } - }); - // 记录已选的页签 - if (selectedTabId.value) { - let selectedTab = categoryTabs?.find((tab: any) => tab.tabId === selectedTabId.value && !tab.hide); - selectedTab = selectedTab || categoryTabs[0]; - } else { - selectedTab = categoryTabs[0]; - } - selectedTabId.value = selectedTab?.tabId; - } - - // 触发属性面板更新的时机 - watch(() => [props.schema, props.isShowPanel], () => { - propertyData.value = props.schema; - propertyConfig.value = getPropertyConfigBySchema(propertyData.value); - checkShowTabCategory(); - onClearEvent(keyword.value); - }); - - onMounted(() => { - checkShowTabCategory(); - }); - - /** 收折属性面板 */ - function onSwitcherClickEvent() { - mode.value = mode.value === 'panel' ? 'sidebar' : 'panel'; - // 收折时清空搜索框; - if (mode.value === 'panel') { - setTimeout(() => { - search(); - }, 100); - width.value = '300px'; - } else { - width.value = '0px'; - } - } - /** 关闭按钮 */ - function handleShowCloseBtn() { - if (showCloseBtn.value) { - return ( -
-
-
- -
-
-
- ); - } - } - function refreshPanel() { - checkShowTabCategory(); - } - /** 搜索框 */ - function hanleSearchComponent() { - if (enableSearch.value) { - return ( - - ); - } - } - - function getCategoryKey(category: ElementPropertyConfig) { - return `${props.propertyName}_${category.categoryId}`; - } - - /** 属性面板值 */ - function handlePanelBody() { - return ( -
-
    - {propertyConfig.value?.map((category: ElementPropertyConfig) => { - return ( -
  • - {!category.hide && !category.hideTitle && ( - changeStatus(category)}> - - {category.categoryName} - - )} - -
  • - ); - })} -
-
- ); - } - /** 面板展示样式 */ - function handleDisplayMode() { - if (mode.value === 'sidebar') { - return ( -
- - 属性 -
- ); - } - } - function handlePropertyPanelStyleObject() { - const propertyPanelStyleObject = { - display: isOpen.value ? 'block' : 'none', - width: width.value - } as Record; - return propertyPanelStyleObject; - } - function handleSwitcher() { - return ( -
- -
- ); - } - function onChangeSelectedTab(tab: any) { - selectedTab = tab; - selectedTabId.value = selectedTab.tabId; - keyword.value = ''; - } - function handCategoryTabs() { - return categoryTabs.map((tab: any) => { - return ( -
onChangeSelectedTab(tab)}> - {tab.tabName} -
- ); - }); - } - onMounted(() => { - search(keyword.value); - }); - onBeforeMount(() => { - if (isPersitOpenState.value) { - isOpen.value = isShowPanel.value; - } - checkShowTabCategory(); - search(keyword.value); - }); - return () => { - return ( - <> -
- - {handleSwitcher()} - {handleDisplayMode()} -
- - ); - }; - } -}); diff --git a/packages/mobile-ui-vue/package.json b/packages/mobile-ui-vue/package.json index 042a2ef17cd..4a8a9c589c2 100644 --- a/packages/mobile-ui-vue/package.json +++ b/packages/mobile-ui-vue/package.json @@ -2,6 +2,8 @@ "name": "@farris/mobile-ui-vue", "private": true, "version": "0.0.1-beta.2", + "main": "./package/index.umd.js", + "module": "./package/index.esm.js", "scripts": { "dev": "farris-cli dev", "prod": "farris-cli build", -- Gitee From 097e7e4e658f85843243934bf3587286c018da9b Mon Sep 17 00:00:00 2001 From: huyuyang Date: Mon, 17 Feb 2025 12:00:37 +0000 Subject: [PATCH 09/13] =?UTF-8?q?!1282=20=E8=A7=A3=E5=86=B3=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=AD=97=E6=AE=B5=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BC=98=E5=8C=96=E6=96=B9=E6=B3=95=E5=90=8D=E7=A7=B0=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farris-v?= =?UTF-8?q?ue=20*=20fix:=20=E4=BF=AE=E6=94=B9API=E5=90=8D=E7=A7=B0=20*=20f?= =?UTF-8?q?ix:=20=E4=BC=98=E5=8C=96=E5=88=87=E6=8D=A2=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E5=8F=96=E6=95=B0=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=9E=9A=E4=B8=BE=E5=AD=97=E6=AE=B5=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=E6=A0=A1=E9=AA=8C=E6=8A=A5=E9=94=99=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=90=88=E5=B9=B6=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E5=88=86=E6=94=AF=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree?= =?UTF-8?q?-view=E8=BE=B9=E6=A1=86=E6=A0=B7=E5=BC=8F=E6=B1=A1=E6=9F=93?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E7=BB=84=E4=BB=B6treeview=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtree-view=E6=BB=9A=E5=8A=A8=E6=9D=A1=E5=92=8C?= =?UTF-8?q?=E5=B1=95=E5=BC=80=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Dtree-view=E6=BB=9A=E5=8A=A8=E6=9D=A1?= =?UTF-8?q?=E5=92=8C=E5=B1=95=E5=BC=80=E6=95=B0=E6=8D=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9tree-view=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=9D=A1=20*=20fix:=20=E4=BF=AE=E6=94=B9tree?= =?UTF-8?q?-view=E7=BB=84=E4=BB=B6=E6=BB=9A=E5=8A=A8=E6=9D=A1=20*=20Merge?= =?UTF-8?q?=20branch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9tree-view=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE=E6=BA=90=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20*=20fix:=20=E8=BF=98=E5=8E=9F=E6=89=93=E5=8C=85?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E5=A4=8DpageSize=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E8=AE=A1=E7=AE=97=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9tree-grid?= =?UTF-8?q?=E5=B8=AE=E5=8A=A9=E7=BB=84=E4=BB=B6=E6=BB=9A=E5=8A=A8=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=B0=BA=E5=AF=B8=E5=92=8C=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=9D=A1=E8=B7=9F=E9=9A=8F=E6=B5=8F=E8=A7=88=E5=99=A8=E5=B0=BA?= =?UTF-8?q?=E5=AF=B8=E5=8F=98=E5=8C=96=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=85=A8=E9=80=89=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC=E6=A1=86;?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=E5=88=97=E8=A1=A8=E6=BB=9A=E5=8A=A8=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=20*=20fix:=20input-group=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC=E6=A1=86=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=94=AF=E6=8C=81hcm=E8=AF=95=E7=82=B9=20*=20fix:=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=B8=8B=E6=8B=89=E7=BB=84=E4=BB=B6=E5=80=BC?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E5=A4=84?= =?UTF-8?q?=E7=90=86data-grid=E6=A0=BC=E5=BC=8F=E5=8C=96=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A1=A8=E6=A0=BC=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9E=9A=E4=B8=BE=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E7=BB=84=20*=20fix:=20=E7=82=B9=E5=87=BB=E5=85=A8=E9=80=89?= =?UTF-8?q?=E4=B8=8D=E5=BD=B1=E5=93=8D=E9=80=89=E4=B8=AD=E8=A1=8C=20*=20fi?= =?UTF-8?q?x:=20=E7=A7=BB=E9=99=A4=E5=A4=9A=E4=BD=99=E4=BB=A3=E7=A0=81=20*?= =?UTF-8?q?=20fix:=20=E8=A7=A3=E5=86=B3=E6=95=B0=E6=8D=AE=E5=88=86?= =?UTF-8?q?=E7=BB=84=E9=97=AE=E9=A2=98;=E8=A7=A3=E5=86=B3=E6=A0=91?= =?UTF-8?q?=E8=A1=A8=E6=BB=9A=E5=8A=A8=E6=94=B6=E6=8A=98=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=9D=A1=E6=B6=88=E5=A4=B1=E6=95=B0=E6=8D=AE=E5=9B=9E=E5=BD=92?= =?UTF-8?q?=E5=88=B0=E7=AC=AC=E4=B8=80=E6=9D=A1=20*=20chore:=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=89=A9=E4=BD=99=E4=BB=A3=E7=A0=81=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E5=88=9D=E5=A7=8B=E5=8C=96dataView=E6=95=B0=E6=8D=AEtop;?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=BB=9A=E5=8A=A8=E6=9D=A1=E9=AB=98=E5=BA=A6?= =?UTF-8?q?;=E5=A2=9E=E5=8A=A0=E6=BB=9A=E5=8A=A8=E8=8A=82=E6=B5=81;=20*=20?= =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=E7=BA=A7=E8=81=94=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E9=80=89=E4=B8=AD=20*=20fix:=20=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E7=AA=97=E5=8F=A3=E5=8F=98=E5=8C=96=E5=90=8E?= =?UTF-8?q?data-grid=E5=B0=BA=E5=AF=B8=E5=93=8D=E5=BA=94=E5=BC=8F=E5=8F=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E5=88=87=E6=8D=A2listview=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E5=90=8E=E6=B8=85=E7=A9=BA=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E8=A1=8C=20*=20fix:=20=E5=AE=8C=E5=96=84tree?= =?UTF-8?q?-grid=E7=BB=84=E4=BB=B6=E7=BA=A7=E8=81=94=E9=80=89=E6=8B=A9=20*?= =?UTF-8?q?=20fix:=20=E4=BC=98=E5=8C=96=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E9=A6=96=E6=AC=A1=E5=8A=A0=E8=BD=BD=E5=8F=96?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=EF=BC=8CoriginalData=E4=BB=85=E5=9C=A8dataView=20*=20?= =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3=20*=20Merge=20bran?= =?UTF-8?q?ch=20'1.17'=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=EF=BC=8CoriginalData=E4=BB=85=E5=9C=A8dataView=20*=20?= =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=88=86=E9=A1=B5=EF=BC=8Corigin?= =?UTF-8?q?alData=E4=BB=85=E5=9C=A8dataView=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=A1=A8=E6=A0=BC=E7=AD=89=E5=86=B2=E5=87=BB=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E4=BD=8D=E7=BD=AE=E7=AD=89=20*=20fix:=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=B1=8F=E8=94=BD=E8=A1=A8=E6=A0=BC=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E7=89=B9=E6=80=A7;=E4=BF=AE=E5=A4=8D=E6=A0=91=E8=A1=A8?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E5=8F=96=E6=B6=88=E5=8B=BE=E9=80=89?= =?UTF-8?q?=E7=88=B6=E8=8A=82=E7=82=B9=E4=B8=AD=E9=97=B4=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8D=E5=B1=95=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=20*=20re?= =?UTF-8?q?factor:=20=E9=87=8D=E6=9E=84=E8=A1=A8=E6=A0=BC=E5=88=86?= =?UTF-8?q?=E9=A1=B5=20*=20Merge=20branch=20'1.16'=20*=20fix:=20data-grid?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=BB=85=E5=8B=BE=E9=80=89=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E9=80=89=E4=B8=AD=E5=BD=93=E5=89=8D=E8=A1=8C=20*=20Me?= =?UTF-8?q?rge=20branch=20'1.16'=20*=20fix:=20=E7=A7=BB=E9=99=A4=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89class=E5=90=8Df-list-item-active=20*=20fix:?= =?UTF-8?q?=20=E8=A1=A8=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A1=A8=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E5=A4=84=E7=90=86tree-grid=E7=BB=84=E4=BB=B6=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4button-edit=E7=82=B9=E5=87=BB=E9=98=BB?= =?UTF-8?q?=E6=AD=A2=E5=86=92=E6=B3=A1=20*=20fix:=20=E4=BF=AE=E6=94=B9size?= =?UTF-8?q?Limits=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=E9=94=99=E8=AF=AF=20?= =?UTF-8?q?*=20fix:=20=E8=BF=98=E5=8E=9F=E5=A4=9A=E9=80=89=E5=92=8C?= =?UTF-8?q?=E8=A1=8C=E7=82=B9=E5=87=BB=E5=88=86=E7=A6=BB;=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=A6=81=E7=94=A8=E5=88=86=E9=A1=B5=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=20*=20fix:=20=E4=BF=AE=E6=94=B9getKey?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E5=8B=BE=E9=80=89=E9=80=89=E4=B8=AD=E8=A1=8C=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F;=E8=B0=83=E6=95=B4data-grid=E7=BB=84=E4=BB=B6demo=20*?= =?UTF-8?q?=20fix:=20=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20Merge=20br?= =?UTF-8?q?anch=20'1.15'=20*=20fix:=20=E9=AA=8C=E8=AF=81=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E6=96=B9=E6=B3=95=20*=20Merge=20branch=20'1.15'=20*?= =?UTF-8?q?=20fix:=20=E4=B8=8D=E5=87=BA=E7=8E=B0=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=9D=A1=E4=BC=9A=E6=BB=9A=E5=8A=A8=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?;=E4=BF=AE=E5=A4=8Dtextarea=E5=9C=A8=E8=A1=A8=E6=A0=BC=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E4=B8=AD=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'1.15'=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=A4=9A=E9=80=89=E6=A8=A1=E5=BC=8F=E5=92=8C?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4console.log=20*=20Merge=20branch=20'1.15'=20*?= =?UTF-8?q?=20fix:=20=E5=A4=84=E7=90=86combo-list=E4=BC=A0=E5=85=A5key?= =?UTF-8?q?=E6=98=AF=E5=B8=83=E5=B0=94=E5=92=8C=E6=95=B0=E5=AD=97=E7=9A=84?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=20*=20Merge=20branch=20'1.15'=20*=20fix:=20?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=E7=BB=93=E6=9D=9F=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=89=8D=E5=B8=AE=E5=8A=A9=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?;=E4=BF=AE=E6=94=B9=E8=A1=A8=E6=A0=BCschema=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E4=BB=B6=E6=A0=B7=E5=BC=8F=EF=BC=8C=E8=B6=85?= =?UTF-8?q?=E5=87=BA=E5=A4=96=E9=83=A8=E5=85=83=E7=B4=A0=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E6=8A=98=E8=A1=8C=E5=B1=95=E7=A4=BA=E5=88=86=E9=A1=B5=20*=20fi?= =?UTF-8?q?x:=20=E7=A7=BB=E9=99=A4=E8=A1=A8=E6=A0=BC=E5=85=A8=E9=80=89?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E9=9A=90=E8=97=8F=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=92=8C=E5=8F=8C=E5=90=91=E7=BB=91=E5=AE=9A;?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A1=A8=E6=A0=BC=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=B8=AE?= =?UTF-8?q?=E5=8A=A9=E5=88=86=E9=A1=B5=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E4=BF=AE=E6=94=B9changed=E5=90=8D=E7=A7=B0=20*=20f?= =?UTF-8?q?ix:=20=E4=BF=AE=E6=94=B9=E8=B0=83=E7=94=A8useEdit=20*=20fix:=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9B=B4=E6=96=B0=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E5=92=8C=E8=A1=8C=E6=95=B0=E6=8D=AE=E7=BC=96=E8=BE=91=E6=97=B6?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E7=82=B9=E5=87=BB=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E4=B8=94=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E8=A1=8C=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=B8=8D=E8=A7=A6=E5=8F=91=E9=97=AE=E9=A2=98;=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=A1=A8=E6=A0=BC=E4=B8=8D=E8=83=BD=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=88=87=E6=8D=A2=E4=BA=8B=E4=BB=B6=20*=20fi?= =?UTF-8?q?x:=20=E8=A7=A3=E5=86=B3=E5=88=86=E9=A1=B5=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E9=A1=B5=E7=A0=81=E5=92=8C=E6=AF=8F=E9=A1=B5?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E7=9A=84=E5=93=8D=E5=BA=94=E5=BC=8F=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'1.?= =?UTF-8?q?13'=20*=20refactor:=20=E9=87=8D=E6=9E=84=E5=8D=95=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E5=92=8C=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84?= =?UTF-8?q?=20*=20fix:=20=E9=87=8D=E6=9E=84=E5=8D=95=E9=80=89=E6=A1=86?= =?UTF-8?q?=E5=92=8C=E5=A4=8D=E9=80=89=E6=A1=86=E7=BB=84=E4=BB=B6=20*=20ch?= =?UTF-8?q?ore:=20merge=20remote=20branch=20and=20resolve=20conflict=20*?= =?UTF-8?q?=20fix:=20=E5=A4=84=E7=90=86listview=E9=80=89=E4=B8=AD=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E9=AB=98=E4=BA=AE=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=A4=84=E7=90=86listview=E9=80=89=E4=B8=AD=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E9=AB=98=E4=BA=AE=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=A4=8D=E9=80=89=E6=A1=86=E5=92=8C=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=BB=84=E7=BB=84=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fi?= =?UTF-8?q?x:=20=E8=B0=83=E6=95=B4=E7=A6=81=E6=AD=A2=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0lock=20*?= =?UTF-8?q?=20feature:=20=E8=A1=A8=E6=A0=BC=E6=94=AF=E6=8C=81=E7=A6=81?= =?UTF-8?q?=E6=AD=A2=E6=93=8D=E4=BD=9C=E5=88=86=E9=A1=B5=E7=89=B9=E6=80=A7?= =?UTF-8?q?=20*=20Merge=20branch=20'1.10'=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=94=AF=E6=8C=81=E5=88=86=E9=A1=B5=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE;=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1=E6=95=B0=E5=9B=BA=E5=AE=9A=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.10'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8bug=20*=20Merge=20branch=20'1.10'=20?= =?UTF-8?q?*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=20pageList=E4=B8=8D?= =?UTF-8?q?=E5=8F=98=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E8=BF=9C=E7=AB=AF=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E9=80=89=E4=B8=AD=E8=A1=8Cemit?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=88=A4=E6=96=AD=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dtree-grid=E6=BB=9A=E5=8A=A8=E5=90=8E=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E6=94=B6=E6=8A=98=E6=8C=89=E9=92=AE=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E4=BF=AE=E5=A4=8D=E6=94=B6=E6=8A=98=E5=90=8E?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=9D=A1=E9=AB=98=E5=BA=A6=E4=B8=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4data-grid=E6=9A=82=E6=97=A0=E6=95=B0=E6=8D=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F;=E5=A4=84=E7=90=86=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=A0=91=E8=A1=A8=E8=AE=BE=E7=BD=AE=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E7=89=B9=E6=80=A7=EF=BC=8C=E6=BB=9A=E5=8A=A8=E5=90=8E=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E6=94=B6=E6=8A=98=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E7=BB=93=E6=9D=9F=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E7=BC=96=E8=BE=91=E5=8F=82=E6=95=B0=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=B5=8B=E5=80=BC=E4=B8=8D=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20chore:=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E5=88=86=E6=94=AF=20*=20chore:=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E6=9C=AC=E5=9C=B0=E5=88=86=E9=A1=B5=E5=88=86=E6=94=AF?= =?UTF-8?q?=20*=20fix:=20=E5=90=88=E5=B9=B6=E5=88=86=E9=A1=B5=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E5=8F=98=E6=9B=B4=E5=88=86=E6=94=AF=20*=20refactor:?= =?UTF-8?q?=20=E8=B0=83=E6=95=B4=E8=A1=A8=E6=A0=BC=E6=A0=91=E8=A1=A8?= =?UTF-8?q?=E7=AD=89=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.7'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=9B=B4=E6=94=B9=E5=80=BC=E5=90=8E?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=BC=96=E8=BE=91=E5=99=A8=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'1.7'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=B8=85=E7=A9=BA=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'1.7'=20*=20?= =?UTF-8?q?fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=BB=84=E4=BB=B6data-grid?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=E5=8F=98=E6=9B=B4=E5=88=97=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=A7=A3=E6=9E=90=E5=85=B3=E8=81=94=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtree=E6=95=B0=E6=8D=AE=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=A2=AB=E8=A6=86=E7=9B=96=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E6=9B=B4=E6=94=B9=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1=E9=AA=8C=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20Merge=20branch=20'1.6'=20*=20fix:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E8=A1=8C=E5=A2=9E=E5=8A=A0=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=97=E6=95=B0=E6=8D=AE=E6=96=B9=E6=B3=95=20*=20fix:=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=89=8D=E6=A0=A1=E9=AA=8C=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E5=87=A0=E4=B8=AA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=20*=20docs:=20=E5=AE=8C=E5=96=84response-toolbar=E6=96=87?= =?UTF-8?q?=E6=A1=A3=20*=20build:=20=E7=BA=A0=E6=AD=A3=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BAindex?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20fix:=20=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BAindex?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20*=20fix:=20=E5=AE=8C=E5=96=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=20*=20fix:=20=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=20*=20Merge=20branch=20'1.3'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E6=9C=9F=E5=A4=9A=E4=BD=99=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E9=97=AE=E9=A2=98=20*=20fix:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6=E6=8C=89=E9=9C=80=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=20*=20fix:=20tooltip=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8C=89=E9=9C=80=E5=8A=A0=E8=BD=BD=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E7=BC=96=E8=AF=91=E5=90=8E=E6=95=B4=E4=BD=93=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=BD=BF=E7=94=A8tree-shaking=20*=20fix:=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=AE=9E=E7=8E=B0=E5=AE=9E=E4=BD=93=E6=A0=91=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=AD=90=E8=A1=A8=E6=88=96=E8=80=85udt=E7=88=B6?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=B8=8D=E5=85=81=E8=AE=B8=E7=94=9F=E6=95=88?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farr?= =?UTF-8?q?is-vue=20*=20refactor:=20=E9=87=8D=E6=9E=84data-grid=E5=88=86?= =?UTF-8?q?=E9=A1=B5=20*=20Merge=20branch=20'1.2'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E9=A1=B5=E7=A0=81=E6=95=B0=E6=8D=AE=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E9=94=99=E4=B9=B1=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E5=8F=8C=E5=87=BB=E5=AE=9E=E4=BD=93=E6=A0=91=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=80=BC=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=A2=9E=E5=8A=A0data-grid?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E7=BC=96=E8=BE=91=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E5=90=88=E5=B9=B6=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E6=9C=80=E6=96=B0=20*=20chore:=20=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E6=9C=80=E6=96=B0=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6=E6=96=B0=E5=A2=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=90=8Edom=E6=B2=A1=E6=9C=89=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98;=E4=BF=AE=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E4=B8=80=E8=A1=8C=E6=95=B0=E6=8D=AE=E5=90=8E=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E8=A7=A6=E5=8F=91=E8=A1=8C=E7=82=B9=E5=87=BB=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20*=20Merge=20branch=20'12.30'=20*=20feature:=20?= =?UTF-8?q?=E7=A9=BF=E6=A2=AD=E6=A1=86=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E6=A0=91=E7=BB=93=E6=9E=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?;=E4=BF=AE=E5=A4=8Ddata-grid=20tree=E7=AD=89=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E9=80=89=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'12.30'=20*=20Merge=20branch=20'main'?= =?UTF-8?q?=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E8=AE=BE=E8=AE=A1=E6=97=B6=E7=BB=84=E4=BB=B6=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E5=92=8C=E6=A0=91=E8=A1=A8=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E7=89=B9=E6=80=A7=20*=20fix:=20=E8=BF=98=E5=8E=9Fdata-area?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=B8=B2=E6=9F=93=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E7=BA=A0=E6=AD=A3=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=B8=8D=E6=AD=A3=E7=A1=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20chore:=20=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E4=B8=BB?= =?UTF-8?q?=E5=88=86=E6=94=AF=E4=BB=A3=E7=A0=81=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E6=A0=91=E5=8F=8C?= =?UTF-8?q?=E5=87=BB=E9=80=89=E4=B8=AD=E7=9A=84=E9=97=AE=E9=A2=98;?= =?UTF-8?q?=E4=BF=AE=E6=94=B9designer=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E6=94=B9data-grid=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E7=BB=84=E4=BB=B6;=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=85=A5=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E4=B8=8D=E5=90=88=E7=90=86=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A7=A3=E5=86=B3data-grid=E9=A2=91=E7=B9=81?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=88=97=E5=B0=BA=E5=AF=B8=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3data-grid=E9=A2=91?= =?UTF-8?q?=E7=B9=81=E8=AE=A1=E7=AE=97=E5=88=97=E5=B0=BA=E5=AF=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81@/components=E5=AF=BC=E5=85=A5=E8=B7=AF=E5=BE=84=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farris-v?= =?UTF-8?q?ue=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82=E6=95=B0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E5=AE=9E=E4=BD=93=E5=AD=97=E6=AE=B5=E6=A0=91?= =?UTF-8?q?;=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=B8=B2=E6=9F=93data-grid=20area=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=89=93=E5=8C=85@/componnets=E9=85=8D=E7=BD=AE=20*?= =?UTF-8?q?=20Merge=20branch=20'12.25'=20*=20fix:=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8;=E4=BF=AE=E6=94=B9=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8treeview=E5=AF=BC=E8=88=AA=20*=20fix?= =?UTF-8?q?:=20=E4=BF=AE=E6=94=B9totalItems=E7=B1=BB=E5=9E=8B=20*=20Merge?= =?UTF-8?q?=20branch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*?= =?UTF-8?q?=20fix:=20=E4=BF=AE=E6=94=B9=E5=88=97=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E6=9E=9A=E4=B8=BE=E5=B1=9E=E6=80=A7=E5=90=8D=20*=20Me?= =?UTF-8?q?rge=20branch=20'12.24'=20*=20fix:=20=E5=A4=84=E7=90=86=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=96=E6=B6=88=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=80=BC=20*=20fix:=20=E4=BF=AE=E6=94=B9=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20?= =?UTF-8?q?*=20fix:=20=E8=A7=A3=E5=86=B3totalData=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E9=94=99=E8=AF=AF=E9=A1=B9?= =?UTF-8?q?;=E8=BF=98=E5=8E=9Fdata-grid=E7=BB=84=E4=BB=B6=E8=B5=8B?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E9=AA=8C=E8=AF=81=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8dom?= =?UTF-8?q?=E5=86=99=E5=80=BC=20*=20refactor:=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E4=BA=8B=E4=BB=B6=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=20*=20build:=20=E4=BF=AE=E5=A4=8Dnp?= =?UTF-8?q?m=E5=8C=85=E5=BC=95=E5=85=A5=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E8=B0=83=E6=95=B4bindingselector=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'designer-param'=20*?= =?UTF-8?q?=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=90=8E=E6=96=B9=E6=B3=95=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E8=B0=83=E6=95=B4=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=20*=20Merge=20branch=20'designer-param'=20*?= =?UTF-8?q?=20fix:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=90=8E=E4=B8=8B=E6=8B=89=E6=A0=91=E8=AE=BE=E7=BD=AE=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20fix:=20=E5=A4=84=E7=90=86const=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=8F=98=E9=87=8F=E5=8F=8C=E5=90=91=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=90=88=E5=B9=B6=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E4=BB=A3=E7=A0=81=20*=20docs:=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=96=87=E6=A1=A3=20*=20fix:=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E6=94=AF=E6=8C=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9C=BA=E5=8A=A8=E4=BD=9C=E8=AE=BE=E7=BD=AE;=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E9=80=9A=E7=94=A8=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=20*=20fix:=20=E8=8E=B7=E5=8F=96=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20*=20fix:=20=E8=B0=83=E6=95=B4=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20*=20Merge=20branch=20'designer-param'=20*=20Merge=20branch?= =?UTF-8?q?=20'12.17'=20*=20fix:=20=E5=AE=9E=E7=8E=B0=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BC=96=E8=BE=91=E5=99=A8=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E8=B0=83=E6=95=B4data-grid=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=86=85=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=8C=96=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E4=B8=8D=E5=8F=98=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9data-grid=E5=88=97=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E8=BF=81=E7=A7=BB=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=BB=84=E4=BB=B6=E5=92=8C=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E7=BB=84=E4=BB=B6=20*=20Merge=20bra?= =?UTF-8?q?nch=20'12.16'=20into=2012.17=20*=20fix:=20=E8=B0=83=E6=95=B4bin?= =?UTF-8?q?ding-selector=E8=B7=AF=20*=20Merge=20branch=20'main'=20of=20git?= =?UTF-8?q?ee.com:hopefulman/farris-vue=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E6=9B=B4?= =?UTF-8?q?=E6=94=B9data-grid=E7=BB=84=E4=BB=B6=E6=9E=9A=E4=B8=BE=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=20*=20fix:=20=E8=B0=83=E6=95=B4data-grid=20?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E8=A1=8C=E4=BA=8B=E4=BB=B6=E4=B8=BA=E5=B0=8F?= =?UTF-8?q?=E9=A9=BC=E5=B3=B0=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E8=BF=98=E5=8E=9Fdata-gr?= =?UTF-8?q?id=E7=A9=BA=E6=95=B0=E6=8D=AE=E6=A0=B7=E5=BC=8F=E4=BD=BF?= =?UTF-8?q?=E5=BE=97=E8=A1=A8=E6=A0=BC=E5=B1=95=E7=A4=BA=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=20*=20fix:=20=E6=8B=89=E5=8F=96=E6=9C=80=E6=96=B0=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E4=BB=A3=E7=A0=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=89=93=E5=BC=80=E6=8A=A5=E9=94=99=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9=E4=B8=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E9=A1=B9=20*=20fix:=20=E8=B0=83=E6=95=B4import?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'12.12'=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E7=BB=84=E4=BB=B6import?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20*=20chore:=20=E8=A7=A3=E5=86=B3=E5=86=B2?= =?UTF-8?q?=E7=AA=81=20*=20fix:=20=E4=BF=AE=E6=94=B9data-grid=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98;=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6=E6=95=B0=E6=8D=AE=E4=B8=BA?= =?UTF-8?q?=E7=A9=BA=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81change?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6;data-grid=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=97field=E8=AE=BE=E7=BD=AE=E4=B8=BA=E5=85=B3?= =?UTF-8?q?=E8=81=94=E5=AD=97=E6=AE=B5=20*=20fix:=20data-grid=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E7=BA=A7field=E8=B5=8B=E5=80=BC=E5=92=8C?= =?UTF-8?q?=E5=8F=96=E5=80=BC=20*=20chore:=20=E5=90=88=E5=B9=B61209?= =?UTF-8?q?=E5=88=86=E6=94=AF=EF=BC=8C=E5=90=88=E5=B9=B6=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E4=B8=AD=E9=97=B4=E7=8A=B6=E6=80=81=E7=89=B9=E6=80=A7?= =?UTF-8?q?=20*=20docs:=20=E8=B0=83=E6=95=B4data-grid=E6=96=87=E6=A1=A3=20?= =?UTF-8?q?*=20fix:=20=E8=BF=98=E5=8E=9Fdata-grid=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E6=96=87=E6=A1=A3=20*=20fix:=20=E5=AE=8C=E5=96=84data-grid?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=E5=92=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=8D=95=E5=85=83=E6=A0=BC=E6=95=B0=E6=8D=AE=E7=89=B9?= =?UTF-8?q?=E6=80=A7;=E4=BF=AE=E6=94=B9listview=E7=A9=BA=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefulman/farr?= =?UTF-8?q?is-vue=20*=20fix:=20=E9=AA=8C=E8=AF=81=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20Merge=20branch=20'12.1?= =?UTF-8?q?1'=20*=20fix:=20=E9=AA=8C=E8=AF=81tree-grid=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E8=A1=8C=E7=89=B9=E6=80=A7=20*=20fix:=20=E6=9B=B4=E6=94=B9data?= =?UTF-8?q?-grid=E6=9C=8D=E5=8A=A1=E7=AB=AF=E5=88=86=E9=A1=B5=20*=20fix:?= =?UTF-8?q?=20=E9=AA=8C=E8=AF=81data-grid=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=92=8C=E9=AA=8C=E8=AF=81data-grid=E6=95=B0=E6=8D=AE=E5=88=86?= =?UTF-8?q?=E7=BB=84=E7=89=B9=E6=80=A7=20*=20fix:=20=E8=BF=98=E5=8E=9F?= =?UTF-8?q?=E8=A1=A8=E5=A4=B4=E9=BB=98=E8=AE=A4=E4=BD=8D=E7=BD=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E4=BF=AE=E6=94=B9=E6=89=93=E5=8C=85?= =?UTF-8?q?=E4=BA=A7=E7=89=A9=20*=20fix:=20=E5=AE=8C=E5=96=84=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE=E9=87=8F=E5=8F=98?= =?UTF-8?q?=E5=B0=91=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12?= =?UTF-8?q?.08'=20*=20Merge=20branch=20'12.06'=20*=20Merge=20branch=20'mai?= =?UTF-8?q?n'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:=20tree-gri?= =?UTF-8?q?d=E5=A2=9E=E5=8A=A0=E5=A4=8D=E9=80=89=E6=A1=86=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E7=8A=B6=E6=80=81;=E8=A7=A3=E5=86=B3=E5=8B=BE?= =?UTF-8?q?=E9=80=89tree-grid=E7=BB=84=E4=BB=B6=E5=8D=A1=E6=AD=BB=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E5=A2=9E=E5=8A=A0class?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0combo-list=E5=AE=9E=E7=8E=B0hover=E9=AB=98?= =?UTF-8?q?=E4=BA=AE=20*=20fix:=20=E7=A7=BB=E9=99=A4combo-list=E5=A4=9A?= =?UTF-8?q?=E4=BD=99=E5=B1=9E=E6=80=A7=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20gitee.com:hopefulman/farris-vue=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4combo-list=E7=BB=84=E4=BB=B6=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E5=B1=9E=E6=80=A7;=E8=BF=98=E5=8E=9Fdata-grid=E7=BB=84?= =?UTF-8?q?=E4=BB=B6mouse=E4=BA=8B=E4=BB=B6=20*=20chore:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3lock=E6=96=87=E4=BB=B6=E5=86=B2=E7=AA=81=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96tree-grid=E5=92=8Cdata-grid=E7=A6=81=E7=94=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7;=E4=BF=AE=E5=A4=8D=E4=B8=A4=E4=B8=AA=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E6=97=B6=E4=BB=8D?= =?UTF-8?q?=E7=84=B6=E8=A7=A6=E5=8F=91=E6=BB=9A=E5=8A=A8=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20refactor:=20=E8=A1=A5?= =?UTF-8?q?=E5=85=85data-grid=E5=8D=95=E5=85=83=E6=A0=BC=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=92=8C=E5=8F=96=E6=B6=88=E7=BC=96=E8=BE=91=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E6=9C=AC=E6=98=BE=E7=A4=BA=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=8D=E7=BB=9F=E4=B8=80=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Ddata-grid=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=E5=88=97=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12?= =?UTF-8?q?.05'=20*=20fix:=20=E5=A2=9E=E5=8A=A0data-grid=E5=92=8Ctree-grid?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E8=A1=8C=E7=89=B9=E6=80=A7=20*=20fix:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96tags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BA=20*?= =?UTF-8?q?=20fix:=20=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E5=88=86?= =?UTF-8?q?=E6=94=AF=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96tags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BA=20*?= =?UTF-8?q?=20fix:=20=E5=A2=9E=E5=8A=A0data-grid=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E4=BF=A1=E6=81=AF=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=20*=20feature:=20data-grid=E5=A2=9E=E5=8A=A0=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4combo-list=E9=80=89=E4=B8=AD=E9=A1=B9=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E8=89=B2=E7=AD=89=E6=A0=B7=E5=BC=8F=20*=20fix:=20?= =?UTF-8?q?=E5=AE=8C=E5=96=84combo-list=E5=A4=9A=E9=80=89=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtags=E7=BB=84=E4=BB=B6=E5=AF=BC=E5=87=BAdefau?= =?UTF-8?q?lt=E7=BB=84=E4=BB=B6=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96combo-list=E4=BD=BF=E7=94=A8=E5=A4=8D=E9=80=89?= =?UTF-8?q?=E6=A1=86=E5=A4=9A=E9=80=89=E7=89=B9=E6=80=A7=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcombo-list=E6=98=BE=E7=A4=BA=E5=80=BC?= =?UTF-8?q?=E5=92=8C=E5=80=BC=E9=A1=BA=E5=BA=8F=E4=B8=8D=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83=E6=95=B4data?= =?UTF-8?q?-grid=E7=BB=84=E4=BB=B6=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=87=BD?= =?UTF-8?q?=E6=95=B0=20*=20fix:=20=E8=BF=98=E5=8E=9Ftree-grid=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E8=AE=A1=E7=AE=97=E5=B0=BA=E5=AF=B8=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9data-grid=E5=88=86=E9=A1=B5=E6=80=BB=E6=95=B0?= =?UTF-8?q?=E8=B5=8B=E5=80=BC=E6=9C=BA=E5=88=B6=20*=20build:=20=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE;=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=8D=E5=90=88=E8=A7=84=E8=8C=83=E7=9A=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=20*=20build:=20=E6=9B=B4=E6=94=B9=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=8F=92=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fix:=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0data-grid=E9=BB=98=E8=AE=A4=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E5=88=97=20*=20fix:=20=E5=AE=8C=E5=96=84=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E7=BB=84=E5=90=88=E5=BC=8F=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E6=80=BB=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=20*=20Merge=20bra?= =?UTF-8?q?nch=20'12.03'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=9A=E8=A1=8C?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=A1=86=E8=BE=B9=E7=BA=BF=E8=BF=87=E7=B2=97?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=A7=A3=E5=86=B3dependent-bas?= =?UTF-8?q?e=E6=89=93=E5=8C=85=E6=A0=B7=E5=BC=8F=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'12.02'=20*?= =?UTF-8?q?=20config:=20=E4=BF=AE=E6=94=B9=E6=9E=84=E5=BB=BA=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E4=BD=BF=E6=89=93=E5=8C=85=E5=90=8E=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BC=95=E5=85=A5=E8=B7=AF=E5=BE=84=E4=B8=BA=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9=E8=B7=AF=E5=BE=84;=E6=94=AF=E6=8C=81=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E5=85=A5=E5=8F=A3tsx=E6=96=87=E4=BB=B6=20*=20Merge=20?= =?UTF-8?q?branch=20'12.02'=20*=20Merge=20branch=20'main'=20of=20gitee.com?= =?UTF-8?q?:hopefulman/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96tree-grid?= =?UTF-8?q?=E6=80=A7=E8=83=BD=E8=A7=A3=E5=86=B3=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=8E=B7=E5=8F=96=E6=9C=80=E6=96=B0?= =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81=20*=20fix:=20textarea?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=94=AF=E6=8C=81=E6=B8=85=E7=A9=BA=E5=86=85?= =?UTF-8?q?=E5=AE=B9=20*=20docs:=20=E4=BF=AE=E6=94=B9textarea=E6=96=87?= =?UTF-8?q?=E6=A1=A3;=E5=90=88=E5=B9=B6=E8=BF=9C=E7=A8=8B=E5=88=86?= =?UTF-8?q?=E6=94=AF=20*=20fix:=20textarea=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8F=AA=E8=AF=BB=E3=80=81=E7=A6=81=E7=94=A8=E3=80=81?= =?UTF-8?q?=E8=81=9A=E7=84=A6=E5=92=8C=E5=A4=B1=E5=8E=BB=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=20*=20Merge=20branch=20'11.29'=20*=20fix:=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=85=8D=E7=BD=AE=E5=85=BC=E5=AE=B9=E6=97=A7?= =?UTF-8?q?=E7=89=88=E6=9C=ACrollupOption=20*=20Merge=20branch=20'11.29'?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E5=85=A8=E9=80=89?= =?UTF-8?q?=E5=90=8E=E4=BC=9A=E9=80=89=E4=B8=AD=E6=9C=80=E5=90=8E=E4=B8=80?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'11?= =?UTF-8?q?.29'=20*=20fix:=20=E4=BF=AE=E5=A4=8Dtree-grid=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E8=A1=8C=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20branch=20'11.29'=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?tree-grid=E6=9B=B4=E6=8D=A2checkbox=E5=90=8E=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=8D=95=E9=80=89=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=96=87=E6=A1=A3=E6=89=93=E5=8C=85=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20Merge?= =?UTF-8?q?=20branch=20'11.28'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=94=B6?= =?UTF-8?q?=E6=8A=98=E9=9D=A2=E6=9D=BF=E5=85=A8=E5=B1=80=E6=94=B6=E6=8A=98?= =?UTF-8?q?=E5=92=8C=E5=85=A8=E9=83=A8=E5=B1=95=E5=BC=80=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98=20*=20Merge=20bra?= =?UTF-8?q?nch=20'11.28'=20*=20fix:=20=E8=B0=83=E6=95=B4tree-grid=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=A4=8D=E9=80=89=E6=A1=86=E5=92=8C=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E5=A4=8D=E9=80=89=E6=A1=86=E6=A0=B7=E5=BC=8F=20*=20Merge=20bra?= =?UTF-8?q?nch=20'11.28'=20*=20fix:=20data-grid=E5=8D=95=E5=85=83=E6=A0=BC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=94=AF=E6=8C=81=E6=97=A5=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E5=88=86=E7=A7=92=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20Merge=20branch=20'11.28'=20*=20f?= =?UTF-8?q?eature:=20combo-list=E6=94=AF=E6=8C=81=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E5=80=BC=E7=AD=9B=E9=80=89=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20gitee.com:hopefulman/farris-vue=20*=20fix:?= =?UTF-8?q?=20=E4=BC=98=E5=8C=96tree-grid=E6=80=A7=E8=83=BD=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E8=BF=98=E5=8E=9F=E5=AE=9A=E4=B9=89cons?= =?UTF-8?q?t=E5=8F=98=E9=87=8F=20*=20fix:=20=E4=BF=AE=E6=94=B9=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=A0=BC=E6=B0=B4=E5=B9=B3=E5=B1=85=E4=B8=AD=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=E5=8F=8A=E7=BC=96=E8=AF=91=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20gitee.c?= =?UTF-8?q?om:hopefulman/farris-vue=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=9E=84=E5=BB=BApackage.json=E6=96=87=E4=BB=B6=E5=BC=95?= =?UTF-8?q?=E7=94=A8css=E8=B7=AF=E5=BE=84=20*=20Merge=20branch=20'11.27'?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8Ddata-grid=E7=BB=84=E4=BB=B6,?= =?UTF-8?q?=E6=A8=AA=E5=90=91=E6=BB=9A=E5=8A=A8=E6=9D=A1=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=80=E5=85=B3=E4=B8=8D=E5=87=86=E7=A1=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20gitee.com:hopefu?= =?UTF-8?q?lman/farris-vue=20*=20Merge=20branch=20'11.27'=20*=20config:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9E=84=E5=BB=BA=E5=90=8E=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=96=87=E4=BB=B6css=E5=90=8D=E7=A7=B0=20*=20fix:=20=E9=AA=8C?= =?UTF-8?q?=E8=AF=81data-grid=E6=8B=96=E6=8B=BD=E5=88=97=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-view/components/column-format/enum.component.tsx | 2 +- .../pagination/data-grid-pagination.component.tsx | 8 ++++++-- .../data-view/composition/data/use-data-view.ts | 7 ++++++- packages/ui-vue/components/data-view/composition/types.ts | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx b/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx index 7f9c8c06926..a6a193806c4 100644 --- a/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx +++ b/packages/ui-vue/components/data-view/components/column-format/enum.component.tsx @@ -6,7 +6,7 @@ export default function () { function renderEnumColumn(column: DataColumn, visualDataRow: VisualData) { const { formatter } = column; const value = resolveField(visualDataRow.raw, column.field); - if (value.includes(',')) { + if (value?.includes(',')) { const valueList = value.split(','); const dataMap = formatter.data.reduce((total: any, next: { value: number, name: number }) => { total[next.value] = next; diff --git a/packages/ui-vue/components/data-view/components/pagination/data-grid-pagination.component.tsx b/packages/ui-vue/components/data-view/components/pagination/data-grid-pagination.component.tsx index 4d2fcee06d3..9f8e076e70b 100644 --- a/packages/ui-vue/components/data-view/components/pagination/data-grid-pagination.component.tsx +++ b/packages/ui-vue/components/data-view/components/pagination/data-grid-pagination.component.tsx @@ -24,7 +24,7 @@ export default function ( virtualScroll: UseVirtualScroll, usePaginationComposition: UsePagination ) { - const { pageIndex, totalItems } = dataView; + const { pageIndex, totalItems, updatePageSize } = dataView; const paginationRef = ref(); const { pageSize, pageList, showGotoPage, showPageIndex, showPageList, mode, disabled, shouldRenderPagination } = usePaginationComposition; // 分页组件总数取决于客户端分页时dataview数量或者服务端分页时total值 @@ -52,7 +52,7 @@ export default function ( function onPageIndexChanged(pageInfo: { pageIndex: number; pageSize: number }) { const { pageIndex, pageSize } = pageInfo; - if (mode.value !== 'server') { + if (shouldRenderPagination.value && mode.value !== 'server') { dataView.navigatePageTo(pageIndex); virtualScroll.resetScroll(); } @@ -64,6 +64,8 @@ export default function ( if (shouldRenderPagination.value && mode.value !== 'server') { dataView.changePageSizeTo(pageSize); virtualScroll.resetScroll(); + }else{ + updatePageSize(pageSize); } context.emit('pageSizeChanged', { pageIndex, pageSize }); } @@ -74,6 +76,8 @@ export default function ( // 服务端分页不执行重定向数据的逻辑 dataView.navigatePageTo(pageIndex); virtualScroll.resetScroll(); + }else { + updatePageSize(pageSize); } context.emit('changed', { pageIndex, pageSize }); } diff --git a/packages/ui-vue/components/data-view/composition/data/use-data-view.ts b/packages/ui-vue/components/data-view/composition/data/use-data-view.ts index d046c0e466f..8e12a26ef12 100644 --- a/packages/ui-vue/components/data-view/composition/data/use-data-view.ts +++ b/packages/ui-vue/components/data-view/composition/data/use-data-view.ts @@ -392,9 +392,13 @@ export function useDataView( return applyFilterAndSorter(collepseFilter, Array.from(sorterMap.values())); } + function updatePageSize(newPageSize: number) { + pagination.value.size = newPageSize; + } + function changePageSizeTo(newPageSize: number) { if (pagination.value) { - pagination.value.size = newPageSize; + updatePageSize(newPageSize); updateDataView(); } } @@ -429,6 +433,7 @@ export function useDataView( addFilter, addNewDataItem, addSorter, + updatePageSize, changePageSizeTo, collapse, dataView, diff --git a/packages/ui-vue/components/data-view/composition/types.ts b/packages/ui-vue/components/data-view/composition/types.ts index 61ef592b51d..a84d4a58955 100644 --- a/packages/ui-vue/components/data-view/composition/types.ts +++ b/packages/ui-vue/components/data-view/composition/types.ts @@ -507,6 +507,8 @@ export interface UseDataView { addSorter: (sortKey: string, sorter: DataViewSorter) => any[]; + updatePageSize: (newPageSize: number) => void; + changePageSizeTo: (newPageSize: number) => void; collapse: (collapseField: string, collapseValue: any) => any[]; -- Gitee From aa99bb7017b8912dbd66d96b2c3ff99ca49e9370 Mon Sep 17 00:00:00 2001 From: XimenaFan Date: Mon, 17 Feb 2025 12:02:21 +0000 Subject: [PATCH 10/13] =?UTF-8?q?!1289=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=BC=96=E8=BE=91=E5=99=A8=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20rem?= =?UTF-8?q?ote-tracking=20branch=20'refs/remotes/origin/main'=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E4=BA=8B=E4=BB=B6=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20remote-tracking=20branch=20'refs/remote?= =?UTF-8?q?s/origin/main'=20*=20feature:=20=E7=A6=81=E7=94=A8=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=8A=9F=E8=83=BD=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20Merge=20rem?= =?UTF-8?q?ote-tracking=20branch=20'refs/remotes/origin/main'=20*=20Merge?= =?UTF-8?q?=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*=20?= =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E5=B7=A5=E5=85=B7=E6=A0=8F=E9=A1=B9?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8F=98=E6=9B=B4=EF=BC=8C=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E7=9A=84=E4=B8=8B=E6=8B=89=E7=AD=89=E6=95=B0=E6=8D=AE=E6=B6=88?= =?UTF-8?q?=E5=A4=B1=E9=97=AE=E9=A2=98=20*=20fix:=20=E9=9A=90=E8=97=8F?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E9=83=A8=E5=88=86=E5=B1=9E=E6=80=A7=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B1=9E=E6=80=A7=E9=A1=B9=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E4=B8=8D=E5=8F=98=E6=9B=B4=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E5=88=97=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E7=BC=96=E8=BE=91=E5=99=A8=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E4=B8=8D=E8=83=BD=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=BC=B9=E5=87=BA=E7=AA=97=E5=8F=A3=E3=80=81=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E6=8E=A7=E4=BB=B6=E6=A0=B7=E5=BC=8F=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BB=9F=E4=B8=80=E9=85=8D=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E8=87=AA=E5=AE=9A=E4=B9=89=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E5=93=8D=E5=BA=94=E5=BC=8F=E5=88=97=E5=AE=BD?= =?UTF-8?q?=E7=A7=BB=E9=99=A4mock=EF=BC=8C=E6=9B=B4=E6=96=B0schema=20*=20M?= =?UTF-8?q?erge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20?= =?UTF-8?q?*=20fix:=20=E8=B0=83=E6=95=B4=E6=97=A5=E6=9C=9F=E5=92=8C?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=BC=8F=E7=BC=96=E8=BE=91=E5=99=A8=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20*=20Merge=20remote-tracking=20branch=20'refs/remote?= =?UTF-8?q?s/origin/main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E9=A1=B9?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E3=80=81=E5=88=86=E6=A0=8F=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9B=E6=95=B0=E5=AD=97=E6=8E=A7=E4=BB=B6=E5=9C=A8?= =?UTF-8?q?=E8=A1=8C=E7=BC=96=E8=BE=91=E6=97=B6=E6=A0=B7=E5=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=9B=20*=20fix:=20=E6=A0=91=E8=A1=A8=E5=88=97?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=8D=E6=9B=B4=E6=96=B0=E7=94=BB=E5=B8=83?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E9=9D=9E=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E4=B8=8B=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E5=8F=B3=E4=BE=A7=E7=9A=84=E5=9C=86=E8=A7=92=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/?= =?UTF-8?q?main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=A4=9A=E9=80=89=E7=BB=84=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E6=9E=9A=E4=B8=BE=E9=A1=B9=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=B0=83=E6=95=B4=E4=B8=8B=E6=8B=89=E5=92=8C?= =?UTF-8?q?=E7=A9=BF=E6=A2=AD=E6=A1=86=E7=9A=84=E6=A0=B7=E5=BC=8F=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A7=E7=9A=84=E7=A9=BF=E6=A2=AD=E6=A1=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=20*=20fix:=20=E8=B0=83=E6=95=B4=E6=A0=91?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20fix:=20=E8=B0=83=E6=95=B4=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E5=A4=9A=E9=80=89=E5=92=8C=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E5=9C=A8=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=8A=E7=9A=84?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=85=B3=E7=B3=BB=20*=20fix:=20=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=B8=A6=E6=97=B6=E9=97=B4=E7=9A=84=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E8=B0=83=E6=95=B4=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E5=B8=A6=E6=97=B6=E9=97=B4=E7=9A=84=E6=A0=B7=E5=BC=8F=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8Dtab=E4=B8=ADtitle=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=A4=9A=E9=80=89=E5=85=B3=E8=81=94=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=B8=85=E7=A9=BA=E8=BF=98=E4=BF=9D=E7=95=99?= =?UTF-8?q?=E4=B8=8A=E6=AC=A1=E6=96=87=E6=9C=AC=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=20*=20Merge=20remote-tracking=20branch=20'refs/remote?= =?UTF-8?q?s/origin/main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A1=AB?= =?UTF-8?q?=E6=8A=A5=E6=A8=A1=E6=9D=BF=20*=20fix:=20=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=90=AF=E7=94=A8=E5=A4=9A=E9=80=89=EF=BC=8C=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=A4=9A=E9=80=89=E6=A1=86=20*=20fix:=20?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=88=86=E6=A0=8F=E9=9D=A2=E6=9D=BF=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=9E=9A=E4=B8=BE=E9=A1=B9=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E9=BB=98=E8=AE=A4=E5=80=BC=EF=BC=8C=E6=9A=B4=E9=9C=B2?= =?UTF-8?q?=E5=87=BA=E9=80=9A=E8=BF=87=E6=9E=9A=E4=B8=BE=E9=A1=B9=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=E5=90=8E?= =?UTF-8?q?=EF=BC=8C=E4=B8=AD=E9=97=B4=E5=87=BA=E7=8E=B0=E4=B8=80=E6=AC=A1?= =?UTF-8?q?=E8=B5=8B=E5=80=BC=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E8=A7=A3=E5=86=B3=E5=A1=AB=E6=8A=A5=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=B7=A5=E5=85=B7=E6=A0=8F=E7=9A=84=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=B1=85=E4=B8=AD=E5=AF=B9=E9=BD=90=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E5=BC=95=E5=85=A5=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E5=B1=82=E7=BA=A7=E4=B8=9A=E5=8A=A1=E5=85=B3=E8=81=94=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=A2=9D=E5=A4=96=E7=9A=84=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=96=87=E4=BB=B6=EF=BC=9B=E6=9B=B4=E6=96=B0=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=BF=AE=E5=A4=8D=E4=B8=8B=E6=8B=89=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20remote-tracking=20branch=20'refs/remote?= =?UTF-8?q?s/origin/main'=20*=20fix:=20=E4=BF=AE=E6=94=B9=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=8B=96=E6=8B=BD=E5=8D=95=E9=80=89=E7=BB=84=E3=80=81?= =?UTF-8?q?=E5=A4=9A=E9=80=89=E7=BB=84=E5=88=B0=E7=94=BB=E5=B8=83=E4=B8=8A?= =?UTF-8?q?=EF=BC=8C=E5=88=9D=E5=A7=8B=E9=83=BD=E6=98=AF=E7=A9=BA=E7=99=BD?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E7=A6=81=E7=94=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E7=BB=9F=E4=B8=80=EF=BC=9B=E5=A4=9A=E8=A1=8C=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=20*=20fix:=20?= =?UTF-8?q?=E6=9B=B4=E6=94=B9=E8=A1=A8=E6=A0=BC=E5=B1=9E=E6=80=A7=20*=20Me?= =?UTF-8?q?rge=20branch=20'xdev'=20*=20Merge=20remote-tracking=20branch=20?= =?UTF-8?q?'refs/remotes/origin/main'=20*=20fix:=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=85=B3=E4=BA=8Erxjs=E7=9A=84=E5=BC=95=E7=94=A8=20*=20fix:=20?= =?UTF-8?q?checkbox=E7=BB=84=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=92=8C=E5=A4=9A?= =?UTF-8?q?=E8=A1=8C=E6=96=87=E6=9C=AC=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E5=88=97=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20xdev=20*=20Merge=20remote-tracking=20branch=20'ref?= =?UTF-8?q?s/remotes/origin/main'=20*=20feature:=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E9=9D=A2=E6=9D=BF=EF=BC=8C=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=96=B0=E6=8E=A7=E5=88=B6=E5=99=A8=E5=90=8E=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=EF=BC=9B=E4=BF=AE=E5=A4=8D=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E6=96=B0=E6=8E=A7=E5=88=B6=E5=99=A8=E5=91=BD=E4=BB=A4=EF=BC=8C?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E7=BC=96=E8=BE=91=E6=8A=A5=E9=94=99=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20xdev=20*=20Merge=20remote-tracking=20branch=20'ref?= =?UTF-8?q?s/remotes/origin/main'=20*=20feature:=20=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E9=9D=A2=E6=9D=BF=E5=A4=84=E7=90=86=E8=A2=AB?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=B9=E6=B3=95=20*=20feature:=20=E5=88=97?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=9B=B4=E6=94=B9=E4=B8=BA=E6=A0=91=E5=9E=8B?= =?UTF-8?q?=E7=BB=93=E6=9E=84=EF=BC=8C=E6=94=AF=E6=8C=81UDT=E5=92=8C?= =?UTF-8?q?=E5=85=B3=E8=81=94=E7=B1=BB=E5=9E=8B=E4=B8=8B=E5=88=97=E7=9A=84?= =?UTF-8?q?=E9=80=89=E6=8B=A9=20*=20fix:=20=E8=A1=A8=E6=A0=BC=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E5=88=97=E4=B8=8D=E6=94=AF=E6=8C=81=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=EF=BC=8C=E8=BF=90=E8=A1=8C=E6=97=B6=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=98=AF=E6=94=AF=E6=8C=81=E6=8B=96=E6=8B=BD=20*=20feature:=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=A6=81=E7=94=A8=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20*=20fix:=20=E4=BA=8B=E4=BB=B6=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E9=9D=A2=E6=9D=BF=E6=94=AF=E6=8C=81=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=99=A8=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=95=B0=E5=AD=97=E6=8E=A7=E4=BB=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=96=B9=E6=B3=95=E5=90=8D=E7=A7=B0=E4=B8=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E9=97=AE=E9=A2=98=20*=20fix:=20=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E8=A1=A8=E5=8D=95=E6=94=AF=E6=8C=81=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=8F=E5=B1=9E=E6=80=A7=20*=20feature:=20=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E9=9D=A2=E6=9D=BF=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E7=9B=AE=E6=A0=87=E7=BB=84=E4=BB=B6=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20*=20fix:=20=E6=9B=B4=E6=96=B0=E5=B7=A5=E7=A8=8B=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E6=96=87=E4=BB=B6=20*=20Merge=20branch=20'xdev'=20*?= =?UTF-8?q?=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/main?= =?UTF-8?q?'=20*=20fix:=20=E8=A7=A3=E5=86=B3=E9=80=9A=E8=BF=87=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E9=9D=A2=E6=9D=BF=E6=B7=BB=E5=8A=A0=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=91=BD=E4=BB=A4=E9=87=8D=E5=A4=8D=E5=BE=97?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=AD=90=E8=A1=A8=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E5=88=86=E9=A1=B5=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9E=9A=E4=B8=BE=E7=B1=BB=E5=9E=8B=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E5=8F=AF=E4=BB=A5=E9=80=9A=E8=BF=87=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E7=BC=96=E8=BE=91=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=B8=8B=E6=8B=89=E6=8E=A7=E4=BB=B6=E5=9C=A8?= =?UTF-8?q?=E5=8D=95=E6=8D=AE=E4=B8=AD=EF=BC=8C=E6=98=AF=E5=90=A6=E5=90=AF?= =?UTF-8?q?=E7=94=A8=E6=B8=85=E7=A9=BA=E6=8C=89=E9=92=AE=E5=BA=94=E8=AF=A5?= =?UTF-8?q?=E4=B8=BA=E5=90=A6=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E5=B8=83=E5=B0=94=E5=92=8C?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E5=B1=95=E7=A4=BA=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC=E8=A1=8C=E5=8F=B7?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E5=85=B3=E8=81=94=E9=97=AE=E9=A2=98=E3=80=81?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=9A=E9=80=89=E5=B1=9E=E6=80=A7=20*=20Me?= =?UTF-8?q?rge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*?= =?UTF-8?q?=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/main?= =?UTF-8?q?'=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/ximena?= =?UTF-8?q?fan/farris-vue=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=B8=8D?= =?UTF-8?q?=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=20*=20feature:=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=96=B9=E6=B3=95=E5=90=8E=E8=83=BD=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E6=89=93=E5=BC=80=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20*=20Merge=20branch=20'code-editor'=20*=20Merge=20re?= =?UTF-8?q?mote-tracking=20branch=20'refs/remotes/origin/main'=20*=20fix:?= =?UTF-8?q?=20=E8=B0=83=E6=95=B4=E5=90=8D=E7=A7=B0=20*=20feature:=20?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE=E6=94=AF=E6=8C=81=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E6=96=B9=E6=B3=95=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'code-editor'=20*=20Merge=20remote-tracking=20br?= =?UTF-8?q?anch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20feature:=20=E4=BA=8B=E4=BB=B6=E7=BC=96=E8=BE=91=E5=99=A8?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=A2=9E=E6=96=B9=E6=B3=95=EF=BC=9B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE=E6=94=AF=E6=8C=81=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=20*=20feature:=20=E4=BB=A3=E7=A0=81=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E7=BB=93=E6=9E=84=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E6=94=B9=E6=97=A5=E6=9C=9F=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E3=80=81=E5=A4=B4=E9=83=A8=E7=BB=84=E4=BB=B6=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8DHeader=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E7=BB=84=E6=97=B6=EF=BC=8C=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E4=B9=9F=E4=B8=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=8B=E4=BB=B6=E7=BC=96=E8=BE=91=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=8B=E4=BB=B6=E5=90=8E=E5=8F=82=E6=95=B0=E7=9C=8B?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20feature:=20?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E6=9D=A1=E4=BB=B6=E8=A1=8C=E5=8F=B7=E7=AD=89?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20feature:=20=E5=A4=9A=E9=80=89=E7=BB=84?= =?UTF-8?q?=E3=80=81=E4=B8=8B=E6=8B=89=E6=94=AF=E6=8C=81=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E9=A1=B9=E4=BF=AE=E6=94=B9=20*=20fix:=20check-box=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=94=AF=E6=8C=81readonly=E5=B1=9E=E6=80=A7=20*=20Mer?= =?UTF-8?q?ge=20branch=20'xdev'=20*=20Merge=20remote-tracking=20branch=20'?= =?UTF-8?q?refs/remotes/origin/main'=20*=20feature:=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=A1=B9=E7=BC=96=E8=BE=91=E5=99=A8=EF=BC=8C=E5=8D=95=E9=80=89?= =?UTF-8?q?=E7=BB=84=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81=E9=A1=B9=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=20*=20fix:=20=E8=B0=83=E6=95=B4=E6=89=93?= =?UTF-8?q?=E5=8C=85=E6=A0=B7=E5=BC=8F=E7=9A=84=E5=91=BD=E4=BB=A4=EF=BC=9B?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E3=80=81=E6=97=A5=E6=9C=9F=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E3=80=81=E5=A4=9A=E8=A1=8C=E6=96=87=E6=9C=AC=E7=AD=89=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=98=BE=E7=A4=BA=E4=B8=8D=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E4=BF=AE=E5=A4=8D=20*=20fix:=20=E5=8D=95=E9=80=89?= =?UTF-8?q?=E3=80=81=E5=8D=95=E9=80=89=E7=BB=84=E3=80=81=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E3=80=81=E5=A4=9A=E9=80=89=E7=BB=84=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=B1=9E=E6=80=A7readonly=E4=BD=86=E6=98=AF?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8F=AA=E6=94=AF=E6=8C=81disabled=20*=20Mer?= =?UTF-8?q?ge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*?= =?UTF-8?q?=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/main?= =?UTF-8?q?'=20*=20fix:=20=E6=A0=B8=E5=AF=B9=E6=8E=A7=E4=BB=B6=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E5=B1=9E=E6=80=A7=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8Dcheckbox?= =?UTF-8?q?=E6=A8=AA=E5=90=91=E6=98=BE=E7=A4=BA=E4=B8=8D=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=B7=A5=E5=85=B7=E6=A0=8F=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?disabled=E9=97=AE=E9=A2=98=EF=BC=9BSplitter=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E9=97=AE=E9=A2=98=EF=BC=9B=E6=89=8B=E6=94=B9=E5=B8=83?= =?UTF-8?q?=E5=B0=94=E5=80=BC=E5=B1=9E=E6=80=A7=E5=BC=82=E5=B8=B8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=B7=A6?= =?UTF-8?q?=E5=88=97=E5=8F=B3=E5=8D=A1=E5=B8=83=E5=B1=80=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8Dsplitter?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=B1=95=E7=A4=BA=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E8=BF=90=E8=A1=8C=E6=97=B6=E5=B7=A6?= =?UTF-8?q?=E5=88=97=E5=8F=B3=E5=8D=A1=E5=B8=83=E5=B1=80=E9=94=99=E4=B9=B1?= =?UTF-8?q?=EF=BC=8C=E5=A4=B4=E9=83=A8=E6=8C=89=E9=92=AE=E4=B8=8D=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A0=B7=E5=BC=8F=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20Merge=20branch=20'xdev'=20*=20Mer?= =?UTF-8?q?ge=20remote-tracking=20branch=20'refs/remotes/origin/main'=20*?= =?UTF-8?q?=20feature:=20=E5=A2=9E=E5=8A=A0=E5=8C=BA=E5=9F=9F=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E6=8C=87=E4=BB=A4=EF=BC=8C=E8=A7=A3=E5=86=B3=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=A0=B7=E5=BC=8F=E5=B8=83=E5=B1=80=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20feature:=20=E5=AE=8C=E5=96=84Splitter=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=20*=20Merge=20branch=20'main'=20into=20xdev?= =?UTF-8?q?=20*=20Merge=20remote-tracking=20branch=20'refs/remotes/origin/?= =?UTF-8?q?main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E6=97=B6=E4=B8=8B=E6=8B=89=E6=9E=9A=E4=B8=BE=E6=8C=87=E5=AE=9A?= =?UTF-8?q?idField=E9=97=AE=E9=A2=98=20*=20feature:=20=E5=AE=8C=E5=96=84sp?= =?UTF-8?q?litter=E7=BB=84=E4=BB=B6=20*=20fix:=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E4=B8=8D=E9=9C=80=E8=A6=81=E7=9A=84=E4=BF=AE=E6=94=B9=EF=BC=8C?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9C=8D=E5=8A=A1=20*=20feature:=20=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=E8=BE=93=E5=85=A5=E6=8E=A7=E4=BB=B6=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=BB=9F=E4=B8=80=E5=B8=83=E5=B1=80=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E6=A0=B7=E5=BC=8F=20*=20feature:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=9B=86=E6=88=90=E7=BB=9F=E4=B8=80=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20into=20xdev=20*=20Merge=20remote-tracking=20branch=20'ref?= =?UTF-8?q?s/remotes/origin/main'=20*=20feature:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=BB=A7=E6=89=BF=E4=B8=AD=E5=93=8D=E5=BA=94=E5=BC=8F=E5=88=97?= =?UTF-8?q?=E5=AE=BD=E7=BC=96=E8=BE=91=E5=99=A8=E9=97=AE=E9=A2=98=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20xdev=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=89=93=E5=8C=85=E8=BF=87=E7=A8=8B=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20feature:=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=AE=B9=E5=99=A8=E5=B1=9E=E6=80=A7=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BA=8B=E4=BB=B6=20*=20fix:=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E9=83=A8=E5=88=86=E6=8E=A7=E4=BB=B6=E8=AE=BE=E8=AE=A1=E6=97=B6?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=90=8D=E7=A7=B0=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=BF=90=E8=A1=8C=E6=97=B6=E8=A1=A8=E6=A0=BC=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=8D=E5=87=86=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20feature:=20Form=E6=B7=BB=E5=8A=A0=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E9=85=8D=E7=BD=AE=20*=20feature:=20Form?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=BB=9F=E4=B8=80=E5=B8=83=E5=B1=80=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=20*=20feature:=20=E9=9B=86=E6=88=90=E5=88=97=E5=AE=BD?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=20*=20feature:=20schema=E4=B8=AD?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E5=85=83=E7=B4=A0=E6=94=AF=E6=8C=81ignore?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=20*=20Merge=20remote-tracking=20branch=20're?= =?UTF-8?q?fs/remotes/origin/main'=20*=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81=E5=90=8E?= =?UTF-8?q?=E5=88=97=E7=BC=96=E8=BE=91=E5=99=A8=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20=E6=97=B6=E9=97=B4=E7=BB=84=E4=BB=B6disable=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E4=B8=BAdisabled=20*=20Merge=20remote-tracking=20bran?= =?UTF-8?q?ch=20'refs/remotes/origin/main'=20*=20fix:=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?editor=E5=86=85=E9=83=A8=E5=8F=96=E4=B8=8D=E5=88=B0=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=EF=BC=9B=E6=9B=BF=E6=8D=A2=E5=88=97=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E8=B0=83=E6=95=B4=E6=94=AF=E6=8C=81=E6=96=B0?= =?UTF-8?q?=E6=97=A7=E5=88=97=E5=B1=9E=E6=80=A7=20*=20fix:=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=B7=A5=E5=85=B7=E6=A0=8F=E6=9D=A5=E5=9B=9E=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=8E=A7=E4=BB=B6=E5=90=8E=E4=B8=8D=E8=83=BD=E8=A2=AB?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E9=97=AE=E9=A2=98=E3=80=81=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=20*=20fi?= =?UTF-8?q?x:=20=E4=BF=AE=E5=A4=8D=E6=A0=91=E8=A1=A8=E6=9A=82=E6=97=A0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E4=BD=8D=E7=BD=AE=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=88=97=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E9=80=89=E6=8B=A9=E5=88=97=E3=80=81=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=8E=A7=E4=BB=B6=E7=B1=BB=E5=9E=8B=E3=80=81=E5=88=97?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20rem?= =?UTF-8?q?ote-tracking=20branch=20'refs/remotes/origin/main'=20*=20fix:?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8DResponseToolbar=E6=8C=89=E9=92=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E6=98=BE=E7=A4=BA=E4=B8=BA=E7=81=B0=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E4=B8=8D=E6=94=AF=E6=8C=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=8F=82=E6=95=B0=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=88=97=E7=BC=96=E8=BE=91=E5=99=A8=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E6=89=93=E5=BC=80=E6=95=B0=E6=8D=AE=E4=B8=8D=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=97=AE=E9=A2=98=20*=20Merge=20remote-tracking=20bra?= =?UTF-8?q?nch=20'refs/remotes/origin/main'=20*=20feature:=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BATreeGrid?= =?UTF-8?q?=E3=80=81=E5=88=97=E5=B1=9E=E6=80=A7=E3=80=81=E5=88=97=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E3=80=81=E7=BB=91=E5=AE=9A=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=20*=20feature:=20=E8=B0=83=E6=95=B4Textarea=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E5=86=99=E6=B3=95=E5=92=8C=E7=A4=BA=E4=BE=8B=20*=20feature:=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=99=84=E4=BB=B6=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BF=A1=E6=81=AF=20*=20fix:=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=8F=AA=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=80=BC=E4=BD=86=E6=98=AF=E6=8E=A7=E4=BB=B6=E4=B8=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fix:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B6=88=E6=81=AF=E6=8F=90=E7=A4=BA=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E9=97=AE=E9=A2=98=20*=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E4=B8=8D=E8=A7=84=E8=8C=83=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=A4=B4=E9=83=A8=E3=80=81?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E6=8C=89=E9=92=AE=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/events-editor/src/events-editor.component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui-vue/components/events-editor/src/events-editor.component.tsx b/packages/ui-vue/components/events-editor/src/events-editor.component.tsx index 8ccee08e5c6..bfde009390d 100644 --- a/packages/ui-vue/components/events-editor/src/events-editor.component.tsx +++ b/packages/ui-vue/components/events-editor/src/events-editor.component.tsx @@ -1,4 +1,4 @@ - + import { SetupContext, defineComponent, onMounted, provide, ref } from "vue"; import { EventsEditorProps, eventsEditorProps } from "./events-editor.props"; import { EventItem, InteractionItem, InternalCommand } from "./types"; @@ -56,6 +56,7 @@ export default defineComponent({ function onDeleteInteraction(interactionIndex: number) { deleteInteracton(interactionIndex); + useMethodsComposition.emitFinalState(false, null); } function renderInteraction(interaction: InteractionItem, displayOrder: number) { const switchElement = interaction.showSwitch[0]; -- Gitee From 09595da1581c7ab76ea46102586a530e093a1c41 Mon Sep 17 00:00:00 2001 From: ing <1123745939@qq.com> Date: Mon, 17 Feb 2025 12:09:18 +0000 Subject: [PATCH 11/13] =?UTF-8?q?!1286=20feature:=20cli=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=B0=86css=E7=9B=B4=E6=8E=A5=E6=89=93=E5=8C=85=E5=88=B0js?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=AD=20*=20feature:=20cli=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=97=B6=E5=B0=86css=E7=9B=B4=E6=8E=A5=E6=89=93?= =?UTF-8?q?=E5=8C=85=E5=88=B0js=E6=96=87=E4=BB=B6=E4=B8=AD=20*=20Merge=20b?= =?UTF-8?q?ranch=20'main'=20of=20gitee.com:ing=5Fy/farris-vue=20*=20Merge?= =?UTF-8?q?=20branch=20'main'=20of=20gitee.com:ing=5Fy/farris-vue=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20of=20gitee.com:ing=5Fy/farris-vue=20*?= =?UTF-8?q?=20feature:=20cli=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AEconfigFile?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=90=8D=20*=20feature:=20=E5=AF=B9=E9=BD=90?= =?UTF-8?q?checkbox=E5=8F=8Aradio=E5=91=BD=E5=90=8D=20*=20Merge=20branch?= =?UTF-8?q?=20'dev-checkbox-rename'=20*=20feature:=20=E5=AF=B9=E9=BD=90che?= =?UTF-8?q?ckbox=E5=8F=8Aradio=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/cli/package.json | 1 + packages/cli/src/common/get-vite-config.ts | 11 +- pnpm-lock.yaml | 248 +++++---------------- 3 files changed, 60 insertions(+), 200 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 9963e6bfb05..5c9bfd3e74e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -30,6 +30,7 @@ "ora": "^8.0.1", "typescript": "^4.6.4", "vite": "^4.4.1", + "vite-plugin-css-injected-by-js": "^3.5.2", "vite-plugin-dts": "^3.9.1" }, "devDependencies": { diff --git a/packages/cli/src/common/get-vite-config.ts b/packages/cli/src/common/get-vite-config.ts index e02b0b12a11..1d11379076e 100644 --- a/packages/cli/src/common/get-vite-config.ts +++ b/packages/cli/src/common/get-vite-config.ts @@ -1,6 +1,7 @@ import { AliasOptions, LibraryOptions, PluginOption, mergeConfig } from 'vite'; import { getFarrisConfigAsync } from './get-farris-config.js'; import { getDependencies } from '../common/get-dependencies.js'; +import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'; type FarrisConfig = { lib: LibraryOptions | false; @@ -12,6 +13,7 @@ type FarrisConfig = { alias?: AliasOptions; outDir?: string; target: string | string[]; + cssInjected?: boolean }; const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { @@ -23,8 +25,9 @@ const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { outDir, externals = { include: [], exclude: [] }, externalDependencies, - plugins, - alias + plugins = [], + alias, + cssInjected } = farrisConfig; const dependencies = externalDependencies ? getDependencies() : []; @@ -35,6 +38,10 @@ const formatFarrisConfig = (farrisConfig: FarrisConfig, type: string) => { format && (process.env.FARRIS_FORMAT = format); + if(cssInjected){ + plugins.push(cssInjectedByJsPlugin()); + } + const viteConfig = { build: { target, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a9bae67ae3..c466d0350f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -366,10 +366,10 @@ importers: version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5) '@vitejs/plugin-vue': specifier: ^4.0.0 - version: 4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vitejs/plugin-vue-jsx': specifier: ^3.0.0 - version: 3.1.0(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 3.1.0(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vue/babel-plugin-jsx': specifier: ^1.1.1 version: 1.2.5(@babel/core@7.25.8) @@ -408,7 +408,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -444,19 +444,19 @@ importers: version: 4.9.5 vite: specifier: ^4.1.4 - version: 4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0) + version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) vite-plugin-dts: specifier: ^2.1.0 - version: 2.3.0(@types/node@18.19.57)(rollup@4.24.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) + version: 2.3.0(@types/node@20.5.1)(rollup@4.24.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) vite-plugin-md: specifier: ^0.20.0 - version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) + version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) vite-svg-loader: specifier: ^4.0.0 version: 4.0.0 vitepress: specifier: 1.0.0-alpha.8 - version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@18.19.57)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) + version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) vitepress-theme-demoblock: specifier: 1.4.2 version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@4.9.5) @@ -505,6 +505,9 @@ importers: vite: specifier: ^4.4.1 version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) + vite-plugin-css-injected-by-js: + specifier: ^3.5.2 + version: 3.5.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) vite-plugin-dts: specifier: ^3.9.1 version: 3.9.1(@types/node@20.5.1)(rollup@4.24.0)(typescript@4.9.5)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) @@ -635,7 +638,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) ora: specifier: ^6.1.2 version: 6.3.1 @@ -871,7 +874,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) ora: specifier: ^6.1.2 version: 6.3.1 @@ -977,10 +980,10 @@ importers: version: 7.18.0(eslint@9.19.0(jiti@1.21.6))(typescript@4.9.5) '@vitejs/plugin-vue': specifier: ^4.0.0 - version: 4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vitejs/plugin-vue-jsx': specifier: ^3.0.0 - version: 3.1.0(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) + version: 3.1.0(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)) '@vue/babel-plugin-jsx': specifier: ^1.1.1 version: 1.2.5(@babel/core@7.25.8) @@ -1019,7 +1022,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -1055,19 +1058,19 @@ importers: version: 4.9.5 vite: specifier: ^4.1.4 - version: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) + version: 4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0) vite-plugin-dts: specifier: ^2.1.0 - version: 2.3.0(@types/node@20.5.1)(rollup@4.24.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + version: 2.3.0(@types/node@18.19.57)(rollup@4.24.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) vite-plugin-md: specifier: ^0.20.0 - version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) + version: 0.20.6(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)) vite-svg-loader: specifier: ^4.0.0 version: 4.0.0 vitepress: specifier: 1.0.0-alpha.8 - version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@20.5.1)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) + version: 1.0.0-alpha.8(@algolia/client-search@4.24.0)(@types/node@18.19.57)(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(search-insights@2.17.2)(terser@5.36.0)(typescript@4.9.5) vitepress-theme-demoblock: specifier: 1.4.2 version: 1.4.2(react-dom@16.14.0(react@16.14.0))(react@16.14.0)(sass@1.80.3)(typescript@4.9.5) @@ -1286,7 +1289,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -1389,7 +1392,7 @@ importers: version: 2.2.2 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) patch-vue-directive-ssr: specifier: ^0.0.1 version: 0.0.1 @@ -1537,7 +1540,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) ora: specifier: ^6.1.2 version: 6.3.1 @@ -1791,7 +1794,7 @@ importers: version: 9.3.7 jest: specifier: ^29.0.0 - version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + version: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) ora: specifier: ^6.1.2 version: 6.3.1 @@ -3450,6 +3453,7 @@ packages: '@ls-lint/ls-lint@2.2.3': resolution: {integrity: sha512-ekM12jNm/7O2I/hsRv9HvYkRdfrHpiV1epVuI2NP+eTIcEgdIdKkKCs9KgQydu/8R5YXTov9aHdOgplmCHLupw==} + cpu: [x64, arm64, s390x] os: [darwin, linux, win32] hasBin: true @@ -10653,6 +10657,11 @@ packages: vite-plugin-banner@0.8.0: resolution: {integrity: sha512-JpDWDYxtrsytuvUOJCgJcTkBb6XM8yPOidjRtB6F5SW1JSzDd/Y+PD/44wR6ovWKXhSUiyDRqPvx7mMf8+8ELg==} + vite-plugin-css-injected-by-js@3.5.2: + resolution: {integrity: sha512-2MpU/Y+SCZyWUB6ua3HbJCrgnF0KACAsmzOQt1UvRVJCGF6S8xdA3ZUhWcWdM9ivG4I5az8PnQmwwrkC2CAQrQ==} + peerDependencies: + vite: '>2.0.0-0' + vite-plugin-dts@2.3.0: resolution: {integrity: sha512-WbJgGtsStgQhdm3EosYmIdTGbag5YQpZ3HXWUAPCDyoXI5qN6EY0V7NXq0lAmnv9hVQsvh0htbYcg0Or5Db9JQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -12957,41 +12966,6 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.57 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 @@ -14711,7 +14685,7 @@ snapshots: fp-ts: 2.16.9 inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 - vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + vite-plugin-md: 0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) transitivePeerDependencies: - '@edge-runtime/vm' - '@vitejs/plugin-vue' @@ -15475,7 +15449,7 @@ snapshots: dependencies: bumpp: 8.2.1 callsites: 4.2.0 - inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) vitest: 0.25.8(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@edge-runtime/vm' @@ -15495,7 +15469,7 @@ snapshots: dependencies: bumpp: 8.2.1 callsites: 4.2.0 - inferred-types: 0.37.6(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) + inferred-types: 0.37.6(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) vitest: 0.25.8(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) transitivePeerDependencies: - '@edge-runtime/vm' @@ -16329,28 +16303,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): + create-jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -18816,35 +18775,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): + jest-cli@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest-cli@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -18916,38 +18856,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@18.19.57)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): - dependencies: - '@babel/core': 7.25.8 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.8) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 18.19.57 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): + jest-config@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: '@babel/core': 7.25.8 '@jest/test-sequencer': 29.7.0 @@ -18973,38 +18882,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.5.1 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): - dependencies: - '@babel/core': 7.25.8 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.25.8) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 20.5.1 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.6.3) + ts-node: 10.9.2(@types/node@18.19.57)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -19272,24 +19150,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)): + jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest@29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@4.9.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@20.5.1)(ts-node@10.9.2(@types/node@18.19.57)(typescript@5.6.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -22036,25 +21902,6 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.5.1 - acorn: 8.13.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -22416,6 +22263,10 @@ snapshots: vite-plugin-banner@0.8.0: {} + vite-plugin-css-injected-by-js@3.5.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)): + dependencies: + vite: 4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0) + vite-plugin-dts@2.3.0(@types/node@18.19.57)(rollup@4.24.0)(vite@4.5.5(@types/node@18.19.57)(sass@1.80.3)(terser@5.36.0)): dependencies: '@babel/parser': 7.25.8 @@ -22686,7 +22537,7 @@ snapshots: vite-plugin-md@0.22.5(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) - '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@20.5.1)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) + '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@4.6.2(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@4.9.5)))(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@4.5.5(@types/node@20.5.1)(sass@1.80.3)(terser@5.36.0)) '@yankeeinlondon/gray-matter': 6.2.1(happy-dom@8.9.0)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) '@yankeeinlondon/happy-wrapper': 2.10.1(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0) markdown-it: 13.0.2 @@ -22707,7 +22558,7 @@ snapshots: - supports-color - terser - vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): + vite-plugin-md@0.22.5(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)): dependencies: '@vitejs/plugin-vue': 5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)) '@yankeeinlondon/builder-api': 1.4.1(@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0))(vue@3.5.12(typescript@5.6.3)))(happy-dom@14.12.3)(jsdom@20.0.3)(sass@1.80.3)(terser@5.36.0)(vite@5.4.9(@types/node@18.19.57)(sass-embedded@1.80.3)(sass@1.80.3)(terser@5.36.0)) @@ -22721,6 +22572,7 @@ snapshots: - '@vitest/browser' - '@vitest/ui' - encoding + - happy-dom - jsdom - less - lightningcss -- Gitee From f18eb19d0176a8cc640d286bd3b2a30b93f5a555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=A7=80=E6=89=8D?= Date: Mon, 17 Feb 2025 12:12:05 +0000 Subject: [PATCH 12/13] =?UTF-8?q?!1291=20fix:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=E9=80=89=E6=8B=A9=E5=99=A8=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8=E5=8F=AF=E8=A7=86=E5=8C=BA=E5=9F=9F=E8=BE=83=E5=B0=8F?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E5=BC=B9=E7=AA=97=E7=A1=AE=E5=AE=9A=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E4=B8=8D=E5=8F=AF=E8=A7=81=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=85=83=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8=EF=BC=8C=E5=9C=A8=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=BA=E5=9F=9F=E8=BE=83=E5=B0=8F=E6=97=B6=EF=BC=8C=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E7=A1=AE=E5=AE=9A=E6=8C=89=E9=92=AE=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E8=A7=81=E7=9A=84=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'ma?= =?UTF-8?q?in'=20of=20https://gitee.com/hxling/farris-vue=20*=20fix:=20?= =?UTF-8?q?=E6=9B=B4=E6=AD=A3modal=E5=B1=9E=E6=80=A7=E5=90=8D=E7=A7=B0=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/farr?= =?UTF-8?q?is-vue=20*=20fix:=20=E7=A7=BB=E9=99=A4=E6=97=A0=E6=95=88?= =?UTF-8?q?=E5=BC=95=E7=94=A8=20*=20fix:=20lookup=20=E6=A0=91=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=A6=81=E7=94=A8=E8=99=9A=E6=8B=9F=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/?= =?UTF-8?q?farris-vue=20*=20fix:=20button-edit=20=E6=96=B0=E5=A2=9E=20popu?= =?UTF-8?q?pOnClick=20=E5=B1=9E=E6=80=A7=20*=20fix:=20button-edit=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20popupOnClick=20=E5=B1=9E=E6=80=A7=20*=20re?= =?UTF-8?q?vert:=20desginer=20=E6=89=93=E5=8C=85=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=BF=98=E5=8E=9F=20*=20fix:=20=E4=BC=98=E5=8C=96combo-list?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=98=BE=E7=A4=BA=20*=20fix:=20lookup?= =?UTF-8?q?=E6=89=93=E5=BC=80=E7=AA=97=E5=8F=A3=E6=95=B0=E6=8D=AE=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96=20*=20fix:=20comb?= =?UTF-8?q?o-tree=E6=94=AF=E6=8C=81=E7=82=B9=E8=BE=93=E5=85=A5=E6=A1=86?= =?UTF-8?q?=E6=89=93=E5=BC=80=E9=9D=A2=E6=9D=BF=20*=20fix:=20=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E7=BB=84=E4=BB=B6=E7=A6=81=E6=AD=A2=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=82=B9=E5=87=BB=E8=BE=93=E5=85=A5=E6=A1=86?= =?UTF-8?q?=E5=BC=B9=E5=87=BA=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/hxling/farris-vue=20*=20fix:=20lookup=E5=B7=A6=E4=BE=A7?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=88=86=E9=A1=B5=E4=BA=8B=E4=BB=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E9=AA=8C=E8=AF=81=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=98=AF=E5=90=A6=E4=B8=BA=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=98=A0=E5=B0=84=E7=BC=96=E8=BE=91=E5=99=A8=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=B8=85=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98=20*=20fi?= =?UTF-8?q?x:=20lookup=E7=BB=91=E5=AE=9A=E5=AD=97=E6=AE=B5=E4=B8=BA?= =?UTF-8?q?=E5=85=B3=E8=81=94=E6=97=B6=EF=BC=8C=E7=A6=81=E7=94=A8=E5=A4=9A?= =?UTF-8?q?=E9=80=89=E5=B1=9E=E6=80=A7=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/hxling/farris-vue=20*=20fix:=20=E8=B0=83lo?= =?UTF-8?q?okup=E5=A4=9A=E9=80=89=E6=A8=A1=E5=BC=8F=20*=20Merge=20branch?= =?UTF-8?q?=20'main'=20of=20https://gitee.com/hxling/farris-vue=20*=20fix:?= =?UTF-8?q?=20lookup=20=E5=8F=8C=E5=88=97=E8=A1=A8=E5=B8=AE=E5=8A=A9?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E9=9D=A2=E6=9D=BF=E9=9A=90=E8=97=8F=E6=97=B6?= =?UTF-8?q?=E6=9C=BA=E4=BC=98=E5=8C=96=20*=20fix:=20button-edit=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=B8=85=E7=90=86=EF=BC=9B=E6=97=A5=E6=9C=9F=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E9=9D=A2=E6=9D=BF=E6=97=B6=E9=97=B4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E8=BF=9B=E8=A1=8C=E6=A0=BC=E5=BC=8F=E5=8C=96?= =?UTF-8?q?=20*=20fix:=20lookup=E5=80=BC=E5=8F=98=E5=8C=96=E5=90=8E?= =?UTF-8?q?=E9=98=BB=E6=AD=A2=E5=88=97=E8=A1=A8=E7=BB=93=E6=9D=9F=E7=BC=96?= =?UTF-8?q?=E8=BE=91=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/hxling/farris-vue=20*=20fix:=20popover=E5=BC=B9=E5=87=BA?= =?UTF-8?q?=E5=B1=82=E4=BD=8D=E7=BD=AE=E4=BC=98=E5=8C=96=20*=20fix:=20?= =?UTF-8?q?=E6=B8=85=E7=90=86console.log=20*=20fix:=20lookup=E5=86=85?= =?UTF-8?q?=E9=83=A8=E7=8A=B6=E6=80=81=E6=B8=85=E7=90=86=20*=20fix:=20?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E7=BB=84=E4=BB=B6=E6=98=BE=E7=A4=BA=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=97=B6=E9=80=89=E6=8B=A9=E6=97=A5=E6=9C=9F=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BC=98=E5=8C=96=20*=20fix:=20=E4=BF=AE=E5=A4=8Dlook?= =?UTF-8?q?up=20=E5=88=97=E8=A1=A8=E5=A4=9A=E9=80=89=E6=97=B6=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E8=AE=B0=E5=BD=95=E4=B8=8D=E5=87=86=E7=A1=AE=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20=E6=97=A5=E6=9C=9F=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=81=A2=E5=A4=8D=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20fix:=20Lookup=E7=BB=84=E4=BB=B6=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=85=B3=E9=97=AD=E4=BA=8B=E4=BB=B6=E5=8F=82?= =?UTF-8?q?=E6=95=B0=20*=20fix:=20=E6=97=A5=E6=9C=9F=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=97=B6=E9=97=B4=E6=97=B6=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E5=90=8E=E5=80=BC=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/hxling/farris-vue=20*=20Merge=20branch=20'lookup-bug-fix'=20*?= =?UTF-8?q?=20fix:=20=E6=97=A5=E6=9C=9F=E7=BB=84=E4=BB=B6blur=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=A7=BB=E9=99=A4=20*=20fix:=20=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E7=BC=96=E8=BE=91=E5=99=A8=E4=B8=8B=E6=8B=89?= =?UTF-8?q?=E6=A0=91=E5=A2=9E=E5=8A=A0=E7=A6=81=E7=94=A8=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=20*=20fix:=20=E8=B0=83=E6=95=B4=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E7=BB=84=E4=BB=B6editable=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=20*=20fix:=20=E6=97=A5=E6=9C=9F=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8A=A0=E5=85=A5blur=20*=20fix:=20=E7=A7=BB=E9=99=A4=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E7=BB=84=E4=BB=B6blur=20*=20fix:=20date-picker=20?= =?UTF-8?q?=E5=A4=B1=E5=8E=BB=E7=84=A6=E7=82=B9=E5=8A=A0=E5=85=A5=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E6=A0=BC=E5=BC=8F=E9=AA=8C=E8=AF=81=20*=20fix:=20date?= =?UTF-8?q?-picker=E7=BB=84=E4=BB=B6=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=98=93=E7=94=A8=E6=80=A7=E4=BC=98=E5=8C=96=20*=20fix:=20look?= =?UTF-8?q?up=E5=B1=9E=E6=80=A7=E5=A4=9A=E9=80=89=E5=88=86=E9=9A=94?= =?UTF-8?q?=E7=AC=A6=E6=94=B9=E4=B8=BA=E4=B8=8B=E6=8B=89=20*=20fix:=20look?= =?UTF-8?q?up=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=B1=9E=E6=80=A7=E8=81=94=E5=8A=A8=20*=20fix:=20look?= =?UTF-8?q?up=E7=BB=84=E4=BB=B6=E5=8D=B8=E8=BD=BD=E5=90=8E=E6=B8=85?= =?UTF-8?q?=E7=90=86=E6=97=A0=E7=94=A8=E6=95=B0=E6=8D=AE=20*=20fix:=20look?= =?UTF-8?q?up=20=E5=AF=BC=E8=88=AA=E5=B8=AE=E5=8A=A9=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E9=80=89=E6=8B=A9=E9=9D=A2=E6=9D=BF=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E6=97=B6=E6=9C=BA=E4=BC=98=E5=8C=96=20*=20fix:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81=20*=20fi?= =?UTF-8?q?x:=20lookup=E7=BB=84=E4=BB=B6=E7=82=B9=E5=87=BB=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=BE=93=E5=85=A5=E6=A1=86=E9=9A=90=E8=97=8F=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E6=B5=AE=E5=8A=A8=E5=B1=82=20*=20fix:=20modal?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=B0=BA=E5=AF=B8=E5=8F=98=E5=8C=96=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E5=85=B6=E4=BB=96=E6=B5=AE=E5=8A=A8=E5=B1=82=20*=20fi?= =?UTF-8?q?x:=20popover=20=E4=BC=98=E5=8C=96=E9=9D=A2=E6=9D=BF=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E6=97=B6=E6=9C=BA=20*=20fix:=20popover=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=B5=8C=E5=A5=97=E4=BD=BF=E7=94=A8=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/?= =?UTF-8?q?farris-vue=20*=20fix:=20search-box=E7=BB=84=E4=BB=B6popup?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=BC=98=E5=8C=96=20*=20fix:=20=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E7=BB=84=E4=BB=B6=E9=80=89=E6=8B=A9=E5=90=8E=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E6=97=A5=E6=9C=9F=E9=9D=A2=E6=9D=BF=20*=20fix:=20butt?= =?UTF-8?q?on-edit=20=E7=BB=84=E4=BB=B6=E4=BC=98=E5=8C=96popup=20=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=20*=20fix:=20=E6=97=A5=E6=9C=9F=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E6=97=B6=EF=BC=8C=E9=9A=90=E8=97=8F=E5=8F=B3?= =?UTF-8?q?=E4=BE=A7=E5=9B=BE=E6=A0=87=20*=20fix:=20=E4=BC=98=E5=8C=96popo?= =?UTF-8?q?ver=E9=9D=A2=E6=9D=BF=E9=9A=90=E8=97=8F=E6=97=B6=E6=9C=BA=20*?= =?UTF-8?q?=20fix:=20lookup=20=E7=BB=84=E4=BB=B6=E6=89=93=E5=BC=80?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=90=8E=E9=80=89=E4=B8=AD=E5=B7=B2=E9=80=89?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/hxling/farris-vue=20*=20fix:=20=E4=BC=98=E5=8C=96pop?= =?UTF-8?q?over=E7=BB=84=E4=BB=B6=E9=9A=90=E8=97=8F=E9=9D=A2=E6=9D=BF=20*?= =?UTF-8?q?=20fix:=20popover=E7=BB=84=E4=BB=B6=E9=9D=A2=E6=9D=BF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=BD=8D=E7=BD=AE=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=B0=83=E8=8A=82=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/hxling/farris-vue=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/hxling/farris-vue=20*=20fix:=20=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E5=AD=97=E6=AE=B5=E7=BC=96=E8=BE=91=E5=99=A8=EF=BC=8C?= =?UTF-8?q?=E6=B8=85=E7=A9=BA=E6=95=B0=E6=8D=AE=E5=90=8E=EF=BC=8C=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E5=8F=96=E6=B6=88=E6=97=A0=E6=B3=95=E8=BF=98=E5=8E=9F?= =?UTF-8?q?=20*=20fix:=20=E4=BB=A3=E7=A0=81=E5=8F=98=E9=87=8F=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E6=9B=B4=E6=96=B0=20*=20fix:=20=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E5=90=8E=E8=BF=98=E5=8E=9F=E6=95=B0=E6=8D=AE=20*=20fix:=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=BA=90=E9=80=89=E6=8B=A9=E5=99=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E4=BC=98=E5=8C=96=20*=20fix:=20Modal=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=BC=B9=E5=BC=80=E5=89=8D=E5=8A=A0=E5=85=A5=E5=B0=BA?= =?UTF-8?q?=E5=AF=B8=E9=AA=8C=E8=AF=81=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/hxling/farris-vue=20*=20fix:=20=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E7=BB=84=E4=BB=B6(Modal)=E6=98=93=E7=94=A8=E6=80=A7?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20*=20fix:=20=E8=A1=A5=E5=85=85lookup=20sche?= =?UTF-8?q?ma=20=E5=86=85=E5=AE=B9=20*=20fix:=20=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86?= =?UTF-8?q?=20*=20fix:=20=E8=A1=A5=E5=85=85lookup=20schema=20=E5=86=85?= =?UTF-8?q?=E5=AE=B9=20*=20fix:=20=E8=B0=83=E6=95=B4=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=B1=95=E5=BC=80=E4=B8=8E=E6=94=B6=E8=B5=B7?= =?UTF-8?q?=E7=9A=84=E6=A0=B7=E5=BC=8F=20*=20fix:=20messager=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=8F=90=E7=A4=BA=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/hxling/farris-vue=20*=20fix:=20=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8=E5=AD=97=E6=AE=B5=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=20*=20fix:=20lookup=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E7=BB=9F=E4=B8=80=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/?= =?UTF-8?q?farris-vue=20*=20fix:=20=E8=AE=BE=E8=AE=A1=E6=97=B6lookup=20?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E6=95=B0=E6=8D=AE=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=20*=20fix:=20lookup=E6=9F=A5=E8=AF=A2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BC=98=E5=8C=96=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/hxling/farris-vue=20*=20fix:=20=E8=A1=A5?= =?UTF-8?q?=E5=85=85lookup=20Schema=20*=20fix:=20=E4=BF=AE=E5=A4=8Dschema-?= =?UTF-8?q?editor=20=E7=BB=84=E4=BB=B6=E6=9F=A5=E8=AF=A2=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20lookup=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=8F=96=E6=95=B0=E4=BC=98=E5=8C=96=20*=20fix:=20=E8=A1=A5?= =?UTF-8?q?=E5=85=85schema=20*=20Merge=20branch=20'main'=20of=20https://gi?= =?UTF-8?q?tee.com/hxling/farris-vue=20*=20fix:=20=E4=BF=AE=E5=A4=8Dschema?= =?UTF-8?q?-editor=20=E7=BB=84=E4=BB=B6=E6=9F=A5=E8=AF=A2=E5=A4=B1?= =?UTF-8?q?=E6=95=88=E9=97=AE=E9=A2=98=20*=20Merge=20branch=20'lookup-bug-?= =?UTF-8?q?fix'=20*=20fix:=20=E5=8F=98=E9=87=8F=E5=91=BD=E5=90=8D=E8=B0=83?= =?UTF-8?q?=E6=95=B4=20*=20Merge=20branch=20'main'=20of=20https://gitee.co?= =?UTF-8?q?m/hxling/farris-vue=20*=20fix:=20lookup=E6=89=93=E5=BC=80?= =?UTF-8?q?=E5=90=8E=E9=80=89=E4=B8=AD=E5=B7=B2=E9=80=89=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=20*=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/?= =?UTF-8?q?farris-vue=20*=20fix:=20lookup=20=E5=88=97=E8=A1=A8=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E4=BA=8B=E4=BB=B6=E6=9B=B4=E6=96=B0=20*=20fix:=20look?= =?UTF-8?q?up=E5=88=97=E8=A1=A8=E5=88=86=E9=A1=B5=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20*=20Merge=20branch=20'main'=20of=20https:/?= =?UTF-8?q?/gitee.com/hxling/farris-vue=20*=20fix:=20=E6=9B=B4=E6=96=B0mon?= =?UTF-8?q?aco-editor=E7=BB=84=E4=BB=B6=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=86=85=E5=AE=B9=20*=20Merge=20branch=20'main'=20of?= =?UTF-8?q?=20https://gitee.com/hxling/farris-vue=20*=20fix:=20monaco-edit?= =?UTF-8?q?or=E7=BB=84=E4=BB=B6=E8=B0=83=E6=95=B4=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E8=AF=BB=E5=8F=96=E6=96=B9=E5=BC=8F=20*=20fe?= =?UTF-8?q?ature:=20=E8=AE=BE=E8=AE=A1=E5=99=A8=E9=9B=86=E6=88=90monaco=20?= =?UTF-8?q?editor=20*=20fix:=20lookup=E5=AF=BC=E5=87=BA=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20*=20fix:=20lookup=20=E6=B8=85=E7=A9=BA=E4=BA=8B=E4=BB=B6=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/farr?= =?UTF-8?q?is-vue=20*=20fix:=20datagrid=E9=9B=86=E6=88=90lookup=20*=20fix:?= =?UTF-8?q?=20lookup=E6=B8=85=E7=A9=BA=E4=BA=8B=E4=BB=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8F=82=E6=95=B0=20*=20Merge=20branch=20'lookup-feature'=20*?= =?UTF-8?q?=20Merge=20branch=20'main'=20of=20https://gitee.com/hxling/farr?= =?UTF-8?q?is-vue=20*=20fix:=20lookup=20=E6=98=A0=E5=B0=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=85=BC=E5=AE=B9=E6=80=A7=E4=BC=98=E5=8C=96=20*=20Me?= =?UTF-8?q?rge=20branch=20'main'=20into=20lookup-feature=20*=20Merge=20bra?= =?UTF-8?q?nch=20'main'=20of=20https://gitee.com/hxling/farris-vue=20*=20f?= =?UTF-8?q?ix:=20notitfy=20=E6=B7=BB=E5=8A=A0=E6=B7=A1=E5=85=A5=E6=95=88?= =?UTF-8?q?=E6=9E=9C=20*=20feature:=20lookup=E6=94=AF=E6=8C=81=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E5=A4=B9=20*=20Merge=20branch=20'lookup-bug-fix'=20in?= =?UTF-8?q?to=20main2=20*=20feature:=20modal=E6=89=93=E5=BC=80=E6=97=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B7=A1=E5=85=A5=E6=B7=A1=E5=87=BA=E6=95=88?= =?UTF-8?q?=E6=9E=9C=20*=20fix:=20modal=E6=9C=80=E5=A4=A7=E5=8C=96?= =?UTF-8?q?=E5=90=8E=E7=A6=81=E6=AD=A2=E7=A7=BB=E5=8A=A8=20*=20fix:=20moda?= =?UTF-8?q?l=E6=9C=80=E5=A4=A7=E5=8C=96=E5=90=8E=E7=A6=81=E6=AD=A2?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=20*=20fix:=20lookup=E5=9B=9E=E8=BD=A6?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=BC=98=E5=8C=96=20*=20fix:=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=98=A0=E5=B0=84=E7=BC=96=E8=BE=91=E5=99=A8=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=91=BD=E5=90=8D=E6=9B=B4=E6=96=B0=20*=20fix:=20look?= =?UTF-8?q?up=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86=20*=20Merge=20branch=20'?= =?UTF-8?q?lookup-bug-fix'=20*=20fix:=20lookup=E7=BB=84=E4=BB=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86=20*?= =?UTF-8?q?=20fix:=20=E6=95=B0=E6=8D=AE=E6=98=A0=E5=B0=84=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=99=A8=E5=8F=96=E6=95=B0=E4=BC=98=E5=8C=96=20*=20fi?= =?UTF-8?q?x:=20=E6=95=B0=E6=8D=AE=E6=98=A0=E5=B0=84=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E6=8F=90=E4=BA=A4=E6=95=B0=E6=8D=AE=E6=97=B6=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E6=95=B0=E6=8D=AE=E5=AE=8C=E6=95=B4=E6=80=A7=20*=20fi?= =?UTF-8?q?x:=20=E6=95=B0=E6=8D=AE=E6=98=A0=E5=B0=84=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=B0=E5=BD=95=E5=9C=A8=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=9C=80=E5=90=8E=E8=BF=BD=E5=8A=A0=20*=20fi?= =?UTF-8?q?x:=20response-toolbar=E5=B7=B2=E7=9F=A5=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20*=20fix:=20lookup=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D=20*=20fi?= =?UTF-8?q?x:=20lookup=E5=88=86=E9=A1=B5=E7=9B=B8=E5=85=B3=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=20*=20fix:=20lookup=E5=8F=8C?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=97=B6=E5=B7=A6=E4=BE=A7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E6=97=A0=E6=B3=95=E5=8A=A0=E8=BD=BD=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=20*=20fix:=20lookup=E5=80=BC=E5=8F=98=E5=8C=96?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E8=A7=A6=E5=8F=91=E6=97=B6=E6=9C=BA=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20*=20fix:=20=E4=BF=AE=E5=A4=8Dlookup=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E5=AD=97=E6=AE=B5=E5=A4=B1=E6=95=88=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20*=20fix:=20=E4=BF=AE=E5=A4=8D=E5=AD=97=E6=AE=B5=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E7=BB=84=E4=BB=B6=E4=B8=80=E4=BA=9B=E5=B7=B2=E7=9F=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20fix:=20lookup=20=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E5=B8=AE=E5=8A=A9=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE=E5=87=BA?= =?UTF-8?q?=E9=94=99=EF=BC=9Bcombo-list=20=E6=98=93=E7=94=A8=E6=80=A7?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9B=20*=20feature:=20datagrid=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E7=BC=96=E8=BE=91=E9=9B=86=E6=88=90?= =?UTF-8?q?lookup=20=E7=BB=84=E4=BB=B6=20*=20fix:=20=E4=BF=AE=E5=A4=8Dlook?= =?UTF-8?q?up=20=E6=9F=A5=E8=AF=A2=E6=89=A7=E8=A1=8C=E4=B8=A4=E6=AC=A1?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=20*=20chore:=20merge=20*=20fix:=20=E6=A0=91?= =?UTF-8?q?=E8=A1=A8=E9=87=8D=E6=96=B0=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=90=8E=E6=BB=9A=E5=8A=A8=E6=9D=A1=E9=87=8D=E7=BD=AE=20*=20Me?= =?UTF-8?q?rge=20branch=20'lookup'=20*=20Merge=20branch=20'main'=20of=20ht?= =?UTF-8?q?tps://gitee.com/hxling/farris-vue=20*=20fix:=20=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20*=20fix:=20=E4=BC=98=E5=8C=96=E5=88=97=E8=A1=A8=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8A=A0=E8=BD=BD=20*=20fix:=20=E6=A0=91=E8=A1=A8?= =?UTF-8?q?=E5=A4=A7=E6=95=B0=E6=8D=AE=E9=87=8F=E4=B8=8B=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E6=8B=96=E5=8A=A8=E6=BB=9A=E5=8A=A8=E6=9D=A1=E5=90=8E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=97=A0=E6=B8=B2=E6=9F=93=20*=20fix:=20datagrid?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E9=87=8D=E6=96=B0=E5=8A=A0=E8=BD=BD=E9=87=8D?= =?UTF-8?q?=E7=BD=AE=E6=BB=9A=E5=8A=A8=E6=9D=A1=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui-vue/components/modal/src/modal.component.tsx | 6 ++++-- packages/ui-vue/components/modal/src/modal.props.ts | 3 ++- .../schema-selector/src/components/list-view.component.tsx | 2 +- .../schema-selector/src/schema-selector.component.tsx | 2 +- .../components/schema-selector/src/schema-selector.css | 7 +++++++ 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/ui-vue/components/modal/src/modal.component.tsx b/packages/ui-vue/components/modal/src/modal.component.tsx index 2f385c7a4b2..858cbbd0f4c 100644 --- a/packages/ui-vue/components/modal/src/modal.component.tsx +++ b/packages/ui-vue/components/modal/src/modal.component.tsx @@ -200,12 +200,14 @@ export default defineComponent({ }); const modalBodyClass = computed(() => { - const classObject = { 'modal-body': true, 'f-utils-flex-column': dialogType.value === 'iframe' }; + const classObject = { 'modal-body': true, 'f-utils-flex-column': dialogType.value === 'iframe', 'f-utils-fill': true }; return classObject; }); function buildFooterStyles(): Record { - return {}; + return { + height: `${props.footerHeight || 60}px` + }; } const modalFooterStyle = computed(() => { diff --git a/packages/ui-vue/components/modal/src/modal.props.ts b/packages/ui-vue/components/modal/src/modal.props.ts index aa3f111fb01..2a468729177 100644 --- a/packages/ui-vue/components/modal/src/modal.props.ts +++ b/packages/ui-vue/components/modal/src/modal.props.ts @@ -79,7 +79,8 @@ export const modalProps = { enableEsc: { type: Boolean, default: true }, enableEnter: { type: Boolean, default: false }, dialogType: { type: String, default: '' }, - src: { type: String, default: '' } + src: { type: String, default: '' }, + footerHeight: { type: Number, default: 60 } }; export type ModalProps = Partial>; diff --git a/packages/ui-vue/components/schema-selector/src/components/list-view.component.tsx b/packages/ui-vue/components/schema-selector/src/components/list-view.component.tsx index 97dfa39fcd0..0d6b046786d 100644 --- a/packages/ui-vue/components/schema-selector/src/components/list-view.component.tsx +++ b/packages/ui-vue/components/schema-selector/src/components/list-view.component.tsx @@ -86,7 +86,7 @@ export default defineComponent({ } return () => { - return ( selectionChangeEventHandler(event)}> {{ content: renderListViewContent, diff --git a/packages/ui-vue/components/schema-selector/src/schema-selector.component.tsx b/packages/ui-vue/components/schema-selector/src/schema-selector.component.tsx index 0742de4679e..12c3922b5b5 100644 --- a/packages/ui-vue/components/schema-selector/src/schema-selector.component.tsx +++ b/packages/ui-vue/components/schema-selector/src/schema-selector.component.tsx @@ -55,7 +55,7 @@ export default defineComponent({ editorParams: props.editorParams, pagination: viewOption.pagination || false }; - return + return onSchemaSelect($event)}> ; } diff --git a/packages/ui-vue/components/schema-selector/src/schema-selector.css b/packages/ui-vue/components/schema-selector/src/schema-selector.css index 11960d5934c..266e53a209b 100644 --- a/packages/ui-vue/components/schema-selector/src/schema-selector.css +++ b/packages/ui-vue/components/schema-selector/src/schema-selector.css @@ -351,4 +351,11 @@ border-radius: 0 8px 0 0px; flex-direction: column; padding-bottom: 1px; +} + +.f-schema-selector .farris-tabs-content { + flex-shrink: 1; + flex-grow: 1; + flex-basis: 0; + overflow: hidden; } \ No newline at end of file -- Gitee From acd062df436f71ebd7b7cceac38ece43cb926786 Mon Sep 17 00:00:00 2001 From: Sagi Date: Mon, 17 Feb 2025 12:32:59 +0000 Subject: [PATCH 13/13] =?UTF-8?q?!1293=20=E5=9B=9E=E6=BB=9A=E5=88=86?= =?UTF-8?q?=E6=94=AF=20*=20Revert=20"Merge=20branch=20'v1.4.0'=20of=20gite?= =?UTF-8?q?e.com:ubml/farris-vue=20into=20main"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lerna.json | 3 +- package.json | 3 +- .../src/composition/class/file.service.ts | 4 +- .../lib/render-engine.service.ts | 36 +-- .../command-services/lib/template.service.ts | 2 +- packages/designer/farris.config.mjs | 2 +- .../components/code-tabs.component.tsx | 7 +- .../code-view/components/code-tabs.scss | 1 - .../components/code-view.component.tsx | 123 +--------- .../code-view/components/code-view.scss | 62 ----- .../components/editor-panels.component.tsx | 12 +- .../components/fields-getter.component.tsx | 137 ----------- .../components/nav-tree.component.tsx | 64 +---- .../composition/entity/metadata-generator.ts | 29 --- .../handler/class-nav-tree.service.ts | 161 ------------- .../composition/handler/editor.controller.ts | 35 +-- .../composition/handler/field-getter.tsx | 34 --- .../composition/handler/frm-cmp-builder.ts | 208 ---------------- .../handler/nav-data-util.service.ts | 2 +- .../handler/tree-data-source.service.ts | 43 +++- .../composition/type/fields-getter.ts | 20 -- .../composition/type/nav/common-file.ts | 100 -------- .../composition/type/nav/node-icon.ts | 21 -- .../code-view/composition/utils/valid.ts | 22 -- .../code-view/props/code-view.props.ts | 2 +- .../code-view/props/fields-getter.props.ts | 29 --- .../code-view/props/nav-tree.props.ts | 3 +- .../form-designer/form-designer.component.tsx | 9 +- .../composition/command-builder.service.ts | 4 +- .../composition/metadata.service.ts | 6 +- .../components/composition/use-form-schema.ts | 3 +- .../src/components/designer.component.tsx | 34 +-- .../designer/src/components/types/metadata.ts | 3 +- .../condition-value/dropdown-value.ts | 5 +- .../condition-value/input-group-value.ts | 11 +- .../components/data/data-area.component.tsx | 2 +- .../data-grid/src/data-grid.component.tsx | 45 +--- .../data-grid-column.design.component.tsx | 18 +- .../sidebar/data-grid-sidebar.component.tsx | 1 + .../components/data-view/composition/types.ts | 4 - .../data-view/composition/use-selection.ts | 24 +- .../visualization/use-visual-data-cell.ts | 18 +- .../designer/date-picker.design.component.tsx | 2 +- .../src/designer-canvas.component.tsx | 7 +- .../drawer/src/drawer.component.tsx | 2 +- .../components/drawer/src/drawer.props.ts | 2 - .../dynamic-form-group.design.component.tsx | 23 +- .../dynamic-form-group.props.ts | 3 +- .../dynamic-form-label.component.tsx | 18 +- .../dynamic-form-label.props.ts | 4 +- .../form-binding-resolver-design.ts | 70 ------ .../src/dynamic-view.component.tsx | 33 +-- .../src/components/drawer.component.tsx | 49 ---- .../filter-item-condition.component.tsx | 76 ------ .../filter-item-condition.props.ts | 11 - .../src/components/filter-item.component.tsx | 55 +++++ .../filter-item/filter-item.component.tsx | 91 ------- .../filter-item/filter-item.props.ts | 13 - ...ar.component.tsx => toolbar-component.tsx} | 26 +- .../filter-bar/src/composition/types.ts | 4 - .../src/composition/use-condition.ts | 201 ---------------- .../src/composition/use-filter-items.ts | 92 ++++--- .../designer/filter-bar.design.component.tsx | 8 +- .../filter-bar/src/filter-bar.component.tsx | 20 +- .../ui-vue/components/filter-bar/src/types.ts | 11 +- .../composition/entity/input-base-property.ts | 5 +- packages/ui-vue/demos/filter-bar/basic.vue | 225 +----------------- .../ui-vue/docs/components/data-grid/index.md | 14 -- 68 files changed, 315 insertions(+), 2102 deletions(-) delete mode 100644 packages/designer/src/components/components/code-view/components/fields-getter.component.tsx delete mode 100644 packages/designer/src/components/components/code-view/composition/entity/metadata-generator.ts delete mode 100644 packages/designer/src/components/components/code-view/composition/handler/class-nav-tree.service.ts delete mode 100644 packages/designer/src/components/components/code-view/composition/handler/field-getter.tsx delete mode 100644 packages/designer/src/components/components/code-view/composition/handler/frm-cmp-builder.ts delete mode 100644 packages/designer/src/components/components/code-view/composition/type/fields-getter.ts delete mode 100644 packages/designer/src/components/components/code-view/composition/type/nav/common-file.ts delete mode 100644 packages/designer/src/components/components/code-view/composition/type/nav/node-icon.ts delete mode 100644 packages/designer/src/components/components/code-view/props/fields-getter.props.ts delete mode 100644 packages/ui-vue/components/dynamic-form/src/composition/form-binding-resolver-design.ts delete mode 100644 packages/ui-vue/components/filter-bar/src/components/drawer.component.tsx delete mode 100644 packages/ui-vue/components/filter-bar/src/components/filter-item-condition/filter-item-condition.component.tsx delete mode 100644 packages/ui-vue/components/filter-bar/src/components/filter-item-condition/filter-item-condition.props.ts create mode 100644 packages/ui-vue/components/filter-bar/src/components/filter-item.component.tsx delete mode 100644 packages/ui-vue/components/filter-bar/src/components/filter-item/filter-item.component.tsx delete mode 100644 packages/ui-vue/components/filter-bar/src/components/filter-item/filter-item.props.ts rename packages/ui-vue/components/filter-bar/src/components/{toolbar.component.tsx => toolbar-component.tsx} (62%) delete mode 100644 packages/ui-vue/components/filter-bar/src/composition/use-condition.ts diff --git a/lerna.json b/lerna.json index 4b81ee2440b..b425e227e27 100644 --- a/lerna.json +++ b/lerna.json @@ -8,8 +8,7 @@ "packages/ui-vue", "packages/mobile-ui-vue", "packages/devkit", - "packages/designer", - "packages/code-editor" + "packages/designer" ], "version": "0.0.0", "useWorkspaces": true, diff --git a/package.json b/package.json index ecc4e9185de..6da5b25e547 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,7 @@ "build:renderer": "pnpm --filter renderer run build:system", "build:ui-vue": "pnpm --filter ui-vue run build:lib && pnpm --filter ui-vue run build:system", "build:designer": "pnpm --filter designer run build:system", - "build:code-editor-vue": "pnpm --filter code-editor-vue run build:system", - "build:system": "pnpm run-s build:ui-vue build:devkit-vue build:bef-vue build:command-services-vue build:ui-binding-vue build:renderer build:designer build:code-editor-vue" + "build:system": "pnpm run-s build:ui-vue build:devkit-vue build:bef-vue build:command-services-vue build:ui-binding-vue build:renderer build:designer" }, "engines": { "node": ">=18", diff --git a/packages/code-editor/components/command-code-view/src/composition/class/file.service.ts b/packages/code-editor/components/command-code-view/src/composition/class/file.service.ts index 25c9cd63487..34c6182f618 100644 --- a/packages/code-editor/components/command-code-view/src/composition/class/file.service.ts +++ b/packages/code-editor/components/command-code-view/src/composition/class/file.service.ts @@ -102,8 +102,8 @@ export class FileService { * @returns 是否成功 */ createTsFile(content: string, fullPath: string): Promise { - const url = API_TS_FILE + '/create?path=' + fullPath+'&formType=Vue'; - return axios.post(url, {}) + const url = API_TS_FILE + '/create?path=' + fullPath; + return axios.post(url, {formType:'Vue'}) .then(() => { if (typeof content === 'string') { return this.saveTsFile(content, fullPath); diff --git a/packages/command-services/lib/render-engine.service.ts b/packages/command-services/lib/render-engine.service.ts index da752d53020..07a32cb0e2f 100644 --- a/packages/command-services/lib/render-engine.service.ts +++ b/packages/command-services/lib/render-engine.service.ts @@ -12,25 +12,9 @@ export class RenderEngineService { public getComponentById(componentId: string) { return this.renderEngine.getComponentById(componentId); } - /** - * 更新组件schema - * @param componentId 组件标识 - * @param partialSchema - */ - public setSchema(componentId: string, partialSchema: Record) { - this.renderEngine.setSchema(componentId, partialSchema); - } - /** - * 获取组件schema - * @param componentId 组件标识 - * @returns - */ - public getSchema(componentId: string) { - return this.renderEngine.getSchema(componentId); - } /** * 更新组件属性 - * @param componentId 组件标识 + * @param componentId * @param props */ public setProps(componentId: string, props: Record) { @@ -38,10 +22,26 @@ export class RenderEngineService { } /** * 获取组件属性 - * @param componentId 组件标识 + * @param componentId * @returns */ public getProps(componentId: string) { return this.renderEngine.getProps(componentId); } + /** + * 更新组件schema + * @param componentId + * @param schema + */ + public setSchema(componentId: string, schema: Record) { + this.renderEngine.setSchema(componentId, schema); + } + /** + * 获取组件schema + * @param componentId + * @returns + */ + public getSchema(componentId: string) { + return this.renderEngine.getSchema(componentId); + } } \ No newline at end of file diff --git a/packages/command-services/lib/template.service.ts b/packages/command-services/lib/template.service.ts index f8cbd69c35e..e9c1bb9015a 100644 --- a/packages/command-services/lib/template.service.ts +++ b/packages/command-services/lib/template.service.ts @@ -14,7 +14,7 @@ export class TemplateService { parent: this.viewModel.getParent() }; return (cell: any, data: any) => { - return createVNode({ render: compiledTemplate, props: ['rowData', 'viewModel'] }, { viewModel, rowData: data.raw }); + return createVNode({ render: compiledTemplate, props: ['rowData', 'viewModel'] }, { viewModel, rowData: data }); }; } } \ No newline at end of file diff --git a/packages/designer/farris.config.mjs b/packages/designer/farris.config.mjs index 65e95d7813f..fab0811a566 100644 --- a/packages/designer/farris.config.mjs +++ b/packages/designer/farris.config.mjs @@ -57,7 +57,7 @@ export default { plugins: [replaceUIVueComponentsPath()] }, manifest: false, - minify: false, + minify: 'terser', terserOptions: { compress: { keep_classnames: true, diff --git a/packages/designer/src/components/components/code-view/components/code-tabs.component.tsx b/packages/designer/src/components/components/code-view/components/code-tabs.component.tsx index c1f65f91544..444ef374681 100644 --- a/packages/designer/src/components/components/code-view/components/code-tabs.component.tsx +++ b/packages/designer/src/components/components/code-view/components/code-tabs.component.tsx @@ -44,8 +44,7 @@ export default defineComponent({ if (currentTab) { currentTab.active = false; context.emit('unselected', currentTab); - } - currentTab=tab; + } // 选中新的标签 tab.active = true; intoView(tab); @@ -104,9 +103,9 @@ export default defineComponent({ tabs.value = tabs.value.filter(n => n.id !== tabId); // 如果右侧存在标签页则优先打开右侧的,否则选中左侧的 if (tabs.value.length > index) { - selectTab(tabs.value[index]); + selectTab(tabs[index]); } else if (index - 1 > -1) { - selectTab(tabs.value[index - 1]); + selectTab(tabs[index - 1]); } } diff --git a/packages/designer/src/components/components/code-view/components/code-tabs.scss b/packages/designer/src/components/components/code-view/components/code-tabs.scss index f120412680a..d7887f6d443 100644 --- a/packages/designer/src/components/components/code-view/components/code-tabs.scss +++ b/packages/designer/src/components/components/code-view/components/code-tabs.scss @@ -66,7 +66,6 @@ $tab-item-text-color-active: #202D40; padding: 0; flex-wrap: nowrap; overflow: hidden; - display: inline-flex; } // 标签项 diff --git a/packages/designer/src/components/components/code-view/components/code-view.component.tsx b/packages/designer/src/components/components/code-view/components/code-view.component.tsx index 1b8b73ab654..afa0317b106 100644 --- a/packages/designer/src/components/components/code-view/components/code-view.component.tsx +++ b/packages/designer/src/components/components/code-view/components/code-view.component.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { computed, defineComponent, inject, onMounted, provide, ref, SetupContext, watch } from 'vue'; +import { computed, defineComponent, inject, provide, ref, SetupContext } from 'vue'; import { codeViewProps, CodeViewProps } from '../props/code-view.props'; import FNavTreeDesign from './nav-tree.component'; import { FSplitter, FSplitterPane, FNotifyService, FLoadingService } from '@farris/ui-vue/components'; @@ -23,9 +23,6 @@ import { EditorController } from '../composition/handler/editor.controller'; import FEditorPanelsDesign from './editor-panels.component'; import { throttle } from 'lodash-es'; import { CommonEvent } from '../composition/event-bus/lib/event-bus'; -import { FrmCmpBuilder } from '../composition/handler/frm-cmp-builder'; -import { ClassNavTreeDataSource } from '../composition/handler/class-nav-tree.service'; -import { TreeDataSource } from '../composition/handler/tree-data-source.service'; export default defineComponent({ name: 'FCodeViewDesign', @@ -34,54 +31,22 @@ export default defineComponent({ setup(props: CodeViewProps, context: SetupContext) { const notifyService: any = new FNotifyService(); const loadingService: any = inject('FLoadingService'); - const frmCmpBuilder = new FrmCmpBuilder(); // 顶部标签页 const tabInstance = ref(); // 编辑器面板 const editorPanelsInstance = ref(); + const treeInstance = ref(); const editorController = new EditorController(); - // 文件导航树 - const fileTreeInstance = ref(); - const fileTreeDataSource = new TreeDataSource(); - // 类导航树 - const classTreeInstance = ref(); - // 类导航数据 - const classNavTreeDataSource = new ClassNavTreeDataSource(editorController); - const eventBusId = ref(editorController.getEventBusId()); const filePath = ref(''); provide('editorService', editorController); function switchViewChangeHandler(ev) { context.emit('changeView', 'designer'); } - function checkEntryFilePath(path: string) { - if (path.startsWith("/")) { return path; } - return '/' + path; - } - // 处理路径 - const entryFilePath = ref(checkEntryFilePath(props.entryFilePath)); function detectFileDirtyHandler(info) { - context.emit('detectFileDirty', info); + context.emit('detectFileDirty', info) } - // 初始化EditorController - editorController.init(tabInstance, editorPanelsInstance, fileTreeInstance, classTreeInstance, detectFileDirtyHandler); - // 赋值路径 - editorController.getContextService().setEntryFilePath(entryFilePath.value); - - watch(() => props.entryFilePath, (newValue) => { - entryFilePath.value = checkEntryFilePath(newValue); - editorController.getContextService().setEntryFilePath(entryFilePath.value); - }); - - onMounted(() => { - fileTreeInstance.value.setDataService(fileTreeDataSource); - classTreeInstance.value.setDataService(classNavTreeDataSource); - }); - - onMounted(() => { - fileTreeInstance.value.setDataService(fileTreeDataSource); - classTreeInstance.value.setDataService(classNavTreeDataSource); - }); + editorController.init(tabInstance, editorPanelsInstance, detectFileDirtyHandler); /** * 处理保存按钮点击事件 */ @@ -112,25 +77,18 @@ export default defineComponent({ ); } + function selectRowHandler(data) { + editorController.openFile(data.path); + filePath.value = data.path; + } - /** - * 刷新导航树 - * @param tsFilePath - */ function refreshNavTree(tsFilePath) { - fileTreeInstance.value.reloadTreeData(tsFilePath); + treeInstance.value.reloadTreeData(tsFilePath); } function open(path: string) { editorController.openFile(path); filePath.value = path; } - /** - * 点击文件导航树 - * @param data - */ - function selectFileNavRowHandler(data) { - open(data.path); - } function saveHandler(event) { event && event.stopPropagation(); throttle(() => { @@ -160,54 +118,6 @@ export default defineComponent({ function sendNotification(path: string, event: CommonEvent) { return editorController.sendNotification(path, event); } - async function executeCommand(command: string): Promise { - if (command === 'frm-file.refresh') { - fileTreeInstance.value.reloadTreeData(); - // editorController.detectChangesFromRoot(); - return; - } - if (command === 'frm-file.addWebCmp') { - const frmPath = editorController.getContextService().entryFilePath.value; - const result = await frmCmpBuilder.addNewCmp(frmPath); - if (!result) { - return; // 用户点击取消 - } - if (result.hasError) { - notifyService.error(result && result.errorTip || '构件创建失败,请刷新后重试'); - } else { - // 打开文件 - editorController.openFile(result.tsFilePath); - } - if (result.hasNewFile) { - fileTreeInstance.value.reloadTreeData(result.tsFilePath); - } - return; - } - } - function getFileNavHeaderHTML() { - return
- 文件导航 -
-
executeCommand("frm-file.refresh")}> - -
-
executeCommand("frm-file.addWebCmp")}> - -
-
-
- -
-
; - } - function getClassNavHeaderHTML() { - return
- 类导航 -
- -
-
; - } context.expose({ refreshNavTree, open, sendNotification }); return () => { @@ -224,25 +134,14 @@ export default defineComponent({
- - {/* 文件导航 */} - - {getFileNavHeaderHTML()} - selectFileNavRowHandler(data)}> - - {/* 类导航 */} -
- {getClassNavHeaderHTML()} - -
-
+ selectRowHandler(data)}>
- + ); }; } diff --git a/packages/designer/src/components/components/code-view/components/code-view.scss b/packages/designer/src/components/components/code-view/components/code-view.scss index dcd675ebd38..825785c24d6 100644 --- a/packages/designer/src/components/components/code-view/components/code-view.scss +++ b/packages/designer/src/components/components/code-view/components/code-view.scss @@ -111,66 +111,4 @@ $divider-image: linear-gradient(180deg, transparent 0%, rgba(40, 60, 93, .1) 23% .app-util-hide { display: none !important; -} - -$tool-bar-button-interval: 6px; - -.split-panel-header { - height: 44px; - cursor: pointer; - display: flex; - align-items: center; - z-index: 10; - padding: 0 15px; - - .split-panel-header--toolbar { - z-index: 1001; - margin-left: auto; - display: flex; - padding: 0px $tool-bar-button-interval 0 0; - - .toolbar-item { - display: flex; - align-items: center; - justify-content: center; - background-repeat: no-repeat; - color: #8592A6; - font-size: 1em; - margin-left: $tool-bar-button-interval; - cursor: pointer; - - &:hover { - background-color: #e9ecef; - color: #495057; - } - } - } - - .header-icon { - display: flex; - align-items: center; - justify-content: center; - color: #8592a6; - cursor: pointer; - overflow: hidden; - width: 24px; - height: 24px; - background-color: transparent; - border-radius: 4px; - - .f-icon { - font-size: 14px; - } - - &:hover { - background-color: #e9ecef; - color: #495057; - } - - &.header-icon--toggler { - .f-icon { - font-size: 18px; - } - } - } } \ No newline at end of file diff --git a/packages/designer/src/components/components/code-view/components/editor-panels.component.tsx b/packages/designer/src/components/components/code-view/components/editor-panels.component.tsx index d04f8e335fe..066deaa88a4 100644 --- a/packages/designer/src/components/components/code-view/components/editor-panels.component.tsx +++ b/packages/designer/src/components/components/code-view/components/editor-panels.component.tsx @@ -29,7 +29,7 @@ export default defineComponent({ const editorPanels = ref([] as any); /** 当前显示的文件路径 */ - const activePath=ref(''); + let activePath: string = ''; /** * 获取打开该文件所需的插件的地址 @@ -77,7 +77,7 @@ export default defineComponent({ if (!targetPanel) { return false; } - activePath.value = path; + activePath = path; return true; } @@ -97,17 +97,17 @@ export default defineComponent({ function close(path: string) { const idx = editorPanels.value.findIndex(panel => panel.path === path); if (idx >= 0) { - if (activePath.value === path) { - activePath.value = ''; + if (activePath === path) { + activePath = ''; } editorPanels.value.splice(idx, 1); } } - context.expose({ close, open, show }); + context.expose({close,open}) return () => { return (editorPanels.value.map(frame => ( -
+
)) diff --git a/packages/designer/src/components/components/code-view/components/fields-getter.component.tsx b/packages/designer/src/components/components/code-view/components/fields-getter.component.tsx deleted file mode 100644 index afc1e646556..00000000000 --- a/packages/designer/src/components/components/code-view/components/fields-getter.component.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { defineComponent, SetupContext, onMounted, reactive, ref } from 'vue'; -import { fieldsGetterProps, FieldsGetterProps } from '../props/fields-getter.props'; - -export default defineComponent({ - name: 'FFieldsGetterDesign', - props: fieldsGetterProps, - emits: ['confirm', 'cancel'] as (string[] & ThisType) | undefined, - setup(props: FieldsGetterProps, context: SetupContext) { - /** 编辑中的字段值 */ - const data = {}; - /** 字段错误提示映射,如果为空则说明没有错误 */ - const fieldErrorMap = reactive({}); - /** 初始化各个字段 */ - function init(): void { - for (const field of props.fields) { - data[field.code] = ref(''); - fieldErrorMap[field.code] = ""; - } - } - init(); - /** 处理取消按钮点击事件 */ - function cancelHandler(reject: boolean = false): void { - context.emit('cancel'); - } - function handleFieldError(error: string, fieldCode: string): void { - fieldErrorMap[fieldCode] = error; - } - - function verifyFieldValue(field) { - let noError = true; - let required = false; - if (field.required) { - if (typeof field.required === 'function') { - required = field.required(data); - } else { - required = true; - } - } - if (required && !data[field.code].value) { - const errorInfo = `请填写${field.name}字段`; - handleFieldError(errorInfo, field.code); - noError = false; - } else { - handleFieldError("", field.code); - } - if (noError && field.validate && typeof field.validate === 'function') { - let error = null; - try { - error = field.validate(data[field.code].value); - } catch (err) { - console.error('参数检验时出错', err); - } - if (error) { - handleFieldError(error, field.code); - noError = false; - } else { - handleFieldError("", field.code); - } - } - return noError; - } - /** 处理确定按钮点击事件 */ - function confirmHandler(): void { - // 进行必填校验以及合法性检查 - let noError = true; - for (const field of props.fields) { - noError = verifyFieldValue(field); - } - if (noError) { - const result={}; - for(const fieldCode in data){ - result[fieldCode]=data[fieldCode].value; - } - context.emit('confirm', result); - } - } - function handleFieldChange(event, fieldCode: string): void { - const target = event.target as HTMLInputElement; - data[fieldCode].value = target.value; - const currentField = props.fields.find(item => item.code === fieldCode); - verifyFieldValue(currentField); - } - onMounted(() => { - - }); - - return () => { - return (
-
- {props.fields.map((field) => ( -
-
-
-
- {field.name} -
-
- handleFieldChange(event, field.code)} - /> -
- {fieldErrorMap[field.code]} -
-
-
-
-
- ))} -
- -
- ); - }; - } -}); diff --git a/packages/designer/src/components/components/code-view/components/nav-tree.component.tsx b/packages/designer/src/components/components/code-view/components/nav-tree.component.tsx index 181abeefe76..ba85c22a6f6 100644 --- a/packages/designer/src/components/components/code-view/components/nav-tree.component.tsx +++ b/packages/designer/src/components/components/code-view/components/nav-tree.component.tsx @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { defineComponent, ref, SetupContext, onMounted, watch } from 'vue'; +import { computed, defineComponent, inject, provide, ref, SetupContext, onMounted } from 'vue'; import { navTreeProps, NavTreeProps } from '../props/nav-tree.props'; -import { VisualData, VisualDataCell, FTreeView } from '@farris/ui-vue/components'; +import './code-view.scss'; +import { VisualData, VisualDataCell,FTreeView } from '@farris/ui-vue/components'; import { NavTreeNode } from '../composition/type/tree'; -import { CommonFileNavTreeDataService } from '../composition/type/nav/common-file'; -import { NavTreeNodeIconService } from '../composition/type/nav/node-icon'; +import { TreeDataSource } from '../composition/handler/tree-data-source.service'; export default defineComponent({ name: 'FNavTreeDesign', @@ -26,20 +26,9 @@ export default defineComponent({ emits: ['selectRow'] as (string[] & ThisType) | undefined, setup(props: NavTreeProps, context: SetupContext) { const treeGridInstance = ref(); - // 资源是否加载完成 - const loadedSource = ref(false); - /** - * 由文件路径到树节点Id的映射 - * @remarks 在导航树中可能存在多个文件路径相同的节点,所以需要记录右侧编辑器中的文件是由那个节点双击打开的 - */ - const path2IdMap = new Map(); - + const dataService = new TreeDataSource(); let currentId = ''; let treeData: any = []; - // 取数服务 - let dataService: CommonFileNavTreeDataService; - // 获取图标服务 - let iconService: NavTreeNodeIconService | undefined; const columns = [{ field: 'name', title: '', @@ -101,10 +90,7 @@ export default defineComponent({ return false; } // 优先通过路径标识映射获取对应标识 - let id = path2IdMap.get(path); - if (!id) { - id = getIdByPath(path); - } + const id = getIdByPath(path); if (id) { treeGridInstance.value?.selectItemById(id); currentId = id; @@ -124,7 +110,7 @@ export default defineComponent({ // ); // 如果数据服务或者根路径为空则直接清空树数据 if (props.entryFilePath) { - return dataService['getChildrenWithValidId'](props.entryFilePath).then((data) => { + return dataService.getChildrenWithValidId(props.entryFilePath).then((data) => { treeData = data; treeGridInstance.value?.updateDataSource(treeData); selectByPath(selectNodePath); @@ -139,41 +125,12 @@ export default defineComponent({ }); } } - /** - * 直接设置导航树数据和图标服务 - */ - function setDataService(dataSource: CommonFileNavTreeDataService,iconSource?: NavTreeNodeIconService): void { - dataService = dataSource; - iconService = iconSource; - // 注册刷新导航树数据回调函数,让数据服务可以通过该方法控制导航树何时刷新数据 - if (dataService) { - dataService['refreshNavTreeCallback'] = async () => { - await reloadTreeData(); - }; - } - loadedSource.value = true; - } - // 监听资源加载 - watch(loadedSource, () => { - reloadTreeData(); - }); - onMounted(() => { - if (dataService) { - loadedSource.value = true; - reloadTreeData(); - } + reloadTreeData(); }); function clickRowHandler(item) { // 仅支持打开TS - if (!dataService || item.path.indexOf('.webcmd') > -1 || item.path.indexOf('.webcmp') > -1) { - return; - } - const { data } = item; - // 执行服务自定义节点双击处理回调 - const toOpenFile = dataService.handleDblClick(item); - if (toOpenFile && data.canOpen) { - path2IdMap.set(data.path, data.id); + if (item.path.indexOf('.ts') > -1) { context.emit('selectRow', item); } } @@ -181,8 +138,7 @@ export default defineComponent({ function setIcon(): void { } - - context.expose({ reloadTreeData, setDataService,selectByPath }); + context.expose({ reloadTreeData }); return () => { return ( diff --git a/packages/designer/src/components/components/code-view/composition/entity/metadata-generator.ts b/packages/designer/src/components/components/code-view/composition/entity/metadata-generator.ts deleted file mode 100644 index 48d8a5be809..00000000000 --- a/packages/designer/src/components/components/code-view/composition/entity/metadata-generator.ts +++ /dev/null @@ -1,29 +0,0 @@ -export class MetadataDto { - id: string; - nameSpace: string; - code: string; - name: string; - fileName: string; - type: string; - bizobjectID: string; - relativePath: string; - extendProperty: string; - content: string; - extendable: boolean; - nameLanguage:Record; - constructor(id: string, nameSpace: string, code: string, name: string, fileName: string, type: string, bizobjectID: string, relativePath: string, extendProperty: string, content: string, extendable: boolean, nameLanguage= {}) { - this.id = id; - this.nameSpace = nameSpace; - this.code = code; - this.name = name; - this.fileName = fileName; - this.type = type; - this.bizobjectID = bizobjectID; - this.relativePath = relativePath; - this.extendProperty = extendProperty; - this.content = content; - this.extendable = extendable; - this.nameLanguage = nameLanguage; - - } -} diff --git a/packages/designer/src/components/components/code-view/composition/handler/class-nav-tree.service.ts b/packages/designer/src/components/components/code-view/composition/handler/class-nav-tree.service.ts deleted file mode 100644 index 793cbd31bd3..00000000000 --- a/packages/designer/src/components/components/code-view/composition/handler/class-nav-tree.service.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { CodeLocationInfo, CodeOutlineInfo, IClass, IMethod } from "../type/code-outline"; -import { CommonFileNavTreeDataService } from "../type/nav/common-file"; -import { EditorEventType } from "../type/editor-event"; -import { NavTreeNode } from "../type/tree"; -import { EditorController } from "./editor.controller"; - -const ICON_CLASS = "nav-treenode-icon nav-treenode-icon--outline_class"; -const ICON_METHOD = "nav-treenode-icon nav-treenode-icon--outline_method"; - -/** 类视图导航数据服务 */ - -export class ClassNavTreeDataSource extends CommonFileNavTreeDataService { - - /** 由打开页签的文件路径到其代码大纲导航树数据的映射 */ - private mainPath2OutlineData = new Map(); - - /** 用于生成递增的节点id序列号 */ - private counter = 0; - constructor(editorController: EditorController) { - super(); - this.editorController = editorController; - this.afterPropertySet(); - } - afterPropertySet(): void { - this.subscribeOuterEvent(); - } - - private subscribeOuterEvent(): void { - const eventBus = this.editorController?.eventBus; - // 订阅代码大纲变化事件,维护大纲数据映射(新增或更新条目) - eventBus?.subscribe(EditorEventType.CodeOutlineChanged, (info: CodeOutlineInfo) => { - this.handleCodeOutlineChanged(info); - }, this); - // 订阅当前标签页切换事件,在当前页签变更时,通知导航树组件刷新数据 - eventBus?.subscribe(EditorEventType.TabSelected, () => { - this.handleTabSelected(); - }, this); - // 订阅标签页关闭事件,当文件关闭时,维护大纲数据映射(删除对应的条目) - eventBus?.subscribe(EditorEventType.CloseFile, (path: string) => { - this.handleCloseFile(path); - }, this); - } - - private handleCodeOutlineChanged(info: CodeOutlineInfo): void { - if (!info || !info.path || !info.classes) { - return; - } - const treeData = this.mapIClass2TreeData(info.classes, info.path); - this.mainPath2OutlineData.set(info.path, treeData); - this.handleTabSelected(); - } - - private handleTabSelected(): void { - if (this.refreshNavTreeCallback && typeof this.refreshNavTreeCallback === 'function') { - this.refreshNavTreeCallback(); - } - } - - private handleCloseFile(path: string): void { - if (!!path && this.mainPath2OutlineData.has(path)) { - this.mainPath2OutlineData.delete(path); - } - this.handleTabSelected(); - } - - /** - * 将类结构信息转化为大纲树节点数据 - * @remarks 同时在此处完成图标样式类的指定 - */ - private mapIClass2TreeData(classes: IClass[], path: string): NavTreeNode[] { - this.counter = 0; - const nodes = [] as any; - for (const _class of classes) { - const newClassNode = this.createClassNode(_class, path); - if (_class.methods) { - for (const _method of _class.methods) { - const newMethodNode = this.createMethodNode(_class, _method, path); - newClassNode.children?.push(newMethodNode); - } - } - nodes.push(newClassNode); - } - return nodes; - } - private createClassNode(_class: IClass, path: string): NavTreeNode { - const serialNumber = ++this.counter; - const id = `${path}_${_class.code}_${serialNumber}`; - return { - id, - data: { - id, - name: _class.code, - path, - canOpen: false, - icon: ICON_CLASS, - appendInfo: { - className: _class.code - } as CodeLocationInfo - }, - icon: ICON_CLASS, - expandedIcon: ICON_CLASS, - collapsedIcon: ICON_CLASS, - children: [], - expanded: true, - leaf: false - }; - } - private createMethodNode(_class: IClass, _method: IMethod, path: string): NavTreeNode { - const serialNumber = ++this.counter; - const id = `${path}_${_class.code}_${_method.code}_${serialNumber}`; - return { - id, - data: { - id, - name: _method.code, - path, - canOpen: false, - icon: ICON_METHOD, - appendInfo: { - className: _class.code, - methodName: _method.code - } as CodeLocationInfo - }, - icon: ICON_METHOD, - expandedIcon: ICON_METHOD, - collapsedIcon: ICON_METHOD, - children: [], - expanded: false, - leaf: true - }; - } - - enableLayeredLoading(): boolean { - return false; - } - - getChildren(): Promise { - const empty = Promise.resolve([]); - const contextService = this.editorController?.getContextService(); - if (contextService) { - const curPath = contextService.currentFileItem && contextService.currentFileItem.mainPath; - if (!curPath) { // 当前文件已被关闭,暂无数据 - return empty; - } - const treeData = this.mainPath2OutlineData.get(curPath); - if (treeData) { - return Promise.resolve(treeData); - } - } - return empty; - } - - handleDblClick(node: NavTreeNode): boolean { - // 通过事件总线将大纲定位信息发送给对应的页签,通知其定位代码 - if (!!node && !!node.data && !!node.data.appendInfo) { - this.editorController?.eventBus.emit(EditorEventType.CodeOutlineLocateRequest, node.data.appendInfo, node.data.path); - } - return false; - } - -} \ No newline at end of file diff --git a/packages/designer/src/components/components/code-view/composition/handler/editor.controller.ts b/packages/designer/src/components/components/code-view/composition/handler/editor.controller.ts index 0fda0a0ccc2..16c956f371b 100644 --- a/packages/designer/src/components/components/code-view/composition/handler/editor.controller.ts +++ b/packages/designer/src/components/components/code-view/composition/handler/editor.controller.ts @@ -24,8 +24,6 @@ export class EditorController { // 标签页 tabs: any; editors: any; - fileNavTree: any; - classNavTree: any; messageService: any; notifyService: any; eventBusHandler: EventBusHandler; @@ -51,23 +49,16 @@ export class EditorController { public getEventBusId(): string { return this.eventBusHandler.eventBusId; } - public getContextService(): ContextService { - return this.context; - } /** - * 初始化 - * @param tabInstanceRef - * @param editorPanelsInstanceRef - * @param fileNavTreeInstanceRef - * @param classNavTreeInstanceRef - * @param detectFileDirtyHandler + * 初始化中央控制器 + * @param root 代码编辑器根组件 + * @param tabs 标签页组件 + * @param editor 中心编辑器组件 */ - public init(tabInstanceRef: any, editorPanelsInstanceRef: any, fileNavTreeInstanceRef: any, classNavTreeInstanceRef: any, detectFileDirtyHandler): void { + public init(tabInstanceRef: any, editorPanelsInstanceRef: any, detectFileDirtyHandler): void { this.tabs = tabInstanceRef; this.editors = editorPanelsInstanceRef; this.detectFileDirtyHandler = detectFileDirtyHandler; - this.fileNavTree = fileNavTreeInstanceRef; - this.classNavTree = classNavTreeInstanceRef; // 订阅内部和外部事件 this.subscribeOuterEvent(); } @@ -110,10 +101,6 @@ export class EditorController { // this.root.detectChanges(); } }, this); - this.eventBus.subscribe(EditorEventType.TabSelected, (path: string) => { - this.fileNavTree?.value?.selectByPath(path); - this.classNavTree?.value?.selectByPath(path); - }, this); } /** * 处理标签页选中事件 @@ -290,14 +277,12 @@ export class EditorController { /** 直接关闭文件 */ private directCloseFile(item: FileItem) { if (this.context.removeFile(item.mainPath)) { - const { mainPath } = item; - this.eventBus.emit(EditorEventType.CloseFile, mainPath, mainPath); - this.tabs.value.removeTab(mainPath); - this.editors.value.close(mainPath); - this.eventBus.clearNotificationQueue(mainPath); - this.eventBus.clearSaveCallback(mainPath); + const token = item.mainPath; + this.tabs.value.removeTab(token); + this.editors.value.close(token); + // 当文件关闭时,需要将当前文件路径也设置为空 - if (this.context.currentFileItem && this.context.currentFileItem.mainPath === mainPath) { + if (this.context.currentFileItem && this.context.currentFileItem.mainPath === token) { this.context.currentFilePath = ''; } } diff --git a/packages/designer/src/components/components/code-view/composition/handler/field-getter.tsx b/packages/designer/src/components/components/code-view/composition/handler/field-getter.tsx deleted file mode 100644 index b1b8202c16a..00000000000 --- a/packages/designer/src/components/components/code-view/composition/handler/field-getter.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FModalService, F_MODAL_SERVICE_TOKEN } from "@farris/ui-vue/components"; -import { inject } from "vue"; -import FFieldsGetterDesign from "../../components/fields-getter.component"; - -/** 用于新增前端控制器构件 */ -export function fieldGetterController() { - - const modalService: FModalService | null = inject(F_MODAL_SERVICE_TOKEN, null); - - async function getFields(title, fields, width, height) { - let resolveFunc: (value: any) => void; - let rejectFunc: (reason?: any) => void; - let myModal: any = null; - const result = new Promise((resolve, reject) => { - resolveFunc = resolve; - rejectFunc = reject; - }); - function resultHandler(state, data) { - state ? resolveFunc(data) : rejectFunc(data); - myModal?.destroy(); - } - myModal = modalService?.open({ - fitContent: false, - width: width, - height: height, - title: title, - showButtons: false, - render: () => ( resultHandler(true, data)} onCancel={() => resultHandler(false, {})}>) - }); - return result; - } - - return { getFields }; -} diff --git a/packages/designer/src/components/components/code-view/composition/handler/frm-cmp-builder.ts b/packages/designer/src/components/components/code-view/composition/handler/frm-cmp-builder.ts deleted file mode 100644 index b41ed994a63..00000000000 --- a/packages/designer/src/components/components/code-view/composition/handler/frm-cmp-builder.ts +++ /dev/null @@ -1,208 +0,0 @@ - -import axios from "axios"; -import { MetadataDto } from "../entity/metadata-generator"; -import { checkCode, checkName } from "../utils/valid"; -import { FieldOption } from "../type/fields-getter"; -import { MetadataService } from "../../../../composition/metadata.service"; -import { NavDataUtilService } from "./nav-data-util.service"; -import { fieldGetterController } from "./field-getter"; - -/** 新建前端构件的结果 */ -export interface CmpBuildResult { - /** ts文件路径,用于在代码视图中直接打开新构件 */ - tsFilePath: string; - /** 是否新增了文件,如果是则需要刷新导航树 */ - hasNewFile: boolean; - /** 是否存在错误,默认不存在 */ - hasError?: boolean; - /** 错误提示信息 */ - errorTip?: string; -} -/** 构件元数据基本信息 */ -interface CmpBuildInfo { - code: string; - name: string; - namespace: string; - bizObjId: string; - relativePath: string; - extendProperty: any; - tsFilePathName: string; -} - -/** 用于新增前端控制器构件 */ -export class FrmCmpBuilder { - metadataService: MetadataService; - navDataUtilService: NavDataUtilService; - fieldGetter; - constructor() { - this.metadataService = new MetadataService(); - this.navDataUtilService = new NavDataUtilService(); - this.fieldGetter = fieldGetterController(); - } - /** - * 弹框新增一个前端控制器构件 - * @param frmPath 表单元数据地址 - * @returns 新建结果,为空则表示用户点击了取消 - */ - async addNewCmp(frmPath: string): Promise { - const fields: FieldOption[] = [{ - code: 'code', - name: '构件编号', - placeholder: '可选,默认为“Controller”,需遵守js变量名规则', - required: true, - validate: (value: string) => { - if (!value) { - return '请填写构件编号'; - } - const error = checkCode(value); - return error ? '编号' + error : ''; - } - }, { - code: 'name', - name: '构件名称', - required: true, - placeholder: '可选,默认与构件编号相同', - validate: (value: string) => { - if (!value) { - return '请填写构件名称'; - } - const error = checkName(value); - return error ? '名称' + error : ''; - } - }]; - const fieldsMap = await this.fieldGetter.getFields("新增前端构件", fields, 550, 220).catch(() => null); - if (fieldsMap) { - const code: string = fieldsMap.code || 'Controller'; - const name: string = fieldsMap.name || code; - return this.doAddNewCmp(code.trim(), name.trim(), frmPath); - } - return null; - } - - /** - * 直接新增一个前端控制器构件 - * @remarks 如果已经存在部分文件则进行补全 - * @param code 构件编号 - * @param name 构件名称 - * @param frmPath 表单元数据路径 - */ - async doAddNewCmp(code: string, name: string, frmPath: string): Promise { - // 获取表单元数据的编号和名称 - const frmMeta = await this.navDataUtilService.loadMetadata(frmPath).then((data) => data).catch(() => null); - if (!frmMeta) { - return { - hasError: true, - errorTip: '无法获取到对应的表单元数据,请刷新后重试', - tsFilePath: '', hasNewFile: false - }; - } - // 生成新的构件的基本信息 - const buildInfo: CmpBuildInfo = { - code: frmMeta.code + '_frm_' + code, - name: (frmMeta.name || frmMeta.code) + '_frm_' + name, - namespace: frmMeta.nameSpace, - bizObjId: frmMeta.bizobjectID, - relativePath: frmMeta.relativePath, - extendProperty: { IsCommon: false, FormCode: frmMeta.code }, - tsFilePathName: '' - }; - buildInfo.tsFilePathName = '/' + buildInfo.relativePath + '/' + buildInfo.code + '.ts'; - const webCmpFileName = buildInfo.code + '.webcmp'; - const webCmdFileName = buildInfo.code + '.webcmd'; - // 判断构件文件是否已经存在 - const notHasWebCmp$ = this.metadataService.validateRepeatName(frmMeta.relativePath, webCmpFileName) - .then(data => data) - .catch(() => undefined); - const notHasWebCmd$ = this.metadataService.validateRepeatName(frmMeta.relativePath, webCmdFileName) - .then(data => data) - .catch(() => undefined); - const [notHasWebCmp, notHasWebCmd] = await Promise.all([notHasWebCmp$, notHasWebCmd$]); - if (notHasWebCmp === undefined || notHasWebCmd === undefined) { - return { - hasError: true, - errorTip: '获取文件状态信息失败,请刷新后重试', - tsFilePath: '', hasNewFile: false - }; - } - if (!notHasWebCmp && !notHasWebCmd) { - return { tsFilePath: buildInfo.tsFilePathName, hasNewFile: false }; - } - const createWebCmpError = notHasWebCmp && (await this.createWebCmp(buildInfo)); - if (createWebCmpError) { - return { - hasError: true, - errorTip: createWebCmpError, - tsFilePath: '', hasNewFile: true - }; - } - const createWebCmdError = notHasWebCmd && (await this.createWebCmd(buildInfo)); - if (createWebCmdError) { - return { - hasError: true, - errorTip: createWebCmdError, - tsFilePath: '', hasNewFile: true - }; - } - return { tsFilePath: buildInfo.tsFilePathName, hasNewFile: true }; - } - - /** - * 新建一个前端服务构件 - * @param buildInfo 构件基本信息 - * @returns 错误信息,为空则表示创建成功 - */ - async createWebCmp(buildInfo: CmpBuildInfo): Promise { - const fileName = buildInfo.code + '.webcmp'; - const metadataDto = new MetadataDto( - '', buildInfo.namespace, buildInfo.code, buildInfo.name, fileName, 'WebComponent', - buildInfo.bizObjId, buildInfo.relativePath, JSON.stringify(buildInfo.extendProperty), '', false - ); - const initedDto = await this.metadataService.initializeMetadataEntity(metadataDto).then((data) => data).catch(() => null); - if (!initedDto) { - return '构件信息初始化失败,请刷新后重试'; - } - initedDto.fileName = metadataDto.fileName; - const webComponent = JSON.parse(initedDto.content); - webComponent.Source = buildInfo.relativePath + '/' + buildInfo.code + '.ts'; - initedDto.content = JSON.stringify(webComponent); - // 发送请求,创建元数据文件 - const createResult = await this.metadataService.createMetadata(initedDto).then((data) => data).catch(() => null); - if (!createResult || !createResult.ok) { - return '构件元数据文件创建失败,请刷新后重试'; - } - // 创建服务构件附带的ts文件 - const tsUrl = '/api/dev/main/v1.0/tsfile/create?path=' + buildInfo.tsFilePathName + '&formType=Vue'; - - try { - await axios.post(tsUrl, {}); - return ''; - } catch (error) { - console.error(error); - return 'ts文件创建失败,请刷新后重试'; - } - } - - /** - * 新建一个前端命令构件 - * @param buildInfo 构件基本信息 - * @returns 错误信息,为空则表示创建成功 - */ - async createWebCmd(buildInfo: CmpBuildInfo): Promise { - const fileName = buildInfo.code + '.webcmd'; - const metadataDto = new MetadataDto( - '', buildInfo.namespace, buildInfo.code, buildInfo.name, fileName, 'WebCommand', - buildInfo.bizObjId, buildInfo.relativePath, JSON.stringify(buildInfo.extendProperty), '', false - ); - const initedDto = await this.metadataService.initializeMetadataEntity(metadataDto).then((data) => data).catch(() => null); - if (!initedDto) { - return '构件信息初始化失败,请刷新后重试'; - } - initedDto.fileName = metadataDto.fileName; - const createResult = await this.metadataService.createMetadata(initedDto).then((data) => data).catch(() => null); - if (!createResult || !createResult.ok) { - return '构件元数据文件创建失败,请刷新后重试'; - } - return ''; - } - -} diff --git a/packages/designer/src/components/components/code-view/composition/handler/nav-data-util.service.ts b/packages/designer/src/components/components/code-view/composition/handler/nav-data-util.service.ts index 45957e3a662..84aa3be95cb 100644 --- a/packages/designer/src/components/components/code-view/composition/handler/nav-data-util.service.ts +++ b/packages/designer/src/components/components/code-view/composition/handler/nav-data-util.service.ts @@ -68,7 +68,7 @@ export class NavDataUtilService { public loadMetadata(path: string): Promise { const uri = path.replace(/\\/g, '/'); const fileName = uri.substring(uri.lastIndexOf('/') + 1); - const filePath = uri.substring(uri.startsWith('/') ? 1 : 0, uri.lastIndexOf('/')); + const filePath = uri.substring(1, uri.lastIndexOf('/')); return this.metadataService.loadMetadata(fileName, filePath); } diff --git a/packages/designer/src/components/components/code-view/composition/handler/tree-data-source.service.ts b/packages/designer/src/components/components/code-view/composition/handler/tree-data-source.service.ts index 09619e8a87d..00f08a4746b 100644 --- a/packages/designer/src/components/components/code-view/composition/handler/tree-data-source.service.ts +++ b/packages/designer/src/components/components/code-view/composition/handler/tree-data-source.service.ts @@ -3,17 +3,17 @@ import { MetadataDto } from "../../../../types"; import { NavTreeData, NavTreeNode } from "../type/tree"; import { MetadataType } from "../type/metadata"; import { NavDataUtilService } from "./nav-data-util.service"; +import { escapeTextForBrowser } from "../utils/escape"; import { getValidId } from "../utils/valid"; -import { CommonFileNavTreeDataService } from "../type/nav/common-file"; +const NODE_CONTENT_FIELD = 'CodeViewNav--ContentInnerHTML'; /** * 处理树绑定的数据 */ -export class TreeDataSource extends CommonFileNavTreeDataService{ +export class TreeDataSource{ private navDataUtilService; private idService; constructor() { - super(); this.navDataUtilService = new NavDataUtilService(); this.idService = new IdService(); } @@ -210,4 +210,41 @@ export class TreeDataSource extends CommonFileNavTreeDataService{ return cmps; } + public async getChildrenWithValidId(rootPath = ''): Promise { + return this.getChildren(rootPath).then((data) => { + const nodes = data; + for (const node of nodes) { + this.traverseTree(node, (n) => { + n.id = getValidId(n.id); + if (!n.data) { + return; + } + n.data.id = n.id; + const name = n.data && n.data.name || ''; + n.data[NODE_CONTENT_FIELD] = escapeTextForBrowser(name); + }); + } + return nodes; + }); + } + + /** + * 递归遍历树 + * @param node 树节点 + * @param handleNode 处理每一个树节点 + */ + private traverseTree( + node: NavTreeNode, + handleNode: (node: NavTreeNode) => void + ): void { + if (!node) { + return; + } + handleNode(node); + if (node.children && node.children.length > 0) { + for (const child of node.children) { + this.traverseTree(child, handleNode); + } + } + } } diff --git a/packages/designer/src/components/components/code-view/composition/type/fields-getter.ts b/packages/designer/src/components/components/code-view/composition/type/fields-getter.ts deleted file mode 100644 index 58bea25a1c0..00000000000 --- a/packages/designer/src/components/components/code-view/composition/type/fields-getter.ts +++ /dev/null @@ -1,20 +0,0 @@ - -export interface FieldOption { - /** 字段编号 */ - code: string; - - /** 字段名称 */ - name: string; - - /** 是否必填 */ - required?: boolean | ((data: any) => boolean); - - /** 是否隐藏 */ - hide?: boolean | ((data: any) => boolean); - - /** 提示信息 */ - placeholder?: string; - - /** 校验字段合法性,返回错误信息 */ - validate?: (value: any) => string; - } \ No newline at end of file diff --git a/packages/designer/src/components/components/code-view/composition/type/nav/common-file.ts b/packages/designer/src/components/components/code-view/composition/type/nav/common-file.ts deleted file mode 100644 index 52df7101a09..00000000000 --- a/packages/designer/src/components/components/code-view/composition/type/nav/common-file.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { EditorController } from "../../handler/editor.controller"; -import { escapeTextForBrowser } from "../../utils/escape"; -import { getValidId } from "../../utils/valid"; -import { NavTreeNode } from "../tree"; -const NODE_CONTENT_FIELD = 'CodeViewNav--ContentInnerHTML'; -/** - * 通用文件导航树 - 数据服务基类 - */ -export class CommonFileNavTreeDataService { - constructor() { } - - /** - * 刷新导航树数据 - * @remarks 子类可以通过调用本方法实现导航树刷新(afterPropertySet被调用后本属性可用) - */ - protected refreshNavTreeCallback?: () => void; - - /** - * 代码视图控制器实例 - * @remarks - * 提供导航树服务对标签页以及其它部件的控制能力(afterPropertySet被调用后本属性可用) - * afterPropertySet、getChildren、handleDblClick被调用时,该属性保证非空 - * 编写预置模板时该属性无效(preset-panel,直接通过依赖注入获取控制器实例即可) - */ - protected editorController?: EditorController; - - /** - * 属性设置完成后回调 - * @remarks - * 当editorController、refreshNavTreeCallback属性设置完成后本方法被调用 - * 如果需要在服务初始化时通过控制器的事件总线订阅一些消息,你需要覆盖本方法(本方法被调用之前,控制器实例可能为空) - */ - afterPropertySet(): void { } - - /** - * 是否启用分层加载 - * @remarks 如果不启用分层加载,则认为一次加载完所有节点 - */ - enableLayeredLoading(): boolean { - return false; - } - - /** - * 获取导航树的节点数据 - * @param rootPath 该导航树的根节点路径,例如:如果该导航树是表单元数据导航树,则该路径为表单元数据的路径 - * @param curPath 当前正要展开的节点的路径,启用分层加载时将会传递此参数 - */ - getChildren(rootPath?: string, curPath?: string): Promise { - return Promise.resolve([]); - } - - /** - * 树节点双击事件处理回调 - * @remarks - * 如果返回true则将打开节点的path对应的页签,如果返回false则不再进行其它处理 - * 默认将打开/切换页签,覆盖本方法以实现自定义双击事件 - * @param node 树节点 - * @returns 是否继续执行打开文件操作 - */ - handleDblClick(node: NavTreeNode): boolean { - return true; - } - public async getChildrenWithValidId(rootPath = ''): Promise { - return this.getChildren(rootPath).then((data) => { - const nodes = data; - for (const node of nodes) { - this.traverseTree(node, (n) => { - n.id = getValidId(n.id); - if (!n.data) { - return; - } - n.data.id = n.id; - const name = n.data && n.data.name || ''; - n.data[NODE_CONTENT_FIELD] = escapeTextForBrowser(name); - }); - } - return nodes; - }); - } - - /** - * 递归遍历树 - * @param node 树节点 - * @param handleNode 处理每一个树节点 - */ - private traverseTree( - node: NavTreeNode, - handleNode: (node: NavTreeNode) => void - ): void { - if (!node) { - return; - } - handleNode(node); - if (node.children && node.children.length > 0) { - for (const child of node.children) { - this.traverseTree(child, handleNode); - } - } - } -} diff --git a/packages/designer/src/components/components/code-view/composition/type/nav/node-icon.ts b/packages/designer/src/components/components/code-view/composition/type/nav/node-icon.ts deleted file mode 100644 index b71343b2cd0..00000000000 --- a/packages/designer/src/components/components/code-view/composition/type/nav/node-icon.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NavTreeNode } from "../interface/tree"; - -/** - * 导航树节点图标类生成服务 - */ -export abstract class NavTreeNodeIconService { - - /** - * 设置导航树节点的图标(css类) - * @remarks - * 每次都重新为整棵树设置图标 - * 如果需要为导航树使用自定义的图标,你需要在本方法设置节点(NavTreeNode)中的如下字段: - * 1. icon - 作为叶子节点时的图标 - * 2. expandedIcon - 作为非叶子节点,展开状态下的图标 - * 3. collapsedIcon - 作为非叶子节点,收折状态下的图标 - * 一般情况下,三个字段的值应该是一致的,除非节点展开和收折状态需要使用不同的图标 - * @param nodes 导航树的根节点数组 - */ - abstract setIconProp(nodes: NavTreeNode[]): void; - -} diff --git a/packages/designer/src/components/components/code-view/composition/utils/valid.ts b/packages/designer/src/components/components/code-view/composition/utils/valid.ts index d4c1ed5046c..7544a62f568 100644 --- a/packages/designer/src/components/components/code-view/composition/utils/valid.ts +++ b/packages/designer/src/components/components/code-view/composition/utils/valid.ts @@ -8,25 +8,3 @@ export function getValidId(id: string): string { return regExp.test(char); }).join(''); } -/** - * 编号是否合法 - * @remarks 编号应由大小写英文字母、数字、下划线、$符号构成,不能由数字开头 - * @param code 编号 - * @returns 错误提示 - */ -export function checkCode(code: string): string { - const errorTip = "应由大小写英文字母、数字、下划线、$符号构成,不能由数字、下划线开头,且不能以_结尾"; - const regExp = /^[A-Za-z$][A-Za-z0-9_$]*(?; export type CodeViewProps = ExtractPropTypes; diff --git a/packages/designer/src/components/components/code-view/props/fields-getter.props.ts b/packages/designer/src/components/components/code-view/props/fields-getter.props.ts deleted file mode 100644 index 3e56c6b4c6c..00000000000 --- a/packages/designer/src/components/components/code-view/props/fields-getter.props.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { ExtractPropTypes, PropType } from 'vue'; -import { FieldOption } from '../composition/type/fields-getter'; - -export const fieldsGetterProps = { - fields: { type: Object as PropType>, default: [] }, - /** 点击确定按钮的回调函数 */ - resolveFunc: { type: Object as PropType<(value: any) => void>, default: (value = null) => { } }, - /** 点击取消按钮的回调函数 */ - rejectFunc: { type: Object as PropType<(reason: any) => void>, default: (reason = null) => { } }, - -} as Record; - -export type FieldsGetterProps = ExtractPropTypes; - diff --git a/packages/designer/src/components/components/code-view/props/nav-tree.props.ts b/packages/designer/src/components/components/code-view/props/nav-tree.props.ts index f12b0704411..441c2456d10 100644 --- a/packages/designer/src/components/components/code-view/props/nav-tree.props.ts +++ b/packages/designer/src/components/components/code-view/props/nav-tree.props.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ExtractPropTypes} from 'vue'; +import { ExtractPropTypes } from 'vue'; + export const navTreeProps = { entryFilePath: { type: String, default: '' }, } as Record; diff --git a/packages/designer/src/components/components/form-designer/form-designer.component.tsx b/packages/designer/src/components/components/form-designer/form-designer.component.tsx index 7b5b72dbecb..f39aa369534 100644 --- a/packages/designer/src/components/components/form-designer/form-designer.component.tsx +++ b/packages/designer/src/components/components/form-designer/form-designer.component.tsx @@ -25,7 +25,7 @@ export default defineComponent({ function onCanvasInitialized(dragula: any) { dragulaCompostion.value = dragula; } - const canvasRef = ref(); + const propertyConfig = ref(); const propertyName = ref(); const focusingSchema = ref(); @@ -114,13 +114,12 @@ export default defineComponent({ context.expose({ reloadPropertyPanel }); function onEntityUpdated() { + // focusingSchema.value = null; onCanvasChanged(); - canvasRef.value?.refreshCanvas(); - nextTick(() => { + nextTick(()=>{ propertyPanelInstance?.value.updatePropertyConfig(); }); } - return () => { return ( @@ -143,7 +142,7 @@ export default defineComponent({
-
- onChangeDesignerView(type)} onSaveAll={(datas) => onCodeViewSaveAll(datas)}> -
+ {/*
+ onChangeDesignerView(type)} onSaveAll={()=>onCodeViewSaveAll()}> +
*/}
: '' ); diff --git a/packages/designer/src/components/types/metadata.ts b/packages/designer/src/components/types/metadata.ts index 97a3d1f04cb..b7686532248 100644 --- a/packages/designer/src/components/types/metadata.ts +++ b/packages/designer/src/components/types/metadata.ts @@ -1,7 +1,7 @@ import { FormComponent, FormExpression, FormStateMachine, FormWebCmd } from "./basic"; import { DesignViewModel } from "./design-viewmodel"; import { FormSchema, FormSchemaEntityField } from "./entity-schema"; -import { FormVariable, FormViewModel, FormViewModelField } from "./view-model"; +import { FormViewModel, FormViewModelField } from "./view-model"; export interface FormOptions { /** @@ -224,7 +224,6 @@ export interface UseFormSchema { setExpressions: (value: FormExpression[]) => void; deleteComponent: (componentId: string) => void; getControlsInCmpWidthBinding: (viewModelId: string, fieldId: string) => any; - getVariableById: (variableId: string) => FormVariable | undefined; } diff --git a/packages/ui-vue/components/condition/src/composition/condition-value/dropdown-value.ts b/packages/ui-vue/components/condition/src/composition/condition-value/dropdown-value.ts index b9d5a9e7821..59128468f5d 100644 --- a/packages/ui-vue/components/condition/src/composition/condition-value/dropdown-value.ts +++ b/packages/ui-vue/components/condition/src/composition/condition-value/dropdown-value.ts @@ -36,7 +36,7 @@ export class ComboListValue implements ConditionValue { } clear(): void { - this.value = ''; + this.value = []; // this.displayText = ''; } @@ -46,8 +46,7 @@ export class ComboListValue implements ConditionValue { } getDisplayText() { - return this.value; - // return this.value.map((enumValue: { value: string; name: string }) => enumValue.name).join(','); + return this.value.map((enumValue: { value: string; name: string }) => enumValue.name).join(','); } // setValue(data: { value: string; displayText: string }) { diff --git a/packages/ui-vue/components/condition/src/composition/condition-value/input-group-value.ts b/packages/ui-vue/components/condition/src/composition/condition-value/input-group-value.ts index d0dc9c9dae4..68edb81b829 100644 --- a/packages/ui-vue/components/condition/src/composition/condition-value/input-group-value.ts +++ b/packages/ui-vue/components/condition/src/composition/condition-value/input-group-value.ts @@ -21,11 +21,11 @@ export class InputGroupValue implements ConditionValue { isInputText: boolean; constructor(initialData: { - value: string; + value: any[]; displayText: string; displayField: string; isInputText: boolean; - } = { value: '', displayText: '', displayField: '', isInputText: false } + } = { value: [], displayText: '', displayField: '', isInputText: false } ) { this.value = initialData.value; this.displayText = initialData.displayText; @@ -34,7 +34,7 @@ export class InputGroupValue implements ConditionValue { } clear(): void { - this.value = ''; + this.value = []; this.displayText = ''; this.valueField = ''; } @@ -54,8 +54,9 @@ export class InputGroupValue implements ConditionValue { } getValue(): string { - - return this.value; + const fieldPath = this.valueField.split('.') || []; + const values = this.value.map(item => this.getPropValue(item, cloneDeep(fieldPath))); + return values && values.length ? values.join(',') : ''; } getDisplayText() { diff --git a/packages/ui-vue/components/data-grid/src/components/data/data-area.component.tsx b/packages/ui-vue/components/data-grid/src/components/data/data-area.component.tsx index 07c14da97c7..5eb94074ab3 100644 --- a/packages/ui-vue/components/data-grid/src/components/data/data-area.component.tsx +++ b/packages/ui-vue/components/data-grid/src/components/data/data-area.component.tsx @@ -164,7 +164,7 @@ export default function ( } function renderDataRow( - visualDataRow: VisualData, + visualDataRow: VisualData, cellPositionMap: Record, ) { return ( diff --git a/packages/ui-vue/components/data-grid/src/data-grid.component.tsx b/packages/ui-vue/components/data-grid/src/data-grid.component.tsx index 670d86be5b4..1d77d0f063b 100644 --- a/packages/ui-vue/components/data-grid/src/data-grid.component.tsx +++ b/packages/ui-vue/components/data-grid/src/data-grid.component.tsx @@ -30,7 +30,7 @@ import './data-grid.css'; export default defineComponent({ name: 'FDataGrid', props: dataGridProps, - emits: ['changed', 'clickRow', 'doubleClickRow', 'selectionChange', 'unSelectItem', 'enterUpInLastCell', 'pageIndexChanged', 'pageSizeChanged', 'beginEditCell', 'endEditCell'], + emits: ['changed', 'clickRow', 'doubleClickRow', 'selectionChange', 'enterUpInLastCell', 'pageIndexChanged', 'pageSizeChanged', 'beginEditCell', 'endEditCell'], setup(props: DataGridProps, context) { const preloadCount = 0; const rowHeight = props.rowOption?.height || 28; @@ -295,31 +295,6 @@ export default defineComponent({ useEditComposition.cancelEditingRow(visualDataRow); } - function updateVisibleDatasByColumns(columns: DataColumn[]) { - visibleDatas.value.forEach(((visibleData: VisualData, index: number) => { - const dataItemRowIndex = dataView.visibleDataItems.value.findIndex( - (dataItem: any) => dataItem === visibleData.raw); - const previousRow = visibleDatas.value[index - 1]; - columns.forEach((column: DataColumn) => { - if (!visibleData.data[column.field]) { - // 新增单元格对象 - visibleData.data[column.field] = - useVisualDataCellComposition.createCellByColumn( - column, - dataItemRowIndex, - visibleData.raw, - visibleData, - previousRow - ); - } else { - // 修改单元格对象 - useVisualDataCellComposition.updateCellByColumn( - visibleData.data[column.field], column, previousRow, visibleData.raw); - } - }); - })); - } - function updateColumns(newColumns: DataColumn[]) { if (newColumns) { columns.value = newColumns; @@ -356,14 +331,6 @@ export default defineComponent({ updateColumns(latestColumns); }); - watch(columns, (newValue, oldValue) => { - updateVisibleDatasByColumns(newValue); - }, { - deep: true, - // 更新列对象后立即触发更新单元格对象 - immediate: true - }); - function selectItemById(dataItemId: string) { useSelectionComposition.selectItemById(dataItemId); } @@ -399,19 +366,11 @@ export default defineComponent({ useEditComposition.endEditCell(); } - function unSelectItemByIds(dataItemIds: string[]) { - useSelectionComposition.unSelectItemByIds(dataItemIds); - } - - function clearSelection() { - useSelectionComposition.clearSelection(); - } - const dataGridComponentInstance = { addNewDataItem, addNewDataItemAtLast, removeDataItem, removeDataItemById, editDataItem, acceptDataItem, cancelDataItem, selectItemById, selectItemByIds, updateColumns, updateDataSource, updatePagination, getVisibleData, getVisibleDataByIds, getSelectedItems, getSelectionRow, - endEditCell, clickRowItemById, clearSelection, unSelectItemByIds + endEditCell, clickRowItemById }; context.expose(dataGridComponentInstance); diff --git a/packages/ui-vue/components/data-grid/src/designer/data-grid-column.design.component.tsx b/packages/ui-vue/components/data-grid/src/designer/data-grid-column.design.component.tsx index 85872b5ddae..9a3d6ba595a 100644 --- a/packages/ui-vue/components/data-grid/src/designer/data-grid-column.design.component.tsx +++ b/packages/ui-vue/components/data-grid/src/designer/data-grid-column.design.component.tsx @@ -1,9 +1,8 @@ import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue'; import { dataGridColumnProps, DataGridColumnProps } from '../data-grid-column.props'; -import { DesignerHostService, DesignerItemContext } from '../../../designer-canvas'; +import { DesignerItemContext } from '../../../designer-canvas'; import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component'; import { useDesignerRulesForDataGridColumn } from './use-column-rules'; -import { useFormBindingResolverDesign } from '../../../dynamic-form/src/composition/form-binding-resolver-design'; export default defineComponent({ name: 'FDataGridColumnDesign', @@ -11,10 +10,10 @@ export default defineComponent({ emits: [], setup(props: DataGridColumnProps, context) { const columnRef = ref(); - const designerHostService = inject('designer-host-service') as DesignerHostService; + const designerHostService=inject('designer-host-service'); const designItemContext = inject('design-item-context') as DesignerItemContext; const designerRulesComposition = useDesignerRulesForDataGridColumn(designItemContext, designerHostService); - const componentInstance = useDesignerComponent(columnRef, designItemContext, designerRulesComposition); + const componentInstance = useDesignerComponent(columnRef, designItemContext,designerRulesComposition); onMounted(() => { columnRef.value.componentInstance = componentInstance; }); @@ -26,17 +25,8 @@ export default defineComponent({ function clickHandler(event) { designItemContext?.setupContext?.emit('selectionChange', componentInstance.value.schema, designItemContext.schema, props.componentId, componentInstance.value); } - const { checkBindingFieldValidation } = useFormBindingResolverDesign(designerHostService, designItemContext, props); - - return () => { - const isValidBinding = checkBindingFieldValidation(); - const inValidTip = '绑定信息已失效,请手动移除列'; - const titleStyle = isValidBinding ? '' : 'color:red'; - return <> - {isValidBinding ? '' : } - clickHandler(event)}>{props.title} - ; + return clickHandler(event)}>{props.title}; }; } }); diff --git a/packages/ui-vue/components/data-view/components/sidebar/data-grid-sidebar.component.tsx b/packages/ui-vue/components/data-view/components/sidebar/data-grid-sidebar.component.tsx index e5868bfeeb6..986c67a58db 100644 --- a/packages/ui-vue/components/data-view/components/sidebar/data-grid-sidebar.component.tsx +++ b/packages/ui-vue/components/data-view/components/sidebar/data-grid-sidebar.component.tsx @@ -48,6 +48,7 @@ export default function (
+ ); } diff --git a/packages/ui-vue/components/data-view/composition/types.ts b/packages/ui-vue/components/data-view/composition/types.ts index 45e6260a0b2..a84d4a58955 100644 --- a/packages/ui-vue/components/data-view/composition/types.ts +++ b/packages/ui-vue/components/data-view/composition/types.ts @@ -616,8 +616,6 @@ export interface UseVisualDataCell { createCellByField: (targetField: string, mode: CellMode, index: number, dataItem: any, parent: VisualData, colSpan?: number) => VisualDataCell; - - updateCellByColumn: (cell: VisualDataCell, column: DataColumn, preVisualData: VisualData, dataItem: any) => void; } export interface UseEdit { @@ -922,8 +920,6 @@ export interface UseSelection { selectItemByIds(dataItemIds: string[]): void; - unSelectItemByIds(dataItemIds: string[]): void; - showCheckBox: Ref; showSelectAll: Ref; diff --git a/packages/ui-vue/components/data-view/composition/use-selection.ts b/packages/ui-vue/components/data-view/composition/use-selection.ts index dc351659051..fc0b63a18c7 100644 --- a/packages/ui-vue/components/data-view/composition/use-selection.ts +++ b/packages/ui-vue/components/data-view/composition/use-selection.ts @@ -76,10 +76,6 @@ export function useSelection( context.emit('selectionChange', selectedItems); } - function emitUnSelectItem(visibleData: VisualData) { - context.emit('unSelectItem',visibleData); - } - function resetSelection() { visibleDatas.value.forEach((visualDataToBeReset: VisualData) => { visualDataToBeReset.checked = false; @@ -196,10 +192,6 @@ export function useSelection( } visualData.checked ? unSelect(visualData) : select(visualData); emitSelectionChanged(); - if(!visualData.checked) { - // 取消选中 - emitUnSelectItem(visualData); - } } function selectItem(visualData: VisualData) { @@ -244,19 +236,6 @@ export function useSelection( } } - function unSelectItemByIds(dataItemIds: string[]) { - for (const dataItemId of dataItemIds) { - if (selectedValues.value.includes(dataItemId)) { - const visibleData = visibleDatas.value.find((visibleData: VisualData) => { - return visibleData.raw[idField.value] === dataItemId; - }); - if (visibleData) { - unSelect(visibleData); - } - } - } - } - /** 勾选所有节点 */ function selectAll() { @@ -311,7 +290,6 @@ export function useSelection( toggleSelectItem, toggleSelectItemWithoutRow, unSelect, - unSelectAll, - unSelectItemByIds + unSelectAll }; } diff --git a/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts b/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts index e9e168aed94..96c27e588f5 100644 --- a/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts +++ b/packages/ui-vue/components/data-view/composition/visualization/use-visual-data-cell.ts @@ -116,26 +116,18 @@ export function useVisualDataCell( targetCell.valign = column.valign || 'middle'; } - function updateCellByColumn(cell: VisualDataCell, column: DataColumn, preVisualData: VisualData, dataItem: any): void { - improveCellByColumn(cell, column); - wrapCellEditor(cell, column, dataItem); - tryToWrapCellCommand(cell, column); - tryToMergeCellValue(cell, preVisualData, column); - } - function createCellByColumn( column: DataColumn, index: number, dataItem: any, parent: VisualData, preVisualData: VisualData ): VisualDataCell { const cellMode = column.readonly ? CellMode.readonly : CellMode.editable; const targetCell: VisualDataCell = createCellByField(column.field, cellMode, index, dataItem, parent); - // improveCellByColumn(targetCell, column); - // wrapCellEditor(targetCell, column, dataItem); - // tryToWrapCellCommand(targetCell, column); - // tryToMergeCellValue(targetCell, preVisualData, column); - updateCellByColumn(targetCell, column, preVisualData, dataItem); + improveCellByColumn(targetCell, column); + wrapCellEditor(targetCell, column, dataItem); + tryToWrapCellCommand(targetCell, column); + tryToMergeCellValue(targetCell, preVisualData, column); return targetCell; } - return { createCellByColumn, createCellByField, updateCellByColumn }; + return { createCellByColumn, createCellByField }; } diff --git a/packages/ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx b/packages/ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx index 95912f47d5f..083088da98a 100644 --- a/packages/ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx +++ b/packages/ui-vue/components/date-picker/src/designer/date-picker.design.component.tsx @@ -25,7 +25,7 @@ export default defineComponent({ props: datePickerDesignProps, emits: ['update:modelValue', 'datePicked'] as (string[] & ThisType) | undefined, setup(props: DatePickerDesignProps, context: SetupContext) { - const groupIcon = ''; + const groupIcon = ''; const modelValue = ref(props.modelValue); const elementRef = ref(); const designerHostService = inject('designer-host-service'); diff --git a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx index 74faf2f0a0a..4d8d9367ade 100644 --- a/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx +++ b/packages/ui-vue/components/designer-canvas/src/designer-canvas.component.tsx @@ -111,17 +111,12 @@ export default defineComponent({ resizeObserver = null; } }); - const canvasKey = ref(0); - function refreshCanvas() { - canvasKey.value++; - } - context.expose({ refreshCanvas }); return () => { return (
- {schema.value && } + {schema.value && }
diff --git a/packages/ui-vue/components/drawer/src/drawer.component.tsx b/packages/ui-vue/components/drawer/src/drawer.component.tsx index 3d6112e536d..3241322cd10 100644 --- a/packages/ui-vue/components/drawer/src/drawer.component.tsx +++ b/packages/ui-vue/components/drawer/src/drawer.component.tsx @@ -57,7 +57,7 @@ export default defineComponent({
{props.modelValue && props.showMask &&
{ - props.closeByMask && onClose(); + onClose(); }, ['stop'])}>
}
diff --git a/packages/ui-vue/components/drawer/src/drawer.props.ts b/packages/ui-vue/components/drawer/src/drawer.props.ts index eb89640f36a..f7fb706fdfd 100644 --- a/packages/ui-vue/components/drawer/src/drawer.props.ts +++ b/packages/ui-vue/components/drawer/src/drawer.props.ts @@ -29,8 +29,6 @@ export const drawerProps = { showClose: { type: Boolean, default: true }, /** 是否展示遮罩层 */ showMask: { type: Boolean, default: true }, - /** 点击遮罩是否关闭抽屉 */ - closeByMask: { type: Boolean, default: true }, /** 标题 */ title: { type: String, default: '' }, /** 宽度 */ diff --git a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.design.component.tsx b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.design.component.tsx index 80cdec0c46b..58da6f8b76c 100644 --- a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.design.component.tsx +++ b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.design.component.tsx @@ -1,10 +1,7 @@ -import { SetupContext, computed, defineComponent, ref, watch, inject } from 'vue'; +import { SetupContext, computed, defineComponent, ref, watch } from 'vue'; import { DynamicFormGroupPropsType, dynamicFormGroupProps } from './dynamic-form-group.props'; import Label from '../dynamic-form-label/dynamic-form-label.component'; import { useTypeResolverDesign } from '../../composition/use-type-resolver-design'; -import { DesignerHostService } from '../../../../../components/designer-canvas/src/composition/types'; -import { DesignerItemContext } from '../../../../designer-canvas/src/types'; -import { useFormBindingResolverDesign } from '../../composition/form-binding-resolver-design'; export default defineComponent({ name: 'FDynamicFormGroupDesign', @@ -21,8 +18,6 @@ export default defineComponent({ const showLabel = ref(props.showLabel); const type = ref(props.type); const editorRef = ref(); - const designerHostService = inject('designer-host-service') as DesignerHostService; - const designItemContext = inject('design-item-context') as DesignerItemContext; const { resolveEditorProps, resolveEditorType } = useTypeResolverDesign(); const conditionItemClass = computed(() => { @@ -55,7 +50,7 @@ export default defineComponent({ ([newId, newCustomClass, newEditor, newLabel, newModelValue, newReadonly, newShowLabel]) => { id.value = newId; customClass.value = newCustomClass; - editor.value = { ...newEditor }; + editor.value = {...newEditor}; label.value = newLabel; modelValue.value = newModelValue; readonly.value = newReadonly; @@ -63,22 +58,16 @@ export default defineComponent({ showLabel.value = newShowLabel; }, { deep: true } ); - - const { checkBindingFieldValidation } = useFormBindingResolverDesign(designerHostService, designItemContext, props); - function renderLabel() { - const isValidBinding = checkBindingFieldValidation(); - const inValidTip = '绑定信息已失效,请切换绑定或移除控件'; - return ; - } - context.expose({ editorRef }); return () => { return ( -
+
- {showLabel.value && renderLabel()} + {showLabel.value && ( + + )}
{renderConditionEditor.value()}
diff --git a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.props.ts b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.props.ts index 24fb1341591..7e093e52533 100644 --- a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.props.ts +++ b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-group/dynamic-form-group.props.ts @@ -18,8 +18,7 @@ export const dynamicFormGroupProps = { visible: { type: Boolean, default: true }, required: { type: Boolean, default: false }, showLabel: { type: Boolean, default: true }, - type: { type: String as PropType, default: 'input-group' }, - componentId: { type: String, default: '' } + type: { type: String as PropType, default: 'input-group' } } as Record; export type DynamicFormGroupPropsType = ExtractPropTypes; diff --git a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-label/dynamic-form-label.component.tsx b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-label/dynamic-form-label.component.tsx index 960e70a208c..616e308333b 100644 --- a/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-label/dynamic-form-label.component.tsx +++ b/packages/ui-vue/components/dynamic-form/src/component/dynamic-form-label/dynamic-form-label.component.tsx @@ -1,4 +1,4 @@ -import { SetupContext, defineComponent, ref, watch, computed } from "vue"; +import { SetupContext, defineComponent, ref, watch } from "vue"; import { dynamicFormLabelProps, DynamicFormLabelProps } from "./dynamic-form-label.props"; export default defineComponent({ @@ -9,8 +9,6 @@ export default defineComponent({ const title = ref(props.title || props.text); const required = ref(props.required); const text = ref(props.text); - const valid = ref(props.valid); - const inValidTip = ref(props.inValidTip); watch(() => props.text, () => { text.value = props.text; @@ -21,22 +19,10 @@ export default defineComponent({ required.value = newValue; } }); - watch([() => props.valid, () => props.inValidTip], ([newValid, newInValidTip]) => { - valid.value = newValid; - inValidTip.value = newInValidTip; - }); - - const labelTitle = computed(() => { - return valid.value ? title.value : inValidTip.value; - }); - const labelColor = computed(() => { - return valid.value ? '' : 'color:red'; - }); return () => { return ( - text.value &&