Commit 852dd552 authored by baoshuang's avatar baoshuang

编辑模式

parent 477758a7
import { PubSub } from 'ray-eventpool';
export const EVENTS_CONSTS = {
// 3D stage 操作
A3D_CAMERA_EFFECTS: 'a3d_camera_effects',
// --------- 画布数据操作 --------
// sketch active change. [sketch 选中]
SKETCH_ACTIVE_CHANGE: 'sketch_active_change',
// design sketch data config change. [sketch 数据配置变化]
DATA_CONFIG_CAHNGE: 'data_config_change',
// design animations config change. [场景动画配置变化]
ANIMATION_CAHNGE: 'animations_config_change',
// design sketch data need reload. [sketch 数据重新加载]
DATA_RELOAD: 'data_reload',
// design sketch visual param property change. [sketch 组件显示参数配置信息变化]
SKETCH_PARAMS_CHANGE: 'sketch_params_change',
// design scene base model change. [画布 - 基础场景模型 配置信息变化]
SCENE_BASE_MODEL_CHANGE: 'scene_base_model_change',
// design scene property change. [画布显示参数配置信息变化]
SCENE_PARAMS_CHANGE: 'scene_params_change',
// design scene change. [画布切换]
SCENE_ACTIVE_CHANGE: 'scene_active_change',
// reference change
SKETCH_REFERENCE_CHANGE: 'sketch_reference_change', // particle/routePath
// -- 细节事件 --
PICKER_COORDINATE: 'picker_coordinate', // 拾取坐标点
PICKER_COORDINATE_SAVE: 'picker_coordinate_save', // 保存拾取坐标点
// 动画中绘制路径
DRAW_PATHPOINTS: 'draw_pathpoints', // 绘制路径
DRAW_PATHPOINTS_SAVE: 'draw_pathpoints_save', // 保存绘制路径
// 线路 routeline editors
ROUTE_LINE_CHANGE: 'route_line_change', // 线路切换
// -- 场景处理 --
STAGE_CAMERA_INFO: 'stage_camera_info' // 场景摄像机信息同步
};
/**
* 操作类型
*/
export const OPERATE_TYPE = {
/** 新增 */
ADD: 'add',
/** 删除 */
DEL: 'del',
/** 修改 */
UPDATE: 'update',
/** 查询 */
SEARCH: 'search'
};
/**
* HTML Event 事件
*/
export const EVENT_TYPES = {
MOUSE_DOWN: 'on_mouse_down',
MOUSE_MOVE: 'on_mouse_move',
MOUSE_UP: 'on_mouse_up',
};
// --- general publish function
/**
* 分发画布上鼠标按下事件
* @param {*} event
*/
export function dispatchMouseDown(event) {
PubSub.publish(EVENT_TYPES.MOUSE_DOWN, event);
}
/**
* 分发画布上鼠标移动事件
* @param {*} event
*/
export function dispatchMouseMove(event) {
PubSub.publish(EVENT_TYPES.MOUSE_MOVE, event);
}
/**
* 分发画布上鼠标抬起
* @param {*} event
*/
export function dispatchMouseUp(event) {
PubSub.publish(EVENT_TYPES.MOUSE_UP, event);
}
......@@ -33,7 +33,7 @@ export const secExtUrl = {
opSearchMenusUrl: completePrefix(securityBaseURI, 'permissionItem/searchPermission-tree?nodeName={nodeName}&type={type}'),
// 根据父菜单 code 获取子菜单
opSearchBizMenusUrl: completePrefix(securityBaseURI, 'permissionItem/searchSubmenuPermission/{code}'),
menusRoutesUrl: completePrefix(baseURI,'privilege/v1/permission/tree/me?menuAgent=WEB&permissionType=MENU,SUBMENU&path='),
menusRoutesUrl: completePrefix(securityBaseURI,'privilege/v1/permission/tree/me?menuAgent=WEB&permissionType=MENU,SUBMENU&path='),
// 获取厂区集合 get
regionListUrl: completePrefix(patrolURI, 'api/group/queryAuthCompanyLeaves'),
......@@ -247,4 +247,14 @@ selectedOrgInfoUrl: completePrefix(baseURI, 'api/region/current'),//获取选择
};
export const ModuleEditUrl = {
getAreaTreeUrl:completePrefix(baseURI, 'api/view3d/region/tree'),//
getPointTreeUrl:completePrefix(baseURI, 'api/view3d/point/tree'),
saveAreaDataUrl:completePrefix(baseURI, 'api/view3d/region/bind'),//
getPointTypeUrl:completePrefix(baseURI, 'api/view3d/point/type'),
getPointListUrl:completePrefix(baseURI, 'api/view3d/init3dViewNode'),//获取初始三维点 type=impEquipment&riskSourceId=1
savePointListUrl:completePrefix(baseURI, 'api/view3d/point/bind'),//批量保存点绑定关系
}
export const securityKey = 'qianyue(xian),fsc,xunjianpassword';
......@@ -53,6 +53,8 @@ import alarmTestView from './../view/bizview/alarm';
import CusVizLib from './../view/planMgmt/cusVizLib';
import RealTimeMonitor from './../view/morphic';
import PublishView from './../view/planMgmt/view';
import ModuleEdit from './../view/3dview/ModuleEdit'
// import ModuleEdit from './../view/bizview/moduleEdit/index'
const Routes = {
// 添加 rules 路由
......@@ -100,7 +102,8 @@ const Routes = {
alarmVideoMonitor: AlarmVideoMonitor,
alarmTest: alarmTestView,
vizlib: CusVizLib,
planDrill: PublishView
planDrill: PublishView,
moduleEdit: ModuleEdit
};
const pageCompontent = key => {
......
import formatUrl from 'amos-processor/lib/utils/urlFormat';
import * as helper from 'base-r3d/lib/utils/helper';
// import { helper } from 'amos-3d/lib/threeTools';
import { ModuleEditUrl } from './../consts/urlConsts';
import { commonGet, commonPost, singleFetch } from './../utils/request';
export const downloadBasicScene = (modelURI) => {
if (!modelURI.endsWith('.json')){
modelURI += '/index.json';
}
return singleFetch(modelURI);
};
/**
* 通过 subjectId 获取场景配置信息
* @param {String} subjectId
*/
export const getDesignerParamAction = (subjectId) => {
// return singleFetch('/_mock/empty.json');
// return singleFetch('/_mock/plant.json');
// return commonGet('/_mock/plant.json');
// const url = formatUrl(GraphURL.getDesignUrl, { subjectId });
// return commonGet(url);
};
/**
* 保存设计视图
* @param {object} object
*/
export const saveDesignAction = object => {
// return commonPost(GraphURL.saveDesignUrl, object);
};
export const getAreaTreeAction = () => {
return commonGet(ModuleEditUrl.getAreaTreeUrl);
}
export const getPointTreeAction = (type) => {
return commonGet(`${ModuleEditUrl.getPointTreeUrl}/${type}`);
}
/**
* 保存区域
* @param {*} routePathParams
*/
export const saveAreaDataAction = (routePathParams) => {
return commonPost(ModuleEditUrl.saveAreaDataUrl, routePathParams);
}
export const getPointTypeAction = () => {
return commonGet(ModuleEditUrl.getPointTypeUrl);
}
/**
* 获取风险点
* @param {点类型} type
* @param {区域id} riskSourceId
*/
export const getPointListAction = (type,riskSourceId) => {
if (type) {
return commonGet(`${ModuleEditUrl.getPointListUrl}?type=${type}&riskSourceId=${riskSourceId}`);
} else {
return commonGet(`${ModuleEditUrl.getPointListUrl}`);
}
}
/**
* 保存风险点
* @param {*} bindParams
*/
export const savePointListAction = (bindParams) => {
return commonPost(ModuleEditUrl.savePointListUrl, bindParams);
}
\ No newline at end of file
......@@ -12,6 +12,7 @@
@import './preControl.scss';
@import './planDetail.scss';
@import './preControl.1024.scss';
@import './moduleEdit.scss';
......
.ModuleEditPage {
position: relative;
height: 100%;
.topBox {
position: absolute;
top: 34px;
left: 40%;
span {
display: inline-block;
}
.editTitle {
width:257px;
height:55px;
background: url('/src/assets/moduleEdit/title.png') no-repeat 100% 100%;
// opacity:0.4;
font-size: 24px;
text-align: center;
color: #fff;
vertical-align: top;
.titleText {
width: 100%;
height: 100%;
line-height: 55px;
// border-bottom:2px transparent solid;
// border-image:linear-gradient(90deg,rgba(50,217,239,0) 2%,rgba(50,217,239,0.49) 29%,rgba(50,217,239,0.73) 73%,rgba(50,217,239,0) 100%);
}
}
.quipBtn {
width: 169px;
height: 44px;
background: url('/src/assets/moduleEdit/quip.png') no-repeat 100% 100%;
margin-top: 10px;
margin-left: 70px;
}
}
.bottomBox {
position: absolute;
bottom: 34px;
left: 40%;
span {
display: inline-block;
width: 177px;
height: 42px;
line-height: 42px;
background: rgba(46,217,239,0.2);
// border: 2px solid #2ED9EF;
margin: 0 10px;
text-align: center;
font-size: 16px;
// color: #2ED9EF;
cursor: pointer;
}
.editAreaBtn {
background: url('/src/assets/moduleEdit/areaBtn.png') no-repeat 100% 100%;
}
.editPointBtn {
background: url('/src/assets/moduleEdit/pointBtn.png') no-repeat 100% 100%;
}
.editAreaBtn.selected {
background: url('/src/assets/moduleEdit/areaBtn_select.png') no-repeat 100% 100%;
}
.editPointBtn.selected {
background: url('/src/assets/moduleEdit/poingBtn_select.png') no-repeat 100% 100%;
}
}
// 左侧树
.leftTree {
position: absolute;
top: 0;
left: 32px;
width: 264px;
height: 100%;
padding: 32px 0;
.leftContainer {
width: 100%;
height: 100%;
background-color: rgba(10, 53, 62, 0.68);
border: 1px solid rgba(46, 217, 239, 0.59);
padding: 12px;
}
.topForm {
.leftSelect {
height: 39px;
width: 100%;
margin-bottom: 10px;
background: url('/src/assets/moduleEdit/selectBox.png') no-repeat 100% 100%;
border: none;
line-height: 31px;
padding: 5px;
color: #F0DF2D;
}
.leftSearch {
height: 33px;
line-height: 33px;
background: url('/src/assets/moduleEdit/searchBg.png') no-repeat 100% 100%;
input {
background-color: transparent;
box-shadow: none;
padding-left: 15px;
color: #fff;
}
.amosicon-search {
color: #2ED9EF;
}
}
}
.treeBox {
height: calc(100% - 132px);
overflow-y: auto;
.amos-tree {
color: rgba(15, 235, 255, 1);
.amos-tree-node-content-wrapper {
color: #fff;
font-size: 15px;
}
}
}
.bottomBtns {
padding-top: 15px;
text-align: center;
.sureBtn {
width: 100px;
height: 33px;
background: url('/src/assets/moduleEdit/sureBtn.png') no-repeat 100% 100%;
border: none;
}
.deleteBtn {
width: 100px;
height: 33px;
background: url('/src/assets/moduleEdit/deleteBtn.png') no-repeat 100% 100%;
border: none;
}
}
}
// 右侧面板
.rightEditPanel {
position: absolute;
top: 0;
right: 32px;
width: 264px;
height: 100%;
padding: 32px 0;
.rightContainer {
width: 100%;
height: 100%;
background-color: rgba(10, 53, 62, 0.68);
border: 1px solid rgba(46, 217, 239, 0.59);
padding: 12px;
.topForm {
height: calc(100% - 48px);
}
}
.bottomBtns {
padding-top: 15px;
text-align: center;
.sureBtn {
width: 100px;
height: 33px;
background: url('/src/assets/moduleEdit/sureBtn.png') no-repeat 100% 100%;
border: none;
}
.deleteBtn {
width: 100px;
height: 33px;
background: url('/src/assets/moduleEdit/deleteBtn.png') no-repeat 100% 100%;
border: none;
}
}
}
}
\ No newline at end of file
......@@ -15,12 +15,13 @@ const defaultPageable = {
const defaultHeaders = {
appKey: 'CONVERTER_STATION',
product: 'CONVERTER_STATION_WEB',
channelType: '3dpage'
};
const compleHeaders = () => {
return {
...defaultHeaders,
token: getToken()
token: getToken(),
};
};
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { utils, UUID } from 'amos-tool';
import { Connect as UIConnect, Modal,message } from 'amos-framework';
import { FatLine } from 'amos-3d/lib/advanced';
import { PubSub } from 'ray-eventpool';
import A3DDesigner, { Connect, FireObject, DESIGNER_CONSTS, PolygonRegion } from 'amos-3d/lib/designer';
import WorkerObjContent from 'amos-3d/lib/worker/WorkerObjContent';
import { transitionHelper } from 'amos-3d/lib/helpers';
import * as endConf from 'amos-processor/lib/config/endconf';
import { LensJumpFactory } from 'base-r3d/lib/factory';
import { CONSTS } from 'CONSTS/storageConsts';
import MaskContent from './MaskContent';
import { getObjFromNet, initView3DAction, query3DStatistics } from '../../services/3dService';
import { desigerConf, desigerHelperConfig } from './moduleEditConf';
import withDesigner from './../connect/withDesigner';
import { getAreaTreeAction, getPointTypeAction, getPointTreeAction } from './../../services/moduleEditServices';
import { getPointListAction,saveAreaDataAction } from './../../services/moduleEditServices';
import PointsPoolEditPage from './PointsPoolEditPage';
import { eventTopics, isControllerEvent, isManualOperate } from './consts';
import { executeView3dCMD, parseManual, parseBubbleMarkers, tirggerPlanTopic, tirggerTransTopic } from './dataProcessor';
import {
dealTroubleMarkers,
removeFireAlarm,
initView3d,
} from './ruleActionView';
// import ScreenSaverView from './screenSaver/ScreenSaverView';
import { lineData } from './datas';
// import PersonCurves from './PersonCurves';
import AreaLeftTree from './moduleEditComponent/AreaLeftTree';
import RightEditPanel from './moduleEditComponent/RightEditPanel';
import { EVENTS_CONSTS, dispatchMouseDown } from './../../consts/EventConsts';
const AmosConfig = endConf.AmosConfig;
const view3dFile = AmosConfig.view3dFile;
let mousewheelCount = AmosConfig.mapLevelconfig.mousewheelCount * 100;
// const showInterval = AmosConfig.screenSaverConf.delayTime * 1000;
const { resizeConnect } = Connect;
const eventConnect = UIConnect.eventConnect;
const { BaseObjHelper } = transitionHelper;
const { FlameFire, FlameFire2, FlameFire3 } = FireObject;
const LENS_LEVEL = {
ROOT: 'root',
SUB: 'sub'
};
const layerConfig = {
defaultSelects: '',
layers: []
};
const { PEN_STATE } = DESIGNER_CONSTS;
@resizeConnect
@eventConnect
@withDesigner({
// initAction: getDesignerParamAction,
// saveAction: saveDesignAction
})
class ModuleEdit extends Component {
constructor(props) {
super(props);
this.state = {
objs: null,
totalDelta: 0, // zoom值
asyncModels: null,
startAsyncLoad: false,
showScreenSaver: false,
showMap: true,
fireTruckRoute: '',
pathRoute: [],
markerList: [],
fireEquipmentPosition: [],
markerType: null,
alarmStarted: false,
drawing: false,
selectArea: "",
treeData: [],
routePathData:[], //区域线位置
pageType: 'region',
pointType: '',
pointTypeArr: [],
// markers: {
// patrol: [],
// risk: [],
// video: [],
// person: [],
// data: [],
// room: []
// },
markers: {
riskSource: [],
patrol: [],
impEquipment: [],
monitorEquipment: [],
video: [],
fireEquipment: []
}
};
this.nativeProps = {
onMouseDown: this.onMouseDown,
onMouseMove: this.onMouseMove
};
getObjFromNet(view3dFile, (objs, asyncModels) => {
this.setState({
objs,
asyncModels
});
});
this.lensLevel = LENS_LEVEL.ROOT;
// this.markerList = {};
}
componentDidMount() {
// this._registerEvents();
getAreaTreeAction().then(data => {
console.log(data);
this.setState({
treeData:data || []
})
})
getPointTypeAction().then(data => {
console.log(data);
this.setState({
pointTypeArr: data||[],
pointType:data[0]?data[0].code:''
})
})
this.getPointList();
}
genPenId = () => {
return UUID.timeUUID('pen');
};
onMouseDown = event => {
if (!this.a3dRef){
return;
}
this.handlePenDown(event);
this.handleAnimatePathDown(event);
// dispatchMouseDown({
// button: event.button,
// clientX: event.clientX,
// clientY: event.clientY,
// objects: this.penTargets
// });
};
onMouseMove = event => {
if (!this.a3dRef){
return;
}
this.handlePenMove(event);
this.handleAnimatePathMove(event);
};
onKeyDownForPen = event => {
const keyCode = event.keyCode;
this.processPen(keyCode);
}
alarmStart = () => {
this.setState({
alarmStarted: true
});
};
componentWillUnmount() {
if (this.timer) {
clearTimeout(this.timer);
}
// this.infoHelper && this.infoHelper.destroy();
}
// eslint-disable-next-line react/sort-comp
_registerEvents = () => {
this.r3d.on('dbclick', evt => {
if (evt.button !== 0) {
return;
}
const object = evt.object;
if (object) {
this.cameraFactory.flyTo({
position: object.position.toArray(),
duration: 6000
});
}
});
this.r3d.on('keydown', evt => {
// 返回上级
if (this.lensLevel === LENS_LEVEL.SUB && evt.code === 'Backspace') {
this.lensJumpFactory.jumpRoot(obj => {
this.lensJumpFactory.fadeIn(obj);
});
this.lensLevel = LENS_LEVEL.ROOT;
}
});
this.r3d.on('camera_zoom', evt => {
console.log('main camera_zoom', evt);
this.onCameraZoomChange(evt.delta);
});
};
onCameraZoomChange = delta => {
let { totalDelta, markerType, showMap } = this.state;
totalDelta = totalDelta + delta;
if (totalDelta < mousewheelCount && showMap) {
// this.asyncLoadMarkerData(markerType);
} else if (totalDelta >= mousewheelCount && !showMap) {
this.loadMarkTypeStatistics(markerType);
}
this.setState({ totalDelta });
}
onGraphCreated = ({ cameraFactory, sceneFactory, outlineFactory, r3d }) => {
this.cameraFactory = cameraFactory;
this.sceneFactory = sceneFactory;
this.outlineFactory = outlineFactory;
this.r3d = r3d;
// 重新设置 outline 风格
this.outlineFactory.outlineConfig = {
visibleEdgeColor: '#f8a303',
hiddenEdgeColor: '#ffe2ad'
};
this.lensJumpFactory = new LensJumpFactory({
r3d,
enbaleAnimation: true,
cameraFactory,
sceneFactory,
cameraEffect: desigerHelperConfig.cameraEffect
});
};
onAllDone = objGroup => {
this.sceneFactory.level.change(objGroup);
this.cameraFactory.fitView(desigerHelperConfig.cameraEffect);
this.setState({
startAsyncLoad: true
});
this.props.onLoadCompleted();
// this.addMouseScrollListener();
// window.onload = enableScreenSaver ? this.loading(this) : () => {};
// enableScreenSaver && this.displayTask(this);
};
onAfterWorkerInit = workerObjGroup => {
// 处理跳跃
this.lensJumpFactory.process(workerObjGroup);
};
// onComplete = obj => {
// const me = this;
// if (!obj.isForceParent) {
// obj.on('click', evt => {
// // console.log('obj click:', evt);
// // me.outlineFactory.toggleOutline(evt.object);
// // me.focusObject(evt.object);
// });
// }
// // 处理跳跃
// this.lensJumpFactory.process(obj);
// };
focusPosition = position => {
if (position) {
this.cameraFactory.flyTo({
position,
duration: 1000
});
}
};
getPointList = () => {
let { markers } = this.state
getPointListAction().then(data => {
console.log(data);
for (let i = 0; i < data.length;i++)
markers[data[i].type].push(data[i])
this.setState({
markers
})
})
}
updateMarker = data => {
const { type, id } = data;
const { markers } = this.state;
const markersArr = markers[type] || [];
if (markersArr.length > 0) {
let needUpdate = false;
const newArr = markersArr.map(ma => {
if (ma.id === id) {
needUpdate = true;
return {
...ma,
...data
};
}
return ma;
});
if (needUpdate) {
markers[type] = newArr;
this.setState({
markers
});
}
}
};
afterRender = () => {
// this.infoHelper && this.infoHelper.update();
};
startDrow = (areaKey) => {
// this.a3dRef.addPen();
this.addPen(areaKey)
}
addPen(areaKey) {
let params = { "displayName": "进攻线路", "thumb": "/a3dres/images/pathline/line-attack.png", "descr": "", "objParam": null, "type": "pen" }
console.log(this.state.selectArea)
const penProps = {
key: this.genPenId(),
color: 0x00ff00,
areaKey: areaKey,
...params
};
this.a3dRef.newPen(penProps);
this.hasCreatePen = true;
}
/** 画笔 down 事件响应 */
handlePenDown = (event) => {
if (!this.isCanBeDraw()){
return;
}
const me = this;
// 鼠标左键(右键),添加一个点
if (event.button === 0 || event.button === 2) {
me.a3dRef.stopPenDrag(event.clientX, event.clientY, me.penTargets, true);
// 鼠标右键 绘制完毕,需要同步处理 reference 数据
if (event.button === 2){
// 保存 reference 数据
const pen = me.a3dRef.currentPen;
let penPoints = pen.getFmtPoints();
if (pen._drawing){
PubSub.publish(EVENTS_CONSTS.SKETCH_REFERENCE_CHANGE, {
type: 'routePath',
key: pen._uuidKey,
eid: pen.userData.eid,
value: {
...pen.userParams,
points: pen.getFmtPoints()
},
position: pen.position
});
me.a3dRef.changeDrawState(PEN_STATE.FINISHED);
this.state.routePathData.push({
riskSourceId: this.state.selectArea,
position3d: JSON.stringify(penPoints)
})
this.setState({
drawing: false,
routePathData: this.state.routePathData
});
}
}
}
// 鼠标中键,清除当前绘制路线
else if (event.button === 1) {
me.a3dRef.changeDrawState(PEN_STATE.CLEARED);
// 结束绘制
this.setState({
drawing: false
});
}
}
stopDrowing = () => {
if (!this.isCanBeDraw()){
return;
}
const me = this;
me.a3dRef.changeDrawState(PEN_STATE.CLEARED);
// 结束绘制
this.setState({
drawing: false
});
}
/** 画笔 move 事件响应 */
handlePenMove = (event) => {
const me = this;
if (!me.isCanBeDraw()){
return;
}
me.a3dRef.startPenDrag(event.clientX, event.clientY, me.penTargets, true);
}
processPen = (code) => {
const me = this;
if (!me.a3dRef || !me.isCanBeDraw()){
return;
}
switch (code) {
case KeyCode.ESC: // 清除画笔
me.a3dRef.changeDrawState(PEN_STATE.CLEARED);
me.setState({
drawing: false
});
break;
case KeyCode.P: // 启动路线编辑 pen (当前画笔)
me.setState({
drawing: true
}, () => {
me.a3dRef.changeDrawState(PEN_STATE.START);
});
break;
case KeyCode.N: // 创建新画笔
this.addPen();
break;
case KeyCode.M: // 绘制路线动起来
me.a3dRef.changeDrawState(PEN_STATE.RUNNING);
break;
default:
break;
}
}
/**
* 当 pen 的 points 改变时的回调,仅处理拖拽 dot 时更改的路线
* @param {Object} pen
*/
handlePenPointsChange = (pen) => {
// 处理动画配置中,改变路径
// this.handleAnimatePathChange(pen);
}
/**
* @param {Object} penEditorInstance
* @param {Object} penEditorInstance.editorsObject
* @param {Object} penEditorInstance.editorCache
* @param {Function} penEditorInstance.addEditor
* @param {Function} penEditorInstance.delEditor
*/
handlePenEditorCreated = (penEditorInstance) => {
this.penEditorInstance = penEditorInstance;
}
isCanBeDraw = () => {
// return this.hasCreatePen && this.props.mouseMode === MOUSE_MODE.pen;
return this.hasCreatePen;
}
/** 处理动画编辑中的画笔 move 事件响应 */
handleAnimatePathMove = (event) => {
if (!this.isCanBeDraw() && !this.enableDrawPath){
return;
}
this.a3dRef.startPenDrag(event.clientX, event.clientY, this.penTargets, true);
}
/** 处理动画编辑中的画笔 down 事件 */
handleAnimatePathDown = (event) => {
if (!this.isCanBeDraw() && !this.enableDrawPath){
return;
}
// 左键添加点, 右键结束绘制,右键所在点不包含在 path 中
if (event.button === 0 || event.button === 2){
this.a3dRef.stopPenDrag(event.clientX, event.clientY, this.penTargets, true);
// 鼠标右键 绘制完毕,需要同步处理 reference 数据
if (event.button === 2) {
const pen = this.a3dRef.currentPen;
if (pen._drawing){
this.a3dRef.changeDrawState(PEN_STATE.FINISHED);
this.setState({
drawing: false
});
// 触发保存动画终点坐标
PubSub.publish(EVENTS_CONSTS.DRAW_PATHPOINTS_SAVE, {
pathKey: pen._uuidKey,
points: pen.getFmtPoints()
});
console.log(pen);
console.log(pen.getFmtPoints())
this.enableDrawPath = false;
}
}
}
// 鼠标中键,清除当前绘制路线
else if (event.button === 1) {
this.a3dRef.changeDrawState(PEN_STATE.CLEARED);
// 结束绘制
this.setState({
drawing: false
});
}
}
selectItemChange = (areaKey) => {
console.log(areaKey);
this.state.selectArea = areaKey
this.setState({
selectArea: areaKey
})
}
renderAreas = () => {
let { treeData } = this.state;
console.log(treeData)
let areas = [];
if (treeData.length>0) {
treeData.map((item) => {
if (item.isRegion && item.isBind) {
if (treeData.children&&treeData.children.length > 0) {
areas.push(<PolygonRegion points={JSON.parse(item.position3d)} />)
{this.renderAreas(item.children)}
}
areas.push(<PolygonRegion points={JSON.parse(item.position3d)} />)
}
});
}
return areas
}
saveAreaData = () => {
let { treeData, routePathData, pageType } = this.state;
let routePathParams = [];
console.log(routePathData)
saveAreaDataAction(routePathData).then(d => {
message.success('保存成功!');
getAreaTreeAction().then(data => {
console.log(data);
this.setState({
treeData:data || []
})
});
}, eer => {
message.error('保存失败!');
});
}
/**
* 切换区域和点页面
*/
changeAreaPoint = (type) => {
let { pointTypeArr } = this.state;
if (type == 'region') {
getAreaTreeAction().then(data => {
this.setState({
treeData:data || [],
pageType: 'region'
})
})
} else {
getPointTreeAction(pointTypeArr[0].code||'').then(data => {
console.log(data);
this.setState({
pointType: pointTypeArr[0].code||'',
treeData: data||[],
pageType: 'point'
})
})
}
}
pointTypeChange = (pointType) => {
this.state.pointType = pointType;
getPointTreeAction(pointType).then(data => {
console.log(data);
this.setState({
pointType: pointType,
treeData: data||[]
})
})
}
drop = (event) => {
event.preventDefault();
console.log(event.clientX)
const objs = this.a3dRef.pickerCoordinate(event.clientX, event.clientY, null, true);
let position;
if (objs.length > 0){
// get point
position = objs[0].point;
}
console.log(position)
}
render() {
const {
fireEquipmentPosition,
drawing,
objs,
markers,
pageType,
pointType,
pointTypeArr
} = this.state;
console.log(this.state)
console.log(this.props)
const { dimension, hiddenScreenSaver } = this.props;
const graphicProps = {
...dimension,
...desigerConf,
enableAnimator: true,
enableOutline: true,
// enableCSS2D: true,
onCreated: this.onGraphCreated,
afterRender: this.afterRender
};
// const modelContentProps = {
// onAllDone: this.onAllDone,
// onComplete: this.onComplete
// };
let firePosition = null;
if (fireEquipmentPosition && fireEquipmentPosition.length > 0) {
firePosition = {
x: fireEquipmentPosition[0],
y: fireEquipmentPosition[1],
z: fireEquipmentPosition[2]
}
} else {
firePosition = { x: -90.827, y: 30.4577, z: 1.0839 };
}
const penProps = {
// 启动 UV 滚动动画
scrollUV: true,
onCreated: this.handlePenEditorCreated,
onPointsChange: this.handlePenPointsChange
};
return (
<div className='ModuleEditPage'>
<div
className='designerBox'
onDragOver={(e) => {e.preventDefault();}}
onDrop={(e)=>this.drop(e)}
>
<A3DDesigner
{...graphicProps}
enableModelParser
disabledEdit
defaultLoading={false}
ref={node => (this.a3dRef = node)}
baseObjs={objs}
drawing={drawing}
enablePen
nativeProps={this.nativeProps}
penProps={penProps}
>
<PointsPoolEditPage markers={markers} updateMarker={this.updateMarker} />
{this.renderAreas()}
</A3DDesigner>
</div>
<AreaLeftTree
startDrow={this.startDrow}
treeData={this.state.treeData}
saveAreaData={this.saveAreaData}
selectItemChange={this.selectItemChange}
stopDrowing={this.stopDrowing}
pageType={pageType}
// pointType={pointType}
pointTypeArr={pointTypeArr}
pointTypeChange={this.pointTypeChange}
/>
<div className='topBox'>
<span className='editTitle'>
<span className='titleText'>编辑模式</span>
</span>
<span className='quipBtn'></span>
</div>
<div className='bottomBox'>
<span className={`editAreaBtn ${pageType == 'region'?'selected':'noSelect'}`} onClick={this.changeAreaPoint.bind(this,'region')}></span>
<span className={`editPointBtn ${pageType == 'point'?'selected':'noSelect'}`} onClick={this.changeAreaPoint.bind(this,'point')}></span>
</div>
<div className='rightBox'>
<RightEditPanel />
</div>
</div>
);
}
}
ModuleEdit.propTypes = {
dimension: PropTypes.shape({
width: PropTypes.number,
height: PropTypes.number
}),
subscribe: PropTypes.func,
hiddenScreenSaver: PropTypes.func,
onLoadCompleted: PropTypes.func,
alarmStart: PropTypes.func,
// planStart: PropTypes.func
};
export default ModuleEdit;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Connect } from 'amos-framework';
import { Store } from 'amos-tool';
import { connect3D } from 'amos-3d/lib/designer';
import { RiskPoint, PatrolPoint, PersonPoint3D, MonitorPoint, ProbePoint,
FireResourcePoint, EquipmentPoint, FireCar3D, FirePoint, WorkerMen3D, PointStatistics } from './moduleEditPoints';
import { eventTopics, isPointEvent , isLevelFilter } from './consts';
import { parseMarkers, parseLevelFilter, objRunning } from './dataProcessor';
import { lineData } from './datas';
import { BaseObjHelper } from 'amos-3d/lib/three/helpers/transitionHelper';
const loginUserName = Store.lsTool.read('userName');
const filterUser = ['tianbo', 'opera1', 'opera2'];
const eventConnect = Connect.eventConnect;
const markers3D = [
{ key: '1', position: [153, -10, -20], size: 10, url: '/threeres/markers/person.png' },
{ key: '2', position: [-100, 22, 0], size: 10, url: '/threeres/markers/video.png', label: '视频点' },
{ key: '4', position: [30, -5, -90], size: 10, keepSize: true, label: '大小不变' }
];
const Shuttle = (props) => props.children;
/**
* Markers 池,所有的 markers 均在本类进行加载
*
* @export
* @class PointsPool
* @extends {Component}
*/
@connect3D
@eventConnect
class PointsPoolEditPage extends Component {
constructor(props) {
super(props);
this.markerList = {};
}
componentDidMount() {
this.props.subscribe(eventTopics.base3d_view, (topic, data) => {
if (isPointEvent(topic)){
parseMarkers(this, topic, data);
} else if (isLevelFilter(topic)) {
parseLevelFilter(this, topic, data);
}
});
this.props.subscribe('base3d.fromws1.showFireTruckRoute', (topic, data) => {
parseMarkers(this, topic, data);
});
// this.props.subscribe(eventTopics.view3d_init, (topic, data) => {
// const fireTruckMarkerCache = this.markerList['fireCar'];
// if (fireTruckMarkerCache) {
// for (let fireTruck of fireTruckMarkerCache.getValues()) {
// fireTruck.stopMove();
// }
// }
// });
}
onMarkersCreated = (type, { markersCache }) => {
this.markerList[type] = markersCache;
(markersCache || []).forEach(mc => {
const extData = mc.getExtData();
if (extData.hasOwnProperty('visible')){
let visible = extData.visible;
if (visible) {
if (extData.type === 'fireCar') {
mc.visible = visible;
mc.object2DPipe.pipeNode.visible = false;
mc.object2DPipe.pipeNode.elementVisible = false;
} else {
mc.show();
}
} else {
if (extData.type === 'fireCar') {
mc.visible = visible;
mc.object2DPipe.pipeNode.visible = false;
mc.object2DPipe.pipeNode.elementVisible = false;
} else {
mc.hide();
}
}
}
});
}
updateMarkers = (data) => {
this.props.updateMarker(data);
}
render() {
const { markers, ...rest } = this.props;
let hideDetector = false;
if (filterUser.includes(loginUserName)) {
hideDetector = true;
}
return (
<Shuttle>
<RiskPoint
{...rest}
markers={markers.riskSource}
onCreated={(val) => this.onMarkersCreated('riskSource', val)}
/>
<PatrolPoint
{...rest}
markers={markers.risk}
onCreated={(val) => this.onMarkersCreated('risk', val)}
/>
<PersonPoint3D
{...rest}
markers={markers.person}
onCreated={(val) => this.onMarkersCreated('person', val)}
/>
<EquipmentPoint
{...rest}
markers={markers.impEquipment}
onCreated={(val) => this.onMarkersCreated('impEquipment', val)}
/>
<FireResourcePoint
{...rest}
markers={markers.pool}
onCreated={(val) => this.onMarkersCreated('pool', val)}
/>
<FireResourcePoint
{...rest}
markers={markers.hydrant}
onCreated={(val) => this.onMarkersCreated('hydrant', val)}
/>
<FireResourcePoint
{...rest}
markers={markers.fireEquipment}
onCreated={(val) => this.onMarkersCreated('fireEquipment', val)}
/>
<FireResourcePoint
{...rest}
markers={markers.fireChamber}
onCreated={(val) => this.onMarkersCreated('fireChamber', val)}
/>
<FireResourcePoint
{...rest}
markers={markers.fireFoamRoom}
onCreated={(val) => this.onMarkersCreated('fireFoamRoom', val)}
/>
{!hideDetector ?
<FireResourcePoint
{...rest}
markers={markers.fireDetection}
onCreated={(val) => this.onMarkersCreated('fireDetection', val)}
/>
: ''
}
<ProbePoint
{...rest}
markers={markers.monitorEquipment}
onCreated={(val) => this.onMarkersCreated('monitorEquipment', val)}
/>
<MonitorPoint
{...rest}
markers={markers.video}
onCreated={(val) => this.onMarkersCreated('video', val)}
/>
<FirePoint
{...rest}
markers={markers.fire}
onCreated={(val) => this.onMarkersCreated('fire', val)}
/>
{/*<FireResourcePoint
{...rest}
markers={markers.fireCar}
onCreated={(val) => this.onMarkersCreated('fireCar', val)}
/> */}
<FireCar3D
{...rest}
markers={markers.fireCar}
onCreated={(val) => this.onMarkersCreated('fireCar', val)}
/>
<PointStatistics
{...rest}
markers={markers.statistics}
onCreated={(val) => this.onMarkersCreated('statistics', val)}
/>
</Shuttle>
);
}
}
PointsPoolEditPage.propTypes = {
subscribe: PropTypes.func,
updateMarker: PropTypes.func,
markers: PropTypes.object
};
export default PointsPoolEditPage;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Connect, Modal, Tree,Select,Search,Button } from 'amos-framework';
import * as endConf from 'amos-processor/lib/config/endconf';
import { getAreaTreeAction,saveAreaDataAction } from './../../../services/moduleEditServices'
const eventConnect = Connect.eventConnect;
const TreeNode = Tree.TreeNode;
const Option = Select.Option;
@eventConnect
class AreaLeftTree extends Component {
constructor(props) {
super(props);
this.state = {
// showScreenSaver: false //是否打开屏保
expandedKeys: [],
autoExpandParent: true,
checkedKeys: [],
selectedKeys: [],
treeData:[],
pointTypeArr:[],
pointType:''
};
}
componentDidMount() {
// getAreaTreeAction().then(data => {
// console.log(data);
// this.setState({
// treeData:data || []
// })
// this.props.getAreaData(data || [])
// })
}
componentWillUnmount() {
}
componentWillReceiveProps(nextProps) {
console.log(nextProps)
let {treeData,pointTypeArr} = nextProps;
this.setState({
treeData,
pointTypeArr,
pointType: pointTypeArr[0]?pointTypeArr[0].code:''
})
}
onSelectChange = (value, item) =>{
console.log(value, item);
this.state.pointType = value;
this.props.pointTypeChange(value);
}
onSearchChange = (e, value) => {
console.log(e, value);
this.setState({
value
});
}
onExpand = (expandedKeys) => {
console.log('onExpand', arguments);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
this.setState({
expandedKeys,
autoExpandParent: false
});
}
onCheck = (checkedKeys,e) => {
console.log('onCheck', checkedKeys);
// console.log('onCheck', e);
let currentKey = checkedKeys.checked[0]?checkedKeys.checked[checkedKeys.checked.length-1]:'';
if (checkedKeys.checked.length<2) {
currentKey = checkedKeys.checked[0]
} else {
if (checkedKeys.checked[0] == this.state.checkedKeys[0]) {
currentKey = checkedKeys.checked[1]
} else {
currentKey = checkedKeys.checked[0]
}
}
// checkedKeys[0] = checkedKeys[checkedKeys.length - 1]
this.setState({ checkedKeys: currentKey?[currentKey]:[] });
this.props.selectItemChange(currentKey);
if (currentKey) {
this.props.startDrow(currentKey);
}else {
this.props.stopDrowing()
}
}
// onTreeSelect = (selectedKeys, info) => {
// console.log('onSelect', info);
// this.setState({ selectedKeys });
// }
renderTreeNodes = (data) => {
console.log(data);
if (data.length>0) {
return data.map((item) => {
if (item.children) {
return (
<TreeNode
title={<div>
<span draggable={item.isRegion?false:true} >{item.name}</span>
</div>}
key={item.id}
dataRef={item}
onDragStart={(e)=>{console.log(e)}}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode
key={item.id}
title={<div>
<span draggable={item.isRegion?false:true} >{item.name}</span>
</div>}
{...item}
onClick={() => {console.log('aaa')}}
onDragStart={(e)=>{console.log(e)}}/>;
});
}
}
render() {
let { treeData, checkedKeys,pointTypeArr,pointType } = this.state;
let { pageType } = this.props;
return (
<div className="leftTree">
<div className='leftContainer'>
<div className='topForm'>
{
pageType=='region'?'':<Select onChange={this.onSelectChange} defaultValue={pointType} className='leftSelect'>
{
pointTypeArr.map(item => {
return (<Option value={item.code}>{item.name}</Option>)
})
}
</Select>
}
<Search className='leftSearch' icon="search" value={''} onChange={this.onSearchChange} onIconClick={this.onSearchChange} />
</div>
<div className='treeBox'>
<Tree
checkable
checkStrictly
selectable={false}
onExpand={this.onExpand}
expandedKeys={this.state.expandedKeys}
autoExpandParent={this.state.autoExpandParent}
onCheck={this.onCheck}
checkedKeys={checkedKeys}
onSelect={this.onTreeSelect}
selectedKeys={this.state.selectedKeys}
blockNode
>
{this.renderTreeNodes(treeData)}
</Tree>
</div>
<div className='bottomBtns'>
<Button
className='sureBtn'
onClick={() => {
this.props.saveAreaData()
}} ></Button>
<Button
className='deleteBtn'
onClick={() => {
// this.props.save()
}} ></Button>
</div>
</div>
</div>
);
}
}
AreaLeftTree.propTypes = {
subscribe: PropTypes.func,
trigger: PropTypes.func
};
export default AreaLeftTree;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Connect, Modal, Tree, Select, Search, Button, Input } from 'amos-framework';
import * as endConf from 'amos-processor/lib/config/endconf';
import { getAreaTreeAction,saveAreaDataAction } from './../../../services/moduleEditServices'
const eventConnect = Connect.eventConnect;
const TreeNode = Tree.TreeNode;
const Option = Select.Option;
@eventConnect
class RightEditPanel extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentDidMount() {
// getAreaTreeAction().then(data => {
// console.log(data);
// this.setState({
// treeData:data || []
// })
// this.props.getAreaData(data || [])
// })
}
componentWillUnmount() {
}
componentWillReceiveProps(nextProps) {
console.log(nextProps)
let {treeData,pointTypeArr} = nextProps;
// this.setState({
// })
}
render() {
let { treeData, checkedKeys,pointTypeArr,pointType } = this.state;
let { pageType } = this.props;
return (
<div className="rightEditPanel">
<div className='rightContainer'>
<div className='topForm'>
<div className='rightTitle'>
<span className='titleIcon'></span>
<span className='titleText'>风险点信息</span>
</div>
<div className='baseMsg'>
<div className='baseTitle'>
<span className='titleIcon'></span>
<span className='titleText'>基本信息</span>
</div>
<div className='baseContent'>
<div className='msgItem'>
<div className='itemLabel'>风险名称</div>
<Input />
</div>
<div className='msgItem'>
<div className='itemLabel'>参考编号</div>
<Input />
</div>
<div className='msgItem'>
<div className='itemLabel'>风险等级</div>
<Input />
</div>
</div>
</div>
<div className='3dMsg'>
<div className='baseTitle'>
<span className='titleIcon'></span>
<span className='titleText'>三维信息</span>
</div>
</div>
</div>
<div className='bottomBtns'>
<Button
className='sureBtn'
onClick={() => {
// this.props.saveAreaData()
}} ></Button>
<Button
className='deleteBtn'
onClick={() => {
// this.props.save()
}} ></Button>
</div>
</div>
</div>
);
}
}
RightEditPanel.propTypes = {
subscribe: PropTypes.func,
trigger: PropTypes.func
};
export default RightEditPanel;
/* eslint-disable no-magic-numbers */
import * as THREE from 'three';
import { TextureFactory, modelClassifyMapper } from 'amos-3d';
import { backgroundHelpers } from 'amos-3d/lib/helpers';
import { utils } from 'amos-tool';
import { getRegion } from '../../utils/cacheUtils';
const { getInnerSkybox } = backgroundHelpers;
const customSkybox = backgroundHelpers.createBackground({
basePath: '/threeres/bg/bluesky/',
names: ['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']
});
const getMaterial = () => {
const groundTexture = TextureFactory.createTextureByUrl('/threeres/mesh/grid-gray.jpg', {
wrapS: THREE.RepeatWrapping,
wrapT: THREE.RepeatWrapping,
anisotropy: 16
});
groundTexture.repeat.set(25, 25);
const groundMaterial = new THREE.MeshLambertMaterial({ map: groundTexture });
return groundMaterial;
};
const getSeriesModel = (key, type, name, count = 1) => {
const result = [];
for (let i = 1; i < count + 1; i++) {
let newKey = i;
if (i < 10){
newKey = `${key}_0${i}`;
}
result.push({
key: newKey, type, sortOrder: 0, displayName: `${name}-${i}`
});
}
return result;
};
/**
* 从数组中组装具体的数据,返回 数组
* @param {Array} arr
* @param {string|array} props
*/
export const getPropFromArr = (arr, props) => {
const result = [];
arr.forEach(a => {
if (utils.isArray(props)){
const item = {};
props.forEach(p => {
if (a[p]){
item[p] = a[p];
}
});
if (!utils.isEmpty(item)){
result.push(item);
}
} else {
if (a[props]){
result.push(a[props]);
}
}
});
return result;
};
/**
* 视图控制
*/
export const viewController = [
{ key: 'park-contorller', icon: 'shu-changqu', type: 'park', label: '选择建筑' },
{ key: 'burst-contorller', icon: 'zhalie', type: 'burst', singleClick: true, label: '炸裂' },
{ key: 'fitview-contorller', icon: 'zuijiashijiao', type: 'fitview', singleClick: true, label: '初始视图' },
{ key: 'explain-controller', icon: 'jianpan', type: 'explain', singleClick: true, label: '控件' }
];
/**
* 业务控制
*/
export const bizControls = [
{ key: 'riskSource-point', icon: 'fengxiandian', type: 'riskSource', label: '风险点', subs: [
{ key: 'level_1', label: '1级' },
{ key: 'level_2', label: '2级' },
{ key: 'level_3', label: '3级' },
{ key: 'level_4', label: '4级' },
{ key: 'level_5', label: '5级' }
] },
{ key: 'risk-point', icon: 'dianwei-zhongdianshebei', type: 'risk', label: '巡检点',subs: [
{ key: 'level_3', label: '漏检' },
{ key: 'level_2', label: '不合格' },
{ key: 'level_1', label: '合格' },
{ key: 'level_0', label: '未计划' }
] },
{ key: 'impEquipment-point', icon: 'zhongdianshebeixiangqing', type: 'impEquipment', label: '重点设备' },
{ key: 'fireResource-point', icon: 'xiaofang', type: 'fireResource', label: '消防设备', subs: [
{ key: 'hydrant', label: '消防栓' },
{ key: 'pool', label: '消防水池' },
{ key: 'fireCar', label: '消防车' },
{ key: 'fireEquipment', label: '灭火器' },
{ key: 'fireChamber', label: '消防室' },
{ key: 'fireFoamRoom', label: '泡沫间' },
{ key: 'fireDetection', label: '火探' }
] },
{ key: 'monitorEquipment-point', icon: 'shujudian', type: 'monitorEquipment', label: '探测设备' },
{ key: 'monitor-point', icon: 'xunjiandian', type: 'video', label: '视频点' }
];
export const bizControlsTypes = [
{ key: 'riskSource', label: '风险点' },
{ key: 'risk' , label: '巡检点' },
{ key: 'impEquipment', label: '重点设备' },
{ key: 'fireResource', label: '消防设备' },
{ key: 'monitorEquipment', label: '探测设备' },
{ key: 'video', label: '视频点' }
];
export const riskSourceLevel = [
{ key: '1', label: '1级' },
{ key: '2', label: '2级' },
{ key: '3', label: '3级' },
{ key: '4', label: '4级' },
{ key: '5', label: '5级' }
];
export const riskSourceStatus = [
{ key: '3', label: '漏检' },
{ key: '2', label: '不合格' },
{ key: '1', label: '合格' },
{ key: '0', label: '未计划' }
];
export const fireResource = [
{ key: 'hydrant', label: '消防栓' },
{ key: 'pool', label: '消防小室' },
{ key: 'fireCar', label: '消防车' },
{ key: 'fireEquipment', label: '灭火器' },
{ key: 'fireChamber', label: '消防室' },
{ key: 'fireFoamRoom', label: '泡沫间' }
];
/**
* 换流站
*/
export const getStationConfig = () => {
return {
cameraEffects: {
initConf: {
position: { x: 2436, y: 1376, z: 1001 }
},
fitConf: {
position: [1232, 1228, 27.98],
target: [-1, -2, -2.5]
}
},
getObjs(){
return {
basePath: '/threeres/models/station/',
objName: 'station.obj',
mtlName: 'station.mtl'
};
}
};
};
export const getYinanConfig = () => {
const names = [
{ key: 'all', type: modelClassifyMapper.ALL, sortOrder: 0, displayName: '厂区', ignore: true },
{ key: 'ground', type: modelClassifyMapper.GROUND, sortOrder: 0, displayName: '地面' },
...getSeriesModel('building', modelClassifyMapper.BUILDING, '监控室', 4),
...getSeriesModel('powerdev', modelClassifyMapper.BUILDING, '电塔', 10)
];
return {
cameraEffects: {
initConf: {
position: { x: 117.20, y: 780.13, z: -944.57 }
},
fitConf: {
position: [-357.67, 318.57, 386.15],
target: [-1, -2, -2.5]
}
},
layerConfig: {
// defaultSelects: getPropFromArr(names, 'key'), // 多选
defaultSelects: 'all',
layers: getPropFromArr(names.filter(n => n.key !== 'helper'), ['key', 'displayName'])
},
getObjs(){
return names.filter(n => !n.ignore).map(o => {
return {
basePath: '/threeres/models/yinan/',
objName: `${o.key}.obj`,
mtlName: `${o.key}.mtl`,
modelClassify: o.type,
sortOrder: o.sortOrder
};
});
}
};
};
export const getCurrentObjs = (key) => {
const region = getRegion();
const regionObj = JSON.parse(region) || {};
const cityCode = key || regionObj.cityCode;
if (cityCode === '济南'){
//
} else if (cityCode === '青岛'){
//
}
return getStationConfig();
};
export default {
ratio: 100,
complete: 100,
// sceneBg: new THREE.Color(0x89bffb),
sceneBg: customSkybox,
skybox: getInnerSkybox('bluesky'),
fog: {
color: 0x89bffb,
neer: 5000,
far: 10000
},
// fog: null,
dlight: {
color: 0xffffff,
intensity: 1.0
},
plight: {
color: 0xffffff,
intensity: 0.8
},
plugins: {
OrbitControls: {
enable: true,
params: {
maxPolarAngle: 1.5, // 上下翻转的最大角度 Math.PI
minPolarAngle: 0, // 上下翻转的最小角度 默认 0
minDistance: 10, // 最近距离,表现在放大
maxDistance: 5000, // 最远距离,表现在缩小
rotateSpeed: 0.5, // 旋转速度 1.0
dampingFactor: 0.2, // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏 0.25
enableZoom: true, // 是否允许缩放
// autoRotate: true, // 是否自动旋转
// autoRotateSpeed: 0.2, // 自动旋转速度
enablePan: true // 是否开启右键拖拽
}
},
CameraHelper: {
enable: true
}
},
camera: {
fov: 45,
near: 1,
far: 10000
},
meshBg: {
geometry: new THREE.PlaneBufferGeometry(20000, 20000),
material: getMaterial(),
position: { y: -30 },
rotation: { x: -Math.PI / 2 }
},
// 展开距离
spacing: 50,
link: {
selectColor: 0x008000,
fatlineProps: {
lineStyle: {
color: 0xff0000,
linewidth: 3
}
},
normalLineProps: {
type: 'Line',
lineStyle: {
color: 0xff0000,
linewidth: 1
}
}
},
// marker 移动耗时
moveDuration: 3000
};
export const desigerConf = {
sceneOptions: {
background: 0x626667
// background: 0x253366,
// skyBox: 'bluesky'
// skyBox: ['pos_x', 'neg_x', 'pos_y', 'neg_y', 'pos_z', 'neg_z'].map(item => `/threeres/bg/bluesky2/${item}.jpg`)
},
cameraOptions: {
fov: 45,
near: 1,
far: 5000,
position: [293.92, 310.55, 1026.64],
// 是否启用拾取器
enablePicker: true,
builtInOrbit: {
maxPolarAngle: Math.PI * 0.5,
minPolarAngle: Math.PI * 0,
minDistance: 1,
maxDistance: 5000
}
},
// 配置信息,支持灯光的配置
options: {
// skybox: 'bluesky'
light: [
{ type: 'AmbientLight', options: { color: 0xffffff, intensity: 0.15 } },
{ type: 'DirectionalLight', options: { color: 0xffffff, intensity: 0.1 } }
],
floorBoard: {
visible: true,
position: { y: 0 },
showType: 'grid',
size: 2000,
divisions: 20,
colorCenterLine: 0x838a94,
colorGrid: 0xd3dbe8,
gridOptions: {
opacity: 0.2,
transparent: true
},
widthSegments: 1,
heightSegments: 1,
boardColor: 0x626667,
boardOptions: {
}
}
}
};
export const curveConf = {
parabola: {
size: 5,
color: 0xff1c1c
}
};
export const desigerHelperConfig = {
cameraEffect: {
position: [-18, 314.33, 410.65],
target: [1, 2.5, 3]
},
objAnchor: {
position: [0, 5, 0]
}
};
export const shortcutKeys = [
{
category: '三维移动控制',
keys: [
{ name: '上移', key: '↑', status: '正常' },
{ name: '下移', key: '↓', status: '正常' },
{ name: '左移', key: '←', status: '正常' },
{ name: '右移', key: '→', status: '正常' }
]
}
];
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { utils, consts } from 'amos-tool';
import classNames from 'classnames';
import imgStatic from './../../../consts/imgStatic';
import BizIcon from '../../common/icon/BizIcon';
const PointStatusEnum = { unplanned: '未计划', miss: '漏检', offGrade: '不合格', pass: '合格', task: '超时' };
const markerIoncMapper = imgStatic.markers;
const markerIoncColorMapper = imgStatic.color;
// 显示巡检点状态、任务
const pointIcon = imgStatic.pointIcon;
const getIcon = (markerType, level, type) => {
if (markerType === 'riskSource' || markerType === 'risk') {
return markerIoncMapper[`${markerType}_${level}`];
}
return markerIoncMapper[`${markerType}`];
};
const getBKIcon = markerType => {
return markerIoncMapper[markerType];
};
const getBKIconColor = markerType => {
return markerIoncColorMapper[markerType];
};
const disableLabel = markerType => {
return !['person'].includes(markerType);
};
class MarkerIcon extends Component {
constructor(props) {
super(props);
this.state = {
showInfo: props.showInfo,
nextShowInfo: props.showInfo,
showRiskName: false
};
}
componentWillMount = () => {
const { title, type } = this.props;
this.setState({ title, type });
};
componentWillReceiveProps = nextProps => {
const { showInfo } = nextProps;
this.setState({ showInfo, nextShowInfo: showInfo });
};
onMouseOver = () => {
this.setState({ showRiskName: true, showInfo: true });
};
// display:none;
onMouseLeave = () => {
const { title, type, nextShowInfo } = this.state;
if (type === 'risk' && (title.includes('miss') > 0 || title.includes('offGrade') > 0)) {
this.setState({ showRiskName: false });
} else if (type === 'riskSource' && this.props.showInfo) {
this.setState({ showRiskName: false });
} else {
if (nextShowInfo) {
this.setState({ showRiskName: false });
} else {
this.setState({ showInfo: false, showRiskName: false });
}
}
};
renderTitle = (title, label, showRiskName, type, showInfo, twinkle) => {
if (type === 'risk') {
// 多图标方式
// let style = { backgroundColor: '#edeff1' };
if (showInfo) {
return (
<div className="marker-icon-title">
{title && title.map(t => {
if (showRiskName) {
return (
<div key={t} className="title-child">
{/* <img src={pointIcon[t]} alt="" /> */}
<div className="title-text">{label}</div>
</div>
);
} else {
return (
<div key={t} className="title-child">
<img src={pointIcon[t]} alt="" />
<div className="title-text">{PointStatusEnum[t]}</div>
</div>
);
}
})}
</div>
);
} else {
return (
<div>
{title.map(t => {
if (t === 'miss' || t === 'offGrade') {
<div className="marker-icon-title">
<div key={t} className="title-child">
<img src={pointIcon[t]} alt="" />
<div className="title-text">{PointStatusEnum[t]}</div>
</div>
</div>;
}
})}
</div>
);
}
} else if (type === 'riskSource') {
if (showInfo) {
if (showRiskName) {
return (
<div className="marker-icon-title">
<div className="title-text">{label}</div>
</div>
);
} else {
twinkle = true;
return (
<div className="marker-icon-title">
<div className="title-text">{'风险值' + parseInt(title)}</div>
</div>
);
}
// return (
// <div className="marker-icon-title">
// {/* <div className="title-text">{title}</div> */}
// {title(t => {
// if (showRiskName) {
// return (
// <div key={t} className="title-text">{title}</div>
// );
// } else {
// return (
// <div key={t} className="title-text">{lable}</div>
// );
// }
// })}
// </div>
// );
}
} else {
if (utils.isString(title) && showInfo) {
// let style = { color: '#000000', backgroundColor: '#edeff1', background: '#edeff1' };
return (
<div className="marker-icon-title">
<div className="title-text">{title}</div>
</div>
);
}
}
};
render() {
let { markerType, title, level, twinkle, label, type, frequency } = this.props;
const { showInfo, showRiskName } = this.state;
let fireImg = '';
if (markerType === 'fireResource') {
fireImg = type;
} else {
fireImg = markerType;
}
const style = {
background: `url(${getIcon(fireImg, level)}) no-repeat`,
backgroundSize: 'contain'
};
twinkle = frequency > 0;
const cls = classNames('marker-icon', {
'marker-anim': twinkle
});
const showLabel = disableLabel(markerType);
let animDur = (twinkle ? 1 / frequency : 0) + 's';
console.log('-------------')
console.log(this.props)
if (showInfo) {
return (
<div className={cls} style={style} onMouseLeave={this.onMouseLeave} onMouseOver={this.onMouseOver}>
{this.renderTitle(title, label, showRiskName, type, showInfo, twinkle)}
{showLabel && markerType === 'riskSource' && level}
{twinkle && <div className="pulse-spread" style={{ animationDuration: animDur }} />}
</div>
);
}
return (
<div className={cls} style={style} onMouseOver={this.onMouseOver}>
{this.renderTitle(title, label, showRiskName, type, showInfo, twinkle)}
{showLabel && markerType === 'riskSource' && level}
{twinkle && <div className="pulse-spread" style={{ animationDuration: animDur }} />}
</div>
);
}
}
MarkerIcon.propTypes = {
markerType: PropTypes.string,
showInfo: PropTypes.bool,
subscribe: PropTypes.func,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
level: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
twinkle: PropTypes.bool
};
export default MarkerIcon;
import React, { Component } from 'react';
import { pointInfoAction } from 'SERVICES/3dService';
import { CONSTS } from 'CONSTS/storageConsts';
import { queryRoutePlanPointAction } from 'SERVICES/checkInfoService';
import { Modal } from 'amos-framework';
import Dialog from './../dialog';
import RiskContent from './RiskContent';
import { tirggerTransTopic } from './../dataProcessor';
import RiskContentTable from './dialogModel/RiskContentTable';
import FireChamberModal from './dialogModel/FireChamberModal';
import FireEquipmentModal from './dialogModel/FireEquipmentModal';
import HydrantModal from './dialogModel/HydrantModal';
import MonitorEquipModal from './dialogModel/MonitorEquipModal';
import RiskWarnModal from './dialogModel/RiskWarnModal';
import FireDetectorModal from './dialogModel/FireDetectorModal';
const footers = [{ key: 'details', icon: 'number-more', text: '详情' }, { key: 'danger', icon: 'danger', text: '隐患' }];
const dialogEum = {
riskSource: '风险触发预警详情',
monitorEquipment: '数据点',
hydrant: '消火栓',
pool: '消防水池',
fireEquipment: '灭火器',
fireChamber: '消防小室',
fireFoamRoom: '泡沫间',
video: '视频点',
fireDetection: '火探'
};
const bussinessEum = { impEquipment: '重点设备', fireCar: '消防车' };
class PointDialog extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
showRight: false,
rightContent: null,
markerData: {},
modal: false
};
}
onOpenClick = marker => {
const { id, type } = marker.extData || {};
if (type === 'risk') {
this.setState(
{
open: true
},
() => {
pointInfoAction(id, type).then(d => {
d.markerExtData = { dialogId: id, type };
this.setState({ markerData: d });
});
this.getTableData(id);
}
);
} else if (type in dialogEum) {
let markerData = {};
markerData.markerExtData = { dialogId: id, type };
this.setState({ markerData, modal: true });
} else if (type in bussinessEum) {
this.tirggerTransBussiness(id, type);
}
};
onDialogClose = () => {
this.setState({
open: false,
showRight: false,
rightContent: null,
markerData: {}
});
};
getTargetInfo = key => {
const { markerData = {} } = this.state;
return markerData.name;
// const info = markerData.info || [];
// return (info.find(i => i.key === key) || {}).value;
};
clickFooterItem = key => {
const { markerData } = this.state;
// 如果点击详情则和业务屏交互
const detailParams = {
...markerData.markerExtData,
detailForw: key
};
if (key === 'details') {
tirggerTransTopic(CONSTS.forward, { details: detailParams, dateTime: Date.now() });
} else if (key === 'danger') {
const name = this.getTargetInfo('name');
tirggerTransTopic(CONSTS.forward, {
name,
details: detailParams,
dateTime: Date.now()
});
} else if (key === 'record') {
tirggerTransTopic(CONSTS.forward, { details: detailParams, dateTime: Date.now() });
}
};
onCheckStatusClick = record => {
const { markerData } = this.state;
const detailParams = {
...markerData.markerExtData,
detailForw: 'record',
checkId: record.id
};
tirggerTransTopic(CONSTS.forward, { details: detailParams, dateTime: Date.now() });
};
getTargetInfo = key => {
const { markerData = {} } = this.state;
const info = markerData.info || [];
return (info.find(i => i.key === key) || {}).value;
};
getContext = markerData => {
const { type, dialogId } = markerData.markerExtData || {};
let obj = {};
switch (type) {
case 'monitorEquipment':
obj = <MonitorEquipModal type="monitorEquipment" dialogId={dialogId} />;
break;
case 'hydrant':
obj = <HydrantModal type="hydrant" dialogId={dialogId} />;
break;
case 'pool':
obj = <HydrantModal type="pool" dialogId={dialogId} />;
break;
case 'fireEquipment':
obj = <FireEquipmentModal type="extinguisher" dialogId={dialogId} />;
break;
case 'fireChamber':
obj = <FireChamberModal type="fireChamber" dialogId={dialogId} />;
break;
case 'fireFoamRoom':
obj = <FireChamberModal type="fireFoamRoom" dialogId={dialogId} />;
break;
case 'fireDetection':
obj = <FireDetectorModal type="fireDetection" dialogId={dialogId} />;
break;
case 'riskSource':
obj = <RiskWarnModal riskSourceId={dialogId} />;
break;
case 'video':
obj = <FireEquipmentModal type="video" dialogId={dialogId} />;
break;
default:
console.log('不支持的类型');
}
return obj;
};
getTableData = pointId => {
pointId &&
queryRoutePlanPointAction([{ name: 'pointID', value: pointId }]).then(data => {
this.setState({ dataList: data });
});
};
tirggerBussines = marker => {
const { id, type } = marker.extData || {};
if (type === 'riskSource') {
this.tirggerTransBussiness(id, type);
}
};
cancel = () => {
this.setState({ modal: false });
};
tirggerTransBussiness = (id, type) => {
switch (type) {
case 'impEquipment':
tirggerTransTopic(CONSTS.forward, { details: { type, detailForw: type, dialogId: id }, dateTime: Date.now() });
break;
case 'fireCar':
tirggerTransTopic(CONSTS.forward, { details: { type: 'fireResource', detailForw: type, dialogId: id }, dateTime: Date.now() });
break;
case 'riskSource':
tirggerTransTopic(CONSTS.forward, { details: { type: 'riskSource', detailForw: type, dialogId: id }, dateTime: Date.now() });
break;
}
};
clickFooterItem = key => {
const { markerData } = this.state;
// 如果点击详情则和业务屏交互
const detailParams = {
...markerData.markerExtData,
detailForw: key
};
if (key === 'details') {
tirggerTransTopic(CONSTS.forward, { details: detailParams, dateTime: Date.now() });
} else if (key === 'danger') {
const name = this.getTargetInfo('name');
tirggerTransTopic(CONSTS.forward, {
name,
details: detailParams,
dateTime: Date.now()
});
} else if (key === 'record') {
tirggerTransTopic(CONSTS.forward, { details: detailParams, dateTime: Date.now() });
}
};
render() {
const { open, showRight, rightContent, markerData, modal, dataList } = this.state;
const { type, dialogId } = markerData.markerExtData || {};
let minInfo = {
footers,
content: <RiskContent markerData={markerData} />,
table: <RiskContentTable pointId={dialogId} dataList={dataList} onCheckStatusClick={this.onCheckStatusClick} fetchData={this.getTableData} />
};
return (
<div>
{
<Dialog
visible={open}
minInfo={minInfo}
showMax={showRight}
maxContent={rightContent}
closeDialog={this.onDialogClose}
clickFooterItem={this.clickFooterItem}
/>
}
{type && (
<Modal
header={dialogEum[type]}
visible={modal}
className={type === 'riskSource' ? 'risk-warn-modal' : 'point-dialog-modal'}
destroyContent
content={this.getContext(markerData)}
noDefaultFooter
onCancel={this.cancel}
/>
)}
</div>
);
}
}
export default PointDialog;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import Value from './../common/Value';
class RiskContent extends Component {
static propTypes = {
markerData: PropTypes.object
};
static defaultProps = {
markerData: {}
};
constructor(props) {
super(props);
this.state = {};
}
render() {
const { markerData } = this.props;
// const { info = [] } = markerData || {};
return (
<Row className="point-detail-table ">
<Row className="point-detail-table-row1">
<Col className="colTitle">编号</Col>
<Col className="colValue">{markerData.no}</Col>
<Col className="colTitle">名称</Col>
<Col className="colValue">{markerData.name}</Col>
<Col className="colTitle">状态</Col>
<Col className="colValue">{markerData.realTimeStatus}</Col>
</Row>
<Row className="point-detail-table-row2">
<Col className="colTitle">责任部门</Col>
<Col className="colValue">{markerData.groupName || ''}</Col>
<Col className="colTitle">责任人</Col>
<Col className="colValue">{markerData.realName || ''}</Col>
<Col className="colTitle">联系方式</Col>
<Col className="colValue">{markerData.loginName || ''}</Col>
</Row>
</Row>
// <Row className="point-detail-table ">
// <Row className="point-detail-table-row1">
// <Col className="colTitle">编号</Col>
// <Col className="colValue">{(info.find(i => i.key === 'label') || {}).value}</Col>
// <Col className="colTitle">名称</Col>
// <Col className="colValue">{(info.find(i => i.key === 'name') || {}).value}</Col>
// <Col className="colTitle">状态</Col>
// <Col className="colValue">{(info.find(i => i.key === 'status') || {}).value}</Col>
// </Row>
// <Row className="point-detail-table-row2">
// <Col className="colTitle">责任部门</Col>
// <Col className="colValue">{(info.find(i => i.key === 'department') || {}).value}</Col>
// <Col className="colTitle">责任人</Col>
// <Col className="colValue">{(info.find(i => i.key === 'chargeUser') || {}).value}</Col>
// <Col className="colTitle">联系方式</Col>
// <Col className="colValue">{(info.find(i => i.key === 'contact') || {}).value}</Col>
// </Row>
// </Row>
);
}
}
export default RiskContent;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import { dialogDetailsAction } from '../../../../services/checkService';
class FireChamberModal extends Component {
constructor(props) {
super(props);
this.state = {
data:{}
};
}
componentDidMount(){
let { dialogId, type } = this.props;
this.queryMarkerDetail(dialogId, type);
};
queryMarkerDetail =(dialogId,type)=>{
dialogDetailsAction(dialogId,type).then(data =>{
this.setState({data});
});
}
getCountRow =(data)=>{
if(Object.keys(data).length>0 ){
return data.fireEquipmentInfo.map(item=>{
if(item.fireEquipmentCount > 0){
return <Row className="point-dialog-modal-row">
<Col className="colTitle">{item.name}</Col>
<Col className="colValue">{`${item.fireEquipmentCount}${item.unit}`}</Col>
</Row>;
}
});
}
}
render() {
const { data } = this.state;
let position = '';
if(Object.keys(data).length>0){
position = data.productionArea ? data.productionArea : position;
position = data.floor3d ? position + "-" + data.floor3d : position;
position = data.room ? position + "-" + data.room : position;
let begin = position.indexOf('-')>=0? position.indexOf('-')+1:0;
position = position.substr(begin);
}
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">安装位置:</Col>
<Col className="colValue">{data.address}</Col>
</Row>
{this.getCountRow(data)}
</Row>
);
}
}
export default FireChamberModal;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import { dialogDetailsAction } from '../../../../services/checkService';
class FireDetectorModal extends Component {
constructor(props) {
super(props);
this.state = {
data: {}
};
}
componentDidMount() {
let { dialogId, type } = this.props;
this.queryMarkerDetail(dialogId, type);
}
queryMarkerDetail = (dialogId, type) => {
dialogDetailsAction(dialogId, type).then(data => {
this.setState({ data });
});
};
render() {
const { data } = this.state;
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">喷发状态:</Col>
<Col className="colValue">{data.eruptionState}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">动作状态:</Col>
<Col className="colValue">{data.actionState}</Col>
</Row>
</Row>
);
}
}
FireDetectorModal.propTypes = {
dialogId: PropTypes.number,
type: PropTypes.string
};
export default FireDetectorModal;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { Row, Col } from 'amos-framework';
import { dialogDetailsAction } from '../../../../services/checkService';
class FireEquipmentModal extends Component {
constructor(props) {
super(props);
this.state = {
data:{}
};
}
componentDidMount(){
let { dialogId, type } = this.props;
this.queryMarkerDetail(dialogId, type);
};
queryMarkerDetail =(dialogId,type)=>{
dialogDetailsAction(dialogId,type).then(data =>{
this.setState({data});
});
}
render() {
const { data } = this.state;
let position = '';
if(Object.keys(data).length>0){
position = data.productionArea ? data.productionArea : position;
position = data.floor3d ? position + "-" + data.floor3d+'层' : position;
position = data.room ? position + "-" + data.room : position;
let begin = position.indexOf('-')>=0? position.indexOf('-')+1:0;
position = position.substr(begin);
}
if(this.props.type === 'video') {
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">安装位置:</Col>
<Col className="colValue">{position}</Col>
</Row>
</Row>
);
}else {
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">安装位置:</Col>
<Col className="colValue">{position}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">生产厂家:</Col>
<Col className="colValue">{data.brand}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">有效日期:</Col>
<Col className="colValue">{data.effectiveDate ? moment(data.effectiveDate).format('YYYY-MM-DD'):'未填写'}</Col>
</Row>
</Row>
);
}
}
}
export default FireEquipmentModal;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import { dialogDetailsAction } from '../../../../services/checkService';
class HydrantModal extends Component {
constructor(props) {
super(props);
this.state = {
data:{}
};
}
componentDidMount(){
let { dialogId, type } = this.props;
this.queryMarkerDetail(dialogId, type);
};
queryMarkerDetail =(dialogId,type)=>{
dialogDetailsAction(dialogId,type).then(data =>{
this.setState({data});
});
}
render() {
const { data } = this.state;
let position = '';
if(Object.keys(data).length>0){
position = data.productionArea ? data.productionArea : position;
position = data.floor3d ? position + "-" + data.floor3d : position;
position = data.room ? position + "-" + data.room : position;
let begin = position.indexOf('-')>=0? position.indexOf('-')+1:0;
position = position.substr(begin);
}
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">安装位置:</Col>
<Col className="colValue">{data.address}</Col>
</Row>
</Row>
);
}
}
export default HydrantModal;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import { dialogDetailsAction } from '../../../../services/checkService';
class MonitorEquipModal extends Component {
constructor(props) {
super(props);
this.state = {
data:{}
};
}
componentDidMount(){
let { dialogId, type } = this.props;
this.queryMarkerDetail(dialogId, type);
};
queryMarkerDetail =(dialogId,type)=>{
dialogDetailsAction(dialogId,type).then(data =>{
this.setState({data});
});
}
render() {
const { data } = this.state;
let position = '';
if(Object.keys(data).length>0){
position = data.productionArea ? data.productionArea : position;
position = data.floor3d ? position + "-" + data.floor3d+'层' : position;
position = data.room ? position + "-" + data.room : position;
let begin = position.indexOf('-')>=0? position.indexOf('-')+1:0;
position = position.substr(begin);
}
return (
<Row className="point-dialog-body">
<Row className="point-dialog-modal-row">
<Col className="colTitle">编号:</Col>
<Col className="colValue">{data.code}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">名称:</Col>
<Col className="colValue">{data.name}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">安装位置:</Col>
<Col className="colValue">{position}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">生产厂家:</Col>
<Col className="colValue">{data.brand}</Col>
</Row>
<Row className="point-dialog-modal-row">
<Col className="colTitle">保护对象:</Col>
<Col className="colValue">{data.protectObjNames}</Col>
</Row>
</Row>
);
}
}
export default MonitorEquipModal;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import AmosGridTable from './../../../bizview/common/tableComponent/table/AmosGridTable';
const checkListColumns = (self) => {
return [
{
title: '巡检路线',
dataIndex: 'routeName',
key: 'routeName',
width: '20%'
},
{
title: '巡检计划',
dataIndex: 'planName',
key: 'planName',
width: '20%'
},
{
title: '执行部门',
dataIndex: 'deptName',
key: 'deptName',
width: '18%'
},
{
title: '执行人',
dataIndex: 'userName',
key: 'userName',
width: '12%'
},
,
{
title: '巡检时间',
dataIndex: 'checkTime',
key: 'checkTime',
width: '20%'
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: '10%',
render: function( text, record, index) {
return <span><a href="javascript:;" onClick={function() { self.onCheckStatusClick(record)} }>{text}</a></span>;
}
}
];
};
class RiskContentTable extends Component {
constructor(props) {
super(props);
this.state = {
selectedRows: [],
selectedRowKeys: []
};
}
/**
* 获取表格刷新方法
*/
reload = r => {
this.setState(
{
reload: () => {
r();
this.setState({ selectedRows: [], selectedRowKeys: [] });
}
},
r()
);
};
onCheckStatusClick =(record)=>{
this.props.onCheckStatusClick(record);
}
render() {
const { dataList,fetchData } = this.props;
return (
<div>
<AmosGridTable
columns={checkListColumns(this)}
getTableDataAction={()=>{}}
callBack={this.reload}
isPageable = {false}
isChecked = {false}
dataList={dataList}
/>
</div>
);
}
}
export default RiskContentTable;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'amos-framework';
import AmosGridTable from './../../../bizview/common/tableComponent/table/AmosGridTable';
import { queryRiskSoureWarningAction } from '../../../../services/checkService';
const checkListColumns = (self) => {
return [
{
title: '可能诱发的风险',
dataIndex: 'riskFactor',
key: 'riskFactor',
width: '20%'
},{
title: '可能导致的事故',
dataIndex: 'accidentType',
key: 'accidentType',
width: '20%'
},{
title: '事故严重程度',
dataIndex: 'severity',
key: 'severity',
width: '18%'
},{
title: '事故发生的概率',
dataIndex: 'occurrence',
key: 'occurrence',
width: '12%'
}
];
};
class RiskWarnModal extends Component {
constructor(props) {
super(props);
this.state = {
selectedRows: [],
selectedRowKeys: []
};
}
componentDidMount(){
let { riskSourceId } = this.props;
this.queryRiskSoureWarning(parseInt(riskSourceId));
};
queryRiskSoureWarning =(riskSourceId)=>{
queryRiskSoureWarningAction(riskSourceId).then(data =>{
this.setState({dataList: data.fmeaList, riskSourceInfo: data.riskSourceInfo, inputitemContent: data.inputitemContent, alarm: data.fire_equipment});
});
}
/**
* 获取表格刷新方法
*/
reload = r => {
this.setState(
{
reload: () => {
r();
this.setState({ selectedRows: [], selectedRowKeys: [] });
}
},
r()
);
};
renderCheck =(inputitemContent)=>{
return inputitemContent.map(item =>{
return <p>
<span>{item.pointName}</span>
<span style= {{color: '#FF0000'}}>{item.inputItemName}-不合格</span>
</p>
});
}
renderEquipWaring =(alarm)=>{
return alarm.map(item =>{
return <p>
<span>{item.fireEquipmentName}</span>
<span style= {{color: '#FF0000'}}>{item.name}-不合格</span>
</p>
});
}
render() {
const { dataList =[], riskSourceInfo={}, inputitemContent=[], alarm =[]} = this.state;
const {code, level ,name } = riskSourceInfo;
return (
<div className = "risk-warn">
<div className = "risk-warn-header">
<p>
<span style= {{fontWeight: 'bold'}}>风险编号:</span>
<span>{code}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span>
<span style= {{fontWeight: 'bold'}}>风险名称:</span>
<span>{name}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span>
<span style= {{fontWeight: 'bold'}}>级别:</span>
<span>{level}</span>
</p>
</div>
<div className = "risk-warn-table">
<AmosGridTable
columns={checkListColumns(this)}
getTableDataAction={()=>{}}
callBack={this.reload}
isPageable = {false}
isChecked = {false}
dataList={dataList}
/>
</div>
<div className = "risk-warn-content">
<p>
<span>风险诱发原因:</span>
</p>
{inputitemContent.length >0 && this.renderCheck(inputitemContent)}
{alarm.length >0 && this.renderEquipWaring(alarm)}
</div>
</div>
);
}
}
export default RiskWarnModal;
import { Component } from 'react';
import PropTypes from 'prop-types';
import markerFactory from './markerFactory';
import marker3DFactory from './marker3DFactory';
class BasicPoint extends Component {
static propTypes = {
children: PropTypes.node
};
render() {
// return <div className="basic-marker-point">{this.props.children}</div>;
return this.props.children;
}
}
/**
* 风险
*/
export const RiskPoint = markerFactory(BasicPoint,
{
markerType: 'riskSource'
}
);
/**
* 巡检
*/
export const PatrolPoint = markerFactory(BasicPoint,
{
markerType: 'risk'
}
);
/**
* 人员
*/
export const PersonPoint = markerFactory(BasicPoint,
{
markerType: 'person'
}
);
/**
* 监控
*/
export const MonitorPoint = markerFactory(BasicPoint,
{
markerType: 'video'
}
);
/**
* 探测点
*/
export const ProbePoint = markerFactory(BasicPoint,
{
markerType: 'monitorEquipment'
}
);
/**
* 消防资源
*/
export const FireResourcePoint = markerFactory(BasicPoint,
{
markerType: 'fireResource'
}
);
export const EquipmentPoint = markerFactory(BasicPoint,
{
markerType: 'impEquipment'
}
);
/**
* 人员 3D
*/
export const PersonPoint3D = marker3DFactory(BasicPoint,
{
markerType: 'person'
}
);
/**
* 消防车 3D
*/
export const FireCar3D = marker3DFactory(BasicPoint,
{
markerType: 'fireCar',
markerParams: {
useModel: true,
objPath: '/threeres/marker-models/fire-car.obj',
mtlPath: '/threeres/marker-models/fire-car.mtl'
}
}
);
/**
* 工人 3D
*/
export const WorkerMen3D = marker3DFactory(BasicPoint,
{
markerType: 'workerMen',
markerParams: {
useModel: true,
objPath: '/threeres/marker-models/user/workers.obj',
mtlPath: '/threeres/marker-models/user/workers.mtl'
}
}
);
/**
* 人员 3D
*/
export const FirePoint = markerFactory(BasicPoint,
{
markerType: 'fire'
}
);
export const PointStatistics = markerFactory(BasicPoint,
{
markerType: 'statistics'
}
);
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { utils } from 'amos-tool';
import { Markers } from 'amos-3d/lib/designer';
import { CONSTS } from 'CONSTS/storageConsts';
import PointDialog from './PointDialog';
import { tirggerPlanTopic } from './../dataProcessor';
import { marker3DIoncMapper } from './../../../consts/imgStatic';
import MarkerIcon from './MarkerIcon';
const getIcon = (markerType, level) => {
return marker3DIoncMapper[`${markerType}_${level}`];
};
const buildMarkerOptions = (markers, markerType, defaultParams = {}) => {
if (!utils.isEmpty(markers)){
markers.forEach(m => {
const url = getIcon(markerType, m.level);
let position;
if (!utils.isArray(m.position)){
position = Object.values(m.position);
}
for (let k of Object.keys(defaultParams)) {
m[k] = defaultParams[k];
}
m.key = m.key || m.id;
m.url = url;
m.position = utils.isArray(m.position) ? m.position : position;
m.size = 10;
});
}
return markers;
};
export default function marker3DFactory(WrappedComponent = 'div', options){
const { markerType, markerParams } = options;
class MarkerPoints extends Component {
static propTypes = {
// marker 显隐
visible: PropTypes.bool,
markers: PropTypes.array,
planStarted: PropTypes.bool
};
constructor(props) {
super(props);
this.markerEvents = {
click: this.onMarkerClick,
mouseover: (marker) => {
marker.object2DPipe.pipeNode.visible = true;
marker.object2DPipe.pipeNode.elementVisible = true;
},
mouseout: (marker) => {
marker.object2DPipe.pipeNode.visible = false;
marker.object2DPipe.pipeNode.elementVisible = false;
}
};
this.state = {
isClick: true
};
}
componentWillMount = () => {
this.setState({ planStarted: this.props.planStarted });
}
componentWillReceiveProps = nextProps => {
this.setState({ planStarted: nextProps.planStarted });
}
onMarkerClick = (marker, e) => {
const { isClick } = this.state;
if (isClick) {
this.setState({ isClick: false }); //将isClick 变成false,将不会执行处理事件
this.pdRef && this.pdRef.onOpenClick(marker);
}
const that = this; // 为定时器中的setState绑定this
setTimeout(function() {
// 设置延迟事件,3秒后将执行
that.setState({ isClick: true }); // 将isClick设置为true
}, 3000);
tirggerPlanTopic(CONSTS.plan_detail, { type: marker.extData.type, data: marker.extData });
}
render() {
const { markers, ...rest } = this.props;
const { planStarted } = this.state;
let dialogStyle = { zIndex: 1000 };
const result = buildMarkerOptions(markers, markerType, markerParams);
return (
<WrappedComponent>
<Markers
{...rest}
markers={result}
events={this.markerEvents}
/>
{ !planStarted && <PointDialog style={dialogStyle} ref={node => this.pdRef = node} />}
</WrappedComponent>
);
}
}
return MarkerPoints;
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Markers } from 'amos-3d';
import { CONSTS } from 'CONSTS/storageConsts';
import { deepCopy } from 'amos-tool';
import PointDialog from './PointDialog';
import MarkerIcon from './MarkerIcon';
import { tirggerTransTopic, tirggerPlanTopic } from './../dataProcessor';
import FireMarkerIcon from './markers/FireMarkerIcon';
import StatisticsMarkerIcon from './markers/StatisticsMarkerIcon'
export default function markerFactory(WrappedComponent = 'div', options){
const { markerType } = options;
class MarkerPoints extends Component {
static propTypes = {
// marker 显隐
visible: PropTypes.bool,
planStarted: PropTypes.bool
};
constructor(props) {
super(props);
this.markerEvents = {
click: this.onMarkerClick,
dblclick: this.onMarkerDblClick
// mouseover: (marker) => {
// marker.redraw(this.renderMarkerHover);
// },
// mouseout: (marker) => {
// marker.redraw(this.renderMarker);
// }
};
}
componentWillMount = () => {
this.setState({ planStarted: this.props.planStarted });
}
componentDidMount() {
}
componentWillReceiveProps = nextProps => {
this.setState({ planStarted: nextProps.planStarted });
}
onMarkerClick = (marker, e) => {
clearTimeout(this.time);
tirggerPlanTopic(CONSTS.plan_detail, { type: marker.extData.type, data: marker.extData });
if (marker.extData.markerType === 'fire' && void 0 !== marker.extData.show) {
tirggerTransTopic(CONSTS.forward, { details: { type: 'impEquipment', dialogId: marker.extData.equipmentId, show: marker.extData.show }, dateTime: Date.now() });
return;
}
this.time = setTimeout(() => this.pdRef && this.pdRef.onOpenClick(marker), 500);
}
onMarkerDblClick = (marker, e) => {
clearTimeout(this.time);
tirggerPlanTopic(CONSTS.plan_detail, { type: marker.extData.type, data: marker.extData });
if (marker.extData.markerType === 'fire' && void 0 !== marker.extData.show) {
tirggerTransTopic(CONSTS.forward, { details: { type: 'impEquipment', dialogId: marker.extData.equipmentId, show: marker.extData.show }, dateTime: Date.now() });
return;
}
this.pdRef.tirggerBussines(marker);
}
renderMarkerHover = (extData) => {
return <MarkerIcon {...extData} markerType={markerType} />;
}
renderMarker = (extData) => {
// console.log('hhhhhhh1')
if (markerType === 'fire') {
return <FireMarkerIcon {...extData} markerType={markerType} />;
} else if (markerType === 'statistics') {
return <StatisticsMarkerIcon statistics={extData} />;
} else {
return <MarkerIcon {...extData} markerType={markerType} />;
}
}
render() {
const { planStarted } = this.state;
const dialogStyle = { zIndex: 1000 };
const { markers } = this.props;
return (
<WrappedComponent>
<Markers
{...this.props}
markers = {deepCopy(markers)}
events={this.markerEvents}
render={this.renderMarker}
/>
{!planStarted && <PointDialog style={dialogStyle} ref={node => this.pdRef = node} />}
</WrappedComponent>
);
}
}
return MarkerPoints;
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import imgStatic from './../../../../consts/imgStatic';
import { baseURI } from './../../../../consts/urlConsts';
const markerIoncMapper = imgStatic.markers;
const getIcon = (markerType) => {
return markerIoncMapper[`${markerType}`];
};
class FireMarkerIcon extends Component {
constructor(props) {
super(props);
this.state = {
showInfo: props.showInfo
};
}
componentWillMount = () => {
const { showInfo, title, show, url } = this.props;
this.setState({ showInfo, title, show, url });
};
componentWillReceiveProps = nextProps => {
const { showInfo, title, show, url } = nextProps;
this.setState({ showInfo, title, show, url });
};
renderTitle = (title, show, url) => {
return (
void 0 === show ? <div className="marker-icon-title"><div className="title-text">{title}</div> </div> : <div className="maker-top-img-div"><img src={baseURI + url} alt="" className='maker-top-img' /> <p>{title}</p></div>
);
};
render() {
const { markerType, twinkle } = this.props;
const { showInfo, title, show, url } = this.state;
const style = {
background: `url(${getIcon(markerType)}) no-repeat`,
backgroundSize: 'contain'
};
const cls = classNames('marker-icon', {
'marker-anim': twinkle
});
return (
<div className={cls} style={style} >
{showInfo && this.renderTitle(title, show, url)}
{twinkle && <div className="pulse-spread" />}
</div>
);
}
}
FireMarkerIcon.propTypes = {
markerType: PropTypes.string,
show: PropTypes.string,
url: PropTypes.string,
showInfo: PropTypes.bool,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
twinkle: PropTypes.bool
};
export default FireMarkerIcon;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { utils, consts } from 'amos-tool';
import classNames from 'classnames';
import imgStatic from './../../../../consts/imgStatic';
import { baseURI } from './../../../../consts/urlConsts';
const markerIoncMapper = imgStatic.pointAggregation;
const getIcon = (level) => {
return markerIoncMapper[`level_${level}`];
};
class StatisticsMarkerIcon extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount = () => {
};
componentWillReceiveProps = nextProps => {
};
renderTitle = statistics => {
const style = {
background: `url(${getIcon(statistics.level)}) no-repeat`,
backgroundSize: 'contain'
};
let str = 50 - statistics.statisticsData.length * 10;
const contentstyle = {
paddingTop: str + '%'
};
if (statistics.statisticsData.length <= 1) {
return (
<div className="marker-icon-title" style={style}>
<div className="title-content" style={contentstyle}>
{statistics.statisticsData.map(t => {
return (
<div key={t} className="title-child">
<div className="title-text">{t.count}</div>
</div>);
})}
</div>
</div>
);
}
return (
<div className="marker-icon-title" style={style}>
<div className="title-content" style={contentstyle}>
{statistics.statisticsData.map(t => {
return (
<div key={t} className="title-child">
<span>{t.name}:</span>
<div className="title-text">{t.count}</div>
</div>);
})}
</div>
</div>
);
};
render() {
const { statistics } = this.props;
const style = {
// background: `url(${getIcon(markerType, level)}) no-repeat`,
backgroundSize: 'contain'
};
const cls = classNames('marker-statistics-icon', {
// 'marker-anim': twinkle
});
return (
<div className={cls} style={style}>
<div className="icon-title" >{statistics.name}</div>
{this.renderTitle(statistics)}
<div className="marker-icon-line" />
</div>
);
}
}
StatisticsMarkerIcon.propTypes = {
statistics: PropTypes.object
};
export default StatisticsMarkerIcon;
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
import imgStatic from 'CONSTS/imgStatic';
class Monitor extends Component {
render() {
return (
<div className="point-details-monitor">
<div className="points-details-empty">
<img src={imgStatic.datapane.smilingFace} alt="" />
<p>暂未连通到监控视频</p>
</div>
</div>
);
}
}
Monitor.propTypes = {
};
export default Monitor;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { XJBaseURI } from 'CONSTS/urlConsts';
import imgStatic from 'CONSTS/imgStatic';
import Carousel from './../../common/Carousel';
const transitionTime = 500;
class Picture extends Component {
static propTypes = {
markerData: PropTypes.object
};
static defaultProps = {
markerData: {}
};
constructor(props) {
super(props);
this.state = {
carouselVisable: false
};
}
componentDidMount() {
//Carousel组件中会计算容器宽度,然而此容器是通过css3过渡属性将宽度在0.5秒内慢慢放大,故目前等待0.5秒进行展示
this.timer = setTimeout(() => {
this.setState({ carouselVisable: true });
}, transitionTime);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
const { markerData } = this.props;
let { photosUrl = [] } = markerData || {};
let imgs = photosUrl.map(e => e.indexOf('\\') === 0 ? `${XJBaseURI}${e.substr(1,e.length - 1)}` : `${XJBaseURI}${e}`);
return (
<div className="point-details-picture">
{ imgs.length > 0 && this.state.carouselVisable && <Carousel files={imgs} />}
{ imgs.length === 0 &&
<div className="points-details-empty">
<img src={imgStatic.datapane.smilingFace} alt="" />
<p>暂无图片</p>
</div>
}
</div>
);
}
}
export default Picture;
import React from 'react';
import Monitor from './Monitor';
import Picture from './Picture';
const mapper = {
monitor: Monitor,
picture: Picture
};
const Unkown = () => <div>暂未定义</div>;
export default function getMaxContent(key){
const MC = mapper[key] || Unkown;
return MC;
}
/* eslint-disable no-magic-numbers */
import { DISABLE_SKYLIGHT, ENABLE_SKYLIGHT, DEFAULT_LIGHT_CONFIG } from 'base-r3d/lib/consts/effectConsts';
import { parseModelConfig } from 'base-r3d/lib/utils/helper';
import { utils, deepCopy, UUID } from 'amos-tool';
import { downloadBasicScene } from './../../services/moduleEditServices';
export const disableSkyLightConfig = deepCopy(DISABLE_SKYLIGHT);
export const skyLightConfig = deepCopy(ENABLE_SKYLIGHT);
export const defaultLightConfig = deepCopy(DEFAULT_LIGHT_CONFIG);
/**
* 解析基础场景
*/
export const parseBaseModel = (baseModel = {}) => {
const { modelURI, objParam } = baseModel;
if (!objParam && modelURI) {
return downloadBasicScene(modelURI).then(data => {
let models = data.models;
const indoors = data.indoors;
const asyncModels = data.asyncModels;
// 该数据值,直接配置在基础场景的 index.json 中 { position: [x, y, z], target: [x, y, z] }
const cameraEffects = data.cameraEffects;
let basePath = modelURI.replace('index.json', '');
!basePath.endsWith('/') && (basePath = basePath.concat('/'));
if (!utils.isEmpty(models)){
if (!utils.isArray(models)) {
if (utils.isObject(models)) {
models = [models];
} else if (utils.isString(models)) {
models = [{
objName: models
}];
}
}
}
const objs = parseModelConfig({
basePath,
models,
indoors
});
// 处理 asyncModels
if (!utils.isEmpty(asyncModels)){
const _asyncModels = asyncModels.map(m => ({
basePath,
...m
}));
return {
asyncModels: _asyncModels,
objs,
cameraEffects
};
}
return {
objs,
cameraEffects
};
});
}
return new Promise(resolve => {
resolve({
cameraEffects: null,
objs: objParam
});
});
};
/**
* 将对象的指定属性转为 string
* @param {Object} obj
* @param {Array<String>} keys
*/
export const stringfyProperty = (obj, keys = []) => {
const copyObj = deepCopy(obj);
keys.forEach(k => {
copyObj[k] && (copyObj[k] = JSON.stringify(copyObj[k]));
});
return copyObj;
};
/**
* 填充 sketch 属性
* @param {Object} widget
*/
export const fillSketch = (widget) => {
const param = deepCopy(widget);
param.modeyKey = param.key;
param.eid = UUID.uuid();
param.basicAttr = {
name: param.name,
visible: true
};
return param;
};
export const defaultOptions = {
light: [],
floorBoard: {
visible: true,
position: { y: -5 },
showType: 'both',
size: 1000,
divisions: 20,
colorCenterLine: 0x444444,
colorGrid: 0x888888,
gridOptions: {
opacity: 0.2,
transparent: true
},
widthSegments: 1,
heightSegments: 1,
boardColor: 0xffffff,
boardOptions: {}
}
};
const defaultBasicScene = {
sceneOptions: {
background: '#253366'
},
cameraOptions: {
fov: 45,
near: 1,
far: 5000,
builtInOrbit: {
maxPolarAngle: Math.PI * 0.5,
minDistance: 1,
maxDistance: 5000,
shortcutKey: {
alt: true,
keyMapping: {
'49': 'enabled',
'50': 'enableDamping',
'51': 'enableZoom',
'52': 'enableRotate',
'53': 'enablePan',
'54': 'screenSpacePanning',
'55': 'autoRotate',
'56': 'enableKeys'
}
}
}
},
options: deepCopy(defaultOptions),
// 内置灯光
lightProps: {
showHelper: false, // show light helper
ambientLight: {
visible: true,
intensity: 0.45,
color: 0xffffff
},
hemisphereLight: {
visible: false,
intensity: 0.0,
color: 0xffffff,
groundColor: 0x222222
},
mainLight: {
visible: true,
// If enable shadow of main light.
shadow: false,
// Quality of main light shadow. 'low'|'medium'|'high'|'ultra'
shadowQuality: 'high',
// Intensity of main light
intensity: 0.5,
// Color of main light
color: 0xffffff,
// Alpha is rotation from bottom to up.
alpha: 30,
// Beta is rotation from left to right.
beta: 30
},
secondLight: {
visible: false,
shadow: false,
shadowQuality: 'high',
intensity: 0,
color: 0xffffff,
alpha: 138,
beta: 0
}
}
};
/**
* 解析数据,将string值转化为 object,如果值为空,则填充默认值
* @param {*} target
* @param {*} key
* @param {*} defaults
*/
const parseProterty = (target, key, defaults) => {
if (utils.isNull(target[key]) || utils.isUndefined(target[key])){
target[key] = defaults;
} else {
if (utils.isString(target[key])){
target[key] = JSON.parse(target[key]);
}
}
};
/**
* 创建默认的 desinger 数据
* @param {*} data
*/
export const designerFactory = data => {
// content animations basicScene baseModel
if (!data) {
return {
content: [],
animations: [],
basicScene: deepCopy(defaultBasicScene),
baseModel: {},
routePath: {},
particles: {}
};
} else {
parseProterty(data, 'content', []);
parseProterty(data, 'animations', []);
parseProterty(data, 'basicScene', deepCopy(defaultBasicScene));
parseProterty(data, 'baseModel', {});
parseProterty(data, 'routePath', {});
parseProterty(data, 'particles', {});
}
return data;
};
class GlobalTrigger {
constructor(){
// 设计器页面是否已经保存
this.un_save_design = false;
this.documentTitle = document.title;
}
/** 已经保存 */
isSave(){
return !this.un_save_design;
}
/**
* 切换场景是否需要保存
* @param {Boolean} flag true 代表未保存
* @memberof GlobalTrigger
*/
toggleSave(flag){
if (flag){
document.title = `*${this.documentTitle}`;
} else {
document.title = this.documentTitle;
}
this.un_save_design = flag;
}
}
const trigger = new GlobalTrigger();
export default trigger;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { PubSub } from 'ray-eventpool';
import { message } from 'amos-framework';
import globalTrigger from './globalTrigger';
import { EVENTS_CONSTS, OPERATE_TYPE } from './../../consts/EventConsts';
import { parseBaseModel, stringfyProperty, designerFactory } from './_dataParser';
import { saveAreaDataAction } from './../../services/moduleEditServices'
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}
const designerPropTypes = {
subjectId: PropTypes.string,
onInit: PropTypes.func,
onError: PropTypes.func
};
/**
* 测试是否为 elements 元素,即:需要填充到 content 节点的所有模型店
* 目前暂定为 model 、shape、pen、particle即:模型元素、内置形状、路线、粒子
* @param {*} key
*/
const isContentEles = (key) => ['model', 'shape','pen','particle'].includes(key);
/**
* designer 核心,仅处理数据
* @param {*} [options={}]
* @returns {Function} HOC Function
*/
export default function withDesigner(options = {}) {
const { initAction, saveAction, newEmptyScene } = options;
return WrappedComponent =>
class EnhanceDesigner extends Component {
static displayName = `withDesigner(${getDisplayName(WrappedComponent)})`;
static propTypes = designerPropTypes;
constructor(props){
super(props);
this.state = {
dataSource: {},
// 基础模型,采用主线程进行加载
baseObjs: null,
// 采用子线程加载的模型
asyncModels: null
};
this.topics = {};
}
componentDidMount() {
const { subjectId } = this.props;
this.syncLoad(subjectId);
this.initPubSubEvents();
}
componentWillUnmount() {
this.unsubscribe();
}
/** 初始化监听事件 */
initPubSubEvents = () => {
// sketch data config
this.subscribe(EVENTS_CONSTS.DATA_CONFIG_CAHNGE, (topic, data) => {
this.updateSketchDataConfig(data);
});
// sketch setting
this.subscribe(EVENTS_CONSTS.SKETCH_PARAMS_CHANGE, (topic, data) => {
this.updateSketchOptions(data);
});
// base model setting
this.subscribe(EVENTS_CONSTS.SCENE_BASE_MODEL_CHANGE, (topic, data) => {
this.updateBaseModel(data);
});
// scene setting
this.subscribe(EVENTS_CONSTS.SCENE_PARAMS_CHANGE, (topic, data) => {
if (data && data.key === 'baseModel'){
this.updateBaseModel(data.value);
} else {
this.updateSceneOptions(data);
}
});
// animation setting
this.subscribe(EVENTS_CONSTS.ANIMATION_CAHNGE, (topic, data) => {
this.updateAnimationOptions(data);
});
// update routePath/particle reference
this.subscribe(EVENTS_CONSTS.SKETCH_REFERENCE_CHANGE, (topic, data) => {
this.updateReferenceOptions(data);
});
}
/** 保存场景 */
save = () => {
const { dataSource } = this.state;
let {routePath = {}} = dataSource;
// const data = stringfyProperty(dataSource, ['content', 'animations', 'basicScene', 'baseModel', 'routePath', 'particles']);
console.log(routePath)
let routePathParams = []
for (let key in routePath) {
routePathParams.push({
riskSourceId: routePath[key].areaKey,
position3d: JSON.stringify(routePath[key].points)
})
}
saveAreaDataAction(routePathParams).then(d => {
// 补全持久化 id
if (d && d.id && !dataSource.id){
dataSource.id = d.id;
this.setState({
dataSource
});
}
globalTrigger.toggleSave(false);
message.success('保存成功!');
}, eer => {
message.error('保存失败!');
});
}
syncLoad = () => {
const { subjectId, onInit, onError } = this.props;
// initAction(subjectId).then(data => {
// const isFirstCreate = !data || !data.basicScene;
// const dataSource = designerFactory(data);
// // 初次创建
// if (!dataSource.subjectId){
// dataSource.subjectId = subjectId;
// }
// this.setState({
// dataSource
// }, () => {
// // 初始创建时,需要持久化新场景
// if (isFirstCreate || !dataSource.subjectId){
// this.save();
// }
// });
// onInit && onInit({routePath:"[[157.5537590812242,10.229799842834472,65.56017266718561],[157.5537590812242,10.229799842834472,65.56017266718561],[232.26412933735003,10.530964560454185,73.04719951903942],[232.26412933735003,10.530964560454185,73.04719951903942],[226.42703425632436,10.32996489037132,39.05010583777198],[226.42703425632436,10.32996489037132,39.05010583777198],[160.41365272637904,10.32978034263292,31.703457440929526],[160.41365272637904,10.32978034263292,31.703457440929526],[157.59505131213876,10.3297339539723,64.59124674036931]]"});
// this.triggerScene(dataSource);
// // 获取基础模型
// parseBaseModel(dataSource.baseModel).then(bm => {
// const { objs, cameraEffects, asyncModels } = bm || {};
// // 更新 cameraEffects
// this._syncCameraEffects(cameraEffects);
// this.setState({
// baseObjs: objs,
// asyncModels
// });
// });
// }, err => {
// onError && onError(err);
// });
}
/**
* 同步更新 basicScene.options.cameraEffects
* 仅在初始加载(更换)基础场景时,进行设置
*/
_syncCameraEffects(cameraEffects) {
const { dataSource } = this.state;
if (cameraEffects && (cameraEffects.position || cameraEffects.target)){
const ce = (dataSource.basicScene.options || {}).cameraEffects;
if (!ce){
// 直接赋值
dataSource.basicScene.options.cameraEffects = cameraEffects;
// 通知 A3D 执行 camera effects 操作
this.trigger(EVENTS_CONSTS.A3D_CAMERA_EFFECTS, cameraEffects);
}
}
}
/**
* 更新数据绑定信息
*/
updateSketchDataConfig = ({ sketchId, dataConfig }) => {
const { dataSource } = this.state;
// 更新具体数据
const newContent = (dataSource.content || []).map(sketch => {
if (sketch.eid === sketchId) {
sketch.dataConfig = dataConfig;
}
return sketch;
});
dataSource.content = newContent;
this.updateDataSource(dataSource);
}
/**
* 更新控件配置信息
* {控件的显示配置信息}
*/
updateSketchOptions = ({ sketchId, sketchOptions = {} }) => {
const { dataSource } = this.state;
const { key, value } = sketchOptions;
if (key){
// 更新 basicAttr 具体数据
const newContent = (dataSource.content || []).map(sketch => {
if (sketch.eid === sketchId) {
sketch[key] = value;
}
return sketch;
});
dataSource.content = newContent;
this.updateDataSource(dataSource);
}
}
/**
* 更新基础模型配置
*/
updateBaseModel = (baseModel) => {
const { dataSource } = this.state;
// 更新具体数据
dataSource.baseModel = baseModel;
this.updateDataSource(dataSource);
// 更新基础模型
parseBaseModel(baseModel).then(bm => {
const { objs, cameraEffects, asyncModels } = bm || {};
this._syncCameraEffects(cameraEffects);
this.setState({
baseObjs: objs,
asyncModels
});
});
}
/**
* 更新画布配置信息
* {画布的显示配置信息}
* key: sceneOptions、cameraOptions、options、lightProps
*/
updateSceneOptions = ({ key, value }) => {
const { dataSource } = this.state;
// 更新具体数据
dataSource.basicScene[key] = value;
this.updateDataSource(dataSource);
}
/**
* 更新动画配置
* @param {String} type 操作类型
* @param {Object} value 待操作数据 (完整动画配置信息)
*/
updateAnimationOptions = ({ type, value }) => {
const { dataSource } = this.state;
if (!dataSource.animations){
dataSource.animations = [];
}
switch (type) {
case OPERATE_TYPE.ADD:
dataSource.animations.push(value);
break;
case OPERATE_TYPE.UPDATE: // 动画更新
dataSource.animations = dataSource.animations.map(anim => {
if (anim.animateKey === value.animateKey){
return value;
}
return anim;
});
break;
case OPERATE_TYPE.DEL: // 删除动画
dataSource.animations = dataSource.animations.filter(anim => anim.animateKey !== value.animateKey);
break;
default:
break;
}
this.updateDataSource(dataSource);
}
/**
* 更新 映射数据,如 routePath、particles
* @param {Object} options
* @param {String} options.type 类型,可选值为 routePath、particles
* @param {String | Number} options.key reference key,用于映射物体的自身属性
* @param {String | Number} options.eid 元素的eid
* @param {Object} options.value 自身属性数据
* @param {Object} options.position 位置数据
* @param {Boolean} options.noContent 是否添加进content
*/
updateReferenceOptions = (options = {}) => {
const { type, key, eid, value, position, noContent } = options;
const { dataSource } = this.state;
if (!dataSource[type]){
dataSource[type] = {};
}
dataSource[type][key] = value;
// 同步处理 content 数据
if (!noContent){
// 更新 basicAttr 具体数据
const newContent = (dataSource.content || []).map(sketch => {
if (sketch.eid === eid) {
sketch.reference = key;
if (!sketch.basicAttr) {
sketch.basicAttr = {};
}
sketch.basicAttr.position = position;
}
return sketch;
});
dataSource.content = newContent;
}
this.updateDataSource(dataSource);
}
updateDataSource = (data) => {
globalTrigger.toggleSave(true);
this.setState({
dataSource: data
});
}
/**
* 添加配置项
* @param {Object} widget
*/
addNewSketch = (widget) => {
if (isContentEles(widget.type)){
const { dataSource } = this.state;
if (!dataSource.content){
dataSource.content = [];
}
dataSource.content.push(widget);
this.updateDataSource(dataSource);
}
}
/** 多个scene时,触发当前聚焦的scene */
triggerScene = (data) => {
this.trigger(EVENTS_CONSTS.SCENE_ACTIVE_CHANGE, data);
// 清空选中内容
this.trigger(EVENTS_CONSTS.SKETCH_ACTIVE_CHANGE, {}); // 清空当前选中的sketch
}
trigger = (topic, data) => {
PubSub.publish(topic, data);
}
subscribe = (topic, callback) => {
this.topics[topic] = PubSub.subscribe(topic, callback);
}
unsubscribe() {
const ts = this.topics;
(Object.values(ts) || []).forEach(v => PubSub.unsubscribe(v));
}
addExtraProps = () => {
return {
...this.props,
...this.state,
subscribe: this.subscribe,
trigger: this.trigger,
save: this.save,
addSketch: this.addNewSketch
};
};
render(){
const props = this.addExtraProps();
return (
<WrappedComponent
{...props}
/>
);
}
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment