From d4b4ea76929a96057b3adade4335eba585e3b573 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 8 Jun 2025 13:40:23 +0800 Subject: [PATCH 01/33] =?UTF-8?q?-=20LowCodeComponentBase=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20StateKey=20=E5=B1=9E=E6=80=A7=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=20ShouldRender=20=E5=88=A4=E6=96=AD=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=BB=84=E4=BB=B6=E9=9D=9E=E5=BF=85=E8=A6=81=E6=B8=B2?= =?UTF-8?q?=E6=9F=93;=20-=20=E6=96=B0=E5=A2=9E=E4=BA=8B=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=A1=B5=E9=9D=A2;=20=E6=94=AF=E6=8C=81=20Table=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=B8=AD=E7=9A=84=E6=8C=89=E9=92=AE=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=BA=8B=E4=BB=B6;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/caseapp.json | 2 +- meta/apps/caseapp/page/2qceiqni.json | 2 +- meta/apps/caseapp/page/2qme5ln5e.json | 2 +- meta/apps/caseapp/page/5kicsevr.json | 2 +- meta/apps/caseapp/page/g0qcqxzd.json | 2 +- meta/apps/caseapp/page/gndz2vecz.json | 2 +- meta/apps/caseapp/page/pl3juvaok.json | 2 +- meta/apps/caseapp/page/xjvks1d3f.json | 2 +- meta/apps/testapp/page/ajzc8ywaa.json | 27 +---- meta/apps/testapp/page/ehduqxwzm.json | 27 +---- meta/apps/testapp/page/g0qcqxzd.json | 2 +- meta/apps/testapp/page/wjrxq0ft.json | 27 +---- meta/apps/testapp/page/xvdr8b6l.json | 27 +---- meta/apps/testapp/testapp.json | 2 +- .../componentParts/antdesign/f2b54b4c.json | 3 +- .../LowCodeComponentBase.cs | 6 +- .../Components/LcTable.razor | 107 +++++++++++++----- .../ComponentPartsSchema.cs | 6 + .../H.LowCode.MetaSchema/AppSchemaBase.cs | 3 +- .../ComponentSchemaBase.cs | 8 +- .../ComponentDataSourceSchema.cs | 2 +- .../Enums/ActionTypeEnum.cs | 16 --- .../Enums/EventHandlerTypeEnum.cs | 27 +++++ .../H.LowCode.MetaSchema/MetaSchemaBase.cs | 2 +- .../PropertySchemas/ComponentEventSchema.cs | 9 -- .../PropertySchemas/EventSchema.cs | 19 ++++ .../PropertySchemas/PropertyItemSchema.cs | 35 ------ .../TableSchemas/TableButtonSchema.cs | 31 +++-- .../StateHasChangeSchema.cs | 16 +++ .../DataSources}/APIDataSource.razor | 0 .../DataSources}/APIParamsList.razor | 0 .../Components/Events/EventList.razor | 91 +++++++++++++++ .../ContainerComponentBase.razor | 47 -------- .../DragDropComponents/ComponentItem.razor | 13 ++- .../OptionDataSourceSetting.razor | 4 +- .../TableDataSourceSetting.razor | 2 +- .../TablePropertyItem.razor | 88 +++++++++++--- .../Layout/WorkbenchLayout.razor | 2 +- src/H.LowCode.sln | 2 +- 39 files changed, 368 insertions(+), 299 deletions(-) delete mode 100644 src/Common/H.LowCode.MetaSchema/Enums/ActionTypeEnum.cs create mode 100644 src/Common/H.LowCode.MetaSchema/Enums/EventHandlerTypeEnum.cs delete mode 100644 src/Common/H.LowCode.MetaSchema/PropertySchemas/ComponentEventSchema.cs create mode 100644 src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs delete mode 100644 src/Common/H.LowCode.MetaSchema/PropertySchemas/PropertyItemSchema.cs create mode 100644 src/Common/H.LowCode.MetaSchema/StateHasChangeSchema.cs rename src/DesignEngine/H.LowCode.DesignEngine.Abstraction/{DataSourceComponents => Components/DataSources}/APIDataSource.razor (100%) rename src/DesignEngine/H.LowCode.DesignEngine.Abstraction/{DataSourceComponents => Components/DataSources}/APIParamsList.razor (100%) create mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/Events/EventList.razor delete mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Abstraction/ContainerComponentBase.razor diff --git a/meta/apps/caseapp/caseapp.json b/meta/apps/caseapp/caseapp.json index 2ad84ce..ce6c8b4 100644 --- a/meta/apps/caseapp/caseapp.json +++ b/meta/apps/caseapp/caseapp.json @@ -1 +1 @@ -{"id":"caseapp","n":"用例系统","desc":"展示典型页面案例","pub":0,"platform":[0,2],"createdTime":"0001-01-01T00:00:00","modifiedTime":"2025-01-02T15:03:41.2355394Z"} \ No newline at end of file +{"id":"caseapp","n":"用例系统","desc":"展示典型页面案例 (参考 amis 示例)","platform":[0,2],"mt":"2025-05-29T16:49:31.1628431Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/2qceiqni.json b/meta/apps/caseapp/page/2qceiqni.json index fda21bf..29f306f 100644 --- a/meta/apps/caseapp/page/2qceiqni.json +++ b/meta/apps/caseapp/page/2qceiqni.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"2qceiqni","n":"主从表单","order":10,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:10:46.3663146Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"2qceiqni","n":"主从表单","order":10,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:30:43.9836585Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/2qme5ln5e.json b/meta/apps/caseapp/page/2qme5ln5e.json index a9032f2..a30172c 100644 --- a/meta/apps/caseapp/page/2qme5ln5e.json +++ b/meta/apps/caseapp/page/2qme5ln5e.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"2qme5ln5e","n":"分组表单","order":3,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:09:16.5141165Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"2qme5ln5e","n":"分组表单","order":3,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:30:22.2545123Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/5kicsevr.json b/meta/apps/caseapp/page/5kicsevr.json index b1ae9f9..cad0006 100644 --- a/meta/apps/caseapp/page/5kicsevr.json +++ b/meta/apps/caseapp/page/5kicsevr.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"5kicsevr","n":"页面分栏表单","order":8,"pt":1,"pageprop":{"playout":3,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:10:33.5454698Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"5kicsevr","n":"页面分栏表单","order":8,"pt":1,"pageprop":{"playout":3,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:30:32.0346739Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/g0qcqxzd.json b/meta/apps/caseapp/page/g0qcqxzd.json index ebe8316..1dc4ff7 100644 --- a/meta/apps/caseapp/page/g0qcqxzd.json +++ b/meta/apps/caseapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"No\",\"t\":\"学号\"},{\"id\":\"vwvoqrn1s\",\"n\":\"Name\",\"t\":\"姓名\"},{\"id\":\"ap0ceewr\",\"n\":\"Age\",\"t\":\"年龄\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"}],\"searchs\":[],\"btns\":[]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180},"ev":{}}],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-05-24T11:36:58.9214723Z"} \ No newline at end of file +{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"No\",\"t\":\"学号\"},{\"id\":\"vwvoqrn1s\",\"n\":\"Name\",\"t\":\"姓名\"},{\"id\":\"ap0ceewr\",\"n\":\"Age\",\"t\":\"年龄\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"}],\"searchs\":[],\"btns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"eat\":13,\"eh\":\"fhumgxyk\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-06-08T05:23:13.9702609Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/gndz2vecz.json b/meta/apps/caseapp/page/gndz2vecz.json index 20f9a5a..56ee2b2 100644 --- a/meta/apps/caseapp/page/gndz2vecz.json +++ b/meta/apps/caseapp/page/gndz2vecz.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"gndz2vecz","n":"多标签页表单","order":4,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:09:28.3110543Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"gndz2vecz","n":"多标签页表单","order":4,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:30:27.8353552Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/pl3juvaok.json b/meta/apps/caseapp/page/pl3juvaok.json index c4c050d..6a7b500 100644 --- a/meta/apps/caseapp/page/pl3juvaok.json +++ b/meta/apps/caseapp/page/pl3juvaok.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"pl3juvaok","n":"校验表单","order":2,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:09:07.8151933Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"pl3juvaok","n":"校验表单","order":2,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:29:46.9891744Z"} \ No newline at end of file diff --git a/meta/apps/caseapp/page/xjvks1d3f.json b/meta/apps/caseapp/page/xjvks1d3f.json index ee74204..4ad5204 100644 --- a/meta/apps/caseapp/page/xjvks1d3f.json +++ b/meta/apps/caseapp/page/xjvks1d3f.json @@ -1 +1 @@ -{"comps":[],"aid":"caseapp","id":"xjvks1d3f","n":"表格样式表单","order":9,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"modifiedTime":"2025-04-03T02:10:39.9091503Z"} \ No newline at end of file +{"comps":[],"aid":"caseapp","id":"xjvks1d3f","n":"表格样式表单","order":9,"pt":1,"pageprop":{"playout":2,"ds":{}},"ds":{"dst":1,"dsv":"tb_test1"},"mt":"2025-05-26T15:30:36.669071Z"} \ No newline at end of file diff --git a/meta/apps/testapp/page/ajzc8ywaa.json b/meta/apps/testapp/page/ajzc8ywaa.json index 48e4934..3b884cb 100644 --- a/meta/apps/testapp/page/ajzc8ywaa.json +++ b/meta/apps/testapp/page/ajzc8ywaa.json @@ -1,26 +1 @@ -{ - "aid": "testapp", - "id": "ajzc8ywaa", - "n": "页面1", - "order": 3, - "pt": 0, - "pubstatus": false, - "comps": [ - - ], - "pageprop": { - "playout": 2 - }, - "ds": { - "order": 0, - "type": 0, - "pubstatus": false, - "fields": [], - "ops": [], - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "0001-01-01T00:00:00" - }, - "i18n": {}, - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "2024-10-13T09:21:54.2980288Z" -} \ No newline at end of file +{"comps":[],"aid":"testapp","id":"ajzc8ywaa","n":"页面1","order":3,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-05-26T15:29:15.2677174Z"} \ No newline at end of file diff --git a/meta/apps/testapp/page/ehduqxwzm.json b/meta/apps/testapp/page/ehduqxwzm.json index 003333d..765d18c 100644 --- a/meta/apps/testapp/page/ehduqxwzm.json +++ b/meta/apps/testapp/page/ehduqxwzm.json @@ -1,26 +1 @@ -{ - "aid": "testapp", - "id": "ehduqxwzm", - "n": "页面3", - "order": 5, - "pt": 0, - "pubstatus": false, - "comps": [ - - ], - "pageprop": { - "playout": 2 - }, - "ds": { - "order": 0, - "type": 0, - "pubstatus": false, - "fields": [], - "ops": [], - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "0001-01-01T00:00:00" - }, - "i18n": {}, - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "2024-10-13T09:22:10.8343157Z" -} \ No newline at end of file +{"comps":[],"aid":"testapp","id":"ehduqxwzm","n":"页面3","order":5,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-05-26T15:29:19.2339683Z"} \ No newline at end of file diff --git a/meta/apps/testapp/page/g0qcqxzd.json b/meta/apps/testapp/page/g0qcqxzd.json index 134801e..1f9b5e3 100644 --- a/meta/apps/testapp/page/g0qcqxzd.json +++ b/meta/apps/testapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"aid":"testapp","id":"g0qcqxzd","n":"页面11","order":0,"pt":0,"pubstatus":false,"comps":[],"pageprop":{"playout":2},"ds":{"order":0,"type":0,"pubstatus":false,"fields":[],"ops":[],"createdTime":"0001-01-01T00:00:00","modifiedTime":"0001-01-01T00:00:00"},"i18n":{},"createdTime":"0001-01-01T00:00:00","modifiedTime":"2024-10-13T08:10:20.0733139Z"} \ No newline at end of file +{"comps":[],"aid":"testapp","id":"g0qcqxzd","n":"页面11","pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-05-26T15:29:01.5525837Z"} \ No newline at end of file diff --git a/meta/apps/testapp/page/wjrxq0ft.json b/meta/apps/testapp/page/wjrxq0ft.json index 3ec06f9..dde26e4 100644 --- a/meta/apps/testapp/page/wjrxq0ft.json +++ b/meta/apps/testapp/page/wjrxq0ft.json @@ -1,26 +1 @@ -{ - "aid": "testapp", - "id": "wjrxq0ft", - "n": "组件嵌套", - "order": 1, - "pt": 0, - "pubstatus": false, - "comps": [ - - ], - "pageprop": { - "playout": 2 - }, - "ds": { - "order": 0, - "type": 0, - "pubstatus": false, - "fields": [], - "ops": [], - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "0001-01-01T00:00:00" - }, - "i18n": {}, - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "2024-10-13T09:21:35.1783317Z" -} \ No newline at end of file +{"comps":[],"aid":"testapp","id":"wjrxq0ft","n":"组件嵌套","order":1,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-05-26T15:29:06.9549831Z"} \ No newline at end of file diff --git a/meta/apps/testapp/page/xvdr8b6l.json b/meta/apps/testapp/page/xvdr8b6l.json index 9e5b6c1..c2a561c 100644 --- a/meta/apps/testapp/page/xvdr8b6l.json +++ b/meta/apps/testapp/page/xvdr8b6l.json @@ -1,26 +1 @@ -{ - "aid": "testapp", - "id": "xvdr8b6l", - "n": "页面1", - "order": 2, - "pt": 0, - "pubstatus": false, - "comps": [ - - ], - "pageprop": { - "playout": 3 - }, - "ds": { - "order": 0, - "type": 1, - "pubstatus": false, - "fields": [], - "ops": [], - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "0001-01-01T00:00:00" - }, - "i18n": {}, - "createdTime": "0001-01-01T00:00:00", - "modifiedTime": "2024-10-13T09:20:24.737612Z" -} \ No newline at end of file +{"comps":[],"aid":"testapp","id":"xvdr8b6l","n":"页面1","order":2,"pageprop":{"playout":3,"ds":{}},"ds":{},"mt":"2025-05-26T15:29:10.6464264Z"} \ No newline at end of file diff --git a/meta/apps/testapp/testapp.json b/meta/apps/testapp/testapp.json index b0b9578..2eb1645 100644 --- a/meta/apps/testapp/testapp.json +++ b/meta/apps/testapp/testapp.json @@ -1 +1 @@ -{"id":"testapp","n":"测试系统","desc":"测试不同页面设计场景","state":0} \ No newline at end of file +{"id":"testapp","n":"测试系统","desc":"测试组件、页面不同设计场景","platform":[0],"mt":"2025-05-29T16:43:23.7831823Z"} \ No newline at end of file diff --git a/meta/parts/componentParts/antdesign/f2b54b4c.json b/meta/parts/componentParts/antdesign/f2b54b4c.json index b6a7693..b8d498e 100644 --- a/meta/parts/componentParts/antdesign/f2b54b4c.json +++ b/meta/parts/componentParts/antdesign/f2b54b4c.json @@ -16,7 +16,8 @@ "hlb": true, "sptds": true, "ds": { - "dsgt":2 + "dsgt":2, + "dsv": "{\"btns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"tgId\":\"xxx\"},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"tgId\":\"xxx\"}]}" }, "stl": { "itemw": 24, diff --git a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs index efd56df..6139c41 100644 --- a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs +++ b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.WebUtilities; -using System; using System.Diagnostics.CodeAnalysis; using Volo.Abp.AspNetCore.Components; @@ -17,6 +16,11 @@ public abstract class LowCodeComponentBase : AbpComponentBase [Inject] private NavigationManager NavigationManager { get; set; } + /// + /// 组件状态标识 (用于 ShouldRender 判断) + /// + protected string StateKey { get; set; } + /// /// /// diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor index 2db38b9..4746ad8 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor @@ -7,14 +7,9 @@ @bind-SelectedRows="_selectedRows" OnChange="OnChange" Size="TableSize.Small"> - @if(_tableSchema.Buttons.Count == 0) - { - - - } @foreach (var btn in _tableSchema.Buttons) { - + } @@ -45,6 +40,9 @@ [Parameter] public ComponentDataSourceSchemaBase DataSource { get; set; } + [CascadingParameter(Name = "pageCascading")] + public PageCascadingModel PageCascading { get; set; } + private TablePropertySchema _tableSchema = new(); private List> _data; @@ -57,11 +55,28 @@ protected override async Task OnInitializedAsync() { - _tableSchema = GetTableSchemaAsync(); + await base.OnInitializedAsync(); + + Init(); _data = await GetTableDataAsync(1, 50); _total = 50; } + protected override bool ShouldRender() + { + //if (StateKey == DataSource.StateKey) + // return false; + + Init(); + return true; + } + + private void Init() + { + _tableSchema = GetTableSchemaAsync(); + StateKey = DataSource.StateKey; + } + public async Task OnChange(QueryModel> queryModel) { await Task.Delay(1); @@ -73,15 +88,24 @@ var dataSource = DataSource?.DataSourceValue; if (dataSource.IsNullOrWhiteSpace() || dataSource.Trim().Equals("[]")) { - var tableSchema = new TablePropertySchema(); + var defaultTableSchema = new TablePropertySchema(); + defaultTableSchema.Columns = new List() + { + new() { Name = "_temp", Title = "(待添加列)" } + }; + return defaultTableSchema; + } + + var tableSchema = dataSource.FromJson(); + if(tableSchema.Columns.Any() == false) + { tableSchema.Columns = new List() { new() { Name = "_temp", Title = "(待添加列)" } }; - return tableSchema; } - return dataSource.FromJson(); + return tableSchema; } public async Task>> GetTableDataAsync(int pageIndex, int pageSize) @@ -100,11 +124,6 @@ return list; } - public async Task CreateAsync() - { - await Task.Delay(100); - } - public async Task EditAsync(Dictionary row) { string primaryKey = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey)?.Name; @@ -116,25 +135,53 @@ await Task.Delay(100); } - public async Task DeleteSelectedAsync() - { - await Task.Delay(100); - } - public async Task ButtonActionAsync(string id) { - await Task.Delay(100); var btn = _tableSchema.Buttons.First(t => t.Id == id); - if (btn.ActionType == ActionTypeEnum.Blank) + foreach(var e in btn.Events) { - string pageUrl = string.Empty; - if (IsDesign) - pageUrl = $"/designer/caseapp/{btn.TargetId}"; - else - pageUrl = $"/caseapp/{btn.TargetId}"; - - await JS.InvokeVoidAsync("open", pageUrl, "_blank"); - // await this.RedirectPageAsync(pageUrl); + if (e.EventHandlerType == EventHandlerTypeEnum.Page) + { + switch ((EventPageHandlerTypeEnum)e.EventActionType) + { + case EventPageHandlerTypeEnum.Modal: + await ButtonActionToWithModalAsync(e); + break; + case EventPageHandlerTypeEnum.Self: + await ButtonActionToWithSelfAsync(e); + break; + case EventPageHandlerTypeEnum.Blank: + await ButtonActionToWithBlankAsync(e); + break; + default: + break; + } + } + else if (e.EventHandlerType == EventHandlerTypeEnum.Custom) + { + await JS.InvokeVoidAsync("eval", e.EventHandler); + } } } + + private async Task ButtonActionToWithModalAsync(EventSchema e) + { + + } + + private async Task ButtonActionToWithSelfAsync(EventSchema e) + { + + } + + private async Task ButtonActionToWithBlankAsync(EventSchema e) + { + string pageUrl = string.Empty; + if (IsDesign) + pageUrl = $"/designer/{PageCascading.AppId}/{e.EventHandler}"; + else + pageUrl = $"/{PageCascading.AppId}/{e.EventHandler}"; + + await JS.InvokeVoidAsync("open", pageUrl, "_blank"); + } } diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs index a371b8a..27a73ce 100644 --- a/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs @@ -51,6 +51,12 @@ public class ComponentPartsSchema : ComponentSchemaBase [JsonPropertyName("childs")] public IList Childrens { get; set; } = []; + /// + /// 组件支持的事件 + /// + [JsonPropertyName("sptevs")] + public string[] SupportEvents { get; set; } + [JsonPropertyName("order")] public int Order { get; set; } diff --git a/src/Common/H.LowCode.MetaSchema/AppSchemaBase.cs b/src/Common/H.LowCode.MetaSchema/AppSchemaBase.cs index d3b2d1c..1d3536d 100644 --- a/src/Common/H.LowCode.MetaSchema/AppSchemaBase.cs +++ b/src/Common/H.LowCode.MetaSchema/AppSchemaBase.cs @@ -1,5 +1,4 @@ -using System.ComponentModel.DataAnnotations; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; diff --git a/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs b/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs index b5dbc87..4c8685f 100644 --- a/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs +++ b/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; -public abstract class ComponentSchemaBase +public abstract class ComponentSchemaBase : StateHasChangeSchema { /// /// 组件实例Id @@ -62,10 +62,10 @@ public abstract class ComponentSchemaBase public ComponentStyleSchema Style { get; set; } = new(); /// - /// + /// 事件 /// - [JsonPropertyName("ev")] - public ComponentEventSchema Event { get; set; } = new(); + [JsonPropertyName("evs")] + public EventSchema Events { get; set; } [JsonPropertyName("desc")] public string Description { get; set; } diff --git a/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/ComponentDataSourceSchema.cs b/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/ComponentDataSourceSchema.cs index 51f9274..a817c67 100644 --- a/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/ComponentDataSourceSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/ComponentDataSourceSchema.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; -public abstract class ComponentDataSourceSchemaBase +public abstract class ComponentDataSourceSchemaBase : StateHasChangeSchema { /// /// 数据源分组类型 diff --git a/src/Common/H.LowCode.MetaSchema/Enums/ActionTypeEnum.cs b/src/Common/H.LowCode.MetaSchema/Enums/ActionTypeEnum.cs deleted file mode 100644 index 376146c..0000000 --- a/src/Common/H.LowCode.MetaSchema/Enums/ActionTypeEnum.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using System.Threading.Tasks; - -namespace H.LowCode.MetaSchema; - -public enum ActionTypeEnum -{ - None, - Modal, - Self, - Blank -} diff --git a/src/Common/H.LowCode.MetaSchema/Enums/EventHandlerTypeEnum.cs b/src/Common/H.LowCode.MetaSchema/Enums/EventHandlerTypeEnum.cs new file mode 100644 index 0000000..19a3baa --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema/Enums/EventHandlerTypeEnum.cs @@ -0,0 +1,27 @@ +using System; + +namespace H.LowCode.MetaSchema; + +public enum EventHandlerTypeEnum +{ + None = 0, + Page = 10, //打开页面 + Data = 30, //操作数据 + Custom = 99, // 自定义事件 +} + +public enum EventPageHandlerTypeEnum +{ + None = 0, + Modal = 11, // 弹窗 + Self = 12, // 当前页 + Blank = 13, // 空白页 +} + +public enum EventDataHandlerTypeEnum +{ + None = 0, + Reload = 31, //重新加载 + Delete = 32, //删除指定数据 + DeleteSelection = 33 //删除选中(常用于列表) +} \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema/MetaSchemaBase.cs b/src/Common/H.LowCode.MetaSchema/MetaSchemaBase.cs index 7e3dada..9a14df0 100644 --- a/src/Common/H.LowCode.MetaSchema/MetaSchemaBase.cs +++ b/src/Common/H.LowCode.MetaSchema/MetaSchemaBase.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; -public abstract class MetaSchemaBase +public abstract class MetaSchemaBase : StateHasChangeSchema { [JsonPropertyName("cu")] public string CreatedUser { get; set; } diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/ComponentEventSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/ComponentEventSchema.cs deleted file mode 100644 index 6d8fc86..0000000 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/ComponentEventSchema.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Text.Json.Serialization; - -namespace H.LowCode.MetaSchema; - -public class ComponentEventSchema -{ - -} diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs new file mode 100644 index 0000000..4bab036 --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs @@ -0,0 +1,19 @@ +using System; +using System.Text.Json.Serialization; + +namespace H.LowCode.MetaSchema; + +public class EventSchema +{ + [JsonPropertyName("en")] + public string EventName { get; set; } + + [JsonPropertyName("eht")] + public EventHandlerTypeEnum EventHandlerType { get; set; } + + [JsonPropertyName("eat")] + public int EventActionType { get; set; } + + [JsonPropertyName("eh")] + public string EventHandler { get; set; } +} diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/PropertyItemSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/PropertyItemSchema.cs deleted file mode 100644 index 45e8b59..0000000 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/PropertyItemSchema.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Text.Json.Serialization; - -namespace H.LowCode.MetaSchema; - -public class PropertyItemSchema -{ - [JsonPropertyName("n")] - public string Name { get; set; } - - [JsonPropertyName("label")] - public string Label { get; set; } - - [JsonPropertyName("desc")] - public string Description { get; set; } - - public int Order { get; set; } - - [JsonPropertyName("strval")] - public string StringValue { get; set; } - - [JsonPropertyName("boolval")] - public bool? BoolValue { get; set; } - - [JsonPropertyName("intval")] - public int? IntValue { get; set; } - - public IDictionary Options { get; set; } - - ///// - ///// 设置项类型 - ///// - //[JsonPropertyName("itemtype")] - //public ComponentAttributeItemTypeEnum SettingItemType { get; set; } -} diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableButtonSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableButtonSchema.cs index 52b7cd3..4e6e52a 100644 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableButtonSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableButtonSchema.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.Json.Serialization; -using System.Threading.Tasks; namespace H.LowCode.MetaSchema; @@ -18,8 +14,8 @@ public class TableButtonSchema [JsonPropertyName("t")] public string Title { get; set; } - [JsonPropertyName("btnType")] - public string ButtonType { get; set; } + [JsonPropertyName("bt")] + public int ButtonType { get; set; } [JsonPropertyName("disabled")] public bool Disabled { get; set; } @@ -30,13 +26,24 @@ public class TableButtonSchema [JsonPropertyName("order")] public int Order { get; set; } - [JsonPropertyName("actType")] - public ActionTypeEnum ActionType { get; set; } = new(); + /// + /// 组件支持的事件 + /// + [JsonPropertyName("sptevs")] + public string[] SupportEvents { get; set; } = ["OnClick"]; /// - /// 目标对象Id + /// 事件 /// - /// 如打开页面时的PageId - [JsonPropertyName("tgId")] - public string TargetId { get; set; } + [JsonPropertyName("evs")] + public IList Events { get; set; } + + public void Update(TableButtonSchema update) + { + this.Name = update.Name; + this.Title = update.Title; + this.ButtonType = update.ButtonType; + this.Disabled = update.Disabled; + this.Order = update.Order; + } } diff --git a/src/Common/H.LowCode.MetaSchema/StateHasChangeSchema.cs b/src/Common/H.LowCode.MetaSchema/StateHasChangeSchema.cs new file mode 100644 index 0000000..6021f24 --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema/StateHasChangeSchema.cs @@ -0,0 +1,16 @@ +using H.Util.Ids; +using System; +using System.Text.Json.Serialization; + +namespace H.LowCode.MetaSchema; + +public abstract class StateHasChangeSchema +{ + [JsonIgnore] + public string StateKey { get; internal set; } = ShortIdGenerator.Generate(); + + public void ChangeStateKey() + { + StateKey = ShortIdGenerator.Generate(); + } +} diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/DataSourceComponents/APIDataSource.razor b/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/DataSources/APIDataSource.razor similarity index 100% rename from src/DesignEngine/H.LowCode.DesignEngine.Abstraction/DataSourceComponents/APIDataSource.razor rename to src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/DataSources/APIDataSource.razor diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/DataSourceComponents/APIParamsList.razor b/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/DataSources/APIParamsList.razor similarity index 100% rename from src/DesignEngine/H.LowCode.DesignEngine.Abstraction/DataSourceComponents/APIParamsList.razor rename to src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/DataSources/APIParamsList.razor diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/Events/EventList.razor b/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/Events/EventList.razor new file mode 100644 index 0000000..4b05b8f --- /dev/null +++ b/src/DesignEngine/H.LowCode.DesignEngine.Abstraction/Components/Events/EventList.razor @@ -0,0 +1,91 @@ +@namespace H.LowCode.DesignEngine.Abstraction +@inherits DesignEngineLowCodeComponentBase + + + + + @foreach(var ev in Events) + { + + } + + + + +
+ + + 无操作 + 打开页面 + 操作数据 + 自定义 + +
+ + @if (_currentEvent.EventHandlerType == EventHandlerTypeEnum.Page) + { +
+ + + 弹窗 + 当前页 + 新标签页 + +
+
+ + +
+ } + else if (_currentEvent.EventHandlerType == EventHandlerTypeEnum.Data) + { +
+ + + 重新加载 + 删除 + 删除选中 + +
+ } + else if (_currentEvent.EventHandlerType == EventHandlerTypeEnum.Custom) + { +
+ - - - - -@code { - [Parameter] - public ComponentPartsSchema Component { get; set; } - - private bool _visible; - private string _selectedValue; - - private void AddEvent() - { - Console.WriteLine($"eventsetting-modal-visible:{_visible}"); - _visible = true; - } - - private void AddCustomEvent() - { - _visible = true; - } -} diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PageSetting.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PageSetting.razor index 0e95d5b..300e836 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PageSetting.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PageSetting.razor @@ -43,8 +43,19 @@ - - - - - - - 待发布 - 已发布 - - -
-
- 组件设计面板属性: - - - - @if (context.IsContainer == false && context.IsSupportDataSource) - { - 数据源: - - - - } -
-
- +Width="1500"> + +Width="800" MaxBodyHeight="700"> @@ -149,14 +84,11 @@ Width="600" MaxBodyHeight="700"> IEnumerable selectedRows; - private bool _formVisible = false; - private Form _form; - private string _textComponentFragment; - private string _textDataSource; - private string _textAttributeDefineGroups; private IList _componentPartsList; private ComponentPartsSchema _componentPartsSchema = new ComponentPartsSchema(); + private bool _formVisible = false; + private StandardComponentPartsDesigner _componentPartsForm; private bool _textFormVisible = false; private string _textFormValue; @@ -168,22 +100,18 @@ Width="600" MaxBodyHeight="700"> _componentPartsList = await ComponentPartsListState.GetOrAddAsync(this, async () => { - return await LoadComponentPartsAsync(); + return await LoadComponentPartsListAsync(); }); } - private async Task> LoadComponentPartsAsync() + private async Task> LoadComponentPartsListAsync() { return await ComponentPartsAppService.GetListAsync(LibraryId); } private async Task GetComponentPartsAsync(string componentPartsId) { - var component = await ComponentPartsAppService.GetByIdAsync(LibraryId, componentPartsId); - _textComponentFragment = component.Fragment.ToJson(writeIndented: true); - _textDataSource = component.DataSource?.ToJson(writeIndented: true); - _textAttributeDefineGroups = component.AttributeDefineGroups?.ToJson(writeIndented: true); - return component; + return await ComponentPartsAppService.GetByIdAsync(LibraryId, componentPartsId); } private void CreateAsync() @@ -230,35 +158,7 @@ Width="600" MaxBodyHeight="700"> private async Task OnConfirmAsync(MouseEventArgs e) { - var validate = _form.Validate(); - if (validate) - { - _componentPartsSchema.Fragment = _textComponentFragment.FromJson(); - _componentPartsSchema.DataSource = _textDataSource.FromJson(); - _componentPartsSchema.AttributeDefineGroups = _textAttributeDefineGroups.FromJson(); - var isSuccess = await SaveComponentPartsSchemaAsync(); - if (isSuccess) - { - _formVisible = false; - _form.Submit(); - await Message.SuccessAsync("保存成功!"); - _form.Reset(); - } - else - { - _formVisible = true; - await Message.ErrorAsync("保存失败"); - } - } - else - { - _formVisible = true; - } - } - - private async Task OnFinishAsync() - { - _componentPartsList = await LoadComponentPartsAsync(); + await _componentPartsForm.SubmitAsync(); } private async Task OnTextFormConfirmAsync(MouseEventArgs e) @@ -268,7 +168,7 @@ Width="600" MaxBodyHeight="700"> if (isSuccess) { _textFormVisible = false; - _componentPartsList = await LoadComponentPartsAsync(); + _componentPartsList = await LoadComponentPartsListAsync(); await Message.SuccessAsync("保存成功!"); } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/PagePartsDesigner.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/PagePartsDesigner.razor index 4f22be3..0f531fa 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/PagePartsDesigner.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/PagePartsDesigner.razor @@ -1,4 +1,4 @@ -@page "/designer/pageparts/{PartsId}" +@page "/myparts/page/designer/{PartsId}" @namespace H.LowCode.PartsDesignEngine @inherits DesignEngineLowCodePageComponentBase @layout PartsDesignEngineLayout diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/StandardComponentPartsDesigner.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/StandardComponentPartsDesigner.razor new file mode 100644 index 0000000..b6199c4 --- /dev/null +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/StandardComponentPartsDesigner.razor @@ -0,0 +1,127 @@ +@page "/myparts/component/standarddesigner/{Tab?}" +@namespace H.LowCode.PartsDesignEngine + +@inherits DesignEngineLowCodeComponentBase +@layout PartsDesignEngineLayout + +@inject IComponentPartsAppService ComponentPartsAppService + +
+
+ + + + + + + + + + + + + + + 原子组件 + 组合组件 + + + + + + @if (context.IsContainer == false) + { + + + + @if (context.IsSupportDataSource) + { + + + + } + } + 组件 RenderFragment: + + + + + + + + + 待发布 + 已发布 + + +
+
+ 组件设计面板属性: + + + + @if (context.IsContainer == false && context.IsSupportDataSource) + { + 数据源: + + + + } +
+
+
+ +@code{ + [Parameter] + public ComponentPartsSchema ComponentParts { get; set; } + + private Form _form; + + private string _textComponentFragment; + private string _textDataSource; + private string _textAttributeDefineGroups; + + protected override async Task OnInitializedAsync() + { + Init(); + + await base.OnInitializedAsync(); + } + + private void Init() + { + _textComponentFragment = ComponentParts.Fragment.ToJson(writeIndented: true); + _textDataSource = ComponentParts.DataSource?.ToJson(writeIndented: true); + _textAttributeDefineGroups = ComponentParts.AttributeDefineGroups?.ToJson(writeIndented: true); + } + + public async Task SubmitAsync() + { + var validate = _form.Validate(); + if (validate) + { + ComponentParts.Fragment = _textComponentFragment.FromJson(); + ComponentParts.DataSource = _textDataSource.FromJson(); + ComponentParts.AttributeDefineGroups = _textAttributeDefineGroups.FromJson(); + var isSuccess = await SaveComponentPartsSchemaAsync(); + if (isSuccess) + { + _form.Submit(); + await Message.SuccessAsync("保存成功!"); + _form.Reset(); + } + else + { + await Message.ErrorAsync("保存失败"); + } + } + } + + private async Task SaveComponentPartsSchemaAsync() + { + return await ComponentPartsAppService.SaveAsync(ComponentParts); + } + +} \ No newline at end of file diff --git a/src/H.LowCode.sln b/src/H.LowCode.sln index dd6a0c4..c60d23a 100644 --- a/src/H.LowCode.sln +++ b/src/H.LowCode.sln @@ -68,8 +68,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.LowCode.ComponentBase", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.LowCode.DbMigrator", "Tools\H.LowCode.DbMigrator\H.LowCode.DbMigrator.csproj", "{F33C7AB6-CA4B-4254-9A75-D803FEDE0CB4}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesignEngine", "DesignEngine", "{A32809CE-52C6-4E00-92D3-76903D8D9C61}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.LowCode.MetaSchema", "Common\H.LowCode.MetaSchema\H.LowCode.MetaSchema.csproj", "{1BF619BF-4992-46CC-B831-8E3ABA9A435A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.LowCode.MetaSchema.DesignEngine", "Common\H.LowCode.MetaSchema.DesignEngine\H.LowCode.MetaSchema.DesignEngine.csproj", "{E1C86933-B2F8-4C53-BF19-AE67A206B00A}" @@ -254,7 +252,7 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {47EE6944-D5F8-46CD-A552-29A237BE87BD} = {89FE3DE3-2E58-4835-A476-CA2E309A1B3F} - {9BE2FECD-B648-4B15-B394-E354F98D1B73} = {A32809CE-52C6-4E00-92D3-76903D8D9C61} + {9BE2FECD-B648-4B15-B394-E354F98D1B73} = {4D070ACB-8367-4889-806E-FA6EEA0D6A67} {4E9BFDA3-AFC6-41F3-817C-FD9E82322BDA} = {A63C9652-517D-4BC3-B935-74D946AB0761} {B8524D2C-164A-46A1-83A3-5F47BC645B01} = {7E5B26AA-4F89-4B8C-B743-AE3F04C9DD58} {2FEAC795-B93C-4164-8A4D-92B2F26F4994} = {B8524D2C-164A-46A1-83A3-5F47BC645B01} @@ -268,7 +266,7 @@ Global {68C4F1D4-C479-4679-8074-B13EA898F4A0} = {240CD8ED-49F9-47E0-91B1-B170252E5437} {8490E431-5F81-4EF4-B765-FF0AC8A6EA10} = {A63C9652-517D-4BC3-B935-74D946AB0761} {9832C124-BE18-48FA-8C60-48857D9B4DA1} = {844CDB6A-8081-4769-8905-8A0D279D6101} - {8C48BC1B-FD9B-4C39-929D-9458BD9B42E1} = {A32809CE-52C6-4E00-92D3-76903D8D9C61} + {8C48BC1B-FD9B-4C39-929D-9458BD9B42E1} = {4D070ACB-8367-4889-806E-FA6EEA0D6A67} {C81282DA-2FD7-4DA4-A607-DBADD3ACD367} = {7E5B26AA-4F89-4B8C-B743-AE3F04C9DD58} {3515BFA8-8D57-4E9E-903D-D74982DE27E0} = {7E5B26AA-4F89-4B8C-B743-AE3F04C9DD58} {543E3996-E69A-4EE6-ABD9-9A69A8383DB8} = {89FE3DE3-2E58-4835-A476-CA2E309A1B3F} @@ -277,7 +275,6 @@ Global {DE9247F1-BABC-4098-A928-960E8E4EC20E} = {4D070ACB-8367-4889-806E-FA6EEA0D6A67} {43C23BD6-6228-4C41-BD73-FC1508178F33} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} {F33C7AB6-CA4B-4254-9A75-D803FEDE0CB4} = {F3ABC418-7234-4DBA-8A5A-6B286A25B8AD} - {A32809CE-52C6-4E00-92D3-76903D8D9C61} = {7E5B26AA-4F89-4B8C-B743-AE3F04C9DD58} {1BF619BF-4992-46CC-B831-8E3ABA9A435A} = {4E9BFDA3-AFC6-41F3-817C-FD9E82322BDA} {E1C86933-B2F8-4C53-BF19-AE67A206B00A} = {4E9BFDA3-AFC6-41F3-817C-FD9E82322BDA} {AFC84C58-A075-45C3-BA33-609F067B471A} = {4E9BFDA3-AFC6-41F3-817C-FD9E82322BDA} -- Gitee From 282da8bfbc76093f0db999a99225ec6193f1baaf Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 27 Jul 2025 21:27:02 +0800 Subject: [PATCH 05/33] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=20global.prop?= =?UTF-8?q?s=20=E4=B8=BA=20common.props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/page/g0qcqxzd.json | 2 +- .../H.LowCode.ComponentBase.csproj | 2 +- .../LowCodeComponentBase.cs | 2 +- .../LowCodePageComponentBase.cs | 13 +++-- .../H.LowCode.Components.Defaults.csproj | 2 +- .../H.LowCode.Configuration.csproj | 2 +- .../H.LowCode.Entity/H.LowCode.Entity.csproj | 2 +- .../H.LowCode.MetaSchema.DesignEngine.csproj | 2 +- .../H.LowCode.MetaSchema.RenderEngine.csproj | 2 +- .../H.LowCode.MetaSchema.csproj | 2 +- .../PropertySchemas/EventSchema.cs | 5 ++ ....DesignEngine.Application.Contracts.csproj | 2 +- .../H.LowCode.DesignEngine.Application.csproj | 2 +- .../H.LowCode.DesignEngine.Domain.csproj | 2 +- ...de.DesignEngine.EntityFrameworkCore.csproj | 2 +- .../H.LowCode.DesignEngine.Host.Client.csproj | 6 +-- .../Components/App.razor | 1 + .../H.LowCode.DesignEngine.Host.csproj | 2 +- .../H.LowCode.DesignEngine.Model.csproj | 2 +- ...de.DesignEngine.Repository.JsonFile.csproj | 2 +- ...signEngine.Repository.RemoteService.csproj | 2 +- .../H.LowCode.DesignEngine.csproj | 2 +- .../Components/Events/EventList.razor | 3 ++ .../DesignEngineLowCodePageComponentBase.cs | 17 +++--- .../H.LowCode.DesignEngineBase.csproj | 2 +- .../H.LowCode.MyApp/H.LowCode.MyApp.csproj | 2 +- .../H.LowCode.PartsDesignEngine.csproj | 2 +- .../H.LowCode.Workbench.csproj | 2 +- src/Directory.Packages.props | 54 +++++++++---------- src/H.LowCode.sln | 2 +- .../H.LowCode.RenderEngine.Abstraction.csproj | 2 +- ....RenderEngine.Application.Contracts.csproj | 2 +- .../H.LowCode.RenderEngine.Application.csproj | 2 +- .../H.LowCode.RenderEngine.Domain.csproj | 2 +- ...de.RenderEngine.EntityFrameworkCore.csproj | 2 +- .../H.LowCode.RenderEngine.Host.Client.csproj | 2 +- .../H.LowCode.RenderEngine.Host.csproj | 2 +- ...de.RenderEngine.Repository.JsonFile.csproj | 2 +- ...nderEngine.Repository.RemoteService.csproj | 2 +- .../H.LowCode.RenderEngine.csproj | 2 +- .../H.LowCode.Themes.AntBlazor.csproj | 2 +- .../H.LowCode.DbMigrator.csproj | 2 +- .../H.LowCode.MetaMigrator.csproj | 2 +- src/global.props | 13 ----- 44 files changed, 89 insertions(+), 95 deletions(-) delete mode 100644 src/global.props diff --git a/meta/apps/caseapp/page/g0qcqxzd.json b/meta/apps/caseapp/page/g0qcqxzd.json index db1a474..7be0440 100644 --- a/meta/apps/caseapp/page/g0qcqxzd.json +++ b/meta/apps/caseapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"No\",\"t\":\"学号\"},{\"id\":\"vwvoqrn1s\",\"n\":\"Name\",\"t\":\"姓名\"},{\"id\":\"ap0ceewr\",\"n\":\"Age\",\"t\":\"年龄\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-06-23T21:36:56.9654253Z"} \ No newline at end of file +{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"No\",\"t\":\"学号\"},{\"id\":\"vwvoqrn1s\",\"n\":\"Name\",\"t\":\"姓名\"},{\"id\":\"ap0ceewr\",\"n\":\"Age\",\"t\":\"年龄\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-07-20T14:57:44.1450175Z"} \ No newline at end of file diff --git a/src/Common/H.LowCode.ComponentBase/H.LowCode.ComponentBase.csproj b/src/Common/H.LowCode.ComponentBase/H.LowCode.ComponentBase.csproj index a1feb81..c277762 100644 --- a/src/Common/H.LowCode.ComponentBase/H.LowCode.ComponentBase.csproj +++ b/src/Common/H.LowCode.ComponentBase/H.LowCode.ComponentBase.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs index 6139c41..3fb0806 100644 --- a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs +++ b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBase.cs @@ -14,7 +14,7 @@ public abstract class LowCodeComponentBase : AbpComponentBase private LowCodeAppState LowCodeAppState { get; set; } [Inject] - private NavigationManager NavigationManager { get; set; } + protected NavigationManager NavigationManager { get; set; } /// /// 组件状态标识 (用于 ShouldRender 判断) diff --git a/src/Common/H.LowCode.ComponentBase/LowCodePageComponentBase.cs b/src/Common/H.LowCode.ComponentBase/LowCodePageComponentBase.cs index 266b1ca..0a5839d 100644 --- a/src/Common/H.LowCode.ComponentBase/LowCodePageComponentBase.cs +++ b/src/Common/H.LowCode.ComponentBase/LowCodePageComponentBase.cs @@ -1,9 +1,5 @@ using Microsoft.AspNetCore.Components; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Extensions.Logging; namespace H.LowCode.ComponentBase; @@ -12,6 +8,13 @@ namespace H.LowCode.ComponentBase; /// public abstract class LowCodePageComponentBase : LowCodeComponentBase { + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + Logger.LogInformation($"渲染模式: {RendererInfo.Name}, path=/{NavigationManager.ToBaseRelativePath(NavigationManager.Uri)}"); + } + protected static T GetQueryValue(string name) { return default; diff --git a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj index 8657411..b6bc67e 100644 --- a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj +++ b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.Configuration/H.LowCode.Configuration.csproj b/src/Common/H.LowCode.Configuration/H.LowCode.Configuration.csproj index e9d821c..8cad3c7 100644 --- a/src/Common/H.LowCode.Configuration/H.LowCode.Configuration.csproj +++ b/src/Common/H.LowCode.Configuration/H.LowCode.Configuration.csproj @@ -1,5 +1,5 @@  - + diff --git a/src/Common/H.LowCode.Entity/H.LowCode.Entity.csproj b/src/Common/H.LowCode.Entity/H.LowCode.Entity.csproj index 0d6052f..bb34684 100644 --- a/src/Common/H.LowCode.Entity/H.LowCode.Entity.csproj +++ b/src/Common/H.LowCode.Entity/H.LowCode.Entity.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/H.LowCode.MetaSchema.DesignEngine.csproj b/src/Common/H.LowCode.MetaSchema.DesignEngine/H.LowCode.MetaSchema.DesignEngine.csproj index cc66883..a40d73f 100644 --- a/src/Common/H.LowCode.MetaSchema.DesignEngine/H.LowCode.MetaSchema.DesignEngine.csproj +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/H.LowCode.MetaSchema.DesignEngine.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.MetaSchema.RenderEngine/H.LowCode.MetaSchema.RenderEngine.csproj b/src/Common/H.LowCode.MetaSchema.RenderEngine/H.LowCode.MetaSchema.RenderEngine.csproj index d6dcfa1..6e858ae 100644 --- a/src/Common/H.LowCode.MetaSchema.RenderEngine/H.LowCode.MetaSchema.RenderEngine.csproj +++ b/src/Common/H.LowCode.MetaSchema.RenderEngine/H.LowCode.MetaSchema.RenderEngine.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.MetaSchema/H.LowCode.MetaSchema.csproj b/src/Common/H.LowCode.MetaSchema/H.LowCode.MetaSchema.csproj index 1312af6..62a0831 100644 --- a/src/Common/H.LowCode.MetaSchema/H.LowCode.MetaSchema.csproj +++ b/src/Common/H.LowCode.MetaSchema/H.LowCode.MetaSchema.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs index 1b90889..a417809 100644 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs @@ -38,6 +38,11 @@ public class EventSchema [JsonPropertyName("ecs")] public string EventCustomScript { get; set; } #endregion + + /// + /// 事件参数 + /// + public IDictionary EventArgs { get; set; } } public class EventConsumeSchema diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj index a0a27e3..61a8efc 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj index 536867b..60433c2 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Domain/H.LowCode.DesignEngine.Domain.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Domain/H.LowCode.DesignEngine.Domain.csproj index ea6a366..596f484 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Domain/H.LowCode.DesignEngine.Domain.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Domain/H.LowCode.DesignEngine.Domain.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/H.LowCode.DesignEngine.EntityFrameworkCore.csproj b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/H.LowCode.DesignEngine.EntityFrameworkCore.csproj index dcfb689..e815e4f 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/H.LowCode.DesignEngine.EntityFrameworkCore.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/H.LowCode.DesignEngine.EntityFrameworkCore.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj index da8a127..d6925cf 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj @@ -1,12 +1,12 @@  - + true Default - true - false + + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor index f7791fc..587e6f8 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor @@ -27,6 +27,7 @@ + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj index 1dc8207..095ad12 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Model/H.LowCode.DesignEngine.Model.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Model/H.LowCode.DesignEngine.Model.csproj index bf01f63..dd3959f 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Model/H.LowCode.DesignEngine.Model.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Model/H.LowCode.DesignEngine.Model.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Repository.JsonFile/H.LowCode.DesignEngine.Repository.JsonFile.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Repository.JsonFile/H.LowCode.DesignEngine.Repository.JsonFile.csproj index 4c08f03..d628bfd 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Repository.JsonFile/H.LowCode.DesignEngine.Repository.JsonFile.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Repository.JsonFile/H.LowCode.DesignEngine.Repository.JsonFile.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Repository.RemoteService/H.LowCode.DesignEngine.Repository.RemoteService.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Repository.RemoteService/H.LowCode.DesignEngine.Repository.RemoteService.csproj index 4c08f03..d628bfd 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Repository.RemoteService/H.LowCode.DesignEngine.Repository.RemoteService.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Repository.RemoteService/H.LowCode.DesignEngine.Repository.RemoteService.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngine/H.LowCode.DesignEngine.csproj b/src/DesignEngine/H.LowCode.DesignEngine/H.LowCode.DesignEngine.csproj index cb44ed7..786f226 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/H.LowCode.DesignEngine.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine/H.LowCode.DesignEngine.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor index 150509d..024560f 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor @@ -49,6 +49,9 @@ 新标签页 +
+ +
} else if (_currentEvent.EventHandlerType == EventTargetTypeEnum.Component) { diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineLowCodePageComponentBase.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineLowCodePageComponentBase.cs index 7be1476..6ab85f0 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineLowCodePageComponentBase.cs +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineLowCodePageComponentBase.cs @@ -1,19 +1,14 @@ -using Microsoft.AspNetCore.Components; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using AntDesign; +using H.LowCode.ComponentBase; +using Microsoft.AspNetCore.Components; namespace H.LowCode.DesignEngineBase; /// /// 页面组件基类 /// -public abstract class DesignEngineLowCodePageComponentBase : DesignEngineLowCodeComponentBase +public abstract class DesignEngineLowCodePageComponentBase : LowCodePageComponentBase { - protected static T GetQueryValue(string name) - { - return default; - } + [Inject] + protected new IMessageService Message { get; set; } } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/H.LowCode.DesignEngineBase.csproj b/src/DesignEngine/H.LowCode.DesignEngineBase/H.LowCode.DesignEngineBase.csproj index df9b18f..41bf0f0 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/H.LowCode.DesignEngineBase.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/H.LowCode.DesignEngineBase.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.MyApp/H.LowCode.MyApp.csproj b/src/DesignEngine/H.LowCode.MyApp/H.LowCode.MyApp.csproj index d8f8ac0..e1275f8 100644 --- a/src/DesignEngine/H.LowCode.MyApp/H.LowCode.MyApp.csproj +++ b/src/DesignEngine/H.LowCode.MyApp/H.LowCode.MyApp.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj b/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj index 81d85bb..3c128e1 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/DesignEngine/H.LowCode.Workbench/H.LowCode.Workbench.csproj b/src/DesignEngine/H.LowCode.Workbench/H.LowCode.Workbench.csproj index cb41abb..38ec87f 100644 --- a/src/DesignEngine/H.LowCode.Workbench/H.LowCode.Workbench.csproj +++ b/src/DesignEngine/H.LowCode.Workbench/H.LowCode.Workbench.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 6990374..daa9064 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -6,45 +6,45 @@ - - + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - + - + diff --git a/src/H.LowCode.sln b/src/H.LowCode.sln index c60d23a..93d66de 100644 --- a/src/H.LowCode.sln +++ b/src/H.LowCode.sln @@ -14,7 +14,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{8B2D37CA-78EA-401B-B598-EFB3C7FD6517}" ProjectSection(SolutionItems) = preProject Directory.Packages.props = Directory.Packages.props - global.props = global.props + common.props = common.props NuGet.config = NuGet.config nuget.pack.props = nuget.pack.props ..\README.md = ..\README.md diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Abstraction/H.LowCode.RenderEngine.Abstraction.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Abstraction/H.LowCode.RenderEngine.Abstraction.csproj index f66cf58..40fd946 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Abstraction/H.LowCode.RenderEngine.Abstraction.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Abstraction/H.LowCode.RenderEngine.Abstraction.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj index e74e0a4..f64dcd7 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj index 7f2e2ee..5fc089a 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj index 9b6baa7..ccfaffb 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/H.LowCode.RenderEngine.EntityFrameworkCore.csproj b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/H.LowCode.RenderEngine.EntityFrameworkCore.csproj index ac31d00..1ebfafb 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/H.LowCode.RenderEngine.EntityFrameworkCore.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/H.LowCode.RenderEngine.EntityFrameworkCore.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj index 4358d04..58f8b6f 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj @@ -1,6 +1,6 @@  - + true diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj index 0d19620..7b34c6e 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/H.LowCode.RenderEngine.Repository.JsonFile.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/H.LowCode.RenderEngine.Repository.JsonFile.csproj index 15163ee..ef8b4f3 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/H.LowCode.RenderEngine.Repository.JsonFile.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/H.LowCode.RenderEngine.Repository.JsonFile.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/H.LowCode.RenderEngine.Repository.RemoteService.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/H.LowCode.RenderEngine.Repository.RemoteService.csproj index b2c56a6..4a1ed43 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/H.LowCode.RenderEngine.Repository.RemoteService.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/H.LowCode.RenderEngine.Repository.RemoteService.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.RenderEngine/H.LowCode.RenderEngine.csproj b/src/RenderEngine/H.LowCode.RenderEngine/H.LowCode.RenderEngine.csproj index 8fe5b14..12193f1 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine/H.LowCode.RenderEngine.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine/H.LowCode.RenderEngine.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/RenderEngine/H.LowCode.Themes.AntBlazor/H.LowCode.Themes.AntBlazor.csproj b/src/RenderEngine/H.LowCode.Themes.AntBlazor/H.LowCode.Themes.AntBlazor.csproj index cc03d50..828bac7 100644 --- a/src/RenderEngine/H.LowCode.Themes.AntBlazor/H.LowCode.Themes.AntBlazor.csproj +++ b/src/RenderEngine/H.LowCode.Themes.AntBlazor/H.LowCode.Themes.AntBlazor.csproj @@ -1,6 +1,6 @@  - + diff --git a/src/Tools/H.LowCode.DbMigrator/H.LowCode.DbMigrator.csproj b/src/Tools/H.LowCode.DbMigrator/H.LowCode.DbMigrator.csproj index a991d83..c385688 100644 --- a/src/Tools/H.LowCode.DbMigrator/H.LowCode.DbMigrator.csproj +++ b/src/Tools/H.LowCode.DbMigrator/H.LowCode.DbMigrator.csproj @@ -1,6 +1,6 @@  - + Exe diff --git a/src/Tools/H.LowCode.MetaMigrator/H.LowCode.MetaMigrator.csproj b/src/Tools/H.LowCode.MetaMigrator/H.LowCode.MetaMigrator.csproj index 5c8ee92..3f47529 100644 --- a/src/Tools/H.LowCode.MetaMigrator/H.LowCode.MetaMigrator.csproj +++ b/src/Tools/H.LowCode.MetaMigrator/H.LowCode.MetaMigrator.csproj @@ -1,6 +1,6 @@  - + Exe diff --git a/src/global.props b/src/global.props deleted file mode 100644 index 7fc71cf..0000000 --- a/src/global.props +++ /dev/null @@ -1,13 +0,0 @@ - - - net9.0 - enable - - 0.5.0 - False - - H - H - H.LowCode - - \ No newline at end of file -- Gitee From e1c78149e7369c215166cd7df322ba19d9c560c9 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sat, 9 Aug 2025 12:09:43 +0800 Subject: [PATCH 06/33] =?UTF-8?q?=E6=8F=90=E4=BA=A4=20common.props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common.props | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/common.props diff --git a/src/common.props b/src/common.props new file mode 100644 index 0000000..7fc71cf --- /dev/null +++ b/src/common.props @@ -0,0 +1,13 @@ + + + net9.0 + enable + + 0.5.0 + False + + H + H + H.LowCode + + \ No newline at end of file -- Gitee From 7615db13fe5b69e2a6a383c2eb1be6b58b3ed722 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Wed, 13 Aug 2025 23:17:37 +0800 Subject: [PATCH 07/33] =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=8A=A8=E7=94=BB?= =?UTF-8?q?=E6=95=88=E6=9E=9C=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/page/fhumgxyk.json | 14 +- .../ComponentDesignStateSchema.cs | 12 ++ .../DragDropComponents/DropItem.razor | 164 +++++++++++++++--- .../DragDropComponents/DropItem.razor.css | 5 + .../DropItemContainer.razor | 73 +++++--- .../Services/DragDropStateService.cs | 15 ++ .../Services/DragDropStateService.cs | 15 ++ 7 files changed, 243 insertions(+), 55 deletions(-) diff --git a/meta/apps/caseapp/page/fhumgxyk.json b/meta/apps/caseapp/page/fhumgxyk.json index a29ce01..0f3b19a 100644 --- a/meta/apps/caseapp/page/fhumgxyk.json +++ b/meta/apps/caseapp/page/fhumgxyk.json @@ -192,7 +192,7 @@ "id": "vjolyn1r", "pid": "zkgldg5b", "n": "f_field6", - "lb": "单选框", + "lb": "单选框3", "sptds": true, "stl": { "itemh": 85, @@ -247,7 +247,7 @@ "id": "4trfp5bk", "pid": "zkgldg5b", "n": "f_field8", - "lb": "复选框", + "lb": "复选框4", "sptds": true, "stl": { "itemh": 85, @@ -279,7 +279,7 @@ "id": "vdyv8q2ay", "pid": "zkgldg5b", "n": "f_field10", - "lb": "日期选择器", + "lb": "日期选择器5", "stl": { "itemh": 85, "labelw": 180, @@ -308,7 +308,7 @@ "id": "itnmgtzg", "pid": "zkgldg5b", "n": "f_field13", - "lb": "时间选择器", + "lb": "时间选择器6", "stl": { "itemh": 85, "labelw": 180, @@ -339,7 +339,7 @@ "id": "ibgtanur", "pid": "ongkggvjy", "n": "f_field7", - "lb": "文本框", + "lb": "文本框7", "stl": { "itemh": 85, "labelw": 180, @@ -368,7 +368,7 @@ "id": "c9acpmcp", "pid": "ongkggvjy", "n": "f_field11", - "lb": "选择器", + "lb": "选择器8", "sptds": true, "stl": { "itemh": 85, @@ -398,7 +398,7 @@ "id": "cgfb0e64", "pid": "ongkggvjy", "n": "f_field9", - "lb": "开关", + "lb": "开关9", "stl": { "itemh": 85, "labelw": 180, diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs index 94ccf02..d7fb1df 100644 --- a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs @@ -33,4 +33,16 @@ public class ComponentDesignStateSchema ///
[JsonIgnore] public bool IsDropedAfter { get; set; } + + /// + /// 动画变换样式(用于平滑让位动画) + /// + [JsonIgnore] + public string AnimationTransform { get; set; } = string.Empty; + + /// + /// 是否正在进行让位动画 + /// + [JsonIgnore] + public bool IsAnimating { get; set; } } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor index 4ec3ee7..ee413ba 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor @@ -1,11 +1,12 @@ -@namespace H.LowCode.DesignEngineBase +@namespace H.LowCode.DesignEngineBase @inherits DesignEngineLowCodeComponentBase @inject DragDropStateService DragDropStateService -
Component.IsContainer); DropItemBoxClassMapper.Clear() - .If("dropitem-box-layout", () => Component.IsContainer); + .If("dropitem-box-layout", () => Component.IsContainer) + .If("dropitem-animating", () => Component.DesignState.IsAnimating); } #endregion @@ -110,7 +112,11 @@ private void OnClick() { Component.DesignState.DragEffectStyle = string.Empty; - //DragDropStateService.ResetDragStyle(); + Component.DesignState.AnimationTransform = string.Empty; + Component.DesignState.IsAnimating = false; + + //重置所有组件的动画状态 + ResetAllAnimationStates(); OnItemClick.Invoke(Component); BlazorEventDispatcher.Publish("designengine.dropitem.onclick", Component); @@ -118,12 +124,16 @@ private void OnDragStart(DragEventArgs dragEventArgs) { - Component.DesignState.Opacity = 0.2; + // 隐藏被拖拽组件,避免与让位组件重叠 + Component.DesignState.Opacity = 0; //记录当前选中对象 DragDropStateService.SetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId, Component); + + //重置所有组件的动画状态 + ResetAllAnimationStates(); } - + private void OnDragEnter(DragEventArgs dragEventArgs) { DragDropStateService.SetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId, Component); @@ -131,25 +141,31 @@ private void OnDragOver(DragEventArgs dragEventArgs) { - if (ReferenceEquals(DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId), Component)) + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + if (ReferenceEquals(currentDragComponent, Component)) return; - if (DateTime.Now < DragDropStateService.GetLastDragOverTime(PageCascading.AppId, PageCascading.PageId).AddMilliseconds(100)) - return; + // var lastDragOverComponent = DragDropStateService.GetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId); + // if (ReferenceEquals(lastDragOverComponent, Component)) + // return; //设置移动位置样式,拖拽到目标元素上半部分时,上方添加虚线边框,下半部分时下方添加虚线边框 - if (dragEventArgs.OffsetY < 30) - { - Component.DesignState.DragEffectStyle = "border-top: 2px dashed #1890ff;"; - Component.DesignState.IsDropedAfter = false; - } - else - { - Console.WriteLine($"OnDragOver: bottom"); - Component.DesignState.DragEffectStyle = "border-bottom: 2px dashed #1890ff; height: auto;"; - Component.DesignState.IsDropedAfter = true; - } - DragDropStateService.SetLastDragOverTime(PageCascading.AppId, PageCascading.PageId, DateTime.Now); + // if (dragEventArgs.OffsetY < 30) + // { + // Component.DesignState.DragEffectStyle = "border-top: 2px dashed #1890ff;"; + // Component.DesignState.IsDropedAfter = false; + // } + // else + // { + // Console.WriteLine($"OnDragOver: bottom"); + // Component.DesignState.DragEffectStyle = "border-bottom: 2px dashed #1890ff; height: auto;"; + // Component.DesignState.IsDropedAfter = true; + // } + + //触发让位动画 + TriggerSiblingAnimation(); + + //DragDropStateService.SetLastDragOverTime(PageCascading.AppId, PageCascading.PageId, DateTime.Now); } private void OnDragLeave() @@ -160,6 +176,9 @@ Console.WriteLine("OnDragLeave"); Component.DesignState.DragEffectStyle = string.Empty; + + //清理让位动画 + //ClearSiblingAnimation(); } private void OnMouseOver() @@ -188,4 +207,107 @@ OnItemCopy.Invoke(Component); } #endregion + + #region Animation Methods + /// + /// 重置所有组件的动画状态 + /// + private void ResetAllAnimationStates() + { + // var rootComponent = DragDropStateService.GetRootComponent(PageCascading.AppId, PageCascading.PageId); + // if (rootComponent?.Childrens != null) + // { + // foreach (var child in rootComponent.Childrens) + // { + // child.DesignState.AnimationTransform = string.Empty; + // child.DesignState.IsAnimating = false; + // child.RefreshState(); + // } + // } + } + + /// + /// 触发兄弟组件的让位动画 + /// + private void TriggerSiblingAnimation() + { + var rootComponent = DragDropStateService.GetRootComponent(PageCascading.AppId, PageCascading.PageId); + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + + if (rootComponent?.Childrens == null || currentDragComponent == null) + return; + + var overIndex = rootComponent.Childrens.IndexOf(Component); + var dragIndex = rootComponent.Childrens.IndexOf(currentDragComponent); + + if (overIndex == -1 || dragIndex == -1) + return; + + // 动态计算组件实际宽度(包括边距) + var itemWidthPercent = Component.Style.ItemWidth > 4 ? Component.Style.ItemWidth : (IsInRootContainer ? 24/PageCascading.PageLayout : 24); + var containerWidth = 1200; // 假设容器宽度,实际应该从DOM获取 + var itemWidth = (int)(itemWidthPercent / 24.0 * containerWidth) + 10; // 10px 为边距 + + foreach (var child in rootComponent.Childrens) + { + if (ReferenceEquals(child, currentDragComponent)) + continue; + + var childIndex = rootComponent.Childrens.IndexOf(child); + var shouldMove = false; + var moveDistance = 0; + + //判断是否需要让位以及让位方向 (区间内的组件才需要移动) + if (dragIndex > overIndex) //往前拖拽,向右让位移动 + { + if (childIndex >= overIndex && childIndex < dragIndex) + { + shouldMove = true; + moveDistance = itemWidth; + } + } + else //往后拖拽,向左让位移动 + { + if (childIndex > dragIndex && childIndex <= overIndex) + { + shouldMove = true; + moveDistance = -itemWidth; + } + } + + if (shouldMove) + { + child.DesignState.AnimationTransform = $"translateX({moveDistance}px)"; + child.DesignState.IsAnimating = true; + } + // else + // { + // child.DesignState.AnimationTransform = string.Empty; + // child.DesignState.IsAnimating = false; + // } + + // child.RefreshState(); + } + } + + /// + /// 清理兄弟组件的让位动画 + /// + private void ClearSiblingAnimation() + { + // var rootComponent = DragDropStateService.GetRootComponent(PageCascading.AppId, PageCascading.PageId); + // if (rootComponent?.Childrens != null) + // { + // foreach (var child in rootComponent.Childrens) + // { + // if (!ReferenceEquals(child, DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId))) + // { + // child.DesignState.AnimationTransform = string.Empty; + // child.DesignState.IsAnimating = false; + // child.RefreshState(); + // } + // } + // } + } + #endregion } \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css index 2667cb9..c93114d 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css @@ -1,12 +1,17 @@ .dropitem-box { height: 85px; border: #f0f2f5 solid 2px; + transition: transform 0.3s ease-in-out; } .dropitem-box-layout { height: auto; } +.dropitem-animating { + transition: transform 0.3s ease-in-out; +} + .dropitem { position: relative; display: flex; diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor index 9753cae..de1471c 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.DesignEngineBase +@namespace H.LowCode.DesignEngineBase @inherits DesignEngineLowCodeComponentBase @inject DragDropStateService DragDropStateService @@ -66,16 +66,31 @@ #region Event private void OnDrop() { - DragDropHandler(DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId)); + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + DragDropHandler(currentDragComponent); - //重置拖拽样式 + // 恢复被拖拽组件的透明度 + if (currentDragComponent != null) + { + currentDragComponent.DesignState.Opacity = 1; + } + + //重置拖拽样式和动画状态 DragDropStateService.ResetDragStyle(PageCascading.AppId, PageCascading.PageId); + ResetAllAnimationStates(); } private void OnClick() { if (IsRootContainer) { + // 恢复被拖拽组件的透明度(处理拖拽取消的情况) + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + if (currentDragComponent != null) + { + currentDragComponent.DesignState.Opacity = 1; + } + DragDropStateService.ResetDragStyle(PageCascading.AppId, PageCascading.PageId); } @@ -127,9 +142,9 @@ } else // 组件在 DesignPanel 内部拖拽 { - bool isSameContainer = ReferenceEquals(ContainerComponent, currentDragComponent); - Console.WriteLine($"isSameContainer: {isSameContainer}"); - if (isSameContainer) //同一个 DropItemContainer 内拖拽,排序 + //bool isSameContainer = ReferenceEquals(ContainerComponent, currentDragComponent); + bool isInnerContainer = ContainerComponent.Childrens.Any(t => t.Id == currentDragComponent.Id); + if (isInnerContainer) //在 DropItemContainer 内拖拽,排序 { DropItem_Sorting(ContainerComponent, currentDragComponent, dragOverComponent); } @@ -166,10 +181,10 @@ //如果拖拽到放置区对象上方,按照顺序添加 if (dragOverComponent != null) { - if (dragOverComponent.DesignState.IsDropedAfter) - containerComponent.Childrens.InsertAfter(dragOverComponent, currentDragComponent); - else - containerComponent.Childrens.InsertBefore(dragOverComponent, currentDragComponent); + //if (dragOverComponent.DesignState.IsDropedAfter) + // containerComponent.Childrens.InsertAfter(dragOverComponent, currentDragComponent); + //else + containerComponent.Childrens.InsertBefore(dragOverComponent, currentDragComponent); } else //添加到末尾 { @@ -209,24 +224,12 @@ if (currentDragComponent == DragDropStateService.GetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId)) return; - if (dragOverComponent.DesignState.IsDropedAfter) - containerComponent.Childrens.InsertAfter(dragOverComponent, currentDragComponent); - else - containerComponent.Childrens.InsertBefore(dragOverComponent, currentDragComponent); - - // var indexDraggedOverItem = containerComponent.Childrens.IndexOf(dragOverComponent); - // if (dragOverComponent.IsDroppedToBack == false) - // indexDraggedOverItem -= 1; - - // if (indexDraggedOverItem < 0) - // indexDraggedOverItem = 0; - // if (indexDraggedOverItem > containerComponent.Childrens.Count) - // indexDraggedOverItem = containerComponent.Childrens.Count - 1; + int dragIndex = containerComponent.Childrens.IndexOf(currentDragComponent); + int overIndex = containerComponent.Childrens.IndexOf(dragOverComponent); - // //先移除,再插入对应位置 - // if (containerComponent.Childrens.Contains(currentDragComponent)) - // containerComponent.Childrens.Remove(currentDragComponent); - // containerComponent.Childrens.Insert(indexDraggedOverItem, currentDragComponent); + //var targetIndex = dragOverComponent.DesignState.IsDropedAfter ? overIndex + 1 : overIndex; + containerComponent.Childrens.RemoveAt(dragIndex); + containerComponent.Childrens.Insert(overIndex, currentDragComponent); } private void DropItem_Remove(ComponentPartsSchema containerComponent, ComponentPartsSchema component) @@ -242,6 +245,22 @@ containerComponent.Childrens.Remove(component); } + /// + /// 重置所有组件的动画状态 + /// + private void ResetAllAnimationStates() + { + if (ContainerComponent?.Childrens != null) + { + foreach (var child in ContainerComponent.Childrens) + { + child.DesignState.AnimationTransform = string.Empty; + child.DesignState.IsAnimating = false; + child.RefreshState(); + } + } + } + public void Dispose() { DragDropStateService.ResetComponent(PageCascading.AppId, PageCascading.PageId); diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs index 83e8d74..8f34b2e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs @@ -170,6 +170,8 @@ public class DragDropStateService if (stateSchema.CurrentDragComponent != null) { stateSchema.CurrentDragComponent.DesignState.Opacity = 1; + stateSchema.CurrentDragComponent.DesignState.AnimationTransform = string.Empty; + stateSchema.CurrentDragComponent.DesignState.IsAnimating = false; } if (stateSchema.LastSelectedComponent != null) @@ -181,8 +183,21 @@ public class DragDropStateService if (stateSchema.LastDragOverComponent != null) { stateSchema.LastDragOverComponent.DesignState.DragEffectStyle = string.Empty; + stateSchema.LastDragOverComponent.DesignState.AnimationTransform = string.Empty; + stateSchema.LastDragOverComponent.DesignState.IsAnimating = false; //stateSchema.LastDragOverComponent.RefreshState(); } + + // 重置根组件下所有子组件的动画状态 + if (stateSchema.RootComponent?.Childrens != null) + { + foreach (var child in stateSchema.RootComponent.Childrens) + { + child.DesignState.AnimationTransform = string.Empty; + child.DesignState.IsAnimating = false; + child.RefreshState(); + } + } } #endregion } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs index e7b815f..8e5886d 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs @@ -184,6 +184,8 @@ internal class DragDropStateService if (stateSchema.CurrentDragComponent != null) { stateSchema.CurrentDragComponent.DesignState.Opacity = 1; + stateSchema.CurrentDragComponent.DesignState.AnimationTransform = string.Empty; + stateSchema.CurrentDragComponent.DesignState.IsAnimating = false; } if (stateSchema.LastSelectedComponent != null) @@ -195,8 +197,21 @@ internal class DragDropStateService if (stateSchema.LastDragOverComponent != null) { stateSchema.LastDragOverComponent.DesignState.DragEffectStyle = string.Empty; + stateSchema.LastDragOverComponent.DesignState.AnimationTransform = string.Empty; + stateSchema.LastDragOverComponent.DesignState.IsAnimating = false; //stateSchema.LastDragOverComponent.RefreshState(); } + + // 重置根组件下所有子组件的动画状态 + if (stateSchema.RootComponent?.Childrens != null) + { + foreach (var child in stateSchema.RootComponent.Childrens) + { + child.DesignState.AnimationTransform = string.Empty; + child.DesignState.IsAnimating = false; + child.RefreshState(); + } + } } #endregion } -- Gitee From 0610e79bc8a72beb0ef0ab49da36f712c8ed7d5c Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 17 Aug 2025 20:41:46 +0800 Subject: [PATCH 08/33] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20elementUtils.js=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=8B=96=E6=8B=BD=E5=AF=B9=E8=B1=A1=E5=AE=BD?= =?UTF-8?q?=E5=BA=A6=E3=80=81=E9=AB=98=E5=BA=A6=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E8=AE=A9=E4=BD=8D=E7=A7=BB=E5=8A=A8=E8=B7=9D?= =?UTF-8?q?=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComponentDesignStateSchema.cs | 17 +- .../Components/App.razor | 2 + .../DragDropComponents/DropItem.razor | 189 ++++++++++++++---- .../DropItemContainer.razor | 13 -- .../Dtos/DragDropElementDimensions.cs | 23 +++ .../Services/DragDropStateService.cs | 1 - .../H.LowCode.DesignEngineBase/_Imports.razor | 1 + .../wwwroot/js/elementUtils.js | 49 +++++ .../Services/DragDropStateService.cs | 1 - 9 files changed, 223 insertions(+), 73 deletions(-) create mode 100644 src/DesignEngine/H.LowCode.DesignEngineBase/Dtos/DragDropElementDimensions.cs create mode 100644 src/DesignEngine/H.LowCode.DesignEngineBase/wwwroot/js/elementUtils.js diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs index d7fb1df..071a7aa 100644 --- a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentDesignStateSchema.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System; using System.Text.Json.Serialization; -using System.Threading.Tasks; namespace H.LowCode.MetaSchema.DesignEngine; @@ -16,9 +12,6 @@ public class ComponentDesignStateSchema [JsonIgnore] public bool IsSelected { get; set; } - [JsonIgnore] - public double Opacity { get; set; } = 1; - [JsonIgnore] public string DragEffectStyle { get; set; } @@ -28,12 +21,6 @@ public class ComponentDesignStateSchema [JsonIgnore] public bool IsDroppedFromComponentPanel { get; set; } - /// - /// 拖拽到后面(true:后面 false:前面) - /// - [JsonIgnore] - public bool IsDropedAfter { get; set; } - /// /// 动画变换样式(用于平滑让位动画) /// @@ -45,4 +32,4 @@ public class ComponentDesignStateSchema ///
[JsonIgnore] public bool IsAnimating { get; set; } -} +} \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor index 587e6f8..3f4440e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor @@ -10,6 +10,8 @@ + + diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor index ee413ba..ffcec4b 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor @@ -1,9 +1,13 @@ @namespace H.LowCode.DesignEngineBase @inherits DesignEngineLowCodeComponentBase +@implements IAsyncDisposable @inject DragDropStateService DragDropStateService +@inject IJSRuntime JSRuntime -
+ @onmouseout="OnMouseOut" @onmouseout:stopPropagation + @onmousemove=OnMouseMove @onmousemove:stopPropagation>
@if (Component.DesignState.IsSelected) @@ -61,6 +67,13 @@ protected ClassMapper DropItemBoxClassMapper { get; } = new ClassMapper(); protected ClassMapper DropItemClassMapper { get; } = new ClassMapper(); + private ElementReference itemRef; + private DragDropElementDimensions dimensions; + + private bool isDragging = false; + private double dragX = 0; + private double dragY = 0; + #region Init protected override async Task OnInitializedAsync() { @@ -70,10 +83,25 @@ SetClassMap(); } - protected override void OnAfterRender(bool firstRender) + protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) + { + await UpdateDimensions(); RegisterEventDispatcher(); + } + } + + private async Task UpdateDimensions() + { + try + { + dimensions = await JSRuntime.InvokeAsync("elementUtils.getDimensions", itemRef); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting element dimensions: {ex.Message}"); + } } private void Init() @@ -124,8 +152,8 @@ private void OnDragStart(DragEventArgs dragEventArgs) { - // 隐藏被拖拽组件,避免与让位组件重叠 - Component.DesignState.Opacity = 0; + //标记正在拖拽中 + isDragging = true; //记录当前选中对象 DragDropStateService.SetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId, Component); @@ -145,36 +173,28 @@ if (ReferenceEquals(currentDragComponent, Component)) return; - // var lastDragOverComponent = DragDropStateService.GetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId); - // if (ReferenceEquals(lastDragOverComponent, Component)) - // return; + var lastDragOverComponent = DragDropStateService.GetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId); - //设置移动位置样式,拖拽到目标元素上半部分时,上方添加虚线边框,下半部分时下方添加虚线边框 - // if (dragEventArgs.OffsetY < 30) - // { - // Component.DesignState.DragEffectStyle = "border-top: 2px dashed #1890ff;"; - // Component.DesignState.IsDropedAfter = false; - // } - // else - // { - // Console.WriteLine($"OnDragOver: bottom"); - // Component.DesignState.DragEffectStyle = "border-bottom: 2px dashed #1890ff; height: auto;"; - // Component.DesignState.IsDropedAfter = true; - // } + // 只有当拖拽到不同组件时才触发让位动画,避免连续拖拽问题 + if (!ReferenceEquals(lastDragOverComponent, Component)) + { + // 先清理之前的动画状态 + ClearSiblingAnimation(); - //触发让位动画 - TriggerSiblingAnimation(); + // 更新最后拖拽经过的组件 + DragDropStateService.SetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId, Component); + } - //DragDropStateService.SetLastDragOverTime(PageCascading.AppId, PageCascading.PageId, DateTime.Now); + TriggerSiblingAnimation(); } private void OnDragLeave() { //如果当前被拖拽的组件和拖拽到上面的组件是同一个,直接返回 - if (ReferenceEquals(DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId), Component)) + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + if (ReferenceEquals(currentDragComponent, Component)) return; - Console.WriteLine("OnDragLeave"); Component.DesignState.DragEffectStyle = string.Empty; //清理让位动画 @@ -197,6 +217,29 @@ } } + private void OnMouseMove(MouseEventArgs e) + { + if (!isDragging) + return; + + var newMoveX = e.MovementX; + var newMoveY = e.MovementY; + + // 只有当鼠标位置有明显变化时才更新(减少不必要的重绘) + var deltaX = Math.Abs(newMoveX - dragX); + var deltaY = Math.Abs(newMoveY - dragX); + + if (deltaX > 5 || deltaY > 5) // 5px 的阈值 + { + dragX = newMoveX; + dragX = newMoveY; + + // 计算拖拽过程中的悬停位置 + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + currentDragComponent.DesignState.AnimationTransform = $"translate({newMoveX}px, {newMoveY}px)"; + } + } + private void OnDelete() { OnItemDelete.Invoke(Component); @@ -231,6 +274,8 @@ /// private void TriggerSiblingAnimation() { + if (dimensions == null) return; + var rootComponent = DragDropStateService.GetRootComponent(PageCascading.AppId, PageCascading.PageId); var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); @@ -243,10 +288,9 @@ if (overIndex == -1 || dragIndex == -1) return; - // 动态计算组件实际宽度(包括边距) - var itemWidthPercent = Component.Style.ItemWidth > 4 ? Component.Style.ItemWidth : (IsInRootContainer ? 24/PageCascading.PageLayout : 24); - var containerWidth = 1200; // 假设容器宽度,实际应该从DOM获取 - var itemWidth = (int)(itemWidthPercent / 24.0 * containerWidth) + 10; // 10px 为边距 + // 计算每行可容纳的组件数量 + var itemsPerRow = Math.Floor(dimensions.ContainerWidth / dimensions.ActualWidth); + if (itemsPerRow < 1) itemsPerRow = 1; foreach (var child in rootComponent.Childrens) { @@ -255,41 +299,85 @@ var childIndex = rootComponent.Childrens.IndexOf(child); var shouldMove = false; - var moveDistance = 0; + var moveDistanceX = 0.0; + var moveDistanceY = 0.0; + + // 计算行位置 + var currentRow = Math.Floor(childIndex / itemsPerRow); + var overRow = Math.Floor(overIndex / itemsPerRow); + var dragRow = Math.Floor(dragIndex / itemsPerRow); - //判断是否需要让位以及让位方向 (区间内的组件才需要移动) - if (dragIndex > overIndex) //往前拖拽,向右让位移动 + if (dragIndex > overIndex) //往前拖拽 { if (childIndex >= overIndex && childIndex < dragIndex) { shouldMove = true; - moveDistance = itemWidth; + + if (currentRow == overRow) + { + // 同行移动 + moveDistanceX = dimensions.ActualWidth; + } + else + { + // 跨行移动 + moveDistanceX = -(itemsPerRow - 1) * dimensions.ActualWidth; + moveDistanceY = dimensions.ActualHeight; + } } } - else //往后拖拽,向左让位移动 + else //往后拖拽 { if (childIndex > dragIndex && childIndex <= overIndex) { shouldMove = true; - moveDistance = -itemWidth; + + if (currentRow == overRow) + { + // 同行移动 + moveDistanceX = -dimensions.ActualWidth; + } + else + { + // 跨行移动 + moveDistanceX = (itemsPerRow - 1) * dimensions.ActualWidth; + moveDistanceY = -dimensions.ActualHeight; + } } } if (shouldMove) { - child.DesignState.AnimationTransform = $"translateX({moveDistance}px)"; + if (moveDistanceY != 0) + { + child.DesignState.AnimationTransform = $"translate({moveDistanceX}px, {moveDistanceY}px)"; + } + else + { + child.DesignState.AnimationTransform = $"translateX({moveDistanceX}px)"; + } child.DesignState.IsAnimating = true; + //child.RefreshState(); } - // else - // { - // child.DesignState.AnimationTransform = string.Empty; - // child.DesignState.IsAnimating = false; - // } - - // child.RefreshState(); } } + private void OnDragEnd(DragEventArgs e) + { + isDragging = false; + dragX = 0; + dragY = 0; + + Component.DesignState.DragEffectStyle = string.Empty; + Component.DesignState.AnimationTransform = string.Empty; + Component.DesignState.IsAnimating = false; + + //重置所有组件的动画状态 + ResetAllAnimationStates(); + + StateHasChanged(); + } + /// /// 清理兄弟组件的让位动画 /// @@ -310,4 +398,19 @@ // } } #endregion + + public async ValueTask DisposeAsync() + { + try + { + if (IsInRootContainer) + { + BlazorEventDispatcher.Remove("designengine.pagesetting.pagelayout.onchange"); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error disposing DropItem: {ex.Message}"); + } + } } \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor index de1471c..048df18 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor @@ -69,12 +69,6 @@ var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); DragDropHandler(currentDragComponent); - // 恢复被拖拽组件的透明度 - if (currentDragComponent != null) - { - currentDragComponent.DesignState.Opacity = 1; - } - //重置拖拽样式和动画状态 DragDropStateService.ResetDragStyle(PageCascading.AppId, PageCascading.PageId); ResetAllAnimationStates(); @@ -84,13 +78,6 @@ { if (IsRootContainer) { - // 恢复被拖拽组件的透明度(处理拖拽取消的情况) - var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); - if (currentDragComponent != null) - { - currentDragComponent.DesignState.Opacity = 1; - } - DragDropStateService.ResetDragStyle(PageCascading.AppId, PageCascading.PageId); } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Dtos/DragDropElementDimensions.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/Dtos/DragDropElementDimensions.cs new file mode 100644 index 0000000..d942961 --- /dev/null +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Dtos/DragDropElementDimensions.cs @@ -0,0 +1,23 @@ +using System; + +namespace H.LowCode.DesignEngineBase; + +internal class DragDropElementDimensions +{ + public double Width { get; set; } + public double Height { get; set; } + public double ActualWidth { get; set; } + public double ActualHeight { get; set; } + public double ContainerWidth { get; set; } + public DragDropElementMargin Margin { get; set; } + public double OffsetTop { get; set; } + public double OffsetLeft { get; set; } +} + +internal class DragDropElementMargin +{ + public double Top { get; set; } + public double Right { get; set; } + public double Bottom { get; set; } + public double Left { get; set; } +} \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs index 8f34b2e..3f5924e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs @@ -169,7 +169,6 @@ public class DragDropStateService if (stateSchema.CurrentDragComponent != null) { - stateSchema.CurrentDragComponent.DesignState.Opacity = 1; stateSchema.CurrentDragComponent.DesignState.AnimationTransform = string.Empty; stateSchema.CurrentDragComponent.DesignState.IsAnimating = false; } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/_Imports.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/_Imports.razor index 9ca323c..f10a78d 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/_Imports.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/_Imports.razor @@ -1,4 +1,5 @@ @using Microsoft.AspNetCore.Components.Web +@using Microsoft.JSInterop @using AntDesign @using AntDesign.ProLayout @using H.LowCode.ComponentBase diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/wwwroot/js/elementUtils.js b/src/DesignEngine/H.LowCode.DesignEngineBase/wwwroot/js/elementUtils.js new file mode 100644 index 0000000..dd16f44 --- /dev/null +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/wwwroot/js/elementUtils.js @@ -0,0 +1,49 @@ +window.elementUtils = { + // ȡԪسߴϢmargin + getDimensions: function (element) { + if (!element) return null; + + const rect = element.getBoundingClientRect(); + const computedStyle = window.getComputedStyle(element); + const containerWidth = element.parentElement ? element.parentElement.getBoundingClientRect().width : 0; + + // ʵʳߴ磨margin + const margin = { + top: parseFloat(computedStyle.marginTop), + right: parseFloat(computedStyle.marginRight), + bottom: parseFloat(computedStyle.marginBottom), + left: parseFloat(computedStyle.marginLeft) + }; + + return { + width: rect.width, + height: rect.height, + actualWidth: rect.width + margin.left + margin.right, + actualHeight: rect.height + margin.top + margin.bottom, + containerWidth: containerWidth, + margin: margin, + offsetTop: rect.top, + offsetLeft: rect.left + }; + }, + + // Ϣ + getContainerInfo: function (element) { + if (!element || !element.parentElement) return null; + + const container = element.parentElement; + const containerRect = container.getBoundingClientRect(); + const computedStyle = window.getComputedStyle(container); + + return { + width: containerRect.width, + height: containerRect.height, + padding: { + top: parseFloat(computedStyle.paddingTop), + right: parseFloat(computedStyle.paddingRight), + bottom: parseFloat(computedStyle.paddingBottom), + left: parseFloat(computedStyle.paddingLeft) + } + }; + } +}; \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs index 8e5886d..b277d2f 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs @@ -183,7 +183,6 @@ internal class DragDropStateService if (stateSchema.CurrentDragComponent != null) { - stateSchema.CurrentDragComponent.DesignState.Opacity = 1; stateSchema.CurrentDragComponent.DesignState.AnimationTransform = string.Empty; stateSchema.CurrentDragComponent.DesignState.IsAnimating = false; } -- Gitee From 46375478bd819f784ed49e608f29b50d4180a008 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 17 Aug 2025 21:04:42 +0800 Subject: [PATCH 09/33] =?UTF-8?q?ondragenter=20=E5=A2=9E=E5=8A=A0=20preven?= =?UTF-8?q?tDefault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DragDropComponents/DropItem.razor | 2 +- .../DragDropComponents/DropItemContainer.razor | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor index ffcec4b..ac6a4aa 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor @@ -14,7 +14,7 @@ @Component.Style.DefaultStyle @Component.Style.CustomStyle" @onclick="OnClick" @onclick:stopPropagation @ondragstart="OnDragStart" @ondragstart:stopPropagation - @ondragenter="OnDragEnter" @ondragenter:stopPropagation + @ondragenter="OnDragEnter" @ondragenter:preventDefault @ondragenter:stopPropagation @ondragover="OnDragOver" @ondragover:preventDefault @ondragover:stopPropagation @ondragleave="OnDragLeave" @ondragleave:stopPropagation @ondragend="OnDragEnd" @ondragend:stopPropagation diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor index 048df18..674adb3 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor @@ -3,7 +3,9 @@ @inject DragDropStateService DragDropStateService -
-- Gitee From e781fcd95c0806fcb335b63643edcc58a942efeb Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 17 Aug 2025 22:17:26 +0800 Subject: [PATCH 10/33] =?UTF-8?q?=E6=8B=96=E6=8B=BD=E8=AE=A9=E4=BD=8D?= =?UTF-8?q?=E6=8D=A2=E8=A1=8C=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DragDropComponents/DropItem.razor | 76 +++++++++---------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor index ac6a4aa..29c12f6 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor @@ -71,8 +71,10 @@ private DragDropElementDimensions dimensions; private bool isDragging = false; - private double dragX = 0; - private double dragY = 0; + private double initialX = 0; + private double initialY = 0; + private double dragOffsetX = 0; + private double dragOffsetY = 0; #region Init protected override async Task OnInitializedAsync() @@ -201,6 +203,24 @@ //ClearSiblingAnimation(); } + private void OnDragEnd(DragEventArgs e) + { + isDragging = false; + initialX = 0; + initialY = 0; + dragOffsetX = 0; + dragOffsetY = 0; + + Component.DesignState.DragEffectStyle = string.Empty; + Component.DesignState.AnimationTransform = string.Empty; + Component.DesignState.IsAnimating = false; + + //重置所有组件的动画状态 + ResetAllAnimationStates(); + + StateHasChanged(); + } + private void OnMouseOver() { if (Component.DesignState.IsSelected == false) @@ -222,22 +242,13 @@ if (!isDragging) return; - var newMoveX = e.MovementX; - var newMoveY = e.MovementY; + // 计算相对于初始位置的偏移量 + dragOffsetX += e.MovementX; + dragOffsetY += e.MovementY; - // 只有当鼠标位置有明显变化时才更新(减少不必要的重绘) - var deltaX = Math.Abs(newMoveX - dragX); - var deltaY = Math.Abs(newMoveY - dragX); - - if (deltaX > 5 || deltaY > 5) // 5px 的阈值 - { - dragX = newMoveX; - dragX = newMoveY; - - // 计算拖拽过程中的悬停位置 - var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); - currentDragComponent.DesignState.AnimationTransform = $"translate({newMoveX}px, {newMoveY}px)"; - } + // 更新组件的变换样式,使其跟随鼠标移动 + Component.DesignState.AnimationTransform = $"translate({dragOffsetX}px, {dragOffsetY}px)"; + Component.DesignState.IsAnimating = true; } private void OnDelete() @@ -302,18 +313,14 @@ var moveDistanceX = 0.0; var moveDistanceY = 0.0; - // 计算行位置 - var currentRow = Math.Floor(childIndex / itemsPerRow); - var overRow = Math.Floor(overIndex / itemsPerRow); - var dragRow = Math.Floor(dragIndex / itemsPerRow); - - if (dragIndex > overIndex) //往前拖拽 + if (dragIndex > overIndex) //往前拖拽,向后移动 { if (childIndex >= overIndex && childIndex < dragIndex) { shouldMove = true; - if (currentRow == overRow) + var isChangeRow = (childIndex + 1) % itemsPerRow == 0; + if (!isChangeRow) { // 同行移动 moveDistanceX = dimensions.ActualWidth; @@ -326,13 +333,14 @@ } } } - else //往后拖拽 + else //往后拖拽,向前移动 { if (childIndex > dragIndex && childIndex <= overIndex) { shouldMove = true; - if (currentRow == overRow) + var isChangeRow = (childIndex + 1) % itemsPerRow == 1; + if (!isChangeRow) { // 同行移动 moveDistanceX = -dimensions.ActualWidth; @@ -362,22 +370,6 @@ } } - private void OnDragEnd(DragEventArgs e) - { - isDragging = false; - dragX = 0; - dragY = 0; - - Component.DesignState.DragEffectStyle = string.Empty; - Component.DesignState.AnimationTransform = string.Empty; - Component.DesignState.IsAnimating = false; - - //重置所有组件的动画状态 - ResetAllAnimationStates(); - - StateHasChanged(); - } - /// /// 清理兄弟组件的让位动画 /// -- Gitee From d31de8846bb97df0e99a2918b29a088ac650a66d Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 17 Aug 2025 23:50:12 +0800 Subject: [PATCH 11/33] =?UTF-8?q?DropItem=20=E9=87=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E4=B8=BA=20DraggableItem=EF=BC=8CDropItemContainer=20=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=BA=20DraggableContainer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/LcCard.razor | 2 +- .../Components/LcFlex.razor | 2 +- .../Components/LcGrid.razor | 2 +- .../Components/LcTabs.razor | 2 +- .../Components/App.razor | 2 - .../DesignPanel/DesignPanel.razor | 2 +- .../SettingPanel/SettingPanel.razor | 4 +- .../DesignEngineDynamicComponentBase.cs | 6 +-- .../ComponentItem.razor | 0 .../ComponentItem.razor.css | 0 .../DraggableContainer.razor} | 26 +++++------ .../DraggableContainer.razor.css} | 2 +- .../DraggableItem.razor} | 46 ++++++++++--------- .../DraggableItem.razor.css} | 28 +++++------ .../Services/DragDropStateService.cs | 2 +- .../DesignPanel/ComponentDesignPanel.razor | 2 +- .../DesignPanel/PageDesignPanel.razor | 2 +- .../Services/DragDropStateService.cs | 2 +- .../SettingPanel/SettingPanel.razor | 4 +- 19 files changed, 68 insertions(+), 68 deletions(-) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents => DraggableComponents}/ComponentItem.razor (100%) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents => DraggableComponents}/ComponentItem.razor.css (100%) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents/DropItemContainer.razor => DraggableComponents/DraggableContainer.razor} (89%) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents/DropItemContainer.razor.css => DraggableComponents/DraggableContainer.razor.css} (44%) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents/DropItem.razor => DraggableComponents/DraggableItem.razor} (89%) rename src/DesignEngine/H.LowCode.DesignEngineBase/{DragDropComponents/DropItem.razor.css => DraggableComponents/DraggableItem.razor.css} (74%) diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcCard.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcCard.razor index f879b1c..49b67ae 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcCard.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcCard.razor @@ -6,7 +6,7 @@ @* More *@ @* *@ @* *@ -@* { component.Style.DefaultStyle="min-height:90px; height:auto; background: #f4f7fa;";})"> *@ +@* { component.Style.DefaultStyle="min-height:90px; height:auto; background: #f4f7fa;";})"> *@ @* *@ @* *@ diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcFlex.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcFlex.razor index 370b4c5..9988233 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcFlex.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcFlex.razor @@ -2,7 +2,7 @@ @* @inherits LowCodeComponentBase *@ @* *@ -@* *@ +@* *@ @* *@ @* @code { *@ diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcGrid.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcGrid.razor index 0437cdf..24e4592 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcGrid.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcGrid.razor @@ -10,7 +10,7 @@ @* { *@ @* string key = $"gridcontainer-{rr}-{c}"; *@ @* *@ -@* *@ +@* *@ @* *@ @* } *@ @* *@ diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTabs.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTabs.razor index 830ed95..60ec08c 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTabs.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTabs.razor @@ -6,7 +6,7 @@ @* { *@ @* string key = $"tab-{i}"; *@ @* *@ -@* *@ +@* *@ @* *@ @* } *@ @* *@ diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor index 3f4440e..587e6f8 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor @@ -10,8 +10,6 @@ - - diff --git a/src/DesignEngine/H.LowCode.DesignEngine/DesignPanel/DesignPanel.razor b/src/DesignEngine/H.LowCode.DesignEngine/DesignPanel/DesignPanel.razor index 581abba..d96a258 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/DesignPanel/DesignPanel.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/DesignPanel/DesignPanel.razor @@ -7,7 +7,7 @@ @if (_rootComponent != null) {
- +
} diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/SettingPanel.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/SettingPanel.razor index 7ec64b3..30f0a47 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/SettingPanel.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/SettingPanel.razor @@ -50,7 +50,7 @@ private void RegisterEventDispatcher() { //订阅设计面板中的组件点击事件 - BlazorEventDispatcher.Subscribe("designengine.dropitem.onclick", (value) => + BlazorEventDispatcher.Subscribe("designengine.draggableitem.onclick", (value) => { _component = (ComponentPartsSchema)value; _showPropertyPanel = true; @@ -59,7 +59,7 @@ }); //订阅设计面板取消选中事件 - BlazorEventDispatcher.Subscribe("designengine.dropitem.onblur", (value) => + BlazorEventDispatcher.Subscribe("designengine.draggableitem.onblur", (value) => { _component = null; _showPropertyPanel = false; diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineDynamicComponentBase.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineDynamicComponentBase.cs index 692a08e..2879f03 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineDynamicComponentBase.cs +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DesignEngineDynamicComponentBase.cs @@ -159,7 +159,7 @@ public abstract class DesignEngineDynamicComponentBase : LowCodeDynamicComponent if (componentFragment.Content.IsNullOrWhiteSpace()) return; - if (string.Equals(componentFragment.Content, $"$({nameof(DropItemContainer)})", + if (string.Equals(componentFragment.Content, $"$({nameof(DraggableContainer)})", StringComparison.OrdinalIgnoreCase)) { //TODO: 此处 containerComponentId 不能保证唯一性, 待优化 @@ -170,7 +170,7 @@ public abstract class DesignEngineDynamicComponentBase : LowCodeDynamicComponent builder.AddAttribute(index++, "ChildContent", (RenderFragment)(childBuilder => { - childBuilder.OpenComponent(index++); + childBuilder.OpenComponent(index++); childBuilder.AddAttribute(index++, "ContainerComponent", containerComponent); childBuilder.CloseComponent(); })); @@ -185,7 +185,7 @@ public abstract class DesignEngineDynamicComponentBase : LowCodeDynamicComponent } #endregion - #region 渲染组件内的 DropItemContainer + #region 渲染组件内的 DraggableContainer private (ComponentPartsSchema, bool) RenderContainerComponent(ComponentPartsSchema component, string key, Action action = null) { var exist = component.Childrens?.Any(t => t.Id == key); diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/ComponentItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/ComponentItem.razor similarity index 100% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/ComponentItem.razor rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/ComponentItem.razor diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/ComponentItem.razor.css b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/ComponentItem.razor.css similarity index 100% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/ComponentItem.razor.css rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/ComponentItem.razor.css diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor similarity index 89% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor index 674adb3..80593eb 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor @@ -3,7 +3,7 @@ @inject DragDropStateService DragDropStateService -
+ }
@@ -83,7 +83,7 @@ DragDropStateService.ResetDragStyle(PageCascading.AppId, PageCascading.PageId); } - BlazorEventDispatcher.Publish("designengine.dropitem.onblur", null); + BlazorEventDispatcher.Publish("designengine.draggableitem.onblur", null); } private void OnItemClick(ComponentPartsSchema component) @@ -104,7 +104,7 @@ private void OnItemDelete(ComponentPartsSchema component) { - DropItem_Remove(ContainerComponent, component); + DraggableItem_Remove(ContainerComponent, component); StateHasChanged(); } @@ -133,11 +133,11 @@ { //bool isSameContainer = ReferenceEquals(ContainerComponent, currentDragComponent); bool isInnerContainer = ContainerComponent.Childrens.Any(t => t.Id == currentDragComponent.Id); - if (isInnerContainer) //在 DropItemContainer 内拖拽,排序 + if (isInnerContainer) //在 DraggableContainer 内拖拽,排序 { - DropItem_Sorting(ContainerComponent, currentDragComponent, dragOverComponent); + DraggableItem_Sorting(ContainerComponent, currentDragComponent, dragOverComponent); } - else //跨 DropItemContainer 拖拽 + else //跨 DraggableContainer 拖拽 { DragItem_Move(ContainerComponent, currentDragComponent, dragOverComponent); } @@ -182,19 +182,19 @@ } /// - /// 跨 DropItemContainer 移动 DropItem + /// 跨 DraggableContainer 移动 DraggableItem /// /// /// /// private void DragItem_Move(ComponentPartsSchema newContainerComponent, ComponentPartsSchema currentDragComponent, ComponentPartsSchema dragOverComponent) { - //上一个 DropItemContainer 移除 + //上一个 DraggableContainer 移除 var oldContainerComponent = DragDropStateService.FindComponentById(PageCascading.AppId, PageCascading.PageId, currentDragComponent.ParentId); oldContainerComponent.Childrens.Remove(currentDragComponent); - oldContainerComponent.RefreshState(); //刷新上一个 DropItemContainer,使 Remove 立即生效 + oldContainerComponent.RefreshState(); //刷新上一个 DraggableContainer,使 Remove 立即生效 - //当前 DropItemContainer 新增 + //当前 DraggableContainer 新增 currentDragComponent.ParentId = newContainerComponent.Id; DragItem_Add(newContainerComponent, currentDragComponent, dragOverComponent); } @@ -205,7 +205,7 @@ /// /// /// - private void DropItem_Sorting(ComponentPartsSchema containerComponent, ComponentPartsSchema currentDragComponent, ComponentPartsSchema dragOverComponent) + private void DraggableItem_Sorting(ComponentPartsSchema containerComponent, ComponentPartsSchema currentDragComponent, ComponentPartsSchema dragOverComponent) { if (dragOverComponent == null) return; @@ -221,7 +221,7 @@ containerComponent.Childrens.Insert(overIndex, currentDragComponent); } - private void DropItem_Remove(ComponentPartsSchema containerComponent, ComponentPartsSchema component) + private void DraggableItem_Remove(ComponentPartsSchema containerComponent, ComponentPartsSchema component) { //将下一个设为选中 int index = containerComponent.Childrens.IndexOf(component); diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor.css b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor.css similarity index 44% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor.css rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor.css index 6ab89af..408a5cb 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItemContainer.razor.css +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableContainer.razor.css @@ -1,3 +1,3 @@ -.dropitemcontainer { +.draggablecontainer { height: 100%; } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor similarity index 89% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor index 29c12f6..be66bc2 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor @@ -5,7 +5,7 @@ @inject DragDropStateService DragDropStateService @inject IJSRuntime JSRuntime -
-
+
@if (Component.DesignState.IsSelected) { -
+
-
-
+
+
-
+
@@ -64,8 +64,8 @@ [Parameter] public Action OnItemCopy { get; set; } - protected ClassMapper DropItemBoxClassMapper { get; } = new ClassMapper(); - protected ClassMapper DropItemClassMapper { get; } = new ClassMapper(); + protected ClassMapper DraggableItemBoxClassMapper { get; } = new ClassMapper(); + protected ClassMapper DraggableItemClassMapper { get; } = new ClassMapper(); private ElementReference itemRef; private DragDropElementDimensions dimensions; @@ -89,6 +89,8 @@ { if (firstRender) { + await JSRuntime.InvokeAsync("import", "./_content/H.LowCode.DesignEngineBase/js/elementUtils.js"); + await UpdateDimensions(); RegisterEventDispatcher(); } @@ -127,14 +129,14 @@ private void SetClassMap() { - DropItemClassMapper.Clear() - .If("dropitem-selected", () => Component.DesignState.IsSelected) - .If("dropitem-component", () => Component.IsContainer == false) - .If("dropitem-container", () => Component.IsContainer); - - DropItemBoxClassMapper.Clear() - .If("dropitem-box-layout", () => Component.IsContainer) - .If("dropitem-animating", () => Component.DesignState.IsAnimating); + DraggableItemClassMapper.Clear() + .If("draggableitem-selected", () => Component.DesignState.IsSelected) + .If("draggableitem-component", () => Component.IsContainer == false) + .If("draggableitem-container", () => Component.IsContainer); + + DraggableItemBoxClassMapper.Clear() + .If("draggableitem-box-layout", () => Component.IsContainer) + .If("draggableitem-animating", () => Component.DesignState.IsAnimating); } #endregion @@ -149,7 +151,7 @@ ResetAllAnimationStates(); OnItemClick.Invoke(Component); - BlazorEventDispatcher.Publish("designengine.dropitem.onclick", Component); + BlazorEventDispatcher.Publish("designengine.draggableitem.onclick", Component); } private void OnDragStart(DragEventArgs dragEventArgs) @@ -186,9 +188,9 @@ // 更新最后拖拽经过的组件 DragDropStateService.SetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId, Component); } - - TriggerSiblingAnimation(); - } + + TriggerSiblingAnimation(); + } private void OnDragLeave() { @@ -240,7 +242,7 @@ private void OnMouseMove(MouseEventArgs e) { if (!isDragging) - return; + return; // 计算相对于初始位置的偏移量 dragOffsetX += e.MovementX; @@ -402,7 +404,7 @@ } catch (Exception ex) { - Console.WriteLine($"Error disposing DropItem: {ex.Message}"); + Console.WriteLine($"Error disposing DraggableItem: {ex.Message}"); } } } \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css similarity index 74% rename from src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css rename to src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css index c93114d..ef7561c 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DragDropComponents/DropItem.razor.css +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css @@ -1,18 +1,18 @@ -.dropitem-box { +.draggableitem-box { height: 85px; border: #f0f2f5 solid 2px; transition: transform 0.3s ease-in-out; } -.dropitem-box-layout { +.draggableitem-box-layout { height: auto; } -.dropitem-animating { +.draggableitem-animating { transition: transform 0.3s ease-in-out; } -.dropitem { +.draggableitem { position: relative; display: flex; height: 100%; @@ -22,32 +22,32 @@ } /* 无法阻止冒泡, 改用 onmouseover, onmouseout 实现 */ - /*.dropitem:not(.dropitem-selected):hover { + /*.draggableitem:not(.draggableitem-selected):hover { outline: #1890ff dashed 1.5px; pointer-events: auto; }*/ -.dropitem-container { +.draggableitem-container { padding: 0; } -.dropitem-component { +.draggableitem-component { padding: 20px 8px 5px 8px; } -.dropitem-selected { +.draggableitem-selected { outline: #1890ff solid 2px; } -.dropitem-border-top { +.draggableitem-border-top { border-top: 2px dashed #1890ff; } -.dropitem-border-bottom { +.draggableitem-border-bottom { border-bottom: 2px dashed #1890ff; } -.dropitem-icon-move { +.draggableitem-icon-move { position: absolute; z-index: 20; top: -2px; @@ -62,7 +62,7 @@ justify-content: center; } -.dropitem-pointer-wrapper { +.draggableitem-pointer-wrapper { position: absolute; z-index: 20; bottom: -2px; @@ -76,11 +76,11 @@ padding: 0 4px; } -.dropitem-pointer { +.draggableitem-pointer { color: #fff; padding: 0 4px; } - .dropitem-pointer:hover { + .draggableitem-pointer:hover { cursor: pointer; } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs index 3f5924e..5052183 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Services/DragDropStateService.cs @@ -212,7 +212,7 @@ public class DragDropStateSchema /// /// 最后选中对象 - /// (当 DropItem 失去焦点时,即页面上没有任何项被选中,LastSelectedModel 仍有值) + /// (当 DraggableItem 失去焦点时,即页面上没有任何项被选中,LastSelectedModel 仍有值) /// public ComponentPartsSchema LastSelectedComponent { get; set; } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/ComponentDesignPanel.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/ComponentDesignPanel.razor index da73659..5d7f695 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/ComponentDesignPanel.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/ComponentDesignPanel.razor @@ -6,7 +6,7 @@ @if (_rootComponent != null) {
- +
} diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/PageDesignPanel.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/PageDesignPanel.razor index 7c027e5..8a9e828 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/PageDesignPanel.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/DesignPanel/PageDesignPanel.razor @@ -6,7 +6,7 @@ @if (_rootComponent != null) {
- +
} diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs index b277d2f..6ec1789 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Services/DragDropStateService.cs @@ -228,7 +228,7 @@ public class DragDropStateSchema /// /// 最后选中对象 - /// (当 DropItem 失去焦点时,即页面上没有任何项被选中,LastSelectedModel 仍有值) + /// (当 DraggableItem 失去焦点时,即页面上没有任何项被选中,LastSelectedModel 仍有值) /// public ComponentPartsSchema LastSelectedComponent { get; set; } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/SettingPanel/SettingPanel.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/SettingPanel/SettingPanel.razor index 0e627dd..ad46031 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/SettingPanel/SettingPanel.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/SettingPanel/SettingPanel.razor @@ -38,7 +38,7 @@ private void RegisterEventDispatcher() { //订阅设计面板中的组件点击事件 - BlazorEventDispatcher.Subscribe("designengine.dropitem.onclick", (value) => + BlazorEventDispatcher.Subscribe("designengine.draggableitem.onclick", (value) => { _component = (ComponentPartsSchema)value; _showPropertyPanel = true; @@ -47,7 +47,7 @@ }); //订阅设计面板取消选中事件 - BlazorEventDispatcher.Subscribe("designengine.dropitem.onblur", (value) => + BlazorEventDispatcher.Subscribe("designengine.draggableitem.onblur", (value) => { _component = null; _showPropertyPanel = false; -- Gitee From 1ec921fe22e059867c455d81b1c6d12d5ef0b4ae Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Tue, 19 Aug 2025 23:20:01 +0800 Subject: [PATCH 12/33] =?UTF-8?q?=E6=8B=96=E6=8B=BD=E6=97=B6=E8=A2=AB?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E7=BB=84=E4=BB=B6=E8=B7=9F=E9=9A=8F=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E7=A7=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DraggableComponents/DraggableItem.razor | 64 +++++++++++++------ .../DraggableItem.razor.css | 9 ++- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor index be66bc2..2bef27e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor @@ -11,6 +11,10 @@ width: @((Component.Style.ItemWidth > 4 ? Component.Style.ItemWidth : (IsInRootContainer ? 24/PageCascading.PageLayout : 24)) /24 * 100)%; min-height: @(Component.Style.ItemHeight)px; transform: @Component.DesignState.AnimationTransform; + will-change: @(Component.DesignState.IsAnimating ? "transform" : "auto"); + transition: @(Component.DesignState.IsAnimating && !isDragging ? "transform 0.2s ease-out" : "none"); + z-index: @(isDragging ? "9999" : "auto"); + position: @(isDragging ? "relative" : "static"); @Component.Style.DefaultStyle @Component.Style.CustomStyle" @onclick="OnClick" @onclick:stopPropagation @ondragstart="OnDragStart" @ondragstart:stopPropagation @@ -19,8 +23,7 @@ @ondragleave="OnDragLeave" @ondragleave:stopPropagation @ondragend="OnDragEnd" @ondragend:stopPropagation @onmouseover="OnMouseOver" @onmouseover:stopPropagation - @onmouseout="OnMouseOut" @onmouseout:stopPropagation - @onmousemove=OnMouseMove @onmousemove:stopPropagation> + @onmouseout="OnMouseOut" @onmouseout:stopPropagation>
@if (Component.DesignState.IsSelected) @@ -73,8 +76,6 @@ private bool isDragging = false; private double initialX = 0; private double initialY = 0; - private double dragOffsetX = 0; - private double dragOffsetY = 0; #region Init protected override async Task OnInitializedAsync() @@ -158,21 +159,33 @@ { //标记正在拖拽中 isDragging = true; + initialX = dragEventArgs.ClientX; + initialY = dragEventArgs.ClientY; + Console.WriteLine($"拖拽开始:{initialX}-{initialY}"); //记录当前选中对象 DragDropStateService.SetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId, Component); //重置所有组件的动画状态 ResetAllAnimationStates(); + + // 立即更新组件状态以应用 z-index 样式 + StateHasChanged(); } private void OnDragEnter(DragEventArgs dragEventArgs) { DragDropStateService.SetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId, Component); + + //重置所有组件的动画状态 + ResetAllAnimationStates(); } private void OnDragOver(DragEventArgs dragEventArgs) { + Console.WriteLine($"OnDragOver:{isDragging}"); + TriggerCurrentSiblingAnimation(dragEventArgs.ClientX, dragEventArgs.ClientY); + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); if (ReferenceEquals(currentDragComponent, Component)) return; @@ -188,9 +201,9 @@ // 更新最后拖拽经过的组件 DragDropStateService.SetLastDragOverComponent(PageCascading.AppId, PageCascading.PageId, Component); } - - TriggerSiblingAnimation(); - } + + TriggerSiblingAnimation(); + } private void OnDragLeave() { @@ -208,11 +221,11 @@ private void OnDragEnd(DragEventArgs e) { isDragging = false; + Console.WriteLine("拖拽结束"); initialX = 0; initialY = 0; - dragOffsetX = 0; - dragOffsetY = 0; + // 清理所有拖动相关的样式和状态 Component.DesignState.DragEffectStyle = string.Empty; Component.DesignState.AnimationTransform = string.Empty; Component.DesignState.IsAnimating = false; @@ -220,6 +233,7 @@ //重置所有组件的动画状态 ResetAllAnimationStates(); + // 强制更新组件状态以清理 will-change 和 z-index 属性 StateHasChanged(); } @@ -239,18 +253,27 @@ } } - private void OnMouseMove(MouseEventArgs e) + private void TriggerCurrentSiblingAnimation(double clientX, double clientY) { - if (!isDragging) - return; + if (!isDragging) return; // 计算相对于初始位置的偏移量 - dragOffsetX += e.MovementX; - dragOffsetY += e.MovementY; + var dragOffsetX = clientX - initialX; + var dragOffsetY = clientY - initialY; + + Console.WriteLine($"dragOffset:{dragOffsetX}-{dragOffsetY}"); - // 更新组件的变换样式,使其跟随鼠标移动 - Component.DesignState.AnimationTransform = $"translate({dragOffsetX}px, {dragOffsetY}px)"; - Component.DesignState.IsAnimating = true; + // 优化:只有当偏移量发生变化时才更新,避免不必要的重渲染 + if (Math.Abs(dragOffsetX) < 2 && Math.Abs(dragOffsetY) < 2) + return; + + // 使用 transform3d 优化性能,触发 GPU 加速,添加 will-change 提示浏览器优化 + var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); + currentDragComponent.DesignState.AnimationTransform = $"translate3d({dragOffsetX}px, {dragOffsetY}px, 0)"; + currentDragComponent.DesignState.IsAnimating = true; + + // 使用 RequestAnimationFrame 优化渲染性能 + //StateHasChanged(); } private void OnDelete() @@ -358,16 +381,17 @@ if (shouldMove) { + // 使用 translate3d 优化性能,触发 GPU 加速 if (moveDistanceY != 0) { - child.DesignState.AnimationTransform = $"translate({moveDistanceX}px, {moveDistanceY}px)"; + child.DesignState.AnimationTransform = $"translate3d({moveDistanceX}px, {moveDistanceY}px, 0)"; } else { - child.DesignState.AnimationTransform = $"translateX({moveDistanceX}px)"; + child.DesignState.AnimationTransform = $"translate3d({moveDistanceX}px, 0, 0)"; } child.DesignState.IsAnimating = true; - //child.RefreshState(); + child.RefreshState(); } } } diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css index ef7561c..8353752 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor.css @@ -1,7 +1,8 @@ -.draggableitem-box { +.draggableitem-box { height: 85px; border: #f0f2f5 solid 2px; transition: transform 0.3s ease-in-out; + will-change: transform; } .draggableitem-box-layout { @@ -10,6 +11,7 @@ .draggableitem-animating { transition: transform 0.3s ease-in-out; + will-change: transform; } .draggableitem { @@ -19,6 +21,9 @@ margin: 1px; border: #ffffff solid 2px; background-color: #ffffff; + transform: translate3d(0, 0, 0); + backface-visibility: hidden; + perspective: 1000px; } /* 无法阻止冒泡, 改用 onmouseover, onmouseout 实现 */ @@ -83,4 +88,4 @@ .draggableitem-pointer:hover { cursor: pointer; - } + } \ No newline at end of file -- Gitee From 2dbaaaee44fc6e37de957f2b29a903837e55fd2c Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Wed, 20 Aug 2025 00:58:05 +0800 Subject: [PATCH 13/33] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=9D=9E=E5=BF=85?= =?UTF-8?q?=E8=A6=81=20StateHasChanged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DraggableComponents/DraggableItem.razor | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor index 2bef27e..e8cf81e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/DraggableComponents/DraggableItem.razor @@ -165,12 +165,8 @@ //记录当前选中对象 DragDropStateService.SetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId, Component); - //重置所有组件的动画状态 ResetAllAnimationStates(); - - // 立即更新组件状态以应用 z-index 样式 - StateHasChanged(); } private void OnDragEnter(DragEventArgs dragEventArgs) @@ -229,12 +225,8 @@ Component.DesignState.DragEffectStyle = string.Empty; Component.DesignState.AnimationTransform = string.Empty; Component.DesignState.IsAnimating = false; - //重置所有组件的动画状态 ResetAllAnimationStates(); - - // 强制更新组件状态以清理 will-change 和 z-index 属性 - StateHasChanged(); } private void OnMouseOver() @@ -271,9 +263,6 @@ var currentDragComponent = DragDropStateService.GetCurrentDragComponent(PageCascading.AppId, PageCascading.PageId); currentDragComponent.DesignState.AnimationTransform = $"translate3d({dragOffsetX}px, {dragOffsetY}px, 0)"; currentDragComponent.DesignState.IsAnimating = true; - - // 使用 RequestAnimationFrame 优化渲染性能 - //StateHasChanged(); } private void OnDelete() -- Gitee From 83e592396392f52fa58c24939f1666363f04eace Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 21 Sep 2025 14:56:51 +0800 Subject: [PATCH 14/33] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trae/rules/project_rules.md | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .trae/rules/project_rules.md diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md new file mode 100644 index 0000000..48f05dd --- /dev/null +++ b/.trae/rules/project_rules.md @@ -0,0 +1,57 @@ +### 项目概述 +本项目为可视化低代码平台,旨在通过元数据驱动的方式实现应用的快速构建与渲染。其核心设计目标是将应用的结构、行为和样式抽象为可配置的元数据,从而实现无需编写代码即可完成应用开发。 + +项目基于 .NET 9.0、Abp 和 Blazor,采用模块化分层架构,前端采用 Blazor Auto 模式,后端采用 .NET 9.0 Web API 技术。 + +#### 设计引擎和渲染引擎 +设计引擎(DesignEngine)和渲染引擎(RenderEngine)是系统的两大核心模块,二者通过共享的 Common 模块进行协作。 + +设计引擎:提供可视化编辑界面,允许用户拖拽组件、配置属性、设置数据源和事件。其输出为结构化的元数据文件(JSON),存储于 meta 目录。 +渲染引擎:读取 meta 目录中的元数据,在运行时动态生成 Blazor 组件树,实现应用的展示与交互。 +两者通过 Common 模块中的元数据 Schema 保持契约一致,确保设计时与运行时的行为统一。 + +#### 核心概念 +* 元数据 +在低代码平台中,元数据是驱动系统配置、设计与渲染的核心。它通过结构化的JSON文件进行序列化存储,并在设计引擎与渲染引擎之间传递,实现“一次设计,多端运行”的能力。本文深入分析元数据的设计原理、继承体系、存储结构、合并机制与生命周期管理,揭示其作为系统配置中枢的关键作用。 + +* 应用 +在低代码平台中,“应用”(App)是最顶层的容器,代表一个完整的、可独立运行和部署的业务系统。它不仅定义了系统的名称、标识、图标、描述等基本信息,还通过元数据配置决定了其支持的平台类型和当前的发布状态。每个应用都拥有唯一的标识(Id),并作为组织和管理其内部页面、菜单、数据源等资源的逻辑边界。 + +应用的生命周期由设计引擎(DesignEngine)管理,其运行时表现则由渲染引擎(RenderEngine)负责。设计引擎允许开发者通过可视化界面进行应用的构建和修改,而渲染引擎则将这些元数据转换为最终用户可交互的前端界面。 + +应用的元数据结构基于 AppSchemaBase 抽象类定义,该类继承自 MetaSchemaBase,并包含了一系列核心属性。 + +* 页面 +低代码平台中“页面”作为用户界面基本单元的建模方式。基于 PageSchemaBase 和 PagePropertySchema 等核心类,详细解释页面的类型、布局配置、事件处理机制、组件树结构以及状态管理,阐述页面在设计引擎中的拖拽构建过程和在渲染引擎中的动态加载与渲染流程。 + +* 组件 +“组件”是低代码平台中可复用的UI元素,其设计遵循模块化、可配置和可扩展的原则。组件在设计时通过元数据定义其结构、属性、样式和事件,在运行时根据配置动态渲染。系统通过分层架构将设计时与运行时逻辑分离,确保灵活性与性能。 + +组件的核心实现基于 ComponentSchemaBase 类,并通过设计时专用的 ComponentPartsSchema 扩展支持拖拽、选中状态等交互功能。属性、样式和事件均采用独立的模式进行管理,便于动态配置与持久化。 + +* 数据源 +数据源(DataSource)是低代码平台中实现数据连接与抽象的核心模块。它为前端组件提供统一的数据访问接口,支持多种数据来源,包括数据库、API接口和静态选项。 + +* 菜单 +菜单功能的核心数据结构由 MenuSchema 类定义,该类继承自 MetaSchemaBase,用于描述菜单项的组织方式和行为特性。 + +#### 设计引擎 +##### 物料 +物料的管理对应 H.LowCode.PartsDesignEngine 项目, 物料主要包含组件、主题等,物料的元数据定义在 H.LowCode.MetaSchema.DesignEngine 项目中。 + +##### 页面设计器 +页面设计器用于设计页面,基于已有物料进行拖拽、配置、事件绑定等操作,最终生成页面的元数据文件。 + +页面设计器位于 H.LowCode.DesignEngine 项目的 DesignPage 页面,包含 ComponentPanel(物料库)、DesignPanel(设计区域)、SettingPanel(配置面板)三个部分。 +* 物料库:提供组件等物料的列表,可拖拽到设计区域。 +* 设计区域:可视化编辑页面,支持组件的添加、删除、移动和调整大小。 + * * DesignPanel 包含多个 DraggableContainer,此组件为一个可拖拽组件容器,用于放置可拖拽组件 DraggableItem。 + * * DraggableItem 作为可拖拽组件,用于包裹真实组件,使所有组件具备可拖拽能力。 + * * DraggableItem 包裹的是 DraggableItem 组件,DraggableItem 组件的子组件为真实组件,例如 Button、Input 等。DraggableItem 将组件元数据动态渲染为真实组件,从而实现基于 json 元数据动态渲染页面的效果。 +* 配置面板:对选中的组件进行属性、样式和事件的配置。 + +#### 渲染引擎 +渲染引擎负责根据页面的元数据文件,动态生成 Blazor 组件树,并在前端页面中渲染出来。渲染引擎位于 H.LowCode.RenderEngine 项目中,主要负责以下几个方面的功能: +* 元数据解析:读取页面的元数据文件,解析出组件、样式、事件等信息。 +* 组件渲染:根据解析出的元数据,动态创建 Blazor 组件实例,并将其添加到组件树中。 +* 事件处理:为组件添加事件处理逻辑,确保用户交互能够正确响应。 -- Gitee From 9d451c94e504bde955eaab8a5eff68419569844c Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Thu, 25 Sep 2025 00:33:27 +0800 Subject: [PATCH 15/33] =?UTF-8?q?=E5=88=97=E8=A1=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=95=B0=E6=8D=AE=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/page/g0qcqxzd.json | 2 +- .../ComponentBaseModule.cs | 11 + .../Services/DefaultTableDataProvider.cs | 40 +++ .../Services/ITableDataProvider.cs | 89 ++++++ .../Components/LcTable.razor | 53 +++- .../H.LowCode.Components.Defaults.csproj | 2 + .../LowCodeDefaultComponentModule.cs | 9 +- .../DataSourcePropertyItem.razor | 21 +- .../TableDataSourceSelector.razor | 114 +++++++ .../TableDataSourceSetting.razor | 48 ++- .../DataDTOs/FormDataDTO.cs | 15 +- .../DataDTOs/TableGetListInput.cs | 40 ++- .../DataDTOs/TableGetListOutput.cs | 35 ++- .../DataAppServices/TableDataAppService.cs | 4 +- .../H.LowCode.RenderEngine.Application.csproj | 3 +- .../RenderEngineApplicationModule.cs | 7 +- .../Services/RenderEngineTableDataProvider.cs | 94 ++++++ .../FormDataDomainService.cs | 295 +++++++++++++++++- .../ITableDataDomainService.cs | 10 +- .../TableDataDomainService.cs | 15 +- .../DataRepositories/ITableDataRepository.cs | 10 +- .../H.LowCode.RenderEngine.Domain.csproj | 1 + .../DataRepositories/FormDataRepository.cs | 20 +- .../DataRepositories/TableDataRepository.cs | 132 +++++++- .../RenderEngineEntityFrameworkCoreModule.cs | 10 +- .../RenderEngineHostModule.cs | 2 +- 26 files changed, 1018 insertions(+), 64 deletions(-) create mode 100644 src/Common/H.LowCode.ComponentBase/ComponentBaseModule.cs create mode 100644 src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs create mode 100644 src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs create mode 100644 src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSelector.razor create mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs diff --git a/meta/apps/caseapp/page/g0qcqxzd.json b/meta/apps/caseapp/page/g0qcqxzd.json index 7be0440..2476f62 100644 --- a/meta/apps/caseapp/page/g0qcqxzd.json +++ b/meta/apps/caseapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"No\",\"t\":\"学号\"},{\"id\":\"vwvoqrn1s\",\"n\":\"Name\",\"t\":\"姓名\"},{\"id\":\"ap0ceewr\",\"n\":\"Age\",\"t\":\"年龄\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-07-20T14:57:44.1450175Z"} \ No newline at end of file +{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dst":1,"dsid":"qgzhc7w3z","dsn":"tb_test1","dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"f_field1\",\"t\":\"输入框1\"},{\"id\":\"vwvoqrn1s\",\"n\":\"f_field3\",\"t\":\"输入框2\"},{\"id\":\"ap0ceewr\",\"n\":\"f_field6\",\"t\":\"单选框3\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"},{\"id\":\"es0qoauj\",\"n\":\"f_field10\",\"t\":\"日期选择5\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-09-24T16:27:03.2680438Z"} \ No newline at end of file diff --git a/src/Common/H.LowCode.ComponentBase/ComponentBaseModule.cs b/src/Common/H.LowCode.ComponentBase/ComponentBaseModule.cs new file mode 100644 index 0000000..e84537b --- /dev/null +++ b/src/Common/H.LowCode.ComponentBase/ComponentBaseModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Modularity; + +namespace H.LowCode.ComponentBase; + +public class ComponentBaseModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + // 基础组件模块配置 + } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs b/src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs new file mode 100644 index 0000000..066f022 --- /dev/null +++ b/src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs @@ -0,0 +1,40 @@ +#nullable enable +using H.LowCode.MetaSchema; + +namespace H.LowCode.ComponentBase.Services; + +/// +/// 默认表格数据提供者(提供模拟数据) +/// +public class DefaultTableDataProvider : ITableDataProvider +{ + public async Task GetTableDataAsync(TableDataRequest request) + { + await Task.Delay(100); // 模拟异步操作 + + // 生成模拟数据 + var items = new List>(); + + // 根据页码和页大小生成数据 + var startIndex = (request.PageIndex - 1) * request.PageSize; + for (int i = 0; i < 6; i++) + { + var rowIndex = startIndex + i + 1; + var row = new Dictionary + { + ["Id"] = rowIndex, + ["Name"] = $"示例数据 {rowIndex}", + ["CreateTime"] = DateTime.Now.AddDays(-rowIndex) + }; + items.Add(row); + } + + return new TableDataResponse + { + Items = items, + TotalCount = 100, // 模拟总数 + PageIndex = request.PageIndex, + PageSize = request.PageSize + }; + } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs b/src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs new file mode 100644 index 0000000..df9848b --- /dev/null +++ b/src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs @@ -0,0 +1,89 @@ +#nullable enable +using H.LowCode.MetaSchema; + +namespace H.LowCode.ComponentBase.Services; + +/// +/// 表格数据提供者接口 +/// +public interface ITableDataProvider +{ + /// + /// 获取表格数据 + /// + /// 数据请求参数 + /// 表格数据响应 + Task GetTableDataAsync(TableDataRequest request); +} + +/// +/// 表格数据请求参数 +/// +public class TableDataRequest +{ + /// + /// 应用ID + /// + public string? AppId { get; set; } + + /// + /// 页面ID + /// + public string? PageId { get; set; } + + /// + /// 数据源ID + /// + public string? DataSourceId { get; set; } + + /// + /// 页码(从1开始) + /// + public int PageIndex { get; set; } = 1; + + /// + /// 每页大小 + /// + public int PageSize { get; set; } = 10; + + /// + /// 排序字段 + /// + public string? SortField { get; set; } + + /// + /// 排序方向 + /// + public string? SortOrder { get; set; } + + /// + /// 筛选条件 + /// + public Dictionary? Filters { get; set; } +} + +/// +/// 表格数据响应 +/// +public class TableDataResponse +{ + /// + /// 数据项列表 + /// + public List> Items { get; set; } = new(); + + /// + /// 总记录数 + /// + public int TotalCount { get; set; } + + /// + /// 当前页码 + /// + public int PageIndex { get; set; } + + /// + /// 每页大小 + /// + public int PageSize { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor index da3a6ff..08bfce3 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor @@ -1,7 +1,10 @@ -@namespace H.LowCode.Components.Defaults +@namespace H.LowCode.Components.Defaults @inherits LowCodeComponentBase +@using H.LowCode.MetaSchema +@using H.LowCode.ComponentBase.Services @inject IJSRuntime JS +@inject ITableDataProvider TableDataProvider @@ -61,8 +64,7 @@ await base.OnInitializedAsync(); Init(); - _data = await GetTableDataAsync(1, 50); - _total = 50; + await LoadDataAsync(); } protected override bool ShouldRender() @@ -82,8 +84,13 @@ public async Task OnChange(QueryModel> queryModel) { - await Task.Delay(1); - Console.WriteLine(queryModel.ToJson()); + _pageIndex = queryModel.PageIndex; + _pageSize = queryModel.PageSize; + + // 重新加载数据 + await LoadDataAsync(); + + StateHasChanged(); } private TablePropertySchema GetTableSchemaAsync() @@ -108,25 +115,41 @@ }; } + Console.WriteLine($"列表列头: {tableSchema.Columns.ToJson()}"); + return tableSchema; } - public async Task>> GetTableDataAsync(int pageIndex, int pageSize) + private async Task LoadDataAsync() { - await Task.Delay(100); - var list = new List>(); - for (int i = 0; i < 3; i++) + try { - Dictionary row = new Dictionary(); - foreach (var col in _tableSchema.Columns) + var request = new TableDataRequest { - row.Add(col.Name, string.Empty); - } - list.Add(row); + AppId = PageCascading?.AppId, + PageId = PageCascading?.PageId, + DataSourceId = DataSource?.DataSourceId, + PageIndex = _pageIndex, + PageSize = _pageSize + }; + + var result = await TableDataProvider.GetTableDataAsync(request); + _data = result.Items; + _total = result.TotalCount; + + Console.WriteLine($"列表数据: {result.ToJson()}"); + } + catch (Exception ex) + { + // 出错时使用空数据 + _data = new List>(); + _total = 0; + Console.WriteLine($"加载数据失败: {ex.Message}"); } - return list; } + + public async Task EditAsync(Dictionary row) { string primaryKey = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey)?.Name; diff --git a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj index b6bc67e..2c29cbb 100644 --- a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj +++ b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj @@ -15,6 +15,8 @@ + + diff --git a/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs b/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs index 9ad9668..1a1abc2 100644 --- a/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs +++ b/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs @@ -1,12 +1,19 @@ -using Microsoft.Extensions.DependencyInjection; +using H.LowCode.ComponentBase; +using H.LowCode.ComponentBase.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Modularity; namespace H.LowCode.Components.Defaults; +[DependsOn(typeof(ComponentBaseModule))] public class LowCodeDefaultComponentModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAntDesign(); + + // 注册默认的表格数据提供者 + context.Services.TryAddTransient(); } } diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/DataSourcePropertyItem.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/DataSourcePropertyItem.razor index 0e0b6b1..da463d9 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/DataSourcePropertyItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/DataSourcePropertyItem.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.DesignEngine +@namespace H.LowCode.DesignEngine @inherits DesignEngineLowCodeComponentBase @if (Component.IsSupportDataSource){ @@ -19,13 +19,13 @@ } else if (Component.DataSource.DataSourceGroupType == ComponentDataSourceGroupTypeEnum.Table) { -
- -
- + +
+ +
} else if (Component.DataSource.DataSourceGroupType == ComponentDataSourceGroupTypeEnum.Tree) { @@ -47,16 +47,19 @@ - + @code { + [CascadingParameter(Name = "pageCascading")] + public PageCascadingModel PageCascading { get; set; } + [Parameter] public ComponentPartsSchema Component { get; set; } - private bool _optionDataSourceVisible; - private bool _tableDataSourceVisible; - private bool _treeDataSourceVisible; + private bool _optionDataSourceVisible = false; + private bool _tableDataSourceVisible = false; + private bool _treeDataSourceVisible = false; protected override async Task OnInitializedAsync() { diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSelector.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSelector.razor new file mode 100644 index 0000000..20b2079 --- /dev/null +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSelector.razor @@ -0,0 +1,114 @@ +@namespace H.LowCode.DesignEngine +@inherits DesignEngineLowCodeComponentBase +@inject IDataSourceAppService DataSourceAppService + +
+ + +
+ +@if (!string.IsNullOrEmpty(_selectedDataSourceId)) +{ +
+ +
+
表名:@_selectedDataSource?.Name
+
中文名:@_selectedDataSource?.DisplayName
+ @if (!string.IsNullOrEmpty(_selectedDataSource?.Description)) + { +
描述:@_selectedDataSource.Description
+ } +
+
+} + +@code { + [Parameter] + public ComponentPartsDataSourceSchema DataSource { get; set; } + + [Parameter] + public EventCallback DataSourceChanged { get; set; } + + [Parameter] + public string AppId { get; set; } + + private IList _dataSourceList; + private string _selectedDataSourceId; + private DataSourceSchema _selectedDataSource; + + protected override async Task OnInitializedAsync() + { + await LoadDataSourcesAsync(); + + // 如果已经配置了数据源,设置选中状态 + if (!string.IsNullOrEmpty(DataSource?.DataSourceId)) + { + _selectedDataSourceId = DataSource.DataSourceId; + await LoadSelectedDataSourceAsync(); + } + } + + private async Task LoadDataSourcesAsync() + { + try + { + var input = new DataSourceInput + { + DataSourceType = ComponentDataSourceTypeEnum.DB + }; + + _dataSourceList = await DataSourceAppService.GetListAsync(AppId, input); + } + catch (Exception ex) + { + Console.WriteLine($"加载数据源列表失败: {ex.Message}"); + _dataSourceList = new List(); + } + } + + private async Task OnDataSourceSelected(DataSourceListModel selectedItem) + { + if (selectedItem != null) + { + _selectedDataSourceId = selectedItem.Id; + await LoadSelectedDataSourceAsync(); + await UpdateDataSourceConfig(); + } + } + + private async Task LoadSelectedDataSourceAsync() + { + if (!string.IsNullOrEmpty(_selectedDataSourceId)) + { + try + { + _selectedDataSource = await DataSourceAppService.GetByIdAsync(AppId, _selectedDataSourceId); + } + catch (Exception ex) + { + Console.WriteLine($"加载数据源详情失败: {ex.Message}"); + } + } + } + + private async Task UpdateDataSourceConfig() + { + if (DataSource != null && _selectedDataSource != null) + { + DataSource.DataSourceId = _selectedDataSource.Id; + DataSource.DataSourceType = ComponentDataSourceTypeEnum.DB; + DataSource.DataSourceGroupType = ComponentDataSourceGroupTypeEnum.Table; + + await DataSourceChanged.InvokeAsync(DataSource); + } + } +} \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSetting.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSetting.razor index df95074..5a7c011 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSetting.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/TableDataSource/TableDataSourceSetting.razor @@ -1,18 +1,26 @@ -@namespace H.LowCode.DesignEngine +@namespace H.LowCode.DesignEngine @inherits DesignEngineLowCodeComponentBase +@using Microsoft.JSInterop @if (DataSource != null) {
- - API + 数据表 SQL + API
- if (DataSource.DataSourceType == ComponentDataSourceTypeEnum.API) + if (DataSource.DataSourceType == ComponentDataSourceTypeEnum.DB) + { + + } + else if (DataSource.DataSourceType == ComponentDataSourceTypeEnum.API) { } @@ -23,7 +31,7 @@ else {
- +
} } @@ -35,8 +43,38 @@ [Parameter] public EventCallback DataSourceChanged { get; set; } + [Parameter] + public string AppId { get; set; } + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); + + // 确保数据源分组类型正确设置 + if (DataSource != null) + { + DataSource.DataSourceGroupType = ComponentDataSourceGroupTypeEnum.Table; + } + } + + private async Task OnDataSourceTypeChanged(ComponentDataSourceTypeEnum dataSourceType) + { + if (DataSource != null) + { + DataSource.DataSourceType = dataSourceType; + + // 清空之前的配置 + DataSource.DataSourceId = null; + DataSource.DataSourceValue = null; + DataSource.APIOptionDataSource = null; + DataSource.SQLOptionDataSource = null; + + await DataSourceChanged.InvokeAsync(DataSource); + } + } + + private async Task OnDataSourceChanged(ComponentPartsDataSourceSchema dataSource) + { + await DataSourceChanged.InvokeAsync(dataSource); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs index 0e2e468..377d9ef 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs @@ -1,4 +1,4 @@ -using H.LowCode.MetaSchema; +using H.LowCode.MetaSchema; using System; using System.Collections.Generic; using System.Linq; @@ -32,14 +32,21 @@ public class FormFieldDTO get { if (string.IsNullOrEmpty(TypeName)) - return new InvalidDataException($"TypeName is null or empty, field={this.ToJson()}"); + throw new InvalidDataException($"TypeName is null or empty, field={this.ToJson()}"); var type = Type.GetType(TypeName); if (type == null) throw new InvalidDataException($"Type '{TypeName}' not found, field={this.ToJson()}"); - var realValue = _value.ConvertToRealType(type); - return realValue; + try + { + var realValue = _value.ConvertToRealType(type); + return realValue; + } + catch (Exception ex) + { + throw new InvalidDataException($"Failed to convert value '{_value}' to type '{TypeName}', field={this.ToJson()}", ex); + } } set { diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs index bef387b..81e991b 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,5 +8,43 @@ namespace H.LowCode.RenderEngine.Application.Contracts; public class TableGetListInput { + /// + /// 应用ID + /// + public string AppId { get; set; } + /// + /// 页面ID + /// + public string PageId { get; set; } + + /// + /// 数据源ID + /// + public string DataSourceId { get; set; } + + /// + /// 页码(从1开始) + /// + public int PageIndex { get; set; } = 1; + + /// + /// 每页大小 + /// + public int PageSize { get; set; } = 10; + + /// + /// 排序字段 + /// + public string SortField { get; set; } + + /// + /// 排序方向(asc/desc) + /// + public string SortOrder { get; set; } + + /// + /// 筛选条件 + /// + public Dictionary Filters { get; set; } = new Dictionary(); } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs index 0faa0d2..2d3deb6 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,5 +8,38 @@ namespace H.LowCode.RenderEngine.Application.Contracts; public class TableGetListOutput { + /// + /// 数据列表 + /// + public List> Items { get; set; } = new List>(); + /// + /// 总记录数 + /// + public int TotalCount { get; set; } + + /// + /// 当前页码 + /// + public int PageIndex { get; set; } + + /// + /// 每页大小 + /// + public int PageSize { get; set; } + + /// + /// 总页数 + /// + public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)TotalCount / PageSize) : 0; + + /// + /// 是否有下一页 + /// + public bool HasNextPage => PageIndex < TotalPages; + + /// + /// 是否有上一页 + /// + public bool HasPreviousPage => PageIndex > 1; } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs index 69f1451..cbed32f 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs @@ -1,4 +1,4 @@ -using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain; using H.LowCode.RenderEngine.Application.Contracts; using Microsoft.Extensions.DependencyInjection; using System; @@ -18,6 +18,6 @@ public class TableDataAppService : ApplicationService, ITableDataAppService public async Task GetList(TableGetListInput input) { - throw new NotImplementedException(); + return await _tableDataDomainService.GetListAsync(input); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj index 5fc089a..a14341d 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj @@ -1,4 +1,4 @@ - + @@ -9,6 +9,7 @@ + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs index 370232e..60a30b4 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs @@ -1,5 +1,7 @@ -using H.LowCode.Configuration; +using H.LowCode.Configuration; using H.LowCode.RenderEngine.Domain; +using H.LowCode.ComponentBase.Services; +using H.LowCode.RenderEngine.Application.Services; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; @@ -23,5 +25,8 @@ public class RenderEngineApplicationModule : AbpModule { options.AddMaps(); }); + + // 注册渲染引擎专用的表格数据提供者,覆盖默认实现 + context.Services.AddTransient(); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs new file mode 100644 index 0000000..9cb80a0 --- /dev/null +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs @@ -0,0 +1,94 @@ +using H.LowCode.ComponentBase.Services; +using H.LowCode.RenderEngine.Application.Contracts; +using H.LowCode.RenderEngine.Domain; + +namespace H.LowCode.RenderEngine.Application.Services; + +/// +/// 渲染引擎表格数据提供者 +/// +public class RenderEngineTableDataProvider : ITableDataProvider +{ + private readonly ITableDataDomainService _tableDataDomainService; + + public RenderEngineTableDataProvider(ITableDataDomainService tableDataDomainService) + { + _tableDataDomainService = tableDataDomainService; + } + + public async Task GetTableDataAsync(TableDataRequest request) + { + try + { + // 检查是否配置了数据源ID + if (string.IsNullOrEmpty(request.DataSourceId)) + { + // 返回默认模拟数据 + return await GetDefaultDataAsync(request); + } + + // 转换为Domain层的输入参数 + var input = new TableGetListInput + { + AppId = request.AppId, + PageId = request.PageId, + DataSourceId = request.DataSourceId, + PageIndex = request.PageIndex, + PageSize = request.PageSize, + SortField = request.SortField, + SortOrder = request.SortOrder, + Filters = request.Filters ?? new Dictionary() + }; + + // 调用Domain层服务获取数据 + var result = await _tableDataDomainService.GetListAsync(input); + + // 转换为组件层的响应格式 + return new TableDataResponse + { + Items = result.Items, + TotalCount = result.TotalCount, + PageIndex = result.PageIndex, + PageSize = result.PageSize + }; + } + catch (Exception ex) + { + // 出错时返回默认数据 + Console.WriteLine($"获取表格数据失败: {ex.Message}"); + return await GetDefaultDataAsync(request); + } + } + + private async Task GetDefaultDataAsync(TableDataRequest request) + { + await Task.Delay(100); // 模拟异步操作 + + // 生成模拟数据 + var items = new List>(); + + // 根据页码和页大小生成数据 + var startIndex = (request.PageIndex - 1) * request.PageSize; + for (int i = 0; i < request.PageSize; i++) + { + var rowIndex = startIndex + i + 1; + var row = new Dictionary + { + ["Id"] = rowIndex, + ["Name"] = $"示例数据 {rowIndex}", + ["Status"] = rowIndex % 2 == 0 ? "启用" : "禁用", + ["CreateTime"] = DateTime.Now.AddDays(-rowIndex), + ["Description"] = $"这是第 {rowIndex} 行的描述信息" + }; + items.Add(row); + } + + return new TableDataResponse + { + Items = items, + TotalCount = 100, // 模拟总数 + PageIndex = request.PageIndex, + PageSize = request.PageSize + }; + } +} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs index 1123a90..09221ca 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs @@ -1,4 +1,4 @@ -using H.LowCode.Entity; +using H.LowCode.Entity; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; @@ -50,16 +50,299 @@ public class FormDataDomainService : DomainService, IFormDataDomainService public async Task SaveAsync(FormEntity entity) { - //TODO + // 验证实体 + if (entity == null) + throw new ArgumentNullException(nameof(entity)); + + // 设置默认表名 entity.Name = entity.Name ?? "tb_test1"; - if (string.IsNullOrEmpty(entity.Id)) - await _formDataRepository.AddAsync(entity); - else - await _formDataRepository.UpdateAsync(entity); + // 验证字段 + if (entity.Fields == null || !entity.Fields.Any()) + throw new ArgumentException("表单字段不能为空", nameof(entity)); + + // 验证字段值类型 + foreach (var field in entity.Fields) + { + if (string.IsNullOrEmpty(field.Name)) + throw new ArgumentException("字段名称不能为空"); + + if (string.IsNullOrEmpty(field.TypeName)) + throw new ArgumentException($"字段 {field.Name} 的类型不能为空"); + } + + // 应用字段验证和默认值 + await ApplyFieldValidationAndDefaults(entity); + + try + { + // 检查是否为新增记录(通过主键字段判断) + string primaryKeyName = "f_id"; + var primaryKeyField = entity.Fields.FirstOrDefault(f => f.Name == primaryKeyName); + + bool isNewRecord = primaryKeyField == null || + string.IsNullOrEmpty(primaryKeyField.Value?.ToString()); + + if (isNewRecord) + { + // 新增记录 - 设置主键字段值 + if (primaryKeyField == null) + { + // 如果主键字段不存在,创建一个 + primaryKeyField = new FormFieldEntity + { + Name = primaryKeyName, + TypeName = typeof(string).FullName, + Value = Guid.NewGuid().ToString() + }; + entity.Fields.Add(primaryKeyField); + } + else + { + // 如果主键字段存在但值为空,设置新值 + primaryKeyField.Value = Guid.NewGuid().ToString(); + } + + await _formDataRepository.AddAsync(entity); + } + else + { + // 更新记录 + await _formDataRepository.UpdateAsync(entity); + } + return true; + } + catch (Exception ex) + { + // 记录错误日志 + string entityId = ""; + try { entityId = entity.Id; } catch { } + Logger.LogError(ex, "保存表单数据失败: EntityName={EntityName}, EntityId={EntityId}", entity.Name, entityId); + throw; + } + } + + /// + /// 应用字段验证和默认值设置 + /// + private async Task ApplyFieldValidationAndDefaults(FormEntity entity) + { + // 获取页面配置以获取字段默认值定义 + var pageConfig = await GetPageConfigForEntity(entity.Name); + + foreach (var field in entity.Fields) + { + // 跳过主键字段的验证和默认值处理 + if (field.Name == "f_id") + continue; + + // 获取字段类型 + var fieldType = Type.GetType(field.TypeName); + if (fieldType == null) + continue; + + // 检查字段是否有有效值 + bool hasValidValue = HasValidValue(field.Value, fieldType); + + if (!hasValidValue) + { + // 首先尝试从页面配置获取默认值 + var configDefaultValue = GetFieldDefaultValueFromConfig(field.Name, fieldType, pageConfig); + if (configDefaultValue != null) + { + field.Value = configDefaultValue; + Logger.LogInformation("Applied config default value for field '{FieldName}': {DefaultValue}", + field.Name, configDefaultValue); + } + else + { + // 如果没有配置默认值,使用类型默认值 + field.Value = GetTypeDefaultValue(fieldType); + Logger.LogInformation("Applied type default value for field '{FieldName}': {DefaultValue}", + field.Name, field.Value); + } + } + + // 验证字段值的有效性 + ValidateFieldValue(field, fieldType); + } + } + + /// + /// 检查字段是否有有效值 + /// + private bool HasValidValue(object value, Type fieldType) + { + if (value == null) + return false; + + // 字符串类型:空字符串视为无效值 + if (fieldType == typeof(string)) + return !string.IsNullOrWhiteSpace(value.ToString()); + + // 数值类型:0值可能是有效值,所以只检查null + if (fieldType == typeof(int) || fieldType == typeof(int?) || + fieldType == typeof(long) || fieldType == typeof(long?) || + fieldType == typeof(decimal) || fieldType == typeof(decimal?)) + return true; + + // 布尔类型:false也是有效值 + if (fieldType == typeof(bool) || fieldType == typeof(bool?)) + return true; + + // DateTime类型:检查是否为默认值 + if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) + { + if (value is DateTime dateValue) + return dateValue != default(DateTime); + return true; + } + + // Guid类型:检查是否为空Guid + if (fieldType == typeof(Guid) || fieldType == typeof(Guid?)) + { + if (value is Guid guidValue) + return guidValue != Guid.Empty; + return true; + } + return true; } + /// + /// 获取类型的默认值 + /// + private object GetTypeDefaultValue(Type type) + { + if (type == null) + return null; + + // 处理可空类型 + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return null; + } + + // 处理字符串类型 + if (type == typeof(string)) + return string.Empty; + + // 处理基本数值类型 + if (type == typeof(int)) + return 0; + if (type == typeof(long)) + return 0L; + if (type == typeof(decimal)) + return 0m; + if (type == typeof(double)) + return 0.0; + if (type == typeof(float)) + return 0.0f; + if (type == typeof(short)) + return (short)0; + if (type == typeof(byte)) + return (byte)0; + + // 处理布尔类型 + if (type == typeof(bool)) + return false; + + // 处理日期时间类型 + if (type == typeof(DateTime)) + return DateTime.Now; + if (type == typeof(DateTimeOffset)) + return DateTimeOffset.Now; + + // 处理Guid类型 + if (type == typeof(Guid)) + return Guid.NewGuid(); + + // 处理集合类型 + if (type.IsArray) + { + return Array.CreateInstance(type.GetElementType(), 0); + } + + if (type.IsGenericType) + { + var genericTypeDef = type.GetGenericTypeDefinition(); + if (genericTypeDef == typeof(List<>) || + genericTypeDef == typeof(IList<>) || + genericTypeDef == typeof(ICollection<>) || + genericTypeDef == typeof(IEnumerable<>)) + { + return Activator.CreateInstance(typeof(List<>).MakeGenericType(type.GetGenericArguments())); + } + } + + // 对于其他值类型,返回类型的默认值 + if (type.IsValueType) + return Activator.CreateInstance(type); + + // 其他引用类型返回null + return null; + } + + /// + /// 验证字段值的有效性 + /// + private void ValidateFieldValue(FormFieldEntity field, Type fieldType) + { + try + { + // 尝试转换值以验证类型兼容性 + if (field.Value != null) + { + Convert.ChangeType(field.Value, fieldType); + } + } + catch (Exception ex) + { + throw new ArgumentException($"Field '{field.Name}' value '{field.Value}' is not compatible with type '{fieldType.Name}'", ex); + } + } + + /// + /// 获取页面配置 + /// + private async Task GetPageConfigForEntity(string entityName) + { + try + { + // 通过实体名称查找对应的页面配置 + // 这里简化处理,实际应该通过数据源配置来查找页面 + // TODO: 实现更精确的页面配置查找逻辑 + return null; + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Failed to get page config for entity '{EntityName}'", entityName); + return null; + } + } + + /// + /// 从页面配置中获取字段默认值 + /// + private object GetFieldDefaultValueFromConfig(string fieldName, Type fieldType, object pageConfig) + { + if (pageConfig == null) + return null; + + try + { + // TODO: 实现从页面配置JSON中解析字段默认值的逻辑 + // 这里需要解析页面配置中的组件定义,找到对应字段的默认值 + // 由于页面配置结构复杂,暂时返回null + return null; + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Failed to get default value from config for field '{FieldName}'", fieldName); + return null; + } + } + public async Task DeleteAsync(string appId, string pageId, string id) { var formPageSchema = await _pageDomainService.GetAsync(appId, pageId); diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs index e64df35..e041a43 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs @@ -1,4 +1,5 @@ -using System; +using H.LowCode.RenderEngine.Application.Contracts; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,5 +10,10 @@ namespace H.LowCode.RenderEngine.Domain; public interface ITableDataDomainService : IDomainService { - + /// + /// 获取表格数据列表 + /// + /// 查询参数 + /// 分页数据结果 + Task GetListAsync(TableGetListInput input); } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs index f7f94bf..e28f4d2 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs @@ -1,4 +1,5 @@ -using System; +using H.LowCode.RenderEngine.Application.Contracts; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,8 +10,20 @@ namespace H.LowCode.RenderEngine.Domain; public class TableDataDomainService : DomainService, ITableDataDomainService { + private readonly ITableDataRepository _tableDataRepository; + public TableDataDomainService(ITableDataRepository tableDataRepository) { + _tableDataRepository = tableDataRepository; + } + /// + /// 获取表格数据列表 + /// + /// 查询参数 + /// 分页数据结果 + public async Task GetListAsync(TableGetListInput input) + { + return await _tableDataRepository.GetListAsync(input); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs index 91a2c31..bc10405 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs @@ -1,4 +1,5 @@ -using System; +using H.LowCode.RenderEngine.Application.Contracts; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -9,5 +10,10 @@ namespace H.LowCode.RenderEngine.Domain; public interface ITableDataRepository : IRepository { - + /// + /// 获取表格数据列表 + /// + /// 查询参数 + /// 分页数据结果 + Task GetListAsync(TableGetListInput input); } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj index ccfaffb..b3a8501 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/H.LowCode.RenderEngine.Domain.csproj @@ -10,6 +10,7 @@ + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs index 1c8a639..3ca04ce 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs @@ -1,4 +1,4 @@ -using H.LowCode.Entity; +using H.LowCode.Entity; using H.LowCode.MetaSchema; using H.LowCode.RenderEngine.Domain; using Microsoft.EntityFrameworkCore; @@ -13,31 +13,35 @@ namespace H.LowCode.RenderEngine.EntityFrameworkCore; public class FormDataRepository : IFormDataRepository { - private RenderEngineDbContext _dbContext; + private readonly IDbContextFactory _dbContextFactory; public bool? IsChangeTrackingEnabled => true; - public FormDataRepository(RenderEngineDbContext dbContext) + public FormDataRepository(IDbContextFactory dbContextFactory) { - _dbContext = dbContext; + _dbContextFactory = dbContextFactory; } public async Task AddAsync(FormEntity entity) { - return await _dbContext.AddAsync(entity); + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.AddAsync(entity); } public async Task GetAsync(string tableName, string id) { - return await _dbContext.GetAsync(tableName, id); + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.GetAsync(tableName, id); } public async Task UpdateAsync(FormEntity entity) { - return await _dbContext.UpdateAsync(entity); + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.UpdateAsync(entity); } public async Task DeleteAsync(string entityName, string id) { - return await _dbContext.DeleteAsync(entityName, id); + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.DeleteAsync(entityName, id); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs index ea711dc..b661ae0 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs @@ -1,7 +1,10 @@ -using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Application.Contracts; +using H.LowCode.RenderEngine.Domain; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -9,9 +12,134 @@ namespace H.LowCode.RenderEngine.EntityFrameworkCore; public class TableDataRepository : ITableDataRepository { + private readonly IDbContextFactory _dbContextFactory; + private readonly IDataSourceDomainService _dataSourceDomainService; public bool? IsChangeTrackingEnabled => true; - public TableDataRepository(RenderEngineDbContext dbContext) + public TableDataRepository(IDbContextFactory dbContextFactory, IDataSourceDomainService dataSourceDomainService) { + _dbContextFactory = dbContextFactory; + _dataSourceDomainService = dataSourceDomainService; + } + + /// + /// 获取表格数据列表 + /// + /// 查询参数 + /// 分页数据结果 + public async Task GetListAsync(TableGetListInput input) + { + try + { + // 根据数据源ID获取数据源信息 + var dataSource = await _dataSourceDomainService.GetAsync(input.AppId, input.DataSourceId); + if (dataSource == null) + { + return new TableGetListOutput + { + Items = new List>(), + TotalCount = 0, + PageIndex = input.PageIndex, + PageSize = input.PageSize + }; + } + + // 使用 DbContextFactory 创建新的 DbContext 实例,确保线程安全 + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + + // 获取实体类型(使用数据源名称) + var entityType = dbContext.GetEntityType(dataSource.Name); + + // 获取DbSet + var dbSetProperty = dbContext.GetType().GetMethod("Set", Type.EmptyTypes)?.MakeGenericMethod(entityType); + var dbSet = dbSetProperty?.Invoke(dbContext, null) as IQueryable; + + if (dbSet == null) + { + return new TableGetListOutput + { + Items = new List>(), + TotalCount = 0, + PageIndex = input.PageIndex, + PageSize = input.PageSize + }; + } + + // 应用筛选条件 + if (input.Filters != null && input.Filters.Any()) + { + // 这里可以根据需要实现更复杂的筛选逻辑 + // 暂时跳过筛选实现 + } + + // 应用排序 + if (!string.IsNullOrEmpty(input.SortField)) + { + var parameter = System.Linq.Expressions.Expression.Parameter(entityType, "x"); + var property = System.Linq.Expressions.Expression.Property(parameter, input.SortField); + var lambda = System.Linq.Expressions.Expression.Lambda(property, parameter); + + var orderByMethod = input.SortOrder?.ToLower() == "desc" ? "OrderByDescending" : "OrderBy"; + var orderByExpression = System.Linq.Expressions.Expression.Call( + typeof(Queryable), + orderByMethod, + new Type[] { entityType, property.Type }, + dbSet.Expression, + System.Linq.Expressions.Expression.Quote(lambda)); + + dbSet = dbSet.Provider.CreateQuery(orderByExpression); + } + + // 获取总数 + var totalCount = await dbSet.CountAsync(); + + // 应用分页 + var pagedData = await dbSet + .Skip((input.PageIndex - 1) * input.PageSize) + .Take(input.PageSize) + .ToListAsync(); + + // 转换为字典格式 + var result = new List>(); + foreach (var item in pagedData) + { + var dict = new Dictionary(); + var properties = entityType.GetProperties(); + foreach (var prop in properties) + { + var value = prop.GetValue(item); + dict[prop.Name] = value; + } + result.Add(dict); + } + + // 计算分页信息 + var totalPages = (int)Math.Ceiling((double)totalCount / input.PageSize); + var hasNextPage = input.PageIndex < totalPages; + var hasPreviousPage = input.PageIndex > 1; + + return new TableGetListOutput + { + Items = result, + TotalCount = totalCount, + PageIndex = input.PageIndex, + PageSize = input.PageSize + }; + } + catch (Exception ex) + { + // 记录详细错误信息,便于调试 + Console.WriteLine($"获取表格数据失败: {ex.Message}"); + Console.WriteLine($"堆栈跟踪: {ex.StackTrace}"); + + // 返回空结果,避免异常中断 + return new TableGetListOutput + { + Items = new List>(), + TotalCount = 0, + PageIndex = input.PageIndex, + PageSize = input.PageSize + }; + } } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/RenderEngineEntityFrameworkCoreModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/RenderEngineEntityFrameworkCoreModule.cs index 09438bf..ca33e67 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/RenderEngineEntityFrameworkCoreModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/RenderEngineEntityFrameworkCoreModule.cs @@ -1,4 +1,4 @@ -using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -17,6 +17,14 @@ public class RenderEngineEntityFrameworkCoreModule : AbpModule context.Services.AddScoped(typeof(EntityTypeManager)); + // 注册 DbContext 工厂,确保每次使用都创建新的实例,避免并发访问问题 + context.Services.AddDbContextFactory(options => + { + var connectionString = context.Services.GetConfiguration().GetConnectionString("Default"); + options.UseSqlServer(connectionString); + }); + + // 保持原有的 DbContext 注册方式作为备用 context.Services.AddDbContext(options => { var connectionString = context.Services.GetConfiguration().GetConnectionString("Default"); diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs index aa068e6..90f76cf 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs @@ -1,4 +1,4 @@ -using H.LowCode.ComponentBase; +using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.RenderEngine.Application; using H.LowCode.RenderEngine.EntityFrameworkCore; -- Gitee From 73300f871d928fe74a0c3e6bcd51f6f9a6ea91dd Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Thu, 25 Sep 2025 01:55:14 +0800 Subject: [PATCH 16/33] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E3=80=81=E8=A1=A8=E5=8D=95=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/page/g0qcqxzd.json | 2 +- .../H.LowCode.Application.Contracts.csproj | 10 ++ .../ITableDataProvider.cs | 7 +- .../Components/LcTable.razor | 63 ++++++++-- .../H.LowCode.Components.Defaults.csproj | 1 + .../LowCodeDefaultComponentModule.cs | 5 - .../PropertySchemas/EventSchema.cs | 8 +- .../TableSchemas/TableColumnSchema.cs | 2 +- .../AppServices}/DefaultTableDataProvider.cs | 1 + .../DesignEngineApplicationModule.cs | 7 +- .../H.LowCode.DesignEngine.Application.csproj | 1 + .../Components/Events/EventList.razor | 116 +++++++++++++++++- src/H.LowCode.sln | 9 +- .../RenderEngineTableDataProvider.cs | 4 +- .../H.LowCode.RenderEngine.Application.csproj | 1 + .../RenderEngineApplicationModule.cs | 4 +- .../FormDataDomainService.cs | 2 +- 17 files changed, 214 insertions(+), 29 deletions(-) create mode 100644 src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj rename src/Common/{H.LowCode.ComponentBase/Services => H.LowCode.Application.Contracts}/ITableDataProvider.cs (93%) rename src/{Common/H.LowCode.ComponentBase/Services => DesignEngine/H.LowCode.DesignEngine.Application/AppServices}/DefaultTableDataProvider.cs (96%) rename src/RenderEngine/H.LowCode.RenderEngine.Application/{Services => DataAppServices}/RenderEngineTableDataProvider.cs (96%) diff --git a/meta/apps/caseapp/page/g0qcqxzd.json b/meta/apps/caseapp/page/g0qcqxzd.json index 2476f62..ab41f10 100644 --- a/meta/apps/caseapp/page/g0qcqxzd.json +++ b/meta/apps/caseapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dst":1,"dsid":"qgzhc7w3z","dsn":"tb_test1","dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"f_field1\",\"t\":\"输入框1\"},{\"id\":\"vwvoqrn1s\",\"n\":\"f_field3\",\"t\":\"输入框2\"},{\"id\":\"ap0ceewr\",\"n\":\"f_field6\",\"t\":\"单选框3\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"},{\"id\":\"es0qoauj\",\"n\":\"f_field10\",\"t\":\"日期选择5\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-09-24T16:27:03.2680438Z"} \ No newline at end of file +{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dst":1,"dsid":"qgzhc7w3z","dsn":"tb_test1","dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"f_field1\",\"t\":\"输入框1\"},{\"id\":\"vwvoqrn1s\",\"n\":\"f_field3\",\"t\":\"输入框2\"},{\"id\":\"ap0ceewr\",\"n\":\"f_field6\",\"t\":\"单选框3\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"},{\"id\":\"es0qoauj\",\"n\":\"f_field10\",\"t\":\"日期选择5\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\",\"eventArgs\":{\"param1\":\"111\"},\"rowparams\":{\"id\":\"f_id\"}}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-09-24T17:22:43.3629139Z"} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj b/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj new file mode 100644 index 0000000..225c07d --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs b/src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs similarity index 93% rename from src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs rename to src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs index df9848b..47fe3b0 100644 --- a/src/Common/H.LowCode.ComponentBase/Services/ITableDataProvider.cs +++ b/src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs @@ -1,12 +1,11 @@ -#nullable enable -using H.LowCode.MetaSchema; +using Volo.Abp; -namespace H.LowCode.ComponentBase.Services; +namespace H.LowCode.Application.Contracts; /// /// 表格数据提供者接口 /// -public interface ITableDataProvider +public interface ITableDataProvider : IRemoteService { /// /// 获取表格数据 diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor index 08bfce3..354928d 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor @@ -1,7 +1,7 @@ @namespace H.LowCode.Components.Defaults @inherits LowCodeComponentBase +@using H.LowCode.Application.Contracts @using H.LowCode.MetaSchema -@using H.LowCode.ComponentBase.Services @inject IJSRuntime JS @inject ITableDataProvider TableDataProvider @@ -33,7 +33,7 @@ @foreach (var rowBtn in _tableSchema.RowButtons) { - @rowBtn.Title + @rowBtn.Title } @@ -161,7 +161,7 @@ await Task.Delay(100); } - public async Task ButtonActionAsync(TableButtonSchema btn) + public async Task ButtonActionAsync(TableButtonSchema btn, Dictionary rowData = null) { foreach(var e in btn.Events) { @@ -183,13 +183,13 @@ break; case EventPageHandlerTypeEnum.Modal: - await ButtonActionToWithModalAsync(e); + await ButtonActionToWithModalAsync(e, rowData); break; case EventPageHandlerTypeEnum.Self: - await ButtonActionToWithSelfAsync(e); + await ButtonActionToWithSelfAsync(e, rowData); break; case EventPageHandlerTypeEnum.Blank: - await ButtonActionToWithBlankAsync(e); + await ButtonActionToWithBlankAsync(e, rowData); break; default: break; @@ -206,17 +206,17 @@ } } - private async Task ButtonActionToWithModalAsync(EventSchema e) + private async Task ButtonActionToWithModalAsync(EventSchema e, Dictionary rowData = null) { } - private async Task ButtonActionToWithSelfAsync(EventSchema e) + private async Task ButtonActionToWithSelfAsync(EventSchema e, Dictionary rowData = null) { } - private async Task ButtonActionToWithBlankAsync(EventSchema e) + private async Task ButtonActionToWithBlankAsync(EventSchema e, Dictionary rowData = null) { string pageUrl = string.Empty; if (IsDesign) @@ -224,6 +224,51 @@ else pageUrl = $"/{PageCascading.AppId}/{e.EventTargetId}"; + // 添加URL参数 + pageUrl = BuildUrlWithParameters(pageUrl, e, rowData); + await JS.InvokeVoidAsync("open", pageUrl, "_blank"); } + + private string BuildUrlWithParameters(string baseUrl, EventSchema eventSchema, Dictionary rowData) + { + var parameters = new List(); + + // 添加事件配置中的参数 + if (eventSchema.EventArgs != null && eventSchema.EventArgs.Any()) + { + foreach (var arg in eventSchema.EventArgs) + { + parameters.Add($"{arg.Key}={Uri.EscapeDataString(arg.Value?.ToString() ?? "")}"); + } + } + + // 添加行数据参数(根据配置映射) + if (rowData != null && rowData.Any() && eventSchema.RowDataParams != null && eventSchema.RowDataParams.Any()) + { + foreach (var paramMapping in eventSchema.RowDataParams) + { + var urlParamName = paramMapping.Key; + var rowFieldName = paramMapping.Value; + + // 检查行数据中是否包含指定字段 + if (rowData.ContainsKey(rowFieldName)) + { + // 避免与EventArgs中的参数重复 + if (eventSchema.EventArgs == null || !eventSchema.EventArgs.ContainsKey(urlParamName)) + { + parameters.Add($"{urlParamName}={Uri.EscapeDataString(rowData[rowFieldName]?.ToString() ?? "")}"); + } + } + } + } + + if (parameters.Any()) + { + var separator = baseUrl.Contains("?") ? "&" : "?"; + return $"{baseUrl}{separator}{string.Join("&", parameters)}"; + } + + return baseUrl; + } } diff --git a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj index 2c29cbb..9e85a29 100644 --- a/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj +++ b/src/Common/H.LowCode.Components.Defaults/H.LowCode.Components.Defaults.csproj @@ -17,6 +17,7 @@ + diff --git a/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs b/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs index 1a1abc2..0b660ff 100644 --- a/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs +++ b/src/Common/H.LowCode.Components.Defaults/LowCodeDefaultComponentModule.cs @@ -1,7 +1,5 @@ using H.LowCode.ComponentBase; -using H.LowCode.ComponentBase.Services; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Modularity; namespace H.LowCode.Components.Defaults; @@ -12,8 +10,5 @@ public class LowCodeDefaultComponentModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAntDesign(); - - // 注册默认的表格数据提供者 - context.Services.TryAddTransient(); } } diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs index a417809..cd30381 100644 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; @@ -43,6 +43,12 @@ public class EventSchema /// 事件参数 /// public IDictionary EventArgs { get; set; } + + /// + /// 行数据参数映射 (key: URL参数名, value: 行数据字段名) + /// + [JsonPropertyName("rowparams")] + public IDictionary RowDataParams { get; set; } } public class EventConsumeSchema diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableColumnSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableColumnSchema.cs index 24ead29..0e0b4d9 100644 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableColumnSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/TableSchemas/TableColumnSchema.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema; diff --git a/src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs similarity index 96% rename from src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs rename to src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs index 066f022..07fd2e0 100644 --- a/src/Common/H.LowCode.ComponentBase/Services/DefaultTableDataProvider.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs @@ -1,4 +1,5 @@ #nullable enable +using H.LowCode.Application.Contracts; using H.LowCode.MetaSchema; namespace H.LowCode.ComponentBase.Services; diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs index 8b316ba..9c49c46 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs @@ -1,4 +1,6 @@ -using H.LowCode.Configuration; +using H.LowCode.Application.Contracts; +using H.LowCode.ComponentBase.Services; +using H.LowCode.Configuration; using H.LowCode.DesignEngine.Domain; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; @@ -12,5 +14,8 @@ public class DesignEngineApplicationModule : AbpModule { var configuration = context.Services.GetConfiguration(); context.Services.Configure>(configuration.GetSection(SiteOption.SectionName)); + + // 注册默认的表格数据提供者 + context.Services.AddTransient(); } } diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj index 60433c2..0fb068d 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/H.LowCode.DesignEngine.Application.csproj @@ -8,6 +8,7 @@ + diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor index 024560f..fbd6a80 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.DesignEngineBase +@namespace H.LowCode.DesignEngineBase @inherits DesignEngineLowCodeComponentBase @inject IPageAppService PageAppService @@ -51,6 +51,46 @@
+
+ + @if (_currentEvent.EventArgs == null) + { + _currentEvent.EventArgs = new Dictionary(); + } + @foreach (var arg in _currentEvent.EventArgs.ToList()) + { + var currentKey = arg.Key; + var currentValue = arg.Value; +
+ + + +
+ } + +
+
+ + @if (_currentEvent.RowDataParams == null) + { + _currentEvent.RowDataParams = new Dictionary(); + } + @foreach (var param in _currentEvent.RowDataParams.ToList()) + { + var currentKey = param.Key; + var currentValue = param.Value; +
+ + + +
+ } + +
} else if (_currentEvent.EventHandlerType == EventTargetTypeEnum.Component) @@ -168,4 +208,78 @@ var component = await PageAppService.GetPageComponentAsync(PageCascading.AppId, PageCascading.PageId, componentId); _componentEventTargetActions = component?.EventConsumes?.ToArray() ?? []; } + + private void AddEventArg() + { + if (_currentEvent.EventArgs == null) + { + _currentEvent.EventArgs = new Dictionary(); + } + + var newKey = $"param{_currentEvent.EventArgs.Count + 1}"; + _currentEvent.EventArgs[newKey] = ""; + } + + private void RemoveEventArg(string key) + { + if (_currentEvent.EventArgs != null && _currentEvent.EventArgs.ContainsKey(key)) + { + _currentEvent.EventArgs.Remove(key); + } + } + + private void AddRowDataParam() + { + if (_currentEvent.RowDataParams == null) + { + _currentEvent.RowDataParams = new Dictionary(); + } + + var newKey = $"param{_currentEvent.RowDataParams.Count + 1}"; + _currentEvent.RowDataParams[newKey] = ""; + } + + private void RemoveRowDataParam(string key) + { + if (_currentEvent.RowDataParams != null && _currentEvent.RowDataParams.ContainsKey(key)) + { + _currentEvent.RowDataParams.Remove(key); + } + } + + private void UpdateEventArgKey(string oldKey, string newKey) + { + if (_currentEvent.EventArgs != null && _currentEvent.EventArgs.ContainsKey(oldKey) && !string.IsNullOrEmpty(newKey) && newKey != oldKey) + { + var value = _currentEvent.EventArgs[oldKey]; + _currentEvent.EventArgs.Remove(oldKey); + _currentEvent.EventArgs[newKey] = value; + } + } + + private void UpdateEventArgValue(string key, string value) + { + if (_currentEvent.EventArgs != null && _currentEvent.EventArgs.ContainsKey(key)) + { + _currentEvent.EventArgs[key] = value ?? ""; + } + } + + private void UpdateRowDataParamKey(string oldKey, string newKey) + { + if (_currentEvent.RowDataParams != null && _currentEvent.RowDataParams.ContainsKey(oldKey) && !string.IsNullOrEmpty(newKey) && newKey != oldKey) + { + var value = _currentEvent.RowDataParams[oldKey]; + _currentEvent.RowDataParams.Remove(oldKey); + _currentEvent.RowDataParams[newKey] = value; + } + } + + private void UpdateRowDataParamValue(string key, string value) + { + if (_currentEvent.RowDataParams != null && _currentEvent.RowDataParams.ContainsKey(key)) + { + _currentEvent.RowDataParams[key] = value ?? ""; + } + } } diff --git a/src/H.LowCode.sln b/src/H.LowCode.sln index 93d66de..f856850 100644 --- a/src/H.LowCode.sln +++ b/src/H.LowCode.sln @@ -13,8 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.LowCode.DesignEngine", "D EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{8B2D37CA-78EA-401B-B598-EFB3C7FD6517}" ProjectSection(SolutionItems) = preProject - Directory.Packages.props = Directory.Packages.props common.props = common.props + Directory.Packages.props = Directory.Packages.props NuGet.config = NuGet.config nuget.pack.props = nuget.pack.props ..\README.md = ..\README.md @@ -104,6 +104,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{844CDB EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.LowCode.MetaMigrator", "Tools\H.LowCode.MetaMigrator\H.LowCode.MetaMigrator.csproj", "{193AF344-CD5E-474A-A872-CB700253967B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.LowCode.Application.Contracts", "Common\H.LowCode.Application.Contracts\H.LowCode.Application.Contracts.csproj", "{677BA66C-2367-4430-82CE-59E09988DF43}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -246,6 +248,10 @@ Global {193AF344-CD5E-474A-A872-CB700253967B}.Debug|Any CPU.Build.0 = Debug|Any CPU {193AF344-CD5E-474A-A872-CB700253967B}.Release|Any CPU.ActiveCfg = Release|Any CPU {193AF344-CD5E-474A-A872-CB700253967B}.Release|Any CPU.Build.0 = Release|Any CPU + {677BA66C-2367-4430-82CE-59E09988DF43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {677BA66C-2367-4430-82CE-59E09988DF43}.Debug|Any CPU.Build.0 = Debug|Any CPU + {677BA66C-2367-4430-82CE-59E09988DF43}.Release|Any CPU.ActiveCfg = Release|Any CPU + {677BA66C-2367-4430-82CE-59E09988DF43}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -293,6 +299,7 @@ Global {2B32F5E0-A1C9-49DA-85DD-9C3202A4AF2C} = {7E5B26AA-4F89-4B8C-B743-AE3F04C9DD58} {844CDB6A-8081-4769-8905-8A0D279D6101} = {89FE3DE3-2E58-4835-A476-CA2E309A1B3F} {193AF344-CD5E-474A-A872-CB700253967B} = {F3ABC418-7234-4DBA-8A5A-6B286A25B8AD} + {677BA66C-2367-4430-82CE-59E09988DF43} = {A63C9652-517D-4BC3-B935-74D946AB0761} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A8C26757-CDED-4779-94DE-C0D4929F64C2} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs similarity index 96% rename from src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs rename to src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs index 9cb80a0..d621577 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/Services/RenderEngineTableDataProvider.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs @@ -1,8 +1,8 @@ -using H.LowCode.ComponentBase.Services; +using H.LowCode.Application.Contracts; using H.LowCode.RenderEngine.Application.Contracts; using H.LowCode.RenderEngine.Domain; -namespace H.LowCode.RenderEngine.Application.Services; +namespace H.LowCode.RenderEngine.Application.DataAppServices; /// /// 渲染引擎表格数据提供者 diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj index a14341d..d0c2090 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/H.LowCode.RenderEngine.Application.csproj @@ -9,6 +9,7 @@ + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs index 60a30b4..49b1cee 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs @@ -1,10 +1,10 @@ using H.LowCode.Configuration; using H.LowCode.RenderEngine.Domain; -using H.LowCode.ComponentBase.Services; -using H.LowCode.RenderEngine.Application.Services; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; +using H.LowCode.RenderEngine.Application.DataAppServices; +using H.LowCode.Application.Contracts; namespace H.LowCode.RenderEngine.Application; diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs index 09221ca..b474711 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs @@ -293,7 +293,7 @@ public class FormDataDomainService : DomainService, IFormDataDomainService // 尝试转换值以验证类型兼容性 if (field.Value != null) { - Convert.ChangeType(field.Value, fieldType); + //Convert.ChangeType(field.Value, fieldType); } } catch (Exception ex) -- Gitee From 56257ec6c235e88e5cbe3898d8612a3a3d0cf836 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Fri, 26 Sep 2025 01:30:26 +0800 Subject: [PATCH 17/33] =?UTF-8?q?=E5=8E=BB=E6=8E=89=20RenderEngine=20?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=20DomainService=EF=BC=8C=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../H.LowCode.Application.Contracts.csproj | 5 + .../ITableDataProvider.cs | 88 ----- .../Components/LcTable.razor | 16 +- .../_Imports.razor | 1 + .../DesignEngineApplicationContractsModule.cs | 11 +- ....DesignEngine.Application.Contracts.csproj | 1 + .../AppServices/DefaultTableDataProvider.cs | 41 -- .../DesignEngineApplicationModule.cs | 5 - .../FormDataDomainService.cs | 5 - .../ITableDataDomainService.cs | 13 - .../TableDataDomainService.cs | 16 - .../DesignEngineHostClientModule.cs | 7 +- .../DataAppServices/IFormDataAppService.cs | 13 - .../DataAppServices/ITableDataAppService.cs | 9 - .../DataDTOs/DataDTOBase.cs | 18 - .../DataDTOs/FormCreateOrUpdateDTO.cs | 12 - .../DataDTOs/FormDataDTO.cs | 56 --- .../DataDTOs/TableGetListInput.cs | 50 --- .../DataDTOs/TableGetListOutput.cs | 45 --- ....RenderEngine.Application.Contracts.csproj | 1 + .../RenderEngineApplicationContractsModule.cs | 9 +- .../DataAppServices/FormDataAppService.cs | 349 ++++++++++++++++- .../RenderEngineTableDataProvider.cs | 94 ----- .../DataAppServices/TableDataAppService.cs | 27 +- .../LowCodeAutoMapperProfile.cs | 15 +- .../RenderAppServices/MetaAppService.cs | 11 +- .../RenderEngineApplicationModule.cs | 5 - .../FormDataDomainService.cs | 352 ------------------ .../IFormDataDomainService.cs | 18 - .../ITableDataDomainService.cs | 19 - .../TableDataDomainService.cs | 29 -- .../DataRepositories/ITableDataRepository.cs | 15 +- .../MetaDomainServices/AppDomainService.cs | 25 -- .../DataSourceDomainService.cs | 37 -- .../MetaDomainServices/IAppDomainService.cs | 11 - .../IDataSourceDomainService.cs | 15 - .../MetaDomainServices/IMenuDomainService.cs | 11 - .../MetaDomainServices/IMetaDomainService.cs | 8 - .../MetaDomainServices/IPageDomainService.cs | 9 - .../MetaDomainServices/MenuDomainService.cs | 25 -- .../MetaDomainServices/MetaDomainService.cs | 8 - .../MetaDomainServices/PageDomainService.cs | 20 - .../MetaRepositories/IDataSourceRepository.cs | 4 + .../DataRepositories/TableDataRepository.cs | 178 ++++----- .../EntityManager/EntityTypeManager.cs | 9 +- .../RenderEngineHostClientModule.cs | 8 +- .../Repositories/DataSourceFileRepository.cs | 12 + .../DataSourceRemoteServiceRepository.cs | 10 + .../PageRender/FormPageRender.razor | 16 +- .../H.LowCode.Themes.AntBlazor/_Imports.razor | 1 + 50 files changed, 504 insertions(+), 1259 deletions(-) delete mode 100644 src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs delete mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs delete mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/ITableDataDomainService.cs delete mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/TableDataDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/IFormDataAppService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/ITableDataAppService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/DataDTOBase.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormCreateOrUpdateDTO.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/IFormDataDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/AppDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/DataSourceDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IAppDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IDataSourceDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMenuDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMetaDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IPageDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MenuDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MetaDomainService.cs delete mode 100644 src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/PageDomainService.cs diff --git a/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj b/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj index 225c07d..d2d651e 100644 --- a/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj +++ b/src/Common/H.LowCode.Application.Contracts/H.LowCode.Application.Contracts.csproj @@ -5,6 +5,11 @@ + + + + + diff --git a/src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs b/src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs deleted file mode 100644 index 47fe3b0..0000000 --- a/src/Common/H.LowCode.Application.Contracts/ITableDataProvider.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Volo.Abp; - -namespace H.LowCode.Application.Contracts; - -/// -/// 表格数据提供者接口 -/// -public interface ITableDataProvider : IRemoteService -{ - /// - /// 获取表格数据 - /// - /// 数据请求参数 - /// 表格数据响应 - Task GetTableDataAsync(TableDataRequest request); -} - -/// -/// 表格数据请求参数 -/// -public class TableDataRequest -{ - /// - /// 应用ID - /// - public string? AppId { get; set; } - - /// - /// 页面ID - /// - public string? PageId { get; set; } - - /// - /// 数据源ID - /// - public string? DataSourceId { get; set; } - - /// - /// 页码(从1开始) - /// - public int PageIndex { get; set; } = 1; - - /// - /// 每页大小 - /// - public int PageSize { get; set; } = 10; - - /// - /// 排序字段 - /// - public string? SortField { get; set; } - - /// - /// 排序方向 - /// - public string? SortOrder { get; set; } - - /// - /// 筛选条件 - /// - public Dictionary? Filters { get; set; } -} - -/// -/// 表格数据响应 -/// -public class TableDataResponse -{ - /// - /// 数据项列表 - /// - public List> Items { get; set; } = new(); - - /// - /// 总记录数 - /// - public int TotalCount { get; set; } - - /// - /// 当前页码 - /// - public int PageIndex { get; set; } - - /// - /// 每页大小 - /// - public int PageSize { get; set; } -} \ No newline at end of file diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor index 354928d..d201216 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor @@ -1,10 +1,8 @@ @namespace H.LowCode.Components.Defaults @inherits LowCodeComponentBase -@using H.LowCode.Application.Contracts -@using H.LowCode.MetaSchema @inject IJSRuntime JS -@inject ITableDataProvider TableDataProvider +@inject ITableDataAppService TableDataAppService
@@ -124,18 +122,18 @@ { try { - var request = new TableDataRequest + var request = new TableDataInput { AppId = PageCascading?.AppId, PageId = PageCascading?.PageId, DataSourceId = DataSource?.DataSourceId, - PageIndex = _pageIndex, - PageSize = _pageSize + SkipCount = (_pageIndex - 1) * _pageSize, + MaxResultCount = _pageSize }; - var result = await TableDataProvider.GetTableDataAsync(request); - _data = result.Items; - _total = result.TotalCount; + var result = await TableDataAppService.GetListAsync(request); + _data = result.Items.ToList(); + _total = (int)result.TotalCount; Console.WriteLine($"列表数据: {result.ToJson()}"); } diff --git a/src/Common/H.LowCode.Components.Defaults/_Imports.razor b/src/Common/H.LowCode.Components.Defaults/_Imports.razor index 64b7a66..5c7a537 100644 --- a/src/Common/H.LowCode.Components.Defaults/_Imports.razor +++ b/src/Common/H.LowCode.Components.Defaults/_Imports.razor @@ -5,6 +5,7 @@ @using Microsoft.JSInterop @using AntDesign @using AntDesign.TableModels +@using H.LowCode.Application.Contracts @using H.LowCode.ComponentBase @using H.LowCode.MetaSchema @using H.Util.Blazor \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/DesignEngineApplicationContractsModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/DesignEngineApplicationContractsModule.cs index 9690860..cb0f8d7 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/DesignEngineApplicationContractsModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/DesignEngineApplicationContractsModule.cs @@ -1,16 +1,13 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; +using H.LowCode.Application.Contracts; using System.Reflection; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using Volo.Abp.Modularity; using Volo.Abp.Validation; namespace H.LowCode.DesignEngine.Application.Contracts; +[DependsOn( + typeof(LowCodeApplicationContractsModule) + )] public class DesignEngineApplicationContractsModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj index 61a8efc..de49e36 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application.Contracts/H.LowCode.DesignEngine.Application.Contracts.csproj @@ -7,6 +7,7 @@ + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs deleted file mode 100644 index 07fd2e0..0000000 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/DefaultTableDataProvider.cs +++ /dev/null @@ -1,41 +0,0 @@ -#nullable enable -using H.LowCode.Application.Contracts; -using H.LowCode.MetaSchema; - -namespace H.LowCode.ComponentBase.Services; - -/// -/// 默认表格数据提供者(提供模拟数据) -/// -public class DefaultTableDataProvider : ITableDataProvider -{ - public async Task GetTableDataAsync(TableDataRequest request) - { - await Task.Delay(100); // 模拟异步操作 - - // 生成模拟数据 - var items = new List>(); - - // 根据页码和页大小生成数据 - var startIndex = (request.PageIndex - 1) * request.PageSize; - for (int i = 0; i < 6; i++) - { - var rowIndex = startIndex + i + 1; - var row = new Dictionary - { - ["Id"] = rowIndex, - ["Name"] = $"示例数据 {rowIndex}", - ["CreateTime"] = DateTime.Now.AddDays(-rowIndex) - }; - items.Add(row); - } - - return new TableDataResponse - { - Items = items, - TotalCount = 100, // 模拟总数 - PageIndex = request.PageIndex, - PageSize = request.PageSize - }; - } -} \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs index 9c49c46..2ce75cd 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/DesignEngineApplicationModule.cs @@ -1,5 +1,3 @@ -using H.LowCode.Application.Contracts; -using H.LowCode.ComponentBase.Services; using H.LowCode.Configuration; using H.LowCode.DesignEngine.Domain; using Microsoft.Extensions.DependencyInjection; @@ -14,8 +12,5 @@ public class DesignEngineApplicationModule : AbpModule { var configuration = context.Services.GetConfiguration(); context.Services.Configure>(configuration.GetSection(SiteOption.SectionName)); - - // 注册默认的表格数据提供者 - context.Services.AddTransient(); } } diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/FormDataDomainService.cs b/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/FormDataDomainService.cs index 951ea4c..5c17f10 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/FormDataDomainService.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/FormDataDomainService.cs @@ -1,10 +1,5 @@ using H.LowCode.Entity; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Services; diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/ITableDataDomainService.cs b/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/ITableDataDomainService.cs deleted file mode 100644 index 5c913ac..0000000 --- a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/ITableDataDomainService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.DesignEngine.Domain; - -public interface ITableDataDomainService : IDomainService -{ - -} diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/TableDataDomainService.cs b/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/TableDataDomainService.cs deleted file mode 100644 index f70b94b..0000000 --- a/src/DesignEngine/H.LowCode.DesignEngine.Domain/DataDomainServices/TableDataDomainService.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.DesignEngine.Domain; - -public class TableDataDomainService : DomainService, ITableDataDomainService -{ - public TableDataDomainService(ITableDataRepository tableDataRepository) - { - - } -} diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs index 8302e34..23a0dbf 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs @@ -1,4 +1,5 @@ -using H.LowCode.ComponentBase; +using H.LowCode.Application.Contracts; +using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.DesignEngine.Application.Contracts; using H.LowCode.MyApp; @@ -59,5 +60,9 @@ public class DesignEngineHostClientModule : AbpModule typeof(DesignEngineApplicationContractsModule).Assembly, RemoteServiceName ); + context.Services.AddHttpClientProxies( + typeof(LowCodeApplicationContractsModule).Assembly, + RemoteServiceName + ); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/IFormDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/IFormDataAppService.cs deleted file mode 100644 index d155939..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/IFormDataAppService.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Volo.Abp.Http; -using Volo.Abp.Application.Services; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public interface IFormDataAppService : IApplicationService -{ - Task SaveAsync(FormDataDTO dto); - - Task GetAsync(string appId, string pageId, string id); - - Task DeleteAsync(string appId, string pageId, string id); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/ITableDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/ITableDataAppService.cs deleted file mode 100644 index 9643cf9..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataAppServices/ITableDataAppService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using H.LowCode.MetaSchema; -using Volo.Abp.Application.Services; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public interface ITableDataAppService : IApplicationService -{ - Task GetList(TableGetListInput input); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/DataDTOBase.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/DataDTOBase.cs deleted file mode 100644 index 872c454..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/DataDTOBase.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public abstract class DataDTOBase -{ - public DateTime CreatedTime { get; set; } - - public string CreatedUser { get; set; } - - public DateTime ModifiedTime { get; set; } - - public string ModifiedUser { get; set; } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormCreateOrUpdateDTO.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormCreateOrUpdateDTO.cs deleted file mode 100644 index 3c718ca..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormCreateOrUpdateDTO.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public class FormCreateOrUpdateDTO -{ - -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs deleted file mode 100644 index 377d9ef..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/FormDataDTO.cs +++ /dev/null @@ -1,56 +0,0 @@ -using H.LowCode.MetaSchema; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public class FormDataDTO : DataDTOBase -{ - public string Name { get; set; } - - public IList Fields { get; set; } - - public IList ValidationRules { get; set; } = []; -} - -public class FormFieldDTO -{ - public string Name { get; set; } - - /// - /// Value 值的类型 - /// - /// init 用于控制允许在 AutoMapper 场景赋值, 不允许外部赋值 - public string TypeName { get; init; } - - private object _value; - public object Value - { - get - { - if (string.IsNullOrEmpty(TypeName)) - throw new InvalidDataException($"TypeName is null or empty, field={this.ToJson()}"); - - var type = Type.GetType(TypeName); - if (type == null) - throw new InvalidDataException($"Type '{TypeName}' not found, field={this.ToJson()}"); - - try - { - var realValue = _value.ConvertToRealType(type); - return realValue; - } - catch (Exception ex) - { - throw new InvalidDataException($"Failed to convert value '{_value}' to type '{TypeName}', field={this.ToJson()}", ex); - } - } - set - { - _value = value; - } - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs deleted file mode 100644 index 81e991b..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListInput.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public class TableGetListInput -{ - /// - /// 应用ID - /// - public string AppId { get; set; } - - /// - /// 页面ID - /// - public string PageId { get; set; } - - /// - /// 数据源ID - /// - public string DataSourceId { get; set; } - - /// - /// 页码(从1开始) - /// - public int PageIndex { get; set; } = 1; - - /// - /// 每页大小 - /// - public int PageSize { get; set; } = 10; - - /// - /// 排序字段 - /// - public string SortField { get; set; } - - /// - /// 排序方向(asc/desc) - /// - public string SortOrder { get; set; } - - /// - /// 筛选条件 - /// - public Dictionary Filters { get; set; } = new Dictionary(); -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs deleted file mode 100644 index 2d3deb6..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/DataDTOs/TableGetListOutput.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace H.LowCode.RenderEngine.Application.Contracts; - -public class TableGetListOutput -{ - /// - /// 数据列表 - /// - public List> Items { get; set; } = new List>(); - - /// - /// 总记录数 - /// - public int TotalCount { get; set; } - - /// - /// 当前页码 - /// - public int PageIndex { get; set; } - - /// - /// 每页大小 - /// - public int PageSize { get; set; } - - /// - /// 总页数 - /// - public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)TotalCount / PageSize) : 0; - - /// - /// 是否有下一页 - /// - public bool HasNextPage => PageIndex < TotalPages; - - /// - /// 是否有上一页 - /// - public bool HasPreviousPage => PageIndex > 1; -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj index f64dcd7..f726ecf 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/H.LowCode.RenderEngine.Application.Contracts.csproj @@ -8,6 +8,7 @@ + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/RenderEngineApplicationContractsModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/RenderEngineApplicationContractsModule.cs index fc56a27..27cd7e1 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/RenderEngineApplicationContractsModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application.Contracts/RenderEngineApplicationContractsModule.cs @@ -1,12 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using H.LowCode.Application.Contracts; using Volo.Abp.Modularity; namespace H.LowCode.RenderEngine.Application.Contracts; +[DependsOn( + typeof(LowCodeApplicationContractsModule) + )] public class RenderEngineApplicationContractsModule : AbpModule { diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/FormDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/FormDataAppService.cs index 786d7ce..139db1d 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/FormDataAppService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/FormDataAppService.cs @@ -1,37 +1,354 @@ -using H.LowCode.RenderEngine.Domain; -using H.LowCode.RenderEngine.Application.Contracts; +using H.LowCode.Application.Contracts; +using H.LowCode.Entity; +using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain.Repositories; using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.Application.Services; -using H.LowCode.Entity; -using System.Text.Json; +using Volo.Abp.Domain.Entities; namespace H.LowCode.RenderEngine.Application; [RemoteService] public class FormDataAppService : ApplicationService, IFormDataAppService { - private IFormDataDomainService _formDataDomainService => LazyServiceProvider.GetRequiredService(); + private IFormDataRepository _formDataRepository => LazyServiceProvider.GetRequiredService(); + private IPageRepository _pageRepository => LazyServiceProvider.GetRequiredService(); - public async Task GetAsync(string appId, string pageId, string id) + public async Task GetAsync(string appId, string pageId, string id) { - var entity = await _formDataDomainService.GetAsync(appId, pageId, id); - var dto = ObjectMapper.Map(entity); + var formPageSchema = await _pageRepository.GetAsync(appId, pageId); + if (formPageSchema == null) + throw new KeyNotFoundException($"page not found: appId={appId}, pageId={pageId}"); + + string entityName = formPageSchema.DataSource.DataSourceValue; + + if (string.IsNullOrEmpty(id)) + { + var defaultEntity = new FormEntity() + { + Name = entityName, + Fields = formPageSchema.Components.Where(t => t.IsContainer == false) + .Select(t => new FormFieldEntity() + { + Name = t.Name, + TypeName = t.Fragment.ValueType, + Value = t.Fragment.GetDefaultValue() + }).ToList() + }; + var defaultDto = ObjectMapper.Map(defaultEntity); + return defaultDto; + } + + var entity = await _formDataRepository.GetAsync(entityName, id); + if (entity == null) + throw new EntityNotFoundException($"Entity {entityName} Not Found: {id}"); + + var dto = ObjectMapper.Map(entity); return dto; } - public async Task SaveAsync(FormDataDTO dto) + public async Task SaveAsync(FormDataDto dto) { - var entity = ObjectMapper.Map(dto); - return await _formDataDomainService.SaveAsync(entity); + if (dto == null) + throw new ArgumentNullException(nameof(dto)); + + var entity = ObjectMapper.Map(dto); + + // 设置默认表名 + entity.Name = entity.Name ?? "tb_test1"; + + // 验证字段 + if (entity.Fields == null || !entity.Fields.Any()) + throw new ArgumentException("表单字段不能为空", nameof(entity)); + + // 验证字段值类型 + foreach (var field in entity.Fields) + { + if (string.IsNullOrEmpty(field.Name)) + throw new ArgumentException("字段名称不能为空"); + + if (string.IsNullOrEmpty(field.TypeName)) + throw new ArgumentException($"字段 {field.Name} 的类型不能为空"); + } + + // 应用字段验证和默认值 + await ApplyFieldValidationAndDefaults(entity); + + try + { + // 检查是否为新增记录(通过主键字段判断) + string primaryKeyName = "f_id"; + var primaryKeyField = entity.Fields.FirstOrDefault(f => f.Name == primaryKeyName); + + bool isNewRecord = primaryKeyField == null || + string.IsNullOrEmpty(primaryKeyField.Value?.ToString()); + + if (isNewRecord) + { + // 新增记录 - 设置主键字段值 + if (primaryKeyField == null) + { + // 如果主键字段不存在,创建一个 + primaryKeyField = new FormFieldEntity + { + Name = primaryKeyName, + TypeName = typeof(string).FullName, + Value = Guid.NewGuid().ToString() + }; + entity.Fields.Add(primaryKeyField); + } + else + { + // 如果主键字段存在但值为空,设置新值 + primaryKeyField.Value = Guid.NewGuid().ToString(); + } + + await _formDataRepository.AddAsync(entity); + } + else + { + // 更新记录 + await _formDataRepository.UpdateAsync(entity); + } + return true; + } + catch (Exception ex) + { + // 记录错误日志 + string entityId = ""; + try { entityId = entity.Id; } catch { } + Logger.LogError(ex, "保存表单数据失败: EntityName={EntityName}, EntityId={EntityId}", entity.Name, entityId); + throw; + } + } + + /// + /// 应用字段验证和默认值设置 + /// + private async Task ApplyFieldValidationAndDefaults(FormEntity entity) + { + // 获取页面配置以获取字段默认值定义 + var pageConfig = await GetPageConfigForEntity(entity.Name); + + foreach (var field in entity.Fields) + { + // 跳过主键字段的验证和默认值处理 + if (field.Name == "f_id") + continue; + + // 获取字段类型 + var fieldType = Type.GetType(field.TypeName); + if (fieldType == null) + continue; + + // 检查字段是否有有效值 + bool hasValidValue = HasValidValue(field.Value, fieldType); + + if (!hasValidValue) + { + // 首先尝试从页面配置获取默认值 + var configDefaultValue = GetFieldDefaultValueFromConfig(field.Name, fieldType, pageConfig); + if (configDefaultValue != null) + { + field.Value = configDefaultValue; + Logger.LogInformation("Applied config default value for field '{FieldName}': {DefaultValue}", + field.Name, configDefaultValue); + } + else + { + // 如果没有配置默认值,使用类型默认值 + field.Value = GetTypeDefaultValue(fieldType); + Logger.LogInformation("Applied type default value for field '{FieldName}': {DefaultValue}", + field.Name, field.Value); + } + } + + // 验证字段值的有效性 + ValidateFieldValue(field, fieldType); + } + } + + /// + /// 检查字段是否有有效值 + /// + private bool HasValidValue(object value, Type fieldType) + { + if (value == null) + return false; + + // 字符串类型:空字符串视为无效值 + if (fieldType == typeof(string)) + return !string.IsNullOrWhiteSpace(value.ToString()); + + // 数值类型:0值可能是有效值,所以只检查null + if (fieldType == typeof(int) || fieldType == typeof(int?) || + fieldType == typeof(long) || fieldType == typeof(long?) || + fieldType == typeof(decimal) || fieldType == typeof(decimal?)) + return true; + + // 布尔类型:false也是有效值 + if (fieldType == typeof(bool) || fieldType == typeof(bool?)) + return true; + + // DateTime类型:检查是否为默认值 + if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) + { + if (value is DateTime dateValue) + return dateValue != default(DateTime); + return true; + } + + // Guid类型:检查是否为空Guid + if (fieldType == typeof(Guid) || fieldType == typeof(Guid?)) + { + if (value is Guid guidValue) + return guidValue != Guid.Empty; + return true; + } + + return true; + } + + /// + /// 获取类型的默认值 + /// + private object GetTypeDefaultValue(Type type) + { + if (type == null) + return null; + + // 处理可空类型 + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + return null; + } + + // 处理字符串类型 + if (type == typeof(string)) + return string.Empty; + + // 处理基本数值类型 + if (type == typeof(int)) + return 0; + if (type == typeof(long)) + return 0L; + if (type == typeof(decimal)) + return 0m; + if (type == typeof(double)) + return 0.0; + if (type == typeof(float)) + return 0.0f; + if (type == typeof(short)) + return (short)0; + if (type == typeof(byte)) + return (byte)0; + + // 处理布尔类型 + if (type == typeof(bool)) + return false; + + // 处理日期时间类型 + if (type == typeof(DateTime)) + return DateTime.Now; + if (type == typeof(DateTimeOffset)) + return DateTimeOffset.Now; + + // 处理Guid类型 + if (type == typeof(Guid)) + return Guid.NewGuid(); + + // 处理集合类型 + if (type.IsArray) + { + return Array.CreateInstance(type.GetElementType(), 0); + } + + if (type.IsGenericType) + { + var genericTypeDef = type.GetGenericTypeDefinition(); + if (genericTypeDef == typeof(List<>) || + genericTypeDef == typeof(IList<>) || + genericTypeDef == typeof(ICollection<>) || + genericTypeDef == typeof(IEnumerable<>)) + { + return Activator.CreateInstance(typeof(List<>).MakeGenericType(type.GetGenericArguments())); + } + } + + // 对于其他值类型,返回类型的默认值 + if (type.IsValueType) + return Activator.CreateInstance(type); + + // 其他引用类型返回null + return null; + } + + /// + /// 验证字段值的有效性 + /// + private void ValidateFieldValue(FormFieldEntity field, Type fieldType) + { + try + { + // 尝试转换值以验证类型兼容性 + if (field.Value != null) + { + //Convert.ChangeType(field.Value, fieldType); + } + } + catch (Exception ex) + { + throw new ArgumentException($"Field '{field.Name}' value '{field.Value}' is not compatible with type '{fieldType.Name}'", ex); + } + } + + /// + /// 获取页面配置 + /// + private async Task GetPageConfigForEntity(string entityName) + { + try + { + // 通过实体名称查找对应的页面配置 + // 这里简化处理,实际应该通过数据源配置来查找页面 + // TODO: 实现更精确的页面配置查找逻辑 + return null; + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Failed to get page config for entity '{EntityName}'", entityName); + return null; + } + } + + /// + /// 从页面配置中获取字段默认值 + /// + private object GetFieldDefaultValueFromConfig(string fieldName, Type fieldType, object pageConfig) + { + if (pageConfig == null) + return null; + + try + { + // TODO: 实现从页面配置JSON中解析字段默认值的逻辑 + // 这里需要解析页面配置中的组件定义,找到对应字段的默认值 + // 由于页面配置结构复杂,暂时返回null + return null; + } + catch (Exception ex) + { + Logger.LogWarning(ex, "Failed to get default value from config for field '{FieldName}'", fieldName); + return null; + } } public async Task DeleteAsync(string appId, string pageId, string id) { - return await _formDataDomainService.DeleteAsync(appId, pageId, id); + var formPageSchema = await _pageRepository.GetAsync(appId, pageId); + + return await _formDataRepository.DeleteAsync(formPageSchema.DataSource.DataSourceValue, id); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs deleted file mode 100644 index d621577..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/RenderEngineTableDataProvider.cs +++ /dev/null @@ -1,94 +0,0 @@ -using H.LowCode.Application.Contracts; -using H.LowCode.RenderEngine.Application.Contracts; -using H.LowCode.RenderEngine.Domain; - -namespace H.LowCode.RenderEngine.Application.DataAppServices; - -/// -/// 渲染引擎表格数据提供者 -/// -public class RenderEngineTableDataProvider : ITableDataProvider -{ - private readonly ITableDataDomainService _tableDataDomainService; - - public RenderEngineTableDataProvider(ITableDataDomainService tableDataDomainService) - { - _tableDataDomainService = tableDataDomainService; - } - - public async Task GetTableDataAsync(TableDataRequest request) - { - try - { - // 检查是否配置了数据源ID - if (string.IsNullOrEmpty(request.DataSourceId)) - { - // 返回默认模拟数据 - return await GetDefaultDataAsync(request); - } - - // 转换为Domain层的输入参数 - var input = new TableGetListInput - { - AppId = request.AppId, - PageId = request.PageId, - DataSourceId = request.DataSourceId, - PageIndex = request.PageIndex, - PageSize = request.PageSize, - SortField = request.SortField, - SortOrder = request.SortOrder, - Filters = request.Filters ?? new Dictionary() - }; - - // 调用Domain层服务获取数据 - var result = await _tableDataDomainService.GetListAsync(input); - - // 转换为组件层的响应格式 - return new TableDataResponse - { - Items = result.Items, - TotalCount = result.TotalCount, - PageIndex = result.PageIndex, - PageSize = result.PageSize - }; - } - catch (Exception ex) - { - // 出错时返回默认数据 - Console.WriteLine($"获取表格数据失败: {ex.Message}"); - return await GetDefaultDataAsync(request); - } - } - - private async Task GetDefaultDataAsync(TableDataRequest request) - { - await Task.Delay(100); // 模拟异步操作 - - // 生成模拟数据 - var items = new List>(); - - // 根据页码和页大小生成数据 - var startIndex = (request.PageIndex - 1) * request.PageSize; - for (int i = 0; i < request.PageSize; i++) - { - var rowIndex = startIndex + i + 1; - var row = new Dictionary - { - ["Id"] = rowIndex, - ["Name"] = $"示例数据 {rowIndex}", - ["Status"] = rowIndex % 2 == 0 ? "启用" : "禁用", - ["CreateTime"] = DateTime.Now.AddDays(-rowIndex), - ["Description"] = $"这是第 {rowIndex} 行的描述信息" - }; - items.Add(row); - } - - return new TableDataResponse - { - Items = items, - TotalCount = 100, // 模拟总数 - PageIndex = request.PageIndex, - PageSize = request.PageSize - }; - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs index cbed32f..8d154d8 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs @@ -1,23 +1,24 @@ +using H.LowCode.Application.Contracts; using H.LowCode.RenderEngine.Domain; -using H.LowCode.RenderEngine.Application.Contracts; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp; +using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace H.LowCode.RenderEngine.Application; -[RemoteService] +/// +/// 渲染引擎表格数据提供者 +/// public class TableDataAppService : ApplicationService, ITableDataAppService { - private ITableDataDomainService _tableDataDomainService => LazyServiceProvider.GetRequiredService(); + private readonly ITableDataRepository _tableDataRepository; - public async Task GetList(TableGetListInput input) + public TableDataAppService(ITableDataRepository tableDataRepository) { - return await _tableDataDomainService.GetListAsync(input); + _tableDataRepository = tableDataRepository; } -} + + public async Task>> GetListAsync(TableDataInput input) + { + return await _tableDataRepository.GetListAsync(input); + } +} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/MapperProfiles/LowCodeAutoMapperProfile.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/MapperProfiles/LowCodeAutoMapperProfile.cs index 4ccfdfb..fc0104c 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/MapperProfiles/LowCodeAutoMapperProfile.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/MapperProfiles/LowCodeAutoMapperProfile.cs @@ -1,11 +1,6 @@ using AutoMapper; -using H.LowCode.RenderEngine.Application.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using H.LowCode.Entity; +using H.LowCode.Application.Contracts; namespace H.LowCode.RenderEngine.Application; @@ -13,10 +8,10 @@ public class LowCodeAutoMapperProfile : Profile { public LowCodeAutoMapperProfile() { - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap(); - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap(); } } \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderAppServices/MetaAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderAppServices/MetaAppService.cs index 29dd630..cfd52ef 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderAppServices/MetaAppService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderAppServices/MetaAppService.cs @@ -2,6 +2,7 @@ using H.LowCode.MetaSchema.RenderEngine; using H.LowCode.RenderEngine.Application.Contracts; using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain.Repositories; using Microsoft.Extensions.DependencyInjection; using System.Text; using Volo.Abp; @@ -12,17 +13,17 @@ namespace H.LowCode.RenderEngine.Application; [RemoteService] public class MetaAppService : ApplicationService, IMetaAppService { - private IMenuDomainService _menuDomainService => LazyServiceProvider.GetRequiredService(); - private IPageDomainService _pageDomainService => LazyServiceProvider.GetRequiredService(); + private IMenuRepository _menuRepository => LazyServiceProvider.GetRequiredService(); + private IPageRepository _pageRepository => LazyServiceProvider.GetRequiredService(); public async Task> GetMenusAsync(string appId) { - return await _menuDomainService.GetListAsync(appId); + return await _menuRepository.GetListAsync(appId); } public async Task GetPageAsync(string appId, string pageId) { - return await _pageDomainService.GetAsync(appId, pageId); + return await _pageRepository.GetAsync(appId, pageId); } /// @@ -33,7 +34,7 @@ public class MetaAppService : ApplicationService, IMetaAppService /// public async Task GetPageWithDefineAsync(string appId, string pageId) { - var pageSchema = await _pageDomainService.GetAsync(appId, pageId); + var pageSchema = await _pageRepository.GetAsync(appId, pageId); if (pageSchema?.Components != null) { diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs index 49b1cee..60cdc5e 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/RenderEngineApplicationModule.cs @@ -3,8 +3,6 @@ using H.LowCode.RenderEngine.Domain; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; -using H.LowCode.RenderEngine.Application.DataAppServices; -using H.LowCode.Application.Contracts; namespace H.LowCode.RenderEngine.Application; @@ -25,8 +23,5 @@ public class RenderEngineApplicationModule : AbpModule { options.AddMaps(); }); - - // 注册渲染引擎专用的表格数据提供者,覆盖默认实现 - context.Services.AddTransient(); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs deleted file mode 100644 index b474711..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/FormDataDomainService.cs +++ /dev/null @@ -1,352 +0,0 @@ -using H.LowCode.Entity; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; -using Volo.Abp.Domain.Entities; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class FormDataDomainService : DomainService, IFormDataDomainService -{ - private IFormDataRepository _formDataRepository => LazyServiceProvider.GetRequiredService(); - private IPageDomainService _pageDomainService => LazyServiceProvider.GetRequiredService(); - - public async Task GetAsync(string appId, string pageId, string id) - { - var formPageSchema = await _pageDomainService.GetAsync(appId, pageId); - if (formPageSchema == null) - throw new KeyNotFoundException($"page not found: appId={appId}, pageId={pageId}"); - - string entityName = formPageSchema.DataSource.DataSourceValue; - - if (string.IsNullOrEmpty(id)) - { - var defaultEntity = new FormEntity() - { - Name = entityName, - Fields = formPageSchema.Components.Where(t => t.IsContainer == false) - .Select(t => new FormFieldEntity() - { - Name = t.Name, - TypeName = t.Fragment.ValueType, - Value = t.Fragment.GetDefaultValue() - }).ToList() - }; - return defaultEntity; - } - - var entity = await _formDataRepository.GetAsync(entityName, id); - if (entity == null) - throw new EntityNotFoundException($"Entity {entityName} Not Found: {id}"); - - return entity; - } - - public async Task SaveAsync(FormEntity entity) - { - // 验证实体 - if (entity == null) - throw new ArgumentNullException(nameof(entity)); - - // 设置默认表名 - entity.Name = entity.Name ?? "tb_test1"; - - // 验证字段 - if (entity.Fields == null || !entity.Fields.Any()) - throw new ArgumentException("表单字段不能为空", nameof(entity)); - - // 验证字段值类型 - foreach (var field in entity.Fields) - { - if (string.IsNullOrEmpty(field.Name)) - throw new ArgumentException("字段名称不能为空"); - - if (string.IsNullOrEmpty(field.TypeName)) - throw new ArgumentException($"字段 {field.Name} 的类型不能为空"); - } - - // 应用字段验证和默认值 - await ApplyFieldValidationAndDefaults(entity); - - try - { - // 检查是否为新增记录(通过主键字段判断) - string primaryKeyName = "f_id"; - var primaryKeyField = entity.Fields.FirstOrDefault(f => f.Name == primaryKeyName); - - bool isNewRecord = primaryKeyField == null || - string.IsNullOrEmpty(primaryKeyField.Value?.ToString()); - - if (isNewRecord) - { - // 新增记录 - 设置主键字段值 - if (primaryKeyField == null) - { - // 如果主键字段不存在,创建一个 - primaryKeyField = new FormFieldEntity - { - Name = primaryKeyName, - TypeName = typeof(string).FullName, - Value = Guid.NewGuid().ToString() - }; - entity.Fields.Add(primaryKeyField); - } - else - { - // 如果主键字段存在但值为空,设置新值 - primaryKeyField.Value = Guid.NewGuid().ToString(); - } - - await _formDataRepository.AddAsync(entity); - } - else - { - // 更新记录 - await _formDataRepository.UpdateAsync(entity); - } - return true; - } - catch (Exception ex) - { - // 记录错误日志 - string entityId = ""; - try { entityId = entity.Id; } catch { } - Logger.LogError(ex, "保存表单数据失败: EntityName={EntityName}, EntityId={EntityId}", entity.Name, entityId); - throw; - } - } - - /// - /// 应用字段验证和默认值设置 - /// - private async Task ApplyFieldValidationAndDefaults(FormEntity entity) - { - // 获取页面配置以获取字段默认值定义 - var pageConfig = await GetPageConfigForEntity(entity.Name); - - foreach (var field in entity.Fields) - { - // 跳过主键字段的验证和默认值处理 - if (field.Name == "f_id") - continue; - - // 获取字段类型 - var fieldType = Type.GetType(field.TypeName); - if (fieldType == null) - continue; - - // 检查字段是否有有效值 - bool hasValidValue = HasValidValue(field.Value, fieldType); - - if (!hasValidValue) - { - // 首先尝试从页面配置获取默认值 - var configDefaultValue = GetFieldDefaultValueFromConfig(field.Name, fieldType, pageConfig); - if (configDefaultValue != null) - { - field.Value = configDefaultValue; - Logger.LogInformation("Applied config default value for field '{FieldName}': {DefaultValue}", - field.Name, configDefaultValue); - } - else - { - // 如果没有配置默认值,使用类型默认值 - field.Value = GetTypeDefaultValue(fieldType); - Logger.LogInformation("Applied type default value for field '{FieldName}': {DefaultValue}", - field.Name, field.Value); - } - } - - // 验证字段值的有效性 - ValidateFieldValue(field, fieldType); - } - } - - /// - /// 检查字段是否有有效值 - /// - private bool HasValidValue(object value, Type fieldType) - { - if (value == null) - return false; - - // 字符串类型:空字符串视为无效值 - if (fieldType == typeof(string)) - return !string.IsNullOrWhiteSpace(value.ToString()); - - // 数值类型:0值可能是有效值,所以只检查null - if (fieldType == typeof(int) || fieldType == typeof(int?) || - fieldType == typeof(long) || fieldType == typeof(long?) || - fieldType == typeof(decimal) || fieldType == typeof(decimal?)) - return true; - - // 布尔类型:false也是有效值 - if (fieldType == typeof(bool) || fieldType == typeof(bool?)) - return true; - - // DateTime类型:检查是否为默认值 - if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?)) - { - if (value is DateTime dateValue) - return dateValue != default(DateTime); - return true; - } - - // Guid类型:检查是否为空Guid - if (fieldType == typeof(Guid) || fieldType == typeof(Guid?)) - { - if (value is Guid guidValue) - return guidValue != Guid.Empty; - return true; - } - - return true; - } - - /// - /// 获取类型的默认值 - /// - private object GetTypeDefaultValue(Type type) - { - if (type == null) - return null; - - // 处理可空类型 - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) - { - return null; - } - - // 处理字符串类型 - if (type == typeof(string)) - return string.Empty; - - // 处理基本数值类型 - if (type == typeof(int)) - return 0; - if (type == typeof(long)) - return 0L; - if (type == typeof(decimal)) - return 0m; - if (type == typeof(double)) - return 0.0; - if (type == typeof(float)) - return 0.0f; - if (type == typeof(short)) - return (short)0; - if (type == typeof(byte)) - return (byte)0; - - // 处理布尔类型 - if (type == typeof(bool)) - return false; - - // 处理日期时间类型 - if (type == typeof(DateTime)) - return DateTime.Now; - if (type == typeof(DateTimeOffset)) - return DateTimeOffset.Now; - - // 处理Guid类型 - if (type == typeof(Guid)) - return Guid.NewGuid(); - - // 处理集合类型 - if (type.IsArray) - { - return Array.CreateInstance(type.GetElementType(), 0); - } - - if (type.IsGenericType) - { - var genericTypeDef = type.GetGenericTypeDefinition(); - if (genericTypeDef == typeof(List<>) || - genericTypeDef == typeof(IList<>) || - genericTypeDef == typeof(ICollection<>) || - genericTypeDef == typeof(IEnumerable<>)) - { - return Activator.CreateInstance(typeof(List<>).MakeGenericType(type.GetGenericArguments())); - } - } - - // 对于其他值类型,返回类型的默认值 - if (type.IsValueType) - return Activator.CreateInstance(type); - - // 其他引用类型返回null - return null; - } - - /// - /// 验证字段值的有效性 - /// - private void ValidateFieldValue(FormFieldEntity field, Type fieldType) - { - try - { - // 尝试转换值以验证类型兼容性 - if (field.Value != null) - { - //Convert.ChangeType(field.Value, fieldType); - } - } - catch (Exception ex) - { - throw new ArgumentException($"Field '{field.Name}' value '{field.Value}' is not compatible with type '{fieldType.Name}'", ex); - } - } - - /// - /// 获取页面配置 - /// - private async Task GetPageConfigForEntity(string entityName) - { - try - { - // 通过实体名称查找对应的页面配置 - // 这里简化处理,实际应该通过数据源配置来查找页面 - // TODO: 实现更精确的页面配置查找逻辑 - return null; - } - catch (Exception ex) - { - Logger.LogWarning(ex, "Failed to get page config for entity '{EntityName}'", entityName); - return null; - } - } - - /// - /// 从页面配置中获取字段默认值 - /// - private object GetFieldDefaultValueFromConfig(string fieldName, Type fieldType, object pageConfig) - { - if (pageConfig == null) - return null; - - try - { - // TODO: 实现从页面配置JSON中解析字段默认值的逻辑 - // 这里需要解析页面配置中的组件定义,找到对应字段的默认值 - // 由于页面配置结构复杂,暂时返回null - return null; - } - catch (Exception ex) - { - Logger.LogWarning(ex, "Failed to get default value from config for field '{FieldName}'", fieldName); - return null; - } - } - - public async Task DeleteAsync(string appId, string pageId, string id) - { - var formPageSchema = await _pageDomainService.GetAsync(appId, pageId); - - return await _formDataRepository.DeleteAsync(formPageSchema.DataSource.DataSourceValue, id); - } -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/IFormDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/IFormDataDomainService.cs deleted file mode 100644 index a2c94bb..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/IFormDataDomainService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using H.LowCode.Entity; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IFormDataDomainService : IDomainService -{ - Task SaveAsync(FormEntity entity); - - Task GetAsync(string appId, string pageId, string id); - - Task DeleteAsync(string appId, string pageId, string id); -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs deleted file mode 100644 index e041a43..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/ITableDataDomainService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using H.LowCode.RenderEngine.Application.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface ITableDataDomainService : IDomainService -{ - /// - /// 获取表格数据列表 - /// - /// 查询参数 - /// 分页数据结果 - Task GetListAsync(TableGetListInput input); -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs deleted file mode 100644 index e28f4d2..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataDomainServices/TableDataDomainService.cs +++ /dev/null @@ -1,29 +0,0 @@ -using H.LowCode.RenderEngine.Application.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class TableDataDomainService : DomainService, ITableDataDomainService -{ - private readonly ITableDataRepository _tableDataRepository; - - public TableDataDomainService(ITableDataRepository tableDataRepository) - { - _tableDataRepository = tableDataRepository; - } - - /// - /// 获取表格数据列表 - /// - /// 查询参数 - /// 分页数据结果 - public async Task GetListAsync(TableGetListInput input) - { - return await _tableDataRepository.GetListAsync(input); - } -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs index bc10405..26f1f71 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs @@ -1,19 +1,10 @@ -using H.LowCode.RenderEngine.Application.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using H.LowCode.Application.Contracts; +using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Repositories; namespace H.LowCode.RenderEngine.Domain; public interface ITableDataRepository : IRepository { - /// - /// 获取表格数据列表 - /// - /// 查询参数 - /// 分页数据结果 - Task GetListAsync(TableGetListInput input); + Task>> GetListAsync(TableDataInput input); } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/AppDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/AppDomainService.cs deleted file mode 100644 index 663f025..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/AppDomainService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using H.LowCode.RenderEngine.Domain.Repositories; -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class AppDomainService : DomainService, IAppDomainService -{ - private readonly IAppRepository _repository; - - public AppDomainService(IAppRepository repository) - { - _repository = repository; - } - - public async Task> GetListAsync() - { - return await _repository.GetListAsync(); - } - - public async Task GetAsync(string appId) - { - return await _repository.GetAsync(appId); - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/DataSourceDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/DataSourceDomainService.cs deleted file mode 100644 index ad6a1ab..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/DataSourceDomainService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using H.LowCode.RenderEngine.Domain.Repositories; -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class DataSourceDomainService : DomainService, IDataSourceDomainService -{ - private readonly IDataSourceRepository _repository; - - public DataSourceDomainService(IDataSourceRepository repository) - { - _repository = repository; - } - - public async Task> GetListAsync(string appId) - { - return await _repository.GetListAsync(appId); - } - - public async Task> GetAllApisAsync(string appId) - { - var list = await GetListAsync(appId); - return list.Where(t => t.DataSourceType == ComponentDataSourceTypeEnum.API).ToList(); - } - - public IEnumerable GetAllEntities(string appId) - { - var list = GetListAsync(appId).Result; - return list.Where(t => t.DataSourceType == ComponentDataSourceTypeEnum.DB).ToList(); - } - - public async Task GetAsync(string appId, string id) - { - return await _repository.GetAsync(appId, id); - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IAppDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IAppDomainService.cs deleted file mode 100644 index 680440b..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IAppDomainService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IAppDomainService : IDomainService -{ - Task> GetListAsync(); - - Task GetAsync(string appId); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IDataSourceDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IDataSourceDomainService.cs deleted file mode 100644 index a6d34c3..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IDataSourceDomainService.cs +++ /dev/null @@ -1,15 +0,0 @@ -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IDataSourceDomainService : IDomainService -{ - Task> GetListAsync(string appId); - - Task> GetAllApisAsync(string appId); - - IEnumerable GetAllEntities(string appId); - - Task GetAsync(string appId, string id); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMenuDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMenuDomainService.cs deleted file mode 100644 index f7cefa5..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMenuDomainService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IMenuDomainService : IDomainService -{ - Task GetAsync(string appId, string menuId); - - Task> GetListAsync(string appId); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMetaDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMetaDomainService.cs deleted file mode 100644 index 667b9e4..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IMetaDomainService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IMetaDomainService : IDomainService -{ - -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IPageDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IPageDomainService.cs deleted file mode 100644 index e5c982f..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/IPageDomainService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using H.LowCode.MetaSchema.RenderEngine; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public interface IPageDomainService : IDomainService -{ - Task GetAsync(string appId, string pageId); -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MenuDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MenuDomainService.cs deleted file mode 100644 index eedd7e5..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MenuDomainService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using H.LowCode.RenderEngine.Domain.Repositories; -using H.LowCode.MetaSchema; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class MenuDomainService : DomainService, IMenuDomainService -{ - private readonly IMenuRepository _repository; - - public MenuDomainService(IMenuRepository repository) - { - _repository = repository; - } - - public async Task> GetListAsync(string appId) - { - return await _repository.GetListAsync(appId); - } - - public async Task GetAsync(string appId, string menuId) - { - return await _repository.GetAsync(appId, menuId); - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MetaDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MetaDomainService.cs deleted file mode 100644 index 83b721a..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/MetaDomainService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class MetaDomainService : DomainService, IMetaDomainService -{ - -} diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/PageDomainService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/PageDomainService.cs deleted file mode 100644 index f37aefe..0000000 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaDomainServices/PageDomainService.cs +++ /dev/null @@ -1,20 +0,0 @@ -using H.LowCode.RenderEngine.Domain.Repositories; -using H.LowCode.MetaSchema.RenderEngine; -using Volo.Abp.Domain.Services; - -namespace H.LowCode.RenderEngine.Domain; - -public class PageDomainService : DomainService, IPageDomainService -{ - private readonly IPageRepository _repository; - - public PageDomainService(IPageRepository repository) - { - _repository = repository; - } - - async Task IPageDomainService.GetAsync(string appId, string pageId) - { - return await _repository.GetAsync(appId, pageId); - } -} \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaRepositories/IDataSourceRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaRepositories/IDataSourceRepository.cs index b13f2ab..9edabcf 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaRepositories/IDataSourceRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/MetaRepositories/IDataSourceRepository.cs @@ -7,4 +7,8 @@ public interface IDataSourceRepository Task> GetListAsync(string appId); Task GetAsync(string appId, string id); + + Task> GetAllApisAsync(string appId); + + IEnumerable GetAllEntities(string appId); } \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs index b661ae0..043be0f 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs @@ -1,25 +1,21 @@ -using H.LowCode.RenderEngine.Application.Contracts; +using H.LowCode.Application.Contracts; using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain.Repositories; using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; namespace H.LowCode.RenderEngine.EntityFrameworkCore; public class TableDataRepository : ITableDataRepository { private readonly IDbContextFactory _dbContextFactory; - private readonly IDataSourceDomainService _dataSourceDomainService; + private readonly IDataSourceRepository _dataSourceRepository; public bool? IsChangeTrackingEnabled => true; - public TableDataRepository(IDbContextFactory dbContextFactory, IDataSourceDomainService dataSourceDomainService) + public TableDataRepository(IDbContextFactory dbContextFactory, IDataSourceRepository dataSourceRepository) { _dbContextFactory = dbContextFactory; - _dataSourceDomainService = dataSourceDomainService; + _dataSourceRepository = dataSourceRepository; } /// @@ -27,119 +23,81 @@ public class TableDataRepository : ITableDataRepository /// /// 查询参数 /// 分页数据结果 - public async Task GetListAsync(TableGetListInput input) + public async Task>> GetListAsync(TableDataInput input) { - try + var dataSource = await _dataSourceRepository.GetAsync(input.AppId, input.DataSourceId); + if (dataSource == null) { - // 根据数据源ID获取数据源信息 - var dataSource = await _dataSourceDomainService.GetAsync(input.AppId, input.DataSourceId); - if (dataSource == null) - { - return new TableGetListOutput - { - Items = new List>(), - TotalCount = 0, - PageIndex = input.PageIndex, - PageSize = input.PageSize - }; - } + return new(); + } - // 使用 DbContextFactory 创建新的 DbContext 实例,确保线程安全 - using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - - // 获取实体类型(使用数据源名称) - var entityType = dbContext.GetEntityType(dataSource.Name); - - // 获取DbSet - var dbSetProperty = dbContext.GetType().GetMethod("Set", Type.EmptyTypes)?.MakeGenericMethod(entityType); - var dbSet = dbSetProperty?.Invoke(dbContext, null) as IQueryable; - - if (dbSet == null) - { - return new TableGetListOutput - { - Items = new List>(), - TotalCount = 0, - PageIndex = input.PageIndex, - PageSize = input.PageSize - }; - } + // 使用 DbContextFactory 创建新的 DbContext 实例,确保线程安全 + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - // 应用筛选条件 - if (input.Filters != null && input.Filters.Any()) - { - // 这里可以根据需要实现更复杂的筛选逻辑 - // 暂时跳过筛选实现 - } + // 获取实体类型(使用数据源名称) + var entityType = dbContext.GetEntityType(dataSource.Name); - // 应用排序 - if (!string.IsNullOrEmpty(input.SortField)) - { - var parameter = System.Linq.Expressions.Expression.Parameter(entityType, "x"); - var property = System.Linq.Expressions.Expression.Property(parameter, input.SortField); - var lambda = System.Linq.Expressions.Expression.Lambda(property, parameter); - - var orderByMethod = input.SortOrder?.ToLower() == "desc" ? "OrderByDescending" : "OrderBy"; - var orderByExpression = System.Linq.Expressions.Expression.Call( - typeof(Queryable), - orderByMethod, - new Type[] { entityType, property.Type }, - dbSet.Expression, - System.Linq.Expressions.Expression.Quote(lambda)); - - dbSet = dbSet.Provider.CreateQuery(orderByExpression); - } + // 获取DbSet + var dbSetProperty = dbContext.GetType().GetMethod("Set", Type.EmptyTypes)?.MakeGenericMethod(entityType); + var dbSet = dbSetProperty?.Invoke(dbContext, null) as IQueryable; - // 获取总数 - var totalCount = await dbSet.CountAsync(); + if (dbSet == null) + { + return new(); + } - // 应用分页 - var pagedData = await dbSet - .Skip((input.PageIndex - 1) * input.PageSize) - .Take(input.PageSize) - .ToListAsync(); + // 应用筛选条件 + if (input.Filters != null && input.Filters.Any()) + { + // 这里可以根据需要实现更复杂的筛选逻辑 + // 暂时跳过筛选实现 + } - // 转换为字典格式 - var result = new List>(); - foreach (var item in pagedData) - { - var dict = new Dictionary(); - var properties = entityType.GetProperties(); - foreach (var prop in properties) - { - var value = prop.GetValue(item); - dict[prop.Name] = value; - } - result.Add(dict); - } + // 应用排序 + if (!string.IsNullOrEmpty(input.Sorting)) + { + var parameter = System.Linq.Expressions.Expression.Parameter(entityType, "x"); + var property = System.Linq.Expressions.Expression.Property(parameter, input.Sorting); + var lambda = System.Linq.Expressions.Expression.Lambda(property, parameter); - // 计算分页信息 - var totalPages = (int)Math.Ceiling((double)totalCount / input.PageSize); - var hasNextPage = input.PageIndex < totalPages; - var hasPreviousPage = input.PageIndex > 1; + var orderByMethod = input.Sorting?.ToLower() == "desc" ? "OrderByDescending" : "OrderBy"; + var orderByExpression = System.Linq.Expressions.Expression.Call( + typeof(Queryable), + orderByMethod, + new Type[] { entityType, property.Type }, + dbSet.Expression, + System.Linq.Expressions.Expression.Quote(lambda)); - return new TableGetListOutput - { - Items = result, - TotalCount = totalCount, - PageIndex = input.PageIndex, - PageSize = input.PageSize - }; + dbSet = dbSet.Provider.CreateQuery(orderByExpression); } - catch (Exception ex) + + // 获取总数 + var totalCount = await dbSet.CountAsync(); + + // 应用分页 + var pagedData = await dbSet + .Skip(input.SkipCount) + .Take(input.MaxResultCount) + .ToListAsync(); + + // 转换为字典格式 + var result = new List>(); + foreach (var item in pagedData) { - // 记录详细错误信息,便于调试 - Console.WriteLine($"获取表格数据失败: {ex.Message}"); - Console.WriteLine($"堆栈跟踪: {ex.StackTrace}"); - - // 返回空结果,避免异常中断 - return new TableGetListOutput + var dict = new Dictionary(); + var properties = entityType.GetProperties(); + foreach (var prop in properties) { - Items = new List>(), - TotalCount = 0, - PageIndex = input.PageIndex, - PageSize = input.PageSize - }; + var value = prop.GetValue(item); + dict[prop.Name] = value; + } + result.Add(dict); } + + return new() + { + Items = result, + TotalCount = totalCount + }; } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/EntityManager/EntityTypeManager.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/EntityManager/EntityTypeManager.cs index cd7aeee..ce0cbaf 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/EntityManager/EntityTypeManager.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/EntityManager/EntityTypeManager.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using H.LowCode.Entity; using H.LowCode.RenderEngine.Domain; +using H.LowCode.RenderEngine.Domain.Repositories; namespace H.LowCode.RenderEngine.EntityFrameworkCore; @@ -20,11 +21,11 @@ public class EntityTypeManager private static List _dynamicEntities = []; - private IDataSourceDomainService _dataSourceDomainService; + private IDataSourceRepository _dataSourceRepository; - public EntityTypeManager(IDataSourceDomainService dataSourceDomainService) + public EntityTypeManager(IDataSourceRepository dataSourceRepository) { - _dataSourceDomainService = dataSourceDomainService; + _dataSourceRepository = dataSourceRepository; } public IReadOnlyList LoadDynamicEntities() @@ -34,7 +35,7 @@ public class EntityTypeManager if(_dynamicEntities.Count > 0) return _dynamicEntities; - var entities = _dataSourceDomainService.GetAllEntities("caseapp"); + var entities = _dataSourceRepository.GetAllEntities("caseapp"); foreach (var entity in entities) { var fields = entity.TableFields.Select(f => new DynamicEntityField() diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs index 3533cd3..82b367b 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs @@ -1,8 +1,8 @@ -using H.LowCode.ComponentBase; +using H.LowCode.Application.Contracts; +using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.RenderEngine.Application.Contracts; using H.LowCode.Themes.AntBlazor; -using H.Util.Blazor; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Volo.Abp.Autofac.WebAssembly; using Volo.Abp.Http.Client; @@ -56,5 +56,9 @@ public class RenderEngineHostClientModule : AbpModule typeof(RenderEngineApplicationContractsModule).Assembly, RemoteServiceName ); + context.Services.AddHttpClientProxies( + typeof(LowCodeApplicationContractsModule).Assembly, + RemoteServiceName + ); } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/Repositories/DataSourceFileRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/Repositories/DataSourceFileRepository.cs index 22bea1c..1980b82 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/Repositories/DataSourceFileRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Repository.JsonFile/Repositories/DataSourceFileRepository.cs @@ -46,4 +46,16 @@ public class DataSourceFileRepository : FileRepositoryBase, IDataSourceRepositor var dataSource = dataSourceSchemaJson.FromJson(); return await Task.FromResult(dataSource); } + + public async Task> GetAllApisAsync(string appId) + { + var list = await GetListAsync(appId); + return list.Where(t => t.DataSourceType == ComponentDataSourceTypeEnum.API).ToList(); + } + + public IEnumerable GetAllEntities(string appId) + { + var list = GetListAsync(appId).Result; + return list.Where(t => t.DataSourceType == ComponentDataSourceTypeEnum.DB).ToList(); + } } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/Repositories/DataSourceRemoteServiceRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/Repositories/DataSourceRemoteServiceRepository.cs index b328381..36a4098 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/Repositories/DataSourceRemoteServiceRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Repository.RemoteService/Repositories/DataSourceRemoteServiceRepository.cs @@ -23,4 +23,14 @@ public class DataSourceRemoteServiceRepository : RemoteServiceRepositoryBase, ID { throw new NotImplementedException(); } + + public Task> GetAllApisAsync(string appId) + { + throw new NotImplementedException(); + } + + public IEnumerable GetAllEntities(string appId) + { + throw new NotImplementedException(); + } } diff --git a/src/RenderEngine/H.LowCode.Themes.AntBlazor/PageRender/FormPageRender.razor b/src/RenderEngine/H.LowCode.Themes.AntBlazor/PageRender/FormPageRender.razor index 9f3646a..5889786 100644 --- a/src/RenderEngine/H.LowCode.Themes.AntBlazor/PageRender/FormPageRender.razor +++ b/src/RenderEngine/H.LowCode.Themes.AntBlazor/PageRender/FormPageRender.razor @@ -2,9 +2,9 @@ @inherits RenderEngineLowCodeComponentBase @inject IFormDataAppService FormDataAppService -@inject ComponentState FormDataState +@inject ComponentState FormDataState -@if (_formDTO != null) +@if (_formDto != null) {
_fieldDictData; protected override async Task OnInitializedAsync() @@ -38,27 +38,27 @@ await base.OnInitializedAsync(); Id = GetQueryValue("id"); - _formDTO = await FormDataState.GetOrAddAsync(this, async () => + _formDto = await FormDataState.GetOrAddAsync(this, async () => { return await FormDataAppService.GetAsync(Page.AppId, Page.Id, Id); }); - if (_formDTO?.Fields == null) + if (_formDto?.Fields == null) _fieldDictData = new Dictionary(); else - _fieldDictData = _formDTO.Fields.ToDictionary(x => x.Name, x => x.Value); + _fieldDictData = _formDto.Fields.ToDictionary(x => x.Name, x => x.Value); } private async Task OnFinishAsync() { - foreach (var field in _formDTO.Fields) + foreach (var field in _formDto.Fields) { if (!_fieldDictData.ContainsKey(field.Name)) continue; field.Value = _fieldDictData[field.Name]; } - var success = await FormDataAppService.SaveAsync(_formDTO); + var success = await FormDataAppService.SaveAsync(_formDto); if (success) await Message.SuccessAsync("保存成功"); else diff --git a/src/RenderEngine/H.LowCode.Themes.AntBlazor/_Imports.razor b/src/RenderEngine/H.LowCode.Themes.AntBlazor/_Imports.razor index 5e27af6..8a7647b 100644 --- a/src/RenderEngine/H.LowCode.Themes.AntBlazor/_Imports.razor +++ b/src/RenderEngine/H.LowCode.Themes.AntBlazor/_Imports.razor @@ -6,6 +6,7 @@ @using Microsoft.AspNetCore.Components.Forms @using AntDesign @using AntDesign.ProLayout +@using H.LowCode.Application.Contracts @using H.LowCode.ComponentBase @using H.LowCode.RenderEngine.Abstraction @using H.LowCode.RenderEngine.Application.Contracts -- Gitee From 9f6cd548694eebaf17740d95d4d55a6ee9a3288e Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Fri, 26 Sep 2025 22:23:31 +0800 Subject: [PATCH 18/33] =?UTF-8?q?=E5=8E=BB=E6=8E=89=20RenderEngine=20?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=20DomainService=EF=BC=8C=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppServices/IFormDataAppService.cs | 13 +++++ .../AppServices/ITableDataAppService.cs | 16 ++++++ .../Dtos/DataDtoBase.cs | 18 ++++++ .../Dtos/FormDataDto.cs | 56 +++++++++++++++++++ .../Dtos/TableDataInput.cs | 30 ++++++++++ .../LowCodeApplicationContractsModule.cs | 18 ++++++ .../AppServices/TableDataAppService.cs | 37 ++++++++++++ 7 files changed, 188 insertions(+) create mode 100644 src/Common/H.LowCode.Application.Contracts/AppServices/IFormDataAppService.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/Dtos/DataDtoBase.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/Dtos/FormDataDto.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/LowCodeApplicationContractsModule.cs create mode 100644 src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs diff --git a/src/Common/H.LowCode.Application.Contracts/AppServices/IFormDataAppService.cs b/src/Common/H.LowCode.Application.Contracts/AppServices/IFormDataAppService.cs new file mode 100644 index 0000000..456343c --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/AppServices/IFormDataAppService.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Http; +using Volo.Abp.Application.Services; + +namespace H.LowCode.Application.Contracts; + +public interface IFormDataAppService : IApplicationService +{ + Task SaveAsync(FormDataDto dto); + + Task GetAsync(string appId, string pageId, string id); + + Task DeleteAsync(string appId, string pageId, string id); +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs b/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs new file mode 100644 index 0000000..4d75c9c --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs @@ -0,0 +1,16 @@ +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace H.LowCode.Application.Contracts; + +/// +/// 列表数据查询 +/// +public interface ITableDataAppService : IApplicationService +{ + /// + /// 获取表格数据 + /// + Task>> GetListAsync(TableDataInput request); +} diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/DataDtoBase.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/DataDtoBase.cs new file mode 100644 index 0000000..263b323 --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/DataDtoBase.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace H.LowCode.Application.Contracts; + +public abstract class DataDtoBase +{ + public DateTime CreatedTime { get; set; } + + public string CreatedUser { get; set; } + + public DateTime ModifiedTime { get; set; } + + public string ModifiedUser { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/FormDataDto.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/FormDataDto.cs new file mode 100644 index 0000000..927e53c --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/FormDataDto.cs @@ -0,0 +1,56 @@ +using H.LowCode.MetaSchema; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace H.LowCode.Application.Contracts; + +public class FormDataDto : DataDtoBase +{ + public string Name { get; set; } + + public IList Fields { get; set; } + + public IList ValidationRules { get; set; } = []; +} + +public class FormFieldDto +{ + public string Name { get; set; } + + /// + /// Value 值的类型 + /// + /// init 用于控制允许在 AutoMapper 场景赋值, 不允许外部赋值 + public string TypeName { get; init; } + + private object _value; + public object Value + { + get + { + if (string.IsNullOrEmpty(TypeName)) + throw new InvalidDataException($"TypeName is null or empty, field={this.ToJson()}"); + + var type = Type.GetType(TypeName); + if (type == null) + throw new InvalidDataException($"Type '{TypeName}' not found, field={this.ToJson()}"); + + try + { + var realValue = _value.ConvertToRealType(type); + return realValue; + } + catch (Exception ex) + { + throw new InvalidDataException($"Failed to convert value '{_value}' to type '{TypeName}', field={this.ToJson()}", ex); + } + } + set + { + _value = value; + } + } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs new file mode 100644 index 0000000..966d217 --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs @@ -0,0 +1,30 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace H.LowCode.Application.Contracts; + +/// +/// 表格数据请求参数 +/// +public class TableDataInput : PagedAndSortedResultRequestDto +{ + /// + /// 应用ID + /// + public string AppId { get; set; } + + /// + /// 页面ID + /// + public string PageId { get; set; } + + /// + /// 数据源ID + /// + public string DataSourceId { get; set; } + + /// + /// 筛选条件 + /// + public Dictionary Filters { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/LowCodeApplicationContractsModule.cs b/src/Common/H.LowCode.Application.Contracts/LowCodeApplicationContractsModule.cs new file mode 100644 index 0000000..5773f73 --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/LowCodeApplicationContractsModule.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Modularity; +using Volo.Abp.Validation; + +namespace H.LowCode.Application.Contracts; + +public class LowCodeApplicationContractsModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + + } +} diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs new file mode 100644 index 0000000..d84649f --- /dev/null +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs @@ -0,0 +1,37 @@ +using H.LowCode.Application.Contracts; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace H.LowCode.ComponentBase.Services; + +/// +/// 默认表格数据提供者(提供模拟数据) +/// +public class TableDataAppService : ApplicationService, ITableDataAppService +{ + public async Task>> GetListAsync(TableDataInput request) + { + await Task.Delay(100); // 模拟异步操作 + + // 生成模拟数据 + var items = new List>(); + + // 根据页码和页大小生成数据 + for (int i = 0; i < request.MaxResultCount; i++) + { + var rowIndex = i + 1; + var row = new Dictionary + { + ["Id"] = rowIndex, + ["CreateTime"] = DateTime.Now.AddDays(-rowIndex) + }; + items.Add(row); + } + + return new() + { + Items = items, + TotalCount = request.MaxResultCount * 2 + }; + } +} \ No newline at end of file -- Gitee From ced5d9b8aabb0981376e8f1e94a8a9b742a0a925 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sat, 27 Sep 2025 01:06:07 +0800 Subject: [PATCH 19/33] =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E3=80=81=E8=A1=8C=E5=86=85=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E7=AD=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/apps/caseapp/page/g0qcqxzd.json | 2 +- .../componentParts/antdesign/f2b54b4c.json | 4 +- .../AppServices/ITableDataAppService.cs | 12 + .../Dtos/TableDataDeleteInput.cs | 34 ++ .../Dtos/TableDataUpdateInput.cs | 40 ++ .../Components/LcTable.razor | 349 ++++++++++++++++-- .../Enums/EventDataActionTypeEnum.cs | 14 + .../Enums/EventTargetTypeEnum.cs | 3 +- .../PropertySchemas/EventSchema.cs | 8 + .../AppServices/TableDataAppService.cs | 23 +- .../Components/Events/EventList.razor | 15 + .../DataAppServices/TableDataAppService.cs | 10 + .../DataRepositories/ITableDataRepository.cs | 2 + .../DataRepositories/TableDataRepository.cs | 90 +++++ 14 files changed, 576 insertions(+), 30 deletions(-) create mode 100644 src/Common/H.LowCode.Application.Contracts/Dtos/TableDataDeleteInput.cs create mode 100644 src/Common/H.LowCode.Application.Contracts/Dtos/TableDataUpdateInput.cs create mode 100644 src/Common/H.LowCode.MetaSchema/Enums/EventDataActionTypeEnum.cs diff --git a/meta/apps/caseapp/page/g0qcqxzd.json b/meta/apps/caseapp/page/g0qcqxzd.json index ab41f10..357ab96 100644 --- a/meta/apps/caseapp/page/g0qcqxzd.json +++ b/meta/apps/caseapp/page/g0qcqxzd.json @@ -1 +1 @@ -{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dst":1,"dsid":"qgzhc7w3z","dsn":"tb_test1","dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"f_field1\",\"t\":\"输入框1\"},{\"id\":\"vwvoqrn1s\",\"n\":\"f_field3\",\"t\":\"输入框2\"},{\"id\":\"ap0ceewr\",\"n\":\"f_field6\",\"t\":\"单选框3\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"},{\"id\":\"es0qoauj\",\"n\":\"f_field10\",\"t\":\"日期选择5\"}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\",\"eventArgs\":{\"param1\":\"111\"},\"rowparams\":{\"id\":\"f_id\"}}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-09-24T17:22:43.3629139Z"} \ No newline at end of file +{"comps":[{"compid":"f2b54b4c","libid":"antdesign","cn":"Table","ct":1,"frag":{"dt":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","t":"H.LowCode.Components.Defaults.LcTable, H.LowCode.Components.Defaults","attrs":[]},"ds":{"dsgt":2,"dst":1,"dsid":"qgzhc7w3z","dsn":"tb_test1","dsv":"{\"tcols\":[{\"id\":\"i79talu1\",\"n\":\"f_field1\",\"t\":\"输入框1\"},{\"id\":\"vwvoqrn1s\",\"n\":\"f_field3\",\"t\":\"输入框2\"},{\"id\":\"ap0ceewr\",\"n\":\"f_field6\",\"t\":\"单选框3\"},{\"id\":\"ck9b6mez\",\"n\":\"Class\",\"t\":\"班级\"},{\"id\":\"es0qoauj\",\"n\":\"f_field10\",\"t\":\"日期选择5\"},{\"id\":\"t910chps\",\"n\":\"f_id\",\"t\":\"Id\",\"pk\":true}],\"searchs\":[],\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\"}]},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"sptevs\":[\"OnClick\"]}],\"rbtns\":[{\"id\":\"za8gxxdz\",\"n\":\"edit\",\"t\":\"编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":10,\"etid\":\"fhumgxyk\",\"eta\":\"14\",\"eventArgs\":{\"param1\":\"111\"},\"rowparams\":{\"id\":\"f_id\"}}]},{\"id\":\"b17d3nrc\",\"n\":\"del\",\"t\":\"删除\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":40,\"edat\":20}]},{\"id\":\"vwrounbq\",\"n\":\"editRow\",\"t\":\"行内编辑\",\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":40,\"edat\":10}]}]}"},"attrdefgroups":[],"childs":[],"order":30,"pub":1,"mt":"2025-05-22T14:26:07.7475675Z","id":"fqmcwygx","pid":"nupedwmm3","n":"Table_926","lb":"表格-A","hlb":true,"sptds":true,"stl":{"itemw":24,"itemh":300,"labelw":180}}],"sptevs":["OnLoad"],"aid":"caseapp","id":"g0qcqxzd","n":"基础列表","order":31,"pt":2,"pageprop":{"playout":2,"ds":{}},"ds":{},"mt":"2025-09-26T16:52:21.2061257Z"} \ No newline at end of file diff --git a/meta/parts/componentParts/antdesign/f2b54b4c.json b/meta/parts/componentParts/antdesign/f2b54b4c.json index 3cecdd7..a205926 100644 --- a/meta/parts/componentParts/antdesign/f2b54b4c.json +++ b/meta/parts/componentParts/antdesign/f2b54b4c.json @@ -1,4 +1,4 @@ -{ +{ "compid": "f2b54b4c", "libid": "antdesign", "cn": "Table", @@ -17,7 +17,7 @@ "sptds": true, "ds": { "dsgt":2, - "dsv": "{\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"tgId\":\"xxx\"},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"tgId\":\"xxx\"}]}" + "dsv": "{\"tbtns\":[{\"id\":\"wpnm70fe\",\"n\":\"create\",\"t\":\"新增\",\"bt\":1,\"tgId\":\"xxx\"},{\"id\":\"2qsecnfo\",\"n\":\"deleteSelections\",\"t\":\"删除选中\",\"tgId\":\"xxx\"}],\"rbtns\":[{\"id\":\"delete_row\",\"n\":\"delete\",\"t\":\"删除\",\"bt\":0,\"disabled\":false,\"order\":1,\"sptevs\":[\"OnClick\"],\"evs\":[{\"en\":\"OnClick\",\"eht\":40,\"edat\":20}]}]}" }, "stl": { "itemw": 24, diff --git a/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs b/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs index 4d75c9c..efbf62f 100644 --- a/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs +++ b/src/Common/H.LowCode.Application.Contracts/AppServices/ITableDataAppService.cs @@ -1,6 +1,8 @@ using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using System.Collections.Generic; +using System.Threading.Tasks; namespace H.LowCode.Application.Contracts; @@ -13,4 +15,14 @@ public interface ITableDataAppService : IApplicationService /// 获取表格数据 /// Task>> GetListAsync(TableDataInput request); + + /// + /// 删除数据 + /// + Task DeleteAsync(TableDataDeleteInput request); + + /// + /// 更新数据 + /// + Task UpdateAsync(TableDataUpdateInput request); } diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataDeleteInput.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataDeleteInput.cs new file mode 100644 index 0000000..25b2340 --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataDeleteInput.cs @@ -0,0 +1,34 @@ +using System; + +namespace H.LowCode.Application.Contracts; + +/// +/// 表格数据删除请求参数 +/// +public class TableDataDeleteInput +{ + /// + /// 应用ID + /// + public string AppId { get; set; } + + /// + /// 页面ID + /// + public string PageId { get; set; } + + /// + /// 数据源ID + /// + public string DataSourceId { get; set; } + + /// + /// 要删除的记录ID + /// + public string Id { get; set; } + + /// + /// 要删除的记录数据(包含主键等信息) + /// + public Dictionary RowData { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataUpdateInput.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataUpdateInput.cs new file mode 100644 index 0000000..96deba5 --- /dev/null +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataUpdateInput.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace H.LowCode.Application.Contracts; + +/// +/// 表格数据更新请求参数 +/// +public class TableDataUpdateInput +{ + /// + /// 应用ID + /// + public string AppId { get; set; } + + /// + /// 页面ID + /// + public string PageId { get; set; } + + /// + /// 数据源ID + /// + public string DataSourceId { get; set; } + + /// + /// 主键值 + /// + public string Id { get; set; } + + /// + /// 行数据 + /// + public Dictionary RowData { get; set; } + + /// + /// 更新的字段数据 + /// + public Dictionary UpdateData { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor index d201216..31abbc8 100644 --- a/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor +++ b/src/Common/H.LowCode.Components.Defaults/Components/LcTable.razor @@ -21,7 +21,22 @@ var column = _tableSchema.Columns.FirstOrDefault(t => string.Equals(t.Name, key, StringComparison.OrdinalIgnoreCase)); if (column != null) { - + + @{ + var primaryKeyColumn = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey); + var primaryKeyValue = primaryKeyColumn != null && row.ContainsKey(primaryKeyColumn.Name) + ? row[primaryKeyColumn.Name]?.ToString() : null; + var isEditing = !string.IsNullOrEmpty(primaryKeyValue) && _editingRows.ContainsKey(primaryKeyValue); + } + @if (isEditing && !column.IsPrimaryKey) + { + + } + else + { + @row[key] + } + } } @if (_tableSchema.RowButtons != null && _tableSchema.RowButtons.Any()) @@ -57,6 +72,10 @@ int _pageSize = 10; int _total = 0; + // 编辑状态管理 + private Dictionary> _editingRows = new(); + private Dictionary> _originalRows = new(); + protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -120,45 +139,34 @@ private async Task LoadDataAsync() { + var request = new TableDataInput + { + AppId = PageCascading?.AppId, + PageId = PageCascading?.PageId, + DataSourceId = DataSource?.DataSourceId, + SkipCount = (_pageIndex - 1) * _pageSize, + MaxResultCount = _pageSize + }; + try { - var request = new TableDataInput - { - AppId = PageCascading?.AppId, - PageId = PageCascading?.PageId, - DataSourceId = DataSource?.DataSourceId, - SkipCount = (_pageIndex - 1) * _pageSize, - MaxResultCount = _pageSize - }; + Console.WriteLine($"列表数据开始加载: {RendererInfo.Name}, {request.ToJson()}"); var result = await TableDataAppService.GetListAsync(request); _data = result.Items.ToList(); _total = (int)result.TotalCount; - Console.WriteLine($"列表数据: {result.ToJson()}"); + Console.WriteLine($"列表数据加载成功: {result.ToJson()}"); } catch (Exception ex) { // 出错时使用空数据 _data = new List>(); _total = 0; - Console.WriteLine($"加载数据失败: {ex.Message}"); + Console.WriteLine($"列表加载数据失败: {RendererInfo.Name}, {request.ToJson()}, {ex.Message}"); } } - - - public async Task EditAsync(Dictionary row) - { - string primaryKey = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey)?.Name; - await Task.Delay(100); - } - - private async Task DeleteAsync(Dictionary row) - { - await Task.Delay(100); - } - public async Task ButtonActionAsync(TableButtonSchema btn, Dictionary rowData = null) { foreach(var e in btn.Events) @@ -201,6 +209,10 @@ await JS.InvokeVoidAsync("eval", e.EventCustomScript); } + else if (e.EventHandlerType == EventTargetTypeEnum.Data) + { + await HandleDataActionAsync(e.EventDataActionType, rowData); + } } } @@ -269,4 +281,293 @@ return baseUrl; } + + private async Task HandleDataActionAsync(EventDataActionTypeEnum actionType, Dictionary rowData) + { + switch (actionType) + { + case EventDataActionTypeEnum.EditRow: + await EditRowAsync(rowData); + break; + case EventDataActionTypeEnum.DeleteRow: + await DeleteRowAsync(rowData); + break; + case EventDataActionTypeEnum.SaveRow: + await SaveRowAsync(rowData); + break; + case EventDataActionTypeEnum.CancelEdit: + await CancelEditAsync(rowData); + break; + case EventDataActionTypeEnum.AddRow: + await AddRowAsync(); + break; + case EventDataActionTypeEnum.RefreshData: + await RefreshDataAsync(); + break; + default: + break; + } + } + + private async Task EditRowAsync(Dictionary rowData) + { + try + { + // 获取主键字段 + var primaryKeyColumn = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey); + if (primaryKeyColumn == null) + { + Console.WriteLine("编辑失败: 未找到主键字段"); + return; + } + + // 获取主键值 + if (!rowData.ContainsKey(primaryKeyColumn.Name)) + { + Console.WriteLine($"编辑失败: 行数据中未找到主键字段 {primaryKeyColumn.Name}"); + return; + } + + var primaryKeyValue = rowData[primaryKeyColumn.Name]?.ToString(); + if (string.IsNullOrEmpty(primaryKeyValue)) + { + Console.WriteLine("编辑失败: 主键值为空"); + return; + } + + // 如果已经在编辑状态,则不重复进入编辑 + if (_editingRows.ContainsKey(primaryKeyValue)) + { + return; + } + + // 保存原始数据副本 + _originalRows[primaryKeyValue] = new Dictionary(rowData); + + // 创建编辑数据副本 + _editingRows[primaryKeyValue] = new Dictionary(rowData); + + Console.WriteLine($"开始编辑行: ID={primaryKeyValue}"); + StateHasChanged(); + } + catch (Exception ex) + { + Console.WriteLine($"编辑行失败: {ex.Message}"); + } + + await Task.CompletedTask; + } + + private async Task DeleteRowAsync(Dictionary row) + { + try + { + // 获取主键字段 + var primaryKeyColumn = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey); + if (primaryKeyColumn == null) + { + Console.WriteLine("删除失败: 未找到主键字段"); + return; + } + + // 获取主键值 + if (!row.ContainsKey(primaryKeyColumn.Name)) + { + Console.WriteLine($"删除失败: 行数据中未找到主键字段 {primaryKeyColumn.Name}"); + return; + } + + var primaryKeyValue = row[primaryKeyColumn.Name]?.ToString(); + if (string.IsNullOrEmpty(primaryKeyValue)) + { + Console.WriteLine("删除失败: 主键值为空"); + return; + } + + // 构建删除请求 + var deleteRequest = new TableDataDeleteInput + { + AppId = PageCascading?.AppId, + PageId = PageCascading?.PageId, + DataSourceId = DataSource?.DataSourceId, + Id = primaryKeyValue, + RowData = row + }; + + // 调用删除服务 + await TableDataAppService.DeleteAsync(deleteRequest); + + // 删除成功后重新加载数据 + await LoadDataAsync(); + + Console.WriteLine($"删除成功: ID={primaryKeyValue}"); + } + catch (Exception ex) + { + Console.WriteLine($"删除失败: {ex.Message}"); + } + } + + private async Task SaveRowAsync(Dictionary rowData) + { + try + { + // 获取主键字段 + var primaryKeyColumn = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey); + if (primaryKeyColumn == null) + { + Console.WriteLine("保存失败: 未找到主键字段"); + return; + } + + // 获取主键值 + if (!rowData.ContainsKey(primaryKeyColumn.Name)) + { + Console.WriteLine($"保存失败: 行数据中未找到主键字段 {primaryKeyColumn.Name}"); + return; + } + + var primaryKeyValue = rowData[primaryKeyColumn.Name]?.ToString(); + if (string.IsNullOrEmpty(primaryKeyValue)) + { + Console.WriteLine("保存失败: 主键值为空"); + return; + } + + // 检查是否在编辑状态 + if (!_editingRows.ContainsKey(primaryKeyValue)) + { + Console.WriteLine("保存失败: 该行不在编辑状态"); + return; + } + + var editingData = _editingRows[primaryKeyValue]; + var originalData = _originalRows[primaryKeyValue]; + + // 找出变更的字段 + var updateData = new Dictionary(); + foreach (var kvp in editingData) + { + if (!originalData.ContainsKey(kvp.Key) || + !Equals(originalData[kvp.Key], kvp.Value)) + { + updateData[kvp.Key] = kvp.Value; + } + } + + // 如果有变更,则调用更新服务 + if (updateData.Any()) + { + var updateRequest = new TableDataUpdateInput + { + AppId = PageCascading?.AppId, + PageId = PageCascading?.PageId, + DataSourceId = DataSource?.DataSourceId, + Id = primaryKeyValue, + RowData = originalData, + UpdateData = updateData + }; + + await TableDataAppService.UpdateAsync(updateRequest); + + // 更新本地数据 + var dataIndex = _data.FindIndex(d => d.ContainsKey(primaryKeyColumn.Name) && + d[primaryKeyColumn.Name]?.ToString() == primaryKeyValue); + if (dataIndex >= 0) + { + _data[dataIndex] = new Dictionary(editingData); + } + + Console.WriteLine($"保存成功: ID={primaryKeyValue}, 更新字段: {string.Join(", ", updateData.Keys)}"); + } + else + { + Console.WriteLine($"无变更,跳过保存: ID={primaryKeyValue}"); + } + + // 退出编辑状态 + _editingRows.Remove(primaryKeyValue); + _originalRows.Remove(primaryKeyValue); + + StateHasChanged(); + } + catch (Exception ex) + { + Console.WriteLine($"保存行失败: {ex.Message}"); + } + } + + private async Task CancelEditAsync(Dictionary rowData) + { + try + { + // 获取主键字段 + var primaryKeyColumn = _tableSchema.Columns.FirstOrDefault(t => t.IsPrimaryKey); + if (primaryKeyColumn == null) + { + Console.WriteLine("取消编辑失败: 未找到主键字段"); + return; + } + + // 获取主键值 + if (!rowData.ContainsKey(primaryKeyColumn.Name)) + { + Console.WriteLine($"取消编辑失败: 行数据中未找到主键字段 {primaryKeyColumn.Name}"); + return; + } + + var primaryKeyValue = rowData[primaryKeyColumn.Name]?.ToString(); + if (string.IsNullOrEmpty(primaryKeyValue)) + { + Console.WriteLine("取消编辑失败: 主键值为空"); + return; + } + + // 检查是否在编辑状态 + if (!_editingRows.ContainsKey(primaryKeyValue)) + { + Console.WriteLine("取消编辑失败: 该行不在编辑状态"); + return; + } + + // 清除编辑状态 + _editingRows.Remove(primaryKeyValue); + _originalRows.Remove(primaryKeyValue); + + Console.WriteLine($"取消编辑: ID={primaryKeyValue}"); + StateHasChanged(); + } + catch (Exception ex) + { + Console.WriteLine($"取消编辑失败: {ex.Message}"); + } + + await Task.CompletedTask; + } + + private async Task AddRowAsync() + { + // TODO: 实现添加行功能 + Console.WriteLine("添加新行"); + } + + private async Task RefreshDataAsync() + { + try + { + // 清除所有编辑状态 + _editingRows.Clear(); + _originalRows.Clear(); + + // 重新加载数据 + await LoadDataAsync(); + + Console.WriteLine("刷新数据成功"); + StateHasChanged(); + } + catch (Exception ex) + { + Console.WriteLine($"刷新数据失败: {ex.Message}"); + } + } } diff --git a/src/Common/H.LowCode.MetaSchema/Enums/EventDataActionTypeEnum.cs b/src/Common/H.LowCode.MetaSchema/Enums/EventDataActionTypeEnum.cs new file mode 100644 index 0000000..0feda43 --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema/Enums/EventDataActionTypeEnum.cs @@ -0,0 +1,14 @@ +using System; + +namespace H.LowCode.MetaSchema; + +public enum EventDataActionTypeEnum +{ + None = 0, + EditRow = 10, // 编辑行 + DeleteRow = 20, // 删除行 + SaveRow = 30, // 保存行 + CancelEdit = 40, // 取消编辑 + AddRow = 50, // 添加行 + RefreshData = 60, // 刷新数据 +} \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema/Enums/EventTargetTypeEnum.cs b/src/Common/H.LowCode.MetaSchema/Enums/EventTargetTypeEnum.cs index ddc9465..d30f2b1 100644 --- a/src/Common/H.LowCode.MetaSchema/Enums/EventTargetTypeEnum.cs +++ b/src/Common/H.LowCode.MetaSchema/Enums/EventTargetTypeEnum.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace H.LowCode.MetaSchema; @@ -7,6 +7,7 @@ public enum EventTargetTypeEnum None = 0, Page = 10, //打开页面 Component = 30, //组件 + Data = 40, //数据操作 Custom = 99, // 自定义事件 } diff --git a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs index cd30381..227da71 100644 --- a/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/PropertySchemas/EventSchema.cs @@ -39,6 +39,14 @@ public class EventSchema public string EventCustomScript { get; set; } #endregion + #region 数据操作事件 + /// + /// 数据操作类型 + /// + [JsonPropertyName("edat")] + public EventDataActionTypeEnum EventDataActionType { get; set; } + #endregion + /// /// 事件参数 /// diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs index d84649f..8465597 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Application/AppServices/TableDataAppService.cs @@ -17,7 +17,7 @@ public class TableDataAppService : ApplicationService, ITableDataAppService var items = new List>(); // 根据页码和页大小生成数据 - for (int i = 0; i < request.MaxResultCount; i++) + for (int i = 0; i < 3; i++) { var rowIndex = i + 1; var row = new Dictionary @@ -31,7 +31,26 @@ public class TableDataAppService : ApplicationService, ITableDataAppService return new() { Items = items, - TotalCount = request.MaxResultCount * 2 + TotalCount = 3 }; } + + public async Task DeleteAsync(TableDataDeleteInput request) + { + await Task.Delay(100); // 模拟异步操作 + + // 在设计引擎中,这只是模拟删除操作 + // 实际上不会删除任何数据,只是为了演示功能 + Console.WriteLine($"模拟删除数据: AppId={request.AppId}, PageId={request.PageId}, DataSourceId={request.DataSourceId}, Id={request.Id}"); + } + + public async Task UpdateAsync(TableDataUpdateInput request) + { + await Task.Delay(100); // 模拟异步操作 + + // 在设计引擎中,这只是模拟更新操作 + // 实际上不会更新任何数据,只是为了演示功能 + Console.WriteLine($"模拟更新数据: AppId={request.AppId}, PageId={request.PageId}, DataSourceId={request.DataSourceId}, Id={request.Id}"); + Console.WriteLine($"更新字段: {string.Join(", ", request.UpdateData?.Select(kv => $"{kv.Key}={kv.Value}") ?? new string[0])}"); + } } \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor index fbd6a80..057e7ac 100644 --- a/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor +++ b/src/DesignEngine/H.LowCode.DesignEngineBase/Components/Events/EventList.razor @@ -24,6 +24,7 @@ 页面 组件 + 数据 自定义 @@ -118,6 +119,20 @@ } + else if (_currentEvent.EventHandlerType == EventTargetTypeEnum.Data) + { +
+ + + 编辑行 + 删除行 + 保存行 + 取消编辑 + 添加行 + 刷新数据 + +
+ } else if (_currentEvent.EventHandlerType == EventTargetTypeEnum.Custom) {
diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs index 8d154d8..8ec7942 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Application/DataAppServices/TableDataAppService.cs @@ -21,4 +21,14 @@ public class TableDataAppService : ApplicationService, ITableDataAppService { return await _tableDataRepository.GetListAsync(input); } + + public async Task DeleteAsync(TableDataDeleteInput request) + { + await _tableDataRepository.DeleteAsync(request); + } + + public async Task UpdateAsync(TableDataUpdateInput request) + { + await _tableDataRepository.UpdateAsync(request); + } } \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs index 26f1f71..992ff24 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Domain/DataRepositories/ITableDataRepository.cs @@ -7,4 +7,6 @@ namespace H.LowCode.RenderEngine.Domain; public interface ITableDataRepository : IRepository { Task>> GetListAsync(TableDataInput input); + Task DeleteAsync(TableDataDeleteInput request); + Task UpdateAsync(TableDataUpdateInput request); } diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs index 043be0f..307eb42 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs @@ -100,4 +100,94 @@ public class TableDataRepository : ITableDataRepository TotalCount = totalCount }; } + + /// + /// 删除数据 + /// + /// 删除请求参数 + public async Task DeleteAsync(TableDataDeleteInput request) + { + var dataSource = await _dataSourceRepository.GetAsync(request.AppId, request.DataSourceId); + if (dataSource == null) + { + throw new ArgumentException($"数据源不存在: {request.DataSourceId}"); + } + + // 使用 DbContextFactory 创建新的 DbContext 实例,确保线程安全 + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + + // 获取实体类型(使用数据源名称) + var entityType = dbContext.GetEntityType(dataSource.Name); + + // 根据ID查找要删除的实体 + var entity = await dbContext.FindAsync(entityType, request.Id); + if (entity == null) + { + throw new ArgumentException($"要删除的记录不存在: {request.Id}"); + } + + // 删除实体 + dbContext.Remove(entity); + await dbContext.SaveChangesAsync(); + } + + /// + /// 更新数据 + /// + /// 更新请求参数 + public async Task UpdateAsync(TableDataUpdateInput request) + { + var dataSource = await _dataSourceRepository.GetAsync(request.AppId, request.DataSourceId); + if (dataSource == null) + { + throw new ArgumentException($"数据源不存在: {request.DataSourceId}"); + } + + // 使用 DbContextFactory 创建新的 DbContext 实例,确保线程安全 + using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + + // 获取实体类型(使用数据源名称) + var entityType = dbContext.GetEntityType(dataSource.Name); + + // 根据ID查找要更新的实体 + var entity = await dbContext.FindAsync(entityType, request.Id); + if (entity == null) + { + throw new ArgumentException($"要更新的记录不存在: {request.Id}"); + } + + // 更新实体属性 + if (request.UpdateData != null && request.UpdateData.Any()) + { + var properties = entityType.GetProperties(); + foreach (var updateField in request.UpdateData) + { + var property = properties.FirstOrDefault(p => + string.Equals(p.Name, updateField.Key, StringComparison.OrdinalIgnoreCase)); + + if (property != null && property.CanWrite) + { + // 类型转换 + var value = updateField.Value; + if (value != null && value.GetType() != property.PropertyType) + { + try + { + value = Convert.ChangeType(value, property.PropertyType); + } + catch + { + // 转换失败时跳过该字段 + continue; + } + } + + property.SetValue(entity, value); + } + } + } + + // 保存更改 + await dbContext.SaveChangesAsync(); + } } -- Gitee From e0a0e08a9f4781bfca4fff87583e71670545207e Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Mon, 29 Sep 2025 21:22:06 +0800 Subject: [PATCH 20/33] =?UTF-8?q?=E5=88=97=E8=A1=A8=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=88=97=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trae/rules/project_rules.md | 22 ++++++++++++++---- .../Dtos/TableDataInput.cs | 2 +- .../TablePropertyItem.razor | 23 ++++++++++++++++++- .../Pages/MetaPage.razor | 2 +- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md index 48f05dd..5f9aa98 100644 --- a/.trae/rules/project_rules.md +++ b/.trae/rules/project_rules.md @@ -35,11 +35,25 @@ * 菜单 菜单功能的核心数据结构由 MenuSchema 类定义,该类继承自 MetaSchemaBase,用于描述菜单项的组织方式和行为特性。 -#### 设计引擎 -##### 物料 +### 元数据 +元数据的定义包含在项目 H.LowCode.MetaSchema (基础元数据据结构定义)、H.LowCode.MetaSchema.DesignEngine (基于 H.LowCode.MetaSchema,扩展出设计引擎特有属性)、H.LowCode.Schema.RenderEngine (基于 H.LowCode.MetaSchema,包含渲染引擎特有属性)。 +设计引擎通过可视化界面设计并使用 H.LowCode.MetaSchema.DesignEngine 项目中的元数据定义序列化生成 json 文件,然后右渲染引擎将 json 反序列化为 H.LowCode.MetaSchema.RenderEngine 中的元数据定义,再绑定到页面中渲染出页面。 + +#### 主要的元数据定义 +* AppSchemaBase:应用的元数据定义,包含应用的名称、标识、图标、描述等基本信息。 +* PageSchemaBase:页面的元数据定义,包含页面的类型、布局配置、事件处理机制、组件树结构以及状态管理。 +* * PagePartsSchema: 设计时页面的元数据定义 +* * PageSchema: 运行时页面的元数据定义 +* ComponentSchemaBase:组件的元数据定义,包含组件的结构、属性、样式和事件。 +* * ComponentPartsSchema: 设计时组件定义 +* * ComponentSchema: 运行时组件定义 +* MenuSchema:菜单的元数据定义,包含菜单项的组织方式和行为特性。 + +### 设计引擎 +#### 物料 物料的管理对应 H.LowCode.PartsDesignEngine 项目, 物料主要包含组件、主题等,物料的元数据定义在 H.LowCode.MetaSchema.DesignEngine 项目中。 -##### 页面设计器 +#### 页面设计器 页面设计器用于设计页面,基于已有物料进行拖拽、配置、事件绑定等操作,最终生成页面的元数据文件。 页面设计器位于 H.LowCode.DesignEngine 项目的 DesignPage 页面,包含 ComponentPanel(物料库)、DesignPanel(设计区域)、SettingPanel(配置面板)三个部分。 @@ -50,7 +64,7 @@ * * DraggableItem 包裹的是 DraggableItem 组件,DraggableItem 组件的子组件为真实组件,例如 Button、Input 等。DraggableItem 将组件元数据动态渲染为真实组件,从而实现基于 json 元数据动态渲染页面的效果。 * 配置面板:对选中的组件进行属性、样式和事件的配置。 -#### 渲染引擎 +### 渲染引擎 渲染引擎负责根据页面的元数据文件,动态生成 Blazor 组件树,并在前端页面中渲染出来。渲染引擎位于 H.LowCode.RenderEngine 项目中,主要负责以下几个方面的功能: * 元数据解析:读取页面的元数据文件,解析出组件、样式、事件等信息。 * 组件渲染:根据解析出的元数据,动态创建 Blazor 组件实例,并将其添加到组件树中。 diff --git a/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs index 966d217..0d826e1 100644 --- a/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs +++ b/src/Common/H.LowCode.Application.Contracts/Dtos/TableDataInput.cs @@ -1,4 +1,4 @@ -using System; +using System; using Volo.Abp.Application.Dtos; namespace H.LowCode.Application.Contracts; diff --git a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/ComponentPropertyItems/TablePropertyItem.razor b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/ComponentPropertyItems/TablePropertyItem.razor index 2f0b4d9..4910414 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/ComponentPropertyItems/TablePropertyItem.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/SettingPanel/PropertySettingItems/ComponentPropertyItems/TablePropertyItem.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.DesignEngine +@namespace H.LowCode.DesignEngine @inherits DesignEngineLowCodeComponentBase
@@ -197,6 +197,18 @@ private void DeleteColumn(string id) { var column = _tableSchema.Columns.First(t => t.Id == id); + + // 如果要删除的是主键列,检查是否还有其他主键列 + if (column.IsPrimaryKey) + { + var otherPrimaryKeys = _tableSchema.Columns.Where(c => c.IsPrimaryKey && c.Id != id).ToList(); + if (!otherPrimaryKeys.Any()) + { + Message.Warning("无法删除该列:这是表格中唯一的主键列,删除后将影响数据操作功能"); + return; + } + } + _tableSchema.Columns.Remove(column); //OnPropertyChanged(); @@ -243,6 +255,15 @@ { //无需赋值 } + + // 验证至少有一个主键列 + var hasPrimaryKey = _tableSchema.Columns.Any(c => c.IsPrimaryKey); + if (!hasPrimaryKey) + { + // 如果没有主键,显示警告消息 + Message.Warning("表格配置警告:建议至少设置一个主键列以确保数据操作的正确性"); + } + return true; } #endregion diff --git a/src/RenderEngine/H.LowCode.Themes.AntBlazor/Pages/MetaPage.razor b/src/RenderEngine/H.LowCode.Themes.AntBlazor/Pages/MetaPage.razor index 17fe96b..3002256 100644 --- a/src/RenderEngine/H.LowCode.Themes.AntBlazor/Pages/MetaPage.razor +++ b/src/RenderEngine/H.LowCode.Themes.AntBlazor/Pages/MetaPage.razor @@ -1,4 +1,4 @@ -@page "/{AppId}/{PageId}" +@page "/{AppId}/{PageId}" @namespace H.LowCode.Themes.AntBlazor @inherits LowCodePageComponentBase @layout AntBlazorThemeLayout -- Gitee From 4c01a5a9d609575579cb4a4a8c133a2ad0c79788 Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Thu, 9 Oct 2025 00:17:18 +0800 Subject: [PATCH 21/33] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=89=A9=E6=96=99=E5=8F=AF=E8=A7=86=E5=8C=96=20=E7=BC=96?= =?UTF-8?q?=E8=BE=91/=E8=AE=BE=E8=AE=A1=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- meta/parts/componentParts/common/common.json | 1 + .../componentParts/common/lybwuphn6.json | 19 ++ .../componentParts/common/qpqayjuhb.json | 22 ++ .../ComponentPartsSchema.cs | 14 +- .../ComponentPartsEventDefineSchema.cs | 65 ++++ .../ComponentPartsStyleDefineSchema.cs | 83 +++++ .../ComponentSchemaBase.cs | 3 + .../OptionDataSourceSchema.cs | 14 +- .../ComponentPanel/ComponentPanel.razor | 3 +- .../ComponentPanel/ComponentPanel.razor | 3 +- .../Components/AddComponentModal.razor | 137 ++++++++ .../H.LowCode.PartsDesignEngine.csproj | 4 + .../{MyParts => AppParts}/AppPartsList.razor | 0 .../ComponentLibraryForm.razor | 0 .../ComponentLibraryList.razor | 0 .../ComponentPartsList.razor | 123 +++---- .../Components/APIDataSourceEditor.razor | 75 +++++ .../Components/AddComponentModal.razor | 110 +++++++ .../Components/ArrayPropertyEditor.razor | 176 ++++++++++ .../AttributeDefineGroupEditor.razor | 282 ++++++++++++++++ .../ComponentDataSourceEditor.razor | 101 ++++++ .../Components/ComponentFragmentEditor.razor | 194 +++++++++++ .../Components/ComponentPartsEditor.razor | 162 ++++++++++ .../Components/EventDefineEditor.razor | 90 ++++++ .../FixedOptionDataSourceEditor.razor | 93 ++++++ .../Components/HeadersEditor.razor | 94 ++++++ .../Components/ObjectArrayEditor.razor | 305 ++++++++++++++++++ .../Components/OptionsEditor.razor | 95 ++++++ .../Components/ParametersEditor.razor | 105 ++++++ .../Components/SQLDataSourceEditor.razor | 48 +++ .../Components/SQLParametersEditor.razor | 265 +++++++++++++++ .../Components/StyleDefineEditor.razor | 194 +++++++++++ .../Components/TableAttributeEditor.razor | 227 +++++++++++++ .../Pages/ComponentPartsEditorPage.razor | 171 ++++++++++ .../Pages/CustomComponentPartsDesigner.razor | 246 ++++++++++---- .../PageLibraryList.razor | 0 .../StandardComponentPartsDesigner.razor | 113 ++----- src/common.props | 1 + 38 files changed, 3392 insertions(+), 246 deletions(-) create mode 100644 meta/parts/componentParts/common/common.json create mode 100644 meta/parts/componentParts/common/lybwuphn6.json create mode 100644 meta/parts/componentParts/common/qpqayjuhb.json create mode 100644 src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsEventDefineSchema.cs create mode 100644 src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsStyleDefineSchema.cs create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Components/AddComponentModal.razor rename src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/{MyParts => AppParts}/AppPartsList.razor (100%) rename src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/{MyParts => ComponentParts}/ComponentLibraries/ComponentLibraryForm.razor (100%) rename src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/{MyParts => ComponentParts/ComponentLibraries}/ComponentLibraryList.razor (100%) rename src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/{MyParts/ComponentLibraries => ComponentParts}/ComponentPartsList.razor (62%) create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/AddComponentModal.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ArrayPropertyEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/AttributeDefineGroupEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ComponentDataSourceEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ComponentFragmentEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ComponentPartsEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/EventDefineEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/FixedOptionDataSourceEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/HeadersEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ObjectArrayEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/OptionsEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/ParametersEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/SQLDataSourceEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/SQLParametersEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/StyleDefineEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/TableAttributeEditor.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentPartsEditorPage.razor rename src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/{MyParts => PageParts}/PageLibraryList.razor (100%) diff --git a/meta/parts/componentParts/common/common.json b/meta/parts/componentParts/common/common.json new file mode 100644 index 0000000..9597294 --- /dev/null +++ b/meta/parts/componentParts/common/common.json @@ -0,0 +1 @@ +{"libid":"common","libname":"common","desc":"常用组件库","platform":[0],"modifiedTime":"2025-10-08T14:26:56.5979486Z"} \ No newline at end of file diff --git a/meta/parts/componentParts/common/lybwuphn6.json b/meta/parts/componentParts/common/lybwuphn6.json new file mode 100644 index 0000000..57bd5f2 --- /dev/null +++ b/meta/parts/componentParts/common/lybwuphn6.json @@ -0,0 +1,19 @@ +{ + "compid": "lybwuphn6", + "libid": "common", + "cn": "行政区划组件", + "ct": 2, + "ds": {}, + "attrdefgroups": [], + "childs": [], + "evdefs": [], + "stydefs": [], + "mt": "2025-10-08T14:42:12.6337976Z", + "id": "76g2ae5m", + "n": "region", + "stl": { + "itemw": 4, + "itemh": 85, + "labelw": 180 + } +} \ No newline at end of file diff --git a/meta/parts/componentParts/common/qpqayjuhb.json b/meta/parts/componentParts/common/qpqayjuhb.json new file mode 100644 index 0000000..a0e38dc --- /dev/null +++ b/meta/parts/componentParts/common/qpqayjuhb.json @@ -0,0 +1,22 @@ +{ + "compid": "qpqayjuhb", + "libid": "common", + "cn": "用户选择组件", + "ct": 2, + "frag": { + "attrs": [] + }, + "ds": {}, + "attrdefgroups": [], + "childs": [], + "evdefs": [], + "stydefs": [], + "mt": "2025-10-08T15:17:34.9054315Z", + "id": "t2f1qecpq", + "lb": "common", + "stl": { + "itemw": 4, + "itemh": 85, + "labelw": 180 + } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs index 5257b2b..1ca317b 100644 --- a/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/ComponentPartsSchema.cs @@ -1,4 +1,4 @@ -using H.Util.Ids; +using H.Util.Ids; using System.Text.Json.Serialization; namespace H.LowCode.MetaSchema.DesignEngine; @@ -58,6 +58,18 @@ public class ComponentPartsSchema : ComponentSchemaBase [JsonPropertyName("sptevs")] public string[] SupportEvents { get; set; } + /// + /// 事件定义 + /// + [JsonPropertyName("evdefs")] + public List EventDefines { get; set; } = []; + + /// + /// 样式定义 + /// + [JsonPropertyName("stydefs")] + public List StyleDefines { get; set; } = []; + [JsonPropertyName("order")] public int Order { get; set; } diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsEventDefineSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsEventDefineSchema.cs new file mode 100644 index 0000000..70f3bcd --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsEventDefineSchema.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace H.LowCode.MetaSchema.DesignEngine; + +public class ComponentPartsEventDefineSchema +{ + /// + /// 事件名称 + /// + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// 事件名称 + /// + [JsonPropertyName("en")] + public string EventName { get; set; } + + /// + /// 事件显示名称 + /// + [JsonPropertyName("disn")] + public string DisplayName { get; set; } + + /// + /// 事件描述 + /// + [JsonPropertyName("desc")] + public string Description { get; set; } + + /// + /// 事件分组 + /// + [JsonPropertyName("group")] + public string Group { get; set; } + + /// + /// 事件类型 + /// + [JsonPropertyName("et")] + public string EventType { get; set; } + + /// + /// 事件参数类型 + /// + [JsonPropertyName("pt")] + public string ParameterType { get; set; } + + /// + /// 是否必需 + /// + [JsonPropertyName("required")] + public bool IsRequired { get; set; } + + /// + /// 排序 + /// + [JsonPropertyName("order")] + public int Order { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsStyleDefineSchema.cs b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsStyleDefineSchema.cs new file mode 100644 index 0000000..337bdf5 --- /dev/null +++ b/src/Common/H.LowCode.MetaSchema.DesignEngine/PropertySchemas/ComponentPartsStyleDefineSchema.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace H.LowCode.MetaSchema.DesignEngine; + +public class ComponentPartsStyleDefineSchema +{ + /// + /// 样式属性名称 + /// + [JsonPropertyName("sn")] + public string StyleName { get; set; } + + /// + /// 样式显示名称 + /// + [JsonPropertyName("disn")] + public string DisplayName { get; set; } + + /// + /// 样式描述 + /// + [JsonPropertyName("desc")] + public string Description { get; set; } + + /// + /// 样式分组 + /// + [JsonPropertyName("group")] + public string Group { get; set; } + + /// + /// CSS属性名 + /// + [JsonPropertyName("cssprop")] + public string CssProperty { get; set; } + + /// + /// 样式类型 + /// + [JsonPropertyName("st")] + public string StyleType { get; set; } + + /// + /// 默认值 + /// + [JsonPropertyName("dftval")] + public string DefaultValue { get; set; } + + /// + /// 是否必需 + /// + [JsonPropertyName("required")] + public bool IsRequired { get; set; } + + /// + /// 排序 + /// + [JsonPropertyName("order")] + public int Order { get; set; } + + /// + /// 选项配置 + /// + [JsonPropertyName("options")] + public string Options { get; set; } + + /// + /// 控件类型 + /// + [JsonPropertyName("controltype")] + public string ControlType { get; set; } + + /// + /// 单位 + /// + [JsonPropertyName("unit")] + public string Unit { get; set; } +} \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs b/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs index ab5a456..1f56904 100644 --- a/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs +++ b/src/Common/H.LowCode.MetaSchema/ComponentSchemaBase.cs @@ -75,4 +75,7 @@ public abstract class ComponentSchemaBase : StateHasChangeSchema [JsonPropertyName("desc")] public string Description { get; set; } + + [JsonPropertyName("v")] + public string Version { get; set; } } \ No newline at end of file diff --git a/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/OptionDataSourceSchema.cs b/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/OptionDataSourceSchema.cs index d890c91..711c5c5 100644 --- a/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/OptionDataSourceSchema.cs +++ b/src/Common/H.LowCode.MetaSchema/DataSourceSchemas/OptionDataSourceSchema.cs @@ -1,4 +1,4 @@ -using H.Util.Ids; +using H.Util.Ids; using System; using System.Collections.Generic; using System.Linq; @@ -18,4 +18,16 @@ public record OptionDataSourceSchema [JsonPropertyName("v")] public string Value { get; set; } + + [JsonPropertyName("s")] + public bool IsSelected { get; set; } + + [JsonPropertyName("o")] + public int Order { get; set; } + + [JsonPropertyName("g")] + public string Group { get; set; } + + [JsonPropertyName("d")] + public string Description { get; set; } } diff --git a/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor b/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor index 1e721d8..0eda42b 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.DesignEngine +@namespace H.LowCode.DesignEngine @inherits DesignEngineLowCodeComponentBase @inject IComponentLibraryAppService ComponentLibraryAppService @@ -68,7 +68,6 @@ @code { - private IList _componentLibraries; private IList _componentPartsList; protected override async Task OnInitializedAsync() diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor index 4b760fa..be48550 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor @@ -1,4 +1,4 @@ -@namespace H.LowCode.PartsDesignEngine +@namespace H.LowCode.PartsDesignEngine @inherits DesignEngineLowCodeComponentBase @inject IComponentLibraryAppService ComponentLibraryAppService @@ -42,7 +42,6 @@ @code { - private IList _componentLibraries; private IList _componentPartsList; protected override async Task OnInitializedAsync() diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Components/AddComponentModal.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Components/AddComponentModal.razor new file mode 100644 index 0000000..467e33e --- /dev/null +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Components/AddComponentModal.razor @@ -0,0 +1,137 @@ +@namespace H.LowCode.PartsDesignEngine +@inherits DesignEngineLowCodeComponentBase + +@inject IComponentPartsAppService ComponentPartsAppService + + + + + + + + + + + + + + 原子组件 + 低代码组件 + + + + + + + + + + + + + - + + @code { [Parameter] @@ -85,12 +87,8 @@ Width="800" MaxBodyHeight="700"> IEnumerable selectedRows; private IList _componentPartsList; - private ComponentPartsSchema _componentPartsSchema = new ComponentPartsSchema(); - - private bool _formVisible = false; - private StandardComponentPartsDesigner _componentPartsForm; - private bool _textFormVisible = false; - private string _textFormValue; + private ComponentPartsSchema _componentPartsSchema; + private bool _showAddModal = false; IDictionary _parameterEditCache = new Dictionary(); @@ -114,40 +112,29 @@ Width="800" MaxBodyHeight="700"> return await ComponentPartsAppService.GetByIdAsync(LibraryId, componentPartsId); } - private void CreateAsync() + private void ShowAddComponentModal() { - _componentPartsSchema = new ComponentPartsSchema(); - _componentPartsSchema.LibraryId = LibraryId; - _formVisible = true; - - StateHasChanged(); + _showAddModal = true; } - private async Task DesignAsync(string componentId) + private async Task OnComponentCreated(ComponentPartsSchema componentParts) { - _componentPartsSchema = await GetComponentPartsAsync(componentId); - _formVisible = true; - + // 刷新组件列表 + _componentPartsList = await LoadComponentPartsListAsync(); StateHasChanged(); - } - - private async Task EditAsync(string componentId) - { - _componentPartsSchema = await GetComponentPartsAsync(componentId); - _formVisible = true; - StateHasChanged(); + // 根据组件类型跳转到不同的编辑页面 + if (componentParts.ComponentType == 1) // 原子组件 + { + NavigateTo($"/myparts/component/editorpage/{componentParts.LibraryId}/{componentParts.ComponentId}"); + } + else if (componentParts.ComponentType == 2) // 低代码组件 + { + NavigateTo($"/myparts/component/customdesigner/{componentParts.ComponentId}"); + } } - private async Task TextEditAsync(string componentId) - { - _componentPartsSchema = await GetComponentPartsAsync(componentId); - - _textFormValue = _componentPartsSchema.ToJson(writeIndented: true); - _textFormVisible = true; - StateHasChanged(); - } private async Task DeleteAsync(string componentPartsId) { @@ -156,33 +143,7 @@ Width="800" MaxBodyHeight="700"> await Message.SuccessAsync("模拟删除成功!"); } - private async Task OnConfirmAsync(MouseEventArgs e) - { - await _componentPartsForm.SubmitAsync(); - } - private async Task OnTextFormConfirmAsync(MouseEventArgs e) - { - _componentPartsSchema = _textFormValue.FromJson(); - var isSuccess = await SaveComponentPartsSchemaAsync(); - if (isSuccess) - { - _textFormVisible = false; - _componentPartsList = await LoadComponentPartsListAsync(); - - await Message.SuccessAsync("保存成功!"); - } - else - { - _textFormVisible = true; - await Message.ErrorAsync("保存失败"); - } - } - - private async Task SaveComponentPartsSchemaAsync() - { - return await ComponentPartsAppService.SaveAsync(_componentPartsSchema); - } private void GoToComponentLibraryList() { diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor new file mode 100644 index 0000000..fbf9b65 --- /dev/null +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor @@ -0,0 +1,75 @@ +@namespace H.LowCode.PartsDesignEngine +@inherits DesignEngineLowCodeComponentBase + +
+ + + +
+ + + + + + + + + + + + + + + + + + - - - - - - - 待发布 - 已发布 - - - -
- 组件设计面板属性: - - - - @if (context.IsContainer == false && context.IsSupportDataSource) - { - 数据源: - - - - } -
-
- +
+ +
@code{ [Parameter] - public ComponentPartsSchema ComponentParts { get; set; } + public string Tab { get; set; } - private Form _form; - - private string _textComponentFragment; - private string _textDataSource; - private string _textAttributeDefineGroups; + [Parameter] + public ComponentPartsSchema ComponentParts { get; set; } protected override async Task OnInitializedAsync() { - Init(); - await base.OnInitializedAsync(); } - private void Init() - { - _textComponentFragment = ComponentParts.Fragment.ToJson(writeIndented: true); - _textDataSource = ComponentParts.DataSource?.ToJson(writeIndented: true); - _textAttributeDefineGroups = ComponentParts.AttributeDefineGroups?.ToJson(writeIndented: true); - } - - public async Task SubmitAsync() + private async Task OnSaveComponent(ComponentPartsSchema componentParts) { - var validate = _form.Validate(); - if (validate) + try { - ComponentParts.Fragment = _textComponentFragment.FromJson(); - ComponentParts.DataSource = _textDataSource.FromJson(); - ComponentParts.AttributeDefineGroups = _textAttributeDefineGroups.FromJson(); - var isSuccess = await SaveComponentPartsSchemaAsync(); + var isSuccess = await ComponentPartsAppService.SaveAsync(componentParts); if (isSuccess) { - _form.Submit(); await Message.SuccessAsync("保存成功!"); - _form.Reset(); } else { await Message.ErrorAsync("保存失败"); } } + catch (Exception ex) + { + await Message.ErrorAsync($"保存失败:{ex.Message}"); + } } - private async Task SaveComponentPartsSchemaAsync() + private async Task OnCancel() { - return await ComponentPartsAppService.SaveAsync(ComponentParts); + // 可以添加取消逻辑,比如返回上一页或重置表单 + await Task.CompletedTask; } - } \ No newline at end of file diff --git a/src/common.props b/src/common.props index 7fc71cf..15eff3b 100644 --- a/src/common.props +++ b/src/common.props @@ -2,6 +2,7 @@ net9.0 enable + preview 0.5.0 False -- Gitee From 74a81bf8473bbc4cf42f80c07fde0b9bc335533d Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sat, 11 Oct 2025 00:32:56 +0800 Subject: [PATCH 22/33] =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=BA=93=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=B8=83=E5=B1=80=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trae/rules/project_rules.md | 7 + .../H.LowCode.DesignEngine.Host/Program.cs | 17 +- .../H.LowCode.PartsDesignEngine.csproj | 4 - .../ComponentLibraryManager.razor | 495 ++++++++++++++++++ .../ComponentParts/ComponentPartsList.razor | 23 +- .../Pages/MyParts.razor | 14 +- .../Pages/ThemeParts/ThemePartsList.razor | 25 + 7 files changed, 568 insertions(+), 17 deletions(-) create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor create mode 100644 src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ThemeParts/ThemePartsList.razor diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md index 5f9aa98..1ab899b 100644 --- a/.trae/rules/project_rules.md +++ b/.trae/rules/project_rules.md @@ -50,6 +50,9 @@ * MenuSchema:菜单的元数据定义,包含菜单项的组织方式和行为特性。 ### 设计引擎 +#### 启动项目 +设计引擎启动项目 H.LowCode.DesignEngine.Host + #### 物料 物料的管理对应 H.LowCode.PartsDesignEngine 项目, 物料主要包含组件、主题等,物料的元数据定义在 H.LowCode.MetaSchema.DesignEngine 项目中。 @@ -65,6 +68,10 @@ * 配置面板:对选中的组件进行属性、样式和事件的配置。 ### 渲染引擎 +#### 启动项目 +设计引擎启动项目 H.LowCode.DesignEngine.Host + +#### 页面渲染 渲染引擎负责根据页面的元数据文件,动态生成 Blazor 组件树,并在前端页面中渲染出来。渲染引擎位于 H.LowCode.RenderEngine 项目中,主要负责以下几个方面的功能: * 元数据解析:读取页面的元数据文件,解析出组件、样式、事件等信息。 * 组件渲染:根据解析出的元数据,动态创建 Blazor 组件实例,并将其添加到组件树中。 diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs b/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs index 7d8761f..36d682e 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs @@ -13,12 +13,27 @@ builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents(); +// Configure SignalR and Circuit options for Blazor Server +builder.Services.AddSignalR(options => +{ + options.MaximumReceiveMessageSize = 1024 * 1024; // 1MB + options.EnableDetailedErrors = builder.Environment.IsDevelopment(); +}); + +builder.Services.Configure(options => +{ + options.DisconnectedCircuitMaxRetained = 100; + options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3); + options.JSInteropDefaultCallTimeout = TimeSpan.FromMinutes(1); + options.MaxBufferedUnacknowledgedRenderBatches = 10; +}); + builder.Services.AddControllers().AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); -// Ӧѹ +// ������Ӧѹ�� builder.Services.AddResponseCompression(options => { options.Providers.Add(); diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj b/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj index 5492297..3c128e1 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/H.LowCode.PartsDesignEngine.csproj @@ -23,8 +23,4 @@ - - - - diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor new file mode 100644 index 0000000..498167c --- /dev/null +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor @@ -0,0 +1,495 @@ +@namespace H.LowCode.PartsDesignEngine +@inherits DesignEngineLowCodeComponentBase +@layout PartsDesignEngineLayout + +@inject IComponentLibraryAppService ComponentLibraryAppService +@inject IComponentPartsAppService ComponentPartsAppService +@inject ComponentState> ComponentLibrariesState +@inject ComponentState> ComponentPartsListState + + + +
+ +
+
+
+

组件库

+ +
+ +
+ +
+ @if (_componentLibraries != null && _componentLibraries.Any()) + { + @foreach (var library in FilteredLibraries) + { +
+
+
+
@library.LibraryName
+
@library.Description
+
+
+ + + + + 编辑 + + + 删除 + + + + +
+
+
+ } + } + else + { +
+ +
暂无组件库
+
+ } +
+
+ + +
+ + +
+ @if (!string.IsNullOrEmpty(_selectedLibraryId)) + { +
+
+

+ @(_selectedLibrary?.LibraryName ?? "组件列表") +

+ +
+ +
+ +
+ @if (FilteredComponents.Any()) + { +
+ @foreach (var component in FilteredComponents) + { + + +
+
+ + @component.Label +
+
+ @component.ComponentName +
+
+ + @(component.ComponentType == 1 ? "原子组件" : "低代码组件") + + @if (component.IsContainer) + { + 容器 + } + @if (component.IsSupportDataSource) + { + 数据源 + } + + @(component.PublishStatus == 1 ? "已发布" : "待发布") + +
+
+ + @component.ModifiedTime.ToString("MM-dd HH:mm") + +
+ @if (component.ComponentType == 1) + { + + } + else if (component.ComponentType == 2) + { + + } + + + +
+
+
+
+
+ } +
+ } + else if (_componentPartsLoading) + { +
+ +
加载组件列表中...
+
+ } + else + { +
+ +
该组件库暂无组件
+
+ } +
+ } + else + { +
+
+ +
请选择一个组件库查看组件列表
+
+
+ } +
+
+ + + + + + + + + + + +@code { + [Parameter] + public Action Refresh { get; set; } + + // 数据字段 + private IList _componentLibraries; + private IList _componentParts; + + private string _selectedLibraryId; + private ComponentLibrarySchema _selectedLibrary; + private bool _componentPartsLoading = false; + + // 搜索 + private string _librarySearchText = ""; + private string _componentSearchText = ""; + + // 模态框 + private bool _libraryModalVisible = false; + private bool _isEditingLibrary = false; + private ComponentLibrarySchema _currentComponentLibrary; + private ComponentLibraryForm _componentLibraryForm; + private bool _showAddModal = false; + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + await LoadComponentLibrariesAsync(); + + // 默认选中第一个组件库 + if (_componentLibraries != null && _componentLibraries.Any()) + { + await SelectLibraryAsync(_componentLibraries.First()); + } + } + + private async Task LoadComponentLibrariesAsync() + { + _componentLibraries = await ComponentLibrariesState.GetOrAddAsync(this, async () => + { + return await ComponentLibraryAppService.GetListAsync(); + }); + } + + private async Task OnLibraryCreated() + { + // 重新加载组件库列表 + await LoadComponentLibrariesAsync(); + + // 选择新创建的组件库 + if (_currentComponentLibrary != null) + { + await SelectLibraryAsync(_currentComponentLibrary); + } + + // 重置状态 + _currentComponentLibrary = null; + _isEditingLibrary = false; + + await Message.SuccessAsync("操作成功"); + StateHasChanged(); + } + + private async Task SelectLibraryAsync(ComponentLibrarySchema library) + { + _selectedLibraryId = library.LibraryId; + await LoadComponentPartsAsync(); + StateHasChanged(); + } + + private async Task LoadComponentPartsAsync() + { + if (string.IsNullOrEmpty(_selectedLibraryId)) + return; + + _componentParts = await ComponentPartsListState.GetOrAddAsync(this, async () => + { + return await ComponentPartsAppService.GetListAsync(_selectedLibraryId); + }); + } + + + + private void OnSearchLibrary(string searchText) + { + _librarySearchText = searchText ?? ""; + StateHasChanged(); + } + + private void OnSearchComponent(string searchText) + { + _componentSearchText = searchText ?? ""; + StateHasChanged(); + } + + private IEnumerable FilteredLibraries => + string.IsNullOrWhiteSpace(_librarySearchText) + ? _componentLibraries ?? Enumerable.Empty() + : _componentLibraries?.Where(lib => + lib.LibraryName.Contains(_librarySearchText, StringComparison.OrdinalIgnoreCase) || + (lib.Description?.Contains(_librarySearchText, StringComparison.OrdinalIgnoreCase) == true)) ?? Enumerable.Empty(); + + private IEnumerable FilteredComponents => + _componentParts?.Where(comp => + string.IsNullOrEmpty(_componentSearchText) || + comp.ComponentName.Contains(_componentSearchText, StringComparison.OrdinalIgnoreCase) || + comp.Label.Contains(_componentSearchText, StringComparison.OrdinalIgnoreCase)) ?? + Enumerable.Empty(); + + #region 组件库操作 + + private void CreateComponentLibrary() + { + _currentComponentLibrary = new(); + _isEditingLibrary = false; + _libraryModalVisible = true; + StateHasChanged(); + } + + private void EditLibrary(string libraryId) + { + _currentComponentLibrary = _componentLibraries?.FirstOrDefault(x => x.LibraryId == libraryId); + _isEditingLibrary = true; + _libraryModalVisible = true; + StateHasChanged(); + } + + private async Task OnLibraryConfirm(MouseEventArgs e) + { + var success = await _componentLibraryForm.SubmitAsync(); + if (success) + { + _libraryModalVisible = false; + await LoadComponentLibrariesAsync(); + + // 如果是新创建的组件库,选中它 + if (!_isEditingLibrary && _currentComponentLibrary != null) + { + await SelectLibraryAsync(_currentComponentLibrary); + } + + await Message.SuccessAsync(_isEditingLibrary ? "组件库更新成功!" : "组件库创建成功!"); + _currentComponentLibrary = null; + _isEditingLibrary = false; + } + } + + private async Task DeleteLibrary(string libraryId) + { + await ComponentLibraryAppService.DeleteAsync(libraryId); + + // 重新加载组件库列表 + await LoadComponentLibrariesAsync(); + + // 清空组件列表 + _componentParts = new List(); + + // 如果删除的是当前选中的组件库,重新选择第一个 + if (_selectedLibraryId == libraryId) + { + _selectedLibraryId = null; + _currentComponentLibrary = null; + + if (_componentLibraries.Any()) + { + await SelectLibraryAsync(_componentLibraries.First()); + } + } + + await Message.SuccessAsync("删除成功"); + StateHasChanged(); + } + + #endregion + + #region 组件操作 + + private void ShowAddComponentModal() + { + if (string.IsNullOrEmpty(_selectedLibraryId)) + { + Message.Warning("请先选择一个组件库"); + return; + } + _showAddModal = true; + } + + private async Task OnComponentCreated(ComponentPartsSchema componentParts) + { + // 刷新当前组件库的组件列表 + await LoadComponentPartsAsync(); + await Message.SuccessAsync("组件创建成功!"); + + // 根据组件类型跳转到不同的编辑页面 + if (componentParts.ComponentType == 1) // 原子组件 + { + NavigateTo($"/myparts/component/editorpage/{componentParts.LibraryId}/{componentParts.ComponentId}"); + } + else if (componentParts.ComponentType == 2) // 低代码组件 + { + NavigateTo($"/myparts/component/customdesigner/{componentParts.ComponentId}"); + } + } + + private void EditComponent(ComponentPartsListModel component) + { + NavigateTo($"/myparts/component/editorpage/{component.LibraryId}/{component.ComponentId}"); + } + + private void DesignComponent(ComponentPartsListModel component) + { + NavigateTo($"/myparts/page/designer/{component.ComponentId}"); + } + + private async Task DeleteComponent(string componentId) + { + try + { + await ComponentPartsAppService.DeleteAsync(_selectedLibraryId, componentId); + + // 重新加载组件列表 + await LoadComponentPartsAsync(); + + await Message.SuccessAsync("组件删除成功!"); + StateHasChanged(); + } + catch (Exception ex) + { + await Message.ErrorAsync($"删除失败:{ex.Message}"); + } + } + + #endregion +} \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor index 0481893..290bd39 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor @@ -138,9 +138,26 @@ HidePagination="true" Style="height:100%;"> private async Task DeleteAsync(string componentPartsId) { - //await ComponentPartsAppService.DeleteAsync(LibraryId, componentPartsId); - - await Message.SuccessAsync("模拟删除成功!"); + try + { + await ComponentPartsAppService.DeleteAsync(LibraryId, componentPartsId); + + // 重新加载组件列表 + _componentPartsList = await LoadComponentPartsListAsync(); + StateHasChanged(); + + await Message.SuccessAsync("组件删除成功!"); + + // 通知父组件刷新 + if (Refresh != null) + { + Refresh(); + } + } + catch (Exception ex) + { + await Message.ErrorAsync($"删除失败:{ex.Message}"); + } } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor index 91cffef..658958d 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor @@ -1,4 +1,4 @@ -@page "/myparts/{Tab?}" +@page "/myparts/{Tab?}" @namespace H.LowCode.PartsDesignEngine @inherits LowCodePageComponentBase @layout DesignEngineNavLayout @@ -10,18 +10,14 @@ - @if (string.IsNullOrEmpty(LibraryId)) - { - - } - else - { - - } + + + + @code { diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ThemeParts/ThemePartsList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ThemeParts/ThemePartsList.razor new file mode 100644 index 0000000..0e9a08b --- /dev/null +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ThemeParts/ThemePartsList.razor @@ -0,0 +1,25 @@ +@namespace H.LowCode.PartsDesignEngine +@inherits DesignEngineLowCodeComponentBase +@layout PartsDesignEngineLayout + +
+
+ +
+
+ + + + 查看 + + +

Card content

+ +
+ +@code { + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + } +} \ No newline at end of file -- Gitee From 61c8d86040e29b44bdb60f887c80df68f24002fd Mon Sep 17 00:00:00 2001 From: "{iliuhai@aliyun.com}" Date: Sun, 12 Oct 2025 00:31:07 +0800 Subject: [PATCH 23/33] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=88=B0=20dotnet=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LowCodeComponentBaseModule.cs | 13 +--- .../DataRepositories/FormDataRepository.cs | 4 ++ .../DataRepositories/TableDataRepository.cs | 4 ++ .../DesignEngineHostClientModule.cs | 6 +- .../H.LowCode.DesignEngine.Host.Client.csproj | 3 +- .../Components/App.razor | 14 ++-- .../Components/_Imports.razor | 2 + .../DesignEngineHostModule.cs | 6 +- .../H.LowCode.DesignEngine.Host.csproj | 4 ++ .../H.LowCode.DesignEngine.Host/Program.cs | 8 ++- .../appsettings.Development.json | 3 +- .../ComponentPanel/ComponentPanel.razor | 14 +--- .../Pages/DesignPage.razor | 13 ++-- .../H.LowCode.MyApp/Layout/MyAppLayout.razor | 19 ++---- .../Pages/DataSource/APIDataSourceList.razor | 10 ++- .../DataSource/TableDataSourceList.razor | 10 ++- .../H.LowCode.MyApp/Pages/MenuManager.razor | 10 ++- .../H.LowCode.MyApp/Pages/MyApps.razor | 10 ++- .../H.LowCode.MyApp/Pages/PageManager.razor | 10 ++- .../ComponentPanel/ComponentPanel.razor | 10 +-- .../Pages/AppParts/AppPartsList.razor | 10 +-- .../ComponentLibraryList.razor | 17 ++--- .../ComponentLibraryManager.razor | 57 ++++++++--------- .../ComponentParts/ComponentPartsList.razor | 10 ++- .../Pages/MyParts.razor | 7 +- .../Pages/Ecosystems/AppTemplates.razor | 10 +-- src/Directory.Packages.props | 64 +++++++++---------- src/H.LowCode.sln | 5 +- .../DataRepositories/FormDataRepository.cs | 4 ++ .../DataRepositories/TableDataRepository.cs | 4 ++ .../H.LowCode.RenderEngine.Host.Client.csproj | 3 +- .../RenderEngineHostClientModule.cs | 6 +- .../Components/App.razor | 15 +++-- .../Components/_Imports.razor | 2 + .../H.LowCode.RenderEngine.Host.csproj | 4 ++ .../H.LowCode.RenderEngine.Host/Program.cs | 7 +- .../RenderEngineHostModule.cs | 4 +- .../Layout/AntBlazorThemeLayout.razor | 14 ++-- .../PageRender/FormPageRender.razor | 23 +++---- .../Pages/MetaPage.razor | 13 ++-- src/common.props | 4 +- global.json => src/global.json | 2 +- 42 files changed, 207 insertions(+), 251 deletions(-) rename global.json => src/global.json (67%) diff --git a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBaseModule.cs b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBaseModule.cs index 7111c89..050786d 100644 --- a/src/Common/H.LowCode.ComponentBase/LowCodeComponentBaseModule.cs +++ b/src/Common/H.LowCode.ComponentBase/LowCodeComponentBaseModule.cs @@ -1,11 +1,4 @@ -using H.Util.Blazor; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Volo.Abp.Modularity; +using Volo.Abp.Modularity; namespace H.LowCode.ComponentBase; @@ -13,8 +6,6 @@ public class LowCodeComponentBaseModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //状态管理 - context.Services.AddScoped(typeof(ComponentState<>)); - context.Services.AddScoped(typeof(ComponentState<,>)); + } } diff --git a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs index 8c1a0cd..ceda7d2 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs @@ -12,6 +12,10 @@ public class FormDataRepository : IFormDataRepository private DesignEngineDbContext _dbContext; public bool? IsChangeTrackingEnabled => true; + public string? EntityName { get; set; } + + public string ProviderName => throw new NotImplementedException(); + public FormDataRepository(DesignEngineDbContext dbContext) { _dbContext = dbContext; diff --git a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs index c913db0..6b4e96d 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs @@ -10,6 +10,10 @@ public class TableDataRepository : ITableDataRepository { public bool? IsChangeTrackingEnabled => true; + public string? EntityName { get; set; } + + public string ProviderName => throw new NotImplementedException(); + public TableDataRepository(DesignEngineDbContext dbContext) { } diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs index 23a0dbf..21f3a0c 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/DesignEngineHostClientModule.cs @@ -1,4 +1,4 @@ -using H.LowCode.Application.Contracts; +using H.LowCode.Application.Contracts; using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.DesignEngine.Application.Contracts; @@ -26,9 +26,7 @@ namespace H.LowCode.DesignEngine.Host.Client; typeof(MyAppModule), typeof(PartsDesignEngineModule), //Components - typeof(LowCodeDefaultComponentModule), - //ComponentBase - typeof(LowCodeComponentBaseModule) + typeof(LowCodeDefaultComponentModule) )] public class DesignEngineHostClientModule : AbpModule { diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj index d6925cf..cd1b5ea 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host.Client/H.LowCode.DesignEngine.Host.Client.csproj @@ -5,8 +5,7 @@ true Default - - + true diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor index 587e6f8..200be48 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/App.razor @@ -14,22 +14,22 @@ - - - - + + + + @* *@ - + - - + + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/_Imports.razor b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/_Imports.razor index bfd93b1..f9a93dd 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/_Imports.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Components/_Imports.razor @@ -9,3 +9,5 @@ @using H.LowCode.DesignEngine.Host @using H.LowCode.DesignEngine.Host.Client @using H.LowCode.DesignEngine.Host.Components +@using AntDesign +@using CssInCSharp \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/DesignEngineHostModule.cs b/src/DesignEngine/H.LowCode.DesignEngine.Host/DesignEngineHostModule.cs index dd3dec4..443e322 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/DesignEngineHostModule.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/DesignEngineHostModule.cs @@ -1,4 +1,4 @@ -using H.LowCode.ComponentBase; +using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.DesignEngine.Application; using H.LowCode.DesignEngine.EntityFrameworkCore; @@ -28,9 +28,7 @@ namespace H.LowCode.DesignEngine.Host; typeof(MyAppModule), typeof(PartsDesignEngineModule), //Components - typeof(LowCodeDefaultComponentModule), - //ComponentBase - typeof(LowCodeComponentBaseModule) + typeof(LowCodeDefaultComponentModule) )] public class DesignEngineHostModule : AbpModule { diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj b/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj index 095ad12..62561de 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/H.LowCode.DesignEngine.Host.csproj @@ -2,6 +2,10 @@ + + true + + diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs b/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs index 36d682e..681a7c6 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/Program.cs @@ -26,6 +26,7 @@ builder.Services.Configure @@ -67,6 +68,11 @@ else app.UseHsts(); } +app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); +app.UseHttpsRedirection(); + +app.UseAntiforgery(); + app.UseResponseCompression(); app.UseStaticFiles(new StaticFileOptions { @@ -76,8 +82,6 @@ app.UseStaticFiles(new StaticFileOptions } }); -app.UseHttpsRedirection(); - app.MapStaticAssets(); app.UseRouting(); app.UseAntiforgery(); diff --git a/src/DesignEngine/H.LowCode.DesignEngine.Host/appsettings.Development.json b/src/DesignEngine/H.LowCode.DesignEngine.Host/appsettings.Development.json index 0c208ae..f8063ef 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine.Host/appsettings.Development.json +++ b/src/DesignEngine/H.LowCode.DesignEngine.Host/appsettings.Development.json @@ -4,5 +4,6 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } - } + }, + "DetailedErrors": true } diff --git a/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor b/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor index 0eda42b..fac12c9 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/ComponentPanel/ComponentPanel.razor @@ -3,8 +3,6 @@ @inject IComponentLibraryAppService ComponentLibraryAppService @inject IComponentPartsAppService ComponentPartsAppService -@* @inject ComponentState> ComponentLibrariesState *@ -@inject ComponentState> ComponentPartsListState @@ -68,20 +66,14 @@ @code { - private IList _componentPartsList; + [PersistentState] + public IList? _componentPartsList { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - // _componentLibraries = await ComponentLibrariesState.GetOrAddAsync(this, async () => - // { - // return await LoadComponentLibraries(); - // }); - _componentPartsList = await ComponentPartsListState.GetOrAddAsync(this, async () => - { - return await LoadComponentPartsAsync(); - }); + _componentPartsList = (await LoadComponentPartsAsync()) ?? []; } private async Task> LoadComponentLibraries() diff --git a/src/DesignEngine/H.LowCode.DesignEngine/Pages/DesignPage.razor b/src/DesignEngine/H.LowCode.DesignEngine/Pages/DesignPage.razor index c87689c..e49216d 100644 --- a/src/DesignEngine/H.LowCode.DesignEngine/Pages/DesignPage.razor +++ b/src/DesignEngine/H.LowCode.DesignEngine/Pages/DesignPage.razor @@ -5,7 +5,6 @@ @inject IPageAppService PageAppService @inject DragDropStateService DragDropStateService -@inject ComponentState PagePartsSchemaState @($"{_pageCascadingModel.PageName} - 页面设计器") @@ -47,12 +46,14 @@ @code { [Parameter] - public string AppId { get; set; } + public required string AppId { get; set; } [Parameter] public string PageId { get; set; } - private PagePartsSchema _pageSchema; + [PersistentState] + public required PagePartsSchema _pageSchema { get; set; } + private PageCascadingModel _pageCascadingModel; private bool _isNewPage; @@ -62,10 +63,8 @@ _pageCascadingModel = new() { AppId = AppId, PageId = PageId, PageName = "..." }; - _pageSchema = await PagePartsSchemaState.GetOrAddAsync(this, async () => - { - return await LoadPageSchemaAsync(); - }); + _pageSchema = await LoadPageSchemaAsync(); + SetPageCascadingModel(_pageSchema); } diff --git a/src/DesignEngine/H.LowCode.MyApp/Layout/MyAppLayout.razor b/src/DesignEngine/H.LowCode.MyApp/Layout/MyAppLayout.razor index 88a0aff..5d5e23f 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Layout/MyAppLayout.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Layout/MyAppLayout.razor @@ -2,8 +2,6 @@ @inherits LowCodeLayoutComponentBase @inject IAppApplicationService AppApplicationService -@inject ComponentState MenuDataState -@inject ComponentState AppState @@ -26,23 +24,18 @@ @code { - private AppPartsSchema _appSchema; - private MenuDataItem[] _menuDataItems; + [PersistentState] + public AppPartsSchema _appSchema { get; set; } + [PersistentState] + public MenuDataItem[] _menuDataItems { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - _appSchema = await AppState.GetOrAddAsync(typeof(AppPartsSchema), async () => - { - return await GetAppSchemaAsync(AppId); - }); + _appSchema = await GetAppSchemaAsync(AppId); - _menuDataItems = await MenuDataState.GetOrAddAsync(this, async () => - { - var menus = InitMenuData(AppId); - return await Task.FromResult(menus); - }); + _menuDataItems = InitMenuData(AppId); } private async Task GetAppSchemaAsync(string appId) diff --git a/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/APIDataSourceList.razor b/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/APIDataSourceList.razor index 166c71f..2348bd6 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/APIDataSourceList.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/APIDataSourceList.razor @@ -2,7 +2,6 @@ @inherits DesignEngineLowCodeComponentBase @inject IDataSourceAppService DataSourceAppService -@inject ComponentState> APIListState
@@ -56,6 +55,9 @@ [Parameter] public string AppId { get; set; } + [PersistentState] + public IList _dataSourceList { get; set; } + int _pageIndex = 1; int _pageSize = 10; int _total = 0; @@ -63,7 +65,6 @@ private bool _visible; private string _modalTitle; private Form _form; - private IList _dataSourceList; private DataSourceSchema _dataSource = new DataSourceSchema(); protected override async Task OnInitializedAsync() @@ -71,10 +72,7 @@ await base.OnInitializedAsync(); _total = 50; - _dataSourceList = await APIListState.GetOrAddAsync(this, async () => - { - return await LoadDataSourcesAsync(1, 50); - }); + _dataSourceList = await LoadDataSourcesAsync(1, 50); } private async Task> LoadDataSourcesAsync(int pageIndex, int pageSize) diff --git a/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/TableDataSourceList.razor b/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/TableDataSourceList.razor index a643d07..4281225 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/TableDataSourceList.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Pages/DataSource/TableDataSourceList.razor @@ -2,7 +2,6 @@ @inherits DesignEngineLowCodeComponentBase @inject IDataSourceAppService DataSourceAppService -@inject ComponentState> DataSourceListState
@@ -162,9 +161,11 @@ [Parameter] public string AppId { get; set; } + [PersistentState] + public IList _dataSourceList { get; set; } + IDictionary _fieldEditCache = new Dictionary(); - private IList _dataSourceList; private DataSourceSchema _dataSource; int _pageIndex = 1; @@ -179,10 +180,7 @@ await base.OnInitializedAsync(); _total = 50; - _dataSourceList = await DataSourceListState.GetOrAddAsync(this, async () => - { - return await LoadDataSourcesAsync(1, 50); - }); + _dataSourceList = await LoadDataSourcesAsync(1, 50); } private async Task> LoadDataSourcesAsync(int pageIndex, int pageSize) diff --git a/src/DesignEngine/H.LowCode.MyApp/Pages/MenuManager.razor b/src/DesignEngine/H.LowCode.MyApp/Pages/MenuManager.razor index dc298a5..fdd3db8 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Pages/MenuManager.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Pages/MenuManager.razor @@ -4,7 +4,6 @@ @layout MyAppLayout @inject IMenuAppService MenuAppService -@inject ComponentState> MenuListState 菜单管理 @@ -80,22 +79,21 @@ RowKey="x=>x.Id" HidePagination DefaultExpandAllRows> [Parameter] public string AppId { get; set; } + [PersistentState] + public IList _menuList { get; set; } + IEnumerable selectedRows; private bool _visible = false; private Form _form; - private IList _menuList; private MenuSchema _menuSchema = new MenuSchema(); protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - _menuList = await MenuListState.GetOrAddAsync(this, async () => - { - return await GetMenuListAsync(); - }); + _menuList = await GetMenuListAsync(); } public async Task> GetMenuListAsync() diff --git a/src/DesignEngine/H.LowCode.MyApp/Pages/MyApps.razor b/src/DesignEngine/H.LowCode.MyApp/Pages/MyApps.razor index 6aaaeb9..b2eae4f 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Pages/MyApps.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Pages/MyApps.razor @@ -4,7 +4,6 @@ @layout DesignEngineNavLayout @inject IAppApplicationService AppApplicationService -@inject ComponentState> MyAppsState 我的应用 - H.LowCode @@ -96,7 +95,9 @@ @code { - private IList _appList; + [PersistentState] + public IList _appList { get; set; } + private AppPartsSchema _currentApp; private bool _createVisible = false; @@ -109,10 +110,7 @@ { await base.OnInitializedAsync(); - _appList = await MyAppsState.GetOrAddAsync(this, async () => - { - return await LoadAppsAsync(); - }); + _appList = await LoadAppsAsync(); } private async Task> LoadAppsAsync() diff --git a/src/DesignEngine/H.LowCode.MyApp/Pages/PageManager.razor b/src/DesignEngine/H.LowCode.MyApp/Pages/PageManager.razor index 3978b5f..9207613 100644 --- a/src/DesignEngine/H.LowCode.MyApp/Pages/PageManager.razor +++ b/src/DesignEngine/H.LowCode.MyApp/Pages/PageManager.razor @@ -4,7 +4,6 @@ @layout MyAppLayout @inject IPageAppService PageAppService -@inject ComponentState> PageListState 页面管理 @@ -88,12 +87,14 @@ [Parameter] public string AppId { get; set; } + [PersistentState] + public IList _pageList { get; set; } + IEnumerable selectedRows; int _total = 0; private bool _visible; private Form _form; - private IList _pageList; private PagePartsSchema _pageSchema = new PagePartsSchema(); protected override async Task OnInitializedAsync() @@ -101,10 +102,7 @@ await base.OnInitializedAsync(); _total = 50; - _pageList = await PageListState.GetOrAddAsync(this, async () => - { - return await LoadPagesAsync(1, 50); - }); + _pageList = await LoadPagesAsync(1, 50); } private async Task> LoadPagesAsync(int pageIndex, int pageSize) diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor index be48550..d531404 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/ComponentPanel/ComponentPanel.razor @@ -3,8 +3,6 @@ @inject IComponentLibraryAppService ComponentLibraryAppService @inject IComponentPartsAppService ComponentPartsAppService -@* @inject ComponentState> ComponentLibrariesState *@ -@inject ComponentState> ComponentPartsListState @@ -42,7 +40,8 @@ @code { - private IList _componentPartsList; + [PersistentState] + public IList _componentPartsList { get; set; } protected override async Task OnInitializedAsync() { @@ -52,10 +51,7 @@ // { // return await LoadComponentLibraries(); // }); - _componentPartsList = await ComponentPartsListState.GetOrAddAsync(this, async () => - { - return await LoadComponentPartsAsync(); - }); + _componentPartsList = await LoadComponentPartsAsync(); } private async Task> LoadComponentLibraries() diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/AppParts/AppPartsList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/AppParts/AppPartsList.razor index 6e402aa..dbc3b1d 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/AppParts/AppPartsList.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/AppParts/AppPartsList.razor @@ -2,8 +2,6 @@ @inherits DesignEngineLowCodeComponentBase @layout PartsDesignEngineLayout -@inject ComponentState> AppPartsState -
@@ -28,16 +26,14 @@ @code { - private IList _appParts; + [PersistentState] + public IList _appParts { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - _appParts = await AppPartsState.GetOrAddAsync(this, async () => - { - return await LoadAppPartsAsync(1, 50); - }); + _appParts = await LoadAppPartsAsync(1, 50); } private async Task> LoadAppPartsAsync(int pageIndex, int pageSize) diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraries/ComponentLibraryList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraries/ComponentLibraryList.razor index f346882..b1c7a29 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraries/ComponentLibraryList.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraries/ComponentLibraryList.razor @@ -3,7 +3,6 @@ @layout PartsDesignEngineLayout @inject IComponentLibraryAppService ComponentLibraryAppService -@inject ComponentState> ComponentLibrariesState
@@ -48,7 +47,9 @@ [Parameter] public Action Refresh { get; set; } - private IList _componentLibraryList; + [PersistentState] + public IList _componentLibraryList { get; set; } + private ComponentLibrarySchema _currentComponentLibrary; private bool _visible = false; @@ -60,15 +61,7 @@ { await base.OnInitializedAsync(); - _componentLibraryList = await ComponentLibrariesState.GetOrAddAsync(this, async () => - { - return await LoadComponentLibrariesAsync(); - }); - } - - private async Task> LoadComponentLibrariesAsync() - { - return await ComponentLibraryAppService.GetListAsync(); + _componentLibraryList = await ComponentLibraryAppService.GetListAsync(); } private async Task OnConfirm(MouseEventArgs e) @@ -78,7 +71,7 @@ if (success) { _visible = false; - _componentLibraryList = await LoadComponentLibrariesAsync(); + _componentLibraryList = await ComponentLibraryAppService.GetListAsync(); StateHasChanged(); } diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor index 498167c..3accf60 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentLibraryManager.razor @@ -4,8 +4,6 @@ @inject IComponentLibraryAppService ComponentLibraryAppService @inject IComponentPartsAppService ComponentPartsAppService -@inject ComponentState> ComponentLibrariesState -@inject ComponentState> ComponentPartsListState @code { - [Parameter] - public Action Refresh { get; set; } + [PersistentState] + public IList _componentLibraries { get; set; } - // 数据字段 - private IList _componentLibraries; private IList _componentParts; - + private string _selectedLibraryId; private ComponentLibrarySchema _selectedLibrary; private bool _componentPartsLoading = false; - + // 搜索 private string _librarySearchText = ""; private string _componentSearchText = ""; - + // 模态框 private bool _libraryModalVisible = false; private bool _isEditingLibrary = false; @@ -287,7 +283,7 @@ { await base.OnInitializedAsync(); await LoadComponentLibrariesAsync(); - + // 默认选中第一个组件库 if (_componentLibraries != null && _componentLibraries.Any()) { @@ -297,36 +293,33 @@ private async Task LoadComponentLibrariesAsync() { - _componentLibraries = await ComponentLibrariesState.GetOrAddAsync(this, async () => - { - return await ComponentLibraryAppService.GetListAsync(); - }); + _componentLibraries = await ComponentLibraryAppService.GetListAsync(); } private async Task OnLibraryCreated() { // 重新加载组件库列表 await LoadComponentLibrariesAsync(); - + // 选择新创建的组件库 if (_currentComponentLibrary != null) { await SelectLibraryAsync(_currentComponentLibrary); } - + // 重置状态 _currentComponentLibrary = null; _isEditingLibrary = false; - + await Message.SuccessAsync("操作成功"); - StateHasChanged(); + //StateHasChanged(); } private async Task SelectLibraryAsync(ComponentLibrarySchema library) { _selectedLibraryId = library.LibraryId; await LoadComponentPartsAsync(); - StateHasChanged(); + //StateHasChanged(); } private async Task LoadComponentPartsAsync() @@ -334,24 +327,24 @@ if (string.IsNullOrEmpty(_selectedLibraryId)) return; - _componentParts = await ComponentPartsListState.GetOrAddAsync(this, async () => - { - return await ComponentPartsAppService.GetListAsync(_selectedLibraryId); - }); + // _componentParts = await ComponentPartsListState.GetOrAddAsync(typeof(IList), + // async () => + // { + // return await ComponentPartsAppService.GetListAsync(_selectedLibraryId); + // }); + _componentParts = await ComponentPartsAppService.GetListAsync(_selectedLibraryId); } - - private void OnSearchLibrary(string searchText) { _librarySearchText = searchText ?? ""; - StateHasChanged(); + //StateHasChanged(); } private void OnSearchComponent(string searchText) { _componentSearchText = searchText ?? ""; - StateHasChanged(); + //StateHasChanged(); } private IEnumerable FilteredLibraries => @@ -375,7 +368,7 @@ _currentComponentLibrary = new(); _isEditingLibrary = false; _libraryModalVisible = true; - StateHasChanged(); + // StateHasChanged(); } private void EditLibrary(string libraryId) @@ -383,7 +376,7 @@ _currentComponentLibrary = _componentLibraries?.FirstOrDefault(x => x.LibraryId == libraryId); _isEditingLibrary = true; _libraryModalVisible = true; - StateHasChanged(); + // StateHasChanged(); } private async Task OnLibraryConfirm(MouseEventArgs e) @@ -429,7 +422,7 @@ } await Message.SuccessAsync("删除成功"); - StateHasChanged(); + // StateHasChanged(); } #endregion @@ -483,7 +476,7 @@ await LoadComponentPartsAsync(); await Message.SuccessAsync("组件删除成功!"); - StateHasChanged(); + // StateHasChanged(); } catch (Exception ex) { diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor index 290bd39..ac4c732 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor @@ -4,7 +4,6 @@ @layout PartsDesignEngineLayout @inject IComponentPartsAppService ComponentPartsAppService -@inject ComponentState> ComponentPartsListState
@@ -84,9 +83,11 @@ HidePagination="true" Style="height:100%;"> [Parameter] public Action Refresh { get; set; } + [PersistentState] + public IList _componentPartsList { get; set; } + IEnumerable selectedRows; - private IList _componentPartsList; private ComponentPartsSchema _componentPartsSchema; private bool _showAddModal = false; @@ -96,10 +97,7 @@ HidePagination="true" Style="height:100%;"> { await base.OnInitializedAsync(); - _componentPartsList = await ComponentPartsListState.GetOrAddAsync(this, async () => - { - return await LoadComponentPartsListAsync(); - }); + _componentPartsList = await LoadComponentPartsListAsync(); } private async Task> LoadComponentPartsListAsync() diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor index 658958d..3ba8d87 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/MyParts.razor @@ -10,7 +10,7 @@ - + @@ -27,9 +27,4 @@ private string LibraryId => GetQueryValue("libId"); private string _tabKey => Tab ?? "apps"; - - private void Refresh() - { - StateHasChanged(); - } } \ No newline at end of file diff --git a/src/DesignEngine/H.LowCode.Workbench/Pages/Ecosystems/AppTemplates.razor b/src/DesignEngine/H.LowCode.Workbench/Pages/Ecosystems/AppTemplates.razor index b491d03..3372b2e 100644 --- a/src/DesignEngine/H.LowCode.Workbench/Pages/Ecosystems/AppTemplates.razor +++ b/src/DesignEngine/H.LowCode.Workbench/Pages/Ecosystems/AppTemplates.razor @@ -2,8 +2,6 @@ @inherits DesignEngineLowCodeComponentBase @layout DesignEngineNavLayout -@inject ComponentState> AppPartsState -
@@ -32,16 +30,14 @@ @code { - private IList _appParts; + [PersistentState] + public IList _appParts { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - _appParts = await AppPartsState.GetOrAddAsync(this, async () => - { - return await LoadAppPartsAsync(1, 50); - }); + _appParts = await LoadAppPartsAsync(1, 50); } private async Task> LoadAppPartsAsync(int pageIndex, int pageSize) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index daa9064..8f7e89e 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -6,53 +6,53 @@ - - + + - - - - + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - + - + - - + + - - - + + + diff --git a/src/H.LowCode.sln b/src/H.LowCode.sln index f856850..ffc66e9 100644 --- a/src/H.LowCode.sln +++ b/src/H.LowCode.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31612.314 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11109.219 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RenderEngine", "RenderEngine", "{89FE3DE3-2E58-4835-A476-CA2E309A1B3F}" EndProject @@ -15,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{8B2D ProjectSection(SolutionItems) = preProject common.props = common.props Directory.Packages.props = Directory.Packages.props + global.json = global.json NuGet.config = NuGet.config nuget.pack.props = nuget.pack.props ..\README.md = ..\README.md diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs index 3ca04ce..d91f0ce 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/FormDataRepository.cs @@ -16,6 +16,10 @@ public class FormDataRepository : IFormDataRepository private readonly IDbContextFactory _dbContextFactory; public bool? IsChangeTrackingEnabled => true; + public string? EntityName { get; set; } + + public string ProviderName => throw new NotImplementedException(); + public FormDataRepository(IDbContextFactory dbContextFactory) { _dbContextFactory = dbContextFactory; diff --git a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs index 307eb42..ca571e2 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.EntityFrameworkCore/DataRepositories/TableDataRepository.cs @@ -12,6 +12,10 @@ public class TableDataRepository : ITableDataRepository private readonly IDataSourceRepository _dataSourceRepository; public bool? IsChangeTrackingEnabled => true; + public string? EntityName { get; set; } + + public string ProviderName => throw new NotImplementedException(); + public TableDataRepository(IDbContextFactory dbContextFactory, IDataSourceRepository dataSourceRepository) { _dbContextFactory = dbContextFactory; diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj index 58f8b6f..1cab00a 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/H.LowCode.RenderEngine.Host.Client.csproj @@ -5,8 +5,7 @@ true Default - true - false + true diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs index 82b367b..9b007b3 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host.Client/RenderEngineHostClientModule.cs @@ -1,4 +1,4 @@ -using H.LowCode.Application.Contracts; +using H.LowCode.Application.Contracts; using H.LowCode.ComponentBase; using H.LowCode.Components.Defaults; using H.LowCode.RenderEngine.Application.Contracts; @@ -22,9 +22,7 @@ namespace H.LowCode.RenderEngine.Host.Client; //Components typeof(LowCodeDefaultComponentModule), //Themes - typeof(AntBlazorThemeModule), - //ComponentBase - typeof(LowCodeComponentBaseModule) + typeof(AntBlazorThemeModule) )] public class RenderEngineHostClientModule : AbpModule { diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/App.razor b/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/App.razor index 85cab2e..abdd1ce 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/App.razor +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/App.razor @@ -14,21 +14,22 @@ - - - - + + + + @* *@ - - + - + + + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/_Imports.razor b/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/_Imports.razor index b4cb54e..4e1abc9 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/_Imports.razor +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/Components/_Imports.razor @@ -9,3 +9,5 @@ @using H.LowCode.RenderEngine.Host @using H.LowCode.RenderEngine.Host.Client @using H.LowCode.RenderEngine.Host.Components +@using AntDesign +@using CssInCSharp \ No newline at end of file diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj b/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj index 7b34c6e..395f632 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/H.LowCode.RenderEngine.Host.csproj @@ -2,6 +2,10 @@ + + true + + diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/Program.cs b/src/RenderEngine/H.LowCode.RenderEngine.Host/Program.cs index 856be7d..c9a533c 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/Program.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/Program.cs @@ -52,6 +52,11 @@ else app.UseHsts(); } +app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); +app.UseHttpsRedirection(); + +app.UseAntiforgery(); + app.UseResponseCompression(); app.UseStaticFiles(new StaticFileOptions { @@ -61,8 +66,6 @@ app.UseStaticFiles(new StaticFileOptions } }); -app.UseHttpsRedirection(); - app.MapStaticAssets(); app.UseRouting(); app.UseAntiforgery(); diff --git a/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs b/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs index 90f76cf..c8074f4 100644 --- a/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs +++ b/src/RenderEngine/H.LowCode.RenderEngine.Host/RenderEngineHostModule.cs @@ -25,9 +25,7 @@ namespace H.LowCode.RenderEngine.Host; //Components typeof(LowCodeDefaultComponentModule), //Themes - typeof(AntBlazorThemeModule), - //ComponentBase - typeof(LowCodeComponentBaseModule) + typeof(AntBlazorThemeModule) )] public class RenderEngineHostModule : AbpModule { diff --git a/src/RenderEngine/H.LowCode.Themes.AntBlazor/Layout/AntBlazorThemeLayout.razor b/src/RenderEngine/H.LowCode.Themes.AntBlazor/Layout/AntBlazorThemeLayout.razor index 9823e54..2bbdfc4 100644 --- a/src/RenderEngine/H.LowCode.Themes.AntBlazor/Layout/AntBlazorThemeLayout.razor +++ b/src/RenderEngine/H.LowCode.Themes.AntBlazor/Layout/AntBlazorThemeLayout.razor @@ -1,8 +1,6 @@ @namespace H.LowCode.Themes.AntBlazor @inherits ThemePartLayoutBase -@inject ComponentState MenuDataState - @code { + + + [PersistentState] public IList _componentLibraries { get; set; } - private IList _componentParts; + [PersistentState] + + public IList _componentParts { get; set; } private string _selectedLibraryId; private ComponentLibrarySchema _selectedLibrary; @@ -323,11 +328,6 @@ if (string.IsNullOrEmpty(_selectedLibraryId)) return; - // _componentParts = await ComponentPartsListState.GetOrAddAsync(typeof(IList), - // async () => - // { - // return await ComponentPartsAppService.GetListAsync(_selectedLibraryId); - // }); _componentParts = await ComponentPartsAppService.GetListAsync(_selectedLibraryId); } @@ -444,17 +444,17 @@ // 根据组件类型跳转到不同的编辑页面 if (componentParts.ComponentType == 1) // 原子组件 { - NavigateTo($"/myparts/component/editorpage/{componentParts.LibraryId}/{componentParts.ComponentId}"); + NavigateTo($"/myparts/component/edit/{componentParts.LibraryId}/{componentParts.ComponentId}"); } else if (componentParts.ComponentType == 2) // 低代码组件 { - NavigateTo($"/myparts/component/customdesigner/{componentParts.ComponentId}"); + NavigateTo($"/myparts/component/designer/{componentParts.ComponentId}"); } } private void EditComponent(ComponentPartsListModel component) { - NavigateTo($"/myparts/component/editorpage/{component.LibraryId}/{component.ComponentId}"); + NavigateTo($"/myparts/component/edit/{component.LibraryId}/{component.ComponentId}"); } private void DesignComponent(ComponentPartsListModel component) diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/CustomComponentPartsDesigner.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsDesignerPage.razor similarity index 98% rename from src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/CustomComponentPartsDesigner.razor rename to src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsDesignerPage.razor index 34a5a51..1443b2c 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/CustomComponentPartsDesigner.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsDesignerPage.razor @@ -1,4 +1,4 @@ -@page "/myparts/component/customdesigner/{PartsId}" +@page "/myparts/component/designer/{PartsId}" @namespace H.LowCode.PartsDesignEngine @inherits DesignEngineLowCodePageComponentBase @layout PartsDesignEngineLayout @@ -174,7 +174,7 @@ else { _isNewComponent = false; // 保存成功后跳转到编辑页面 - NavigateTo($"/myparts/component/customdesigner/{PartsId}?libId={_libraryId}"); + NavigateTo($"/myparts/component/designer/{PartsId}?libId={_libraryId}"); } await Message.SuccessAsync("保存成功!"); diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentPartsEditorPage.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsEditorPage.razor similarity index 98% rename from src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentPartsEditorPage.razor rename to src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsEditorPage.razor index ca34025..7e7dca4 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentPartsEditorPage.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsEditorPage.razor @@ -1,4 +1,4 @@ -@page "/myparts/component/editorpage/{LibraryId}/{ComponentId}" +@page "/myparts/component/edit/{LibraryId}/{ComponentId}" @namespace H.LowCode.PartsDesignEngine @inherits DesignEngineLowCodePageComponentBase @layout PartsDesignEngineLayout diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor index ac4c732..980528e 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/ComponentPartsList.razor @@ -52,7 +52,7 @@ HidePagination="true" Style="height:100%;"> @if (context.ComponentType == 1) { - 编辑 @@ -124,16 +124,14 @@ HidePagination="true" Style="height:100%;"> // 根据组件类型跳转到不同的编辑页面 if (componentParts.ComponentType == 1) // 原子组件 { - NavigateTo($"/myparts/component/editorpage/{componentParts.LibraryId}/{componentParts.ComponentId}"); + NavigateTo($"/myparts/component/edit/{componentParts.LibraryId}/{componentParts.ComponentId}"); } else if (componentParts.ComponentType == 2) // 低代码组件 { - NavigateTo($"/myparts/component/customdesigner/{componentParts.ComponentId}"); + NavigateTo($"/myparts/component/designer/{componentParts.ComponentId}"); } } - - private async Task DeleteAsync(string componentPartsId) { try diff --git a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor index fbf9b65..20781e1 100644 --- a/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor +++ b/src/DesignEngine/H.LowCode.PartsDesignEngine/Pages/ComponentParts/Components/APIDataSourceEditor.razor @@ -6,30 +6,35 @@
- +
+ - +
- +
+ - + +
- +
+ - - +
+
+ - - +
+
+