refactor(map): branchOffice Camera 对接
parent
97792143b0
commit
da80837605
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Spin } from "antd";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import AliPlayer from "zy-react-library/components/Video/AliPlayer";
|
||||||
|
|
||||||
|
function VideoItem({ cameraNumber, videoName, getFixedCameraPlayUrl }) {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [playUrl, setPlayUrl] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let isUnmounted = false;
|
||||||
|
|
||||||
|
const loadPlayUrl = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
setPlayUrl("");
|
||||||
|
const { data = {}, success } = await getFixedCameraPlayUrl({ indexCode: cameraNumber });
|
||||||
|
if (!isUnmounted && success)
|
||||||
|
setPlayUrl(data?.url || "");
|
||||||
|
|
||||||
|
if (!isUnmounted)
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadPlayUrl();
|
||||||
|
return () => {
|
||||||
|
isUnmounted = true;
|
||||||
|
};
|
||||||
|
}, [cameraNumber]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="branch-office-camera-modal__video">
|
||||||
|
<div className="branch-office-camera-modal__video-name">{videoName}</div>
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
{playUrl
|
||||||
|
? <AliPlayer source={playUrl} height="100%" isLive />
|
||||||
|
: <div className="branch-office-camera-modal__empty">暂无视频</div>}
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VideoItem;
|
||||||
|
|
@ -1,95 +1,133 @@
|
||||||
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
import { useBoolean } from "ahooks";
|
import { useBoolean } from "ahooks";
|
||||||
import { Modal } from "antd";
|
import { Button, Modal, Spin } from "antd";
|
||||||
import { useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import AliPlayer from "zy-react-library/components/Video/AliPlayer";
|
import useDictionary from "zy-react-library/hooks/useDictionary";
|
||||||
|
import { NS_BI_STATISTICS } from "~/enumerate/namespace";
|
||||||
|
import { Context } from "~/pages/Container/Map/js/context";
|
||||||
|
import VideoItem from "./VideoItem";
|
||||||
import "./index.less";
|
import "./index.less";
|
||||||
|
|
||||||
function Camera() {
|
const gridList = [
|
||||||
|
{ title: "四宫格", value: 4, gridColumnCount: 2, gridRowCount: 2 },
|
||||||
|
{ title: "六宫格", value: 6, gridColumnCount: 3, gridRowCount: 2 },
|
||||||
|
{ title: "九宫格", value: 9, gridColumnCount: 3, gridRowCount: 3 },
|
||||||
|
{ title: "单画面", value: 1, gridColumnCount: 1, gridRowCount: 1 },
|
||||||
|
];
|
||||||
|
function Camera(props) {
|
||||||
|
const { portArea, currentBranchOffice } = useContext(Context);
|
||||||
|
|
||||||
|
const { getDictionary, loading: dictionaryLoading } = useDictionary();
|
||||||
const [state, { setFalse }] = useBoolean(true);
|
const [state, { setFalse }] = useBoolean(true);
|
||||||
const [parentList, setParentList] = useState([
|
const [currentGrid, setCurrentGrid] = useState(9);
|
||||||
{ title: "一级一级一级一级一级一级一级一级一级一级一级一级一级一级一级一级" },
|
const [levelList, setLevelList] = useState([]);
|
||||||
{ title: "二级" },
|
const [currentLevel, setCurrentLevel] = useState("");
|
||||||
{ title: "三级" },
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
]);
|
const [videoList, setVideoList] = useState([]);
|
||||||
const [parentCurrentIndex, setParentCurrentIndex] = useState(0);
|
|
||||||
const [childList, setChildList] = useState([
|
|
||||||
{ title: "一级_一一级_一一级_一一级_一一级_一一级_一一级_一一级_一一级_一一级_一" },
|
|
||||||
{ title: "一级_二" },
|
|
||||||
{ title: "一级_三" },
|
|
||||||
{ title: "一级_四" },
|
|
||||||
{ title: "一级_五" },
|
|
||||||
{ title: "一级_六" },
|
|
||||||
]);
|
|
||||||
const [childCurrentIndex, setChildCurrentIndex] = useState(0);
|
|
||||||
const [videoList, setVideoList] = useState([
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
{ src: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const onChangeParentList = (index) => {
|
const loadData = async () => {
|
||||||
if (index === parentCurrentIndex)
|
const [dictionaryData, { data = [] }] = await Promise.all([
|
||||||
return;
|
getDictionary({ dictValue: "videoLevel" }),
|
||||||
setParentCurrentIndex(index);
|
props.getFixedCameraVideoInfoPage({
|
||||||
setChildCurrentIndex(0);
|
portArea,
|
||||||
|
corpinfoId: currentBranchOffice,
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 9999,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
setLevelList(dictionaryData);
|
||||||
|
setVideoList(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeChildList = (index) => {
|
useEffect(() => {
|
||||||
if (index === childCurrentIndex)
|
loadData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onChangeCurrentGrid = (value) => {
|
||||||
|
if (value === currentGrid)
|
||||||
return;
|
return;
|
||||||
setChildCurrentIndex(index);
|
setCurrentGrid(value);
|
||||||
|
setCurrentPage(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onChangeChildList = (value) => {
|
||||||
|
if (value === currentLevel)
|
||||||
|
return;
|
||||||
|
setCurrentLevel(value);
|
||||||
|
setCurrentPage(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 先按左侧等级筛选,再按当前宫格数量截取当前页,只有这些视频格会请求播放地址。
|
||||||
|
const filteredVideoList = videoList.filter(item => !currentLevel || item.videoLevel === currentLevel);
|
||||||
|
const pageCount = Math.ceil(filteredVideoList.length / currentGrid);
|
||||||
|
const currentVideoList = filteredVideoList.slice(currentPage * currentGrid, (currentPage + 1) * currentGrid);
|
||||||
|
const currentGridConfig = gridList.find(item => item.value === currentGrid);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
open={state}
|
open={state}
|
||||||
mask={{ closable: false }}
|
mask={{ closable: false }}
|
||||||
footer={null}
|
footer={[
|
||||||
|
<Button key="cancel" onClick={setFalse}>取消</Button>,
|
||||||
|
]}
|
||||||
width={1500}
|
width={1500}
|
||||||
onCancel={setFalse}
|
onCancel={setFalse}
|
||||||
title="视频巡屏"
|
title="视频巡屏"
|
||||||
classNames={{ wrapper: "map_content_branch_office_camera_modal map_bi_model" }}
|
classNames={{ wrapper: "branch-office-camera-modal map_bi_model" }}
|
||||||
>
|
>
|
||||||
<div className="container">
|
<div className="branch-office-camera-modal__container">
|
||||||
<div className="parent_tabs">
|
<Spin spinning={dictionaryLoading}>
|
||||||
{parentList.map((item, index) => (
|
<div className="branch-office-camera-modal__level-tabs">
|
||||||
|
{[{ dictValue: "", dictLabel: "全部" }, ...levelList].map(item => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={item.dictValue}
|
||||||
className={`tab ${parentCurrentIndex === index ? "active" : ""}`}
|
className={`branch-office-camera-modal__tab ${currentLevel === item.dictValue ? "branch-office-camera-modal__tab--active" : ""}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onChangeParentList(index);
|
onChangeChildList(item.dictValue);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.dictLabel}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Spin>
|
||||||
|
<div className="branch-office-camera-modal__content">
|
||||||
|
<div className="branch-office-camera-modal__grid-tabs">
|
||||||
|
{gridList.map(item => (
|
||||||
|
<div
|
||||||
|
key={item.value}
|
||||||
|
className={`branch-office-camera-modal__tab ${currentGrid === item.value ? "branch-office-camera-modal__tab--active" : ""}`}
|
||||||
|
onClick={() => {
|
||||||
|
onChangeCurrentGrid(item.value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item.title}
|
{item.title}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="info">
|
<Spin spinning={props.biStatistics.getFixedCameraVideoInfoPageLoading}>
|
||||||
<div className="child_tabs">
|
|
||||||
{childList.map((item, index) => (
|
|
||||||
<div
|
<div
|
||||||
key={index}
|
className="branch-office-camera-modal__videos"
|
||||||
className={`tab ${childCurrentIndex === index ? "active" : ""}`}
|
style={{
|
||||||
onClick={() => {
|
gridTemplateColumns: `repeat(${currentGridConfig.gridColumnCount}, 1fr)`,
|
||||||
onChangeChildList(index);
|
gridTemplateRows: `repeat(${currentGridConfig.gridRowCount}, minmax(0, 1fr))`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item.title}
|
{currentVideoList.length
|
||||||
|
? currentVideoList.map(item => (
|
||||||
|
<VideoItem
|
||||||
|
key={item.cameraNumber}
|
||||||
|
cameraNumber={item.cameraNumber}
|
||||||
|
videoName={item.videoName}
|
||||||
|
getFixedCameraPlayUrl={props.getFixedCameraPlayUrl}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
: <div className="branch-office-camera-modal__empty">暂无视频</div>}
|
||||||
</div>
|
</div>
|
||||||
))}
|
</Spin>
|
||||||
</div>
|
<div className="branch-office-camera-modal__pagination">
|
||||||
<div className="videos">
|
<Button disabled={currentPage === 0} onClick={() => setCurrentPage(currentPage - 1)}>上一组</Button>
|
||||||
{videoList.map((item, index) => (
|
<Button disabled={currentPage >= pageCount - 1} type="primary" onClick={() => setCurrentPage(currentPage + 1)}>下一组</Button>
|
||||||
<div key={index} className="video">
|
|
||||||
<AliPlayer source={item.src} height="150px" isLive />
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -97,4 +135,4 @@ function Camera() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Camera;
|
export default Connect([NS_BI_STATISTICS], true)(Camera);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
.map_content_branch_office_camera_modal {
|
.branch-office-camera-modal {
|
||||||
.container {
|
.branch-office-camera-modal__container {
|
||||||
.parent_tabs {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 14px;
|
|
||||||
|
|
||||||
.tab {
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
.branch-office-camera-modal__level-tabs {
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.branch-office-camera-modal__tab {
|
||||||
|
margin-top: 5px;
|
||||||
background-color: #0B1544;
|
background-color: #0B1544;
|
||||||
border: 1px solid #0c1957;
|
border: 1px solid #0c1957;
|
||||||
border-radius: 10px 10px 10px 2px;
|
border-radius: 10px 10px 10px 2px;
|
||||||
|
|
@ -19,25 +22,26 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.active {
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.branch-office-camera-modal__tab--active {
|
||||||
background-color: #1537CC;
|
background-color: #1537CC;
|
||||||
border: 1px solid rgba(0, 180, 255, 0.61);
|
border: 1px solid rgba(0, 180, 255, 0.61);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.branch-office-camera-modal__content {
|
||||||
margin-top: 12px;
|
flex: 1;
|
||||||
|
|
||||||
|
.branch-office-camera-modal__grid-tabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 25px;
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
.child_tabs {
|
.branch-office-camera-modal__tab {
|
||||||
width: 240px;
|
|
||||||
background-color: rgba(35, 55, 140, 0.15);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 50px 20px;
|
|
||||||
|
|
||||||
.tab {
|
|
||||||
background-color: #0B1544;
|
background-color: #0B1544;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 10px 2px;
|
border-radius: 10px 2px;
|
||||||
|
|
@ -45,26 +49,22 @@
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-top: 17px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
border: 1px solid #0c1957;
|
border: 1px solid #0c1957;
|
||||||
|
|
||||||
&:first-child {
|
&.branch-office-camera-modal__tab--active {
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background-color: #1537CC;
|
background-color: #1537CC;
|
||||||
border: 1px solid rgba(0, 180, 255, 0.61);
|
border: 1px solid rgba(0, 180, 255, 0.61);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.videos {
|
.branch-office-camera-modal__videos {
|
||||||
|
margin-top: 20px;
|
||||||
|
height: 632px;
|
||||||
background-color: rgba(35, 55, 140, 0.149);
|
background-color: rgba(35, 55, 140, 0.149);
|
||||||
flex: 1;
|
|
||||||
border: 1px solid rgb(9, 23, 93);
|
border: 1px solid rgb(9, 23, 93);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -72,10 +72,58 @@
|
||||||
gap: 20px 27px;
|
gap: 20px 27px;
|
||||||
padding: 35px 29px;
|
padding: 35px 29px;
|
||||||
|
|
||||||
.video {
|
.branch-office-camera-modal__video {
|
||||||
border: 1px solid #294695;
|
border: 1px solid #294695;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.branch-office-camera-modal__video-name {
|
||||||
|
height: 24px;
|
||||||
|
flex: none;
|
||||||
|
padding: 0 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-spin-nested-loading {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
.@{ant-prefix}-spin-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.branch-office-camera-modal__empty {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .branch-office-camera-modal__empty {
|
||||||
|
min-height: 150px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.branch-office-camera-modal__pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@
|
||||||
|
|
||||||
&-close {
|
&-close {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-header {
|
&-header {
|
||||||
|
|
@ -123,6 +127,12 @@
|
||||||
&-empty-description {
|
&-empty-description {
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-btn{
|
||||||
|
&:disabled {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue