From 5d0ef88d1d0a2164994e888f2768ca1aabaf1901 Mon Sep 17 00:00:00 2001 From: wq1234wq Date: Thu, 24 Mar 2022 18:58:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BB=93=E6=9D=9F=E6=A0=87?= =?UTF-8?q?=E5=BF=97=E5=A2=9E=E5=8A=A0text=E6=97=A0=E6=B3=95=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E5=BA=93=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=8A=82=E7=82=B9=E8=B0=83=E7=94=A8=E8=80=97=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IoTSharp.TaskAction/DeviceActionExcutor.cs | 2 +- IoTSharp/ClientApp/angular.json | 6 +- IoTSharp/ClientApp/package.json | 5 +- .../flow/flowevents/flowevents.component.ts | 2 +- .../floweventview.component.html | 17 +++--- .../floweventview/floweventview.component.ts | 31 +++++++++- .../ClientApp/src/app/routes/routes.module.ts | 15 ++--- .../dynamicformdesigner.component.ts | 61 ++----------------- IoTSharp/ClientApp/src/typings.d.ts | 2 +- IoTSharp/Controllers/RulesController.cs | 43 ++++++++++++- IoTSharp/FlowRuleEngine/FlowRuleProcessor.cs | 25 ++------ 11 files changed, 100 insertions(+), 109 deletions(-) diff --git a/IoTSharp.TaskAction/DeviceActionExcutor.cs b/IoTSharp.TaskAction/DeviceActionExcutor.cs index c1819276..94ba141d 100644 --- a/IoTSharp.TaskAction/DeviceActionExcutor.cs +++ b/IoTSharp.TaskAction/DeviceActionExcutor.cs @@ -32,7 +32,7 @@ namespace IoTSharp.TaskAction request.RequestFormat = DataFormat.Json; request.AddHeader("Content-Type", contentType); request.AddHeader("cache-control", "no-cache"); - request.AddJsonBody(JsonConvert.SerializeObject(new{ sosType="1", sosContent= input.Input, usingUserId= "" })); + request.AddJsonBody(new{ sosType="1", sosContent= input.Input, usingUserId= "" }); var response = await restclient.ExecutePostAsync(request); if (response.StatusCode == HttpStatusCode.OK) { diff --git a/IoTSharp/ClientApp/angular.json b/IoTSharp/ClientApp/angular.json index 18b42961..23253dd1 100644 --- a/IoTSharp/ClientApp/angular.json +++ b/IoTSharp/ClientApp/angular.json @@ -37,12 +37,12 @@ "output": "/assets/vs/" }], "styles": [ - "node_modules/grapesjs/dist/css/grapes.min.css", + "node_modules/bpmn-js/dist/assets/diagram-js.css", "node_modules/bpmn-js/dist/assets/bpmn-font/css/bpmn.css", "src/styles.less"], - "scripts": ["node_modules/grapesjs/dist/grapes.min.js"], - "allowedCommonJsDependencies": ["@antv/g2", "file-saver", "ajv", "ajv-formats", "date-fns", "jquery", "mousetrap","grapesjs-blocks-basic"] + "scripts": [], + "allowedCommonJsDependencies": ["@antv/g2", "file-saver", "ajv", "ajv-formats", "date-fns", "jquery", "mousetrap"] }, "configurations": { "production": { diff --git a/IoTSharp/ClientApp/package.json b/IoTSharp/ClientApp/package.json index 6333c78f..b9471ea9 100644 --- a/IoTSharp/ClientApp/package.json +++ b/IoTSharp/ClientApp/package.json @@ -65,16 +65,15 @@ "angular-baidu-maps": "^12.0.0", "angular-draggable-droppable": "^5.0.0", "bpmn-js": "^8.1.0", + "echarts": "^5.3.1", "file-saver": "^2.0.5", - "grapesjs": "^0.17.29", - "grapesjs-blocks-basic": "^0.1.8", - "grapesjs-plugin-forms": "^2.0.1", "guid-typescript": "^1.0.9", "monaco-editor": "^0.30.1", "ng-zorro-antd": "^12.0.1", "ngw-json-view": "^3.0.6", "ngx-clipboard": "^14.0.2", "ngx-countdown": "^12.0.1", + "ngx-echarts": "^7.1.0", "ngx-tinymce": "^12.0.0", "ngx-ueditor": "^12.0.0", "rxjs": "~6.6.0", diff --git a/IoTSharp/ClientApp/src/app/routes/flow/flowevents/flowevents.component.ts b/IoTSharp/ClientApp/src/app/routes/flow/flowevents/flowevents.component.ts index 4f734d03..bdd2b517 100644 --- a/IoTSharp/ClientApp/src/app/routes/flow/flowevents/flowevents.component.ts +++ b/IoTSharp/ClientApp/src/app/routes/flow/flowevents/flowevents.component.ts @@ -95,7 +95,7 @@ export class FloweventsComponent implements OnInit { const drawerRef = this.drawerService.create({ nzTitle: title, nzContent: FloweventviewComponent, - nzWidth: width, + nzWidth: 1080, nzMaskClosable: nzMaskClosable, nzContentParams: { event: event, diff --git a/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.html b/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.html index a9a60e1f..0b0710ea 100644 --- a/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.html +++ b/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.html @@ -1,13 +1,11 @@ -
+
-
-
- - + + - - -
+ + +
+
+ +
\ No newline at end of file diff --git a/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.ts b/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.ts index 5ed18a0e..093436f4 100644 --- a/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.ts +++ b/IoTSharp/ClientApp/src/app/routes/flow/floweventview/floweventview.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { _HttpClient } from '@delon/theme'; +import { EChartsOption } from 'echarts'; import { interval, Subscription } from 'rxjs'; import { concat, } from 'rxjs'; import { map } from 'rxjs/operators'; import { appmessage } from '../../common/AppMessage'; @@ -22,6 +23,7 @@ export class FloweventviewComponent implements OnInit, OnDestroy { @ViewChild('flowview', { static: true }) flowview: FlowviewerComponent; current: 0; + option: EChartsOption; constructor(private http: _HttpClient,) { } ngOnDestroy(): void { @@ -39,8 +41,31 @@ export class FloweventviewComponent implements OnInit, OnDestroy { ), this.http.get('api/rules/GetFlowOperations?eventId=' + this.event.eventId).pipe( map((x) => { - if(x.data.length>0){ - this.nodes = x.data; + if(x.data&&x.data.steps.length>0){ + this.nodes = x.data.steps; + this.option = { + // title: { + // text: '' + // }, + tooltip: { + trigger: 'item', + triggerOn: 'mousemove' + }, + series: [ + { + type: 'sankey', + data: x.data.charts.sankey.nodes, + links: x.data.charts.sankey.links, + emphasis: { + focus: 'adjacency' + }, + lineStyle: { + color: 'gradient', + curveness: 0.5 + } + } + ] + }; this.play(); } @@ -53,7 +78,7 @@ export class FloweventviewComponent implements OnInit, OnDestroy { if (this.obs) { this.obs.unsubscribe(); } - this.obs = interval(1000).subscribe(async (x) => { + this.obs = interval(1500).subscribe(async (x) => { var index = x % this.nodes.length; if (index == 0) { await this.flowview.redraw(); diff --git a/IoTSharp/ClientApp/src/app/routes/routes.module.ts b/IoTSharp/ClientApp/src/app/routes/routes.module.ts index 8ddccfb1..6c1f24d9 100644 --- a/IoTSharp/ClientApp/src/app/routes/routes.module.ts +++ b/IoTSharp/ClientApp/src/app/routes/routes.module.ts @@ -75,16 +75,14 @@ import { DevivceshapeComponent } from './device/devicegraph/panels/devivceshape/ import { GatewayshapeComponent } from './device/devicegraph/panels/gatewayshape/gatewayshape.component'; import { PortshapeComponent } from './device/devicegraph/panels/portshape/portshape.component'; import { toolpaneldirective } from './device/devicegraph/panels/toolpaneldirective'; - - +import { NgxEchartsModule } from 'ngx-echarts'; const COMPONENTS: Array> = []; -const Directive: Type[] = [ - fielddirective, - controldirective, - toolpaneldirective]; +const Directive: Type[] = [fielddirective, controldirective, toolpaneldirective]; @NgModule({ - imports: [SharedModule, RouteRoutingModule, G2BarModule, G2GaugeModule, NzIconModule, WidgetsModule, ClipboardModule ], + imports: [SharedModule, RouteRoutingModule, G2BarModule, G2GaugeModule, NzIconModule, WidgetsModule, ClipboardModule, NgxEchartsModule.forRoot({ + echarts: () => import('echarts'), + }),], declarations: [ ...COMPONENTS, @@ -153,8 +151,7 @@ const Directive: Type[] = [ ConnectionedgeComponent, DevivceshapeComponent, GatewayshapeComponent, - PortshapeComponent, - + PortshapeComponent ] }) export class RoutesModule {} diff --git a/IoTSharp/ClientApp/src/app/routes/util/dynamicform/dynamicformdesigner/dynamicformdesigner.component.ts b/IoTSharp/ClientApp/src/app/routes/util/dynamicform/dynamicformdesigner/dynamicformdesigner.component.ts index 82d42569..7abc65d6 100644 --- a/IoTSharp/ClientApp/src/app/routes/util/dynamicform/dynamicformdesigner/dynamicformdesigner.component.ts +++ b/IoTSharp/ClientApp/src/app/routes/util/dynamicform/dynamicformdesigner/dynamicformdesigner.component.ts @@ -1,6 +1,5 @@ import { Component, Injector, OnInit } from '@angular/core'; -import pluginForms from 'grapesjs-plugin-forms'; -import pluginBlocks from 'grapesjs-blocks-basic'; + import { createCustomElement } from '@angular/elements'; import { NzSelectComponent } from 'ng-zorro-antd/select'; import { TextBoxComponent } from '../cps/text-box/text-box.component'; @@ -15,61 +14,11 @@ export class DynamicformdesignerComponent implements OnInit { constructor(private injector: Injector) { } editor; ngOnInit(): void { - this.editor = grapesjs.init({ - container: '#gjs', - showOffsets: 1, - storageManager: false, - plugins: ['form'], - pluginsOpts: { - 'form': {}, - }, - // ... - - }); - //导入布局栏 - pluginBlocks(this.editor, {}); - //导入Form栏 - pluginForms(this.editor, {}); - - - - console.log(customElements.get('nz-select')) - //导入ng-zorro组件 需要安装@angular/elements支持 - if (!customElements.get('nz-select')) { - customElements.define('nz-select', createCustomElement(NzSelectComponent, { injector: this.injector })); - } - - // Input没有专门的Component,再包装一下就行了,AutoComplate也是一样,把属性和事件暴露出来,然后就跟普通Component一样用,difine和add中的名字和你定义的selector一定要保持一致 - if (!customElements.get('app-text-box')) { - customElements.define('app-text-box', createCustomElement(TextBoxComponent, { injector: this.injector })); - } - - - //样式丢了,结构没有问题 - this._initBlock(); + + + } - _initBlock() { - - + - this.editor.BlockManager.add('nz-select', { - label: 'nz-select', - content: ` - - - - - `, - }); - - - this.editor.BlockManager.add('app-text-box', { - label: 'nz-textbox', - content: ` - - - `, - }); - } } diff --git a/IoTSharp/ClientApp/src/typings.d.ts b/IoTSharp/ClientApp/src/typings.d.ts index 32e6e26e..e5e54449 100644 --- a/IoTSharp/ClientApp/src/typings.d.ts +++ b/IoTSharp/ClientApp/src/typings.d.ts @@ -1,4 +1,4 @@ // # 3rd Party Library // If the library doesn't have typings available at `@types/`, // you can still use it by manually adding typings for it -declare var grapesjs: any; + diff --git a/IoTSharp/Controllers/RulesController.cs b/IoTSharp/Controllers/RulesController.cs index 80e6b114..8a168823 100644 --- a/IoTSharp/Controllers/RulesController.cs +++ b/IoTSharp/Controllers/RulesController.cs @@ -1235,13 +1235,50 @@ namespace IoTSharp.Controllers public ApiResult GetFlowOperations(Guid eventId) { var profile = this.GetUserProfile(); - return new ApiResult(ApiCode.Success, "OK", _context.FlowOperations.Where(c => c.BaseEvent.EventId == eventId).ToList().OrderBy(c => c.Step). - ToList() + var _event = _context.BaseEvents.Include(c=>c.FlowRule).SingleOrDefault(c => c.EventId == eventId); + var _operations = _context.FlowOperations.Include(c=>c.Flow).Where(c => c.BaseEvent == _event).ToList(); + + + + var flows = _context.Flows.Where(c => c.FlowRule.RuleId == _event.FlowRule.RuleId); + var sf = flows.Where(c => c.FlowType == "bpmn:SequenceFlow").ToArray(); + var links = new List(); + var nodes = new List(); + foreach (var item in sf) + { + var target = _operations.FirstOrDefault(c => c.Flow.bpmnid == item.TargetId); + var source = _operations.FirstOrDefault(c => c.Flow.bpmnid == item.SourceId); + if (target != null && source != null) + { + + links.Add(new {source= source.Flow.Flowname?? source.bpmnid, target=target.Flow.Flowname ?? target.bpmnid, value= (target.AddDate - source.AddDate).Value.TotalMilliseconds }); + var _sourcename = source.Flow.Flowname ?? source.bpmnid; + var _targetname = target.Flow.Flowname ?? target.bpmnid; + if (nodes.All(c => c != _sourcename)) + { + nodes.Add(_sourcename); + } + if (nodes.All(c => c != _targetname)) + { + nodes.Add(_targetname); + } + } + } + var steps = _operations.OrderBy(c => c.Step). + ToList() .GroupBy(c => c.Step).Select(c => new { Step = c.Key, Nodes = c - }).ToList()); + }).ToList(); + return new ApiResult(ApiCode.Success, "OK", new + { + steps, + charts=new + { + sankey=new { links, nodes= nodes.Select(c=>new { name=c}).ToList() } + } + }); } [HttpGet("[action]")] diff --git a/IoTSharp/FlowRuleEngine/FlowRuleProcessor.cs b/IoTSharp/FlowRuleEngine/FlowRuleProcessor.cs index b1a460fe..28cbd777 100644 --- a/IoTSharp/FlowRuleEngine/FlowRuleProcessor.cs +++ b/IoTSharp/FlowRuleEngine/FlowRuleProcessor.cs @@ -180,7 +180,7 @@ namespace IoTSharp.FlowRuleEngine return; } - var flow = _allFlows.FirstOrDefault(c => c.bpmnid == peroperation.Flow.TargetId); + var flow = _allFlows.FirstOrDefault(c => c.bpmnid == peroperation.Flow.TargetId && c.FlowType != "label"); switch (flow.FlowType) { case "bpmn:SequenceFlow": @@ -456,25 +456,8 @@ namespace IoTSharp.FlowRuleEngine case "bpmn:EndEvent": - var end = _allflowoperation.FirstOrDefault(c => c.bpmnid == flow.bpmnid); - - if (end != null) - { - end.BuildFlowOperation(peroperation, flow); - end.bpmnid = flow.bpmnid; - end.AddDate = DateTime.Now; - end.FlowRule = peroperation.BaseEvent.FlowRule; - end.Flow = flow; - - end.Data = JsonConvert.SerializeObject(data); - end.NodeStatus = 1; - end.OperationDesc = "处理完成"; - end.Step = 1 + _allflowoperation.Max(c => c.Step); - end.BaseEvent = peroperation.BaseEvent; - } - else - { - end = new FlowOperation(); + + var end = new FlowOperation(); end.BuildFlowOperation(peroperation, flow); end.OperationId = Guid.NewGuid(); end.bpmnid = flow.bpmnid; @@ -487,7 +470,7 @@ namespace IoTSharp.FlowRuleEngine end.Step = 1 + _allflowoperation.Max(c => c.Step); end.BaseEvent = peroperation.BaseEvent; _allflowoperation.Add(end); - } + _logger.Log(LogLevel.Warning, "规则链执行完成"); break; -- GitLab