数据采集页面
parent
290733b67c
commit
4f05da26e7
@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10 0C8.02219 0 6.08879 0.58649 4.4443 1.6853C2.79981 2.78412 1.51809 4.3459 0.761209 6.17317C0.00433281 8.00043 -0.193701 10.0111 0.192152 11.9509C0.578004 13.8907 1.53041 15.6725 2.92894 17.0711C4.32746 18.4696 6.10929 19.422 8.0491 19.8079C9.98891 20.1937 11.9996 19.9957 13.8268 19.2388C15.6541 18.4819 17.2159 17.2002 18.3147 15.5557C19.4135 13.9112 20 11.9778 20 10C20 7.34784 18.9464 4.8043 17.0711 2.92893C15.1957 1.05357 12.6522 0 10 0ZM10 18C8.41775 18 6.87104 17.5308 5.55544 16.6518C4.23985 15.7727 3.21447 14.5233 2.60897 13.0615C2.00347 11.5997 1.84504 9.99113 2.15372 8.43928C2.4624 6.88743 3.22433 5.46197 4.34315 4.34315C5.46197 3.22433 6.88743 2.4624 8.43928 2.15372C9.99113 1.84504 11.5997 2.00346 13.0615 2.60896C14.5233 3.21446 15.7727 4.23985 16.6518 5.55544C17.5308 6.87103 18 8.41775 18 10C18 12.1217 17.1572 14.1566 15.6569 15.6569C14.1566 17.1571 12.1217 18 10 18Z" fill="white"/>
|
||||
<path d="M12.8692 4H7.78922L6.19922 10.63H8.98922L7.04922 16H8.12922L13.7992 8.83H10.4692L12.8692 4Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.7551 1.98145C8.73746 1.83952 8.50412 1.83952 8.48646 1.98145C7.90193 6.69329 4.91346 7.66393 4.91346 10.9383C4.91346 12.9617 6.61055 14.6019 8.62117 14.6019C10.631 14.6019 12.3281 12.9617 12.3281 10.9383C12.3281 7.66393 9.33963 6.69329 8.7551 1.98145ZM9.38656 13.7406C9.17605 13.7406 9.00648 13.5706 9.00648 13.3605C9.00648 13.1504 9.17686 12.9804 9.38656 12.9804C9.91018 12.9804 10.336 12.5562 10.336 12.0338C10.336 11.8237 10.5059 11.6537 10.7161 11.6537C10.7907 11.6536 10.8637 11.6754 10.926 11.7164C10.9883 11.7575 11.0372 11.816 11.0664 11.8846C11.0866 11.9318 11.097 11.9825 11.0969 12.0338C11.0969 12.9752 10.3295 13.7406 9.38656 13.7406ZM13.4113 3.5676C13.4051 3.51721 13.3222 3.51721 13.316 3.5676C13.1084 5.24053 12.0474 5.58514 12.0474 6.74768C12.0474 7.4661 12.6499 8.04844 13.3638 8.04844C14.0774 8.04844 14.6799 7.4661 14.6799 6.74768C14.6799 5.58514 13.6189 5.24051 13.4113 3.5676ZM13.6355 7.74262C13.6178 7.74265 13.6003 7.73917 13.5839 7.7324C13.5675 7.72562 13.5526 7.71568 13.5401 7.70314C13.5275 7.69061 13.5176 7.67572 13.5108 7.65933C13.5041 7.64295 13.5006 7.62539 13.5006 7.60766C13.5006 7.57187 13.5148 7.53755 13.5401 7.51225C13.5654 7.48694 13.5998 7.47272 13.6355 7.47272C13.8214 7.47272 13.9726 7.32211 13.9726 7.13665C13.9726 7.11892 13.9761 7.10137 13.9829 7.08499C13.9897 7.06862 13.9996 7.05374 14.0121 7.0412C14.0247 7.02867 14.0395 7.01873 14.0559 7.01195C14.0723 7.00518 14.0899 7.00169 14.1076 7.0017C14.1253 7.00167 14.1429 7.00513 14.1593 7.0119C14.1757 7.01866 14.1906 7.0286 14.2032 7.04113C14.2157 7.05366 14.2257 7.06855 14.2325 7.08494C14.2393 7.10133 14.2428 7.1189 14.2428 7.13665C14.2428 7.47086 13.9704 7.74262 13.6355 7.74262ZM17.5454 15.434C17.2585 15.3126 16.9275 15.4467 16.8061 15.7336C16.4846 16.4931 15.7385 16.9969 14.8996 16.9969C14.0498 16.9969 13.2962 16.4801 12.9822 15.7064C12.8651 15.4177 12.5362 15.2787 12.2475 15.3958C12.1422 15.4384 12.0523 15.5121 11.9898 15.6069C11.9596 15.6454 11.9324 15.6867 11.9124 15.7338C11.5915 16.4931 10.8455 16.9969 10.0066 16.9969C9.17674 16.9969 8.44148 16.5025 8.11463 15.759C8.0691 15.5958 7.95297 15.4542 7.78363 15.3861C7.49459 15.2699 7.16613 15.4101 7.04998 15.6991C6.73742 16.4769 5.98197 16.9969 5.12936 16.9969C4.27059 16.9969 3.51057 16.4689 3.20266 15.6829C3.08904 15.3928 2.7618 15.2498 2.47176 15.3634C2.1817 15.477 2.03867 15.8043 2.15229 16.0943C2.62818 17.3091 3.80252 18.125 5.12936 18.125C6.09225 18.125 6.97381 17.6942 7.56771 16.9937C8.16168 17.6944 9.04367 18.125 10.0066 18.125C10.973 18.125 11.8594 17.6917 12.4536 16.9851C13.0475 17.6909 13.9328 18.125 14.8996 18.125C16.1956 18.125 17.3484 17.3465 17.8449 16.1733C17.9664 15.8864 17.8322 15.5555 17.5454 15.434Z" fill="#DADCFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 10C0 12.6522 1.05357 15.1957 2.92893 17.0711C4.8043 18.9464 7.34784 20 10 20C12.6522 20 15.1957 18.9464 17.0711 17.0711C18.9464 15.1957 20 12.6522 20 10C20 7.34784 18.9464 4.8043 17.0711 2.92893C15.1957 1.05357 12.6522 0 10 0C7.34784 0 4.8043 1.05357 2.92893 2.92893C1.05357 4.8043 0 7.34784 0 10Z" fill="#DADCFF"/>
|
||||
<path d="M10.8926 16C10.8926 16 14.4406 15.7055 14.9996 12C14.9996 9.5035 12.9461 8.089 12.9461 8.089C12.9461 8.089 12.5236 8.844 12.0531 9.0665C12.0571 9.1005 13.3241 5.688 9.10705 4C9.10205 4.0635 9.29705 4.896 9.28555 5.2445C9.27405 5.593 8.98105 7.1665 7.41055 8.3555C5.84055 9.5445 5.02555 10.401 5.00055 12C4.97455 13.5985 5.85655 15.322 8.92855 16C8.92605 16.0185 7.68055 14.6275 7.67855 13.0665C7.67655 11.5055 9.17755 10.4725 9.91055 10.0445C9.89455 10.0395 9.83055 10.3155 9.82105 10.7555C9.81205 11.1955 10.0896 11.9785 10.6246 12.4445C11.1601 12.91 11.6146 13.6645 11.6071 14.133C11.5996 14.602 11.2321 15.55 10.8926 16Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,10 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_5176_22848)">
|
||||
<path d="M6.38984 6.59905C10.0064 6.59905 12.5287 5.63793 12.5287 4.45329V3.16545C12.5287 1.98057 10.0064 1.01953 6.38984 1.01953C2.77328 1.01953 0.660156 1.98057 0.660156 3.16545V4.45329C0.660156 5.63793 2.77328 6.59905 6.38984 6.59905ZM0.950316 10.4473C0.754876 10.6516 0.660156 10.869 0.660156 11.0944V12.8203C0.660156 14.0118 2.78056 14.9772 6.41 14.9772C6.5912 14.9772 6.76976 14.9741 6.94632 14.9688V11.9482C6.76304 11.9539 6.57792 11.9572 6.3904 11.9572C3.44648 11.9572 1.78736 11.3224 0.950316 10.4473ZM0.950316 6.25385C0.754876 6.45913 0.660156 6.67681 0.660156 6.90281V8.63281C0.660156 9.82649 2.78056 10.7953 6.41 10.7953C6.59096 10.7953 6.76968 10.7925 6.94632 10.7872V7.76393C6.76616 7.76641 6.58112 7.76769 6.3904 7.76769C3.44648 7.76769 1.78736 7.13129 0.950316 6.25385ZM12.6365 8.33257C12.6365 9.22169 11.916 9.94225 11.0271 9.94225C10.1382 9.94225 9.4176 9.22169 9.4176 8.33257C9.4176 7.44385 10.1382 6.72329 11.0271 6.72329C11.9162 6.72329 12.6365 7.44385 12.6365 8.33257ZM7.2624 13.0051C7.2624 13.2079 7.30235 13.4087 7.37997 13.5961C7.45759 13.7835 7.57136 13.9538 7.71479 14.0972C7.85821 14.2406 8.02848 14.3544 8.21588 14.432C8.40327 14.5097 8.60412 14.5496 8.80696 14.5496C9.00979 14.5496 9.21064 14.5097 9.39803 14.432C9.58543 14.3544 9.7557 14.2406 9.89913 14.0972C10.0426 13.9538 10.1563 13.7835 10.2339 13.5961C10.3116 13.4087 10.3515 13.2079 10.3515 13.0051C10.3515 12.5954 10.1888 12.2025 9.89913 11.9129C9.60946 11.6232 9.2166 11.4605 8.80696 11.4605C8.39731 11.4605 8.00445 11.6232 7.71479 11.9129C7.42513 12.2025 7.2624 12.5954 7.2624 13.0051ZM15.7484 12.2399C15.7484 13.0379 15.1015 13.6843 14.3038 13.6843C13.5059 13.6843 12.859 13.0379 12.859 12.2399C12.859 11.4419 13.5059 10.7953 14.3038 10.7953C15.1015 10.7953 15.7484 11.4419 15.7484 12.2399ZM10.6817 8.33481L11.0345 8.55481L8.25952 13.0054L7.90672 12.7854L10.6817 8.33481ZM15.3175 12.4931L10.6559 8.21681L10.8928 7.95857L15.5544 12.2349L15.3175 12.4931Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5176_22848">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.4361 3.02605C1.4361 3.23442 1.60581 3.44075 1.93553 3.63326C2.26526 3.82577 2.74854 4.00069 3.35779 4.14803C3.96704 4.29537 4.69033 4.41224 5.48636 4.49198C6.28238 4.57172 7.13556 4.61276 7.99717 4.61276C8.85878 4.61276 9.71195 4.57172 10.508 4.49198C11.304 4.41224 12.0273 4.29537 12.6365 4.14803C13.2458 4.00069 13.7291 3.82577 14.0588 3.63326C14.3885 3.44075 14.5582 3.23442 14.5582 3.02605C14.5582 2.81768 14.3885 2.61135 14.0588 2.41884C13.7291 2.22633 13.2458 2.05141 12.6365 1.90407C12.0273 1.75673 11.304 1.63986 10.508 1.56012C9.71195 1.48038 8.85878 1.43934 7.99717 1.43934C7.13556 1.43934 6.28238 1.48038 5.48636 1.56012C4.69033 1.63986 3.96704 1.75673 3.35779 1.90407C2.74854 2.05141 2.26526 2.22633 1.93553 2.41884C1.60581 2.61135 1.4361 2.81768 1.4361 3.02605ZM7.99717 4.62174C6.2437 4.62174 4.5967 4.45627 3.35632 4.15612C2.11337 3.85468 1.42969 3.45448 1.42969 3.02605C1.42969 2.59762 2.11337 2.19742 3.35632 1.89726C4.5967 1.59839 6.2437 1.43164 7.99717 1.43164C9.75063 1.43164 11.3976 1.59711 12.638 1.89726C13.881 2.1987 14.5646 2.59891 14.5646 3.02605C14.5646 3.45319 13.881 3.85468 12.638 4.15484C11.3976 4.45499 9.75063 4.62174 7.99717 4.62174ZM7.99717 1.44575C4.38249 1.44575 1.44251 2.15509 1.44251 3.02605C1.44251 3.89829 4.38249 4.60763 7.99717 4.60763C11.6118 4.60763 14.5531 3.89829 14.5531 3.02605C14.5531 2.15509 11.6118 1.44575 7.99717 1.44575ZM13.1639 5.42472C11.962 5.76592 10.0944 5.98526 7.99717 5.98526C5.89994 5.98526 4.03103 5.76592 2.83041 5.42472C1.95816 5.67228 1.43738 5.98526 1.43738 6.32518C1.43738 7.13329 4.37479 7.78619 7.99845 7.78619C11.6221 7.78619 14.5608 7.13201 14.5608 6.32518C14.5595 5.98526 14.0387 5.67228 13.1639 5.42472ZM7.99717 7.79389C6.2437 7.79389 4.5967 7.64124 3.35632 7.36546C2.11337 7.0884 1.42969 6.71898 1.42969 6.32518C1.42969 5.99296 1.91327 5.6787 2.82913 5.41831H2.83169C4.0849 5.7749 5.96792 5.97885 7.99717 5.97885C10.0264 5.97885 11.9082 5.7749 13.1626 5.41831H13.1652C14.0798 5.6787 14.5646 5.99296 14.5646 6.32518C14.5646 6.71898 13.881 7.08711 12.638 7.36418C11.3976 7.64124 9.75063 7.79389 7.99717 7.79389ZM2.83041 5.43113C2.38916 5.55684 2.04539 5.69665 1.80937 5.84673C1.56565 6.00066 1.44251 6.16228 1.44251 6.32518C1.44251 7.12688 4.38377 7.78106 7.99845 7.78106C11.6131 7.78106 14.5531 7.12816 14.5531 6.32518C14.5531 6.161 14.43 6.00066 14.1862 5.84545C13.9502 5.69537 13.6065 5.55684 13.1652 5.42985C11.9094 5.78644 10.0277 5.9904 7.99717 5.9904C5.96664 5.9904 4.0849 5.78644 2.83041 5.43113ZM13.1639 8.81877C11.962 9.15997 10.0944 9.37932 7.99717 9.37932C5.89994 9.37932 4.03103 9.15997 2.83041 8.81877C1.95688 9.06762 1.4361 9.3806 1.4361 9.71924C1.4361 10.5273 4.37351 11.1802 7.99717 11.1802C11.6208 11.1802 14.5595 10.5261 14.5595 9.71924C14.5595 9.3806 14.0387 9.06762 13.1639 8.81877ZM7.99717 11.1892C6.2437 11.1892 4.5967 11.0366 3.35632 10.7608C2.11337 10.4837 1.42969 10.113 1.42969 9.71924C1.42969 9.38701 1.91327 9.07275 2.82913 8.81236H2.83169C4.0849 9.16895 5.96664 9.3729 7.99717 9.3729C10.0277 9.3729 11.9082 9.16895 13.1626 8.81236H13.1652C14.0798 9.07275 14.5646 9.38701 14.5646 9.71924C14.5646 10.113 13.881 10.4812 12.638 10.7582C11.3976 11.0366 9.75063 11.1892 7.99717 11.1892ZM2.83041 8.82519C2.38787 8.95217 2.04539 9.09071 1.80937 9.24078C1.56565 9.39471 1.44251 9.55633 1.44251 9.71924C1.44251 10.5209 4.38377 11.1751 7.99845 11.1751C11.6131 11.1751 14.5531 10.5222 14.5531 9.71924C14.5531 9.55505 14.43 9.39471 14.1862 9.2395C13.9502 9.08942 13.6065 8.95089 13.1652 8.8239C11.9094 9.18178 10.0277 9.38573 7.99717 9.38573C5.96664 9.38573 4.0849 9.18178 2.83041 8.82519ZM13.1639 12.1987C11.962 12.5399 10.0944 12.7593 7.99717 12.7593C5.89994 12.7593 4.03103 12.5412 2.83041 12.1987C1.95816 12.4463 1.43738 12.7593 1.43738 13.0992C1.43738 13.9073 4.37479 14.5602 7.99845 14.5602C11.6221 14.5602 14.5608 13.906 14.5608 13.0992C14.5595 12.7605 14.0387 12.4476 13.1639 12.1987ZM7.99717 14.5692C6.2437 14.5692 4.5967 14.4165 3.35632 14.1407C2.11337 13.8637 1.42969 13.493 1.42969 13.0992C1.42969 12.767 1.91327 12.4527 2.82913 12.1923H2.83169C4.0849 12.5489 5.96792 12.7528 7.99717 12.7528C10.0264 12.7528 11.9082 12.5489 13.1626 12.1923H13.1652C14.0798 12.4527 14.5646 12.767 14.5646 13.0992C14.5646 13.493 13.881 13.8611 12.638 14.1382C11.3976 14.4165 9.75063 14.5692 7.99717 14.5692ZM2.83041 12.2051C2.38916 12.3308 2.04539 12.4707 1.80937 12.6207C1.56565 12.7747 1.44251 12.9363 1.44251 13.0992C1.44251 13.9022 4.38377 14.5551 7.99845 14.5551C11.6131 14.5551 14.5531 13.9022 14.5531 13.0992C14.5531 12.935 14.43 12.7747 14.1862 12.6194C13.9502 12.4694 13.6065 12.3308 13.1652 12.2038C11.9094 12.5604 10.0277 12.7657 7.99717 12.7657C5.96664 12.7657 4.0849 12.5604 2.83041 12.2051Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 1.6 MiB |
@ -0,0 +1,74 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
|
||||
import styles from './basic.less';
|
||||
import Nyfl from './components/nyfl';
|
||||
import Fgpsdsz from './components/fgpsdsz';
|
||||
import Jgfx from './components/jgfx';
|
||||
import Bmzstx from './components/bmzstx';
|
||||
import Nhtjcs from './components/nhtjcs';
|
||||
|
||||
|
||||
|
||||
const SafeMajorHazardList = () => {
|
||||
const [activeModule, setActiveModule] = useState('nyfl');
|
||||
|
||||
const handleModuleClick = (module) => {
|
||||
setActiveModule(module)
|
||||
}
|
||||
|
||||
|
||||
const renderModule = () => {
|
||||
switch (activeModule) {
|
||||
case 'nyfl':
|
||||
return <Nyfl />;
|
||||
case 'fgpsdsz':
|
||||
return <Fgpsdsz />;
|
||||
case 'jgtx':
|
||||
return <Jgfx />;
|
||||
case 'bmzstx':
|
||||
return <Bmzstx />;
|
||||
case 'nhtjcs':
|
||||
return <Nhtjcs />;
|
||||
default:
|
||||
return <Nyfl />;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.TopButton}>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "nyfl" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("nyfl")}
|
||||
>能源分类
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "fgpsdsz" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("fgpsdsz")}
|
||||
>峰谷平时段设置
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "jgtx" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("jgtx")}
|
||||
>价格体系
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "bmzstx" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("bmzstx")}
|
||||
>标煤折算体系
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "nhtjcs" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("nhtjcs")}
|
||||
>能耗统计参数
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{renderModule()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SafeMajorHazardList;
|
||||
@ -0,0 +1,69 @@
|
||||
.container {
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 89vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.TopButton {
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: 10px 30px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-left: 6px;
|
||||
|
||||
.TopButtonItem {
|
||||
background-color: transparent !important;
|
||||
color: #333333 !important;
|
||||
font-family: 'PingFang SC', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 100% !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 6px 10px !important;
|
||||
height: auto !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
position: relative !important;
|
||||
|
||||
&:hover {
|
||||
color: #333333 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: #2E4CD4 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(72, 81, 255, 1) !important;
|
||||
color: #fff !important;
|
||||
border-radius: 20px !important;
|
||||
padding: 6px 10px 10px !important;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 3px;
|
||||
width: 16.573974609375px;
|
||||
height: 2.615234375px;
|
||||
background-color: rgba(255, 255, 255, 0.52);
|
||||
border-radius: 15px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
// ======== 内容区域样式 ========
|
||||
flex: 1; // ======== 占据剩余空间 ========
|
||||
overflow-y: auto; // ======== 允许垂直滚动 ========
|
||||
padding: 0; // ======== 无内边距 ========
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,919 @@
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,160 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 2px 0 14px;
|
||||
}
|
||||
|
||||
.toolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbarRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
font-size: 12px;
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
width: 170px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #e7eaf2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
color: #b1b7c4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background-color: rgba(72, 81, 255, 1);
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.tableWrap {
|
||||
width: 100%;
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f8fb;
|
||||
color: #6d7383;
|
||||
font-weight: 500;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #2b2f3a;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #fafbff;
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
margin: 14px 0 0;
|
||||
}
|
||||
|
||||
.ant-pagination-total-text {
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.ant-pagination-options {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtn {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnInfo {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #13c2c2 !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnDanger {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #ff4d4f !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,458 @@
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.leftPanel {
|
||||
width: 200px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.leftTitle {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #2b2f3a;
|
||||
padding: 2px 10px 14px;
|
||||
}
|
||||
|
||||
.leftList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.leftItemBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
padding: 0 14px !important;
|
||||
border-radius: 999px !important;
|
||||
border: 1px solid #e8ecf3 !important;
|
||||
background: #fff !important;
|
||||
box-shadow: none !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: flex-start !important;
|
||||
color: #a5adbb !important;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(72, 81, 255, 0.35) !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.leftItemActive {
|
||||
background: rgba(72, 81, 255, 1) !important;
|
||||
border-color: rgba(72, 81, 255, 1) !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 10px 20px rgba(72, 81, 255, 0.18) !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
background: rgba(255, 255, 255, 0.26);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(72, 81, 255, 0.12);
|
||||
color: rgba(72, 81, 255, 1);
|
||||
flex: none;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconImg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.leftItemText {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.leftAddBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
border-radius: 999px !important;
|
||||
border: none !important;
|
||||
background: #f2f4f8 !important;
|
||||
color: #b7bdc9 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px 12px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.cardsRow {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.priceCard {
|
||||
flex: 1;
|
||||
min-height: 118px;
|
||||
padding: 14px 16px 12px;
|
||||
border-radius: 14px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.priceCard_peak {
|
||||
background: linear-gradient(135deg, #ff5e57 0%, #ffb1ae 100%);
|
||||
}
|
||||
|
||||
.priceCard_flat {
|
||||
background: linear-gradient(135deg, #ff9c3c 0%, #ffd8a8 100%);
|
||||
}
|
||||
|
||||
.priceCard_valley {
|
||||
background: linear-gradient(135deg, #4cc9ff 0%, #a7e9ff 100%);
|
||||
}
|
||||
|
||||
.priceCardCorner {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.35);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.priceCardTop {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.priceCardTitle {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.priceCardTags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-right: 28px;
|
||||
|
||||
:global {
|
||||
.ant-tag {
|
||||
margin: 0;
|
||||
// margin-right: 30px;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.26);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
padding: 0 10px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.priceCardBody {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.priceLeft {
|
||||
min-width: 96px;
|
||||
}
|
||||
|
||||
.priceLabel {
|
||||
font-size: 12px;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
.priceValue {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
line-height: 1.05;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.priceUnit {
|
||||
font-size: 12px;
|
||||
opacity: 0.92;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.priceRight {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.pricePeriodBox {
|
||||
width: 220px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.22);
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.pricePeriodLine {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
opacity: 0.96;
|
||||
}
|
||||
|
||||
.scheduleSection {
|
||||
flex: 1;
|
||||
background: #f7f9ff;
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.scheduleTopBar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 0 4px 10px;
|
||||
}
|
||||
|
||||
.scheduleTopLeft {
|
||||
width: 88px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.monthSwitcher {
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
color: #3757ff;
|
||||
|
||||
:global {
|
||||
.ant-btn {
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.monthText {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.periodRadios {
|
||||
:global {
|
||||
.ant-radio-wrapper {
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
margin-inline-end: 10px;
|
||||
}
|
||||
|
||||
.ant-radio-wrapper-checked {
|
||||
color: #3757ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scheduleGrid {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 10px 10px 12px;
|
||||
overflow: auto;
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.scheduleHeaderRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 0 0 10px;
|
||||
}
|
||||
|
||||
.scheduleHeaderLeft {
|
||||
width: 88px;
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
:global {
|
||||
.ant-radio-group {
|
||||
background: #eef3ff;
|
||||
border-radius: 999px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ant-radio-button-wrapper {
|
||||
border: none;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 12px;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ant-radio-button-wrapper-checked {
|
||||
background: #3a66ff;
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.timeHeader {
|
||||
flex: 1;
|
||||
min-width: 780px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
border-radius: 999px;
|
||||
background: #f7f9ff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: linear-gradient(to right, rgba(232, 236, 243, 0.9) 1px, transparent 1px);
|
||||
background-size: calc(100% / 13) 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.timeHeaderCell {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.scheduleBody {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.scheduleRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dayCell {
|
||||
width: 44px;
|
||||
text-align: center;
|
||||
color: #2b2f3a;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.weekCell {
|
||||
width: 44px;
|
||||
text-align: center;
|
||||
color: #8d93a3;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.timeArea {
|
||||
flex: 1;
|
||||
min-width: 780px;
|
||||
height: 28px;
|
||||
border-radius: 12px;
|
||||
background: #f7f9ff;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: linear-gradient(to right, rgba(232, 236, 243, 0.9) 1px, transparent 1px);
|
||||
background-size: calc(100% / 13) 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.timeBar {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.timeBar_peak {
|
||||
background: rgba(255, 111, 111, 0.92);
|
||||
}
|
||||
|
||||
.timeBar_flat {
|
||||
background: rgba(255, 177, 61, 0.92);
|
||||
}
|
||||
|
||||
.timeBar_valley {
|
||||
background: rgba(120, 205, 255, 0.92);
|
||||
}
|
||||
|
||||
.timeBarDim {
|
||||
opacity: 0.25;
|
||||
}
|
||||
@ -0,0 +1,253 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, message, Popconfirm, Select, Space, Table } from 'antd';
|
||||
import { DeleteOutlined, DownloadOutlined, EditOutlined, FileTextOutlined, PlusOutlined, UploadOutlined } from '@ant-design/icons';
|
||||
import styles from './jgfx.less';
|
||||
|
||||
const Jgfx = () => {
|
||||
const [filterA, setFilterA] = useState(undefined);
|
||||
const [filterB, setFilterB] = useState(undefined);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
|
||||
|
||||
const selectOptionsA = useMemo(
|
||||
() => [
|
||||
{ label: '千瓦时(kWh)', value: '千瓦时(kWh)' },
|
||||
{ label: '立方米(m³)', value: '立方米(m³)' },
|
||||
{ label: '吨(t)', value: '吨(t)' },
|
||||
{ label: 'kWh', value: 'kWh' },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const selectOptionsB = useMemo(
|
||||
() => [
|
||||
{ label: '电能', value: '电能' },
|
||||
{ label: '燃气', value: '燃气' },
|
||||
{ label: '水', value: '水' },
|
||||
{ label: '汽油', value: '汽油' },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const rows = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 1,
|
||||
energyType: '电能',
|
||||
unit: '千瓦时(kWh)',
|
||||
unitPrice: 0.5,
|
||||
priceUnit: '元',
|
||||
scope: 'xxxx',
|
||||
pricingUnit: 'xxxxxx',
|
||||
latestUpdateTime: '2025-12-02 03:56:02',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
energyType: '燃气',
|
||||
unit: '立方米(m³)',
|
||||
unitPrice: 2.5,
|
||||
priceUnit: '元',
|
||||
scope: 'xxxx',
|
||||
pricingUnit: 'xxxxxx',
|
||||
latestUpdateTime: '2025-11-22 11:56:50',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
energyType: '水',
|
||||
unit: '吨(t)',
|
||||
unitPrice: 1.2,
|
||||
priceUnit: '元',
|
||||
scope: 'xxxx',
|
||||
pricingUnit: 'xxxxxx',
|
||||
latestUpdateTime: '2025-12-04 21:12:20',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
energyType: '汽油',
|
||||
unit: 'kWh',
|
||||
unitPrice: 1.5,
|
||||
priceUnit: '元',
|
||||
scope: 'xxxx',
|
||||
pricingUnit: 'xxxxxx',
|
||||
latestUpdateTime: '2025-11-26 10:28:20',
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const tableData = useMemo(() => {
|
||||
return rows
|
||||
.filter((r) => (filterA ? r.unit === filterA : true))
|
||||
.filter((r) => (filterB ? r.energyType === filterB : true));
|
||||
}, [filterA, filterB, rows]);
|
||||
|
||||
const pagedData = useMemo(() => {
|
||||
const start = (pagination.current - 1) * pagination.pageSize;
|
||||
return tableData.slice(start, start + pagination.pageSize);
|
||||
}, [pagination.current, pagination.pageSize, tableData]);
|
||||
|
||||
const handleAdd = () => message.info('新增');
|
||||
const handleUpload = () => message.info('上传');
|
||||
const handleBatchDownload = () => message.info('批量下载');
|
||||
const handleQuery = () => message.info('查询');
|
||||
|
||||
const handleEdit = (record) => message.info(`编辑:${record.energyType}`);
|
||||
const handleView = (record) => message.info(`详情:${record.energyType}`);
|
||||
const handleDelete = (record) => message.success(`已删除:${record.energyType}`);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 70,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '能源类型',
|
||||
dataIndex: 'energyType',
|
||||
key: 'energyType',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '单价',
|
||||
dataIndex: 'unitPrice',
|
||||
key: 'unitPrice',
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
title: '价格单位',
|
||||
dataIndex: 'priceUnit',
|
||||
key: 'priceUnit',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '适用范围',
|
||||
dataIndex: 'scope',
|
||||
key: 'scope',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '定价单位',
|
||||
dataIndex: 'pricingUnit',
|
||||
key: 'pricingUnit',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
title: '最后更新时间',
|
||||
dataIndex: 'latestUpdateTime',
|
||||
key: 'latestUpdateTime',
|
||||
width: 210,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 140,
|
||||
align: 'center',
|
||||
render: (_, record) => (
|
||||
<Space size={14}>
|
||||
<Button
|
||||
className={styles.actionIconBtn}
|
||||
type="text"
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => handleEdit(record)}
|
||||
/>
|
||||
<Button
|
||||
className={styles.actionIconBtnInfo}
|
||||
type="text"
|
||||
icon={<FileTextOutlined />}
|
||||
onClick={() => handleView(record)}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="删除确认"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onConfirm={() => handleDelete(record)}
|
||||
>
|
||||
<Button className={styles.actionIconBtnDanger} type="text" icon={<DeleteOutlined />} />
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.toolbar}>
|
||||
<div className={styles.toolbarLeft}>
|
||||
<Space size={12}>
|
||||
<Button className={styles.primaryBtn} type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||
新增
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<UploadOutlined />} onClick={handleUpload}>
|
||||
上传
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<DownloadOutlined />} onClick={handleBatchDownload}>
|
||||
批量下载
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<div className={styles.toolbarRight}>
|
||||
<div className={styles.filterLabel}>筛选条件</div>
|
||||
<Space size={10}>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={selectOptionsA}
|
||||
value={filterA}
|
||||
allowClear
|
||||
onChange={setFilterA}
|
||||
/>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={selectOptionsB}
|
||||
value={filterB}
|
||||
allowClear
|
||||
onChange={setFilterB}
|
||||
/>
|
||||
<Button className={styles.queryBtn} onClick={handleQuery}>
|
||||
查询
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.tableWrap}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={pagedData}
|
||||
size="middle"
|
||||
pagination={{
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
total: tableData.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: false,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
position: ['bottomRight'],
|
||||
onChange: (current, pageSize) => setPagination({ current, pageSize }),
|
||||
}}
|
||||
rowSelection={{
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys),
|
||||
columnWidth: 44,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Jgfx;
|
||||
@ -0,0 +1,161 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px 12px;
|
||||
margin:15px 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 2px 0 14px;
|
||||
}
|
||||
|
||||
.toolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbarRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
font-size: 12px;
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
width: 170px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #e7eaf2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
color: #b1b7c4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background-color: rgba(72, 81, 255, 1);
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.tableWrap {
|
||||
width: 100%;
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f8fb;
|
||||
color: #6d7383;
|
||||
font-weight: 500;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #2b2f3a;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #fafbff;
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
margin: 14px 0 0;
|
||||
}
|
||||
|
||||
.ant-pagination-total-text {
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.ant-pagination-options {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtn {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnInfo {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #13c2c2 !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnDanger {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #ff4d4f !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import styles from './nhtj.less';
|
||||
|
||||
const Nhtj = () => {
|
||||
return (
|
||||
<div className={styles.placeholder}>待开发</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Nhtj;
|
||||
@ -0,0 +1,4 @@
|
||||
.placeholder {
|
||||
padding: 20px;
|
||||
color: #999;
|
||||
}
|
||||
@ -0,0 +1,260 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, message, Popconfirm, Select, Space, Table } from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined,
|
||||
UploadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import styles from './nyfl.less';
|
||||
import Component1 from '@/assets/basic_data/Component1.svg';
|
||||
import Component2 from '@/assets/basic_data/Component2.svg';
|
||||
import Component3 from '@/assets/basic_data/Component3.svg';
|
||||
|
||||
const Nhtjcs = () => {
|
||||
const [activeEnergyKey, setActiveEnergyKey] = useState('electric');
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [filterA, setFilterA] = useState(undefined);
|
||||
const [filterB, setFilterB] = useState(undefined);
|
||||
|
||||
const energyTypes = useMemo(
|
||||
() => [
|
||||
{ key: 'electric', label: '电能', icon: Component1 },
|
||||
{ key: 'water', label: '水', icon: Component2 },
|
||||
{ key: 'gas', label: '天然气', icon: Component3 },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const [rows, setRows] = useState(() => [
|
||||
{
|
||||
id: 1,
|
||||
energyKey: 'electric',
|
||||
powerType: '泵类系统',
|
||||
deviceCount: 28,
|
||||
statisticMethod: '智能电表',
|
||||
usageDesc: '用于油品输送的各类泵设备的耗电量。',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
energyKey: 'electric',
|
||||
powerType: '加热保温系统',
|
||||
deviceCount: 23,
|
||||
statisticMethod: '智能电表',
|
||||
usageDesc: '用于油罐加热和管道保温的电加热设备的耗电量。',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
energyKey: 'electric',
|
||||
powerType: '照明系统',
|
||||
deviceCount: 55,
|
||||
statisticMethod: '手动抄表',
|
||||
usageDesc: '油库区域内照明设备的耗电量,包括室内照明和室外照明。',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
energyKey: 'electric',
|
||||
powerType: '生活用电系统',
|
||||
deviceCount: 21,
|
||||
statisticMethod: '手动抄表',
|
||||
usageDesc: '油库工作人员生活区的用电,如宿舍、办公区等的耗电量。',
|
||||
},
|
||||
]);
|
||||
|
||||
const scopedRows = useMemo(() => {
|
||||
return rows.filter((row) => row.energyKey === activeEnergyKey);
|
||||
}, [activeEnergyKey, rows]);
|
||||
|
||||
const selectOptionsA = useMemo(() => {
|
||||
const values = Array.from(new Set(scopedRows.map((r) => r.powerType).filter(Boolean)));
|
||||
return values.map((value) => ({ label: value, value }));
|
||||
}, [scopedRows]);
|
||||
|
||||
const selectOptionsB = useMemo(() => {
|
||||
const values = Array.from(new Set(scopedRows.map((r) => r.statisticMethod).filter(Boolean)));
|
||||
return values.map((value) => ({ label: value, value }));
|
||||
}, [scopedRows]);
|
||||
|
||||
const tableData = useMemo(() => {
|
||||
return scopedRows
|
||||
.filter((row) => (filterA ? row.powerType === filterA : true))
|
||||
.filter((row) => (filterB ? row.statisticMethod === filterB : true));
|
||||
}, [filterA, filterB, scopedRows]);
|
||||
|
||||
const handleAdd = () => message.info('新增');
|
||||
const handleUpload = () => message.info('上传');
|
||||
const handleBatchDownload = () => message.info('批量下载');
|
||||
const handleQuery = () => message.info('查询');
|
||||
|
||||
const handleEdit = (record) => message.info(`编辑:${record.powerType}`);
|
||||
const handleDelete = (record) => message.success(`已删除:${record.powerType}`);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 70,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '耗电类型',
|
||||
dataIndex: 'powerType',
|
||||
key: 'powerType',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '设备数量',
|
||||
dataIndex: 'deviceCount',
|
||||
key: 'deviceCount',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '统计方式',
|
||||
dataIndex: 'statisticMethod',
|
||||
key: 'statisticMethod',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
title: '用途描述',
|
||||
dataIndex: 'usageDesc',
|
||||
key: 'usageDesc',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
render: (_, record) => (
|
||||
<Space size={14}>
|
||||
<Button
|
||||
className={styles.actionIconBtn}
|
||||
type="text"
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => handleEdit(record)}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="删除确认"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onConfirm={() => handleDelete(record)}
|
||||
>
|
||||
<Button className={styles.actionIconBtnDanger} type="text" icon={<DeleteOutlined />} />
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.leftPanel}>
|
||||
<div className={styles.leftTitle}>能源类型</div>
|
||||
|
||||
<div className={styles.leftList}>
|
||||
{energyTypes.map((item) => {
|
||||
const isActive = item.key === activeEnergyKey;
|
||||
return (
|
||||
<Button
|
||||
key={item.key}
|
||||
className={`${styles.leftItemBtn} ${isActive ? styles.leftItemActive : ''}`}
|
||||
onClick={() => {
|
||||
setActiveEnergyKey(item.key);
|
||||
setFilterA(undefined);
|
||||
setFilterB(undefined);
|
||||
}}
|
||||
>
|
||||
<span className={styles.leftIconCircle}>
|
||||
<img className={styles.leftIconImg} src={item.icon} alt={item.label} />
|
||||
</span>
|
||||
<span className={styles.leftItemText}>{item.label}</span>
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
|
||||
<Button className={styles.leftAddBtn} disabled icon={<PlusOutlined />}>
|
||||
添加分类
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.rightPanel}>
|
||||
<div className={styles.toolbar}>
|
||||
<div className={styles.toolbarLeft}>
|
||||
<Space size={12}>
|
||||
<Button
|
||||
className={styles.primaryBtn}
|
||||
type="primary"
|
||||
icon={<PlusOutlined />}
|
||||
onClick={handleAdd}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<UploadOutlined />} onClick={handleUpload}>
|
||||
上传
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<DownloadOutlined />} onClick={handleBatchDownload}>
|
||||
批量下载
|
||||
</Button>
|
||||
|
||||
|
||||
</Space>
|
||||
</div>
|
||||
<div className={styles.toolbarRight}>
|
||||
<div className={styles.filterLabel}>筛选条件</div>
|
||||
<Space size={10}>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={selectOptionsA}
|
||||
value={filterA}
|
||||
allowClear
|
||||
onChange={setFilterA}
|
||||
/>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={selectOptionsB}
|
||||
value={filterB}
|
||||
allowClear
|
||||
onChange={setFilterB}
|
||||
/>
|
||||
<Button className={styles.queryBtn} onClick={handleQuery}>
|
||||
查询
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.tableWrap}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={tableData}
|
||||
size="middle"
|
||||
pagination={{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: tableData.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: false,
|
||||
}}
|
||||
rowSelection={{
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys),
|
||||
columnWidth: 44,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Nhtjcs;
|
||||
@ -0,0 +1,245 @@
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
padding: 15px 10px
|
||||
}
|
||||
|
||||
.leftPanel {
|
||||
width: 200px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.leftTitle {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #2b2f3a;
|
||||
padding: 2px 10px 14px;
|
||||
}
|
||||
|
||||
.leftList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.leftItemBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
padding: 0 14px !important;
|
||||
border-radius: 999px !important;
|
||||
border: 1px solid #e8ecf3 !important;
|
||||
background: #fff !important;
|
||||
box-shadow: none !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: flex-start !important;
|
||||
color: #a5adbb !important;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(72, 81, 255, 0.35) !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.leftItemActive {
|
||||
background: rgba(72, 81, 255, 1) !important;
|
||||
border-color: rgba(72, 81, 255, 1) !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 10px 20px rgba(72, 81, 255, 0.18) !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
background: rgba(255, 255, 255, 0.26);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(72, 81, 255, 0.12);
|
||||
color: rgba(72, 81, 255, 1);
|
||||
flex: none;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconImg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.leftItemText {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.leftAddBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
border-radius: 999px !important;
|
||||
border: none !important;
|
||||
background: #f2f4f8 !important;
|
||||
color: #b7bdc9 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 2px 0 14px;
|
||||
}
|
||||
|
||||
.toolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbarRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
font-size: 12px;
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
width: 150px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #e7eaf2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
color: #b1b7c4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background-color: rgba(72, 81, 255, 1);
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.tableWrap {
|
||||
width: 100%;
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f8fb;
|
||||
color: #2b2f3a;
|
||||
// font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #2b2f3a;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #fafbff;
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
margin: 12px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtn {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnDanger {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #ff4d4f !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,295 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, message, Popconfirm, Select, Space, Switch, Table } from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined,
|
||||
UploadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import styles from './nyfl.less';
|
||||
import Component1 from '@/assets/basic_data/Component1.svg';
|
||||
import Component2 from '@/assets/basic_data/Component2.svg';
|
||||
import Component3 from '@/assets/basic_data/Component3.svg';
|
||||
|
||||
const Nyfl = () => {
|
||||
const [activeEnergyKey, setActiveEnergyKey] = useState('electric');
|
||||
const [filterUnit, setFilterUnit] = useState(undefined);
|
||||
const [filterCollection, setFilterCollection] = useState(undefined);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
|
||||
const energyTypes = useMemo(
|
||||
() => [
|
||||
{ key: 'electric', label: '电能', icon: Component1 },
|
||||
{ key: 'water', label: '水', icon: Component2 },
|
||||
{ key: 'gas', label: '天然气', icon: Component3 },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const unitOptions = useMemo(
|
||||
() => [
|
||||
{ label: 'kWh', value: 'kWh' },
|
||||
{ label: 'm³', value: 'm³' },
|
||||
{ label: 't', value: 't' },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const collectionOptions = useMemo(
|
||||
() => [
|
||||
{ label: '市电', value: '市电' },
|
||||
{ label: '光伏发电', value: '光伏发电' },
|
||||
{ label: '自备发电', value: '自备发电' },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const [rows, setRows] = useState(() => [
|
||||
{
|
||||
id: 1,
|
||||
energyKey: 'electric',
|
||||
energyType: '电能',
|
||||
unit: 'kWh',
|
||||
collectionType: '市电',
|
||||
enabled: true,
|
||||
latestUpdateTime: '2025-12-02 03:56:02',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
energyKey: 'electric',
|
||||
energyType: '电能',
|
||||
unit: 'kWh',
|
||||
collectionType: '光伏发电',
|
||||
enabled: false,
|
||||
latestUpdateTime: '2025-11-22 11:56:50',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
energyKey: 'electric',
|
||||
energyType: '电能',
|
||||
unit: 'kWh',
|
||||
collectionType: '自备发电',
|
||||
enabled: true,
|
||||
latestUpdateTime: '2025-12-04 21:12:20',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
energyKey: 'electric',
|
||||
energyType: '电能',
|
||||
unit: 'kWh',
|
||||
collectionType: 'xxxxxx',
|
||||
enabled: false,
|
||||
latestUpdateTime: '2025-11-26 10:28:20',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
energyKey: 'water',
|
||||
energyType: '水',
|
||||
unit: 'm³',
|
||||
collectionType: '市政供水',
|
||||
enabled: true,
|
||||
latestUpdateTime: '2025-12-06 09:12:10',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
energyKey: 'gas',
|
||||
energyType: '天然气',
|
||||
unit: 'm³',
|
||||
collectionType: '管网供气',
|
||||
enabled: true,
|
||||
latestUpdateTime: '2025-12-01 16:08:45',
|
||||
},
|
||||
]);
|
||||
|
||||
const tableData = useMemo(() => {
|
||||
return rows
|
||||
.filter((row) => row.energyKey === activeEnergyKey)
|
||||
.filter((row) => (filterUnit ? row.unit === filterUnit : true))
|
||||
.filter((row) => (filterCollection ? row.collectionType === filterCollection : true));
|
||||
}, [activeEnergyKey, filterCollection, filterUnit, rows]);
|
||||
|
||||
const handleAdd = () => message.info('新增');
|
||||
const handleUpload = () => message.info('上传');
|
||||
const handleBatchDownload = () => message.info('批量下载');
|
||||
const handleQuery = () => message.info('查询');
|
||||
|
||||
const handleEdit = (record) => message.info(`编辑:${record.energyType}`);
|
||||
const handleDelete = (record) => message.success(`已删除:${record.energyType}`);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 70,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '能源类型',
|
||||
dataIndex: 'energyType',
|
||||
key: 'energyType',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '采集类型',
|
||||
dataIndex: 'collectionType',
|
||||
key: 'collectionType',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'enabled',
|
||||
key: 'enabled',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
render: (value, record) => (
|
||||
<Switch
|
||||
size="small"
|
||||
checked={Boolean(value)}
|
||||
onChange={(checked) => {
|
||||
setRows((prev) =>
|
||||
prev.map((item) => (item.id === record.id ? { ...item, enabled: checked } : item)),
|
||||
);
|
||||
message.success(checked ? '已启用' : '已停用');
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '最后更新时间',
|
||||
dataIndex: 'latestUpdateTime',
|
||||
key: 'latestUpdateTime',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
render: (_, record) => (
|
||||
<Space size={14}>
|
||||
<Button
|
||||
className={styles.actionIconBtn}
|
||||
type="text"
|
||||
icon={<EditOutlined />}
|
||||
onClick={() => handleEdit(record)}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="删除确认"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onConfirm={() => handleDelete(record)}
|
||||
>
|
||||
<Button className={styles.actionIconBtnDanger} type="text" icon={<DeleteOutlined />} />
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.leftPanel}>
|
||||
<div className={styles.leftTitle}>能源类型</div>
|
||||
|
||||
<div className={styles.leftList}>
|
||||
{energyTypes.map((item) => {
|
||||
const isActive = item.key === activeEnergyKey;
|
||||
return (
|
||||
<Button
|
||||
key={item.key}
|
||||
className={`${styles.leftItemBtn} ${isActive ? styles.leftItemActive : ''}`}
|
||||
onClick={() => setActiveEnergyKey(item.key)}
|
||||
>
|
||||
<span className={styles.leftIconCircle}>
|
||||
<img className={styles.leftIconImg} src={item.icon} alt={item.label} />
|
||||
</span>
|
||||
<span className={styles.leftItemText}>{item.label}</span>
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
|
||||
<Button className={styles.leftAddBtn} disabled icon={<PlusOutlined />}>
|
||||
添加分类
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.rightPanel}>
|
||||
<div className={styles.toolbar}>
|
||||
<div className={styles.toolbarLeft}>
|
||||
<Space size={12}>
|
||||
<Button className={styles.primaryBtn} type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||
新增
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<UploadOutlined />} onClick={handleUpload}>
|
||||
上传
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} icon={<DownloadOutlined />} onClick={handleBatchDownload}>
|
||||
批量下载
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<div className={styles.toolbarRight}>
|
||||
<div className={styles.filterLabel}>筛选条件</div>
|
||||
<Space size={10}>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={unitOptions}
|
||||
value={filterUnit}
|
||||
allowClear
|
||||
onChange={setFilterUnit}
|
||||
/>
|
||||
<Select
|
||||
className={styles.filterSelect}
|
||||
placeholder="请选择"
|
||||
options={collectionOptions}
|
||||
value={filterCollection}
|
||||
allowClear
|
||||
onChange={setFilterCollection}
|
||||
/>
|
||||
<Button className={styles.queryBtn} onClick={handleQuery}>
|
||||
查询
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.tableWrap}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={tableData}
|
||||
size="middle"
|
||||
pagination={{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: tableData.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: false,
|
||||
}}
|
||||
rowSelection={{
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys),
|
||||
columnWidth: 44,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Nyfl;
|
||||
@ -0,0 +1,245 @@
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
padding: 15px 10px
|
||||
}
|
||||
|
||||
.leftPanel {
|
||||
width: 200px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.leftTitle {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #2b2f3a;
|
||||
padding: 2px 10px 14px;
|
||||
}
|
||||
|
||||
.leftList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.leftItemBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
padding: 0 14px !important;
|
||||
border-radius: 999px !important;
|
||||
border: 1px solid #e8ecf3 !important;
|
||||
background: #fff !important;
|
||||
box-shadow: none !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: flex-start !important;
|
||||
color: #a5adbb !important;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(72, 81, 255, 0.35) !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.leftItemActive {
|
||||
background: rgba(72, 81, 255, 1) !important;
|
||||
border-color: rgba(72, 81, 255, 1) !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 10px 20px rgba(72, 81, 255, 0.18) !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
background: rgba(255, 255, 255, 0.26);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconCircle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(72, 81, 255, 0.12);
|
||||
color: rgba(72, 81, 255, 1);
|
||||
flex: none;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leftIconImg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.leftItemText {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.leftAddBtn {
|
||||
width: 100%;
|
||||
height: 40px !important;
|
||||
border-radius: 999px !important;
|
||||
border: none !important;
|
||||
background: #f2f4f8 !important;
|
||||
color: #b7bdc9 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 2px 0 14px;
|
||||
}
|
||||
|
||||
.toolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbarRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
font-size: 12px;
|
||||
color: #8d93a3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.filterSelect {
|
||||
width: 150px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #e7eaf2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-placeholder {
|
||||
color: #b1b7c4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background-color: rgba(72, 81, 255, 1);
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.tableWrap {
|
||||
width: 100%;
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f8fb;
|
||||
color: #6d7383;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #2b2f3a;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #fafbff;
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
margin: 12px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtn {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: rgba(72, 81, 255, 1) !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionIconBtnDanger {
|
||||
padding: 0 !important;
|
||||
height: 24px !important;
|
||||
color: #ff4d4f !important;
|
||||
|
||||
:global {
|
||||
.anticon {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
import { useEffect } from 'react'
|
||||
import { Button, Col, Form, Input, Row } from 'antd'
|
||||
import { UpOutlined, SearchOutlined, RedoOutlined } from '@ant-design/icons'
|
||||
import SelectDeptTree from '@/components/SelectDeptTree'
|
||||
import SelectOrganTree from '@/components/SelectOrganTree'
|
||||
import style from '@/global.less'
|
||||
|
||||
const { Item: FormItem } = Form
|
||||
let getDeptTreeBySelectTree
|
||||
let getOrganTreeBySelectTree
|
||||
|
||||
const StaffSheetRenderAdvancedForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { dispatch, handleSearch, handleFormReset, toggleForm, selectDeptTree, selectOrganTree, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
deptname: params?.deptname,
|
||||
orgname: params?.orgname,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
// if (getDeptTreeBySelectTree) {
|
||||
// values.dept_code = getDeptTreeBySelectTree.dept_code
|
||||
// values.deptname = getDeptTreeBySelectTree.title
|
||||
// }
|
||||
|
||||
if (getOrganTreeBySelectTree) {
|
||||
values.org_code = getOrganTreeBySelectTree.org_code
|
||||
values.orgname = getOrganTreeBySelectTree.title
|
||||
}
|
||||
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
const selectedDeptTreeValue = (deptRecord) => {
|
||||
getDeptTreeBySelectTree = deptRecord
|
||||
}
|
||||
|
||||
const selectedOrganTreeValue = (orgRecord) => {
|
||||
getOrganTreeBySelectTree = orgRecord
|
||||
}
|
||||
|
||||
const parentDeptTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectDeptTree: selectDeptTree,
|
||||
selectedDeptTreeValue: selectedDeptTreeValue
|
||||
}
|
||||
|
||||
const parentOrganTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectOrganTree: selectOrganTree,
|
||||
selectedOrganTreeValue: selectedOrganTreeValue
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名' name='user_name'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名称' name='user_name_cn'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='机构代码' name='orgname'>
|
||||
<SelectOrganTree {...parentOrganTreeMethod} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={{md: 8, lg: 24, xl: 48}} className={style.searchBox}>
|
||||
{/*<Col md={8} sm={24}>*/}
|
||||
{/* <FormItem label='部门名称' name='deptname'>*/}
|
||||
{/* <SelectDeptTree placeholder={'请选择部门'} {...parentDeptTreeMethod} />*/}
|
||||
{/* </FormItem>*/}
|
||||
{/*</Col>*/}
|
||||
|
||||
<Col md={24} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
|
||||
<a onClick={() => toggleForm(form)}>
|
||||
收起 <UpOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderAdvancedForm
|
||||
@ -0,0 +1,81 @@
|
||||
import { useEffect } from 'react'
|
||||
import {Button, Col, Form, Input, Row, DatePicker, Select} from 'antd'
|
||||
import {DownOutlined, RedoOutlined, SearchOutlined} from '@ant-design/icons'
|
||||
import style from '@/global.less'
|
||||
import dayjs from 'dayjs'
|
||||
const { Item: FormItem } = Form
|
||||
|
||||
const StaffSheetRenderSimpleForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { handleSearch, handleFormReset, toggleForm, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='我的查询条件' name='wdcxtj'>
|
||||
<Select
|
||||
placeholder='请选择'
|
||||
options={[]}
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='日期' name='rq' rules={[{ required: true, message: '请选择日期!' }]}>
|
||||
<DatePicker defaultValue={dayjs('2025-04-10', 'YYYY-MM-DD')} format='YYYY-MM-DD' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工作地点' name='gzdd'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工号' name='gh'>
|
||||
<Input placeholder='请输入' defaultValue="123456"/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='名称' name='gh'>
|
||||
<Input placeholder='请输入'/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderSimpleForm
|
||||
@ -0,0 +1,319 @@
|
||||
import { deleteByPrimaryKeyForProUser, selectByPrimaryKeyForProUser, insertForProUser, updateForProUser, deleteByMapForProUser,updateByMapForProUser, getOneForProUser,getAllForProUser,queryPageForProUser, countForProUser, insertBatchForProUser, deleteBatchForProUser,updateBatchForProUser, resetPwdForProUser } from '@/services/system/api_prouser';
|
||||
|
||||
export default {
|
||||
namespace: 'safemajorha33zard',
|
||||
|
||||
state: {
|
||||
params: {},
|
||||
data: {
|
||||
list: [],
|
||||
pagination: {},
|
||||
},
|
||||
},
|
||||
|
||||
effects: {
|
||||
*delete_by_primarykey_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'deleteByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*select_by_primarykey_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(selectByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'selectByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*insert_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertForProUser, payload)
|
||||
yield put({
|
||||
type: 'insertForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*update_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateForProUser, payload)
|
||||
yield put({
|
||||
type: 'updateForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*delete_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_one_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getOneForProUser, payload);
|
||||
yield put({
|
||||
type: 'getOneForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_all_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getAllForProUser, payload);
|
||||
yield put({
|
||||
type: 'getAllForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*query_page_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const newParams = payload?.resetFlag ? payload : {...params, ...payload};
|
||||
yield put({
|
||||
type: 'setQueryPageByParams',
|
||||
payload: newParams,
|
||||
});
|
||||
const response = yield call(queryPageForProUser, newParams);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*count_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(countForProUser, payload);
|
||||
yield put({
|
||||
type: 'countForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*insert_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'insertBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*delete_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*resetpwd_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(resetPwdForProUser, payload);
|
||||
yield put({
|
||||
type: 'resetPwdForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
},
|
||||
|
||||
reducers: {
|
||||
setQueryPageByParams(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
params: {...payload},
|
||||
};
|
||||
},
|
||||
deleteByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
selectByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getOneForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getAllForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
queryPageForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
countForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
resetPwdForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,74 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
|
||||
import styles from './basic.less';
|
||||
|
||||
import Cjgl from './components/Cjgl';
|
||||
import Zdcj from './components/Zdcj';
|
||||
import Sglr from './components/Sglr';
|
||||
import Sjjy from './components/Sjjy';
|
||||
import Cjrz from './components/Cjrz';
|
||||
|
||||
|
||||
const SafeMajorHazardList = () => {
|
||||
const [activeModule, setActiveModule] = useState('Cjgl');
|
||||
|
||||
const handleModuleClick = (module) => {
|
||||
setActiveModule(module)
|
||||
}
|
||||
|
||||
|
||||
const renderModule = () => {
|
||||
switch (activeModule) {
|
||||
case 'Cjgl':
|
||||
return <Cjgl />;
|
||||
case 'Zdcj':
|
||||
return <Zdcj />;
|
||||
case 'Sglr':
|
||||
return <Sglr />;
|
||||
case 'Sjjy':
|
||||
return <Sjjy />;
|
||||
case 'Cjrz':
|
||||
return <Cjrz />;
|
||||
default:
|
||||
return <Cjgl />;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.TopButton}>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "Cjgl" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("Cjgl")}
|
||||
>采集概览
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "Zdcj" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("Zdcj")}
|
||||
>自动采集
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "Sglr" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("Sglr")}
|
||||
>手工录入
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "Sjjy" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("Sjjy")}
|
||||
>数据校验
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "Cjrz" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("Cjrz")}
|
||||
>采集日志
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{renderModule()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SafeMajorHazardList;
|
||||
@ -0,0 +1,69 @@
|
||||
.container {
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 89vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.TopButton {
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: 10px 30px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-left: 6px;
|
||||
|
||||
.TopButtonItem {
|
||||
background-color: transparent !important;
|
||||
color: #333333 !important;
|
||||
font-family: 'PingFang SC', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 100% !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 6px 10px !important;
|
||||
height: auto !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
position: relative !important;
|
||||
|
||||
&:hover {
|
||||
color: #333333 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: #2E4CD4 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(72, 81, 255, 1) !important;
|
||||
color: #fff !important;
|
||||
border-radius: 20px !important;
|
||||
padding: 6px 10px 10px !important;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 3px;
|
||||
width: 16.573974609375px;
|
||||
height: 2.615234375px;
|
||||
background-color: rgba(255, 255, 255, 0.52);
|
||||
border-radius: 15px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
// ======== 内容区域样式 ========
|
||||
flex: 1; // ======== 占据剩余空间 ========
|
||||
overflow-y: auto; // ======== 允许垂直滚动 ========
|
||||
padding: 0; // ======== 无内边距 ========
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,603 @@
|
||||
.container {
|
||||
padding: 12px;
|
||||
background: linear-gradient(180deg, rgba(241, 248, 255, 1) 0%, rgba(246, 250, 255, 1) 100%);
|
||||
min-height: 100%;
|
||||
|
||||
.overview {
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
margin-bottom: 12px;
|
||||
|
||||
.overviewHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.overviewTitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.overviewIcon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.16), rgba(99, 102, 241, 0.10));
|
||||
color: #2f66ff;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.overviewText {
|
||||
.overviewMainTitle {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.overviewSubTitle {
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
line-height: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overviewTime {
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
}
|
||||
|
||||
.overviewCards {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.metricCard {
|
||||
border-radius: 14px;
|
||||
padding: 12px;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
box-shadow: 0 10px 20px rgba(15, 23, 42, 0.05);
|
||||
transition: transform 150ms ease, box-shadow 150ms ease;
|
||||
height: 78px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 14px 30px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.metricInner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.metricIcon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.metricContent {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
|
||||
.metricValue {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.3px;
|
||||
color: #0f172a;
|
||||
line-height: 26px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.metricSuffix {
|
||||
margin-left: 2px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
}
|
||||
|
||||
.metricLabel {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.metricCard_primary {
|
||||
.metricIcon {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.18), rgba(37, 99, 235, 0.10));
|
||||
color: #2563eb;
|
||||
}
|
||||
}
|
||||
|
||||
.metricCard_success {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.12), rgba(255, 255, 255, 0.85));
|
||||
|
||||
.metricIcon {
|
||||
background: linear-gradient(135deg, rgba(34, 197, 94, 0.18), rgba(34, 197, 94, 0.08));
|
||||
color: #16a34a;
|
||||
}
|
||||
}
|
||||
|
||||
.metricCard_warning {
|
||||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.12), rgba(255, 255, 255, 0.85));
|
||||
|
||||
.metricIcon {
|
||||
background: linear-gradient(135deg, rgba(245, 158, 11, 0.18), rgba(245, 158, 11, 0.08));
|
||||
color: #d97706;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.panelCard {
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
|
||||
|
||||
:global(.ant-card-head) {
|
||||
border-bottom: 1px solid rgba(226, 232, 240, 0.6);
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
:global(.ant-card-body) {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.panelTitle {
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.iconBtn {
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
}
|
||||
|
||||
.middle {
|
||||
.realtimeSummary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.summaryItem {
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
background: rgba(248, 250, 252, 0.8);
|
||||
|
||||
.summaryValue {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
line-height: 26px;
|
||||
|
||||
.summaryUnit {
|
||||
margin-left: 2px;
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.summaryLabel {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.summaryItem_primary {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.10), rgba(248, 250, 252, 0.85));
|
||||
}
|
||||
|
||||
.summaryItem_danger {
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.10), rgba(248, 250, 252, 0.85));
|
||||
|
||||
.summaryValue {
|
||||
color: #ef4444;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.deviceListWrap {
|
||||
max-height: 420px;
|
||||
overflow: auto;
|
||||
padding-right: 4px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(148, 163, 184, 0.5);
|
||||
border-radius: 8px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.deviceList {
|
||||
:global(.ant-list-item) {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px dashed rgba(226, 232, 240, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.deviceItem {
|
||||
.deviceRow {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.deviceMain {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.deviceTitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 4px;
|
||||
|
||||
.deviceName {
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.deviceId {
|
||||
border-radius: 999px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.deviceMeta {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
color: rgba(15, 23, 42, 0.72);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.deviceStatus {
|
||||
flex: 0 0 auto;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyBody {
|
||||
display: grid;
|
||||
grid-template-columns: 150px 1fr;
|
||||
gap: 12px;
|
||||
min-height: 360px;
|
||||
|
||||
.anomalyTabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.anomalyTab {
|
||||
border-radius: 12px;
|
||||
padding: 12px 12px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
background: rgba(248, 250, 252, 0.7);
|
||||
cursor: pointer;
|
||||
transition: background 150ms ease, transform 150ms ease, box-shadow 150ms ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 10px 20px rgba(15, 23, 42, 0.06);
|
||||
}
|
||||
|
||||
.anomalyTabTitleRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.anomalyTabTitle {
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.anomalyTabDesc {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
|
||||
.anomalyBadge {
|
||||
:global(.ant-badge-count) {
|
||||
background: #2563eb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyTabActive {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.18), rgba(255, 255, 255, 0.7));
|
||||
border-color: rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
|
||||
.anomalyContent {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.anomalyCards {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 6px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(148, 163, 184, 0.5);
|
||||
border-radius: 8px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyCard {
|
||||
min-width: 260px;
|
||||
max-width: 300px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0 10px 22px rgba(15, 23, 42, 0.06);
|
||||
overflow: hidden;
|
||||
|
||||
.anomalyCardHeader {
|
||||
padding: 10px 12px;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.18), rgba(255, 255, 255, 0.5));
|
||||
border-bottom: 1px solid rgba(226, 232, 240, 0.7);
|
||||
|
||||
.anomalyCardHeaderLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.anomalyCardHeaderIcon {
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.anomalyCardHeaderTitle {
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyCardBody {
|
||||
padding: 10px 12px;
|
||||
|
||||
.anomalyField {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px dashed rgba(226, 232, 240, 0.8);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyLabel {
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.anomalyValue {
|
||||
color: rgba(15, 23, 42, 0.82);
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.anomalyCardFooter {
|
||||
padding: 6px 12px 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
.donutSection {
|
||||
display: grid;
|
||||
grid-template-columns: 220px 1fr;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
|
||||
.donut {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 999px;
|
||||
background: var(--donut-bg);
|
||||
position: relative;
|
||||
margin: 4px 0;
|
||||
box-shadow: inset 0 0 0 10px rgba(255, 255, 255, 0.85);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -10px;
|
||||
border-radius: 999px;
|
||||
background: radial-gradient(circle at 30% 20%, rgba(59, 130, 246, 0.22), transparent 55%),
|
||||
radial-gradient(circle at 70% 80%, rgba(34, 197, 94, 0.18), transparent 55%);
|
||||
filter: blur(10px);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.donutInner {
|
||||
position: absolute;
|
||||
inset: 42px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 999px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
z-index: 1;
|
||||
|
||||
.donutCenterTitle {
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
|
||||
.donutCenterValue {
|
||||
margin-top: 2px;
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.donutLegends {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
.legendItem {
|
||||
display: grid;
|
||||
grid-template-columns: 10px 1fr auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
background: rgba(248, 250, 252, 0.7);
|
||||
}
|
||||
|
||||
.legendDot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.legendName {
|
||||
color: rgba(15, 23, 42, 0.75);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.legendValue {
|
||||
color: rgba(15, 23, 42, 0.85);
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.storageSection {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 220px;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
|
||||
.storageLegend {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
.storageLegendItem {
|
||||
display: grid;
|
||||
grid-template-columns: 10px 1fr auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
background: rgba(248, 250, 252, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
.storageRings {
|
||||
position: relative;
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.storageRingLayer {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
:global(.ant-progress-text) {
|
||||
font-weight: 900;
|
||||
color: rgba(15, 23, 42, 0.75);
|
||||
}
|
||||
}
|
||||
|
||||
.storageRingLayer_mid {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.storageRingLayer_inner {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.middle {
|
||||
.anomalyBody {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
.donutSection {
|
||||
grid-template-columns: 1fr;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.storageSection {
|
||||
grid-template-columns: 1fr;
|
||||
justify-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,325 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, Checkbox, DatePicker, message, Popconfirm, Select, Space, Table } from 'antd';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
EyeOutlined,
|
||||
PlusOutlined,
|
||||
ReloadOutlined,
|
||||
SearchOutlined,
|
||||
UploadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import styles from './Cjrz.less';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const Cjrz = () => {
|
||||
const [levelAll, setLevelAll] = useState(true);
|
||||
const [levels, setLevels] = useState(['信息', '警告']);
|
||||
const [deviceType, setDeviceType] = useState('全部');
|
||||
const [meterAll, setMeterAll] = useState(true);
|
||||
const [meterTypes, setMeterTypes] = useState(['电表']);
|
||||
const [taskAll, setTaskAll] = useState(true);
|
||||
const [taskTypes, setTaskTypes] = useState(['自动']);
|
||||
const [timeRangePreset, setTimeRangePreset] = useState('本月');
|
||||
|
||||
const [timeRange, setTimeRange] = useState(null);
|
||||
|
||||
const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
|
||||
|
||||
const levelOptions = useMemo(() => ['信息', '警告', '错误', '严重'], []);
|
||||
const meterOptions = useMemo(() => ['电表', '水表', '燃气表'], []);
|
||||
const taskOptions = useMemo(() => ['自动', '手工'], []);
|
||||
|
||||
const rows = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 1,
|
||||
time: '2025-11-25 01:07:46',
|
||||
level: '信息',
|
||||
device: '变压器1#',
|
||||
opType: '自动采集',
|
||||
detail: 'xxxxxxxxxxxxxxxxxxxx',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
time: '2025-11-29 01:15:57',
|
||||
level: '信息',
|
||||
device: 'SCADA',
|
||||
opType: '自动采集',
|
||||
detail: 'xxxxxxxxxxxxxxxxxxxx',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
time: '2025-11-30 02:21:41',
|
||||
level: '信息',
|
||||
device: '燃气表B',
|
||||
opType: '自动采集',
|
||||
detail: 'xxxxxxxxxxxxxxxxxxxx',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
time: '2025-12-04 20:10:27',
|
||||
level: '警告',
|
||||
device: '水表A',
|
||||
opType: '手动录入',
|
||||
detail: 'xxxxxxxxxxxxxxxxxxxx',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
time: '2025-12-12 04:35:20',
|
||||
level: '警告',
|
||||
device: '数据校验',
|
||||
opType: '手动录入',
|
||||
detail: 'xxxxxxxxxxxxxxxxxxxx',
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const filteredRows = useMemo(() => {
|
||||
return rows
|
||||
.filter((r) => (levelAll ? true : levels.includes(r.level)))
|
||||
.filter((r) => (deviceType === '全部' ? true : r.device.includes(deviceType)))
|
||||
.filter((r) => (meterAll ? true : meterTypes.some((m) => r.device.includes(m))))
|
||||
.filter((r) => (taskAll ? true : taskTypes.some((t) => r.opType.includes(t))));
|
||||
}, [deviceType, levelAll, levels, meterAll, meterTypes, rows, taskAll, taskTypes]);
|
||||
|
||||
const handleQuery = () => message.info('查询');
|
||||
const handleReset = () => {
|
||||
setLevelAll(true);
|
||||
setLevels(['信息', '警告']);
|
||||
setDeviceType('全部');
|
||||
setMeterAll(true);
|
||||
setMeterTypes(['电表']);
|
||||
setTaskAll(true);
|
||||
setTaskTypes(['自动']);
|
||||
setTimeRangePreset('本月');
|
||||
setTimeRange(null);
|
||||
setPagination({ current: 1, pageSize: pagination.pageSize });
|
||||
message.success('已重置');
|
||||
};
|
||||
|
||||
const handleAdd = () => message.info('新增');
|
||||
const handleUpload = () => message.info('上传');
|
||||
const handleBatchDownload = () => message.info('批量下载');
|
||||
|
||||
const handleView = (record) => message.info(`查看:${record.device}`);
|
||||
const handleDelete = (record) => message.success(`已删除:${record.device}`);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 70,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'time',
|
||||
key: 'time',
|
||||
sorter: (a, b) => String(a.time).localeCompare(String(b.time)),
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '级别',
|
||||
dataIndex: 'level',
|
||||
key: 'level',
|
||||
width: 90,
|
||||
},
|
||||
{
|
||||
title: '设备',
|
||||
dataIndex: 'device',
|
||||
key: 'device',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '操作类型',
|
||||
dataIndex: 'opType',
|
||||
key: 'opType',
|
||||
width: 130,
|
||||
filters: [
|
||||
{ text: '自动采集', value: '自动采集' },
|
||||
{ text: '手动录入', value: '手动录入' },
|
||||
],
|
||||
onFilter: (value, record) => String(record.opType).includes(String(value)),
|
||||
},
|
||||
{
|
||||
title: '详情',
|
||||
dataIndex: 'detail',
|
||||
key: 'detail',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 110,
|
||||
align: 'center',
|
||||
render: (_, record) => (
|
||||
<Space size={12} className={styles.actionCell}>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
className={styles.actionBtnView}
|
||||
icon={<EyeOutlined />}
|
||||
onClick={() => handleView(record)}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="确认删除这条记录?"
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
onConfirm={() => handleDelete(record)}
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
className={styles.actionBtnDelete}
|
||||
icon={<DeleteOutlined />}
|
||||
/>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.panel}>
|
||||
<div className={styles.rowTop}>
|
||||
<div className={styles.filters}>
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterLabel}>日志级别</div>
|
||||
<div className={styles.checkGroup}>
|
||||
<Checkbox checked={levelAll} onChange={(e) => setLevelAll(e.target.checked)}>
|
||||
全部
|
||||
</Checkbox>
|
||||
<Checkbox.Group
|
||||
options={levelOptions}
|
||||
value={levels}
|
||||
disabled={levelAll}
|
||||
onChange={(next) => setLevels(next)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterLabel}>设备类型</div>
|
||||
<Select
|
||||
className={styles.pillSelect}
|
||||
value={deviceType}
|
||||
onChange={setDeviceType}
|
||||
options={[
|
||||
{ label: '全部', value: '全部' },
|
||||
{ label: '电表', value: '电表' },
|
||||
{ label: '水表', value: '水表' },
|
||||
{ label: '燃气表', value: '燃气表' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterLabel}>电表</div>
|
||||
<div className={styles.checkGroup}>
|
||||
<Checkbox checked={meterAll} onChange={(e) => setMeterAll(e.target.checked)}>
|
||||
全部
|
||||
</Checkbox>
|
||||
<Checkbox.Group
|
||||
options={meterOptions}
|
||||
value={meterTypes}
|
||||
disabled={meterAll}
|
||||
onChange={(next) => setMeterTypes(next)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.filterItem}>
|
||||
<div className={styles.filterLabel}>任务状态</div>
|
||||
<div className={styles.checkGroup}>
|
||||
<Checkbox checked={taskAll} onChange={(e) => setTaskAll(e.target.checked)}>
|
||||
全部
|
||||
</Checkbox>
|
||||
<Checkbox.Group
|
||||
options={taskOptions}
|
||||
value={taskTypes}
|
||||
disabled={taskAll}
|
||||
onChange={(next) => setTaskTypes(next)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.topActions}>
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<SearchOutlined />}
|
||||
className={styles.queryBtn}
|
||||
onClick={handleQuery}
|
||||
>
|
||||
查询
|
||||
</Button>
|
||||
<Button icon={<ReloadOutlined />} className={styles.resetBtn} onClick={handleReset}>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.rowSecond}>
|
||||
<div className={styles.toolbarLeft}>
|
||||
<Button type="primary" icon={<PlusOutlined />} className={styles.primaryBtn} onClick={handleAdd}>
|
||||
新增
|
||||
</Button>
|
||||
<Button icon={<UploadOutlined />} className={styles.ghostBtn} onClick={handleUpload}>
|
||||
上传
|
||||
</Button>
|
||||
<Button icon={<DownloadOutlined />} className={styles.ghostBtn} onClick={handleBatchDownload}>
|
||||
批量下载
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={styles.timeRange}>
|
||||
<div className={styles.filterLabel}>时间范围</div>
|
||||
<Select
|
||||
className={styles.presetSelect}
|
||||
value={timeRangePreset}
|
||||
onChange={setTimeRangePreset}
|
||||
options={[
|
||||
{ label: '本月', value: '本月' },
|
||||
{ label: '本周', value: '本周' },
|
||||
{ label: '今日', value: '今日' },
|
||||
]}
|
||||
/>
|
||||
<RangePicker
|
||||
className={styles.pillRange}
|
||||
value={timeRange}
|
||||
onChange={setTimeRange}
|
||||
placeholder={['开始日期', '结束日期']}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.tableWrap}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={filteredRows}
|
||||
pagination={{
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
total: filteredRows.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: false,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
onChange: (current, pageSize) => setPagination({ current, pageSize }),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Cjrz;
|
||||
@ -0,0 +1,277 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px 16px;
|
||||
margin: 15px 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: #f6f8fc;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.rowTop {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px 22px;
|
||||
}
|
||||
|
||||
.filterItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.checkGroup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
:global {
|
||||
.ant-checkbox-wrapper {
|
||||
margin-inline-start: 0 !important;
|
||||
font-size: 12px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.ant-checkbox-group {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topActions {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.rowSecond {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.toolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.timeRange {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.pillSelect {
|
||||
width: 120px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #dfe5f2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
font-size: 12px;
|
||||
color: #111827;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.presetSelect {
|
||||
width: 92px;
|
||||
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #dfe5f2 !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
box-shadow: none !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.ant-select-selection-item {
|
||||
font-size: 12px;
|
||||
color: #111827;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pillRange {
|
||||
width: 300px;
|
||||
|
||||
:global {
|
||||
.ant-picker {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
border-color: #dfe5f2 !important;
|
||||
box-shadow: none !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
.ant-picker-input > input {
|
||||
font-size: 12px;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.ant-picker-separator {
|
||||
color: #9ca3af;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.queryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 18px !important;
|
||||
box-shadow: none !important;
|
||||
background: #3b5bfd;
|
||||
border-color: #3b5bfd;
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resetBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 18px !important;
|
||||
border: 1px solid #dfe5f2 !important;
|
||||
background: #fff !important;
|
||||
color: #4b5563 !important;
|
||||
box-shadow: none !important;
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background: #3b5bfd;
|
||||
border-color: #3b5bfd;
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #dfe5f2 !important;
|
||||
background: #fff !important;
|
||||
color: #374151 !important;
|
||||
box-shadow: none !important;
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tableWrap {
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f3f5f9;
|
||||
color: #6b7280;
|
||||
font-weight: 500;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #111827;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #f7f9ff;
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
margin: 14px 0 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ant-pagination-total-text {
|
||||
color: #6b7280;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionCell {
|
||||
:global {
|
||||
.ant-btn {
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actionBtnView {
|
||||
color: #22c55e;
|
||||
}
|
||||
|
||||
.actionBtnDelete {
|
||||
color: #ef4444;
|
||||
}
|
||||
@ -0,0 +1,362 @@
|
||||
.container {
|
||||
padding: 16px;
|
||||
background: #f6f8fc;
|
||||
min-height: calc(89vh - 0px);
|
||||
|
||||
.grid {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: #ffffff;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 6px 18px rgba(12, 24, 52, 0.06);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panelHeader {
|
||||
padding: 14px 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
|
||||
.panelTitle {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1f2a37;
|
||||
}
|
||||
|
||||
.headerBtn {
|
||||
border-radius: 18px;
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.leftBody {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
padding: 14px;
|
||||
|
||||
.formWrap {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding-right: 6px;
|
||||
|
||||
.form {
|
||||
:global {
|
||||
.ant-form-item {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.ant-radio-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.ant-radio-button-wrapper {
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.fullWidth {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.valueRow {
|
||||
width: 100%;
|
||||
|
||||
.valueSelect {
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.valueInput {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.addBtn {
|
||||
width: 36px;
|
||||
border-radius: 10px;
|
||||
border-color: #c7d2fe;
|
||||
color: #2f54eb;
|
||||
}
|
||||
}
|
||||
|
||||
.uploader {
|
||||
border-radius: 12px;
|
||||
|
||||
:global {
|
||||
.ant-upload-drag {
|
||||
border-radius: 12px;
|
||||
border: 1px dashed #cbd5e1;
|
||||
background: #fbfcfe;
|
||||
}
|
||||
.ant-upload-drag:hover {
|
||||
border-color: #5b7cff;
|
||||
}
|
||||
}
|
||||
|
||||
.uploadInner {
|
||||
padding: 14px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.uploadIcon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 12px;
|
||||
background: rgba(91, 124, 255, 0.12);
|
||||
color: #2f54eb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.uploadBtn {
|
||||
border-radius: 18px;
|
||||
height: 30px;
|
||||
padding: 0 14px;
|
||||
}
|
||||
|
||||
.uploadHint {
|
||||
font-size: 12px;
|
||||
color: #94a3b8;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.formActions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding-top: 6px;
|
||||
|
||||
.primaryAction {
|
||||
border-radius: 18px;
|
||||
height: 34px;
|
||||
padding: 0 22px;
|
||||
background: #4b63ff;
|
||||
}
|
||||
|
||||
.secondaryAction {
|
||||
border-radius: 18px;
|
||||
height: 34px;
|
||||
padding: 0 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.templateWrap {
|
||||
width: 200px;
|
||||
border-left: 1px solid #eef2f7;
|
||||
padding-left: 12px;
|
||||
|
||||
.templateTitle {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #6b7280;
|
||||
padding: 2px 2px 10px;
|
||||
}
|
||||
|
||||
.templateList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
max-height: 560px;
|
||||
overflow: auto;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.templateItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 10px;
|
||||
border-radius: 12px;
|
||||
background: #f7faff;
|
||||
border: 1px solid #eef2f7;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: #c7d2fe;
|
||||
background: #f3f6ff;
|
||||
}
|
||||
|
||||
.templateIcon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 10px;
|
||||
background: rgba(47, 84, 235, 0.12);
|
||||
color: #2f54eb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.templateText {
|
||||
font-size: 13px;
|
||||
color: #334155;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pendingRow {
|
||||
padding: 14px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 12px;
|
||||
|
||||
.pendingCard {
|
||||
border-radius: 14px;
|
||||
background: #f5f9ff;
|
||||
border: 1px solid #cfe0ff;
|
||||
box-shadow: none;
|
||||
|
||||
:global {
|
||||
.ant-card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.pendingDevice {
|
||||
font-size: 12px;
|
||||
color: #475569;
|
||||
|
||||
.deviceLink {
|
||||
color: #2f54eb;
|
||||
}
|
||||
}
|
||||
|
||||
.pendingMeta {
|
||||
padding-top: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
|
||||
.metaLine {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.metaKey {
|
||||
width: 66px;
|
||||
color: #94a3b8;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.metaVal {
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.statusDot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #22c55e;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.statusText {
|
||||
color: #16a34a;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pendingActions {
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.detailBtn {
|
||||
width: 100%;
|
||||
border-radius: 18px;
|
||||
height: 32px;
|
||||
background: #4b63ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.todaySection {
|
||||
padding: 0 14px 14px;
|
||||
|
||||
.todayHeader {
|
||||
padding: 8px 0 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.todayTitle {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1f2a37;
|
||||
}
|
||||
|
||||
.todayRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.todayCount {
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.auditBtn {
|
||||
border-radius: 18px;
|
||||
height: 32px;
|
||||
background: #4b63ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f2f6ff;
|
||||
color: #475569;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.paginationWrap {
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.container {
|
||||
.leftBody {
|
||||
flex-direction: column;
|
||||
|
||||
.templateWrap {
|
||||
width: 100%;
|
||||
border-left: none;
|
||||
border-top: 1px solid #eef2f7;
|
||||
padding-left: 0;
|
||||
padding-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.pendingRow {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,290 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Form,
|
||||
Input,
|
||||
InputNumber,
|
||||
Pagination,
|
||||
Radio,
|
||||
Select,
|
||||
Space,
|
||||
Switch,
|
||||
Table,
|
||||
Tabs,
|
||||
Typography,
|
||||
message,
|
||||
} from 'antd';
|
||||
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import styles from './Sjjy.less';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
const ruleTypeOptions = [
|
||||
{ label: '一致性', value: '一致性' },
|
||||
{ label: '完整性', value: '完整性' },
|
||||
{ label: '准确性', value: '准确性' },
|
||||
{ label: '其他', value: '其他' },
|
||||
];
|
||||
|
||||
const deviceOptions = [
|
||||
{ label: 'Lucy', value: 'Lucy' },
|
||||
{ label: '变压器1#', value: '变压器1#' },
|
||||
{ label: '水表A', value: '水表A' },
|
||||
];
|
||||
|
||||
const paramKeyOptions = [
|
||||
{ label: '容错率', value: '容错率' },
|
||||
{ label: '检查周期', value: '检查周期' },
|
||||
{ label: '异常级别', value: '异常级别' },
|
||||
];
|
||||
|
||||
const seedRules = Array.from({ length: 23 }).map((_, idx) => ({
|
||||
id: idx + 1,
|
||||
name: '电表巡检检查',
|
||||
type: '一致性',
|
||||
enabled: true,
|
||||
lastRun: '2025-10-15 14:30:00',
|
||||
}));
|
||||
|
||||
const Sjjy = () => {
|
||||
const [activeTab, setActiveTab] = useState('rules');
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(8);
|
||||
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const [rules, setRules] = useState(() => seedRules);
|
||||
const [activeRuleId, setActiveRuleId] = useState(() => seedRules[0]?.id);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const activeRule = useMemo(() => rules.find((r) => r.id === activeRuleId) || rules[0], [activeRuleId, rules]);
|
||||
|
||||
const pageData = useMemo(() => {
|
||||
const start = (page - 1) * pageSize;
|
||||
return rules.slice(start, start + pageSize);
|
||||
}, [page, pageSize, rules]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeRule) return;
|
||||
form.setFieldsValue({
|
||||
ruleName: activeRule.name,
|
||||
ruleType: activeRule.type,
|
||||
device: 'Lucy',
|
||||
ruleLogic: '内容信息',
|
||||
params: [
|
||||
{ key: '容错率', value: 3 },
|
||||
{ key: '检查周期', value: 3 },
|
||||
{ key: '异常级别', value: 3 },
|
||||
],
|
||||
autoHandle: 'useLast',
|
||||
notify: 'system',
|
||||
});
|
||||
}, [activeRule, form]);
|
||||
|
||||
const handleAdd = () => message.info('新增');
|
||||
const handleBatchToggle = () => message.info('批量启用/禁用');
|
||||
const handleTemplate = () => message.info('规则模板');
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: '规则名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 220,
|
||||
render: (val) => <span className={styles.ruleNameCell}>{val}</span>,
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'enabled',
|
||||
key: 'enabled',
|
||||
width: 110,
|
||||
render: (val, record) => (
|
||||
<Switch
|
||||
checked={val}
|
||||
onChange={(checked) => {
|
||||
setRules((prev) => prev.map((r) => (r.id === record.id ? { ...r, enabled: checked } : r)));
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '最后执行',
|
||||
dataIndex: 'lastRun',
|
||||
key: 'lastRun',
|
||||
width: 180,
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.leftPanel}>
|
||||
<Tabs
|
||||
className={styles.topTabs}
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
items={[
|
||||
{ key: 'rules', label: '校验规则' },
|
||||
{ key: 'test', label: '测试规则' },
|
||||
{ key: 'template', label: '规则模板' },
|
||||
]}
|
||||
/>
|
||||
|
||||
{activeTab !== 'rules' ? (
|
||||
<div className={styles.placeholder}>模块待开发</div>
|
||||
) : (
|
||||
<>
|
||||
<div className={styles.leftToolbar}>
|
||||
<div className={styles.leftToolbarLeft}>
|
||||
<Space size={10}>
|
||||
<Button className={styles.primaryBtn} type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||
新增
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} onClick={handleBatchToggle}>
|
||||
批量启用/禁用
|
||||
</Button>
|
||||
<Button className={styles.ghostBtn} onClick={handleTemplate}>
|
||||
规则模板
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<div className={styles.leftToolbarRight}>
|
||||
<Typography.Text className={styles.counterText}>当前生效规则(条): 12</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.listWrap}>
|
||||
<Table
|
||||
rowKey="id"
|
||||
size="middle"
|
||||
columns={columns}
|
||||
dataSource={pageData}
|
||||
pagination={false}
|
||||
rowSelection={{
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys),
|
||||
columnWidth: 44,
|
||||
}}
|
||||
rowClassName={(record) => (record.id === activeRuleId ? styles.rowActive : '')}
|
||||
onRow={(record) => ({
|
||||
onClick: () => setActiveRuleId(record.id),
|
||||
})}
|
||||
/>
|
||||
|
||||
<div className={styles.paginationBar}>
|
||||
<Pagination
|
||||
current={page}
|
||||
pageSize={pageSize}
|
||||
total={rules.length}
|
||||
showSizeChanger={false}
|
||||
onChange={(nextPage, nextPageSize) => {
|
||||
setPage(nextPage);
|
||||
if (nextPageSize && nextPageSize !== pageSize) setPageSize(nextPageSize);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.rightPanel}>
|
||||
<div className={styles.rightHeader}>
|
||||
<div className={styles.rightTitle}>详情</div>
|
||||
<Button
|
||||
type="link"
|
||||
icon={<EditOutlined />}
|
||||
className={styles.editBtn}
|
||||
onClick={() => setEditing((v) => !v)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={styles.detailBody}>
|
||||
<Form
|
||||
form={form}
|
||||
className={styles.detailForm}
|
||||
layout="horizontal"
|
||||
labelCol={{ flex: '92px' }}
|
||||
wrapperCol={{ flex: 'auto' }}
|
||||
colon={false}
|
||||
disabled={!editing}
|
||||
>
|
||||
<Form.Item label="规则名称" name="ruleName">
|
||||
<Input placeholder="请输入" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="规则类型" name="ruleType">
|
||||
<Radio.Group options={ruleTypeOptions} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="适用设备" name="device">
|
||||
<Select placeholder="请选择" options={deviceOptions} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="校验逻辑" name="ruleLogic">
|
||||
<TextArea rows={3} placeholder="请输入" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="参数设置">
|
||||
<Form.List name="params">
|
||||
{(fields) => (
|
||||
<div className={styles.paramList}>
|
||||
{fields.map((field, index) => (
|
||||
<div key={field.key} className={styles.paramRow}>
|
||||
<div className={styles.paramLabel}>{`参数${index + 1}`}</div>
|
||||
<Space.Compact className={styles.paramCompact}>
|
||||
<Form.Item name={[field.name, 'key']} noStyle>
|
||||
<Select options={paramKeyOptions} className={styles.paramSelect} />
|
||||
</Form.Item>
|
||||
<Form.Item name={[field.name, 'value']} noStyle>
|
||||
<InputNumber min={0} className={styles.paramNumber} />
|
||||
</Form.Item>
|
||||
</Space.Compact>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Form.List>
|
||||
</Form.Item>
|
||||
|
||||
<Divider className={styles.divider} />
|
||||
<div className={styles.sectionTitle}>异常处理</div>
|
||||
|
||||
<Form.Item label="自动处理" name="autoHandle">
|
||||
<Radio.Group
|
||||
options={[
|
||||
{ label: '使用上次有效值', value: 'useLast' },
|
||||
{ label: '重新设置', value: 'reset' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="报警方式" name="notify">
|
||||
<Radio.Group
|
||||
options={[
|
||||
{ label: '系统提示', value: 'system' },
|
||||
{ label: '邮件', value: 'email' },
|
||||
{ label: '短信', value: 'sms' },
|
||||
{ label: 'APP推送', value: 'app' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sjjy;
|
||||
@ -0,0 +1,248 @@
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 560px;
|
||||
padding: 12px;
|
||||
background: linear-gradient(180deg, rgba(241, 248, 255, 1) 0%, rgba(246, 250, 255, 1) 100%);
|
||||
}
|
||||
|
||||
.leftPanel {
|
||||
flex: 1.15;
|
||||
min-width: 560px;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
flex: 1;
|
||||
min-width: 420px;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
border-radius: 14px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.06);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.topTabs {
|
||||
padding: 6px 14px 0;
|
||||
|
||||
:global {
|
||||
.ant-tabs-nav {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ant-tabs-tab {
|
||||
padding: 12px 2px 10px;
|
||||
font-weight: 600;
|
||||
color: rgba(15, 23, 42, 0.65);
|
||||
}
|
||||
|
||||
.ant-tabs-tab-active {
|
||||
.ant-tabs-tab-btn {
|
||||
color: rgba(15, 23, 42, 0.95);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
padding: 18px 16px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
|
||||
.leftToolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 14px 10px;
|
||||
}
|
||||
|
||||
.leftToolbarLeft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.leftToolbarRight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.counterText {
|
||||
font-size: 12px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
|
||||
.primaryBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
box-shadow: none !important;
|
||||
background-color: rgba(72, 81, 255, 1);
|
||||
|
||||
:global {
|
||||
.ant-btn-icon {
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ghostBtn {
|
||||
height: 32px !important;
|
||||
border-radius: 999px !important;
|
||||
padding: 0 16px !important;
|
||||
border: 1px solid #e7eaf2 !important;
|
||||
background: #fff !important;
|
||||
color: #5b6070 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.listWrap {
|
||||
padding: 0 14px 12px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.paginationBar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 12px 0 0;
|
||||
}
|
||||
|
||||
.rowActive {
|
||||
:global {
|
||||
td {
|
||||
background: rgba(72, 81, 255, 0.06) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ruleNameCell {
|
||||
color: rgba(15, 23, 42, 0.9);
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-table {
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th {
|
||||
background: #f7f8fb;
|
||||
color: #6d7383;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
color: #2b2f3a;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: #fafbff;
|
||||
}
|
||||
}
|
||||
|
||||
.rightHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid rgba(226, 232, 240, 0.6);
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.rightTitle {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: rgba(15, 23, 42, 0.95);
|
||||
}
|
||||
|
||||
.editBtn {
|
||||
padding: 0 4px !important;
|
||||
}
|
||||
|
||||
.detailBody {
|
||||
padding: 12px 16px 16px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.detailForm {
|
||||
:global {
|
||||
.ant-form-item {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.ant-form-item-label > label {
|
||||
color: rgba(15, 23, 42, 0.65);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ant-input,
|
||||
.ant-input-affix-wrapper,
|
||||
.ant-select-selector {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 8px 0 12px !important;
|
||||
}
|
||||
|
||||
.sectionTitle {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: rgba(15, 23, 42, 0.85);
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.paramList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.paramRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.paramLabel {
|
||||
width: 52px;
|
||||
color: rgba(15, 23, 42, 0.55);
|
||||
}
|
||||
|
||||
.paramCompact {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.paramSelect {
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.paramNumber {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.leftPanel,
|
||||
.rightPanel {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
.container {
|
||||
padding: 16px;
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
import { useEffect } from 'react'
|
||||
import { Button, Col, Form, Input, Row } from 'antd'
|
||||
import { UpOutlined, SearchOutlined, RedoOutlined } from '@ant-design/icons'
|
||||
import SelectDeptTree from '@/components/SelectDeptTree'
|
||||
import SelectOrganTree from '@/components/SelectOrganTree'
|
||||
import style from '@/global.less'
|
||||
|
||||
const { Item: FormItem } = Form
|
||||
let getDeptTreeBySelectTree
|
||||
let getOrganTreeBySelectTree
|
||||
|
||||
const StaffSheetRenderAdvancedForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { dispatch, handleSearch, handleFormReset, toggleForm, selectDeptTree, selectOrganTree, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
deptname: params?.deptname,
|
||||
orgname: params?.orgname,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
// if (getDeptTreeBySelectTree) {
|
||||
// values.dept_code = getDeptTreeBySelectTree.dept_code
|
||||
// values.deptname = getDeptTreeBySelectTree.title
|
||||
// }
|
||||
|
||||
if (getOrganTreeBySelectTree) {
|
||||
values.org_code = getOrganTreeBySelectTree.org_code
|
||||
values.orgname = getOrganTreeBySelectTree.title
|
||||
}
|
||||
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
const selectedDeptTreeValue = (deptRecord) => {
|
||||
getDeptTreeBySelectTree = deptRecord
|
||||
}
|
||||
|
||||
const selectedOrganTreeValue = (orgRecord) => {
|
||||
getOrganTreeBySelectTree = orgRecord
|
||||
}
|
||||
|
||||
const parentDeptTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectDeptTree: selectDeptTree,
|
||||
selectedDeptTreeValue: selectedDeptTreeValue
|
||||
}
|
||||
|
||||
const parentOrganTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectOrganTree: selectOrganTree,
|
||||
selectedOrganTreeValue: selectedOrganTreeValue
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名' name='user_name'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名称' name='user_name_cn'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='机构代码' name='orgname'>
|
||||
<SelectOrganTree {...parentOrganTreeMethod} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={{md: 8, lg: 24, xl: 48}} className={style.searchBox}>
|
||||
{/*<Col md={8} sm={24}>*/}
|
||||
{/* <FormItem label='部门名称' name='deptname'>*/}
|
||||
{/* <SelectDeptTree placeholder={'请选择部门'} {...parentDeptTreeMethod} />*/}
|
||||
{/* </FormItem>*/}
|
||||
{/*</Col>*/}
|
||||
|
||||
<Col md={24} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
|
||||
<a onClick={() => toggleForm(form)}>
|
||||
收起 <UpOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderAdvancedForm
|
||||
@ -0,0 +1,81 @@
|
||||
import { useEffect } from 'react'
|
||||
import {Button, Col, Form, Input, Row, DatePicker, Select} from 'antd'
|
||||
import {DownOutlined, RedoOutlined, SearchOutlined} from '@ant-design/icons'
|
||||
import style from '@/global.less'
|
||||
import dayjs from 'dayjs'
|
||||
const { Item: FormItem } = Form
|
||||
|
||||
const StaffSheetRenderSimpleForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { handleSearch, handleFormReset, toggleForm, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='我的查询条件' name='wdcxtj'>
|
||||
<Select
|
||||
placeholder='请选择'
|
||||
options={[]}
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='日期' name='rq' rules={[{ required: true, message: '请选择日期!' }]}>
|
||||
<DatePicker defaultValue={dayjs('2025-04-10', 'YYYY-MM-DD')} format='YYYY-MM-DD' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工作地点' name='gzdd'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工号' name='gh'>
|
||||
<Input placeholder='请输入' defaultValue="123456"/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='名称' name='gh'>
|
||||
<Input placeholder='请输入'/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderSimpleForm
|
||||
@ -0,0 +1,319 @@
|
||||
import { deleteByPrimaryKeyForProUser, selectByPrimaryKeyForProUser, insertForProUser, updateForProUser, deleteByMapForProUser,updateByMapForProUser, getOneForProUser,getAllForProUser,queryPageForProUser, countForProUser, insertBatchForProUser, deleteBatchForProUser,updateBatchForProUser, resetPwdForProUser } from '@/services/system/api_prouser';
|
||||
|
||||
export default {
|
||||
namespace: 'dataCollection',
|
||||
|
||||
state: {
|
||||
params: {},
|
||||
data: {
|
||||
list: [],
|
||||
pagination: {},
|
||||
},
|
||||
},
|
||||
|
||||
effects: {
|
||||
*delete_by_primarykey_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'deleteByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*select_by_primarykey_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(selectByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'selectByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*insert_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertForProUser, payload)
|
||||
yield put({
|
||||
type: 'insertForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*update_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateForProUser, payload)
|
||||
yield put({
|
||||
type: 'updateForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*delete_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_one_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getOneForProUser, payload);
|
||||
yield put({
|
||||
type: 'getOneForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_all_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getAllForProUser, payload);
|
||||
yield put({
|
||||
type: 'getAllForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*query_page_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const newParams = payload?.resetFlag ? payload : {...params, ...payload};
|
||||
yield put({
|
||||
type: 'setQueryPageByParams',
|
||||
payload: newParams,
|
||||
});
|
||||
const response = yield call(queryPageForProUser, newParams);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*count_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(countForProUser, payload);
|
||||
yield put({
|
||||
type: 'countForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*insert_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'insertBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*delete_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*resetpwd_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(resetPwdForProUser, payload);
|
||||
yield put({
|
||||
type: 'resetPwdForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
},
|
||||
|
||||
reducers: {
|
||||
setQueryPageByParams(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
params: {...payload},
|
||||
};
|
||||
},
|
||||
deleteByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
selectByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getOneForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getAllForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
queryPageForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
countForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
resetPwdForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,69 @@
|
||||
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';
|
||||
|
||||
|
||||
|
||||
const SafeMajorHazardList = () => {
|
||||
const [activeModule, setActiveModule] = useState('organization');
|
||||
|
||||
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 />;
|
||||
default:
|
||||
return <ResponsibilityImplementation />;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.TopButton}>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "organization" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("organization")}
|
||||
>组织机构管理
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "license" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("license")}
|
||||
>资质证照管理
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "firefighting" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("firefighting")}
|
||||
>设备设施管理
|
||||
</Button>
|
||||
<Button
|
||||
className={`${styles.TopButtonItem} ${activeModule === "other" ? styles.active : ""}`}
|
||||
onClick={() => handleModuleClick("other")}
|
||||
>建筑消防与器材管理
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{renderModule()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SafeMajorHazardList;
|
||||
@ -0,0 +1,66 @@
|
||||
.container {
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 89vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.TopButton {
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
padding: 10px 30px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-left: 6px;
|
||||
|
||||
.TopButtonItem {
|
||||
background-color: transparent !important;
|
||||
color: #333333 !important;
|
||||
font-family: 'PingFang SC', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 100% !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 6px 10px !important;
|
||||
height: auto !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
position: relative !important;
|
||||
|
||||
&:hover {
|
||||
color: #333333 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: #2E4CD4 !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #2E4CD4 !important;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background-color: #2E4CD4;
|
||||
border-radius: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
// ======== 内容区域样式 ========
|
||||
flex: 1; // ======== 占据剩余空间 ========
|
||||
overflow-y: auto; // ======== 允许垂直滚动 ========
|
||||
padding: 0; // ======== 无内边距 ========
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,498 @@
|
||||
.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,919 @@
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,113 @@
|
||||
import { useEffect } from 'react'
|
||||
import { Button, Col, Form, Input, Row } from 'antd'
|
||||
import { UpOutlined, SearchOutlined, RedoOutlined } from '@ant-design/icons'
|
||||
import SelectDeptTree from '@/components/SelectDeptTree'
|
||||
import SelectOrganTree from '@/components/SelectOrganTree'
|
||||
import style from '@/global.less'
|
||||
|
||||
const { Item: FormItem } = Form
|
||||
let getDeptTreeBySelectTree
|
||||
let getOrganTreeBySelectTree
|
||||
|
||||
const StaffSheetRenderAdvancedForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { dispatch, handleSearch, handleFormReset, toggleForm, selectDeptTree, selectOrganTree, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
deptname: params?.deptname,
|
||||
orgname: params?.orgname,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
// if (getDeptTreeBySelectTree) {
|
||||
// values.dept_code = getDeptTreeBySelectTree.dept_code
|
||||
// values.deptname = getDeptTreeBySelectTree.title
|
||||
// }
|
||||
|
||||
if (getOrganTreeBySelectTree) {
|
||||
values.org_code = getOrganTreeBySelectTree.org_code
|
||||
values.orgname = getOrganTreeBySelectTree.title
|
||||
}
|
||||
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
const selectedDeptTreeValue = (deptRecord) => {
|
||||
getDeptTreeBySelectTree = deptRecord
|
||||
}
|
||||
|
||||
const selectedOrganTreeValue = (orgRecord) => {
|
||||
getOrganTreeBySelectTree = orgRecord
|
||||
}
|
||||
|
||||
const parentDeptTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectDeptTree: selectDeptTree,
|
||||
selectedDeptTreeValue: selectedDeptTreeValue
|
||||
}
|
||||
|
||||
const parentOrganTreeMethod = {
|
||||
dispatch: dispatch,
|
||||
selectOrganTree: selectOrganTree,
|
||||
selectedOrganTreeValue: selectedOrganTreeValue
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名' name='user_name'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='用户名称' name='user_name_cn'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label='机构代码' name='orgname'>
|
||||
<SelectOrganTree {...parentOrganTreeMethod} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={{md: 8, lg: 24, xl: 48}} className={style.searchBox}>
|
||||
{/*<Col md={8} sm={24}>*/}
|
||||
{/* <FormItem label='部门名称' name='deptname'>*/}
|
||||
{/* <SelectDeptTree placeholder={'请选择部门'} {...parentDeptTreeMethod} />*/}
|
||||
{/* </FormItem>*/}
|
||||
{/*</Col>*/}
|
||||
|
||||
<Col md={24} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
|
||||
<a onClick={() => toggleForm(form)}>
|
||||
收起 <UpOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderAdvancedForm
|
||||
@ -0,0 +1,81 @@
|
||||
import { useEffect } from 'react'
|
||||
import {Button, Col, Form, Input, Row, DatePicker, Select} from 'antd'
|
||||
import {DownOutlined, RedoOutlined, SearchOutlined} from '@ant-design/icons'
|
||||
import style from '@/global.less'
|
||||
import dayjs from 'dayjs'
|
||||
const { Item: FormItem } = Form
|
||||
|
||||
const StaffSheetRenderSimpleForm = (props) => {
|
||||
const [form] = Form.useForm()
|
||||
const { handleSearch, handleFormReset, toggleForm, params } = props
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
user_name: params?.user_name,
|
||||
user_name_cn: params?.user_name_cn,
|
||||
})
|
||||
}, [params])
|
||||
|
||||
const onFinish = values => {
|
||||
handleSearch(values)
|
||||
}
|
||||
|
||||
const myHandleFormReset = () => {
|
||||
form.resetFields()
|
||||
handleFormReset()
|
||||
}
|
||||
|
||||
return (
|
||||
<Form form={form} onFinish={onFinish} layout='inline'>
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='我的查询条件' name='wdcxtj'>
|
||||
<Select
|
||||
placeholder='请选择'
|
||||
options={[]}
|
||||
/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='日期' name='rq' rules={[{ required: true, message: '请选择日期!' }]}>
|
||||
<DatePicker defaultValue={dayjs('2025-04-10', 'YYYY-MM-DD')} format='YYYY-MM-DD' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工作地点' name='gzdd'>
|
||||
<Input placeholder='请输入' />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='工号' name='gh'>
|
||||
<Input placeholder='请输入' defaultValue="123456"/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<FormItem label='名称' name='gh'>
|
||||
<Input placeholder='请输入'/>
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={4} sm={24}>
|
||||
<div className={style.searchBtn}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
查询
|
||||
</Button>
|
||||
|
||||
<Button onClick={myHandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default StaffSheetRenderSimpleForm
|
||||
@ -0,0 +1,319 @@
|
||||
import { deleteByPrimaryKeyForProUser, selectByPrimaryKeyForProUser, insertForProUser, updateForProUser, deleteByMapForProUser,updateByMapForProUser, getOneForProUser,getAllForProUser,queryPageForProUser, countForProUser, insertBatchForProUser, deleteBatchForProUser,updateBatchForProUser, resetPwdForProUser } from '@/services/system/api_prouser';
|
||||
|
||||
export default {
|
||||
namespace: 'safemajo333hazard',
|
||||
|
||||
state: {
|
||||
params: {},
|
||||
data: {
|
||||
list: [],
|
||||
pagination: {},
|
||||
},
|
||||
},
|
||||
|
||||
effects: {
|
||||
*delete_by_primarykey_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'deleteByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*select_by_primarykey_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(selectByPrimaryKeyForProUser, payload)
|
||||
yield put({
|
||||
type: 'selectByPrimaryKeyForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*insert_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertForProUser, payload)
|
||||
yield put({
|
||||
type: 'insertForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*update_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateForProUser, payload)
|
||||
yield put({
|
||||
type: 'updateForProUser',
|
||||
payload: response
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
callback && callback(response)
|
||||
return
|
||||
}
|
||||
|
||||
const params = yield select(state => state.prouser.params)
|
||||
const responseData = yield call(queryPageForProUser, params)
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responseData
|
||||
})
|
||||
|
||||
if (callback) callback(response)
|
||||
},
|
||||
*delete_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_by_map_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateByMapForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateByMapForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_one_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getOneForProUser, payload);
|
||||
yield put({
|
||||
type: 'getOneForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*get_all_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getAllForProUser, payload);
|
||||
yield put({
|
||||
type: 'getAllForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*query_page_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const newParams = payload?.resetFlag ? payload : {...params, ...payload};
|
||||
yield put({
|
||||
type: 'setQueryPageByParams',
|
||||
payload: newParams,
|
||||
});
|
||||
const response = yield call(queryPageForProUser, newParams);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*count_for_prouser({ payload, callback }, { call, put }) {
|
||||
const response = yield call(countForProUser, payload);
|
||||
yield put({
|
||||
type: 'countForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*insert_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(insertBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'insertBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*delete_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(deleteBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'deleteBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*update_batch_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(updateBatchForProUser, payload);
|
||||
yield put({
|
||||
type: 'updateBatchForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
*resetpwd_for_prouser({ payload, callback }, { select, call, put }) {
|
||||
const response = yield call(resetPwdForProUser, payload);
|
||||
yield put({
|
||||
type: 'resetPwdForProUser',
|
||||
payload: response,
|
||||
});
|
||||
|
||||
const params = yield select(state => state.prouser.params);
|
||||
const responsedata = yield call(queryPageForProUser, params);
|
||||
yield put({
|
||||
type: 'queryPageForProUser',
|
||||
payload: responsedata,
|
||||
});
|
||||
|
||||
if (callback) callback(response);
|
||||
},
|
||||
},
|
||||
|
||||
reducers: {
|
||||
setQueryPageByParams(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
params: {...payload},
|
||||
};
|
||||
},
|
||||
deleteByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
selectByPrimaryKeyForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateByMapForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getOneForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
getAllForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
queryPageForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
countForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
insertBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
deleteBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
updateBatchForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
resetPwdForProUser(state, action) {
|
||||
return {
|
||||
...state,
|
||||
data: action.payload,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
Loading…
Reference in New Issue