Commit dc32c2c9 authored by 单奇雲's avatar 单奇雲

预案演练

parent 8300e844
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="52" width="40" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 52.000001">
<g stroke-linejoin="round" transform="translate(0 -1000.4)" stroke="#fff" stroke-linecap="round" fill="none">
<path d="m20 1051.9v-12"/>
<path style="color:#000000" d="m20 1000.9 19.5 19.5-19.5 19.5-19.5-19.5z"/>
</g>
</svg>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 0 12 12" width="12" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<g transform="translate(0 -1040.4)">
<path style="color:#000000" transform="translate(0 1040.4)" fill="#fff" d="m6 0.0019531c-2.1986 0-4.1328 1.2132-5.1777 2.998h-0.8223v6h0.82031c1.0446 1.785 2.9803 3 5.1797 3s4.135-1.215 5.18-3h0.82v-6h-0.822c-1.045-1.7848-2.9794-2.998-5.178-2.998zm0 4c1.1283 0 2 0.8717 2 2 0 1.1282-0.8717 1.998-2 1.998s-2-0.8698-2-1.998c0-1.1283 0.8717-2 2-2z"/>
</g>
</svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1585209132602" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7105" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M10.53940227 513.08802072c0 277.51113799 224.97261203 502.48276716 502.48276716 502.48276717s502.48276716-224.97261203 502.48276715-502.48276717c0-277.51113799-224.97261203-502.48276716-502.48276715-502.48276715-277.51113799 0-502.48276716 224.97261203-502.48276716 502.48276715z" fill="#66FF00" p-id="7106"></path></svg>
\ No newline at end of file
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="18" width="18" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 18 18">
<g transform="translate(0 -1034.4)">
<circle cx="9" cy="1043.4" r="9" fill="#fff"/>
</g>
</svg>
...@@ -11,6 +11,8 @@ import TextPlan from './../view/planMgmt/view/TextPlan'; ...@@ -11,6 +11,8 @@ import TextPlan from './../view/planMgmt/view/TextPlan';
import PlanDrill from './../view/planMgmt/view/PlanDrill'; import PlanDrill from './../view/planMgmt/view/PlanDrill';
import LeaderStruct from './../view/planMgmt/view/leaderStruct'; import LeaderStruct from './../view/planMgmt/view/leaderStruct';
import PubView from './../view/planMgmt/view/pubview';
/** /**
* 系统自定义路由 * 系统自定义路由
...@@ -24,7 +26,8 @@ export const customRoutes = [ ...@@ -24,7 +26,8 @@ export const customRoutes = [
{ path: 'checkdetail', parent: 'patrolpoint', component: CheckDetail }, { path: 'checkdetail', parent: 'patrolpoint', component: CheckDetail },
{ path: 'differentiateDetail', parent: 'biz', component: DifferentiateDetail }, { path: 'differentiateDetail', parent: 'biz', component: DifferentiateDetail },
{ path: 'leaderStruct', parent: 'biz', component: LeaderStruct }, { path: 'leaderStruct', parent: 'biz', component: LeaderStruct },
{ path: 'pubview', parent: 'planDrill', component: PlanDrill }, // { path: 'pubview', parent: 'planDrill', component: PlanDrill },
{ path: 'pubview', parent: 'planDrill', component: PubView },
{ path: 'textview', parent: 'planDrill', component: TextPlan }, { path: 'textview', parent: 'planDrill', component: TextPlan },
...parseCusotmRoutes() ...parseCusotmRoutes()
]; ];
......
...@@ -3,3 +3,5 @@ ...@@ -3,3 +3,5 @@
@import './leaderStruct.scss'; @import './leaderStruct.scss';
@import './text.scss'; @import './text.scss';
@import './taskTopo.scss'; @import './taskTopo.scss';
@import './pubview.scss';
@import './play.scss';
\ No newline at end of file
$bar-black: black;
$bar-bg-black: rgba($bar-black, 0.8);
$play-control-bg: rgba(0,0,0,0.8);
@mixin make-img($svgUrl) {
display: inline-block;
cursor: pointer;
background-image: url($svgUrl);
background-repeat: no-repeat;
background-size: 100% 100%;
}
.pubview-play{
position: absolute;
left: 0px;
bottom: 0px;
width: 100%;
height: 32px;
.player-control {
position: initial;
float: left;
width: 7%;
height: 100%;
padding: 0px 8px;
background-color: $play-control-bg;
border-radius: 0;
.media-control {
position: initial;
width: 100%;
height: 100%;
margin: 0px;
padding: 6px;
.play-prev {
@include make-img('../../assets/planMgmt/play/prev.png');
margin: 0px 1px;
width: 20px;
height: 20px;
}
.play {
@include make-img('../../assets/planMgmt/play/play_animation.png');
margin: 0px 1px;
width: 20px;
height: 20px;
}
.play-next {
@include make-img('../../assets/planMgmt/play/next.png');
margin: 0px 1px;
width: 20px;
height: 20px;
}
.play-stop {
@include make-img('../../assets/planMgmt/play/stop_animation.png');
margin: 0px 1px;
width: 20px;
height: 20px;
}
}
}
.pubview-play-progress {
position: initial;
float: left;
width: 77%;
display: block;
height: 100%;
padding-right: 20px;
padding-left: 6px;
margin-right: 0px;
margin-left: 0px;
background-color: $bar-bg-black;
opacity: 1;
.middle-play-content {
position: relative;
width: 100%;
margin: 0px;
.play-item {
margin: 8px 0px;
height: 18px;
background-color: rgba(0,0,0,0.93);
&:first-child > .play-item-dot {
left: 0;
width: 50%;
}
.play-item-dot{
height: 100%;
}
.play-item-progress{
width: calc(100% + 11px);
margin-top: 2.5px;
height: 65%;
background-color: rgba(0, 204, 0, 0.7);
&:first-child {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
&:last-child {
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
}
}
.play-item::after {
display: none;
}
}
}
.play-item {
position: absolute;
width: 12px;
height: 12px;
padding-right: 11px;
margin-top: -3px;
cursor: pointer;
background-image: url('./../../assets/planMgmt/play/play_circle.png');
background-size: 12px 12px;
background-repeat: no-repeat;
box-sizing: border-box;
background-position-y: 3px;
&::after {
display: block;
width: 100%;
height: 6px;
margin-top: 3px;
margin-left: 12px;
background-color: white;
content: '';
}
.play-item-dot {
position: absolute;
top: -50%;
left: -50%;
width: 100%;
height: 200%;
}
.play-item-qipao {
position: absolute;
top: 0;
left: 0;
display: none;
width: auto;
white-space: nowrap;
margin-top: -33px;
min-width: 10em;
margin-left: -50px;
padding: 3px 15px 9px 15px;
font-size: 13px;
color: white;
text-align: left;
background: url('./../../assets/planMgmt/play/play_qipao.png') no-repeat center center/100% 100%;;
}
&.active-item {
width: 18px;
height: 18px;
margin-top: -6px;
margin-left: -3px;
background-image: url('./../../assets/planMgmt/play/play_fill_circle.svg');
background-repeat: no-repeat;
background-position-y: 0px;
&::after {
margin-top: 6px;
margin-left: 16px;
}
}
&:hover {
.play-item-qipao {
display: block;
}
}
&:last-child {
&.active-item {
padding-right: 18px;
}
.play-item-dot {
left: 0;
width: 12px;
}
}
}
.play-menu{
width: 16%;
float: left;
background-color: rgba(0,0,0,0.8);
.play-menu-select{
padding: 0px 5px;
margin: 5px 10px;
border-radius: 11px;
color: rgba(102, 255, 0, 1);
background-color: rgba(0,0,0,0.9);
border: none;
float: right;
.amos-select-dropdown-icon {
margin-top: -9px;
}
}
.play-menu-button-group{
height: 100%;
margin-right: 14px;
float: right;
.amos-btn {
background-color: transparent;
border: 0px;
padding: 6px;
margin: 0px;
}
.amos-btn-active {
background-color: rgba(0,0,0,0.9);
}
.button-icon{
width: 16px;
height: 16px;
}
}
}
}
.tip-control-panel {
position: absolute !important;
bottom: 50px !important;
width: 206px;
height: 245px;
font-size: 12px;
padding: 0px;
background: transparent;
box-shadow: 0 2px 6px #000000;
border-radius: 0px;
.control-panel-content {
height: calc(100% - 29px);
&-header {
padding: 7px;
text-align: center;
height: 29px;
font-size:13px;
font-family:Microsoft YaHei;
font-weight:400;
color: white;
background-color:rgba(0,0,0,0.9);
i {
color: red;
font-size: 13px;
position: absolute;
right: 12px;
}
}
&-body {
height: 100%;
padding: 20px 20px;
background-color:rgba(0,0,0,0.6);
.tip-step-item {
height: 20px;
line-height: 20px;
&-icon {
width: 100px;
height: 20px;
vertical-align: middle;
}
&-name {
display: inline-block;
vertical-align: middle;
}
}
.control-panel-content-item{
width: 50%;
float: left;
color: white;
margin-bottom: 10px;
padding-left: 12px;
.tulie-img{
width: 24px;
height: 24px;
}
span {
top: -7px;
padding: 5px;
position: relative;
}
}
}
}
}
.task-open{
right: 250px !important;
}
.task-close{
right: 20px !important;
}
.zimu-control-panel{
width: 60%;
left: 20%;
height: 8%;
text-align: center;
font-size: 30px;
font-family: Microsoft YaHei;
font-weight: bold;
line-height: 40px;
color: rgba(255,255,255,1);
text-shadow: 0px 2px 5px rgb(0, 0, 0);
}
\ No newline at end of file
.publish-view,
.board-actuator,
.three-renderer,
.three-container {
width: 100%;
height: 100%;
}
.publish-view {
position: relative;
overflow: hidden;
}
.three-ui-infowindow {
position: absolute;
// top: 48%;
// left: 50%;
// display: inline-block;
width: auto;
height: auto;
padding: 5px 10px;
// white-space: nowrap;
background: url('../../assets/planMgmt/qipao.png') no-repeat center center/100% 100%;
// background-size: 100% 100%;
// transform: translate(-50%, -50%);
}
.three-ui-anchor{
padding: 3px 9px 7px 9px;
margin: 0;
left: 50%;
font-size: 14px;
line-height: 24px;
color: black;
background: url('../../assets/planMgmt/qipao.png') no-repeat center center/100% 100%;
}
.center{
}
// .leftTop{
// background: url('../../assets/planMgmt/leftTop.png') no-repeat center center/100% 100% !important;
// }
// .rightTop{
// background: url('../../assets/planMgmt/rightTop.png') no-repeat center center/100% 100% !important;
// }
.board-actuator-tasktab{
position: absolute;
height: calc(100% - 72px);
width: 230px;
right: 0;
top: 40px;
color: white;
.amos-tabs{
height: 100%;
font-size: 10px;
.amos-tabs-list{
padding: 36px 0px;
width: 36px;
height: 100%;
background:rgba(0,0,0,0.8);
border:none;
.amos-tabs-tabitem-inner{
padding: 0px;
.board-tabs-img{
width: 36px;
height: 36px;
}
}
}
.amos-tabs-panel{
padding: 0px;
height: 100%;
border: none;
.board-tasktab-all{
color: white;
background:rgba(0,0,0,0.5);
height: 100%;
border:none;
.amos-collapse-item{
border:none;
.amos-collapse-header{
background:rgba(0,0,0,0.5);
color: white;
height: 36px;
padding: 8px 14px;
.amos-collapse-header-title{
font-size: 13px;
}
}
.amos-collapse-header.amos-collapse-header-arrow-left .amos-collapse-header-arrow > i {
left: calc(100% - 40px)
}
.amos-collapse-content{
background:rgba(0,0,0,0);
color: white;
padding: 0px;
.amos-collapse-content-box{
.board-tasktab-part{
background:rgba(0,0,0,0);
height: 100%;
border:none;
.amos-collapse-header{
background:rgba(0,0,0,0);
color: white;
.amos-collapse-header-title{
font-size: 13px;
}
}
.amos-collapse-content{
background:rgba(0,0,0,0);
color: white;
padding: 0px 20px;
.board-tasktab-timeLine{
.amos-timeline-item{
font-size: 10px;
.amos-timeline-item-head{
color:white;
border: none;
}
.amos-timeline-item-tail{
border-left: 1px dotted #e8e8e8;
}
}
.amos-timeline-item-last .amos-timeline-item-tail {
display: block;
border-left: 1px dotted #e8e8e8;
}
}
}
}
}
}
.amos-collapse-content::before, .amos-collapse-content::after {
display: none;
}
.amos-collapse-active .amos-collapse-header .amos-collapse-header-arrow > i[class*='icon'] {
transform: scale(0.75) rotate(0);
}
}
}
}
}
}
.board-actuator-modal-row{
display: flex;
background: $model-body-color-3d;
.colTitle {
float: left;
font-weight: bold;
padding-top: 7px;
height: 40px;
padding-left: 8px;
border-left: 1px solid $core-border-color;
box-sizing: border-box;
flex: 1;
}
.colValue {
float: left;
padding-top: 7px;
height: 40px;
padding-left: 8px;
flex: 1;
border-left: 1px solid $core-border-color;
}
}
\ No newline at end of file
.websudio-vizlib { .websudio-vizlib {
.amos-context-menu-list { .amos-context-menu-list {
li:first-child {
display: none;
}
} }
} }
...@@ -84,7 +84,9 @@ export const eventTopics = { ...@@ -84,7 +84,9 @@ export const eventTopics = {
fire_confirm_msg: 'base3d.view.fireConfirm_msg', //预案开始消息 fire_confirm_msg: 'base3d.view.fireConfirm_msg', //预案开始消息
biz_preplan_view: 'base3d.forward.preplan',//预案打开业务菜单 biz_preplan_view: 'base3d.forward.preplan',//预案打开业务菜单
top_afe_msg: 'base3d.fromws.top_alarm_fire_equip_msg', //顶部传感器报警消息 top_afe_msg: 'base3d.fromws.top_alarm_fire_equip_msg', //顶部传感器报警消息
top_ae_msg: 'base3d.fromws.top_alarm_equip_msg' //顶部重点装备报警提醒消息 top_ae_msg: 'base3d.fromws.top_alarm_equip_msg', //顶部重点装备报警提醒消息
plan_task_ist:'task_tabs_show'//预案演练任务列表展开事件
}; };
export const isPointEvent = (topic) => topic.indexOf('.point_') > -1; export const isPointEvent = (topic) => topic.indexOf('.point_') > -1;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,7 +2,8 @@ export const headerButton = [ ...@@ -2,7 +2,8 @@ export const headerButton = [
// { key: 'back', text: '返回', icon: 'fanhui' }, // { key: 'back', text: '返回', icon: 'fanhui' },
{ key: 'onOff', text: '显示窗', icon: 'yuan1' }, { key: 'onOff', text: '显示窗', icon: 'yuan1' },
{ key: 'planDrill', text: '预案演练', icon: 'yuan1' }, { key: 'planDrill', text: '预案演练', icon: 'yuan1' },
{ key: 'textPlan', text: '文字预案', icon: 'yuan-shuxing' } { key: 'textPlan', text: '文字预案', icon: 'yuan-shuxing' },
{ key: 'taskList', text: '任务列表', icon: 'renwu' },
]; ];
export const pageUrl = { export const pageUrl = {
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import PublishApp from 'amos-iot-3dgraph/lib/view/pubview'; import PublishApp from 'amos-iot-3dgraph/lib/view/pubview';
import { TopCardFacroty } from 'base-r3d/lib/factory';
import { fastDeepEqual } from 'amos-tool'; import { fastDeepEqual } from 'amos-tool';
import { Button, Modal, message, AmosAlert } from 'amos-framework';
import 'amos-iot-3dgraph/lib/styles'; import 'amos-iot-3dgraph/lib/styles';
/** /**
...@@ -15,7 +17,17 @@ class PlanDrill extends Component { ...@@ -15,7 +17,17 @@ class PlanDrill extends Component {
super(props); super(props);
this.state = { this.state = {
params: {}, params: {},
shouldRender: true shouldRender: true,
modal: true,
toolBarFlag: '',
modalData: {//模态框数据
openModel: true,
label: '是否确认着火',
},
voiceData: {//语音播报数据
isVoice: true,
content: '我是谁,我在哪',
}
}; };
} }
...@@ -35,12 +47,72 @@ class PlanDrill extends Component { ...@@ -35,12 +47,72 @@ class PlanDrill extends Component {
setTimeout(()=>{this.setState({ shouldRender: true });}, 50); setTimeout(()=>{this.setState({ shouldRender: true });}, 50);
} }
getHeader = (toolBarFlag) => {
return '提示';
}
getContext = (toolBarFlag) => {
const { modalData } = this.state;
return <div>{modalData.label}</div>;
};
getFooter = () => {
return (<div>
<Button onClick={() => this.cancel()}>取消</Button>
<Button onClick={() => this.onOk()}>确定</Button>
</div> );
}
onOk = () => {
const { voiceData } = this.state;
if(voiceData.isVoice){
this.text2Speech(voiceData);
}
AmosAlert.success('提示', '操作成功');
this.setState({ modal: false, toolBarFlag: '' });
};
cancel = () => {
this.setState({ modal: false, toolBarFlag: '' });
};
text2Speech = (obj) => {
if ('speechSynthesis' in window) {
let { content } = obj;
let sentence = new SpeechSynthesisUtterance(content);
let voices = window.speechSynthesis.getVoices();
for (let i = 0; i < voices.length; i++) {
if (voices[i]['name'] === 'Alex') {
sentence.voice = voices[i];
}
}
sentence.pitch = 1;
sentence.rate = 1.5;//速度
sentence.text = content;
window.speechSynthesis.speak(sentence);
} else {
console.log('当前浏览器不支持语音朗读.');
}
};
render() { render() {
const { params,shouldRender } = this.state; const { params,shouldRender,toolBarFlag,modal } = this.state;
if (shouldRender){ if (shouldRender){
return ( return (
<div className='plan-drill-root'> <div className='plan-drill-root'>
<PublishApp params={params} /> <PublishApp params={params} />
<Modal
header={this.getHeader(toolBarFlag)}
visible={modal}
destroyContent
width='45%'
content={this.getContext(toolBarFlag)}
onCancel={() => this.cancel()}
onOk={() => this.onOk()}
outterClosable={false}
footer={this.getFooter()}
/>
</div> </div>
); );
} else { } else {
......
...@@ -10,14 +10,16 @@ import { textPlanDownloadFileAction } from './../../../services/preControlServic ...@@ -10,14 +10,16 @@ import { textPlanDownloadFileAction } from './../../../services/preControlServic
import formatUrl from 'amos-processor/lib/utils/urlFormat'; import formatUrl from 'amos-processor/lib/utils/urlFormat';
import { FasSerUrl } from 'CONSTS/urlConsts'; import { FasSerUrl } from 'CONSTS/urlConsts';
import _amosTool from 'amos-tool'; import _amosTool from 'amos-tool';
import { PubSub } from 'ray-eventpool';
import { eventTopics } from './../../3dview/consts';
const sidePaneStyle = { const sidePaneStyle = {
planDrill: { planDrill: {
left: 0, left: 0,
top: 82, top: 82,
bottom: 72, bottom: 32,
style: { style: {
backgroundColor: 'rgba(50,50,50,0.5)', backgroundColor: 'rgba(0,0,0,0.6)',
color: 'white', color: 'white',
overflow: 'auto' overflow: 'auto'
} }
...@@ -53,6 +55,7 @@ class PublishView extends Component { ...@@ -53,6 +55,7 @@ class PublishView extends Component {
rightClickNodeTreeItem: null, rightClickNodeTreeItem: null,
node: {}, node: {},
shareVisible: false, shareVisible: false,
taskTabsShow: false,//任务列表
}; };
} }
...@@ -120,6 +123,10 @@ class PublishView extends Component { ...@@ -120,6 +123,10 @@ class PublishView extends Component {
case 'onOff': case 'onOff':
this.setState({ visible: !this.state.visible }); this.setState({ visible: !this.state.visible });
break; break;
case 'taskList': //任务列表
PubSub.publish(eventTopics.plan_task_ist,!this.state.taskTabsShow);
this.setState({ taskTabsShow: !this.state.taskTabsShow });
break;
default: default:
break; break;
} }
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import StageActuator from './StageActuator';
import { fastDeepEqual } from 'amos-tool';
import { getPubSceneAction, getDesignerParamAction } from 'amos-iot-3dgraph/lib/view/pubview/../../services';
import withActuator from 'amos-iot-3dgraph/lib/view/pubview/../connect/withActuator';
/**
* 三维可视化 发布模式
*
* @class ActuatorContainer
* @extends {Component}
*/
@withActuator({
initAction: getDesignerParamAction
// initAction: getPubSceneAction
})
class ActuatorContainer extends Component {
constructor(props){
super(props);
this.state = {
baseObjs: undefined,
dataSource: true,
};
}
render() {
const { baseObjs, dataSource } = this.props;
const { content, animations, basicScene, routePath, particles } = dataSource || {};
const length = (animations || []).length;
return (
<StageActuator
graphConf={basicScene}
baseObjs={baseObjs}
content={content}
routePath={routePath}
particles={particles}
animations={animations}
total={length}
/>
);
}
}
ActuatorContainer.propTypes = {
// 基础模型配置
baseObjs: PropTypes.oneOfType([
PropTypes.object,
PropTypes.array
]),
dataSource: PropTypes.object,
subjectId: PropTypes.string
};
export default ActuatorContainer;
This diff is collapsed.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { LocationParam, utils, fastDeepEqual } from 'amos-tool';
import ActuatorContainer from './ActuatorContainer';
/**
* 三维可视化 发布模式
*
* @class PublishView
* @extends {Component}
*/
class PublishView extends Component {
constructor(props){
super(props);
this.state = {
params: {},
shouldRender: true,
};
}
componentWillMount(){
this.setState({ params: Object.assign({},this.props.location.state) });
}
componentWillReceiveProps(nextProps) {
if (!fastDeepEqual(this.state.params, nextProps.location.state)) {
this.setState({ params: nextProps.location.state, shouldRender: false },
()=>this.timer());
}
}
timer = ()=>{
setTimeout(()=>{this.setState({ shouldRender: true });}, 50);
}
calcParams = () => {
const result = {};
const { params } = this.state;
if (utils.isEmpty(params)){
const locParams = LocationParam.getLocationParams();
locParams.isPublish = locParams.isPublish === 'true' ? true : false;
Object.assign(result, locParams);
} else {
Object.assign(result, params);
}
return result;
}
render() {
const { shouldRender } = this.state;
const params = this.calcParams();
const { appId } = params || {};
if (shouldRender){
return (
<div className="publish-view">
<ActuatorContainer
subjectId={appId}
params={params}
/>
</div>
);
}else{
return null;
}
}
}
PublishView.propTypes = {
params: PropTypes.shape({
appId: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
id: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
token: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
isPublish: PropTypes.bool
})
};
export default PublishView;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
class PlayItem extends Component {
render() {
const { num, name, playAnimate, style, isActive, isPlayed, activeIndex } = this.props;
const cls = classnames({
'play-item': true,
// 'active-item': isActive
});
let progressStyle = {}
if(num == 0 && num <= activeIndex){
progressStyle.borderTopLeftRadius = '10px';
progressStyle.borderBottomLeftRadius = '10px';
}
if(activeIndex - 1 == num){
progressStyle.borderTopRightRadius = '10px';
progressStyle.borderBottomRightRadius = '10px';
}
return (
<div className={cls} style={style} onClick={playAnimate}>
<div className="play-item-dot" />
{isPlayed && <div className="play-item-progress" style={progressStyle}/>}
{/* <div className="play-item-num">{num}</div>
<div className="play-item-name">{name}</div> */}
<div className="play-item-qipao">{num + 1}.{name}</div>
</div>
);
}
}
PlayItem.propTypes = {
style: PropTypes.object,
playAnimate: PropTypes.func,
num: PropTypes.number,
name: PropTypes.string,
isActive: PropTypes.bool
};
export default PlayItem;
import React, { Component } from 'react';
import { Select, Button, SidePane, Icon } from 'amos-framework';
import SymIcon from './../../../../common/icon/SymIcon';
import { PubSub } from 'ray-eventpool';
import { eventTopics } from './../../../../../view/3dview/consts';
const Option = Select.Option;
const steps = [
{ key: 'investigate', label: '侦查', img: '/src/assets/planMgmt/play/tuli/zhencha.png' },
{ key: 'retreat', label: '撤退', img: '/src/assets/planMgmt/play/tuli/chetui.png' },
{ key: 'attack', label: '进攻', img: '/src/assets/planMgmt/play/tuli/jingong.png' },
{ key: 'evacuate', label: '疏散', img: '/src/assets/planMgmt/play/tuli/shusan.png' },
{ key: 'dismantling', label: '破拆', img: '/src/assets/planMgmt/play/tuli/pochai.png' },
{ key: 'guandao', label: '管道', img: '/src/assets/planMgmt/play/tuli/guandao.png' },
{ key: 'ejectsmoke', label: '排烟', img: '/src/assets/planMgmt/play/tuli/paiyan.png' },
{ key: 'watersupply', label: '供水', img: '/src/assets/planMgmt/play/tuli/gongshui.png' },
{ key: 'jingjiequ', label: '警戒区', img: '/src/assets/planMgmt/play/tuli/jingjiequ.png' },
];
/**
* 播放栏
*/
class PlayMenuBar extends Component {
constructor(props){
super(props);
this.state = {
tulieActive: false,
zimuActive: true,
quanpingActive: false,
taskTabsShow: false
};
}
componentDidMount(){
this.tabsPubsub = PubSub.subscribe(eventTopics.plan_task_ist,function(topic,message){
this.setState({ taskTabsShow: message })
}.bind(this));
}
onSelectChange = () => {
}
onButtonClick = (value) => {
if(value == 'tulie'){
this.setState({tulieActive: !this.state.tulieActive})
}else if(value == 'zimu'){
this.setState({zimuActive: !this.state.zimuActive})
}else if(value == 'quanping'){
this.setState({quanpingActive: !this.state.quanpingActive})
}
}
closeMenu = () => {
this.setState({
tulieActive: false
});
}
renderTipPanel = () => {
return (
<div className="control-panel-content">
<div className="control-panel-content-header">
预案图例
<Icon icon="cross" onClick={this.closeMenu} />
</div>
<div className="control-panel-content-body">
{
steps.map(s => (
<div className="control-panel-content-item" key={s.key}>
<div><img src={s.img} className="tulie-img"/>
<span>{s.label}</span></div>
</div>
))
}
</div>
</div>
);
}
renderZimuPanel = () => {
const { ativeAnimate = '', animations = [] } = this.props;
let anima = animations.filter(a => a.animateKey == ativeAnimate)[0];
return (
<div>
{anima && anima.description}
</div>
)
}
render() {
const { tulieActive,zimuActive,quanpingActive,taskTabsShow } = this.state;
const animateProps = {
transitionAppear: true
};
return (
<div className='play-menu'>
<div className='play-menu-button-group'>
<Button className={ tulieActive ? 'amos-btn-active' : '' } value="tulie" onClick={() => this.onButtonClick('tulie')}>
<SymIcon icon='yuan-tuli' className="button-icon"/>
</Button>
<Button className={ zimuActive ? 'amos-btn-active' : '' } value="zimu" onClick={() => this.onButtonClick('zimu')}>
<SymIcon icon='yuan-zimu' className="button-icon"/>
</Button>
<Button className={ quanpingActive ? 'amos-btn-active' : '' } value="quanping" onClick={() => this.onButtonClick('quanping')}>
<SymIcon icon='yuan-quanping' className="button-icon"/>
</Button>
</div>
<Select className='play-menu-select' defaultValue="1" onChange={this.onSelectChange} size="sm" minWidth={'10em'}>
<Option value="1">选择演绎视角</Option>
</Select>
{/* 图列 */}
<SidePane
className={`tip-control-panel ${taskTabsShow ? 'task-open' : 'task-close'}`}
left={false}
top={false}
animateName="slide-down"
visible={tulieActive}
animateProps={animateProps}
>
{this.renderTipPanel()}
</SidePane>
{/* 字幕 */}
<SidePane
className='zimu-control-panel'
left={false}
top={false}
bottom={50}
animateName="slide-down"
visible={zimuActive}
animateProps={animateProps}
>
{this.renderZimuPanel()}
</SidePane>
</div>
);
}
}
PlayMenuBar.propTypes = {
};
export default PlayMenuBar;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { utils } from 'amos-tool';
import PlayItem from './PlayItem';
const calcItemStyle = (index, anims) => {
let width = 100 / (anims.length - 1);
let borderTopLeftRadius = 0;
let borderTopRightRadius = 0;
let borderBottomLeftRadius = 0;
let borderBottomRightRadius = 0;
const left = width * index;
if (index === anims.length - 1) {
width = 0;
borderTopRightRadius = 10;
borderBottomRightRadius = 10;
}
if(index === 0){
borderTopLeftRadius = 10;
borderBottomLeftRadius = 10;
}
return {
width: `${width}%`,
left: `${left}%`,
borderTopLeftRadius: `${borderTopLeftRadius}px`,
borderTopRightRadius: `${borderTopRightRadius}px`,
borderBottomLeftRadius: `${borderBottomLeftRadius}px`,
borderBottomRightRadius: `${borderBottomRightRadius}px`,
};
};
/**
* 播放进度
*
* @class PlayProgress
* @extends {Component}
*/
class PlayProgress extends Component {
constructor(props) {
super(props);
}
render() {
const { animations, ativeAnimate, playTargetAnimate } = this.props;
return (
<div className="pubview-play-progress">
<div className="middle-play-content">
{
(animations || []).map((anim, index) => {
// 将数组的序号,添加为动画的播放序号
anim.animateIndex === undefined && (anim.animateIndex = index);
const style = calcItemStyle(index, animations);
let isActive = false;
let activeIndex = 0;
let isPlayed = false;
if (utils.isEmpty(ativeAnimate)){
isActive = index === 0;
} else {
isActive = ativeAnimate === anim.animateKey;
activeIndex = (animations || []).findIndex(i => i.animateKey == ativeAnimate);
isPlayed = index < activeIndex ? true : false;
}
return (
<PlayItem
key={anim.animateKey}
style={style}
num={index}
name={anim.displayName}
isActive={isActive}
playAnimate={(e) => playTargetAnimate(anim, e)}
isPlayed={isPlayed}
activeIndex={activeIndex}
/>
);
})
}
<div></div>
</div>
</div>
);
}
}
PlayProgress.propTypes = {
animations: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string,
name: PropTypes.string
}),
),
ativeAnimate: PropTypes.string,
playTargetAnimate: PropTypes.func
};
export default PlayProgress;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
/**
* 播放器控制
* @class PlayerControl
* @extends {Component}
*/
class PlayerControl extends Component {
render() {
const { playAll, playPrev, playNext, playStop } = this.props;
return (
<div className="player-control">
<div className="media-control">
<div className="play-prev" onClick={playPrev} />
{this.props.playing ?
<div className="play-stop" onClick={playStop} /> :
<div className="play" onClick={playAll} />
}
<div className="play-next" onClick={playNext} />
</div>
</div>
);
}
}
PlayerControl.propTypes = {
playAll: PropTypes.func,
playPrev: PropTypes.func,
playNext: PropTypes.func
};
export default PlayerControl;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import PlayProgress from './PlayProgress';
import PlayerControl from './PlayerControl';
import PlayMenuBar from './PlayMenuBar';
/**
*
* 播放栏
* @class play
* @extends {Component}
*/
class play extends Component {
constructor(props){
super(props);
this.state = {
};
}
componentDidMount(){
}
render() {
return (
<div className='pubview-play'>
<PlayerControl
playAll={this.props.playAll}
playPrev={this.props.playPrev}
playNext={this.props.playNext}
playStop={this.props.playStop}
playing={this.props.playing}
/>
<PlayProgress
ativeAnimate={this.props.ativeAnimate}
animations={this.props.animations}
playTargetAnimate={this.props.playTargetAnimate}
/>
<PlayMenuBar
ativeAnimate={this.props.ativeAnimate}
animations={this.props.animations}
/>
</div>
);
}
}
play.propTypes = {
state: PropTypes.object
};
export default play;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { fastDeepEqual } from 'amos-tool';
import { Button, Modal, message, AmosAlert, Tabs, Collapse,Timeline } from 'amos-framework';
import moment from 'moment';
import { PubSub } from 'ray-eventpool';
import { eventTopics } from './../../../../../view/3dview/consts';
const { TabList, Tab, TabPanel } = Tabs;
const Panel = Collapse.Panel;
/**
*
* 步骤Tabs
* @class taskTabs
* @extends {Component}
*/
class taskTabs extends Component {
constructor(props){
super(props);
this.state = {
taskTabsShow: false,
tabs:[
{key:1, type:'person', icon:'person', models:[]},
{key:2, type:'car', icon:'car', models:[]}
]
};
}
componentDidMount(){
let { tabs } = this.state;
let models = this.props.content || [];
tabs[0].models = models.filter(e => e.key.indexOf('person') != -1);
tabs[1].models = models.filter(e => e.key.indexOf('car') != -1);
this.setState({ tabs });
this.tabsPubsub = PubSub.subscribe(eventTopics.plan_task_ist,function(topic,message){
this.setState({ taskTabsShow: message })
}.bind(this));
}
componentWillUnmount(){
PubSub.unsubscribe(this.tabsPubsub);
}
componentDidUpdate(prevProps, prevState) {
if (!fastDeepEqual(prevProps.content, this.props.content)){
let { tabs } = this.state;
let models = this.props.content|| [];
tabs[0].models = models.filter(e => e.key.indexOf('person') != -1);
tabs[1].models = models.filter(e => e.key.indexOf('car') != -1);
this.setState({ tabs });
}
}
addTask = (animate) => {
let { tabs } = this.state;
outerloop :
for (let i = 0; i < tabs.length; i++) {
for (let j = 0; j < tabs[i].models.length; j++) {
if(tabs[i].models[j].id == animate.target){
let task = {};
task.taskDes = animate.description;
task.startTime = moment().format("YYYY-MM-DD HH:mm:ss");
tabs[i].models[j].tasks = tabs[i].models[j].tasks == undefined ? [] : tabs[i].models[j].tasks;
tabs[i].models[j].tasks.push(task);
break outerloop;
}
}
}
this.setState({ tabs });
}
render() {
const { tabs,taskTabsShow } = this.state;
if(taskTabsShow){
return (
<div className='board-actuator-tasktab'>
<Tabs defaultActiveKey="1" tabPosition="left">
<TabList>
{tabs.map(e => (
<Tab tab={`Tab-${e.key}`} key={e.key}>
{/* <BizIcon icon={e.icon}/> */}
<img className='board-tabs-img' src={`/src/assets/planMgmt/${e.icon}.png`}/>
</Tab>
))}
</TabList>
{tabs.map(tab => (
<TabPanel tab={`Tab-${tab.key}`} key={tab.key}>
<Collapse className='board-tasktab-all' activeKey={['1']}>
<Panel header='全部' key={'1'}>
<Collapse className='board-tasktab-part' accordion>
{tab.models && tab.models.map(model => {
return <Panel header={model.displayName} key={model.key}>
<Timeline className='board-tasktab-timeLine'>
{model.tasks && model.tasks.map(task => {
return <Timeline.Item>
<p>{task.startTime}</p>
<p>{task.taskDes}</p>
</Timeline.Item>
})}
</Timeline>
</Panel>
})}
</Collapse>
</Panel>
</Collapse>
</TabPanel>
))}
</Tabs>
</div>
);
}else{
return null;
}
}
}
taskTabs.propTypes = {
state: PropTypes.object
};
export default taskTabs;
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