@ -0,0 +1,159 @@ |
|||
'use strict'; |
|||
|
|||
async function getCameraProject (ctx, next) { |
|||
try { |
|||
const models = ctx.fs.dc.models; |
|||
const { limit, page, orderBy, orderDirection, keyword, abilityId, type, venderId } = ctx.query |
|||
const { userId, token } = ctx.fs.api |
|||
|
|||
let findOption = { |
|||
attributes: { exclude: ['delete', 'recycleTime',] }, |
|||
where: { |
|||
createUserId: userId, |
|||
recycleTime: null, |
|||
delete: false |
|||
}, |
|||
order: [ |
|||
[orderBy || 'id', orderDirection || 'DESC'] |
|||
], |
|||
include: [{ |
|||
model: models.CameraAbility |
|||
}, { |
|||
model: models.CameraKind |
|||
}] |
|||
} |
|||
if (limit) { |
|||
findOption.limit = limit |
|||
} |
|||
if (page && limit) { |
|||
findOption.offset = page * limit |
|||
} |
|||
if (keyword) { |
|||
findOption.where.$or = [{ |
|||
name: { $like: `%${keyword}%` } |
|||
}, { |
|||
serialNo: { $like: `%${keyword}%` } |
|||
}] |
|||
} |
|||
if (type) { |
|||
findOption.where.type = type |
|||
} |
|||
if (abilityId) { |
|||
findOption.where.abilityId = abilityId |
|||
} |
|||
if (venderId) { |
|||
findOption.where.venderId = venderId |
|||
} |
|||
|
|||
const cameraRes = await models.Camera.findAll(findOption) |
|||
const total = await models.Camera.count({ |
|||
where: findOption.where |
|||
}) |
|||
|
|||
// 查在安心云绑定的数据
|
|||
const cameraIds = cameraRes.map(c => { |
|||
return c.dataValues.id |
|||
}) |
|||
const axbindCameraRes = await ctx.app.fs.axyRequest.get('vcmp/camera/project', { query: { token, cameraId: cameraIds.join(',') } }) |
|||
|
|||
for (let { dataValues: camera } of cameraRes) { |
|||
const corBindCamera = axbindCameraRes.find(b => b.cameraId == camera.id) |
|||
if (corBindCamera) { |
|||
camera.station = corBindCamera.stations |
|||
} else { |
|||
camera.station = [] |
|||
} |
|||
} |
|||
|
|||
ctx.status = 200; |
|||
ctx.body = { |
|||
total: total, |
|||
data: cameraRes |
|||
} |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = {} |
|||
} |
|||
} |
|||
|
|||
async function getCamera (ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { cameraId } = ctx.query |
|||
|
|||
const cameraRes = await models.Camera.findAll({ |
|||
attributes: { exclude: ['delete', 'recycleTime',] }, |
|||
where: { |
|||
id: { $in: cameraId.split(',') } |
|||
}, |
|||
include: [{ |
|||
model: models.CameraAbility |
|||
}, { |
|||
model: models.CameraKind |
|||
}, { |
|||
model: models.Vender |
|||
}] |
|||
}) |
|||
|
|||
ctx.status = 200; |
|||
ctx.body = cameraRes |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = {} |
|||
} |
|||
} |
|||
|
|||
async function banned (ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const data = ctx.request.body; |
|||
|
|||
// 向视频服务发送通知
|
|||
|
|||
// 库记录
|
|||
await models.Camera.update({ |
|||
forbidden: data.forbidden |
|||
}, { |
|||
where: { |
|||
id: data.cameraId |
|||
} |
|||
}) |
|||
|
|||
ctx.status = 204; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = {} |
|||
} |
|||
} |
|||
|
|||
async function del (ctx) { |
|||
try { |
|||
const { models } = ctx.fs.dc; |
|||
const { cameraId } = ctx.query |
|||
const { token } = ctx.fs.api |
|||
|
|||
await models.cameraId.destroy({ |
|||
where: { |
|||
id: cameraId |
|||
} |
|||
}) |
|||
|
|||
await ctx.app.fs.axyRequest.delete('vcmp/camera/project', { query: { token, cameraId: cameraId.join(',') } }) |
|||
|
|||
ctx.status = 204; |
|||
} catch (error) { |
|||
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); |
|||
ctx.status = 400; |
|||
ctx.body = {} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
getCameraProject, |
|||
getCamera, |
|||
banned, |
|||
del, |
|||
}; |
@ -1,50 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
const request = require('superagent'); |
|||
const buildUrl = (url,token) => { |
|||
let connector = url.indexOf('?') === -1 ? '?' : '&'; |
|||
return `${url}${connector}token=${token}`; |
|||
}; |
|||
|
|||
function factory(app, router, opts) { |
|||
return async function (ctx, next) { |
|||
|
|||
const token = ctx.fs.api.token; |
|||
|
|||
//console.log(username,password)
|
|||
const req = { |
|||
get: (url, query) => { |
|||
return request |
|||
.get(buildUrl(url,token)) |
|||
.query(query) |
|||
}, |
|||
post: (url, data, query) => { |
|||
return request |
|||
.post(buildUrl(url,token)) |
|||
.query(query) |
|||
//.set('Content-Type', 'application/json')
|
|||
.send(data); |
|||
}, |
|||
|
|||
put: (url, data) => { |
|||
return request |
|||
.put(buildUrl(url,token)) |
|||
//.set('Content-Type', 'application/json')
|
|||
.send(data); |
|||
}, |
|||
|
|||
delete: (url) => { |
|||
return request |
|||
.del(buildUrl(url,token)) |
|||
}, |
|||
}; |
|||
|
|||
app.business = app.business || {}; |
|||
app.business.request = req; |
|||
|
|||
await next(); |
|||
}; |
|||
} |
|||
|
|||
module.exports = factory; |
|||
|
@ -0,0 +1,17 @@ |
|||
'use strict'; |
|||
|
|||
const camera = require('../../controllers/camera'); |
|||
|
|||
module.exports = function (app, router, opts) { |
|||
app.fs.api.logAttr['GET/camera/project'] = { content: '获取摄像头列表及项目绑定信息', visible: false }; |
|||
router.get('/camera/project', camera.getCameraProject); |
|||
|
|||
app.fs.api.logAttr['GET/camera'] = { content: '获取摄像头信息', visible: false }; |
|||
router.get('/camera', camera.getCamera); |
|||
|
|||
app.fs.api.logAttr['PUT/camera/banned'] = { content: '禁用摄像头', visible: false }; |
|||
router.put('/camera/banned', camera.banned); |
|||
|
|||
app.fs.api.logAttr['DEL/camera'] = { content: '删除摄像头', visible: false }; |
|||
router.delete('/camera', camera.del); |
|||
}; |
@ -0,0 +1,66 @@ |
|||
'use strict'; |
|||
const request = require('superagent') |
|||
|
|||
class paasRequest { |
|||
constructor(root, { query = {} } = {}) { |
|||
this.root = root; |
|||
this.query = query |
|||
} |
|||
|
|||
#buildUrl = (url) => { |
|||
return `${this.root}/${url}`; |
|||
} |
|||
|
|||
#resultHandler = (resolve, reject) => { |
|||
return (err, res) => { |
|||
if (err) { |
|||
reject(err); |
|||
} else { |
|||
resolve(res.body); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
get = (url, { query = {}, header = {} } = {}) => { |
|||
return new Promise((resolve, reject) => { |
|||
request.get(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject)); |
|||
}) |
|||
} |
|||
|
|||
post = (url, { data = {}, query = {}, header = {} } = {}) => { |
|||
return new Promise((resolve, reject) => { |
|||
request.post(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject)); |
|||
}) |
|||
} |
|||
|
|||
put = (url, { data = {}, header = {}, query = {}, } = {}) => { |
|||
return new Promise((resolve, reject) => { |
|||
request.put(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).send(data).end(this.#resultHandler(resolve, reject)); |
|||
}) |
|||
} |
|||
|
|||
delete = (url, { header = {}, query = {} } = {}) => { |
|||
return new Promise((resolve, reject) => { |
|||
request.delete(this.#buildUrl(url)).set(header).query(Object.assign(query, this.query)).end(this.#resultHandler(resolve, reject)); |
|||
}) |
|||
} |
|||
} |
|||
|
|||
function factory (app, opts) { |
|||
if (opts.pssaRequest) { |
|||
try { |
|||
for (let r of opts.pssaRequest) { |
|||
if (r.name && r.root) { |
|||
app.fs[r.name] = new paasRequest(r.root, { ...(r.params || {}) }) |
|||
} else { |
|||
throw 'opts.pssaRequest 参数错误!' |
|||
} |
|||
} |
|||
} catch (error) { |
|||
console.error(error) |
|||
process.exit(-1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = factory; |
@ -0,0 +1,5 @@ |
|||
{ |
|||
"recommendations": [ |
|||
"formulahendry.code-runner" |
|||
] |
|||
} |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 169 B |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 434 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 853 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
@ -1,47 +1,85 @@ |
|||
'use strict'; |
|||
import React from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Nav } from '@douyinfe/semi-ui'; |
|||
"use strict"; |
|||
import React from "react"; |
|||
import { connect } from "react-redux"; |
|||
import { Nav, Avatar, Dropdown } from "@douyinfe/semi-ui"; |
|||
|
|||
const Header = props => { |
|||
const { dispatch, history, user, actions, socket } = props |
|||
const Header = (props) => { |
|||
const { dispatch, history, user, actions, socket } = props; |
|||
|
|||
return ( |
|||
<div style={{ position: 'relative', height: 60, minWidth: 520 }}> |
|||
<div style={{ float: 'left', paddingLeft: 32, fontSize: 16 }}> |
|||
<div style={{ |
|||
lineHeight: '60px', display: 'inline-block', fontSize: 20, textShadow: '0 4px 3px rgba(0, 0, 0, 0.2)', |
|||
userSelect: 'none' |
|||
}}> |
|||
飞尚物联 |
|||
</div> |
|||
</div> |
|||
<div id="nav" style={{ float: 'right' }}> |
|||
<Nav mode={'horizontal'} onClick={({ itemKey }) => { |
|||
if (itemKey == 'logout') { |
|||
dispatch(actions.auth.logout(user)); |
|||
if (socket) { |
|||
socket.disconnect() |
|||
} |
|||
history.push(`/signin`); |
|||
} |
|||
}}> |
|||
<Nav.Sub itemKey={'user'} text={<div style={{ display: 'inline-block' }}>{user && user.namePresent}</div>}> |
|||
<Nav.Item itemKey={'logout'} text={'退出'} /> |
|||
</Nav.Sub> |
|||
</Nav> |
|||
</div> |
|||
</div> |
|||
) |
|||
return ( |
|||
<> |
|||
<Nav |
|||
mode={"horizontal"} |
|||
onClick={({ itemKey }) => { |
|||
if (itemKey == "logout") { |
|||
dispatch(actions.auth.logout(user)); |
|||
if (socket) { |
|||
socket.disconnect(); |
|||
} |
|||
history.push(`/signin`); |
|||
} |
|||
}} |
|||
style={{ |
|||
height: 60, |
|||
minWidth: 520, |
|||
background: "url(/assets/images/background/header.png)", |
|||
backgroundSize: "100% 100%", |
|||
color: "white", |
|||
}} |
|||
header={{ |
|||
logo: ( |
|||
<img |
|||
src="/assets/images/background/logo.png" |
|||
style={{ display: "inline-block", width: 280, height: 52}} |
|||
/> |
|||
), |
|||
text: "", |
|||
}} |
|||
footer={ |
|||
<Nav.Sub |
|||
itemKey={"user"} |
|||
text={ |
|||
<div |
|||
style={{ |
|||
marginLeft: 20, |
|||
display: "inline-block", |
|||
color: "white", |
|||
}} |
|||
> |
|||
<img |
|||
src="/assets/images/background/notice.png" |
|||
style={{ |
|||
display: "inline-block", |
|||
width: 18, |
|||
height: 18, |
|||
position: "relative", |
|||
top: 6, |
|||
left: -10, |
|||
}} |
|||
/> |
|||
|
|||
<Avatar size="small" color="light-blue" style={{ margin: 4 }}> |
|||
<img src="/assets/images/avatar/6.png" /> |
|||
</Avatar> |
|||
{user && user.namePresent} |
|||
</div> |
|||
} |
|||
> |
|||
<Nav.Item itemKey={"logout"} text={"退出"} /> |
|||
</Nav.Sub> |
|||
} |
|||
/> |
|||
</> |
|||
); |
|||
}; |
|||
|
|||
function mapStateToProps (state) { |
|||
const { global, auth, webSocket } = state; |
|||
return { |
|||
actions: global.actions, |
|||
user: auth.user, |
|||
socket: webSocket.socket |
|||
}; |
|||
function mapStateToProps(state) { |
|||
const { global, auth, webSocket } = state; |
|||
return { |
|||
actions: global.actions, |
|||
user: auth.user, |
|||
socket: webSocket.socket, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(Header); |
|||
export default connect(mapStateToProps)(Header); |
|||
|
@ -0,0 +1,192 @@ |
|||
import React, { useState ,useRef,useEffect,useImperativeHandle} from 'react' |
|||
import { connect } from "react-redux"; |
|||
import { Form,Row,Col,CheckboxGroup, Checkbox,Radio,Input } from '@douyinfe/semi-ui'; |
|||
import { IconEdit,IconPlayCircle } from '@douyinfe/semi-icons'; |
|||
import "./cameraModal.less"; |
|||
function cascadeCamera({dRef}){ |
|||
const form = useRef(); |
|||
const [memoryList,setMemoryList] = useState([ |
|||
{ |
|||
id:1, |
|||
value:'8g' |
|||
},{ |
|||
id:2, |
|||
value:'16g' |
|||
},{ |
|||
id:3, |
|||
value:'32g' |
|||
},{ |
|||
id:4, |
|||
value:'64g' |
|||
},{ |
|||
id:5, |
|||
value:'128g' |
|||
},{ |
|||
id:6, |
|||
value:'256g' |
|||
},{ |
|||
id:7, |
|||
value:'>256g' |
|||
} |
|||
])//内存卡列表 |
|||
const [nvrCheckList, setNvrCheckList] = useState([]);//nvr视频流多选 |
|||
const [NVRcameraList,setNVRcameraList]=useState([])//nvr视频流列表 |
|||
const [isAllChoose,setIsAllChoose]=useState(false)//全选 |
|||
const [equipmentNum,setEquipmentNum]=useState('')//nvr视频编号 |
|||
function NvrChangeName(e,index){//nvr摄像头视频流获取修改名称 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].change=true |
|||
setNVRcameraList(NvrchangeList) |
|||
e.stopPropagation() |
|||
} |
|||
function nvronBlur(index){//nvr摄像头名称修改失去焦点 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].change=false |
|||
setNVRcameraList(NvrchangeList) |
|||
} |
|||
function inputchange(e,index){//nvr摄像头名称修改 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].name=e |
|||
setNVRcameraList(NvrchangeList) |
|||
} |
|||
function toggle(e,index){//nvr云台支持 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].support=e.target.checked |
|||
setNVRcameraList(NvrchangeList) |
|||
e.stopPropagation() |
|||
} |
|||
function allChoose(e){//全选/全不选 |
|||
let chooseList=[] |
|||
if(NVRcameraList.length==nvrCheckList.length){ |
|||
setNvrCheckList([]) |
|||
setIsAllChoose(false) |
|||
} |
|||
else{ |
|||
for (let index = 0; index < NVRcameraList.length; index++) { |
|||
chooseList.push(NVRcameraList[index].id) |
|||
} |
|||
setNvrCheckList(chooseList) |
|||
setIsAllChoose(true) |
|||
} |
|||
} |
|||
function playVideo(e) {//nvr播放视频 |
|||
console.log('22222222222222222'); |
|||
e.stopPropagation() |
|||
} |
|||
useImperativeHandle(dRef,() => ({//传给父组件方法 |
|||
//子组件暴露给父组件的方法 |
|||
cascadeCameraForm : form.current.validate, |
|||
resetCascadeCamera : form.current.reset, |
|||
setNVRcameraList : setNVRcameraList, |
|||
setNvrCheckList : setNvrCheckList, |
|||
setIsAllChoose : setIsAllChoose, |
|||
})) |
|||
return ( |
|||
<> |
|||
<Form |
|||
allowEmpty |
|||
labelPosition='left' |
|||
labelAlign='left' |
|||
labelWidth= '115px' |
|||
onValueChange={values=>{console.log(values);setEquipmentNum(values.equipmentNum)}} |
|||
getFormApi={formApi => form.current = formApi}> |
|||
<Row> |
|||
<Col span={12}> |
|||
<Form.Input field='foreignDomainName' label='外域名称:' initValue={''} placeholder='请输入外域名称' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请输入外域名称' } |
|||
]}/> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.Select label="级联方式:" field='cascadeMode' placeholder='请选择级联方式' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择输入级联方式' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.Select label="SIP编号:" field='sipNum' placeholder='请选择SIP编号' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择SIP编号' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</Col> |
|||
<Col span={24}> |
|||
{NVRcameraList.length>0?<div style={{display: 'flex',alignItems: 'center',justifyContent: 'flex-end',marginRight:19}}> |
|||
<Radio |
|||
checked={isAllChoose} |
|||
mode="advanced" |
|||
onChange={e=>allChoose(e)} |
|||
aria-label="全选"> |
|||
全选 |
|||
</Radio> |
|||
</div>:''} |
|||
</Col> |
|||
</Row> |
|||
<Row> |
|||
<CheckboxGroup type='pureCard' direction='vertical' aria-label="视频流获取" |
|||
value={nvrCheckList} |
|||
onChange={(nvrCheck) => { |
|||
setNvrCheckList(nvrCheck); |
|||
console.log('11111111111',nvrCheck); |
|||
if(NVRcameraList.length==nvrCheck.length){ |
|||
setIsAllChoose(true) |
|||
} |
|||
else{ |
|||
setIsAllChoose(false) |
|||
} |
|||
}}> |
|||
{NVRcameraList.length>0?NVRcameraList.map((item,index)=>( |
|||
<Col key={index} span={12} style={{display:'flex',justifyContent:'center',marginTop:12}}> |
|||
<Checkbox value={item.id} |
|||
extra={ |
|||
<div> |
|||
<div style={{display:'flex',alignItems:'center',justifyContent:'space-between',height:30}}> |
|||
<div>通道名称:{item.change?<Input autofocus style={{width:100}} value={item.name} onChange={e=>inputchange(e,index)} onBlur={()=>nvronBlur(index)}></Input>:item.name}</div> |
|||
<div style={{display:'flex',alignItems:'center'}}> |
|||
<IconEdit |
|||
style={{fontSize:16,marginLeft:18,cursor: "pointer",color:'#1859C1'}} |
|||
onClick={e=>NvrChangeName(e,index)}/> |
|||
</div> |
|||
</div> |
|||
<div style={{marginTop:8,width:246}}>设备编号:{item.number}</div> |
|||
<div style={{marginTop:12,display:'flex',justifyContent:'space-between',alignItems:'center'}}> |
|||
<IconPlayCircle size='extra-large' style={{color:'#1859C1',}} onClick={e=>playVideo(e)}/> |
|||
<Radio |
|||
checked={item.support} |
|||
mode="advanced" |
|||
onChange={e=>toggle(e,index)} |
|||
aria-label="单选" |
|||
> |
|||
云台支持 |
|||
</Radio> |
|||
</div> |
|||
</div> |
|||
} |
|||
style={{width:280,border:'1px solid #F9F9F9',}}> |
|||
</Checkbox> |
|||
</Col> |
|||
)):''} |
|||
</CheckboxGroup> |
|||
</Row> |
|||
</Form> |
|||
</> |
|||
); |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global, members } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
members: members.data, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(cascadeCamera); |
@ -0,0 +1,262 @@ |
|||
import React, { useState ,useRef,useEffect,useImperativeHandle} from 'react' |
|||
import { connect } from "react-redux"; |
|||
import { Form,Row,Col} from '@douyinfe/semi-ui'; |
|||
import "./cameraModal.less"; |
|||
function fluoriteCamera({cRef}){ |
|||
const { TextArea } = Form; |
|||
const form = useRef(); |
|||
const [cloud,setcloud] = useState('')//云台支持 |
|||
const [voice,setvoice] = useState('')//语音支持 |
|||
const [switching,setSwitching] = useState('')//高清切换 |
|||
const [memoryList,setMemoryList] = useState([ |
|||
{ |
|||
id:1, |
|||
value:'8g' |
|||
},{ |
|||
id:2, |
|||
value:'16g' |
|||
},{ |
|||
id:3, |
|||
value:'32g' |
|||
},{ |
|||
id:4, |
|||
value:'64g' |
|||
},{ |
|||
id:5, |
|||
value:'128g' |
|||
},{ |
|||
id:6, |
|||
value:'256g' |
|||
},{ |
|||
id:7, |
|||
value:'>256g' |
|||
} |
|||
])//内存卡列表 |
|||
function handleLocation(){//高德经纬度 |
|||
window.open('https://lbs.amap.com/tools/picker','_blank') |
|||
} |
|||
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 '' |
|||
} |
|||
} |
|||
useImperativeHandle(cRef,() => ({//传给父组件方法 |
|||
//子组件暴露给父组件的方法 |
|||
fluoriteCameraForm : form.current.validate, |
|||
resetFluoriteCamera : form.current.reset |
|||
})) |
|||
return ( |
|||
<> |
|||
<Form |
|||
labelPosition='left' |
|||
labelAlign='left' |
|||
labelWidth= '115px' |
|||
onValueChange={values=>console.log(values)} |
|||
getFormApi={formApi => form.current = formApi}> |
|||
<Row> |
|||
<Col span={12}> |
|||
{/* 设备名称 */} |
|||
<Form.Input field='UserName' label='设备名称:' initValue={''} placeholder='请输入设备名称、常用项目或位置定义' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请输入设备名称' } |
|||
]}/> |
|||
{/* 高清切换 */} |
|||
<Form.RadioGroup |
|||
label="高清切换:" |
|||
field='hdSwitching' |
|||
type='pureCard' |
|||
direction='horizontal' |
|||
style={{padding:0,paddingTop:1,paddingBottom:1}} |
|||
rules={[ |
|||
{ required: true, message: '请选择高清切换' } |
|||
]} |
|||
onChange={(checked) => { |
|||
console.log(checked.target.value); |
|||
if(checked.target.value=='yes'){ |
|||
setSwitching('yes') |
|||
} |
|||
else{ |
|||
setSwitching('no') |
|||
} |
|||
}}> |
|||
<Form.Radio value="yes" style={{width:58,height:30,padding:0,margin:0,background:'#F9F9F9'}}> |
|||
<div className='switching' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
支持 |
|||
</div> |
|||
{switching=='yes'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
<Form.Radio value="no" style={{width:58,height:30,padding:0,margin:0,marginLeft:18,background:'#F9F9F9'}}> |
|||
<div className='switching' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
不支持 |
|||
</div> |
|||
{switching=='no'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
</Form.RadioGroup> |
|||
{/* 安装位置 */} |
|||
<div style={{display:'flex'}}> |
|||
<Form.Input field='Use11rName1312' label='安装位置:' placeholder='请输入或拾取高德经纬度坐标' style={{ width:270 }} |
|||
validate={positionForm} |
|||
rules={[ |
|||
{ 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> |
|||
{/* 设备类型 */} |
|||
<div style={{display:'flex',}}> |
|||
<div> |
|||
<Form.Select label="设备类型:" field='business23' placeholder='请选择摄像头类型' style={{ width:160 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择摄像头类型' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</div> |
|||
<div style={{marginLeft:7}}> |
|||
<Form.Select noLabel='true' field='business244' placeholder='请选择能力' style={{ width:140 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择能力' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</div> |
|||
</div> |
|||
</Col> |
|||
<Col span={12}> |
|||
{/* 云台支持 */} |
|||
<Form.RadioGroup |
|||
label="云台支持:" |
|||
field='role' |
|||
type='pureCard' |
|||
direction='horizontal' |
|||
style={{padding:0,paddingTop:1,paddingBottom:1}} |
|||
rules={[ |
|||
{ required: true, message: '请选择云台支持' } |
|||
]} |
|||
onChange={(checked) => { |
|||
console.log(checked.target.value); |
|||
if(checked.target.value=='yes'){ |
|||
setcloud('yes') |
|||
} |
|||
else{ |
|||
setcloud('no') |
|||
} |
|||
}}> |
|||
<Form.Radio value="yes" style={{width:58,height:30,padding:0,margin:0,background:'#F9F9F9'}}> |
|||
<div className='cloud' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
支持 |
|||
</div> |
|||
{cloud=='yes'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
<Form.Radio value="no" style={{width:58,height:30,padding:0,margin:0,marginLeft:18,background:'#F9F9F9'}}> |
|||
<div className='cloud' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
不支持 |
|||
</div> |
|||
{cloud=='no'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
</Form.RadioGroup> |
|||
{/* 内存 */} |
|||
<div style={{display:'flex'}}> |
|||
<Form.Select label="内存:" field='business2' placeholder='未安装' style={{ width:92 }}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
{/* 语音支持 */} |
|||
<div style={{marginLeft:18}}> |
|||
<Form.RadioGroup |
|||
labelWidth= '76px' |
|||
label="语音支持:" |
|||
field='role2' |
|||
type='pureCard' |
|||
direction='horizontal' |
|||
style={{padding:0,paddingTop:1,paddingBottom:1}} |
|||
onChange={(checked) => { |
|||
console.log(checked.target.value); |
|||
if(checked.target.value=='yes'){ |
|||
setvoice('yes') |
|||
} |
|||
else{ |
|||
setvoice('no') |
|||
} |
|||
}}> |
|||
<Form.Radio value="yes" style={{width:58,height:30,padding:0,margin:0,background:'#F9F9F9'}}> |
|||
<div className='voice' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
支持 |
|||
</div> |
|||
{voice=='yes'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
<Form.Radio value="no" style={{width:58,height:30,padding:0,margin:0,marginLeft:18,background:'#F9F9F9'}}> |
|||
<div className='voice' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
不支持 |
|||
</div> |
|||
{voice=='no'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
</Form.RadioGroup> |
|||
</div> |
|||
</div> |
|||
{/* RTMP地址接入 */} |
|||
<TextArea |
|||
style={{ width:320, height: 90 }} |
|||
field='description' |
|||
label='RTMP地址接入:' |
|||
placeholder='请输入RTMP地址接入' |
|||
/> |
|||
</Col> |
|||
</Row> |
|||
</Form> |
|||
</> |
|||
); |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global, members } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
members: members.data, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(fluoriteCamera); |
@ -0,0 +1,224 @@ |
|||
import React, { useState ,useRef,useEffect,useImperativeHandle} from 'react' |
|||
import { connect } from "react-redux"; |
|||
import { Form,Row,Col } from '@douyinfe/semi-ui'; |
|||
import "./cameraModal.less"; |
|||
function ipcCamera({aRef}){ |
|||
const { TextArea } = Form; |
|||
const form = useRef(); |
|||
const [cloud,setcloud] = useState('')//云台支持 |
|||
const [voice,setvoice] = useState('')//语音支持 |
|||
const [memoryList,setMemoryList] = useState([ |
|||
{ |
|||
id:1, |
|||
value:'8g' |
|||
},{ |
|||
id:2, |
|||
value:'16g' |
|||
},{ |
|||
id:3, |
|||
value:'32g' |
|||
},{ |
|||
id:4, |
|||
value:'64g' |
|||
},{ |
|||
id:5, |
|||
value:'128g' |
|||
},{ |
|||
id:6, |
|||
value:'256g' |
|||
},{ |
|||
id:7, |
|||
value:'>256g' |
|||
} |
|||
])//内存卡列表 |
|||
function handleLocation(){//高德经纬度 |
|||
window.open('https://lbs.amap.com/tools/picker','_blank') |
|||
} |
|||
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 '' |
|||
} |
|||
} |
|||
useImperativeHandle(aRef,() => ({//传给父组件方法 |
|||
//子组件暴露给父组件的方法 |
|||
ipcCameraForm : form.current.validate, |
|||
resetIpcCamera : form.current.reset |
|||
})) |
|||
return ( |
|||
<> |
|||
<Form |
|||
labelPosition='left' |
|||
labelAlign='left' |
|||
labelWidth= '115px' |
|||
onValueChange={values=>console.log(values)} |
|||
getFormApi={formApi => form.current = formApi}> |
|||
<Row> |
|||
<Col span={12}> |
|||
<Form.Input field='UserName' label='设备名称:' initValue={''} placeholder='请输入设备名称、常用项目或位置定义' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请输入设备名称' } |
|||
]}/> |
|||
<Form.Input field='Use11rName11' label='设备厂家:' placeholder='请选择设备厂家' style={{ width:307 }}/> |
|||
<div style={{display:'flex'}}> |
|||
<Form.Input field='Use11rName1312' label='安装位置:' placeholder='请输入或拾取高德经纬度坐标' style={{ width:270 }} |
|||
validate={positionForm} |
|||
rules={[ |
|||
{ 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> |
|||
<div> |
|||
<Form.Input field='UserName11' label='设备编号接入:' initValue={''} placeholder='请输入设备编号' style={{ width:307 }}/> |
|||
</div> |
|||
</Col> |
|||
<Col span={12}> |
|||
<Form.RadioGroup |
|||
label="云台支持:" |
|||
field='role' |
|||
type='pureCard' |
|||
direction='horizontal' |
|||
style={{padding:0,paddingTop:1,paddingBottom:1}} |
|||
rules={[ |
|||
{ required: true, message: '请选择云台支持' } |
|||
]} |
|||
onChange={(checked) => { |
|||
console.log(checked.target.value); |
|||
if(checked.target.value=='yes'){ |
|||
setcloud('yes') |
|||
} |
|||
else{ |
|||
setcloud('no') |
|||
} |
|||
}}> |
|||
<Form.Radio value="yes" style={{width:58,height:30,padding:0,margin:0,background:'#F9F9F9'}}> |
|||
<div className='cloud' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
支持 |
|||
</div> |
|||
{cloud=='yes'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
<Form.Radio value="no" style={{width:58,height:30,padding:0,margin:0,marginLeft:18,background:'#F9F9F9'}}> |
|||
<div className='cloud' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
不支持 |
|||
</div> |
|||
{cloud=='no'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
</Form.RadioGroup> |
|||
<div style={{display:'flex'}}> |
|||
<Form.Select label="内存:" field='business2' placeholder='未安装' style={{ width:92 }}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
<div style={{marginLeft:18}}> |
|||
<Form.RadioGroup |
|||
labelWidth= '76px' |
|||
label="语音支持:" |
|||
field='role2' |
|||
type='pureCard' |
|||
direction='horizontal' |
|||
style={{padding:0}} |
|||
onChange={(checked) => { |
|||
console.log(checked.target.value); |
|||
if(checked.target.value=='yes'){ |
|||
setvoice('yes') |
|||
} |
|||
else{ |
|||
setvoice('no') |
|||
} |
|||
}}> |
|||
<Form.Radio value="yes" style={{width:58,height:30,padding:0,margin:0,background:'#F9F9F9'}}> |
|||
<div className='voice' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
支持 |
|||
</div> |
|||
{voice=='yes'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
<Form.Radio value="no" style={{width:58,height:30,padding:0,margin:0,marginLeft:18,background:'#F9F9F9'}}> |
|||
<div className='voice' style={{width:58,height:30,textAlign:'center',lineHeight:'30px'}}> |
|||
不支持 |
|||
</div> |
|||
{voice=='no'?<div style={{position: 'absolute', top: '-2px', right: '-1px'}}> |
|||
<img src="/assets/images/background/formchoose.png" alt="1" /> |
|||
</div>:''} |
|||
</Form.Radio> |
|||
</Form.RadioGroup> |
|||
</div> |
|||
</div> |
|||
<TextArea |
|||
style={{ width:320, height: 90 }} |
|||
field='description' |
|||
label='RTMP地址接入:' |
|||
placeholder='请输入RTMP地址接入' |
|||
/> |
|||
</Col> |
|||
<Col span={18}> |
|||
<div style={{display:'flex',}}> |
|||
<div> |
|||
<Form.Select label="设备类型:" field='business23' placeholder='请选择摄像头类型' style={{ width:160 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择摄像头类型' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</div> |
|||
<div style={{marginLeft:7}}> |
|||
<Form.Select noLabel='true' field='business244' placeholder='请选择能力' style={{ width:140 }} |
|||
rules={[ |
|||
{ required: true, message: '请选择能力' } |
|||
]}> |
|||
{memoryList.map((item,index)=>( |
|||
<Form.Select.Option key={index} value={item.id}>{item.value}</Form.Select.Option> |
|||
))} |
|||
</Form.Select> |
|||
</div> |
|||
</div> |
|||
</Col> |
|||
</Row> |
|||
</Form> |
|||
</> |
|||
); |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global, members } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
members: members.data, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(ipcCamera); |
@ -0,0 +1,182 @@ |
|||
import React, { useState ,useRef,useEffect,useImperativeHandle} from 'react' |
|||
import { connect } from "react-redux"; |
|||
import { Form,Row,Col,Button,CheckboxGroup, Checkbox,Radio,Input } from '@douyinfe/semi-ui'; |
|||
import { IconEdit,IconPlayCircle } from '@douyinfe/semi-icons'; |
|||
import "./cameraModal.less"; |
|||
function nvrCamera({cRef}){ |
|||
const form = useRef(); |
|||
const [nvrCheckList, setNvrCheckList] = useState([]);//nvr视频流多选 |
|||
const [NVRcameraList,setNVRcameraList]=useState([])//nvr视频流列表 |
|||
const [isAllChoose,setIsAllChoose]=useState(false)//全选 |
|||
const [equipmentNum,setEquipmentNum]=useState('')//nvr视频编号 |
|||
function NvrChangeName(e,index){//nvr摄像头视频流获取修改名称 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].change=true |
|||
setNVRcameraList(NvrchangeList) |
|||
e.stopPropagation() |
|||
} |
|||
function nvronBlur(index){//nvr摄像头名称修改失去焦点 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].change=false |
|||
setNVRcameraList(NvrchangeList) |
|||
} |
|||
function inputchange(e,index){//nvr摄像头名称修改 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].name=e |
|||
setNVRcameraList(NvrchangeList) |
|||
} |
|||
function toggle(e,index){//nvr云台支持 |
|||
let NvrchangeList = JSON.parse(JSON.stringify(NVRcameraList)) |
|||
NvrchangeList[index].support=e.target.checked |
|||
setNVRcameraList(NvrchangeList) |
|||
e.stopPropagation() |
|||
} |
|||
function getVideoList(){ |
|||
form.current.validate().then(values=>{//表单校验成功 |
|||
let chooseList=[] |
|||
let nvrCameraList=[{ |
|||
id:10, |
|||
name:'南昌县1', |
|||
number:'111111111111111111', |
|||
support:false, |
|||
change:false, |
|||
},{ |
|||
id:20, |
|||
name:'南昌县2', |
|||
number:'222222222222222222', |
|||
support:false, |
|||
change:false, |
|||
},{ |
|||
id:30, |
|||
name:'南昌县3', |
|||
number:'333333333333333333', |
|||
support:false, |
|||
change:false, |
|||
},{ |
|||
id:40, |
|||
name:'南昌县4', |
|||
number:'444444444444444444', |
|||
support:false, |
|||
change:false, |
|||
}] |
|||
setNVRcameraList(nvrCameraList) |
|||
for (let index = 0; index < nvrCameraList.length; index++) { |
|||
chooseList.push(nvrCameraList[index].id) |
|||
} |
|||
setNvrCheckList(chooseList) |
|||
setIsAllChoose(true) |
|||
}) |
|||
.catch(errors=>{//表单校验失败 |
|||
console.log('errors',errors); |
|||
}) |
|||
} |
|||
function allChoose(e){//全选/全不选 |
|||
let chooseList=[] |
|||
if(NVRcameraList.length==nvrCheckList.length){ |
|||
setNvrCheckList([]) |
|||
setIsAllChoose(false) |
|||
} |
|||
else{ |
|||
for (let index = 0; index < NVRcameraList.length; index++) { |
|||
chooseList.push(NVRcameraList[index].id) |
|||
} |
|||
setNvrCheckList(chooseList) |
|||
setIsAllChoose(true) |
|||
} |
|||
} |
|||
function playVideo(e) {//nvr播放视频 |
|||
console.log('22222222222222222'); |
|||
e.stopPropagation() |
|||
} |
|||
// useImperativeHandle(cRef,() => ({//传给父组件方法 |
|||
// //aa即为子组件暴露给父组件的方法 |
|||
// getDate : form.current.validate, |
|||
// // resetFluoriteCamera : form.current.reset |
|||
// })) |
|||
return ( |
|||
<> |
|||
<Form |
|||
allowEmpty |
|||
labelPosition='left' |
|||
labelAlign='left' |
|||
labelWidth= '115px' |
|||
onValueChange={values=>{setEquipmentNum(values.equipmentNum)}} |
|||
getFormApi={formApi => form.current = formApi}> |
|||
<div style={{display:'flex'}}> |
|||
<Form.Input field='equipmentNum' maxLength='39' label='设备编号:' initValue={''} placeholder='请输入设备编号' style={{ width:307 }} |
|||
rules={[ |
|||
{ required: true, message: '请输入设备编号' }, |
|||
{ pattern: '^[A-Za-z0-9]+$', message: '只能输入数字或者字母' } |
|||
]}/> |
|||
<Button disabled={!equipmentNum.length>0} theme='solid' type='primary' onClick={()=>{getVideoList()}} style={{ marginLeft: 8,marginTop:12 }}>视频流获取</Button> |
|||
{NVRcameraList.length>0?<div style={{display: 'flex',alignItems: 'center',marginLeft: 211}}> |
|||
<Radio |
|||
checked={isAllChoose} |
|||
mode="advanced" |
|||
onChange={e=>allChoose(e)} |
|||
aria-label="全选"> |
|||
全选 |
|||
</Radio> |
|||
</div>:''} |
|||
</div> |
|||
<Row> |
|||
<CheckboxGroup type='pureCard' direction='vertical' aria-label="视频流获取" |
|||
value={nvrCheckList} |
|||
onChange={(nvrCheck) => { |
|||
setNvrCheckList(nvrCheck); |
|||
// console.log('11111111111',nvrCheck); |
|||
if(NVRcameraList.length==nvrCheck.length){ |
|||
setIsAllChoose(true) |
|||
} |
|||
else{ |
|||
setIsAllChoose(false) |
|||
} |
|||
}}> |
|||
{NVRcameraList.length>0?NVRcameraList.map((item,index)=>( |
|||
<Col key={index} span={12} style={{display:'flex',justifyContent:'center',marginTop:12}}> |
|||
<Checkbox value={item.id} |
|||
extra={ |
|||
<div> |
|||
<div style={{display:'flex',alignItems:'center',justifyContent:'space-between',height:30}}> |
|||
<div>通道名称:{item.change?<Input autofocus style={{width:100}} value={item.name} onChange={e=>inputchange(e,index)} onBlur={()=>nvronBlur(index)}></Input>:item.name}</div> |
|||
<div style={{display:'flex',alignItems:'center'}}> |
|||
<IconEdit |
|||
style={{fontSize:16,marginLeft:18,cursor: "pointer",color:'#1859C1'}} |
|||
onClick={e=>NvrChangeName(e,index)}/> |
|||
</div> |
|||
</div> |
|||
<div style={{marginTop:8,width:246}}>设备编号:{item.number}</div> |
|||
<div style={{marginTop:12,display:'flex',justifyContent:'space-between',alignItems:'center'}}> |
|||
<IconPlayCircle size='extra-large' style={{color:'#1859C1',}} onClick={e=>playVideo(e)}/> |
|||
<Radio |
|||
checked={item.support} |
|||
mode="advanced" |
|||
onChange={e=>toggle(e,index)} |
|||
aria-label="单选" |
|||
> |
|||
云台支持 |
|||
</Radio> |
|||
</div> |
|||
</div> |
|||
} |
|||
style={{width:280,border:'1px solid #F9F9F9',}}> |
|||
</Checkbox> |
|||
</Col> |
|||
)):''} |
|||
</CheckboxGroup> |
|||
</Row> |
|||
</Form> |
|||
</> |
|||
); |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, global, members } = state; |
|||
return { |
|||
loading: members.isRequesting, |
|||
user: auth.user, |
|||
actions: global.actions, |
|||
members: members.data, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(nvrCamera); |