After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 983 B |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 475 B |
@ -0,0 +1,88 @@ |
|||
"use strict"; |
|||
|
|||
import { basicAction } from "@peace/utils"; |
|||
import { ApiTable } from "$utils"; |
|||
|
|||
export function getCameraListAll() {//获取摄像头能力列表
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "get", |
|||
dispatch: dispatch, |
|||
actionType: "GET_CAMERA_LIST_ALL", |
|||
url: `${ApiTable.getCameraListAll}`, |
|||
msg: { option: "" }, |
|||
reducer: { name: "" }, |
|||
}); |
|||
} |
|||
export function getStatusPush(query) {//获取推送配置
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "get", |
|||
dispatch: dispatch, |
|||
actionType: "GET_STATUS_PUSH", |
|||
query: query, |
|||
url: `${ApiTable.getStatusPush}`, |
|||
msg: { option: "获取推送配置" }, |
|||
reducer: { name: "StatusPushList" }, |
|||
}); |
|||
} |
|||
export function putSasdtatusPush(data) { //编辑推送配置
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "put", |
|||
dispatch: dispatch, |
|||
actionType: "PUT_SASDTATUS_PUSH", |
|||
data, |
|||
url: `${ApiTable.putSasdtatusPush}`, |
|||
msg: { option: '编辑推送配置' }, |
|||
reducer: {}, |
|||
}); |
|||
} |
|||
export function delPush(orgId) {//删除推送配置
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "del", |
|||
dispatch: dispatch, |
|||
actionType: "DEL_PUSH", |
|||
url: `${ApiTable.delPush.replace("{configId}", orgId)}`, |
|||
msg: { |
|||
option: |
|||
"删除推送配置", |
|||
}, |
|||
reducer: { name: "" }, |
|||
}); |
|||
} |
|||
export function putPushBanned(data, forbidden) {//禁用推送配置
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "put", |
|||
dispatch: dispatch, |
|||
actionType: "PUT_PUSH_BANNED", |
|||
data, |
|||
url: `${ApiTable.putPushBanned}`, |
|||
msg: { option: forbidden ? "启用" : "禁用" }, |
|||
reducer: {}, |
|||
}); |
|||
} |
|||
export function getPushCopy(orgId) {//复制推送配置
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "get", |
|||
dispatch: dispatch, |
|||
actionType: "GET_PUSH_COPY", |
|||
url: `${ApiTable.getPushCopy.replace("{configId}", orgId)}`, |
|||
msg: { option: "复制推送配置" }, |
|||
reducer: { name: "" }, |
|||
}); |
|||
} |
|||
export function getPushLog(orgId) {//获取推送记录
|
|||
return (dispatch) => |
|||
basicAction({ |
|||
type: "get", |
|||
dispatch: dispatch, |
|||
actionType: "GET_PUSH_LOG", |
|||
url: `${ApiTable.getPushLog.replace("{configId}", orgId)}`, |
|||
msg: { option: "获取推送记录" }, |
|||
reducer: { name: "" }, |
|||
}); |
|||
} |
@ -1,9 +1,8 @@ |
|||
'use strict'; |
|||
|
|||
import * as statuscode from './statuscode' |
|||
// import * as camera from './camera'
|
|||
import * as carrierpigeon from './carrierpigeon' |
|||
|
|||
export default { |
|||
// ...statuscode,...camera
|
|||
...statuscode |
|||
...statuscode,...carrierpigeon |
|||
} |
@ -1,298 +1,582 @@ |
|||
import React, { useState, useRef, useEffect, useImperativeHandle } from "react"; |
|||
import React, { useState, useRef, useEffect } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import { Modal, Form, Row, Col, Spin } from "@douyinfe/semi-ui"; |
|||
import { IconTickCircle } from "@douyinfe/semi-icons"; |
|||
|
|||
import moment from "moment"; |
|||
|
|||
import { Modal, Form, Button,TimePicker,Transfer, Checkbox, Avatar } from "@douyinfe/semi-ui"; |
|||
import { IconClose } from '@douyinfe/semi-icons'; |
|||
import './pushModal.less' |
|||
function pushModal (props) { |
|||
const { modalName, pushRef } = props; |
|||
const { dispatch, actions, vender, close } = props; |
|||
const pushData = props.pushData || {}; //修改时传来的值 |
|||
const form = useRef(); |
|||
const [visible, setVisible] = useState(false); //是否显示弹框 |
|||
const [isloading, setloading] = useState(false); //是否显示loading |
|||
const [loadingTip, setloadingTip] = useState("获取中...请稍后..."); //loading tip的值 |
|||
const [step, setstep] = useState("none"); //第几步 |
|||
const [okText, setokText] = useState("测试校验"); //ok弹框text 右边 |
|||
const [cancelText, setcancelText] = useState("取消"); //取消弹框text 左边 |
|||
const [formObj, setformObj] = useState(); //接口入参 |
|||
const { |
|||
close, |
|||
rowId, |
|||
dispatch, |
|||
actions, |
|||
title,//是编辑还是修改 |
|||
pushData,//数据值 |
|||
cameraList, |
|||
} = props; |
|||
const { offline } = actions;//接口 |
|||
const form = useRef();//第一步表单 |
|||
const [stepNum, setStepNum] = useState(0);//第几步 |
|||
const [okText, setOkText] = useState('下一步');//右边的按钮显示名称 |
|||
const [cancelText, setCancelText] = useState('取消');//左边的按钮显示名称 |
|||
const [finishSrc, setFinishSrc] = useState('/assets/images/background/icon_choose.png');//步骤完成图片 |
|||
const [stepList, setStepList] = useState([ |
|||
{ |
|||
chooseSrc: '/assets/images/background/icon_one.png', |
|||
unCheckedSrc: '/assets/images/background/icon_one.png', |
|||
title: '推送策略', |
|||
text: '基本信息配置' |
|||
}, { |
|||
chooseSrc: '/assets/images/background/icon_two_choose.png', |
|||
unCheckedSrc: '/assets/images/background/icon_two.png', |
|||
title: '通知策略', |
|||
text: '选择推送方式及周期' |
|||
}, { |
|||
chooseSrc: '/assets/images/background/icon_three_choose.png', |
|||
unCheckedSrc: '/assets/images/background/icon_three.png', |
|||
title: '监听范围', |
|||
text: '选择跟踪状态的设备' |
|||
}, { |
|||
chooseSrc: '/assets/images/background/icon_four_choose.png', |
|||
unCheckedSrc: '/assets/images/background/icon_four.png', |
|||
title: '创建完成', |
|||
text: '完成' |
|||
}, |
|||
]);//阶段信息 |
|||
// const [pushWay, setPushWay] = useState('email');//策略类型 |
|||
|
|||
function showDialog () { |
|||
//打开弹框 |
|||
setVisible(true); |
|||
} |
|||
function positionForm (val) { |
|||
let zz = /^(-?\d+)(\.\d+)?$/; |
|||
if (!val) { |
|||
return "请输入或拾取高德经纬度坐标"; |
|||
} else if (val.split(",").length != 2) { |
|||
return "请输入格式为116.354169,39.835452的经纬度坐标"; |
|||
} else if (!zz.test(val.split(",")[0])) { |
|||
return "只能填写数字"; |
|||
} else if (!zz.test(val.split(",")[1])) { |
|||
return "只能填写数字"; |
|||
} else { |
|||
return ""; |
|||
const pushWay = useRef('email');//策略类型 |
|||
const emailList = useRef([]);//邮箱列表 |
|||
const phoneList = useRef([]);//电话列表 |
|||
|
|||
const strategyList = [ |
|||
//循环摄像头列表 |
|||
{ |
|||
id: 1, |
|||
img: "/assets/images/background/icon_offLine.png", |
|||
title: "离线即时通知", |
|||
value: "offline", |
|||
}, |
|||
{ |
|||
id: 2, |
|||
img: "/assets/images/background/icon_online.png", |
|||
title: "上线即时通知", |
|||
value: "online", |
|||
}, |
|||
{ |
|||
id: 3, |
|||
img: "/assets/images/background/icon_timing.png", |
|||
title: "定时统计", |
|||
value: "timing", |
|||
}, |
|||
]; |
|||
const [showList, setShowList] = useState([false, false, false]);//选中通知策略 |
|||
const showstrategyListList = useRef(strategyList);//通知策略列表 |
|||
const [timevalue, setTimevalue] = useState('18:00');//选中通知策略时间 |
|||
const [noticeNum, setNoticeNum] = useState(0);//最新点击的通知策略 |
|||
const [policyList, setPolicyList] = useState([//通知策略备注 |
|||
{ |
|||
strategy: '系统监听到设备离线时,进行一次邮件推送,并将当前所 有离线的设备一同推送至信息邮箱,每次起始推送间隔不少于15分钟。', |
|||
example: '【superadmin】账号下的设备:【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,请及时处理!', |
|||
}, |
|||
{ |
|||
strategy: '系统监听到设备上线时,推送至信息邮箱,每次推送间隔 不少于15分钟。', |
|||
example: '【superadmin】账号下的设备:【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,【2022年22时00分】已恢复!', |
|||
}, |
|||
{ |
|||
strategy: '系统在设定时间前统计所有离线的设备信息,并推送至信 息邮箱。', |
|||
example: '【superadmin】账号下的设备,截止【2022年22时00分】,有15个设备掉线:【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,【智慧小蓝排涝-乡山站排口】于【2022年22时00分】掉线,请及时处理!', |
|||
}, |
|||
]);//阶段信息 |
|||
const [chooseCameraList, setChooseCameraList] = useState([]);//第三阶段选中监听范围摄像头列表 |
|||
const [mypushData, setMypushData] = useState({});//修改过格式的props的值 |
|||
//初始化 |
|||
useEffect(() => { |
|||
let pushDataObj= JSON.parse(JSON.stringify(pushData)) |
|||
let cameraIdList=[] |
|||
let receiverList=[] |
|||
if(pushDataObj.cameraStatusPushMonitors){//摄像头默认选择 |
|||
for (let index = 0; index < pushDataObj.cameraStatusPushMonitors.length; index++) { |
|||
cameraIdList.push(String(pushDataObj.cameraStatusPushMonitors[index].cameraId)) |
|||
} |
|||
} |
|||
} |
|||
if(pushDataObj.cameraStatusPushReceivers){//邮箱或者手机号默认 |
|||
for (let index = 0; index < pushDataObj.cameraStatusPushReceivers.length; index++) { |
|||
receiverList.push(pushDataObj.cameraStatusPushReceivers[index].receiver) |
|||
} |
|||
} |
|||
if(pushDataObj.pushWay){ |
|||
pushWay.current=pushDataObj.pushWay |
|||
if(pushDataObj.pushWay=='email'){ |
|||
emailList.current=receiverList |
|||
} |
|||
else{ |
|||
phoneList.current=receiverList |
|||
} |
|||
} |
|||
if(pushDataObj.timing){//定时推送时间 |
|||
setTimevalue(pushDataObj.timing) |
|||
} |
|||
setChooseCameraList(cameraIdList) |
|||
setMypushData({ |
|||
...pushDataObj, |
|||
receiverList:receiverList, |
|||
}) |
|||
if(pushDataObj.noticeWay){//通知策略 |
|||
let arr = ['offline','online','timing'] |
|||
let arr2 = [false,false,false] |
|||
for (let i = 0; i < arr.length; i++) { |
|||
for (let j = 0; j < pushDataObj.noticeWay.length; j++) { |
|||
if(arr[i]==pushDataObj.noticeWay[j]){ |
|||
arr2[i]=true |
|||
} |
|||
} |
|||
} |
|||
setShowList(arr2) |
|||
} |
|||
}, []); |
|||
|
|||
function handleOk () { |
|||
//点击弹框确定 右边按钮 |
|||
if (step == "none") { |
|||
let num = stepNum |
|||
if (num == 0) { |
|||
form.current |
|||
.validate() |
|||
.then((values) => { |
|||
//表单校验 |
|||
console.log(values) |
|||
let valuesObj = JSON.parse(JSON.stringify(values)); |
|||
valuesObj.longitude = values.position.split(",")[0]; |
|||
valuesObj.latitude = values.position.split(",")[1]; |
|||
delete valuesObj.position; |
|||
if (pushData.id) { |
|||
valuesObj.id = pushData.id; |
|||
setStepNum(num + 1) |
|||
setOkText('下一步') |
|||
setCancelText('上一步') |
|||
if(showList.indexOf(true)>-1){ |
|||
setRightDisabled(false) |
|||
} |
|||
else{ |
|||
setRightDisabled(true) |
|||
} |
|||
var front = new moment(); //验证前时间 |
|||
setloading(true); |
|||
dispatch( |
|||
actions.equipmentWarehouse.getCheck({ |
|||
serialNo: valuesObj.serialNo, |
|||
}) |
|||
).then((res) => { |
|||
var after = new moment(); //验证后时间 |
|||
var duration = moment.duration(after.diff(front))._data.milliseconds; |
|||
if (res.success) { |
|||
setTimeout( |
|||
() => { |
|||
setloadingTip("已完成"); |
|||
setTimeout(() => { |
|||
setstep("block"); |
|||
setloading(false); |
|||
setokText("确认"); |
|||
setcancelText("上一步"); |
|||
setloadingTip("获取中...请稍后..."); |
|||
}, 1000); |
|||
}, |
|||
duration > 2000 ? 0 : 2000 - duration |
|||
); |
|||
} else { |
|||
setTimeout( |
|||
() => { |
|||
setloadingTip("校验失败"); |
|||
setTimeout(() => { |
|||
setstep("none"); |
|||
setloading(false); |
|||
setokText("测试校验"); |
|||
setcancelText("取消"); |
|||
setloadingTip("获取中...请稍后..."); |
|||
}, 1000); |
|||
}, |
|||
duration > 2000 ? 0 : 2000 - duration |
|||
); |
|||
} |
|||
}); |
|||
setformObj(valuesObj); |
|||
}) |
|||
.catch((errors) => { |
|||
//表单校验失败 |
|||
console.log("errors", errors); |
|||
}); |
|||
} else { |
|||
dispatch(actions.equipmentWarehouse.addchangepush(formObj)).then((res) => { |
|||
setVisible(false); |
|||
} |
|||
else if (num == 1) { |
|||
setStepNum(num + 1) |
|||
setOkText('下一步') |
|||
setCancelText('上一步') |
|||
if(chooseCameraList.length>0){ |
|||
setRightDisabled(false) |
|||
} |
|||
else{ |
|||
setRightDisabled(true) |
|||
} |
|||
} |
|||
else if (num == 2) { |
|||
setStepNum(num + 1) |
|||
setOkText('确认并启用') |
|||
setCancelText('上一步') |
|||
} |
|||
else if (num == 3) { |
|||
//点击弹框确定 右边按钮 |
|||
let arr = ['offline','online','timing'] |
|||
let noticeWay =[] |
|||
for (let index = 0; index < showList.length; index++) { |
|||
if(showList[index]){ |
|||
noticeWay.push(arr[index]) |
|||
} |
|||
} |
|||
let pushobj={} |
|||
if(showList[2]){ |
|||
pushobj={ |
|||
...form.current.getValues(), |
|||
noticeWay:noticeWay, |
|||
timing:timevalue, |
|||
cameraId:chooseCameraList, |
|||
} |
|||
} |
|||
else{ |
|||
pushobj={ |
|||
...form.current.getValues(), |
|||
noticeWay:noticeWay, |
|||
cameraId:chooseCameraList, |
|||
} |
|||
} |
|||
if(rowId){ |
|||
pushobj.configId=rowId |
|||
} |
|||
dispatch( |
|||
offline.putSasdtatusPush(pushobj) |
|||
).then((res) => { |
|||
close(); |
|||
}); |
|||
}) |
|||
} |
|||
} |
|||
function handleAfterClose () { |
|||
//在关闭之后 |
|||
setstep("none"); |
|||
setokText("测试校验"); |
|||
setcancelText("取消"); |
|||
} |
|||
function handleCancel () { |
|||
//点击弹框取消 左边按钮 |
|||
if (step == "none") { |
|||
setVisible(false); |
|||
} else { |
|||
setstep("none"); |
|||
setokText("测试校验"); |
|||
setcancelText("取消"); |
|||
let num = stepNum |
|||
if (num == 0) { |
|||
close(); |
|||
} |
|||
else if (num == 1) { |
|||
setStepNum(num - 1) |
|||
setOkText('下一步') |
|||
setCancelText('取消') |
|||
setRightDisabled(false) |
|||
} |
|||
else if (num == 2) { |
|||
setStepNum(num - 1) |
|||
setOkText('下一步') |
|||
setCancelText('上一步') |
|||
setRightDisabled(false) |
|||
} |
|||
else if (num == 3) { |
|||
setStepNum(num - 1) |
|||
setOkText('下一步') |
|||
setCancelText('上一步') |
|||
setRightDisabled(false) |
|||
} |
|||
} |
|||
function handleClose () { |
|||
close(); |
|||
} |
|||
function formChange (value, field) {//第一步表单变化 |
|||
if (Object.keys(field)[0] == 'receiver') { |
|||
form.current.validate(['receiver']) |
|||
} |
|||
if (value.pushWay !== pushWay.current) { |
|||
if (value.pushWay == 'phone') { |
|||
pushWay.current = value.pushWay |
|||
emailList.current = value.receiver |
|||
form.current.setValue('receiver', phoneList.current) |
|||
} |
|||
else { |
|||
pushWay.current = value.pushWay |
|||
phoneList.current = value.receiver |
|||
form.current.setValue('receiver', emailList.current) |
|||
} |
|||
} |
|||
} |
|||
const [rightDisabled, setRightDisabled] = useState(false);//选中通知策略时间 |
|||
function twohandleChoose (value,index) {//第二步选中通知策略 |
|||
let chooselist = JSON.parse(JSON.stringify(showList)) |
|||
chooselist[value - 1] = !chooselist[value - 1] |
|||
setShowList(chooselist) |
|||
let arrtrue =chooselist.indexOf(true) |
|||
if(arrtrue>-1){ |
|||
setRightDisabled(false) |
|||
}else{ |
|||
setRightDisabled(true) |
|||
} |
|||
} |
|||
function twohandleMouseOver (value,index){//第二步鼠标移入通知策略 |
|||
setNoticeNum(index) |
|||
} |
|||
function positionForm (val) {//第一步邮箱或者电话校验 |
|||
let myform = form.current.getValue() |
|||
if (!val||val.length<1) { |
|||
return "请输入接收信息"; |
|||
} |
|||
else { |
|||
if (myform.pushWay == 'email') { |
|||
let zz = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/; |
|||
for (let index = 0; index < val.length; index++) { |
|||
if (!zz.test(val[index])) { |
|||
return "请输入正确的邮箱"; |
|||
} |
|||
} |
|||
} |
|||
else { |
|||
let zz = /^[1][3,4,5,7,8][0-9]{9}$/; |
|||
for (let index = 0; index < val.length; index++) { |
|||
if (!zz.test(val[index])) { |
|||
return "请输入正确的手机号码"; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
function handleLocation () { |
|||
//高德经纬度 |
|||
window.open("https://lbs.amap.com/tools/picker", "_blank"); |
|||
function toTimePicker(e){//阻止定时事件冒泡 |
|||
e.stopPropagation() |
|||
} |
|||
function timeChange(value){//定时统计时间 |
|||
let time = String(value).split(' ') |
|||
let timearr=time[4].split(':') |
|||
setTimevalue(timearr[0]+':'+timearr[1]) |
|||
} |
|||
function renderSourceItem(item,index){//自定义左侧单个候选项的渲染 |
|||
return ( |
|||
<div className="components-transfer-demo-source-item" key={item.key}> |
|||
<Checkbox |
|||
onChange={() => { |
|||
item.onChange(); |
|||
}} |
|||
key={item.key} |
|||
checked={item.checked} |
|||
style={{ height: 52 }} |
|||
> |
|||
<Avatar style={{backgroundColor:item.color}} size="small"> |
|||
{item.abbr} |
|||
</Avatar> |
|||
<div className="info"> |
|||
<div className="name">{item.label}</div> |
|||
<div className="email">{item.value}</div> |
|||
</div> |
|||
</Checkbox> |
|||
</div> |
|||
); |
|||
} |
|||
function renderSelectedItem(item,index){//自定义右侧已选面板的渲染 |
|||
return ( |
|||
<div className="components-transfer-demo-selected-item" key={item.key}> |
|||
<Avatar style={{backgroundColor:item.color}} size="small"> |
|||
{item.abbr} |
|||
</Avatar> |
|||
<div className="info"> |
|||
<div className="name">{item.label}</div> |
|||
<div className="email">{item.value}</div> |
|||
</div> |
|||
<IconClose onClick={item.onRemove} /> |
|||
</div> |
|||
); |
|||
} |
|||
function customFilter(sugInput, item){//自定义筛选逻辑, 当为 false 时,不展示搜索框 |
|||
return item.value.includes(sugInput) || item.label.includes(sugInput); |
|||
} |
|||
function CameraChooseList(id, items){ |
|||
if(id.length>0){ |
|||
setRightDisabled(false) |
|||
} |
|||
else{ |
|||
setRightDisabled(true) |
|||
} |
|||
setChooseCameraList(id) |
|||
} |
|||
useImperativeHandle(pushRef, () => ({ |
|||
//传给父组件方法 |
|||
//aa即为子组件暴露给父组件的方法 |
|||
pushNumber: () => formObj.serialNo |
|||
})); |
|||
return ( |
|||
<> |
|||
<div onClick={showDialog}>{modalName == "add" ? "创建推送" : "修改"}</div> |
|||
<Modal |
|||
title={modalName == "add" ? "创建推送" : "修改"} |
|||
okText={okText} |
|||
cancelText={cancelText} //取消按钮 |
|||
visible={visible} |
|||
onOk={handleOk} |
|||
width={782} |
|||
height={720} |
|||
afterClose={handleAfterClose} |
|||
onCancel={handleCancel} |
|||
title={title} |
|||
visible={true} |
|||
width={835} |
|||
onCancel={handleClose} |
|||
footer={ |
|||
<div> |
|||
<Button type="primary" onClick={handleCancel}> |
|||
{cancelText} |
|||
</Button> |
|||
<Button theme='solid' disabled={rightDisabled} type="primary" onClick={handleOk}> |
|||
{okText} |
|||
</Button> |
|||
</div> |
|||
} |
|||
> |
|||
<Spin tip={loadingTip} spinning={isloading}> |
|||
<div style={{ margin: '0px -24px', borderTop: '1px solid rgba(0,0,0,0.06)', borderBottom: '1px solid rgba(0,0,0,0.06)', display: 'flex' }}> |
|||
{stepList.map((item, index) => { |
|||
return ( |
|||
<div key={index} style={{ width: '25%' }} className={stepNum == index ? 'myChoose' : ''}> |
|||
<div style={{ display: 'flex', margin: '12px 0px 8px 0px', justifyContent: 'center', alignItems: 'center' }}> |
|||
<img |
|||
src={index == stepNum ? item.chooseSrc : stepNum < index ? item.unCheckedSrc : finishSrc} |
|||
alt="设置" |
|||
style={{ width: 24, height: 24, marginRight: 21 }} |
|||
/> |
|||
<div> |
|||
<div style={{ fontSize: 14, color: '#1859C1' }}> |
|||
{item.title} |
|||
</div> |
|||
<div style={{ fontSize: 12, color: 'rgba(0,0,0,0.45)', marginTop: 7 }}> |
|||
{item.text} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div className="myChooseButton"></div> |
|||
</div> |
|||
) |
|||
})} |
|||
</div> |
|||
{/* 第一步 */} |
|||
<div style={{ margin: '29px 32px 0px 32px', display: stepNum == "0" ? "block" : "none", }}> |
|||
<Form |
|||
allowEmpty |
|||
labelPosition="left" |
|||
labelAlign="right" |
|||
labelWidth="90px" |
|||
onValueChange={(values, field) => formChange(values, field)} |
|||
getFormApi={(formApi) => (form.current = formApi)} |
|||
> |
|||
<div style={{ display: 'flex' }}> |
|||
<div> |
|||
<Form.Input |
|||
maxLength="16" |
|||
field="name" |
|||
label="策略名称:" |
|||
initValue={mypushData.name || ""} |
|||
placeholder="请输入策略名称,不超过16个字符" |
|||
style={{ width: 307 }} |
|||
rules={[{ required: true, message: "请输入策略名称,不超过16个字符" }]} |
|||
/> |
|||
</div> |
|||
<div style={{ marginLeft: 21 }}> |
|||
<Form.Select |
|||
label="策略类型:" |
|||
field="pushWay" |
|||
initValue={mypushData.pushWay || 'email'} |
|||
placeholder="请选择策略类型" |
|||
style={{ width: 210 }} |
|||
> |
|||
<Form.Select.Option value='email'> |
|||
邮件推送 |
|||
</Form.Select.Option> |
|||
<Form.Select.Option value='phone'> |
|||
短信推送 |
|||
</Form.Select.Option> |
|||
</Form.Select> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<Form.TagInput |
|||
addOnBlur={true} |
|||
label='接收信息:' |
|||
field="receiver" |
|||
initValue={mypushData.receiverList||[]} |
|||
placeholder='请输入接收信息' |
|||
style={{ width: 630 }} |
|||
validate={positionForm} |
|||
rules={[{ required: true, message: "请输入接收信息" }]} |
|||
/> |
|||
</div> |
|||
</Form> |
|||
<div style={{ color: 'rgba(0,0,0,0.45)', fontSize: 12, textAlign: 'right' }}> |
|||
敲击回车键后,输入内容将成为标签 |
|||
</div> |
|||
<div style={{ margin: '20px -56px 0px', borderTop: '1px solid rgba(0,0,0,0.06)' }}></div> |
|||
</div> |
|||
{/* 第二步 */} |
|||
<div style={{ margin: '29px 32px 0px 32px', display: stepNum == "1" ? "block" : "none", }}> |
|||
<div |
|||
style={{ |
|||
paddingLeft: 16, |
|||
display: step == "none" ? "block" : "none", |
|||
}} |
|||
style={{ display: "flex", alignItems: "center",justifyContent: 'space-between', height: 102 }} |
|||
> |
|||
<Form |
|||
allowEmpty |
|||
labelPosition="left" |
|||
labelAlign="left" |
|||
labelWidth="90px" |
|||
onValueChange={(values) => console.log(values)} |
|||
getFormApi={(formApi) => (form.current = formApi)} |
|||
> |
|||
<Row> |
|||
<Col span={12}> |
|||
<Form.Input |
|||
maxLength="39" |
|||
field="serialNo" |
|||
label="设备编号:" |
|||
initValue={pushData.serialNo || ""} |
|||
placeholder="请输入设备编号" |
|||
style={{ width: 149 }} |
|||
rules={[{ required: true, message: "请输入设备编号" }]} |
|||
/> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.InputNumber |
|||
formatter={(value) => `${value}`.replace(/\D/g, "")} |
|||
hideButtons={true} |
|||
maxLength="15" |
|||
field="regionCode" |
|||
label="行政区区码:" |
|||
initValue={pushData.regionCode || ""} |
|||
placeholder="请输入行政区区码" |
|||
style={{ width: 149 }} |
|||
/> |
|||
</Col> |
|||
<Col span={24}> |
|||
<Form.Input |
|||
maxLength="36" |
|||
field="name" |
|||
label="设备名称:" |
|||
initValue={pushData.name || ""} |
|||
placeholder="请输入设备名称" |
|||
style={{ width: 421 }} |
|||
rules={[ |
|||
{ |
|||
required: true, |
|||
message: "请输入设备名称、常用项目或位置定义", |
|||
}, |
|||
]} |
|||
/> |
|||
</Col> |
|||
<Col span={24}> |
|||
<Form.Select |
|||
label="设备厂家:" |
|||
field="venderId" |
|||
initValue={pushData.venderId || null} |
|||
placeholder="请选择设备厂家" |
|||
style={{ width: 421 }} |
|||
rules={[{ required: true, message: "请选择设备厂家" }]} |
|||
> |
|||
{vender.map((item, index) => ( |
|||
<Form.Select.Option key={index} value={item.id}> |
|||
{item.name} |
|||
</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</Col> |
|||
<Col span={24} style={{ display: "flex" }}> |
|||
<Form.Input |
|||
maxLength="39" |
|||
field="position" |
|||
label="安装位置:" |
|||
initValue={ |
|||
pushData.longitude && pushData.latitude |
|||
? pushData.longitude + "," + pushData.latitude |
|||
: "" |
|||
} |
|||
placeholder="请输入或拾取高德经纬度坐标" |
|||
style={{ width: 386 }} |
|||
validate={positionForm} |
|||
rules={[ |
|||
{ |
|||
required: true, |
|||
message: "请输入或拾取高德经纬度坐标", |
|||
}, |
|||
]} |
|||
/> |
|||
{showstrategyListList.current.map((item, index) => ( |
|||
<div |
|||
key={item.id} |
|||
style={{ |
|||
width: 215, |
|||
height: 102, |
|||
border: |
|||
showList[index] |
|||
? "1px solid #1859C1" |
|||
: "1px solid #F9F9F9", |
|||
borderRadius: 3, |
|||
display: "flex", |
|||
boxShadow: '0px 2px 4px 0px rgba(231,231,231,0.5)', |
|||
cursor: "pointer", |
|||
position: "relative", |
|||
}} |
|||
onClick={() => twohandleChoose(item.id,index)} |
|||
onMouseOver={() => twohandleMouseOver(item.id,index)} |
|||
> |
|||
<img src={item.img} style={{width:56,height:56,margin:'23px 20px'}} alt="设置" /> |
|||
{ |
|||
item.id==3?( |
|||
<div> |
|||
<div style={{marginTop:22,color: '#34383E'}}> |
|||
{item.title} |
|||
</div> |
|||
<div style={{marginTop:10}} |
|||
onClick={(e)=>toTimePicker(e)}> |
|||
<TimePicker |
|||
showClear={false} |
|||
format={'HH:mm'} |
|||
placeholder="时间" |
|||
minuteStep={5} |
|||
defaultValue={'18:00'} |
|||
onChange={timeChange} |
|||
value={timevalue} |
|||
style={{ width: 108 }}/> |
|||
</div> |
|||
</div> |
|||
):( |
|||
<div style={{marginTop:48,color: '#34383E'}}> |
|||
{item.title} |
|||
</div> |
|||
) |
|||
} |
|||
{showList[index] ? ( |
|||
<div |
|||
style={{ |
|||
width: 32, |
|||
height: 32, |
|||
background: "#1859C1", |
|||
marginLeft: 4, |
|||
display: "flex", |
|||
justifyContent: "center", |
|||
alignItems: "center", |
|||
cursor: "pointer", |
|||
marginTop: 12, |
|||
borderRadius: 3 + "px", |
|||
position: "absolute", |
|||
top: "-3px", |
|||
right: "-6px", |
|||
}} |
|||
onClick={handleLocation} |
|||
> |
|||
<img |
|||
src="../../../assets/images/background/location.png" |
|||
width={16} |
|||
height={20} |
|||
src="/assets/images/background/noteTopChoose.png" |
|||
alt="1" |
|||
style={{width:49,height:34}} |
|||
/> |
|||
</div> |
|||
</Col> |
|||
</Row> |
|||
</Form> |
|||
) : ( |
|||
"" |
|||
)} |
|||
</div> |
|||
))} |
|||
</div> |
|||
|
|||
<div style={{ height: 224, display: step }}> |
|||
<div |
|||
style={{ |
|||
paddingTop: 50, |
|||
display: "flex", |
|||
justifyContent: "center", |
|||
}} |
|||
> |
|||
<IconTickCircle style={{ color: "#04B234", fontSize: 60 }} /> |
|||
</div> |
|||
<div |
|||
style={{ |
|||
marginTop: 20, |
|||
display: "flex", |
|||
justifyContent: "center", |
|||
}} |
|||
> |
|||
是否确认创建推送? |
|||
<div style={{ display: "flex", alignItems: "center",justifyContent: 'space-between'}}> |
|||
{showstrategyListList.current.map((item, index) => ( |
|||
<div style={{width:215,height:15,textAlign: 'center'}} key={index}> |
|||
{ |
|||
noticeNum==index?( |
|||
<img |
|||
src="/assets/images/background/triangle.png" |
|||
alt="1" |
|||
style={{width:14,height:12}} |
|||
/> |
|||
):'' |
|||
} |
|||
</div> |
|||
))} |
|||
</div> |
|||
<div style={{background: 'rgba(231,240,251,0.8)',borderRadius: 3}}> |
|||
<div style={{margin:'0px 20px 0px'}}> |
|||
<div style={{paddingTop:13}}> |
|||
<span style={{color: '#1859C1'}}>策略:</span> |
|||
<span style={{color: 'rgba(0,0,0,0.65)'}}>{policyList[noticeNum].strategy}</span> |
|||
</div> |
|||
<div style={{marginTop:12,paddingBottom:12}}> |
|||
<span style={{color: '#1859C1'}}>实例:</span> |
|||
<span style={{color: 'rgba(0,0,0,0.65)'}}>{policyList[noticeNum].example}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</Spin> |
|||
<div style={{ margin: '20px -56px 0px', borderTop: '1px solid rgba(0,0,0,0.06)' }}></div> |
|||
</div> |
|||
{/* 第三步 */} |
|||
<div style={{ margin: '29px 32px 0px 32px', display: stepNum == "2" ? "block" : "none", }}> |
|||
<Transfer |
|||
style={{ width: 683,height:220 }} |
|||
dataSource={cameraList} |
|||
filter={customFilter} |
|||
renderSelectedItem={renderSelectedItem} |
|||
renderSourceItem={renderSourceItem} |
|||
value={chooseCameraList} |
|||
inputProps={{ placeholder: '搜项目或设备名称或设备编号' }} |
|||
onChange={(id, items) => CameraChooseList(id, items)} |
|||
/> |
|||
<div style={{ margin: '20px -56px 0px', borderTop: '1px solid rgba(0,0,0,0.06)' }}></div> |
|||
</div> |
|||
{/* 第四步 */} |
|||
<div style={{ margin: '30px 32px 0px 32px',textAlign: 'center', display: stepNum == "3" ? "block" : "none", }}> |
|||
<img |
|||
src='/assets/images/background/createdSuccessfully.png' |
|||
alt="设置" |
|||
style={{ width: 97, height: 92}} |
|||
/> |
|||
<div style={{color: '#34383E',marginTop:4}}>创建完成</div> |
|||
<div style={{ margin: '25px -56px 0px', borderTop: '1px solid rgba(0,0,0,0.06)' }}></div> |
|||
</div> |
|||
</Modal> |
|||
</> |
|||
); |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth, global, members, vender } = state; |
|||
const { auth, global, members, CameraKind, CameraAbility } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
members: members.data, |
|||
vender: vender.data || [], //设备厂家 |
|||
CameraKind: CameraKind.data || [], |
|||
CameraAbility: CameraAbility.data || [], |
|||
}; |
|||
} |
|||
|
|||
|
@ -0,0 +1,44 @@ |
|||
.myChoose{ |
|||
background: #F9FBFF; |
|||
.myChooseButton{ |
|||
height: 4px; |
|||
background: #0058C8; |
|||
} |
|||
} |
|||
.components-transfer-demo-selected-item { |
|||
.semi-icon-close { |
|||
visibility: hidden; |
|||
color: var(--semi-color-tertiary); |
|||
} |
|||
&:hover { |
|||
.semi-icon-close { |
|||
visibility: visible; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.components-transfer-demo-selected-item, |
|||
.components-transfer-demo-source-item { |
|||
height: 52px; |
|||
box-sizing: border-box; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 10px 12px; |
|||
&:hover { |
|||
background-color: var(--semi-color-fill-0); |
|||
} |
|||
.info { |
|||
margin-left: 8px; |
|||
flex-grow: 1; |
|||
} |
|||
.name { |
|||
font-size: 14px; |
|||
line-height: 20px; |
|||
} |
|||
.email { |
|||
font-size: 12px; |
|||
line-height: 16px; |
|||
color: var(--semi-color-text-2); |
|||
} |
|||
} |
@ -0,0 +1,77 @@ |
|||
import React, { useState, useRef, useEffect } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import { Modal, Spin,Input,Collapse ,SideSheet,Tabs, TabPane} from "@douyinfe/semi-ui"; |
|||
import moment from "moment"; |
|||
import './pushSideSheet.less' |
|||
function pushSideSheet (props) { |
|||
const { |
|||
close, |
|||
actions, |
|||
pushData,//表格信息 |
|||
journal//日志信息 |
|||
} = props; |
|||
const { offline } = actions; |
|||
const [notesValue, setNotesValue] = useState('');//释义 |
|||
|
|||
//初始化 |
|||
useEffect(() => { |
|||
let timeList = [] |
|||
for (let index = 0; index < journal.length; index++) { |
|||
timeList.push( |
|||
{ |
|||
title:getTimeTitle(journal[index].time), |
|||
time:getTimeData(journal[index].time) |
|||
} |
|||
) |
|||
} |
|||
console.log('timeList',timeList); |
|||
}, []); |
|||
function getTimeTitle(date){ |
|||
let year = moment(date).year()+'年' |
|||
let month = (moment(date).month()+1)>10?(moment(date).month()+1)+'月':'0'+(moment(date).month()+1)+'月' |
|||
return year+month |
|||
} |
|||
function getTimeData(date){ |
|||
let day=moment(date).date()>10?moment(date).date()+'日':'0'+moment(date).date()+'日'; |
|||
let hour=moment(date).hour()>10?moment(date).hour():'0'+moment(date).hour(); |
|||
let minute=moment(date).minute()>10?moment(date).minute():'0'+moment(date).minute(); |
|||
let second=moment(date).second()>10?moment(date).second():'0'+moment(date).second(); |
|||
return day+' '+hour+':'+minute+':'+second |
|||
} |
|||
function sideSheetChange(){ |
|||
close() |
|||
} |
|||
return ( |
|||
<> |
|||
<SideSheet title={pushData.name} className='sideSheet' width={670} visible={true} onCancel={sideSheetChange}> |
|||
<Tabs type="line"> |
|||
<TabPane tab="推送日志" itemKey="1"> |
|||
<Collapse> |
|||
<Collapse.Panel header={<div style={{width:'100%',textAlign:'center'}}>11111111</div>} itemKey="1"> |
|||
<p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p> |
|||
</Collapse.Panel> |
|||
</Collapse> |
|||
</TabPane> |
|||
<TabPane tab="监听范围" itemKey="2"> |
|||
22 |
|||
</TabPane> |
|||
<TabPane tab="接收信息" itemKey="3"> |
|||
33 |
|||
</TabPane> |
|||
</Tabs> |
|||
</SideSheet> |
|||
</> |
|||
); |
|||
} |
|||
function mapStateToProps (state) { |
|||
const { auth, global, members, CameraKind, CameraAbility } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
CameraKind: CameraKind.data || [], |
|||
CameraAbility: CameraAbility.data || [], |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(pushSideSheet); |
@ -0,0 +1,8 @@ |
|||
.sideSheet{ |
|||
.semi-tabs-tab{ |
|||
font-size: 16px; |
|||
} |
|||
.semi-tabs-tab-active{ |
|||
color: #1859C1; |
|||
} |
|||
} |