邵佳豪 4 years ago
parent
commit
2a8396d5c3
  1. 20
      package-lock.json
  2. 2
      package.json
  3. 458
      src/app/canvas-share-data.service.ts
  4. 109
      src/app/examiner/create-test-score/create-test-score.component.ts
  5. 32
      src/app/examiner/create-test-score/editors.html
  6. 44
      src/app/examiner/create-test-score/finishDia.scss
  7. 32
      src/app/examiner/examiner-index/editors.html
  8. 23
      src/app/examiner/examiner-index/examiner-index.component.ts
  9. 12
      src/app/examiner/examiner-new-one/examiner-new-one.component.ts
  10. 3
      src/app/examiner/examiner.module.ts
  11. 3
      src/app/examiner/mark-papers-two/mark-papers-two.component.ts
  12. 41
      src/app/examiner/review-files/review-files.component.html
  13. 80
      src/app/examiner/review-files/review-files.component.ts
  14. 4
      src/app/student/student-exam-record/student-exam-record.component.html
  15. 6
      src/app/student/student-exam-record/student-exam-record.component.ts
  16. 4
      src/app/tabbar/tabbar.component.html
  17. 17
      src/app/ui/collection-tools-examinee/collection-tools.component.html
  18. 6
      src/app/ui/collection-tools-examinee/collection-tools.component.scss
  19. 25
      src/app/ui/collection-tools-read/collection-tools.component.html
  20. 6
      src/app/ui/collection-tools-read/collection-tools.component.scss
  21. 13
      src/app/ui/collection-tools-read/collection-tools.component.ts
  22. 2
      src/app/ui/collection-tools-read/examinationQuestions.html
  23. 14
      src/app/ui/collection-tools/collection-tools.component.html
  24. 6
      src/app/ui/collection-tools/collection-tools.component.scss
  25. 15
      src/app/ui/collection-tools/collection-tools.component.ts
  26. 46
      src/app/ui/enterpriseuser/addenterpriseuser.component.html
  27. 90
      src/app/ui/enterpriseuser/addenterpriseuser.component.ts
  28. 39
      src/app/ui/enterpriseuser/editenterpriseuser.html
  29. 25
      src/app/ui/enterpriseuser/enterpriseuser.component.html
  30. 30
      src/app/ui/enterpriseuser/enterpriseuser.component.scss
  31. 217
      src/app/ui/enterpriseuser/enterpriseuser.component.ts
  32. 46
      src/app/ui/teacherManagement/addenterpriseuser.component.html
  33. 91
      src/app/ui/teacherManagement/addenterpriseuser.component.ts
  34. 41
      src/app/ui/teacherManagement/editenterpriseuser.html
  35. 21
      src/app/ui/teacherManagement/enterpriseuser.component.html
  36. 30
      src/app/ui/teacherManagement/enterpriseuser.component.scss
  37. 200
      src/app/ui/teacherManagement/enterpriseuser.component.ts
  38. 71
      src/app/working-area/model/axArrowConnector.ts
  39. 179
      src/app/working-area/model/axGrid.ts
  40. 492
      src/app/working-area/model/axImageShape.ts
  41. 11
      src/app/working-area/model/axImageShapeTest.ts
  42. 404
      src/app/working-area/model/axLegend.ts
  43. 90
      src/app/working-area/model/axMessageSystem.ts
  44. 21
      src/app/working-area/model/axRectangleShape.ts
  45. 64
      src/app/working-area/model/axSelection.ts
  46. 196
      src/app/working-area/model/axShape.ts
  47. 165
      src/app/working-area/model/configuration.ts
  48. 145
      src/app/working-area/model/dimensioning.ts
  49. 71
      src/app/working-area/model/events.ts
  50. 87
      src/app/working-area/model/grid2D.ts
  51. 37
      src/app/working-area/model/messageSystem.ts
  52. 49
      src/app/working-area/model/multipointIcon.ts
  53. 10
      src/app/working-area/model/polygonIcon.ts
  54. 3
      src/app/working-area/working-area.component.html
  55. 1493
      src/app/working-area/working-area.component.ts
  56. BIN
      src/assets/images/enterPaintButton.png

20
package-lock.json generated

@ -11999,7 +11999,7 @@
},
"parse5": {
"version": "5.1.1",
"resolved": "https://registry.npm.taobao.org/parse5/download/parse5-5.1.1.tgz?cache=0&sync_timestamp=1595849319979&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse5%2Fdownload%2Fparse5-5.1.1.tgz",
"resolved": "https://registry.npm.taobao.org/parse5/download/parse5-5.1.1.tgz",
"integrity": "sha1-9o5OW6GFKsLK3AD0VV//bCq7YXg=",
"optional": true
},
@ -12898,6 +12898,11 @@
"sha.js": "^2.4.8"
}
},
"penner": {
"version": "0.1.3",
"resolved": "https://registry.npm.taobao.org/penner/download/penner-0.1.3.tgz",
"integrity": "sha1-C4tILU6bOa8vPXw3WSIpuKzClwU="
},
"perfect-scrollbar": {
"version": "1.5.0",
"resolved": "https://registry.npm.taobao.org/perfect-scrollbar/download/perfect-scrollbar-1.5.0.tgz",
@ -12975,6 +12980,14 @@
"@pixi/filter-zoom-blur": "3.1.1"
}
},
"pixi-viewport": {
"version": "4.20.0",
"resolved": "https://registry.npm.taobao.org/pixi-viewport/download/pixi-viewport-4.20.0.tgz",
"integrity": "sha1-Gu3vsQhZqv7toJUJ8o4jNvaVDQ4=",
"requires": {
"penner": "^0.1.3"
}
},
"pixi.js": {
"version": "5.3.3",
"resolved": "https://registry.npm.taobao.org/pixi.js/download/pixi.js-5.3.3.tgz",
@ -15913,6 +15926,11 @@
}
}
},
"three": {
"version": "0.125.2",
"resolved": "https://registry.npm.taobao.org/three/download/three-0.125.2.tgz",
"integrity": "sha1-3LoSdJoutBUi4VISuRnNP79ymxI="
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz",

2
package.json

@ -35,9 +35,11 @@
"ngx-echarts": "^4.2.2",
"ngx-perfect-scrollbar": "^8.0.0",
"pixi-filters": "^3.1.1",
"pixi-viewport": "^4.20.0",
"pixi.js": "^5.3.2",
"rxjs": "~6.5.4",
"swiper": "^5.3.7",
"three": "^0.125.2",
"tslib": "^1.10.0",
"viewerjs": "^1.9.0",
"zone.js": "~0.10.2"

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

@ -1,75 +1,79 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {ReplaySubject} from 'rxjs';
import { ReplaySubject } from 'rxjs';
import { Observable } from 'rxjs';
import { GameMode } from './working-area/model/gameMode';
@Injectable({
providedIn: 'root'
})
export class CanvasShareDataService {
constructor() { }
constructor(private http: HttpClient) { }
private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1);
examDisposalNodesData//考生进入时获取当前试卷的处置节点
examFacilityAssetsData//考生进入时获取当前试卷要考察的消防设施
examDisposalNodesData; // 考生进入时获取当前试卷的处置节点
examFacilityAssetsData; // 考生进入时获取当前试卷要考察的消防设施
examOriginaleveryStoreyData: any; // 考生答卷 总平面图/楼层/区域 楼层数据
hiddenBasicInfoFacilities: any = []; // 考生答卷 当前楼层需要隐藏的基本信息素材
isChange = false; // 数据 是否改动
isChange: boolean = false; // 数据 是否改动
selectTemplateData: any; // 选择当前 模板数据
// 总平面图/建筑 楼层
selectStorey: any = {area: '', details: ''}; // 选择当前 楼层 数据
selectStorey: any = { area: '', details: '' }; // 选择当前 楼层 数据
originalcompanyBuildingData: any; // 单位/建筑 数据
originaleveryStoreyData: any; // 总平面图/楼层/区域 楼层数据
examOriginaleveryStoreyData: any; // 考生答卷 总平面图/楼层/区域 楼层数据
hiddenBasicInfoFacilities: any = []// 考生答卷 当前楼层需要隐藏的基本信息素材
// 总平面图/建筑 楼层
// 处置 节点
allDisposalNode: any = []; // 所有 处置节点
allNodeMarkers: any; // 灾情 标签信息
selectPanelPoint: DisposalNodeData = new DisposalNodeData();
selectPanelPointBaseData: any = {description: '', notes: '', weather: '', airTemperature: '', windDirection: '', windScale: ''}; // 当前 数据节点 所对应的 天气,详情 数据节点
allNodeMarkers: any = { highlightMarkers: {}, markers: {} }; // 灾情 标签信息
selectPanelPoint: DisposalNodeData = new DisposalNodeData(); // 当前数据节点
selectPanelPointBaseData: any = { description: '', notes: '', weather: '', airTemperature: '', windDirection: '', windScale: '' }; // 当前 数据节点 对应 父级节点
customizeDisposalNode: any; // 新建 自定义数据节点 底图+名称
// 处置 节点
/**
*
*/
gameMode: GameMode = GameMode.Examinee;
gameMode: GameMode = GameMode.BasicInformation;
facilityAssetsName = new Map<string, string>([
[ '消防水池', '消防水池'],
[ '疏散楼梯', '疏散楼梯'],
[ '消防电梯', '消防电梯'],
[ '避难区域', '避难区域'],
[ '安全出口', '安全出口'],
[ '地上消火栓', '室外消火栓' ],
[ '地下消火栓', '室外消火栓' ],
[ '室内消火栓', '室内消火栓' ],
[ '供水管网', '供水管网'],
[ '湿式自动喷淋系统', '湿式自动喷淋系统'],
[ '水幕系统', '水幕系统' ],
[ '消防泵房', '消防泵房'],
[ '水泵接合器(地上)', '水泵接合器'],
[ '水泵接合器(地下)', '水泵接合器'],
[ '水泵接合器(墙壁)', '水泵接合器'],
[ '消防水泵房', '消防水泵房'],
[ '箱式消火栓', '箱式消火栓'],
[ '固定水炮', '消防水炮' ],
[ '消防水罐', '储水罐'],
[ '消防水罐2', '储水罐'],
[ '卧式水罐', '储水罐'],
[ '消防泵', '水泵' ],
[ '泡沫泵', '水泵' ],
[ '泡沫泵房', '泡沫站'],
[ '泡沫栓', '泡沫栓' ],
[ '泡沫枪', '泡沫枪'],
[ '泡沫发生器', '泡沫发生器' ],
[ '消防管网', '消防管网'],
[ 'DCS控制室', 'DCS控制室']
['消防水池', '消防水池'],
['疏散楼梯', '疏散楼梯'],
['消防电梯', '消防电梯'],
['避难区域', '避难区域'],
['安全出口', '安全出口'],
['地上消火栓', '室外消火栓'],
['地下消火栓', '室外消火栓'],
['室内消火栓', '室内消火栓'],
['供水管网', '供水管网'],
['湿式自动喷淋系统', '湿式自动喷淋系统'],
['水幕系统', '水幕系统'],
['消防泵房', '消防泵房'],
['水泵接合器(地上)', '水泵接合器'],
['水泵接合器(地下)', '水泵接合器'],
['水泵接合器(墙壁)', '水泵接合器'],
['水泵接合器(喷淋)', '水泵接合器'],
['水泵接合器(消防)', '水泵接合器'],
['消防水泵房', '消防水泵房'],
['箱式消火栓', '箱式消火栓'],
['固定水炮', '消防水炮'],
['消防水罐', '储水罐'],
['消防水罐2', '储水罐'],
['卧式水罐', '储水罐'],
['消防泵', '水泵'],
['泡沫泵', '水泵'],
['泡沫泵房', '泡沫站'],
['泡沫栓', '泡沫栓'],
['泡沫枪', '泡沫枪'],
['泡沫发生器', '泡沫发生器'],
['消防管网', '消防管网'],
['泡沫管网', '消防管网'],
['DCS控制室', 'DCS控制室']
]);
/** * *
@ -77,12 +81,55 @@ export class CanvasShareDataService {
public sendMessage(message: any) {
this._sendMessage.next(message);
}
public getMessage(): Observable <any> {
public getMessage(): Observable<any> {
return this._sendMessage.asObservable();
}
//分段上传
sectionUpload(companyId: string, file) {
let data = { filename: file.name }
return new Promise((resolve, reject) => {
this.http.post(`/api/NewMultipartUpload/PlanPlatform/${companyId}/DisposalNode`, {}, { params: data }).subscribe(async (data: any) => { //初始化分段上传
let objectName = data.objectName
let uploadId = data.uploadId
let PartNumberETag = []; //每次返回需要保存的信息
//分块 处理
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/${objectName}?uploadId=${uploadId}&partNumber=${i + 1}`, formData).subscribe((data: any) => {
let msg = { "partNumber": data.partNumber || null, "eTag": data.eTag || null }
resolve(msg) // 调用 promise 内置方法处理成功
})
});
PartNumberETag.push(result)
if (PartNumberETag.length === allSlice) { //分块上传完成
let data = PartNumberETag
let paramsData = { uploadId: uploadId }
this.http.post(`/api/CompleteMultipartUpload/PlanPlatform/${objectName}`, data, { params: paramsData }).subscribe(data => {
resolve(objectName)
})
}
}//for循环
//分块 处理
})
})
}
// 处置节点 筛选出 匹配数据 匹配不到 return undefined
findDisposalNode(parentId: string= null, name: string= null) {
findDisposalNode(parentId: string = null, name: string = null) {
if (parentId && name) { // 匹配 父id, name
const returnData = this.allDisposalNode.find(item => item.parentId === parentId && item.name === name);
return returnData;
@ -95,6 +142,13 @@ export class CanvasShareDataService {
*
*/
public updateBuildingData() {
// 删除建筑数据中当前层数据
Object.keys(this.originalcompanyBuildingData.data).forEach((key) => {
if (this.originalcompanyBuildingData.data[key].FloorId === this.selectStorey.id) {
delete this.originalcompanyBuildingData.data[key];
}
});
// 新增当前层数据到建筑数据
Object.keys(this.originaleveryStoreyData.data).forEach((key) => {
this.originalcompanyBuildingData.data[key] = this.originaleveryStoreyData.data[key];
});
@ -102,7 +156,7 @@ export class CanvasShareDataService {
/**
*
*/
public deleteBuildingDataByCurrentFloorData():void {
public deleteBuildingDataByCurrentFloorData(): void {
Object.keys(this.originaleveryStoreyData.data).forEach((key) => {
// 删除建筑数据
delete this.originalcompanyBuildingData.data[key];
@ -242,7 +296,22 @@ export class CanvasShareDataService {
facility.Id = '';
facility.Name = this.facilityAssetsName.get(item.Name);
facility.AssetName = item.Name;
facility.PropertyInfos = item.PropertyInfos;
facility.PropertyInfos = [];
item.PropertyInfos.forEach(e => {
var p: PropertyInfo = new PropertyInfo();
p.Enabled = e.Enabled;
p.Order = e.Order;
p.PhysicalUnit = e.PhysicalUnit;
p.PropertyName = e.PropertyName;
p.PropertyType = e.PropertyType;
p.PropertyValue = e.PropertyValue.toString();
p.Required = e.Required;
p.RuleName = e.RuleName;
p.RuleValue = e.RuleValue;
p.Tag = e.Tag;
p.Visible = e.Visible;
facility.PropertyInfos.push(p);
});
facility.SitePlanId = item.FloorId;
list.push(facility);
}
@ -263,7 +332,22 @@ export class CanvasShareDataService {
facility.Id = '';
facility.Name = this.facilityAssetsName.get(item.Name);
facility.AssetName = item.Name;
facility.PropertyInfos = item.PropertyInfos;
facility.PropertyInfos = [];
item.PropertyInfos.forEach(e => {
var p: PropertyInfo = new PropertyInfo();
p.Enabled = e.Enabled;
p.Order = e.Order;
p.PhysicalUnit = e.PhysicalUnit;
p.PropertyName = e.PropertyName;
p.PropertyType = e.PropertyType;
p.PropertyValue = e.PropertyValue.toString();
p.Required = e.Required;
p.RuleName = e.RuleName;
p.RuleValue = e.RuleValue;
p.Tag = e.Tag;
p.Visible = e.Visible;
facility.PropertyInfos.push(p);
});
facility.BuildingAreaId = item.FloorId;
list.push(facility);
}
@ -312,7 +396,7 @@ export class CompanyAdjoinInfo {
*
*/
export class BuildingAdjoinInfo {
public BuildingId: string;
public BuildingId: string;
public Id: string;
public Name: string;
public Direction: number;
@ -354,7 +438,7 @@ export class CompanyFacilityAssetInfo {
public Id: string;
public Name: string;
public AssetName: string;
public PropertyInfos: string;
public PropertyInfos: PropertyInfo[];
public AssetId: string;
public CompanyId: string;
public SitePlanId: string;
@ -366,7 +450,7 @@ export class BuildingFacilityAssetInfo {
public Id: string;
public Name: string;
public AssetName: string;
public PropertyInfos: string;
public PropertyInfos: PropertyInfo[];
public AssetId: string;
public BuildingId: string;
public BuildingAreaId: string;
@ -506,62 +590,62 @@ export class DisposalNode {
*
*/
export enum Direction {
/**
*
*/
East,
/**
* 西
*/
West,
/**
*
*/
South,
/**
*
*/
North,
/**
*
*/
Southeast,
/**
* 西
*/
Southwest,
/**
*
*/
Northeast,
/**
* 西
*/
Northwest
/**
*
*/
East,
/**
* 西
*/
West,
/**
*
*/
South,
/**
*
*/
North,
/**
*
*/
Southeast,
/**
* 西
*/
Southwest,
/**
*
*/
Northeast,
/**
* 西
*/
Northwest
}
/**
*
*/
export enum WindScale {
WS0,
WS1,
WS2,
WS3,
WS4,
WS5,
WS6,
WS7,
WS8,
WS9,
WS10,
WS11,
WS12,
WS13,
WS14,
WS15,
WS16,
WS17,
WS18
WS0,
WS1,
WS2,
WS3,
WS4,
WS5,
WS6,
WS7,
WS8,
WS9,
WS10,
WS11,
WS12,
WS13,
WS14,
WS15,
WS16,
WS17,
WS18
}
/**
*
@ -579,6 +663,14 @@ export class DisposalNodeData {
*
*/
public Version: string;
/**
*
*/
public BackgroundImageUrl: string;
/**
*
*/
public BackgroundImageAngle: number;
/**
*
*/
@ -609,105 +701,105 @@ export class FloorNodeData {
*
*/
export class AssetData {
/// <summary>
/// 模板编号
/// </summary>
/// <summary>
/// 模板编号
/// </summary>
public TemplateId: string;
/// <summary>
/// 编号
/// </summary>
/// <summary>
/// 编号
/// </summary>
public Id: string;
/// <summary>
/// 名称
/// </summary>
/// <summary>
/// 名称
/// </summary>
public Name: string;
/// <summary>
/// 角度
/// </summary>
/// <summary>
/// 角度
/// </summary>
public Angle: number;
/// <summary>
/// 颜色
/// </summary>
/// <summary>
/// 颜色
/// </summary>
public Color: string;
/// <summary>
/// 坐标
/// </summary>
/// <summary>
/// 坐标
/// </summary>
public Point: PIXI.Point;
/// <summary>
/// 宽度
/// </summary>
/// <summary>
/// 宽度
/// </summary>
public Width: number;
/// <summary>
/// 高度
/// </summary>
/// <summary>
/// 高度
/// </summary>
public Height: number;
/// <summary>
/// 是否启用
/// </summary>
/// <summary>
/// 是否启用
/// </summary>
public Enabled: boolean;
/// <summary>
/// 填充方式
/// </summary>
/// <summary>
/// 填充方式
/// </summary>
public FillMode: FillMode;
/// <summary>
/// 图片地址
/// </summary>
/// <summary>
/// 图片地址
/// </summary>
public ImageUrl: string;
/// <summary>
/// 是否固定大小
/// </summary>
public FixedSize: boolean;
/// <summary>
/// 点路径
/// </summary>
/// <summary>
/// 是否固定大小
/// </summary>
public FixedSize: boolean;
/// <summary>
/// 点路径
/// </summary>
public MultiPoint: PIXI.Point[];
/// <summary>
/// 建筑ID
/// </summary>
/// <summary>
/// 建筑ID
/// </summary>
public BuildingId: string;
/// <summary>
/// 单位ID
/// </summary>
/// <summary>
/// 单位ID
/// </summary>
public CompanyId: string;
/// <summary>
/// 楼层编号
/// </summary>
/// <summary>
/// 楼层编号
/// </summary>
public FloorId: string;
/// <summary>
/// 楼层名称
/// </summary>
/// <summary>
/// 楼层名称
/// </summary>
public FloorName: string;
/// <summary>
/// 消防要素编号
/// </summary>
/// <summary>
/// 消防要素编号
/// </summary>
public FireElementId: string;
/// <summary>
/// 属性列表
/// </summary>
/// <summary>
/// 属性列表
/// </summary>
public PropertyInfos: PropertyInfo[];
/// <summary>
/// 交互方式
/// </summary>
/// <summary>
/// 交互方式
/// </summary>
public InteractiveMode: InteractiveMode;
/// <summary>
/// 是否来自建筑
/// </summary>
/// <summary>
/// 是否来自建筑
/// </summary>
public IsFromBuilding: boolean;
/// <summary>
/// 渲染方式。
/// </summary>
/// <summary>
/// 渲染方式。
/// </summary>
public DrawMode: ImageType;
/// <summary>
/// 9宫格边框数值。
/// </summary>
/// <summary>
/// 9宫格边框数值。
/// </summary>
public Border: Border;
/// <summary>
/// 厚度。
/// </summary>
/// <summary>
/// 厚度。
/// </summary>
public Thickness: number;
/// <summary>
/// 素材类型
/// </summary>
/// <summary>
/// 素材类型
/// </summary>
public GameMode: GameMode;
}
/**
@ -748,9 +840,9 @@ export enum ImageType {
*/
export class Border {
public x: number;
public x: number;
public y: number;
public y: number;
public z: number;

109
src/app/examiner/create-test-score/create-test-score.component.ts

@ -75,8 +75,10 @@ export class CreateTestScoreComponent implements OnInit {
}
//获得指定试卷信息。
editdata
getSoloPaper(){
this.http.get(`/api/Papers/${sessionStorage.getItem('paperId')}`).subscribe((data:any) => {
this.editdata=data
data.paperDataInfo.forEach(item => {
this.unitId.push(JSON.parse(item.originalData))
})
@ -1283,13 +1285,17 @@ export class CreateTestScoreComponent implements OnInit {
paperDataInfo:paperDataInfo
}
this.http.put(`/api/Papers/UpdatePaperData/${sessionStorage.getItem('paperId')}`,body).subscribe(data => {
const config = new MatSnackBarConfig();
const dialogRef = this.dialog.open(editorsDia, {
width: '650px',
data: this.editdata
});
/* const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('创建试卷成功,页面将于一秒后退出','确定',config);
setTimeout(() => {
this.router.navigateByUrl('/home/createexam-index')
}, 1000);
}, 1000); */
})
})
@ -1550,3 +1556,102 @@ export class LookTreeNodeDialog {
}
}
//编辑试题弹窗
@Component({
selector: 'finish-dialog',
templateUrl: 'editors.html',
styleUrls: ['finishDia.scss']
})
export class editorsDia{
constructor(private router:Router,private http: HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar,public dialogRef: MatDialogRef<editorsDia>,@Inject(MAT_DIALOG_DATA) public datas: any) {}
ngOnInit(): void {
/* this.startTime=this.datas.startTime
this.endTime=this.datas.endTime */
this.startTime=this.datas.startTime.split("+")[0]
this.endTime=this.datas.endTime.split("+")[0]
this.examName=this.datas.title
console.log(this.datas)
}
//获取登录账号的个人资料
Profiles:any
getProfiles(){
this.http.get('/api/ExamAccounts/Profiles').subscribe((data:any) => {
console.log(data)
this.Profiles = data
sessionStorage.setItem('creatorData',JSON.stringify(data))
})
}
startTime:string//考试开始时间
endTime:string//考试结束时间
examName:string//考试名称
indexid:string//创建考试的id
tabledate
//弹窗确定点击事件
onNoClick(): void {
//console.log( this.startTime,this.endTime)
if(this.startTime>this.endTime){
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('开始时间不能早于结束时间','确定',config);
}else{
let body = {
id:this.datas.id,
startTime:this.startTime,
endTime:this.endTime,
title:this.examName
}
let params = {
id: null,
title: this.examName,
duration: this.datas.duration,
modifiedTime: new Date(),
deleted: false,
startTime: this.startTime,
endTime: this.endTime,
organizationId: this.datas.organizationId,
creatorId: this.datas.creatorId,
paperDataInfo: null
}
this.http.put(`/api/Papers/${this.datas.id}`,body).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('修改试卷成功','确定',config);
this.router.navigateByUrl('/home/createexam-index')
this.dialogRef.close();
/* setTimeout(() => {
this.http.get(`/api/Papers/${this.datas.id}`).subscribe((data:any) => {
if(data.paperDataInfo.length==0){
this.http.delete(`/api/Papers/${this.datas.id}`).subscribe((data:any) => {
})
this.http.post('/api/Papers',params).subscribe(data => {
//sessionStorage.removeItem("checkedWork")
sessionStorage.setItem("paperId",this.datas.id)
this.router.navigate(['/home/createexam-index/examiner-index']) //跳转试卷列表页面
},err => {
this.snackBar.open(err,'确定',config);
})
}else{
sessionStorage.setItem("paperId",this.datas.id)
this.router.navigateByUrl("/examiner/create-test-score?pattern=edit")
}
})
this.dialogRef.close();
}, 1000); */
})
}
}
close(){
this.dialogRef.close();
}
}

32
src/app/examiner/create-test-score/editors.html

@ -0,0 +1,32 @@
<!--
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2021-02-23 14:49:48
* @LastEditors: sueRimn
* @LastEditTime: 2021-02-23 15:38:47
-->
<div class="box">
<div class="diaone">
<div style="margin-bottom: 5px;"><label>请填写修改后的试卷名称:</label></div>
<div><input placeholder="请填写" [(ngModel)]="examName"></div>
</div>
<div class="diatwo">
<div class="starttime">
<div style="margin-bottom: 5px;"><label>请选择开始时间:</label></div>
<!-- <div><nz-range-picker class="datepicker" nzFormat="yyyy-MM-dd HH:mm" [nzShowTime]="{ nzHideDisabledOptions: true, nzDefaultOpenValue: timeDefaultValue }" [nzDisabledTime]="disabledDateTime" [(ngModel)]="date" (ngModelChange)="onChange($event)"></nz-range-picker>
</div> -->
<div><input type="datetime-local" name="start_time" [(ngModel)]="startTime" /></div>
</div>
<div class="endtime">
<div style="margin-bottom: 5px;"><label>请选择结束时间:</label></div>
<div><input type="datetime-local" name="end_time" [(ngModel)]="endTime"/></div>
</div>
</div>
<div mat-dialog-actions style="margin-top: 20px;">
<button mat-button (click)="onNoClick()" style="background-color: #07CDCF;margin-left: 200px;color: #fff;">确定</button>
<button mat-button type="button" (click)="close()" style=" background-color: #FF8678;margin-left: 25px;color: #fff;">取消</button>
</div>
</div>

44
src/app/examiner/create-test-score/finishDia.scss

@ -0,0 +1,44 @@
.box{
display: flex;
flex-direction: column;
margin-left: 20px;
input{
width: 260px;
height: 40px;
line-height: 34px;
border-radius: 5px;
padding-left: 5px;
outline: none;
border: 1px solid rgb(226, 211, 211);
}
.diaone{
display: flex;
flex-direction: column;
button {
border: none;
color: white;
padding: 5px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 8px;
outline:0 none !important;
}
}
.diatwo{
margin-top: 20px;
display: flex;
flex-direction: row;
.endtime{
margin-left: 20px;
}
.datepicker{
height: 44px;
border-radius: 5px;
}
}
}

32
src/app/examiner/examiner-index/editors.html

@ -0,0 +1,32 @@
<!--
* @Descripttion:
* @version:
* @Author: sueRimn
* @Date: 2021-02-23 14:49:48
* @LastEditors: sueRimn
* @LastEditTime: 2021-02-23 15:38:47
-->
<div class="box">
<div class="diaone">
<div style="margin-bottom: 5px;"><label>请填写修改后的试卷名称:</label></div>
<div><input placeholder="请填写" [(ngModel)]="examName"></div>
</div>
<div class="diatwo">
<div class="starttime">
<div style="margin-bottom: 5px;"><label>请选择开始时间:</label></div>
<!-- <div><nz-range-picker class="datepicker" nzFormat="yyyy-MM-dd HH:mm" [nzShowTime]="{ nzHideDisabledOptions: true, nzDefaultOpenValue: timeDefaultValue }" [nzDisabledTime]="disabledDateTime" [(ngModel)]="date" (ngModelChange)="onChange($event)"></nz-range-picker>
</div> -->
<div><input type="datetime-local" name="start_time" [(ngModel)]="startTime" /></div>
</div>
<div class="endtime">
<div style="margin-bottom: 5px;"><label>请选择结束时间:</label></div>
<div><input type="datetime-local" name="end_time" [(ngModel)]="endTime"/></div>
</div>
</div>
<div mat-dialog-actions style="margin-top: 20px;">
<button mat-button (click)="onNoClick()" style="background-color: #07CDCF;margin-left: 200px;color: #fff;">确定</button>
<button mat-button type="button" (click)="close()" style=" background-color: #FF8678;margin-left: 25px;color: #fff;">取消</button>
</div>
</div>

23
src/app/examiner/examiner-index/examiner-index.component.ts

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-11 09:06:03
* @LastEditors: sueRimn
* @LastEditTime: 2021-01-04 16:13:12
* @LastEditTime: 2021-02-25 11:44:34
*/
import { Component, OnInit, ViewChild, Inject,Input } from '@angular/core';
import {HttpClient} from '@angular/common/http'
@ -126,12 +126,23 @@ export class ExaminerIndexComponent implements OnInit {
//编辑试卷
editPaper(item){
console.log(item)
if(item.status == 2){
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('考试结束,不能编辑','确定',config);
}else{
}else if(item.status == 1){
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('开考中,不能编辑','确定',config);
}
else{
/* const dialogRef = this.dialog.open(editorsDia, {
width: '650px',
data: item
}); */
sessionStorage.setItem("paperId",item.id)
this.router.navigateByUrl("/examiner/create-test-score?pattern=edit")
}
@ -308,6 +319,7 @@ export class ExaminerIndexComponent implements OnInit {
}
//创建试题弹窗
@Component({
selector: 'finish-dialog',
templateUrl: 'finishDia.html',
@ -361,8 +373,6 @@ export class FinishDia{
var n=min2-min1;
//将日期和时间两个部分计算出来的差值相加,即得到两个时间相减后的分钟数
var minutes=m+n;
console.log(this.startTime,this.endTime)
let params = {
id: null,
title: this.examName,
@ -375,7 +385,7 @@ export class FinishDia{
creatorId: this.Profiles.id,
paperDataInfo: null
}
//console.log(params)
this.http.post('/api/Papers',params).subscribe(data => {
this.snackBar.open('创建成功','确定',config);
this.dialogRef.close();
@ -405,3 +415,6 @@ export class FinishDia{
this.dialogRef.close();
}
}

12
src/app/examiner/examiner-new-one/examiner-new-one.component.ts

@ -4,7 +4,7 @@
* @Author: sueRimn
* @Date: 2020-12-11 16:34:26
* @LastEditors: sueRimn
* @LastEditTime: 2020-12-21 11:03:29
* @LastEditTime: 2021-02-23 17:13:27
*/
import { Component, OnInit, ViewChild, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http'
@ -36,6 +36,7 @@ export class ExaminerNewOneComponent implements OnInit {
this.getUnittype();
this.getAllKeyUnit();
}
pattern:any = this.route.snapshot.queryParams.pattern || ''
indexid=sessionStorage.getItem("paperId") //上个页面传过来的id
removeClass=document.getElementsByClassName("mat-form-field-underline")
@ -343,7 +344,7 @@ export class ExaminerNewOneComponent implements OnInit {
}
//下一步事件
nextClick(){
//console.log(this.selectedunitArr)
console.log(this.pattern)
/* var workDate=[]
for(var i=0;i<this.selectedunitArr.length;i++){
workDate.push(this.selectedunitArr[i].buildingTypes)
@ -356,8 +357,13 @@ export class ExaminerNewOneComponent implements OnInit {
this.snackBar.open('请选择单位','确定',config);
}
else{
sessionStorage.setItem(this.indexid,JSON.stringify(this.selectedunitArr) )
if(this.pattern=='edit'){
this.router.navigateByUrl("/examiner/create-test-score?pattern=edit")
}else{
sessionStorage.setItem(this.indexid,JSON.stringify(this.selectedunitArr) )
this.router.navigateByUrl("/examiner/create-test-score")
}
}
}

3
src/app/examiner/examiner.module.ts

@ -58,10 +58,11 @@ import { MarkPapersTwoComponent } from './mark-papers-two/mark-papers-two.compon
import { StatisticAnalysisComponent } from './statistic-analysis/statistic-analysis.component';
import { FinishDia }from './examiner-index/examiner-index.component';
import { ReviewFilesComponent,editRightWrongComponent } from './review-files/review-files.component'
import { editorsDia } from './create-test-score/create-test-score.component'
@NgModule({
declarations: [CreateTestScoreComponent,AddPlanDialog,AddPlanTwoDialog,LookTreeNodeDialog,ExaminerIndexComponent, ExaminerNewOneComponent,FinishDialog,PlanLevel,MarkPapersIndexComponent, MarkPapersTwoComponent, StatisticAnalysisComponent,FinishDia, ReviewFilesComponent,editRightWrongComponent],
declarations: [CreateTestScoreComponent,AddPlanDialog,AddPlanTwoDialog,LookTreeNodeDialog,ExaminerIndexComponent, ExaminerNewOneComponent,FinishDialog,PlanLevel,MarkPapersIndexComponent, MarkPapersTwoComponent, StatisticAnalysisComponent,FinishDia, ReviewFilesComponent,editRightWrongComponent,editorsDia],
imports: [
CommonModule,
examinerRoutingModule,

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

@ -60,7 +60,6 @@ export class MarkPapersTwoComponent implements OnInit {
this.http.get("/api/Examinations",{params:paramsdata}).subscribe((data:any)=>{
this.dataSource=data.items
this.length=data.totalCount
console.log(this.dataSource)
})
}
@ -72,7 +71,7 @@ export class MarkPapersTwoComponent implements OnInit {
//阅卷
reviewFiles (e) {
window.open(`/reviewFiles?examId=${e.id}`)
window.open(`/reviewFiles?examId=${e.id}&paperType=1`)
}
}

41
src/app/examiner/review-files/review-files.component.html

@ -19,7 +19,7 @@
<div class="headerRight">
<label (click)='togglePaperType(1)' [ngClass]="{'selectPaperType': selectPaperType == '1'}">基本信息</label>
<label (click)='togglePaperType(2)' [ngClass]="{'selectPaperType': selectPaperType == '2'}">作战部署</label>
<button (click)='submitResult()' style="width: 100px;">提交阅卷结果</button>
<button (click)='submitResult()' style="width: 100px;" *ngIf="paperType==1">提交阅卷结果</button>
<label style="float: right;margin-right: 25px;opacity: 1;width: 150px;" *ngIf="selectPaperType == '1'">基本信息总分:
{{selectPaper.basicInfoTotalPoints+selectPaper.adjoinTotalPoints+selectPaper.importLocationTotalPoints+selectPaper.functionalDivisionTotalPoints+selectPaper.facilityTotalPoints}}分
</label>
@ -33,7 +33,7 @@
<mat-expansion-panel-header class="panelHeader">
<label class="mariginRight">基本信息</label>
<label>总分: <label class="mark"> {{selectPaper.basicInfoScore}}</label>分, </label><label>单项<label class="mark"> {{selectPaper.basicInfoItemScore}}</label></label>
<button class="headerButton" *ngIf="selectPaper.basicInfoScore == selectPaper.basicInfoTotalPoints">全部正确</button>
<button class="headerButton" *ngIf="selectPaper.basicInfoScore == selectPaper.basicInfoTotalPoints && paperType==1">全部正确</button>
</mat-expansion-panel-header>
<div class="publicTest" *ngFor="let item of selectPaper.basicInfoData;let itemkey = index">
<div class="publicTitle">{{item.name}}</div>
@ -46,8 +46,8 @@
<input type="text" [(ngModel)]="elements.userAnswer" name="userAnswer" *ngIf="key!=0" readonly>
<mat-icon *ngIf="key!=0 && elements.isRight" class="rightWrong">done</mat-icon>
<mat-icon *ngIf="key!=0 && !elements.isRight" class="mistakeIcon rightWrong">clear</mat-icon>
<mat-icon *ngIf="key!=0" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0" class="rightKey">{{elements.result}}</p>
<mat-icon *ngIf="key!=0 && paperType==1" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0 && paperType==1" class="rightKey">{{elements.result}}</p>
</div>
</ng-container>
</div>
@ -57,8 +57,8 @@
<label>{{element.name}}:</label><input type="text" [(ngModel)]="element.userAnswer" name="userAnswer" readonly>
<mat-icon *ngIf="element.isRight">done</mat-icon>
<mat-icon class="mistakeIcon" *ngIf="!element.isRight">clear</mat-icon>
<button class="modificationResults" (click)='editResults(element)'>修改结果</button>
<p class="rightKey">{{element.result}}</p>
<button class="modificationResults" (click)='editResults(element)' *ngIf="paperType==1">修改结果</button>
<p class="rightKey" *ngIf="paperType==1">{{element.result}}</p>
</div>
</ng-container>
</div>
@ -69,7 +69,7 @@
<mat-expansion-panel-header class="panelHeader">
<label class="mariginRight">四周毗邻</label>
<label>总分: <label class="mark"> {{selectPaper.adjoinScore}}</label>分, </label><label>单项<label class="mark"> {{selectPaper.adjoinItemScore}}</label></label>
<button class="headerButton" *ngIf="selectPaper.adjoinScore == selectPaper.adjoinTotalPoints">全部正确</button>
<button class="headerButton" *ngIf="selectPaper.adjoinScore == selectPaper.adjoinTotalPoints && paperType==1">全部正确</button>
</mat-expansion-panel-header>
<div class="publicTest" *ngFor="let item of selectPaper.adjoinData">
<div class="publicTitle">{{item.name}}</div>
@ -77,8 +77,8 @@
<label>{{element.name}}:</label><input type="text" [(ngModel)]="element.userAnswer" name="userAnswer" readonly>
<mat-icon *ngIf="element.isRight">done</mat-icon>
<mat-icon class="mistakeIcon" *ngIf="!element.isRight">clear</mat-icon>
<button class="modificationResults" (click)='editResults(element)'>修改结果</button>
<p class="rightKey">{{element.result}}</p>
<button class="modificationResults" (click)='editResults(element)' *ngIf="paperType==1">修改结果</button>
<p class="rightKey" *ngIf="paperType==1">{{element.result}}</p>
</div>
</div>
</mat-expansion-panel>
@ -88,7 +88,7 @@
<mat-expansion-panel-header class="panelHeader">
<label class="mariginRight">重点部位</label>
<label>总分: <label class="mark"> {{selectPaper.importLocationScore}}</label>分, </label><label>单项<label class="mark"> {{selectPaper.importLocationItemScore}}</label></label>
<button class="headerButton" *ngIf="selectPaper.importLocationScore == selectPaper.importLocationTotalPoints">全部正确</button>
<button class="headerButton" *ngIf="selectPaper.importLocationScore == selectPaper.importLocationTotalPoints && paperType==1">全部正确</button>
</mat-expansion-panel-header>
<div class="publicTest" *ngFor="let item of selectPaper.importLocationData">
<div class="publicTitle">{{item.name}}</div>
@ -100,8 +100,8 @@
<input type="text" [(ngModel)]="elements.userAnswer" name="userAnswer" *ngIf="key!=0" readonly>
<mat-icon *ngIf="key!=0 && elements.isRight">done</mat-icon>
<mat-icon *ngIf="key!=0 && !elements.isRight" class="mistakeIcon">clear</mat-icon>
<mat-icon *ngIf="key!=0" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0" class="rightKey">{{elements.result}}</p>
<mat-icon *ngIf="key!=0 && paperType==1" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0 && paperType==1" class="rightKey">{{elements.result}}</p>
</div>
</div>
</div>
@ -113,7 +113,7 @@
<mat-expansion-panel-header class="panelHeader">
<label class="mariginRight">功能分区</label>
<label>总分: <label class="mark"> {{selectPaper.functionalDivisionScore}}</label>分, </label><label>单项<label class="mark"> {{selectPaper.functionalDivisionItemSocre}}</label></label>
<button class="headerButton" *ngIf="selectPaper.functionalDivisionScore == selectPaper.functionalDivisionTotalPoints">全部正确</button>
<button class="headerButton" *ngIf="selectPaper.functionalDivisionScore == selectPaper.functionalDivisionTotalPoints && paperType==1">全部正确</button>
</mat-expansion-panel-header>
<div class="publicTest" *ngFor="let item of selectPaper.functionalDivisionData">
<div class="publicTitle">{{item.name}}</div>
@ -125,8 +125,8 @@
<input type="text" [(ngModel)]="elements.userAnswer" name="userAnswer" *ngIf="key!=0" readonly>
<mat-icon *ngIf="key!=0 && elements.isRight">done</mat-icon>
<mat-icon *ngIf="key!=0 && !elements.isRight" class="mistakeIcon">clear</mat-icon>
<mat-icon *ngIf="key!=0" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0" class="rightKey">{{elements.result}}</p>
<mat-icon *ngIf="key!=0 && paperType==1" title="修改结果" (click)='editResults(elements)'>create</mat-icon>
<p *ngIf="key!=0 && paperType==1" class="rightKey">{{elements.result}}</p>
</div>
</div>
</div>
@ -138,7 +138,7 @@
<mat-expansion-panel-header class="panelHeader">
<label class="mariginRight">数据核验</label>
<label>总分: <label class="mark"> {{selectPaper.facilityScore}}</label>分, </label><label>单项<label class="mark"> {{selectPaper.facilityItemScore}}</label></label>
<button class="headerButton" *ngIf="selectPaper.facilityScore == selectPaper.facilityTotalPoints">全部正确</button>
<button class="headerButton" *ngIf="selectPaper.facilityScore == selectPaper.facilityTotalPoints && paperType==1">全部正确</button>
</mat-expansion-panel-header>
<div class="publicTest" *ngFor="let item of selectPaper.facilityData">
<div class="publicTitle">{{item.name}}</div>
@ -146,8 +146,8 @@
<label>{{element.name}}:</label><input type="text" [(ngModel)]="element.userAnswer" name="userAnswer" readonly>
<mat-icon *ngIf="element.isRight">done</mat-icon>
<mat-icon class="mistakeIcon" *ngIf="!element.isRight">clear</mat-icon>
<button class="modificationResults" (click)='editResults(element)'>修改结果</button>
<p class="rightKey">{{element.result}}</p>
<button class="modificationResults" (click)='editResults(element)' *ngIf="paperType==1">修改结果</button>
<p class="rightKey" *ngIf="paperType==1">{{element.result}}</p>
</div>
</div>
</mat-expansion-panel>
@ -176,12 +176,13 @@
<td style="color: #FF8678;">{{item.score || '暂未评分'}}</td>
<td>{{item.score ? '已阅' : '未阅'}}</td>
<td>
<span style="color: #07CDCF;" (click)="readExam(item)">阅卷</span>
<span style="color: #07CDCF;" (click)="readExam(item,0)" *ngIf="paperType==1">阅卷</span>
<span style="color: #07CDCF;" (click)="readExam(item,1)" *ngIf="paperType!=1">查看</span>
</td>
</tr>
</table>
</div>
<div class="refresh">
<div class="refresh" *ngIf="paperType==1">
<mat-icon style="margin-left: 14%;" (click)="refreshTable()">refresh</mat-icon>
<span style="font-size: 12px;">(阅卷完成后请点击此按钮刷新表格数据)</span>
</div>

80
src/app/examiner/review-files/review-files.component.ts

@ -14,10 +14,12 @@ export class ReviewFilesComponent implements OnInit {
constructor(public http:HttpClient,public dialog: MatDialog,public snackBar: MatSnackBar,public route:ActivatedRoute) { }
async ngOnInit(): Promise<void> {
this.paperType = this.route.snapshot.queryParams.paperType || 1
await this.getTest()
this.getUnitPlans()//将试卷的预案考题放进数据中
}
paperType:any = 1; //阅卷/查看
examId:any = this.route.snapshot.queryParams.examId; //考卷id
paperId:any; //试卷id
paperData:any //试卷信息
@ -32,6 +34,7 @@ export class ReviewFilesComponent implements OnInit {
this.http.get(`/api/Examinations/${this.examId}`).subscribe((data:any)=>{
this.paperData = data
this.paperId = this.paperData.paperId
this.paperData.examinationDataInfo.forEach((element,index) => {
element.adjoinData? element.adjoinData = JSON.parse(element.adjoinData) : null
element.basicInfoData? element.basicInfoData = JSON.parse(element.basicInfoData) : null
@ -43,11 +46,19 @@ export class ReviewFilesComponent implements OnInit {
element.facilityItemScore = data.paperInfo.paperDataInfo[index].facilityItemScore //消防设施单项分
element.functionalDivisionItemSocre = data.paperInfo.paperDataInfo[index].functionalDivisionItemSocre //功能分区单选分
element.importLocationItemScore = data.paperInfo.paperDataInfo[index].importLocationItemScore //重点部位单项分
if (this.paperType == 1) { //阅卷
element.adjoinScore = data.paperInfo.paperDataInfo[index].adjoinScore //四周毗邻 总分
element.basicInfoScore = data.paperInfo.paperDataInfo[index].basicInfoScore //基本信息 总分
element.facilityScore = data.paperInfo.paperDataInfo[index].facilityScore //消防设施 总分
element.functionalDivisionScore = data.paperInfo.paperDataInfo[index].functionalDivisionScore //功能分区 总分
element.importLocationScore = data.paperInfo.paperDataInfo[index].importLocationScore //重点部位 总分
}
element.score = element.adjoinScore + element.basicInfoScore + element.facilityScore + element.functionalDivisionScore + element.importLocationScore
});
this.paperCompanyData = JSON.parse( JSON.stringify(data.examinationDataInfo) ) //具体考卷
this.selectPaper = this.paperCompanyData[0]
resolve(1)
})
})
}
@ -65,7 +76,7 @@ export class ReviewFilesComponent implements OnInit {
await new Promise((resolve,reject)=>{
this.http.get(`/api/ExaminationPlans`,{params:params}).subscribe(data => {
item.planList = data
item.planList.forEach(element => { item.planScore = item.planScore + element.paperPlanInfo.score });
item.planList.forEach(element => { this.paperType == 1? item.planScore = item.planScore + element.paperPlanInfo.score : item.planScore = item.planScore + element.score });
if(type == false){
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
@ -76,7 +87,7 @@ export class ReviewFilesComponent implements OnInit {
})
})
}
this.handleResults() //计算答案正确错误
type? this.handleResults() : null //计算答案正确错误
}
//处理数据 计算答案正确错误
@ -182,7 +193,6 @@ export class ReviewFilesComponent implements OnInit {
});
//forEach
});
console.log(this.selectPaper)
}
//修改结果
@ -229,22 +239,62 @@ export class ReviewFilesComponent implements OnInit {
//提交阅卷结果
submitResult () {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('阅卷结果提交成功','确定',config);
let bodyData = {
id: this.paperData.id,
isMarked: true,
totalScore: 0,
examinationDataInfo: [],
}
let paramsData = JSON.parse(JSON.stringify( this.paperCompanyData )) //考卷
paramsData.forEach(element => {
//计算总分
bodyData.totalScore = bodyData.totalScore+element.adjoinTotalPoints+element.basicInfoTotalPoints+element.facilityTotalPoints+element.functionalDivisionTotalPoints+element.importLocationTotalPoints
element.planList.forEach(item => {
bodyData.totalScore = bodyData.totalScore + item.score || 0
});
//计算总分
element.adjoinScore = element.adjoinTotalPoints //四周毗邻
delete element.adjoinTotalPoints
delete element.adjoinItemScore
element.basicInfoScore = element.basicInfoTotalPoints //基本信息
delete element.basicInfoTotalPoints
delete element.basicInfoItemScore
element.facilityScore = element.facilityTotalPoints //消防设施
delete element.facilityTotalPoints
delete element.facilityItemScore
element.functionalDivisionScore = element.functionalDivisionTotalPoints //功能分区
delete element.functionalDivisionTotalPoints
delete element.functionalDivisionItemSocre
element.importLocationScore = element.importLocationTotalPoints //重点部位
delete element.importLocationTotalPoints
delete element.importLocationItemScore
delete element.planList
delete element.planScore
delete element.score
element.adjoinData = JSON.stringify(element.adjoinData)
element.basicInfoData = JSON.stringify(element.basicInfoData)
element.facilityData = JSON.stringify(element.facilityData)
element.functionalDivisionData = JSON.stringify(element.functionalDivisionData)
element.importLocationData = JSON.stringify(element.importLocationData)
});
bodyData.examinationDataInfo = paramsData
this.http.put(`/api/Examinations/${this.paperData.id}`,bodyData).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 5000
this.snackBar.open('阅卷结果提交成功','确定',config);
})
}
//作战部署 阅卷
readExam(item){
console.log(item)
sessionStorage.setItem('companyName',this.selectPaper.companyInfo.name)
sessionStorage.setItem('planId',item.paperPlanInfo.planComponentId)
sessionStorage.setItem('buildingTypeId',this.selectPaper.companyInfo.buildingTypes[0].id)
sessionStorage.setItem('companyId',this.selectPaper.companyInfo.id)
readExam(item,e){
sessionStorage.setItem('companyName', this.selectPaper.companyInfo.name)
sessionStorage.setItem('planId', item.paperPlanInfo.planComponentId)
sessionStorage.setItem('buildingTypeId', this.selectPaper.companyInfo.buildingTypes[0].id)
sessionStorage.setItem('companyId', this.selectPaper.companyInfo.id)
let openType
item.examPlanType == 0 ? openType = 1 : openType = 2
window.open(`/canvasToolRead?planName=${item.paperPlanInfo.title}&paperplanId=${item.paperPlanId}&openType=${openType}&paperId=${this.paperId}&examId=${this.route.snapshot.queryParams.examId}&planComponentId=${item.paperPlanInfo.planComponentId}`)
item.paperPlanInfo.examPlanType == 0 ? openType = 1 : openType = 2
window.open(`/canvasToolRead?planName=${item.paperPlanInfo.title}&paperplanId=${item.paperPlanId}&openType=${openType}&paperId=${this.paperId}&examId=${this.route.snapshot.queryParams.examId}&planComponentId=${item.paperPlanInfo.planComponentId}&paperType=${e}`)
}

4
src/app/student/student-exam-record/student-exam-record.component.html

@ -23,8 +23,8 @@
<td>{{item.examineeName}}</td>
<td>{{item.paperInfo.organizationsName}}</td>
<td>{{item.paperInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</td>
<td style="color: #FF8678;">90分</td>
<td style="color: #07CDCF;cursor: pointer;">查看</td>
<td style="color: #FF8678;">{{ item.totalScore && item.totalScore!=0 ? item.totalScore+'分' : '未阅卷' }}</td>
<td style="color: #07CDCF;cursor: pointer;" (click)='seePaper(item)'>查看</td>
</tr>
</tbody>

6
src/app/student/student-exam-record/student-exam-record.component.ts

@ -61,8 +61,12 @@ export class StudentExamRecordComponent implements OnInit {
this.http.get("/api/Examinations",{params:paramsdata}).subscribe((data:any)=>{
this.tabledataSource=data.items
this.length=data.totalCount
console.log(this.tabledataSource)
})
}
//查看试卷
seePaper (e) {
window.open(`/reviewFiles?examId=${e.id}&paperType=2`)
}
}

4
src/app/tabbar/tabbar.component.html

@ -15,7 +15,9 @@
<!-- <button mat-icon-button class="login">
<mat-icon>account_circle</mat-icon>
</button> -->
<span style="position: absolute;right:80px;color: #1E2323;font-size: 16px;">{{realName}}<mat-icon [matMenuTriggerFor]="appMenu" style="color: #1E2323;position: relative;top: 8px;cursor: pointer;">keyboard_arrow_down</mat-icon></span>
<span style="position: absolute;right:80px;color: #1E2323;font-size: 16px;cursor: pointer;" [matMenuTriggerFor]="appMenu" >
{{realName}}<mat-icon style="color: #1E2323;position: relative;top: 8px;cursor: pointer;">keyboard_arrow_down</mat-icon>
</span>
<mat-menu #appMenu="matMenu">
<!-- <button mat-menu-item (click)='changeUserData()'>
<mat-icon>perm_identity</mat-icon>

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

@ -23,13 +23,16 @@
<app-working-area #canvas [init]='this'></app-working-area>
<!-- H5Canvas -->
<!-- 拖拽窗口 -->
<div class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div (mousewheel)="$event.stopPropagation()" class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div class="centerTotal">
<div class="centerTotalHeader overflowText">
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>{{beforeOneCheckedBuilding.name}}</label>
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above" class="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>
{{beforeOneCheckedBuilding.name}}
<mat-icon *ngIf="beforeOneCheckedBuildingIsShow">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!beforeOneCheckedBuildingIsShow">keyboard_arrow_down</mat-icon>
</label>
</div>
<div class="everyTotal overflowText" *ngFor="let item of sitePlanData;let key = index"
[ngClass]="{'selectSitePlan': selectSitePlanIndex==key,'selectSitePlanColor':item.isLabel}" (click)='selectSitePlan(item,key)'>
@ -45,9 +48,7 @@
</div>
</div>
<div id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<!-- 处置预案 -->
<div class="handlePlan">
@ -153,7 +154,7 @@
</div>
<div id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<!-- 右侧div鼠标拖动div -->
<div style="width: 3px;height: 100%;position: absolute;left: 0;cursor: e-resize;z-index: 1000;" (mousedown)="rightDivMouseDown($event)"></div>
<!-- 属性 -->

6
src/app/ui/collection-tools-examinee/collection-tools.component.scss

@ -188,11 +188,11 @@
box-sizing: border-box;
padding: 0 5px;
font-size: 14px;
.mat-icon:hover {cursor: move;;}
.mat-icon {
.above:hover {cursor: move;;}
.above {
font-size: 24px;
color: rgb(175, 164, 164);
margin: 0 30px 0 10px;
margin: 0 10px 0 10px;
}
}
.everyTotal {

25
src/app/ui/collection-tools-read/collection-tools.component.html

@ -7,13 +7,18 @@
<span [title]="planData.mainPoint">考试要点 : {{planData.mainPoint}}</span>
</div>
</div>
<div class="headerRight">
<div class="headerRight" *ngIf="paperType == 0">
<button style="border: 1px solid #07CDCF; border-radius: 5px; margin: 0 15px;" (click)='lookAnswerDiv()'><mat-icon>visibility</mat-icon>
查看答案
</button>
<button (click)="score()"><mat-icon>description</mat-icon>评分</button>
<button (click)="submitScore()"><mat-icon>open_in_browser</mat-icon>提交</button>
</div>
<div class="headerRight" *ngIf="paperType != 0" style="text-align: right; padding-right: 30px;">
<button style="border: 1px solid #07CDCF; border-radius: 5px;" (click)='openFireExamination()'><mat-icon>visibility</mat-icon>
查看消防设施
</button>
</div>
</div>
<!-- header头部 -->
<!--功能区 -->
@ -23,13 +28,16 @@
<app-working-area #canvas [init]='this'></app-working-area>
<!-- H5Canvas -->
<!-- 拖拽窗口 -->
<div class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div (mousewheel)="$event.stopPropagation()" class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div class="centerTotal">
<div class="centerTotalHeader overflowText">
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>{{beforeOneCheckedBuilding.name}}</label>
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above" class="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>
{{beforeOneCheckedBuilding.name}}
<mat-icon *ngIf="beforeOneCheckedBuildingIsShow">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!beforeOneCheckedBuildingIsShow">keyboard_arrow_down</mat-icon>
</label>
</div>
<div class="everyTotal overflowText" *ngFor="let item of sitePlanData;let key = index"
[ngClass]="{'selectSitePlan': selectSitePlanIndex==key,'selectSitePlanColor':item.isLabel}" (click)='selectSitePlan(item,key)'>
@ -46,7 +54,7 @@
</div>
<!-- 查看答案拖拽窗口 -->
<div class="answerDivDrag" style="user-select: none;" cdkDrag *ngIf="answerDivDrag">
<div (mousewheel)="$event.stopPropagation()" class="answerDivDrag" style="user-select: none;" cdkDrag *ngIf="answerDivDrag">
<div>
<nz-tree *ngIf="answertreeData.length != 0" nzExpandAll #nzTreeComponent [nzData]="answertreeData" nzBlockNode [nzTreeTemplate]="nzTreeTemplate"></nz-tree>
@ -58,8 +66,7 @@
</div>
</div>
<div id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<!-- 处置预案 -->
<div class="handlePlan">
@ -124,7 +131,7 @@
</div>
<div id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<!-- 右侧div鼠标拖动div -->
<div style="width: 3px;height: 100%;position: absolute;left: 0;cursor: e-resize;z-index: 1000;" (mousedown)="rightDivMouseDown($event)"></div>
<!-- 属性 -->

6
src/app/ui/collection-tools-read/collection-tools.component.scss

@ -201,11 +201,11 @@
box-sizing: border-box;
padding: 0 5px;
font-size: 14px;
.mat-icon:hover {cursor: move;;}
.mat-icon {
.above:hover {cursor: move;;}
.above {
font-size: 24px;
color: rgb(175, 164, 164);
margin: 0 30px 0 10px;
margin: 0 10px 0 10px;
}
}
.everyTotal {

13
src/app/ui/collection-tools-read/collection-tools.component.ts

@ -192,7 +192,7 @@ export class CollectionToolsReadComponent implements OnInit {
}
async ngOnInit(): Promise<void> {
this.getAllBuildings() //获取所有建筑
this.getAllFirePlan() //获取当前单位灾情
@ -211,6 +211,8 @@ export class CollectionToolsReadComponent implements OnInit {
}
})
}
paperType:any = this.route.snapshot.queryParams.paperType // 阅卷 / 查看试卷
paperId:any = this.route.snapshot.queryParams.paperId
planData:any //当前考题题目
Facilities:any //当前预案考题所有楼层要考的基本信息素材
@ -228,14 +230,13 @@ export class CollectionToolsReadComponent implements OnInit {
let questions = JSON.parse(this.planData.examDisposalNodesData)
this.handleHybridTree(questions,'题目')
this.Facilities = JSON.parse(this.planData.examFacilityAssetsData)
this.Facilities = JSON.parse(this.planData.examFacilityAssetsData)
console.log('当前预案设定需要隐藏的基本信息图标',this.Facilities)
resolve(1)
})
})
}
ngAfterViewInit(): void {
this.getSitePlan() //获取总平面图/楼层
@ -457,16 +458,14 @@ export class CollectionToolsReadComponent implements OnInit {
//打开消防设施考题设定
openFireExamination () {
let buildFloorData = {
buildingData:this.beforeOneCheckedBuilding,
floorData:this.selectingSitePlan
}
let data = { oldRealData:this.storeyData ,buildFloorData:buildFloorData,Facilities:this.Facilities,allFireElements:this.allFireElements}
let dialogRef = this.dialog.open(examinationQuestionsRead,{data});
let data = { oldRealData:this.storeyData ,buildFloorData:buildFloorData,Facilities:this.Facilities,allFireElements:this.allFireElements,paperType:this.paperType}
let dialogRef = this.dialog.open(examinationQuestionsRead,{data}); //examinationQuestionsExaminee
}
answerDivDrag:boolean = false//查看答案窗口的显隐
answertreeData:any = []
lookAnswerDiv(){

2
src/app/ui/collection-tools-read/examinationQuestions.html

@ -1,5 +1,5 @@
<div style="min-width: 240px;" >
<div style="text-align: center;font-weight: 550;">需要标记的消防设施</div>
<div style="text-align: center;font-weight: 550;"><label *ngIf="data.paperType == 0">需要标记的</label>消防设施</div>
<div id="nodeTree" style="max-height: 300px;overflow-y: auto; margin: 25px 0;">
<!-- 消防列表树 -->
<nz-tree

14
src/app/ui/collection-tools/collection-tools.component.html

@ -16,11 +16,15 @@
<!-- H5Canvas -->
<app-working-area #canvas [init]='this'></app-working-area>
<!-- H5Canvas -->
<div class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div (mousewheel)="$event.stopPropagation()" class="centerBuildingDiv" style="user-select: none;" cdkDrag>
<div class="centerTotal">
<div class="centerTotalHeader overflowText">
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>{{beforeOneCheckedBuilding.name}}</label>
<mat-icon cdkDragHandle matTooltip="可移动窗口" matTooltipPosition="above" class="above">open_with</mat-icon>
<label (click)='togglebeforeOneCheckedBuilding()'>
{{beforeOneCheckedBuilding.name}}
<mat-icon *ngIf="beforeOneCheckedBuildingIsShow">keyboard_arrow_up</mat-icon>
<mat-icon *ngIf="!beforeOneCheckedBuildingIsShow">keyboard_arrow_down</mat-icon>
</label>
</div>
<div class="everyTotal overflowText" *ngFor="let item of sitePlanData;let key = index"
[ngClass]="{'selectSitePlan': selectSitePlanIndex==key}" (click)='selectSitePlan(item,key)'>
@ -35,7 +39,7 @@
</div>
</div>
</div>
<div id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="leftDiv" class='functionalDomainLeft publicCss scenarioAssignment' [ngClass]="{'togglePanel': toggleExpandPanel==true}" style="user-select: none;">
<!-- 处置预案 -->
<div class="handlePlan">
@ -138,7 +142,7 @@
</div>
<div id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<div (mousewheel)="$event.stopPropagation()" id="rightDiv" class="functionalDomainRight publicCss " [ngClass]="{'togglePanel2': toggleExpandPanelRight==true}" style="user-select: none;">
<!-- 右侧div鼠标拖动div -->
<div style="width: 3px;height: 100%;position: absolute;left: 0;cursor: e-resize;z-index: 1000;" (mousedown)="rightDivMouseDown($event)"></div>
<!-- 属性 -->

6
src/app/ui/collection-tools/collection-tools.component.scss

@ -183,11 +183,11 @@
box-sizing: border-box;
padding: 0 5px;
font-size: 14px;
.mat-icon:hover {cursor: move;;}
.mat-icon {
.above:hover {cursor: move;;}
.above {
font-size: 24px;
color: rgb(175, 164, 164);
margin: 0 30px 0 10px;
margin: 0 10px 0 10px;
}
}
.everyTotal {

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

@ -1250,12 +1250,7 @@ export class CollectionToolsComponent implements OnInit {
this.canvasData.originaleveryStoreyData.version? null : this.canvasData.originaleveryStoreyData.version = "2.0"
this.canvasData.originaleveryStoreyData.sitePlanId? null : this.canvasData.originaleveryStoreyData.sitePlanId = e.id || null
this.renovateTreeData()
this.canvas.onExaminerClickFloor()
// this.canvas.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
// this.canvas.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// this.canvas.createNodeShape(this.canvasData.selectPanelPoint.Data);
// // 隐藏基本信息图形
// this.canvas.setNameVisible(false, 0);
this.canvas.onExaminerClickFloor_CreateTestpaper()
})
}
@ -1281,13 +1276,7 @@ export class CollectionToolsComponent implements OnInit {
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()
this.canvas.onExaminerClickFloor()
// this.canvas.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
// await this.canvas.refreshBackgroundImage();
// this.canvas.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// this.canvas.createNodeShape(this.canvasData.selectPanelPoint.Data);
// // 隐藏基本信息图形
// this.canvas.setNameVisible(false, 0);
this.canvas.onExaminerClickFloor_CreateTestpaper()
})
}

46
src/app/ui/enterpriseuser/addenterpriseuser.component.html

@ -1,48 +1,50 @@
<h2 mat-dialog-title>创建用户</h2>
<h2 mat-dialog-title>新增用户</h2>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div>
<mat-form-field>
<input matInput id="idNumber" name="idNumber"
required ngModel placeholder="请输入身份证号" autocomplete="off" pattern="^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$">
<mat-error>
<strong>请输入正确身份证号</strong>
</mat-error>
<input matInput id="realName" name="realName" required ngModel placeholder="用户姓名" autocomplete="off">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input matInput id="realName" name="realName"
maxlength="100"
required ngModel placeholder="请输入真实姓名" autocomplete="off">
<input matInput id="identityCard" name="identityCard" required ngModel placeholder="身份证号" autocomplete="off" pattern="^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$">
</mat-form-field>
</div>
<div>
<mat-form-field>
<mat-select placeholder="请选择职务" [formControl]="toppings" multiple required>
<div style="float: left;">
<mat-option *ngFor="let item of detachmentPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of brigadePosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of RescueStationPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
</mat-select>
<input matInput id="phone" name="phone" required ngModel placeholder="手机号" type="number" autocomplete="off" pattern="^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4(?:[14]0\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$">
</mat-form-field>
</div>
<div style="margin-bottom: 10px;">
<p style="font-size: 14px;">消防救援站: <label style="margin-left: 10px;">{{organizationName}}</label></p>
</div>
<div class="treeDiv">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
<div mat-dialog-content *ngIf="errmsg">
<p style="font-size: 14px; color: red;">{{errmsg}}</p>
</div>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid || toppings.value == null">确定</button>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">确定</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>

90
src/app/ui/enterpriseuser/addenterpriseuser.component.ts

@ -1,8 +1,10 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialogRef} from '@angular/material/dialog';
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
@Component({
selector: 'addenterpriseuser',
@ -11,57 +13,59 @@ import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
})
export class AddEnterpriserUser {
toppings = new FormControl();
constructor(private http: HttpClient,public dialogRef: MatDialogRef<AddEnterpriserUser>,public snackBar: MatSnackBar) {}
errmsg:any; //捕获错误信息
detachmentPosts: any = []//支队职务列表
brigadePosts: any = []//大队职务列表
RescueStationPosts: any = []//救援站职务列表
ngOnInit(): void {
this.getAllPosts()
}
constructor(private http: HttpClient,public dialogRef: MatDialogRef<AddEnterpriserUser>,public snackBar: MatSnackBar,@Inject(MAT_DIALOG_DATA) public data) {}
ngOnInit(): void { this.dataSource.data = this.data }
errmsg:string = null;
organizationId:string = null;
organizationName:string = null;
//获得所有职务
getAllPosts(){
this.http.get("/api/Posts").subscribe( (data:any) =>{
data.forEach(item => {
if(item.name.indexOf("支队级") != -1){
this.detachmentPosts.push(item)
}else if(item.name.indexOf("大队级") != -1){
this.brigadePosts.push(item)
}else{
this.RescueStationPosts.push(item)
}
});
})
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
}
//提交创建表单
onSubmit (e) {
let date = new Date()
let postsArr = this.toppings.value
let postsObj = []
postsArr.forEach((item) => {
postsObj.push({id:item, name:""})
})
let body = {
name : e.idNumber,
realName : e.realName,
roleType : 2,
enabled : true,
creationTime : date,
posts : postsObj
}
this.http.post("/api/Users",body).subscribe( data => {
this.dialogRef.close(data);
},err => {
if (this.organizationId && this.organizationName) {
e.phone = String(e.phone)
e.roleType = 2
e.enabled = true
e.creationTime = new Date()
e.organizationId = this.organizationId
e.organizationName = this.organizationName
this.http.post("/api/ExamUsers",e).subscribe(data => {
this.dialogRef.close(data);
},err => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
this.snackBar.open('请选择消防救援站','确定',config);
}
}
}

39
src/app/ui/enterpriseuser/editenterpriseuser.html

@ -4,42 +4,47 @@
<div>
<mat-form-field>
<input matInput id="idNumber" name="idNumber"
required [(ngModel)]="IdNumber" placeholder="请输入身份证号" autocomplete="off" disabled pattern="^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$">
<input matInput id="realName" name="realName" [(ngModel)]="realName" required placeholder="用户姓名" autocomplete="off">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input matInput id="realName" name="realName"
maxlength="100"
required [(ngModel)]="realName" placeholder="请输入真实姓名" autocomplete="off">
<input matInput id="identityCard" name="identityCard" [(ngModel)]="identityCard" required placeholder="身份证号" autocomplete="off" pattern="^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$">
</mat-form-field>
</div>
<div>
<mat-form-field>
<mat-select placeholder="请选择职务" [formControl]="toppings" multiple required>
<div style="float: left;">
<mat-option *ngFor="let item of detachmentPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of brigadePosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of RescueStationPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
</mat-select>
<input matInput id="phone" name="phone" [(ngModel)]="phone" required placeholder="手机号" type="number" autocomplete="off" pattern="^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4(?:[14]0\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$">
</mat-form-field>
</div>
<div style="margin-bottom: 10px;">
<p style="font-size: 14px;">消防救援站: <label style="margin-left: 10px;">{{organizationName}}</label></p>
</div>
<div class="treeDiv">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
<div mat-dialog-content *ngIf="errmsg">
<p style="font-size: 14px; color: red;">{{errmsg}}</p>
</div>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid || toppings.value == null">确定</button>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">确定</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>

25
src/app/ui/enterpriseuser/enterpriseuser.component.html

@ -11,9 +11,24 @@
<label style="margin-right: 10px;">身份证号:</label>
<input type="text" [(ngModel)]="identityCard" name="identityCard" autocomplete="off" placeholder="请输入身份证号">
</div>
<div class="queryField">
<div class="queryField" style="position: relative;">
<label style="margin-right: 10px;">消防救援站:</label>
<input type="text" [(ngModel)]="fireTeam" name="fireTeam" autocomplete="off" placeholder="请选择消防救援站">
<input type="text" [(ngModel)]="organizationName" name="organizationName" readonly autocomplete="off" placeholder="请选择消防救援站" (click)='showTree()'>
<mat-icon class="closeTree" *ngIf="isShowTree" (click)='hideTree()'>highlight_off</mat-icon>
<div class="treeDiv searchTree" *ngIf="isShowTree">
<mat-tree [dataSource]="dataSources" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
</div>
<div class="queryField">
<button mat-raised-button (click)='initData()' style="background-color: #07CDCF;">查询</button>
@ -26,7 +41,7 @@
</div>
</form>
</div>
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="name">
@ -36,7 +51,7 @@
<ng-container matColumnDef="identitycard">
<th mat-header-cell *matHeaderCellDef>身份证号</th>
<td mat-cell *matCellDef="let element">{{element.name}}</td>
<td mat-cell *matCellDef="let element">{{element.identityCard}}</td>
</ng-container>
<ng-container matColumnDef="post">
@ -60,7 +75,7 @@
<span class="operationSpan"><span class="spanbtn green" (click)="reset(element)">重置密码</span></span>
<span class="operationSpan"><span class="spanbtn green" (click)="edit(element)">编辑</span></span>
<span *ngIf="element.enabled" class="operationSpan"><span class="spanbtn red" (click)="noEnabled(element)">禁用</span></span>
<span *ngIf="!element.enabled" class="operationSpan"><span class="spanbtn gray" (click)="enabled(element)"></span></span>
<span *ngIf="!element.enabled" class="operationSpan"><span class="spanbtn gray" (click)="enabled(element)"></span></span>
<span class="operationSpan"><span class="spanbtn red" (click)="delete(element)">删除</span></span>
</td>
</ng-container>

30
src/app/ui/enterpriseuser/enterpriseuser.component.scss

@ -52,3 +52,33 @@ table {
.red{ color: #FF8678 }
.gray{ color: gray; }
}
//tree
.treeDiv {
max-height: 300px;
overflow-y: auto;
.mat-icon-button {
width: 20px;
height: 20px;
line-height: 20px;
}
li { cursor: pointer; }
.mat-tree-node:hover { background-color: rgb(240, 236, 236); }
}
.closeTree {
cursor: pointer;
position: absolute;
top: 40px;
right: -95px;
z-index: 100;
}
.searchTree {
.mat-tree-node button .mat-icon { color: #000; }
border: 1px solid rgb(207, 204, 204);
width: 350px;
max-height: 150px;
position: absolute;
top: 40px;
left: 0;
}

217
src/app/ui/enterpriseuser/enterpriseuser.component.ts

@ -8,6 +8,8 @@ import { AddEnterpriserUser } from './addenterpriseuser.component'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import {FormControl} from '@angular/forms';
import { Router,ActivatedRoute } from '@angular/router'
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
@Component({
selector: 'app-enterpriseuser',
@ -20,6 +22,53 @@ export class EnterpriseuserComponent implements OnInit {
ngOnInit() {
this.initData()
this.getOrganizations()
}
allOrganizations:any; //所有组织机构
treeData:any = []; //tree型 data
isShowTree:boolean = false; //树形结构是否展示
showTree () { this.isShowTree = true }
hideTree () { this.isShowTree = false }
//获取所有组织机构
getOrganizations () {
this.http.get('/api/Organizations').subscribe((data:any)=>{
this.allOrganizations = data
data.forEach(element => {
element.children = []
data.forEach(item => { item.parentId === element.id? element.children.push(item) : null });
});
data.forEach(element => {
!element.parentId? this.treeData.push(element) : null
});
this.dataSources.data = this.treeData
}) //http
}
organizationId:string = null;
organizationName:string = null;
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSources = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
this.isShowTree = false
}
displayedColumns: string[] = [ 'name','identitycard', 'post', 'tel', 'time', 'operation',];
@ -27,7 +76,6 @@ export class EnterpriseuserComponent implements OnInit {
name:any //姓名
identityCard:any //身份证
fireTeam:any; //消防救援站
//分页
@ViewChild(MatPaginator, {static: true})
@ -42,8 +90,9 @@ export class EnterpriseuserComponent implements OnInit {
chagePage (e) {
this.pageNumber = e.pageIndex+1
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
IdentityCard: this.identityCard || '',
OrganizationId: this.organizationId || '',
RoleType: '2',
PageNumber: String(this.pageNumber),
}
@ -57,8 +106,9 @@ export class EnterpriseuserComponent implements OnInit {
//页面初始化 + 查询 + 重置
initData () {
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
IdentityCard: this.identityCard || '',
OrganizationId: this.organizationId || '',
RoleType: '2',
}
this.http.get('/api/ExamUsers',{params:data}).subscribe((data:any)=>{
@ -72,8 +122,9 @@ export class EnterpriseuserComponent implements OnInit {
//更新当前页数据
getAllUsers () {
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
IdentityCard: this.identityCard || '',
OrganizationId: this.organizationId || '',
RoleType: '2',
PageNumber: String(this.pageNumber),
}
@ -86,16 +137,17 @@ export class EnterpriseuserComponent implements OnInit {
//清空搜索
empty () {
this.identityCard = ''
this.name = ''
this.name = '',
this.identityCard = '',
this.organizationId = '',
this.organizationName = '',
this.initData()
}
//创建用户
open(){
let dialogRef = this.dialog.open(AddEnterpriserUser, {//调用open方法打开对话框并且携带参数过去
width: '250px',
});
let data = this.treeData
let dialogRef = this.dialog.open(AddEnterpriserUser,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) {
const config = new MatSnackBarConfig();
@ -109,10 +161,8 @@ export class EnterpriseuserComponent implements OnInit {
//编辑企业用户
edit (e) {
let dialogRef = this.dialog.open(editenterpriseuser,{
width: '250px',
data:e
});
let data = {treeData: this.treeData, userData: e}
let dialogRef = this.dialog.open(editenterpriseuser,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) {
const config = new MatSnackBarConfig();
@ -126,32 +176,34 @@ export class EnterpriseuserComponent implements OnInit {
//重置密码
reset (e) {
this.http.put(`/api/ExamUsers/${e.name}/ResetPassword`,{}).subscribe(
data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('重置密码成功!','确定',config);
},err=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('重置密码失败!','确定',config);
})
this.http.put(`/api/ExamUsers/${e.id}/ResetPassword`,{}).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('重置密码成功!','确定',config);
},err=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('重置密码失败!','确定',config);
})
}
//启用
enabled (e) {
let date = new Date()
let body = {
creationTime: new Date(),
enabled: true,
id: e.id,
identityCard: e.identityCard,
name : e.name,
organizationId: e.organizationId,
organizationName: e.organizationName,
phone: e.phone,
realName : e.realName,
roleType : e.roleType,
enabled : true,
creationTime : date,
posts : e.posts
}
this.http.put(`/api/ExamUsers/${e.name}`,body).subscribe(data => {
this.http.put(`/api/ExamUsers/${e.id}`,body).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000;
@ -162,16 +214,19 @@ export class EnterpriseuserComponent implements OnInit {
//禁用
noEnabled (e) {
let date = new Date()
let body = {
creationTime: new Date(),
enabled: false,
id: e.id,
identityCard: e.identityCard,
name : e.name,
organizationId: e.organizationId,
organizationName: e.organizationName,
phone: e.phone,
realName : e.realName,
roleType : e.roleType,
enabled : false,
creationTime : date,
posts : e.posts
}
this.http.put(`/api/ExamUsers/${e.name}`,body).subscribe(data => {
this.http.put(`/api/ExamUsers/${e.id}`,body).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000;
@ -184,7 +239,7 @@ export class EnterpriseuserComponent implements OnInit {
delete (e) {
let isTrue = confirm('您确定要删除吗')
if (isTrue) {
this.http.delete(`/api/ExamUsers/${e.name}`).subscribe(data=>{
this.http.delete(`/api/ExamUsers/${e.id}`).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
@ -208,49 +263,71 @@ export class EnterpriseuserComponent implements OnInit {
})
export class editenterpriseuser {
toppings:any = new FormControl();
constructor(private http: HttpClient,public dialogRef: MatDialogRef<editenterpriseuser>,@Inject(MAT_DIALOG_DATA) public data) {}
errmsg:any; //捕获错误信息
detachmentPosts: any = []//支队职务列表
brigadePosts: any = []//大队职务列表
RescueStationPosts: any = []//救援站职务列表
constructor(private http: HttpClient,public dialogRef: MatDialogRef<editenterpriseuser>,@Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar,) {}
IdNumber:any //身份证号
realName:any //真实姓名
ngOnInit(): void {
this.toppings.value = []
this.IdNumber = this.data.name
this.realName = this.data.realName
this.data.posts.forEach((item) => {
this.toppings.value.push(item.id)
})
this.dataSource.data = this.data.treeData
this.realName = JSON.parse(JSON.stringify(this.data.userData.realName))
this.identityCard = JSON.parse(JSON.stringify(this.data.userData.identityCard))
this.phone = JSON.parse(JSON.stringify(this.data.userData.phone))
this.organizationId = JSON.parse(JSON.stringify(this.data.userData.organizationId))
this.organizationName = JSON.parse(JSON.stringify(this.data.userData.organizationName))
}
//获得所有职务
getAllPosts(){
errmsg:string = null; //捕获错误信息
realName:string = null;
identityCard:string = null;
phone:number = null;
organizationId:string = null;
organizationName:string = null;
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
}
//提交创建表单
onSubmit (e) {
let date = new Date()
let postsArr = this.toppings.value
let postsObj = []
postsArr.forEach((item) => {
postsObj.push({id:item, name:""})
})
let body = {
name : this.data.name,
realName : e.realName,
roleType : 2,
enabled : this.data.enabled,
creationTime : date,
posts : postsObj
if (this.organizationId && this.organizationName) {
e.phone = String(e.phone)
e.roleType = 2
e.name = this.data.userData.name
e.id = this.data.userData.id
e.enabled = this.data.userData.enabled
e.creationTime = new Date()
e.organizationId = this.organizationId
e.organizationName = this.organizationName
this.http.put(`/api/ExamUsers/${this.data.userData.id}`,e).subscribe(data => {
this.dialogRef.close('success');
},err => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择消防救援站','确定',config);
}
this.http.put(`/api/ExamUsers/${this.data.name}`,body).subscribe(data => {
this.dialogRef.close("修改成功");
})
}
}

46
src/app/ui/teacherManagement/addenterpriseuser.component.html

@ -1,48 +1,44 @@
<h2 mat-dialog-title>创建教员</h2>
<h2 mat-dialog-title>新增用户</h2>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div>
<mat-form-field>
<input matInput id="idNumber" name="idNumber"
required ngModel placeholder="请输入帐号" autocomplete="off" pattern="^[a-zA-Z][a-zA-Z0-9_]{4,19}$">
<mat-error>
<strong>帐号格式为字母+数字</strong>
</mat-error>
<input matInput id="name" name="name" required ngModel placeholder="登录账号" autocomplete="off" pattern="^[a-zA-Z][a-zA-Z0-9_]{4,19}$">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input matInput id="realName" name="realName"
maxlength="100"
required ngModel placeholder="请输入真实姓名" autocomplete="off">
<input matInput id="realName" name="realName" required ngModel placeholder="用户姓名" autocomplete="off">
</mat-form-field>
</div>
<div>
<mat-form-field>
<mat-select placeholder="请选择职务" [formControl]="toppings" multiple required>
<div style="float: left;">
<mat-option *ngFor="let item of detachmentPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of brigadePosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of RescueStationPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
</mat-select>
</mat-form-field>
<div style="margin-bottom: 10px;">
<p style="font-size: 14px;">消防救援站: <label style="margin-left: 10px;">{{organizationName}}</label></p>
</div>
<div class="treeDiv">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
<div mat-dialog-content *ngIf="errmsg">
<p style="font-size: 14px; color: red;">{{errmsg}}</p>
</div>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid || toppings.value == null">确定</button>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">确定</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>

91
src/app/ui/teacherManagement/addenterpriseuser.component.ts

@ -1,8 +1,10 @@
import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {MatDialogRef} from '@angular/material/dialog';
import {MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {FormControl} from '@angular/forms';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { FlatTreeControl } from '@angular/cdk/tree';
@Component({
selector: 'addenterpriseuser',
@ -11,57 +13,60 @@ import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
})
export class AddTeacher {
toppings = new FormControl();
constructor(private http: HttpClient,public dialogRef: MatDialogRef<AddTeacher>,public snackBar: MatSnackBar) {}
errmsg:any; //捕获错误信息
detachmentPosts: any = []//支队职务列表
brigadePosts: any = []//大队职务列表
RescueStationPosts: any = []//救援站职务列表
ngOnInit(): void {
this.getAllPosts()
}
constructor(private http: HttpClient,public dialogRef: MatDialogRef<AddTeacher>,public snackBar: MatSnackBar,@Inject(MAT_DIALOG_DATA) public data) {}
ngOnInit(): void { this.dataSource.data = this.data }
errmsg:string = null;
organizationId:string = null;
organizationName:string = null;
//获得所有职务
getAllPosts(){
this.http.get("/api/Posts").subscribe( (data:any) =>{
data.forEach(item => {
if(item.name.indexOf("支队级") != -1){
this.detachmentPosts.push(item)
}else if(item.name.indexOf("大队级") != -1){
this.brigadePosts.push(item)
}else{
this.RescueStationPosts.push(item)
}
});
})
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
}
//提交创建表单
onSubmit (e) {
let date = new Date()
let postsArr = this.toppings.value
let postsObj = []
postsArr.forEach((item) => {
postsObj.push({id:item, name:""})
})
let body = {
name : e.idNumber,
realName : e.realName,
roleType : 1,
enabled : true,
creationTime : date,
posts : postsObj
}
this.http.post("/api/Users",body).subscribe( data => {
this.dialogRef.close(data);
},err=>{
if (this.organizationId && this.organizationName) {
e.phone = null
e.identityCard = null
e.roleType = 1
e.enabled = true
e.creationTime = new Date()
e.organizationId = this.organizationId
e.organizationName = this.organizationName
this.http.post("/api/ExamUsers",e).subscribe(data => {
this.dialogRef.close(data);
},err => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
this.snackBar.open('请选择消防救援站','确定',config);
}
}
}

41
src/app/ui/teacherManagement/editenterpriseuser.html

@ -1,45 +1,44 @@
<h2 mat-dialog-title>编辑教员</h2>
<h2 mat-dialog-title>编辑用户</h2>
<form (ngSubmit)="onSubmit(form.value)" #form="ngForm" class="example-container">
<div>
<mat-form-field>
<input matInput id="idNumber" name="idNumber"
required [(ngModel)]="IdNumber" placeholder="请输入帐号" autocomplete="off" disabled pattern="^[a-zA-Z][a-zA-Z0-9_]{4,19}$">
<input matInput id="name" name="name" [(ngModel)]="name" required readonly placeholder="登录账号" autocomplete="off">
</mat-form-field>
</div>
<div>
<mat-form-field>
<input matInput id="realName" name="realName"
maxlength="100"
required [(ngModel)]="realName" placeholder="请输入真实姓名" autocomplete="off">
<input matInput id="realName" name="realName" [(ngModel)]="realName" required placeholder="用户姓名" autocomplete="off">
</mat-form-field>
</div>
<div>
<mat-form-field>
<mat-select placeholder="请选择职务" [formControl]="toppings" multiple required>
<div style="float: left;">
<mat-option *ngFor="let item of detachmentPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of brigadePosts" [value]="item.id">{{item.name}}</mat-option>
</div>
<div style="float: left;">
<mat-option *ngFor="let item of RescueStationPosts" [value]="item.id">{{item.name}}</mat-option>
</div>
</mat-select>
</mat-form-field>
<div style="margin-bottom: 10px;">
<p style="font-size: 14px;">消防救援站: <label style="margin-left: 10px;">{{organizationName}}</label></p>
</div>
<div class="treeDiv">
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
<div mat-dialog-content *ngIf="errmsg">
<p style="font-size: 14px; color: red;">{{errmsg}}</p>
</div>
<div mat-dialog-actions>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid || toppings.value == null">确定</button>
<button mat-raised-button color="primary" type="submit" [disabled]="!form.form.valid">确定</button>
<button mat-raised-button mat-dialog-close>取消</button>
</div>

21
src/app/ui/teacherManagement/enterpriseuser.component.html

@ -11,9 +11,24 @@
<label style="margin-right: 10px;">用户姓名:</label>
<input type="text" [(ngModel)]="name" name="name" autocomplete="off" placeholder="请输入用户姓名">
</div>
<div class="queryField">
<div class="queryField" style="position: relative;">
<label style="margin-right: 10px;">消防救援站:</label>
<input type="text" [(ngModel)]="fireTeam" name="fireTeam" autocomplete="off" placeholder="请选择消防救援站">
<input type="text" [(ngModel)]="organizationName" name="organizationName" readonly autocomplete="off" placeholder="请选择消防救援站" (click)='showTree()'>
<mat-icon class="closeTree" *ngIf="isShowTree" (click)='hideTree()'>highlight_off</mat-icon>
<div class="treeDiv searchTree" *ngIf="isShowTree">
<mat-tree [dataSource]="dataSources" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button disabled ></button>
<li>{{node.name}}</li>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding (click)='selectTree(node)'>
<button type="button" mat-icon-button matTreeNodeToggle [attr.aria-label]="'toggle ' + node.name">
<mat-icon mat-icon class="mat-icon-rtl-mirror">{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}</mat-icon>
</button>
<li>{{node.name}}</li>
</mat-tree-node>
</mat-tree>
</div>
</div>
<div class="queryField">
<button mat-raised-button (click)='initData()' style="background-color: #07CDCF;">查询</button>
@ -55,7 +70,7 @@
<span class="operationSpan"><span class="spanbtn green" (click)="reset(element)">重置密码</span></span>
<span class="operationSpan"><span class="spanbtn green" (click)="edit(element)">编辑</span></span>
<span *ngIf="element.enabled" class="operationSpan"><span class="spanbtn red" (click)="noEnabled(element)">禁用</span></span>
<span *ngIf="!element.enabled" class="operationSpan"><span class="spanbtn gray" (click)="enabled(element)"></span></span>
<span *ngIf="!element.enabled" class="operationSpan"><span class="spanbtn gray" (click)="enabled(element)"></span></span>
<span class="operationSpan"><span class="spanbtn red" (click)="delete(element)">删除</span></span>
</td>
</ng-container>

30
src/app/ui/teacherManagement/enterpriseuser.component.scss

@ -52,3 +52,33 @@ table {
.red{ color: #FF8678 }
.gray{ color: gray; }
}
//tree
.treeDiv {
max-height: 300px;
overflow-y: auto;
.mat-icon-button {
width: 20px;
height: 20px;
line-height: 20px;
}
li { cursor: pointer; }
.mat-tree-node:hover { background-color: rgb(240, 236, 236); }
}
.closeTree {
cursor: pointer;
position: absolute;
top: 40px;
right: -95px;
z-index: 100;
}
.searchTree {
.mat-tree-node button .mat-icon { color: #000; }
border: 1px solid rgb(207, 204, 204);
width: 350px;
max-height: 150px;
position: absolute;
top: 40px;
left: 0;
}

200
src/app/ui/teacherManagement/enterpriseuser.component.ts

@ -7,6 +7,8 @@ import { PageEvent } from '@angular/material/paginator';
import { AddTeacher } from './addenterpriseuser.component'
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
import {FormControl} from '@angular/forms';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
@Component({
selector: 'app-enterpriseuser',
@ -19,6 +21,53 @@ export class TeacherManagementComponent implements OnInit {
ngOnInit() {
this.initData()
this.getOrganizations()
}
allOrganizations:any; //所有组织机构
treeData:any = []; //tree型 data
isShowTree:boolean = false; //树形结构是否展示
showTree () { this.isShowTree = true }
hideTree () { this.isShowTree = false }
//获取所有组织机构
getOrganizations () {
this.http.get('/api/Organizations').subscribe((data:any)=>{
this.allOrganizations = data
data.forEach(element => {
element.children = []
data.forEach(item => { item.parentId === element.id? element.children.push(item) : null });
});
data.forEach(element => {
!element.parentId? this.treeData.push(element) : null
});
this.dataSources.data = this.treeData
}) //http
}
organizationId:string = null;
organizationName:string = null;
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSources = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
this.isShowTree = false
}
displayedColumns: string[] = ['identitycard', 'name', 'post', 'time', 'operation',];
@ -26,7 +75,6 @@ export class TeacherManagementComponent implements OnInit {
name:any //用户姓名
identityCard:any //用户账号
fireTeam:any; //消防救援站
//分页
@ViewChild(MatPaginator, {static: true})
@ -41,8 +89,9 @@ export class TeacherManagementComponent implements OnInit {
chagePage (e) {
this.pageNumber = e.pageIndex+1
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
name: this.identityCard || '',
realName: this.name || '',
OrganizationId: this.organizationId || '',
RoleType: '1',
PageNumber: String(this.pageNumber),
}
@ -56,8 +105,9 @@ export class TeacherManagementComponent implements OnInit {
//页面初始化 + 查询 + 重置
initData () {
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
name: this.identityCard || '',
realName: this.name || '',
OrganizationId: this.organizationId || '',
RoleType: '1',
}
this.http.get('/api/ExamUsers',{params:data}).subscribe((data:any)=>{
@ -71,8 +121,9 @@ export class TeacherManagementComponent implements OnInit {
//更新当前页数据
getAllUsers () {
let data= {
Name: this.identityCard || '',
RealName: this.name || '',
name: this.identityCard || '',
realName: this.name || '',
OrganizationId: this.organizationId || '',
RoleType: '1',
PageNumber: String(this.pageNumber),
}
@ -85,16 +136,17 @@ export class TeacherManagementComponent implements OnInit {
//清空搜索
empty () {
this.identityCard = ''
this.name = ''
this.name = '',
this.identityCard = '',
this.organizationId = '',
this.organizationName = '',
this.initData()
}
//创建教员
open(){
let dialogRef = this.dialog.open(AddTeacher, {//调用open方法打开对话框并且携带参数过去
width: '250px',
});
let data = this.treeData
let dialogRef = this.dialog.open(AddTeacher,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) {
const config = new MatSnackBarConfig();
@ -108,10 +160,8 @@ export class TeacherManagementComponent implements OnInit {
//编辑企业用户
edit (e) {
let dialogRef = this.dialog.open(editTeacher,{
width: '250px',
data:e
});
let data = {treeData: this.treeData, userData: e}
let dialogRef = this.dialog.open(editTeacher,{data});
dialogRef.afterClosed().subscribe(data=>{
if (data) {
const config = new MatSnackBarConfig();
@ -125,7 +175,7 @@ export class TeacherManagementComponent implements OnInit {
//重置密码
reset (e) {
this.http.put(`/api/ExamUsers/${e.name}/ResetPassword`,{}).subscribe(
this.http.put(`/api/ExamUsers/${e.id}/ResetPassword`,{}).subscribe(
data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
@ -141,16 +191,9 @@ export class TeacherManagementComponent implements OnInit {
//启用
enabled (e) {
let date = new Date()
let body = {
name : e.name,
realName : e.realName,
roleType : e.roleType,
enabled : true,
creationTime : date,
posts : e.posts
}
this.http.put(`/api/ExamUsers/${e.name}`,body).subscribe(data => {
e.date = new Date()
e.enabled = true
this.http.put(`/api/ExamUsers/${e.id}`,e).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000;
@ -161,16 +204,9 @@ export class TeacherManagementComponent implements OnInit {
//禁用
noEnabled (e) {
let date = new Date()
let body = {
name : e.name,
realName : e.realName,
roleType : e.roleType,
enabled : false,
creationTime : date,
posts : e.posts
}
this.http.put(`/api/ExamUsers/${e.name}`,body).subscribe(data => {
e.date = new Date()
e.enabled = false
this.http.put(`/api/ExamUsers/${e.id}`,e).subscribe(data => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000;
@ -183,7 +219,7 @@ export class TeacherManagementComponent implements OnInit {
delete (e) {
let isTrue = confirm('您确定要删除吗')
if (isTrue) {
this.http.delete(`/api/ExamUsers/${e.name}`).subscribe(data=>{
this.http.delete(`/api/ExamUsers/${e.id}`).subscribe(data=>{
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
@ -207,49 +243,69 @@ export class TeacherManagementComponent implements OnInit {
})
export class editTeacher {
toppings:any = new FormControl();
constructor(private http: HttpClient,public dialogRef: MatDialogRef<editTeacher>,@Inject(MAT_DIALOG_DATA) public data) {}
errmsg:any; //捕获错误信息
detachmentPosts: any = []//支队职务列表
brigadePosts: any = []//大队职务列表
RescueStationPosts: any = []//救援站职务列表
constructor(private http: HttpClient,public dialogRef: MatDialogRef<editTeacher>,@Inject(MAT_DIALOG_DATA) public data,public snackBar: MatSnackBar,) {}
IdNumber:any //身份证号
realName:any //真实姓名
ngOnInit(): void {
this.toppings.value = []
this.IdNumber = this.data.name
this.realName = this.data.realName
this.data.posts.forEach((item) => {
this.toppings.value.push(item.id)
})
this.dataSource.data = this.data.treeData
this.name = JSON.parse(JSON.stringify(this.data.userData.name))
this.realName = JSON.parse(JSON.stringify(this.data.userData.realName))
this.organizationId = JSON.parse(JSON.stringify(this.data.userData.organizationId))
this.organizationName = JSON.parse(JSON.stringify(this.data.userData.organizationName))
}
//获得所有职务
getAllPosts(){
errmsg:string = null; //捕获错误信息
name:string = null;
realName:string = null;
organizationId:string = null;
organizationName:string = null;
private _transformer = (node, level: number) => { //初始化tree
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level: level,
id: node.id,
parentId: node.parentId,
children: node.children
};
}
treeControl = new FlatTreeControl<any>(node => node.level, node => node.expandable);
treeFlattener = new MatTreeFlattener(this._transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
hasChild = (_: number, node: any) => node.expandable;
//选择tree节点
selectTree (e) {
this.organizationId = e.id
this.organizationName = e.name
}
//提交创建表单
onSubmit (e) {
let date = new Date()
let postsArr = this.toppings.value
let postsObj = []
postsArr.forEach((item) => {
postsObj.push({id:item, name:""})
})
let body = {
name : this.data.name,
realName : e.realName,
roleType : 1,
enabled : this.data.enabled,
creationTime : date,
posts : postsObj
if (this.organizationId && this.organizationName) {
e.phone = this.data.userData.phone
e.identityCard = this.data.userData.identityCard
e.roleType = 1
e.id = this.data.userData.id
e.enabled = this.data.userData.enabled
e.creationTime = new Date()
e.organizationId = this.organizationId
e.organizationName = this.organizationName
this.http.put(`/api/ExamUsers/${this.data.userData.id}`,e).subscribe(data => {
this.dialogRef.close('success');
},err => {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open(err,'确定',config);
})
} else {
const config = new MatSnackBarConfig();
config.verticalPosition = 'top';
config.duration = 3000
this.snackBar.open('请选择消防救援站','确定',config);
}
this.http.put(`/api/ExamUsers/${this.data.name}`,body).subscribe(data => {
this.dialogRef.close("修改成功");
})
}
}

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

@ -9,7 +9,7 @@ import { GameMode } from './gameMode';
*/
export class AxArrowConnector extends AxShape {
pointSprites: Array<Sprite> = new Array<Sprite>();
line: PIXI.Graphics;
tempLine: PIXI.Graphics;
text: PIXI.Text;
style = new PIXI.TextStyle({
fontFamily: 'Arial',
@ -29,34 +29,34 @@ export class AxArrowConnector extends AxShape {
});
pts: PIXI.Point[];
markerStart = true;// 是否绘制起始箭头
markerEnd = true;// 是否绘制结束箭头
constructor(assetData: any, workingArea: WorkingAreaComponent,markerStart: boolean,markerEnd:boolean) {
markerStart = true; // 是否绘制起始箭头
markerEnd = true; // 是否绘制结束箭头
constructor(assetData: any, workingArea: WorkingAreaComponent, markerStart: boolean, markerEnd: boolean) {
super(assetData, workingArea);
this.markerStart = markerStart;
this.markerEnd = markerEnd;
this.position = this.assetData.Point;
this.name = assetData.Id;
this.text = new PIXI.Text(this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos?.find((item: { PropertyName: string; }) =>
item.PropertyName === '名称/编号')?.PropertyValue, this.style);
this.line = new PIXI.Graphics();
this.tempLine = new PIXI.Graphics();
this.addChild(this.text);
this.addChild(this.line);
this.addChild(this.tempLine);
this.workingArea.backgroundImage.addChild(this);
this.refresh();
this.drawPoints();
this.sortableChildren = true;
this.text.zIndex = this.children.length;
this.text.visible = this.showName;
this.text.angle = -this.workingArea.backgroundImage.angle;
this.text.angle = -this.workingArea.backgroundImage.angle;
}
public drawPoints() {
this.assetData.MultiPoint.forEach(element => {
var point = new Sprite(this.pointTexture);
const point = new Sprite(this.pointTexture);
point.position = element;
point.anchor.set(0.5);
this.pointSprites.push(point);
@ -67,7 +67,7 @@ export class AxArrowConnector extends AxShape {
value
.on('pointerdown', event => {
event.stopPropagation();
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
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;
@ -102,7 +102,7 @@ export class AxArrowConnector extends AxShape {
})
.on('rightclick', event => {
});
})
});
this.setPointVisiable(false);
}
@ -110,10 +110,10 @@ export class AxArrowConnector extends AxShape {
*
* @param b true/false
*/
public setPointVisiable(b:boolean) {
public setPointVisiable(b: boolean) {
this.pointSprites.forEach(item => {
item.visible = b;
})
});
}
// 设置缩放
public setItemScale(scale: number) {
@ -121,17 +121,28 @@ export class AxArrowConnector extends AxShape {
this.pointSprites.forEach(point => {
point.scale.set(scale);
});
this.refresh();
}
public setNameVisible(value: boolean, mode: GameMode) {
if (this.assetData.GameMode === mode) {
this.text.visible = value;
}
}
/**
*
* @param scale
*/
public drawBorder(scale: number) {
const visible = this.pointSprites[0].visible;
this.setPointVisiable(false);
super.drawBorder(scale);
this.setPointVisiable(visible);
}
/**
*
*/
public refresh(): void {
const c = this.line;
const c = this.tempLine;
const pts = this.assetData.MultiPoint;
if (pts.length < 2) {
return;
@ -142,17 +153,22 @@ export class AxArrowConnector extends AxShape {
+ '\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 ? 5 : this.assetData.Thickness; // 宽度
const startWidth = edgeWidth * 2 + strokeWidth;
const endWidth = edgeWidth * 2 + strokeWidth;
const openEnded = false;
const spacing = (openEnded) ? 0 : 0 + strokeWidth / 2;
const startSize = 30 + strokeWidth;
const endSize = 30 + strokeWidth;
const startSize = edgeWidth * 2 + strokeWidth;
const endSize = edgeWidth * 2 + strokeWidth;
const isRounded = true;
const lineColor = 0x000000;
const fillColor: number = this.assetData.Color.substring(0, 7).replace('#', '0x');;
const fillColor: number = this.assetData.Color.substring(0, 7).replace('#', '0x');
const pe = pts[pts.length - 1];
@ -190,8 +206,8 @@ export class AxArrowConnector extends AxShape {
// }
// c.lineStyle(1, 0x000000, 1);
c.clear();
c.lineTextureStyle({ width: 1, color: lineColor, join: PIXI.LINE_JOIN.ROUND });
c.lineTextureStyle({ width: 1 / this.workingArea.backgroundImage.scale.x, color: lineColor, join: PIXI.LINE_JOIN.ROUND });
const startNx = nx;
const startNy = ny;
if (!openEnded) {
@ -328,12 +344,9 @@ export class AxArrowConnector extends AxShape {
fns[i]();
}
if (openEnded)
{
if (openEnded) {
c.closePath();
}
else
{
} else {
c.closePath();
c.endFill();
}
@ -410,10 +423,10 @@ export class AxArrowConnector extends AxShape {
return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
}
redraw(): void{
redraw(): void {
this.pointSprites.forEach(item => {
item.destroy();
})
});
this.pointSprites.splice(0, this.pointSprites.length);
this.refresh();
this.drawPoints();

179
src/app/working-area/model/axGrid.ts

@ -0,0 +1,179 @@
import * as PIXI from 'pixi.js';
const DEFAULT_LINE_STYLE = {
width: 1,
color: 0xffffff,
alpha: 1,
alignment: 0.5,
native: true,
};
export class AxGrid extends PIXI.Graphics {
private _cellSize: number;
private _correctedWidth: number;
private _gridWidth: number;
private _useCorrectedWidth: boolean;
private _drawBoundaries: any;
private _amtLines: any;
set cellSize(cellSize) {
this._cellSize = cellSize || Math.sqrt(this._correctedWidth);
}
get cellSize() {
return this._cellSize;
}
get amtLines() {
return Math.floor(this.gridWidth / this.cellSize);
}
get originalWidth() {
return this._gridWidth;
}
/**
*
*/
get correctedWidth() {
return this._correctedWidth;
}
get useCorrectedWidth() {
return this._useCorrectedWidth;
}
/**
*
*/
get bounds() {
return {
x1: this.x,
y1: this.y,
x2: this.x + this._correctedWidth,
y2: this.y + this._correctedWidth,
};
}
set drawBoundaries(drawBoundaries) {
this._drawBoundaries = drawBoundaries;
}
get drawBoundaries() {
return this._drawBoundaries;
}
get gridWidth() {
if (!this.useCorrectedWidth) { return this._gridWidth; }
return Math.abs(this.cellSize - Math.sqrt(this._correctedWidth)) <= 1e-6 ? this._correctedWidth : this._gridWidth;
}
constructor(
width,
cellSize= null,
lineConfig = null,
useCorrectedWidth = true,
drawBoundaries = true,
) {
super();
this._cellSize = null;
this._amtLines = null;
this._gridWidth = width;
this._useCorrectedWidth = useCorrectedWidth;
this._correctedWidth = null;
this._correctWidth();
this._drawBoundaries = drawBoundaries;
this.cellSize = cellSize;
const lConfig = { ...DEFAULT_LINE_STYLE, ...(lineConfig || {} )};
this.lineStyle(
lConfig.width,
lConfig.color,
lConfig.alpha,
lConfig.alignment,
lConfig.native
);
this.interactive = true;
this.on('mousemove', (evt) => {
const mouseCoords = evt.data.getLocalPosition(evt.currentTarget.parent);
if (
mouseCoords.x >= this.bounds.x1 &&
mouseCoords.x <= this.bounds.x2 &&
mouseCoords.y >= this.bounds.y1 &&
mouseCoords.y <= this.bounds.y2
) {
const gridCoords = this.getCellCoordinates(mouseCoords.x, mouseCoords.y);
this.onMousemove(evt, gridCoords);
}
});
}
/**
*
*/
drawGrid() {
this.clearGrid(true);
for (let i = (this._drawBoundaries ? 0 : 1); i <= this.amtLines - (this._drawBoundaries ? 0 : 1); i += 1) {
const startCoord = i * this._cellSize;
// 画列
this.moveTo(startCoord, 0);
this.lineTo(startCoord, this._correctedWidth);
// 画行
this.moveTo(0, startCoord);
this.lineTo(this._correctedWidth, startCoord);
}
this.endFill();
return this;
}
/**
*
*/
clearGrid(retainLineStyle = true) {
const { width, alignment, color, alpha, native } = this.line;
this.clear();
if (!retainLineStyle) { return; }
this.lineStyle(width, color, alpha, alignment, native);
return this;
}
/**
*
* @param x x
* @param y y
*/
getCellCoordinates(x, y) {
return {
x: Math.floor((x - this.bounds.x1) / this.cellSize),
y: Math.floor((y - this.bounds.y1) / this.cellSize),
};
}
/**
*
* @param evt
* @param gridCoords
*/
onMousemove(evt, gridCoords) {
}
// 默认宽度
_correctWidth() {
if (!this._useCorrectedWidth) {
this._correctedWidth = this._gridWidth;
}
this._correctedWidth = Math.ceil(Math.sqrt(this._gridWidth)) ** 2;
}
// 自定义宽度
correctWidth(width: number) {
if (!this._useCorrectedWidth) {
this._correctedWidth = width;
}
this._correctedWidth = Math.ceil(Math.sqrt(width)) ** 2;
this.cellSize = null;
}
}

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

@ -5,15 +5,17 @@ import { PaintMode } from './paintModel';
import * as PIXI from 'pixi.js';
import { PropertyInfo } from './PropertyInfo';
import { AxShape } from './axShape';
import { Sprite } from 'pixi.js';
import { Sprite, Point, Rectangle } from 'pixi.js';
import { AxArrowConnector } from './axArrowConnector';
import { AxMessageSystem } from './axMessageSystem';
import { EVENT_IMAGE_RESIZE } from './events';
/**
*
* AxImageShape
*/
export class AxImageShape extends AxShape {
connectPointTexture = PIXI.Texture.from('assets/images/handle-secondary.png');
// connectPointTexture = PIXI.Texture.from('assets/images/handle-secondary.png');
style = new PIXI.TextStyle({
fontFamily: 'Arial',
fontSize: 18,
@ -31,6 +33,7 @@ export class AxImageShape extends AxShape {
wordWrapWidth: 100,
});
text = new PIXI.Text(this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos?.find(item => item.PropertyName === '名称/编号')?.PropertyValue, this.style);
@ -48,6 +51,16 @@ export class AxImageShape extends AxShape {
upRight: PIXI.Sprite;
downLeft: PIXI.Sprite;
downRight: PIXI.Sprite;
upDrag: boolean = false;
downDrag: boolean = false;
leftDrag: boolean = false;
rightDrag: boolean = false;
upLeftDrag: boolean = false;
upRightDrag: boolean = false;
downLeftDrag: boolean = false;
downRightDrag: boolean = false;
constructor(assetData: any, workingArea: WorkingAreaComponent) {
super(assetData, workingArea);
this.angle = -this.workingArea.backgroundImage.angle;
@ -71,84 +84,353 @@ export class AxImageShape extends AxShape {
this.addChild(this.image);
this.addChild(this.selectionBox);
////
// up
this.up = new PIXI.Sprite(this.pointTexture);
this.up.cursor = 'ns-resize';
this.up.anchor.set(0.5);
this.addChild(this.up);
this.up.interactive = true;
this.up.on('pointerdown', event => {
this.upDrag = true;
this.image.anchor.set(0.5, 1);
this.image.position.set(this.image.position.x, this.image.position.y + (this.image.height / 2));
event.stopPropagation();
});
this.up.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.upDrag) {
var pos = this.toLocal(event.data.global);
var dY = Math.abs(pos.y - this.image.y);
this.assetData.Height = Math.abs(dY);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.up.on('pointerup', event => {
if (this.upDrag) {
this.upDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x, this.image.position.y - (this.image.height / 2));
}
});
this.up.on('pointerupoutside', event => {
if (this.upDrag) {
this.upDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x, this.image.position.y - (this.image.height / 2));
}
});
this.up.visible = false;
// down
this.down = new PIXI.Sprite(this.pointTexture);
this.down.cursor = 'ns-resize';
this.down.anchor.set(0.5);
this.addChild(this.down);
this.down.interactive = true;
this.down.on('pointerdown', event => {
this.downDrag = true;
this.image.anchor.set(0.5, 0);
this.image.position.set(this.image.position.x, this.image.position.y - (this.image.height / 2));
event.stopPropagation();
});
this.down.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.downDrag) {
var pos = this.toLocal(event.data.global);
var dY = Math.abs(pos.y - this.image.y);
this.assetData.Height = Math.abs(dY);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.down.on('pointerup', event => {
if (this.downDrag) {
this.downDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x, this.image.position.y + (this.image.height / 2));
}
});
this.down.on('pointerupoutside', event => {
if (this.downDrag) {
this.downDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x, this.image.position.y + (this.image.height / 2));
}
});
this.down.visible = false;
// left
this.left = new PIXI.Sprite(this.pointTexture);
this.left.cursor = 'ew-resize';
this.left.anchor.set(0.5);
this.addChild(this.left);
this.left.interactive = true;
this.left.on('pointerdown', event => {
this.leftDrag = true;
this.image.anchor.set(1, 0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y);
event.stopPropagation();
});
this.left.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.leftDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
this.assetData.Width = Math.abs(dX);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.left.on('pointerup', event => {
if (this.leftDrag) {
this.leftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y);
}
});
this.left.on('pointerupoutside', event => {
if (this.leftDrag) {
this.leftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y);
}
});
this.left.visible = false;
// right
this.right = new PIXI.Sprite(this.pointTexture);
this.right.cursor = 'ew-resize';
this.right.anchor.set(0.5);
this.addChild(this.right);
this.right.interactive = true;
this.right.on('pointerdown', event => {
this.rightDrag = true;
this.image.anchor.set(0, 0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y);
event.stopPropagation();
});
this.right.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.rightDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
this.assetData.Width = Math.abs(dX);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.right.on('pointerup', event => {
if (this.rightDrag) {
this.rightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y);
}
});
this.right.on('pointerupoutside', event => {
if (this.rightDrag) {
this.rightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2));
}
});
this.right.visible = false;
// up-left
this.upLeft = new PIXI.Sprite(this.pointTexture);
this.upLeft.cursor = 'nwse-resize';
this.upLeft.anchor.set(0.5);
this.addChild(this.upLeft);
this.upLeft.interactive = true;
this.upLeft.on('pointerdown', event => {
this.upLeftDrag = true;
this.image.anchor.set(1);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y + (this.image.height / 2));
event.stopPropagation();
});
this.upLeft.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.upLeftDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
var dY = Math.abs(pos.y - this.image.y);
var result = dX > dY ? dX : dY;
this.assetData.Width = Math.abs(result);
this.assetData.Height = Math.abs(result);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.upLeft.on('pointerup', event => {
if (this.upLeftDrag) {
this.upLeftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y - (this.image.height / 2));
}
});
this.upLeft.on('pointerupoutside', event => {
if (this.upLeftDrag) {
this.upLeftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y - (this.image.height / 2));
}
});
this.upLeft.visible = false;
// up-right
this.upRight = new PIXI.Sprite(this.pointTexture);
this.upRight.cursor = 'nesw-resize';
this.upRight.anchor.set(0.5);
this.addChild(this.upRight);
this.upRight.interactive = true;
this.upRight.on('pointerdown', event => {
this.upRightDrag = true;
this.image.anchor.set(0, 1);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y + (this.image.height / 2));
event.stopPropagation();
});
this.upRight.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.upRightDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
var dY = Math.abs(pos.y - this.image.y);
var result = dX > dY ? dX : dY;
this.assetData.Width = Math.abs(result);
this.assetData.Height = Math.abs(result);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.upRight.on('pointerup', event => {
if (this.upRightDrag) {
this.upRightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y - (this.image.height / 2));
}
});
this.upRight.on('pointerupoutside', event => {
if (this.upRightDrag) {
this.upRightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y - (this.image.height / 2));
}
});
this.upRight.visible = false;
// down-left
this.downLeft = new PIXI.Sprite(this.pointTexture);
this.downLeft.cursor = 'nesw-resize';
this.downLeft.anchor.set(0.5);
this.addChild(this.downLeft);
this.downLeft.interactive = true;
this.downLeft.on('pointerdown', event => {
this.downLeftDrag = true;
this.image.anchor.set(1, 0);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y - (this.image.height / 2));
event.stopPropagation();
});
this.downLeft.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.downLeftDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
var dY = Math.abs(pos.y - this.image.y);
var result = dX > dY ? dX : dY;
this.assetData.Width = Math.abs(result);
this.assetData.Height = Math.abs(result);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.downLeft.on('pointerup', event => {
if (this.downLeftDrag) {
this.downLeftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y + (this.image.height / 2));
}
});
this.downLeft.on('pointerupoutside', event => {
if (this.downLeftDrag) {
this.downLeftDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y + (this.image.height / 2));
}
});
this.downLeft.visible = false;
// down-right
this.downRight = new PIXI.Sprite(this.pointTexture);
this.downRight.cursor = 'nwse-resize';
this.downRight.anchor.set(0.5);
this.addChild(this.downRight);
this.downRight.interactive = true;
this.downRight.on('pointerdown', event => {
this.downRightDrag = true;
this.image.anchor.set(0, 0);
this.image.position.set(this.image.position.x - (this.image.width / 2), this.image.position.y - (this.image.height / 2));
event.stopPropagation();
});
this.downRight.on('pointermove', event => {
// 移动时调整形状大小,然后重绘边框
// 检查右下角距离鼠标的位置,
if (this.downRightDrag) {
var pos = this.toLocal(event.data.global);
var dX = Math.abs(pos.x - this.image.x);
var dY = Math.abs(pos.y - this.image.y);
var result = dX > dY ? dX : dY;
this.assetData.Width = Math.abs(result);
this.assetData.Height = Math.abs(result);
this.refresh();
AxMessageSystem.send(EVENT_IMAGE_RESIZE, this.assetData);
}
});
this.downRight.on('pointerup', event => {
if (this.downRightDrag) {
this.downRightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y + (this.image.height / 2));
}
});
this.downRight.on('pointerupoutside', event => {
if (this.downRightDrag) {
this.downRightDrag = false;
this.image.anchor.set(0.5);
this.image.position.set(this.image.position.x + (this.image.width / 2), this.image.position.y + (this.image.height / 2));
}
});
this.downRight.visible = false;
////
if (this.assetData.CanConnect) {
// connectPoint
this.connectPoint = new PIXI.Sprite(this.connectPointTexture);
this.connectPoint.anchor.set(0.5);
this.connectPoint.x = this.image.x;
this.connectPoint.y = this.image.y;
this.addChild(this.connectPoint);
this.connectPoint.interactive = true;
this.connectPoint
.on('pointerdown', event => {
event.stopPropagation();
this.paintingPipeline(this.x, this.y);
})
.on('pointerover', event => {
this.setSelectionBox(true, this.connectPoint);
})
.on('pointerout', event => {
this.setSelectionBox(false);
});
this.showConnectionPoint(false);
}
this.setItemScale(1 / this.workingArea.backgroundImage.scale.x);
}
// 设置选择框
public setSelectionBox(b: boolean, sprite?: PIXI.Sprite) {
if (b) {
this.selectionBox.lineStyle(2, 0x00EB00, 1);
this.selectionBox.position = sprite.position;
this.selectionBox.drawRect(- sprite.width / 2, - sprite.height / 2, sprite.width, sprite.height);
} else {
this.selectionBox.clear();
}
}
// 设置名称
public setNameVisible(value: boolean, mode: GameMode) {
if (this.assetData.GameMode === mode) {
this.text.visible = value;
}
}
// 显示连接点
public showConnectionPoint(b: boolean) {
this.connectPoint.visible = b;
}
/**
*
* @param value
*/
public setPointVisiable(value: boolean) {
let rect = this.getLocalBounds();
const rect = this.getLocalBounds();
this.up.x = rect.right - rect.width / 2;
this.up.y = rect.top;
this.down.x = rect.right - rect.width / 2;
this.down.y = rect.bottom;
this.left.x = rect.left;
this.left.y = rect.bottom - rect.height / 2;
this.right.x = rect.right;
this.right.y = rect.bottom - rect.height / 2;
this.upLeft.x = rect.left;
this.upLeft.y = rect.top;
this.upRight.x = rect.right;
@ -157,21 +439,33 @@ export class AxImageShape extends AxShape {
this.downLeft.y = rect.bottom;
this.downRight.x = rect.right;
this.downRight.y = rect.bottom;
this.up.visible = value;
this.down.visible = value;
this.left.visible = value;
this.right.visible = value;
this.upLeft.visible = value;
this.upRight.visible = value;
this.downLeft.visible = value;
this.downRight.visible = value;
}
/**
*
*
* @param scale
*/
public drawBorder(scale: number) {
let visible = this.upLeft.visible;
const visible = this.upLeft.visible;
this.setPointVisiable(false);
super.drawBorder(scale);
let rect = this.getLocalBounds();
const rect = this.getLocalBounds();
this.up.x = rect.right - rect.width / 2;
this.up.y = rect.top;
this.down.x = rect.right - rect.width / 2;
this.down.y = rect.bottom;
this.left.x = rect.left;
this.left.y = rect.bottom - rect.height / 2;
this.right.x = rect.right;
this.right.y = rect.bottom - rect.height / 2;
this.upLeft.x = rect.left;
this.upLeft.y = rect.top;
this.upRight.x = rect.right;
@ -191,81 +485,57 @@ export class AxImageShape extends AxShape {
this.upRight.scale.set(scale);
this.downLeft.scale.set(scale);
this.downRight.scale.set(scale);
this.up.scale.set(scale);
this.down.scale.set(scale);
this.left.scale.set(scale);
this.right.scale.set(scale);
}
}
paintingPipeline(x: number, y: number) {
if (this.assetData.CanConnect) {
if (this.workingArea.getPaintMode() === PaintMode.Pipeline) {
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);
this.workingArea.paintPoints.push(new PIXI.Point(x, y));
const json = JSON.parse(JSON.stringify(this.workingArea.canvasData.selectTemplateData.propertyInfos));
const list = [];
json.forEach(element => {
const property = new PropertyInfo(element);
list.push(property);
});
const tempData = {
TemplateId: this.workingArea.canvasData.selectTemplateData.id,
CanConnect: this.workingArea.canvasData.selectTemplateData.canConnect,
Pipelines: new Array(),
FloorId: this.workingArea.canvasData.selectStorey.id,
Angle: this.workingArea.canvasData.selectTemplateData.angle,
Color: this.workingArea.canvasData.selectTemplateData.color,
Enabled: this.workingArea.canvasData.selectTemplateData.enabled,
FillMode: this.workingArea.canvasData.selectTemplateData.fillMode,
FireElementId: this.workingArea.canvasData.selectTemplateData.fireElementId,
FixedSize: this.workingArea.canvasData.selectTemplateData.fixedSize,
Height : 32,
Width : 32,
Id: ObjectID.default.generate(),
ImageUrl: this.workingArea.canvasData.selectTemplateData.imageUrl,
InteractiveMode: this.workingArea.canvasData.selectTemplateData.interactiveMode,
MultiPoint : JSON.parse(JSON.stringify(this.workingArea.paintPoints)),
Point: new PIXI.Point(0, 0),
Name : this.workingArea.canvasData.selectTemplateData.name,
PropertyInfos: list,
Border : this.workingArea.canvasData.selectTemplateData.border,
DrawMode : this.workingArea.canvasData.selectTemplateData.drawMode,
Thickness : this.workingArea.canvasData.selectTemplateData.thickness,
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.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.paintingShape.assetData.MultiPoint =
JSON.parse(JSON.stringify(this.workingArea.paintPoints));
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();
}
}
}
}
// 刷新
public refresh() {
if (this.assetData.CanConnect) {
}
this.image.width = this.assetData.Width;
this.image.height = this.assetData.Height;
this.image.angle = this.assetData.Angle;
this.text.text = this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos?.find(item => item.PropertyName === '名称/编号')?.PropertyValue;
this.text.x = this.image.x;
this.text.y = this.image.y - this.image.height / 2;
if (this.image.anchor.x == 0) {
if (this.image.anchor.y == 0) {
this.text.x = this.image.x + this.image.width / 2;
this.text.y = this.image.y;
} else if (this.image.anchor.y == 0.5) {
this.text.x = this.image.x + this.image.width / 2;
this.text.y = this.image.y - this.image.height / 2;
} else if (this.image.anchor.y == 1) {
this.text.x = this.image.x + this.image.width / 2;
this.text.y = this.image.y - this.image.height;
}
} else if (this.image.anchor.x == 0.5) {
if (this.image.anchor.y == 0) {
this.text.x = this.image.x;
this.text.y = this.image.y;
} else if (this.image.anchor.y == 0.5) {
} else if (this.image.anchor.y == 1) {
this.text.x = this.image.x;
this.text.y = this.image.y - this.image.height;
}
} else if (this.image.anchor.x == 1) {
if (this.image.anchor.y == 0) {
this.text.x = this.image.x - this.image.width / 2;
this.text.y = this.image.y;
} else if (this.image.anchor.y == 0.5) {
this.text.x = this.image.x - this.image.width / 2;
this.text.y = this.image.y - this.image.height / 2;
} else if (this.image.anchor.y == 1) {
this.text.x = this.image.x - this.image.width / 2;
this.text.y = this.image.y - this.image.height;
}
}
this.angle = -this.workingArea.backgroundImage.angle;
this.drawBorder(1 / this.workingArea.backgroundImage.scale.x);
}
}

11
src/app/working-area/model/axImageShapeTest.ts

@ -0,0 +1,11 @@
import { AxRectangleShape } from "./axRectangleShape";
export class AxImageShapeTest extends AxRectangleShape{
/**
*
*/
constructor(x:number,y:number,width:number,height:number) {
super(x,y,width,height);
}
}

404
src/app/working-area/model/axLegend.ts

@ -1,5 +1,7 @@
import { Constructor } from '@angular/material/core/common-behaviors/constructor';
import { Sprite, Texture,Text, Graphics, Point } from 'pixi.js';
import { MatGridTileHeaderCssMatStyler } from '@angular/material/grid-list';
import { DefaultProxy } from 'cesium';
import { Sprite, Texture, Text, Graphics, Point } from 'pixi.js';
import { WorkingAreaComponent } from '../working-area.component';
import { AxShape } from './axShape';
@ -8,20 +10,35 @@ import { AxShape } from './axShape';
*/
export class AxLegend extends AxShape {
// 数据
public shapeMap: Map<string,Legend> = new Map<string,Legend>();
public shapeMap: Map<string, Legend> = new Map<string, Legend>();
pen: Graphics = new Graphics();
// up: Sprite = new Sprite(this.pointTexture);
// down: Sprite= new Sprite(this.pointTexture);
// left: Sprite= new Sprite(this.pointTexture);
// right: Sprite= new Sprite(this.pointTexture);
upLeft: Sprite = new Sprite(this.pointTexture);
upRight: Sprite = new Sprite(this.pointTexture);
downLeft: Sprite = new Sprite(this.pointTexture);
downRight: Sprite = new Sprite(this.pointTexture);
/**
*
*/
constructor(assetData: any, workingArea: WorkingAreaComponent,shapeMap:Map<string,Legend>) {
constructor(assetData: any, workingArea: WorkingAreaComponent, shapeMap: Map<string, Legend>) {
super(assetData, workingArea);
this.angle = -this.workingArea.backgroundImage.angle;
this.name = this.assetData.Id;
this.pivot.set(this.assetData.PivotX, this.assetData.PivotY);
this.x = this.assetData.Point.x;
this.y = this.assetData.Point.y;
this.scale.set(this.assetData.Scale);
this.shapeMap = shapeMap;
this.createPoint();
this.refresh();
this.sortableChildren = true;
this.pen.zIndex = -1;
}
// 添加数据
public addItem(item:Legend) {
public addItem(item: Legend) {
if (this.shapeMap.has(item.Name)) {
this.shapeMap.get(item.Name).Count++;
} else {
@ -43,35 +60,35 @@ export class AxLegend extends AxShape {
refresh() {
this.removeChildren();
let index = 1;
let offset = 25;
let number = this.assetData.PropertyInfos[0].PropertyValue;
let width = 300;
let height = 50;
for (let i = 0; i < number; i++){
if (i >= this.shapeMap.size) break;
let x = width * i;
var textImage = new Text('图例',{
const offset = 25;
let number = Number(this.assetData.PropertyInfos[0].PropertyValue);
const width = 300;
const height = 50;
for (let i = 0; i < number; i++) {
if (i >= this.shapeMap.size) { break; }
const x = width * i;
const textImage = new Text('图例', {
fontSize: 20,
fill: ['#0000ff'],
fill: ['#0000ff'],
});
textImage.anchor.set(0.5)
textImage.anchor.set(0.5);
textImage.x = x;
textImage.y = 0;
this.addChild(textImage);
var textName = new Text("名称"+' 【数量】',{
const textName = new Text('名称' + ' 【数量】', {
fontSize: 20,
fill: ['#0000ff'],
fill: ['#0000ff'],
});
textName.anchor.set(0,0.5);
textName.anchor.set(0, 0.5);
textName.x = x + 32 + offset;
textName.y = 0;
this.addChild(textName);
}
for (let item of this.shapeMap.values()) {
let x = index % number === 0 ? (number -1) * width : (index % number - 1) * width;
let y = Math.ceil(index / number) * height;
let image: Sprite = Sprite.from(item.ImageUrl);
for (const item of this.shapeMap.values()) {
const x = index % number === 0 ? (number - 1) * width : (index % number - 1) * width;
const y = Math.ceil(index / number) * height;
const image: Sprite = Sprite.from(item.ImageUrl);
image.width = 32;
image.height = 32;
image.anchor.set(0.5);
@ -79,40 +96,363 @@ export class AxLegend extends AxShape {
image.y = y;
this.addChild(image);
var textName = new Text(item.Name+' 【'+item.Count.toString()+'】',{
const textName = new Text(item.Name + ' 【' + item.Count.toString() + '】', {
fontSize: 20,
});
textName.anchor.set(0,0.5);
textName.x = x + image.width/2 + offset;
textName.anchor.set(0, 0.5);
textName.x = x + image.width / 2 + offset;
textName.y = y;
this.addChild(textName);
index++;
}
if (this.shapeMap.size > 0) {
let rect = this.getLocalBounds();
const rect = this.getLocalBounds();
this.pen.clear();
this.pen.beginFill(0xffffff,0.01);
this.pen.beginFill(0xffffff, 1);
this.pen.lineStyle(3, 0x000000);
this.pen.moveTo(rect.left-offset, rect.top-offset);
this.pen.lineTo(rect.right+offset, rect.top-offset);
this.pen.lineTo(rect.right+offset, rect.bottom+offset);
this.pen.moveTo(rect.left - offset, rect.top - offset);
this.pen.lineTo(rect.right + offset, rect.top - offset);
this.pen.lineTo(rect.right + offset, rect.bottom + offset);
this.pen.lineTo(rect.left - offset, rect.bottom + offset);
this.pen.closePath();
this.pen.endFill();
}
}
this.addChild(this.pen);
// 添加border
this.addChild(this.border);
// 添加控制点
this.addChild(this.upLeft);
this.addChild(this.upRight);
this.addChild(this.downLeft);
this.addChild(this.downRight);
this.angle = -this.workingArea.backgroundImage.angle;
this.drawBorder(1 / this.workingArea.backgroundImage.scale.x);
}
public createPoint() {
// this.addChild(this.upLeft);
this.upLeft.anchor.set(0.5);
this.upLeft.interactive = true;
this.upLeft.visible = false;
this.upLeft
.on('pointerdown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
const pointStart = this.position;
const pointEnd = this.workingArea.backgroundImage.toLocal(this.toGlobal(this.downRight.position));
const delX = pointEnd.x - pointStart.x;
const delY = pointEnd.y - pointStart.y;
this.pivot.set(this.downRight.x, this.downRight.y);
this.position.x += delX;
this.position.y += delY;
this.assetData.PivotX = this.pivot.x;
this.assetData.PivotY = this.pivot.y;
this.assetData.Point = new Point(this.x, this.y);
})
.on('pointerup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointerupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointermove', event => {
if (event.currentTarget.dragging) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
const startPos = this.position;
const endPos = this.workingArea.backgroundImage.toLocal(this.toGlobal(newPosition));
const width = (endPos.x - startPos.x);
const height = (endPos.y - startPos.y);
const scaleX = width / (this.width / this.scale.x);
const scaleY = height / (this.width / this.scale.x);
const angle = Math.abs(this.angle);
console.log(angle);
if (angle === 0) {
this.scale.set(-scaleX);
} else if (angle === 90) {
this.scale.set(scaleY);
} else if (angle === 180) {
this.scale.set(scaleX);
} else if (angle === 270) {
this.scale.set(-scaleY);
}
this.assetData.Scale = this.scale.x;
}
})
.on('rightclick', event => {
this.border.visible = false;
});
// this.addChild(this.upRight);
this.upRight.anchor.set(0.5);
this.upRight.interactive = true;
this.upRight.visible = false;
this.upRight
.on('pointerdown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
const pointStart = this.position;
const pointEnd = this.workingArea.backgroundImage.toLocal(this.toGlobal(this.downLeft.position));
const delX = pointEnd.x - pointStart.x;
const delY = pointEnd.y - pointStart.y;
this.pivot.set(this.downLeft.x, this.downLeft.y);
this.position.x += delX;
this.position.y += delY;
this.assetData.PivotX = this.pivot.x;
this.assetData.PivotY = this.pivot.y;
this.assetData.Point = new Point(this.x, this.y);
})
.on('pointerup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointerupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointermove', event => {
if (event.currentTarget.dragging) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
const startPos = this.position;
const endPos = this.workingArea.backgroundImage.toLocal(this.toGlobal(newPosition));
const width = (endPos.x - startPos.x);
const height = (endPos.y - startPos.y);
const scaleX = width / (this.width / this.scale.x);
const scaleY = height / (this.width / this.scale.x);
const angle = Math.abs(this.angle);
console.log(angle);
if (angle === 0) {
this.scale.set(scaleX);
} else if (angle === 90) {
this.scale.set(-scaleY);
} else if (angle === 180) {
this.scale.set(-scaleX);
} else if (angle === 270) {
this.scale.set(scaleY);
}
this.assetData.Scale = this.scale.x;
}
})
.on('rightclick', event => {
this.border.visible = false;
});
// this.addChild(this.downLeft);
this.downLeft.anchor.set(0.5);
this.downLeft.interactive = true;
this.downLeft.visible = false;
this.downLeft
.on('pointerdown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
const pointStart = this.position;
const pointEnd = this.workingArea.backgroundImage.toLocal(this.toGlobal(this.upRight.position));
const delX = pointEnd.x - pointStart.x;
const delY = pointEnd.y - pointStart.y;
this.pivot.set(this.upRight.x, this.upRight.y);
this.position.x += delX;
this.position.y += delY;
this.assetData.PivotX = this.pivot.x;
this.assetData.PivotY = this.pivot.y;
this.assetData.Point = new Point(this.x, this.y);
})
.on('pointerup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointerupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointermove', event => {
if (event.currentTarget.dragging) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
const startPos = this.position;
const endPos = this.workingArea.backgroundImage.toLocal(this.toGlobal(newPosition));
const width = (endPos.x - startPos.x);
const height = (endPos.y - startPos.y);
const scaleX = width / (this.width / this.scale.x);
const scaleY = height / (this.width / this.scale.x);
const angle = Math.abs(this.angle);
console.log(angle);
if (angle === 0) {
this.scale.set(-scaleX);
} else if (angle === 90) {
this.scale.set(scaleY);
} else if (angle === 180) {
this.scale.set(scaleX);
} else if (angle === 270) {
this.scale.set(-scaleY);
}
this.assetData.Scale = this.scale.x;
}
})
.on('rightclick', event => {
this.border.visible = false;
});
// this.addChild(this.downRight);
this.downRight.anchor.set(0.5);
this.downRight.interactive = true;
this.downRight.visible = false;
this.downRight
.on('pointerdown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
const pointStart = this.position;
const pointEnd = this.workingArea.backgroundImage.toLocal(this.toGlobal(this.upLeft.position));
const delX = pointEnd.x - pointStart.x;
const delY = pointEnd.y - pointStart.y;
this.pivot.set(this.upLeft.x, this.upLeft.y);
this.position.x += delX;
this.position.y += delY;
this.assetData.PivotX = this.pivot.x;
this.assetData.PivotY = this.pivot.y;
this.assetData.Point = new Point(this.x, this.y);
})
.on('pointerup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointerupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('pointermove', event => {
if (event.currentTarget.dragging) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
const startPos = this.position;
const endPos = this.workingArea.backgroundImage.toLocal(this.toGlobal(newPosition));
const width = (endPos.x - startPos.x);
const height = (endPos.y - startPos.y);
const scaleX = width / (this.width / this.scale.x);
const scaleY = height / (this.width / this.scale.x);
const angle = Math.abs(this.angle);
console.log(angle);
if (angle === 0) {
this.scale.set(scaleX);
} else if (angle === 90) {
this.scale.set(-scaleY);
} else if (angle === 180) {
this.scale.set(-scaleX);
} else if (angle === 270) {
this.scale.set(scaleY);
}
this.assetData.Scale = this.scale.x;
}
})
.on('rightclick', event => {
this.border.visible = false;
});
}
/**
*
* @param value
*/
public setPointVisiable(value: boolean) {
const rect = this.getLocalBounds();
this.upLeft.x = rect.left;
this.upLeft.y = rect.top;
this.upRight.x = rect.right;
this.upRight.y = rect.top;
this.downLeft.x = rect.left;
this.downLeft.y = rect.bottom;
this.downRight.x = rect.right;
this.downRight.y = rect.bottom;
this.upLeft.visible = value;
this.upRight.visible = value;
this.downLeft.visible = value;
this.downRight.visible = value;
}
/**
*
* @param scale
*/
public drawBorder(scale: number) {
const visible = this.upLeft.visible;
this.setPointVisiable(false);
super.drawBorder(scale);
const rect = this.getLocalBounds();
this.upLeft.x = rect.left;
this.upLeft.y = rect.top;
this.upRight.x = rect.right;
this.upRight.y = rect.top;
this.downLeft.x = rect.left;
this.downLeft.y = rect.bottom;
this.downRight.x = rect.right;
this.downRight.y = rect.bottom;
this.setPointVisiable(visible);
}
}
export class Legend{
export class Legend {
public Name: string;
public ImageUrl: string;
public Count: number;
/**
*
*/
constructor(name:string,imageUrl:string,count:number) {
constructor(name: string, imageUrl: string, count: number) {
this.Name = name;
this.ImageUrl = imageUrl;
this.Count = count;

90
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: Function, context: any) {
let 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: Function, context: any) {
let observers: Observer[] = AxMessageSystem.listeners[name];
if (!observers) return;
let length = observers.length;
for (let i = 0; i < length; i++) {
let 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[]) {
let observers: Observer[] = AxMessageSystem.listeners[name];
if (!observers) return;
let length = observers.length;
for (let i = 0; i < length; i++) {
let observer = observers[i];
observer.notify(name, ...args);
}
}
}
/**
*
*/
class Observer {
/** 回调函数 */
private callback: Function = null;
/** 上下文 */
private context: any = null;
constructor(callback: Function, context: any) {
let self = this;
self.callback = callback;
self.context = context;
}
/**
*
* @param args
*/
notify(...args: any[]): void {
let self = this;
self.callback.call(self.context, ...args);
}
/**
*
* @param context
*/
compar(context: any): boolean {
return context == this.context;
}
}

21
src/app/working-area/model/axRectangleShape.ts

@ -0,0 +1,21 @@
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 {
/**
*
*/
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();
}
}

64
src/app/working-area/model/axSelection.ts

@ -0,0 +1,64 @@
/**
*
*/
export class AxSelection {
constructor() {
}
private objects: Set<any> = new Set<any>();
// 获得第一个对象
public first(): any {
if (this.objects.size > 0) {
return [...this.objects][0];
} else {
return null;
}
}
// 是否已经选择了对象
public has(obj: any): boolean {
return this.objects.has(obj);
}
// 是否所有选择对象都允许编辑
public allowEdit(): boolean {
let allowEdit = true;
for (const item of this.objects) {
if (!item.allowEdit) {
allowEdit = false;
break;
}
}
return allowEdit;
}
// 获得所有对象
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();
}
}

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

@ -6,21 +6,23 @@ import { WorkingAreaComponent } from '../working-area.component';
/**
*
*/
export class AxShape extends Container {
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;
// 可以被选中的
selectable = true;
// 允许选择
allowSelect = true;
// 允许编辑
allowEdit = true;
// 是否显示名称
showName = true;
// 边框
border: PIXI.Graphics = new PIXI.Graphics();
// 鼠标位置
mousePosition: PIXI.Point;
// 鼠标拖动
mouseDragging: boolean;
constructor(assetData: any, workingArea: WorkingAreaComponent) {
super();
this.border.visible = false;
@ -30,105 +32,71 @@ export class AxShape extends Container {
this.workingArea.backgroundImage.addChild(this);
this.zIndex = 200;
this.interactive = true;
this.buttonMode = true;
// this.buttonMode = true;
this
.on('pointerdown', event => {
event.stopPropagation();
if (this.selectable) {
this.workingArea.selection.selectOne(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;
}
event.stopPropagation();
if (this.allowSelect
&& event.data.button === 0) {
this.workingArea.select(this);
}
if (this.allowEdit) {
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.camera2D.scale.x);
item.y += y * (1 / this.workingArea.camera2D.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 => {
this.border.visible = false;
})
.on('pointerover', event => {
event.stopPropagation();
})
.on('pointerout', event => {
event.stopPropagation();
});
}
redraw(): void {
}
refresh(): void{
refresh(): void {
}
public setItemScale(scale: number) {
}
/**
*
*/
public showBorder() {
if (this.assetData.FixedSize) {
this.drawBorder(1);
}
else {
this.drawBorder(1/this.workingArea.backgroundImage.scale.x);
}
this.border.visible = true;
}
/**
*
*/
public hideBorder() {
this.border.clear();
this.border.visible = false;
}
/**
*
* @param value
*/
/**
*
* @param value
*/
public setPointVisiable(value: boolean) {
}
/**
*
*
* @param rect
*/
public drawBorder(scale: number) {
@ -142,52 +110,52 @@ export class AxShape extends Container {
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);
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);
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.beginFill(0x00ff00,0.1);
this.border.moveTo(p1.x, p1.y);
this.border.lineTo(p2.x, p2.y);
this.border.lineTo(p3.x, p4.y);
this.border.lineTo(p4.x, p4.y);
this.border.closePath();
this.border.endFill();
}
// 画虚线
drawDash(target, x1, y1, x2, y2,dashLength = 5, spaceLength = 1) {
let x = x2 - x1;
let 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;
// this.border.endFill();
}
// 画虚线
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));
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;
hyp -= dashLength;
if (hyp < 0) {
x1 = x2;
y1 = y2;
}
target.lineTo(x1, y1);
x1 += spaceX;
y1 += spaceY;
target.moveTo(x1, y1);
hyp -= spaceLength;
}
target.moveTo(x2, y2);
while (hyp > 0) {
x1 += dashX;
y1 += dashY;
hyp -= dashLength;
if (hyp < 0) {
x1 = x2;
y1 = y2;
}
target.lineTo(x1, y1);
x1 += spaceX;
y1 += spaceY;
target.moveTo(x1, y1);
hyp -= spaceLength;
}
target.moveTo(x2, y2);
}
// 计算多边形重心
public calculatePolygonGravityCenter(points: PIXI.Point[]) {
@ -215,7 +183,7 @@ export class AxShape extends Container {
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);
}
}

165
src/app/working-area/model/configuration.ts

@ -0,0 +1,165 @@
import { EventDispatcher } from 'three';
import { EVENT_CHANGED } from './events';
// GENERAL:
/** The dimensioning unit for 2D floorplan measurements. */
export var configDimUnit = 'dimUnit';
// WALL:
/** The initial wall height in cm. */
export const configWallHeight = 'wallHeight';
/** The initial wall thickness in cm. */
export const configWallThickness = 'wallThickness';
export const configSystemUI = 'systemUI';
export const scale = 'scale';
export const gridSpacing = 'gridSpacing';
export const snapToGrid = 'snapToGrid';
export const directionalDrag = 'directionalDrag';
export const dragOnlyX = 'dragOnlyX';
export const dragOnlyY = 'dragOnlyY';
export const snapTolerance = 'snapTolerance'; //In CMS
export const boundsX = 'boundsX'; //In CMS
export const boundsY = 'boundsY'; //In CMS
export const viewBounds = 'viewBounds';//In CMS
export const dimInch = 'inch';
/** Dimensioning in Inch. */
export const dimFeetAndInch = 'feetAndInch';
/** Dimensioning in Meter. */
export const dimMeter = 'm';
/** Dimensioning in Centi Meter. */
export const dimCentiMeter = 'cm';
/** Dimensioning in Milli Meter. */
export const dimMilliMeter = 'mm';
export const VIEW_TOP = 'topview';
export const VIEW_FRONT = 'frontview';
export const VIEW_RIGHT = 'rightview';
export const VIEW_LEFT = 'leftview';
export const VIEW_ISOMETRY = 'isometryview';
export enum WallTypes {
STRAIGHT,
CURVED
}
export const TEXTURE_DEFAULT_REPEAT = 300;
export const defaultWallTexture =
{
color: '#FFFFFF', repeat: TEXTURE_DEFAULT_REPEAT, normalmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_normal.jpg', roughnessmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_roughness.jpg', colormap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_basecolor.jpg', ambientmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_ambientOcclusion.jpg', bumpmap: 'textures/Wall/Brick_Wall_017_SD/Brick_Wall_017_height.png'
};
export const defaultFloorTexture =
{
color: '#FFFFFF', emissive: '#181818', repeat: TEXTURE_DEFAULT_REPEAT, ambientmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_ambientOcclusion.jpg', colormap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_basecolor.jpg', roughnessmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_roughness.jpg', normalmap: 'textures/Floor/Marble_Tiles_001/Marble_Tiles_001_normal.jpg'
};
export const TEXTURE_PROPERTY_COLOR = 'color';
export const TEXTURE_NO_PREVIEW = 'textures/NoPreview.jpg';
export var config = {
dimUnit: dimCentiMeter,
wallHeight: 250,
wallThickness: 20,
systemUI: false,
scale: 1,
snapToGrid: true,
dragOnlyX: false,
dragOnlyY: false,
snapTolerance: 50,
gridSpacing: 20, // 50,
directionalDrag: true,
boundsX: 500,
boundsY: 500,
viewBounds: 60000
};
export var wallInformation = { exterior: false, interior: false, midline: true, labels: true, exteriorlabel: 'e:', interiorlabel: 'i:', midlinelabel: 'm:' };
/**
* The tolerance in cms between corners, otherwise below this tolerance they will snap together as one corner*/
export const cornerTolerance = 20;
/** Global configuration to customize the whole system.
* This is a singleton instance;
*/
export class Configuration extends EventDispatcher {
private static instance = new Configuration();
constructor() {
/** Configuration data loaded from/stored to extern. */
// this.data = {dimUnit: dimCentiMeter, wallHeight: 250, wallThickness: 10};
super();
}
static getInstance() {
if (this.instance === undefined
|| this.instance === null) {
this.instance = new Configuration();
}
return this.instance;
}
static getData() {
// return {dimUnit: dimCentiMeter,wallHeight: 250, wallThickness: 10};
return config;
}
/** Set a configuration parameter. */
static setValue(key, value) {
// this.data[key] = value;
config[key] = value;
// if(key !== viewBounds){
Configuration.getInstance().dispatchEvent({ type: EVENT_CHANGED, item: Configuration.getInstance(), 'key': key, 'value': value });
// }
}
/** Get a string configuration parameter. */
static getStringValue(key) {
switch (key) {
case configDimUnit:
// return String(this.data[key]);
return String(Configuration.getData()[key]);
default:
throw new Error('Invalid string configuration parameter: ' + key);
}
}
/** Get a numeric configuration parameter. */
static getNumericValue(key) {
switch (key) {
case configSystemUI:
case configWallHeight:
case configWallThickness:
case scale:
case snapTolerance:
case gridSpacing:
case boundsX:
case boundsY:
case viewBounds:
// return Number(this.data[key]);
return Number(Configuration.getData()[key]);
default:
throw new Error('Invalid numeric configuration parameter: ' + key);
}
}
/** Get a numeric configuration parameter. */
static getBooleanValue(key) {
switch (key) {
case snapToGrid:
case directionalDrag:
case dragOnlyX:
case dragOnlyY:
return Boolean(Configuration.getData()[key]);
default:
throw new Error('Invalid Boolean configuration parameter: ' + key);
}
}
}

145
src/app/working-area/model/dimensioning.ts

@ -0,0 +1,145 @@
import { Vector2, Vector3 } from 'three';
import { Configuration, configDimUnit,dimInch, dimFeetAndInch, dimMeter, dimCentiMeter, dimMilliMeter } from './configuration';
export const decimals = 1000;
export const cmPerFoot = 30.48;
export const pixelsPerFoot = 5.0;
export const pixelsPerCm = 1; // 0.5;
export const cmPerPixel = (1.0 / pixelsPerCm);
export const dimensioningOptions = [dimInch, dimFeetAndInch, dimMeter, dimCentiMeter, dimMilliMeter];
/** Dimensioning functions. */
export class Dimensioning {
static cmToPixelVector2D(cmV2d) {
let pixelV2d = new Vector2(Dimensioning.cmToPixel(cmV2d.x), Dimensioning.cmToPixel(cmV2d.y));
return pixelV2d;
}
static cmToPixelVector3D(cmV3d) {
let pixelV2d = new Vector3(Dimensioning.cmToPixel(cmV3d.x), Dimensioning.cmToPixel(cmV3d.y), Dimensioning.cmToPixel(cmV3d.z));
return pixelV2d;
}
static pixelToCmVector2D(pixelV2d) {
let cmV2d = new Vector2(Dimensioning.cmToPixel(pixelV2d.x), Dimensioning.cmToPixel(pixelV2d.y));
return cmV2d;
}
static pixelToCmVector3D(pixel3d) {
let cmV2d = new Vector3(Dimensioning.cmToPixel(pixel3d.x), Dimensioning.cmToPixel(pixel3d.y), Dimensioning.cmToPixel(pixel3d.z));
return cmV2d;
}
static cmToPixel(cm, apply_scale = true) {
if (apply_scale) {
return cm * pixelsPerCm * Configuration.getNumericValue('scale');
}
return cm * pixelsPerCm;
}
static pixelToCm(pixel, apply_scale = true) {
if (apply_scale) {
return pixel * cmPerPixel * (1.0 / Configuration.getNumericValue('scale'));
}
return pixel * cmPerPixel;
}
static roundOff(value, decimals) {
return Math.round(decimals * value) / decimals;
}
/** Converts cm to dimensioning number.
* @param cm Centi meter value to be converted.
* @returns Number representation.
*/
static cmFromMeasureRaw(measure) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
return Math.round(decimals * (measure * 30.480016459203095991)) / decimals;
case dimInch:
return Math.round(decimals * (measure * 2.5400013716002578512)) / decimals;
case dimMilliMeter:
return Math.round(decimals * (measure * 0.10000005400001014955)) / decimals;
case dimCentiMeter:
return measure;
case dimMeter:
default:
return Math.round(decimals * 100 * measure) / decimals;
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmFromMeasure(measure) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
return Math.round(decimals * (measure * 30.480016459203095991)) / decimals + 'cm';
case dimInch:
return Math.round(decimals * (measure * 2.5400013716002578512)) / decimals + 'cm';
case dimMilliMeter:
return Math.round(decimals * (measure * 0.10000005400001014955)) / decimals + 'cm';
case dimCentiMeter:
return measure;
case dimMeter:
default:
return Math.round(decimals * 100 * measure) / decimals + 'cm';
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmToMeasureRaw(cm, power = 1) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch: // dimFeetAndInch returns only the feet
var allInFeet = (cm * Math.pow(0.032808416666669996953, power));
return allInFeet;
case dimInch:
var inches = Math.round(decimals * (cm * Math.pow(0.393700, power))) / decimals;
return inches;
case dimMilliMeter:
var mm = Math.round(decimals * (cm * Math.pow(10, power))) / decimals;
return mm;
case dimCentiMeter:
return Math.round(decimals * cm) / decimals;
case dimMeter:
default:
var m = Math.round(decimals * (cm * Math.pow(0.01, power))) / decimals;
return m;
}
}
/** Converts cm to dimensioning string.
* @param cm Centi meter value to be converted.
* @returns String representation.
*/
static cmToMeasure(cm, power = 1) {
switch (Configuration.getStringValue(configDimUnit)) {
case dimFeetAndInch:
var allInFeet = (cm * Math.pow(0.032808416666669996953, power));
var floorFeet = Math.floor(allInFeet);
var remainingFeet = allInFeet - floorFeet;
var remainingInches = Math.round(remainingFeet * 12);
return floorFeet + '\'' + remainingInches + '';
case dimInch:
var inches = Math.round(decimals * (cm * Math.pow(0.393700, power))) / decimals;
return inches + '\'';
case dimMilliMeter:
var mm = Math.round(decimals * (cm * Math.pow(10, power))) / decimals;
return '' + mm + 'mm';
case dimCentiMeter:
return '' + Math.round(decimals * cm) / decimals + 'cm';
case dimMeter:
default:
var m = Math.round(decimals * (cm * Math.pow(0.01, power))) / decimals;
return '' + m + 'm';
}
}
}

71
src/app/working-area/model/events.ts

@ -0,0 +1,71 @@
export const EVENT_ACTION = 'ACTION_EVENT';
export const EVENT_DELETED = 'DELETED_EVENT';
export const EVENT_MOVED = 'MOVED_EVENT';
export const EVENT_REDRAW = 'REDRAW_EVENT';
export const EVENT_NEW = 'NEW_EVENT';
export const EVENT_LOADED = 'LOADED_EVENT';
export const EVENT_LOADING = 'LOADING_EVENT';
export const EVENT_UPDATED = 'UPDATED_EVENT';
export const EVENT_SAVED = 'SAVED_EVENT';
export const EVENT_CHANGED = 'CHANGED_EVENT';
export const EVENT_GLTF_READY = 'GLTF_READY_EVENT';
export const EVENT_EXTERNAL_FLOORPLAN_LOADED = 'EXTERNAL_FLOORPLAN_LOADED_EVENT';
export const EVENT_NEW_PARAMETRIC_ITEM = 'NEW_PARAMETRIC_ITEM_EVENT';
export const EVENT_NEW_ITEM = 'NEW_ITEM_EVENT';
export const EVENT_ITEM_LOADING = 'ITEM_LOADING_EVENT';
export const EVENT_ITEM_LOADED = 'ITEM_LOADED_EVENT';
export const EVENT_ITEM_REMOVED = 'ITEM_REMOVED_EVENT';
export const EVENT_ITEM_SELECTED = 'ITEM_SELECTED_EVENT';
export const EVENT_ITEM_MOVE = 'ITEM_MOVED_EVENT';
export const EVENT_ITEM_MOVE_FINISH = 'ITEM_MOVED_FINISH_EVENT';
export const EVENT_ITEM_HOVERON = 'ITEM_HOVERON_EVENT';
export const EVENT_ITEM_HOVEROFF = 'ITEM_HOVEROFF_EVENT';
export const EVENT_NO_ITEM_SELECTED = 'ITEM_NO_SELECTED_EVENT';
export const EVENT_MODE_RESET = 'MODE_RESET_EVENT';
export const EVENT_CAMERA_MOVED = 'CAMERA_MOVED_EVENT';
export const EVENT_CAMERA_ACTIVE_STATUS = 'CAMERA_ACTIVE_STATUS_EVENT';
export const EVENT_CAMERA_VIEW_CHANGE = 'CAMERA_VIEW_CHANGE_EVENT';
export const EVENT_FPS_EXIT = 'CAMERA_FPS_EXIT_EVENT';
export const EVENT_WALL_CLICKED = 'WALL_CLICKED_EVENT';
export const EVENT_ROOM_CLICKED = 'ROOM_CLICKED_EVENT';
export const EVENT_FLOOR_CLICKED = 'FLOOR_CLICKED_EVENT';
export const EVENT_NOTHING_CLICKED = 'NOTHING_CLICKED_EVENT';
export const EVENT_ROOM_NAME_CHANGED = 'CHANGED_ROOM_NAME_EVENT';
export const EVENT_NEW_ROOMS_ADDED = 'ADDED_NEW_ROOMS_EVENT';
export const EVENT_CORNER_ATTRIBUTES_CHANGED = 'CORNER_ATTRIBUTES_CHANGED_EVENT';
export const EVENT_WALL_ATTRIBUTES_CHANGED = 'WALL_ATTRIBUTES_CHANGED_EVENT';
export const EVENT_ROOM_ATTRIBUTES_CHANGED = 'ROOM_ATTRIBUTES_CHANGED_EVENT';
export const EVENT_CORNER_2D_CLICKED = 'CORNER_CLICKED_2D_EVENT';
export const EVENT_WALL_2D_CLICKED = 'WALL_CLICKED_2D_EVENT';
export const EVENT_ROOM_2D_CLICKED = 'ROOM_CLICKED_2D_EVENT';
export const EVENT_2D_UNSELECTED = 'UNSELECTED_2D_EVENT';
export const EVENT_2D_SELECTED = 'SELECTED_2D_EVENT';
export const EVENT_NOTHING_2D_SELECTED = 'NOTHING_2D_SELECTED_EVENT';
export const EVENT_CORNER_2D_DOUBLE_CLICKED = 'CORNER_DOUBLE_CLICKED_2D_EVENT';
export const EVENT_WALL_2D_DOUBLE_CLICKED = 'WALL_DOUBLE_CLICKED_2D_EVENT';
export const EVENT_ROOM_2D_DOUBLE_CLICKED = 'ROOM_DOUBLE_CLICKED_2D_EVENT';
export const EVENT_CORNER_2D_HOVER = 'CORNER_HOVER_2D_EVENT';
export const EVENT_WALL_2D_HOVER = 'WALL_HOVER_2D_EVENT';
export const EVENT_ROOM_2D_HOVER = 'ROOM_HOVER_2D_EVENT';
export const EVENT_KEY_PRESSED = 'KEY_PRESSED_EVENT';
export const EVENT_KEY_RELEASED = 'KEY_RELEASED_EVENT';
export const EVENT_UPDATE_TEXTURES = 'UPDATE_TEXTURES_EVENT';
export const EVENT_MODIFY_TEXTURE_ATTRIBUTE = 'MODIFY_TEXTURE_ATTRIBUTE_EVENT';
export const EVENT_PARAMETRIC_GEOMETRY_UPATED = 'PARAMETRIC_GEOMETRY_UPATED_EVENT';
export const EVENT_SELECTION_CHANGED = 'selectionChanged';
export const EVENT_IMAGE_RESIZE = 'imageResize';

87
src/app/working-area/model/grid2D.ts

@ -0,0 +1,87 @@
import { Configuration, gridSpacing, viewBounds } from './configuration';
import { EVENT_CHANGED } from './events';
import { Graphics } from 'pixi.js';
import { Vector2 } from 'three';
import { Dimensioning } from './dimensioning';
const GRID_SIZE = 10000;
export class Grid2D extends Graphics {
canvas;
options;
size;
gridScale;
constructor(canvas, options) {
super();
// this.drawRect(0, 0, GRID_SIZE, GRID_SIZE);
this.canvas = canvas;
this.options = options;
this.size = new Vector2(GRID_SIZE, GRID_SIZE);
this.gridScale = 1.0;
this.width = this.size.x;
this.height = this.size.y;
this.drawRect(0, 0, GRID_SIZE, GRID_SIZE);
this.pivot.x = this.pivot.y = 0.5;
Configuration.getInstance().addEventListener(EVENT_CHANGED, (evt) => this.updateGrid());
this.updateGrid();
}
updateGrid() {
let gridSize = Dimensioning.cmToPixel(Configuration.getNumericValue(viewBounds) * 1);
let spacingCMS = Configuration.getNumericValue(gridSpacing);
let spacing = Dimensioning.cmToPixel(spacingCMS);
let totalLines = gridSize / spacing;
let halfSize = gridSize * 0.5;
let linewidth = Math.max(1.0 / this.gridScale, 1.0) * 1 / this.canvas.scale.x;// 增加缩放系数
let highlightLineWidth = Math.max(1 / this.gridScale, 1.0) * 1 / this.canvas.scale.x;// 增加缩放系数
let normalColor = 0xE0E0E0;
let highlightColor = 0xD0D0D0;
const cellSize = 5;
this.clear();
for (let i = 0; i <= totalLines; i++) {
let co = (i * spacing) - halfSize;
if (i % cellSize === 0) {
this.lineStyle(highlightLineWidth, highlightColor).moveTo(-halfSize, co).lineTo(halfSize, co);
this.lineStyle(highlightLineWidth, highlightColor).moveTo(co, -halfSize).lineTo(co, halfSize);
} else {
this.lineStyle(linewidth, normalColor).moveTo(-halfSize, co).lineTo(halfSize, co);
this.lineStyle(linewidth, normalColor).moveTo(co, -halfSize).lineTo(co, halfSize);
}
}
this.endFill();
this.beginFill(0xFF0000, 1.0);
this.drawCircle(-halfSize, -halfSize, 5);
this.drawCircle(halfSize, -halfSize, 5);
this.drawCircle(halfSize, halfSize, 5);
this.drawCircle(-halfSize, halfSize, 5);
this.drawCircle(0, 0, 5);
this.endFill();
}
getGridScale() {
return this.gridScale;
}
setGridScale(value) {
this.gridScale = value;
this.updateGrid();
}
configurationUpdate(evt) {
if (evt.key === gridSpacing) {
this.updateGrid();
}
}
getCellCoordinates(x, y) {
let gridSize = Dimensioning.cmToPixel(Configuration.getNumericValue(viewBounds) * 1);
let spacingCMS = Configuration.getNumericValue(gridSpacing);
let spacing = Dimensioning.cmToPixel(spacingCMS);
let halfSize = gridSize * 0.5;
return {
x: Math.floor((x - -halfSize) / spacing),
y: Math.floor((y - -halfSize) / spacing),
};
}
}

37
src/app/working-area/model/messageSystem.ts

@ -0,0 +1,37 @@
class MyEvent<T> extends CustomEvent<T> {
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<T>($data: T, $type: string = MyEvent.CMD): void {
const $event: CustomEvent = new MyEvent<T>($type, $data);
this.dispatchEvent($event);
}
}
class Test {
public constructor() {
MyDispatch.Instance.addEventListener(MyEvent.CMD, this.onEvent as EventListener);
}
private onEvent($e: MyEvent<ITest>): 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<ITest>({ _name: `Aonaufly`, _occupation: `it` });

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

@ -48,6 +48,8 @@ export class MultipointIcon extends AxShape {
this.text.visible = this.showName;
this.text.angle = -this.workingArea.backgroundImage.angle;
this.addChild(this.text);
this.assetData.Thickness = this.assetData.Thickness === 0 ? 32: this.assetData.Thickness;
var tileScale = this.assetData.Thickness/64;
// 画线图标
for (let i = 0, count = this.pointsData.length - 1; i < count; i++) {
const pointA = this.pointsData[i];
@ -58,15 +60,17 @@ export class MultipointIcon extends AxShape {
const b = pointB.y - pointA.y;
const distance = Math.sqrt(a * a + b * b);
const icon = new PIXI.TilingSprite(PIXI.Texture.from(this.assetData.ImageUrl), distance, 64);
const icon = new PIXI.TilingSprite(PIXI.Texture.from(this.assetData.ImageUrl), distance, this.assetData.Thickness);
icon.tileScale.set(tileScale);
icon.anchor.set(0, 0.5);
icon.x = pointA.x;
icon.y = pointA.y;
icon.angle = angle;
// icon.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
this.iconsTilingSprite.push(icon);
this.addChild(icon);
this.text.position = this.getLineCenter(this.pointsData[0], this.pointsData[1]);
// 等距等分
this.tileDistanceEqual(icon);
}
this.sortableChildren = true;
this.text.zIndex = this.pointsData.length;
@ -128,6 +132,8 @@ export class MultipointIcon extends AxShape {
const distance = Math.sqrt(a * a + b * b);
this.iconsTilingSprite[index].angle = angle;
this.iconsTilingSprite[index].width = distance;
this.tileDistanceEqual(this.iconsTilingSprite[index]);
} else if (index < array.length - 1) {// 不是第一个点,也不是最后一个点
this.iconsTilingSprite[index].x = newPosition.x;
this.iconsTilingSprite[index].y = newPosition.y;
@ -143,12 +149,16 @@ export class MultipointIcon extends AxShape {
this.iconsTilingSprite[index].angle = angle;
this.iconsTilingSprite[index].width = distance;
this.tileDistanceEqual(this.iconsTilingSprite[index]);
const angleC = Math.atan2((pointA.y - pointC.y), (pointA.x - pointC.x)) * (180 / Math.PI);
const aC = pointA.x - pointC.x;
const bC = pointA.y - pointC.y;
const distanceC = Math.sqrt(aC * aC + bC * bC);
this.iconsTilingSprite[index - 1].angle = angleC;
this.iconsTilingSprite[index - 1].width = distanceC;
this.tileDistanceEqual(this.iconsTilingSprite[index - 1]);
} else if (index === array.length - 1) { // 最后一个点
const pointA = array[index]; // 当前点
const pointC = array[index - 1]; // 前一个点
@ -159,6 +169,8 @@ export class MultipointIcon extends AxShape {
const distanceC = Math.sqrt(aC * aC + bC * bC);
this.iconsTilingSprite[index - 1].angle = angleC;
this.iconsTilingSprite[index - 1].width = distanceC;
this.tileDistanceEqual(this.iconsTilingSprite[index - 1]);
}
this.drawBorder(1 / this.workingArea.backgroundImage.scale.x);
this.text.position = this.getLineCenter(this.pointsData[0], this.pointsData[1]);
@ -177,6 +189,16 @@ export class MultipointIcon extends AxShape {
item.visible = value;
});
}
/**
*
* @param scale
*/
public drawBorder(scale: number) {
let visible = this.pointsGraphics[0].visible;
this.setPointVisiable(false);
super.drawBorder(scale);
this.setPointVisiable(visible);
}
// 设置名称
public setNameVisible(value: boolean, mode: GameMode) {
if (this.assetData.GameMode === mode) {
@ -192,13 +214,28 @@ export class MultipointIcon extends AxShape {
}
// 刷新数据
public refresh() {
// console.log(this.assetData);
// this.iconsTilingSprite.forEach(element => {
// element.height = this.assetData.Thickness === 0 ? 32 : this.assetData.Thickness;
// });
this.assetData.Thickness = this.assetData.Thickness === 0 ? 32: this.assetData.Thickness;
this.iconsTilingSprite.forEach(item => {
// 厚度优化
this.tileDistanceEqual(item);
});
this.text.text = this.assetData.Name
+ '\r\n'
+ this.assetData.PropertyInfos.find(item => item.PropertyName === '名称/编号')?.PropertyValue;
this.text.angle = -this.workingArea.backgroundImage.angle;
}
// 等距等分
public tileDistanceEqual(icon: PIXI.TilingSprite) {
icon.height = this.assetData.Thickness;
var tileScale = this.assetData.Thickness / 64;
icon.tileScale.set(tileScale);
console.log(tileScale);
var tileWidth = tileScale * 64;
var tileCount = Math.ceil(icon.width / tileWidth);
tileWidth = icon.width / tileCount;
tileScale = tileWidth / 64;
console.log(tileScale);
icon.tileScale.set(tileScale);
}
}

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

@ -155,6 +155,16 @@ export class PolygonIcon extends AxShape {
item.visible = value;
});
}
/**
*
* @param scale
*/
public drawBorder(scale: number) {
let visible = this.pointsGraphics[0].visible;
this.setPointVisiable(false);
super.drawBorder(scale);
this.setPointVisiable(visible);
}
// 设置缩放
public setItemScale(scale: number) {
// this.text.scale.set(scale);

3
src/app/working-area/working-area.component.html

@ -1,2 +1 @@
<div #content style="width:100%;height:100%;" (mousewheel)='this.mouseWheelHandel($event)'
(DOMMouseScroll)='this.mouseWheelHandel($event)'></div>
<div #content style="width:100%;height:100%;"></div>

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

File diff suppressed because it is too large Load Diff

BIN
src/assets/images/enterPaintButton.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 939 B

Loading…
Cancel
Save