陈鹏飞 4 years ago
parent
commit
c542fa2f19
  1. 15
      .vscode/launch.json
  2. 3
      debug.log
  3. 9
      src/app/canvas-share-data.service.ts
  4. 21
      src/app/examiner/mark-papers-index/mark-papers-index.component.html
  5. 36
      src/app/examiner/mark-papers-index/mark-papers-index.component.ts
  6. 19
      src/app/examiner/mark-papers-two/mark-papers-two.component.html
  7. 40
      src/app/examiner/mark-papers-two/mark-papers-two.component.ts
  8. 16
      src/app/ui/collection-tools-examinee/collection-tools.component.html
  9. 220
      src/app/ui/collection-tools-examinee/collection-tools.component.ts
  10. 8
      src/app/ui/collection-tools-examinee/examinationQuestions.html
  11. 299
      src/app/ui/collection-tools-examinee/examinationQuestions.ts
  12. 3
      src/app/ui/collection-tools-examinee/panel.scss
  13. 36
      src/app/ui/collection-tools-examinee/uploadQuestions.html
  14. 1
      src/app/ui/collection-tools/collection-tools.component.ts
  15. 3
      src/app/ui/collection-tools/examinationQuestions.ts
  16. 125
      src/app/working-area/model/axArrowConnector.ts
  17. 24
      src/app/working-area/model/axImageShape.ts
  18. 6
      src/app/working-area/model/axShape.ts
  19. 3
      src/app/working-area/model/gameMode.ts
  20. 104
      src/app/working-area/model/multipointIcon.ts
  21. 328
      src/app/working-area/model/pipeline.ts
  22. 120
      src/app/working-area/model/polygonIcon.ts
  23. 203
      src/app/working-area/working-area.component.ts

15
.vscode/launch.json vendored

@ -0,0 +1,15 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:4300",
"webRoot": "${workspaceFolder}"
}
]
}

3
debug.log

@ -0,0 +1,3 @@
[1225/112746.821:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1225/152100.333:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)
[1226/082525.401:ERROR:directory_reader_win.cc(43)] FindFirstFile: 系统找不到指定的路径。 (0x3)

9
src/app/canvas-share-data.service.ts

@ -18,8 +18,15 @@ export class CanvasShareDataService {
// 总平面图/建筑 楼层
selectStorey: any = {area: '', details: ''}; // 选择当前 楼层 数据
originalcompanyBuildingData: any; // 单位/建筑 数据
originaleveryStoreyData: any; // 总平面图/楼层/区域 楼层数据
examOriginaleveryStoreyData: any; // 考生答卷 总平面图/楼层/区域 楼层数据
hiddenBasicInfoFacilities: any = []// 考生答卷 当前楼层需要隐藏的基本信息素材
// 总平面图/建筑 楼层
// 处置 节点
@ -31,7 +38,7 @@ export class CanvasShareDataService {
/**
*
*/
gameMode: GameMode = GameMode.Assignment;
gameMode: GameMode = GameMode.Examinee;
facilityAssetsName = new Map<string, string>([
[ '消防水池', '消防水池'],

21
src/app/examiner/mark-papers-index/mark-papers-index.component.html

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-14 16:30:31
* @LastEditors: sueRimn
* @LastEditTime: 2020-12-14 17:39:30
* @LastEditTime: 2020-12-25 08:59:47
-->
<div class="content">
<div class="header">
@ -35,21 +35,22 @@
</thead>
<tbody>
<tr *ngFor="let item of dataSource">
<td>{{item.name}}</td>
<td>{{item.organization}}</td>
<td>{{item.startTime}}</td>
<td>{{item.overTime}}</td>
<td>{{item.title}}</td>
<td>广西总队</td>
<td>{{item.startTime|date:'yyyy-MM-dd HH:mm'}}</td>
<td>{{item.endTime|date:'yyyy-MM-dd HH:mm'}}</td>
<td >
<span id={{item.name}} style="color: #07CDCF;cursor: pointer;" (click)="markTwo(item.name)">阅卷</span>
<span id={{item.name}} style="color: #07CDCF;cursor: pointer;" (click)="markTwo(item.title,item.id)">阅卷</span>
</td>
</tr>
</tbody>
</table>
<mat-paginator [length]="100"
[pageSize]="10"
[pageSizeOptions]="[10]">
</mat-paginator>
<mat-paginator [length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
(page)="chagePage($event)">
</mat-paginator>
</div>
</div>

36
src/app/examiner/mark-papers-index/mark-papers-index.component.ts

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-14 16:30:31
* @LastEditors: sueRimn
* @LastEditTime: 2020-12-15 08:53:09
* @LastEditTime: 2020-12-25 09:00:41
*/
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import {HttpClient} from '@angular/common/http'
@ -36,19 +36,47 @@ export class MarkPapersIndexComponent implements OnInit {
constructor(private router: Router,private activatedRoute: ActivatedRoute,public http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar) { }
ngOnInit(): void {
this.getAlltabledate()
}
dataSource = ELEMENT_DATA;
dataSource
markName//试卷名称
markDate//考试日期
//分页
@ViewChild(MatPaginator, {static: true})
pageEvent: PageEvent;
paginator: MatPaginator;
length:any; //共多少条数据
pageSize:any; //每页条数
pageSizeOptions: number[] = [10] //设置每页条数
PageNumber:any //第几页
//重置功能
resert(){
this.markName=undefined
this.markDate=undefined
}
//点击阅卷跳转
markTwo(e){
markTwo(e,id){
console.log(e)
this.router.navigate(['/home/mark-papers-index/mark-papers-two'],{queryParams:{'level':e}})
this.router.navigate(['/home/mark-papers-index/mark-papers-two'],{queryParams:{'level':e,'id':id}})
}
//获取表格信息
getAlltabledate(){
let paramsdata:any = {
PageNumber: this.PageNumber || '1',
PageSize: this.pageSizeOptions[0],
Sort: null,
SortType: null,
}
this.http.get("/api/Papers",{params:paramsdata}).subscribe((data:any)=>{
this.dataSource=data.items
this.length=data.totalCount
console.log(this.dataSource)
})
}
//分页事件
chagePage(e){
this.PageNumber = e.pageIndex+1
this.getAlltabledate()
}
}

19
src/app/examiner/mark-papers-two/mark-papers-two.component.html

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-14 17:21:02
* @LastEditors: sueRimn
* @LastEditTime: 2020-12-15 09:21:32
* @LastEditTime: 2020-12-25 11:26:01
-->
<div class="content">
<div class="header">
@ -30,10 +30,10 @@
<tbody>
<tr *ngFor="let item of dataSource">
<td>{{item.name}}</td>
<td>{{item.organization}}</td>
<td>{{item.startTime}}</td>
<td [ngClass]="{'green': item.testState == '已阅卷','red':item.testState == '未阅卷'}">{{item.testState}}</td>
<td>{{item.mark}}</td>
<td>广西总队</td>
<td>{{item.endTime|date:'yyyy-MM-dd HH:mm'}}</td>
<td [ngClass]="{'green': item.isMarked == true,'red':item.isMarked == false}">{{item.isMarked== true?"已阅卷":"未阅卷"}}</td>
<td>90</td>
<td >
<span style="color: #01CFD5;">阅卷</span>
</td>
@ -41,10 +41,11 @@
</tbody>
</table>
<mat-paginator [length]="100"
[pageSize]="10"
[pageSizeOptions]="[10]">
</mat-paginator>
<mat-paginator [length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
(page)="chagePage($event)">
</mat-paginator>
</div>
</div>

40
src/app/examiner/mark-papers-two/mark-papers-two.component.ts

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-14 17:21:02
* @LastEditors: sueRimn
* @LastEditTime: 2020-12-15 09:16:29
* @LastEditTime: 2020-12-25 09:15:42
*/
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import {HttpClient} from '@angular/common/http'
@ -19,11 +19,6 @@ const ELEMENT_DATA = [
{name: "张三三", organization: '浦东支队', startTime: "2020-09-19 10:00", mark: '120',testState:'未阅卷'},
{name: "提亚马特", organization: '黄埔支队', startTime: "2020-09-19 10:00", mark: '100',testState:'已阅卷'},
{name: "艾泽拉斯", organization: '徐汇支队', startTime: "2020-09-19 10:00", mark: '90',testState:'已阅卷'},
/* {name: "", organization: '', startTime: "2020-09-19 10:00", overTime: '2020-09-19 12:00',testState:''},
{name: "立新加油站", organization: '浦东支队', startTime: "2020-09-19 10:00", overTime: '2020-09-19 12:00',testState:'开考中'},
{name: "富华酒店", organization: '宝山支队', startTime: "2020-07-19 10:00", overTime: '2020-07-19 12:00',testState:'已结束'},
{name: "裕达国际酒店", organization: '浦东支队', startTime: "2020-08-19 10:00", overTime: '2020-08-19 12:00',testState:'已结束'},
{name: "锦德大酒店", organization: '长宁支队', startTime: "2019-09-19 10:00", overTime: '2019-09-19 12:00',testState:'已结束'}, */
];
@Component({
@ -38,12 +33,43 @@ export class MarkPapersTwoComponent implements OnInit {
ngOnInit(): void {
this.activatedRoute.queryParams.subscribe(param=>{
this.headtext=param.level
this.getid=param.id
//console.log(headName)
});
this.getAlltabledate()
}
headtext
dataSource = ELEMENT_DATA;
getid//试卷id
dataSource
markName//试卷名称
markDate//考试日期
//分页
@ViewChild(MatPaginator, {static: true})
pageEvent: PageEvent;
paginator: MatPaginator;
length:any; //共多少条数据
pageSize:any; //每页条数
pageSizeOptions: number[] = [10] //设置每页条数
PageNumber:any //第几页
//获取表格信息
getAlltabledate(){
let paramsdata:any = {
PaperId:this.getid,
PageNumber: this.PageNumber || '1',
PageSize: this.pageSizeOptions[0],
Sort: null,
SortType: null,
}
this.http.get("/api/Examinations",{params:paramsdata}).subscribe((data:any)=>{
this.dataSource=data.items
this.length=data.totalCount
console.log(this.dataSource)
})
}
//分页事件
chagePage(e){
this.PageNumber = e.pageIndex+1
this.getAlltabledate()
}
}

16
src/app/ui/collection-tools-examinee/collection-tools.component.html

@ -8,9 +8,11 @@
</div>
</div>
<div class="headerRight">
<button style="border: 1px solid #07CDCF; border-radius: 5px; margin: 0 15px;" (click)='openFireExamination()'><mat-icon>visibility</mat-icon>消防设施考题设定</button>
<button style="border: 1px solid #07CDCF; border-radius: 5px; margin: 0 15px;" (click)='openFireExamination()'><mat-icon>visibility</mat-icon>
需要标记的消防设施
</button>
<button (click)="saveSite()"><mat-icon>description</mat-icon>保存</button>
<button (click)="openUploadQuestions()"><mat-icon>open_in_browser</mat-icon>上传</button>
<button (click)="openUploadQuestions()"><mat-icon>open_in_browser</mat-icon>提交</button>
</div>
</div>
<!-- header头部 -->
@ -20,6 +22,9 @@
<!-- H5Canvas -->
<app-working-area #canvas [init]='this'></app-working-area>
<!-- H5Canvas -->
<!-- 拖拽窗口 -->
<div class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div class="centerTotal">
<div class="centerTotalHeader overflowText">
@ -27,7 +32,7 @@
<label (click)='togglebeforeOneCheckedBuilding()'>{{beforeOneCheckedBuilding.name}}</label>
</div>
<div class="everyTotal overflowText" *ngFor="let item of sitePlanData;let key = index"
[ngClass]="{'selectSitePlan': selectSitePlanIndex==key}" (click)='selectSitePlan(item,key)'>
[ngClass]="{'selectSitePlan': selectSitePlanIndex==key,'selectSitePlanColor':item.isLabel}" (click)='selectSitePlan(item,key)'>
{{item.name}}
</div>
</div>
@ -39,6 +44,9 @@
</div>
</div>
</div>
<div id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<!-- 处置预案 -->
@ -101,7 +109,7 @@
</div>
<!-- 素材库 -->
<!-- 消防设施 -->
<div class="planarGraph">
<div class="planarGraph" style="display: none;">
<div class="planarGraphHeader" (click)='togglePlanarGraph()'>
<mat-icon *ngIf="togglePlane">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!togglePlane">keyboard_arrow_down</mat-icon>

220
src/app/ui/collection-tools-examinee/collection-tools.component.ts

@ -423,13 +423,13 @@ export class CollectionToolsExamineeComponent implements OnInit {
keynote: '', //考试要点
}
ngOnInit(): void {
async ngOnInit(): Promise<void> {
this.getAllLibrary('plan') //获取素材库
this.getAllBuildings() //获取所有建筑
this.getAllFirePlan() //获取当前单位灾情
this.getPaperPlanData()//获得当前考题题目
await this.getPaperPlanData()//获得当前考题题目
let that = this
window.setTimeout(()=>{
document.getElementById("functionalDomainContent").oncontextmenu = function (event) {
@ -449,12 +449,12 @@ export class CollectionToolsExamineeComponent implements OnInit {
planData:any //当前考题题目
Facilities:any //当前预案考题所有楼层要考的基本信息素材
//获得单位预案设定
getPaperPlanData(){
async getPaperPlanData(){
let params = {
paperId : this.paperId
}
await new Promise((resolve,reject)=>{
this.http.get(`/api/PaperPlans`,{params:params}).subscribe((data:any) => {
console.log(456,data)
data.forEach(item => {
item.id == this.route.snapshot.queryParams.paperplanId ?
this.planData = item : null
@ -463,15 +463,29 @@ export class CollectionToolsExamineeComponent implements OnInit {
let questions = JSON.parse(this.planData.examDisposalNodesData)
this.handleHybridTree(questions,'题目')
this.Facilities = JSON.parse(this.planData.examFacilityAssetsData)
console.log('当前预案设定需要隐藏的基本信息图标',this.Facilities)
resolve(1)
})
})
}
//获得所有素材库
//
/**
*
*/
basicAssetLibraries:any = []//基本信息素材库
getAllAssetLibraries(Facilitiesitem){
console.log('具体到当前楼层需要隐藏的基本信息图标',Facilitiesitem.children)
let arr = []
Facilitiesitem.children.forEach(item => {
arr.push(item.Id)
})
this.canvasData.hiddenBasicInfoFacilities = arr
this.canvas.loadExamineeData()
this.basicAssetLibraries = []
this.http.get('/api/AssetLibraries').subscribe(async(data:any) => {
console.log('素材库',data)
for (let index = 0; index < data.length; index++) {
const element = data[index];
let params = {
@ -481,18 +495,21 @@ export class CollectionToolsExamineeComponent implements OnInit {
await new Promise ((resolve,reject)=>{
this.http.get('/api/Assets',{params:params})
.subscribe((data:any) => {
console.log(index,data)
if(data && data.length != 0){
data.forEach(item => {
item.tag = 1
})
element.images = data
this.basicAssetLibraries.push(
element
)
}
resolve()
resolve(1)
})
})
}
console.log(55555,this.basicAssetLibraries)
this.allLibrary = [...this.originalallLibrary,...this.basicAssetLibraries]
})
@ -508,6 +525,7 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.canvas.on("select",obj=>{
//选中素材属性注入函数
this.setAssetsProperty(obj.assetData)
})
// 监听canvas组件取消选中素材事件
this.canvas.on("deselect",obj=>{
@ -515,11 +533,12 @@ export class CollectionToolsExamineeComponent implements OnInit {
})
// 监听canvas组件新增素材事件
this.canvas.on("createIcon",obj=>{
this.renovateTreeData(false)
console.log(obj.assetData)
// this.renovateTreeData(false)
})
// 监听canvas组件删除素材事件
this.canvas.on("deleteIcon",obj=>{
this.renovateTreeData(false)
// this.renovateTreeData(false)
})
@ -563,20 +582,49 @@ export class CollectionToolsExamineeComponent implements OnInit {
//保存平面图
saveNum :any = []
saveSite(){
async saveSite(){
if (this.selectingSitePlan && this.selectingSitePlan.id) {
this.saveNum = []
let SitePlanData = JSON.parse(JSON.stringify(this.canvasData.originaleveryStoreyData));
let SitePlanData = JSON.parse(JSON.stringify(this.canvasData.examOriginaleveryStoreyData));
SitePlanData.data = JSON.stringify(SitePlanData.data)
let CompanyData = JSON.parse(JSON.stringify(this.canvasData.originalcompanyBuildingData));
CompanyData.data = JSON.stringify(CompanyData.data)
let object = this.canvasData.originalcompanyBuildingData.data
let adjoinArr = [] //毗邻数组
SitePlanData.examinationId = this.route.snapshot.queryParams.examId
SitePlanData.planComponentId = this.route.snapshot.queryParams.planComponentId
//如果是单位 总平面图
if(this.checkedBuildingIndex==-1){
//保存平面图数据
SitePlanData.sitePlanId = this.selectingSitePlan.id
await new Promise((resolve,reject)=>{
this.http.post("/api/ExamSitePlanData",SitePlanData,{
params:{
companyId:this.params.companyId
}
}).subscribe(data => {
console.log('保存基本素材成功')
resolve(1)
},err=>{
console.log('保存基本素材失败')
resolve(1)
})
})
}else{ //如果是建筑
SitePlanData.buildingAreaId = this.selectingSitePlan.id
//建筑平面图数据
await new Promise((resolve,reject)=>{
this.http.post("/api/ExamBuildingAreaData",SitePlanData,{
params:{
companyId:this.params.companyId
}
}).subscribe(data => {
console.log('保存基本素材成功')
resolve(1)
},err=>{
console.log('保存基本素材失败')
resolve(1)
})
})
if(this.pattern){//如果是基本信息编辑模式
return true
}else{//如果是想定作业编辑模式
}
const dialogRef = this.dialog.open(saveOneDialogExaminee, {
data: {
allDisposalNode: this.canvasData.allDisposalNode,
@ -590,7 +638,7 @@ export class CollectionToolsExamineeComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
} else { //if
const config = new MatSnackBarConfig();
@ -709,8 +757,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.setAssetsProperty(this.canvasData.originaleveryStoreyData.data[node.id])
}
// console.log(node)
// canvas上的素材高亮
let iconHighLightArr:any = []
if(node.isTemplate){//如果是模板,则开始向下找
@ -726,7 +772,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
}else{
iconHighLightArr.push(node.id)
}
// console.log(456,iconHighLightArr)
this.canvas.setHighlight(iconHighLightArr)
}
@ -806,28 +851,20 @@ export class CollectionToolsExamineeComponent implements OnInit {
//打开消防设施考题设定
openFireExamination () {
let treeData = JSON.parse( JSON.stringify(this.dataSource.data) )
let buildFloorData = {
buildingData:this.beforeOneCheckedBuilding,
floorData:this.selectingSitePlan
}
let data = { treeData: treeData,oldRealData:this.storeyData ,buildFloorData:buildFloorData}
let data = { oldRealData:this.storeyData ,buildFloorData:buildFloorData,Facilities:this.Facilities,allFireElements:this.allFireElements}
let dialogRef = this.dialog.open(examinationQuestionsExaminee,{data});
}
//上传考题
openUploadQuestions () {
let treeData = JSON.parse( JSON.stringify(this.dataSource.data) )
let nodes = JSON.parse( JSON.stringify( JSON.parse(sessionStorage.getItem('examNodeList')) ) )
if (nodes) {
let data = { treeData: treeData, question: JSON.parse( JSON.stringify(this.examMsg) ), node: nodes ,allFireElements:this.allFireElements}
let data = {allFireElements:this.allFireElements,Facilities:this.Facilities}
let dialogRef = this.dialog.open(uploadQuestionsExaminee,{data});
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('未选择考核处置节点','确定',config);
}
}
//封装 刷新 tree 数据
@ -844,12 +881,13 @@ export class CollectionToolsExamineeComponent implements OnInit {
let beforeOneId = this.selectingSitePlan.id || '' //当前 选中 平面图 楼层/区域 id
let companyBuildingData = JSON.parse(JSON.stringify( this.canvasData.originalcompanyBuildingData || {} )) // 当前 单位/建筑 数据
let storeyData = JSON.parse(JSON.stringify( this.canvasData.originaleveryStoreyData || {} )) //当前 楼层 数据
console.log(566,storeyData.data)
this.Facilities.forEach(item => {
// console.log('看看这是啥',this.Facilities)
this.Facilities ? this.Facilities.forEach(item => {
item.key == this.selectingSitePlan.id ?
this.getAllAssetLibraries(item) :
null
})
this.canvas.loadExamineeData()
}) : this.canvas.loadExamineeData();this.allLibrary = this.originalallLibrary
for(let key in storeyData.data){ //筛选数据
storeyData.data[key].key = storeyData.data[key].Id
let noMatch = this.allFireElements.find( every=> every.id===storeyData.data[key].FireElementId )
@ -858,6 +896,7 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.allFireElements[this.allFireElements.length-1].children.push(storeyData.data[key])
}
}
this.handleTreeData(storeyData) //处理tree数据结构
}
@ -908,6 +947,14 @@ export class CollectionToolsExamineeComponent implements OnInit {
let planData = this.getSitePlanCompanyData() //获取 单位 数据
this.http.get('/api/SitePlans',{params:this.params}).subscribe(data=>{
this.sitePlanData = data
console.log('建筑楼层数据',this.sitePlanData)
this.Facilities ? this.sitePlanData.forEach(item => {
this.Facilities.forEach(i =>{
if(item.id == i.key){
item.isLabel = true
}
})
}) : null
this.selectingSitePlan = this.sitePlanData[0] || {}
this.canvasData.selectStorey = this.sitePlanData[0] || {} //服务中 存一份数据
this.selectSitePlanIndex = 0
@ -926,6 +973,14 @@ export class CollectionToolsExamineeComponent implements OnInit {
let planData = this.getBuildingData(params) //获取 建筑 数据
this.http.get('/api/BuildingAreas',{params}).subscribe(data=>{
this.sitePlanData = data
console.log('预案平台当前有哪些楼层',this.sitePlanData)
this.Facilities ? this.sitePlanData.forEach(item => {
this.Facilities.forEach(i =>{
if(item.id == i.key){
item.isLabel = true
}
})
}) : null
this.selectingSitePlan = this.sitePlanData[0] || {}
this.canvasData.selectStorey = this.sitePlanData[0] || {} //服务中 存一份数据
this.selectSitePlanIndex = 0
@ -976,14 +1031,49 @@ export class CollectionToolsExamineeComponent implements OnInit {
getSitePlanStorey (e) {
let params = {sitePlanId: e.id}
this.http.get(`/api/SitePlanData`,{params}).subscribe((data:any)=>{
console.log('预案平台楼层原始素材',data)
this.canvasData.originaleveryStoreyData = data || {} // 楼层原数据
this.canvasData.originaleveryStoreyData.data? this.canvasData.originaleveryStoreyData.data = JSON.parse(this.canvasData.originaleveryStoreyData.data) : this.canvasData.originaleveryStoreyData.data = {}
this.canvasData.originaleveryStoreyData.version? null : this.canvasData.originaleveryStoreyData.version = "2.0"
this.canvasData.originaleveryStoreyData.sitePlanId? null : this.canvasData.originaleveryStoreyData.sitePlanId = e.id || null
let examParams = {
sitePlanId : e.id,
examinationId : this.route.snapshot.queryParams.examId,
planComponentId : this.route.snapshot.queryParams.planComponentId
}
this.http.get('/api/ExamSitePlanData',{params:examParams}).subscribe((data2:any)=>{
console.log('考生新添加的基本信息素材数据',data2)
this.canvasData.examOriginaleveryStoreyData = data2 || {} // 楼层原数据
this.canvasData.examOriginaleveryStoreyData.data? this.canvasData.examOriginaleveryStoreyData.data = JSON.parse(this.canvasData.examOriginaleveryStoreyData.data) : this.canvasData.examOriginaleveryStoreyData.data = {}
this.canvasData.examOriginaleveryStoreyData.version? null : this.canvasData.examOriginaleveryStoreyData.version = "2.0"
this.canvasData.examOriginaleveryStoreyData.buildingAreaId? null : this.canvasData.examOriginaleveryStoreyData.buildingAreaId = e.id || null
this.renovateTreeData()
})
})
}
//获取 建筑 楼层数据
getBuildingStorey (e) {
let params = {buildingAreaId: e.id}
this.http.get(`/api/BuildingAreaData`,{params}).subscribe((data:any)=>{
this.canvasData.originaleveryStoreyData = data || {} // 楼层原数据
this.canvasData.originaleveryStoreyData.data? this.canvasData.originaleveryStoreyData.data = JSON.parse(this.canvasData.originaleveryStoreyData.data) : this.canvasData.originaleveryStoreyData.data = {}
this.canvasData.originaleveryStoreyData.version? null : this.canvasData.originaleveryStoreyData.version = "2.0"
this.canvasData.originaleveryStoreyData.buildingAreaId? null : this.canvasData.originaleveryStoreyData.buildingAreaId = e.id || null
let examParams = {
buildingAreaId : e.id,
examinationId : this.route.snapshot.queryParams.examId,
planComponentId : this.route.snapshot.queryParams.planComponentId
}
this.http.get('/api/ExamBuildingAreaData',{params:examParams}).subscribe((data:any)=>{
this.canvasData.examOriginaleveryStoreyData = data || {} // 楼层原数据
this.canvasData.examOriginaleveryStoreyData.data? this.canvasData.examOriginaleveryStoreyData.data = JSON.parse(this.canvasData.examOriginaleveryStoreyData.data) : this.canvasData.examOriginaleveryStoreyData.data = {}
this.canvasData.examOriginaleveryStoreyData.version? null : this.canvasData.examOriginaleveryStoreyData.version = "2.0"
this.canvasData.examOriginaleveryStoreyData.buildingAreaId? null : this.canvasData.examOriginaleveryStoreyData.buildingAreaId = e.id || null
this.renovateTreeData()
})
})
}
//获取 建筑 数据
getBuildingData (e) {
return new Promise ((resolve,reject)=>{
@ -997,17 +1087,7 @@ export class CollectionToolsExamineeComponent implements OnInit {
})
}
//获取 建筑 楼层数据
getBuildingStorey (e) {
let params = {buildingAreaId: e.id}
this.http.get(`/api/BuildingAreaData`,{params}).subscribe((data:any)=>{
this.canvasData.originaleveryStoreyData = data || {} // 楼层原数据
this.canvasData.originaleveryStoreyData.data? this.canvasData.originaleveryStoreyData.data = JSON.parse(this.canvasData.originaleveryStoreyData.data) : this.canvasData.originaleveryStoreyData.data = {}
this.canvasData.originaleveryStoreyData.version? null : this.canvasData.originaleveryStoreyData.version = "2.0"
this.canvasData.originaleveryStoreyData.buildingAreaId? null : this.canvasData.originaleveryStoreyData.buildingAreaId = e.id || null
this.renovateTreeData()
})
}
//点击选中 平面图 楼层/区域 时
selectSitePlan (item,index) {
@ -1298,8 +1378,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.originalallLibrary = data
this.allLibrary = data
this.selectImageIndex = -1
console.log(654,this.allLibrary)
// this.canvas.cancelPaint()
})
}
@ -1354,7 +1432,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
//获取所有处置节点
getDisposalNode () {
let api
console.log(4444,this.examType)
api='/api/ExamDisposalNodes'
this.selectDisposalNode = ''
let params
@ -1374,7 +1451,7 @@ export class CollectionToolsExamineeComponent implements OnInit {
let treeData = []
let data = JSON.parse(JSON.stringify( disposalNodedata || [] ))
data.forEach(element => {
// this.defaultExpandedKeys.push(element.id)
element.title = element.name //name
element.key = element.id //id
element.children = [] //children
@ -1394,7 +1471,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
})
type == '题目' ? this.questionstreeData = [...treeData] : this.treeData = [...treeData]
// this.defaultExpandedKeys = [...this.defaultExpandedKeys]
}
//刷新 treeData 保存已展开节点
@ -1410,8 +1486,6 @@ export class CollectionToolsExamineeComponent implements OnInit {
oldTreeData.forEach(item=>{
this.defaultExpandedKeys.push(item.key)
})
console.log(1,oldTreeData)
console.log(2,this.defaultExpandedKeys)
let treeData = []
let data = JSON.parse(JSON.stringify( this.canvasData.allDisposalNode || [] ))
data.forEach(element => {
@ -1562,8 +1636,8 @@ export class CollectionToolsExamineeComponent implements OnInit {
//点击 处置Tree节点
selectanelPoint (e) {
console.log(12111,e)
if (!e.buildingAreaId && !e.sitePlanId) { //当前节点 不是 数据节点 时
let msg = this.canvasData.findDisposalNode(e.id)
this.canvasData.selectPanelPointBaseData = msg
this.selectDisposalNode == msg.id? this.selectDisposalNode = '' : this.selectDisposalNode = msg.id //选中 节点
@ -1572,7 +1646,13 @@ export class CollectionToolsExamineeComponent implements OnInit {
let msg = this.canvasData.findDisposalNode(e.parentId)
this.canvasData.selectPanelPointBaseData = msg
this.selectDisposalNode = e.parentId //选中 节点
this.Facilities ? this.sitePlanData.forEach(item => {
this.Facilities.forEach(i =>{
if(item.id == i.key){
item.isLabel = true
}
})
}) : null
if (this.canvasData.selectPanelPoint.DisposalNodeId != e.id) { //选择节点 不是当前节点时
let api
api='/api/ExamDisposalNodeData'
@ -1605,10 +1685,18 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.canvasData.selectStorey = this.sitePlanData[index] || {} //服务中 存一份数据
this.selectSitePlanIndex = index
this.Facilities ? this.sitePlanData.forEach(item => {
this.Facilities.forEach(i =>{
if(item.id == i.key){
item.isLabel = true
}
})
}) : null
Promise.all([fireData,planData]).then((res)=>{
this.getSitePlanStorey(this.selectingSitePlan) //获取 平面图 楼层数据
})
}) //get
} else { //建筑时
this.beforeOneCheckedBuilding=this.allBuildings[paramsData.buildingIndex]
let params = { buildingId: this.beforeOneCheckedBuilding.id }
@ -1620,7 +1708,13 @@ export class CollectionToolsExamineeComponent implements OnInit {
this.selectingSitePlan = this.sitePlanData[index] || {}
this.canvasData.selectStorey = this.sitePlanData[index] || {} //服务中 存一份数据
this.selectSitePlanIndex = index
this.Facilities ? this.sitePlanData.forEach(item => {
this.Facilities.forEach(i =>{
if(item.id == i.key){
item.isLabel = true
}
})
}) : null
Promise.all([fireData,planData]).then((res)=>{
this.getBuildingStorey(this.selectingSitePlan) //获取 建筑 楼层数据
})

8
src/app/ui/collection-tools-examinee/examinationQuestions.html

@ -1,15 +1,12 @@
<div style="min-width: 240px;" >
<div style="text-align: center;font-weight: 550;">消防设施考题设定</div>
<div style="text-align: center;font-weight: 550;">需要标记的消防设施</div>
<div id="nodeTree" style="max-height: 300px;overflow-y: auto; margin: 25px 0;">
<!-- 消防列表树 -->
<nz-tree
#nzTreeComponent
[nzData]="renderData"
nzCheckable
nzExpandAll
nzMultiple
[nzCheckedKeys]="defaultCheckedKeys"
[nzExpandedKeys]="defaultExpandedKeys"
[nzSelectedKeys]="defaultSelectedKeys"
(nzClick)="nzEvent($event)"
(nzExpandChange)="nzEvent($event)"
(nzCheckBoxChange)="nzEvent($event)"
@ -24,7 +21,6 @@
<!-- 消防列表树 -->
</div>
<div style="text-align: center;">
<button mat-stroked-button style="margin-right: 15px;border: none;background: #07CDCF;color: #fff;" (click)='submit()'>确定</button>
<button mat-stroked-button style="margin-left: 15px;border: none;background: #dfe0e0;" mat-dialog-close>取消</button>
</div>
</div>

299
src/app/ui/collection-tools-examinee/examinationQuestions.ts

@ -7,7 +7,7 @@ import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { NzFormatBeforeDropEvent, NzFormatEmitEvent,NzTreeComponent } from 'ng-zorro-antd/tree';
import { ActivatedRoute } from '@angular/router';
//查看需要标记的消防设施按钮
@Component({
selector: 'dialog-examination-questions',
templateUrl: './examinationQuestions.html',
@ -20,129 +20,77 @@ export class examinationQuestionsExaminee {
@ViewChild('nzTreeComponent', { static: false }) nzTreeComponent!: NzTreeComponent;
defaultCheckedKeys = []; //指定选中复选框的树节点 key值
defaultExpandedKeys = []; //展开指定的树节点 key值
defaultSelectedKeys = []; //指定选中的树节点 key值
renderData:any
ngOnInit(): void {
this.renderData = this.data.treeData
if(JSON.parse(sessionStorage.getItem('tree型数据')) && JSON.parse(sessionStorage.getItem('tree型数据'))[this.data.buildFloorData.floorData.id]){
this.defaultCheckedKeys = JSON.parse(sessionStorage.getItem('tree型数据'))[this.data.buildFloorData.floorData.id]
}
this.data.treeData.forEach(element => {
if(element.isTemplate){
element.isLeaf = false
}else{
element.isLeaf = true
}
if(element.children && element.children.length != 0){
element.children.forEach(ele => {
if(ele.isTemplate){
ele.isLeaf = false
}else{
ele.isLeaf = true
}
if(ele.children && ele.children.length != 0){
ele.children.forEach(item => {
if(item.isTemplate){
item.isLeaf = false
}else{
item.isLeaf = true
}
});
}})
}
})
let data = JSON.parse(JSON.stringify(this.data.Facilities))
data ? data.forEach(item => {
let realData = item.children
let allFireElements = JSON.parse(JSON.stringify(this.data.allFireElements))
item.children = this.processingData(allFireElements,realData)
}) :null
this.renderData = data
}
//处理数据 将消防要素模板与真实素材结合
processingData(allFireElements,realData){
allFireElements[allFireElements.length-1].children = []
nzEvent($event){
console.log($event)
realData.forEach(item => {
item.isLeaf = true
let noMatch = allFireElements.find( every=> every.id === item.FireElementId)
if (!noMatch) {
allFireElements[allFireElements.length-1].children.push(item)
}
//提交
submit () {
let oldTreeData = this.nzTreeComponent.getCheckedNodeList()
let alltreedata = JSON.parse(sessionStorage.getItem("tree型数据"))
let keyArr = []
oldTreeData.forEach(element => {
keyArr.push(element.origin.key)
})
if(alltreedata){
//如果已经保存过当前楼层则替换
alltreedata[this.data.buildFloorData.floorData.id] = keyArr
sessionStorage.setItem('tree型数据',JSON.stringify(alltreedata))
}else{
alltreedata = {}
alltreedata[this.data.buildFloorData.floorData.id] = keyArr
sessionStorage.setItem('tree型数据',JSON.stringify(alltreedata))
}
let checkList = [] //只存真实素材
for (const key in this.data.oldRealData.data) {
let element = this.data.oldRealData.data[key]
let isChecked = (this.nzTreeComponent.getTreeNodeByKey(key)).isChecked
isChecked? checkList.push(element) : null
let treeData = [] //tree型 处理完成后的数据
allFireElements.forEach(element => {
element.key = element.id
element.name != '其他' ? element.children = [] : null
if(realData && realData.length != 0){
realData.forEach(item => {
if(element.id == item.FireElementId){
element.children.push(item)
}
//存储真实素材数据
let basicAssetsId = []
if(checkList && checkList.length != 0){
checkList.forEach(item => {
basicAssetsId.push(item.TemplateId)
})
}
basicAssetsId = Array.from(new Set(basicAssetsId))
console.log(123,this.data.buildFloorData)
let obj = {
name:this.data.buildFloorData.buildingData.name + '-' + this.data.buildFloorData.floorData.name,
key:this.data.buildFloorData.floorData.id,
buildingId:this.data.buildFloorData.buildingData.id,
children:checkList,
basicAssetsId:basicAssetsId
}
let data = JSON.parse(sessionStorage.getItem("消防设施"+sessionStorage.getItem('paperId')))
allFireElements.forEach(item => { if (item.parentId == element.id) {element.children.push(item)} });
});
allFireElements.forEach(element => {
if (!element.parentId) { treeData.push(element) }
});
function recursionFilterEmpty(originalList, result) {
      for(let i = 0, length = originalList.length; i < length; i++) {
          const item = originalList[i];
          if (item.PropertyInfos) {
              // 最内层
              result.push(item);
          } else if (item.children && item.children.length) {
              const newChildren = [];
              // 递归调用,底层的真实数据会全部 push  newChildren 
              recursionFilterEmpty(item.children, newChildren);
              if (newChildren.length) {
                  // 替换原始数据
                  item.children = newChildren;
                  // 子项有真实的数据,就保留这一项
                  result.push(item);
              } // 如果没有这一项就会被删除
          }
      }
  }
  function filterEmpty(listData) {
      const result = [];
      recursionFilterEmpty(listData, result);
      return result;
  }
return filterEmpty(treeData)
if(data && data.length != 0){
console.log(1)
let ind = null
data.forEach((item,index) => {
if(item.key == obj.key){
ind = index + 1
}
})
if(ind){
if(checkList.length != 0){
data[ind - 1].children = checkList
}else{
data.splice(ind - 1,1)
}
}else{
data.push(obj)
}
sessionStorage.setItem("消防设施"+sessionStorage.getItem('paperId'),JSON.stringify(data))
}else{
console.log(2)
data = []
data[0] = obj
sessionStorage.setItem("消防设施"+sessionStorage.getItem('paperId'),JSON.stringify(data))
nzEvent($event){
console.log($event)
}
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('当层消防设施考题设置完成','确定',config);
this.dialogRef.close()
}
}
@ -158,28 +106,80 @@ export class uploadQuestionsExaminee {
constructor(private http:HttpClient, public dialog: MatDialog, public snackBar: MatSnackBar, public dialogRef: MatDialogRef<any>,
@Inject(MAT_DIALOG_DATA) public data,private route:ActivatedRoute) {}
defaultCheckedKeys = []; //指定选中复选框的树节点 key值
defaultExpandedKeys = []; //展开指定的树节点 key值
defaultSelectedKeys = []; //指定选中的树节点 key值
renderData:any
labeledOfBasicIcon:any //当前页面各建筑各楼层已标注的基本信息集合
async ngOnInit(): Promise<void> {
let params = {
examinationId : this.route.snapshot.queryParams.examId,
planComponentId : this.route.snapshot.queryParams.planComponentId
}
let SitePlanData
let BuildingPlanData
await new Promise((resolve,reject) => {
this.http.get('/api/ExamSitePlanData/ExamData',{params}).subscribe(data => {
SitePlanData = data
resolve(1)
})
})
await new Promise((resolve,reject) => {
this.http.get('/api/ExamBuildingAreaData/ExamData',{params}).subscribe(data => {
BuildingPlanData = data
resolve(2)
})
})
this.labeledOfBasicIcon = [...SitePlanData,...BuildingPlanData]
ngOnInit(): void {
let data = JSON.parse(sessionStorage.getItem("消防设施"+sessionStorage.getItem('paperId')))
let data = JSON.parse(JSON.stringify(this.data.Facilities))
console.log('一共有哪几层需要标注',data)
data ? data.forEach(item => {
let realData = item.children
item.children = this.processingData(this.data.allFireElements,realData)
let allFireElements = JSON.parse(JSON.stringify(this.data.allFireElements))
item.children = this.processingData(allFireElements,realData,item.key)
}) :null
this.renderData = data
this.getProfiles()
this.nodeInit()
}
//处理数据 将消防要素模板与真实素材结合
processingData(allFireElements,realData){
processingData(allFireElements,realData,key){
//key为当前处理数据的层id
allFireElements[allFireElements.length-1].children = []
//数组根据某个属性去重 (一类素材只保留一个)
const res = new Map();
realData = realData.filter((a) => !res.has(a.TemplateId) && res.set(a.TemplateId, 1))
console.log('当层需要标记的',realData)
this.labeledOfBasicIcon.forEach(item => {
if(item.sitePlanId == key || item.buildingAreaId == key ){
let data = JSON.parse(item.data)
console.log('当层已经标记的',data)
let arr = []
for (const key in data) {
arr.push(data[key])
}
realData.forEach(i => {
let isexist = arr.some((ele)=>{
return ele.TemplateId == i.TemplateId
})
isexist ? i.xxx = true : null
console.log(666,isexist)
})
}
})
realData.forEach(item => {
item.isLeaf = true
let noMatch = allFireElements.find( every=> every.id === item.FireElementId )
let noMatch = allFireElements.find( every=> every.id === item.FireElementId)
if (!noMatch) {
allFireElements[allFireElements.length-1].children.push(item)
}
@ -188,7 +188,7 @@ export class uploadQuestionsExaminee {
allFireElements.forEach(element => {
element.key = element.id
element.name != '其他' ? element.children = [] : null
if(realData){
if(realData && realData.length != 0){
realData.forEach(item => {
if(element.id == item.FireElementId){
element.children.push(item)
@ -225,40 +225,7 @@ export class uploadQuestionsExaminee {
      return result;
  }
return filterEmpty(treeData)
}
//获取登录账号的个人资料
Profiles:any
getProfiles(){
this.http.get('/api/ExamAccounts/Profiles').subscribe(data => {
this.Profiles = data
})
}
nodeTreeData:any = []; //处置节点tree
//节点初始化
nodeInit () {
let treeData = []
this.data.node.forEach(element => {
element.title = element.name //name
element.key = element.id //id
element.children = [] //children
if (element.sitePlanId || element.buildingAreaId) { //是数据节点
element.isLeaf = true
element.isDataNode = true
} else { //不是数据节点
element.isLeaf = false
element.isDataNode = false
}
this.data.node.forEach(item=>{
item.parentId === element.id? element.children.push(item) : null
})
});
this.data.node.forEach(element=>{
!element.parentId? treeData.push(element) : null
})
this.nodeTreeData = [...treeData]
}
nzEvent($event){
@ -266,36 +233,8 @@ export class uploadQuestionsExaminee {
}
//上传
submit () {
console.log(this.data.question)
let body:any = {
id: this.route.snapshot.queryParams.paperplanId,
paperId: sessionStorage.getItem('paperId'),
planComponentId: sessionStorage.getItem('planId'),
examPlanType: this.route.snapshot.queryParams.openType == 1 ? 0 : 1,
creatorId: this.Profiles.id,
modifiedTime: new Date(),
isPublic: true,
title: this.route.snapshot.queryParams.planName,
mainPoint: this.data.question.keynote,
score: 0,
examFacilityAssetsData: sessionStorage.getItem('消防设施' + sessionStorage.getItem('paperId')) ? sessionStorage.getItem('消防设施' + sessionStorage.getItem('paperId')) : null,
examDisposalNodesData: sessionStorage.getItem('examNodeList') ? sessionStorage.getItem('examNodeList') : null,
companyId:sessionStorage.getItem('companyId')
}
this.http.put(`/api/PaperPlans/${this.route.snapshot.queryParams.paperplanId}`,body).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('设置完成,页面将于一秒后关闭','确定',config);
setTimeout(() => {
window.close()
}, 1000);
})
}

3
src/app/ui/collection-tools-examinee/panel.scss

@ -252,6 +252,9 @@
color: #fff;
background-color: #07CDCF;
}
.selectSitePlanColor {
color: #FF8678;
}
//选中素材库图片时
.selectImg {
color: #fff;

36
src/app/ui/collection-tools-examinee/uploadQuestions.html

@ -1,19 +1,14 @@
<div style="min-width: 260px;" id="uploadfiretree">
<div style="text-align: center;font-weight: 550;">上传</div>
<div style="padding-left: 10px; font-size: 14px; font-weight: 550;margin: 5px 0;">考试要点</div>
<div style="margin-bottom: 25px;">
<textarea style="width: 100%;background-color: #dfe0e0;border: none;outline: none;height: 50px;border-radius: 5px;resize: none;" placeholder="请填写考试要点" [(ngModel)]="data.question.keynote"></textarea>
</div>
<div style="padding-left: 10px; font-size: 14px; font-weight: 550;margin: 5px 0;">考核消防设施</div>
<div style="text-align: center;font-weight: 550;">提交</div>
<div style="font-size: 14px; font-weight: 550;margin: 5px 0;">考核消防设施:</div>
<div style="max-height: 200px;overflow-y: auto;margin-bottom: 25px;">
<!-- 消防列表树 -->
<nz-tree
#nzTreeComponent
*ngIf="renderData"
[nzData]="renderData"
nzMultiple
[nzCheckedKeys]="defaultCheckedKeys"
[nzExpandedKeys]="defaultExpandedKeys"
[nzSelectedKeys]="defaultSelectedKeys"
nzExpandAll
(nzClick)="nzEvent($event)"
(nzExpandChange)="nzEvent($event)"
(nzCheckBoxChange)="nzEvent($event)"
@ -22,24 +17,9 @@
</nz-tree>
<ng-template #nzTreeTemplate let-node let-origin="origin">
<div class="treeNodeTemplate">
<label class="overflowText textNode">{{node.origin.name || node.origin.Name}}</label>
</div>
</ng-template>
<!-- 消防列表树 -->
</div>
<div style="padding-left: 10px; font-size: 14px; font-weight: 550;margin: 5px 0;">考核处置节点</div>
<div style="max-height: 200px;overflow-y: auto;margin-bottom: 25px;">
<!-- 消防列表树 -->
<nz-tree
#nzTreeComponent
[nzData]="nodeTreeData"
nzMultiple
[nzTreeTemplate]="nzTreeTemplate"
>
</nz-tree>
<ng-template #nzTreeTemplate let-node let-origin="origin">
<div class="treeNodeTemplate">
<label class="overflowText textNode">{{node.origin.name || node.origin.Name}}</label>
<label class="overflowText textNode">{{node.origin.name || node.origin.Name}}
<span *ngIf="node.origin.xxx" style="color: #FF8678;">(已标注)</span>
</label>
</div>
</ng-template>
<!-- 消防列表树 -->

1
src/app/ui/collection-tools/collection-tools.component.ts

@ -1134,6 +1134,7 @@ export class CollectionToolsComponent implements OnInit {
}
}
this.handleTreeData(storeyData) //处理tree数据结构
this.canvas.loadExamineeData(false)
}

3
src/app/ui/collection-tools/examinationQuestions.ts

@ -169,7 +169,8 @@ export class uploadQuestions {
let data = JSON.parse(sessionStorage.getItem("消防设施"+sessionStorage.getItem('paperId')))
data ? data.forEach(item => {
let realData = item.children
item.children = this.processingData(this.data.allFireElements,realData)
let allFireElements = JSON.parse(JSON.stringify(this.data.allFireElements))
item.children = this.processingData(allFireElements,realData)
}) :null
this.renderData = data
this.getProfiles()

125
src/app/working-area/model/axArrowConnector.ts

@ -1,12 +1,15 @@
import { WorkingAreaComponent } from '../working-area.component';
import * as PIXI from 'pixi.js';
import { AxShape } from './axShape';
import { Sprite } from 'pixi.js';
/**
*
*
*/
export class AxArrowConnector extends AxShape {
pointTexture: PIXI.Texture = PIXI.Texture.from('assets/images/handle-main.png')
pointSprites: Array<Sprite> = new Array<Sprite>();
line: PIXI.Graphics;
text: PIXI.Text;
style = new PIXI.TextStyle({
@ -27,8 +30,14 @@ export class AxArrowConnector extends AxShape {
});
pts: PIXI.Point[];
constructor(assetData: any, workingArea: WorkingAreaComponent) {
markerStart = true;// 是否绘制起始箭头
markerEnd = true;// 是否绘制结束箭头
constructor(assetData: any, workingArea: WorkingAreaComponent,markerStart: boolean,markerEnd:boolean) {
super(assetData, workingArea);
this.markerStart = markerStart;
this.markerEnd = markerEnd;
this.name = assetData.Id;
this.text = new PIXI.Text(this.assetData.Name
+ '\r\n'
@ -38,25 +47,92 @@ export class AxArrowConnector extends AxShape {
this.addChild(this.text);
this.addChild(this.line);
this.workingArea.backgroundImage.addChild(this);
this.refresh(this.line, this.assetData.MultiPoint);
this.refresh();
this.drawPoints();
this.sortableChildren = true;
this.text.zIndex = this.children.length;
this.text.visible = this.showName;
}
public drawPoints() {
this.assetData.MultiPoint.forEach(element => {
var point = new Sprite(this.pointTexture);
point.position = element;
point.anchor.set(0.5);
this.pointSprites.push(point);
this.addChild(point);
});
this.pointSprites.forEach((value, index, array) => {
value.interactive = true;
value.on('mousedown', event => {
event.stopPropagation();
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
}
})
.on('mouseup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('mouseupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('mousemove', event => {
if (event.currentTarget.dragging) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
event.currentTarget.x = newPosition.x;
event.currentTarget.y = newPosition.y;
this.assetData.MultiPoint[index].x = newPosition.x;
this.assetData.MultiPoint[index].y = newPosition.y;
this.workingArea.canvasData.isChange = true;
this.refresh();
}
})
.on('rightclick', event => {
});
})
this.setPointsVisible(false);
}
/**
*
* @param b true/false
*/
public setPointsVisible(b:boolean) {
this.pointSprites.forEach(item => {
item.visible = b;
})
}
/**
*
*/
public refresh(c: PIXI.Graphics, pts: PIXI.Point[]): void {
public refresh(): void {
const c = this.line;
const pts = this.assetData.MultiPoint;
if (pts.length < 2) {
return;
}
this.text.position = pts[0];
this.text.anchor.set(0.5, 1);
this.text.text = this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos?.find(item => item.PropertyName === '名称/编号')?.PropertyValue;
const strokeWidth = 1;
const startWidth = 30 + strokeWidth;
const endWidth = 30 + strokeWidth;
const edgeWidth = this.assetData.Thickness === 0?10:this.assetData.Thickness; // 宽度
const edgeWidth = this.assetData.Thickness === 0 ? 10 : this.assetData.Thickness; // 宽度
const openEnded = false;
const markerStart = false;// 起始箭头
const markerEnd = false;// 结束箭头
const spacing = (openEnded) ? 0 : 0 + strokeWidth / 2;
const startSize = 30 + strokeWidth;
const endSize = 30 + strokeWidth;
@ -101,11 +177,13 @@ export class AxArrowConnector extends AxShape {
// c.lineStyle(1, 0x000000, 1);
c.clear();
c.lineTextureStyle({ width: 1, color: lineColor, join: PIXI.LINE_JOIN.ROUND });
c.beginFill(fillColor);
const startNx = nx;
const startNy = ny;
if (markerStart && !openEnded) {
if (!openEnded) {
c.beginFill(fillColor);
}
if (this.markerStart && !openEnded) {
this.paintMarker(c, pts[0].x, pts[0].y, nx, ny, startSize, startWidth, edgeWidth, spacing, true);
} else {
const outStartX = pts[0].x + orthx / 2 + spacing * nx;
@ -213,7 +291,7 @@ export class AxArrowConnector extends AxShape {
orthx = edgeWidth * ny1;
orthy = - edgeWidth * nx1;
if (markerEnd && !openEnded) {
if (this.markerEnd && !openEnded) {
this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, false);
} else {
c.lineTo(pe.x - spacing * nx1 + orthx / 2, pe.y - spacing * ny1 + orthy / 2);
@ -235,18 +313,16 @@ export class AxArrowConnector extends AxShape {
for (let i = fns.length - 1; i >= 0; i--) {
fns[i]();
}
if (openEnded)
{
c.closePath();
}
else
{
c.closePath();
c.endFill();
// if (openEnded)
// {
// c.end();
// c.stroke();
// }
// else
// {
// c.close();
// c.fillAndStroke();
// }
}
// c.setShadow(false);
@ -320,6 +396,11 @@ export class AxArrowConnector extends AxShape {
}
redraw(): void{
this.refresh(this.line, this.assetData.MultiPoint);
this.pointSprites.forEach(item => {
item.destroy();
})
this.pointSprites.splice(0, this.pointSprites.length);
this.refresh();
this.drawPoints();
}
}

24
src/app/working-area/model/axImageShape.ts

@ -1,12 +1,12 @@
import { WorkingAreaComponent } from '../working-area.component';
import * as ObjectID from 'bson-objectid';
import { GameMode } from './gameMode';
import { Pipeline } from './pipeline';
import { PaintMode } from './paintModel';
import * as PIXI from 'pixi.js';
import { PropertyInfo } from './PropertyInfo';
import { AxShape } from './axShape';
import { Sprite } from 'pixi.js';
import { AxArrowConnector } from './axArrowConnector';
/**
*
@ -139,10 +139,7 @@ export class AxImageShape extends AxShape {
this.text.x = this.image.x;
this.text.y = this.image.y - this.image.height / 2;
this.text.anchor.set(0.5, 1);
if (this.assetData.GameMode === 2) {
this.text.visible = false;
}
this.text.visible = this.showName;
this.addChild(this.text);
this.addChild(this.image);
this.addChild(this.selectionBox);
@ -370,7 +367,7 @@ export class AxImageShape extends AxShape {
paintingPipeline(x: number, y: number) {
if (this.assetData.CanConnect) {
if (this.workingArea.getPaintMode() === PaintMode.Pipeline) {
if (this.workingArea.paintingPipeline === null) {
if (this.workingArea.paintingShape === null) {
this.workingArea.previewLineSegment.visible = true;
this.workingArea.currentClickPoint.position =
new PIXI.Point(this.workingArea.circleShadow.x, this.workingArea.circleShadow.y);
@ -407,20 +404,21 @@ export class AxImageShape extends AxShape {
IsFromBuilding : this.workingArea.canvasData.selectTemplateData.isFromBuilding,
GameMode: this.workingArea.canvasData.gameMode,
LinkedObjects: new Array(this.assetData.Id),
Tag: this.workingArea.canvasData.selectTemplateData.tag
};
this.workingArea.paintingPipeline = new Pipeline(tempData, this.workingArea);
this.assetData.Pipelines.push(this.workingArea.paintingPipeline.assetData.Id);
this.workingArea.emit('createIcon', this.workingArea.paintingPipeline);
this.workingArea.paintingShape = new AxArrowConnector(tempData, this.workingArea,false,true);
this.assetData.Pipelines.push(this.workingArea.paintingShape.assetData.Id);
this.workingArea.emit('createIcon', this.workingArea.paintingShape);
} else {
this.workingArea.previewLineSegment.visible = false;
this.workingArea.currentClickPoint.position =
new PIXI.Point(this.workingArea.circleShadow.x, this.workingArea.circleShadow.y);
this.workingArea.paintPoints.push(new PIXI.Point(x, y));
this.workingArea.paintingPipeline.assetData.MultiPoint =
this.workingArea.paintingShape.assetData.MultiPoint =
JSON.parse(JSON.stringify(this.workingArea.paintPoints));
this.workingArea.paintingPipeline.assetData.LinkedObjects.push(this.assetData.Id);
this.assetData.Pipelines.push(this.workingArea.paintingPipeline.assetData.Id);
this.workingArea.paintingPipeline.refresh();
this.workingArea.paintingShape.assetData.LinkedObjects.push(this.assetData.Id);
this.assetData.Pipelines.push(this.workingArea.paintingShape.assetData.Id);
this.workingArea.paintingShape.redraw();
this.workingArea.initPipelineData();
}
}

6
src/app/working-area/model/axShape.ts

@ -13,6 +13,8 @@ export class AxShape extends Container {
moveable = true;
// 可以被选中的
selectable = true;
// 是否显示名称
showName = true;
constructor(assetData: any, workingArea: WorkingAreaComponent) {
super();
@ -73,4 +75,8 @@ export class AxShape extends Container {
redraw(): void {
}
refresh(): void{
}
}

3
src/app/working-area/model/gameMode.ts

@ -3,5 +3,6 @@
*/
export enum GameMode {
BasicInformation,
Assignment
Assignment,
Examinee
}

104
src/app/working-area/model/multipointIcon.ts

@ -1,11 +1,12 @@
import { WorkingAreaComponent } from '../working-area.component';
import { GameMode } from './gameMode';
import * as PIXI from 'pixi.js';
import { AxShape } from './axShape';
/**
* 线
*/
export class MultipointIcon extends PIXI.Container {
export class MultipointIcon extends AxShape {
public pointsData: PIXI.Point[];
public pointsGraphics: PIXI.Graphics[] = [];
public iconsTilingSprite: PIXI.TilingSprite[] = [];
@ -34,8 +35,8 @@ export class MultipointIcon extends PIXI.Container {
* @param texture
* @param points
*/
constructor(public assetData: any, private workingArea: WorkingAreaComponent) {
super();
constructor(assetData: any,workingArea: WorkingAreaComponent) {
super(assetData,workingArea);
this.name = this.assetData.Id;
this.pointsData = this.assetData.MultiPoint;
this.x = this.assetData.Point.x;
@ -56,13 +57,14 @@ export class MultipointIcon extends PIXI.Container {
icon.x = pointA.x;
icon.y = pointA.y;
icon.angle = angle;
icon.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
// icon.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
this.iconsTilingSprite.push(icon);
this.addChild(icon);
if (i === 0) {
this.text.anchor.set(0.5);
this.text.position = icon.position;
this.text.y -= this.assetData.Height;
this.text.visible = this.showName;
this.addChild(this.text);
}
}
@ -173,50 +175,50 @@ export class MultipointIcon extends PIXI.Container {
// this.text.scale.set(scale);
// });
// 添加选中事件
this.iconsTilingSprite.forEach((item, index, array) => {
item.interactive = true;
item.buttonMode = true;
item.on('mousedown', event => {
event.stopPropagation();
this.workingArea.selection.selectOne(this);
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
event.currentTarget.parent.data = event.data;
event.currentTarget.parent.alpha = 0.5;
event.currentTarget.parent.dragging = true;
// this.iconsTilingSprite.forEach((item, index, array) => {
// item.interactive = true;
// item.buttonMode = true;
// item.on('mousedown', event => {
// event.stopPropagation();
// this.workingArea.selection.selectOne(this);
// if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
// event.currentTarget.parent.data = event.data;
// event.currentTarget.parent.alpha = 0.5;
// event.currentTarget.parent.dragging = true;
// event.currentTarget.parent.dragPoint = event.data.getLocalPosition(event.currentTarget.parent.parent);
// event.currentTarget.parent.dragPoint.x -= event.currentTarget.parent.x;
// event.currentTarget.parent.dragPoint.y -= event.currentTarget.parent.y;
// }
// })
// .on('mouseup', event => {
// if (event.currentTarget.parent.dragging) {
// event.currentTarget.parent.alpha = 1;
// event.currentTarget.parent.dragging = false;
// event.currentTarget.parent.data = null;
// }
// })
// .on('mouseupoutside', event => {
// if (event.currentTarget.parent.dragging) {
// event.currentTarget.parent.alpha = 1;
// event.currentTarget.parent.dragging = false;
// event.currentTarget.parent.data = null;
// }
// })
// .on('mousemove', event => {
// if (event.currentTarget.parent.dragging) {
// const newPosition = event.currentTarget.parent.data.getLocalPosition(event.currentTarget.parent.parent);
// event.currentTarget.parent.x = newPosition.x - event.currentTarget.parent.dragPoint.x;
// event.currentTarget.parent.y = newPosition.y - event.currentTarget.parent.dragPoint.y;
// this.assetData.Point = new PIXI.Point(this.x, this.y);
// this.workingArea.canvasData.isChange = true;
// }
// })
// .on('rightclick', event => {
event.currentTarget.parent.dragPoint = event.data.getLocalPosition(event.currentTarget.parent.parent);
event.currentTarget.parent.dragPoint.x -= event.currentTarget.parent.x;
event.currentTarget.parent.dragPoint.y -= event.currentTarget.parent.y;
}
})
.on('mouseup', event => {
if (event.currentTarget.parent.dragging) {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
}
})
.on('mouseupoutside', event => {
if (event.currentTarget.parent.dragging) {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
}
})
.on('mousemove', event => {
if (event.currentTarget.parent.dragging) {
const newPosition = event.currentTarget.parent.data.getLocalPosition(event.currentTarget.parent.parent);
event.currentTarget.parent.x = newPosition.x - event.currentTarget.parent.dragPoint.x;
event.currentTarget.parent.y = newPosition.y - event.currentTarget.parent.dragPoint.y;
this.assetData.Point = new PIXI.Point(this.x, this.y);
this.workingArea.canvasData.isChange = true;
}
})
.on('rightclick', event => {
});
});
// });
// });
}
/**
*
@ -235,10 +237,10 @@ export class MultipointIcon extends PIXI.Container {
}
// 刷新数据
public refresh() {
console.log(this.assetData);
this.iconsTilingSprite.forEach(element => {
element.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
});
// console.log(this.assetData);
// this.iconsTilingSprite.forEach(element => {
// element.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
// });
this.text.text = this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos.find(item => item.PropertyName === '名称/编号')?.PropertyValue;

328
src/app/working-area/model/pipeline.ts

@ -1,328 +0,0 @@
import { WorkingAreaComponent } from '../working-area.component';
import * as PIXI from 'pixi.js';
import { AxShape } from './axShape';
/**
* 线
*/
export class Pipeline extends AxShape {
public line: PIXI.Graphics = new PIXI.Graphics();
constructor(assetData: any, workingArea: WorkingAreaComponent) {
super(assetData, workingArea);
this.name = this.assetData.Id;
this.moveable = false;
this.x = this.assetData.Point.x;
this.y = this.assetData.Point.y;
this.workingArea.backgroundImage.addChild(this);
this.addChild(this.line);
// 画线图标
this.refresh();
this.interactive = true;
this.on('mousedown', event => {
event.stopPropagation();
this.workingArea.selection.selectOne(this);
});
}
/**
*
*/
public refresh() {
const strokeWidth = 1;
const startWidth = 30 + strokeWidth;
const endWidth = 30 + strokeWidth;
const edgeWidth = 10;
const openEnded = false;
const markerStart = false;
const markerEnd = true;
const spacing = (openEnded) ? 0 : 0 + strokeWidth / 2;
const startSize = 30 + strokeWidth;
const endSize = 30 + strokeWidth;
const isRounded = true;
const pts = this.assetData.MultiPoint;
const c = this.line;
if (pts.length < 2) { return; }
// Base vector (between first points)
const pe = pts[pts.length - 1];
// Finds first non-overlapping point
let i0 = 1;
while (i0 < pts.length - 1 && pts[i0].x === pts[0].x && pts[i0].y === pts[0].y) {
i0++;
}
const dx = pts[i0].x - pts[0].x;
const dy = pts[i0].y - pts[0].y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) {
return;
}
// Computes the norm and the inverse norm
let nx = dx / dist;
let nx1 = nx;
let nx2 = nx;
let ny = dy / dist;
let ny2 = ny;
let ny1 = ny;
let orthx = edgeWidth * ny;
let orthy = -edgeWidth * nx;
// Stores the inbound function calls in reverse order in fns
const fns = [];
// if (isRounded) {
// // c.setLineJoin('round');
// c.lineTextureStyle({ join: PIXI.LINE_JOIN.ROUND });
// } else if (pts.length > 2) {
// // Only mitre if there are waypoints
// // c.setMiterLimit(1.42);
// c.lineTextureStyle({ miterLimit: 1.42 });
// }
// c.lineStyle(1, 0x000000, 1);
c.clear();
c.lineTextureStyle({ width: 1, color: 0x00000, join: PIXI.LINE_JOIN.ROUND });
// c.begin();
c.beginFill(0xffffff);
const startNx = nx;
const startNy = ny;
if (markerStart && !openEnded) {
this.paintMarker(c, pts[0].x, pts[0].y, nx, ny, startSize, startWidth, edgeWidth, spacing, true);
} else {
const outStartX = pts[0].x + orthx / 2 + spacing * nx;
const outStartY = pts[0].y + orthy / 2 + spacing * ny;
const inEndX = pts[0].x - orthx / 2 + spacing * nx;
const inEndY = pts[0].y - orthy / 2 + spacing * ny;
if (openEnded) {
c.moveTo(outStartX, outStartY);
fns.push( () => {
c.lineTo(inEndX, inEndY);
});
} else {
c.moveTo(inEndX, inEndY);
c.lineTo(outStartX, outStartY);
}
}
let dx1 = 0;
let dy1 = 0;
let dist1 = 0;
for (let i = 0; i < pts.length - 2; i++) {
// Work out in which direction the line is bending
const pos = this.relativeCcw(pts[i].x, pts[i].y, pts[i + 1].x, pts[i + 1].y, pts[i + 2].x, pts[i + 2].y);
dx1 = pts[i + 2].x - pts[i + 1].x;
dy1 = pts[i + 2].y - pts[i + 1].y;
dist1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
if (dist1 !== 0) {
nx1 = dx1 / dist1;
ny1 = dy1 / dist1;
const tmp1 = nx * nx1 + ny * ny1;
const tmp = Math.max(Math.sqrt((tmp1 + 1) / 2), 0.04);
// Work out the normal orthogonal to the line through the control point and the edge sides intersection
nx2 = (nx + nx1);
ny2 = (ny + ny1);
const dist2 = Math.sqrt(nx2 * nx2 + ny2 * ny2);
if (dist2 !== 0) {
nx2 = nx2 / dist2;
ny2 = ny2 / dist2;
// Higher strokewidths require a larger minimum bend, 0.35 covers all but the most extreme cases
const strokeWidthFactor = Math.max(tmp, Math.min(1 / 200 + 0.04, 0.35));
const angleFactor = (pos !== 0 && isRounded) ? Math.max(0.1, strokeWidthFactor) : Math.max(tmp, 0.06);
const outX = pts[i + 1].x + ny2 * edgeWidth / 2 / angleFactor;
const outY = pts[i + 1].y - nx2 * edgeWidth / 2 / angleFactor;
const inX = pts[i + 1].x - ny2 * edgeWidth / 2 / angleFactor;
const inY = pts[i + 1].y + nx2 * edgeWidth / 2 / angleFactor;
if (pos === 0 || !isRounded) {
// If the two segments are aligned, or if we're not drawing curved sections between segments
// just draw straight to the intersection point
c.lineTo(outX, outY);
((x, y) => {
fns.push(() => {
c.lineTo(x, y);
});
})(inX, inY);
} else if (pos === -1) {
const c1x = inX + ny * edgeWidth;
const c1y = inY - nx * edgeWidth;
const c2x = inX + ny1 * edgeWidth;
const c2y = inY - nx1 * edgeWidth;
c.lineTo(c1x, c1y);
if (isRounded) {
c.quadraticCurveTo(outX, outY, c2x, c2y); // 圆角
} else {
c.lineTo(outX, outY);
}
((x, y) => {
fns.push(() => {
c.lineTo(x, y);
});
})(inX, inY);
} else {
c.lineTo(outX, outY);
((x, y) => {
const c1x = outX - ny * edgeWidth;
const c1y = outY + nx * edgeWidth;
const c2x = outX - ny1 * edgeWidth;
const c2y = outY + nx1 * edgeWidth;
fns.push(() => {
if (isRounded) {
c.quadraticCurveTo(x, y, c1x, c1y);
} else {
c.lineTo(x, y);
}
});
fns.push(() => {
c.lineTo(c2x, c2y);
});
})(inX, inY);
}
nx = nx1;
ny = ny1;
}
}
}
orthx = edgeWidth * ny1;
orthy = - edgeWidth * nx1;
if (markerEnd && !openEnded) {
this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, false);
} else {
c.lineTo(pe.x - spacing * nx1 + orthx / 2, pe.y - spacing * ny1 + orthy / 2);
const inStartX = pe.x - spacing * nx1 - orthx / 2;
const inStartY = pe.y - spacing * ny1 - orthy / 2;
if (!openEnded) {
c.lineTo(inStartX, inStartY);
} else {
c.moveTo(inStartX, inStartY);
fns.splice(0, 0, () => {
c.moveTo(inStartX, inStartY);
});
}
}
for (let i = fns.length - 1; i >= 0; i--) {
fns[i]();
}
c.closePath();
c.endFill();
// if (openEnded)
// {
// c.end();
// c.stroke();
// }
// else
// {
// c.close();
// c.fillAndStroke();
// }
// Workaround for shadow on top of base arrow
// c.setShadow(false);
// Need to redraw the markers without the low miter limit
// c.setMiterLimit(4);
// if (isRounded)
// {
// c.setLineJoin('flat');
// }
// if (pts.length > 2) {
// // Only to repaint markers if no waypoints
// // Need to redraw the markers without the low miter limit
// // c.setMiterLimit(4);
// c.lineTextureStyle({ width: 1, color: 0x00000, miterLimit: 4 });
// if (markerStart && !openEnded) {
// // c.begin();
// this.paintMarker(c, pts[0].x, pts[0].y, startNx, startNy, startSize, startWidth, edgeWidth, spacing, true);
// // c.stroke();
// // c.end();
// // c.closePath();
// }
// if (markerEnd && !openEnded) {
// // c.begin();
// this.paintMarker(c, pe.x, pe.y, -nx, -ny, endSize, endWidth, edgeWidth, spacing, true);
// // c.stroke();
// // c.end();
// // c.closePath();
// }
// }
}
/**
*
* @param c
* @param ptX
* @param ptY
* @param nx
* @param ny
* @param size
* @param arrowWidth
* @param edgeWidth
* @param spacing
* @param initialMove
*/
paintMarker(c: PIXI.Graphics, ptX: number, ptY: number, nx: number, ny: number,
size: number, arrowWidth: number, edgeWidth: number, spacing: number, initialMove: boolean) {
const widthArrowRatio = edgeWidth / arrowWidth;
const orthx = edgeWidth * ny / 2;
const orthy = -edgeWidth * nx / 2;
const spaceX = (spacing + size) * nx;
const spaceY = (spacing + size) * ny;
if (initialMove) {
c.moveTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
} else {
c.lineTo(ptX - orthx + spaceX, ptY - orthy + spaceY);
}
c.lineTo(ptX - orthx / widthArrowRatio + spaceX, ptY - orthy / widthArrowRatio + spaceY);
c.lineTo(ptX + spacing * nx, ptY + spacing * ny);
c.lineTo(ptX + orthx / widthArrowRatio + spaceX, ptY + orthy / widthArrowRatio + spaceY);
c.lineTo(ptX + orthx + spaceX, ptY + orthy + spaceY);
}
relativeCcw(x1: number, y1: number, x2: number, y2: number, px: number, py: number) {
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
let ccw = px * y2 - py * x2;
if (ccw === 0.0) {
ccw = px * x2 + py * y2;
if (ccw > 0.0) {
px -= x2;
py -= y2;
ccw = px * x2 + py * y2;
if (ccw < 0.0) {
ccw = 0.0;
}
}
}
return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
}
}

120
src/app/working-area/model/polygonIcon.ts

@ -2,11 +2,12 @@ import { WorkingAreaComponent } from '../working-area.component';
import { GameMode } from './gameMode';
import * as PIXI from 'pixi.js';
import { PaintMode } from './paintModel';
import { AxShape } from './axShape';
/**
*
*/
export class PolygonIcon extends PIXI.Container {
export class PolygonIcon extends AxShape {
public pointsData: PIXI.Point[];
public pointsGraphics: PIXI.Graphics[] = [];
public polygonGraphics: PIXI.Graphics = new PIXI.Graphics();
@ -35,8 +36,8 @@ export class PolygonIcon extends PIXI.Container {
*
* @param points
*/
constructor(public assetData: any, private workingArea: WorkingAreaComponent) {
super();
constructor(assetData: any,workingArea: WorkingAreaComponent) {
super(assetData,workingArea);
this.name = this.assetData.Id;
this.x = this.assetData.Point.x;
this.y = this.assetData.Point.y;
@ -72,6 +73,7 @@ export class PolygonIcon extends PIXI.Container {
this.text.anchor.set(0.5);
this.text.position = this.calculatePolygonGravityCenter(this.pointsData);
this.text.visible = this.showName;
// console.log(this.calculatePolygonGravityCenter(this.pointsData));
this.polygonGraphics.addChild(this.text);
// 添加圆点事件
@ -140,64 +142,64 @@ export class PolygonIcon extends PIXI.Container {
}
});
});
// 添加选中事件
this.polygonGraphics.interactive = true;
this.polygonGraphics.buttonMode = true;
this.polygonGraphics
.on('mousedown', event => {
event.stopPropagation();
this.workingArea.selection.selectOne(this);
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
event.currentTarget.parent.data = event.data;
event.currentTarget.parent.alpha = 0.5;
event.currentTarget.parent.dragging = true;
// // 添加选中事件
// this.polygonGraphics.interactive = true;
// this.polygonGraphics.buttonMode = true;
// this.polygonGraphics
// .on('mousedown', event => {
// event.stopPropagation();
// this.workingArea.selection.selectOne(this);
// if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
// event.currentTarget.parent.data = event.data;
// event.currentTarget.parent.alpha = 0.5;
// event.currentTarget.parent.dragging = true;
event.currentTarget.parent.dragPoint = event.data.getLocalPosition(event.currentTarget.parent.parent);
event.currentTarget.parent.dragPoint.x -= event.currentTarget.parent.x;
event.currentTarget.parent.dragPoint.y -= event.currentTarget.parent.y;
}
})
.on('mouseup', event => {
if (event.currentTarget.parent.dragging) {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
}
})
.on('mouseupoutside', event => {
if (event.currentTarget.parent.dragging) {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
}
})
.on('mousemove', event => {
if (event.currentTarget.parent.dragging) {
const newPosition = event.currentTarget.parent.data.getLocalPosition(event.currentTarget.parent.parent);
event.currentTarget.parent.x = newPosition.x - event.currentTarget.parent.dragPoint.x;
event.currentTarget.parent.y = newPosition.y - event.currentTarget.parent.dragPoint.y;
// event.currentTarget.parent.dragPoint = event.data.getLocalPosition(event.currentTarget.parent.parent);
// event.currentTarget.parent.dragPoint.x -= event.currentTarget.parent.x;
// event.currentTarget.parent.dragPoint.y -= event.currentTarget.parent.y;
// }
// })
// .on('mouseup', event => {
// if (event.currentTarget.parent.dragging) {
// event.currentTarget.parent.alpha = 1;
// event.currentTarget.parent.dragging = false;
// event.currentTarget.parent.data = null;
// }
// })
// .on('mouseupoutside', event => {
// if (event.currentTarget.parent.dragging) {
// event.currentTarget.parent.alpha = 1;
// event.currentTarget.parent.dragging = false;
// event.currentTarget.parent.data = null;
// }
// })
// .on('mousemove', event => {
// if (event.currentTarget.parent.dragging) {
// const newPosition = event.currentTarget.parent.data.getLocalPosition(event.currentTarget.parent.parent);
// event.currentTarget.parent.x = newPosition.x - event.currentTarget.parent.dragPoint.x;
// event.currentTarget.parent.y = newPosition.y - event.currentTarget.parent.dragPoint.y;
this.assetData.Point = new PIXI.Point(this.x, this.y);
this.workingArea.canvasData.isChange = true;
}
})
.on('rightclick', event => {
// this.workingArea.selection.deselectAll();
})
.on('mouseover', event => {
event.stopPropagation();
if (this.workingArea.previewImage !== null
&& this.workingArea.getPaintMode() === PaintMode.singlePointIcon) {
this.workingArea.previewImage.visible = false;
}
})
.on('mouseout', event => {
event.stopPropagation();
if (this.workingArea.previewImage !== null
&& this.workingArea.getPaintMode() === PaintMode.singlePointIcon) {
this.workingArea.previewImage.visible = true;
}
});
// this.assetData.Point = new PIXI.Point(this.x, this.y);
// this.workingArea.canvasData.isChange = true;
// }
// })
// .on('rightclick', event => {
// // this.workingArea.selection.deselectAll();
// })
// .on('mouseover', event => {
// event.stopPropagation();
// if (this.workingArea.previewImage !== null
// && this.workingArea.getPaintMode() === PaintMode.singlePointIcon) {
// this.workingArea.previewImage.visible = false;
// }
// })
// .on('mouseout', event => {
// event.stopPropagation();
// if (this.workingArea.previewImage !== null
// && this.workingArea.getPaintMode() === PaintMode.singlePointIcon) {
// this.workingArea.previewImage.visible = true;
// }
// });
}
/**
*

203
src/app/working-area/working-area.component.ts

@ -10,7 +10,6 @@ import { AxImageShape } from './model/axImageShape';
import { GameMode } from './model/gameMode';
import { MultipointIcon } from './model/multipointIcon';
import { PolygonIcon } from './model/polygonIcon';
import { Pipeline } from './model/pipeline';
import { PaintMode } from './model/paintModel';
import { AxShape } from './model/axShape';
import { PropertyInfo } from './model/PropertyInfo';
@ -82,10 +81,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*
*/
public paintPoints: PIXI.Point[] = [];
/**
* 线
*/
public paintingPipeline: Pipeline = null;
/**
*
*/
@ -278,11 +273,11 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
this.animator.update();
this.mousePosition = this.app.renderer.plugins.interaction.mouse.global;
// 预览图片
if (this.previewImage !== null) {
if (this.previewImage !== null && this.backgroundImage !== null) {
this.previewImage.position = this.backgroundImage.toLocal(this.mousePosition);
}
if (this.backgroundImage !== null) {
if (this.circleShadow !== null && this.backgroundImage !== null) {
this.circleShadow.position = this.backgroundImage.toLocal(this.mousePosition);
this.refreshPreviewLineSegment(this.currentClickPoint.position, this.circleShadow.position);
}
@ -314,7 +309,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*/
this.on('select', obj => {
if (this.allowEdit) {
if (obj instanceof MultipointIcon) {
if (obj instanceof AxArrowConnector) {
obj.setPointsVisible(true);
}
else if (obj instanceof MultipointIcon) {
if (obj.assetData.GameMode === this.canvasData.gameMode) {
obj.setPointVisiable(true);
} else {
@ -338,7 +336,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*/
this.on('deselect', obj => {
if (this.allowEdit) {
if (obj instanceof MultipointIcon) {
if (obj instanceof AxArrowConnector) {
obj.setPointsVisible(false);
}
else if (obj instanceof MultipointIcon) {
obj.setPointVisiable(false);
} else if (obj instanceof PolygonIcon) {
obj.filters = [];
@ -375,6 +376,12 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
} else if (item instanceof AxPreviewImageShape) {
const data = 1 / scale;
item.scale.set(data);
}else if (item instanceof AxArrowConnector) {
const data = 1 / scale;
item.text.scale.set(data);
item.pointSprites.forEach(point => {
point.scale.set(data);
});
}
});
@ -383,11 +390,21 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*
*/
this.on('createIcon', obj => {
if (obj.assetData.GameMode === GameMode.BasicInformation) {
if (obj.assetData.GameMode === GameMode.BasicInformation) { // 基本信息
// 添加楼层数据
this.canvasData.originaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
// 添加建筑数据
this.canvasData.originalcompanyBuildingData.data[obj.assetData.Id] = obj.assetData;
} else if(obj.assetData.GameMode === GameMode.Assignment){ // 处置预案
if (this.canvasData.selectPanelPoint.Data === undefined
|| this.canvasData.selectPanelPoint.Data === null) {
this.canvasData.selectPanelPoint.Data = new FloorNodeData();
}
this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id] = obj.assetData;
} else if (obj.assetData.GameMode === GameMode.Examinee) { // 考生考试
console.log(obj.assetData.Tag)
if (obj.assetData.Tag === 1) {
this.canvasData.examOriginaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
} else {
if (this.canvasData.selectPanelPoint.Data === undefined
|| this.canvasData.selectPanelPoint.Data === null) {
@ -395,6 +412,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
}
this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id] = obj.assetData;
}
}
this.canvasData.isChange = true;
});
}
@ -465,30 +483,65 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
}
this.selection.select(obj);
});
}
// /**
// * 刷新工作区
// */
public async refresh() {
//this.loadExamineeData();
// this.setPaintMode(PaintMode.endPaint);
// this.resetCanvas();
// this.destroyBackgroundImage();
// if (!this.canvasData.selectStorey.imageUrl) {
// return;
// }
// await this.createBackgroundImage(this.canvasData.selectStorey.imageUrl);
// this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// if (this.canvasData.gameMode === GameMode.Assignment) {
// this.createNodeShape(this.canvasData.selectPanelPoint.Data);
// }
}
/**
*
*
*/
public async refresh() {
this.setPaintMode(PaintMode.endPaint);
this.resetCanvas();
this.destroyBackgroundImage();
if (!this.canvasData.selectStorey.imageUrl) {
return;
public loadExamineeData(b: boolean = true) {
this.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
if (b) {
this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data);
this.processinghiddenData();
}
await this.createBackgroundImage(this.canvasData.selectStorey.imageUrl);
this.createFloorShape();
if (this.canvasData.gameMode === GameMode.Assignment) {
this.createWorkNode();
this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
this.createNodeShape(this.canvasData.selectPanelPoint.Data);
this.setNameVisible(false, 0);
this.setNameVisible(false, 1);
}
this.emit('backgroundScale', this.backgroundImage.scale.x);
/**
*
*/
public processinghiddenData() {
for (let key in this.canvasData.originaleveryStoreyData.data){
if (this.canvasData.hiddenBasicInfoFacilities.indexOf(key)!==-1) {
delete this.canvasData.originaleveryStoreyData.data[key];
}
}
}
/**
*
*/
public createBackground(imageUrl:string,imageAngle:number) {
if (this.backgroundImage !== null) {
this.backgroundImage.destroy();
this.backgroundImage = null;
}
this.createBackgroundImage()
this.refreshBackgroundImage(imageUrl,imageAngle);
}
/**
*
*/
private createFloorShape() {
const floorData = this.canvasData.originaleveryStoreyData.data;
public createFloorShape(floorData: any) {
Object.keys(floorData).forEach((key) => {
switch (floorData[key].InteractiveMode) {
case 0:
@ -503,18 +556,21 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
break;
case 3:
if (floorData[key].Name === '水带') {
const pipeline = new Pipeline(floorData[key], this);
} else {
const wall = new AxArrowConnector(floorData[key], this);
const distance = new AxArrowConnector(floorData[key], this, false, true);
} else if(floorData[key].Name === '距离'){
const distance = new AxArrowConnector(floorData[key], this, true, true);
}else if(floorData[key].Name === '普通墙' || floorData[key].Name === '承重墙'){
const wall = new AxArrowConnector(floorData[key], this, false, false);
}
break;
}
});
this.emit('backgroundScale', this.backgroundImage.scale.x);
}
private createWorkNode() {
// 加载处置节点数据
const nodeData = this.canvasData.selectPanelPoint.Data;
/**
*
*/
public createNodeShape(nodeData: any) {
if (nodeData !== undefined && nodeData !== null) {
Object.keys(nodeData).forEach((key) => {
Object.keys(nodeData[key]).forEach((tempKey) => {
@ -530,13 +586,15 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
const polygonIcon = new PolygonIcon(nodeData[key][tempKey], this);
break;
case 3:
const pipeline = new Pipeline(nodeData[key][tempKey], this);
const pipeline = new AxArrowConnector(nodeData[key][tempKey], this,false,true);
break;
}
});
});
}
this.emit('backgroundScale', this.backgroundImage.scale.x);
}
/**
*
* @param id ID
@ -607,19 +665,16 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
/**
*
*/
private async createBackgroundImage(imageUrl: string): Promise<void> {
const image = await PIXI.Texture.fromURL(imageUrl);
this.backgroundImage = new PIXI.Sprite(image);
public createBackgroundImage(){
this.backgroundImage = PIXI.Sprite.from('assets/images/noImg.png')
this.backgroundImage.anchor.set(0.5);
this.backgroundImage.x = this.app.view.width / 2;
this.backgroundImage.y = this.app.view.height / 2;
this.backgroundImage.interactive = true;
this.backgroundImage.name = 'background';
this.backgroundImage.angle = this.canvasData.selectStorey.imageAngle;
// const left = this.init.element.nativeElement.querySelector('.functionalDomainLeft').clientWidth;
// const right = this.init.element.nativeElement.querySelector('.functionalDomainRight').clientWidth;
const imageWidth = this.backgroundImage.texture.width;
const imageHeight = this.backgroundImage.texture.height;
const imageWidth = 665;
const imageHeight = 530;
const appWidth = this.app.view.width - 470;
const appHeight = this.app.view.height;
@ -675,7 +730,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
DrawMode : this.canvasData.selectTemplateData.drawMode,
Thickness : this.canvasData.selectTemplateData.thickness,
IsFromBuilding : this.canvasData.selectTemplateData.isFromBuilding,
GameMode : this.canvasData.gameMode
GameMode: this.canvasData.gameMode,
Tag: this.canvasData.selectTemplateData.tag
};
const singleIcon = new AxImageShape(assetData, this);
this.emit('createIcon', singleIcon);
@ -722,7 +778,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
DrawMode: this.canvasData.selectTemplateData.drawMode,
Thickness: this.canvasData.selectTemplateData.thickness,
IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding,
GameMode: this.canvasData.gameMode
GameMode: this.canvasData.gameMode,
Tag: this.canvasData.selectTemplateData.tag
};
// const assetData1 = {
// ImageUrl: this.canvasData.selectTemplateData.imageUrl,
@ -763,20 +820,20 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
break;
case PaintMode.Pipeline:
if (this.canvasData.selectTemplateData.name === '水带') {
if (this.paintingPipeline !== null) {
if (this.paintingShape !== null) {
this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
this.paintingPipeline.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
this.paintingPipeline.refresh();
this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
this.paintingShape.refresh();
}
} else {
this.previewLineSegment.visible = true;
this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
if (this.paintPoints.length >= 2) {
this.enterPaintEndButton.position = this.circleShadow.position;
this.enterPaintEndButton.visible = true;
this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
if (this.paintPoints.length < 2) {
return;
}
if (this.paintingShape === null) {
const jsonObject = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos));
@ -807,9 +864,14 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
DrawMode: this.canvasData.selectTemplateData.drawMode,
Thickness: this.canvasData.selectTemplateData.thickness,
IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding,
GameMode: this.canvasData.gameMode
GameMode: this.canvasData.gameMode,
Tag: this.canvasData.selectTemplateData.tag
};
this.paintingShape = new AxArrowConnector(assetData2, this);
if (this.canvasData.selectTemplateData.name === '距离') {
this.paintingShape = new AxArrowConnector(assetData2, this,true,true);
} else if (this.canvasData.selectTemplateData.name === '普通墙' || this.canvasData.selectTemplateData.name === '承重墙') {
this.paintingShape = new AxArrowConnector(assetData2, this,false,false);
}
} else {
this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
this.paintingShape.redraw();
@ -907,14 +969,23 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
/**
*
*/
public refreshBackgroundImage(): void {
if (!this.canvasData.selectStorey.imageUrl) {
public async refreshBackgroundImage(imageUrl:string = this.canvasData.selectStorey.imageUrl,imageAngle:number = this.canvasData.selectStorey.imageAngle): Promise<void> {
if (!imageUrl) {
this.backgroundImage.visible = false;
} else {
// this.backgroundImage.texture = PIXI.Texture.from(this.canvasData.selectStorey.imageUrl);
// this.backgroundImage.angle = this.canvasData.selectStorey.imageAngle;
// this.backgroundImage.visible = true;
this.refresh();
this.backgroundImage.texture = await PIXI.Texture.fromURL(imageUrl);
const imageWidth = this.backgroundImage.texture.width;
const imageHeight = this.backgroundImage.texture.height;
const appWidth = this.app.view.width - 470;
const appHeight = this.app.view.height;
const wScale = appWidth / imageWidth;
const hScale = appHeight / imageHeight;
const scale = wScale < hScale? wScale: hScale;
this.backgroundImage.scale.set(scale);
this.backgroundImage.angle = imageAngle;
this.backgroundImage.visible = true;
}
}
/**
@ -922,6 +993,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*/
public destroyBackgroundImage(): void {
this.app.stage.removeChild(this.backgroundImage);
this.backgroundImage = null;
}
/**
*
@ -1000,6 +1072,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*
*/
public beginPaint() {
console.log(this.canvasData.selectTemplateData);
this.selection.deselectAll();
this.setPaintMode(PaintMode.endPaint);
this.setPaintMode(this.canvasData.selectTemplateData.interactiveMode);
@ -1009,7 +1082,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
*/
public initPipelineData(): void {
this.paintPoints = [];
this.paintingPipeline = null;
this.paintingShape = null;
}
public beginPaintingArrows(): void {
this.paintMode = PaintMode.Arrows;
@ -1064,10 +1137,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
this.backgroundImage.removeChild(this.paintingIcon);
}
if (this.paintingPipeline !== undefined
&& this.paintingPipeline !== null) {
this.backgroundImage.removeChild(this.paintingPipeline);
}
// if (this.paintingShape !== undefined
// && this.paintingShape !== null) {
// this.backgroundImage.removeChild(this.paintingShape);
// }
if (this.paintingShape !== null) {
this.backgroundImage.removeChild(this.paintingShape);
this.paintingShape = null;
@ -1196,8 +1269,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV
const polygonIcon = new PolygonIcon(newData, this);
break;
case PaintMode.Pipeline:
if (item.Name !== '水带') {
const wall = new AxArrowConnector(newData, this);
if (item.Name === '距离') {
const wall = new AxArrowConnector(newData, this,true,true);
} else if (item.Name === '普通墙' || item.Name === '承重墙') {
const wall = new AxArrowConnector(newData, this,false,false);
}
break;
}

Loading…
Cancel
Save