From 9ec8ef05d4347402c14ab47af23e62bb74989d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Fri, 22 Jan 2021 15:32:09 +0800 Subject: [PATCH 1/7] 1.0.11.20210122 --- src/app/working-area/working-area.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index 43a2acd..adaa4d7 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -148,7 +148,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。 * Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号®。 */ - public VERSION = '1.0.10.20210118_beta'; + public VERSION = '1.0.11.20210122_beta'; /** * 数据初始化 */ From e2df63a0f31a04de8cdef60dd87a92e7573222f4 Mon Sep 17 00:00:00 2001 From: chenjingyu Date: Sat, 23 Jan 2021 14:31:34 +0800 Subject: [PATCH 2/7] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wait-examineer.component.html | 3 +- .../wait-examineer.component.ts | 119 +++++++++++----- .../entry-plan/entry-plan.component.html | 9 ++ .../entry-plan/entry-plan.component.ts | 3 + .../meet-plan/meet-plan.component.ts | 4 +- .../onetwo-entry-plan.component.ts | 6 +- .../pass-plan/pass-plan.component.html | 132 +----------------- .../pass-plan/pass-plan.component.ts | 6 +- .../type-plan/type-plan.component.ts | 8 +- 9 files changed, 117 insertions(+), 173 deletions(-) diff --git a/src/app/plan-audit/wait-examineer/wait-examineer.component.html b/src/app/plan-audit/wait-examineer/wait-examineer.component.html index c7961ea..fccb149 100644 --- a/src/app/plan-audit/wait-examineer/wait-examineer.component.html +++ b/src/app/plan-audit/wait-examineer/wait-examineer.component.html @@ -56,7 +56,8 @@ diff --git a/src/app/plan-audit/wait-examineer/wait-examineer.component.ts b/src/app/plan-audit/wait-examineer/wait-examineer.component.ts index a444aff..d7e833a 100644 --- a/src/app/plan-audit/wait-examineer/wait-examineer.component.ts +++ b/src/app/plan-audit/wait-examineer/wait-examineer.component.ts @@ -4,7 +4,7 @@ * @Author: sueRimn * @Date: 2020-12-25 16:13:50 * @LastEditors: sueRimn - * @LastEditTime: 2021-01-21 11:17:39 + * @LastEditTime: 2021-01-23 14:16:10 */ import { Component, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; @@ -91,6 +91,7 @@ export class WaitExamineerComponent implements OnInit { checked//是否选中 chuorzhong//判断初审还是终审 radioid//选中的id + shenheTable=[]//选中要审核的对象 //获取表格数据 getAlltabledate(){ @@ -132,11 +133,21 @@ export class WaitExamineerComponent implements OnInit { this.getAlltabledate() } //radio点击事件 - radioClick(item){ + radioClick(e,item){ //e.target.parentElement.bgColor='#2196F3' - console.log(item) - this.chuorzhong=item.verifyState - this.radioid=item.itemId + //console.log(e,item) + if(e.checked){ + this.shenheTable.push(item) + } + else{ + for(var i=0;i{ + this.snackBar.open('操作成功!','确定',config); + this.getAlltabledate() + }) + }else if(this.shenheTable[0].verifyState==3){ + this.http.put(`/api/PlanAudits/${this.radioid}`,{auditStatus:2}).subscribe(data=>{ + this.snackBar.open('操作成功!','确定',config); + this.getAlltabledate() + }) + } + } + else{ + for(var i=0;i{ + this.snackBar.open('操作成功!','确定',config); + this.getAlltabledate() + }) } - if(this.chuorzhong==0){ - this.http.put(`/api/PlanAudits/${this.radioid}/First`,{auditStatus:16}).subscribe(data=>{ + this.shenheTable=[] + } + //拒绝操作 + refuse(){ + const config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + var refuseList=[] + if(this.shenheTable.length==0){ + this.snackBar.open('请选择要审核的预案!','确定',config); + } + else if(this.shenheTable.length==1){ + if(this.shenheTable[0].verifyState==0){ + this.http.put(`/api/PlanAudits/${this.shenheTable[0].itemId}/First`,{auditStatus:32}).subscribe(data=>{ + this.snackBar.open('操作成功!','确定',config); + this.getAlltabledate() + }) + }else if(this.shenheTable[0].verifyState==3){ + this.http.put(`/api/PlanAudits/${this.radioid}`,{auditStatus:4}).subscribe(data=>{ this.snackBar.open('操作成功!','确定',config); - this.checked='' this.getAlltabledate() }) + } } - else if(this.chuorzhong==3){ - this.http.put(`/api/PlanAudits/${this.radioid}`,{auditStatus:2}).subscribe(data=>{ + else{ + for(var i=0;i{ this.snackBar.open('操作成功!','确定',config); - this.checked='' this.getAlltabledate() }) } - this.chuorzhong=undefined - } - //拒绝操作 - refuse(){ - const config = new MatSnackBarConfig(); - config.verticalPosition = 'top'; - config.duration = 3000 - if(this.chuorzhong==2){ - this.snackBar.open('审核未通过,请修改后再来审核!','确定',config); - } -if(this.chuorzhong==0){ - this.http.put(`/api/PlanAudits/${this.radioid}/First`,{auditStatus:32}).subscribe(data=>{ - this.snackBar.open('操作成功!','确定',config); - this.checked='' - this.getAlltabledate() - }) -} -else if(this.chuorzhong==3){ -this.http.put(`/api/PlanAudits/${this.radioid}`,{auditStatus:4}).subscribe(data=>{ - this.snackBar.open('操作成功!','确定',config); - this.checked='' - this.getAlltabledate() -}) -} -this.chuorzhong=undefined + this.shenheTable=[] + + } //分数饼状图 diff --git a/src/app/plan-management/entry-plan/entry-plan.component.html b/src/app/plan-management/entry-plan/entry-plan.component.html index fcc41f3..67ad0fb 100644 --- a/src/app/plan-management/entry-plan/entry-plan.component.html +++ b/src/app/plan-management/entry-plan/entry-plan.component.html @@ -94,6 +94,15 @@ +
+ + + + 有预案 + 无预案 + + +
diff --git a/src/app/plan-management/entry-plan/entry-plan.component.ts b/src/app/plan-management/entry-plan/entry-plan.component.ts index feb6b5d..807af6f 100644 --- a/src/app/plan-management/entry-plan/entry-plan.component.ts +++ b/src/app/plan-management/entry-plan/entry-plan.component.ts @@ -53,6 +53,7 @@ export class EntryPlanComponent implements OnInit { organizationName:any //当前单位组织机构名称 preparelevels:any integritySort:any //完整度排序 + haveyuan//有无预案 colorRgb(sColor){ var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; var sColor = sColor.toLowerCase(); @@ -304,6 +305,7 @@ export class EntryPlanComponent implements OnInit { PageSize: this.pageSizeOptions[0], Sort: this.integritySort ? 'integrityscore' : '', SortType: this.integritySort || '', + HasPlanComponents:this.haveyuan||'' } this.http.get("/api/Plans",{params:paramsdata}).subscribe((data:any)=>{ @@ -349,6 +351,7 @@ export class EntryPlanComponent implements OnInit { this.preparelevel = '' this.integritySort = '' this.plcheck = false + this.haveyuan='' //重新获取初始化列表 // console.log(this.pageEvent) this.pageEvent.pageIndex = 0 diff --git a/src/app/plan-management/meet-plan/meet-plan.component.ts b/src/app/plan-management/meet-plan/meet-plan.component.ts index 8ff1a69..cc7d5f8 100644 --- a/src/app/plan-management/meet-plan/meet-plan.component.ts +++ b/src/app/plan-management/meet-plan/meet-plan.component.ts @@ -87,8 +87,8 @@ export class MeetPlanComponent implements OnInit { PlanType:reservePlanType||'', CreatorName:this.addname||'', AuditStatus:this.unitstate|| '', - QueryStartTime:this.addtime||'', - QueryEndTime:this.endtime||'', + CreationTimeRangeStart:this.addtime||'', + CreationTimeRangeEnd:this.endtime||'', PlanLevel:this.projectlevel||'', HasChildrenPlanLevel:this.plcheck||'', PageNumber: this.PageNumber || '1', diff --git a/src/app/plan-management/onetwo-entry-plan/onetwo-entry-plan.component.ts b/src/app/plan-management/onetwo-entry-plan/onetwo-entry-plan.component.ts index 693ad3a..01ff599 100644 --- a/src/app/plan-management/onetwo-entry-plan/onetwo-entry-plan.component.ts +++ b/src/app/plan-management/onetwo-entry-plan/onetwo-entry-plan.component.ts @@ -4,7 +4,7 @@ * @Author: sueRimn * @Date: 2020-12-24 14:15:10 * @LastEditors: sueRimn - * @LastEditTime: 2021-01-21 14:32:43 + * @LastEditTime: 2021-01-22 09:17:40 */ import { Component, OnInit, ViewChild, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http' @@ -98,8 +98,8 @@ export class OnetwoEntryPlanComponent implements OnInit { PlanType:reservePlanType||'', CreatorName:this.addname||'', AuditStatus:this.unitstate|| '', - QueryStartTime:this.addtime||'', - QueryEndTime:this.endtime||'', + CreationTimeRangeStart:this.addtime||'', + CreationTimeRangeEnd:this.endtime||'', PlanLevel:this.projectlevel||'', HasChildrenPlanLevel:this.plcheck||'', PageNumber: this.PageNumber || '1', diff --git a/src/app/plan-management/pass-plan/pass-plan.component.html b/src/app/plan-management/pass-plan/pass-plan.component.html index 8c34ed6..6c0411c 100644 --- a/src/app/plan-management/pass-plan/pass-plan.component.html +++ b/src/app/plan-management/pass-plan/pass-plan.component.html @@ -83,16 +83,6 @@
-
- - - - - 🠊 - - - -
@@ -114,126 +104,16 @@
- + + + + + diff --git a/src/app/plan-management/pass-plan/pass-plan.component.ts b/src/app/plan-management/pass-plan/pass-plan.component.ts index 0f0334d..9096503 100644 --- a/src/app/plan-management/pass-plan/pass-plan.component.ts +++ b/src/app/plan-management/pass-plan/pass-plan.component.ts @@ -42,7 +42,7 @@ export class PassPlanComponent implements OnInit { pageSizeOptions: number[] = [10] //设置每页条数 PageNumber:any; //第几页 - displayedColumns: string[] = ['planname', 'addpeople','addtime','plantype','auditStatus','openRange','projectlevel','operation']; + displayedColumns: string[] = ['planname', 'addpeople','level','addtime','plantype','auditStatus','openRange','projectlevel','operation']; allorganizations:any //所有组织机构 allunittype:any //所有单位类型 tabledataSource:any //表格数据 @@ -97,6 +97,8 @@ export class PassPlanComponent implements OnInit { AuditStatus:'', //审核状态 PlanLevel: this.preparelevel || '', HasChildrenPlanLevel: this.plcheck || '', + CreationTimeRangeStart:this.addtime||'', + CreationTimeRangeEnd:this.endtime||'', PageNumber: this.PageNumber || '1', PageSize: this.pageSizeOptions[0], Sort: '' @@ -342,6 +344,8 @@ export class PassPlanComponent implements OnInit { this.unittype = '' this.reservePlanType = '' this.preparelevel = '' + this.addtime='' + this.endtime='' this.plcheck = false //重新获取初始化列表 this.pageEvent.pageIndex = 0 diff --git a/src/app/plan-management/type-plan/type-plan.component.ts b/src/app/plan-management/type-plan/type-plan.component.ts index 0a1163c..91227db 100644 --- a/src/app/plan-management/type-plan/type-plan.component.ts +++ b/src/app/plan-management/type-plan/type-plan.component.ts @@ -4,7 +4,7 @@ * @Author: sueRimn * @Date: 2021-01-06 09:47:43 * @LastEditors: sueRimn - * @LastEditTime: 2021-01-21 14:15:40 + * @LastEditTime: 2021-01-23 09:45:17 */ import { Component, OnInit, ViewChild, Inject } from '@angular/core'; import { HttpClient } from '@angular/common/http' @@ -86,8 +86,8 @@ export class TypePlanComponent implements OnInit { planCategories:8, CreatorName:this.addname||'', AuditStatus:this.unitstate|| '', - QueryStartTime:this.addtime||'', - QueryEndTime:this.endtime||'', + CreationTimeRangeStart:this.addtime||'', + CreationTimeRangeEnd:this.endtime||'', PlanLevel:this.projectlevel||'', HasChildrenPlanLevel:this.plcheck||'', PageNumber: this.PageNumber || '1', @@ -371,6 +371,7 @@ export class newunitType{ PlanCategory:8, PlanLevel:PlanLevel, PlanMode:1, + PlanType:8, attachmentUrls:[`${this.objectName}`] } this.http.post("/api/PlanComponentsMajor",body).subscribe((data:any)=>{ @@ -461,6 +462,7 @@ export class newunitType{ PlanCategory:8, PlanLevel:PlanLevel, PlanMode:1, + PlanType:8, attachmentUrls:[`${this.objectName}`] } From 82a7aa33408f75d9c9aa626091649dbbfbc3aee7 Mon Sep 17 00:00:00 2001 From: SHAOJIAHAO <55341701@qq.com> Date: Sat, 23 Jan 2021 17:25:25 +0800 Subject: [PATCH 3/7] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=B6=88=E9=98=B2=E5=8A=9B=E9=87=8F=E9=87=87=E9=9B=86=20?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=81=94=E5=8A=A8=E5=8A=9B=E9=87=8F=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E9=87=87=E9=9B=86=E5=8A=9F=E8=83=BD=20=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E7=BC=96=E7=BB=87=E5=B7=A5=E5=8F=8A=E6=B6=88=E9=98=B2?= =?UTF-8?q?=E8=A6=81=E7=B4=A0icon=E7=82=B9=E5=87=BBbug=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84gis=E7=AE=A1=E7=90=86=E6=B0=B4=E6=BA=90=E5=92=8C?= =?UTF-8?q?=E5=8D=95=E4=BD=8D=E6=A0=87=E7=82=B9=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-collection/data-collection.module.ts | 4 +- .../linkage-forces/addLinkageForce.html | 15 + .../linkage-forces.component.html | 258 +++++- .../linkage-forces.component.scss | 518 ++++++++++++ .../linkage-forces.component.ts | 760 +++++++++++++++++- .../linkage-forces/viewdetails.html | 1 + .../water-collection.component.html | 2 +- .../water-collection.component.ts | 2 +- .../gis-labeling/gis-labeling.component.html | 2 + .../gis-labeling/gis-labeling.component.ts | 504 ++++++------ .../collection-tools.component.html | 44 +- .../collection-tools.component.ts | 2 + .../collection-tools.component.html | 44 +- .../collection-tools.component.scss | 1 + .../collection-tools.component.ts | 13 +- src/app/ui/collection-tools/save.ts | 16 +- src/app/ui/collection-tools/saveTwo.html | 2 +- .../working-area/working-area.component.ts | 2 +- src/assets/images/其他.png | Bin 791 -> 2280 bytes src/assets/images/古建筑.png | Bin 904 -> 2298 bytes src/assets/images/轨道交通.png | Bin 1161 -> 2610 bytes src/assets/linkageForces/交通.png | Bin 0 -> 737 bytes src/assets/linkageForces/住建.png | Bin 0 -> 786 bytes src/assets/linkageForces/公安.png | Bin 0 -> 943 bytes src/assets/linkageForces/医疗.png | Bin 0 -> 839 bytes src/assets/linkageForces/安监.png | Bin 0 -> 916 bytes src/assets/linkageForces/市政.png | Bin 0 -> 789 bytes src/assets/linkageForces/应急管理.png | Bin 0 -> 901 bytes src/assets/linkageForces/民政.png | Bin 0 -> 827 bytes src/assets/linkageForces/气象局.png | Bin 0 -> 901 bytes src/assets/linkageForces/水利.png | Bin 0 -> 788 bytes src/assets/linkageForces/海事.png | Bin 0 -> 960 bytes src/assets/linkageForces/燃气局.png | Bin 0 -> 862 bytes src/assets/linkageForces/环保局.png | Bin 0 -> 1068 bytes src/assets/linkageForces/电力局.png | Bin 0 -> 920 bytes src/assets/linkageForces/通信.png | Bin 0 -> 561 bytes src/styles.scss | 12 +- 37 files changed, 1907 insertions(+), 295 deletions(-) create mode 100644 src/app/data-collection/linkage-forces/addLinkageForce.html create mode 100644 src/app/data-collection/linkage-forces/viewdetails.html create mode 100644 src/assets/linkageForces/交通.png create mode 100644 src/assets/linkageForces/住建.png create mode 100644 src/assets/linkageForces/公安.png create mode 100644 src/assets/linkageForces/医疗.png create mode 100644 src/assets/linkageForces/安监.png create mode 100644 src/assets/linkageForces/市政.png create mode 100644 src/assets/linkageForces/应急管理.png create mode 100644 src/assets/linkageForces/民政.png create mode 100644 src/assets/linkageForces/气象局.png create mode 100644 src/assets/linkageForces/水利.png create mode 100644 src/assets/linkageForces/海事.png create mode 100644 src/assets/linkageForces/燃气局.png create mode 100644 src/assets/linkageForces/环保局.png create mode 100644 src/assets/linkageForces/电力局.png create mode 100644 src/assets/linkageForces/通信.png diff --git a/src/app/data-collection/data-collection.module.ts b/src/app/data-collection/data-collection.module.ts index ad38bdf..50060c8 100644 --- a/src/app/data-collection/data-collection.module.ts +++ b/src/app/data-collection/data-collection.module.ts @@ -45,11 +45,11 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DataCollectionRoutingModule } from './data-collection.routing'; import { AddWater, WaterCollectionComponent } from './water-collection/water-collection.component'; import { AddFireForce, FireForceComponent, ViewDetails } from './fire-force/fire-force.component'; -import { LinkageForcesComponent } from './linkage-forces/linkage-forces.component'; +import { AddLinkageForce, LinkageForcesComponent, ViewDetails2 } from './linkage-forces/linkage-forces.component'; import { NzTreeModule } from 'ng-zorro-antd/tree'; @NgModule({ - declarations: [WaterCollectionComponent, FireForceComponent, LinkageForcesComponent,AddWater,AddFireForce,ViewDetails], + declarations: [WaterCollectionComponent, FireForceComponent, LinkageForcesComponent,AddWater,AddFireForce,ViewDetails,AddLinkageForce,ViewDetails2], imports: [ CommonModule, A11yModule, diff --git a/src/app/data-collection/linkage-forces/addLinkageForce.html b/src/app/data-collection/linkage-forces/addLinkageForce.html new file mode 100644 index 0000000..4ba38db --- /dev/null +++ b/src/app/data-collection/linkage-forces/addLinkageForce.html @@ -0,0 +1,15 @@ +
+
+ 新增联动力量 +
+
+
+ + {{item.name}} +
+
+
+ + +
+
\ No newline at end of file diff --git a/src/app/data-collection/linkage-forces/linkage-forces.component.html b/src/app/data-collection/linkage-forces/linkage-forces.component.html index 413184e..abc51c7 100644 --- a/src/app/data-collection/linkage-forces/linkage-forces.component.html +++ b/src/app/data-collection/linkage-forces/linkage-forces.component.html @@ -1,8 +1,260 @@ -
+
+
+
+
+ 列表过滤 +
+
+ + +
+
+ +
+
+
+
+ 消防队 + 完整度 +
+
+
    +
  • +
    {{item.name}}
    +
    + + {{accMul(item.integrityScore.toFixed(3),100,1)}}% + +
    +
    +
    +
    highlight_off
    +
  • +
+
+
+ +
+
-
- +
+
+ +
+ + + + {{item.name}} + + +
+ +
+
+ +
+
+
+ +
+
+
+ + 请等待... +
+
+ + 上传中...({{progressBarValue}}%) + +
+
+ + 下载中...({{progressBarValue}}%) +
+
+
+
+ 详情 +
+
+ 相关资料 +
+
+
+
+ + + + +
+ + save保存 + open_in_browser提交审核 +
+
+ +
+
+

基本信息

+ + + + * + 类型: + + + + + + * + 名称: + + + + + + 单位联系电话: + + + + + + 单位传真: + + + + + + 备注: + + + + +

位置信息

+ + + + 行政区: + + + + 地址: + + + + + + 经度: + + + + 纬度: + + + + + + +

联系人

+ + + + 联系人: + + + + + + 职务: + + + + + + 电话: + + + + +

应急信息

+ + + + 服务内容: + + + + + + 资源说明: + + + + + +
+
+ +
+
+ highlight_off +
+ + + + + +
+ {{item.fileName}} + + +
+
+
+
+ + \ No newline at end of file diff --git a/src/app/data-collection/linkage-forces/linkage-forces.component.scss b/src/app/data-collection/linkage-forces/linkage-forces.component.scss index ef03c8d..9fbcf0f 100644 --- a/src/app/data-collection/linkage-forces/linkage-forces.component.scss +++ b/src/app/data-collection/linkage-forces/linkage-forces.component.scss @@ -5,14 +5,532 @@ display: flex; box-sizing: border-box; padding: 10px; + font-size: 16px; + font-family: Source Han Sans CN; + font-weight: 400; + color: #000000; } .listbox{ width: 400px; height: 100%; background-color: #fff; + display: flex; + flex-direction: column; + .topbox{ + max-height: 200px; + box-sizing: border-box; + padding: 10px 22px 22px; + .add{ + height: 36px; + line-height: 36px; + display: flex; + justify-content: space-between; + } + .searchbox{ + .inputbox{ + width: 100%; + height: 36px; + font-size: 14px; + line-height: 36px; + margin: 10px 0; + display: flex; + span{ + margin-right: 5px; + } + select,input{ + flex: 1; + background-color: #F2F4F6; + border: 0; + border-radius: 5px; + box-sizing: border-box; + padding:0 8px; + + } + .gray{ + color: gray; + } + // input::-moz-placeholder { + // color: rgba(90, 83, 83, 0.89); + // opacity: 1; + // } + // input:-ms-input-placeholder { + // color: rgba(90, 83, 83, 0.89);; + // } + // input::-webkit-input-placeholder { + // color: rgba(90, 83, 83, 0.89);; + // } + } + } + } + .contantbox{ + flex: 1; + overflow-y: auto; + display: flex; + flex-direction: column; + .title{ + display: flex; + justify-content: space-between; + width: 100%; + box-sizing: border-box; + padding: 0 33px 0 22px; + height: 36px; + line-height: 36px; + span{ + font-size: 14px; + font-weight: 500; + } + } + .linkageForceList{ + flex: 1; + overflow-y: auto; + li{ + cursor: pointer; + width: 100%; + height: 36px; + line-height: 36px; + display: flex; + align-items: center; + font-size: 14px; + div{ + float: left; + box-sizing: border-box; + } + .name{ + text-align: left; + width: 60%; + padding-left: 22px; + white-space:nowrap; + overflow:hidden; + text-overflow:ellipsis; + } + .integrity{ + height: 58%; + width: 32%; + position: relative; + background-color: #F2F4F6; + .integrityNum{ + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + color: black; + font-size: 13px; + cursor: default; + } + .integrityColorDiv{ + height: 100%; + } + } + .deletebtn{ + flex: 1; + text-align: center; + mat-icon{ + width: 20px; + height: 20px; + cursor: pointer; + font-size: 20px; + vertical-align: text-top; + color: rgba(49, 46, 46, 0.144); + } + mat-icon:hover{ + color: #000; + } + } + } + li:hover{ + background-color: #b3d3ee; + } + .selectedLi{ + background-color: #b3d3ee; + } + } + .paginator{ + height: 56px; + width: 100%; + } + } } .mapbox{ flex: 1; margin-left: 10px; background-color: #fff; + display: flex; + overflow: hidden; + flex-direction: column; + .mapcheckbox,.swiper-container{ + width: 100%; + height: 50px; + .swiper-wrapper{ + flex: 1; + display: flex; + height: 50px; + line-height: 50px; + } + mat-checkbox{ + font-size: 15px; + span{ + display: flex; + justify-content: center; + align-items: center; + img{ + margin-right: 3px; + } + } + + } + mat-checkbox:nth-child(1){ + margin-left: 20px; + } + + } + #map{ + flex: 1; + position: relative; + #container{ + width: 100%; + height: 100%; + } + .gistopbox{ + position: absolute; + box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16); + border-radius: 5px; + top: 3px; + width: 30%; + height:40px; + background: #FFFFFF; + display: flex; + align-items: center; + cursor: default;; + .inputBox{ + width: 100%; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + font-size: 14px; + .positionInput{ + border: 0; + border-radius: 6px; + width: 80%; + height: 28px; + background: #F2F2F2; + margin-left: 8px; + box-sizing: border-box; + padding-left: 10px; + } + } + + } + .hidden{ + opacity: 0; + z-index: -1; + } + .show{ + opacity: 1; + z-index: 1; + } + } + .detailsbox{ + width: 100%; + height:500px; + position: relative; + .tabsbox{ + width: 100%; + height: 40px; + overflow: hidden; + overflow-x: auto; + line-height: 40px; + display: flex; + justify-content: space-between; + font-size: 15px; + .tabs{ + div{ + float: left; + width: 120px; + text-align: center; + cursor: pointer; + color: #000000; + opacity: 0.4; + border-right: 1px solid #F2F4F6; + } + .selectedBtn{ + background-color: #2196F3; + color: #fff; + opacity: 1; + } + } + .btnbox{ + display: flex; + align-items: center; + .uploadAttachment{ + display: inline-block; + margin-right: 20px; + width: 120px; + text-align: center; + height: 28px; + line-height: 28px; + position: relative; + button{ + width: 100%; + height: 28px; + line-height: 28px; + mat-icon{ + transform: rotate(25deg); + font-size: 20px; + width: 20px; + height: 20px; + } + } + .a-upload{ + display: inline-block; + position: absolute; + left: 0; + top: 0; + display: inline-block; + width: 100%; + height: 100%; + opacity: 0; + input{ + width: 100%; + height: 100%; + cursor: pointer; + } + } + } + span{ + display: inline-block; + cursor: pointer; + color: #2196F3; + mat-icon{ + vertical-align: text-top; + font-size: 20px; + width: 20px; + height: 20px; + } + } + span:hover{ + text-decoration: underline; + } + .submitAudit{ + margin: 0 30px; + } + + } + } + .contant{ + width: 100%; + height:460px; + overflow-y: auto; + p{ + color: #2196F3; + background-color: #F2F4F6; + height: 33px; + line-height: 33px; + box-sizing: border-box; + padding-left: 20px; + font-size: 15px; + } + span{ + font-size: 15px; + } + input,select{ + height: 30px; + line-height: 30px; + box-sizing: border-box; + padding: 0 12px; + width: 60%; + margin-left: 5px; + border: 1px solid #EBEBEB; + border-radius: 5px; + } + textarea{ + width: 89%; + margin-left: 5px; + height: 85%; + border: 1px solid #EBEBEB; + border-radius: 5px; + } + .longinput{ + width: 74%; + } + .unitDiv{ + width: 60%; + position: relative; + input,select{ + width: 100%; + box-sizing: border-box; + padding-right: 50px; + } + .unit{ + position: absolute; + right: 13px; + top: 4px; + color: #000000; + opacity: 0.4; + } + } + .smallwidth{ + width: 30%; + } + // 相关资料 + .fileDivBox{ + position: relative; + float: left; + border: 1px solid #EBEBEB; + width: 160px; + height: 162px; + box-sizing: border-box; + padding: 16px 16px 0; + display: flex; + flex-direction: column; + margin: 12px; + align-items: center; + cursor: pointer; + .imgbox{ + width: 134px; + height: 110px; + display: flex; + justify-content: center; + align-items: center; + .thumbnailImg{ + width: 134px; + height: 110px; + } + } + + span{ + width: 100%; + text-align: center; + margin-top: 5px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + color: gray; + font-size: 14px; + } + .deleteFile{ + position: absolute; + right: 0; + top: 0; + width: 18px; + height: 18px; + font-size: 18px; + display: none; + } + .btn{ + position: absolute; + height: 30px; + line-height: 30px; + font-size: 14px; + display: none; + } + .btn1{ + top: 37px; + } + .btn2{ + top: 78px; + } + } + .fileDivBox:hover{ + border: 1px solid #000; + .deleteFile{ + display: block; + + } + .deleteFile:hover{ + color: red; + } + .btn{ + display: block; + } + } + } + .masklayer{ + position: absolute; + left: 0; + top: 0; + z-index: 2000; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.2); + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + span{ + font-size: 14px; + margin-top: 5px; + } + .progressbar{ + width: 15%; + } + .cancelbtn{ + height: 32px; + line-height: 32px; + font-size: 14px; + margin-top: 12px; + } + } + } +} + + +.addLinkageForceBox{ + width: 530px; + height: 262px; + display: flex; + flex-direction: column; + .topbox{ + width: 100%; + height: 40px; + line-height: 40px; + background-color: #2196F3; + text-align: center; + color: #FFFFFF; + font-size: 15px; + } + .contant{ + flex: 1; + box-sizing: border-box; + padding:20px 30px; + + div{ + width:86px; + margin: 3px; + height: 36px; + float: left; + line-height: 36px; + text-align: center; + background-color: #F2F4F6; + font-size: 14px; + cursor: pointer; + border: 1px solid #fff; + border-radius: 4px; + display: flex; + justify-content: center; + align-items: center; + img{ + margin-right: 3px; + } + } + .selectedDiv{ + background-color: #fff; + border: 1px solid #2196F3; + } + } + .btnbox{ + width: 100%; + height: 50px; + box-sizing: border-box; + padding: 0px 30px; + display: flex; + align-items: flex-start;; + justify-content: center; + button{ + width: 80px; + height: 36px; + line-height: 36px; + margin: 0 20px; + } + } } \ No newline at end of file diff --git a/src/app/data-collection/linkage-forces/linkage-forces.component.ts b/src/app/data-collection/linkage-forces/linkage-forces.component.ts index cbddc20..919b746 100644 --- a/src/app/data-collection/linkage-forces/linkage-forces.component.ts +++ b/src/app/data-collection/linkage-forces/linkage-forces.component.ts @@ -1,5 +1,16 @@ +import { FlatTreeControl } from '@angular/cdk/tree'; +import { HttpClient } from '@angular/common/http'; +import { Inject, Renderer2 } from '@angular/core'; +import { ElementRef } from '@angular/core'; import { Component, OnInit } from '@angular/core'; - +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar'; +import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; +import { NzTreeNode } from 'ng-zorro-antd/tree'; +import { TreeService } from 'src/app/http-interceptors/tree.service'; +import Viewer from 'viewerjs' +import Swiper from 'swiper'; +declare var AMap: any; @Component({ selector: 'app-linkage-forces', templateUrl: './linkage-forces.component.html', @@ -7,9 +18,754 @@ import { Component, OnInit } from '@angular/core'; }) export class LinkageForcesComponent implements OnInit { - constructor() { } + constructor(private tree: TreeService,public snackBar: MatSnackBar,private http:HttpClient,private elementRef: ElementRef,public renderer2: Renderer2,public dialog: MatDialog) { } + + isCheckedOfSearchDiv:boolean = true//列表过滤滑块 + slideChange(e){ + this.isCheckedOfSearchDiv = e.checked + } + //搜索表单 + searchForm:any = { + name:'', + integrityNum:'' + } + listIntegrityNum:any[] = [ + {id:-1,name:'全部'}, + {id:0,name:'<=50%'}, + {id:1,name:'50%-60%'}, + {id:2,name:'60%-70%'}, + {id:3,name:'70%-80%'}, + {id:4,name:'80%-90%'}, + {id:5,name:'90%-100%'} + ] + checkBoxList:any[] = [ + {id:0,name:'安监',imgUrl:'/assets/linkageForces/安监.png'}, + {id:1,name:'电力局',imgUrl:'/assets/linkageForces/电力局.png'}, + {id:2,name:'公安',imgUrl:'/assets/linkageForces/公安.png'}, + {id:3,name:'海事',imgUrl:'/assets/linkageForces/海事.png'}, + {id:4,name:'环保局',imgUrl:'/assets/linkageForces/环保局.png'}, + {id:5,name:'交通',imgUrl:'/assets/linkageForces/交通.png'}, + {id:6,name:'民政',imgUrl:'/assets/linkageForces/民政.png'}, + {id:7,name:'气象局',imgUrl:'/assets/linkageForces/气象局.png'}, + {id:8,name:'燃气局',imgUrl:'/assets/linkageForces/燃气局.png'}, + {id:9,name:'市政',imgUrl:'/assets/linkageForces/市政.png'}, + {id:10,name:'水利',imgUrl:'/assets/linkageForces/水利.png'}, + {id:11,name:'通信',imgUrl:'/assets/linkageForces/通信.png'}, + {id:12,name:'医疗',imgUrl:'/assets/linkageForces/医疗.png'}, + {id:13,name:'应急管理',imgUrl:'/assets/linkageForces/应急管理.png'}, + {id:14,name:'住建',imgUrl:'/assets/linkageForces/住建.png'} + ] + ngOnInit(): void { + this.getAllFireForce() + window.onload = () => { + var mySwiper = new Swiper('.swiper-container', { + slidesPerView: 10,//每页显示的个数 + slidesPerGroup: 3,//点击一次需要跳多少次 + // 如果需要前进后退按钮 + navigation: { + nextEl: '.swiper-button-next', + prevEl: '.swiper-button-prev', + }, + }) + } + setTimeout(() => { + + this.createMap() + }, 0); + } + //获得所有联动力量 + allLinkageForceObj:any//获得的所有联动力量 + dataLength:any //获取的数据一共多少条 + PageNumber:any = 1 //当前第几页 + getAllFireForce(){ + let MinIntegrity = 0 + let MaxIntegrity = 1.1 + if(this.searchForm.integrityNum == '0'){ + MinIntegrity = 0 + MaxIntegrity = 0.5 + }else if(this.searchForm.integrityNum == '1'){ + MinIntegrity = 0.5 + MaxIntegrity = 0.6 + }else if(this.searchForm.integrityNum == '2'){ + MinIntegrity = 0.6 + MaxIntegrity = 0.7 + }else if(this.searchForm.integrityNum == '3'){ + MinIntegrity = 0.7 + MaxIntegrity = 0.8 + }else if(this.searchForm.integrityNum == '4'){ + MinIntegrity = 0.8 + MaxIntegrity = 0.9 + }else if(this.searchForm.integrityNum == '5'){ + MinIntegrity = 0.9 + MaxIntegrity = 1.1 + }else if(this.searchForm.integrityNum == '-1'){ + MinIntegrity = 0 + MaxIntegrity = 1.1 + } + let params:any = { + Keyword : this.searchForm.name ? this.searchForm.name : '', + MinIntegrity : MinIntegrity, + MaxIntegrity : MaxIntegrity, + PageSize : 15, + PageNumber : this.PageNumber, + } + this.http.get('/api/LinkageForces',{params:params}).subscribe((data:any) => { + console.log('所有消防力量列表',data) + this.dataLength = data.totalCount + this.allLinkageForceObj = data + }) + } + + + //选择要显示的联动力量 + selectedLinkageForce(item){ + this.isGisTopBox = false + if(this.LinkageForceDetailInfo.id != item.id){ + this.clearData() + this.LinkageForceDetailInfo = item + item.location?this.positionLngLat = item.location:null + this.AttachmentArr = JSON.parse(item.relevantInfomationData) + if(this.newPositionMarker){ + this.map.remove(this.newPositionMarker); + } + console.log('当前点击的li',item) + if(item.location && item.location.x){//如果已经标注单位坐标 + console.log('开始标注') + + this.map.setCenter([item.location.x,item.location.y]); + this.newPositionMarker = new AMap.Marker({ + position: [item.location.x,item.location.y], + content: this.newPositionMarkerContent, + offset: new AMap.Pixel(-15, -18) + }) + // 将 markers 添加到地图 + this.map.add(this.newPositionMarker); + } + } + } + //搜索 + searchList(){ + this.getAllFireForce() + } + //重置搜索 + reset(){ + this.searchForm = { + name:'', + integrityNum:'' + } + this.getAllFireForce() + } + //分页事件 + chagePage(e){ + this.PageNumber = e.pageIndex+1 + this.getAllFireForce() + } + //js乘法 + accMul(arg1,arg2,fix) { + if(!parseInt(fix)==fix) + { + return; + } + var m=0,s1=arg1.toString(),s2=arg2.toString(); + try{m+=s1.split(".")[1].length}catch(e){} + try{m+=s2.split(".")[1].length}catch(e){} + if(m>fix){ + return (Math.round(Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m-fix))/Math.pow(10,fix)); + }else if(m<=fix){ + return (Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)).toFixed(fix); + }else{ + return (arg1*arg2).toFixed(fix).toString(); + } + } + //完整度颜色 + integrity(width){ + let _this = this + let style:any = {} + style.width = width +'%'; + if(width < 30){ + style.background = '#FF5D4A' + } + if(width >= 30 && width < 60){ + style.background = '#FFDD00' + } + if(width >= 60){ + style.background = '#5CD64E' + } + return style + } + //删除某条联动力量 + deleteLinkageForc(item,e){ + e.stopPropagation() + let isDelete = window.confirm(`确定要删除${item.name}吗`) + if(isDelete){ + this.http.delete(`/api/LinkageForces/${item.id}`).subscribe(data => { + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('删除成功','确定',config); + if(item.id == this.LinkageForceDetailInfo.id){ + this.LinkageForceDetailInfo.linkageForceType = null + } + this.getAllFireForce() + }) + } + } + //当前点击tab页面第几个 + tabIndex:any = 1 + selectedTab(index){ + this.tabIndex = index + } + + //联动力量详情提交信息 + LinkageForceDetailInfo:any = { + // id:'',//编号 + linkageForceType:'', + name:'',//名称 + phoneNumber:'',//联系电话 + faxNumber:'',//传真 + remark:'',//备注 + administrativeRegion:'',//行政区 + address:'',//地址 + location:{ + x:'', + y:'' + }, + contactName:'',//联系人姓名 + contactTitle:'',//联系人职务 + contactPhone:'',//联系人电话 + serviceContent:'',//服务内容 + resourceRemark:'',//资源说明 + relevantInfomationData:[]//相关资料 + } + + //清空表单数据 + clearData(){ + this.deletedFile = []//清空相关资料已删除缓存 + this.AttachmentArr = []//清空相关资料 + this.positionLngLat = {x:'',y:''} + this.atLastPositionLngLat = {x:'',y:''} + this.LinkageForceDetailInfo = { + // id:'',//编号 + linkageForceType:'', + name:'',//名称 + phoneNumber:'',//联系电话 + faxNumber:'',//传真 + remark:'',//备注 + administrativeRegion:'',//行政区 + address:'',//地址 + location:{ + x:'', + y:'' + }, + contactName:'',//联系人姓名 + contactTitle:'',//联系人职务 + contactPhone:'',//联系人电话 + serviceContent:'',//服务内容 + resourceRemark:'',//资源说明 + relevantInfomationData:[]//相关资料 + } + } + //新增联动力量 + selectedFireForceTypeIndex:any//新增消防力量名称 + addLinkageForce(){ + const dialogRef = this.dialog.open(AddLinkageForce, { + data: {}, + id:'addLinkageForce' + }); + dialogRef.afterClosed().subscribe( + data=>{ + if(typeof data === 'number' && !isNaN(data)){ + this.clearData() + console.log('清空了',this.LinkageForceDetailInfo) + this.LinkageForceDetailInfo.linkageForceType = data + this.newPositionMarker ? this.map.remove(this.newPositionMarker) : null + this.map.setCity('上海市'); + + } + } + ) + } + //保存 + save(){ + if(!this.LinkageForceDetailInfo.name){ + alert('名称必填') + return + } + this.isMasklayer = true + //删除一下数据库的文件 + if(this.deletedFile.length != 0){ + this.deletedFile.forEach(item => { + this.http.delete(`/api/Objects/PlanPlatform/${item.objectName}`).subscribe(data=>{ + console.log('删除原文件成功') + }) + }); + } + + this.LinkageForceDetailInfo.location = {x:'',y:''} + this.LinkageForceDetailInfo.RelevantInfomationData = JSON.stringify(this.AttachmentArr) + if(this.atLastPositionLngLat.x){ + this.LinkageForceDetailInfo.location.x = this.atLastPositionLngLat.x + this.LinkageForceDetailInfo.location.y = this.atLastPositionLngLat.y + }else{ + this.LinkageForceDetailInfo.location = null + } + this.LinkageForceDetailInfo.relevantInfomationData = JSON.stringify(this.LinkageForceDetailInfo.relevantInfomationData) + let body = this.LinkageForceDetailInfo + if(this.LinkageForceDetailInfo.id){ + this.http.put(`/api/LinkageForces/${this.LinkageForceDetailInfo.id}`,body).subscribe((data:any) =>{ + console.log('修改成功',data) + this.isMasklayer = false + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('修改成功','确定',config); + // this.LinkageForceDetailInfo.id = data.id + this.getAllFireForce() + + }) + }else{ + this.http.post('/api/LinkageForces',body).subscribe((data:any) =>{ + console.log('创建成功',data) + this.isMasklayer = false + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('保存成功','确定',config); + this.LinkageForceDetailInfo = data + this.getAllFireForce() + }) + } + + + } + + map:any + placeSearch:any//构造地点查询类 + isMapLabel:boolean = false //是否已经标记坐标 + newPositionMarkerContent:any = + '
' + + ' ' + + '
' + newPositionMarkerContentBtn:any = + '
' + + ' ' + + '
|
' + + '
' + //创建地图 + newPositionMarker:any//坐标实例 + createMap(){ + this.map = new AMap.Map('container', { + zoom:12 + }) + this.map.setCity('上海市'); + //输入提示 + var autoOptions = { + input: "tipinput" + }; + AMap.plugin(['AMap.PlaceSearch','AMap.AutoComplete'], ()=>{ + let auto = new AMap.AutoComplete(autoOptions); + this.placeSearch = new AMap.PlaceSearch(); //构造地点查询类 + auto.on("select", (e)=>{ + this.newPositionMarker.setPosition([e.poi.location.lng,e.poi.location.lat]) + this.positionLngLat = {x: e.poi.location.lng, y: e.poi.location.lat} + this.map.setCenter([e.poi.location.lng,e.poi.location.lat]); //设置地图中心点 + });//注册监听,当选中某条记录时会触发 + + }); + + if(this.isMapLabel){//如果已经标注单位坐标 + console.log('已标注单位位置') + // this.map.setCenter([this.unitinfo.location.x,this.unitinfo.location.y]); + // this.oldPositionMarker = new AMap.Marker({ + // position: [this.unitinfo.location.x,this.unitinfo.location.y], + // content: this.newPositionMarkerContent, + // offset: new AMap.Pixel(-15, -18) + // }) + // // 将 markers 添加到地图 + // this.map.add(this.oldPositionMarker); + }else{ + console.log('未标注单位位置') + // this.map.setCity('上海市'); + } + } + //点击位置 + isGisTopBox:boolean = false // + searchTitle:any = ''// + + positionLngLat:any = {x:'',y:''}//临时坐标点 + atLastPositionLngLat:any = {x:'',y:''}//最终坐标点 + setPosition(){ + if(!this.isGisTopBox){ + this.isGisTopBox = true + this.newPositionMarker ? this.map.remove(this.newPositionMarker) : null + let center + console.log(789,this.atLastPositionLngLat) + if(this.newPositionMarker && this.atLastPositionLngLat.x){//如果已经标注单位坐标 + console.log(1) + center = [this.atLastPositionLngLat.x, this.atLastPositionLngLat.y] + }else if(this.newPositionMarker && !this.atLastPositionLngLat.x && this.LinkageForceDetailInfo.location && this.LinkageForceDetailInfo.location.x){ + console.log(2) + center = [this.LinkageForceDetailInfo.location.x, this.LinkageForceDetailInfo.location.y] + }else{ + console.log(3) + center = this.map.getCenter(); //获取当前地图中心位置 + } + this.newPositionMarker = new AMap.Marker({ + draggable: true, + position: center, + content: this.newPositionMarkerContentBtn, + offset: new AMap.Pixel(-15, -18) + }); + this.positionLngLat = {x: center.lng || center[0], y: center.lat || center[1]} + this.map.add(this.newPositionMarker); + this.isMapLabel = true + this.newPositionMarker.on('dragend', (e)=>{ + this.positionLngLat = {x: e.lnglat.lng, y: e.lnglat.lat} + }) + //点击确定 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#setPositionOk'),'click',(event)=>{ + this.isGisTopBox = false + this.map.remove(this.newPositionMarker) + this.newPositionMarker = new AMap.Marker({ + position: [this.positionLngLat.x,this.positionLngLat.y], + content: this.newPositionMarkerContent, + offset: new AMap.Pixel(-15, -18) + }); + this.atLastPositionLngLat = JSON.parse(JSON.stringify(this.positionLngLat)) + this.map.add(this.newPositionMarker); + this.positionLngLat = this.atLastPositionLngLat + }) + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#setPositionClose'),'click',(event)=>{ + this.isGisTopBox = false + this.map.remove(this.newPositionMarker) + if(this.positionLngLat.x && this.positionLngLat.x != 0 && !this.atLastPositionLngLat.x){//直接取消 + this.map.remove(this.newPositionMarker) + this.positionLngLat = {} + this.atLastPositionLngLat = {} + }else{ + this.newPositionMarker = new AMap.Marker({ + position: [this.atLastPositionLngLat.x,this.atLastPositionLngLat.y], + content: this.newPositionMarkerContent, + offset: new AMap.Pixel(-15, -18) + }); + this.map.setCenter([this.atLastPositionLngLat.x,this.atLastPositionLngLat.y]); //设置地图中心点 + this.map.add(this.newPositionMarker); + this.positionLngLat = this.atLastPositionLngLat + } + })//取消 + } + + } + + + + + //上传附件 + file:any; //上传的文件 + AttachmentArr:any = []//上传附件地址集合 + uploadId:any//分块上传id + objectName:any + progressBarValue:any = 0//分块上传进度 + isMasklayer:boolean = false//圆圈遮罩层是否打开 + isMasklayerUploading:boolean = false//上传进度条遮罩层是否打开 + isMasklayerDownload:boolean = false//下载进度条遮罩层是否打开 + uploadAttachment(e){ + console.log('选择的文件',e) + this.file = e.target.files[0] || null //上传的文件 + let file = e.target.files[0] || null //获取上传的文件 + let fileSize = file.size || null //上传文件的总大小 + let shardSize = 5 * 1024 * 1024 //5MB一个分片 + + if (file && fileSize<=shardSize) { //上传文件<=5MB时 + this.isMasklayer = true + console.log('file',this.file) + let formData = new FormData() + formData.append("file",file) + //this.selectedFireForce.id 选择的组织机构的id + this.http.post(`/api/Objects/PlanPlatform/LinkageForce/${this.LinkageForceDetailInfo.id}`,formData).subscribe((data:any)=>{ + // this.objectName = data.objectName + let obj = { + objectName:data.objectName, + fileName:data.fileName, + fileLength:data.fileLength + } + this.AttachmentArr.push(obj) + this.isMasklayer = false + console.log('上传成功',data) + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('上传成功','确定',config); + }) + } else if (file && fileSize>shardSize) { //上传文件>5MB时,分块上传 + this.isMasklayerUploading = true + let data = {filename: file.name} + this.http.post(`/api/NewMultipartUpload/PlanPlatform/LinkageForce/${this.LinkageForceDetailInfo.id}`,{},{params:data}).subscribe((data:any)=>{ //初始化分段上传 + console.log('初始化分块上传成功',data) + this.objectName = data.objectName + this.uploadId = data.uploadId + this.subsectionUploading() + }) + } + } + PartNumberETag:any=[]; //每次返回需要保存的信息 + + //开始分段上传 + async subsectionUploading () { + let file = this.file || null //获取上传的文件 + let fileSize = file.size || null //上传文件的总大小 + let shardSize = 5 * 1024 * 1024 //5MB一个分片 + let allSlice = Math.ceil(fileSize / shardSize) //总文件/5MB===共分多少段 + for (let i = 0;i < allSlice;i++) { //循环分段上传 + let start = i * shardSize //切割文件开始位置 + let end = Math.min(fileSize, start + shardSize); //切割文件结束位置 + let formData = new FormData() + formData.append("file",file.slice(start, end)) + + //同步写法实现异步调用 + let result = await new Promise((resolve, reject) => { + // await 需要后面返回一个 promise 对象 + this.http.post(`/api/MultipartUpload/PlanPlatform/${this.objectName}?uploadId=${this.uploadId}&partNumber=${i+1}`,formData).subscribe((data:any)=>{ + let msg = { + "partNumber":data.partNumber || null, + "eTag": data.eTag || null} + resolve(msg) // 调用 promise 内置方法处理成功 + }) + }); + this.PartNumberETag.push(result) + // this.progressBarValue = Number((i/allSlice).toFixed(2))*100 + this.progressBarValue = this.accMul(Number((i/allSlice).toFixed(2))*100,1,0) + if (this.PartNumberETag.length === allSlice) { + this.progressBarValue = 100 + this.endUploading()} + }//for循环 + + } + + //完成分块上传 + endUploading () { + let data = this.PartNumberETag + let paramsData = {uploadId:this.uploadId} + this.http.post(`/api/CompleteMultipartUpload/PlanPlatform/${this.objectName}`,data,{params:paramsData}).subscribe(data=>{ + this.PartNumberETag =[] //清空保存返回的信息 + let obj = { + objectName:this.objectName, + fileName:this.file.name, + fileLength:this.file.size + } + this.AttachmentArr.push(obj) + this.isMasklayerUploading = false//关闭进度条遮罩层 + this.progressBarValue = 0//重置进度数 + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('上传成功','确定',config); + }) + } + //取消分块上传 + cancelUploading() { + this.http.delete(`/api/MultipartUpload/PlanPlatform/${this.objectName}?uploadId=${this.uploadId}`).subscribe(data=>{ + this.progressBarValue = 0; + this.isMasklayerUploading= false + this.PartNumberETag =[] //清空保存返回的信息 + const config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('取消上传成功','确定',config); + }) + } + + //下载 + download (e) { + this.isMasklayerDownload = true //开启下载进度条 + let file = e //传递过来的文件元数据 + let fileSize = file.fileLength //下载文件的总大小 + let shardSize = 3 * 1024 * 1024 //文件大小是否大于10MB + if (file && fileSize<=shardSize) { //<=3MB时直接下载 + this.progressBarValue = 60 + this.http.get(`/api/Objects/PlanPlatform/${e.objectName}`,{responseType: 'blob'},).subscribe(data=>{ + let url = window.URL.createObjectURL(new Blob([data])); //createObjectURL创建一个下载Blob的url地址 + let link = document.createElement("a"); + link.style.display = "none"; + link.href = url; + let fileName = e.fileName ? e.fileName : e.objectName.split('/')[e.objectName.split('/').length-1] + link.setAttribute("download", fileName); + document.body.appendChild(link); + link.click(); + this.isMasklayerDownload = false //关闭下载进度条 + this.progressBarValue = 0 //初始化进度条 + }) + } else if (file && fileSize>shardSize) { //>3MB时分块下载 + this.blockingDownload(e) //分段下载 + } + + } + + //分段下载并合并 + async blockingDownload (e) { + let file = e //传递过来的文件元数据 + let fileSize = file.fileLength //下载文件的总大小 + let shardSize = 3 * 1024 * 1024 //3MB一个分片 + let allSlice = Math.ceil(fileSize / shardSize) //总文件/3MB===共分多少段 + let allFile:any = [] //所有的file分段 + + for (let i=0;i{ + this.http.get(`/api/Objects/PlanPlatform/${e.objectName}`,{headers:{'range':`bytes= ${start}-${end}`},responseType:'blob'}).subscribe(data=>{ + result(data) }) + }) + allFile.push(result) + // this.progressBarValue = Number((i/allSlice).toFixed(2))*100 //文件进度数 + this.progressBarValue = this.accMul(Number((i/allSlice).toFixed(2))*100,1,0) + if (allFile.length === allSlice) { //合并文件输出给浏览器 + let url = window.URL.createObjectURL(new Blob(allFile)); //createObjectURL创建一个下载Blob的url地址 + let link = document.createElement("a"); + link.style.display = "none"; + link.href = url; + let fileName = e.fileName ? e.fileName : e.objectName.split('/')[e.objectName.split('/').length-1] + link.setAttribute("download", fileName); + document.body.appendChild(link); + link.click(); + this.isMasklayerDownload = false //关闭下载进度条 + this.progressBarValue = 0 //初始化进度条 + } + + } //for循环结束 + + } + + //删除图片 + deletedFile:any = [] + deleteFile(item,e){ + console.log(this.AttachmentArr) + e.stopPropagation() + let isTrue = window.confirm('确定要删除该文件吗?') + if(isTrue){ + let index + this.AttachmentArr.forEach((element,key) => { + if(element.objectName == item.objectName){ + index = key + } + }); + this.AttachmentArr.splice(index,1) + this.deletedFile.push(item) + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('删除成功','确定',config); + } + } + + //点击文件 + clickFile(item){ + console.log(item) + let suffix = item.fileName.split('.')[item.fileName.split('.').length-1] + if(suffix == 'png' || suffix == 'jpg' || suffix == 'JPG'){ + console.log('这是图片') + let dom = document.getElementById(`viewerjs`) + let pObjs = dom.childNodes; + let node = document.createElement("img") + node.style.display = "none"; + node.src = "/api/Objects/PlanPlatform/" + item.objectName; + node.id = 'img' + dom.appendChild(node) + setTimeout(() => { + let viewer = new Viewer(document.getElementById(`viewerjs`), { + hidden:()=>{ + dom.removeChild(pObjs[0]); + viewer.destroy(); + } + }); + node.click(); + }, 0); + } + if(suffix == 'docx' || suffix == 'doc' || suffix == 'pdf'){ + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('暂不支持查看','确定',config); + } + if(suffix == 'mp4'){ + const dialogRef = this.dialog.open(ViewDetails2, {//调用open方法打开对话框并且携带参数过去 + data: {item:item,type:"video"}, + id:'videodialog2' + }); + dialogRef.afterClosed().subscribe(); + } + } + +} + + + + +//新增联动力量弹出框 +@Component({ + selector: 'AddLinkageForce', + templateUrl: './addLinkageForce.html', + styleUrls: ['./linkage-forces.component.scss'] +}) +export class AddLinkageForce { + + constructor(private http: HttpClient,public dialogRef: MatDialogRef,@Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar) {} + + + addList:any = [ + {id:0,name:'安监',imgUrl:'/assets/linkageForces/安监.png'}, + {id:1,name:'电力局',imgUrl:'/assets/linkageForces/电力局.png'}, + {id:2,name:'公安',imgUrl:'/assets/linkageForces/公安.png'}, + {id:3,name:'海事',imgUrl:'/assets/linkageForces/海事.png'}, + {id:4,name:'环保局',imgUrl:'/assets/linkageForces/环保局.png'}, + {id:5,name:'交通',imgUrl:'/assets/linkageForces/交通.png'}, + {id:6,name:'民政',imgUrl:'/assets/linkageForces/民政.png'}, + {id:7,name:'气象局',imgUrl:'/assets/linkageForces/气象局.png'}, + {id:8,name:'燃气局',imgUrl:'/assets/linkageForces/燃气局.png'}, + {id:9,name:'市政',imgUrl:'/assets/linkageForces/市政.png'}, + {id:10,name:'水利',imgUrl:'/assets/linkageForces/水利.png'}, + {id:11,name:'通信',imgUrl:'/assets/linkageForces/通信.png'}, + {id:12,name:'医疗',imgUrl:'/assets/linkageForces/医疗.png'}, + {id:13,name:'应急管理',imgUrl:'/assets/linkageForces/应急管理.png'}, + {id:14,name:'住建',imgUrl:'/assets/linkageForces/住建.png'} + ] + selectedFireForceTypeIndex:any = 0 + selecteAddType(item,key){ + this.selectedFireForceTypeIndex = item.id + + } ngOnInit(): void { + + } + + confirm(){ + this.dialogRef.close(this.selectedFireForceTypeIndex) } } + +//查看图片大图和视频 +@Component({ + selector: 'viewdetails', + templateUrl: './viewdetails.html', + styleUrls: ['./linkage-forces.component.scss'] +}) +export class ViewDetails2 { + // myControl = new FormControl(); + //注入MatDialogRef,可以用来关闭对话框 + //要访问对话框组件中的数据,必须使用MAT_DIALOG_DATA注入令牌 + constructor(private http: HttpClient,public dialogRef: MatDialogRef,@Inject(MAT_DIALOG_DATA) public data) {} + Url:string + onNoClick(): void { + this.dialogRef.close(); + } + ngOnInit(): void { + this.Url = '/api/Objects/PlanPlatform/' + this.data.item.objectName + } + closeDialog(){ + this.dialogRef.close(); + } + +} \ No newline at end of file diff --git a/src/app/data-collection/linkage-forces/viewdetails.html b/src/app/data-collection/linkage-forces/viewdetails.html new file mode 100644 index 0000000..6d917bb --- /dev/null +++ b/src/app/data-collection/linkage-forces/viewdetails.html @@ -0,0 +1 @@ + diff --git a/src/app/data-collection/water-collection/water-collection.component.html b/src/app/data-collection/water-collection/water-collection.component.html index 542ed80..9fe492c 100644 --- a/src/app/data-collection/water-collection/water-collection.component.html +++ b/src/app/data-collection/water-collection/water-collection.component.html @@ -52,7 +52,7 @@
- +
diff --git a/src/app/data-collection/water-collection/water-collection.component.ts b/src/app/data-collection/water-collection/water-collection.component.ts index 17dd475..c88aa80 100644 --- a/src/app/data-collection/water-collection/water-collection.component.ts +++ b/src/app/data-collection/water-collection/water-collection.component.ts @@ -74,7 +74,7 @@ export class WaterCollectionComponent implements OnInit { } let params:any = { Keyword : this.searchForm.name, - PageSize : 30, + PageSize : 15, PageNumber : this.PageNumber, MinIntegrity : MinIntegrity, MaxIntegrity : MaxIntegrity diff --git a/src/app/gis-management/gis-labeling/gis-labeling.component.html b/src/app/gis-management/gis-labeling/gis-labeling.component.html index 331be05..60f2b04 100644 --- a/src/app/gis-management/gis-labeling/gis-labeling.component.html +++ b/src/app/gis-management/gis-labeling/gis-labeling.component.html @@ -114,6 +114,7 @@ 显示范围 : + diff --git a/src/app/gis-management/gis-labeling/gis-labeling.component.ts b/src/app/gis-management/gis-labeling/gis-labeling.component.ts index 819a3ff..d8d3330 100644 --- a/src/app/gis-management/gis-labeling/gis-labeling.component.ts +++ b/src/app/gis-management/gis-labeling/gis-labeling.component.ts @@ -27,28 +27,14 @@ export class GisLabelingComponent implements OnInit { {id:'0',name:'消火栓',selected:false}, {id:'1',name:'消防水池',selected:false}, {id:'2',name:'天然水源',selected:false}, - // {id:'0',name:'单位地上消火栓',selected:false}, - // {id:'0',name:'单位地下消火栓',selected:false}, - // {id:'0',name:'市政地上消火栓',selected:false}, - // {id:'0',name:'消防水池',selected:false}, - // {id:'0',name:'方形储水池',selected:false}, - // {id:'0',name:'蓄水池',selected:false}, - // {id:'0',name:'原型水塔',selected:false}, - // {id:'0',name:'水库',selected:false}, - // {id:'0',name:'消防水箱',selected:false}, - // {id:'0',name:'码头',selected:false}, - // {id:'0',name:'海洋',selected:false}, - // {id:'0',name:'河流',selected:false}, - // {id:'0',name:'湖泊',selected:false}, - // {id:'0',name:'沟渠',selected:false} - ] + ] keyUnitForm : FormGroup//gis右上角重点单位表单 watertForm : FormGroup//gis右上角水源表单 selectedUnitList:any = []//选择提交的单位 selectedWaterList:any = []//选择提交的水源 - unitAreaDefault:any = '0'//默认单位范围 - waterAreaDefault:any = '0'//默认水源范围 + unitAreaDefault:any = '-1'//默认单位范围 + waterAreaDefault:any = '-1'//默认水源范围 //获得单位循环出来的checkbox列表(formControl实例) get units():any{ return this.keyUnitForm.get('units') @@ -156,17 +142,19 @@ export class GisLabelingComponent implements OnInit { //重点单位提交 ketUnitSubmit(value){ if(this.markers.length == 0){ - const config = new MatSnackBarConfig(); - config.verticalPosition = 'top'; - config.duration = 3000 - this.snackBar.open('请先选择一个单位','确定',config); + let paramsdata:any = { + PageSize:99999, + BuildingTypeIdList : this.selectedUnitList.length != 0 ? this.selectedUnitList : ['123'] + } + this.http.get("/api/Companies",{params:paramsdata}).subscribe((data:any) => { + this.createUnitMarker(data.items) + }) }else if(!this.mapPattern){ const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请切换2D模式使用此功能','确定',config); }else{ - // console.log('提交',this.selectedUnit) this.circle.setRadius(Number(this.unitAreaDefault)) this.circle.setCenter(this.markers[0]._position) this.circle.setMap(this.map) @@ -178,32 +166,43 @@ export class GisLabelingComponent implements OnInit { }else{ Distance = Math.abs(lnglat.offset(0, this.unitAreaDefault).lat - this.selectedUnit.location.y) } - - let paramsdata:any = { - Lon : this.selectedUnit.location.x, - Lat : this.selectedUnit.location.y, - Distance : Distance, - BuildingTypeIdList : this.selectedUnitList.length != 0 ? this.selectedUnitList : ['123'] - } - // console.log(666,paramsdata) - this.http.get("/api/Companies",{params:paramsdata}).subscribe((data:any) => { - data.items.forEach((i,index) => { - if(i.id == this.selectedUnit.id){ - data.items.splice(index,1) - } + if(this.unitAreaDefault == '-1'){//如果勾选全部 + let paramsdata:any = { + PageSize:99999, + BuildingTypeIdList : this.selectedUnitList.length != 0 ? this.selectedUnitList : ['123'] + } + this.http.get("/api/Companies",{params:paramsdata}).subscribe((data:any) => { + data.items.forEach((i,index) => { + if(i.id == this.selectedUnit.id){ + data.items.splice(index,1) + } + }) + this.createUnitMarker(data.items) }) - this.createUnitMarker(data.items) - }) + }else{ + let paramsdata:any = { + PageSize:99999, + Lon : this.selectedUnit.location.x, + Lat : this.selectedUnit.location.y, + Distance : Distance, + BuildingTypeIdList : this.selectedUnitList.length != 0 ? this.selectedUnitList : ['123'] + } + this.http.get("/api/Companies",{params:paramsdata}).subscribe((data:any) => { + data.items.forEach((i,index) => { + if(i.id == this.selectedUnit.id){ + data.items.splice(index,1) + } + }) + this.createUnitMarker(data.items) + }) + } } } //创建单位markers - unitMarkerList:any = [] - unitlabelsLayer:any + unitCluster:any //重点单位点聚合实例 createUnitMarker(list){ - this.unitlabelsLayer ? this.map.remove(this.unitlabelsLayer) : null - this.unitMarkerList ? this.map.remove(this.unitMarkerList) : null - - let markerArr = [] + let unitMarkerArrcluster = [] + this.unitCluster ? this.unitCluster.setData([]) : null list.forEach((item) => { let image if(item.buildingTypes[0].name.indexOf('高层') != -1){ @@ -241,176 +240,262 @@ export class GisLabelingComponent implements OnInit { }else{ image = '/assets/images/其他.png' } - var icon = { - // 图标类型,现阶段只支持 image 类型 - type: 'image', - // 图片 url - image: image, - // 图片尺寸 - size: [32, 32], - // 图片相对 position 的锚点,默认为 bottom-center - anchor: 'center', - }; - var text = { - // 要展示的文字内容 - content: item.name, - // 文字方向,有 icon 时为围绕文字的方向,没有 icon 时,则为相对 position 的位置 - direction: 'bottom', - // 在 direction 基础上的偏移量 - offset: [-3, -3], - // 文字样式 - style: { - // 字体大小 - fontSize: 12, - // 字体颜色 - fillColor: '#22886f', - // 描边颜色 - strokeColor: '#fff', - // 描边宽度 - strokeWidth: 2, - } + // 用于点集合的数组 + unitMarkerArrcluster.push({ + lnglat : [item.location.x,item.location.y], + image : image, + data : item + }) + }) + this.map.plugin(["AMap.MarkerClusterer"],() => { + var gridSize = 60 + var count = unitMarkerArrcluster.length; + var _renderClusterMarker = function (context) { + var factor = Math.pow(context.count / count, 1 / 18); + var div = document.createElement('div'); + var Hue = 180 - factor * 180; + var bgColor = 'hsla(' + Hue + ',100%,40%,0.7)'; + var fontColor = 'hsla(' + Hue + ',100%,90%,1)'; + var borderColor = 'hsla(' + Hue + ',100%,40%,1)'; + var shadowColor = 'hsla(' + Hue + ',100%,90%,1)'; + div.style.backgroundColor = bgColor; + var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20); + div.style.width = div.style.height = size + 'px'; + div.style.border = 'solid 1px ' + borderColor; + div.style.borderRadius = size / 2 + 'px'; + div.style.boxShadow = '0 0 5px ' + shadowColor; + div.innerHTML = context.count; + div.style.lineHeight = size + 'px'; + div.style.color = fontColor; + div.style.fontSize = '14px'; + div.style.textAlign = 'center'; + context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2)); + context.marker.setContent(div) }; - var labelMarker = new AMap.LabelMarker({ - name: item.name, // 此属性非绘制文字内容,仅最为标识使用 - position: [item.location.x,item.location.y], - zIndex: 16, - // 将第一步创建的 icon 对象传给 icon 属性 - icon: icon, - // 将第二步创建的 text 对象传给 text 属性 - text: text, - }); - labelMarker.on('click', (e)=>{ - // console.log(item) - let markerContent = - `
-
${item.name}
-
-
单位性质:
-
消防负责人:
-
-
-
防火级别:
-
消防管理人:
-
-
-
防火管辖:
-
防火监督员:
-
-
-
责任队站:
-
总建筑面积:
-
-
-
建筑信息分类:
-
总占地面积:
-
-
-
值班电话:
-
-
-
基本信息
-
导航
-
全景漫游
-
三维场景
-
查看预案
-
分享
-
-
` - // 创建一个自定义内容的 infowindow 实例 - this.infoWindow = new AMap.InfoWindow({ - position: [item.location.x,item.location.y], - offset: new AMap.Pixel(0, -30), - content: markerContent, - }); - this.infoWindow.open(this.map); - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#baseInformation'),'click',(event)=>{ this.baseInformation(item) })//基本信息点击事件 - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#route'),'click',(event)=>{ this.route(item) })//导航点击事件 - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#fullViewNavigation'),'click',(event)=>{ this.fullViewNavigation(item) })//全景漫游点击事件 - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#threeeScene'),'click',(event)=>{ this.threeeScene(item) })//三维场景点击事件 - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#seePlan'),'click',(event)=>{ this.seePlan(item) })//查看预案点击事件 - this.renderer2.listen(this.elementRef.nativeElement.querySelector('#share'),'click',(event)=>{ this.share(item) })//分享点击事件 + var _renderMarker = (context)=> { + var content = ``; + var offset = new AMap.Pixel(-15, -25); + context.marker.setContent(content) + context.marker.setOffset(offset) + } + this.unitCluster = new AMap.MarkerCluster(this.map, unitMarkerArrcluster, { + gridSize: gridSize, // 设置网格像素大小 + renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式 + renderMarker: _renderMarker, // 自定义非聚合点样式 }); - markerArr.push(labelMarker) - }) - this.unitlabelsLayer = new AMap.LabelsLayer({ - zooms: [3, 20], - zIndex: 1000, - // 该层内标注是否避让 - collision: false, - // 设置 allowCollision:true,可以让标注避让用户的标注 - // allowCollision: true, + this.unitCluster.on('click',(e)=>{ + if(e.clusterData.length == 1){ + let item = e.clusterData[0].data + let markerContent = + `
+
${item.name}
+
+
单位性质:
+
消防负责人:
+
+
+
防火级别:
+
消防管理人:
+
+
+
防火管辖:
+
防火监督员:
+
+
+
责任队站:
+
总建筑面积:
+
+
+
建筑信息分类:
+
总占地面积:
+
+
+
值班电话:
+
+
+
基本信息
+
导航
+
全景漫游
+
三维场景
+
查看预案
+
分享
+
+
` + // 创建一个自定义内容的 infowindow 实例 + this.infoWindow = new AMap.InfoWindow({ + position: [item.location.x,item.location.y], + offset: new AMap.Pixel(0, -30), + content: markerContent, + }); + this.infoWindow.open(this.map); + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#baseInformation'),'click',(event)=>{ this.baseInformation(item) })//基本信息点击事件 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#route'),'click',(event)=>{ this.route(item) })//导航点击事件 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#fullViewNavigation'),'click',(event)=>{ this.fullViewNavigation(item) })//全景漫游点击事件 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#threeeScene'),'click',(event)=>{ this.threeeScene(item) })//三维场景点击事件 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#seePlan'),'click',(event)=>{ this.seePlan(item) })//查看预案点击事件 + this.renderer2.listen(this.elementRef.nativeElement.querySelector('#share'),'click',(event)=>{ this.share(item) })//分享点击事件 + } + }) }); - this.unitlabelsLayer.add(markerArr); - this.map.add(this.unitlabelsLayer);//增加图层 - - this.unitMarkerList = markerArr - this.map.add(this.unitMarkerList);//将markers添加到图层上 + } - //取消单位markers - clearUnitMarker(){ - this.map.remove(this.unitlabelsLayer) - this.map.remove(this.unitMarkerList); + //取消显示单位 + resetUnit(){ + this.keyUnitForm.reset() + this.keyUnitForm.controls.areaUnit.setValue('-1') + this.map.remove(this.circle) + this.unitCluster.setData([]) } - //水源提交 waterSubmit(value){ if(this.markers.length == 0){ - const config = new MatSnackBarConfig(); - config.verticalPosition = 'top'; - config.duration = 3000 - this.snackBar.open('请先选择一个单位','确定',config); + if(this.selectedWaterList.length != 0){//勾选了水源类型 + let paramsdata:any = { + PageSize:99999, + WaterSourceTypes : this.selectedWaterList + } + this.http.get("/api/WaterSources",{params:paramsdata}).subscribe((data:any) => { + console.log('所有水源',data) + this.createwaterMarker(data.items) + }) + }else{ + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('请勾选想要显示的水源类型','确定',config); + } }else if(!this.mapPattern){ const config = new MatSnackBarConfig(); config.verticalPosition = 'top'; config.duration = 3000 this.snackBar.open('请切换2D模式使用此功能','确定',config); }else{ - this.createwaterMarker() this.circleofwater.setRadius(Number(this.waterAreaDefault)) this.circleofwater.setCenter(this.markers[0]._position) this.circleofwater.setMap(this.map) + let Distance + let lnglat = new AMap.LngLat(this.selectedUnit.location.x, this.selectedUnit.location.y) // lng, lat 替换成传入的坐标 + + //如果选择当前的视野范围算出查询半径 if(this.waterAreaDefault == '0'){ this.circleofwater.setRadius(this.Calculationofdistance(this.map.getBounds())/2) + Distance = Math.abs(lnglat.offset(0, this.Calculationofdistance(this.map.getBounds())/2).lat - this.selectedUnit.location.y) + }else{ + Distance = Math.abs(lnglat.offset(0, this.waterAreaDefault).lat - this.selectedUnit.location.y) + } + //如果选择全部 + if(this.waterAreaDefault == '-1'){ + if(this.selectedWaterList.length != 0){ + let paramsdata:any = { + PageSize:99999, + WaterSourceTypes : this.selectedWaterList + } + this.http.get("/api/WaterSources",{params:paramsdata}).subscribe((data:any) => { + console.log('所有水源',data) + this.createwaterMarker(data.items) + }) + }else{ + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('请勾选想要显示的水源类型','确定',config); + } + + }else{ + if(this.selectedWaterList.length != 0){ + let paramsdata:any = { + PageSize:99999, + Lon : this.selectedUnit.location.x, + Lat : this.selectedUnit.location.y, + Distance : Distance, + WaterSourceTypes :this.selectedWaterList + } + this.http.get("/api/WaterSources",{params:paramsdata}).subscribe((data:any) => { + console.log('所有水源',data) + this.createwaterMarker(data.items) + }) + }else{ + let config = new MatSnackBarConfig(); + config.verticalPosition = 'top'; + config.duration = 3000 + this.snackBar.open('请勾选想要显示的水源类型','确定',config); + } } } } - waterIconList = []; //展示的水源图标 + //取消显示水源 + resetWater(){ + this.watertForm.reset() + + this.watertForm.controls.areaWater.setValue('-1') + + this.map.remove(this.circleofwater) + this.waterCluster.setData([]) + } //循环渲染出所有水源markers - createwaterMarker(){ - this.waterIconList.forEach((element,index) => { this.map.remove(element) }); //先删除所有标点 - this.waterIconList = [] - let waterType = this.selectedWaterList //筛选出展示的 水源类型 - if (waterType.length) { - let x = JSON.parse( JSON.stringify(this.markers[0]._position[0]) ) //中心标注的 坐标 - let y = JSON.parse( JSON.stringify(this.markers[0]._position[1]) ) //中心标注的 坐标 - let positonList = [0.015, -0.035, 0.045, 0.061, -0.013, 0.029] - // 创建一个 Icon - let startIcon = new AMap.Icon({ - image: '../../../assets/images/fireHydrant.png', - imageSize: new AMap.Size(20, 20), - }); - positonList.forEach((item,index)=>{ - let marker = new AMap.Marker({ - map: this.map, - position: index%2==0? JSON.parse( JSON.stringify([x+item,y-item]) ) : JSON.parse( JSON.stringify([x-item,y+item]) ), - icon: startIcon, - }); - this.waterIconList.push(marker) + waterCluster:any //水源聚合实例 + createwaterMarker(list){ + let waterMarkerArrcluster = [] + this.waterCluster ? this.waterCluster.setData([]) : null + list.forEach((item) => { + let image + if(item.waterSourceType == 0){//消火栓 + image = '/assets/images/市政消火栓.png' + }else if(item.waterSourceType == 1){//消防水池 + image = '/assets/images/方形储水池.png' + }else if(item.waterSourceType == 2){//天然水源 + image = '/assets/images/天然水源.png' + } + // 用于点集合的数组 + waterMarkerArrcluster.push({ + lnglat : [item.location.x,item.location.y], + image : image, + data : item }) - positonList.forEach((item,index)=>{ - let marker = new AMap.Marker({ - map: this.map, - position: index%2==0? JSON.parse( JSON.stringify([x+item,y+item]) ) : JSON.parse( JSON.stringify([x-item,y-item]) ), - icon: startIcon, - }); - this.waterIconList.push(marker) + }) + this.map.plugin(["AMap.MarkerClusterer"],() => { + var gridSize = 60 + var count = waterMarkerArrcluster.length; + var _renderClusterMarker = function (context) { + var factor = Math.pow(context.count / count, 1 / 18); + var div = document.createElement('div'); + var Hue = 180 - factor * 180; + var bgColor = 'hsla(' + Hue + ',100%,40%,0.7)'; + var fontColor = 'hsla(' + Hue + ',100%,90%,1)'; + var borderColor = 'hsla(' + Hue + ',100%,40%,1)'; + var shadowColor = 'hsla(' + Hue + ',100%,90%,1)'; + div.style.backgroundColor = bgColor; + var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20); + div.style.width = div.style.height = size + 'px'; + div.style.border = 'solid 1px ' + borderColor; + div.style.borderRadius = size / 2 + 'px'; + div.style.boxShadow = '0 0 5px ' + shadowColor; + div.innerHTML = context.count; + div.style.lineHeight = size + 'px'; + div.style.color = fontColor; + div.style.fontSize = '14px'; + div.style.textAlign = 'center'; + context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2)); + context.marker.setContent(div) + }; + var _renderMarker = (context)=> { + var content = ``; + var offset = new AMap.Pixel(-15, -25); + context.marker.setContent(content) + context.marker.setOffset(offset) + } + this.waterCluster = new AMap.MarkerCluster(this.map, waterMarkerArrcluster, { + gridSize: gridSize, // 设置网格像素大小 + renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式 + renderMarker: _renderMarker, // 自定义非聚合点样式 + }); + this.waterCluster.on('click',(e)=>{ + if(e.clusterData.length == 1){ + + } }) - } else { - const config = new MatSnackBarConfig(); - config.verticalPosition = 'top'; - config.duration = 3000 - this.snackBar.open('请选择水源类型','确定',config); - } + }); + } //计算两地距离 @@ -442,24 +527,9 @@ export class GisLabelingComponent implements OnInit { } } - //取消显示单位 - resetUnit(){ - this.keyUnitForm.reset() - this.keyUnitForm.controls.areaUnit.setValue('0') - this.map.remove(this.circle) - this.clearUnitMarker()//取消显示单位markers - // console.log('取消') - } - //取消显示水源 - resetWater(){ - this.waterIconList.forEach((element,index) => { this.map.remove(element) }); //先删除所有标点 - this.waterIconList = [] - this.watertForm.reset() - this.watertForm.controls.areaWater.setValue('0') - this.map.remove(this.circleofwater) - // console.log('取消') - } + + //右上角点击每一个title clickTitle(index){ @@ -482,15 +552,6 @@ export class GisLabelingComponent implements OnInit { loadChange(e){ e.checked ? this.map.add(this.roadNetLayer) : this.map.remove(this.roadNetLayer); } - // floorLayer = new AMap.Buildings({ - // zooms: [16, 18], - // zIndex: 10, - // heightFactor: 2 //2倍于默认高度,3D下有效 - // }) - //楼层图层 - // floorChange(e){ - // e.checked ? this.map.add(this.floorLayer) : this.map.remove(this.floorLayer); - // } @ViewChild( 'appLeft',{static: false} ) appLeft:any //子组件 leftDivState:boolean = false; //左侧工作区显示隐藏 @@ -556,19 +617,6 @@ export class GisLabelingComponent implements OnInit { that.map.setCity('上海市'); AMap.plugin(["AMap.RangingTool", "AMap.MouseTool"],function () { that.mouseTool=new AMap.MouseTool(that.map); - /* that.measureDistance = new AMap.RangingTool(that.map, rulerOptions); //测距离 - that.measureArea = new AMap.MouseTool(that.map); //侧面积 */ - /* that.measureDistance.on('addnode',function(e){ //监听测距离 标点事件 - that.distanceList.push(e.marker) - }) - that.measureDistance.on('end',function(e){ //监听测距离 连线事件 - that.distanceList.push(e.polyline) - }) */ - /* that.mouseTool.on("rightclick",function(e){ - if(this.mouseTool.eventsList[1]==undefined){ - alert("000") - } - }) */ }); } @@ -1093,7 +1141,6 @@ export class LookPlanDialog { } this.http.get("/api/PlanComponents",{params:paramsData}).subscribe((data:any)=>{ this.allPlanComponents = data.items - // console.log(this.allPlanComponents) }) } //查看预案 @@ -1137,7 +1184,6 @@ export class LookPlanDialog { dialogRef.afterClosed().subscribe( data=>{ if(data){ - // console.log(123,data) this.downloadFileName = data.fileName this.download = data this.downloadFile() diff --git a/src/app/ui/collection-tools-plan/collection-tools.component.html b/src/app/ui/collection-tools-plan/collection-tools.component.html index e461b35..a574865 100644 --- a/src/app/ui/collection-tools-plan/collection-tools.component.html +++ b/src/app/ui/collection-tools-plan/collection-tools.component.html @@ -332,44 +332,44 @@

{{item.PropertyName}}

{{item.PropertyName}}

- - + +

{{item.PropertyName}}

{{item.PropertyName}}

diff --git a/src/app/ui/collection-tools-plan/collection-tools.component.ts b/src/app/ui/collection-tools-plan/collection-tools.component.ts index b776406..ba10c1b 100644 --- a/src/app/ui/collection-tools-plan/collection-tools.component.ts +++ b/src/app/ui/collection-tools-plan/collection-tools.component.ts @@ -661,6 +661,7 @@ export class CollectionToolsPlanComponent implements OnInit { this.canvas.on("select",obj=>{ //选中素材属性注入函数 this.setAssetsProperty(obj.assetData) + console.log(obj.assetData) }) // 监听canvas组件取消选中素材事件 this.canvas.on("deselect",obj=>{ @@ -1258,6 +1259,7 @@ export class CollectionToolsPlanComponent implements OnInit { //点击数节点的显示隐藏icon clickLookItem(node){ + //修改真实素材islook属性 for(let key in this.storeyData.data){ if(key == node.id){ diff --git a/src/app/ui/collection-tools/collection-tools.component.html b/src/app/ui/collection-tools/collection-tools.component.html index 58b9396..04fe06a 100644 --- a/src/app/ui/collection-tools/collection-tools.component.html +++ b/src/app/ui/collection-tools/collection-tools.component.html @@ -334,44 +334,44 @@

{{item.PropertyName}}

{{item.PropertyName}}

- - + +

{{item.PropertyName}}

{{item.PropertyName}}

diff --git a/src/app/ui/collection-tools/collection-tools.component.scss b/src/app/ui/collection-tools/collection-tools.component.scss index 19402a6..0a5f53f 100644 --- a/src/app/ui/collection-tools/collection-tools.component.scss +++ b/src/app/ui/collection-tools/collection-tools.component.scss @@ -304,6 +304,7 @@ //右侧消防要素 .firecategories{ position: relative; + background-color: #fff; display: flex; flex-flow: column; .firecategoriesTree{ diff --git a/src/app/ui/collection-tools/collection-tools.component.ts b/src/app/ui/collection-tools/collection-tools.component.ts index b101e13..b360f15 100644 --- a/src/app/ui/collection-tools/collection-tools.component.ts +++ b/src/app/ui/collection-tools/collection-tools.component.ts @@ -1217,10 +1217,9 @@ export class CollectionToolsComponent implements OnInit { if(selectPanelPoint.Data){ for(let key in selectPanelPoint.Data.Stock){ selectPanelPoint.Data.Stock[key].isLookPattern = true + selectPanelPoint.Data.Stock[key].isLook = true if(element.id == selectPanelPoint.Data.Stock[key].FireElementId){ selectPanelPoint.Data.Stock[key].isTemplate = false - selectPanelPoint.Data.Stock[key].isLook = true - element.isNewElement = true //该节点children是否存在新添加的真实素材 标识 //定义查看模式下能看到的元素 @@ -1276,13 +1275,19 @@ export class CollectionToolsComponent implements OnInit { //点击数节点的显示隐藏icon clickLookItem(node){ - //修改真实素材islook属性 for(let key in this.storeyData.data){ if(key == node.id){ this.storeyData.data[key].isLook = !this.storeyData.data[key].isLook } } + if(this.selectPanelPoint && this.selectPanelPoint.Data){ + for(let key in this.selectPanelPoint.Data.Stock){ + if(key == node.id){ + this.selectPanelPoint.Data.Stock[key].isLook = !this.selectPanelPoint.Data.Stock[key].isLook + } + } + } //所有消防要素模板变化islook值 if(node.isTemplate){ @@ -1395,7 +1400,7 @@ export class CollectionToolsComponent implements OnInit { this.allFireElements[this.allFireElements.length-1].children.push(storeyData.data[key]) } } - let selectPanelPoint = JSON.parse(JSON.stringify(this.canvasData.selectPanelPoint || {} )) //当前 节点 数据 + let selectPanelPoint:any = this.canvasData.selectPanelPoint || {} //当前 节点 数据 if(selectPanelPoint.Data){ for(let key in selectPanelPoint.Data.Stock){ //筛选数据 没有匹配全部放入到 其他 数组 let noMatch = this.allFireElements.find( every=> every.id===selectPanelPoint.Data.Stock[key].FireElementId ) diff --git a/src/app/ui/collection-tools/save.ts b/src/app/ui/collection-tools/save.ts index 1657b66..0cd4303 100644 --- a/src/app/ui/collection-tools/save.ts +++ b/src/app/ui/collection-tools/save.ts @@ -57,11 +57,13 @@ export class saveOneDialog { @Inject(MAT_DIALOG_DATA) public data) {} type = this.data.type - allDisposalNode = this.data.allDisposalNode - allPlanDisposalNode = [] + allDisposalNode = this.data.allDisposalNode//所有节点数据 + allPlanDisposalNode = []//所有非数据节点 allRootDisposalNode = [{name:"根节点",id:null}] allDisposalNodeChild = [] + defaultSelectedName = '根节点' ngOnInit(): void { + console.log(111,this.allDisposalNode) //所有非数据节点 this.allDisposalNode.forEach(item => { if(!item.sitePlanId && !item.buildingAreaId){ @@ -89,10 +91,9 @@ export class saveOneDialog { onNoClick(): void { this.dialogRef.close(); } - nodeItem - itemChildNum = 0 //点击处置节点子数据节点的数量 + nodeItem:any//当前选中的要保存到的父节点 + itemChildNum = 0 //点击处置节点子数据节点的数量(赋值order) clickNode(item){ - // console.log(item) this.nodeItem = item this.allDisposalNodeChild.forEach(item => { if(item.id == this.nodeItem.id){ @@ -150,6 +151,10 @@ export class saveOneDialog { // 保存平面图数据到当前节点 let postdata =JSON.parse(JSON.stringify(this.canvasData.selectPanelPoint)) postdata.Data = JSON.stringify(postdata.Data) + postdata.Version ? null : postdata.Version = "2.0" + postdata.DisposalNodeId ? null : postdata.DisposalNodeId = istrue.id + postdata.PlanComponentId ? null : postdata.PlanComponentId = sessionStorage.getItem("planId") + postdata.Id ? null : postdata.Id = '' this.http.post(`/api/DisposalNodeData`,postdata).subscribe(data => { this.maskLayerService.sendMessage(false) const config = new MatSnackBarConfig(); @@ -173,7 +178,6 @@ export class saveOneDialog { resolve("更新处置节点成功,将天气 节点详情等信息保存到点击的节点") }) }).then((values)=>{ - // console.log(values) postdata.level = putdata.level + 1 new Promise((resolve,reject) => { this.http.post(`/api/DisposalNodes`,postdata).subscribe(data => { diff --git a/src/app/ui/collection-tools/saveTwo.html b/src/app/ui/collection-tools/saveTwo.html index fec97ff..ad8f075 100644 --- a/src/app/ui/collection-tools/saveTwo.html +++ b/src/app/ui/collection-tools/saveTwo.html @@ -11,7 +11,7 @@
- + {{item.name}} diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index 04d2c17..73adefd 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -315,7 +315,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.app.stage.addChild(this.grid); this.grid.drawGrid(); this.grid.onMousemove = (evt, gridCoord) => { - console.log(gridCoord); + // console.log(gridCoord); }; this.createBackgroundImage(); diff --git a/src/assets/images/其他.png b/src/assets/images/其他.png index 5b0bcbc6788b7486e3dee94f427b28128fa5d6f8..678a7dce1e5805469eb4e93250c5f4b9d97eae0f 100644 GIT binary patch literal 2280 zcmbVO3se(l7M>)$!b=;pwLWlm5EM%?Gf4TXt0V^l$(GqAWS)MdI7&f5Jk<|F`MYpNKCxo3o4ufQT6XBLNzl zrU5|kOuC>@D75Bc1mjfUBvVYOJWf_b13=mW4~r9JlmHe}cG_itZg(DoK$pgJ~X2Byds!4tksp7ms-i&?qk^j{VCp1dc+4G6R(1 zHwYG5^Fb5CQDCx4rzB8qGMJ)Qp*oFLuTKKi2$~8bsW7ThqB=~AU}`lu{)0qo99e=b zGCwzNOPm>?QbAxb7-8|AhSh4Nh*0tsE&=x_U3}aGgPGz9j%Ed# zae;nDyqGB$43OyQSO`uwK)O0^0db=PXeEG}NaT?Az@ z8z5016-|>ES&S1pq*$v=(dtlTs!pp`rjkU8lAzEOiqa)(^(ESg^Ja!9_h-SxdGbe| z&*NyZ3US9z=JD62KYg$qnins&V!V15Q>({E4jLTI7z`);m0*Afe+p0}G`>v#WCg}( z-KCUB`d{*548}7hf*a?k47;e-|C4&K=s)Z)+p$pKe~)r>?~xLpfQx;@KMXW1aS~{G zluPV$oY>GH+3(x{Amc3Ni~>*7@UCNJG59p!F-FxCW=NYXt*IWI(t5Y!38C!7;2)E# zKks)8UrkVc7kV)xM@Ph$O|_%HZvCq9g{%{a8}{Z;mMX*c{lV9|j<}TY`DeEt^z9$1 zGAeF0kNk7}mq!~?o|^o`t6|vb!`ixKtp~7ExBk{24_>>l_EbFPIr~oR?(5rr6FcqV zq)A2XH{0~H6oB_`-fnb1*>!gQ661}O;ivlNUi|HrbnN#_!c%{Ce?4LR>~hc>JFZ0Z zwmIbA$|nJl^J+W4dM+!^TmAHq_H@GWm!RBeK2|cjcG~`a*ZYTRkJcwi4rCn4eyeII zXnxnhCyCQ%wu9^B8>1%yLB6<;nnDJTPk*+0io~|zLTfjFcq3dNz2cqF;|<28-*#-T zen_8MvweAIZzHtDvP`PzmKiT;PWA@j(m9*2hc$p^@18p|TNRlR`7@j2ax>>i8jtfE zbHb9kmL>T9asK?2=DKfkwJud%OotJaoKx$YtEL0b-sqCPdo5&DMtr1lsD9J+pq)s) zcXdPf0VK`0ZANM2OI!auVq-tvCzaJd$c+kaJ=jb!p|R?-wmZ3-LV;Jd{B;+*$6LEl zW1pY4x%KMx^lL^*Xz(xPt1O{&KXD8{)8c#c^7}nTxgoeV-(y=T_XX7!d2D&|%|W%S z=Nu}3b6r>4lCwldw_9`X>*y!F-I|uReN&@6UGd+4JYYkvt@`d>>YSS~4@`*3Ywl(Nft3Qxla2Y0CZe!lD8<=btB z6EA;%^0gOc)P11i+Gg!-$$5208{2c@!k@IwcHf=u-n+9O4&k)yWPfz*=BEdGpD#S* ztxT_4h1R@B6}f*E^Wis>VQ0~iBQGsYlXJ7fIh|_~_)wG{EGdF+gip7V$ zp}O>~;%pn9C0P5UUkt!k8-^NZwZGWKgdL3z+bx0M_1T{;x4+(WZ{>#9fh$or5)>_+ zk}GDZkkax-j`voG5HqUZeR)x7kJA)xT@d;}CXLv>H-2Z{a{sr8CCg@R&n&9`7cJR7 AzyJUM delta 747 zcmVPx#1ZP1_K>z@;j|==^1poj7tVu*cRCodH znL%q4K^TVLNs1yE3&F*IAfgwwn9r8Xivoo0ma(|?`tsgc&>iY;06TV}L z9+wVsLLmpnfj9p7`tk0P>cBJJ1vEeDE;ObM`%NQZ9Uk#2U`F^qXrTLfNv*;Y-UPUW zxA>GGE}*re>ssTDDYuf`XC%C>R-NG+iCLAQog6CS7|Uk1Mp(Ef5m^^k&80tyt~l3GGy z0R;?iNhKlCPVnlsUMXmJqP|eYPSPVb=Mg~RP34y;1AiJTyUXg8OI0TUr3!CxlrVD& z(8+D-!V?Nzm&4Zo3K%!=4CQ5GmV~KOV9LpDS($p`e5`;u3vW4A!Vv*;8s2h5!XW{3 z9^P_D!e0S_gtx3437d2=xeACLKNpE1aK>IcZG`9rCQ69u<(c_JPKC=v6o9~q0uVS+ z00JipK!4yYz$3LPaPJ(jTm#OZ7!~5j0r2%Fur(N!Z~O3um#r`becCX=PrKEB_Z@h? zmt905w!(K!kH5a+9-g>!c61NjD~;$BSX%@hEFu*&T^?N=eZJU(7-A!UdM|DGNl2pP zNDvV~bAF8>yoK7b4@_=E1kewrq00re_2d#nU}P6SJw*>OZm!pOrCQhpv;|+AN<0hL z1>6=CkYp)!gZxDeK1t4&u00d4HfWV0Y5I9kQQ!Rx) d%17U&(r-Y@3g;l--@^a^002ovPDHLkV1n~EK_LJD diff --git a/src/assets/images/古建筑.png b/src/assets/images/古建筑.png index 0d3c068c02a3a28dd142748f3b78fbde1bcd612b..7329c511dc9ce1c220ef5c25b7a9976757eb6709 100644 GIT binary patch literal 2298 zcmbVO2~-nj9-n}K3W%)K#&S4}3k4;|BqWe|M2>`#v_=A?iq)!I&U%UD^ppp6%W*v_p#Gw3U#SI2Zv904b>@42l&IJZL2fNJ%8D=z4yDcnQ%Vqlz(MdRSmLl#98#i%hIkQS?b((=;1Gl_(n9GTfndJL z4C-i>098`81cMV*V3I}(tCfiwO#-Np!^tvvvJ6&AU^S8`M-&Qhf#stGYNGUJ)FhxlAx)#38?m<}9TQAX_ z(>&HNh>j&to@OmHZ66Jkc~oUkr}G3x1IEoIDV%n4@lV_#^e9hgA%$E4OXRRbp|rqq zBrzFLsAtHN5xIOAYNBz{R{9&zMCH$*Le}6YkNzPT#}FIMI#9u8(t#EbGKMOEK(8ke z9c`ysL9n2m^2vRpPG@Fm8)+8~xZJD^(3q)H!y2_(qL9Kv>Y7Z5k>Yri!U&^Y3km*_ zk|d5KqbLEZQCyHwxm6)iS=E{(Or=pMVe9C9J&hH6vS9Q+{(s)jW=Ww6 zQTw0f@zka#eGmi534tvgsh&Jy>B!1XfVN+zkv~uX|i4q@$3w^`0^foNv!`t!*O6YT} z(9i}>`R)e*-!(>kx}~Jy-nQ)QN$KLQH|F*Jy*p}2vLPr|^TO zi9f)sq!%wANb8uGJ8SO-#<40Y$kOz*=Ha*vUE(iK?~aC_>lx@zJMme?vSoLUG=6jc z;MMKU*UN3!N(-EU`L3I~6>h(OG$|+`panx$Ku&Bi_brwaKYcaAOyJ4Ts`)j-CQ#+Z0duZ z3woQszKq2LN8H?8O}Yjn14G};j{~a5B;MPY|Gilrc{s=U!1XkdH6{iV`Me(ZtZJ># zhxIixW(B${Cw!W>1#3vS20mDk^5xFwC*=U$O;G^G7MpZha`eO+qTd?4wd=!#E!=%WQ+_(dO= ztntfOc#6iV<_Cm7+qE`U@x6~LtTn8EBB766l>D;qpx8LkeZ(EcvsWLaFdd&`;Iz6S{Nq>f|YoOLtJm@EIIucALL#||qj>t>!SoYsAo zXj!Z8zwH|wbo=VN20wAv<=#c%bmj7vgt{$zBFlHwh&tv@ejA+Awn&9sc!V~6aK^f` zr{-ezYHg0N{n^yJ?2kc*=+!EkIQ-Psw$qme%Uuqj4WR74?S2e4_*&h?p1qnCC!;eu zMAGm4S52B1RM~c};s-JC?Y+JUN288({?H%)_}@`^@mYVsSN~ODfq!|H z_)+AE)W=iqUmV!KG4j=&Q{Mc<)u*4lk=wfEQu`GmW&5Xnm$H)v4sH_fu!Vjz)o}fM z>w$ysywNbf>TJjP^vqjLaNmROva9dWm1ke>I`zOF@YMEQCtap1{pGckD&ks3d1E`@ z{jn?ki(0;ZaOL$0ac^JmrPmBA9)4Wn3cn0cqAO2?r$Th^OlZWd{DA46zY}BTZ2i8B H#jAb-*~Ck| delta 861 zcmV-j1ET!;5r_wnIDY^Eb5ch_0Itp)=>Px#1ZP1_K>z@;j|==^1poj89Z5t%RCodH zn!j!nK@i5jz1Ttmil7uw1Su#l;FdHP;zSgn7>ZCq9Eli{CV2zwCy41H2Z;n8AO#c% zOkyfZo&ecG6f{U_5CWe)%-SaSKi<7)eYw4#boTk~e7Ez>&VSDA+JFaWeIZ8a`4x-_ zdYIVcEe;Pj@PbP#Ad#oc%^4Vm))r#i`YqnQ1`l`>03r#2Nz~luFi1mif&FF^un7-n z3qTp!^=PKmh&Zjy8xf&le7$zq_UuV7VGw~XBsliz-)A9GlwOGQP8N>yL2SRN-~^#e zoDGkpxVLRIdVgIz4wm?}1PufH;|AzwZAR z2OCgCDFm81*e%1aXoP`U51`r;_!$`nXQEpwUl~~dN`EJ^AWFgSa2q)#W=Fkzq!8dT zH_w%xa(s=II&$J!G5f#Eh6>P%c{%A&9$o!`sKA-HKCCPs7y@#x&2{%DoLb{0T&=PV zlwKTIBx%nDIv$fwP{&OR#S^)&iRXA+4>E-Y0bn_y0I(cEj}nJGi;BZW2qg!< z+*R00)qh=ecgUc!FF)kZJS2q_+?Xa$2k-+wOfyj{w01Aiw&0ZWV7K_`aK1_O~6+53g}dxOrZ z{WjROD(hENR*S<05m-(r04ygI0G6ZwPf=aYo(Jad0#_G-sf*2HUq1t1czgX4`2Gzh zF)M&HdU>5iIM;c6dbYX6=73i(fP;OQ!khro>&uUaUn6_RJr?Na58&fln83^!Fm(yI z^;Tf?>!naq3ff)fV&qA5GMVP>h0Mi-*$gnX$SO~##LIGeo np#ZR)Pykp?C;%+SdIA0b-qZHT-?kul00000NkvXXu0mjfshNB@ diff --git a/src/assets/images/轨道交通.png b/src/assets/images/轨道交通.png index 9d2483a4b4edd16a945d96b2ef342fcb6423b74f..2d2f97da8df65941588c8ecd1816fc0a559ac92f 100644 GIT binary patch literal 2610 zcmbVO3se(V8omjHmm;j7fFg{MqG=nF2}vLWQ7{1$G!zjPDpiNc1R_Z$B*6r&GNK}` z77?s#0RgKh6<47`6_JMuK6bUj3W|?f5Np?}TdTELMCk;OWB0WC=$tci?|<)izyERn z|39-iCVGyu(+4`geGjVBZc~G!UY1}4V2qpfrGdg?PXHL+>bQ7Q zykZ`L5!wJ$NhIL`7OkE_0}wjPqDQe*+yo`z$!eXL`F(v86H+V1%*6r)SD}~SDQej& z1HNEYbR4!S6%#3$vt~k}7K9?u;wBWbXf-+`Vi7ZkcoAxDUFI;MA&4ne%nY|GgyI!3 zkc2SckRU+F#$dhx3K9jt!a%-A^e)8X!oeJFFb57~!$O45MR+`D5ylkacc@3Vf2Dv5twJ%X<2P;5YDZNVO%W?8H%0>Tn`mQPh92j{;zlCf zfZ-78z0o5Q1CE*qLmWY9USCwqYm*^~#CkCzXvSi-PDz-JtT)c!Qq+WtnLI8J zW^-XSFE9?~BK%;42fxD&M!4KzsDeXFlbTAXSEhh z#yNUjG7}n&BqAX+gn?2_Sr_=`x?CcOF%T-XhT1U3&Y2C#BP2ptBowlF0q~Hy3I!t9 z8BM4T!{t&jlZsD(TCGF^gHe?d3ru2Te3;AT!F-f0f`vSG5*~!Ze2lL`1*7Ms1eR{i zg4gGj|L6Jl3~H(hQOzIbvDT(FeGr-2NL_5kNcAkh(?(_*H8hkl2#Q%NLCnOgDS#`P zBg^VP9D!k4a|%w8{)fC6h8YQ!$&4EC@MJ1l|4Zs|DEm3qvK@AX^Y2~`?Y&Xrui;eR zuuexC7A1_fJX}ZhIRn+ubThK60I)qNmxjk#iaU$y3Ab?9vrQl5c`wlmMP*K>Cpa?} z&;Ho7Lz+_qIqmb~=aQN9{9tFNIM*m!cav#P)=uUG8M&e5g%>1^I_a+Lefo`0$Wi0x zKc~-M`P03#K}U^W|BGee3JBeq?!?=>dcdwvnr~O-mhPyVm3gkD$fdgf9@f*gv32f> zY@XTslAyRy&>Iot0+y`>eLh$|GPrxr@jLpbpsnzv>TJc+C0#V~bj5?V+VqaDYiVf_ zz3$g`P66fId&n2>pCY~+K&KG9?I)X;_7?4O4<*s)Ta=2vPbb)3Ger<`1QITLjGc29XWzSc?GS=Qenz``zMf{JnNsX(Bun3-UC z4@@1Tg;p%8ifWL?pIZ%FqMoQH8^9M=Z`rk~?t%t~Y#PiU&u*;r|8(glZ?IRtb;X(T zs6#e|^X<>m+FBCFc+D*e4^7tA}RuwC!pntg@wzUQgb z#A3lFmR&t-eaIB)pYOSrG&FC%pK)t?VfFoi)lNGT&lS+i*3FkZa|l)h^T=nBhQ|HMQRm zJI|oycsBlMpLHZ!P}V8@=-IeNUSeHqmAp5!v$=L$FnfKb(3N#|b?cj(&fS=)I-e!V<>46W`m_>iFQI*>O(kZhG^C$=Nm^-sx)Xv1{*4J~o|X z3G?v3x}OH$CuHZ&^srlgLd$ezxNf;zSyjI16lecu1!1wCt9Y4B=#yoij;Yz|-ID6^^oNs~Dm(IoO|g_( zve+H{9^PK@JyPzg_-ubZGK#M%eNg1$8t86Ul=d@#{!Z?j^!oP-}sEy?F6mgdiDOxuzt7h z>Q^rBdiB*z12gI8$%41@9y*ZQ0Pmms9Q{HT(OhVLxi5PBCoK)Rq^4i^5|5dhm29v7 z$xpS-x7DpFVO7S7EH|@Hh8^@x=ke(b|C{?+Q^~5@0q+l^3tLkB8Tlo^;So6cC1c_# z5m6i&3*C1n@A!snJ0tRlmuej<^D5Yzk+P?+L^AHUXcg=;h=qVgdQQX>!SQ`{t8Mci zf#*)p#8TtB2-(9x&_I_5F*Zb#4htW|W!Jsf;CP2F4+Yy>?#6Z^AKl1{nUeEWY7p@G z`m2`h9rS{nPLC@uTOw_e=nmlaxA2->_2{hXcJkq$p7TzGZBeeN?mM(jQ%#1mJ}8T* zY1B0Q__C6gMVEO|;-SgXzLbVnrM9l8bgo_FWi^+_>GOH@&Ah{V1d+9H#auPx#1ZP1_K>z@;j|==^1poj99!W$&RCod1 zo4s$-Kp4i~JCI5}Ku8c1h)gUDbYvqNBOT}p6H*IHEBGs*G~Ft;mJuq+2PSL*jDZ$*?BW8DA+?Od&t)2x0PAg6a}JiUlA zgCPL*80wq?ynhz3`2P1?VF(aW+lDx&(P0cI{qI@40A#3bL!DEAR{@SzZiSnm$IYn) z2G3lQ;S_FyeQJ+iII;+20i1!`KqO*RfIo&Rf@SysSpZAyHO>6HKO z2aZngt%`2}Q~v%B#0#PpdMtKe75aY&VXi0-@L|Jo7k)#9!1@4c9pJ+T!`L_8ydI0U z0wUUP0e`+80GUBRvY$5&cUjD^L9z-Au$R)vIim#Nh7EPWMkv4)5j$sG1u(;gNTUL{ zA|mIUD?o1pL<~Rz4TTC2h=>YEas}vg_|JdIRyZK>5lldmD}ZJ8zemFauU!Q;2C*K< z_W;2H=rm2x6EAX>^TuQfzzIOc(J(>bIdTJ%On(7<00K-j3{c}--JI>Q&H3?E4KN_` zlAIQ{l7q9*Fu;Js2qDJ@QU##C0iLF=*aAW^n^|v;Qw2Eg@E?DkNU;K>=gJC5(px|n zfRx1qJy`)smH?svq%;Pwow16bB0wiBum6fzFNRnH?Rwn?(lJ-_R zQGWnqWKV!H5*uOSdLX$1oXh}Ai9@!4BmgNni2=!s0FnTt>?8#wGXmH%*#Ci~fMoW) zfFC4W0X)11aOW1N^65+e18NCLZ;mG_z`p^O1Rw#;RbW7AciEf{NG1f(dIPMv6%J_a zE~f*MNdXN1v-5E@x59yl@wI6pQ$Ap`et+Z=6;J_+yUU3M(NF+s01{{vaQBtZJrR%$ z1&{_Hfg%hrpye&&0m-NZl)eBd!TRB|Mdb}pa>%z3E*^EAS$o|)cnPb z{>7#zfMx(v0TcApLO{|Jfb$7_8dWesPq^lu0BKWM zTkQa(5+>NE7m!%V8{lb*G{7SMh7U+=y!=(Ots)IDpxI(^8ywojbFdc&1-l@`-K#00009*dEiKh!-QA6Ecc&17;R*)xI@=!fJDi?&09kv1Q+B*US7f$W zuHBK#=%8mVX-mk(l8=SfaF9tvA{@5FWs292{~uJvW6Yl4Ma{9Kq?@ z0GvzNaIcH8xJo0LOgD@QUD2@3*3(6pOjG)S!AZN&b}|W6>B9KBN~876I=}+YCks)k ziQwbB4CEh-c<Z z$E!k+WU-i@m4l`jEUwTzCE@V^nG{leuz>PF97W0)4Amh_OewJL6Q^4j0C)-wjRPYK z^WO9jS(XLEuzV$MBN}xS-_|IwU?Cz&kh|7UqE(C%X7h}`w{If7#)1MVjK(8;aA{c~ z{QfXvu>^`W`FQl$j)euU&_MilPm>{aNcV>vPB(u@V(~tlZ>>QfxCNO^0!p$Ufxs4& zg*mWV-^1_US3GhR#*CzFEhc T@!WoF00000NkvXXu0mjf?5I-i literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/住建.png b/src/assets/linkageForces/住建.png new file mode 100644 index 0000000000000000000000000000000000000000..d3378a4bf0022c44541649dd2b9213a909330bd7 GIT binary patch literal 786 zcmV+t1MU2YP)CwlY7^Dr#r_04K5znV=vjRTpW>oPR6|8)z&o zr0N7=BG`!3PD>Sqc7wGPbkt2LokhiBKk%cZ46MyfZ|;$MYi2sx`R|W)NdH_bF8MUC$&XVH+mrA2ZAC@eh&;N7!f!b%jiBvFlgE} z{{r;Nx>JJeOExAf#k5Qhnh5i~Q@A%UM06zXTq`A4jEUYa2^O0UK(D-5E@%u#mq&h1Cf{EFi>9uA2cjU3lKG+sE*%t6H8wP1S?pUjm-6KWe14{xmhyGDT^b)( z-Jo^Gn>6kz#^3M1*0s~}=sD?WV-f%d&}7dkXQIyOFFv7gMmB-QyWD&* zKxlKJt$>QgyR7%+653Qq=d*vKAhyC|NE`Z zGt-YY@bXoRqa}-2n3u)g`r8Z+$8C7EP;ucSU2{D`NoL7hFRKf3@n7x0<4R-ef*B6r zN@pL2nc#=g#oX_U($Lv&&&ITng^nxSfx1dfFsm#)T=_;Q1yp3%A+>QVirdaYnsRn*6TJ#JPCYj;>Vr8+e%y{k`tf Qr2qf`07*qoM6N<$g0W0>j{pDw literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/公安.png b/src/assets/linkageForces/公安.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3a71ce38a4229e0ed72ae24316dc1ecea8ef95 GIT binary patch literal 943 zcmV;g15o^lP)p;oO~(# zPs#Fxv^0Kh&*ZPka8+k5Z5{T(=ALK1Gnt-B{d=7HXM+$z#ZSLAFm`_WMM2Ap4Q>H~ z(~5#(L3Tz_H*fL&?CgHwd5l;fUyW_O3r@WKM;Df%{AnB)407dcUWXh>apWhcR&*j(j+evt$rVKtfdn#6~mNLLK#J2K%*b*x47r ze(x1rC#vPfVqe;t3msu$>*nU_*$DPaQl(O(?We5U?l-G?rHyM0S+Aur- z*c&a-7G@W@(4J;0GdZxOoERV0a|@uE8g7|ZVdTOLe)>(q#?}&A+$uglBf&svc=J^r zJG?hQ2!Zg36TBzbLlHvwO!U1mIg#k1lnS(R1@`qT!74fEbp~2R1?_Nv;TV+TccBpm zj3mGs@LjR5{$%s=7s}787!lNqBVdKKtqEvR|IV|fOAODHGnpVvMJEs zZE5a{Edzv%8jH6tovam7yQ=8|h*|?`DrlaEUR(ra-~ho0)*`~_X{u8O>si(43cFmd zlpYGx)RzY~P;725&EQGa!1x%N7H9)Y)meUlcQ_YRtv-^K)uGOv{jvLD`U^+YYbhB~ ReX{@n002ovPDHLkV1n?iv{?WE literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/医疗.png b/src/assets/linkageForces/医疗.png new file mode 100644 index 0000000000000000000000000000000000000000..61d8034547434d694f372adfbb76619807716636 GIT binary patch literal 839 zcmV-N1GxN&P) zYem%nWmCLkl78hB1KC}(+FA@i|T_^T57GDc_pPj zL`9jcEYhVFWd%w>1u=1(w{3Z;+}swMTfC3;W`5~>d(Lyt?>TUO4}}?_iwKRPLqiJr zD`S(mVzGj`cAHHG`IA|Apm`Hd_(Z{n^|nL+lArM)A-&{2T&A*TX#TwvKSm+-@lOE8I22CwAs{` zMe~#>P?8LQ#^T= zL;3i?<87(BdF?Y&HZQJOYlN9~iNWYZL1! zU4%3$=-lOx>>9mZSWX>>{kax0bsYhWUakOFXw8;Svc>A`oJz^ESBM#^sUd$N0$aA-f<${T;Xrb*Sb`}13G|Dpdga(gyCl1I#@?}v17ye zK9{*Dibydr8IO|29=M{jBPa6)yz{)^tQ4G`f`)P+9tQLRkOR^z9$b}x+~NeRe58h< z`f)y?QBha-Y#)_0w^@NHC6__9JmBzELqFITN&+JJG$G*IB-HF$fx9F7@ON?34Pu); z(N>Wb7dh+tTTCvk?3bJYp0x__m0l1RAg+=@DDm`5&KRn*l5u;&Fr?;HKPUFMXxrZO z@W}bs?U-+Q_;qIfci%@ecwUU*Tr^OIc7=wmfX^_=Zndu;={O4j7;b z0-Rl7G8rHjK>B(H?k*loMRT|UX-68ZM2d^wb>NS{ef9u~!t4j&+#<@?#^AKcjjK7G zcx4)mGt&hK?>-{)Pz#t!iL}C47&|y@DQhbt?AS4FW8H;k);W50P|FJ#?{#3?3JFsj zzhL4kfFm+gg>{0dl}M@S!)ucsPD2D{TJDSb#3jc5kF;=ccGmh~c~p?Ybfp<{D&Jtu zKSL29a`?o#;L<2i@n0`21&i=h;lS`7hAgwq%-_D1=_g=}@%Pe~m6uKOrZjXlA)`f) zH-RGl59xr&yqNZ31fmg&qVR_>sbaC|Quk#kw=~&kGA73yGu zTkJtkfD9BAfetsg;1THLU1F?YC~e=kai<|E$^Ctpc$;l^#{rejRJNOH}Q(~kK8;5-W0000NcruyXoRL73sf9+Z-xmwK2YWkV=6Gz_|cO69GKIa5m? z>?MSRd`O%oMN|}CDw9-nsdMvwX}a7065CKWiGFYAch33z&N;vDA=q++w8&U{s62;? zKc+;GMDBFY8g=})kKLG^tY+HA`rT8=x-pg{7e~a#Xvmo?6?Nh?Kzn(jZC3E_+Q7Z6 zY0?jmUXJS4SsVdQfFoHJuXs%tX_Q1F-AEJ!0amLOVzGGhZq5LP5^r; zxsfVvR=Fpe&1PsS?qg=4A30@@Ad|^FA-6J{n3^{k#FiQrM_(!Hqm*Yi0t^NN9_FcW z)G`i6Cda4YDWu=kK%r1<#PHe{Q04gth%MuIy{NW53yk-M(^2-MDiOx$gRmqdLH?u= z+iE)@iH_Nv3&+BKF}aqoRRzQJ)qBy-Rt9^3=}8Cx=IctpPEUXbKr!BssBgn7AP9ok z7osCdCy1*q8X;_RrJX*X>m0eMEDsfHJR(=-!BG^3g2N#-Eh5Bh!m`*G zoz?|-QN?-!%Ja}VIfWf-E8qx$-aiQ2Eo%t0n_*(aSn&2k`ic?3_3nVjMZXSZ0wgFMdXLbj9j*!<6pj!!Gf_j=b!Iz+;{X&} zDC}LH0mHHQDviSK18*C>f(=YIjhzofjr54-m5(a`7ADw3EA;wCJIU*K5q zZ(G5?YG~5`{N=e!?oZlMqT&!9nL`~qoPNob$ss!tw^t{Chg+`?(u&CAooAD TV1yZR00000NkvXXu0mjf&q#8$ literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/应急管理.png b/src/assets/linkageForces/应急管理.png new file mode 100644 index 0000000000000000000000000000000000000000..3cd54b850ce91319c687801e1bf126784d03cf18 GIT binary patch literal 901 zcmV;01A6?4P)ariQMq2#=_(w^a z3kMq|r=_f^tY&llxFv(OenCQjC|vGl;(_){gyZhM-}^r8&Q<91$Fn`p^ZvZHXM4W{ z_bjtVu5qry>nWmq#eJ+!JYTy>uz!f&z)jlJFU9cU5%J%lOj_3G(7wBpnynkbXtt;M}4HWwoyC)=7NIoV<678GuW74A<{2~OMi=uJVs<1+gE1l@z> z>}s{;iO06d&Vd7cyHczcZi#j5>s;W{RfR332A=U4l3zLTRh)C*tE_oQqiKhorTP$B zY>vV`r5&QKRZbqM3pml|`Q*p7G_*-xtJc_9Y~j!HLYJBT;V3P~&9r(IDvHJt ziizEwu7GGdCe^)94;Y1FX77nSy3R=sy{L2GW5`|^$DXQk@k$B})q?tW4R|Y|rRoyI zBkcdINJ|3tZ5cOWu<}mND!%?{fu@~S7NU~p4+_$ks2<4b z#3yS1uW}w|yWi5w9kwat>@XrF17XbqT}4J`kddn>%N{2*mrYfZ@b`}{s`9@+6s)Gb zp^BQyGO(EMmPw04w;v9l!Z-Nqy)rGznmn?=nT2tzg}M00000NkvXXu0mjfF_ODB literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/民政.png b/src/assets/linkageForces/民政.png new file mode 100644 index 0000000000000000000000000000000000000000..790924f3ab1304d90dc5caaccc330a0ad9b2d2f2 GIT binary patch literal 827 zcmV-B1H}A^P)ugd)*ow2# zMX4#d(PB|FlwK4s)J8;5u(OPo>bwwiTkA)v)hd4Eea4#?r+6`TZVu;g{=f5ozJ!mK zHaCB1cAseA^DnBIHOnQ2Av!Vfw~miz9o5xINvDTCl*qe-syfWotACXF^Y_ry^eH|c z8jr)s2y}EHxg7fQPk9~uE$!I1FDl{il%*{IEOFlNKg!mvwRk)jB_%d@`SQZ1i3Adh zVV*q;xyR_q?tW)``?nGZJSza+`2BGs7;K@m6uo~RsjNiG%FxDWodOZe>(`Ol zv(dYE;n1NT=jiBmd3o%ZyQr^kR9jm=vFu7k1+=xn#fuOO!h!|R)rGEDfsszzE{cnh z3l}hRxvwR^?5kfm-WAnHj}WI5u>@W(>hU0hgLVjhKXUad98aMeH=tLpAm!yqDAX@` zulILOpI%8ei)`8i4mXVxBt(GiSo#!w)21RrORdna_Cf z0$H>Oy>Y_^oIC;Fg=|1J3xR+QsH;OKCSYhxw*7J@9+O_z^_T9z77qAP_GvT1|G}XB}-BgiR_R}1`ZxXi;BSd;rj*% zM+)V$LePc=B(@vo%|#C!fK{uIOP4Oo>&C_k$H?#?fBt1ySywCOKmd)!Fz($e0Mxe@ zjVF-v=aE;hP?rncyxB_lH-$!eTfQa002ovPDHLk FV1l%9jU500 literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/气象局.png b/src/assets/linkageForces/气象局.png new file mode 100644 index 0000000000000000000000000000000000000000..654a1987e287ee5e44c95100423bf71e218ac3cf GIT binary patch literal 901 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 literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/环保局.png b/src/assets/linkageForces/环保局.png new file mode 100644 index 0000000000000000000000000000000000000000..21d6bbdcdcb54be773f4d310da1bbf8eb172c1ee GIT binary patch literal 1068 zcmV+{1k?M8P)*m_j1`1!Be#s^=2H}$~bOo70@3E2DFsq)m|*gwA0 zb{s`Lloy}iXs_l~?1vBnHKGO;pn`h2vAk@;ZqE0{$w%^p-1=_)aGECj@G($1)D){V z>rxGl#X^^J4U_tbI)&llh6_V2RaU2U8$uzNH_7haC6yhWpE2b2J=X4G5-d*|FR~GE z$zdRGuT$BfJ8XVwA(la-Pwz~4NqwZVw$Hid;^hS-%V>b^Y%&kD0u*%>CFdoLPffhN z=(44X{I_U17()+=d(Kr48MIa=N@R!n1eW*D-`hQ5oh=F>d1D5-CT8Qskn;sM4Gv3k zgm>UiuY{*p4nEX=zT~#)q(L!u@W!?3Zy&9iquC6vw&J**7ZtzP+?aJ*BM^#0#J<5A z2%&r0W-NpV0RA}3cq#8hOm*)CmB+m%;nO)QKz2o4OQ0B=hG3RBKhfC+?bTMJ%Nh|# z^BUvQSu=c+dsDw+mQ6bsw(<$~?7@^br6W^+9awfcV!W7a9Z=q=ukSV9O-E6%T9u)c zmvqz>KXg3a_g-Q_k!jVo3;_i=7<={7=r0;yoZb0Js^a~sp&v9Z%EOoP#KWMl^|ZTMgH=y~SB3-XJE{Tf2Os=fsN=fFu+e;68&fo4*L)E5pDLu9cfDq!ZUQvJXOxUwErxIS%E86ReBe}uL6P5>2 zI7+O$C=bD;G10p1MXJ*?J%L@fx<2|eO{tPRsqzLyr_&L~N1Km0aZ3L|lA_sc8ugj7 zm}xjhLm3p}@bdL{{%q*W0uFbqJUpi=QzH3Srl<8RY5g+Zkqp%U literal 0 HcmV?d00001 diff --git a/src/assets/linkageForces/电力局.png b/src/assets/linkageForces/电力局.png new file mode 100644 index 0000000000000000000000000000000000000000..69f21cdda2d3eb603ce4224b1abc3eafa47e477f GIT binary patch literal 920 zcmV;J184k+P)ctNfslgWZ2 z{t&`{KZ4BIy^v%i1J*YGI~}00&~-Y}qhdZ2*~N3+X@yEh69F#9#UnB!2|3ck2s!@C zzXHQ4%mDe*gouTHkcDkVF;#6O6-|vV6Xa)S@Ht%U3S5OvNr}imm6U# z*kChl(bx9{)Z1n#%I?Di0$bJ?$ig;WA<8Do>uGge%@jVLv2MN?*>`S11T@mspyBB0f3?TQ*+6sIZ+7P)bGsQlv< zvf`wuX==o=f~$Zv3t#}CX}EHDkcNh<7r1+hy##`ukyp~7*N?4js81`YtCmnLEmj>J zZ74jNiaS&lPTtIe9m@`ZGiM>tdw!lf&pF!H!{g(~XBvIk#kJKwJ)ewGtsiuYb=?N1 uAm6#fU^Mo885(+I?_hr}SmdJ`jsFY3l~bhn|Ke!?0000*mB{VC#IqL!`&dJs+&Li6s*0B|~C$xov@fL!uJgu1^bdqHIwIAkCm z;HJOw_RY||7gQmeg}^Gf_Y&TJ@!^$$ge4~>)~yj$CcIE}In Date: Sat, 23 Jan 2021 18:27:53 +0800 Subject: [PATCH 4/7] axSelection,axMessageSystem --- .../working-area/model/axImageShapeTest.ts | 11 - src/app/working-area/model/axLegend.ts | 1 - src/app/working-area/model/axMessageSystem.ts | 90 +++++ .../working-area/model/axRectangleShape.ts | 24 +- src/app/working-area/model/axSelection.ts | 48 +++ src/app/working-area/model/axShape.ts | 58 +-- src/app/working-area/model/messageSystem.ts | 37 -- .../working-area/working-area.component.ts | 347 +++++++----------- 8 files changed, 321 insertions(+), 295 deletions(-) delete mode 100644 src/app/working-area/model/axImageShapeTest.ts create mode 100644 src/app/working-area/model/axMessageSystem.ts create mode 100644 src/app/working-area/model/axSelection.ts delete mode 100644 src/app/working-area/model/messageSystem.ts diff --git a/src/app/working-area/model/axImageShapeTest.ts b/src/app/working-area/model/axImageShapeTest.ts deleted file mode 100644 index 81c141c..0000000 --- a/src/app/working-area/model/axImageShapeTest.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { AxRectangleShape } from "./axRectangleShape"; - -export class AxImageShapeTest extends AxRectangleShape{ - /** - * - */ - constructor(x:number,y:number,width:number,height:number) { - super(x,y,width,height); - - } -} \ No newline at end of file diff --git a/src/app/working-area/model/axLegend.ts b/src/app/working-area/model/axLegend.ts index a886fd3..f2158ac 100644 --- a/src/app/working-area/model/axLegend.ts +++ b/src/app/working-area/model/axLegend.ts @@ -429,7 +429,6 @@ export class AxLegend extends AxShape { */ public drawBorder(scale: number) { const visible = this.upLeft.visible; - console.log(visible); this.setPointVisiable(false); super.drawBorder(scale); diff --git a/src/app/working-area/model/axMessageSystem.ts b/src/app/working-area/model/axMessageSystem.ts new file mode 100644 index 0000000..1451f9c --- /dev/null +++ b/src/app/working-area/model/axMessageSystem.ts @@ -0,0 +1,90 @@ +/** + * 事件系统 + */ +export class AxMessageSystem { + /** 监听数组 */ + private static listeners = {}; + + /** + * 注册事件 + * @param name 事件名称 + * @param callback 回调函数 + * @param context 上下文 + */ + public static addListener(name: string, callback: () => void, context: any) { + const observers: Observer[] = AxMessageSystem.listeners[name]; + if (!observers) { + AxMessageSystem.listeners[name] = []; + } + AxMessageSystem.listeners[name].push(new Observer(callback, context)); + } + + /** + * 移除事件 + * @param name 事件名称 + * @param callback 回调函数 + * @param context 上下文 + */ + public static removeListener(name: string, callback: () => void, context: any) { + const observers: Observer[] = AxMessageSystem.listeners[name]; + if (!observers) { return; } + const length = observers.length; + for (let i = 0; i < length; i++) { + const observer = observers[i]; + if (observer.compar(context)) { + observers.splice(i, 1); + break; + } + } + if (observers.length === 0) { + delete AxMessageSystem.listeners[name]; + } + } + + /** + * 发送事件 + * @param name 事件名称 + */ + public static send(name: string, ...args: any[]) { + const observers: Observer[] = AxMessageSystem.listeners[name]; + if (!observers) { return; } + const length = observers.length; + for (let i = 0; i < length; i++) { + const observer = observers[i]; + observer.notify(name, ...args); + } + } +} + +/** + * 观察者 + */ +class Observer { + /** 回调函数 */ + private callback: () => void; + /** 上下文 */ + private context: any = null; + + constructor(callback: () => void, context: any) { + const self = this; + self.callback = callback; + self.context = context; + } + + /** + * 发送通知 + * @param args 不定参数 + */ + notify(...args: any[]): void { + const self = this; + self.callback.call(self.context, ...args); + } + + /** + * 上下文比较 + * @param context 上下文 + */ + compar(context: any): boolean { + return context === this.context; + } +} diff --git a/src/app/working-area/model/axRectangleShape.ts b/src/app/working-area/model/axRectangleShape.ts index 297ffdb..cf61f6c 100644 --- a/src/app/working-area/model/axRectangleShape.ts +++ b/src/app/working-area/model/axRectangleShape.ts @@ -1,21 +1,21 @@ -import { Sprite } from "pixi.js"; -import { Graphics } from "pixi.js"; -import { WorkingAreaComponent } from "../working-area.component"; -import { AxShape } from "./axShape"; +import { Sprite } from 'pixi.js'; +import { Graphics } from 'pixi.js'; +import { WorkingAreaComponent } from '../working-area.component'; +import { AxShape } from './axShape'; -export class AxRectangleShape extends AxShape{ +export class AxRectangleShape extends AxShape { /** * */ - constructor(x:number,y:number,width:number,height:number,assetData: any, workingArea: WorkingAreaComponent) { - super(assetData,workingArea); - this.beginFill(0x0000ff,1); - this.lineStyle(1, 0xff0000,1); + constructor(x: number, y: number, width: number, height: number, assetData: any, workingArea: WorkingAreaComponent) { + super(assetData, workingArea); + this.beginFill(0x0000ff, 1); + this.lineStyle(1, 0xff0000, 1); this.drawRect(x, y, width, height); this.endFill(); - - + + } - + } diff --git a/src/app/working-area/model/axSelection.ts b/src/app/working-area/model/axSelection.ts new file mode 100644 index 0000000..e61cd78 --- /dev/null +++ b/src/app/working-area/model/axSelection.ts @@ -0,0 +1,48 @@ +/** + * 选择器 + */ +export class AxSelection { + constructor() { + } + private objects: Set = new Set(); + // 获得第一个对象 + public first(): any { + if (this.objects.size > 0) { + return this.objects[0]; + } else { + return null; + } + } + // 获得所有对象 + public all() { + return this.objects; + } + // 获取集合长度 + public size(): number { + return this.objects.size; + } + // 添加对象 + public add(obj: any) { + this.objects.add(obj); + } + // 添加集合 + public addArray(array: any[]) { + array.forEach(item => { + this.objects.add(item); + }); + } + // 移除对象 + public delete(obj: any) { + this.objects.delete(obj); + } + // 移除集合 + public deleteArray(array: any[]) { + array.forEach(item => { + this.objects.delete(item); + }); + } + // 清空所有对象 + public clear() { + this.objects.clear(); + } +} diff --git a/src/app/working-area/model/axShape.ts b/src/app/working-area/model/axShape.ts index 27c1773..2d032d5 100644 --- a/src/app/working-area/model/axShape.ts +++ b/src/app/working-area/model/axShape.ts @@ -8,7 +8,7 @@ import { WorkingAreaComponent } from '../working-area.component'; */ export class AxShape extends Graphics { assetData: any; - pointTexture: PIXI.Texture = PIXI.Texture.from('assets/images/handle-main.png') + pointTexture: PIXI.Texture = PIXI.Texture.from('assets/images/handle-main.png'); workingArea: WorkingAreaComponent; // 可以被移动的 moveable = true; @@ -20,7 +20,7 @@ export class AxShape extends Graphics { showName = true; // 边框 border: PIXI.Graphics = new PIXI.Graphics(); - + constructor(assetData: any, workingArea: WorkingAreaComponent) { super(); this.border.visible = false; @@ -35,7 +35,7 @@ export class AxShape extends Graphics { .on('pointerdown', event => { event.stopPropagation(); if (this.selectable) { - this.workingArea.selection.selectOne(this); + this.workingArea.selectSingle(this); } if (this.moveable) { event.currentTarget.data = event.data; @@ -86,14 +86,14 @@ export class AxShape extends Graphics { }); } redraw(): void { - + } - refresh(): void{ - + refresh(): void { + } public setItemScale(scale: number) { - + } public showBorder() { @@ -110,10 +110,10 @@ export class AxShape extends Graphics { * @param value 显示状态 */ public setPointVisiable(value: boolean) { - + } /** - * + * * @param rect 画边框 */ public drawBorder(scale: number) { @@ -127,14 +127,14 @@ export class AxShape extends Graphics { this.border.lineStyle(scale * 1, 0x00a8ff); - var spaceLength = scale * 1; - var lineLenght = rect.width + 0.5 + 0.5; - var dashLength = scale*( lineLenght +spaceLength - Math.floor((rect.width + rect.height)/2 / 4.1))/Math.floor((rect.width + rect.height)/2 / 4.1); - this.drawDash(this.border, p1.x -0.5*scale, p1.y, p2.x + 0.5*scale, p2.y,dashLength,spaceLength); - this.drawDash(this.border, p2.x, p2.y -0.5*scale, p3.x, p3.y + 0.5*scale, dashLength, spaceLength); - this.drawDash(this.border, p3.x+0.5*scale, p3.y, p4.x - 0.5*scale, p4.y, dashLength, spaceLength); - this.drawDash(this.border, p4.x, p4.y + 0.5*scale, p1.x, p1.y - 0.5*scale, dashLength, spaceLength); - + let spaceLength = scale * 1; + let lineLenght = rect.width + 0.5 + 0.5; + let dashLength = scale * ( lineLenght + spaceLength - Math.floor((rect.width + rect.height) / 2 / 4.1)) / Math.floor((rect.width + rect.height) / 2 / 4.1); + this.drawDash(this.border, p1.x - 0.5 * scale, p1.y, p2.x + 0.5 * scale, p2.y, dashLength, spaceLength); + this.drawDash(this.border, p2.x, p2.y - 0.5 * scale, p3.x, p3.y + 0.5 * scale, dashLength, spaceLength); + this.drawDash(this.border, p3.x + 0.5 * scale, p3.y, p4.x - 0.5 * scale, p4.y, dashLength, spaceLength); + this.drawDash(this.border, p4.x, p4.y + 0.5 * scale, p1.x, p1.y - 0.5 * scale, dashLength, spaceLength); + this.border.lineStyle(0, 0x0000ff); // this.border.beginFill(0x00ff00,0.1); this.border.moveTo(p1.x, p1.y); @@ -145,19 +145,19 @@ export class AxShape extends Graphics { // this.border.endFill(); } // 画虚线 - drawDash(target, x1, y1, x2, y2,dashLength = 5, spaceLength = 1) { - let x = x2 - x1; - let y = y2 - y1; + drawDash(target, x1, y1, x2, y2, dashLength = 5, spaceLength = 1) { + const x = x2 - x1; + const y = y2 - y1; let hyp = Math.sqrt((x) * (x) + (y) * (y)); - let units = hyp / (dashLength + spaceLength); - let dashSpaceRatio = dashLength / (dashLength + spaceLength); - let dashX = (x / units) * dashSpaceRatio; - let spaceX = (x / units) - dashX; - let dashY = (y / units) * dashSpaceRatio; - let spaceY = (y / units) - dashY; + const units = hyp / (dashLength + spaceLength); + const dashSpaceRatio = dashLength / (dashLength + spaceLength); + const dashX = (x / units) * dashSpaceRatio; + const spaceX = (x / units) - dashX; + const dashY = (y / units) * dashSpaceRatio; + const spaceY = (y / units) - dashY; target.moveTo(x1, y1); - + while (hyp > 0) { x1 += dashX; y1 += dashY; @@ -200,7 +200,7 @@ export class AxShape extends Graphics { return new PIXI.Point(gravityLat, gravityLng); } // 计算线段中点坐标 - public getLineCenter(point1:PIXI.Point,point2:PIXI.Point) { - return new PIXI.Point((point1.x+point2.x)/2,(point1.y+point2.y)/2) + public getLineCenter(point1: PIXI.Point, point2: PIXI.Point) { + return new PIXI.Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2); } } diff --git a/src/app/working-area/model/messageSystem.ts b/src/app/working-area/model/messageSystem.ts deleted file mode 100644 index 322eef4..0000000 --- a/src/app/working-area/model/messageSystem.ts +++ /dev/null @@ -1,37 +0,0 @@ -class MyEvent extends CustomEvent { - public static readonly CMD: string = "EVENT_NAME"; - public constructor($type: string , $data: T ) { - super( $type , { detail: $data, bubbles: true, cancelable: true, composed: true }); - } -} - -class MyDispatch extends EventTarget { - private static _instance: MyDispatch; - public static get Instance(): MyDispatch { - if (!MyDispatch._instance) MyDispatch._instance = new MyDispatch(); - return MyDispatch._instance; - } - public send($data: T, $type: string = MyEvent.CMD): void { - const $event: CustomEvent = new MyEvent($type, $data); - this.dispatchEvent($event); - } -} - -class Test { - - public constructor() { - MyDispatch.Instance.addEventListener(MyEvent.CMD, this.onEvent as EventListener); - } - private onEvent($e: MyEvent): void { - console.log(`target ${$e.target}`); - console.log(`name: ${$e.detail._name} , occupation: ${$e.detail._occupation}`); - } -} - -interface ITest { - _name: string; - _occupation: string; -} - -let $test: Test = new Test(); -MyDispatch.Instance.send({ _name: `Aonaufly`, _occupation: `it` }); diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index adaa4d7..1b05d4c 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -16,9 +16,9 @@ import { PropertyInfo } from './model/PropertyInfo'; import { AxPreviewImageShape } from './model/axPreviewImageShape'; import { AxArrowConnector } from './model/axArrowConnector'; import { AxLegend, Legend } from './model/axLegend'; -import { NullTemplateVisitor } from '@angular/compiler'; -import { AxRectangleShape } from './model/axRectangleShape'; import { AxGrid } from './model/axGrid'; +import { AxSelection } from './model/axSelection'; +import { AxMessageSystem } from './model/axMessageSystem'; @Component({ @@ -76,7 +76,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV /** * 选择器 */ - public selection: Selection = new Selection(this); + public readonly selection: AxSelection = new AxSelection(); /** * 当前鼠标的点 */ @@ -141,6 +141,9 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * 网格 */ public grid: AxGrid = null; + // 是否按下Ctrl键 + isCtrlKeyClicked = false; + isMove = false; /** * 本软件版本号由四部分组成:<主版本号><次版本号><修订版本号><日期加希腊字母版本号> 例如:1.0.0.20210105_beta * Alpha版: 此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。 @@ -157,12 +160,12 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.sayHello(); this.eventManager.addGlobalEventListener('window', 'keydown', (event: any) => { if (event.keyCode === 17) { - this.selection.isMultiselection = true; + this.isCtrlKeyClicked = true; } }); this.eventManager.addGlobalEventListener('window', 'keyup', (event: any) => { if (event.keyCode === 17) { - this.selection.isMultiselection = false; + this.isCtrlKeyClicked = false; this.rectToolGraphics.visible = false; this.rectToolGraphics.clear(); } @@ -171,23 +174,56 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.deleteSelectedShape(); } }); + // 消息系统事件监听 + AxMessageSystem.addListener(CanvasAction.selectionChanged, () => { + this.selection.all().forEach(item => { + item.showBorder(); + item.drawBorder(1 / this.backgroundImage.scale.x); + item.setPointVisiable(this.allowEdit); + }); + }, this); } /** * 删除选中的图标 */ public deleteSelectedShape() { - this.selection.objects.forEach(item => { - this.deleteShape(item); - }); - this.selection.deselectAll(); - } - /** - * - * @param obj 删除一个形状 - */ - public deleteShape(shape) { - if (this.allowEdit && this.canvasData.gameMode === shape.assetData.GameMode) { - this.emit('deleteIcon', shape); + if (this.selection.all().size > 0) { + this.selection.all().forEach(axShape => { + if (this.allowEdit && this.canvasData.gameMode === axShape.assetData.GameMode) { + // 删除图例对象 + const temp = this.backgroundImage.getChildByName('图例') as AxLegend; + if ( temp !== undefined + && temp !== null + && axShape.assetData.Name !== '图例') { + const itemLegend = new Legend(axShape.assetData.Name, axShape.assetData.ImageUrl, 1); + temp.deleteItem(itemLegend); + } + if (axShape.assetData.GameMode === GameMode.BasicInformation) { // 基本信息 + // 删除楼层数据 + delete this.canvasData.originaleveryStoreyData.data[axShape.assetData.Id]; + // 删除建筑数据 + delete this.canvasData.originalcompanyBuildingData.data[axShape.assetData.Id]; + } else if (axShape.assetData.GameMode === GameMode.Assignment) { // 处置预案 + delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; + delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; + delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; + } else if (axShape.assetData.GameMode === GameMode.Examinee) { // 考生考试 + if (axShape.assetData.Tag === 1) { + // 删除楼层数据 + delete this.canvasData.examOriginaleveryStoreyData.data[axShape.assetData.Id]; + } else { + delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; + delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; + delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; + } + } + this.backgroundImage.removeChild(axShape); + } + }); + this.selection.clear(); + this.emit('canvasDataChanged'); + this.canvasData.isChange = true; + AxMessageSystem.send(CanvasAction.selectionChanged); } } /** @@ -315,7 +351,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.app.stage.addChild(this.grid); this.grid.drawGrid(); this.grid.onMousemove = (evt, gridCoord) => { - console.log(gridCoord); + }; this.createBackgroundImage(); @@ -419,39 +455,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * 删除图标事件(数据处理) */ this.on('deleteIcon', (axShape: AxShape) => { - // 删除图例对象 - const temp = this.backgroundImage.getChildByName('图例') as AxLegend; - if ( temp !== undefined - && temp !== null - && axShape.assetData.Name !== '图例') { - const itemLegend = new Legend(axShape.assetData.Name, axShape.assetData.ImageUrl, 1); - temp.deleteItem(itemLegend); - } - - if (axShape.assetData.GameMode === GameMode.BasicInformation) { // 基本信息 - // 删除楼层数据 - delete this.canvasData.originaleveryStoreyData.data[axShape.assetData.Id]; - // 删除建筑数据 - delete this.canvasData.originalcompanyBuildingData.data[axShape.assetData.Id]; - } else if (axShape.assetData.GameMode === GameMode.Assignment) { // 处置预案 - delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; - delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; - delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; - } else if (axShape.assetData.GameMode === GameMode.Examinee) { // 考生考试 - if (axShape.assetData.Tag === 1) { - // 删除楼层数据 - delete this.canvasData.examOriginaleveryStoreyData.data[axShape.assetData.Id]; - } else { - delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; - delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; - delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; - } - - } - this.backgroundImage.removeChild(axShape); - this.emit('canvasDataChanged'); - this.canvasData.isChange = true; }); } /** @@ -514,17 +518,16 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV }); } /** - * 设置高亮 + * 设置选中 + * 清空所有选择对象,选择ids集合元素 */ public setHighlight(ids: string[]): void { - this.selection.deselectAll(); + this.selection.clear(); ids.forEach(item => { - let obj = this.backgroundImage.getChildByName(item); - if (obj === null) { - obj = this.app.stage.getChildByName(item); - } - this.selection.select(obj); + const obj = this.backgroundImage.getChildByName(item); + this.selection.add(obj); }); + AxMessageSystem.send(''); } /** * 创建楼层图形 @@ -631,10 +634,9 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV .on('pointerdown', event => { if (event.data.button !== 0) { return; } console.log(this.backgroundImage.toLocal(this.mousePosition)); - if (!event.currentTarget.dragging && this.selection.isMultiselection === false) { - this.selection.deselectAll(); + if (!this.isMove && this.isCtrlKeyClicked === false) { event.currentTarget.data = event.data; - event.currentTarget.dragging = true; + this.isMove = true; event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent); event.currentTarget.dragPoint.x -= event.currentTarget.x; event.currentTarget.dragPoint.y -= event.currentTarget.y; @@ -828,18 +830,17 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV // this.emit('backgroundScale', this.backgroundImage.scale.x); break; } - } else if (!event.currentTarget.dragging && this.selection.isMultiselection === true) { + } else if (!this.isMove && this.isCtrlKeyClicked === true) { this.rectToolGraphics.visible = true; - event.currentTarget.dragging = true; + this.isMove = true; this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); } }) .on('pointerup', event => { - if (event.currentTarget.dragging) { - event.currentTarget.dragging = false; - event.currentTarget.data = null; - } + this.isMove = false; + event.currentTarget.data = null; + if (this.rectToolGraphics.visible === true) { this.backgroundImage.children.forEach(item => { if ( item instanceof AxImageShape @@ -850,26 +851,27 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV const rect1 = this.rectToolGraphics.getBounds(); const rect2 = item.getBounds(); if (this.isOverlap(rect1, rect2)) { - this.selection.select(item); + this.selection.add(item); } } }); this.rectToolGraphics.clear(); this.rectToolGraphics.visible = false; + AxMessageSystem.send(CanvasAction.selectionChanged); } }) .on('pointerupoutside', event => { - if (event.currentTarget.dragging) { - event.currentTarget.dragging = false; + if (this.isMove) { + this.isMove = false; event.currentTarget.data = null; } }) .on('pointermove', event => { - if (event.currentTarget.dragging && this.selection.isMultiselection === false) { + if (this.isMove && this.isCtrlKeyClicked === false) { const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent); event.currentTarget.x = newPosition.x - event.currentTarget.dragPoint.x; event.currentTarget.y = newPosition.y - event.currentTarget.dragPoint.y; - } else if (event.currentTarget.dragging && this.selection.isMultiselection === true) { + } else if (this.isMove && this.isCtrlKeyClicked === true) { if (this.rectToolGraphics.visible === true) { this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); } @@ -877,7 +879,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV }) .on('rightclick', event => { event.stopPropagation(); - this.selection.deselectAll(); + this.deselectAll(); this.setPaintMode(PaintMode.endPaint); }) .on('pointerover', (event) => { @@ -951,11 +953,11 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * @param imageUrl * @param imageAngle */ - public async refresh(imageUrl: string = this.canvasData.selectStorey.imageUrl, imageAngle: number = this.canvasData.selectStorey.imageAngle): Promise { + public async refresh(imageUrl: string = this.canvasData.selectStorey.imageUrl, + imageAngle: number = this.canvasData.selectStorey.imageAngle): Promise { await this.refreshBackgroundImage(); - // 清空所有图形 - this.selection.deselectAll(); + this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { @@ -978,10 +980,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * 加载无关联信息处置预案 * @data 处置预案数据 */ - public async loadNoRelevantInformationDisposalPlan(data:DisposalNodeData): Promise { - await this.refreshBackgroundImage(data.BackgroundImageUrl,data.BackgroundImageAngle); + public async loadNoRelevantInformationDisposalPlan(data: DisposalNodeData): Promise { + await this.refreshBackgroundImage(data.BackgroundImageUrl, data.BackgroundImageAngle); // 清空所有图形 - this.selection.deselectAll(); + this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { @@ -1142,7 +1144,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV */ public beginPaint() { console.log(this.canvasData.selectTemplateData); - this.selection.deselectAll(); + this.deselectAll(); this.setPaintMode(PaintMode.endPaint); this.setPaintMode(this.canvasData.selectTemplateData.interactiveMode); } @@ -1291,49 +1293,52 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * 复制 */ public copy(): void { - this.copyData = []; - this.selection.objects.forEach(item => { - const newData = JSON.parse(JSON.stringify(item.assetData)); - this.copyData.push(newData); - }); + this.copyData = []; + this.selection.all().forEach(item => { + const newData = JSON.parse(JSON.stringify(item.assetData)); + this.copyData.push(newData); + }); } /** * 粘贴 */ public paste(companyId: string, buildingId: string, floorId: string): void { - this.copyData.forEach(item => { - item.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); - const newData = JSON.parse(JSON.stringify(item)); - newData.Id = ObjectID.default.generate(), - newData.CompanyId = companyId; - newData.BuildingId = buildingId; - newData.FloorId = floorId; - newData.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); - switch (item.InteractiveMode) { - case PaintMode.singlePointIcon: - const singleIcon = new AxImageShape(newData, this); - this.emit('createIcon', singleIcon); - break; - case PaintMode.lineIcon: - const lineIcon = new MultipointIcon(newData, this); - this.emit('createIcon', lineIcon); - break; - case PaintMode.polygonIcon: - const polygonIcon = new PolygonIcon(newData, this); - this.emit('createIcon', polygonIcon); - break; - case PaintMode.Pipeline: - if (item.Name === '距离') { - const wall = new AxArrowConnector(newData, this, true, true); - this.emit('createIcon', wall); - } else if (item.Name === '普通墙' || item.Name === '承重墙') { - const wall = new AxArrowConnector(newData, this, false, false); - this.emit('createIcon', wall); - } - break; - } - this.selection.select(this.backgroundImage.getChildByName(newData.Id)); - }); + if (this.copyData.length > 0) { + this.copyData.forEach(item => { + item.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); + const newData = JSON.parse(JSON.stringify(item)); + newData.Id = ObjectID.default.generate(), + newData.CompanyId = companyId; + newData.BuildingId = buildingId; + newData.FloorId = floorId; + newData.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); + switch (item.InteractiveMode) { + case PaintMode.singlePointIcon: + const singleIcon = new AxImageShape(newData, this); + this.emit('createIcon', singleIcon); + break; + case PaintMode.lineIcon: + const lineIcon = new MultipointIcon(newData, this); + this.emit('createIcon', lineIcon); + break; + case PaintMode.polygonIcon: + const polygonIcon = new PolygonIcon(newData, this); + this.emit('createIcon', polygonIcon); + break; + case PaintMode.Pipeline: + if (item.Name === '距离') { + const wall = new AxArrowConnector(newData, this, true, true); + this.emit('createIcon', wall); + } else if (item.Name === '普通墙' || item.Name === '承重墙') { + const wall = new AxArrowConnector(newData, this, false, false); + this.emit('createIcon', wall); + } + break; + } + this.selection.add(this.backgroundImage.getChildByName(newData.Id)); + }); + AxMessageSystem.send(CanvasAction.selectionChanged); + } } //////////////////////////////////////////////////////////////////////// 通用///////////////////////////////////////////////////////////////////////////// /** @@ -1357,7 +1362,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV public async onExamineeClickFloor() { await this.refreshBackgroundImage(); // 清空所有图形 - this.selection.deselectAll(); + this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { @@ -1384,7 +1389,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV public async onExaminerClickFloor() { await this.refreshBackgroundImage(); // 清空所有图形 - this.selection.deselectAll(); + this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { @@ -1410,7 +1415,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV public async onExaminerClickFloor_CreateTestpaper() { await this.refreshBackgroundImage(); // 清空所有图形 - this.selection.deselectAll(); + this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { @@ -1428,94 +1433,26 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV // 隐藏图标 this.setNameVisible(false, 0); } -} - -/** - * 选择器 - */ -export class Selection { - constructor(private workingArea: WorkingAreaComponent) {} - public objects: any[] = []; - public isMultiselection = false; - /** - * 返回选择器中是否包含对象 - * @param obj 对象 - */ - public contains(obj: any): boolean { - return this.objects.includes(obj); - } - /** - * 选定对象 - * @param obj 对象 - */ - public select(obj: any) { - if (!this.contains(obj)) { - this.workingArea.emit('select', obj); - this.objects.push(obj); - } - } - /** - * 取消选定对象 - * @param obj 对象 - */ - public deselect(obj: any) { - if (this.contains(obj)) { - this.workingArea.emit('deselect', obj); - const idx = this.objects.findIndex(x => x === obj); - this.objects.splice(idx, 1); - } - } - /** - * 选定或取消选定对象 - * @param obj 对象 - */ - public selectOrDeselect(obj: any) { - if (this.contains(obj)) { - this.deselect(obj); - } else { - this.select(obj); - } - } - /** - * 取消选定所有已选定对象 - */ + //////////////////////////////////////////////////////////////////// 选择逻辑 + // 取消所有选择 public deselectAll() { - this.objects.forEach(item => { - this.workingArea.emit('deselect', item); - }); - this.objects.splice(0, this.objects.length); - } - /** - * 取消选定所有对象后选定一个对象 - * @param obj 对象 - */ - public selectOne(obj: any) { - if (this.isMultiselection) { - this.selectOrDeselect(obj); - } else { - this.deselectAll(); - this.select(obj); + if (this.selection.first() !== null) { + this.selection.all().forEach(item => { + item.hideBorder(); + item.setPointVisiable(false); + }); + this.selection.clear(); + AxMessageSystem.send(CanvasAction.selectionChanged); } } - /** - * 选定对象集合中所有对象 - * @param objects 对象集合 - */ - public selectAll(objects: any[]) { - this.objects.forEach(item => { - this.select(item); - }); + // 选择单个 + public selectSingle(obj: any) { + this.deselectAll(); + this.selection.add(obj); + AxMessageSystem.send(CanvasAction.selectionChanged); } } - - -/** - * 车辆类型 - */ -export enum Type { - 水源 = 0, - 举高喷射消防车 = 1, - 泡沫消防车 = 2, - 水罐消防车 = 3, - 压缩空气泡沫消防车 = 4 +enum CanvasAction { + selectionChanged = 'selectionChanged', + copyDataChanged = 'copyDataChanged' } From e6c0c6c8b889935ee97c9df45dcb03fa2106acbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Mon, 25 Jan 2021 09:11:03 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E5=88=A0=E9=99=A4debug.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debug.log | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 debug.log diff --git a/debug.log b/debug.log deleted file mode 100644 index c4638ef..0000000 --- a/debug.log +++ /dev/null @@ -1,3 +0,0 @@ -[1229/141605.754:ERROR:directory_reader_win.cc(43)] FindFirstFile: ϵͳҲָ· (0x3) -[0104/100053.968:ERROR:directory_reader_win.cc(43)] FindFirstFile: ϵͳҲָ· (0x3) -[0122/085819.900:ERROR:directory_reader_win.cc(43)] FindFirstFile: ϵͳҲָ· (0x3) From 45ffea975865fcafe9fc7d1e378c1ef09ad64355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Mon, 25 Jan 2021 11:47:35 +0800 Subject: [PATCH 6/7] 1.0.12.20210125b --- .gitignore | 1 + src/app/working-area/model/axSelection.ts | 4 + src/app/working-area/model/axShape.ts | 60 +++--- .../working-area/working-area.component.ts | 171 +++++++++++------- 4 files changed, 132 insertions(+), 104 deletions(-) diff --git a/.gitignore b/.gitignore index 86d943a..a80a6b3 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ testem.log # System Files .DS_Store Thumbs.db +debug.log diff --git a/src/app/working-area/model/axSelection.ts b/src/app/working-area/model/axSelection.ts index e61cd78..ce7a6e0 100644 --- a/src/app/working-area/model/axSelection.ts +++ b/src/app/working-area/model/axSelection.ts @@ -13,6 +13,10 @@ export class AxSelection { return null; } } + // 是否已经选择了对象 + public has(obj: any): boolean { + return this.objects.has(obj); + } // 获得所有对象 public all() { return this.objects; diff --git a/src/app/working-area/model/axShape.ts b/src/app/working-area/model/axShape.ts index 2d032d5..3a5dae7 100644 --- a/src/app/working-area/model/axShape.ts +++ b/src/app/working-area/model/axShape.ts @@ -20,6 +20,10 @@ export class AxShape extends Graphics { showName = true; // 边框 border: PIXI.Graphics = new PIXI.Graphics(); + // 鼠标位置 + mousePosition: PIXI.Point; + // 鼠标拖动 + mouseDragging: boolean; constructor(assetData: any, workingArea: WorkingAreaComponent) { super(); @@ -35,50 +39,30 @@ export class AxShape extends Graphics { .on('pointerdown', event => { event.stopPropagation(); if (this.selectable) { - this.workingArea.selectSingle(this); + this.workingArea.select(this); } if (this.moveable) { - event.currentTarget.data = event.data; - event.currentTarget.alpha = 0.5; - event.currentTarget.dragging = true; - - event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent); - event.currentTarget.dragPoint.x -= event.currentTarget.x; - event.currentTarget.dragPoint.y -= event.currentTarget.y; + this.mouseDragging = true; + this.mousePosition = new PIXI.Point(event.data.global.x, event.data.global.y); } }) .on('pointerup', event => { - if (event.currentTarget.dragging) { - event.currentTarget.alpha = 1; - event.currentTarget.dragging = false; - event.currentTarget.data = null; - } + this.mouseDragging = false; }) .on('pointerupoutside', event => { - if (event.currentTarget.dragging) { - event.currentTarget.alpha = 1; - event.currentTarget.dragging = false; - event.currentTarget.data = null; - } + this.mouseDragging = false; }) .on('pointermove', event => { - if (event.currentTarget.dragging) { - const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent); - - // const offsetX = newPosition.x - event.currentTarget.dragPoint.x; - // const offsetY = newPosition.y - event.currentTarget.dragPoint.y; - // const offset = this.workingArea.backgroundImage.toLocal(new Point(offsetX, offsetY)); - // event.currentTarget.position += offset; - // // this.workingArea.selection.objects.forEach(shpae => { - // // shpae.x = newPosition.x - event.currentTarget.dragPoint.x; - // // shpae.y = newPosition.y - event.currentTarget.dragPoint.y; - // // shpae.assetData.Point = new PIXI.Point(this.x, this.y); - // // this.workingArea.canvasData.isChange = true; - // // }) - event.currentTarget.x = newPosition.x - event.currentTarget.dragPoint.x; - event.currentTarget.y = newPosition.y - event.currentTarget.dragPoint.y; - this.assetData.Point = new PIXI.Point(this.x, this.y); - this.workingArea.canvasData.isChange = true; + if (this.mouseDragging) { + this.workingArea.selection.all().forEach(item => { + const x = event.data.global.x - this.mousePosition.x; + const y = event.data.global.y - this.mousePosition.y; + item.x += x * (1 / this.workingArea.backgroundImage.scale.x); + item.y += y * (1 / this.workingArea.backgroundImage.scale.y); + item.assetData.Point = new PIXI.Point(item.x, item.y); + this.workingArea.canvasData.isChange = true; + }); + this.mousePosition = new PIXI.Point(event.data.global.x, event.data.global.y); } }) .on('rightclick', event => { @@ -127,9 +111,9 @@ export class AxShape extends Graphics { this.border.lineStyle(scale * 1, 0x00a8ff); - let spaceLength = scale * 1; - let lineLenght = rect.width + 0.5 + 0.5; - let dashLength = scale * ( lineLenght + spaceLength - Math.floor((rect.width + rect.height) / 2 / 4.1)) / Math.floor((rect.width + rect.height) / 2 / 4.1); + const spaceLength = scale * 1; + const lineLenght = rect.width + 0.5 + 0.5; + const dashLength = scale * ( lineLenght + spaceLength - Math.floor((rect.width + rect.height) / 2 / 4.1)) / Math.floor((rect.width + rect.height) / 2 / 4.1); this.drawDash(this.border, p1.x - 0.5 * scale, p1.y, p2.x + 0.5 * scale, p2.y, dashLength, spaceLength); this.drawDash(this.border, p2.x, p2.y - 0.5 * scale, p3.x, p3.y + 0.5 * scale, dashLength, spaceLength); this.drawDash(this.border, p3.x + 0.5 * scale, p3.y, p4.x - 0.5 * scale, p4.y, dashLength, spaceLength); diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index 1b05d4c..851b75d 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -151,7 +151,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。 * Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号®。 */ - public VERSION = '1.0.11.20210122_beta'; + public VERSION = '1.0.12.20210125_beta'; /** * 数据初始化 */ @@ -174,14 +174,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.deleteSelectedShape(); } }); - // 消息系统事件监听 - AxMessageSystem.addListener(CanvasAction.selectionChanged, () => { - this.selection.all().forEach(item => { - item.showBorder(); - item.drawBorder(1 / this.backgroundImage.scale.x); - item.setPointVisiable(this.allowEdit); - }); - }, this); } /** * 删除选中的图标 @@ -391,28 +383,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.rectToolGraphics.endFill(); } }); - /** - * 选中事件 - */ - this.on('select', (axShape: AxShape) => { - // if (axShape instanceof AxRectangleShape) { - // let upLeft: PIXI.Sprite= new PIXI.Sprite(this.editorPointTexture); - // let upRight: PIXI.Sprite= new PIXI.Sprite(this.editorPointTexture); - // let downLeft: PIXI.Sprite= new PIXI.Sprite(this.editorPointTexture); - // let downRight: PIXI.Sprite = new PIXI.Sprite(this.editorPointTexture); - // } else { - axShape.showBorder(); - axShape.drawBorder(1 / this.backgroundImage.scale.x); - axShape.setPointVisiable(this.allowEdit); - // } - }); - /** - * 取消选中事件 - */ - this.on('deselect', (axShape: AxShape) => { - axShape.hideBorder(); - axShape.setPointVisiable(false); - }); /** * 创建图标事件(数据处理) */ @@ -451,12 +421,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.emit('canvasDataChanged'); this.canvasData.isChange = true; }); - /** - * 删除图标事件(数据处理) - */ - this.on('deleteIcon', (axShape: AxShape) => { - - }); } /** * 重置画布 @@ -517,18 +481,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } }); } - /** - * 设置选中 - * 清空所有选择对象,选择ids集合元素 - */ - public setHighlight(ids: string[]): void { - this.selection.clear(); - ids.forEach(item => { - const obj = this.backgroundImage.getChildByName(item); - this.selection.add(obj); - }); - AxMessageSystem.send(''); - } /** * 创建楼层图形 */ @@ -842,22 +794,21 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV event.currentTarget.data = null; if (this.rectToolGraphics.visible === true) { + const shapes: AxShape[] = []; this.backgroundImage.children.forEach(item => { - if ( item instanceof AxImageShape - || item instanceof MultipointIcon - || item instanceof PolygonIcon - || item instanceof AxArrowConnector) { + if ( item instanceof AxShape + && item instanceof AxPreviewImageShape === false) { // 判断2个矩形是否相交 const rect1 = this.rectToolGraphics.getBounds(); const rect2 = item.getBounds(); if (this.isOverlap(rect1, rect2)) { - this.selection.add(item); + shapes.push(item); } } }); this.rectToolGraphics.clear(); this.rectToolGraphics.visible = false; - AxMessageSystem.send(CanvasAction.selectionChanged); + this.selectAll(shapes); } }) .on('pointerupoutside', event => { @@ -1303,12 +1254,13 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV * 粘贴 */ public paste(companyId: string, buildingId: string, floorId: string): void { + const ids: string[] = []; if (this.copyData.length > 0) { this.copyData.forEach(item => { item.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); const newData = JSON.parse(JSON.stringify(item)); newData.Id = ObjectID.default.generate(), - newData.CompanyId = companyId; + newData.CompanyId = companyId; newData.BuildingId = buildingId; newData.FloorId = floorId; newData.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); @@ -1335,9 +1287,9 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } break; } - this.selection.add(this.backgroundImage.getChildByName(newData.Id)); + ids.push(newData.Id); }); - AxMessageSystem.send(CanvasAction.selectionChanged); + this.setHighlight(ids); } } //////////////////////////////////////////////////////////////////////// 通用///////////////////////////////////////////////////////////////////////////// @@ -1434,22 +1386,109 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.setNameVisible(false, 0); } //////////////////////////////////////////////////////////////////// 选择逻辑 - // 取消所有选择 + /** + * 清空选择,选择单个形状 + * @param shape 形状 + */ + public selectSingle(shape: AxShape) { + if (this.selection.first() !== null) { + this.selection.all().forEach(item => { + this.clearSelectEffect(item); + }); + this.selection.clear(); + } + this.selection.add(shape); + this.setSelectEffect(shape); + AxMessageSystem.send(CanvasAction.selectionChanged); + } + /** + * 选择 + * @param shape 形状 + */ + public select(shape: AxShape) { + if (this.selection.first() !== null + && !this.isCtrlKeyClicked + && !this.selection.has(shape)) { + this.selection.all().forEach(item => { + this.clearSelectEffect(item); + }); + this.selection.clear(); + } + this.selection.add(shape); + this.setSelectEffect(shape); + AxMessageSystem.send(CanvasAction.selectionChanged); + } + /** + * 选择集合中的形状 + * @param shape 形状集合 + */ + public selectAll(shape: AxShape[]) { + this.selection.addArray(shape); + this.selection.all().forEach(item => { + this.setSelectEffect(item); + }); + AxMessageSystem.send(CanvasAction.selectionChanged); + } + /** + * 先清空再选择全部 + * @param shape 形状集合 + */ + public selectAllWithClear(shape: AxShape[]) { + if (this.selection.first() !== null) { + this.selection.all().forEach(item => { + this.clearSelectEffect(item); + }); + this.selection.clear(); + } + this.selection.addArray(shape); + this.selection.all().forEach(item => { + this.setSelectEffect(item); + }); + AxMessageSystem.send(CanvasAction.selectionChanged); + } + /** + * 选择集合中所有id的形状 + * @param ids 形状id集合 + */ + public setHighlight(ids: string[]): void { + const shapes: AxShape[] = []; + // 重新选择 + ids.forEach(item => { + const obj = this.backgroundImage.getChildByName(item); + shapes.push(obj as AxShape); + }); + this.selectAllWithClear(shapes); + } + /** + * 取消所有选择 + */ public deselectAll() { if (this.selection.first() !== null) { this.selection.all().forEach(item => { - item.hideBorder(); - item.setPointVisiable(false); + this.clearSelectEffect(item); }); this.selection.clear(); AxMessageSystem.send(CanvasAction.selectionChanged); } } - // 选择单个 - public selectSingle(obj: any) { - this.deselectAll(); - this.selection.add(obj); - AxMessageSystem.send(CanvasAction.selectionChanged); + /** + * 设置选中效果 + * @param shape 形状 + */ + public setSelectEffect(shape: AxShape) { + shape.hideBorder(); + shape.setPointVisiable(false); + shape.showBorder(); + shape.drawBorder(1 / this.backgroundImage.scale.x); + shape.setPointVisiable(this.allowEdit); + } + /** + * 设置形状选中效果 + * @param shape 形状 + */ + public clearSelectEffect(shape: AxShape) { + shape.hideBorder(); + shape.setPointVisiable(false); } } enum CanvasAction { From 34177788a2f5d512463f430361ba355064d5f941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=8C=AF=E5=8D=87?= <359059686@qq.com> Date: Mon, 25 Jan 2021 12:02:24 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=9B=BE=E4=BE=8B?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=9A=90=E8=97=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/working-area/working-area.component.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index 851b75d..0d407f3 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -1490,6 +1490,15 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV shape.hideBorder(); shape.setPointVisiable(false); } + ////////////////////////////////////////////////////////////////////////////////////////////////图例 + /** + * 设置图例显示隐藏 + * @param b true 显示,false隐藏 + */ + public setLegendVisible(b: boolean): void { + const legend = this.backgroundImage.getChildByName('图例') as AxLegend; + legend.visible = b; + } } enum CanvasAction { selectionChanged = 'selectionChanged',
- + + {{item.contentType=='1'?'Ⅰ级预案':item.contentType=='2'?'Ⅱ级预案':item.contentType=='3'?'Ⅲ级预案':item.contentType=='4'?'Ⅳ级预案':item.contentType=='5'? 'Ⅴ级预案':item.contentType=='6'?'应急预案(国家级)':item.contentType=='7'?'应急预案(市级)':item.contentType=='8'?'类型预案':item.contentType=='11'?'重点单位':'消防车辆'}} {{item.operation=='0'?'新增':item.operation=='1'?'更新':'删除'}}预案名称 {{element.name}} 添加人 {{element.creatorName}} 预案级别{{element.planCategory==1?'Ⅰ级预案':element.planCategory==2?'Ⅱ级预案': + element.planCategory==3?'Ⅲ级预案':element.planCategory==4?'Ⅳ级预案':element.planCategory==5?'Ⅴ级预案':element.planCategory==8?'类型预案':'应急预案'}} 添加时间 {{element.creationTime | date:'yyyy-MM-dd'}}