巴林闲侠
2 years ago
17 changed files with 878 additions and 492 deletions
@ -0,0 +1,3 @@ |
|||
export default { |
|||
navigationBarTitleText: '视频监控' |
|||
} |
@ -0,0 +1,85 @@ |
|||
import React, { useState, useEffect } from 'react' |
|||
import Taro from '@tarojs/taro' |
|||
import { View, Image, Input, Picker, LivePlayer } from '@tarojs/components' |
|||
import request from '@/services/request' |
|||
import './index.scss' |
|||
import '../patrolView/index.scss' |
|||
import patrolIcon from '../../static/img/patrolView/patrol.svg' |
|||
import patrolActiveIcon from '../../static/img/patrolView/patrol-active.svg' |
|||
import conserveIcon from '../../static/img/patrolView/conserve.svg' |
|||
import conserveActiveIcon from '../../static/img/patrolView/conserve-active.svg' |
|||
import chevronDown from '../../static/img/patrolView/chevron-down.png' |
|||
import searchIcon from '../../static/img/patrolView/search.png' |
|||
|
|||
function Index() { |
|||
const [isBus, setIsBus] = useState(true) |
|||
const [filterText, setFilterText] = useState('') |
|||
const [videoList, setVideoList] = useState([]) |
|||
|
|||
useEffect(() => { |
|||
getVideoList() |
|||
}, []) |
|||
|
|||
const getVideoList = () => { |
|||
let nextVideoList = [] |
|||
for (let i = 0; i < 10; i++) { |
|||
nextVideoList.push({ title: '视频' + i, url: '链接' + i }) |
|||
} |
|||
setVideoList(nextVideoList) |
|||
} |
|||
|
|||
const onTypeChange = bool => { |
|||
setIsBus(bool) |
|||
} |
|||
|
|||
const handleConfirm = e => { |
|||
|
|||
} |
|||
|
|||
const handleInput = e => { |
|||
|
|||
} |
|||
|
|||
return ( |
|||
<View> |
|||
<View className='type-box'> |
|||
<View className='item' onClick={() => onTypeChange(true)}> |
|||
<Image className='type-img' src={isBus ? patrolActiveIcon : patrolIcon} /> |
|||
<View style={{ color: isBus ? '#346FC2' : '#999999' }}>公交</View> |
|||
</View> |
|||
<View className='line'></View> |
|||
<View className='item' onClick={() => onTypeChange(false)}> |
|||
<Image className='type-img' src={isBus ? conserveIcon : conserveActiveIcon} /> |
|||
<View style={{ color: isBus ? '#999999' : '#346FC2' }}>道路</View> |
|||
</View> |
|||
</View> |
|||
<View className='filter-box'> |
|||
<View className='filter-item'> |
|||
<View style={{ float: 'left', marginLeft: '20rpx', color: '#333' }}>路段:</View> |
|||
<Picker> |
|||
<View className='filter-name'>{'请选择'}</View> |
|||
<Image className='filter-img' src={chevronDown} /> |
|||
</Picker> |
|||
</View> |
|||
<View class='head-search'> |
|||
<Image className='search-img' src={searchIcon} /> |
|||
<Input class='heard-search-input' value={filterText} placeholder='请输入道路名称' onConfirm={handleConfirm} onInput={handleInput} /> |
|||
</View> |
|||
</View> |
|||
<View className='video-box'> |
|||
{ |
|||
videoList && videoList.map(v => { |
|||
return ( |
|||
<View className='video-card'> |
|||
<View className='title'>{v.title}</View> |
|||
<LivePlayer className='video' src={v.url} mode='live' /> |
|||
</View> |
|||
) |
|||
}) |
|||
} |
|||
</View> |
|||
</View> |
|||
) |
|||
} |
|||
|
|||
export default Index |
@ -0,0 +1,28 @@ |
|||
page { |
|||
background-color: #f6f6f6; |
|||
|
|||
.video-box { |
|||
padding-top: 180px; |
|||
|
|||
.video-card { |
|||
background-color: #fff; |
|||
height: 488px; |
|||
margin-bottom: 20px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: left; |
|||
|
|||
.title { |
|||
height: 88px; |
|||
margin-left: 30px; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.video { |
|||
height: 400px; |
|||
width: 100%; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,213 @@ |
|||
import React, { useState, useEffect } from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Modal, Form, Button, Input, Card, List } from 'antd'; |
|||
import Uploads from "../../../../components/Upload/index" |
|||
import { putAddPropagata } from '../../actions/infor'; |
|||
import { putEditPropagata } from '../../actions/infor'; |
|||
import { getPropagata } from '../../actions/infor'; |
|||
|
|||
|
|||
const VideoUpload = (props) => { |
|||
// const [counts, setCounts] = useState()//shuju
|
|||
|
|||
|
|||
const { dispatch, record, counts, setCounts } = props |
|||
const [success, setSuccess] = useState() //状态
|
|||
const [form] = Form.useForm(); |
|||
|
|||
//弹窗
|
|||
const [isModalVisible, setIsModalVisible] = useState(false); |
|||
const showModal = () => { |
|||
setIsModalVisible(true); |
|||
|
|||
} |
|||
const showModalEdit = () => { |
|||
|
|||
setIsModalVisible(true); |
|||
}; |
|||
|
|||
|
|||
//新增
|
|||
const handleOkAdd = () => { |
|||
form.validateFields().then((values) => { |
|||
const videoAddress = values.video.map((item) => { |
|||
return item.storageUrl |
|||
}) |
|||
const videoname = values.videoname |
|||
const data = { name: videoname, video: videoAddress } |
|||
dispatch(putAddPropagata(data)).then(() => { |
|||
dispatch(getPropagata()).then((res) => { |
|||
setCounts(res.payload.data) |
|||
}) |
|||
}) |
|||
setIsModalVisible(false); |
|||
} |
|||
); |
|||
}; |
|||
//编辑
|
|||
const handleOkEdit = (record) => { |
|||
|
|||
form.validateFields().then((values) => { |
|||
const videoAddress = values.video.map((item) => { |
|||
return item.storageUrl |
|||
}) |
|||
const videoname = values.username |
|||
const id = record.id |
|||
const video = record.video |
|||
|
|||
const data = { publicityId: id, name: videoname, video: video } |
|||
dispatch(putEditPropagata(data)).then(() => { |
|||
dispatch(getPropagata()).then((res) => { |
|||
setCounts(res.payload.data) |
|||
|
|||
}) |
|||
}) |
|||
|
|||
} |
|||
); |
|||
setIsModalVisible(false); |
|||
}; |
|||
|
|||
|
|||
|
|||
const handleCancel = () => { |
|||
setIsModalVisible(false); |
|||
}; |
|||
|
|||
const onFinish = (values) => { |
|||
console.log('Success:', values); |
|||
}; |
|||
|
|||
const onFinishFailed = (errorInfo) => { |
|||
console.log('Failed:', errorInfo); |
|||
}; |
|||
|
|||
|
|||
|
|||
return ( |
|||
<div > |
|||
{ |
|||
props.type_ys ? <div><Button type='primary' onClick={showModal}>新增</Button> |
|||
<Modal visible={isModalVisible} onOk={handleOkAdd} onCancel={handleCancel}> |
|||
<Form |
|||
form={form} |
|||
name="basic" |
|||
labelCol={{ |
|||
span: 5, |
|||
}} |
|||
wrapperCol={{ |
|||
span: 16, |
|||
}} |
|||
initialValues={{ |
|||
remember: true, |
|||
}} |
|||
onFinish={onFinish} |
|||
onFinishFailed={onFinishFailed} |
|||
autoComplete="off" |
|||
> |
|||
<Form.Item |
|||
label="视频名称" |
|||
name="videoname" |
|||
rules={[ |
|||
{ |
|||
required: true, |
|||
message: '请输入视频名称!', |
|||
max: 50, |
|||
}, |
|||
]} |
|||
> |
|||
<Input |
|||
placeholder="请输入视频名称" /> |
|||
</Form.Item> |
|||
|
|||
<Form.Item |
|||
label="选择视频" |
|||
name="video" |
|||
> |
|||
<Uploads |
|||
maxFilesNum={10} |
|||
fileTypes={['mp4']} |
|||
maxFileSize={200} |
|||
/> |
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
</div> |
|||
: |
|||
<div><Button type='link' onClick={showModalEdit} style={{ Position: "absolute", left: "-50px", top: "32px" }}>编辑</Button> |
|||
<Modal visible={isModalVisible} onOk={() => handleOkEdit(record)} onCancel={handleCancel}> |
|||
<Form |
|||
form={form} |
|||
name="basic" |
|||
labelCol={{ |
|||
span: 5, |
|||
}} |
|||
wrapperCol={{ |
|||
span: 16, |
|||
}} |
|||
initialValues={{ |
|||
username: record.name, video: record.video.map((item) => { |
|||
return { url: item } |
|||
}) |
|||
}} |
|||
onFinish={onFinish} |
|||
onFinishFailed={onFinishFailed} |
|||
autoComplete="off" |
|||
|
|||
> |
|||
<Form.Item |
|||
label="视频名称" |
|||
name="username" |
|||
rules={[ |
|||
{ |
|||
required: false, |
|||
message: '没有做出任何修改!', |
|||
max: 50, |
|||
}, |
|||
]} |
|||
> |
|||
<Input |
|||
placeholder="请输入视频名称" |
|||
/> |
|||
|
|||
</Form.Item> |
|||
<Form.Item |
|||
label="选择视频" |
|||
name="video" |
|||
> |
|||
<Uploads |
|||
maxFilesNum={10} |
|||
fileTypes={['mp4']} |
|||
maxFileSize={200} |
|||
/> |
|||
|
|||
|
|||
</Form.Item> |
|||
</Form> |
|||
</Modal> |
|||
</div> |
|||
} |
|||
</div > |
|||
) |
|||
} |
|||
|
|||
|
|||
|
|||
function mapStateToProps (state) { |
|||
const { depMessage } = state; |
|||
const pakData = (dep) => { |
|||
return dep.map((d) => { |
|||
return { |
|||
title: d.name, |
|||
value: d.id, |
|||
children: pakData(d.subordinate) |
|||
} |
|||
}) |
|||
} |
|||
let depData = pakData(depMessage.data || []) |
|||
return { |
|||
loading: depMessage.isRequesting, |
|||
depData, |
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(VideoUpload); |
@ -1,169 +1,181 @@ |
|||
import React, { useEffect, useState } from 'react'; |
|||
import React, { useEffect, useState} from 'react'; |
|||
import { connect } from 'react-redux'; |
|||
import { Spin, Button, Popconfirm, Badge } from 'antd'; |
|||
import { Spin, Button, Popconfirm, Switch } from 'antd'; |
|||
import ProTable from '@ant-design/pro-table'; |
|||
import './protable.less' |
|||
import moment from 'moment'; |
|||
import { getReportStatistic } from "../actions/infor" |
|||
import VideoUpload from './infor/videoUpload'; |
|||
import { getPropagata } from '../actions/infor'; |
|||
import { putEditPropagata } from '../actions/infor'; |
|||
import { delPropagata } from '../actions/infor'; |
|||
|
|||
const promotionalTable = (props) => { |
|||
const { dispatch, user, depData, depMessage, depLoading } = props |
|||
const [rowSelected, setRowSelected] = useState([]) |
|||
const [regionId, setRegionId] = useState()//区域id
|
|||
const [placeType, setPlaceType] = useState()//场所
|
|||
const [day, setDay] = useState([moment('2022-03-01').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')])//日期
|
|||
const [sitename, setSitename] = useState()//场所名称
|
|||
const [counts, setCounts] = useState()//shuju
|
|||
const { dispatch, } = props |
|||
const [rowSelected, setRowSelected] = useState([]) |
|||
const [counts, setCounts] = useState()//shuju
|
|||
|
|||
const onClickEnable = (record) => { |
|||
const id = record.id |
|||
const name = record.name |
|||
const video = record.video |
|||
|
|||
const columns = |
|||
[{ |
|||
title: '序号', |
|||
search: false, |
|||
dataIndex: 'containers', |
|||
const enable = true ? record.enable == false : true |
|||
const data = ({ publicityId: id, name: name, video: video, enable: enable }) |
|||
dispatch(putEditPropagata(data)).then((res) => { |
|||
dispatch(getPropagata()).then((res) => { |
|||
setCounts(res.payload.data) |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
fixed: 'left', |
|||
width: 120, |
|||
render: (dom, record) => { |
|||
return record.address |
|||
}, |
|||
fieldProps: { |
|||
getPopupContainer: (triggerNode) => triggerNode.parentNode, |
|||
} |
|||
}, |
|||
{ |
|||
title: '视频名称', |
|||
dataIndex: 'placeName', |
|||
fixed: 'left', |
|||
width: 120, |
|||
options: 1, |
|||
backgroundColor: "#ffffff", |
|||
fieldProps: { |
|||
onChange: (value, cs) => { |
|||
setSitename(value.currentTarget.value) |
|||
}, |
|||
placeholder: '请输入视频名称进行搜索', |
|||
getPopupContainer: (triggerNode) => triggerNode.parentNode, |
|||
}, |
|||
}, |
|||
|
|||
{ |
|||
title: '修改时间', |
|||
search: false, |
|||
dataIndex: 'time2', |
|||
valueType: 'dateRange', |
|||
// align: 'right',
|
|||
width: 120, |
|||
render: (dom, record) => { |
|||
return record.address |
|||
}, |
|||
fieldProps: { |
|||
getPopupContainer: (triggerNode) => triggerNode.parentNode, |
|||
} |
|||
}, |
|||
{ |
|||
key: "direction", |
|||
hideInTable: true, |
|||
dataIndex: "direction", |
|||
order: 6, |
|||
renderFormItem: (item, { type, defaultRender, ...rest }, form) => { |
|||
return ( |
|||
<div> <Button |
|||
type="primary" |
|||
style={{ width: "100px" }} |
|||
onClick={() => { |
|||
dispatch(push(`article/update/post`)); |
|||
}} |
|||
> |
|||
新增 |
|||
</Button> |
|||
</div> |
|||
|
|||
|
|||
); |
|||
}, |
|||
}, |
|||
] |
|||
return ( |
|||
<Spin spinning={false}> |
|||
<div className='protable-transpor'> |
|||
<ProTable |
|||
scroll={{ x: 800 }} |
|||
options={false} |
|||
ref={c => { finishedProductTable = c; }} |
|||
style={{ width: "100% ", overflow: "auto", height: '760px' }} |
|||
rowKey='id' |
|||
onReset={(v) => { |
|||
const { id } = depMessage[0] |
|||
console.log(id) |
|||
setRegionId(id) |
|||
setPlaceType(-1) |
|||
setDay([moment('2022-03-01').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]) |
|||
setSitename('') |
|||
}} |
|||
rowSelection={{ |
|||
selectedRowKeys: rowSelected, |
|||
onChange: (selectedRowKeys) => { |
|||
setRowSelected(selectedRowKeys); |
|||
}, |
|||
}} |
|||
columns={columns} |
|||
const columns = |
|||
[{ |
|||
title: '序号', |
|||
search: false, |
|||
dataIndex: 'containers', |
|||
fixed: 'left', |
|||
width: 120, |
|||
render: (dom, record, key) => { |
|||
return key + 1 |
|||
} |
|||
}, |
|||
{ |
|||
title: '视频名称', |
|||
dataIndex: 'videoName', |
|||
fixed: 'left', |
|||
search: false, |
|||
width: 120, |
|||
options: 1, |
|||
render: (dom, record) => { |
|||
return record.name |
|||
} |
|||
}, |
|||
{ |
|||
title: '是否展示', |
|||
dataIndex: 'shuffling', |
|||
valueType: 'shufflingRange', |
|||
search: false, |
|||
width: 120, |
|||
fixed: 'right', |
|||
render: (dom, record) => { |
|||
return <div > |
|||
|
|||
dataSource={(counts || {}).rows || []} |
|||
request={async (params) => { |
|||
<Switch checkedChildren="展示" unCheckedChildren="关闭" onClick={() => onClickEnable(record)} defaultChecked={true ? record.enable == true : false} /></div> |
|||
} |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
dataIndex: 'creatTime', |
|||
valueType: 'dateTimeRange', |
|||
hideInSearch: true, |
|||
width: 120, |
|||
fixed: 'right', |
|||
render: (dom, record) => { |
|||
return <div style={{ position: 'relative', marginTop: '-30px' }}> |
|||
<VideoUpload record={record} counts={counts} setCounts={setCounts} /> |
|||
<Popconfirm |
|||
title="是否确定删除?" |
|||
arrowPointAtCenter={true} |
|||
showArrow={true} |
|||
position="topRight" |
|||
onConfirm={ |
|||
() => { |
|||
const query = { |
|||
// startDate: day[0],
|
|||
// endDate: day[1],
|
|||
// placeType: placeType,
|
|||
// regionId: regionId,
|
|||
// placeName: sitename,
|
|||
// limit: params.pageSize,
|
|||
// offset: ((params.current ? params.current : 1) - 1) * params.pageSize
|
|||
} |
|||
setRowSelected([]); |
|||
const res = await dispatch(getReportStatistic(query)); |
|||
setCounts(res.payload.data) |
|||
return { |
|||
...res, |
|||
total: res.payload.data ? res.payload.data.count : 0 |
|||
publicityId: record.id |
|||
} |
|||
}} |
|||
// search={{
|
|||
// defaultCollapsed: false,
|
|||
// optionRender: (searchConfig, formProps, dom) => [
|
|||
// ...dom.reverse(),
|
|||
// <Popconfirm title="确认导出?" onConfirm={() => { props.exports(rowSelected, counts) }}>
|
|||
// <Button
|
|||
// >
|
|||
// 导出
|
|||
// </Button>
|
|||
// </Popconfirm>
|
|||
// ],
|
|||
// }}
|
|||
dispatch(delPropagata(query)).then(() => { |
|||
dispatch(getPropagata()).then((res) => { |
|||
setCounts(res.payload.data) |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
|
|||
> |
|||
<Button type="link" float="right" |
|||
>删除</Button> |
|||
</Popconfirm> |
|||
</div> |
|||
|
|||
} |
|||
}, |
|||
{ |
|||
key: "direction", |
|||
hideInTable: true, |
|||
dataIndex: "direction", |
|||
order: 6, |
|||
renderFormItem: (item, { type, defaultRender, ...rest }, form, record) => { |
|||
return ( |
|||
<div> |
|||
<VideoUpload type_ys={1} counts={counts} setCounts={setCounts} /> |
|||
</div> |
|||
); |
|||
}, |
|||
}, |
|||
] |
|||
|
|||
> |
|||
</ProTable></div> |
|||
//获取数据
|
|||
useEffect(() => { |
|||
const vedio = dispatch(getPropagata()).then((res) => { |
|||
setCounts(res.payload.data) |
|||
console.log(res.payload.data) |
|||
}) |
|||
}, []) |
|||
|
|||
</Spin > |
|||
) |
|||
|
|||
return ( |
|||
|
|||
<Spin spinning={false}> |
|||
<div className='protable-transpor'> |
|||
<ProTable |
|||
scroll={{ x: 800 }} |
|||
options={false} |
|||
style={{ width: "100% ", overflow: "auto", height: '760px' }} |
|||
rowKey='id' |
|||
rowSelection={{ |
|||
selectedRowKeys: rowSelected, |
|||
onChange: (selectedRowKeys) => { |
|||
setRowSelected(selectedRowKeys); |
|||
}, |
|||
}} |
|||
form={{ |
|||
submitter: false, |
|||
}} |
|||
columns={columns} |
|||
dataSource={counts || []} |
|||
request={async (params) => { |
|||
const query = { |
|||
limit: params.pageSize, |
|||
offset: ((params.current ? params.current : 1) - 1) * params.pageSize |
|||
} |
|||
setRowSelected([]); |
|||
}} |
|||
> |
|||
</ProTable></div> |
|||
</Spin > |
|||
) |
|||
} |
|||
function mapStateToProps(state) { |
|||
const { auth, depMessage } = state; |
|||
const pakData = (dep) => { |
|||
return dep.map((d) => { |
|||
return { |
|||
title: d.name, |
|||
value: d.id, |
|||
// children: d.type >= 2 ? [] : pakData(d.subordinate)
|
|||
children: pakData(d.subordinate) |
|||
} |
|||
}) |
|||
} |
|||
let depData = pakData(depMessage.data || []) |
|||
return { |
|||
user: auth.user, |
|||
depMessage: depMessage.data || [], |
|||
depLoading: depMessage.isRequesting, |
|||
depData, |
|||
}; |
|||
|
|||
function mapStateToProps (state) { |
|||
|
|||
const { auth, depMessage } = state; |
|||
const pakData = (dep) => { |
|||
return dep.map((d) => { |
|||
return { |
|||
title: d.name, |
|||
value: d.id, |
|||
// children: d.type >= 2 ? [] : pakData(d.subordinate)
|
|||
children: pakData(d.subordinate) |
|||
} |
|||
}) |
|||
} |
|||
let depData = pakData(depMessage.data || []) |
|||
return { |
|||
user: auth.user, |
|||
depMessage: depMessage.data || [], |
|||
depLoading: depMessage.isRequesting, |
|||
depData, |
|||
}; |
|||
} |
|||
export default connect(mapStateToProps)(promotionalTable); |
Loading…
Reference in new issue