From 3145aae56b3df6e83ae36af507a09242a965d4d0 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <15703339975@163.com> Date: Mon, 20 Jul 2026 18:38:17 +0800 Subject: [PATCH] =?UTF-8?q?portIndex=20=E6=96=87=E4=BB=B6=E6=8C=89?= =?UTF-8?q?=E5=9D=97=E6=8B=86=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Map/components/Content/IndexInfo/index.js | 1 - .../components/Content/IndexInfo/index.less | 3 - .../port/Index/BasicInfoPanel/index.js | 69 ++++++ .../port/Index/BasicInfoPanel/index.less | 71 +++++++ .../port/Index/PersonnelStatsPanel/index.js | 93 ++++++++ .../port/Index/PersonnelStatsPanel/index.less | 62 ++++++ .../port/Index/RiskStatsPanel/index.js | 102 +++++++++ .../port/Index/RiskStatsPanel/index.less | 75 +++++++ .../components/Content/port/Index/index.js | 187 +--------------- .../components/Content/port/Index/index.less | 200 ------------------ .../components/Content/port/Panel/index.js | 29 +++ .../components/Content/port/Panel/index.less | 49 +++++ 12 files changed, 560 insertions(+), 381 deletions(-) delete mode 100644 src/pages/Container/Map/components/Content/IndexInfo/index.less create mode 100644 src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.js create mode 100644 src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.less create mode 100644 src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.js create mode 100644 src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.less create mode 100644 src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.js create mode 100644 src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.less delete mode 100644 src/pages/Container/Map/components/Content/port/Index/index.less create mode 100644 src/pages/Container/Map/components/Content/port/Panel/index.js create mode 100644 src/pages/Container/Map/components/Content/port/Panel/index.less diff --git a/src/pages/Container/Map/components/Content/IndexInfo/index.js b/src/pages/Container/Map/components/Content/IndexInfo/index.js index 1d1d37e..7d56317 100644 --- a/src/pages/Container/Map/components/Content/IndexInfo/index.js +++ b/src/pages/Container/Map/components/Content/IndexInfo/index.js @@ -3,7 +3,6 @@ import Btn from "./Btn"; import LeftPanel from "./LeftPanel"; import RightPanel from "./RightPanel"; // import Search from "./Search"; -import "./index.less"; function IndexInfo(props) { return ( diff --git a/src/pages/Container/Map/components/Content/IndexInfo/index.less b/src/pages/Container/Map/components/Content/IndexInfo/index.less deleted file mode 100644 index a2690ca..0000000 --- a/src/pages/Container/Map/components/Content/IndexInfo/index.less +++ /dev/null @@ -1,3 +0,0 @@ -.index_info_container { - -} diff --git a/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.js b/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.js new file mode 100644 index 0000000..7ec0c6d --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.js @@ -0,0 +1,69 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Spin } from "antd"; +import { useContext, useEffect, useState } from "react"; +import CountUp from "react-countup"; +import branchIcon from "~/assets/images/map_bi/content/img3.png"; +import relatedIcon from "~/assets/images/map_bi/content/img4.png"; +import userIcon from "~/assets/images/map_bi/content/img5.png"; +import oval from "~/assets/images/map_bi/content/oval.png"; +import { NS_BI } 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: "分公司企业数", image: branchIcon, count: 0 }, + { label: "相关方单位数", image: relatedIcon, count: 0 }, + { label: "员工数", image: userIcon, count: 0 }, +]; + +/** 负责查询并展示港区单位、相关方及员工基础统计。 */ +function BasicInfoPanel(props) { + const { portArea } = useContext(Context); + const [statistics, setStatistics] = useState(defaultStatistics); + + useEffect(() => { + const loadStatistics = async () => { + const { data } = await props.getCorpInfoCorpUserSummary({ portArea }); + const counts = [ + data.branchCorpCount, + data.relatedCorpCount, + data.userCount, + ]; + + setStatistics( + defaultStatistics.map((item, index) => ({ + ...item, + count: counts[index], + })), + ); + }; + + loadStatistics(); + }, []); + + return ( + + +
+ {statistics.map(item => ( +
+ + +
{item.label}
+
+ +
+
+ ))} +
+
+
+ ); +} + +export default Connect([NS_BI], true)(BasicInfoPanel); diff --git a/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.less b/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.less new file mode 100644 index 0000000..fae4e27 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/BasicInfoPanel/index.less @@ -0,0 +1,71 @@ +.port-index__basic-info { + background-image: linear-gradient(to bottom, + rgba(0, 0, 0, 0), + rgba(0, 0, 0, 0.8)); +} + +.port-basic-info__options { + display: flex; + justify-content: space-between; + padding: 10px; + border: 1px solid; + border-top: none; + border-image: linear-gradient(to bottom, + rgba(58, 122, 149, 0), + rgba(58, 122, 149, 1)) 1; +} + +.port-basic-info__option { + position: relative; + display: flex; + flex-basis: 33.33%; + flex-direction: column; + align-items: center; +} + +.port-basic-info__option-icon { + position: absolute; + width: 70px; + height: 70px; + animation: portBasicInfoSlideY 2s infinite; +} + +.port-basic-info__option-oval { + position: absolute; + top: 5px; + width: 75px; + height: 75px; +} + +.port-basic-info__option-label { + margin-top: 80px; + color: #fff; + font-size: 14px !important; +} + +.port-basic-info__option-count { + margin-top: 6px; + font-family: "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", "Segoe UI", + "Microsoft YaHei", "微软雅黑", sans-serif; + font-weight: bold; + background-image: linear-gradient(to bottom, #5bb4f7, #fff); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.port-basic-info__option-count span { + font-size: 26px; +} + +@keyframes portBasicInfoSlideY { + 0% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } + 100% { + transform: translateY(0); + } +} diff --git a/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.js b/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.js new file mode 100644 index 0000000..5c80f96 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.js @@ -0,0 +1,93 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Spin } from "antd"; +import { useContext, useEffect, useState } from "react"; +import SeamlessScroll from "zy-react-library/components/SeamlessScroll"; +import activeTabBackground from "~/assets/images/map_bi/content/title.png"; +import tabBackground from "~/assets/images/map_bi/content/title_on.png"; +import { NS_BI } 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 tabs = ["分公司统计", "相关方单位统计"]; + +/** 负责切换企业类型并展示单位人员统计列表。 */ +function PersonnelStatsPanel(props) { + const { portArea } = useContext(Context); + const [activeTab, setActiveTab] = useState(0); + const [statistics, setStatistics] = useState([]); + const [isVisible, setIsVisible] = useState(false); + + const loadStatistics = async (enterpriseType) => { + const { data } = await props.getCorpInfoCorpUserStatisticPage({ + portArea, + enterpriseType, + }); + setStatistics(data); + setIsVisible(true); + }; + + const handleTabClick = (index) => { + if (index === activeTab) + return; + + setIsVisible(false); + setActiveTab(index); + loadStatistics(index === 0 ? 2 : 3); + }; + + useEffect(() => { + loadStatistics(2); + }, []); + + return ( + +
+
+ {tabs.map((item, index) => ( +
handleTabClick(index)} + > + {item} +
+ ))} +
+
+
+
公司名称
+
部门数
+
人员数
+
+
+ + {isVisible && ( + + {statistics.map((item, index) => ( +
+
+ {item.corpName} +
+
+ {item.departmentCount} +
+
+ {item.userCount} +
+
+ ))} +
+ )} +
+
+
+
+
+ ); +} + +export default Connect([NS_BI], true)(PersonnelStatsPanel); diff --git a/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.less b/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.less new file mode 100644 index 0000000..a5e44db --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/PersonnelStatsPanel/index.less @@ -0,0 +1,62 @@ +.port-index__personnel-stats { + margin-top: 10px; + + background-image: linear-gradient(to bottom, + rgba(0, 0, 0, 0), + rgba(0, 0, 0, 0.8)); +} + +.port-personnel-stats__content { + padding: 10px; + border: 1px solid; + border-top: none; + border-image: linear-gradient(to bottom, + rgba(58, 122, 149, 0), + rgba(58, 122, 149, 1)) 1; +} + +.port-personnel-stats__tabs { + display: flex; + justify-content: flex-end; +} + +.port-personnel-stats__tab { + width: 113px; + height: 26px; + color: #fff; + font-size: 14px; + line-height: 26px; + text-align: center; + cursor: pointer; + background-repeat: no-repeat; + background-size: 100% 100%; +} + +.port-personnel-stats__table { + margin-top: 14px; +} + +.port-personnel-stats__table-body { + height: 300px; + overflow-y: hidden; +} + +.port-personnel-stats__table-body .port-personnel-stats__row:nth-child(odd) { + background-color: transparent; +} + +.port-personnel-stats__row { + display: grid; + grid-template-columns: 2fr 1fr 1fr; + background-color: rgba(42, 86, 158, 0.53); +} + +.port-personnel-stats__cell { + padding: 5px; + overflow: hidden; + color: #fff; + font-size: 12px; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.js b/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.js new file mode 100644 index 0000000..8a152df --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.js @@ -0,0 +1,102 @@ +import { Connect } from "@cqsjjb/jjb-dva-runtime"; +import { Spin } from "antd"; +import { useContext, useEffect, useState } from "react"; +import CountUp from "react-countup"; +import highBackground from "~/assets/images/map_bi/content/img2_1.png"; +import normalBackground from "~/assets/images/map_bi/content/img2_2.png"; +import majorIcon from "~/assets/images/map_bi/content/img2ico1.png"; +import highIcon from "~/assets/images/map_bi/content/img2ico2.png"; +import normalIcon from "~/assets/images/map_bi/content/img2ico3.png"; +import lowIcon from "~/assets/images/map_bi/content/img2ico4.png"; +import { NS_BI } 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: "重大风险点数", + image: majorIcon, + background: highBackground, + level: "levelA", + count: 0, + }, + { + label: "较大风险点数", + image: highIcon, + background: highBackground, + level: "levelB", + count: 0, + }, + { + label: "一般风险点数", + image: normalIcon, + background: normalBackground, + level: "levelC", + count: 0, + }, + { + label: "低风险点数", + image: lowIcon, + background: normalBackground, + level: "levelD", + count: 0, + }, +]; + +/** 负责查询并展示不同风险等级的风险点数量。 */ +function RiskStatsPanel(props) { + const { portArea } = useContext(Context); + const [statistics, setStatistics] = useState(defaultStatistics); + + useEffect(() => { + const loadStatistics = async () => { + const { data } = await props.getRiskPointCorpRiskLevel({ portArea }); + const countByLevel = Object.fromEntries( + data.map(item => [item.level, item.count]), + ); + + setStatistics( + defaultStatistics.map(item => ({ + ...item, + count: countByLevel[item.level] || 0, + })), + ); + }; + + loadStatistics(); + }, []); + + return ( + + +
+ {statistics.map(item => ( +
+ + +
+
+ {item.label} +
+
+ +
+
+
+ ))} +
+
+
+ ); +} + +export default Connect([NS_BI], true)(RiskStatsPanel); diff --git a/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.less b/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.less new file mode 100644 index 0000000..606348c --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Index/RiskStatsPanel/index.less @@ -0,0 +1,75 @@ +.port-index__risk-stats { + margin-top: 10px; + + background-image: linear-gradient(to bottom, + rgba(0, 0, 0, 0), + rgba(0, 0, 0, 0.8)); +} + +.port-risk-stats__options { + display: flex; + flex-wrap: wrap; + padding: 10px; + border: 1px solid; + border-top: none; + border-image: linear-gradient(to bottom, + rgba(58, 122, 149, 0), + rgba(58, 122, 149, 1)) 1; +} + +.port-risk-stats__option { + position: relative; + display: flex; + flex-basis: 50%; + align-items: center; + padding-left: 8px; +} + +.port-risk-stats__option-icon { + position: absolute; + top: 10px; + left: 25px; + width: 34px; + height: 34px; + animation: portRiskStatsSlideY 2s infinite; +} + +.port-risk-stats__option-background { + width: 70px; + height: 80px; +} + +.port-risk-stats__option-label { + margin-left: 10px; + color: #fff; + font-size: 14px; +} + +.port-risk-stats__option-count { + margin-top: 12px; + margin-left: 10px; + font-family: "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", "Segoe UI", + "Microsoft YaHei", "微软雅黑", sans-serif; + font-size: 26px; + font-weight: bold; + background-image: linear-gradient(to bottom, #5bb4f7, #fff); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.port-risk-stats__option-count span { + font-size: 26px; +} + +@keyframes portRiskStatsSlideY { + 0% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } + 100% { + transform: translateY(0); + } +} diff --git a/src/pages/Container/Map/components/Content/port/Index/index.js b/src/pages/Container/Map/components/Content/port/Index/index.js index 260268f..2e6f494 100644 --- a/src/pages/Container/Map/components/Content/port/Index/index.js +++ b/src/pages/Container/Map/components/Content/port/Index/index.js @@ -1,183 +1,16 @@ -import { Connect } from "@cqsjjb/jjb-dva-runtime"; -import { Spin } from "antd"; -import { useContext, useEffect, useState } from "react"; -import CountUp from "react-countup"; -import SeamlessScroll from "zy-react-library/components/SeamlessScroll"; -import img2_1 from "~/assets/images/map_bi/content/img2_1.png"; -import img2_2 from "~/assets/images/map_bi/content/img2_2.png"; -import img2ico1 from "~/assets/images/map_bi/content/img2ico1.png"; -import img2ico2 from "~/assets/images/map_bi/content/img2ico2.png"; -import img2ico3 from "~/assets/images/map_bi/content/img2ico3.png"; -import img2ico4 from "~/assets/images/map_bi/content/img2ico4.png"; -import img3 from "~/assets/images/map_bi/content/img3.png"; -import img4 from "~/assets/images/map_bi/content/img4.png"; -import img5 from "~/assets/images/map_bi/content/img5.png"; -import oval from "~/assets/images/map_bi/content/oval.png"; -import navTitleOn from "~/assets/images/map_bi/content/title.png"; -import navTitle from "~/assets/images/map_bi/content/title_on.png"; -import { NS_BI } from "~/enumerate/namespace"; -import Title from "~/pages/Container/Map/components/Content/port/Title"; -import { Context } from "~/pages/Container/Map/js/context"; -import "./index.less"; - -const block3OptionsNavList = ["分公司统计", "相关方单位统计"]; - -function Index(props) { - const { portArea } = useContext(Context); - - const [block1OptionsList, setBlock1OptionsList] = useState([ - { label: "分公司企业数", img: img3, count: 0 }, - { label: "相关方单位数", img: img4, count: 0 }, - { label: "员工数", img: img5, count: 0 }, - ]); - - const [block2OptionsList, setBlock2OptionsList] = useState([ - { label: "重大风险点数", img: img2ico1, bg_img: img2_1, count: 0 }, - { label: "较大风险点数", img: img2ico2, bg_img: img2_1, count: 0 }, - { label: "一般风险点数", img: img2ico3, bg_img: img2_2, count: 0 }, - { label: "低风险点数", img: img2ico4, bg_img: img2_2, count: 0 }, - ]); - - const [block3Index, setBlock3Index] = useState(0); - const [block3List, setBlock3List] = useState([]); - const [isShow, setIsShow] = useState(false); - - const getCorpInfoCorpUserSummary = async () => { - const { data } = await props.getCorpInfoCorpUserSummary({ portArea }); - setBlock1OptionsList((prevState) => { - prevState[0].count = data.branchCorpCount; - prevState[1].count = data.relatedCorpCount; - prevState[2].count = data.userCount; - return [...prevState]; - }); - }; - - const getRiskPointCorpRiskLevel = async () => { - const { data } = await props.getRiskPointCorpRiskLevel({ portArea }); - setBlock2OptionsList((prevState) => { - for (let i = 0; i < data.length; i++) { - switch (data[i].level) { - case "levelD": - prevState[3].count = data[i].count; - break; - case "levelC": - prevState[2].count = data[i].count; - break; - case "levelB": - prevState[1].count = data[i].count; - break; - case "levelA": - prevState[0].count = data[i].count; - break; - } - } - return [...prevState]; - }); - }; - - const getCorpInfoCorpUserStatisticPage = async (enterpriseType) => { - const { data } = await props.getCorpInfoCorpUserStatisticPage({ portArea, enterpriseType }); - setBlock3List(data); - setIsShow(true); - }; - - const block3OptionsClick = (index) => { - if (index === block3Index) - return; - setIsShow(false); - setBlock3Index(index); - getCorpInfoCorpUserStatisticPage(index === 0 ? 2 : 3); - }; - - useEffect(() => { - getCorpInfoCorpUserSummary(); - getRiskPointCorpRiskLevel(); - getCorpInfoCorpUserStatisticPage(2); - }, []); +import BasicInfoPanel from "./BasicInfoPanel"; +import PersonnelStatsPanel from "./PersonnelStatsPanel"; +import RiskStatsPanel from "./RiskStatsPanel"; +/** 港区首页只负责按页面顺序组合各信息区块。 */ +function Index() { return ( -
-
- - <Spin spinning={props.bi.portIndexBasicInfoSummaryLoading}> - <div className="options"> - {block1OptionsList.map((item, index) => ( - <div key={index} className="option"> - <img src={item.img} className="img_top" alt="" /> - <img className="img_bottom" src={oval} alt="" /> - <div className="label">{item.label}</div> - <div className="count"> - <CountUp end={+item.count} /> - </div> - </div> - ))} - </div> - </Spin> - </div> - - <div className="block2"> - <Title title="风险区域统计" /> - <Spin spinning={props.bi.portIndexRiskLoading}> - <div className="options"> - {block2OptionsList.map((item, index) => ( - <div key={index} className="option"> - <img src={item.img} className="img" alt="" /> - <img src={item.bg_img} className="img_bg" alt="" /> - <div> - <div className="label">{item.label}</div> - <div className="count"> - <CountUp end={+item.count} /> - </div> - </div> - </div> - ))} - </div> - </Spin> - </div> - - <div className="block3"> - <Title title="单位人员信息统计" /> - <div className="content"> - <div className="options"> - {block3OptionsNavList.map((item, index) => ( - <div - key={index} - className="title" - style={{ backgroundImage: index === block3Index ? `url(${navTitleOn})` : `url(${navTitle})` }} - onClick={() => block3OptionsClick(index)} - > - {item} - </div> - ))} - </div> - <div className="table"> - <div className="tr"> - <div className="td">公司名称</div> - <div className="td">部门数</div> - <div className="td">人员数</div> - </div> - <div className="scroll"> - <Spin spinning={props.bi.portIndexBasicInfoStatisticPageLoading}> - { - isShow && ( - <SeamlessScroll list={block3List} step={0.5}> - {block3List.map((item, index) => ( - <div key={index} className="tr"> - <div className="td">{item.corpName}</div> - <div className="td">{item.departmentCount}</div> - <div className="td">{item.userCount}</div> - </div> - ))} - </SeamlessScroll> - ) - } - </Spin> - </div> - </div> - </div> - </div> + <div className="port-index"> + <BasicInfoPanel /> + <RiskStatsPanel /> + <PersonnelStatsPanel /> </div> ); } -export default Connect([NS_BI], true)(Index); +export default Index; diff --git a/src/pages/Container/Map/components/Content/port/Index/index.less b/src/pages/Container/Map/components/Content/port/Index/index.less deleted file mode 100644 index f25588e..0000000 --- a/src/pages/Container/Map/components/Content/port/Index/index.less +++ /dev/null @@ -1,200 +0,0 @@ -.port_index { - .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; - padding: 10px; - border: 1px solid; - border-image: linear-gradient(to bottom, - rgba(58, 122, 149, 0), - rgba(58, 122, 149, 1)) 1; - border-top: none; - - .option { - flex-basis: 33.33%; - display: flex; - flex-direction: column; - align-items: center; - position: relative; - - .img_top { - position: absolute; - width: 70px; - height: 70px; - animation: portIndexSlideY 2s infinite; - } - - .img_bottom { - position: absolute; - width: 75px; - height: 75px; - top: 5px; - } - - .label { - margin-top: 80px; - color: #fff; - font-size: 14px !important; - } - - .count { - background-image: linear-gradient(to bottom, #5bb4f7, #ffffff); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - font-weight: bold; - margin-top: 6px; - font-family: "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", - "Segoe UI", "Microsoft YaHei", "微软雅黑", sans-serif; - - span { - font-size: 26px; - } - } - } - } - } - - .block2 { - margin-top: 10px; - background-image: linear-gradient(to bottom, - rgba(0, 0, 0, 0), - rgba(0, 0, 0, 0.8)); - - .options { - display: flex; - flex-wrap: wrap; - border: 1px solid; - border-image: linear-gradient(to bottom, - rgba(58, 122, 149, 0), - rgba(58, 122, 149, 1)) 1; - border-top: none; - padding: 10px; - - .option { - display: flex; - align-items: center; - position: relative; - flex-basis: 50%; - padding-left: 8px; - - .img { - width: 34px; - height: 34px; - position: absolute; - left: 25px; - top: 10px; - animation: portIndexSlideY 2s infinite; - } - - .img_bg { - width: 70px; - height: 80px; - } - - .label { - color: #fff; - font-size: 14px; - margin-left: 10px; - } - - .count { - background-image: linear-gradient(to bottom, #5bb4f7, #ffffff); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - font-weight: bold; - font-size: 26px; - margin-top: 12px; - margin-left: 10px; - font-family: "PingFang SC", "Helvetica Neue", "Hiragino Sans GB", - "Segoe UI", "Microsoft YaHei", "微软雅黑", sans-serif; - - span { - font-size: 26px; - } - } - } - } - } - - .block3 { - margin-top: 10px; - background-image: linear-gradient(to bottom, - rgba(0, 0, 0, 0), - rgba(0, 0, 0, 0.8)); - - .content { - border: 1px solid; - border-image: linear-gradient(to bottom, - rgba(58, 122, 149, 0), - rgba(58, 122, 149, 1)) 1; - border-top: none; - padding: 10px; - - .options { - display: flex; - justify-content: flex-end; - - .title { - cursor: pointer; - background-size: 100% 100%; - background-repeat: no-repeat; - width: 113px; - height: 26px; - font-size: 14px; - line-height: 26px; - text-align: center; - color: #fff; - } - } - - .table { - margin-top: 14px; - - .scroll { - height: 300px; - overflow-y: hidden; - - .tr { - &:nth-child(odd) { - background-color: transparent; - } - } - } - - .tr { - display: grid; - grid-template-columns: 2fr 1fr 1fr; - background-color: rgba(42, 86, 158, 0.53); - - .td { - text-align: center; - font-size: 12px; - color: #fff; - padding: 5px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - } - } - } - } - - @keyframes portIndexSlideY { - 0% { - transform: translateY(0); - } - 50% { - transform: translateY(-5px); - } - 100% { - transform: translateY(0); - } - } -} diff --git a/src/pages/Container/Map/components/Content/port/Panel/index.js b/src/pages/Container/Map/components/Content/port/Panel/index.js new file mode 100644 index 0000000..c22ea27 --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Panel/index.js @@ -0,0 +1,29 @@ +import titleBackground from "~/assets/images/map_bi/content/title_bg1.png"; +import titleIcon from "~/assets/images/map_bi/content/title_ico.png"; +import "./index.less"; + +/** + * 港区大屏信息区块的统一外层,负责展示标题并承载区块业务内容。 + */ +function Panel({ title, extra, children, className = "" }) { + return ( + <section className={`port-panel ${className}`.trim()}> + <div + className="port-panel__title" + style={{ backgroundImage: `url(${titleBackground})` }} + > + <div className="port-panel__title-main"> + <div + className="port-panel__title-icon" + style={{ backgroundImage: `url(${titleIcon})` }} + /> + <div className="port-panel__title-label">{title}</div> + </div> + <div className="port-panel__title-extra">{extra}</div> + </div> + <div className="port-panel__content">{children}</div> + </section> + ); +} + +export default Panel; diff --git a/src/pages/Container/Map/components/Content/port/Panel/index.less b/src/pages/Container/Map/components/Content/port/Panel/index.less new file mode 100644 index 0000000..af0d8bd --- /dev/null +++ b/src/pages/Container/Map/components/Content/port/Panel/index.less @@ -0,0 +1,49 @@ +.port-panel { + &__title { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + height: 32px; + background-repeat: no-repeat; + background-size: 100% 100%; + } + + &__title-main { + display: flex; + align-items: center; + } + + &__title-icon { + width: 31px; + height: 27px; + margin-top: 3px; + margin-left: 5px; + background-repeat: no-repeat; + background-size: 100% 100%; + animation: portPanelTitleSlideX 2s infinite; + } + + &__title-label { + padding-left: 5px; + color: #fff; + font-size: 14px; + font-weight: bold; + } + + &__title-extra { + margin-right: 5px; + } +} + +@keyframes portPanelTitleSlideX { + 0% { + transform: translateX(0); + } + 50% { + transform: translateX(5px); + } + 100% { + transform: translateX(0); + } +}