Browse Source

信鸽服务

release_1.1.2
deartibers 3 years ago
parent
commit
5b9d2c746e
  1. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/createdSuccessfully.png
  2. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_choose.png
  3. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_four.png
  4. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_four_choose.png
  5. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_offLine.png
  6. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_one.png
  7. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_online.png
  8. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_three.png
  9. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_three_choose.png
  10. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_timing.png
  11. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_two.png
  12. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/icon_two_choose.png
  13. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/noteTopChoose.png
  14. BIN
      code/VideoAccess-VCMP/web/client/assets/images/background/triangle.png
  15. 10
      code/VideoAccess-VCMP/web/client/src/index.less
  16. 88
      code/VideoAccess-VCMP/web/client/src/sections/offline/actions/carrierpigeon.js
  17. 5
      code/VideoAccess-VCMP/web/client/src/sections/offline/actions/index.js
  18. 4
      code/VideoAccess-VCMP/web/client/src/sections/offline/actions/statuscode.js
  19. 754
      code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushModal.jsx
  20. 44
      code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushModal.less
  21. 77
      code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushSideSheet.jsx
  22. 8
      code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushSideSheet.less
  23. 328
      code/VideoAccess-VCMP/web/client/src/sections/offline/containers/carrierpigeon.jsx
  24. 7
      code/VideoAccess-VCMP/web/client/src/utils/webapi.js

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/createdSuccessfully.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_choose.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_four.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_four_choose.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_offLine.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_one.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_online.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_three.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_three_choose.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_timing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_two.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/icon_two_choose.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/noteTopChoose.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
code/VideoAccess-VCMP/web/client/assets/images/background/triangle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

10
code/VideoAccess-VCMP/web/client/src/index.less

@ -19,6 +19,16 @@ body {
#App{ #App{
height: 100%; height: 100%;
} }
.semi-timepicker-panel{//时间选择器不显示滚动栏
::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
overflow-x: hidden;
overflow-y: auto;
}
a:link { a:link {
text-decoration: none; text-decoration: none;
color: unset color: unset

88
code/VideoAccess-VCMP/web/client/src/sections/offline/actions/carrierpigeon.js

@ -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: "" },
});
}

5
code/VideoAccess-VCMP/web/client/src/sections/offline/actions/index.js

@ -1,9 +1,8 @@
'use strict'; 'use strict';
import * as statuscode from './statuscode' import * as statuscode from './statuscode'
// import * as camera from './camera' import * as carrierpigeon from './carrierpigeon'
export default { export default {
// ...statuscode,...camera ...statuscode,...carrierpigeon
...statuscode
} }

4
code/VideoAccess-VCMP/web/client/src/sections/offline/actions/statuscode.js

@ -36,7 +36,7 @@ export function postStatusResolve(data) {
data, data,
actionType: "POST_STATUS_RESOLVE", actionType: "POST_STATUS_RESOLVE",
url: `${ApiTable.postStatusResolve}`, url: `${ApiTable.postStatusResolve}`,
msg: { option: "" }, //编辑解决方案 msg: { option: "编辑解决方案" }, //编辑解决方案
reducer: { name: "" }, reducer: { name: "" },
}); });
} }
@ -48,7 +48,7 @@ export function postStatusCustom(data) {
data, data,
actionType: "POST_STATUS_CUSTOM", actionType: "POST_STATUS_CUSTOM",
url: `${ApiTable.postStatusCustom}`, url: `${ApiTable.postStatusCustom}`,
msg: { option: "" }, //自定义状态码释义 msg: { option: "自定义状态码释义" }, //自定义状态码释义
reducer: { name: "" }, reducer: { name: "" },
}); });
} }

754
code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushModal.jsx

@ -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 { connect } from "react-redux";
import { Modal, Form, Row, Col, Spin } from "@douyinfe/semi-ui"; import { Modal, Form, Button,TimePicker,Transfer, Checkbox, Avatar } from "@douyinfe/semi-ui";
import { IconTickCircle } from "@douyinfe/semi-icons"; import { IconClose } from '@douyinfe/semi-icons';
import './pushModal.less'
import moment from "moment";
function pushModal (props) { function pushModal (props) {
const { modalName, pushRef } = props; const {
const { dispatch, actions, vender, close } = props; close,
const pushData = props.pushData || {}; // rowId,
const form = useRef(); dispatch,
const [visible, setVisible] = useState(false); // actions,
const [isloading, setloading] = useState(false); //loading title,//
const [loadingTip, setloadingTip] = useState("获取中...请稍后..."); //loading tip pushData,//
const [step, setstep] = useState("none"); // cameraList,
const [okText, setokText] = useState("测试校验"); //oktext } = props;
const [cancelText, setcancelText] = useState("取消"); //text const { offline } = actions;//
const [formObj, setformObj] = useState(); // 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');//
const pushWay = useRef('email');//
const emailList = useRef([]);//
const phoneList = useRef([]);//
function showDialog () { const strategyList = [
// //
setVisible(true); {
} id: 1,
function positionForm (val) { img: "/assets/images/background/icon_offLine.png",
let zz = /^(-?\d+)(\.\d+)?$/; title: "离线即时通知",
if (!val) { value: "offline",
return "请输入或拾取高德经纬度坐标"; },
} else if (val.split(",").length != 2) { {
return "请输入格式为116.354169,39.835452的经纬度坐标"; id: 2,
} else if (!zz.test(val.split(",")[0])) { img: "/assets/images/background/icon_online.png",
return "只能填写数字"; title: "上线即时通知",
} else if (!zz.test(val.split(",")[1])) { value: "online",
return "只能填写数字"; },
} else { {
return ""; 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 () { function handleOk () {
// let num = stepNum
if (step == "none") { if (num == 0) {
form.current form.current
.validate() .validate()
.then((values) => { .then((values) => {
// setStepNum(num + 1)
console.log(values) setOkText('下一步')
let valuesObj = JSON.parse(JSON.stringify(values)); setCancelText('上一步')
valuesObj.longitude = values.position.split(",")[0]; if(showList.indexOf(true)>-1){
valuesObj.latitude = values.position.split(",")[1]; setRightDisabled(false)
delete valuesObj.position; }
if (pushData.id) { else{
valuesObj.id = pushData.id; setRightDisabled(true)
} }
var front = new moment(); //
setloading(true);
dispatch(
actions.equipmentWarehouse.getCheck({
serialNo: valuesObj.serialNo,
}) })
}
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) => { ).then((res) => {
var after = new moment(); // close();
var duration = moment.duration(after.diff(front))._data.milliseconds; })
if (res.success) { }
setTimeout( }
() => { function handleCancel () {
setloadingTip("已完成"); //
setTimeout(() => { let num = stepNum
setstep("block"); if (num == 0) {
setloading(false); close();
setokText("确认"); }
setcancelText("上一步"); else if (num == 1) {
setloadingTip("获取中...请稍后..."); setStepNum(num - 1)
}, 1000); setOkText('下一步')
}, setCancelText('取消')
duration > 2000 ? 0 : 2000 - duration 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 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>
); );
} else { }
setTimeout( function renderSelectedItem(item,index){//
() => { return (
setloadingTip("校验失败"); <div className="components-transfer-demo-selected-item" key={item.key}>
setTimeout(() => { <Avatar style={{backgroundColor:item.color}} size="small">
setstep("none"); {item.abbr}
setloading(false); </Avatar>
setokText("测试校验"); <div className="info">
setcancelText("取消"); <div className="name">{item.label}</div>
setloadingTip("获取中...请稍后..."); <div className="email">{item.value}</div>
}, 1000); </div>
}, <IconClose onClick={item.onRemove} />
duration > 2000 ? 0 : 2000 - duration </div>
); );
} }
}); function customFilter(sugInput, item){//, false
setformObj(valuesObj); return item.value.includes(sugInput) || item.label.includes(sugInput);
})
.catch((errors) => {
//
console.log("errors", errors);
});
} else {
dispatch(actions.equipmentWarehouse.addchangepush(formObj)).then((res) => {
setVisible(false);
close();
});
} }
function CameraChooseList(id, items){
if(id.length>0){
setRightDisabled(false)
} }
function handleAfterClose () { else{
// setRightDisabled(true)
setstep("none"); }
setokText("测试校验"); setChooseCameraList(id)
setcancelText("取消");
} }
function handleCancel () {
//
if (step == "none") {
setVisible(false);
} else {
setstep("none");
setokText("测试校验");
setcancelText("取消");
}
}
function handleLocation () {
//
window.open("https://lbs.amap.com/tools/picker", "_blank");
}
useImperativeHandle(pushRef, () => ({
//
//aa
pushNumber: () => formObj.serialNo
}));
return ( return (
<> <>
<div onClick={showDialog}>{modalName == "add" ? "创建推送" : "修改"}</div>
<Modal <Modal
title={modalName == "add" ? "创建推送" : "修改"} title={title}
okText={okText} visible={true}
cancelText={cancelText} // width={835}
visible={visible} onCancel={handleClose}
onOk={handleOk} footer={
width={782} <div>
height={720} <Button type="primary" onClick={handleCancel}>
afterClose={handleAfterClose} {cancelText}
onCancel={handleCancel} </Button>
> <Button theme='solid' disabled={rightDisabled} type="primary" onClick={handleOk}>
<Spin tip={loadingTip} spinning={isloading}> {okText}
<div </Button>
style={{ </div>
paddingLeft: 16, }
display: step == "none" ? "block" : "none",
}}
> >
<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 <Form
allowEmpty allowEmpty
labelPosition="left" labelPosition="left"
labelAlign="left" labelAlign="right"
labelWidth="90px" labelWidth="90px"
onValueChange={(values) => console.log(values)} onValueChange={(values, field) => formChange(values, field)}
getFormApi={(formApi) => (form.current = formApi)} getFormApi={(formApi) => (form.current = formApi)}
> >
<Row> <div style={{ display: 'flex' }}>
<Col span={12}> <div>
<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 <Form.Input
maxLength="36" maxLength="16"
field="name" field="name"
label="设备名称:" label="策略名称:"
initValue={pushData.name || ""} initValue={mypushData.name || ""}
placeholder="请输入设备名称" placeholder="请输入策略名称,不超过16个字符"
style={{ width: 421 }} style={{ width: 307 }}
rules={[ rules={[{ required: true, message: "请输入策略名称,不超过16个字符" }]}
{
required: true,
message: "请输入设备名称、常用项目或位置定义",
},
]}
/> />
</Col> </div>
<Col span={24}> <div style={{ marginLeft: 21 }}>
<Form.Select <Form.Select
label="设备厂家:" label="策略类型:"
field="venderId" field="pushWay"
initValue={pushData.venderId || null} initValue={mypushData.pushWay || 'email'}
placeholder="请选择设备厂家" placeholder="请选择策略类型"
style={{ width: 421 }} style={{ width: 210 }}
rules={[{ required: true, message: "请选择设备厂家" }]}
> >
{vender.map((item, index) => ( <Form.Select.Option value='email'>
<Form.Select.Option key={index} value={item.id}> 邮件推送
{item.name} </Form.Select.Option>
<Form.Select.Option value='phone'>
短信推送
</Form.Select.Option> </Form.Select.Option>
))}
</Form.Select> </Form.Select>
</Col> </div>
<Col span={24} style={{ display: "flex" }}> </div>
<Form.Input <div>
maxLength="39" <Form.TagInput
field="position" addOnBlur={true}
label="安装位置:" label='接收信息:'
initValue={ field="receiver"
pushData.longitude && pushData.latitude initValue={mypushData.receiverList||[]}
? pushData.longitude + "," + pushData.latitude placeholder='请输入接收信息'
: "" style={{ width: 630 }}
}
placeholder="请输入或拾取高德经纬度坐标"
style={{ width: 386 }}
validate={positionForm} validate={positionForm}
rules={[ rules={[{ required: true, message: "请输入接收信息" }]}
{
required: true,
message: "请输入或拾取高德经纬度坐标",
},
]}
/>
<div
style={{
width: 32,
height: 32,
background: "#1859C1",
marginLeft: 4,
display: "flex",
justifyContent: "center",
alignItems: "center",
cursor: "pointer",
marginTop: 12,
borderRadius: 3 + "px",
}}
onClick={handleLocation}
>
<img
src="../../../assets/images/background/location.png"
width={16}
height={20}
/> />
</div> </div>
</Col>
</Row>
</Form> </Form>
<div style={{ color: 'rgba(0,0,0,0.45)', fontSize: 12, textAlign: 'right' }}>
敲击回车键后输入内容将成为标签
</div> </div>
<div style={{ margin: '20px -56px 0px', borderTop: '1px solid rgba(0,0,0,0.06)' }}></div>
<div style={{ height: 224, display: step }}> </div>
{/* 第二步 */}
<div style={{ margin: '29px 32px 0px 32px', display: stepNum == "1" ? "block" : "none", }}>
<div <div
style={{ display: "flex", alignItems: "center",justifyContent: 'space-between', height: 102 }}
>
{showstrategyListList.current.map((item, index) => (
<div
key={item.id}
style={{ style={{
paddingTop: 50, width: 215,
height: 102,
border:
showList[index]
? "1px solid #1859C1"
: "1px solid #F9F9F9",
borderRadius: 3,
display: "flex", display: "flex",
justifyContent: "center", 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)}
> >
<IconTickCircle style={{ color: "#04B234", fontSize: 60 }} /> <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>
):(
<div style={{marginTop:48,color: '#34383E'}}>
{item.title}
</div>
)
}
{showList[index] ? (
<div <div
style={{ style={{
marginTop: 20, position: "absolute",
display: "flex", top: "-3px",
justifyContent: "center", right: "-6px",
}} }}
> >
是否确认创建推送 <img
src="/assets/images/background/noteTopChoose.png"
alt="1"
style={{width:49,height:34}}
/>
</div> </div>
) : (
""
)}
</div>
))}
</div>
<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>
<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> </div>
</Spin>
</Modal> </Modal>
</> </>
); );
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { auth, global, members, vender } = state; const { auth, global, members, CameraKind, CameraAbility } = state;
return { return {
loading: members.isRequesting, loading: members.isRequesting,
user: auth.user, user: auth.user,
actions: global.actions, actions: global.actions,
members: members.data, CameraKind: CameraKind.data || [],
vender: vender.data || [], // CameraAbility: CameraAbility.data || [],
}; };
} }

44
code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushModal.less

@ -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);
}
}

77
code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushSideSheet.jsx

@ -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);

8
code/VideoAccess-VCMP/web/client/src/sections/offline/components/pushSideSheet.less

@ -0,0 +1,8 @@
.sideSheet{
.semi-tabs-tab{
font-size: 16px;
}
.semi-tabs-tab-active{
color: #1859C1;
}
}

328
code/VideoAccess-VCMP/web/client/src/sections/offline/containers/carrierpigeon.jsx

@ -1,14 +1,13 @@
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import moment from "moment"; import moment from "moment";
import { Button, Form, Table, Pagination, Skeleton, Popconfirm, Popover, Tag, } from "@douyinfe/semi-ui"; import { Button, Form, Table, Pagination, Skeleton, Popconfirm, SideSheet, Tag, } from "@douyinfe/semi-ui";
import "../style.less"; import "../style.less";
import { ApiTable } from "$utils"; import { ApiTable } from "$utils";
import { Setup } from "$components"; import { Setup } from "$components";
import PushModal from "../components/pushModal"; import PushModal from "../components/pushModal";
import PushSideSheet from "../components/pushSideSheet";
// import SideSheets from "../components/sideSheet"; // import SideSheets from "../components/sideSheet";
// import { skeletonScreen } from "../components/skeletonScreen";
// import { ReminderBox } from "../../../components/index";
export const accessType = [ export const accessType = [
{ name: "萤石云", key: "yingshi" }, { name: "萤石云", key: "yingshi" },
@ -18,82 +17,86 @@ export const accessType = [
]; ];
const Carrierpigeon = (props) => { const Carrierpigeon = (props) => {
const { history, dispatch, actions, user, loading, equipmentWarehouseNvr } = props; const { history, dispatch, actions, user, loading, StatusPushList } = props;
const { equipmentWarehouse } = actions; const { offline } = actions;
const [setup, setSetup] = useState(false); const [setup, setSetup] = useState(false);
const [sideSheet, setSideSheet] = useState(false);
const [setupp, setSetupp] = useState([]); const [setupp, setSetupp] = useState([]);
const [venderList, setvenderList] = useState([]); //
const [query, setQuery] = useState({ limit: 10, page: 0 }); // const [query, setQuery] = useState({ limit: 10, page: 0 }); //
const [search, setearch] = useState({}); // const [search, setearch] = useState({}); //
const [rowId, setRowId] = useState(); //id const [rowId, setRowId] = useState(); //id
const [reminder, setReminder] = useState(false); // const [pigeonPush, setPigeonPush] = useState(false); //
const [pushTitle, setPushTitle] = useState(''); //
const api = useRef(); const api = useRef();
const searchData = useRef(search) const searchData = useRef(search)
const limits = useRef(); // const limits = useRef(); //
const page = useRef(query.page); const page = useRef(query.page);
const PIGEON = "pigeon"; const PIGEON = "pigeon";
const USER = "user" + props.user.id const cameraList = useRef([]);//
const nvrRef = useRef(); // const [sideSheetVisible, setSideSheetVisible] = useState(false);
const [pushData, setPushData] = useState({});
const [journal, setJournal] = useState([]);
const tableList = [// const tableList = [//
{ {
title: '推送信息', title: '推送信息',
list: [ list: [
{ name: "策略类型", value: "PolicyType" }, { name: "策略类型", value: "pushWay" },
{ name: "推送机制", value: "PushMechanism" }, { name: "推送机制", value: "noticeWay" },
{ name: "监听设备数量", value: "DevicesNumber" }, { name: "监听设备数量", value: "logCount" },
{ name: "累计推送次数", value: "PushNumber" }, { name: "累计推送次数", value: "monitorCount" },
] ]
}, },
]; ];
const noticeWayObj = {
'offline':'离线及时通知',
'online':'上线及时通知',
'timing':'定时统计',
}
useEffect(() => { useEffect(() => {
dispatch(actions.equipmentWarehouse.getVender()).then((res) => { attribute();
setvenderList(res.payload.data); dispatch(offline.getCameraListAll()).then((res) => {//
attribute(res.payload.data); let mycameraList = res.payload.data
for (let index = 0; index < mycameraList.length; index++) {
mycameraList[index].label=mycameraList[index].name
mycameraList[index].key=index+1
mycameraList[index].value=String(mycameraList[index].id)
if(mycameraList[index].type=='cascade'){
mycameraList[index].color='#808FD3'
mycameraList[index].abbr='级联'
}
else if(mycameraList[index].type=='nvr'){
mycameraList[index].color='#F6D86F'
mycameraList[index].abbr='NVR'
}
else if(mycameraList[index].type=='ipc'){
mycameraList[index].color='#1859C1'
mycameraList[index].abbr='IPC'
}
else{
mycameraList[index].color='#57CBD3'
mycameraList[index].abbr='莹石'
}
}
cameraList.current=mycameraList
}); });
// //
localStorage.getItem(PIGEON) == null localStorage.getItem(PIGEON) == null
? localStorage.setItem( ? localStorage.setItem(
PIGEON, PIGEON,
JSON.stringify(["PolicyType", "PushMechanism", "DevicesNumber", "PushNumber"]) JSON.stringify(['pushWay','noticeWay','logCount','monitorCount'])
) )
: ""; : "";
}, []); }, []);
useEffect(() => { useEffect(() => {
equipmentGetNvr(); equipmentGetStatusPush();
}, [query, search]); }, [query, search]);
const equipmentGetNvr = () => { const equipmentGetStatusPush = () => {
searchData.current = { ...query, ...search } searchData.current = { ...query, ...search }
dispatch(equipmentWarehouse.getNvr(searchData.current)).then((res) => { dispatch(offline.getStatusPush(searchData.current)).then((res) => {
limits.current = res.payload.data.data.length limits.current = res.payload.data.length
}); });
} }
function equipmentStatus (data) {
switch (data) {
case "email":
return "邮件通知"
case "note":
return "短信通知"
default:
return "未知"
}
}
function colorStatus (data) {
switch (data) {
case "ON":
return "#04B234"
case "ONLINE":
return "#04B234"
case "OFF":
return "rgba(0, 0, 0, 0.45)"
default:
return "#1859C1"
}
}
const columns = [ const columns = [
{ {
title: "序号", title: "序号",
@ -105,7 +108,6 @@ const Carrierpigeon = (props) => {
title: "策略名称", title: "策略名称",
dataIndex: "name", dataIndex: "name",
render: (_, r, index) => { render: (_, r, index) => {
console.log("r:" + r.name);
return r.name return r.name
}, },
}, },
@ -116,27 +118,67 @@ const Carrierpigeon = (props) => {
render: (_, row) => { render: (_, row) => {
return ( return (
<div style={{ display: "flex" }}> <div style={{ display: "flex" }}>
<Button theme="borderless">
<PushModal
modalName="revise"
/>
</Button>
<Button <Button
theme="borderless" theme="borderless"
onClick={() => { onClick={() => {
setSideSheet(true); setPigeonPush(true);
// setTableNews(row);
setPushTitle('修改推送');
setPushData(row);
setRowId(row.id); setRowId(row.id);
}} }}
> >
禁用 修改
</Button> </Button>
{row.forbidden ? (
<Button
theme="borderless"
onClick={() => {
dispatch(
offline.putPushBanned(
{
configId: row.id,
forbidden: !row.forbidden,
},
row.forbidden
)
).then(() => {
equipmentGetStatusPush();
});
}}
>
启用
</Button>
) : (
<Popconfirm
title="禁用期间产生的通知将不会触达收信端"
arrowPointAtCenter={false}
showArrow={true}
position="topRight"
onConfirm={() => {
dispatch(
offline.putPushBanned(
{
configId: row.id,
forbidden: !row.forbidden,
},
row.forbidden
)
).then(() => {
equipmentGetStatusPush();
});
}}
>
<Button theme="borderless">禁用</Button>
</Popconfirm>
)}
<Popconfirm <Popconfirm
title="是否确定删除?" title="是否确定删除?"
arrowPointAtCenter={false} arrowPointAtCenter={false}
showArrow={true} showArrow={true}
position="topRight" position="topRight"
onConfirm={() => { onConfirm={() => {
dispatch(equipmentWarehouse.delNvr(row.id)).then(() => { dispatch(offline.delPush(row.id)).then(() => {
if (page.current > 0 && limits.current < 2) { if (page.current > 0 && limits.current < 2) {
setQuery({ limit: 10, page: page.current - 1 }) setQuery({ limit: 10, page: page.current - 1 })
} else { } else {
@ -147,10 +189,21 @@ const Carrierpigeon = (props) => {
> >
<Button theme="borderless">删除</Button> <Button theme="borderless">删除</Button>
</Popconfirm> </Popconfirm>
<Button theme="borderless"> <Button onClick={()=>{
dispatch(offline.getPushCopy(row.id)).then(() => {
equipmentGetStatusPush();
});
}} theme="borderless">
复制 复制
</Button> </Button>
<Button theme="borderless"> <Button onClick={()=>{
dispatch(offline.getPushLog(row.id)).then((res) => {
// equipmentGetStatusPush();
setJournal(res.payload.data);
setSideSheetVisible(true);
setPushData(row);
});
}} theme="borderless">
日志 日志
</Button> </Button>
</div> </div>
@ -160,7 +213,7 @@ const Carrierpigeon = (props) => {
]; ];
// //
function attribute (data) { function attribute () {
const arr = localStorage.getItem(PIGEON) const arr = localStorage.getItem(PIGEON)
? JSON.parse(localStorage.getItem(PIGEON)) ? JSON.parse(localStorage.getItem(PIGEON))
: []; : [];
@ -168,51 +221,41 @@ const Carrierpigeon = (props) => {
const column = [ const column = [
{ {
title: "推送机制", title: "推送机制",
dataIndex: "venderId", dataIndex: "noticeWay",
key: "PushMechanism", key: "noticeWay",
render: (_, r, index) => { render: (_, r, index) => {
let manufactorName = data.find((item) => item.id == r.venderId); let noticeWayValue=[]
return manufactorName ? manufactorName.name : ""; for (let index = 0; index < r.noticeWay.length; index++) {
let val = r.noticeWay[index]
noticeWayValue.push(noticeWayObj[val])
}
let noticeWayString=noticeWayValue.join(';')
return noticeWayString;
}, },
}, },
{ {
title: "监听设备数量", title: "监听设备数量",
dataIndex: "DevicesNum", dataIndex: "logCount",
key: "DevicesNumber", key: "logCount",
render: (_, r, index) => { render: (_, r, index) => {
return r.name return r.logCount
}, },
}, },
{ {
title: "累计推送次数", title: "累计推送次数",
dataIndex: "PushNum", dataIndex: "monitorCount",
key: "PushNumber", key: "monitorCount",
render: (_, r, index) => { render: (_, r, index) => {
return (r.name + '次') return (r.monitorCount + '次')
}, },
}, },
{ {
title: "策略类型", title: "策略类型",
dataIndex: "size", dataIndex: "pushWay",
key: "PolicyType", key: "pushWay",
render: (_, r, index) => { render: (_, r, index) => {
let status = r.gbNvr; return r.pushWay=='email' ? '邮件通知' : '短信通知';
return (
<div>
<span
style={{
width: 8,
height: 8,
display: "inline-block",
borderRadius: "50%",
backgroundColor: status ? colorStatus(status.online) : "",
margin: "0 8px 0 0",
}}
/>
{status ? "邮件通知" : equipmentStatus(status.email)}
</div>
);
}, },
}, },
]; ];
@ -224,32 +267,6 @@ const Carrierpigeon = (props) => {
} }
setSetupp(columns); setSetupp(columns);
} }
//station
// function station (r, name, projects) {
// let data = []
// if (projects == "projects") {
// r.station.map((v) => {
// if (v.structure.projects.length > 0) {
// v.structure.projects.map((item) => data.push(item[name]))
// }
// })
// } else {
// r.station.map((v, index) => data.push(v.structure[name]))
// }
// let dataSet = [...(new Set(data))]
// return dataSet.length > 0 ? <Popover
// key="updateTime"
// position="top"
// content={
// dataSet.length > 1 ? <article style={{ padding: 12 }}>{dataSet.map((v, index) => <div key={index}>{v}</div>)}</article> : ""
// }
// >
// <Tag>{dataSet.length > 1 ? `${dataSet[0]}...` : dataSet.length > 0 ? dataSet[0] : ""}</Tag>
// </Popover> : ""
// }
// //
const screen = { const screen = {
width: 193, width: 193,
@ -302,23 +319,12 @@ const Carrierpigeon = (props) => {
color: "#1859C1", color: "#1859C1",
cursor: "pointer", cursor: "pointer",
}} }}
> onClick={() => {
<PushModal setPigeonPush(true);
modalName="add" setPushTitle('创建推送')
/>
{/* <NvrModal
modalName="add"
venderList={venderList}
nvrRef={nvrRef}
close={() => {
const remind = localStorage.getItem(USER);
console.log(remind)
if (!remind) {
setReminder(true)
}
equipmentGetNvr();
}} }}
/> */} >
创建推送
</div> </div>
</div> </div>
</div> </div>
@ -354,7 +360,7 @@ const Carrierpigeon = (props) => {
> >
<Form.Input <Form.Input
label="策略名称:" label="策略名称:"
field="keyword" field="name"
maxLength="36" maxLength="36"
placeholder="请输入策略名称" placeholder="请输入策略名称"
labelPosition="left" labelPosition="left"
@ -363,14 +369,14 @@ const Carrierpigeon = (props) => {
<Form.Select <Form.Select
label="策略类型:" label="策略类型:"
labelPosition="left" labelPosition="left"
field="PolicyType" field="pushWay"
style={screen} style={screen}
placeholder="全部" placeholder="全部"
showClear showClear
> >
<Form.Select.Option value="ALL">全部</Form.Select.Option> <Form.Select.Option value="">全部</Form.Select.Option>
<Form.Select.Option value="OFF">短信通知</Form.Select.Option> <Form.Select.Option value="phone">短信通知</Form.Select.Option>
<Form.Select.Option value="UNKONW">邮件通知</Form.Select.Option> <Form.Select.Option value="email ">邮件通知</Form.Select.Option>
</Form.Select> </Form.Select>
</Form> </Form>
<div <div
@ -469,12 +475,12 @@ const Carrierpigeon = (props) => {
</div> </div>
<Skeleton <Skeleton
loading={loading} loading={loading}
// placeholder={skeletonScreen()}
active={true} active={true}
> >
<Table <Table
columns={setupp.filter((s) => s)} columns={setupp.filter((s) => s)}
dataSource={equipmentWarehouseNvr.data} // dataSource={StatusPushList.data}
dataSource={StatusPushList}
bordered={false} bordered={false}
empty="暂无数据" empty="暂无数据"
style={{ style={{
@ -492,10 +498,10 @@ const Carrierpigeon = (props) => {
}} }}
> >
<span style={{ lineHeight: "30px" }}> <span style={{ lineHeight: "30px" }}>
{equipmentWarehouseNvr.total}条策略 {StatusPushList.total}条策略
</span> </span>
<Pagination <Pagination
total={equipmentWarehouseNvr.total} total={StatusPushList.total}
showSizeChanger showSizeChanger
currentPage={query.page + 1} currentPage={query.page + 1}
pageSizeOpts={[10, 20, 30, 40]} pageSizeOpts={[10, 20, 30, 40]}
@ -512,54 +518,46 @@ const Carrierpigeon = (props) => {
tableList={tableList} tableList={tableList}
close={() => { close={() => {
setSetup(false); setSetup(false);
attribute(venderList); attribute();
}} }}
/> />
) : ( ) : (
"" ""
)} )}
{pigeonPush&&<PushModal
{/* {sideSheet ? (
<SideSheets
visible={true}
rowId={rowId} rowId={rowId}
accessType={accessType} title={pushTitle}
venderList={venderList} pushData={pushData}
cameraList={cameraList.current}
close={() => { close={() => {
setSideSheet(false); setPigeonPush(false);
}} setRowId();
/> setPushData({})
) : ( equipmentGetStatusPush();
[]
)} */}
{/* <ReminderBox
title="是否继续添加NVR摄像头?"
wait="再等等"
toadd="去添加"
visible={reminder}
USER={USER}
onOk={() => {
history.push({ pathname: '/equipmentWarehouse/camera', query: { addNvr: true, serialNo: nvrRef.current.nvrNumber() } });
localStorage.setItem('vcmp_selected_sider', JSON.stringify("camera"))
setReminder(false)
}} }}
/>}
{sideSheetVisible&&<PushSideSheet
pushData={pushData}
journal={journal}
close={() => { close={() => {
setReminder(false) setSideSheetVisible(false);
setPushData({})
}} }}
/> */} />}
</div> </div>
</> </>
); );
}; };
function mapStateToProps (state) { function mapStateToProps (state) {
const { auth, global, members, equipmentWarehouseNvr } = state; const { auth, global, members, StatusPushList } = state;
return { return {
loading: equipmentWarehouseNvr.isRequesting && !equipmentWarehouseNvr.data, loading: StatusPushList.isRequesting && !StatusPushList.data,
user: auth.user, user: auth.user,
actions: global.actions, actions: global.actions,
members: members.data, members: members.data,
equipmentWarehouseNvr: equipmentWarehouseNvr.data || {}, StatusPushList: StatusPushList.data || [],
// StatusPushList: StatusPushList.data || {},
}; };
} }

7
code/VideoAccess-VCMP/web/client/src/utils/webapi.js

@ -45,6 +45,13 @@ export const ApiTable = {
postStatusResolve:'status/resolve',//编辑解决方案 postStatusResolve:'status/resolve',//编辑解决方案
postStatusCustom:'status/custom',//自定义状态码释义 postStatusCustom:'status/custom',//自定义状态码释义
getStatusSimpleAll:'status/simple_all',//获取全部状态码简略信息 getStatusSimpleAll:'status/simple_all',//获取全部状态码简略信息
getCameraListAll:'camera/listAll',//获取所有摄像头信息
getStatusPush:'status/push',//获取推送配置
putSasdtatusPush:'sasdtatus/push',//编辑推送配置
delPush:'status/push/{configId}',//删除推送配置
putPushBanned:'status/push/banned',//禁用推送配置
getPushCopy:'status/push/{configId}/copy',//复制推送配置
getPushLog:'/status/push/{configId}/log',//获取推送记录
}; };
export const VideoServeApi = { export const VideoServeApi = {

Loading…
Cancel
Save