port WeiXian 文件按块拆分
parent
c68862b954
commit
1ce00bc82c
|
|
@ -60,3 +60,15 @@ export const getFirePointDeviceList = declareRequest(
|
||||||
"portXiaoFangFirePointDeviceListLoading",
|
"portXiaoFangFirePointDeviceListLoading",
|
||||||
"Post > @/fireCheck/firePoint/deviceList",
|
"Post > @/fireCheck/firePoint/deviceList",
|
||||||
);
|
);
|
||||||
|
export const getEightWorkInfoScreenStatusStatistics = declareRequest(
|
||||||
|
"portWeiXianEightWorkInfoScreenStatusStatisticsLoading",
|
||||||
|
"Post > @/eightwork/eightworkInfo/screenStatusStatistics",
|
||||||
|
);
|
||||||
|
export const getEightWorkInfoScreenWorkRecord = declareRequest(
|
||||||
|
"portWeiXianEightWorkInfoScreenWorkRecordLoading",
|
||||||
|
"Post > @/eightwork/eightworkInfo/screenWorkRecord",
|
||||||
|
);
|
||||||
|
export const getEightWorkInfoScreenWorkTrend = declareRequest(
|
||||||
|
"portWeiXianEightWorkInfoScreenWorkTrendLoading",
|
||||||
|
"Post > @/eightwork/eightworkInfo/screenWorkTrend",
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
|
import { useContext, useEffect, useState } from "react";
|
||||||
|
import SeamlessScroll from "zy-react-library/components/SeamlessScroll";
|
||||||
|
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 rankStyleNames = ["first", "second", "third"];
|
||||||
|
|
||||||
|
/** 负责查询并展示危险作业记录及其排行样式。 */
|
||||||
|
function WorkRecordPanel(props) {
|
||||||
|
const { portArea } = useContext(Context);
|
||||||
|
const [records, setRecords] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadRecords = async () => {
|
||||||
|
const { data = [] } = await props.getEightWorkInfoScreenWorkRecord({
|
||||||
|
portArea,
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 9999,
|
||||||
|
});
|
||||||
|
setRecords(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadRecords();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="安全作业记录" className="port-danger-work__record">
|
||||||
|
<div className="port-danger-work-record__content">
|
||||||
|
<div className="port-danger-work-record__table">
|
||||||
|
<div className="port-danger-work-record__row">
|
||||||
|
<div className="port-danger-work-record__cell">序号</div>
|
||||||
|
<div className="port-danger-work-record__cell">作业类型</div>
|
||||||
|
<div className="port-danger-work-record__cell">状态</div>
|
||||||
|
<div className="port-danger-work-record__cell">下一步操作人</div>
|
||||||
|
</div>
|
||||||
|
<div className="port-danger-work-record__table-body">
|
||||||
|
<SeamlessScroll list={records} step={0.5}>
|
||||||
|
{records.map((item, index) => (
|
||||||
|
<div key={index} className="port-danger-work-record__row">
|
||||||
|
<div className="port-danger-work-record__cell">
|
||||||
|
<div
|
||||||
|
className={`port-danger-work-record__rank port-danger-work-record__rank--${rankStyleNames[index] || "default"}`}
|
||||||
|
>
|
||||||
|
{index + 1}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="port-danger-work-record__cell">
|
||||||
|
{item.workTypeName}
|
||||||
|
</div>
|
||||||
|
<div className="port-danger-work-record__cell">
|
||||||
|
{item.statusName}
|
||||||
|
</div>
|
||||||
|
<div className="port-danger-work-record__cell">
|
||||||
|
{item.nextStepName}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</SeamlessScroll>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Connect([NS_BI_STATISTICS], true)(WorkRecordPanel);
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
.port-danger-work__record {
|
||||||
|
margin-top: 10px;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 0.8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.port-danger-work-record__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-danger-work-record__table {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__table-body {
|
||||||
|
height: 400px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__row:nth-child(odd) {
|
||||||
|
background-color: rgba(42, 86, 158, 0.53);
|
||||||
|
}
|
||||||
|
.port-danger-work-record__cell {
|
||||||
|
flex: 1;
|
||||||
|
padding: 5px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__cell:first-child {
|
||||||
|
flex: none;
|
||||||
|
flex-basis: 50px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__cell:nth-child(2) {
|
||||||
|
flex-basis: 20%;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__rank {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 21px;
|
||||||
|
height: 15px;
|
||||||
|
margin: auto;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.port-danger-work-record__rank--first {
|
||||||
|
background: linear-gradient(135deg, #ff6d73, #f23f47);
|
||||||
|
}
|
||||||
|
.port-danger-work-record__rank--second {
|
||||||
|
background: linear-gradient(135deg, #ffb856, #ff871f);
|
||||||
|
}
|
||||||
|
.port-danger-work-record__rank--third {
|
||||||
|
background: linear-gradient(135deg, #ffe477, #f6be1b);
|
||||||
|
}
|
||||||
|
.port-danger-work-record__rank--default {
|
||||||
|
background: linear-gradient(135deg, #5a8fdc, #3367b4);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
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 applyIcon from "~/assets/images/map_bi/content/icon27.png";
|
||||||
|
import approvingIcon from "~/assets/images/map_bi/content/icon28.png";
|
||||||
|
import archivedIcon from "~/assets/images/map_bi/content/icon29.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: applyIcon, label: "申请数", count: 0 },
|
||||||
|
{ image: approvingIcon, label: "审批中", count: 0 },
|
||||||
|
{ image: archivedIcon, label: "归档数", count: 0 },
|
||||||
|
];
|
||||||
|
|
||||||
|
/** 负责查询并展示危险作业申请、审批和归档状态统计。 */
|
||||||
|
function WorkStatusPanel(props) {
|
||||||
|
const { portArea } = useContext(Context);
|
||||||
|
const [statistics, setStatistics] = useState(defaultStatistics);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadStatistics = async () => {
|
||||||
|
const { data = {} } = await props.getEightWorkInfoScreenStatusStatistics({
|
||||||
|
portArea,
|
||||||
|
});
|
||||||
|
const counts = [
|
||||||
|
data.appliedCount,
|
||||||
|
data.approvingCount,
|
||||||
|
data.archivedCount,
|
||||||
|
];
|
||||||
|
setStatistics(
|
||||||
|
defaultStatistics.map((item, index) => ({
|
||||||
|
...item,
|
||||||
|
count: counts[index],
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadStatistics();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="安全作业状态统计" className="port-danger-work__status">
|
||||||
|
<Spin
|
||||||
|
spinning={
|
||||||
|
props.biStatistics
|
||||||
|
.portWeiXianEightWorkInfoScreenStatusStatisticsLoading
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="port-danger-work-status__options">
|
||||||
|
{statistics.map((item) => (
|
||||||
|
<div key={item.label} className="port-danger-work-status__option">
|
||||||
|
<div
|
||||||
|
className="port-danger-work-status__icon"
|
||||||
|
style={{ backgroundImage: `url(${iconBackground})` }}
|
||||||
|
>
|
||||||
|
<img src={item.image} alt="" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="port-danger-work-status__label"
|
||||||
|
style={{ backgroundImage: `url(${labelBackground})` }}
|
||||||
|
>
|
||||||
|
{item.label}:<CountUp end={+item.count} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Spin>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Connect([NS_BI_STATISTICS], true)(WorkStatusPanel);
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
.port-danger-work__status {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 0.8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.port-danger-work-status__options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 13px 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-danger-work-status__option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.port-danger-work-status__icon {
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
padding-top: 13px;
|
||||||
|
text-align: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
.port-danger-work-status__icon img {
|
||||||
|
width: 25px;
|
||||||
|
height: 26px;
|
||||||
|
animation: portDangerWorkStatusSlideY 2s infinite;
|
||||||
|
}
|
||||||
|
.port-danger-work-status__label {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 120px;
|
||||||
|
height: 24px;
|
||||||
|
margin-top: 6px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 25px;
|
||||||
|
text-align: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
@keyframes portDangerWorkStatusSlideY {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||||
|
import { useMount } from "ahooks";
|
||||||
|
import { Spin } from "antd";
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
import { useContext, useRef } from "react";
|
||||||
|
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";
|
||||||
|
|
||||||
|
/** 将接口的作业趋势记录转换为图表横轴、图例与序列数据。 */
|
||||||
|
function formatWorkTrendData(data) {
|
||||||
|
const workDates = [...new Set(data.map(item => item.workDate))];
|
||||||
|
const workTypes = [
|
||||||
|
...new Map(data.map(item => [item.workType, item.workTypeName])),
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
xData: workDates,
|
||||||
|
date: workTypes.map(([workType]) =>
|
||||||
|
data
|
||||||
|
.filter(item => item.workType === workType)
|
||||||
|
.map(item => Number(item.count)),
|
||||||
|
),
|
||||||
|
name: workTypes.map(([, workTypeName]) => workTypeName),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 负责初始化安全作业趋势图表并在卸载时释放图表实例。 */
|
||||||
|
function WorkTrendPanel(props) {
|
||||||
|
const { portArea } = useContext(Context);
|
||||||
|
const chartRef = useRef(null);
|
||||||
|
const chartInstance = useRef(null);
|
||||||
|
|
||||||
|
const initEcharts = (mainRef, chartInstance, data) => {
|
||||||
|
const colors = [
|
||||||
|
"29,128,219",
|
||||||
|
"1,245,255",
|
||||||
|
"228,187,45",
|
||||||
|
"45,118,228",
|
||||||
|
"188,45,228",
|
||||||
|
"228,72,45",
|
||||||
|
"58,45,228",
|
||||||
|
"221,44,67",
|
||||||
|
];
|
||||||
|
const series = data.date.map((seriesData, index) => ({
|
||||||
|
name: data.name[index],
|
||||||
|
type: "line",
|
||||||
|
symbol: "circle",
|
||||||
|
showAllSymbol: true,
|
||||||
|
symbolSize: 0,
|
||||||
|
smooth: true,
|
||||||
|
lineStyle: { width: 2, color: `rgba(${colors[index]},1)` },
|
||||||
|
itemStyle: { color: `rgba(${colors[index]},1)` },
|
||||||
|
tooltip: { show: true },
|
||||||
|
areaStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
{ offset: 0, color: `rgba(${colors[index]},0.3)` },
|
||||||
|
{ offset: 1, color: `rgba(${colors[index]},0)` },
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
shadowColor: "rgba(25,163,223, 0.5)",
|
||||||
|
shadowBlur: 20,
|
||||||
|
},
|
||||||
|
data: seriesData,
|
||||||
|
}));
|
||||||
|
chartInstance.current = echarts.init(mainRef.current);
|
||||||
|
chartInstance.current.setOption({
|
||||||
|
tooltip: { trigger: "axis" },
|
||||||
|
legend: {
|
||||||
|
top: "0",
|
||||||
|
align: "left",
|
||||||
|
type: "plain",
|
||||||
|
data: data.name,
|
||||||
|
textStyle: { color: "#fff", fontSize: 12 },
|
||||||
|
itemWidth: 18,
|
||||||
|
},
|
||||||
|
grid: { top: "20%", left: "10%", right: "5%", bottom: "15%" },
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
boundaryGap: false,
|
||||||
|
axisLine: { show: true, lineStyle: { color: "#15578b" } },
|
||||||
|
axisLabel: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: 12,
|
||||||
|
formatter(value) {
|
||||||
|
return value.substring(5);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: { show: false, lineStyle: { color: "#fff" } },
|
||||||
|
axisTick: { show: false },
|
||||||
|
data: data.xData,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
min: 0,
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: { color: "rgba(221,221,221,0.1)" },
|
||||||
|
},
|
||||||
|
axisLine: { show: false, lineStyle: { color: "#fff" } },
|
||||||
|
axisLabel: { show: true, color: "#fff", padding: 10 },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useMount(() => {
|
||||||
|
const loadTrendData = async () => {
|
||||||
|
const { data = [] } = await props.getEightWorkInfoScreenWorkTrend({
|
||||||
|
portArea,
|
||||||
|
});
|
||||||
|
initEcharts(chartRef, chartInstance, formatWorkTrendData(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
loadTrendData();
|
||||||
|
return () => chartInstance.current?.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel title="安全作业情况统计" className="port-danger-work__trend">
|
||||||
|
<div className="port-danger-work-trend__content">
|
||||||
|
<Spin
|
||||||
|
spinning={
|
||||||
|
props.biStatistics.portWeiXianEightWorkInfoScreenWorkTrendLoading
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div ref={chartRef} className="port-danger-work-trend__chart" />
|
||||||
|
</Spin>
|
||||||
|
</div>
|
||||||
|
</Panel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Connect([NS_BI_STATISTICS], true)(WorkTrendPanel);
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
.port-danger-work__trend {
|
||||||
|
margin-top: 10px;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(0, 0, 0, 0),
|
||||||
|
rgba(0, 0, 0, 0.8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.port-danger-work-trend__content {
|
||||||
|
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-danger-work-trend__chart {
|
||||||
|
width: 100%;
|
||||||
|
height: 240px;
|
||||||
|
}
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
import * as echarts from "echarts";
|
|
||||||
|
|
||||||
export const initEcharts1 = (mainRef, chartInstance, data) => {
|
|
||||||
const colors = [
|
|
||||||
"29,128,219",
|
|
||||||
"1,245,255",
|
|
||||||
"228,187,45",
|
|
||||||
"45,118,228",
|
|
||||||
"188,45,228",
|
|
||||||
"228,72,45",
|
|
||||||
"58,45,228",
|
|
||||||
"221,44,67",
|
|
||||||
];
|
|
||||||
|
|
||||||
const date = data.date;
|
|
||||||
const name = data.name;
|
|
||||||
const series = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < date.length; i++) {
|
|
||||||
series.push({
|
|
||||||
name: name[i],
|
|
||||||
type: "line",
|
|
||||||
symbol: "circle",
|
|
||||||
showAllSymbol: true,
|
|
||||||
symbolSize: 0,
|
|
||||||
smooth: true,
|
|
||||||
lineStyle: {
|
|
||||||
width: 2,
|
|
||||||
color: `rgba(${colors[i]},1)`,
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
color: `rgba(${colors[i]},1)`,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
areaStyle: {
|
|
||||||
color: new echarts.graphic.LinearGradient(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: `rgba(${colors[i]},0.3)`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: `rgba(${colors[i]},0)`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
shadowColor: "rgba(25,163,223, 0.5)",
|
|
||||||
shadowBlur: 20,
|
|
||||||
},
|
|
||||||
data: date[i],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
chartInstance.current = echarts.init(mainRef.current);
|
|
||||||
|
|
||||||
const option = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
top: "0",
|
|
||||||
align: "left",
|
|
||||||
type: "plain",
|
|
||||||
data: name,
|
|
||||||
textStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
fontSize: 12,
|
|
||||||
},
|
|
||||||
itemWidth: 18,
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
top: "20%",
|
|
||||||
left: "10%",
|
|
||||||
right: "5%",
|
|
||||||
bottom: "15%",
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
boundaryGap: false,
|
|
||||||
axisLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#15578b",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
color: "#fff",
|
|
||||||
fontSize: 12,
|
|
||||||
formatter(data) {
|
|
||||||
return data.substring(5);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: false,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisTick: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
data: data.clickDate,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
min: 0,
|
|
||||||
splitLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: "rgba(221,221,221,0.1)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLine: {
|
|
||||||
show: false,
|
|
||||||
lineStyle: {
|
|
||||||
color: "#fff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
axisLabel: {
|
|
||||||
show: true,
|
|
||||||
color: "#fff",
|
|
||||||
padding: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
series,
|
|
||||||
};
|
|
||||||
|
|
||||||
chartInstance.current.setOption(option);
|
|
||||||
};
|
|
||||||
|
|
@ -1,137 +1,16 @@
|
||||||
import { useMount } from "ahooks";
|
import WorkRecordPanel from "./WorkRecordPanel";
|
||||||
import { useContext, useRef, useState } from "react";
|
import WorkStatusPanel from "./WorkStatusPanel";
|
||||||
import CountUp from "react-countup";
|
import WorkTrendPanel from "./WorkTrendPanel";
|
||||||
import anquan_bg1 from "~/assets/images/map_bi/content/anquan_bg1.png";
|
|
||||||
import anquan_bg2 from "~/assets/images/map_bi/content/anquan_bg2.png";
|
|
||||||
import anquan_bg3 from "~/assets/images/map_bi/content/anquan_bg3.png";
|
|
||||||
import anquan_bg4 from "~/assets/images/map_bi/content/anquan_bg4.png";
|
|
||||||
import icobg from "~/assets/images/map_bi/content/icobg.png";
|
|
||||||
import icon27 from "~/assets/images/map_bi/content/icon27.png";
|
|
||||||
import icon28 from "~/assets/images/map_bi/content/icon28.png";
|
|
||||||
import icon29 from "~/assets/images/map_bi/content/icon29.png";
|
|
||||||
import label from "~/assets/images/map_bi/content/label.png";
|
|
||||||
import Title from "~/pages/Container/Map/components/Content/port/Title";
|
|
||||||
import { Context } from "~/pages/Container/Map/js/context";
|
|
||||||
import { initEcharts1 } from "./echarts";
|
|
||||||
import "./index.less";
|
|
||||||
|
|
||||||
const WeiXian = () => {
|
|
||||||
const { currentPort, portArea, currentBranchOffice } = useContext(Context);
|
|
||||||
const [block3List, setBlock3List] = useState([
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "现场负责人", USER_NAME: "李长健" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "运行乙班" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "卸车部运行乙班" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "动火后", USER_NAME: "王启龙" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "装船部" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "装船队机修乙班" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "动火后", USER_NAME: "彭俊伟" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "装船队机修乙班" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "运行乙班" },
|
|
||||||
{ WORK_TYPE: "动火作业", STATUS_NAME: "延时监火", USER_NAME: "卸车队运行甲班" },
|
|
||||||
]);
|
|
||||||
const [block1OptionsList, setBlock1OptionsList] = useState([
|
|
||||||
{ img: icon27, label: "申请数", count: 0 },
|
|
||||||
{ img: icon28, label: "审批中", count: 0 },
|
|
||||||
{ img: icon29, label: "归档数", count: 0 },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const main1Ref = useRef(null);
|
|
||||||
const chartInstance = useRef(null);
|
|
||||||
|
|
||||||
useMount(() => {
|
|
||||||
initEcharts1(main1Ref, chartInstance, {
|
|
||||||
clickDate: ["2025-12-31", "2026-01-01", "2026-01-02", "2026-01-03", "2026-01-04"],
|
|
||||||
date: [
|
|
||||||
["7.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
["0.0", "0.0", "0.0", "0.0", "0.0"],
|
|
||||||
],
|
|
||||||
name: ["动火作业", "盲板作业", "有限空间作业", "高处作业", "吊装作业", "临时用电", "动土作业", "断路作业"],
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (chartInstance.current) {
|
|
||||||
chartInstance.current.dispose();
|
|
||||||
chartInstance.current = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
|
/** 危险作业模块仅负责按展示顺序组合业务区块。 */
|
||||||
|
function WeiXian() {
|
||||||
return (
|
return (
|
||||||
<div className="port_weixian">
|
<div className="port-danger-work">
|
||||||
<div className="block1">
|
<WorkStatusPanel />
|
||||||
<Title title="安全作业状态统计" />
|
<WorkTrendPanel />
|
||||||
<div className="options">
|
<WorkRecordPanel />
|
||||||
{block1OptionsList.map((item, index) => (
|
|
||||||
<div key={index} className="option">
|
|
||||||
<div className="circular" style={{ backgroundImage: `url(${icobg})` }}>
|
|
||||||
<img src={item.img} alt="" />
|
|
||||||
</div>
|
|
||||||
<div className="label" style={{ backgroundImage: `url(${label})` }}>
|
|
||||||
{item.label}
|
|
||||||
:
|
|
||||||
<CountUp end={+item.count} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="block2">
|
|
||||||
<Title title="安全作业情况统计" />
|
|
||||||
<div className="content">
|
|
||||||
<div ref={main1Ref} style={{ width: "100%", height: "240px" }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="block3">
|
|
||||||
<Title title="安全作业记录" />
|
|
||||||
<div className="content">
|
|
||||||
<div className="table">
|
|
||||||
<div className="tr">
|
|
||||||
<div className="td">序号</div>
|
|
||||||
<div className="td">作业类型</div>
|
|
||||||
<div className="td">状态</div>
|
|
||||||
<div className="td">下一步操作人</div>
|
|
||||||
</div>
|
|
||||||
{block3List && block3List.length > 0
|
|
||||||
? (
|
|
||||||
block3List.map((item, index) => (
|
|
||||||
<div key={index} className="tr">
|
|
||||||
<div className="td">
|
|
||||||
<div
|
|
||||||
className="bg"
|
|
||||||
style={{
|
|
||||||
...(index === 0 && { backgroundImage: `url(${anquan_bg1})` }),
|
|
||||||
...(index === 1 && { backgroundImage: `url(${anquan_bg2})` }),
|
|
||||||
...(index === 2 && { backgroundImage: `url(${anquan_bg3})` }),
|
|
||||||
...(index > 2 && { backgroundImage: `url(${anquan_bg4})` }),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{index + 1}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="td">{item.WORK_TYPE}</div>
|
|
||||||
<div className="td">{item.STATUS_NAME}</div>
|
|
||||||
<div className="td">{item.USER_NAME}</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<div className="tr">
|
|
||||||
<div className="empty">暂无数据</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default WeiXian;
|
export default WeiXian;
|
||||||
|
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
.port_weixian {
|
|
||||||
.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: 13px 15px;
|
|
||||||
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: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.circular {
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: 70px;
|
|
||||||
height: 70px;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 13px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 25px;
|
|
||||||
height: 26px;
|
|
||||||
animation: weixianSlideY 2s infinite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: 120px;
|
|
||||||
height: 24px;
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 25px;
|
|
||||||
text-align: center;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.block2 {
|
|
||||||
margin-top: 10px;
|
|
||||||
background-image: linear-gradient(to bottom,
|
|
||||||
rgba(0, 0, 0, 0),
|
|
||||||
rgba(0, 0, 0, 0.8));
|
|
||||||
|
|
||||||
.content {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
margin-top: 5px;
|
|
||||||
|
|
||||||
.scroll{
|
|
||||||
height: 400px;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tr {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
&:nth-child(odd) {
|
|
||||||
background-color: rgba(42, 86, 158, 0.53);
|
|
||||||
}
|
|
||||||
|
|
||||||
.td {
|
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #fff;
|
|
||||||
padding: 5px;
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
flex: none;
|
|
||||||
flex-basis: 50px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
flex-basis: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg {
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: 21px;
|
|
||||||
height: 15px;
|
|
||||||
margin: auto;
|
|
||||||
line-height: 15px;
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(n + 11) {
|
|
||||||
.bg {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes weixianSlideY {
|
|
||||||
0% {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue