Browse Source

视频播放完成

dev
wenlele 2 years ago
parent
commit
e430b16418
  1. 1
      web/client/src/layout/actions/global.js
  2. 2
      web/client/src/layout/reducers/global.js
  3. 13
      web/client/src/sections/problem/actions/problem.jsx
  4. 25
      web/client/src/sections/problem/components/tableData.jsx
  5. 36
      web/client/src/sections/problem/containers/dataAlarm.jsx
  6. 1
      web/client/src/utils/webapi.js
  7. 6
      web/config.js
  8. 2
      web/package.json
  9. 3
      web/routes/attachment/index.js

1
web/client/src/layout/actions/global.js

@ -38,6 +38,7 @@ export function initApiRoot () {
type: INIT_API_ROOT, type: INIT_API_ROOT,
payload: { payload: {
apiRoot: res.root, apiRoot: res.root,
iotVcmpWeb:res.iotVcmpWeb,
} }
}) })
}); });

2
web/client/src/layout/reducers/global.js

@ -11,6 +11,7 @@ function global (state = {
clientHeight: 768, clientHeight: 768,
clientWidth: 1024, clientWidth: 1024,
apiRoot: '', apiRoot: '',
iotVcmpWeb: '',
}, action) { }, action) {
const payload = action.payload; const payload = action.payload;
switch (action.type) { switch (action.type) {
@ -30,6 +31,7 @@ function global (state = {
case INIT_API_ROOT: case INIT_API_ROOT:
return Immutable.fromJS(state).merge({ return Immutable.fromJS(state).merge({
apiRoot: payload.apiRoot, apiRoot: payload.apiRoot,
iotVcmpWeb: payload.iotVcmpWeb
}).toJS(); }).toJS();
default: default:
return state; return state;

13
web/client/src/sections/problem/actions/problem.jsx

@ -34,7 +34,7 @@ export function putAlarmApplicationNoted (data) { //预览状态
data, data,
actionType: 'PUT-AIARM-APPLICATIO-NNOTED', actionType: 'PUT-AIARM-APPLICATIO-NNOTED',
url: `${ApiTable.putAlarmApplicationNoted}`, url: `${ApiTable.putAlarmApplicationNoted}`,
msg: { option: '预览失败' }, msg: { option: '预览' },
reducer: { name: '' } reducer: { name: '' }
}); });
} }
@ -159,3 +159,14 @@ export function putAlarmVideoConfirm (data) { //确认视频告警
reducer: { name: '' } reducer: { name: '' }
}); });
} }
export function getVcmpAuth () { //token
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,
actionType: 'GET_VCMP_AUTH',
url: `${ApiTable.getVcmpAuth}`,
msg: { option: '获取视频平台应用鉴权token' },
reducer: { name: '' }
});
}

25
web/client/src/sections/problem/components/tableData.jsx

@ -25,7 +25,6 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
console.log(res.payload.data) console.log(res.payload.data)
if (res.success) { if (res.success) {
let typeData = { element: "元素异常", apiError: "接口报错 ", timeout: "加载超时" } let typeData = { element: "元素异常", apiError: "接口报错 ", timeout: "加载超时" }
setCount(res.payload.data?.count || 0)
let tableDatas = res.payload.data?.rows.map(v => ({ let tableDatas = res.payload.data?.rows.map(v => ({
key: v.id, key: v.id,
// serialNumber: v.serialNumber, // serialNumber: v.serialNumber,
@ -43,14 +42,15 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
confirm: v.confirm, confirm: v.confirm,
})) }))
// console.log(tableDatas); // console.log(tableDatas);
setCount(tableDatas?.length || 0);
setTableData(tableDatas) setTableData(tableDatas)
} }
}) })
break; break;
case 'videoAbnormal': case 'videoAbnormal':
dispatch(problem.getAlarmVideoList({})).then((res) => { dispatch(problem.getAlarmVideoList({ ...search, pepProjectId: '' })).then((res) => {
if (res.success) { if (res.success) {
console.log(res); // console.log(res);
let tableDatas = res.payload.data?.map(v => ({ let tableDatas = res.payload.data?.map(v => ({
key: v.alarmId, key: v.alarmId,
StructureName: v.struc, StructureName: v.struc,
@ -61,12 +61,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
updateTime: v.updateTime ? moment(v.updateTime).format("YYYY-MM-DD HH:mm:ss") : "", updateTime: v.updateTime ? moment(v.updateTime).format("YYYY-MM-DD HH:mm:ss") : "",
confirmTime: v.confirmTime ? moment(v.confirmTime).format("YYYY-MM-DD HH:mm:ss") : "", confirmTime: v.confirmTime ? moment(v.confirmTime).format("YYYY-MM-DD HH:mm:ss") : "",
SourceName: v.cameraName, SourceName: v.cameraName,
// AlarmGroupUnit: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "", yingshiToken: v.yingshiToken,
// Strategy: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "",
// type: v.AlarmGroupUnit ? genreData.find(r => r.value == v.AlarmGroupUnit)?.name : "",
// AlarmCodeName: v.AlarmCodeName,
// CurrentLevel: v.CurrentLevel,
// detailCount: v.detailCount,
AlarmContent: v.statusDescribe, AlarmContent: v.statusDescribe,
// State: v.State, // State: v.State,
station: v.station, station: v.station,
@ -79,7 +74,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
confirm: v.confirmedContent, confirm: v.confirmedContent,
camerOnline: v.camerOnline, camerOnline: v.camerOnline,
})) }))
console.log(tableDatas); // console.log(tableDatas);
setCount(tableDatas?.length || 0); setCount(tableDatas?.length || 0);
setTableData(tableDatas) setTableData(tableDatas)
} }
@ -180,7 +175,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
field={v.field} field={v.field}
placeholder="项目或应用关键字" placeholder="项目或应用关键字"
showClear showClear
style={{ width: 115, marginRight: 16, marginBottom: 16 }} />) style={{ width: 146, marginRight: 16, marginBottom: 16 }} />)
} else { } else {
frame.push(<Form.InputGroup key={v.field} label={v.name + ':'} labelPosition="left" style={{ width: 203, marginRight: 16, marginBottom: 16 }}> frame.push(<Form.InputGroup key={v.field} label={v.name + ':'} labelPosition="left" style={{ width: 203, marginRight: 16, marginBottom: 16 }}>
<Form.Select style={{ width: 88 }} field='keywordTarget' initValue='source' rules={[{ required: true, message: '请选择筛选类型' }]} showClear> <Form.Select style={{ width: 88 }} field='keywordTarget' initValue='source' rules={[{ required: true, message: '请选择筛选类型' }]} showClear>
@ -282,7 +277,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
> >
<Table <Table
columns={exhibition} columns={exhibition}
dataSource={route == 'useAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData} dataSource={route == 'useAbnormal' || route == 'videoAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData}
// dataSource={[{ key: '1' }]} // dataSource={[{ key: '1' }]}
bordered={false} bordered={false}
empty="暂无数据" empty="暂无数据"
@ -323,7 +318,7 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
<div style={{ display: 'inline-block', lineHeight: '30px', fontSize: 13 }}>勾选<span style={{ fontWeight: 400, color: '#0F7EFB', margin: '0 6px' }}>{selected.length}</span>问题</div> <div style={{ display: 'inline-block', lineHeight: '30px', fontSize: 13 }}>勾选<span style={{ fontWeight: 400, color: '#0F7EFB', margin: '0 6px' }}>{selected.length}</span>问题</div>
<Button onClick={() => { <Button onClick={() => {
if (checkAll) { if (checkAll) {
setSelected((route == 'useAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData)?.map(v => { setSelected((route == 'useAbnormal' || route == 'videoAbnormal' ? tableData.slice(query.page * query.limit, (query.page + 1) * query.limit) || [] : tableData)?.map(v => {
if (['videoAbnormal', 'useAbnormal'].includes(route)) { if (['videoAbnormal', 'useAbnormal'].includes(route)) {
if (!v.confirmTime) { if (!v.confirmTime) {
return v.key return v.key
@ -346,11 +341,11 @@ const TableData = ({ route, dispatch, actions, collectData, setSetup, exhibition
</div> </div>
{count > 0 ? <div style={{ display: 'flex', }}> {count > 0 ? <div style={{ display: 'flex', }}>
<span style={{ lineHeight: "30px", fontSize: 13 }}> <span style={{ lineHeight: "30px", fontSize: 13 }}>
{route == 'useAbnormal' ? tableData.length : count}个问题 {count}个问题
</span> </span>
<Pagination <Pagination
className="22" className="22"
total={route == 'useAbnormal' ? tableData.length : count} total={count}
showSizeChanger showSizeChanger
currentPage={(query?.page || 0) + 1} currentPage={(query?.page || 0) + 1}
pageSizeOpts={[10, 20, 30, 40]} pageSizeOpts={[10, 20, 30, 40]}

36
web/client/src/sections/problem/containers/dataAlarm.jsx

@ -14,7 +14,7 @@ import { request } from 'screenfull';
import { useRef } from 'react'; import { useRef } from 'react';
import { render } from 'less'; import { render } from 'less';
const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => { const DataAlarm = ({ match, dispatch, actions, user, loading, socket, iotVcmpWeb }) => {
let route = match.url.substring(match.url.lastIndexOf("/") + 1, match.url.length) let route = match.url.substring(match.url.lastIndexOf("/") + 1, match.url.length)
const { problem } = actions const { problem } = actions
@ -36,6 +36,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
const [tableData, setTableData] = useState([]) // const [tableData, setTableData] = useState([]) //
const [videoModal, setVideoModal] = useState(false) // const [videoModal, setVideoModal] = useState(false) //
const [videoData, setVideoData] = useState({}) // const [videoData, setVideoData] = useState({}) //
const [videoToken, setVideoToken] = useState() //token
@ -57,9 +58,14 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
: ""; : "";
} }
attribute(tableType[route], route); attribute(tableType[route], route);
//token
dispatch(problem.getVcmpAuth({})).then((res) => {
if (res.success) setVideoToken(res.payload.data?.token)
})
}, []) }, [])
// console.log(selected); // console.log(videoData);
// //
const collectData = { const collectData = {
@ -277,7 +283,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
}, },
{ name: '设备厂家', sort: 10, value: 'venderName', render: (_, r, index) => r.platform ? '未知' : r.venderName }, { name: '设备厂家', sort: 10, value: 'venderName', render: (_, r, index) => r.platform ? '未知' : r.venderName },
{ name: '通道号', sort: 10.1, value: 'cameraChannelNo' }, { name: '通道号', sort: 10.1, value: 'cameraChannelNo' },
{ name: '列号', sort: 10.2, value: 'cameraSerialNo' }, { name: '列号', sort: 10.2, value: 'cameraSerialNo' },
{ {
name: '接入方式', sort: 9, value: 'platform', render: (_, r, index) => { name: '接入方式', sort: 9, value: 'platform', render: (_, r, index) => {
let accessType = { yingshi: "萤石云", nvr: "NVR", ipc: "IPC", cascade: "级联" } let accessType = { yingshi: "萤石云", nvr: "NVR", ipc: "IPC", cascade: "级联" }
@ -288,7 +294,12 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
{ name: 'URL地址', sort: 16, value: 'url' }, { name: 'URL地址', sort: 16, value: 'url' },
{ name: '异常类型', sort: 6, value: 'type' }, { name: '异常类型', sort: 6, value: 'type' },
{ name: '解决方案', sort: 17, value: 'resolve', render: (_, r, index) => r.resolve?.map(v => <div key={v.resolve + v.id} style={{ lineHeight: "22px" }}>{v.resolve}</div>) }, { name: '解决方案', sort: 17, value: 'resolve', render: (_, r, index) => r.resolve?.map(v => <div key={v.resolve + v.id} style={{ lineHeight: "22px" }}>{v.resolve}</div>) },
{ name: '在离线', sort: 18, value: 'camerOnline' }, {
name: '在离线', sort: 18, value: 'camerOnline', render: (_, r, index) => {
let data = { ON: '在线', ONLINE: "在线", OFF: "离线" }
return data[r.camerOnline] || '未知'
}
},
{ {
name: '操作', sort: 25, value: 'text', render: (_, r, index) => { name: '操作', sort: 25, value: 'text', render: (_, r, index) => {
return <div style={{ width: 195 }}> return <div style={{ width: 195 }}>
@ -312,7 +323,7 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
<Button theme='borderless' style={{ width: 65 }} disabled>已派单</Button> <Button theme='borderless' style={{ width: 65 }} disabled>已派单</Button>
<Button theme='borderless' style={{ width: 65 }} onClick={() => { <Button theme='borderless' style={{ width: 65 }} onClick={() => {
setVideoModal(true) setVideoModal(true)
setVideoData({ channeNo: r.cameraChannelNo, serialNo: r.cameraSerialNo, type: r.platform }) setVideoData({ channeNo: r.cameraChannelNo, serialNo: r.cameraSerialNo, type: r.platform, yingshiToken: r.yingshiToken })
}}>播放</Button> }}>播放</Button>
</> : "" </> : ""
} }
@ -322,7 +333,6 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
] ]
const attribute = (name, route) => { const attribute = (name, route) => {
let arr = localStorage.getItem(name) let arr = localStorage.getItem(name)
? JSON.parse(localStorage.getItem(name)) ? JSON.parse(localStorage.getItem(name))
@ -505,12 +515,13 @@ const DataAlarm = ({ match, dispatch, actions, user, loading, socket }) => {
<div style={{ width: 918, height: 460, marginLeft: -24 }}> <div style={{ width: 918, height: 460, marginLeft: -24 }}>
<iframe <iframe
allowFullScreen allowFullScreen
src={`https://mediaconsole.ngaiot.com/video_play_cross?slideDown=true&videoObj=${encodeURIComponent(JSON.stringify({ src={`${iotVcmpWeb}/video_play_cross?videoObj=${encodeURIComponent(JSON.stringify({
channelNo: 1, channelNo: videoData.channeNo,
content: ['5442542542', '452345', '234524525'], // content: ['5442542542', '452345', '234524525'],
serialNo: "F61504020", serialNo: videoData.serialNo,
type: "yingshi", type: videoData.type,
yingshiToken: "at.7tj6k9mzcwmn112xag96e23tcdsta8nn-7p2qvqv6zq-1k500nr-tsd9bn01o" yingshiToken: videoData.yingshiToken,
videoToken: videoToken,
// type: 'cascade', // type: 'cascade',
// serialNo: '34020000001310000003', // // serialNo: '34020000001310000003', //
// topSerialNo: '34020000001110000079', // // topSerialNo: '34020000001110000079', //
@ -548,6 +559,7 @@ function mapStateToProps (state) {
// loading: members.isRequesting, // loading: members.isRequesting,
user: auth.user, user: auth.user,
actions: global.actions, actions: global.actions,
iotVcmpWeb: global.iotVcmpWeb,
// members: members.data, // members: members.data,
// socket: webSocket.socket // socket: webSocket.socket
} }

1
web/client/src/utils/webapi.js

@ -46,6 +46,7 @@ export const ApiTable = {
getAlarmVideoList: 'alarm/video/list', //查询视频告警列表 getAlarmVideoList: 'alarm/video/list', //查询视频告警列表
getAlarmVideoDeviceKind: 'alarm/video/device_kind', //查询视频设备类型 getAlarmVideoDeviceKind: 'alarm/video/device_kind', //查询视频设备类型
putAlarmVideoConfirm: 'alarm/video/confirm', //确认视频告警信息 putAlarmVideoConfirm: 'alarm/video/confirm', //确认视频告警信息
getVcmpAuth: 'vcmp/auth', // 获取视频平台应用鉴权token
}; };

6
web/config.js

@ -15,6 +15,8 @@ args.option(['u', 'api-url'], 'webapi的URL');
args.option('apiPomsUrl', 'webapi的URL 外网可访问'); args.option('apiPomsUrl', 'webapi的URL 外网可访问');
args.option('apiAnxinyunUrl', '安心云 api'); args.option('apiAnxinyunUrl', '安心云 api');
args.option('apiEmisUrl', '企业管理 api'); args.option('apiEmisUrl', '企业管理 api');
args.option('iotVcmpWeb', 'IOT 视频服务');
// 七牛 // 七牛
args.option('qnak', 'qiniuAccessKey'); args.option('qnak', 'qiniuAccessKey');
args.option('qnsk', 'qiniuSecretKey'); args.option('qnsk', 'qiniuSecretKey');
@ -27,6 +29,7 @@ const API_URL = process.env.API_URL || flags.apiUrl;
const API_POMS_URL = process.env.API_POMS_URL || flags.apiPomsUrl; const API_POMS_URL = process.env.API_POMS_URL || flags.apiPomsUrl;
const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl; const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl;
const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.apiAnxinyunUrl; const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.apiAnxinyunUrl;
const IOT_VIDEO_WEB = process.env.IOT_VIDEO_WEB || flags.iotVcmpWeb;
// 七牛 // 七牛
const ANXINCLOUD_QINIU_AK = process.env.ANXINCLOUD_QINIU_ACCESSKEY || flags.qnak; const ANXINCLOUD_QINIU_AK = process.env.ANXINCLOUD_QINIU_ACCESSKEY || flags.qnak;
@ -38,7 +41,7 @@ const ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE = process.env.ANXINCLOUD_QINIU_DOMA
if ( if (
!API_URL !API_URL
|| !API_ANXINYUN_URL || !API_ANXINYUN_URL
|| !ANXINCLOUD_QINIU_AK || !ANXINCLOUD_QINIU_SK || !ANXINCLOUD_QINIU_BUCKET_RESOURCE || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE) { || !ANXINCLOUD_QINIU_AK || !ANXINCLOUD_QINIU_SK || !ANXINCLOUD_QINIU_BUCKET_RESOURCE || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE || !IOT_VIDEO_WEB) {
console.log('缺少启动参数,异常退出'); console.log('缺少启动参数,异常退出');
args.showHelp(); args.showHelp();
process.exit(-1); process.exit(-1);
@ -81,6 +84,7 @@ const product = {
entry: require('./routes').entry, entry: require('./routes').entry,
opts: { opts: {
apiUrl: API_POMS_URL, apiUrl: API_POMS_URL,
iotVcmpWeb: IOT_VIDEO_WEB,
staticRoot: './client', staticRoot: './client',
qiniu: { qiniu: {
fetchUrl: '/_file-server', fetchUrl: '/_file-server',

2
web/package.json

@ -7,7 +7,7 @@
"test": "mocha", "test": "mocha",
"start-vite": "cross-env NODE_ENV=developmentVite npm run start-params", "start-vite": "cross-env NODE_ENV=developmentVite npm run start-params",
"start": "cross-env NODE_ENV=development npm run start-params", "start": "cross-env NODE_ENV=development npm run start-params",
"start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://10.8.30.112:14000 --qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5 --qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa --qnbkt dev-highways4good --qndmn http://rhvqdivo5.hn-bkt.clouddn.com", "start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://10.8.30.112:14000 --qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5 --qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa --qnbkt dev-highways4good --qndmn http://rhvqdivo5.hn-bkt.clouddn.com --iotVcmpWeb https://mediaconsole.ngaiot.com",
"deploy": "export NODE_ENV=production&& npm run build && node server", "deploy": "export NODE_ENV=production&& npm run build && node server",
"build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js", "build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js",
"build": "cross-env NODE_ENV=production&&webpack --config webpack.config.prod.js" "build": "cross-env NODE_ENV=production&&webpack --config webpack.config.prod.js"

3
web/routes/attachment/index.js

@ -19,11 +19,12 @@ module.exports = {
entry: function (app, router, opts) { entry: function (app, router, opts) {
const getApiRoot = async function (ctx) { const getApiRoot = async function (ctx) {
const { apiUrl, } = opts; const { apiUrl, iotVcmpWeb } = opts;
ctx.status = 200; ctx.status = 200;
ctx.body = { ctx.body = {
root: apiUrl, root: apiUrl,
iotVcmpWeb: iotVcmpWeb,
}; };
}; };

Loading…
Cancel
Save