diff --git a/src/api/biMark/index.js b/src/api/biMark/index.js index c8ce112..91b101b 100644 --- a/src/api/biMark/index.js +++ b/src/api/biMark/index.js @@ -32,3 +32,11 @@ export const getEightWorkInfoScreenWorkList = declareRequest( "biFullLoading", "Post > @/eightwork/eightworkInfo/screenWorkPage", ); +export const getKeyProjectLargeScreenList = declareRequest( + "biFullLoading", + "Post > @/keyProject/keyProject/largeScreenPage", +); +export const getFixedCameraVideoList = declareRequest( + "biFullLoading", + "Post > @/videopatrol/fixedCamera/getVideoList", +); diff --git a/src/api/biMarkInfo/index.js b/src/api/biMarkInfo/index.js index 7d10e6e..2cac1bc 100644 --- a/src/api/biMarkInfo/index.js +++ b/src/api/biMarkInfo/index.js @@ -36,3 +36,11 @@ export const eightWorkMeasuresLogs = declareRequest( "biFullLoading", `Get > /eightwork/measuresLogs/listAll/{workId}`, ); +export const keyProjectInfo = declareRequest( + "biFullLoading", + "Get > /keyProject/keyProject/{id}", +); +export const getFixedCameraPlayUrl = declareRequest( + "biFullLoading", + "Get > /videopatrol/fixedCamera/getPlayUrl", +); diff --git a/src/api/biStatistics/index.js b/src/api/biStatistics/index.js index 601c859..9348e15 100644 --- a/src/api/biStatistics/index.js +++ b/src/api/biStatistics/index.js @@ -72,3 +72,11 @@ export const getEightWorkInfoScreenWorkTrend = declareRequest( "portWeiXianEightWorkInfoScreenWorkTrendLoading", "Post > @/eightwork/eightworkInfo/screenWorkTrend", ); +export const getKeyProjectLargeScreenProjectStatistics = declareRequest( + "portZhongDianKeyProjectLargeScreenProjectStatisticsLoading", + "Post > @/keyProject/keyProject/largeScreenProjectStatistics", +); +export const getFixedCameraVideoLocationStat = declareRequest( + "portZhongDianFixedCameraVideoLocationStatLoading", + "Post > @/videopatrol/fixedCamera/getVideoLocationStat", +); diff --git a/src/pages/Container/Map/components/BottomUtils/branchOfficeUtilsList.js b/src/pages/Container/Map/components/BottomUtils/branchOfficeUtilsList.js index 713ed25..8a995eb 100644 --- a/src/pages/Container/Map/components/BottomUtils/branchOfficeUtilsList.js +++ b/src/pages/Container/Map/components/BottomUtils/branchOfficeUtilsList.js @@ -228,19 +228,23 @@ export const branchOfficeUtilsList = [ }, { label: "重点工程", - type: "project", + type: "keyProject", list: [ { label: "重点工程定位", check: false, - type: "project", + type: "keyProject", markIcon: pointIco30, + request: "getKeyProjectLargeScreenList", + titleKey: "projectName", }, { label: "视频定位", check: false, type: "video", markIcon: pointIco31, + request: "getFixedCameraVideoList", + titleKey: "videoName", }, ], }, @@ -253,6 +257,8 @@ export const branchOfficeUtilsList = [ check: false, type: "platCamera", markIcon: pointIco3, + request: "getFixedCameraVideoList", + titleKey: "videoName", }, ], }, diff --git a/src/pages/Container/Map/components/BottomUtils/index.js b/src/pages/Container/Map/components/BottomUtils/index.js index 2acd1ae..1fd5800 100644 --- a/src/pages/Container/Map/components/BottomUtils/index.js +++ b/src/pages/Container/Map/components/BottomUtils/index.js @@ -118,18 +118,26 @@ function BottomUtils(props) { const check = !list[index].list[index1].check; if (check) { if (item1.request) { + let pointData = []; const requestParams = { portArea, corpinfoId: currentBranchOffice, pageIndex: 1, pageSize: 9999 }; if (dangerWorkTypes.includes(item1.type)) { requestParams.workType = item1.type; } const { data = [] } = await props[item1.request](requestParams); + pointData = [...data]; if (dangerWorkTypes.includes(item1.type)) { - for (let i = 0; i < data.length; i++) { - data[i].latitude = data[i].info.latitude; - data[i].longitude = data[i].info.longitude; + for (let i = 0; i < pointData.length; i++) { + pointData[i].latitude = pointData[i].info.latitude; + pointData[i].longitude = pointData[i].info.longitude; } } - mapMethods.current.addMarkPoint(data, { + if (["platCamera", "video"].includes(item1.type)) { + pointData = []; + for (let i = 0; i < data.length; i++) { + pointData.push(...data[i].fixedCameraCOList); + } + } + mapMethods.current.addMarkPoint(pointData, { markType: item1.type, markIcon: item1.markIcon, subLabel: item1.label, diff --git a/src/pages/Container/Map/components/BottomUtils/portUtilsList.js b/src/pages/Container/Map/components/BottomUtils/portUtilsList.js index dba6880..cf226be 100644 --- a/src/pages/Container/Map/components/BottomUtils/portUtilsList.js +++ b/src/pages/Container/Map/components/BottomUtils/portUtilsList.js @@ -353,7 +353,7 @@ export const portUtilsList = [ { img: bottomImg10, checkImg: bottomImg10On, - label: "摄像头", + label: "视频巡屏", type: "camera", list: [ { @@ -363,6 +363,8 @@ export const portUtilsList = [ img: ico26, checkImg: ico26On, markIcon: pointIco3, + request: "getFixedCameraVideoList", + titleKey: "videoName", }, ], }, @@ -370,15 +372,17 @@ export const portUtilsList = [ img: bottomImg12, checkImg: bottomImg12On, label: "重点工程", - type: "project", + type: "keyProject", list: [ { label: "重点工程定位", check: false, - type: "project", + type: "keyProject", img: ico27, checkImg: ico27On, markIcon: pointIco30, + request: "getKeyProjectLargeScreenList", + titleKey: "projectName", }, { label: "视频定位", @@ -387,6 +391,8 @@ export const portUtilsList = [ img: ico26, checkImg: ico26On, markIcon: pointIco31, + request: "getFixedCameraVideoList", + titleKey: "videoName", }, ], }, diff --git a/src/pages/Container/Map/components/Content/modal/KeyProject/index.js b/src/pages/Container/Map/components/Content/modal/KeyProject/index.js new file mode 100644 index 0000000..eceaa98 --- /dev/null +++ b/src/pages/Container/Map/components/Content/modal/KeyProject/index.js @@ -0,0 +1,150 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Descriptions, Divider } from "antd"; +import { useEffect, useState } from "react"; +import PreviewImg from "zy-react-library/components/PreviewImg"; +import PreviewPdf from "zy-react-library/components/PreviewPdf"; +import PreviewWord from "zy-react-library/components/PreviewWord"; +import Table from "zy-react-library/components/Table"; +import { UPLOAD_FILE_TYPE_ENUM } from "zy-react-library/enum/uploadFile/gwj"; +import useGetFile from "zy-react-library/hooks/useGetFile"; +import { getFileSuffix, getLabelName, isEmptyToWhether } from "zy-react-library/utils"; +import { NS_BI_MARK_INFO } from "~/enumerate/namespace"; + +const STATUS = [ + { bianma: "0", name: "暂存" }, + { bianma: "1", name: "未开工" }, + { bianma: "2", name: "开工申请中" }, + { bianma: "4", name: "进行中" }, + { bianma: "5", name: "完工申请中" }, + { bianma: "6", name: "已结束" }, +]; +const VIDEO_TYPE = [ + { bianma: 1, name: "固定摄像头" }, + { bianma: 2, name: "移动摄像头" }, +]; + +const renderFiles = (files = []) => { + const pdfFiles = []; + const imgFiles = []; + const wordFiles = []; + for (let i = 0; i < files.length; i++) { + const file = files[i]; + if (getFileSuffix(file.filePath) === "pdf") { + pdfFiles.push(file); + } + else if (["jpg", "jpeg", "png"].includes(getFileSuffix(file.filePath))) { + imgFiles.push(file); + } + else if (["doc", "docx"].includes(getFileSuffix(file.filePath))) { + wordFiles.push(file); + } + } + return ( + <> + {imgFiles.length > 0 && } + {pdfFiles.length > 0 && } + {wordFiles.length > 0 && } + + ); +}; + +const KeyProject = (props) => { + const { getFile } = useGetFile(); + + const [info, setInfo] = useState({}); + + const getData = async () => { + const { data = {} } = await props.keyProjectInfo({ id: props.id }); + console.log(data); + const files = await getFile({ + eqType: UPLOAD_FILE_TYPE_ENUM["168"], + eqForeignKey: data.keyProjectId, + }); + setInfo({ + files, + ...data, + }); + }; + + useEffect(() => { + getData(); + }, []); + + return ( +
+ 基本信息 +
+ + + 经度: + {info.longitude || "-"} + + + 纬度: + {info.latitude || "-"} + + + ), + }, + { label: "安全协议管理", children: renderFiles(info.files) }, + ]} + /> +
+ 绑定视频监控 +
+ getLabelName({ status: record.cameraType, list: VIDEO_TYPE }) }, + ]} + disabledResizer + options={false} + pagination={false} + /> + + 处罚人员设置 +
+
+ + + ); +}; + +export default Connect([NS_BI_MARK_INFO], true)(KeyProject); diff --git a/src/pages/Container/Map/components/Content/modal/VideoPlay/index.js b/src/pages/Container/Map/components/Content/modal/VideoPlay/index.js new file mode 100644 index 0000000..53557f2 --- /dev/null +++ b/src/pages/Container/Map/components/Content/modal/VideoPlay/index.js @@ -0,0 +1,32 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { useEffect, useState } from "react"; +import AliPlayer from "zy-react-library/components/Video/AliPlayer"; +import { NS_BI_MARK_INFO } from "~/enumerate/namespace"; + +const VideoPlay = (props) => { + const [playUrl, setPlayUrl] = useState(""); + + const getData = async () => { + const { data, success } = await props.getFixedCameraPlayUrl({ indexCode: props.cameraNumber }); + if (success && data) + setPlayUrl(data.url); + }; + + useEffect(() => { + getData(); + }, []); + + return ( +
+ {playUrl + ? ( + + ) + : ( +
暂无视频
+ )} +
+ ); +}; + +export default Connect([NS_BI_MARK_INFO], true)(VideoPlay); diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.js b/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.js new file mode 100644 index 0000000..e1c6d2b --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.js @@ -0,0 +1,77 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Spin } from "antd"; +import { useContext, useEffect, useState } from "react"; +import CountUp from "react-countup"; +import iconBackground from "~/assets/images/map_bi/content/icobg.png"; +import totalProjectIcon from "~/assets/images/map_bi/content/icon25.png"; +import startedProjectIcon from "~/assets/images/map_bi/content/icon26.png"; +import labelBackground from "~/assets/images/map_bi/content/label.png"; +import { NS_BI_STATISTICS } from "~/enumerate/namespace"; +import Panel from "~/pages/Container/Map/components/Content/port/Panel"; +import { Context } from "~/pages/Container/Map/js/context"; +import "./index.less"; + +const defaultStatistics = [ + { image: totalProjectIcon, label: "重点工程总数", count: 0 }, + { image: startedProjectIcon, label: "重点工程开工数量", count: 0 }, +]; + +/** 负责查询并展示重点工程总量与开工数量。 */ +function KeyProjectPanel(props) { + const { portArea } = useContext(Context); + const [statistics, setStatistics] = useState(defaultStatistics); + + useEffect(() => { + const loadStatistics = async () => { + const { data = {} } = await props.getKeyProjectLargeScreenProjectStatistics({ + portArea, + }); + const counts = [data.totalProjectCount, data.startCount]; + setStatistics( + defaultStatistics.map((item, index) => ({ + ...item, + count: counts[index], + })), + ); + }; + + loadStatistics(); + }, []); + + return ( + + +
+ {statistics.map(item => ( +
+
+ +
+
+
+ {item.label} +
+
+ +
+
+
+ ))} +
+
+
+ ); +} + +export default Connect([NS_BI_STATISTICS], true)(KeyProjectPanel); diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.less b/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.less new file mode 100644 index 0000000..2bf6c84 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/ZhongDian/KeyProjectPanel/index.less @@ -0,0 +1,85 @@ +.port-key-supervision__project { + margin-top: 10px; + background-image: linear-gradient( + to bottom, + rgba(0, 0, 0, 0), + rgba(0, 0, 0, 0.8) + ); +} +.port-key-project__options { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + height: 150px; + padding: 10px 15px; + border: 1px solid; + border-top: none; + border-image: linear-gradient( + to bottom, + rgba(58, 122, 149, 0), + rgba(58, 122, 149, 1) + ) + 1; +} +.port-key-project__option { + display: flex; + align-items: center; + justify-content: space-around; + width: 50%; +} +.port-key-project__icon { + width: 70px; + height: 70px; + margin-top: 5px; + padding-top: 13px; + text-align: center; + background-repeat: no-repeat; + background-size: 100% 100%; +} +.port-key-project__icon img { + width: 25px; + height: 26px; + animation: portKeyProjectSlideY 2s infinite; +} +.port-key-project__info { + flex: 1; + text-align: center; +} +.port-key-project__label { + width: 120px; + height: 24px; + margin-top: 5px; + color: #fff; + font-size: 12px; + line-height: 25px; + text-align: center; + background-repeat: no-repeat; + background-size: 100% 100%; +} +.port-key-project__count { + margin-top: 13px; + font-family: + "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", "Segoe UI", + "Microsoft YaHei", "微软雅黑", sans-serif; + font-weight: bold; + background: linear-gradient(to top, #48bbf0, #fff); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} +.port-key-project__count span { + font-size: 24px; +} +@keyframes portKeyProjectSlideY { + 0% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } + 100% { + transform: translateY(0); + } +} diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.js b/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.js new file mode 100644 index 0000000..4e4bb43 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.js @@ -0,0 +1,75 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Spin } from "antd"; +import { useContext, useEffect, useState } from "react"; +import CountUp from "react-countup"; +import videoBackground from "~/assets/images/map_bi/content/videoimg1.png"; +import { NS_BI_STATISTICS } from "~/enumerate/namespace"; +import Panel from "~/pages/Container/Map/components/Content/port/Panel"; +import { Context } from "~/pages/Container/Map/js/context"; +import "./index.less"; + +const defaultStatistics = [ + { label: "视频总数", count: 0 }, + { label: "在线数量", count: 0 }, + { label: "离线数量", count: 0 }, +]; + +/** 负责查询并展示摄像头总数、在线与离线统计。 */ +function VideoLocationPanel(props) { + const { portArea } = useContext(Context); + const [statistics, setStatistics] = useState(defaultStatistics); + + useEffect(() => { + const loadStatistics = async () => { + const { data = {} } = await props.getFixedCameraVideoLocationStat({ + portArea, + }); + const counts = [data.totalCount, data.onlineCount, data.offlineCount]; + setStatistics( + defaultStatistics.map((item, index) => ({ + ...item, + count: counts[index], + })), + ); + }; + + loadStatistics(); + }, []); + + return ( + + +
+
+
+
+ {statistics.map(item => ( +
+
+ {item.label} + : +
+
+ +
+
+ ))} +
+
+
+ + + ); +} + +export default Connect([NS_BI_STATISTICS], true)(VideoLocationPanel); diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.less b/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.less new file mode 100644 index 0000000..9b83ac0 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/ZhongDian/VideoLocationPanel/index.less @@ -0,0 +1,43 @@ +.port-key-supervision__video-location { + background-image: linear-gradient( + to bottom, + rgba(0, 0, 0, 0), + rgba(0, 0, 0, 0.8) + ); +} +.port-video-location__options { + display: flex; + justify-content: space-between; + border: 1px solid; + border-top: none; + border-image: linear-gradient( + to bottom, + rgba(58, 122, 149, 0), + rgba(58, 122, 149, 1) + ) + 1; +} +.port-video-location__option { + display: flex; + flex-direction: row; + align-items: center; +} +.port-video-location__image { + width: 225px; + height: 160px; + background-repeat: no-repeat; + background-size: 100% 100%; +} +.port-video-location__statistic { + display: flex; + flex: 1; + color: #fff; + font-size: 14px; + line-height: 3; +} +.port-video-location__statistic > div:first-child { + margin-right: 5px; +} +.port-video-location__statistic span { + font-size: 14px; +} diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/index.js b/src/pages/Container/Map/components/Content/port/ZhongDian/index.js index 6a90299..18cf9cd 100644 --- a/src/pages/Container/Map/components/Content/port/ZhongDian/index.js +++ b/src/pages/Container/Map/components/Content/port/ZhongDian/index.js @@ -1,74 +1,14 @@ -import { useContext, useState } from "react"; -import CountUp from "react-countup"; -import icobg from "~/assets/images/map_bi/content/icobg.png"; -import icon25 from "~/assets/images/map_bi/content/icon25.png"; -import icon26 from "~/assets/images/map_bi/content/icon26.png"; -import label from "~/assets/images/map_bi/content/label.png"; -import videoimg1 from "~/assets/images/map_bi/content/videoimg1.png"; -import Title from "~/pages/Container/Map/components/Content/port/Title"; -import { Context } from "~/pages/Container/Map/js/context"; -import "./index.less"; - -const ZhongDian = () => { - const { currentPort, portArea, currentBranchOffice } = useContext(Context); - - const [block1OptionsList, setBlock1OptionsList] = useState([ - { lable: "视频总数", count: 0 }, - { lable: "在线数量", count: 0 }, - { lable: "离线数量", count: 0 }, - ]); - - const [block2OptionsList, setBlock2OptionsList] = useState([ - { img: icon25, label: "重点工程总数", count: 0 }, - { img: icon26, label: "重点工程开工数量", count: 0 }, - ]); +import KeyProjectPanel from "./KeyProjectPanel"; +import VideoLocationPanel from "./VideoLocationPanel"; +/** 重点监管模块仅负责按展示顺序组合业务区块。 */ +function ZhongDian() { return ( -
-
- - <div className="options"> - <div className="option"> - <div className="leftimg" style={{ backgroundImage: `url(${videoimg1})` }} /> - <div> - {block1OptionsList.map((item, index) => ( - <div key={index} className="info"> - <div className="lable"> - {item.lable} - : - </div> - <div className="count"> - <CountUp end={+item.count} /> - </div> - </div> - ))} - </div> - </div> - </div> - </div> - - <div className="block2"> - <Title title="重点工程" /> - <div className="options"> - {block2OptionsList.map((item, index) => ( - <div key={index} className="option"> - <div className="circular" style={{ backgroundImage: `url(${icobg})` }}> - <img src={item.img} alt="" /> - </div> - <div className="info"> - <div className="title" style={{ backgroundImage: `url(${label})` }}> - {item.label} - </div> - <div className="count"> - <CountUp end={+item.count} /> - </div> - </div> - </div> - ))} - </div> - </div> + <div className="port-key-supervision"> + <VideoLocationPanel /> + <KeyProjectPanel /> </div> ); -}; +} export default ZhongDian; diff --git a/src/pages/Container/Map/components/Content/port/ZhongDian/index.less b/src/pages/Container/Map/components/Content/port/ZhongDian/index.less deleted file mode 100644 index b82a411..0000000 --- a/src/pages/Container/Map/components/Content/port/ZhongDian/index.less +++ /dev/null @@ -1,138 +0,0 @@ -.port_zhongdian { - .block1 { - background-image: linear-gradient(to bottom, - rgba(0, 0, 0, 0), - rgba(0, 0, 0, 0.8)); - - .options { - display: flex; - justify-content: space-between; - - border: 1px solid; - border-image: linear-gradient(to bottom, - rgba(58, 122, 149, 0), - rgba(58, 122, 149, 1)) 1; - border-top: none; - - .option { - display: flex; - flex-direction: row; - align-items: center; - - .leftimg { - width: 225px; - height: 160px; - background-size: 100% 100%; - background-repeat: no-repeat; - } - - .info { - flex: 1; - color: #fff; - font-size: 14px; - display: flex; - line-height: 3; - - .lable { - margin-right: 5px; - } - - .count { - span { - font-size: 14px; - } - } - } - } - } - } - - .block2 { - background-image: linear-gradient(to bottom, - rgba(0, 0, 0, 0), - rgba(0, 0, 0, 0.8)); - margin-top: 10px; - - .options { - padding: 10px 15px; - border: 1px solid; - border-image: linear-gradient(to bottom, - rgba(58, 122, 149, 0), - rgba(58, 122, 149, 1)) 1; - border-top: none; - display: flex; - flex-wrap: wrap; - justify-content: space-between; - align-items: center; - position: relative; - height: 150px; - - .option { - width: 50%; - display: flex; - align-items: center; - justify-content: space-around; - - .circular { - margin-top: 5px; - background-size: 100% 100%; - background-repeat: no-repeat; - width: 70px; - height: 70px; - text-align: center; - padding-top: 13px; - - img { - width: 25px; - height: 26px; - animation: zhongdianSlideY 2s infinite; - } - } - - .info { - flex: 1; - text-align: center; - - .title { - background-size: 100% 100%; - background-repeat: no-repeat; - width: 120px; - height: 24px; - margin-top: 5px; - font-size: 12px; - line-height: 25px; - text-align: center; - color: #fff; - } - - .count { - margin-top: 13px; - background: linear-gradient(to top, #48bbf0, #ffffff); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - font-weight: bold; - font-family: "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", - "Segoe UI", "Microsoft YaHei", "微软雅黑", sans-serif; - - span { - font-size: 24px; - } - } - } - } - } - } - - @keyframes zhongdianSlideY { - 0% { - transform: translateY(0); - } - 50% { - transform: translateY(-5px); - } - 100% { - transform: translateY(0); - } - } -}