整体样式

main
wangyunfei 1 month ago
parent e2f1a8611e
commit 624acb2d76

@ -1,7 +1,15 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.5 3.5H12.5V15H4.5V3.5ZM8.5 11.5C9.16304 11.5 9.79893 11.2366 10.2678 10.7678C10.7366 10.2989 11 9.66304 11 9C11 8.33696 10.7366 7.70107 10.2678 7.23223C9.79893 6.76339 9.16304 6.5 8.5 6.5C7.83696 6.5 7.20107 6.76339 6.73223 7.23223C6.26339 7.70107 6 8.33696 6 9C6 9.66304 6.26339 10.2989 6.73223 10.7678C7.20107 11.2366 7.83696 11.5 8.5 11.5ZM8.5 10.5C8.10218 10.5 7.72064 10.342 7.43934 10.0607C7.15804 9.77936 7 9.39782 7 9C7 8.60218 7.15804 8.22064 7.43934 7.93934C7.72064 7.65804 8.10218 7.5 8.5 7.5C8.89782 7.5 9.27936 7.65804 9.56066 7.93934C9.84196 8.22064 10 8.60218 10 9C10 9.39782 9.84196 9.77936 9.56066 10.0607C9.27936 10.342 8.89782 10.5 8.5 10.5Z" fill="white"/>
<path d="M3.5 15.5V14H13.5V15.5H3.5Z" fill="white"/>
<path d="M8 0.5H9C9.13261 0.5 9.25979 0.552678 9.35355 0.646447C9.44732 0.740215 9.5 0.867392 9.5 1V2H7.5V1C7.5 0.867392 7.55268 0.740215 7.64645 0.646447C7.74021 0.552678 7.86739 0.5 8 0.5Z" fill="white"/>
<path d="M4.51172 4C4.66922 2.322 6.39522 1 8.50022 1C10.6052 1 12.3312 2.322 12.4887 4H4.51172Z" fill="white"/>
<path d="M4 4.25C3.86739 4.25 3.74021 4.19732 3.64645 4.10355C3.55268 4.00979 3.5 3.88261 3.5 3.75C3.5 3.61739 3.55268 3.49021 3.64645 3.39645C3.74021 3.30268 3.86739 3.25 4 3.25H12.9565C13.0891 3.25 13.2163 3.30268 13.3101 3.39645C13.4038 3.49021 13.4565 3.61739 13.4565 3.75C13.4565 3.88261 13.4038 4.00979 13.3101 4.10355C13.2163 4.19732 13.0891 4.25 12.9565 4.25H4ZM4.5 10.449H4C3.86739 10.449 3.74021 10.3963 3.64645 10.3026C3.55268 10.2088 3.5 10.0816 3.5 9.949V7.5C3.5 7.36739 3.55268 7.24021 3.64645 7.14645C3.74021 7.05268 3.86739 7 4 7H4.5C4.63261 7 4.75979 7.05268 4.85355 7.14645C4.94732 7.24021 5 7.36739 5 7.5V9.949C5 10.0816 4.94732 10.2088 4.85355 10.3026C4.75979 10.3963 4.63261 10.449 4.5 10.449ZM13 10.449H12.5C12.3674 10.449 12.2402 10.3963 12.1464 10.3026C12.0527 10.2088 12 10.0816 12 9.949V7.5C12 7.36739 12.0527 7.24021 12.1464 7.14645C12.2402 7.05268 12.3674 7 12.5 7H13C13.1326 7 13.2598 7.05268 13.3536 7.14645C13.4473 7.24021 13.5 7.36739 13.5 7.5V9.949C13.5 10.0816 13.4473 10.2088 13.3536 10.3026C13.2598 10.3963 13.1326 10.449 13 10.449Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3391_13457)">
<path d="M2.27074 1.61914H10.1667C10.8357 1.61914 11.3828 2.16645 11.3828 2.83532V10.7339C11.3828 11.4027 10.8357 11.9499 10.1667 11.9499H6.23086C6.19852 11.3148 5.67304 10.8097 5.02974 10.8097C4.38673 10.8097 3.86126 11.3148 3.8289 11.9499H2.27074C1.60201 11.9499 1.05469 11.4027 1.05469 10.7339V2.83532C1.05467 2.16645 1.602 1.61914 2.27074 1.61914Z" fill="white"/>
<path d="M5.03034 9.64453C6.33849 9.64453 7.39884 10.7049 7.39884 12.0127C7.39884 13.3208 6.33849 14.3811 5.03034 14.3811C3.72246 14.3811 2.66211 13.3208 2.66211 12.0127C2.66213 10.7049 3.72246 9.64453 5.03034 9.64453ZM5.03034 10.8104C4.36631 10.8104 3.82812 11.3487 3.82812 12.0127C3.82812 12.6769 4.36631 13.2153 5.03034 13.2153C5.69464 13.2153 6.23285 12.6769 6.23285 12.0127C6.23285 11.3487 5.69466 10.8104 5.03034 10.8104ZM13.0088 9.64453C14.3166 9.64453 15.377 10.7049 15.377 12.0127C15.377 13.3208 14.3166 14.3811 13.0088 14.3811C11.7006 14.3811 10.6403 13.3208 10.6403 12.0127C10.6403 10.7049 11.7006 9.64453 13.0088 9.64453ZM13.0088 10.8104C12.3445 10.8104 11.8063 11.3487 11.8063 12.0127C11.8063 12.6769 12.3445 13.2153 13.0088 13.2153C13.6728 13.2153 14.211 12.6769 14.211 12.0127C14.211 11.3487 13.6728 10.8104 13.0088 10.8104Z" fill="white"/>
<path d="M16.7418 11.8912H14.7875C14.6766 11.8912 14.5859 11.8004 14.5859 11.6895V10.6197C14.5859 10.5087 14.6767 10.418 14.7875 10.418H16.7418C16.8529 10.418 16.9437 10.5087 16.9437 10.6197V11.6895C16.9437 11.8004 16.8529 11.8912 16.7418 11.8912Z" fill="white"/>
<path d="M11.384 7.98596H16.1528V10.4861H11.384V7.98596ZM11.0762 3.99609H12.8288V5.20027H11.0762V3.99609Z" fill="white"/>
<path d="M15.0312 7.34766H16.1519V8.11969H15.0312V7.34766Z" fill="white"/>
<path d="M12.8282 3.99609L16.1309 7.34876L15.0316 7.73111L12.5093 5.20027L12.8282 3.99609ZM6.97852 8.33567H11.5983V11.9507H6.97852V8.33567Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_3391_13457">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,45 @@
<svg width="136" height="46" viewBox="0 0 136 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_3423_26639" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="4" y="3" width="126" height="36">
<foreignObject x="0" y="0" width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.7px);clip-path:url(#bgblur_0_3423_26639_clip_path);height:100%;width:100%"></div></foreignObject><path data-figma-bg-blur-radius="3.4" d="M122 3.5C126.142 3.5 129.5 6.85786 129.5 11V38.5H4.5V3.5H122Z" fill="black" stroke="url(#paint0_linear_3423_26639)"/>
</mask>
<g mask="url(#mask0_3423_26639)">
<g filter="url(#filter0_f_3423_26639)">
<circle cx="125" cy="8" r="17" fill="#53B4A2" fill-opacity="0.8"/>
</g>
</g>
<foreignObject x="0" y="-0.4" width="136" height="46.4"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.7px);clip-path:url(#bgblur_1_3423_26639_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter1_d_3423_26639)" data-figma-bg-blur-radius="3.4">
<path d="M4 3H122C126.418 3 130 6.58172 130 11V39H4V3Z" fill="#69EBD3" fill-opacity="0.2" shape-rendering="crispEdges"/>
<path d="M122 3.5C126.142 3.5 129.5 6.85786 129.5 11V38.5H4.5V3.5H122Z" stroke="url(#paint1_linear_3423_26639)" shape-rendering="crispEdges"/>
</g>
<defs>
<clipPath id="bgblur_0_3423_26639_clip_path" transform="translate(0 0)"><path d="M122 3.5C126.142 3.5 129.5 6.85786 129.5 11V38.5H4.5V3.5H122Z"/>
</clipPath><filter id="filter0_f_3423_26639" x="97.4" y="-19.6" width="55.2" height="55.2" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="5.3" result="effect1_foregroundBlur_3423_26639"/>
</filter>
<filter id="filter1_d_3423_26639" x="0" y="-0.4" width="136" height="46.4" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dx="1" dy="2"/>
<feGaussianBlur stdDeviation="2.5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0.4 0 0 0 0 0.396078 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3423_26639"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3423_26639" result="shape"/>
</filter>
<clipPath id="bgblur_1_3423_26639_clip_path" transform="translate(0 0.4)"><path d="M4 3H122C126.418 3 130 6.58172 130 11V39H4V3Z"/>
</clipPath><linearGradient id="paint0_linear_3423_26639" x1="1.70313" y1="-10.2857" x2="104.746" y2="31.0913" gradientUnits="userSpaceOnUse">
<stop offset="0.052725" stop-color="white"/>
<stop offset="0.360577" stop-color="white" stop-opacity="0"/>
<stop offset="0.764423" stop-color="#008F8E" stop-opacity="0"/>
<stop offset="1" stop-color="#008F8E"/>
</linearGradient>
<linearGradient id="paint1_linear_3423_26639" x1="1.70313" y1="-10.2857" x2="104.746" y2="31.0913" gradientUnits="userSpaceOnUse">
<stop offset="0.052725" stop-color="white"/>
<stop offset="0.360577" stop-color="white" stop-opacity="0"/>
<stop offset="0.764423" stop-color="#008F8E" stop-opacity="0"/>
<stop offset="1" stop-color="#008F8E"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

@ -1,40 +0,0 @@
<svg width="174" height="25" viewBox="0 0 174 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M172.379 4.32216C172.379 3.88599 172.296 3.48254 172.13 3.1118C171.985 2.74105 171.778 2.41393 171.508 2.13042C171.26 1.86872 170.949 1.65064 170.576 1.47617C170.224 1.32351 169.851 1.24718 169.457 1.24718H151.584H147.046V4.4203V9.81787V10.2104V13.0237H172.379V12.9583V9.81787V4.32216ZM167.84 9.81787H151.584V4.4203H166.877C167.146 4.4203 167.374 4.51843 167.561 4.71471C167.747 4.91099 167.84 5.16178 167.84 5.4671V9.81787ZM146.549 14.5939L152.548 24.4404H156.93L152.89 17.7997H166.815L163.769 23.1319H167.934L173.218 13.8415H169.084L168.649 14.5939H150.931H147.792H146.549Z" fill="url(#paint0_linear_999_11044)"/>
<path d="M136.792 11.6173L138.594 19.7954H142.324L140.521 11.6173H136.792ZM126.099 11.6173H122.369L120.691 19.7954H124.421L126.099 11.6173ZM144.935 7.13569H133.466V1.11658H129.145V7.13569H117.645V7.98622V10.178V10.3415H129.145V21.3329H118.67V21.8236V24.0154V24.5388H143.909V24.0154V21.8236V21.3329H133.466V10.3415H144.935V10.178V7.98622V7.13569Z" fill="url(#paint1_linear_999_11044)"/>
<path d="M91.4438 11.0613V19.4684H89.0194V22.6743H91.4438V24.6697H95.2981V22.6743H96.8211V19.4684H95.2981V15.6084H97.536L95.2981 10.6361V4.12627C95.2981 3.6901 95.2255 3.28665 95.0805 2.9159C94.9354 2.54516 94.7386 2.21804 94.4899 1.93453C94.262 1.67283 93.9822 1.45475 93.6507 1.28028C93.3399 1.12762 92.9979 1.05129 92.625 1.05129H89.268L89.9829 3.34117H90.5424C90.7911 3.34117 90.9983 3.43931 91.1641 3.63558C91.3506 3.83186 91.4438 4.07175 91.4438 4.35526V5.66376H88.9883L91.4438 11.0613ZM116.372 18.7815H112.394V19.5339C112.394 19.8174 112.3 20.0573 112.114 20.2535C111.927 20.4498 111.699 20.548 111.43 20.548H102.043V18.7815H98.0644V23.0668H104.747L104.126 24.5062H108.819L109.441 23.0668H113.295C114.248 23.0668 114.994 22.8378 115.533 22.3799C116.092 21.9219 116.372 21.1913 116.372 20.1881V18.7815ZM103.38 13.4493H98.6861L101.111 18.1272H105.804L103.38 13.4493ZM115.346 13.4493H110.653L108.228 18.1272H112.922L115.346 13.4493ZM104.903 4.25712V9.32756H98.9658V12.5661H115.16V9.32756H109.192V4.25712H115.999V1.01858H98.1577V4.25712H104.903Z" fill="url(#paint2_linear_999_11044)"/>
<path d="M84.4529 18.389C84.9088 18.389 85.3336 18.2909 85.7273 18.0946C86.1417 17.9201 86.494 17.6693 86.7841 17.3422C87.0742 17.0369 87.3022 16.6661 87.4679 16.23C87.6544 15.8156 87.7477 15.3685 87.7477 14.8887V14.2999H85.5719V12.5007V11.0941C85.5719 10.3962 85.3336 9.7965 84.857 9.29491C84.3804 8.79331 83.8105 8.54252 83.1474 8.54252H67.0777V7.39758H85.5719V6.90689V4.94414V3.57021C85.5719 3.22128 85.5097 2.89415 85.3854 2.58884C85.2611 2.28352 85.0849 2.01092 84.857 1.77102C84.6498 1.55294 84.3907 1.37847 84.0799 1.24762C83.7898 1.11677 83.479 1.05135 83.1474 1.05135H62.8504V3.43936V4.94414V7.39758V8.54252V10.9632V12.5007V14.2999H60.457V18.389H71.5225L71.0562 19.2722H75.7497L76.216 18.389H84.4529ZM67.0777 4.94414V3.43936H80.8473C81.1789 3.43936 81.3446 3.61383 81.3446 3.96276V4.94414H67.0777ZM64.7154 16.1973V14.9215H83.4893V15.3467C83.4893 15.5866 83.4064 15.7829 83.2407 15.9355C83.0956 16.11 82.9091 16.1973 82.6812 16.1973H76.1849H71.9266H64.7154ZM81.3446 12.5007H67.0777V10.9632H80.8473C81.1789 10.9632 81.3446 11.1377 81.3446 11.4866V12.5007ZM73.4496 21.464H70.5589L71.3671 19.8938H67.7615L66.9222 21.464H65.4303L64.7464 19.8938H60.457L62.5707 24.6044H66.829L66.4249 23.6884H73.4496V21.464ZM80.6919 24.6044L80.2567 23.6884H87.2814V21.464H84.3907L85.23 19.8938H81.5933L80.7541 21.464H79.2621L78.5783 19.8938H74.2888L76.4025 24.6044H80.6919Z" fill="url(#paint3_linear_999_11044)"/>
<path d="M40.6891 3.07923C40.8134 3.07923 40.8963 3.11194 40.9378 3.17737C40.9378 3.19918 40.9689 3.24279 41.031 3.30822L41.0932 3.47178V5.20555H34.5347V4.09332L33.8509 0.920204H30.4629L31.0535 4.09332V16.6549H42.1189C42.8442 16.6549 43.4658 16.3714 43.9839 15.8044C44.5226 15.2592 44.792 14.6049 44.792 13.8417V3.56992C44.792 3.04652 44.7299 2.63216 44.6055 2.32684C44.4812 2.02153 44.2947 1.73802 44.046 1.47632C43.8595 1.25824 43.6523 1.10558 43.4244 1.01834C43.1757 0.952919 42.9478 0.920204 42.7406 0.920204H39.3215L40.1918 3.07923H40.6891ZM58.0644 16.4587L56.6656 13.5472H49.0193C48.6048 13.5472 48.2319 13.6236 47.9003 13.7762C47.5066 13.9289 47.1854 14.147 46.9367 14.4305C46.6674 14.6922 46.4601 15.0193 46.3151 15.4119C46.1493 15.8262 46.0664 16.2297 46.0664 16.6222V24.5387H50.1072V20.0897L53.1533 24.1788H57.194L52.1276 17.4727H50.1072C50.1072 17.211 50.1901 16.9602 50.3558 16.7204C50.5838 16.5459 50.8221 16.4587 51.0707 16.4587H58.0644ZM58.0644 4.25688L56.6656 1.37818H49.0193C48.5841 1.37818 48.2111 1.45451 47.9003 1.60717C47.7138 1.67259 47.5377 1.75983 47.3719 1.86887C47.2268 1.99972 47.0818 2.13057 46.9367 2.26142C46.6674 2.50131 46.4601 2.82844 46.3151 3.2428C46.1493 3.63535 46.0664 4.0388 46.0664 4.45316V12.3042H50.1072V7.85526L53.1533 12.0098H57.194L52.1276 5.27097H50.1072C50.1072 4.96565 50.1901 4.72576 50.3558 4.5513C50.5838 4.35502 50.8221 4.25688 51.0707 4.25688H58.0644ZM33.8198 24.7676H37.8295L35.9956 20.6786H40.4094L39.7255 22.5105H43.5487L45.2583 17.898H42.9892V17.8653H30.9602L33.8198 24.7676ZM41.0932 7.72441V9.5236H34.5347V7.72441H41.0932ZM34.5347 13.7762V12.0425H41.0932V12.7294C41.0932 13.0129 40.9896 13.2528 40.7824 13.4491C40.5959 13.6672 40.3679 13.7762 40.0985 13.7762H34.5347Z" fill="url(#paint4_linear_999_11044)"/>
<path d="M1.15424 1.05135V3.89734V5.20584V7.43029V8.73879V11.3231V11.6502H23.1919H27.6989V8.73879V7.43029V5.33669V5.20584C27.6782 4.61701 27.5746 4.07181 27.3881 3.57021C27.2223 3.06862 26.984 2.63245 26.6732 2.26171C26.3623 1.89097 25.9997 1.59656 25.5853 1.37847C25.1708 1.16039 24.7357 1.05135 24.2798 1.05135H5.56799H1.15424ZM5.56799 7.43029H23.1919V8.73879H5.56799V7.43029ZM5.56799 3.89734H22.1973C22.4874 3.89734 22.7257 4.01728 22.9122 4.25718C23.0987 4.49707 23.1919 4.79148 23.1919 5.14042V5.20584H5.56799V3.89734ZM15.732 24.6044H28.0719V24.31V21.3658V16.0664C28.0719 15.5648 27.9786 15.0959 27.7921 14.6598C27.6264 14.2236 27.3881 13.8419 27.0772 13.5148C26.7664 13.1877 26.4038 12.926 25.9893 12.7297C25.5749 12.5553 25.1294 12.468 24.6528 12.468H15.732V13.7438V15.7066V21.3658V24.31V24.6044ZM23.7514 21.3658H20.0525V15.7066H22.7878C23.0572 15.7066 23.2852 15.8047 23.4716 16.001C23.6581 16.1973 23.7514 16.4371 23.7514 16.7207V21.3658ZM0.843415 12.468L4.51118 15.8047H0.78125V19.0432H6.12748V20.2209H5.07067H2.77054H0.78125L2.24214 24.6044H6.53156L6.15856 23.4594H14.3022V20.2209H10.448V19.0432H14.4887V15.8047H12.1886L14.8928 12.468H10.5723L8.58302 14.9542L5.84774 12.468H0.843415Z" fill="url(#paint5_linear_999_11044)"/>
<defs>
<linearGradient id="paint0_linear_999_11044" x1="159.883" y1="24.4404" x2="159.883" y2="1.24718" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
<linearGradient id="paint1_linear_999_11044" x1="131.29" y1="24.5388" x2="131.29" y2="1.11658" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
<linearGradient id="paint2_linear_999_11044" x1="102.68" y1="24.6697" x2="102.68" y2="1.01858" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
<linearGradient id="paint3_linear_999_11044" x1="74.1024" y1="24.6044" x2="74.1024" y2="1.05135" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
<linearGradient id="paint4_linear_999_11044" x1="44.2636" y1="24.7676" x2="44.2636" y2="0.920206" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
<linearGradient id="paint5_linear_999_11044" x1="14.4266" y1="24.6044" x2="14.4266" y2="1.05135" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0"/>
<stop offset="0.379808" stop-color="white" stop-opacity="0.01"/>
<stop offset="1" stop-color="white" stop-opacity="0.38"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

@ -1,8 +1,33 @@
<svg width="174" height="25" viewBox="0 0 174 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M172.379 20.9349C172.379 21.3711 172.296 21.7745 172.13 22.1453C171.985 22.516 171.778 22.8432 171.508 23.1267C171.26 23.3884 170.949 23.6064 170.576 23.7809C170.224 23.9336 169.851 24.0099 169.457 24.0099H151.584H147.046V20.8368V15.4392V15.0467V12.2334H172.379V12.2988V15.4392V20.9349ZM167.84 15.4392H151.584V20.8368H166.877C167.146 20.8368 167.374 20.7386 167.561 20.5424C167.747 20.3461 167.84 20.0953 167.84 19.79V15.4392ZM146.549 10.6632L152.548 0.816711H156.93L152.89 7.45736H166.815L163.769 2.12521H167.934L173.218 11.4156H169.084L168.649 10.6632H150.931H147.792H146.549Z" fill="white"/>
<path d="M136.792 13.6398L138.594 5.46164H142.324L140.521 13.6398H136.792ZM126.099 13.6398H122.369L120.691 5.46164H124.421L126.099 13.6398ZM144.935 18.1214H133.466V24.1405H129.145V18.1214H117.645V17.2709V15.0791V14.9156H129.145V3.92415H118.67V3.43346V1.24172V0.718323H143.909V1.24172V3.43346V3.92415H133.466V14.9156H144.935V15.0791V17.2709V18.1214Z" fill="white"/>
<path d="M91.4438 14.1958V5.78863H89.0194V2.58281H91.4438V0.587341H95.2981V2.58281H96.8211V5.78863H95.2981V9.64871H97.536L95.2981 14.621V21.1308C95.2981 21.567 95.2255 21.9704 95.0805 22.3412C94.9354 22.7119 94.7386 23.039 94.4899 23.3225C94.262 23.5842 93.9822 23.8023 93.6507 23.9768C93.3399 24.1295 92.9979 24.2058 92.625 24.2058H89.268L89.9829 21.9159H90.5424C90.7911 21.9159 90.9983 21.8178 91.1641 21.6215C91.3506 21.4252 91.4438 21.1853 91.4438 20.9018V19.5933H88.9883L91.4438 14.1958ZM116.372 6.4756H112.394V5.72321C112.394 5.4397 112.3 5.19981 112.114 5.00353C111.927 4.80726 111.699 4.70912 111.43 4.70912H102.043V6.4756H98.0644V2.19026H104.747L104.126 0.750906H108.819L109.441 2.19026H113.295C114.248 2.19026 114.994 2.41924 115.533 2.87722C116.092 3.33519 116.372 4.06577 116.372 5.06896V6.4756ZM103.38 11.8077H98.6861L101.111 7.12985H105.804L103.38 11.8077ZM115.346 11.8077H110.653L108.228 7.12985H112.922L115.346 11.8077ZM104.903 21V15.9295H98.9658V12.691H115.16V15.9295H109.192V21H115.999V24.2385H98.1577V21H104.903Z" fill="white"/>
<path d="M84.4529 6.86809C84.9088 6.86809 85.3336 6.96623 85.7273 7.1625C86.1417 7.33697 86.494 7.58777 86.7841 7.91489C87.0742 8.22021 87.3022 8.59095 87.4679 9.02712C87.6544 9.44148 87.7477 9.88855 87.7477 10.3683V10.9572H85.5719V12.7563V14.163C85.5719 14.8609 85.3336 15.4606 84.857 15.9622C84.3804 16.4638 83.8105 16.7146 83.1474 16.7146H67.0777V17.8595H85.5719V18.3502V20.3129V21.6869C85.5719 22.0358 85.5097 22.3629 85.3854 22.6682C85.2611 22.9736 85.0849 23.2462 84.857 23.4861C84.6498 23.7041 84.3907 23.8786 84.0799 24.0095C83.7898 24.1403 83.479 24.2057 83.1474 24.2057H62.8504V21.8177V20.3129V17.8595V16.7146V14.2938V12.7563V10.9572H60.457V6.86809H71.5225L71.0562 5.98485H75.7497L76.216 6.86809H84.4529ZM67.0777 20.3129V21.8177H80.8473C81.1789 21.8177 81.3446 21.6432 81.3446 21.2943V20.3129H67.0777ZM64.7154 9.05983V10.3356H83.4893V9.91036C83.4893 9.67046 83.4064 9.47419 83.2407 9.32153C83.0956 9.14706 82.9091 9.05983 82.6812 9.05983H76.1849H71.9266H64.7154ZM81.3446 12.7563H67.0777V14.2938H80.8473C81.1789 14.2938 81.3446 14.1194 81.3446 13.7704V12.7563ZM73.4496 3.79311H70.5589L71.3671 5.36331H67.7615L66.9222 3.79311H65.4303L64.7464 5.36331H60.457L62.5707 0.65271H66.829L66.4249 1.56866H73.4496V3.79311ZM80.6919 0.65271L80.2567 1.56866H87.2814V3.79311H84.3907L85.23 5.36331H81.5933L80.7541 3.79311H79.2621L78.5783 5.36331H74.2888L76.4025 0.65271H80.6919Z" fill="white"/>
<path d="M40.6891 22.1778C40.8134 22.1778 40.8963 22.1451 40.9378 22.0797C40.9378 22.0579 40.9689 22.0143 41.031 21.9489L41.0932 21.7853V20.0515H34.5347V21.1638L33.8509 24.3369H30.4629L31.0535 21.1638V8.60215H42.1189C42.8442 8.60215 43.4658 8.88566 43.9839 9.45267C44.5226 9.99788 44.792 10.6521 44.792 11.4154V21.6872C44.792 22.2106 44.7299 22.6249 44.6055 22.9302C44.4812 23.2356 44.2947 23.5191 44.046 23.7808C43.8595 23.9988 43.6523 24.1515 43.4244 24.2387C43.1757 24.3042 42.9478 24.3369 42.7406 24.3369H39.3215L40.1918 22.1778H40.6891ZM58.0644 8.79842L56.6656 11.7098H49.0193C48.6048 11.7098 48.2319 11.6335 47.9003 11.4809C47.5066 11.3282 47.1854 11.1101 46.9367 10.8266C46.6674 10.5649 46.4601 10.2378 46.3151 9.84522C46.1493 9.43087 46.0664 9.02741 46.0664 8.63486V0.718428H50.1072V5.16733L53.1533 1.07827H57.194L52.1276 7.78433H50.1072C50.1072 8.04604 50.1901 8.29683 50.3558 8.53672C50.5838 8.71119 50.8221 8.79842 51.0707 8.79842H58.0644ZM58.0644 21.0002L56.6656 23.8789H49.0193C48.5841 23.8789 48.2111 23.8026 47.9003 23.6499C47.7138 23.5845 47.5377 23.4973 47.3719 23.3882C47.2268 23.2574 47.0818 23.1265 46.9367 22.9957C46.6674 22.7558 46.4601 22.4286 46.3151 22.0143C46.1493 21.6217 46.0664 21.2183 46.0664 20.8039V12.9529H50.1072V17.4018L53.1533 13.2473H57.194L52.1276 19.9861H50.1072C50.1072 20.2914 50.1901 20.5313 50.3558 20.7058C50.5838 20.9021 50.8221 21.0002 51.0707 21.0002H58.0644ZM33.8198 0.489441H37.8295L35.9956 4.57851H40.4094L39.7255 2.74661H43.5487L45.2583 7.35907H42.9892V7.39179H30.9602L33.8198 0.489441ZM41.0932 17.5327V15.7335H34.5347V17.5327H41.0932ZM34.5347 11.4809V13.2146H41.0932V12.5277C41.0932 12.2441 40.9896 12.0043 40.7824 11.808C40.5959 11.5899 40.3679 11.4809 40.0985 11.4809H34.5347Z" fill="white"/>
<path d="M1.15424 24.2057V21.3597V20.0512V17.8268V16.5183V13.934V13.6069H23.1919H27.6989V16.5183V17.8268V19.9204V20.0512C27.6782 20.6401 27.5746 21.1853 27.3881 21.6869C27.2223 22.1885 26.984 22.6246 26.6732 22.9954C26.3623 23.3661 25.9997 23.6605 25.5853 23.8786C25.1708 24.0967 24.7357 24.2057 24.2798 24.2057H5.56799H1.15424ZM5.56799 17.8268H23.1919V16.5183H5.56799V17.8268ZM5.56799 21.3597H22.1973C22.4874 21.3597 22.7257 21.2398 22.9122 20.9999C23.0987 20.76 23.1919 20.4656 23.1919 20.1167V20.0512H5.56799V21.3597ZM15.732 0.65271H28.0719V0.947123V3.89125V9.19068C28.0719 9.69227 27.9786 10.1612 27.7921 10.5973C27.6264 11.0335 27.3881 11.4151 27.0772 11.7423C26.7664 12.0694 26.4038 12.3311 25.9893 12.5274C25.5749 12.7018 25.1294 12.7891 24.6528 12.7891H15.732V11.5133V9.55052V3.89125V0.947123V0.65271ZM23.7514 3.89125H20.0525V9.55052H22.7878C23.0572 9.55052 23.2852 9.45238 23.4716 9.25611C23.6581 9.05983 23.7514 8.81994 23.7514 8.53643V3.89125ZM0.843415 12.7891L4.51118 9.45238H0.78125V6.21384H6.12748V5.03619H5.07067H2.77054H0.78125L2.24214 0.65271H6.53156L6.15856 1.79765H14.3022V5.03619H10.448V6.21384H14.4887V9.45238H12.1886L14.8928 12.7891H10.5723L8.58302 10.3029L5.84774 12.7891H0.843415Z" fill="white"/>
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3397_13439)">
<g filter="url(#filter0_d_3397_13439)">
<path d="M2.51172 18.0978C2.56285 19.0299 3.33969 19.7562 4.27348 19.7444H13.3305V22.2529H9.86473C9.49996 22.2529 9.2041 22.5488 9.2041 22.9135C9.2041 23.2783 9.49996 23.5742 9.86473 23.5742H18.137C18.5018 23.5742 18.7977 23.2783 18.7977 22.9135C18.7977 22.5488 18.5018 22.2529 18.137 22.2529H14.6709V19.7444H23.7283C24.6618 19.7562 25.4386 19.0299 25.49 18.0978V16.5851H2.51172V18.0978ZM23.728 4.42589H4.27348C3.31836 4.41523 2.53277 5.17538 2.51172 6.13023V15.1107H25.4898V6.13023C25.4687 5.17511 24.6831 4.41523 23.728 4.42589Z" fill="url(#paint0_linear_3397_13439)" shape-rendering="crispEdges"/>
<path d="M25.6396 16.4355V18.1064C25.5836 19.1179 24.7413 19.9052 23.7285 19.8936V19.8945H14.8213V22.1025H18.1367C18.5842 22.1025 18.947 22.4657 18.9473 22.9131C18.9473 23.3607 18.5843 23.7246 18.1367 23.7246H9.86426C9.41686 23.7244 9.05371 23.3605 9.05371 22.9131C9.05396 22.4658 9.41702 22.1028 9.86426 22.1025H13.1807V19.8945H4.27344V19.8936C3.2603 19.9053 2.41805 19.118 2.3623 18.1064L2.36133 18.0977V16.4355H25.6396ZM25.6396 15.2607H2.36133V6.12695C2.38418 5.09051 3.23687 4.26668 4.27344 4.27734V4.27637H23.7275V4.27734C24.7643 4.26641 25.6168 5.09005 25.6396 6.12695V15.2607Z" stroke="url(#paint1_linear_3397_13439)" stroke-width="0.3" shape-rendering="crispEdges"/>
</g>
</g>
<defs>
<filter id="filter0_d_3397_13439" x="1.21094" y="3.125" width="27.5781" height="23.75" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dx="1" dy="1"/>
<feGaussianBlur stdDeviation="1"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3397_13439"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3397_13439" result="shape"/>
</filter>
<linearGradient id="paint0_linear_3397_13439" x1="25.49" y1="14" x2="2.51172" y2="14" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.8"/>
<stop offset="1" stop-color="white" stop-opacity="0.95"/>
</linearGradient>
<linearGradient id="paint1_linear_3397_13439" x1="2.99043" y1="4.42578" x2="24.3116" y2="5.53887" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="0.154628" stop-color="white" stop-opacity="0"/>
<stop offset="0.860577" stop-color="#033838" stop-opacity="0"/>
<stop offset="1" stop-color="#033838"/>
</linearGradient>
<clipPath id="clip0_3397_13439">
<rect width="28" height="28" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -247,7 +247,7 @@ const CustomBreadcrumb = () => {
}, [location.pathname]);
return (
<div className="bread-crumb" style={{ maxHeight: '32px', flexWrap: 'nowrap' }}>
<div className="bread-crumb" style={{ Height: '50px', flexWrap: 'nowrap' }}>
<Breadcrumb separator="" >
{breadcrumbList.map((item, index) => (
<Breadcrumb.Item

@ -6,7 +6,7 @@
overflow-y: hidden;
height: auto;
max-width: 100%;
margin: 8px 0;
margin: 2px 0;
padding: 0 12px;
background-color: transparent;
flex-wrap: nowrap;
@ -45,7 +45,7 @@
// 面包屑项基础样式
.breadcrumb-item {
height: 32px;
height: 38px;
padding: 0 12px;
border-radius: 8px;
// 使用rgba格式设置带透明度的背景色最后一个参数0.13表示13%的透明度
@ -84,7 +84,7 @@
// 悬停效果
&:hover {
border-color: #0056FF;
// border-color: #0056FF;
// transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 86, 255, 0.1);
}
@ -92,11 +92,14 @@
// 面包屑项选中状态样式
.breadcrumb-item-active {
background-color: rgba(94, 121, 246, 0.13);
// border-color: #0056FF;
background: url("@/assets/img/menu2.svg") no-repeat center center;
background-size: 100% 100%;
// border: 1px solid #fff;
border-radius: 8px;
.ant-breadcrumb-link {
color: #0056FF !important;
// color: #0056FF !important;
font-weight: 500;
}
}
@ -145,7 +148,7 @@
flex-shrink: 0;
&:hover {
color: #0056FF;
// color: #0056FF;
}
}
@ -156,9 +159,9 @@
}
.ant-breadcrumb-link:hover {
color: #0056FF !important;
// color: #0056FF !important;
}
.ant-breadcrumb-item-active .ant-breadcrumb-link {
color: #0056FF !important;
// color: #0056FF !important;
}

@ -1,36 +1,28 @@
import React, { useState } from 'react';
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
import styles from './basic.less';
import ResponsibilityImplementation from './components/ResponsibilityImplementation';
import OnlineMonitoring from './components/OnlineMonitoring';
import RiskAssessment from './components/RiskAssessment';
import EvaluationReport from './components/EvaluationReport';
import LicenseManagement from './components/LicenseManagement';
import OilDataManagement from './components/OilDataManagement';
import CustomerInfoManagement from './components/CustomerInfoManagement';
import DataModeling from './components/DataModeling';
const SafeMajorHazardList = () => {
const [activeModule, setActiveModule] = useState('organization');
const [activeModule, setActiveModule] = useState('oilData');
const handleModuleClick = (module) => {
setActiveModule(module)
}
const renderModule = () => {
switch (activeModule) {
case 'organization':
return <ResponsibilityImplementation />;
case 'license':
return <LicenseManagement />;
case 'equipment':
return <OnlineMonitoring />;
case 'firefighting':
return <RiskAssessment />;
case 'other':
return <EvaluationReport />;
case 'oilData':
return <OilDataManagement />;
case 'customerInfo':
return <CustomerInfoManagement />;
case 'dataModeling':
return <DataModeling />;
default:
return <ResponsibilityImplementation />;
return <OilDataManagement />;
}
};
@ -39,24 +31,19 @@ const SafeMajorHazardList = () => {
<div className={styles.container}>
<div className={styles.TopButton}>
<Button
className={`${styles.TopButtonItem} ${activeModule === "organization" ? styles.active : ""}`}
onClick={() => handleModuleClick("organization")}
>组织机构管理
className={`${styles.TopButtonItem} ${activeModule === "oilData" ? styles.active : ""}`}
onClick={() => handleModuleClick("oilData")}
>油资料管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "license" ? styles.active : ""}`}
onClick={() => handleModuleClick("license")}
>资质证照管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "firefighting" ? styles.active : ""}`}
onClick={() => handleModuleClick("firefighting")}
>设备设施管理
className={`${styles.TopButtonItem} ${activeModule === "customerInfo" ? styles.active : ""}`}
onClick={() => handleModuleClick("customerInfo")}
>客户信息管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "other" ? styles.active : ""}`}
onClick={() => handleModuleClick("other")}
>建筑消防与器材管理
className={`${styles.TopButtonItem} ${activeModule === "dataModeling" ? styles.active : ""}`}
onClick={() => handleModuleClick("dataModeling")}
>数据建模
</Button>
</div>
<div className={styles.content}>

@ -1,5 +1,4 @@
.container {
background-color: transparent;
width: 100%;
height: 89vh;
overflow: hidden;
@ -7,7 +6,7 @@
flex-direction: column;
.TopButton {
background-color: white;
background-color: #FFFFFF;
width: 100%;
padding: 10px 30px;
display: flex;

@ -0,0 +1,122 @@
import React from 'react';
import { Card, Table, Input, Button, Space } from 'antd';
import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
import styles from './CustomerInfoManagement.less';
const CustomerInfoManagement = () => {
const onSearch = (value) => {
console.log('搜索内容:', value);
};
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: '客户名称',
dataIndex: 'customerName',
key: 'customerName',
width: 150,
},
{
title: '联系人',
dataIndex: 'contact',
key: 'contact',
width: 120,
},
{
title: '联系电话',
dataIndex: 'phone',
key: 'phone',
width: 150,
},
{
title: '公司地址',
dataIndex: 'address',
key: 'address',
width: 200,
},
{
title: '客户类型',
dataIndex: 'customerType',
key: 'customerType',
width: 120,
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 180,
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
width: 150,
render: (text, record) => (
<Space>
<Button type="link" size="small">编辑</Button>
<Button type="link" size="small" danger>删除</Button>
</Space>
),
},
];
const tableData = [
{
key: '1',
id: '001',
customerName: '某某石油公司',
contact: '张经理',
phone: '138****8888',
address: '北京市朝阳区xxx路xxx号',
customerType: '企业客户',
createTime: '2024-12-20 10:00:00',
},
{
key: '2',
id: '002',
customerName: '某某加油站',
contact: '李经理',
phone: '139****9999',
address: '上海市浦东新区xxx路xxx号',
customerType: '零售客户',
createTime: '2024-12-20 10:00:00',
},
];
return (
<div className={styles.container}>
<Card>
<div className={styles.header}>
<div className={styles.title}>客户信息管理</div>
<Space>
<Input.Search
placeholder="搜索客户名称..."
onSearch={onSearch}
style={{ width: 200 }}
prefix={<SearchOutlined />}
/>
<Button type="primary" icon={<PlusOutlined />}>
新增客户
</Button>
</Space>
</div>
<Table
columns={columns}
dataSource={tableData}
pagination={{
pageSize: 10,
showTotal: (total) => `${total}`,
}}
/>
</Card>
</div>
);
};
export default CustomerInfoManagement;

@ -0,0 +1,19 @@
.container {
padding: 20px;
background: #f5f5f5;
min-height: 100%;
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.title {
font-size: 18px;
font-weight: 600;
color: #333;
}
}
}

@ -0,0 +1,136 @@
import React from 'react';
import { Card, Table, Input, Button, Space } from 'antd';
import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
import styles from './DataModeling.less';
const DataModeling = () => {
const onSearch = (value) => {
console.log('搜索内容:', value);
};
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: '模型名称',
dataIndex: 'modelName',
key: 'modelName',
width: 150,
},
{
title: '模型类型',
dataIndex: 'modelType',
key: 'modelType',
width: 120,
},
{
title: '数据源',
dataIndex: 'dataSource',
key: 'dataSource',
width: 150,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (text) => {
const statusMap = {
'运行中': { color: '#52c41a', bg: '#f6ffed' },
'已停止': { color: '#ff4d4f', bg: '#fff1f0' },
'待启动': { color: '#faad14', bg: '#fffbe6' },
};
const style = statusMap[text] || {};
return (
<span
style={{
color: style.color,
backgroundColor: style.bg,
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px',
}}
>
{text}
</span>
);
},
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 180,
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
width: 200,
render: (text, record) => (
<Space>
<Button type="link" size="small">编辑</Button>
<Button type="link" size="small">运行</Button>
<Button type="link" size="small" danger>删除</Button>
</Space>
),
},
];
const tableData = [
{
key: '1',
id: '001',
modelName: '销售预测模型',
modelType: '预测模型',
dataSource: '销售数据表',
status: '运行中',
createTime: '2024-12-20 10:00:00',
},
{
key: '2',
id: '002',
modelName: '库存分析模型',
modelType: '分析模型',
dataSource: '库存数据表',
status: '已停止',
createTime: '2024-12-20 10:00:00',
},
];
return (
<div className={styles.container}>
<Card>
<div className={styles.header}>
<div className={styles.title}>数据建模</div>
<Space>
<Input.Search
placeholder="搜索模型名称..."
onSearch={onSearch}
style={{ width: 200 }}
prefix={<SearchOutlined />}
/>
<Button type="primary" icon={<PlusOutlined />}>
新建模型
</Button>
</Space>
</div>
<Table
columns={columns}
dataSource={tableData}
pagination={{
pageSize: 10,
showTotal: (total) => `${total}`,
}}
/>
</Card>
</div>
);
};
export default DataModeling;

@ -0,0 +1,19 @@
.container {
padding: 20px;
background: #f5f5f5;
min-height: 100%;
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.title {
font-size: 18px;
font-weight: 600;
color: #333;
}
}
}

@ -1,922 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, Result, Select, Button, Segmented, Progress, Input } from 'antd';
import { CheckCircleOutlined, ExportOutlined, HeartFilled, LineHeightOutlined, ExclamationCircleOutlined, SearchOutlined } from '@ant-design/icons';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
import styles from './EvaluationReport.less';
import img1 from '@/assets/safe_majorHazard/online_monitoring/img1.png';
import img2 from '@/assets/safe_majorHazard/online_monitoring/img2.png';
import img3 from '@/assets/safe_majorHazard/online_monitoring/img3.png';
import map1 from '@/assets/safe_majorHazard/online_monitoring/map.png';
import risk1 from '@/assets/safe_majorHazard/online_monitoring/risk1.png';
import risk2 from '@/assets/safe_majorHazard/online_monitoring/risk2.png';
import risk3 from '@/assets/safe_majorHazard/online_monitoring/risk3.png';
import eqicon1 from '@/assets/business_basic/eqicon1.png';
import eqicon2 from '@/assets/business_basic/eqicon2.png';
import eqicon3 from '@/assets/business_basic/eqicon3.png';
import eqicon4 from '@/assets/business_basic/eqicon4.png';
const EvaluationReport = () => {
const chartRef = useRef(null);
const pieChartRef = useRef(null);
const faultPieChartRef = useRef(null);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [selectedRows, setSelectedRows] = useState([]);
const [loading, setLoading] = useState(false);
const [dataSource, setDataSource] = useState([]);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 8,
total: 0,
});
const [searchText, setSearchText] = useState('');
// 柱状图初始化
useEffect(() => {
if (pieChartRef.current) {
const barChart = echarts.init(pieChartRef.current);
const barOption = {
grid: {
left: '5%',
right: '5%',
bottom: '10%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['灭火器', '消火栓', '报警器', '疏散灯', '排烟设备'],
axisLabel: {
fontSize: 12,
color: '#333',
interval: 0,
rotate: 0
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
yAxis: {
type: 'value',
min: 0,
max: 50,
interval: 10,
axisLabel: {
fontSize: 12,
color: '#666',
formatter: '{value}'
},
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
lineStyle: {
color: '#00001A26',
type: 'dashed'
}
}
},
series: [{
name: '使用次数',
type: 'bar',
barWidth: 27,
data: [35, 28, 42, 31, 38],
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: '#199BFB' },
{ offset: 1, color: '#1373FA' }
]
}
},
emphasis: {
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: '#0D7AE8' },
{ offset: 1, color: '#0F5BC7' }
]
}
}
}
}],
legend: {
show: true,
top: '5%',
left: 'center',
itemWidth: 15,
itemHeight: 3,
textStyle: {
fontSize: 12,
color: '#333'
},
data: [{
name: '使用次数',
icon: 'rect',
itemStyle: {
color: '#4B69F1'
}
}]
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
return `${params[0].name}<br/>使用次数: ${params[0].value}`;
}
}
};
barChart.setOption(barOption);
// 响应式调整
const handleBarResize = () => {
if (barChart && !barChart.isDisposed()) {
barChart.resize();
}
};
window.addEventListener('resize', handleBarResize);
return () => {
window.removeEventListener('resize', handleBarResize);
if (barChart && !barChart.isDisposed()) {
barChart.dispose();
}
};
}
}, []);
// 维护费用趋势折线图初始化
useEffect(() => {
if (faultPieChartRef.current) {
const faultPieChart = echarts.init(faultPieChartRef.current);
const faultPieOption = {
legend: {
show: true,
top: '5%',
left: 'center',
itemWidth: 20,
itemHeight: 8,
textStyle: {
color: '#333',
fontSize: 12
}
},
grid: {
left: '5%',
right: '5%',
bottom: '10%',
top: '20%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisLine: {
lineStyle: {
color: '#E5E5E5'
}
},
axisTick: {
show: false
},
axisLabel: {
color: '#666',
fontSize: 12,
interval: 0
}
},
yAxis: {
type: 'value',
min: 20000,
max: 30000,
interval: 2000,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#666',
fontSize: 12,
formatter: '¥{value}'
},
splitLine: {
lineStyle: {
color: '#00001A26',
type: 'dashed'
}
}
},
series: [{
name: '费用',
type: 'line',
data: [29000, 21000, 27500, 21900, 26000, 25000, 27000, 24000, 22300, 28000, 29000, 27000],
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: {
color: '#1269FF',
width: 1
},
itemStyle: {
color: '#fff',
borderColor: '#1269FF',
borderWidth: 1
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(18, 105, 255, 0.3)'
}, {
offset: 1,
color: 'rgba(18, 105, 255, 0.05)'
}]
}
}
}]
};
faultPieChart.setOption(faultPieOption);
// 响应式调整
const handleFaultPieResize = () => {
if (faultPieChart && !faultPieChart.isDisposed()) {
faultPieChart.resize();
}
};
window.addEventListener('resize', handleFaultPieResize);
return () => {
window.removeEventListener('resize', handleFaultPieResize);
if (faultPieChart && !faultPieChart.isDisposed()) {
faultPieChart.dispose();
}
};
}
}, []);
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
// 强制初始化时调整大小
setTimeout(() => {
if (chart && !chart.isDisposed()) {
chart.resize();
}
}, 100);
const option = {
color: ['#3C7EFF', '#FF8800', '#FFC403', '#31BCFF'],
legend: {
orient: 'vertical',
right: '2%',
top: 'middle',
itemWidth: 14,
itemHeight: 5,
textStyle: {
fontSize: 10,
color: '#666'
}
},
tooltip: {
trigger: 'item',
formatter: '{b}<br/>{d}%'
},
series: [
{
name: '设备类型占比',
type: 'pie',
radius: '70%',
center: ['40%', '55%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 0,
borderColor: '#fff',
borderWidth: 1
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: false
}
},
labelLine: {
show: false
},
data: [
{ value: 25, name: '灭火器' },
{ value: 30, name: '消防栓' },
{ value: 20, name: '报警器' },
{ value: 25, name: '烟雾探测器' }
]
}
]
};
chart.setOption(option);
// 响应式调整 - 使用多种方式监听容器尺寸变化
let resizeTimer = null;
const handleResize = () => {
// 防抖处理避免频繁调用resize
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(() => {
if (chart && !chart.isDisposed()) {
chart.resize();
}
}, 50); // 减少延迟时间
};
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
// 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题)
let resizeObserver = null;
if (window.ResizeObserver) {
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
// 使用requestAnimationFrame确保在下一帧执行
requestAnimationFrame(() => {
handleResize();
});
}
});
resizeObserver.observe(chartRef.current);
}
// 额外监听父容器的尺寸变化
const parentContainer = chartRef.current?.parentElement;
let parentObserver = null;
if (parentContainer && window.ResizeObserver) {
parentObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
requestAnimationFrame(() => {
handleResize();
});
}
});
parentObserver.observe(parentContainer);
}
// 使用MutationObserver监听DOM结构变化菜单展开收起时
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
// 延迟执行确保DOM更新完成
setTimeout(() => {
handleResize();
}, 200);
}
});
});
// 监听整个页面的class和style变化
mutationObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style'],
subtree: true
});
return () => {
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
}
if (parentObserver) {
parentObserver.disconnect();
}
if (mutationObserver) {
mutationObserver.disconnect();
}
if (resizeTimer) {
clearTimeout(resizeTimer);
}
if (chart && !chart.isDisposed()) {
chart.dispose();
}
};
}
}, []);
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 60,
render: (text, record, index) => {
const page = pagination.current || 1;
const pageSize = pagination.pageSize || 8;
const number = (page - 1) * pageSize + index + 1;
return `0${number}`.slice(-2);
}
},
{
title: '设备编号',
dataIndex: 'deviceId',
key: 'deviceId',
width: 140,
},
{
title: '设备名称',
dataIndex: 'deviceName',
key: 'deviceName',
width: 110,
},
{
title: '类型',
dataIndex: 'modelSpec',
key: 'modelSpec',
width: 120,
},
{
title: '安装位置',
dataIndex: 'installLocation',
key: 'installLocation',
width: 100,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (text) => {
const statusMap = {
'报废': { color: '#FF3E48', bg: '#FFE0E2' },
'待维修': { color: '#FF8800', bg: '#FFF3E9' },
'已使用': { color: '#00AAFA', bg: '#DAF3FF' },
'正常': { color: '#44BB5F', bg: '#D8F7DE' }
};
const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
return (
<span style={{
color: status.color,
backgroundColor: status.bg,
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px'
}}>
{text}
</span>
);
}
},
{
title: '最后维护时间',
dataIndex: 'lastMaintenance',
key: 'lastMaintenance',
width: 150,
},
{
title: '操作',
key: 'action',
width: 140,
render: (_, record) => (
<div>
<Button type="link" size="small" style={{
padding: '2px 8px',
fontSize: 12,
marginRight: 8,
border: '1px solid #E6E9FB',
backgroundColor: 'transparent',
borderRadius: '4px'
}}>
编辑
</Button>
<Button type="link" size="small" style={{
padding: '2px 8px',
fontSize: 12,
color: '#FF2526',
border: '1px solid #FFE0E2',
backgroundColor: 'transparent',
borderRadius: '4px'
}}>
删除
</Button>
</div>
),
},
];
// 模拟数据
const mockData = [
{
key: '1',
id: '001',
deviceId: 'HQ-XF-01-001',
deviceName: '干粉灭火器',
modelSpec: '灭火设备',
installLocation: '1层大厅',
status: '报废',
lastMaintenance: '2025-09-10',
},
{
key: '2',
id: '002',
deviceId: 'HQ-XF-02-015',
deviceName: '室内消火栓',
modelSpec: '灭火设备',
installLocation: '3层东区',
status: '已使用',
lastMaintenance: '2025-09-10',
},
{
key: '3',
id: '003',
deviceId: 'HQ-XF-03-007',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '4',
id: '004',
deviceId: 'HQ-XF-03-008',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '待维修',
lastMaintenance: '2025-09-10',
},
{
key: '5',
id: '005',
deviceId: 'HQ-XF-01-009',
deviceName: '干粉灭火器',
modelSpec: '灭火设备',
installLocation: '地下一层',
status: '报废',
lastMaintenance: '2025-09-10',
},
{
key: '6',
id: '006',
deviceId: 'HQ-XF-01-010',
deviceName: '室内消火栓',
modelSpec: '灭火设备',
installLocation: '地下一层',
status: '已使用',
lastMaintenance: '2025-09-10',
},
{
key: '7',
id: '007',
deviceId: 'HQ-XF-01-011',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '待维修',
lastMaintenance: '2025-09-10',
},
{
key: '8',
id: '008',
deviceId: 'HQ-XF-01-012',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '9',
id: '009',
deviceId: 'HQ-XF-01-013',
deviceName: '干粉灭火器',
modelSpec: '灭火设备',
installLocation: '地下一层',
status: '已使用',
lastMaintenance: '2025-09-10',
},
{
key: '10',
id: '010',
deviceId: 'HQ-XF-01-014',
deviceName: '室内消火栓',
modelSpec: '灭火设备',
installLocation: '地下一层',
status: '待维修',
lastMaintenance: '2025-09-10',
},
{
key: '11',
id: '011',
deviceId: 'HQ-XF-01-015',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '12',
id: '012',
deviceId: 'HQ-XF-01-016',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下一层',
status: '已使用',
lastMaintenance: '2025-09-10',
},
{
key: '13',
id: '013',
deviceId: 'HQ-XF-01-017',
deviceName: '干粉灭火器',
modelSpec: '灭火设备',
installLocation: '2层西区',
status: '报废',
lastMaintenance: '2024-08-15',
},
{
key: '14',
id: '014',
deviceId: 'HQ-XF-02-018',
deviceName: '室内消火栓',
modelSpec: '灭火设备',
installLocation: '4层南区',
status: '报废',
lastMaintenance: '2024-07-20',
},
{
key: '15',
id: '015',
deviceId: 'HQ-XF-03-019',
deviceName: '火警报警器',
modelSpec: '报警设备',
installLocation: '地下二层',
status: '报废',
lastMaintenance: '2024-06-10',
},
{
key: '16',
id: '016',
deviceId: 'HQ-XF-01-020',
deviceName: '干粉灭火器',
modelSpec: '灭火设备',
installLocation: '5层北区',
status: '报废',
lastMaintenance: '2024-05-05',
},
];
// 初始化数据
useEffect(() => {
setPagination(prev => ({ ...prev, total: mockData.length }));
}, []);
// 根据分页获取当前页数据
const getCurrentPageData = () => {
const { current, pageSize } = pagination;
const startIndex = (current - 1) * pageSize;
const endIndex = startIndex + pageSize;
return mockData.slice(startIndex, endIndex);
};
// 表格选择变化
const onSelectChange = (newSelectedRowKeys, newSelectedRows) => {
setSelectedRowKeys(newSelectedRowKeys);
setSelectedRows(newSelectedRows);
};
// 新增设备按钮点击事件
const handleAddDevice = () => {
console.log('新增设备');
// TODO: 实现新增设备逻辑
};
// 导出数据按钮点击事件
const handleExportData = () => {
console.log('导出数据');
// TODO: 实现导出数据逻辑
};
// 分页变化处理
const handleTableChange = (pagination) => {
setPagination(prev => ({
...prev,
current: pagination.current,
pageSize: pagination.pageSize,
}));
};
// 搜索处理
const handleSearchChange = (e) => {
setSearchText(e.target.value);
console.log('搜索:', e.target.value);
// TODO: 实现搜索逻辑,根据设备名称、编号等筛选数据
};
return (
<div className={styles.Econtainer}>
{/* 第1个div - 高度39% */}
<div className={styles.EcontainerMiddle}>
<div className={styles.sectionContent}>
<div className={styles.middleBlock1}>
<div className={styles.block1Header}>
<div className={styles.block1Title}>
<div className={styles.titleIcon}></div>
设备使用频率分析
</div>
</div>
{/* 设备状态饼图 */}
<div className={styles.deviceStatusChart} ref={pieChartRef}>
</div>
</div>
<div className={styles.middleBlock12}>
<div className={styles.block1Header}>
<div className={styles.block1Title}>
<div className={styles.titleIcon}></div>
近一年维护费用趋势
</div>
</div>
{/* 维护费用趋势折线图 */}
<div className={styles.deviceStatusChart} ref={faultPieChartRef}>
</div>
</div>
<div className={styles.middleBlock2}>
<div className={styles.middleBlock2Title}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>设备类型占比</div>
</div>
</div>
<div className={styles.middleBlock2Chart} ref={chartRef}>
</div>
</div>
</div>
</div>
{/* 第2个div - 占满剩余位置 */}
<div className={styles.EcontainerBottom}>
<div className={styles.sectionContent}>
<div className={styles.leftBlock}>
<div className={styles.maintenanceStack}>
<div className={styles.maintenanceSection}>
<div className={styles.maintenanceTitle}>
<div className={styles.titleIcon}></div>
<div>近期维护提醒</div>
</div>
<div className={styles.maintenanceContent1}>
<div className={styles.maintenanceItem}>
<div className={styles.maintenanceLeft}>
<div className={styles.maintenanceText1}>SH-MHQ-023-C 干粉灭火器</div>
<div className={styles.maintenanceText2}>位置: 4楼办公区丨维护类型: 季度检查</div>
<div className={styles.maintenanceText3}>负责人: 张三</div>
</div>
<div className={styles.maintenanceRight}>
<div className={styles.maintenanceStatus}>3天后到期</div>
</div>
</div>
<div className={styles.maintenanceItem}>
<div className={styles.maintenanceLeft}>
<div className={styles.maintenanceText1}>SH-XHS-045-D 室内消火栓</div>
<div className={styles.maintenanceText2}>位置: 2楼东侧走廊丨维护类型: 水压测试</div>
<div className={styles.maintenanceText3}>负责人: 李四</div>
</div>
<div className={styles.maintenanceRight2}>
<div className={styles.maintenanceStatus}>8天后到期</div>
</div>
</div>
</div>
</div>
<div className={styles.maintenanceSection}>
<div className={styles.maintenanceTitle}>
<div className={styles.titleIcon}></div>
<div>维护任务进度</div>
</div>
<div className={styles.maintenanceContent2}>
{/* 进度条区域 */}
<div className={styles.progressSection}>
<div className={styles.progressLabel}>月度维护计划</div>
<Progress percent={75} status="active" />
<div className={styles.progressLabel}>季度维护计划</div>
<Progress percent={60} status="active" />
<div className={styles.progressLabel}>年度维护计划</div>
<Progress percent={85} status="active" />
{/* 警告提示框 */}
<div className={styles.warningBox}>
<ExclamationCircleOutlined className={styles.warningIcon} />
<span className={styles.warningText}>本月有5项维护任务即将到期</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.rightBlock}>
{/* 表格 */}
<div className={styles.tableHeader}>
<div className={styles.tableTitle}>
<div className={styles.titleIcon}></div>
<div>消防设施与器材列表</div>
</div>
</div>
{/* 操作按钮 */}
<div className={styles.tableActions}>
<div className={styles.leftActions}>
<Input
placeholder="搜索设备名称、编号..."
onChange={handleSearchChange}
value={searchText}
style={{ width: 250, fontSize: 12 }}
allowClear
suffix={<SearchOutlined />}
/>
</div>
<div className={styles.rightActions}>
<button className={styles.actionButton} onClick={handleAddDevice}>
<span className={styles.buttonIcon}>+</span>
<span>新增设备</span>
</button>
<button className={styles.actionButton} onClick={handleExportData}>
<span className={styles.buttonIcon}><ExportOutlined /></span>
<span>导出数据</span>
</button>
</div>
</div>
{/* 表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: getCurrentPageData(),
pagination: pagination
}}
loading={loading}
selectionType="checkbox"
onSelectRow={onSelectChange}
onChange={handleTableChange}
pagination={{
...pagination,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
}}
/>
</div>
</div>
</div>
</div>
</div>
);
};
export default EvaluationReport;

@ -1,558 +0,0 @@
.Econtainer {
padding: 8px 6px 0px 6px;
height: 100%;
display: flex;
flex-direction: column;
gap: 10px;
// 第二个div - 高度35%
.EcontainerMiddle {
// height: 400px;
min-height: 35%;
border-radius: 4px;
display: flex;
flex-direction: column;
.sectionContent {
height: 100%;
display: flex;
display: flex;
gap: 10px;
height: 100%;
.middleBlock1 {
width: 30%;
height: 100%;
background: #fff;
border: 2px solid #fff;
position: relative;
padding: 0px 10px 10px 2px;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
.block1Header {
position: absolute;
top: 5px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
.block1Title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
margin-top: 5px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
}
.deviceStatusChart {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
z-index: 10;
min-height: 100%;
}
}
.middleBlock12 {
flex: 1;
height: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
padding: 5px 10px 5px 10px;
position: relative;
.block1Header {
position: absolute;
top: 5px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
.block1Title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
margin-top: 5px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
}
.deviceStatusChart {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
// bottom: 10px;
z-index: 10;
}
}
.middleBlock12 {
width: 45%;
height: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
padding: 5px 10px 5px 10px;
position: relative;
.block1Header {
position: absolute;
top: 5px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
.block1Title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
}
.deviceStatusChart {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
// bottom: 10px;
min-height: 100%;
z-index: 10;
}
}
.middleBlock2 {
// flex: 1;
width: calc(100% - 75% - 15px);
height: 100%;
// background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 53.01%);
// border: 2px solid #fff;
background-color: #fff;
// border-radius: 4px;
display: flex;
flex-direction: column;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
padding: 5px 10px 5px 10px;
.middleBlock2Title {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 5px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
}
.middleBlock2Chart {
width: 100%;
height: 100%;
}
}
}
}
// 第三个div - 占满剩余位置
.EcontainerBottom {
display: flex;
flex-direction: column;
flex-shrink: 0;
.sectionContent {
display: flex;
flex-direction: row;
flex: 1;
gap: 10px;
padding: 0;
.leftBlock {
width: 30%;
flex-shrink: 0;
height: 100%;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
.leftBlockTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
margin-bottom: 10px;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.maintenanceStack {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 10px;
.maintenanceSection {
width: 100%;
height: 50%;
background: #FFF;
border-radius: 4px;
display: flex;
flex-direction: column;
padding: 12px 14px;
.maintenanceTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
margin-bottom: 8px;
}
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
.maintenanceContent {
flex: 1;
width: 100%;
}
.maintenanceContent1 {
flex: 1;
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 8px;
.maintenanceItem {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #F1F7FF;
border-radius: 4px;
padding: 16px 16px;
.maintenanceLeft {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
.maintenanceText1 {
font-size: 14px;
font-weight: 500;
color: #333333;
font-family: PingFang SC;
}
.maintenanceText2 {
font-size: 12px;
color: #666666;
font-family: PingFang SC;
}
.maintenanceText3 {
font-size: 12px;
color: #666666;
font-family: PingFang SC;
}
}
.maintenanceRight {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
.maintenanceStatus {
font-size: 12px;
color: #FF3E48;
font-weight: 500;
font-family: PingFang SC;
background-color: #FFE0E2;
padding: 4px 8px;
border-radius: 4px;
// border: 1px solid #FFE0E2;
}
}
.maintenanceRight2 {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
.maintenanceStatus {
font-size: 12px;
color: #FF8800;
font-weight: 500;
font-family: PingFang SC;
background-color: #FFF3E9;
padding: 4px 8px;
border-radius: 4px;
// padding-right: 2px;
}
}
}
}
.maintenanceContent2 {
flex: 1;
width: 100%;
display: flex;
flex-direction: column;
gap: 15px;
padding: 8px 0;
.warningBox {
display: flex;
align-items: center;
gap: 8px;
background-color: #FFF3CD;
border: 1px solid #F4E3AE;
border-radius: 4px;
padding: 8px 12px;
// margin-bottom: 8px;
// margin-top: 10px;
.warningIcon {
color: #8C6C0B;
font-size: 14px;
}
.warningText {
color: #8C6C0B;
font-size: 12px;
font-family: PingFang SC;
font-weight: 400;
}
}
.progressSection {
width: 100%;
display: flex;
flex-direction: column;
// gap: 12px;
padding: 0px 12px 12px 12px;
.progressLabel {
font-size: 12px;
color: #666666;
font-family: PingFang SC;
font-weight: 400;
}
// 自定义进度条样式
:global(.ant-progress) {
.ant-progress-bg {
background: linear-gradient(90deg, #2E4CD4 0%, #4B69F1 100%);
}
.ant-progress-text {
color: #2E4CD4;
font-weight: 500;
}
}
}
}
}
}
}
.rightBlock {
width: calc(100% - 28% - 10px);
height: 100%;
background-color: #fff;
padding: 0;
display: flex;
flex-direction: column;
.tableHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 11px 15px 5px 15px;
.tableTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
}
.tableActions {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
margin-top: 5px;
padding: 0px 15px;
.leftActions {
display: flex;
align-items: center;
}
.rightActions {
display: flex;
gap: 8px;
align-items: center;
}
.actionButton {
display: flex;
align-items: center;
gap: 4px;
height: 28px;
border: 1px solid #DFE4F6;
border-radius: 4px;
color: #2E4CD4;
font-weight: 500;
font-size: 12px;
padding: 0px 8px;
background: transparent;
cursor: pointer;
transition: all 0.2s ease;
&:hover {
background-color: #f0f2ff;
border-color: #2E4CD4;
}
&:active {
background-color: #e6ebff;
}
.buttonIcon {
font-size: 14px;
font-weight: bold;
}
}
}
.tableContainer {
flex: 1;
overflow: hidden;
margin: 10px 15px 0 15px; // 上边距10px左右边距15px
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
color: #666666;
}
:global(.ant-table-tbody > tr:hover > td) {
background-color: #f5f5f5;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}
}
}
}

@ -1,604 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, Table, Tag, Space, Typography, Progress, Row, Col, Button, Input, Select } from 'antd';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
import styles from './LicenseManagement.less';
import icon_echart from '@/assets/business_basic/icon_echart.svg';
const { Title } = Typography;
const { Search } = Input;
const { Option } = Select;
const LicenseManagement = () => {
const chartRef = useRef(null);
const [searchValue, setSearchValue] = useState('');
const [selectedType, setSelectedType] = useState('all');
// 图表数据
const chartData = [
{ name: '安全生产许可证', value: 35, itemStyle: { color: '#3C7DFF' } },
{ name: '安全评估报告', value: 25, itemStyle: { color: '#FF8800' } },
{ name: '安全三同时材料', value: 20, itemStyle: { color: '#FF3E48' } },
{ name: '施工资质证书', value: 15, itemStyle: { color: '#FFC403' } },
{ name: '应急预案', value: 10, itemStyle: { color: '#22C55E' } },
{ name: '其他', value: 5, itemStyle: { color: '#31BCFF' } }
];
// 初始化图表
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
const option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'horizontal',
bottom: 0,
left: 'center',
itemWidth: 14,
itemHeight: 4,
itemGap: 10,
textStyle: {
fontSize: 12,
color: '#333',
width: 100
},
formatter: function (name) {
return name;
},
data: (() => {
// 找到最长的名称长度
const maxLength = Math.max(...chartData.map(item => item.name.length));
// 将所有名称填充到相同长度
return chartData.map(item => {
const paddingLength = maxLength - item.name.length;
return item.name + ' '.repeat(paddingLength);
});
})()
},
series: [
{
name: '证件类型分布',
type: 'pie',
radius: ['20%', '65%'],
center: ['50%', '38%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 5,
// color:"red",/
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '16',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: (() => {
// 找到最长的名称长度
const maxLength = Math.max(...chartData.map(item => item.name.length));
// 将所有名称填充到相同长度
return chartData.map(item => ({
...item,
name: item.name + ' '.repeat(maxLength - item.name.length)
}));
})()
}
]
};
chart.setOption(option);
// 响应式处理
const handleResize = () => {
chart.resize();
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
chart.dispose();
};
}
}, []);
// 表格数据
const tableData = [
{
key: '1',
no: '01',
name: '安全生产许可证',
type: '资质证书',
id: 'HQ-XF-01-001',
authority: '应急管理部',
validUntil: '2025-09-10',
status: '已过期',
statusType: 'error'
},
{
key: '2',
no: '02',
name: '安全预评估报告',
type: '安全三同时',
id: 'HQ-XF-02-015',
authority: '第三方评估机构',
validUntil: '2025-09-10',
status: '有效',
statusType: 'warning'
},
{
key: '3',
no: '03',
name: '施工资质证书',
type: '资质证书',
id: 'HQ-XF-03-007',
authority: '3设计院',
validUntil: '2025-09-10',
status: '有效',
statusType: 'success'
},
{
key: '4',
no: '04',
name: '安全标准化证书',
type: '资质证书',
id: 'HQ-XF-03-007',
authority: '第三方评估机构',
validUntil: '2025-09-10',
status: '有效',
statusType: 'success'
},
{
key: '5',
no: '05',
name: '消防验收合格证',
type: '消防证书',
id: 'HQ-XF-05-012',
authority: '消防局',
validUntil: '2026-03-15',
status: '有效',
statusType: 'success'
},
{
key: '6',
no: '06',
name: '职业健康安全管理体系认证',
type: '管理体系认证',
id: 'HQ-XF-06-008',
authority: '认证机构',
validUntil: '2026-06-20',
status: '有效',
statusType: 'success'
},
{
key: '7',
no: '07',
name: '环境管理体系认证',
type: '管理体系认证',
id: 'HQ-XF-07-009',
authority: '认证机构',
validUntil: '2026-08-25',
status: '有效',
statusType: 'success'
},
{
key: '8',
no: '08',
name: '特种设备使用登记证',
type: '特种设备证书',
id: 'HQ-XF-08-011',
authority: '质量技术监督局',
validUntil: '2026-12-10',
status: '有效',
statusType: 'success'
},
{
key: '9',
no: '09',
name: '危险化学品经营许可证',
type: '经营许可证',
id: 'HQ-XF-09-013',
authority: '应急管理局',
validUntil: '2027-01-30',
status: '有效',
statusType: 'success'
},
{
key: '10',
no: '10',
name: '辐射安全许可证',
type: '辐射安全证书',
id: 'HQ-XF-10-014',
authority: '生态环境部',
validUntil: '2027-04-18',
status: '有效',
statusType: 'success'
}
];
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'no',
key: 'no',
width: 80,
},
{
title: '证照名称',
dataIndex: 'name',
key: 'name',
width: 150,
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
width: 120,
},
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 150,
},
{
title: '发证机关',
dataIndex: 'authority',
key: 'authority',
width: 150,
},
{
title: '有效期至',
dataIndex: 'validUntil',
key: 'validUntil',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
render: (text, record) => {
const getStatusStyle = (status) => {
if (status === '有效') {
return {
color: '#44BB5F',
backgroundColor: '#D8F7DE',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
} else if (status === '即将到期') {
return {
color: '#FF8800',
backgroundColor: '#FFF3E9',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
} else if (status === '已过期') {
return {
color: '#FF3E48',
backgroundColor: '#FFE0E2',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
}
return {};
};
return (
<span style={getStatusStyle(text)}>
{text}
</span>
);
}
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
width: 120,
render: (text, record) => {
const handleEdit = (record) => {
console.log('编辑记录:', record);
};
const handleDelete = (record) => {
console.log('删除记录:', record);
};
return (
<div style={{
display: 'flex',
gap: '8px',
justifyContent: 'center',
alignItems: 'center'
}}>
<Button
onClick={() => handleEdit(record)}
style={{
color: '#2E4CD4',
backgroundColor: 'transparent',
// borderColor: '#E6E9FB',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
更新
</Button>
<Button
onClick={() => handleDelete(record)}
style={{
color: '#2E4CD4',
backgroundColor: 'transparent',
// borderColor: '#E6E9FB',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
查看
</Button>
</div>
);
}
},
];
return (
<div className={styles.licenseManagementContainer}>
<div className={styles.topSectionContainer}>
<div className={styles.firstBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证件类型分布</span>
</div>
<div className={styles.chartContainer}>
<div ref={chartRef} className={styles.chart}></div>
</div>
</div>
<div className={styles.secondBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证件状态概览</span>
</div>
<div className={styles.chartContainer}>
{/* 上半部分:进度条和百分比 */}
<div className={styles.progressSection}>
<div className={styles.progressItem}>
<div className={styles.progressLabel}>有效证照</div>
<div className={styles.progressWrapper}>
<Progress
percent={50}
strokeColor="#3C7DFF"
trailColor="#F0F0F0"
showInfo={false}
className={styles.customProgress}
/>
<span className={styles.progressPercent}>50%</span>
</div>
</div>
<div className={styles.progressItem}>
<div className={styles.progressLabel}>即将到期</div>
<div className={styles.progressWrapper}>
<Progress
percent={15}
strokeColor="#FFC403"
trailColor="#F0F0F0"
showInfo={false}
className={styles.customProgress}
/>
<span className={styles.progressPercent}>15%</span>
</div>
</div>
<div className={styles.progressItem}>
<div className={styles.progressLabel}>已过期</div>
<div className={styles.progressWrapper}>
<Progress
percent={20}
strokeColor="#FF3E48"
trailColor="#F0F0F0"
showInfo={false}
className={styles.customProgress}
/>
<span className={styles.progressPercent}>20%</span>
</div>
</div>
<div className={styles.progressItem}>
<div className={styles.progressLabel}>待审核材料</div>
<div className={styles.progressWrapper}>
<Progress
percent={15}
strokeColor="#FF8800"
trailColor="#F0F0F0"
showInfo={false}
className={styles.customProgress}
/>
<span className={styles.progressPercent}>15%</span>
</div>
</div>
</div>
{/* 下半部分:数字统计 */}
<div className={styles.statsSection}>
<Row gutter={[16, 16]}>
<Col span={6}>
<div className={styles.statItem}>
<div className={styles.statNumber} style={{ color: '#3C7DFF' }}>42</div>
<div className={styles.statLabel}>总证照数</div>
</div>
</Col>
<Col span={6}>
<div className={styles.statItem}>
<div className={styles.statNumber} style={{ color: '#FFC403' }}>8</div>
<div className={styles.statLabel}>即将过期</div>
</div>
</Col>
<Col span={6}>
<div className={styles.statItem}>
<div className={styles.statNumber} style={{ color: '#FF3E48' }}>6</div>
<div className={styles.statLabel}>已过期</div>
</div>
</Col>
<Col span={6}>
<div className={styles.statItem}>
<div className={styles.statNumber} style={{ color: '#FF8800' }}>6</div>
<div className={styles.statLabel}>待审核材料</div>
</div>
</Col>
</Row>
</div>
</div>
</div>
<div className={styles.thirdBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>临期预警</span>
</div>
<div className={styles.chartContainer}>
{/* 透明块容器 */}
<div className={styles.transparentBlock}>
{/* 四个垂直分布的卡片 */}
<div className={styles.licenseCard}>
<div className={styles.cardContent}>
<div className={styles.licenseName}>安全生产许可证</div>
<div className={styles.licenseNumber}>编号: AQXK-2023-0582</div>
</div>
<div className={styles.expiryTag}>
<span className={styles.expiryText}>15天后到期</span>
</div>
</div>
<div className={styles.licenseCard}>
<div className={styles.cardContent}>
<div className={styles.licenseName}>安全评估报告</div>
<div className={styles.licenseNumber}>编号: AQPG-2023-0125</div>
</div>
<div className={styles.expiryTag}>
<span className={styles.expiryText}>30天后到期</span>
</div>
</div>
<div className={styles.licenseCard}>
<div className={styles.cardContent}>
<div className={styles.licenseName}>施工资质证书</div>
<div className={styles.licenseNumber}>编号: SGZZ-2023-0089</div>
</div>
<div className={styles.expiryTag} style={{ backgroundColor: '#FFE0E2' }}>
<span className={styles.expiryText} style={{ color: '#FF2526' }}>7天后到期</span>
</div>
</div>
<div className={styles.licenseCard}>
<div className={styles.cardContent}>
<div className={styles.licenseName}>应急预案</div>
<div className={styles.licenseNumber}>编号: YJYA-2023-0045</div>
</div>
<div className={styles.expiryTag} style={{ backgroundColor: '#FFE0E2' }}>
<span className={styles.expiryText} style={{ color: '#FF2526' }}>4天后到期</span>
</div>
</div>
</div>
</div>
</div>
</div>
{/* 证照列表区域 */}
<div className={styles.listCard}>
<div className={styles.chartHeader}>
<div className={styles.headerLeft}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证照列表</span>
</div>
<div className={styles.headerRight}>
<Search
placeholder="搜索证照名称或编号..."
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
onSearch={(value) => console.log('搜索:', value)}
className={styles.searchInput}
/>
<Select
value={selectedType}
onChange={setSelectedType}
className={styles.typeSelector}
>
<Option value="all">全部类型</Option>
<Option value="safety">安全生产许可证</Option>
<Option value="assessment">安全评估报告</Option>
<Option value="construction">施工资质证书</Option>
<Option value="emergency">应急预案</Option>
<Option value="other">其他</Option>
</Select>
<Button
type="primary"
className={styles.addButton}
onClick={() => console.log('新增证照')}
>
新增证照
</Button>
</div>
</div>
<StandardTable
columns={columns}
data={{
list: tableData, // ======== 表格数据列表 ========
pagination: { // ======== 分页配置 ========
currentPage: 1, // ======== 当前页码 ========
pageSize: 5, // ======== 每页显示5条数据 ========
total: tableData.length, // ======== 总数据条数 ========
} // ======== 分页配置结束 ========
}} // ======== 数据对象结束 ========
selectedRows={[]} // ======== 选中的行数据,初始为空数组 ========
onSelectRow={() => { }} // ======== 行选择事件处理函数 ========
onChange={() => { }} // ======== 表格变化事件处理函数 ========
pagination={{
currentPage: 1,
pageSize: 5,
total: tableData.length,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
locale: {
jump_to: '前往',
page: '页',
items_per_page: '条/页',
}
}}
/>
</div>
</div>
);
};
export default LicenseManagement;

@ -1,498 +0,0 @@
.licenseManagementContainer {
height: 90vh;
.topSectionContainer {
padding: 0;
margin: 15px 0px 15px 5px;
height: 40%;
display: flex;
gap: 15px;
align-items: stretch;
.firstBlock {
width: 30%;
background-color: #fff;
display: flex;
flex-direction: column;
padding: 10px 16px;
border-radius: 2px;
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 16px;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 14px;
font-weight: 500;
color: #333333;
line-height: 18px;
}
}
.chartContainer {
flex: 1;
width: 100%;
position: relative;
.chart {
width: 100%;
height: 100%;
min-height: 200px;
}
// 进度条区域样式
.progressSection {
margin-bottom: 20px;
.progressItem {
margin-bottom: 16px;
.progressLabel {
font-size: 12px;
color: #666;
margin-bottom: 8px;
font-weight: 400;
}
.progressWrapper {
display: flex;
align-items: center;
gap: 12px;
.customProgress {
flex: 1;
:global(.ant-progress-bg) {
height: 8px !important;
border-radius: 4px;
}
:global(.ant-progress-outer) {
.ant-progress-inner {
background-color: #F0F0F0;
border-radius: 4px;
}
}
}
.progressPercent {
font-size: 12px;
color: #333;
font-weight: 500;
min-width: 30px;
text-align: right;
}
}
}
}
// 数字统计区域样式
.statsSection {
.statItem {
text-align: center;
padding: 8px;
.statNumber {
font-size: 24px;
font-weight: 600;
line-height: 1.2;
margin-bottom: 4px;
}
.statLabel {
font-size: 12px;
color: #666;
font-weight: 400;
}
}
}
}
}
.secondBlock {
width: 30%;
background-color: #fff;
display: flex;
flex-direction: column;
padding: 10px 16px;
border-radius: 2px;
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 8px;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 14px;
font-weight: 500;
color: #333333;
// line-height: 18px;
}
}
.chartContainer {
flex: 1;
width: 100%;
position: relative;
// 进度条区域样式
.progressSection {
// margin-bottom: 20px;
.progressItem {
// margin-bottom: 16px;
.progressLabel {
font-size: 10px;
color: #666;
// margin-bottom: 8px;
font-weight: 400;
}
.progressWrapper {
display: flex;
align-items: center;
gap: 5px;
.customProgress {
flex: 1;
:global(.ant-progress-bg) {
height: 8px !important;
border-radius: 4px;
}
:global(.ant-progress-outer) {
.ant-progress-inner {
background-color: #F0F0F0;
border-radius: 4px;
}
}
}
.progressPercent {
font-size: 12px;
color: #333;
font-weight: 500;
min-width: 30px;
text-align: right;
}
}
}
}
// 数字统计区域样式
.statsSection {
.statItem {
text-align: center;
padding: 0px 2px 2px 2px;
.statNumber {
font-size: 22px;
font-weight: 600;
line-height: 1.2;
margin-bottom: 4px;
}
.statLabel {
font-size: 12px;
color: #666;
font-weight: 400;
}
}
}
}
}
.thirdBlock {
flex: 1;
background-image: url('@/assets/business_basic/background_lqyj.svg');
background-color: #fff;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
display: flex;
flex-direction: column;
padding: 10px 16px;
border-radius: 2px;
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 8px;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 14px;
font-weight: 500;
color: #333333;
}
}
.chartContainer {
flex: 1;
width: 100%;
position: relative;
// 透明块容器样式
.transparentBlock {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
padding: 4px 8px;
.licenseCard {
width: 60%;
height: auto;
background-color: #FFF9F4;
border: 1px solid #FFD7BB;
border-radius: 2px;
padding: 5px 8px;
display: flex;
justify-content: space-between;
align-items: center;
// box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
.cardContent {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
.licenseName {
font-size: 12px;
font-weight: 500;
color: #333;
line-height: 1.2;
}
.licenseNumber {
font-size: 12px;
color: #666;
font-weight: 400;
}
}
.expiryTag {
width: 38%;
background-color: #FFEDDE;
border-radius: 2px;
padding: 5px 12px;
margin-left: 12px;
.expiryText {
font-size: 12px;
font-weight: 500;
display: flex;
align-items: center;
color: #D46B08;
}
}
}
}
}
}
}
.listCard {
padding: 0;
padding: 15px 5px 15px 20px;
flex: 1;
// display: flex;
gap: 15px;
background-color: #fff;
// align-items: stretch;
.chartHeader {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
.headerLeft {
display: flex;
align-items: center;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 14px;
font-weight: 500;
color: #333333;
line-height: 18px;
}
}
.headerRight {
display: flex;
align-items: center;
gap: 12px;
.searchInput {
width: 280px;
.ant-input {
border-radius: 2px;
border: 1px solid #d9d9d9;
&:hover {
border-color: #40a9ff;
}
&:focus {
border-color: #40a9ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
}
}
.typeSelector {
width: 120px;
.ant-select-selector {
border-radius: 2px;
border: 1px solid #d9d9d9;
&:hover {
border-color: #40a9ff;
}
}
&.ant-select-focused .ant-select-selector {
border-color: #40a9ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
}
.addButton {
border-radius: 4px;
background-color: #2E4CD4;
// border-color: #1890ff;
height: 32px;
padding: 4px 15px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
&:hover {
background-color: #2E4CD4;
// border-color: #40a9ff;
}
&:focus {
background-color: #2E4CD4;
// border-color: #40a9ff;
}
}
}
}
// StandardTable 组件样式
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-pagination-options-quick-jumper input) {
text-align: center !important;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
color: #666666;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}
// 覆盖Ant Design默认样式
.licenseManagementContainer {
.ant-card {
box-shadow: none;
}
.ant-card-body {
padding: 20px;
}
.ant-table {
font-size: 14px;
}
.ant-tag {
border-radius: 4px;
font-size: 12px;
padding: 2px 8px;
}
.ant-btn-link {
padding: 0;
height: auto;
font-size: 14px;
}
.ant-input-search {
.ant-input {
border-radius: 6px;
}
}
.ant-select {
.ant-select-selector {
border-radius: 6px;
}
}
.ant-btn-primary {
border-radius: 6px;
}
}

@ -0,0 +1,122 @@
import React from 'react';
import { Card, Table, Input, Button, Space } from 'antd';
import { PlusOutlined, SearchOutlined } from '@ant-design/icons';
import styles from './OilDataManagement.less';
const OilDataManagement = () => {
const onSearch = (value) => {
console.log('搜索内容:', value);
};
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 80,
},
{
title: '油品名称',
dataIndex: 'oilName',
key: 'oilName',
width: 120,
},
{
title: '油品类型',
dataIndex: 'oilType',
key: 'oilType',
width: 120,
},
{
title: '规格',
dataIndex: 'specification',
key: 'specification',
width: 100,
},
{
title: '库存量',
dataIndex: 'stock',
key: 'stock',
width: 100,
},
{
title: '单位',
dataIndex: 'unit',
key: 'unit',
width: 80,
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
width: 180,
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
width: 150,
render: (text, record) => (
<Space>
<Button type="link" size="small">编辑</Button>
<Button type="link" size="small" danger>删除</Button>
</Space>
),
},
];
const tableData = [
{
key: '1',
id: '001',
oilName: '92号汽油',
oilType: '汽油',
specification: '92#',
stock: '5000',
unit: '升',
createTime: '2024-12-20 10:00:00',
},
{
key: '2',
id: '002',
oilName: '95号汽油',
oilType: '汽油',
specification: '95#',
stock: '3000',
unit: '升',
createTime: '2024-12-20 10:00:00',
},
];
return (
<div className={styles.container}>
<Card>
<div className={styles.header}>
<div className={styles.title}>油资料管理</div>
<Space>
<Input.Search
placeholder="搜索油品名称..."
onSearch={onSearch}
style={{ width: 200 }}
prefix={<SearchOutlined />}
/>
<Button type="primary" icon={<PlusOutlined />}>
新增油品
</Button>
</Space>
</div>
<Table
columns={columns}
dataSource={tableData}
pagination={{
pageSize: 10,
showTotal: (total) => `${total}`,
}}
/>
</Card>
</div>
);
};
export default OilDataManagement;

@ -0,0 +1,19 @@
.container {
padding: 20px;
background: #f5f5f5;
min-height: 100%;
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.title {
font-size: 18px;
font-weight: 600;
color: #333;
}
}
}

@ -1,716 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, Result, Select, Button } from 'antd';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
import styles from './OnlineMonitoring.less';
import alarm0 from '@/assets/safe_majorHazard/online_monitoring/alarm0.png';
import alarm1 from '@/assets/safe_majorHazard/online_monitoring/alarm1.png';
import alarm2 from '@/assets/safe_majorHazard/online_monitoring/alarm2.png';
import alarm3 from '@/assets/safe_majorHazard/online_monitoring/alarm3.png';
import exportIcon from '@/assets/safe_majorHazard/online_monitoring/export.png';
import deleteIcon from '@/assets/safe_majorHazard/online_monitoring/delete.png';
const OnlineMonitoring = () => {
const chartRef = useRef(null);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [selectedRows, setSelectedRows] = useState([]);
const [loading, setLoading] = useState(false);
const [dataSource, setDataSource] = useState([]);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 5,
total: 0,
});
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
const option = {
color: ['#04A7F3', '#E7C42C', '#EC6941'],
legend: {
data: ['液位', '温度', '压力'],
top: "-3px",
left: "center",
itemGap: 40, // 图例间距
textStyle: {
fontSize: 10
}
},
grid: {
left: '2%',
right: '4%',
bottom: '2%',
top: '12%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['0:00', '2:00', '4:00', '6:00', '8:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00'],
axisLabel: {
fontSize: 10
}
},
yAxis: {
type: 'value',
min: 0,
max: 500,
axisLabel: {
formatter: '{value}',
fontSize: 10
}
},
series: [
{
name: '液位',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#04A7F3'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(4, 167, 243, 0.3)' },
{ offset: 1, color: 'rgba(4, 167, 243, 0)' }
]
}
},
symbol: 'none', // 不显示数据点
data: [120, 200, 150, 300, 250, 400, 350, 280, 320, 180, 220, 160, 140]
},
{
name: '温度',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#E7C42C'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(231, 196, 44, 0.3)' },
{ offset: 1, color: 'rgba(231, 196, 44, 0)' }
]
}
},
symbol: 'none',
data: [80, 120, 100, 180, 160, 220, 200, 150, 170, 90, 110, 85, 75]
},
{
name: '压力',
type: 'line',
smooth: true,
lineStyle: {
width: 1.5,
color: '#EC6941'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 1,
x2: 0,
y2: 0,
colorStops: [
{ offset: 0, color: 'rgba(236, 105, 65, 0)' },
{ offset: 1, color: 'rgba(236, 105, 65, 0.3)' }
]
}
},
symbol: 'none',
data: [200, 300, 250, 450, 400, 430, 480, 420, 480, 280, 320, 260, 240]
}
]
};
chart.setOption(option);
// 响应式调整 - 使用ResizeObserver监听容器尺寸变化
let resizeTimer = null;
const handleResize = () => {
// 防抖处理避免频繁调用resize
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(() => {
chart.resize();
}, 100);
};
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
// 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题)
let resizeObserver = null;
if (window.ResizeObserver) {
resizeObserver = new ResizeObserver(() => {
// 使用setTimeout确保DOM更新完成后再调整图表
setTimeout(() => {
handleResize();
}, 0);
});
resizeObserver.observe(chartRef.current);
}
return () => {
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
}
if (resizeTimer) {
clearTimeout(resizeTimer);
}
chart.dispose();
};
}
}, []);
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 80,
render: (text, record, index) => {
const page = pagination.current || 1;
const pageSize = pagination.pageSize || 5;
const number = (page - 1) * pageSize + index + 1;
return `0${number}`.slice(-2);
}
},
{
title: '报警时间',
dataIndex: 'alarmTime',
key: 'alarmTime',
width: 150,
},
{
title: '报警传感器名称',
dataIndex: 'sensorName',
key: 'sensorName',
width: 150,
},
{
title: '报警类型',
dataIndex: 'alarmType',
key: 'alarmType',
width: 120,
},
{
title: '报警内容',
dataIndex: 'alarmContent',
key: 'alarmContent',
width: 200,
},
{
title: '优先级',
dataIndex: 'priority',
key: 'priority',
width: 80,
render: (text) => {
const colorMap = {
'高': '#FF4D4F',
'中': '#FAAD14',
'低': '#52C41A'
};
return <span style={{ color: colorMap[text] || '#333' }}>{text}</span>;
}
},
{
title: '处理状态',
dataIndex: 'status',
key: 'status',
width: 100,
render: (text) => {
const statusMap = {
'未处理': { color: '#FF4D4F', bg: '#FFF2F0' },
'处理中': { color: '#FAAD14', bg: '#FFFBE6' },
'已处理': { color: '#52C41A', bg: '#F6FFED' }
};
const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
return (
<span style={{
color: status.color,
backgroundColor: status.bg,
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px'
}}>
{text}
</span>
);
}
},
{
title: '处理时间',
dataIndex: 'processTime',
key: 'processTime',
width: 150,
},
{
title: '处理人',
dataIndex: 'processor',
key: 'processor',
width: 100,
},
{
title: '操作',
key: 'action',
width: 120,
render: (_, record) => (
<div>
<Button type="link" size="small" style={{ padding: 0, marginRight: 8 }}>
查看
</Button>
</div>
),
},
];
// 模拟数据
const mockData = [
{
key: '1',
id: '001',
alarmTime: '2024-01-15 08:30:25',
sensorName: 'LNG储罐',
alarmType: '温度超限',
alarmContent: '储罐温度超过安全阈值',
priority: '高',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '2',
id: '002',
alarmTime: '2024-01-15 09:15:10',
sensorName: 'LNG储罐',
alarmType: '压力异常',
alarmContent: '管道压力异常波动',
priority: '中',
status: '处理中',
processTime: '2024-01-15 09:20:00',
processor: '张三',
},
{
key: '3',
id: '003',
alarmTime: '2024-01-15 10:45:30',
sensorName: 'LNG储罐',
alarmType: '液位异常',
alarmContent: '储罐液位低于警戒线',
priority: '高',
status: '已处理',
processTime: '2024-01-15 11:00:15',
processor: '李四',
},
{
key: '4',
id: '004',
alarmTime: '2024-01-15 11:20:45',
sensorName: 'LNG储罐',
alarmType: '气体泄漏',
alarmContent: '检测到可燃气体泄漏',
priority: '高',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '5',
id: '005',
alarmTime: '2024-01-15 12:10:20',
sensorName: 'LNG储罐',
alarmType: '设备振动',
alarmContent: '设备异常振动',
priority: '低',
status: '已处理',
processTime: '2024-01-15 12:30:00',
processor: '王五',
},
{
key: '6',
id: '006',
alarmTime: '2024-01-15 13:25:15',
sensorName: 'LNG管道',
alarmType: '流量异常',
alarmContent: '管道流量异常波动',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '7',
id: '007',
alarmTime: '2024-01-15 14:10:30',
sensorName: 'LNG储罐',
alarmType: '温度异常',
alarmContent: '储罐温度异常升高',
priority: '高',
status: '处理中',
processTime: '2024-01-15 14:15:00',
processor: '赵六',
},
{
key: '8',
id: '008',
alarmTime: '2024-01-15 15:45:20',
sensorName: 'LNG管道',
alarmType: '压力超限',
alarmContent: '管道压力超过安全阈值',
priority: '高',
status: '已处理',
processTime: '2024-01-15 16:00:00',
processor: '孙七',
},
{
key: '9',
id: '009',
alarmTime: '2024-01-15 16:30:45',
sensorName: 'LNG储罐',
alarmType: '液位超限',
alarmContent: '储罐液位超过警戒线',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
{
key: '10',
id: '010',
alarmTime: '2024-01-15 17:15:10',
sensorName: 'LNG管道',
alarmType: '泄漏检测',
alarmContent: '检测到轻微气体泄漏',
priority: '低',
status: '已处理',
processTime: '2024-01-15 17:30:00',
processor: '周八',
},
{
key: '11',
id: '011',
alarmTime: '2024-01-15 18:20:35',
sensorName: 'LNG储罐',
alarmType: '设备故障',
alarmContent: '储罐阀门异常关闭',
priority: '高',
status: '处理中',
processTime: '2024-01-15 18:25:00',
processor: '吴九',
},
{
key: '12',
id: '012',
alarmTime: '2024-01-15 19:05:50',
sensorName: 'LNG管道',
alarmType: '温度异常',
alarmContent: '管道温度异常下降',
priority: '中',
status: '未处理',
processTime: '-',
processor: '-',
},
];
// 初始化数据
useEffect(() => {
setPagination(prev => ({ ...prev, total: mockData.length }));
}, []);
// 根据分页获取当前页数据
const getCurrentPageData = () => {
const { current, pageSize } = pagination;
const startIndex = (current - 1) * pageSize;
const endIndex = startIndex + pageSize;
return mockData.slice(startIndex, endIndex);
};
// 表格选择变化
const onSelectChange = (newSelectedRowKeys, newSelectedRows) => {
setSelectedRowKeys(newSelectedRowKeys);
setSelectedRows(newSelectedRows);
};
// 分页变化处理
const handleTableChange = (pagination) => {
setPagination(prev => ({
...prev,
current: pagination.current,
pageSize: pagination.pageSize,
}));
};
// 导出功能
const handleExport = () => {
console.log('导出数据');
// 这里可以添加导出逻辑
};
// 批量删除功能
const handleBatchDelete = () => {
if (selectedRowKeys.length === 0) {
console.log('没有选中任何行');
// 可以在这里添加提示用户选择行的逻辑
return;
}
console.log('批量删除', selectedRowKeys);
// 这里可以添加批量删除逻辑
};
return (
<div className={styles.Ocontainer}>
<div className={styles.OcontainerTop}>
<div className={styles.OcontainerTopLeft}>
<div className={styles.OcontainerTopLeftTop}>
<div className={styles.alarmO}>
<div className={styles.alarmOLeft}>
<img style={{ width: 58, height: 47 }} src={alarm0} alt='alarm0' />
</div>
<div className={styles.alarmORight}>
<div className={styles.alarmORightText1}>总报警</div>
<div className={styles.alarmORightText2}>1456</div>
<div className={styles.alarmORightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmTw}>
<div className={styles.alarmTwLeft}>
<img style={{ width: 58, height: 47 }} src={alarm1} alt='alarm1' />
</div>
<div className={styles.alarmTwRight}>
<div className={styles.alarmTwRightText1}>一级报警</div>
<div className={styles.alarmTwRightText2}>357</div>
<div className={styles.alarmTwRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmTh}>
<div className={styles.alarmThLeft}>
<img style={{ width: 58, height: 47 }} src={alarm2} alt='alarm2' />
</div>
<div className={styles.alarmThRight}>
<div className={styles.alarmThRightText1}>二级报警</div>
<div className={styles.alarmThRightText2}>401</div>
<div className={styles.alarmThRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
<div className={styles.alarmF}>
<div className={styles.alarmFLeft}>
<img style={{ width: 58, height: 47 }} src={alarm3} alt='alarm3' />
</div>
<div className={styles.alarmFRight}>
<div className={styles.alarmFRightText1}>三级报警</div>
<div className={styles.alarmFRightText2}>556</div>
<div className={styles.alarmFRightText3}>
<div>
未处理 <text style={{ color: '#FF4D4F' }}>6</text>
</div>
<div>
处理中 <text style={{ color: '#2e4cd4' }}>10</text>
</div>
</div>
</div>
</div>
</div>
<div className={styles.OcontainerTopLeftBottom}>
<div className={styles.OcontainerTopLeftBottomTitle}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>预警看板</div>
</div>
<div className={styles.titleRight}>
<div>检测对象</div>
<Select
style={{ width: 80 }}
defaultValue="储罐"
options={[
{ value: '储罐', label: '储罐' },
{ value: '管道', label: '管道' },
{ value: '设备', label: '设备' }
]}
/>
</div>
</div>
<div className={styles.OcontainerTopLeftBottomChart} ref={chartRef}>
</div>
</div>
</div>
<div className={styles.OcontainerTopRight}>
<div className={styles.realTimeDataHeader}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>实时数据采集</div>
</div>
<div className={styles.totalCount}>
总数 <text style={{ color: '#2e4cd4' }}>1378</text>
</div>
</div>
<div className={styles.dataItem1}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>三级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem2}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>一级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem3}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>二级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.dataItem4}>
<div className={styles.dataItemLeft}>
<div className={styles.areaName}>储罐液化装置区</div>
<div className={styles.rValue}>R值: 1765</div>
<div className={styles.codeNumber}>编号:XXXXXXXX</div>
</div>
<div className={styles.dataItemRight}>
<div className={styles.circleContainer}>
<div className={styles.outerCircle}>
<div className={styles.innerCircle}>
<div className={styles.levelText}>三级</div>
<div className={styles.riskText}>危险等级</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{/* 表格 */}
<div className={styles.OcontainerBottom}>
{/* 首行 左侧标题左对齐 右侧按钮右对齐 */}
<div className={styles.tableHeader}>
<div className={styles.tableTitle}>
<div className={styles.titleIcon}></div>
<div>报警信息列表</div>
</div>
<div className={styles.tableActions}>
<Button
type="primary"
onClick={handleExport}
style={{ marginRight: 8 }}
>
<img src={exportIcon} alt="导出" style={{ width: 16, height: 16, margin: '-2px 6px 0 0px'}} />
导出word 报告
</Button>
<Button
type="primary"
onClick={handleBatchDelete}
>
<img src={deleteIcon} alt="删除" style={{ width: 16, height: 16, margin: '-2px 6px 0 0px' }} />
批量删除
</Button>
</div>
</div>
{/* 表格 5行10列 带页码 每页5条数据 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: getCurrentPageData(),
pagination: pagination
}}
loading={loading}
selectionType="checkbox"
onSelectRow={onSelectChange}
onChange={handleTableChange}
pagination={{
...pagination,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
}}
scroll={{ x: 1200 }}
/>
</div>
</div>
</div>
);
};
export default OnlineMonitoring;

@ -1,919 +0,0 @@
.Ocontainer {
padding: 8px 6px 0px 6px;
height: 100%;
display: flex;
flex-direction: column;
.OcontainerTop {
display: flex;
height: 50%;
margin-bottom: 5px;
.OcontainerTopLeft {
width: 72%;
height: 100%;
// background-color: pink;
margin-right: 10px;
// display: flex;
.OcontainerTopLeftTop {
width: 100%;
height: 35%;
display: flex;
gap: 12px;
.alarmO {
flex: 1;
height: 100%;
background-color: #F4F7FF;
border: 1px solid #AED3FF;
border-bottom: 0px solid #AED3FF;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #5382FE33 inset;
display: flex;
.alarmOLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmORight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmORightText1 {
margin-top: 15px;
}
.alarmORightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmORightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmTw {
flex: 1;
height: 100%;
background-color: #FFF5f4;
border: 1px solid #FFC5BC;
border-bottom: 0px solid #FFC5BC;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #FE5F4C33 inset;
display: flex;
.alarmTwLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmTwRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmTwRightText1 {
margin-top: 15px;
}
.alarmTwRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmTwRightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmTh {
flex: 1;
height: 100%;
background-color: #FFF7F2;
border: 1px solid #FFD9B2;
border-bottom: 0px solid #FFD9B2;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #FD883C33 inset;
display: flex;
.alarmThLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmThRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmThRightText1 {
margin-top: 15px;
}
.alarmThRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmThRightText3 {
display: flex;
gap: 22px;
}
}
}
.alarmF {
flex: 1;
height: 100%;
background-color: #EFF9FF;
border: 1px solid #89E1FF;
border-bottom: 0px solid #89E1FF;
border-radius: 4px;
box-shadow: 0px 2px 31px 0px #22A4FD33 inset;
display: flex;
.alarmFLeft {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.alarmFRight {
flex: 1;
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
margin-left: 2px;
gap: 18px;
font-family: PingFang SC;
font-weight: 400;
font-style: Regular;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
color: #333333;
.alarmFRightText1 {
margin-top: 15px;
}
.alarmFRightText2 {
font-weight: 700;
font-size: 16px;
}
.alarmFRightText3 {
display: flex;
gap: 22px;
}
}
}
}
.OcontainerTopLeftBottom {
margin-top: 12px;
background-color: #fff;
width: 100%;
height: 60%;
.OcontainerTopLeftBottomTitle {
display: flex;
justify-content: space-between;
align-items: center;
// padding: 8px 15px;
padding: 8px 15px 0px 15px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-style: Medium;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.titleRight {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-style: Medium;
font-size: 13px;
line-height: 100%;
letter-spacing: 0%;
.selectBox {
padding: 4px 8px;
border: 1px solid #d9d9d9;
border-radius: 4px;
background-color: #fff;
font-size: 12px;
color: #333;
outline: none;
&:focus {
border-color: #2E4CD4;
}
}
}
}
.OcontainerTopLeftBottomChart {
flex: 1;
width: 100%;
height: 75%;
}
}
}
.OcontainerTopRight {
flex: 1;
height: calc(100% - 3.3px);
background-color: #fff;
background-image: url('@/assets/safe_majorHazard/online_monitoring/backTopRight.png');
background-size: 100% auto;
display: flex;
flex-direction: column;
overflow-y: auto;
.realTimeDataHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 15px;
margin-bottom: 10px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-style: Medium;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.totalCount {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
}
}
.dataItem {
height: 23%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 2px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFang SC;
font-size: 14px;
// color: #666;
background-color: #EFF9FF;
&:last-child {
// margin-bottom: 1px;
}
}
.dataItem1 {
height: 25%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #EFF9FF;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1; // 强制宽高比1:1
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(51, 176, 253, 0.3);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(4, 128, 251, 0.8);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem2 {
height: 25%;
flex-shrink: 0;
border: 1px solid rgba(255, 197, 188, 1);
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #fff5f4;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(254, 214, 209, 1);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(253, 41, 14, 1);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem3 {
height: 25%;
flex-shrink: 0;
border: 1px solid rgba(255, 217, 178, 1);
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #fef6f1;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(255, 234, 218, 1);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(252, 103, 18, 1);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
.dataItem4 {
height: 25%;
flex-shrink: 0;
border: 1px solid #89E1FF;
border-radius: 4px;
margin: 0 15px;
margin-bottom: 6px;
display: flex;
align-items: center;
padding: 0px 15px;
background-color: #EFF9FF;
.dataItemLeft {
width: 65%;
display: flex;
flex-direction: column;
gap: 8px;
.areaName {
font-family: PingFang SC;
font-weight: 400;
font-size: 13px;
color: #333333;
line-height: 2.2;
}
.rValue {
font-family: PingFang SC;
font-weight: 400;
font-size: 14px;
color: #666666;
line-height: 0.2;
}
.codeNumber {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #666666;
}
}
.dataItemRight {
width: 35%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.circleContainer {
position: relative;
height: 80%;
aspect-ratio: 1;
.outerCircle {
width: 100%;
height: 100%;
background-color: rgba(51, 176, 253, 0.3);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.innerCircle {
width: 70%;
height: 70%;
background-color: rgba(4, 128, 251, 0.8);
border-radius: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.levelText {
font-family: PingFang SC;
font-weight: 500;
font-size: 11px;
color: #FFFFFF;
line-height: 1.4;
margin-top: -4px;
}
.riskText {
font-family: PingFang SC;
font-weight: 300;
font-size: 8px;
color: #FFFFFF;
line-height: 1;
}
}
}
}
}
}
}
}
.OcontainerBottom {
background-color: #fff;
flex: 1;
padding: 8px 15px 5px 15px;
display: flex;
flex-direction: column;
.tableHeader {
display: flex;
justify-content: space-between;
align-items: center;
// margin-bottom: 15px;
padding-bottom: 5px;
// border-bottom: 1px solid #f0f0f0;
.tableTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.tableActions {
display: flex;
gap: 8px;
// 自定义按钮样式
:global(.ant-btn) {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
// 主要按钮样式
&.ant-btn-primary {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
}
// 危险按钮样式
&.ant-btn-dangerous {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
&:hover {
background-color: #f5f5f5 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:focus {
background-color: #ffffff !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
&:active {
background-color: #e6e6e6 !important;
border-color: #DFE4F6 !important;
color: #333333 !important;
box-shadow: none !important;
}
}
// 禁用状态
&:disabled {
background-color: #f5f5f5 !important;
border-color: #d9d9d9 !important;
color: #bfbfbf !important;
box-shadow: none !important;
}
}
}
}
.tableContainer {
flex: 1;
overflow: hidden;
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
}
:global(.ant-table-tbody > tr:hover > td) {
background-color: #f5f5f5;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}
}

@ -1,581 +0,0 @@
import React from 'react';
import { Card, Statistic, Table,Row, Input,Button,Col, Select} from 'antd';
import { PhoneOutlined, IdcardOutlined, PlusOutlined } from '@ant-design/icons';
import StandardTable from '@/components/StandardTable';
import styles from './ResponsibilityImplementation.less';
import upload from '@/assets/business_basic/upload.png';
import download from '@/assets/business_basic/download.png';
import import1 from '@/assets/business_basic/import1.png';
import fire_fighting1 from '@/assets/business_basic/fire_fighting1.png';
import fire_fighting2 from '@/assets/business_basic/fire_fighting2.png';
import fire_fighting3 from '@/assets/business_basic/fire_fighting3.png';
import frameIcon from '@/assets/business_basic/Frame.png';
import background1 from '@/assets/business_basic/background1.png';
import export1 from '@/assets/business_basic/export1.png';
const ResponsibilityImplementation = () => {
// 搜索处理函数
const onSearch = (value) => {
console.log('搜索内容:', value);
// 这里可以添加实际的搜索逻辑
};
const columns = [
{
title:"编号",
dataIndex:"id",
key:"id",
width:80,
},
{
title:"组织代码",
dataIndex:"orgCode",
key:"orgCode",
width:120,
},
{
title:"组织类型",
dataIndex:"orgType",
key:"orgType",
width:120,
},
{
title:"负责人",
dataIndex:"manager",
key:"manager",
width:100,
},
{
title:"所属部门",
dataIndex:"department",
key:"department",
width:120,
},
{
title:"创建时间",
dataIndex:"createTime",
key:"createTime",
width:120,
},
{
title:"人员规模",
dataIndex:"staffCount",
key:"staffCount",
width:100,
},
{
title:"状态",
dataIndex:"status",
key:"status",
width:80,
render: (text, record) => {
const getStatusStyle = (status) => {
if (status === '正常') {
return {
color: '#44BB5F',
backgroundColor: '#D8F7DE',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
} else if (status === '信息不全') {
return {
color: '#FF8800',
backgroundColor: '#FFF3E9',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
}
return {};
};
return (
<span style={getStatusStyle(text)}>
{text}
</span>
);
}
},
{
title:"操作",
dataIndex:"action",
key:"action",
width:120,
render: (text, record) => {
const handleEdit = (record) => {
console.log('编辑记录:', record);
};
const handleDelete = (record) => {
console.log('删除记录:', record);
};
return (
<div style={{
display: 'flex',
gap: '8px',
justifyContent: 'center',
alignItems: 'center'
}}>
<Button
onClick={() => handleEdit(record)}
style={{
color: '#2E4CD4',
backgroundColor: 'transparent',
borderColor: '#E6E9FB',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
编辑
</Button>
<Button
onClick={() => handleDelete(record)}
style={{
color: '#FF2526',
backgroundColor: 'transparent',
borderColor: '#FFE0E2',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
删除
</Button>
</div>
);
}
}
];
// 固定的假数据
const tableData = [
{
key: '1',
id: '01',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-19 14:32:15',
staffCount: '15人',
status: '正常'
},
{
key: '2',
id: '02',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-18 09:25:43',
staffCount: '20人',
status: '正常'
},
{
key: '3',
id: '03',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-17 16:48:22',
staffCount: '25人',
status: '信息不全'
},
{
key: '4',
id: '04',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-16 11:15:37',
staffCount: '18人',
status: '正常'
},
{
key: '5',
id: '05',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-15 08:42:56',
staffCount: '22人',
status: '正常'
},
{
key: '6',
id: '06',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-14 13:27:18',
staffCount: '16人',
status: '信息不全'
},
{
key: '7',
id: '07',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-13 15:33:29',
staffCount: '19人',
status: '正常'
},
{
key: '8',
id: '08',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-12 10:56:44',
staffCount: '21人',
status: '正常'
},
{
key: '9',
id: '09',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-11 17:19:52',
staffCount: '17人',
status: '信息不全'
},
{
key: '10',
id: '10',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-10 12:41:07',
staffCount: '23人',
status: '正常'
},
{
key: '11',
id: '11',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-09 14:08:33',
staffCount: '24人',
status: '正常'
},
{
key: '12',
id: '12',
orgCode: 'DH002',
orgType: '义务消防队',
manager: '张明',
department: '安全管理部',
createTime: '2024-12-08 16:52:14',
staffCount: '26人',
status: '信息不全'
}
];
return (
<div className={styles.XcontainerR}>
{/* 警告提示框 */}
<div className={styles.warningBox}>
<img src={frameIcon} alt="警告" className={styles.warningIcon} />
<span className={styles.warningText}>
有5个消防设备需要维护3个资质证书即将到期请及时处理
</span>
</div>
<div className={styles.containerOne}>
<div className={styles.containerOneLeft}>
{/* 第一行:标题和按钮 */}
<div className={styles.leftTopSection}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>组织架构图预览</div>
</div>
<div className={styles.buttonGroup}>
<Button className={styles.actionBtn}>
<img src={upload} alt="上传图表" className={styles.btnIcon} />
上传图表
</Button>
<Button className={styles.actionBtn}>
<img src={download} alt="下载" className={styles.btnIcon} />
下载
</Button>
</div>
</div>
{/* 第二行:图片占位 */}
<div className={styles.leftBottomSection}>
<div className={styles.imagePlaceholder}>
<img src={fire_fighting1} alt="消防1" className={styles.imageIcon1} />
<div className={styles.imageRow}>
<img src={fire_fighting2} alt="消防2" className={styles.imageIcon2} />
<img src={fire_fighting3} alt="消防3" className={styles.imageIcon3} />
</div>
</div>
</div>
</div>
<div className={styles.containerOneRight}>
{/* 第一行:标题 + 搜索栏 + 下拉选择框 */}
<div className={styles.rightTopSection}>
<div className={styles.rightTopLeft}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>成员信息管理</div>
</div>
</div>
<div className={styles.rightTopRight}>
<div className={styles.searchGroup}>
<Input.Search placeholder="搜索成员..." onSearch={onSearch} style={{ width: 200}} />
<Select
defaultValue="全部组织"
className={styles.organizationSelect}
options={[
{ value: '全部组织', label: '全部组织' },
{ value: '技术部', label: '技术部' },
{ value: '生产部', label: '生产部' },
{ value: '安全部', label: '安全部' },
]}
/>
</div>
</div>
</div>
{/* 第二行:三个小块 */}
<div className={styles.rightBottomSection}>
<div className={styles.threeBlocksContainer}>
<div className={styles.blockItem}>
<div className={styles.blockContent}>
<div className={styles.backgroundContainer}>
{/* 第一个块:姓名和单位 */}
<div className={styles.infoBlock}>
<div className={styles.nameText}>张明</div>
<div className={styles.unitText}>东义区消防队</div>
</div>
{/* 第二个块:电话 */}
<div className={styles.infoBlock}>
<PhoneOutlined className={styles.infoIcon} />
<span className={styles.infoText}>132****3847</span>
</div>
{/* 第三个块:身份证 */}
<div className={styles.infoBlock}>
<IdcardOutlined className={styles.infoIcon} />
<span className={styles.infoText}>1304************10</span>
</div>
{/* 第四个块:职位标签 */}
<div className={styles.infoBlock}>
<div className={styles.tagContainer}>
<div className={styles.tagBlue1}>队长</div>
<div className={styles.tagBlue2}>消防工程师</div>
</div>
</div>
{/* 第五个块:证书状态 */}
<div className={styles.infoBlock}>
<div className={styles.tagContainer}>
<div className={styles.tagBlue3}>消防工程师</div>
<div className={styles.tagYellow}>证书7天后到期</div>
</div>
</div>
{/* 第六个块:操作按钮 */}
<div className={styles.actionBlock}>
<div className={styles.buttonContainer}>
<Button className={styles.editBtn}>编辑</Button>
<Button className={styles.deleteBtn}>删除</Button>
</div>
</div>
</div>
</div>
</div>
<div className={styles.blockItem}>
<div className={styles.blockContent}>
<div className={styles.backgroundContainer2}>
{/* 第一个块:姓名和单位 */}
<div className={styles.infoBlock2}>
<span className={styles.nameText2}>李小明</span>
<span className={styles.unitText2}>消防支队</span>
</div>
{/* 第二个块:电话 */}
<div className={styles.infoBlock2}>
<PhoneOutlined className={styles.infoIcon2} />
<span className={styles.infoText2}>138****5678</span>
</div>
{/* 第三个块:身份证 */}
<div className={styles.infoBlock2}>
<IdcardOutlined className={styles.infoIcon2} />
<span className={styles.infoText2}>1304************20</span>
</div>
{/* 第四个块:职位标签 */}
<div className={styles.infoBlock2}>
<div className={styles.tagContainer2}>
<div className={styles.tagBlue4}>副队长</div>
<div className={styles.tagBlue5}>安全员</div>
</div>
</div>
{/* 第五个块:证书状态 */}
<div className={styles.infoBlock2}>
<div className={styles.tagContainer2}>
<div className={styles.tagBlue6}>安全员证</div>
<div className={styles.tagGreen}>证书正常</div>
</div>
</div>
{/* 第六个块:操作按钮 */}
<div className={styles.actionBlock2}>
<div className={styles.buttonContainer2}>
<Button className={styles.editBtn2}>编辑</Button>
<Button className={styles.deleteBtn2}>删除</Button>
</div>
</div>
</div>
</div>
</div>
<div className={styles.blockItem}>
<div className={styles.blockContent}>
<div className={styles.backgroundContainer3}>
{/* 第一个块:姓名和单位 */}
<div className={styles.infoBlock3}>
<span className={styles.nameText3}>王小红</span>
<span className={styles.unitText3}>消防中队</span>
</div>
{/* 第二个块:电话 */}
<div className={styles.infoBlock3}>
<PhoneOutlined className={styles.infoIcon3} />
<span className={styles.infoText3}>139****9012</span>
</div>
{/* 第三个块:身份证 */}
<div className={styles.infoBlock3}>
<IdcardOutlined className={styles.infoIcon3} />
<span className={styles.infoText3}>1304************30</span>
</div>
{/* 第四个块:职位标签 */}
<div className={styles.infoBlock3}>
<div className={styles.tagContainer3}>
<div className={styles.tagBlue7}>队员</div>
<div className={styles.tagBlue8}>技术员</div>
</div>
</div>
{/* 第五个块:证书状态 */}
<div className={styles.infoBlock3}>
<div className={styles.tagContainer3}>
<div className={styles.tagBlue9}>技术员证</div>
<div className={styles.tagOrange}>证书3天后到期</div>
</div>
</div>
{/* 第六个块:操作按钮 */}
<div className={styles.actionBlock3}>
<div className={styles.buttonContainer3}>
<Button className={styles.editBtn3}>编辑</Button>
<Button className={styles.deleteBtn3}>删除</Button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className={styles.containerTwo}>
{/* 第一块:标题 */}
<div className={styles.containerTwoTitle}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>组织架构管理</div>
</div>
</div>
{/* 第二个大块:搜索和按钮 */}
<div className={styles.containerTwoActions}>
<div className={styles.searchSection}>
<Input.Search placeholder="搜索姓名、工号..." onSearch={onSearch} style={{ width: 180 }} />
</div>
<div className={styles.buttonSection}>
<Button className={styles.addBtn}>
<PlusOutlined className={styles.addIcon} />
新增组织
</Button>
<Button className={styles.importBtn}>
<img src={import1} alt="批量导入" className={styles.importIcon} />
批量导入
</Button>
<Button className={styles.exportBtn}>
<img src={export1} alt="批量导出" className={styles.exportIcon} />
批量导出
</Button>
</div>
</div>
{/* 第三个大块:表格 */}
<div className={styles.containerTwoTable}>
<StandardTable
columns={columns}
data={{
list: tableData, // ======== 表格数据列表 ========
pagination: { // ======== 分页配置 ========
currentPage: 1, // ======== 当前页码 ========
pageSize: 5, // ======== 每页显示10条数据 ========
total: tableData.length, // ======== 总数据条数 ========
} // ======== 分页配置结束 ========
}} // ======== 数据对象结束 ========
selectedRows={[]} // ======== 选中的行数据,初始为空数组 ========
onSelectRow={() => {}} // ======== 行选择事件处理函数 ========
onChange={() => {}} // ======== 表格变化事件处理函数 ========
pagination={{
currentPage: 1,
pageSize: 5,
total: tableData.length,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
locale: {
jump_to: '前往',
page: '页',
items_per_page: '条/页',
}
}}
/>
</div>
</div>
</div>
);
};
export default ResponsibilityImplementation;

@ -1,865 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, Result, Select, Button, Segmented } from 'antd';
import { CheckCircleOutlined, ExportOutlined } from '@ant-design/icons';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
import styles from './RiskAssessment.less';
// import './RiskAssessment.less';
import img1 from '@/assets/safe_majorHazard/online_monitoring/img1.png';
import img2 from '@/assets/safe_majorHazard/online_monitoring/img2.png';
import img3 from '@/assets/safe_majorHazard/online_monitoring/img3.png';
import map1 from '@/assets/safe_majorHazard/online_monitoring/map.png';
import risk1 from '@/assets/safe_majorHazard/online_monitoring/risk1.png';
import risk2 from '@/assets/safe_majorHazard/online_monitoring/risk2.png';
import risk3 from '@/assets/safe_majorHazard/online_monitoring/risk3.png';
import eqicon1 from '@/assets/business_basic/eqicon1.png';
import eqicon2 from '@/assets/business_basic/eqicon2.png';
import eqicon3 from '@/assets/business_basic/eqicon3.png';
import eqicon4 from '@/assets/business_basic/eqicon4.png';
const RiskAssessment = () => {
const chartRef = useRef(null);
const pieChartRef = useRef(null);
const faultPieChartRef = useRef(null);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [selectedRows, setSelectedRows] = useState([]);
const [loading, setLoading] = useState(false);
const [dataSource, setDataSource] = useState([]);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 5,
total: 0,
});
// 饼图初始化
useEffect(() => {
if (pieChartRef.current) {
const pieChart = echarts.init(pieChartRef.current);
const pieOption = {
color: ['#44BB5F', '#F8C541', '#A493FB', '#4B69F1', '#949FD0'],
legend: {
orient: 'vertical',
right: '10%',
top: 'center',
itemWidth: 8,
itemHeight: 8,
textStyle: {
fontSize: 12,
color: '#333'
}
},
series: [{
name: '设备状态',
type: 'pie',
radius: ['40%', '70%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '14',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [
{ value: 480, name: '正常' },
{ value: 289, name: '故障' },
{ value: 200, name: '维修中' },
{ value: 150, name: '待验收' },
{ value: 161, name: '停用' }
]
}]
};
pieChart.setOption(pieOption);
// 响应式调整
const handlePieResize = () => {
if (pieChart && !pieChart.isDisposed()) {
pieChart.resize();
}
};
window.addEventListener('resize', handlePieResize);
return () => {
window.removeEventListener('resize', handlePieResize);
if (pieChart && !pieChart.isDisposed()) {
pieChart.dispose();
}
};
}
}, []);
// 故障类型饼图初始化
useEffect(() => {
if (faultPieChartRef.current) {
const faultPieChart = echarts.init(faultPieChartRef.current);
const faultPieOption = {
color: ['#FF3E48', '#FF8800', '#FFC403'],
legend: {
orient: 'vertical',
right: '10%',
top: 'center',
itemWidth: 8,
itemHeight: 8,
textStyle: {
fontSize: 12,
color: '#333'
}
},
series: [{
name: '设备故障类型',
type: 'pie',
radius: '70%',
center: ['35%', '50%'],
avoidLabelOverlap: false,
label: {
show: true,
position: 'outside',
formatter: '{b}: {c}',
fontSize: 12
},
emphasis: {
label: {
show: true,
fontSize: '14',
fontWeight: 'bold'
}
},
labelLine: {
show: true
},
data: [
{ value: 120, name: '紧急' },
{ value: 80, name: '重要' },
{ value: 60, name: '一般' }
]
}]
};
faultPieChart.setOption(faultPieOption);
// 响应式调整
const handleFaultPieResize = () => {
if (faultPieChart && !faultPieChart.isDisposed()) {
faultPieChart.resize();
}
};
window.addEventListener('resize', handleFaultPieResize);
return () => {
window.removeEventListener('resize', handleFaultPieResize);
if (faultPieChart && !faultPieChart.isDisposed()) {
faultPieChart.dispose();
}
};
}
}, []);
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
// 强制初始化时调整大小
setTimeout(() => {
if (chart && !chart.isDisposed()) {
chart.resize();
}
}, 100);
const option = {
color: ['#8979FF', '#3CC3DF'],
legend: {
// data: ['消防水泵1', '消防水泵2'],
top: "-3px",
// left: "center",
// itemGap: 40,
itemWidth: 20,
itemHeight: 8,
// icon: 'path://M902 472.7H747.9c-19.1-113.3-117.7-200-236.4-200s-217.3 86.7-236.4 200H119.7c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h155.5c19.1 113.3 117.7 200 236.4 200S728.9 666 748 552.7h154c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z m-390.5 200c-88.2 0-160-71.8-160-160s71.8-160 160-160 160 71.8 160 160-71.8 160-160 160z',
textStyle: {
fontSize: 10
}
},
grid: {
left: '2%',
right: '4%',
bottom: '2%',
top: '12%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00'],
axisLabel: {
fontSize: 10
}
},
yAxis: {
type: 'value',
min: 0,
max: 30,
axisLabel: {
formatter: '{value}',
fontSize: 10
}
},
series: [
{
name: '消防水泵1',
type: 'line',
smooth: false,
lineStyle: {
width: 2,
color: '#8979FF'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(137, 121, 255, 0.3)' },
{ offset: 1, color: 'rgba(137, 121, 255, 0.05)' }
]
}
},
symbol: 'circle',
symbolSize: 4,
itemStyle: {
color: '#fff',
borderColor: '#8979FF',
borderWidth: 1
},
data: [12, 15, 18, 14, 16, 20, 22, 19, 17, 21, 23, 25]
},
{
name: '消防水泵2',
type: 'line',
smooth: false,
lineStyle: {
width: 2,
color: '#3CC3DF'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(60, 195, 223, 0.3)' },
{ offset: 1, color: 'rgba(60, 195, 223, 0.05)' }
]
}
},
symbol: 'circle',
symbolSize: 4,
itemStyle: {
color: '#fff',
borderColor: '#3CC3DF',
borderWidth: 1
},
data: [8, 11, 14, 10, 13, 17, 19, 16, 14, 18, 20, 22]
}
]
};
chart.setOption(option);
// 响应式调整 - 使用多种方式监听容器尺寸变化
let resizeTimer = null;
const handleResize = () => {
// 防抖处理避免频繁调用resize
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(() => {
if (chart && !chart.isDisposed()) {
chart.resize();
}
}, 50); // 减少延迟时间
};
// 监听窗口大小变化
window.addEventListener('resize', handleResize);
// 监听容器尺寸变化(解决菜单栏伸缩时的自适应问题)
let resizeObserver = null;
if (window.ResizeObserver) {
resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
// 使用requestAnimationFrame确保在下一帧执行
requestAnimationFrame(() => {
handleResize();
});
}
});
resizeObserver.observe(chartRef.current);
}
// 额外监听父容器的尺寸变化
const parentContainer = chartRef.current?.parentElement;
let parentObserver = null;
if (parentContainer && window.ResizeObserver) {
parentObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
requestAnimationFrame(() => {
handleResize();
});
}
});
parentObserver.observe(parentContainer);
}
// 使用MutationObserver监听DOM结构变化菜单展开收起时
const mutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'class' || mutation.attributeName === 'style')) {
// 延迟执行确保DOM更新完成
setTimeout(() => {
handleResize();
}, 200);
}
});
});
// 监听整个页面的class和style变化
mutationObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style'],
subtree: true
});
return () => {
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
}
if (parentObserver) {
parentObserver.disconnect();
}
if (mutationObserver) {
mutationObserver.disconnect();
}
if (resizeTimer) {
clearTimeout(resizeTimer);
}
if (chart && !chart.isDisposed()) {
chart.dispose();
}
};
}
}, []);
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 60,
render: (text, record, index) => {
const page = pagination.current || 1;
const pageSize = pagination.pageSize || 5;
const number = (page - 1) * pageSize + index + 1;
return `0${number}`.slice(-2);
}
},
{
title: '设备编号',
dataIndex: 'deviceId',
key: 'deviceId',
width: 140,
},
{
title: '设备名称',
dataIndex: 'deviceName',
key: 'deviceName',
width: 110,
},
{
title: '型号规格',
dataIndex: 'modelSpec',
key: 'modelSpec',
width: 140,
},
{
title: '安装位置',
dataIndex: 'installLocation',
key: 'installLocation',
width: 200,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 80,
render: (text) => {
const statusMap = {
'故障': { color: '#FF4D4F', bg: '#FFF2F0' },
'预警': { color: '#FAAD14', bg: '#FFF3E9' },
'正常': { color: '#44BB5F', bg: '#D8F7DE' }
};
const status = statusMap[text] || { color: '#333', bg: '#F5F5F5' };
return (
<span style={{
color: status.color,
backgroundColor: status.bg,
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px'
}}>
{text}
</span>
);
}
},
{
title: '最后维护',
dataIndex: 'lastMaintenance',
key: 'lastMaintenance',
width: 150,
},
{
title: '操作',
key: 'action',
width: 140,
render: (_, record) => (
<div>
<Button type="link" size="small" style={{
padding: '2px 8px',
fontSize: 12,
marginRight: 8,
border: '1px solid #E6E9FB',
backgroundColor: 'transparent',
borderRadius: '4px'
}}>
编辑
</Button>
<Button type="link" size="small" style={{
padding: '2px 8px',
fontSize: 12,
border: '1px solid #E6E9FB',
backgroundColor: 'transparent',
borderRadius: '4px'
}}>
详情
</Button>
</div>
),
},
];
// 模拟数据
const mockData = [
{
key: '1',
id: '001',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼1层大厅',
status: '故障',
lastMaintenance: '2025-09-10',
},
{
key: '2',
id: '002',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼3层 东区',
status: '预警',
lastMaintenance: '2025-09-10',
},
{
key: '3',
id: '003',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '4',
id: '004',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '故障',
lastMaintenance: '2025-09-10',
},
{
key: '5',
id: '005',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '6',
id: '006',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '预警',
lastMaintenance: '2025-09-10',
},
{
key: '7',
id: '007',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '故障',
lastMaintenance: '2025-09-10',
},
{
key: '8',
id: '008',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '9',
id: '009',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '预警',
lastMaintenance: '2025-09-10',
},
{
key: '10',
id: '010',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '故障',
lastMaintenance: '2025-09-10',
},
{
key: '11',
id: '011',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '正常',
lastMaintenance: '2025-09-10',
},
{
key: '12',
id: '012',
deviceId: 'HQ-XF-01-001',
deviceName: '消防水泵',
modelSpec: 'XBD5.0/30-125',
installLocation: '总部大楼地下一层',
status: '预警',
lastMaintenance: '2025-09-10',
},
];
// 初始化数据
useEffect(() => {
setPagination(prev => ({ ...prev, total: mockData.length }));
}, []);
// 根据分页获取当前页数据
const getCurrentPageData = () => {
const { current, pageSize } = pagination;
const startIndex = (current - 1) * pageSize;
const endIndex = startIndex + pageSize;
return mockData.slice(startIndex, endIndex);
};
// 表格选择变化
const onSelectChange = (newSelectedRowKeys, newSelectedRows) => {
setSelectedRowKeys(newSelectedRowKeys);
setSelectedRows(newSelectedRows);
};
// 新增设备按钮点击事件
const handleAddDevice = () => {
console.log('新增设备');
// TODO: 实现新增设备逻辑
};
// 导出数据按钮点击事件
const handleExportData = () => {
console.log('导出数据');
// TODO: 实现导出数据逻辑
};
// 分页变化处理
const handleTableChange = (pagination) => {
setPagination(prev => ({
...prev,
current: pagination.current,
pageSize: pagination.pageSize,
}));
};
return (
<div className={styles.Rcontainer}>
{/* 第一个div - 高度20% */}
<div className={styles.RcontainerTop}>
<div className={styles.sectionContent}>
<div className={styles.blocksContainer}>
{/* 块1 */}
<div className={styles.blockItem}>
<div className={styles.blockLeft}>
<div className={styles.blockTitle}>设备总数</div>
<div className={styles.blockNumber}>1280</div>
</div>
<div className={styles.blockRight}>
<img src={eqicon1} alt="设备总数" className={styles.blockImage} />
</div>
</div>
{/* 块2 */}
<div className={styles.blockItem}>
<div className={styles.blockLeft}>
<div className={styles.blockTitle}>正常运行</div>
<div className={styles.blockNumber}>480</div>
</div>
<div className={styles.blockRight}>
<img src={eqicon2} alt="高风险设备" className={styles.blockImage} />
</div>
</div>
{/* 块3 */}
<div className={styles.blockItem}>
<div className={styles.blockLeft}>
<div className={styles.blockTitle}>需要维护</div>
<div className={styles.blockNumber}>347</div>
</div>
<div className={styles.blockRight}>
<img src={eqicon3} alt="今日预警次数" className={styles.blockImage} />
</div>
</div>
{/* 块4 */}
<div className={styles.blockItem}>
<div className={styles.blockLeft}>
<div className={styles.blockTitle}>故障设备</div>
<div className={styles.blockNumber}>289</div>
</div>
<div className={styles.blockRight}>
<img src={eqicon4} alt="未处理预警" className={styles.blockImage} />
</div>
</div>
</div>
</div>
</div>
<div className={styles.RcontainerMiddle}>
<div className={styles.sectionContent}>
<div className={styles.middleBlock1}>
<div className={styles.block1Header}>
<div className={styles.block1Title}>
<div className={styles.titleIcon}></div>
设备状态分布
</div>
<Segmented
className={styles.block1Segmented}
options={['月', '季', '年']}
onChange={(value) => {
console.log(value);
}}
/>
</div>
{/* 设备状态饼图 */}
<div className={styles.deviceStatusChart} ref={pieChartRef}>
</div>
</div>
<div className={styles.middleBlock12}>
<div className={styles.block1Header}>
<div className={styles.block1Title}>
<div className={styles.titleIcon}></div>
设备故障类型分布
</div>
<Select
className={styles.customSelect}
style={{
width: 120,
display: 'flex',
alignItems: 'center'
}}
defaultValue="全部区域"
options={[
{ value: '全部区域', label: '全部区域' },
{ value: '部分区域', label: '部分区域' },
]}
/>
</div>
{/* 设备故障类型饼图 */}
<div className={styles.deviceStatusChart} ref={faultPieChartRef}>
</div>
</div>
<div className={styles.middleBlock2}>
<div className={styles.middleBlock2Title}>
<div className={styles.titleLeft}>
<div className={styles.titleIcon}></div>
<div>设备运行参数</div>
</div>
<div className={styles.titleRight}>
<Select
style={{ width: 80 }}
defaultValue="今日"
options={[
{ value: '近3天', label: '近3天' },
{ value: '近7天', label: '近7天' },
]}
/>
</div>
</div>
<div className={styles.middleBlock2Chart} ref={chartRef}>
</div>
</div>
</div>
</div>
{/* 第三个div - 占满剩余位置 */}
<div className={styles.RcontainerBottom}>
<div className={styles.sectionContent}>
<div className={styles.leftBlock}>
{/* 第一行块 - 蓝色方块加标题 */}
<div className={styles.leftBlockTitle}>
<div className={styles.titleIcon}></div>
<div>预警信息</div>
</div>
<div className={styles.developmentContainer}>
<div className={styles.developmentBlock1}>
<div className={styles.leftContent}>
<div className={styles.mainText}>灭火器压力不足</div>
<div className={styles.subText}>2号楼3层 15分钟前</div>
</div>
<div className={styles.rightContent}>
<div className={styles.importantTag}>重要</div>
</div>
</div>
<div className={styles.developmentBlock1}>
<div className={styles.leftContent}>
<div className={styles.mainText}>烟雾探测器电池低电量</div>
<div className={styles.subText}>1号楼5层 1小时前</div>
</div>
<div className={styles.rightContent}>
<div className={styles.importantTag}>重要</div>
</div>
</div>
<div className={styles.developmentBlock1}>
<div className={styles.leftContent}>
<div className={styles.mainText}>消防栓维护到期</div>
<div className={styles.subText}>3号楼1层 2小时前</div>
</div>
<div className={styles.rightContent}>
<div className={styles.normalTag}>一般</div>
</div>
</div>
<div className={styles.developmentBlock1}>
<div className={styles.leftContent}>
<div className={styles.mainText}>应急照明故障</div>
<div className={styles.subText}>地下停车场 3小时前</div>
</div>
<div className={styles.rightContent}>
<div className={styles.normalTag}>一般</div>
</div>
</div>
</div>
</div>
<div className={styles.rightBlock}>
{/* 表格 */}
<div className={styles.tableHeader}>
<div className={styles.tableTitle}>
<div className={styles.titleIcon}></div>
<div>消防设备台账</div>
</div>
<div className={styles.tableActions}>
<button className={styles.actionButton} onClick={handleAddDevice}>
<span className={styles.buttonIcon}>+</span>
<span>新增设备</span>
</button>
<button className={styles.actionButton} onClick={handleExportData}>
<span className={styles.buttonIcon}><ExportOutlined /></span>
<span>导出数据</span>
</button>
</div>
</div>
{/* 表格 */}
<div className={styles.tableContainer}>
<StandardTable
columns={columns}
data={{
list: getCurrentPageData(),
pagination: pagination
}}
loading={loading}
selectionType="checkbox"
onSelectRow={onSelectChange}
onChange={handleTableChange}
pagination={{
...pagination,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total, range) =>
`${total}`,
}}
// scroll={{ x: 1200 }}
/>
</div>
</div>
</div>
</div>
</div>
);
};
export default RiskAssessment;

@ -1,594 +0,0 @@
.Rcontainer {
padding: 8px 6px 0px 6px;
height: 100%;
display: flex;
flex-direction: column;
gap: 10px;
// 第一个div - 高度20%
.RcontainerTop {
height: 16%;
// background-color: #fff;
border-radius: 4px;
display: flex;
flex-direction: column;
.sectionContent {
height: 100%;
display: flex;
flex-direction: column;
// padding: 15px;
.blocksContainer {
flex: 1;
display: flex;
gap: 10px;
height: 100%;
.blockItem {
flex: 1;
height: 100%;
display: flex;
background: linear-gradient(170.5deg, #F5F7FF 6.87%, #FFFFFF 47.65%);
border-radius: 4px;
border: 2px solid #FFFFFF;
.blockLeft {
width: 60%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding: 15px;
padding-left: 20px;
gap: 8px;
.blockTitle {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #333333;
line-height: 1.2;
}
.blockNumber {
font-family: PingFang SC;
font-weight: 700;
font-size: 24px;
color: #333333;
line-height: 1.2;
}
.blockChange {
font-family: PingFang SC;
font-weight: 400;
font-size: 12px;
color: #1269FF;
line-height: 1.2;
display: flex;
align-items: center;
gap: 4px;
.arrow {
font-size: 14px;
font-weight: bold;
}
.checkIcon {
font-size: 16px;
color: #1269FF;
}
}
}
.blockRight {
flex: 1;
height: 100%;
background-color: transparent;
border-radius: 0 4px 4px 0;
display: flex;
align-items: center;
justify-content: center;
.blockImage {
// width: 80%;
height: 65%;
// height: 80%;
object-fit: contain;
margin-right: -5px;
}
}
}
}
}
}
// 第二个div - 高度39%
.RcontainerMiddle {
height: 33%;
border-radius: 4px;
display: flex;
flex-direction: column;
.sectionContent {
height: 100%;
display: flex;
display: flex;
gap: 10px;
height: 100%;
.middleBlock1 {
// flex: 1;
width: 28%;
height: 100%;
background: #fff;
border: 2px solid #fff;
// border-radius: 4px;
position: relative;
padding: 0px 10px 10px 2px;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
.block1Header {
position: absolute;
top: 5px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
.block1Title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
.block1Segmented {
padding: 0;
margin: 0;
border: 1px solid #E3E3E3;
border-radius: 4px;
height: 28px;
:global(.ant-segmented) {
padding: 0;
margin: 0;
height: 28px;
}
:global(.ant-segmented-item) {
font-size: 12px;
padding: 2px 8px;
height: 26px;
line-height: 26px;
display: flex;
align-items: center;
justify-content: center;
}
:global(.ant-segmented-item-selected) {
background-color: #1890ff;
color: #fff;
}
}
}
.deviceStatusChart {
position: absolute;
top: 35px;
left: 10px;
right: 10px;
bottom: 10px;
z-index: 10;
}
// .block1Chart {
// width: 100%;
// height: 100%;
// margin-top: 20px;
// .mapImage {
// margin-top: 7%;
// width: 90%;
// height: 77%;
// object-fit: cover;
// border-radius: 4px;
// display: block;
// margin-left: auto;
// margin-right: auto;
// }
// }
}
.middleBlock12 {
flex: 1;
height: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
padding: 5px 10px 5px 10px;
position: relative;
.block1Header {
position: absolute;
top: 5px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 10;
.block1Title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
.block1Segmented {
padding: 0;
margin: 0;
border: 1px solid #E3E3E3;
border-radius: 4px;
height: 28px;
:global(.ant-segmented) {
padding: 0;
margin: 0;
height: 28px;
}
:global(.ant-segmented-item) {
font-size: 12px;
padding: 2px 8px;
height: 26px;
line-height: 26px;
display: flex;
align-items: center;
justify-content: center;
}
:global(.ant-segmented-item-selected) {
background-color: #1890ff;
color: #fff;
}
}
.customSelect {
:global(.ant-select-single:not(.ant-select-customize-input) .ant-select-selector) {
height: 26px !important;
display: flex !important;
align-items: center !important;
}
:global(.ant-select-selection-item) {
line-height: 24px !important;
// height: 24px !important;
display: flex !important;
align-items: center !important;
}
}
}
.deviceStatusChart {
position: absolute;
top: 35px;
left: 10px;
right: 10px;
bottom: 10px;
z-index: 10;
}
}
.middleBlock2 {
flex: 1;
height: 100%;
// background: linear-gradient(170.5deg, #EBEFF4 6.87%, #FFFFFF 53.01%);
// border: 2px solid #fff;
background-color: #fff;
// border-radius: 4px;
display: flex;
flex-direction: column;
font-family: PingFang SC;
font-size: 14px;
color: #333333;
padding: 5px 10px 5px 10px;
.middleBlock2Title {
display: flex;
justify-content: space-between;
align-items: center;
// margin-bottom: 10px;
.titleLeft {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 14px;
background-color: #2E4CD4;
}
}
.titleRight {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: #666;
}
}
.middleBlock2Chart {
width: 100%;
height: 100%;
// min-height: 200px;
}
}
}
}
// 第三个div - 高度不超过45%
.RcontainerBottom {
height: 45%; // 限制高度不超过45%
max-height: 45%; // 确保最大高度不超过45%
display: flex;
flex-direction: column;
.sectionContent {
display: flex;
flex-direction: row;
gap: 10px;
padding: 0;
.leftBlock {
width: 28%;
flex-shrink: 0;
height: 100%;
background: #fff;
// background-size: cover;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
padding: 15px;
.leftBlockTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
margin-bottom: 10px;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.developmentContainer {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 8px;
.developmentBlock1 {
flex: 1;
background-color: #F1F7FF;
border-radius: 4px;
padding: 15px 20px;
display: flex;
align-items: center;
width: 100%;
.leftContent {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
min-width: 0;
.mainText {
color: #333333;
font-size: 14px;
font-weight: 500;
font-family: PingFang SC;
width: 100%;
max-width: 500px;
}
.subText {
color: #666666;
font-size: 12px;
font-weight: 400;
font-family: PingFang SC;
width: 100%;
max-width: 400px;
}
}
.rightContent {
flex: 0 0 auto;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 10px;
min-width: 80px;
.importantTag {
background-color: #FFE0E2;
color: #FF3E48;
font-size: 14px;
font-weight: 500;
font-family: PingFang SC;
width: 45px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
.normalTag {
background-color: #DAF3FF;
color: #00AAFA;
font-size: 14px;
font-weight: 500;
font-family: PingFang SC;
width: 45px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
}
}
}
}
}
.rightBlock {
width: calc(100% - 28% - 10px);
height: 100%;
background-color: #fff;
padding: 0;
display: flex;
flex-direction: column;
.tableHeader {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 15px 5px 15px;
.tableTitle {
display: flex;
align-items: center;
gap: 8px;
font-family: PingFang SC;
font-weight: 500;
font-size: 14px;
color: #333333;
.titleIcon {
width: 3px;
height: 16px;
background-color: #2E4CD4;
}
}
.tableActions {
display: flex;
gap: 8px;
margin-top: 5px;
.actionButton {
display: flex;
align-items: center;
gap: 4px;
height: 28px;
border: 1px solid #DFE4F6;
border-radius: 4px;
color: #2E4CD4;
font-weight: 500;
font-size: 12px;
padding: 0px 8px;
background: transparent;
cursor: pointer;
transition: all 0.2s ease;
&:hover {
background-color: #f0f2ff;
border-color: #2E4CD4;
}
&:active {
background-color: #e6ebff;
}
.buttonIcon {
font-size: 14px;
font-weight: bold;
}
}
}
}
.tableContainer {
flex: 1;
overflow: hidden;
margin: 10px 15px 0 15px; // 上边距10px左右边距15px
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
color: #666666;
}
:global(.ant-table-tbody > tr:hover > td) {
background-color: #f5f5f5;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}
}
}
}

@ -9,7 +9,6 @@ import { userInfo } from '@/utils/globalCommon'
import { HomeOutlined, LogoutOutlined, AppstoreOutlined, UserOutlined, SettingOutlined, DatabaseOutlined, FileTextOutlined, LockOutlined, AreaChartOutlined, CaretDownOutlined, BellOutlined, SearchOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import { getPageQuery } from '@/utils/utils'
import menuTitle from '@/assets/img/智能管控平台.svg'
import menuTitle1 from '@/assets/img/智能管控平台-1.svg'
import fireHydrant from '@/assets/img/fireHydrant.svg'
import fireHydrant1 from '@/assets/img/fireHydrant1.svg'
import fireKeynoteArea from '@/assets/img/fire_keynote_area.svg'
@ -96,7 +95,7 @@ const SystemContentList = (props) => {
path: '/topnavbar00/business/basic',
icon: <img
src={icon1}
alt="基础信息管理"
alt="信息管理"
style={{
width: '16px',
height: '16px',
@ -104,7 +103,7 @@ const SystemContentList = (props) => {
}}
/>,
key: "/topnavbar00/business/basic",
"label": "基础信息管理"
"label": "信息管理"
},
]
setMenuItems(fixedMenuItems)
@ -195,10 +194,12 @@ const SystemContentList = (props) => {
>
<div className='menuTitle' style={{
marginBottom: '10px',
display: isMenuCollapsed ? 'none' : 'flex'
display: isMenuCollapsed ? 'none' : 'flex',
flexDirection: 'row',
alignItems: 'center'
}}>
<img src={menuTitle} alt='menuTitle' style={{ marginTop: '20px', marginBottom: '2px', width: '172.44px', height: '51.28px' }} />
<img src={menuTitle1} alt='menuTitle1' style={{ width: '172.44px', height: '51.28px' }} />
<img src={menuTitle} alt='menuTitle' style={{marginTop: '6px', marginBottom: '2px', width: '30px', height: '30px', marginRight: '8px' }} />
<span className="menuTitleText">智能管控平台</span>
</div>
<div style={{
textAlign: 'center',
@ -211,8 +212,8 @@ const SystemContentList = (props) => {
style={{
width: 192,
height: 42,
borderColor: '#3D81FF',
backgroundColor: '#003AA7',
borderColor: '#008F8E',
backgroundColor: '#00666599',
borderRadius: 0,
color: '#fff',
fontSize: 22,
@ -222,8 +223,8 @@ const SystemContentList = (props) => {
{ value: '储运管理系统', label: '储运管理系统' }
]}
dropdownStyle={{
backgroundColor: '#003AA7',
borderColor: '#3D81FF'
backgroundColor: '#00666599',
borderColor: '#008F8E'
}}
popupClassName="custom-select-dropdown"
className="custom-select"
@ -233,9 +234,10 @@ const SystemContentList = (props) => {
<style jsx>{`
.custom-select .ant-select-selector {
height: 42px !important;
border-radius: 0 !important;
border-color: #3D81FF !important;
background-color: #003AA7 !important;
border-radius: 4px !important;
border:2px solid #008F8E !important;
border-color: #008F8E !important;
background-color: #00666599 !important;
color: #fff !important;
fontSize: 22px !important;
fontWeight: 600 !important;
@ -395,7 +397,7 @@ const SystemContentList = (props) => {
</Row>
</div>
{/* </div> */}
<div style={{ padding: '12px', height: '100%' }}>
<div style={{ padding: '0px 12px 12px 12px', height: '100%' }}>
<div className='rightContentMain'>
<Outlet />
</div>

@ -6,7 +6,7 @@
// padding: 12px;
.tabBarHeader {
background-color: #fff;
// background-color: #fff;
padding: 0;
width: 100%;
min-height: 62px;
@ -16,6 +16,7 @@
.tabBarRow {
padding: 0 12px;
justify-content: flex-end;
// background: pink !important;
.tabBarLeft {
display: flex;
@ -77,11 +78,17 @@
width: 230px;
overflow-y: auto;
overflow-x: hidden;
background-color: #2E4CD4;
// background-image: url('@/assets/img/menuBg.png');
background-color: #006665;
border-top-right-radius: 20px;
.ant-menu-inline,
.ant-menu-vertical {
background: #2E4CD4 !important;
width: 100%;
background-color: transparent;
}
// 默认情况字体样式和右边距
@ -105,7 +112,9 @@
// 选中状态样式
.ant-menu-item-selected {
color: rgba(255, 255, 255, 1) !important;
background-color: rgba(255, 255, 255, 0.22) !important;
background-color: #398584;
backdrop-filter: blur(8.5px);
box-shadow: 0px 2px 2px 0px #00000040;
}
// 选中状态下的文本颜色和右边距
@ -122,6 +131,18 @@
align-items: center;
height: 62px;
width: 100%;
.menuTitleText {
font-family: FontName;
font-weight: 500;
font-style: italic;
color: #FFFFFF;
font-size: 24px;
line-height: 100%;
letter-spacing: 0%;
text-shadow: 2px 3px 3px #00000040;
}
}
}

@ -9,7 +9,7 @@ import { userInfo } from '@/utils/globalCommon'
const menuItem = [
{
label: '基础信息管理',
label: '信息管理',
key: '/topnavbar00/business/basic',
},
]
@ -94,29 +94,6 @@ const TopNavBar = (props) => {
return (
<div className={styles.layoutContainer}>
{/* <div className={styles.tabBarHeader}>
<Row className={styles.tabBarRow}>
<Col xs={16} sm={16} md={16} lg={16} xl={16} className={styles.tabBarLeft}>
<img src={Logo} alt='logo' className={styles.leftLogo} />
<Menu mode='horizontal' className={styles.leftMenu} selectedKeys={[activeKey]} items={menuItems} onClick={value => setRouteActive(value)} />
</Col>
<Col xs={8} sm={8} md={8} lg={8} xl={8} className={styles.tabBarRight}>
<Avatar className={styles.tabBarRightAvaTor} src='https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F31%2F20170731021444_2YUfe.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1669779871&t=ec025ed48a1668dee9cfa0e803b6f787' />
<span className={styles.tabBarRightName}>{userInfo?.user_name_cn ? userInfo.user_name_cn : (userInfo?.user_name || '')}</span>
<Dropdown dropdownRender={dropDownMenu}>
<Button type='text' className={styles.tabBarRightBtn}><SettingOutlined /></Button>
</Dropdown>
</Col>
</Row>
</div> */}
{/* <div className={styles.contentMain}>
<Outlet />
</div> */}
<Outlet />
</div>
)

@ -1,14 +1,19 @@
.layoutContainer {
height: 100%;
background-color: #f0f2f5;
background-color:#f0f7f7;
// 激活状态样式
&.active {
}
.tabBarHeader {
background-color: #fff;
background-color: transparent;
padding: 0;
width: 100%;
.tabBarRow {
padding: 0 12px;
// background-color: red !important;
.tabBarLeft {
display: flex;
@ -53,4 +58,12 @@
height: calc(100% - 46px);
overflow-y: hidden;
}
}
// 覆盖面包屑激活文本样式
:global {
.breadcrumb-item-text-active {
color: #006665 !important;
font-weight: 500 !important;
}
}
}
Loading…
Cancel
Save