695593266@qq.com 7 месяцев назад
Родитель
Сommit
fa22607beb

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
public/echarts-china.json


+ 15 - 0
src/assets/renewable_icon_1.svg

@@ -0,0 +1,15 @@
+<svg width="20" height="27" viewBox="0 0 20 27" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M10 19.2383C15.5228 19.2383 20 20.7641 20 22.6462C20 24.5283 15.5228 26.0541 10 26.0541C4.47716 26.0541 0 24.5283 0 22.6462C0 20.7641 4.47716 19.2383 10 19.2383V19.2383Z" fill="url(#paint0_linear_424_5342)"/>
+<path d="M9.80078 0C14.9921 0.000211681 19.2002 4.21844 19.2002 9.42188C19.2002 13.2466 14.122 19.1384 11.4307 21.9922C10.5381 22.9386 9.06251 22.9386 8.16992 21.9922C5.47855 19.1383 0.400391 13.2466 0.400391 9.42188C0.400409 4.21831 4.60932 0 9.80078 0ZM10.001 4.80469C7.79184 4.80469 6.00098 6.60017 6.00098 8.81445C6.00121 11.0285 7.79199 12.8232 10.001 12.8232C12.21 12.8232 14.0007 11.0285 14.001 8.81445C14.001 6.60017 12.2101 4.80469 10.001 4.80469Z" fill="#C4C4C4"/>
+<path d="M9.80078 0C14.9921 0.000211681 19.2002 4.21844 19.2002 9.42188C19.2002 13.2466 14.122 19.1384 11.4307 21.9922C10.5381 22.9386 9.06251 22.9386 8.16992 21.9922C5.47855 19.1383 0.400391 13.2466 0.400391 9.42188C0.400409 4.21831 4.60932 0 9.80078 0ZM10.001 4.80469C7.79184 4.80469 6.00098 6.60017 6.00098 8.81445C6.00121 11.0285 7.79199 12.8232 10.001 12.8232C12.21 12.8232 14.0007 11.0285 14.001 8.81445C14.001 6.60017 12.2101 4.80469 10.001 4.80469Z" fill="url(#paint1_linear_424_5342)"/>
+<defs>
+<linearGradient id="paint0_linear_424_5342" x1="1.02251" y1="19.4344" x2="0.954126" y2="25.9593" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3DF3F7"/>
+<stop offset="1" stop-color="#1A7CD5" stop-opacity="0.0705882"/>
+</linearGradient>
+<linearGradient id="paint1_linear_424_5342" x1="1.36232" y1="0.653274" x2="0.55658" y2="22.3589" gradientUnits="userSpaceOnUse">
+<stop stop-color="#1DF1FF"/>
+<stop offset="1" stop-color="#2797FF"/>
+</linearGradient>
+</defs>
+</svg>

+ 116 - 0
src/assets/renewable_icon_2.svg

@@ -0,0 +1,116 @@
+<svg width="121" height="121" viewBox="0 0 121 121" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="60.3942" cy="60.3942" r="59.5314" stroke="#5184EA" stroke-opacity="0.529412" stroke-width="1.72555"/>
+<circle cx="60.3941" cy="60.3943" r="53.492" fill="#004CAE"/>
+<circle cx="60.3941" cy="60.3943" r="53.492" fill="url(#paint0_radial_424_4533)"/>
+<mask id="mask0_424_4533" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="6" y="6" width="108" height="108">
+<circle cx="60.3941" cy="60.3943" r="53.492" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask0_424_4533)">
+<g filter="url(#filter0_f_424_4533)">
+<circle cx="89.7285" cy="108.709" r="32.7854" fill="#4D8FFF" fill-opacity="0.376471"/>
+</g>
+<g filter="url(#filter1_f_424_4533)">
+<ellipse cx="91.371" cy="108.01" rx="22.4321" ry="12.9416" transform="rotate(-34.9527 91.371 108.01)" fill="#2FB1FF"/>
+</g>
+<g filter="url(#filter2_f_424_4533)">
+<ellipse cx="24.8791" cy="19.6745" rx="22.4321" ry="8.32184" transform="rotate(-34.9527 24.8791 19.6745)" fill="#1CAEFF" fill-opacity="0.211765"/>
+</g>
+</g>
+<g filter="url(#filter3_d_424_4533)">
+<mask id="mask1_424_4533" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="6" y="6" width="108" height="108">
+<circle cx="60.3941" cy="60.3943" r="51.7664" stroke="#4772E1" stroke-width="3.4511"/>
+</mask>
+<g mask="url(#mask1_424_4533)">
+<circle cx="60.3941" cy="60.3943" r="51.7664" stroke="#4772E1" stroke-width="3.4511"/>
+<circle cx="60.3941" cy="60.3943" r="51.7664" stroke="url(#paint1_linear_424_4533)" stroke-opacity="0.22" style="mix-blend-mode:overlay" stroke-width="3.4511"/>
+<g filter="url(#filter4_f_424_4533)">
+<circle cx="29.3344" cy="22.4323" r="15.5299" fill="#5A9DE9" fill-opacity="0.94902"/>
+</g>
+<g filter="url(#filter5_f_424_4533)">
+<circle cx="88.0029" cy="101.809" r="32.7854" fill="#A0DFF8"/>
+</g>
+<g filter="url(#filter6_f_424_4533)">
+<circle cx="29.3342" cy="22.4314" r="10.3533" fill="#90CDF4"/>
+</g>
+<g filter="url(#filter7_f_424_4533)">
+<circle cx="88.0028" cy="103.532" r="15.5299" fill="#F4FFFF"/>
+</g>
+</g>
+</g>
+<path d="M59.651 33.763C60.1295 33.579 60.6592 33.579 61.1377 33.763L84.8012 42.8636C84.997 42.9385 85.1654 43.071 85.2842 43.2437C85.403 43.4163 85.4666 43.621 85.4666 43.8306C85.4666 44.0402 85.403 44.2448 85.2842 44.4175C85.1654 44.5902 84.997 44.7227 84.8012 44.7976L61.1377 53.8981C60.6592 54.0822 60.1295 54.0822 59.651 53.8981L35.9875 44.7976C35.7918 44.7227 35.6234 44.5902 35.5045 44.4175C35.3857 44.2448 35.3221 44.0402 35.3221 43.8306C35.3221 43.621 35.3857 43.4163 35.5045 43.2437C35.6234 43.071 35.7918 42.9385 35.9875 42.8636L59.651 33.763ZM34.8777 49.0403C34.7211 48.9811 34.5524 48.9607 34.3862 48.9809C34.22 49.0011 34.0611 49.0613 33.9233 49.1564C33.7854 49.2515 33.6727 49.3786 33.5948 49.5268C33.5169 49.675 33.476 49.8399 33.4758 50.0073V78.3981C33.4759 78.8174 33.6032 79.2267 33.8409 79.5721C34.0787 79.9174 34.4156 80.1824 34.8073 80.3321L56.9177 88.7866C57.0746 88.8467 57.2437 88.8678 57.4105 88.848C57.5772 88.8282 57.7367 88.7681 57.8751 88.6729C58.0135 88.5778 58.1266 88.4503 58.2048 88.3017C58.2829 88.153 58.3238 87.9876 58.3237 87.8196V59.3626C58.3238 58.9425 58.196 58.5323 57.9575 58.1865C57.719 57.8407 57.3809 57.5756 56.9881 57.4265L34.8777 49.0403Z" fill="#C0DCFF"/>
+<path d="M59.651 33.763C60.1295 33.579 60.6592 33.579 61.1377 33.763L84.8012 42.8636C84.997 42.9385 85.1654 43.071 85.2842 43.2437C85.403 43.4163 85.4666 43.621 85.4666 43.8306C85.4666 44.0402 85.403 44.2448 85.2842 44.4175C85.1654 44.5902 84.997 44.7227 84.8012 44.7976L61.1377 53.8981C60.6592 54.0822 60.1295 54.0822 59.651 53.8981L35.9875 44.7976C35.7918 44.7227 35.6234 44.5902 35.5045 44.4175C35.3857 44.2448 35.3221 44.0402 35.3221 43.8306C35.3221 43.621 35.3857 43.4163 35.5045 43.2437C35.6234 43.071 35.7918 42.9385 35.9875 42.8636L59.651 33.763ZM34.8777 49.0403C34.7211 48.9811 34.5524 48.9607 34.3862 48.9809C34.22 49.0011 34.0611 49.0613 33.9233 49.1564C33.7854 49.2515 33.6727 49.3786 33.5948 49.5268C33.5169 49.675 33.476 49.8399 33.4758 50.0073V78.3981C33.4759 78.8174 33.6032 79.2267 33.8409 79.5721C34.0787 79.9174 34.4156 80.1824 34.8073 80.3321L56.9177 88.7866C57.0746 88.8467 57.2437 88.8678 57.4105 88.848C57.5772 88.8282 57.7367 88.7681 57.8751 88.6729C58.0135 88.5778 58.1266 88.4503 58.2048 88.3017C58.2829 88.153 58.3238 87.9876 58.3237 87.8196V59.3626C58.3238 58.9425 58.196 58.5323 57.9575 58.1865C57.719 57.8407 57.3809 57.5756 56.9881 57.4265L34.8777 49.0403Z" fill="url(#paint2_linear_424_4533)" fill-opacity="0.29" style="mix-blend-mode:overlay"/>
+<path d="M59.651 33.763C60.1295 33.579 60.6592 33.579 61.1377 33.763L84.8012 42.8636C84.997 42.9385 85.1654 43.071 85.2842 43.2437C85.403 43.4163 85.4666 43.621 85.4666 43.8306C85.4666 44.0402 85.403 44.2448 85.2842 44.4175C85.1654 44.5902 84.997 44.7227 84.8012 44.7976L61.1377 53.8981C60.6592 54.0822 60.1295 54.0822 59.651 53.8981L35.9875 44.7976C35.7918 44.7227 35.6234 44.5902 35.5045 44.4175C35.3857 44.2448 35.3221 44.0402 35.3221 43.8306C35.3221 43.621 35.3857 43.4163 35.5045 43.2437C35.6234 43.071 35.7918 42.9385 35.9875 42.8636L59.651 33.763ZM34.8777 49.0403C34.7211 48.9811 34.5524 48.9607 34.3862 48.9809C34.22 49.0011 34.0611 49.0613 33.9233 49.1564C33.7854 49.2515 33.6727 49.3786 33.5948 49.5268C33.5169 49.675 33.476 49.8399 33.4758 50.0073V78.3981C33.4759 78.8174 33.6032 79.2267 33.8409 79.5721C34.0787 79.9174 34.4156 80.1824 34.8073 80.3321L56.9177 88.7866C57.0746 88.8467 57.2437 88.8678 57.4105 88.848C57.5772 88.8282 57.7367 88.7681 57.8751 88.6729C58.0135 88.5778 58.1266 88.4503 58.2048 88.3017C58.2829 88.153 58.3238 87.9876 58.3237 87.8196V59.3626C58.3238 58.9425 58.196 58.5323 57.9575 58.1865C57.719 57.8407 57.3809 57.5756 56.9881 57.4265L34.8777 49.0403Z" fill="url(#paint3_radial_424_4533)"/>
+<path d="M85.9111 49.0403C86.0677 48.9811 86.2363 48.9607 86.4026 48.9809C86.5688 49.0011 86.7276 49.0613 86.8655 49.1564C87.0033 49.2515 87.116 49.3786 87.194 49.5268C87.2719 49.675 87.3127 49.8399 87.3129 50.0073V78.3981C87.3129 78.8174 87.1856 79.2267 86.9478 79.5721C86.7101 79.9174 86.3731 80.1824 85.9815 80.3321L63.8731 88.7866C63.7162 88.8467 63.5472 88.8678 63.3804 88.848C63.2136 88.8282 63.0541 88.7681 62.9157 88.6729C62.7773 88.5778 62.6642 88.4503 62.586 88.3017C62.5079 88.153 62.4671 87.9876 62.4671 87.8196V59.3626C62.467 58.9425 62.5948 58.5323 62.8333 58.1865C63.0719 57.8407 63.4099 57.5756 63.8027 57.4265L85.9131 49.0403H85.9111Z" fill="#C0DCFF"/>
+<path d="M85.9111 49.0403C86.0677 48.9811 86.2363 48.9607 86.4026 48.9809C86.5688 49.0011 86.7276 49.0613 86.8655 49.1564C87.0033 49.2515 87.116 49.3786 87.194 49.5268C87.2719 49.675 87.3127 49.8399 87.3129 50.0073V78.3981C87.3129 78.8174 87.1856 79.2267 86.9478 79.5721C86.7101 79.9174 86.3731 80.1824 85.9815 80.3321L63.8731 88.7866C63.7162 88.8467 63.5472 88.8678 63.3804 88.848C63.2136 88.8282 63.0541 88.7681 62.9157 88.6729C62.7773 88.5778 62.6642 88.4503 62.586 88.3017C62.5079 88.153 62.4671 87.9876 62.4671 87.8196V59.3626C62.467 58.9425 62.5948 58.5323 62.8333 58.1865C63.0719 57.8407 63.4099 57.5756 63.8027 57.4265L85.9131 49.0403H85.9111Z" fill="url(#paint4_linear_424_4533)" fill-opacity="0.29" style="mix-blend-mode:overlay"/>
+<path d="M85.9111 49.0403C86.0677 48.9811 86.2363 48.9607 86.4026 48.9809C86.5688 49.0011 86.7276 49.0613 86.8655 49.1564C87.0033 49.2515 87.116 49.3786 87.194 49.5268C87.2719 49.675 87.3127 49.8399 87.3129 50.0073V78.3981C87.3129 78.8174 87.1856 79.2267 86.9478 79.5721C86.7101 79.9174 86.3731 80.1824 85.9815 80.3321L63.8731 88.7866C63.7162 88.8467 63.5472 88.8678 63.3804 88.848C63.2136 88.8282 63.0541 88.7681 62.9157 88.6729C62.7773 88.5778 62.6642 88.4503 62.586 88.3017C62.5079 88.153 62.4671 87.9876 62.4671 87.8196V59.3626C62.467 58.9425 62.5948 58.5323 62.8333 58.1865C63.0719 57.8407 63.4099 57.5756 63.8027 57.4265L85.9131 49.0403H85.9111Z" fill="url(#paint5_radial_424_4533)"/>
+<defs>
+<filter id="filter0_f_424_4533" x="10.3533" y="29.334" width="158.75" height="158.75" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="23.2949" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter1_f_424_4533" x="47.3836" y="67.188" width="87.975" height="81.6435" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="12.0788" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter2_f_424_4533" x="-6.19846" y="-6.95579" width="62.155" height="53.2612" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="6.03942" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter3_d_424_4533" x="1.72546" y="1.7257" width="117.337" height="117.338" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="2.58832"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.486275 0 0 0 0 0.709804 0 0 0 0 1 0 0 0 0.37 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_424_4533"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_424_4533" result="shape"/>
+</filter>
+<filter id="filter4_f_424_4533" x="5.17671" y="-1.72539" width="48.3153" height="48.316" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="4.31387" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter5_f_424_4533" x="46.5898" y="60.3957" width="82.8263" height="82.8258" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="4.31387" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter6_f_424_4533" x="10.3532" y="3.45039" width="37.962" height="37.9625" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="4.31387" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<filter id="filter7_f_424_4533" x="63.8452" y="79.3742" width="48.3153" height="48.316" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="4.31387" result="effect1_foregroundBlur_424_4533"/>
+</filter>
+<radialGradient id="paint0_radial_424_4533" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(87.1401 100.082) rotate(-122.217) scale(74.4439)">
+<stop stop-color="#5F95F9" stop-opacity="0.83"/>
+<stop offset="1" stop-color="#5F95F9" stop-opacity="0"/>
+</radialGradient>
+<linearGradient id="paint1_linear_424_4533" x1="21.5693" y1="24.1578" x2="90.5912" y2="102.67" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1"/>
+</linearGradient>
+<linearGradient id="paint2_linear_424_4533" x1="60.3944" y1="33.625" x2="60.3944" y2="88.8552" gradientUnits="userSpaceOnUse">
+<stop/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<radialGradient id="paint3_radial_424_4533" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(74.1981 91.4557) rotate(-112.932) scale(24.3571 23.7427)">
+<stop stop-color="#E9F2FF"/>
+<stop offset="1" stop-color="#E9F2FF" stop-opacity="0"/>
+</radialGradient>
+<linearGradient id="paint4_linear_424_4533" x1="60.3944" y1="33.625" x2="60.3944" y2="88.8552" gradientUnits="userSpaceOnUse">
+<stop/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<radialGradient id="paint5_radial_424_4533" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(74.1981 91.4557) rotate(-112.932) scale(24.3571 23.7427)">
+<stop stop-color="#E9F2FF"/>
+<stop offset="1" stop-color="#E9F2FF" stop-opacity="0"/>
+</radialGradient>
+</defs>
+</svg>

+ 75 - 0
src/assets/renewable_icon_3.svg

@@ -0,0 +1,75 @@
+<svg width="137" height="121" viewBox="0 0 137 121" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="67.2959" cy="60.3942" r="59.5314" stroke="#5084EA" stroke-opacity="0.286275" stroke-width="1.72555"/>
+<circle cx="67.2964" cy="60.395" r="53.492" fill="#024DB0"/>
+<mask id="mask0_424_5372" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="13" y="6" width="108" height="108">
+<circle cx="67.2954" cy="60.3932" r="53.492" fill="#3A9CFF"/>
+</mask>
+<g mask="url(#mask0_424_5372)">
+<circle cx="67.2954" cy="60.3932" r="53.492" fill="#3FAAFF" fill-opacity="0.0470588"/>
+<g filter="url(#filter0_f_424_5372)">
+<ellipse cx="20.8419" cy="66.4049" rx="16.3927" ry="49.1781" transform="rotate(-7.37322 20.8419 66.4049)" fill="#39A4FF" fill-opacity="0.12"/>
+</g>
+<g filter="url(#filter1_f_424_5372)">
+<ellipse cx="99.2002" cy="73.4393" rx="26.3421" ry="49.1781" transform="rotate(13.9386 99.2002 73.4393)" fill="#38AAFF" fill-opacity="0.0705882"/>
+</g>
+<g filter="url(#filter2_f_424_5372)">
+<ellipse cx="116.126" cy="80.6489" rx="26.3421" ry="32.1122" transform="rotate(13.9386 116.126 80.6489)" fill="#38A5FF" fill-opacity="0.17"/>
+</g>
+</g>
+<path d="M113.393 34.3542C108.706 26.4722 102.04 19.9517 94.0569 15.4388C86.0737 10.9259 77.0499 8.57737 67.8796 8.62581C58.7093 8.67426 49.7108 11.118 41.7757 15.715C33.8406 20.3119 27.2445 26.9025 22.6408 34.8336" stroke="#3269DB" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M18.8516 42.8492C14.2922 55.0634 14.4287 68.5353 19.2346 80.6546" stroke="#3269DB" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M117.464 42.8492C122.023 55.0634 121.887 68.5353 117.081 80.6546" stroke="#3269DB" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M113.393 88.155C108.706 96.0371 102.04 102.558 94.0569 107.07C86.0737 111.583 77.0499 113.932 67.8796 113.883C58.7093 113.835 49.7108 111.391 41.7757 106.794C33.8406 102.197 27.2445 95.6068 22.6408 87.6756" stroke="#3269DB" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+<g filter="url(#filter3_d_424_5372)">
+<path d="M18.8531 43.1388C14.2937 55.353 14.4302 68.8249 19.2361 80.9442M117.465 43.1388C122.025 55.353 121.888 68.8249 117.082 80.9442" stroke="#309FFF" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M18.8531 43.1388C14.2937 55.353 14.4302 68.8249 19.2361 80.9442M117.465 43.1388C122.025 55.353 121.888 68.8249 117.082 80.9442" stroke="url(#paint0_linear_424_5372)" stroke-width="3.4511" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<circle cx="67.2964" cy="60.395" r="51.7664" stroke="url(#paint1_linear_424_5372)" stroke-width="3.4511"/>
+<circle cx="67.2964" cy="60.395" r="51.7664" stroke="url(#paint2_linear_424_5372)" stroke-width="3.4511"/>
+<path d="M44.9662 48.0695L51.464 37.2401C51.7389 36.7849 52.1264 36.4081 52.5892 36.146C53.052 35.884 53.5744 35.7456 54.1063 35.7441H69.0823V48.0695H44.9662ZM71.5474 48.0695H95.6634L89.1657 37.2401C88.8908 36.7849 88.5033 36.4081 88.0405 36.146C87.5777 35.884 87.0553 35.7456 86.5234 35.7441H71.5474V48.0695ZM96.1981 50.5346V81.9642C96.1971 82.7811 95.8722 83.5643 95.2945 84.142C94.7169 84.7196 93.9337 85.0446 93.1167 85.0455H47.513C46.696 85.0446 45.9128 84.7196 45.3351 84.142C44.7575 83.5643 44.4325 82.7811 44.4316 81.9642V50.5346H96.1981ZM78.9426 61.6274C78.9426 61.4655 78.9107 61.3052 78.8488 61.1557C78.7868 61.0061 78.696 60.8703 78.5816 60.7558C78.4671 60.6414 78.3313 60.5506 78.1817 60.4886C78.0322 60.4267 77.8719 60.3948 77.71 60.3948H62.9196C62.5928 60.3948 62.2793 60.5247 62.0481 60.7558C61.817 60.987 61.6871 61.3005 61.6871 61.6274C61.6871 61.9542 61.817 62.2677 62.0481 62.4989C62.2793 62.73 62.5928 62.8599 62.9196 62.8599H77.71C77.8719 62.8599 78.0322 62.828 78.1817 62.7661C78.3313 62.7041 78.4671 62.6133 78.5816 62.4989C78.696 62.3844 78.7868 62.2486 78.8488 62.099C78.9107 61.9495 78.9426 61.7892 78.9426 61.6274Z" fill="#5CA5FF"/>
+<path d="M44.9662 48.0695L51.464 37.2401C51.7389 36.7849 52.1264 36.4081 52.5892 36.146C53.052 35.884 53.5744 35.7456 54.1063 35.7441H69.0823V48.0695H44.9662ZM71.5474 48.0695H95.6634L89.1657 37.2401C88.8908 36.7849 88.5033 36.4081 88.0405 36.146C87.5777 35.884 87.0553 35.7456 86.5234 35.7441H71.5474V48.0695ZM96.1981 50.5346V81.9642C96.1971 82.7811 95.8722 83.5643 95.2945 84.142C94.7169 84.7196 93.9337 85.0446 93.1167 85.0455H47.513C46.696 85.0446 45.9128 84.7196 45.3351 84.142C44.7575 83.5643 44.4325 82.7811 44.4316 81.9642V50.5346H96.1981ZM78.9426 61.6274C78.9426 61.4655 78.9107 61.3052 78.8488 61.1557C78.7868 61.0061 78.696 60.8703 78.5816 60.7558C78.4671 60.6414 78.3313 60.5506 78.1817 60.4886C78.0322 60.4267 77.8719 60.3948 77.71 60.3948H62.9196C62.5928 60.3948 62.2793 60.5247 62.0481 60.7558C61.817 60.987 61.6871 61.3005 61.6871 61.6274C61.6871 61.9542 61.817 62.2677 62.0481 62.4989C62.2793 62.73 62.5928 62.8599 62.9196 62.8599H77.71C77.8719 62.8599 78.0322 62.828 78.1817 62.7661C78.3313 62.7041 78.4671 62.6133 78.5816 62.4989C78.696 62.3844 78.7868 62.2486 78.8488 62.099C78.9107 61.9495 78.9426 61.7892 78.9426 61.6274Z" fill="url(#paint3_linear_424_5372)" fill-opacity="0.29" style="mix-blend-mode:overlay"/>
+<defs>
+<filter id="filter0_f_424_5372" x="-12.132" y="2.05735" width="65.9476" height="128.695" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="7.76496" result="effect1_foregroundBlur_424_5372"/>
+</filter>
+<filter id="filter1_f_424_5372" x="55.486" y="9.75383" width="87.4284" height="127.371" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="7.76496" result="effect1_foregroundBlur_424_5372"/>
+</filter>
+<filter id="filter2_f_424_5372" x="73.8782" y="33.3068" width="84.4959" height="94.6843" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="7.76496" result="effect1_foregroundBlur_424_5372"/>
+</filter>
+<filter id="filter3_d_424_5372" x="0" y="27.6084" width="136.318" height="68.8663" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="6.90219"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.176471 0 0 0 0 0.529412 0 0 0 0 1 0 0 0 0.7 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_424_5372"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_424_5372" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_424_5372" x1="68.1591" y1="43.1388" x2="68.1591" y2="80.9442" gradientUnits="userSpaceOnUse">
+<stop stop-color="#66B6FF" stop-opacity="0"/>
+<stop offset="0.483113" stop-color="#8CC8FF"/>
+<stop offset="1" stop-color="#66B6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint1_linear_424_5372" x1="67.2964" y1="6.90298" x2="67.2964" y2="113.887" gradientUnits="userSpaceOnUse">
+<stop offset="0.599777" stop-color="#96B9FF" stop-opacity="0"/>
+<stop offset="1" stop-color="#96B9FF" stop-opacity="0.45"/>
+</linearGradient>
+<linearGradient id="paint2_linear_424_5372" x1="44.8643" y1="6.90298" x2="67.2964" y2="113.887" gradientUnits="userSpaceOnUse">
+<stop stop-color="#95B7FF" stop-opacity="0.294118"/>
+<stop offset="0.234001" stop-color="#95B7FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint3_linear_424_5372" x1="70.3148" y1="35.7441" x2="70.3148" y2="85.0455" gradientUnits="userSpaceOnUse">
+<stop/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+</defs>
+</svg>

+ 101 - 0
src/assets/renewable_icon_4.svg

@@ -0,0 +1,101 @@
+<svg width="118" height="120" viewBox="0 0 118 120" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_i_424_5390)">
+<circle cx="58.6683" cy="60.3936" r="46.5898" fill="#0058B4"/>
+</g>
+<path d="M57.8058 6.9006C47.0558 6.90067 36.547 10.0884 27.6086 16.0608C18.6701 22.0332 11.7031 30.5225 7.58905 40.4543C3.4751 50.3863 2.39807 61.3159 4.4953 71.8596C6.59257 82.4031 11.7699 92.0881 19.3713 99.6897C26.9729 107.291 36.6586 112.468 47.2023 114.566C50.4265 115.207 53.6869 115.55 56.9435 115.602V119.053C53.4617 119.001 49.9756 118.636 46.5285 117.95C35.3154 115.72 25.015 110.214 16.9308 102.13C8.84676 94.0459 3.34095 83.7455 1.11053 72.5324C-1.11979 61.3194 0.0254486 49.6965 4.40057 39.134C8.77573 28.5715 16.1846 19.5434 25.6906 13.1916C35.1966 6.8399 46.3731 3.4495 57.8058 3.44943V6.9006ZM115.612 61.2551C115.612 72.6879 112.222 83.8643 105.87 93.3703C99.5185 102.876 90.4896 110.286 79.9269 114.661C74.7628 116.8 69.3451 118.165 63.8459 118.742V115.271C68.8931 114.706 73.8636 113.437 78.6066 111.473C88.5386 107.359 97.0276 100.392 103 91.4533C108.973 82.5148 112.16 72.0054 112.16 61.2551H115.612Z" fill="url(#paint0_linear_424_5390)"/>
+<circle cx="57.806" cy="61.2562" r="56.0803" stroke="url(#paint1_linear_424_5390)" stroke-width="3.4511"/>
+<circle cx="110.435" cy="39.6869" r="3.4511" fill="#63A5FF" fill-opacity="0.815686"/>
+<circle cx="113.887" cy="53.4907" r="3.4511" fill="#62A4FF" fill-opacity="0.517647"/>
+<circle cx="113.887" cy="69.0218" r="3.4511" fill="#5FA7FF" fill-opacity="0.12549"/>
+<circle cx="103.533" cy="27.6083" r="3.4511" fill="#62A4FF" fill-opacity="0.85098"/>
+<circle cx="93.1797" cy="15.5297" r="3.4511" fill="#63A5FF" fill-opacity="0.815686"/>
+<circle cx="79.3757" cy="8.62888" r="3.4511" fill="#63A5FF" fill-opacity="0.560784"/>
+<circle cx="65.5705" cy="5.1763" r="3.4511" fill="#65A3FF" fill-opacity="0.207843"/>
+<circle cx="51.7665" cy="3.4511" r="3.4511" fill="#5F9FFF" fill-opacity="0.0313726"/>
+<mask id="mask0_424_5390" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="12" y="13" width="94" height="94">
+<circle cx="58.6697" cy="60.3951" r="46.5898" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask0_424_5390)">
+<circle cx="58.6697" cy="60.3951" r="46.5898" fill="url(#paint2_linear_424_5390)" fill-opacity="0.0823529"/>
+<g filter="url(#filter1_f_424_5390)">
+<ellipse cx="26.8414" cy="24.7304" rx="11.2161" ry="21.6005" transform="rotate(46.5065 26.8414 24.7304)" fill="#57A8FF" fill-opacity="0.25"/>
+</g>
+<g filter="url(#filter2_f_424_5390)">
+<circle cx="80.2391" cy="87.1411" r="30.1971" fill="#3C9BFF" fill-opacity="0.2"/>
+</g>
+<g filter="url(#filter3_f_424_5390)">
+<ellipse cx="90.4274" cy="94.5744" rx="14.6672" ry="10.3533" transform="rotate(-35.2824 90.4274 94.5744)" fill="#51A6FF" fill-opacity="0.576471"/>
+</g>
+</g>
+<circle cx="58.6683" cy="60.3936" r="45.727" stroke="#3A8EFF" stroke-opacity="0.478431" stroke-width="1.72555"/>
+<g filter="url(#filter4_d_424_5390)">
+<circle cx="58.6685" cy="60.3932" r="43.1387" stroke="url(#paint3_linear_424_5390)" stroke-width="3.4511"/>
+<circle cx="58.6685" cy="60.3932" r="43.1387" stroke="url(#paint4_linear_424_5390)" stroke-width="3.4511"/>
+</g>
+<path d="M83.9827 56.0353L75 38.8545C74.7998 38.4717 74.4986 38.1509 74.129 37.9271C73.7594 37.7033 73.3356 37.585 72.9036 37.5849H43.8341C43.4021 37.585 42.9783 37.7033 42.6087 37.9271C42.2391 38.1509 41.9379 38.4717 41.7377 38.8545L32.7549 56.0353C32.5335 56.4588 32.4454 56.9393 32.5023 57.4138C32.5593 57.8882 32.7586 58.3343 33.0739 58.6933L56.5914 85.4565C56.8134 85.7091 57.0868 85.9116 57.3932 86.0502C57.6996 86.1889 58.0321 86.2606 58.3684 86.2606C58.7048 86.2606 59.0373 86.1889 59.3437 86.0502C59.6501 85.9116 59.9235 85.7091 60.1455 85.4565L83.663 58.6933C83.9785 58.3343 84.1779 57.8883 84.235 57.4139C84.2921 56.9394 84.2041 56.4588 83.9827 56.0353ZM73.9307 57.1579L60.1246 72.45C59.9029 72.6958 59.632 72.8922 59.3296 73.0267C59.0271 73.1611 58.6998 73.2306 58.3688 73.2306C58.0379 73.2306 57.7106 73.1611 57.4081 73.0267C57.1057 72.8922 56.8348 72.6958 56.6131 72.45L42.8062 57.1579C42.3858 56.6921 42.1676 56.0784 42.1996 55.4518C42.2317 54.8251 42.5114 54.2369 42.9771 53.8165C43.4429 53.396 44.0566 53.1778 44.6832 53.2099C45.3099 53.242 45.8981 53.5216 46.3185 53.9874L58.3688 67.3345L70.4191 53.9874C70.626 53.7521 70.8776 53.5602 71.1592 53.4228C71.4408 53.2855 71.7469 53.2055 72.0597 53.1875C72.3725 53.1694 72.6858 53.2137 72.9813 53.3177C73.2769 53.4217 73.5488 53.5834 73.7814 53.7934C74.014 54.0033 74.2025 54.2574 74.3361 54.5408C74.4696 54.8243 74.5455 55.1314 74.5594 55.4444C74.5733 55.7574 74.5249 56.0701 74.417 56.3642C74.309 56.6584 74.1437 56.9281 73.9307 57.1579Z" fill="#72A0FF"/>
+<path d="M83.9827 56.0353L75 38.8545C74.7998 38.4717 74.4986 38.1509 74.129 37.9271C73.7594 37.7033 73.3356 37.585 72.9036 37.5849H43.8341C43.4021 37.585 42.9783 37.7033 42.6087 37.9271C42.2391 38.1509 41.9379 38.4717 41.7377 38.8545L32.7549 56.0353C32.5335 56.4588 32.4454 56.9393 32.5023 57.4138C32.5593 57.8882 32.7586 58.3343 33.0739 58.6933L56.5914 85.4565C56.8134 85.7091 57.0868 85.9116 57.3932 86.0502C57.6996 86.1889 58.0321 86.2606 58.3684 86.2606C58.7048 86.2606 59.0373 86.1889 59.3437 86.0502C59.6501 85.9116 59.9235 85.7091 60.1455 85.4565L83.663 58.6933C83.9785 58.3343 84.1779 57.8883 84.235 57.4139C84.2921 56.9394 84.2041 56.4588 83.9827 56.0353ZM73.9307 57.1579L60.1246 72.45C59.9029 72.6958 59.632 72.8922 59.3296 73.0267C59.0271 73.1611 58.6998 73.2306 58.3688 73.2306C58.0379 73.2306 57.7106 73.1611 57.4081 73.0267C57.1057 72.8922 56.8348 72.6958 56.6131 72.45L42.8062 57.1579C42.3858 56.6921 42.1676 56.0784 42.1996 55.4518C42.2317 54.8251 42.5114 54.2369 42.9771 53.8165C43.4429 53.396 44.0566 53.1778 44.6832 53.2099C45.3099 53.242 45.8981 53.5216 46.3185 53.9874L58.3688 67.3345L70.4191 53.9874C70.626 53.7521 70.8776 53.5602 71.1592 53.4228C71.4408 53.2855 71.7469 53.2055 72.0597 53.1875C72.3725 53.1694 72.6858 53.2137 72.9813 53.3177C73.2769 53.4217 73.5488 53.5834 73.7814 53.7934C74.014 54.0033 74.2025 54.2574 74.3361 54.5408C74.4696 54.8243 74.5455 55.1314 74.5594 55.4444C74.5733 55.7574 74.5249 56.0701 74.417 56.3642C74.309 56.6584 74.1437 56.9281 73.9307 57.1579Z" fill="url(#paint5_linear_424_5390)" fill-opacity="0.29" style="mix-blend-mode:overlay"/>
+<defs>
+<filter id="filter0_i_424_5390" x="12.0785" y="13.8038" width="93.1796" height="93.1796" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="4.31387"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.458824 0 0 0 0 0.713726 0 0 0 0 1 0 0 0 0.36 0"/>
+<feBlend mode="normal" in2="shape" result="effect1_innerShadow_424_5390"/>
+</filter>
+<filter id="filter1_f_424_5390" x="-7.88639" y="-9.47622" width="69.4557" height="68.4133" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="8.62774" result="effect1_foregroundBlur_424_5390"/>
+</filter>
+<filter id="filter2_f_424_5390" x="27.6099" y="34.5119" width="105.258" height="105.258" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="11.2161" result="effect1_foregroundBlur_424_5390"/>
+</filter>
+<filter id="filter3_f_424_5390" x="58.0601" y="63.6267" width="64.7347" height="61.8954" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feGaussianBlur stdDeviation="9.49051" result="effect1_foregroundBlur_424_5390"/>
+</filter>
+<filter id="filter4_d_424_5390" x="8.62761" y="10.3524" width="100.082" height="100.082" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="2.58832"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.247059 0 0 0 0 0.635294 0 0 0 0 1 0 0 0 0.35 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_424_5390"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_424_5390" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_424_5390" x1="57.8058" y1="3.44943" x2="57.8058" y2="119.053" gradientUnits="userSpaceOnUse">
+<stop stop-color="#395DDC"/>
+<stop offset="1" stop-color="#66A4EC"/>
+</linearGradient>
+<linearGradient id="paint1_linear_424_5390" x1="92.317" y1="69.884" x2="57.806" y2="119.062" gradientUnits="userSpaceOnUse">
+<stop stop-color="#6DC2FF" stop-opacity="0"/>
+<stop offset="0.440004" stop-color="#6DC2FF" stop-opacity="0.482353"/>
+<stop offset="1" stop-color="#6DC2FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint2_linear_424_5390" x1="17.2566" y1="76.7878" x2="96.6318" y2="31.0608" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3C9DFF" stop-opacity="0.13"/>
+<stop offset="0.306213" stop-color="#3C9DFF"/>
+<stop offset="0.636305" stop-color="#3C9DFF"/>
+<stop offset="1" stop-color="#3C9DFF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint3_linear_424_5390" x1="31.9225" y1="25.0195" x2="85.4145" y2="95.767" gradientUnits="userSpaceOnUse">
+<stop stop-color="#74C3FF" stop-opacity="0.419608"/>
+<stop offset="0.378498" stop-color="#33A7FF" stop-opacity="0.137255"/>
+<stop offset="1" stop-color="#4CB5FF" stop-opacity="0.905882"/>
+</linearGradient>
+<linearGradient id="paint4_linear_424_5390" x1="31.9225" y1="25.0195" x2="85.4145" y2="95.767" gradientUnits="userSpaceOnUse">
+<stop offset="0.927285" stop-color="#97D3FF" stop-opacity="0"/>
+<stop offset="0.964559" stop-color="#97D3FF" stop-opacity="0.823529"/>
+</linearGradient>
+<linearGradient id="paint5_linear_424_5390" x1="58.3687" y1="37.5849" x2="58.3687" y2="86.2606" gradientUnits="userSpaceOnUse">
+<stop/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+</defs>
+</svg>

+ 153 - 0
src/views/bpm/vis-page/components/charts/AreaLineChart.vue

@@ -0,0 +1,153 @@
+<template>
+  <div ref="chartRef" class="area-line-chart"></div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+
+export default {
+  name: 'AreaLineChart',
+  props: {
+    categories: {
+      type: Array,
+      default: () => []
+    },
+    /** 面积/折线系列,如 [{ name: '采购量', data: [] }, { name: '库存量', data: [] }] */
+    series: {
+      type: Array,
+      default: () => []
+    },
+    colors: {
+      type: Array,
+      default: () => ['#1163fb', '#4a90a4']
+    },
+    showLegend: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      chartInstance: null
+    };
+  },
+  watch: {
+    categories: { handler() { this.updateChart(); }, deep: true },
+    series: { handler() { this.updateChart(); }, deep: true }
+  },
+  mounted() {
+    this.initChart();
+    window.addEventListener('resize', this.handleResize);
+  },
+  beforeDestroy() {
+    if (this.chartInstance) {
+      this.chartInstance.dispose();
+      this.chartInstance = null;
+    }
+    window.removeEventListener('resize', this.handleResize);
+  },
+  methods: {
+    initChart() {
+      if (!this.$refs.chartRef) return;
+      this.chartInstance = echarts.init(this.$refs.chartRef);
+      this.updateChart();
+    },
+    updateChart() {
+      if (!this.chartInstance || !this.categories?.length) return;
+      const colors = this.colors || ['#1163fb', '#4a90a4'];
+      const seriesList = (this.series || []).map((s, i) => {
+        const c = colors[i % colors.length];
+        return {
+          name: s.name || '',
+          type: 'line',
+          smooth: 0.45,
+          symbol: 'circle',
+          symbolSize: 8,
+          showSymbol: false,
+          emphasis: { focus: 'series', itemStyle: { borderColor: '#fff', borderWidth: 2 } },
+          data: s.data || [],
+          areaStyle: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              { offset: 0, color: c + 'aa' },
+              { offset: 0.5, color: c + '55' },
+              { offset: 1, color: c + '08' }
+            ])
+          },
+          lineStyle: { color: c, width: 2.5 },
+          itemStyle: { color: c }
+        };
+      });
+      const option = {
+        backgroundColor: 'transparent',
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'line',
+            lineStyle: { color: 'rgba(255,255,255,0.25)', width: 1 }
+          },
+          backgroundColor: 'rgba(255,255,255,0.96)',
+          borderColor: '#ddd',
+          textStyle: { color: '#333', fontSize: 13 },
+          formatter: (params) => {
+            if (!params || !params.length) return '';
+            let html = `<b style="font-size:14px">${params[0].axisValue}</b><br/>`;
+            params.forEach((p) => {
+              const dot = `<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${p.color};margin-right:6px;vertical-align:middle;"></span>`;
+              html += `${dot}${p.seriesName}&emsp;<b style="color:${p.color}">${p.value}</b><br/>`;
+            });
+            if (params.length >= 2) {
+              const a = params[0].value || 1;
+              const b = params[1].value || 0;
+              const rate = Math.round((b / a) * 100);
+              html += `准时到货率 <b>${rate}%</b>`;
+            }
+            return html;
+          }
+        },
+        legend: {
+          show: this.showLegend,
+          top: 4,
+          right: 8,
+          textStyle: { color: '#e9ecef', fontSize: 11 },
+          itemWidth: 14,
+          itemHeight: 8
+        },
+        grid: {
+          left: '6%',
+          right: '4%',
+          top: this.showLegend ? '18%' : '10%',
+          bottom: '10%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: this.categories,
+          boundaryGap: false,
+          axisLine: { lineStyle: { color: 'rgba(18, 76, 119, 0.45)' } },
+          axisTick: { show: false },
+          axisLabel: { color: '#d4ebff', fontSize: 11 }
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: { show: false },
+          axisTick: { show: false },
+          axisLabel: { color: '#b8d4ef', fontSize: 11 },
+          splitLine: { lineStyle: { color: 'rgba(18, 76, 119, 0.22)' } }
+        },
+        series: seriesList
+      };
+      this.chartInstance.setOption(option, true);
+    },
+    handleResize() {
+      this.chartInstance?.resize();
+    }
+  }
+};
+</script>
+
+<style scoped>
+.area-line-chart {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 204 - 0
src/views/bpm/vis-page/components/charts/ChinaMapChart.vue

@@ -0,0 +1,204 @@
+<template>
+  <div ref="chartRef" class="china-map-chart"></div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+
+const CHINA_SCATTER = [
+  { name: '北京', value: [116.4074, 39.9042] },
+  { name: '上海', value: [121.4737, 31.2304] },
+  { name: '广东', value: [113.2644, 23.1291] },
+  { name: '山东', value: [117.0208, 36.6683] },
+  { name: '河南', value: [113.6254, 34.7466] },
+  { name: '福建', value: [119.2965, 26.1006] },
+  { name: '新疆', value: [87.6168, 43.8256] },
+  { name: '甘肃', value: [103.8236, 36.0581] },
+  { name: '四川', value: [104.0665, 30.5723] },
+  { name: '湖北', value: [114.3055, 30.5931] },
+  { name: '江苏', value: [118.7969, 32.0603] },
+  { name: '浙江', value: [120.1536, 30.2875] }
+];
+const SCATTER_COLORS = ['#ff9f2d', '#00e1ff', '#21d07a', '#b96cff'];
+
+export default {
+  name: 'ChinaMapChart',
+  props: {
+    scatterData: { type: Array, default: () => [] },
+    legendCategories: {
+      type: Array,
+      default: () => [
+        { name: '类别 A', count: 15 },
+        { name: '类别 B', count: 12 },
+        { name: '类别 C', count: 10 },
+        { name: '类别 D', count: 13 }
+      ]
+    },
+    mapJson: { type: Object, default: null }
+  },
+  data() {
+    return { chartInstance: null, registered: false };
+  },
+  watch: {
+    scatterData: { handler() { this.updateChart(); }, deep: true },
+    legendCategories: { handler() { this.updateChart(); }, deep: true },
+    mapJson: { handler(v) { if (v) this.registerAndUpdate(); }, deep: true }
+  },
+  mounted() {
+    this.loadMapAndInit();
+    window.addEventListener('resize', this.handleResize);
+  },
+  beforeDestroy() {
+    if (this.chartInstance) {
+      this.chartInstance.dispose();
+      this.chartInstance = null;
+    }
+    window.removeEventListener('resize', this.handleResize);
+  },
+  methods: {
+    isValidMapJson(json) {
+      return json && (Array.isArray(json.features) || (json.regions && json.regions.length));
+    },
+    getMapJsonUrl() {
+      const baseUrl = process.env.BASE_URL || '/';
+      return `${baseUrl.replace(/\/?$/, '/') }echarts-china.json`;
+    },
+    loadMapAndInit() {
+      if (this.mapJson && this.isValidMapJson(this.mapJson)) {
+        echarts.registerMap('china', this.mapJson);
+        this.registered = true;
+        this.initChart();
+        this.updateChart();
+        return;
+      }
+      if (!this.mapJson) {
+        fetch(this.getMapJsonUrl())
+          .then((res) => res.ok ? res.json() : Promise.reject(new Error('Not ok')))
+          .then((json) => {
+            if (!this.isValidMapJson(json)) return;
+            echarts.registerMap('china', json);
+            this.registered = true;
+          })
+          .catch(() => {})
+          .finally(() => {
+            this.initChart();
+            this.updateChart();
+          });
+        return;
+      }
+      this.initChart();
+      this.updateChart();
+    },
+    registerAndUpdate() {
+      if (this.mapJson && this.isValidMapJson(this.mapJson) && !this.registered) {
+        echarts.registerMap('china', this.mapJson);
+        this.registered = true;
+        this.updateChart();
+      }
+    },
+    initChart() {
+      if (!this.$refs.chartRef) return;
+      this.chartInstance = echarts.init(this.$refs.chartRef);
+    },
+    getScatterSeriesData() {
+      const raw = this.scatterData && this.scatterData.length
+        ? this.scatterData
+        : CHINA_SCATTER.map((p, i) => ({ name: p.name, value: p.value, category: i % 4 }));
+      return raw.map((d) => ({
+        name: d.name,
+        value: Array.isArray(d.value) ? d.value : [d.lng, d.lat],
+        category: d.category != null ? d.category : 0
+      }));
+    },
+    updateChart() {
+      if (!this.chartInstance) return;
+      const hasMap = this.registered;
+      const scatterData = this.getScatterSeriesData();
+      const categories = this.legendCategories || [];
+      const option = {
+        backgroundColor: 'transparent',
+        tooltip: {
+          trigger: 'item',
+          formatter: (p) => (p.data && p.data.name ? `${p.data.name}` : ''),
+          backgroundColor: 'rgba(8, 29, 65, 0.9)',
+          borderColor: '#124c77',
+          textStyle: { color: '#fff' }
+        },
+        legend: {
+          show: categories.length > 0,
+          bottom: 8,
+          left: 'center',
+          textStyle: { color: '#e9ecef', fontSize: 11 },
+          itemWidth: 12,
+          itemHeight: 8,
+          data: categories.map((c) => c.name),
+          formatter: (name) => {
+            const item = categories.find((c) => c.name === name);
+            return item ? `${name} ${item.count || ''}` : name;
+          }
+        },
+        series: [{
+          name: '分布',
+          type: 'scatter',
+          coordinateSystem: hasMap ? 'geo' : null,
+          data: hasMap ? scatterData : scatterData.map((d) => ({ ...d, value: [...d.value, 1] })),
+          symbolSize: 12,
+          itemStyle: {
+            color: (params) => SCATTER_COLORS[params.data?.category || 0] || SCATTER_COLORS[0],
+            borderColor: '#fff',
+            borderWidth: 1,
+            shadowBlur: 6,
+            shadowColor: 'rgba(255, 149, 0, 0.5)'
+          },
+          emphasis: { scale: 1.2 }
+        }]
+      };
+      if (hasMap) {
+        option.geo = {
+          map: 'china',
+          roam: false,
+          label: {
+            show: true,
+            color: 'rgba(191, 230, 255, 0.65)',
+            fontSize: 9
+          },
+          itemStyle: {
+            areaColor: 'rgba(3, 29, 65, 0.85)',
+            borderColor: '#124c77',
+            borderWidth: 1
+          },
+          emphasis: {
+            itemStyle: { areaColor: 'rgba(17, 99, 251, 0.4)' },
+            label: { color: '#fff' }
+          }
+        };
+      } else {
+        option.grid = { left: '8%', right: '8%', top: '10%', bottom: '18%', containLabel: true };
+        option.xAxis = {
+          type: 'value', min: 80, max: 130,
+          axisLine: { show: false }, axisTick: { show: false },
+          splitLine: { lineStyle: { color: 'rgba(18, 76, 119, 0.2)' } },
+          axisLabel: { show: false }
+        };
+        option.yAxis = {
+          type: 'value', min: 18, max: 52,
+          axisLine: { show: false }, axisTick: { show: false },
+          splitLine: { lineStyle: { color: 'rgba(18, 76, 119, 0.2)' } },
+          axisLabel: { show: false }
+        };
+        option.series[0].coordinateSystem = 'cartesian2d';
+        option.series[0].data = scatterData.map((d) => [d.value[0], d.value[1], d.name]);
+        option.series[0].symbolSize = 10;
+      }
+      this.chartInstance.setOption(option, true);
+    },
+    handleResize() {
+      this.chartInstance?.resize();
+    }
+  }
+};
+</script>
+
+<style scoped>
+.china-map-chart { width: 100%; height: 100%; }
+</style>

+ 789 - 0
src/views/bpm/vis-page/equipmentMaintenanceDashboard.vue

@@ -0,0 +1,789 @@
+<template>
+  <vue-fullscreen
+    class="em-container"
+    v-cloak
+    v-model="isFullscreen"
+    fullscreenClass="em-container"
+    :exit-on-click-wrapper="false"
+  >
+    <div class="em-container" v-cloak>
+      <!-- Header Section -->
+      <div class="em-header">
+        <div class="em-header-side em-header-left">
+          <div class="em-header-chip"><i class="el-icon-date"></i> 2024-2-27 - 2024-3-27</div>
+        </div>
+
+        <div class="em-title">设备运维管理看板</div>
+
+        <div class="em-header-side em-header-right">
+          <div class="em-time-box">
+            <span class="em-date">{{ date }}</span>
+            <span class="em-week">{{ week }}</span>
+            <span class="em-time">{{ time }}</span>
+          </div>
+          <span class="em-weather">
+             <img src="https://img.icons8.com/fluent/48/000000/partly-cloudy-day.png" width="20" height="20" style="vertical-align: middle; margin-right: 4px;" />
+            27-19°C
+          </span>
+          <span class="em-fullscreen" @click="onFullscreen">
+            <i v-if="isFullscreen" class="el-icon-_screen-restore" title="退出全屏"></i>
+            <i v-else class="el-icon-_screen-full" title="全屏"></i>
+          </span>
+        </div>
+      </div>
+
+      <!-- Main Body -->
+      <div class="em-body">
+        <!-- Left Column -->
+        <div class="em-side-column">
+          <!-- 设备台账概览 -->
+          <section class="em-panel">
+            <div class="em-panel-title">设备台账概览</div>
+            <div class="em-summary-grid">
+              <div v-for="item in deviceStats" :key="item.label" class="em-summary-card">
+                <div class="em-summary-icon">
+                   <img :src="item.icon" width="24" height="24" />
+                </div>
+                <div class="em-summary-info">
+                  <div class="em-summary-label">{{ item.label }}</div>
+                  <div class="em-summary-value-row">
+                    <span class="em-summary-value">{{ item.value }}</span>
+                    <span class="em-summary-unit">{{ item.unit }}</span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+
+          <!-- 设备状态 -->
+          <section class="em-panel">
+            <div class="em-panel-title">设备状态</div>
+            <div class="em-chart-box">
+              <device-status-chart :data="deviceStatusData" />
+            </div>
+          </section>
+
+          <!-- 设备动态 -->
+          <section class="em-panel">
+            <div class="em-panel-title">设备动态</div>
+            <div class="em-list-box scroll-box">
+              <div v-for="(item, index) in deviceDynamics" :key="index" class="em-dynamic-item">
+                <img :src="item.img" class="em-dynamic-img" />
+                <div class="em-dynamic-info">
+                   <div class="em-dynamic-row">
+                     <span class="em-dynamic-name">{{ item.name }}</span>
+                     <span class="em-dynamic-model">{{ item.model }}</span>
+                     <span :class="['em-status-tag', item.statusType]">{{ item.status }}</span>
+                   </div>
+                   <div class="em-dynamic-time">{{ item.time }}</div>
+                </div>
+              </div>
+            </div>
+          </section>
+
+          <!-- 运维工单 -->
+          <section class="em-panel">
+            <div class="em-panel-title">运维工单</div>
+            <div class="em-table-container">
+              <table class="em-table">
+                <thead>
+                  <tr>
+                    <th>工单编号</th>
+                    <th>维护设备</th>
+                    <th>负责人员</th>
+                    <th>开始时间</th>
+                    <th>结束时间</th>
+                    <th>状态</th>
+                  </tr>
+                </thead>
+                <tbody>
+                  <tr v-for="(row, index) in maintenanceOrders" :key="index">
+                    <td>{{ row.no }}</td>
+                    <td>{{ row.device }}</td>
+                    <td>{{ row.person }}</td>
+                    <td>{{ row.startTime }}</td>
+                    <td>{{ row.endTime }}</td>
+                    <td><span :class="['em-status-dot', row.statusType]"></span> {{ row.status }}</td>
+                  </tr>
+                </tbody>
+              </table>
+            </div>
+          </section>
+        </div>
+
+        <!-- Center Column -->
+        <div class="em-center-column">
+          <div class="em-factory-view">
+             <!-- Placeholder for 3D Factory Model -->
+             <div class="em-factory-placeholder">
+                <!-- Informational Overlays -->
+                <div class="em-info-overlay card-1">
+                   <div class="em-overlay-title">设备保养</div>
+                   <div class="em-overlay-row"><span>运维单号:</span><strong>YW600005</strong></div>
+                   <div class="em-overlay-row"><span>运维类型:</span><strong>预防性</strong></div>
+                   <div class="em-overlay-row"><span>最近一次日期:</span><strong>2023-3-3</strong></div>
+                   <div class="em-overlay-row"><span>时间:</span><strong>10:00:00</strong></div>
+                   <div class="em-overlay-footer">维修组:<strong>总装二部</strong></div>
+                </div>
+                <div class="em-info-overlay card-2">
+                   <div class="em-overlay-title">工单详情</div>
+                   <div class="em-overlay-row"><span>生产工单号:</span><strong>SC000005</strong></div>
+                   <div class="em-overlay-row"><span>当前产品:</span><strong>轮毂块</strong></div>
+                   <div class="em-overlay-row"><span>生产目标:</span><strong>1000</strong></div>
+                   <div class="em-overlay-row"><span>完成量:</span><strong>550</strong></div>
+                   <div class="em-overlay-row"><span>当前工序:</span><strong>磨床</strong></div>
+                </div>
+                <div class="em-info-overlay card-3">
+                   <div class="em-overlay-title">传感器参数监控 <span class="em-tag-green">运行中</span></div>
+                   <div class="em-overlay-row"><span>设备编号:</span><strong>X1192569</strong></div>
+                   <div class="em-overlay-row"><span>低层型号:</span><strong>6568734</strong></div>
+                   <div class="em-overlay-row"><span>状态:</span><strong>启用</strong></div>
+                   <div class="em-overlay-row"><span>温度:</span><strong>240°C</strong></div>
+                   <div class="em-overlay-row"><span>压力:</span><strong>401.55Kpa</strong></div>
+                   <div class="em-overlay-row"><span>振动:</span><strong>41.332/s</strong></div>
+                   <div class="em-overlay-row"><span>功率:</span><strong>28.5KW</strong></div>
+                </div>
+             </div>
+          </div>
+        </div>
+
+        <!-- Right Column -->
+        <div class="em-side-column">
+          <!-- 报警统计 -->
+          <section class="em-panel">
+            <div class="em-panel-title">报警统计</div>
+            <div class="em-summary-grid">
+               <div v-for="item in alarmStats" :key="item.label" class="em-summary-card alarm-card">
+                  <div class="em-summary-icon">
+                     <img :src="item.icon" width="24" height="24" />
+                  </div>
+                  <div class="em-summary-info">
+                    <div class="em-summary-label">{{ item.label }}</div>
+                    <div class="em-summary-value">{{ item.value }}</div>
+                  </div>
+               </div>
+            </div>
+          </section>
+
+          <!-- 报警等级分布 -->
+          <section class="em-panel">
+            <div class="em-panel-title">报警等级分布</div>
+            <div class="em-chart-box">
+               <bar-chart :data="alarmLevelData" :horizontal="false" :showLegend="false" :colors="['#1163fb', '#14cdc9', '#f9bb19', '#712ed2', '#ec4899', '#ff4d4f']" />
+            </div>
+          </section>
+
+          <!-- 报警原因分析 -->
+          <section class="em-panel">
+            <div class="em-panel-title">报警原因分析</div>
+            <div class="em-chart-box">
+               <device-status-chart :data="alarmReasonData" />
+            </div>
+          </section>
+
+          <!-- 报警列表 -->
+          <section class="em-panel">
+            <div class="em-panel-title">报警列表</div>
+            <div class="em-list-box scroll-box">
+                <div v-for="(item, index) in alarmList" :key="index" class="em-alarm-item">
+                   <div class="em-alarm-header">
+                      <span class="em-alarm-time">{{ item.time }}</span>
+                      <span :class="['em-alarm-status', item.statusType]">{{ item.status }}</span>
+                   </div>
+                   <div class="em-alarm-content">{{ item.content }}</div>
+                </div>
+            </div>
+          </section>
+
+          <!-- 告警趋势图 -->
+          <section class="em-panel">
+            <div class="em-panel-title">告警趋势图</div>
+            <div class="em-chart-box">
+               <area-line-chart :categories="timeCategories" :series="alarmTrendSeries" :colors="['#1163fb', '#14cdc9', '#f9bb19', '#ff4d4f']" />
+            </div>
+          </section>
+        </div>
+      </div>
+    </div>
+  </vue-fullscreen>
+</template>
+
+<script>
+import { component as VueFullscreen } from 'vue-fullscreen';
+import DeviceStatusChart from './components/charts/DeviceStatusChart.vue';
+import BarChart from './components/charts/BarChart.vue';
+import AreaLineChart from './components/charts/AreaLineChart.vue';
+
+export default {
+  name: 'EquipmentMaintenanceDashboard',
+  components: {
+    VueFullscreen,
+    DeviceStatusChart,
+    BarChart,
+    AreaLineChart
+  },
+  data() {
+    return {
+      isFullscreen: false,
+      resizeTimer: null,
+      clockTimer: null,
+      date: '',
+      time: '',
+      week: '',
+      deviceStats: [
+        { label: '设备总数', value: 727, unit: '台', icon: require('@/assets/renewable_icon_1.svg') },
+        { label: '生产设备', value: 579, unit: '台', icon: require('@/assets/renewable_icon_2.svg') },
+        { label: '视频监控', value: 85, unit: '台', icon: require('@/assets/renewable_icon_3.svg') },
+        { label: '无线设备', value: 63, unit: '台', icon: require('@/assets/renewable_icon_4.svg') }
+      ],
+      deviceStatusData: [
+        { name: '启用', value: 533 },
+        { name: '待机', value: 28 },
+        { name: '故障', value: 51 },
+        { name: '维修', value: 23 },
+        { name: '保养', value: 83 }
+      ],
+      deviceDynamics: [
+        { name: '垂直分拣器', model: 'SCGZ200305', status: '启机', statusType: 'on', time: '2024-2-27 9:30:00', img: 'https://via.placeholder.com/60?text=Device' },
+        { name: '垂直分拣器', model: 'SCGZ200305', status: '启机', statusType: 'on', time: '2024-2-27 9:30:00', img: 'https://via.placeholder.com/60?text=Device' },
+        { name: '垂直分拣器', model: 'SCGZ200305', status: '启机', statusType: 'on', time: '2024-2-27 9:30:00', img: 'https://via.placeholder.com/60?text=Device' }
+      ],
+      maintenanceOrders: [
+        { no: '0000001', device: '金属质检机', person: '李四', startTime: '2024-2-27 9:30:00', endTime: '2024-2-27 11:30:00', status: '已完成', statusType: 'done' },
+        { no: '0000002', device: '金属质检机', person: '李四', startTime: '2024-2-27 9:30:00', endTime: '2024-2-27 11:30:00', status: '已完成', statusType: 'done' },
+        { no: '0000003', device: '金属质检机', person: '李四', startTime: '2024-2-27 9:30:00', endTime: '2024-2-27 11:30:00', status: '已完成', statusType: 'done' },
+        { no: '0000004', device: '金属质检机', person: '李四', startTime: '2024-2-27 9:30:00', endTime: '2024-2-27 11:30:00', status: '处理中', statusType: 'doing' },
+        { no: '0000005', device: '金属质检机', person: '李四', startTime: '2024-2-27 9:30:00', endTime: '2024-2-27 11:30:00', status: '处理中', statusType: 'doing' }
+      ],
+      alarmStats: [
+        { label: '故障总数(条)', value: 128, icon: require('@/assets/renewable_icon_1.svg') },
+        { label: '已处理故障(条)', value: 121, icon: require('@/assets/renewable_icon_2.svg') },
+        { label: '待处理故障(条)', value: 7, icon: require('@/assets/renewable_icon_3.svg') },
+        { label: '严重故障(条)', value: 30, icon: require('@/assets/renewable_icon_4.svg') }
+      ],
+      alarmLevelData: [
+        { name: '特级', value: 45 },
+        { name: '一级', value: 75 },
+        { name: '二级', value: 40 },
+        { name: '三级', value: 60 },
+        { name: '四级', value: 20 },
+        { name: '五级', value: 15 }
+      ],
+      alarmReasonData: [
+        { name: '设备故障', value: 75 },
+        { name: '维护保养时间间隔过长', value: 34 },
+        { name: '负载过高', value: 30 },
+        { name: '系统崩溃', value: 25 },
+        { name: '环境异常', value: 68 }
+      ],
+      alarmList: [
+        { time: '2024-3-5 9:30:00', content: '压力240Mpa已超过环境 负载导致', status: '已处理', statusType: 'done' },
+        { time: '2024-3-5 9:30:00', content: '压力240Mpa已超过环境 负载导致', status: '待处理', statusType: 'todo' },
+        { time: '2024-3-5 9:30:00', content: '压力240Mpa已超过环境 负载导致', status: '待处理', statusType: 'todo' }
+      ],
+      timeCategories: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
+      alarmTrendSeries: [
+        { name: '特级', data: [10, 12, 8, 15, 13, 11, 14, 16, 12, 10, 15, 12] },
+        { name: '一级', data: [15, 18, 12, 22, 19, 16, 20, 24, 18, 15, 22, 18] },
+        { name: '二级', data: [8, 10, 6, 12, 10, 8, 11, 13, 10, 8, 12, 10] },
+        { name: '三级', data: [5, 7, 4, 9, 7, 5, 8, 10, 7, 5, 9, 7] }
+      ]
+    };
+  },
+  created() {
+    this.updateTime();
+    this.clockTimer = setInterval(this.updateTime, 1000);
+  },
+  mounted() {
+    this.applyScreenSize();
+    window.addEventListener('resize', this.handleResize);
+  },
+  beforeDestroy() {
+    clearInterval(this.clockTimer);
+    window.removeEventListener('resize', this.handleResize);
+  },
+  methods: {
+    onFullscreen() {
+      this.isFullscreen = !this.isFullscreen;
+    },
+    updateTime() {
+      const now = new Date();
+      const pad = (n) => String(n).padStart(2, '0');
+      this.time = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
+      this.date = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
+      const weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
+      this.week = weeks[now.getDay()];
+    },
+    handleResize() {
+      clearTimeout(this.resizeTimer);
+      this.resizeTimer = setTimeout(() => {
+        this.applyScreenSize();
+      }, 120);
+    },
+    applyScreenSize() {
+      const isFs = !!(document.fullscreenElement || document.webkitFullscreenElement);
+      const deviceWidth = isFs ? window.innerWidth : document.documentElement.clientWidth;
+      const deviceHeight = isFs ? window.innerHeight : document.documentElement.clientHeight;
+      
+      const designWidth = 1920;
+      const designHeight = 1080;
+      
+      const scale = Math.min(deviceWidth / designWidth, deviceHeight / designHeight);
+      const baseFontSize = isFs ? Math.max(12, Math.min(18, 16 * scale)) : 16;
+      document.documentElement.style.fontSize = `${baseFontSize}px`;
+
+      document.querySelectorAll('.em-container').forEach((el) => {
+        el.style.height = `${deviceHeight}px`;
+        el.style.width = `${deviceWidth}px`;
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+[v-cloak] { display: none !important; }
+
+.em-container {
+  width: 100vw;
+  height: 100vh;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  background: #020817;
+  background-image: 
+    radial-gradient(circle at top center, rgba(30, 113, 255, 0.15), transparent 40%),
+    linear-gradient(180deg, #04122b 0%, #020817 100%);
+  font-size: 1rem;
+  position: relative;
+
+  &::before {
+    content: '';
+    position: absolute;
+    top: 0; left: 0; right: 0; bottom: 0;
+    background-image: url('https://img.js.design/assets/static/76718d097973c155f9488f55928669e2.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    opacity: 0.6;
+    pointer-events: none;
+  }
+}
+
+.em-header {
+  height: 5.6rem;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0 1.5rem 0.5rem;
+  background-image: url('https://img.js.design/assets/static/6b95d97f6424e650d88924b220755928.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  position: relative;
+  z-index: 10;
+  flex-shrink: 0;
+}
+
+.em-title {
+  position: absolute;
+  left: 50%;
+  top: 1.2rem;
+  transform: translateX(-50%);
+  font-size: 2.4rem;
+  font-weight: bold;
+  letter-spacing: 0.25rem;
+  color: #f3fbff;
+  text-shadow: 0 0 12px rgba(80, 184, 255, 0.8);
+  font-family: '优设标题黑', sans-serif;
+  font-style: italic;
+}
+
+.em-header-side {
+  display: flex;
+  align-items: center;
+  gap: 1.2rem;
+  margin-top: 1.2rem;
+}
+
+.em-header-chip {
+  padding: 0.25rem 0.75rem;
+  background: rgba(30, 113, 255, 0.15);
+  border: 1px solid rgba(30, 113, 255, 0.3);
+  border-radius: 2px;
+  font-size: 0.85rem;
+  color: #a9d0ff;
+}
+
+.em-time-box {
+  display: flex;
+  align-items: center;
+  gap: 0.75rem;
+  font-size: 0.85rem;
+  color: #a9d0ff;
+
+  .em-time {
+    font-size: 1.1rem;
+    color: #fff;
+    font-weight: 600;
+  }
+}
+
+.em-weather {
+  color: #f6d067;
+  font-size: 0.85rem;
+}
+
+.em-fullscreen {
+  cursor: pointer;
+  color: #7fa7ce;
+  font-size: 1.2rem;
+  transition: all 0.3s;
+  &:hover { 
+    color: #fff;
+    transform: scale(1.1);
+  }
+}
+
+.em-body {
+  flex: 1;
+  display: grid;
+  grid-template-columns: 24.5% 51% 24.5%;
+  gap: 0.8rem;
+  padding: 0 1rem 1rem;
+  min-height: 0;
+  position: relative;
+  z-index: 5;
+}
+
+.em-side-column {
+  display: flex;
+  flex-direction: column;
+  gap: 0.8rem;
+  min-height: 0;
+}
+
+.em-center-column {
+  display: flex;
+  flex-direction: column;
+  min-height: 0;
+  position: relative;
+}
+
+.em-panel {
+  background: rgba(10, 31, 68, 0.75);
+  border: 1px solid rgba(50, 116, 193, 0.4);
+  box-shadow: inset 0 0 15px rgba(0, 133, 255, 0.1);
+  display: flex;
+  flex-direction: column;
+  min-height: 0;
+
+  .em-panel-title {
+    height: 2.2rem;
+    display: flex;
+    align-items: center;
+    padding: 0 1rem 0 1.8rem;
+    font-weight: bold;
+    font-size: 0.95rem;
+    color: #d6ebff;
+    position: relative;
+    background: linear-gradient(90deg, rgba(30, 113, 255, 0.2) 0%, transparent 100%);
+    border-bottom: 1px solid rgba(50, 116, 193, 0.2);
+    flex-shrink: 0;
+
+    &::before {
+      content: '';
+      position: absolute;
+      left: 0.6rem;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 0.8rem;
+      height: 0.8rem;
+      background: #1e71ff;
+      clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 0%, 20% 20%, 20% 80%, 80% 80%, 80% 20%, 20% 20%);
+    }
+
+    &::after {
+      content: '';
+      position: absolute;
+      left: 0.8rem;
+      top: 50%;
+      transform: translateY(-50%);
+      width: 0.4rem;
+      height: 0.4rem;
+      background: #00d2ff;
+      border-radius: 50%;
+    }
+  }
+}
+
+.em-summary-grid {
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 0.6rem;
+  padding: 0.8rem;
+  flex-shrink: 0;
+}
+
+.em-summary-card {
+  display: flex;
+  align-items: center;
+  padding: 0.7rem;
+  background: rgba(30, 113, 255, 0.08);
+  border: 1px solid rgba(30, 113, 255, 0.15);
+  border-radius: 4px;
+
+  .em-summary-icon {
+    width: 2.4rem;
+    height: 2.4rem;
+    background: radial-gradient(circle, rgba(30, 113, 255, 0.4), transparent);
+    border: 1px solid rgba(30, 113, 255, 0.3);
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 0.6rem;
+  }
+
+  .em-summary-info {
+    flex: 1;
+    min-width: 0;
+  }
+
+  .em-summary-label {
+    font-size: 0.75rem;
+    color: #a9d0ff;
+    margin-bottom: 0.2rem;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  .em-summary-value-row {
+    display: flex;
+    align-items: baseline;
+    gap: 2px;
+  }
+
+  .em-summary-value {
+    font-size: 1.25rem;
+    font-weight: bold;
+    color: #fff;
+    font-family: 'Arial', sans-serif;
+  }
+
+  .em-summary-unit {
+    font-size: 0.7rem;
+    color: #7fa7ce;
+  }
+}
+
+.em-chart-box {
+  flex: 1;
+  min-height: 0;
+  padding: 0.4rem;
+  position: relative;
+}
+
+.em-list-box {
+  flex: 1;
+  overflow-y: auto;
+  padding: 0.4rem;
+}
+
+.scroll-box {
+  &::-webkit-scrollbar { width: 3px; }
+  &::-webkit-scrollbar-track { background: transparent; }
+  &::-webkit-scrollbar-thumb { background: rgba(30, 113, 255, 0.3); border-radius: 2px; }
+}
+
+.em-dynamic-item {
+  display: flex;
+  gap: 0.7rem;
+  padding: 0.6rem;
+  background: rgba(30, 113, 255, 0.03);
+  margin-bottom: 0.4rem;
+  border: 1px solid transparent;
+  transition: all 0.3s;
+
+  &:hover {
+    background: rgba(30, 113, 255, 0.1);
+    border-color: rgba(30, 113, 255, 0.2);
+  }
+
+  .em-dynamic-img {
+    width: 3.2rem;
+    height: 3.2rem;
+    object-fit: cover;
+    border: 1px solid rgba(30, 113, 255, 0.3);
+  }
+
+  .em-dynamic-info {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    min-width: 0;
+  }
+
+  .em-dynamic-row {
+    display: flex;
+    align-items: center;
+    gap: 0.5rem;
+    flex-wrap: nowrap;
+  }
+
+  .em-dynamic-name { font-size: 0.85rem; color: #fff; font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+  .em-dynamic-model { font-size: 0.75rem; color: #7fa7ce; }
+  .em-dynamic-time { font-size: 0.75rem; color: #5a8bc7; }
+}
+
+.em-status-tag {
+  font-size: 0.7rem;
+  padding: 0 5px;
+  line-height: 1.3;
+  border-radius: 10px;
+  &.on { background: rgba(33, 208, 122, 0.15); color: #21d07a; border: 1px solid rgba(33, 208, 122, 0.4); }
+  &.off { background: rgba(255, 77, 79, 0.15); color: #ff4d4f; border: 1px solid rgba(255, 77, 79, 0.4); }
+}
+
+.em-table-container {
+  flex: 1;
+  overflow-y: auto;
+  padding: 0.4rem;
+}
+
+.em-table {
+  width: 100%;
+  border-collapse: collapse;
+  font-size: 0.75rem;
+
+  th {
+    text-align: left;
+    padding: 0.6rem 0.4rem;
+    color: #7fa7ce;
+    border-bottom: 1px solid rgba(30, 113, 255, 0.2);
+    font-weight: 600;
+    position: sticky;
+    top: 0;
+    background: rgba(10, 31, 68, 1);
+  }
+
+  td {
+    padding: 0.5rem 0.4rem;
+    color: #d6ebff;
+    border-bottom: 1px solid rgba(30, 113, 255, 0.05);
+  }
+}
+
+.em-status-dot {
+  display: inline-block;
+  width: 5px;
+  height: 5px;
+  border-radius: 50%;
+  margin-right: 5px;
+  vertical-align: middle;
+  &.done { background: #21d07a; box-shadow: 0 0 5px #21d07a; }
+  &.doing { background: #f9bb19; box-shadow: 0 0 5px #f9bb19; }
+}
+
+.em-factory-view {
+  flex: 1;
+  position: relative;
+  overflow: hidden;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.em-factory-placeholder {
+  width: 100%;
+  height: 100%;
+  background: url('https://img.js.design/assets/static/679a8383a8b2734614631313.png') no-repeat center center;
+  background-size: cover;
+  position: relative;
+}
+
+.em-info-overlay {
+  position: absolute;
+  width: 13rem;
+  background: rgba(8, 29, 65, 0.8);
+  border: 1px solid rgba(30, 113, 255, 0.6);
+  backdrop-filter: blur(4px);
+  padding: 0.8rem;
+  border-radius: 2px;
+  box-shadow: 0 0 15px rgba(30, 113, 255, 0.3);
+  pointer-events: none;
+  animation: float 4s ease-in-out infinite;
+
+  .em-overlay-title {
+    font-size: 0.9rem;
+    font-weight: bold;
+    color: #fff;
+    margin-bottom: 0.6rem;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1px solid rgba(30, 113, 255, 0.2);
+    padding-bottom: 0.3rem;
+  }
+
+  .em-overlay-row {
+    font-size: 0.75rem;
+    color: #a9d0ff;
+    margin-bottom: 0.25rem;
+    display: flex;
+    justify-content: space-between;
+
+    strong { color: #fff; }
+  }
+
+  .em-overlay-footer {
+    margin-top: 0.4rem;
+    padding-top: 0.4rem;
+    border-top: 1px dotted rgba(30, 113, 255, 0.3);
+    font-size: 0.75rem;
+    color: #7fa7ce;
+    strong { color: #1e71ff; }
+  }
+
+  &.card-1 { top: 15%; left: 15%; animation-delay: 0s; }
+  &.card-2 { top: 22%; left: 45%; animation-delay: 1s; }
+  &.card-3 { top: 10%; right: 10%; width: 15rem; animation-delay: 2s; }
+}
+
+@keyframes float {
+  0%, 100% { transform: translateY(0); }
+  50% { transform: translateY(-8px); }
+}
+
+.alarm-card {
+  .em-summary-value { color: #ff4d4f; }
+  .em-summary-icon { background: radial-gradient(circle, rgba(255, 77, 79, 0.3), transparent); border-color: rgba(255, 77, 79, 0.3); }
+}
+
+.em-alarm-item {
+  padding: 0.6rem;
+  background: rgba(255, 77, 79, 0.04);
+  border: 1px solid rgba(255, 77, 79, 0.1);
+  margin-bottom: 0.5rem;
+  border-left: 3px solid #ff4d4f;
+
+  .em-alarm-header {
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 0.2rem;
+  }
+
+  .em-alarm-time { font-size: 0.7rem; color: #7fa7ce; }
+  .em-alarm-status {
+    font-size: 0.7rem;
+    &.done { color: #21d07a; }
+    &.todo { color: #ff4d4f; }
+  }
+  .em-alarm-content { font-size: 0.8rem; color: #d6ebff; line-height: 1.4; }
+}
+
+@media (max-width: 1500px) {
+  .em-body { grid-template-columns: 28% 44% 28%; }
+}
+</style>

+ 2144 - 0
src/views/bpm/vis-page/renewableResourcesDashboard.vue

@@ -0,0 +1,2144 @@
+<template>
+  <vue-fullscreen
+    class="rr-container"
+    v-cloak
+    v-model="isFullscreen"
+    fullscreenClass="rr-container"
+    :exit-on-click-wrapper="false"
+  >
+    <div class="rr-container" v-cloak>
+      <div class="rr-header">
+        <div class="rr-header-side rr-header-left">
+          <!-- <div class="rr-header-chip">黑屏看板</div> -->
+          <el-date-picker
+            v-model="dateRange"
+            class="rr-date-picker"
+            size="mini"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            value-format="yyyy-MM-dd"
+          />
+        </div>
+
+        <div class="rr-title">越隆达再生资源集团公司</div>
+
+        <div class="rr-header-side rr-header-right">
+          <div class="rr-time-box">
+            <span class="rr-date">{{ date }}</span>
+            <span class="rr-week">{{ week }}</span>
+            <span class="rr-time">{{ time }}</span>
+          </div>
+          <span class="rr-weather">晴 27-19°C</span>
+          <span class="rr-fullscreen" @click="onFullscreen">
+            <i
+              v-if="isFullscreen"
+              class="el-icon-_screen-restore"
+              title="退出全屏"
+            ></i>
+            <i v-else class="el-icon-_screen-full" title="全屏"></i>
+          </span>
+        </div>
+      </div>
+
+      <div class="rr-body">
+        <div class="rr-side-column">
+          <section class="rr-panel rr-panel-sales">
+            <div class="rr-panel-title">营销总览</div>
+            <div class="rr-summary-strip">
+              <div
+                v-for="item in salesCards"
+                :key="item.key"
+                class="rr-summary-item"
+              >
+                <div class="rr-summary-icon-box">
+                  <div class="rr-summary-icon-wrap">
+                    <div class="rr-summary-icon-ring"></div>
+                    <div class="rr-summary-icon">
+                      <img
+                        class="rr-summary-icon-img"
+                        :src="item.iconSrc"
+                        :alt="item.label"
+                      />
+                    </div>
+                  </div>
+                </div>
+                <div class="rr-summary-content">
+                  <div class="rr-summary-label">{{ item.label }}</div>
+                  <div class="rr-summary-main">
+                    <span class="rr-summary-value">{{ item.value }}</span>
+                    <span class="rr-summary-unit">{{ item.unit }}</span>
+                    <div class="rr-summary-trend" :class="item.trendType">
+                      <span class="rr-summary-trend-label">{{
+                        item.trendLabel
+                      }}</span>
+                      <span class="rr-summary-trend-value"
+                        >{{ item.trendType === 'up' ? '↗' : '↘'
+                        }}{{ item.trend }}%</span
+                      >
+                    </div>
+                  </div>
+                </div>
+                <div
+                  v-if="item.key !== salesCards[salesCards.length - 1].key"
+                  class="rr-summary-divider"
+                ></div>
+              </div>
+            </div>
+          </section>
+
+          <section class="rr-panel rr-panel-procurement">
+            <div class="rr-panel-title">采购总览</div>
+            <div class="rr-procurement-body">
+              <div class="rr-procurement-pane rr-procurement-pane-area">
+                <div class="rr-pane-caption">
+                  <span>单位:件</span>
+                  <div class="rr-pane-legend">
+                    <span class="rr-legend-item rr-legend-item-blue"
+                      >采购量</span
+                    >
+                    <span class="rr-legend-item rr-legend-item-gold"
+                      >到货量</span
+                    >
+                  </div>
+                </div>
+                <div class="rr-chart-panel rr-chart-panel-compact">
+                  <area-line-chart
+                    v-if="isChartReady"
+                    :categories="monthCategories"
+                    :series="procurementSeries"
+                    :colors="['#3c87ff', '#e5b15d']"
+                    :show-legend="false"
+                    class="rr-fill-chart"
+                  />
+                </div>
+              </div>
+              <div class="rr-procurement-pane rr-procurement-pane-bar">
+                <div class="rr-pane-caption rr-pane-caption-right">
+                  <span>准时交付率</span>
+                </div>
+                <div class="rr-mini-bar-panel rr-mini-bar-panel-fill">
+                  <div ref="procurementBarRef" class="rr-native-chart"></div>
+                </div>
+              </div>
+            </div>
+          </section>
+
+          <section class="rr-panel rr-panel-inventory">
+            <div class="rr-panel-title">仓储总览</div>
+            <div class="rr-inventory-body">
+              <div class="rr-inv-left">
+                <div class="rr-inv-chart-wrap">
+                  <div ref="inventoryDonutRef" class="rr-native-chart"></div>
+                  <div class="rr-inv-center">
+                    <span class="rr-inv-center-value">{{ inventoryOverview.total }}</span>
+                    <span class="rr-inv-center-label">库存总量</span>
+                  </div>
+                </div>
+              </div>
+              <div class="rr-inv-right">
+                <div class="rr-inv-trend-caption">周转率</div>
+                <div class="rr-inv-trend-chart">
+                  <div ref="inventoryTrendRef" class="rr-native-chart"></div>
+                </div>
+              </div>
+            </div>
+          </section>
+        </div>
+
+        <section class="rr-map-panel">
+          <div class="rr-map-head">
+            <div class="rr-map-tabs">
+              <span
+                class="rr-tab"
+                :class="{ active: mapTab === 'nation' }"
+                @click="mapTab = 'nation'"
+              >
+                全国
+              </span>
+              <span
+                class="rr-tab"
+                :class="{ active: mapTab === 'factory' }"
+                @click="mapTab = 'factory'"
+              >
+                工厂分布
+              </span>
+            </div>
+            <div class="rr-map-summary">
+              <div
+                v-for="item in mapHeaderStats"
+                :key="item.label"
+                class="rr-map-summary-item"
+              >
+                <span>{{ item.label }}</span>
+                <strong>{{ item.value }}</strong>
+              </div>
+            </div>
+          </div>
+
+          <div class="rr-map-body">
+            <china-map-chart
+              v-if="isChartReady"
+              :scatter-data="currentMapScatterData"
+              :legend-categories="currentMapLegendCategories"
+              class="rr-map-chart"
+            />
+          </div>
+        </section>
+
+        <div class="rr-side-column">
+          <section class="rr-panel rr-panel-quality">
+            <div class="rr-panel-title">质量总览</div>
+            <div class="rr-quality-grid">
+              <div
+                v-for="item in qualityCards"
+                :key="item.title"
+                class="rr-quality-card"
+              >
+                <div class="rr-quality-header">
+                  <span class="rr-quality-dot"></span>
+                  <span>{{ item.title }}</span>
+                </div>
+                <div class="rr-quality-rate">{{ item.passRate }}%</div>
+                <div class="rr-quality-bars">
+                  <div class="rr-progress-row">
+                    <span>合格率</span>
+                    <strong>{{ item.passRate }}%</strong>
+                  </div>
+                  <div class="rr-progress-track">
+                    <span
+                      class="rr-progress-fill rr-progress-fill-good"
+                      :style="{ width: item.passRate + '%' }"
+                    ></span>
+                  </div>
+                  <div class="rr-progress-row">
+                    <span>不合格率</span>
+                    <strong>{{ item.failRate }}%</strong>
+                  </div>
+                  <div class="rr-progress-track">
+                    <span
+                      class="rr-progress-fill rr-progress-fill-bad"
+                      :style="{ width: item.failRate + '%' }"
+                    ></span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </section>
+
+          <section class="rr-panel rr-panel-production">
+            <div class="rr-panel-title">生产总览</div>
+            <div class="rr-chart-panel">
+              <area-line-chart
+                v-if="isChartReady"
+                :categories="monthCategories"
+                :series="productionSeries"
+                :colors="['#4fa5ff', '#22d4b8']"
+                class="rr-fill-chart"
+              />
+            </div>
+            <div class="rr-mini-bar-panel">
+              <div ref="productionBarRef" class="rr-native-chart"></div>
+            </div>
+          </section>
+
+          <section class="rr-panel rr-panel-equipment">
+            <div class="rr-panel-title">设备总览</div>
+            <div class="rr-equipment-body">
+              <div class="rr-equipment-gauge">
+                <div class="rr-gauge-wrap">
+                  <div ref="utilDonutRef" class="rr-native-chart"></div>
+                </div>
+                <ul class="rr-equipment-list">
+                  <li v-for="item in leftEquipmentList" :key="item.label">
+                    <span>{{ item.label }}</span>
+                    <strong>{{ item.value }}</strong>
+                  </li>
+                </ul>
+              </div>
+              <div class="rr-equipment-gauge">
+                <div class="rr-gauge-wrap">
+                  <div ref="faultDonutRef" class="rr-native-chart"></div>
+                </div>
+                <ul class="rr-equipment-list">
+                  <li v-for="item in rightEquipmentList" :key="item.label">
+                    <span>{{ item.label }}</span>
+                    <strong>{{ item.value }}</strong>
+                  </li>
+                </ul>
+              </div>
+            </div>
+          </section>
+        </div>
+      </div>
+    </div>
+  </vue-fullscreen>
+</template>
+
+<script>
+  import { component as VueFullscreen } from 'vue-fullscreen';
+  import * as echarts from 'echarts';
+  import AreaLineChart from './components/charts/AreaLineChart';
+  import ChinaMapChart from './components/charts/ChinaMapChart';
+
+  export default {
+    name: 'RenewableResourcesDashboard',
+    components: {
+      VueFullscreen,
+      AreaLineChart,
+      ChinaMapChart
+    },
+    data() {
+      return {
+        isFullscreen: false,
+        isChartReady: false,
+        resizeTimer: null,
+        clockTimer: null,
+        date: '',
+        time: '',
+        week: '',
+        dateRange: [],
+        mapTab: 'nation',
+        monthCategories: [
+          '1月',
+          '2月',
+          '3月',
+          '4月',
+          '5月',
+          '6月',
+          '7月',
+          '8月',
+          '9月',
+          '10月',
+          '11月',
+          '12月'
+        ],
+        salesCards: [
+          {
+            key: 'order',
+            iconSrc: require('@/assets/renewable_icon_2.svg'),
+            label: '订单量',
+            value: '1024',
+            unit: '万',
+            trend: 25,
+            trendType: 'up',
+            trendLabel: '同比上升'
+          },
+          {
+            key: 'ship',
+            iconSrc: require('@/assets/renewable_icon_3.svg'),
+            label: '出货量',
+            value: '2048',
+            unit: '万',
+            trend: 25,
+            trendType: 'warn',
+            trendLabel: '同比上升'
+          },
+          {
+            key: 'delivery',
+            iconSrc: require('@/assets/renewable_icon_4.svg'),
+            label: '准时交货率',
+            value: '89',
+            unit: '%',
+            trend: 25,
+            trendType: 'up',
+            trendLabel: '同比下降'
+          }
+        ],
+        qualityCards: [
+          { title: '成品质检', passRate: 98, failRate: 2 },
+          { title: '原料质检', passRate: 91, failRate: 9 }
+        ],
+        inventoryOverview: {
+          total: 6247
+        },
+        inventoryStats: [
+          { label: '成品数', value: 2533 },
+          { label: '半成品数', value: 1050 },
+          { label: '原材料数', value: 2523 },
+          { label: '备品备件数', value: 58 },
+          { label: '呆滞品数', value: 83 }
+        ],
+        // mapHeaderStats: [
+        //   { label: '覆盖省份', value: 24 },
+        //   { label: '合作基地', value: 16 },
+        //   { label: '实时车辆', value: 37 }
+        // ],
+        nationMapScatterData: [
+          { name: '新疆', value: [87.6168, 43.8256], category: 0 },
+          { name: '甘肃', value: [103.8236, 36.0581], category: 1 },
+          { name: '河南', value: [113.6254, 34.7466], category: 2 },
+          { name: '山东', value: [117.0208, 36.6683], category: 3 },
+          { name: '江苏', value: [118.7969, 32.0603], category: 0 },
+          { name: '浙江', value: [120.1536, 30.2875], category: 1 },
+          { name: '福建', value: [119.2965, 26.1006], category: 2 },
+          { name: '广东', value: [113.2644, 23.1291], category: 3 }
+        ],
+        factoryMapScatterData: [
+          { name: '乌鲁木齐工厂', value: [87.6168, 43.8256], category: 0 },
+          { name: '兰州工厂', value: [103.8236, 36.0581], category: 1 },
+          { name: '郑州工厂', value: [113.6254, 34.7466], category: 2 },
+          { name: '青岛工厂', value: [120.3826, 36.0671], category: 3 },
+          { name: '南京工厂', value: [118.7969, 32.0603], category: 0 },
+          { name: '广州工厂', value: [113.2644, 23.1291], category: 2 }
+        ],
+        nationMapLegendCategories: [
+          { name: '危废回收', count: 15 },
+          { name: '金属分拣', count: 12 },
+          { name: '塑料再生', count: 10 },
+          { name: '纸类回收', count: 13 }
+        ],
+        factoryMapLegendCategories: [
+          { name: '总装厂', count: 3 },
+          { name: '分拣厂', count: 5 },
+          { name: '再生厂', count: 4 },
+          { name: '仓储站', count: 4 }
+        ],
+        procurementSeries: [
+          {
+            name: '采购量',
+            data: [2100, 3200, 2800, 4200, 4673, 2600, 1800, 2200, 1500, 2800, 4800, 1900]
+          },
+          {
+            name: '到货量',
+            data: [1400, 2100, 1800, 2600, 2895, 1700, 1300, 1600, 1100, 1700, 2500, 1200]
+          }
+        ],
+        productionSeries: [
+          {
+            name: '生产量',
+            data: [240, 286, 332, 365, 398, 430, 412, 448, 470, 502, 534, 561]
+          },
+          {
+            name: '达成量',
+            data: [205, 240, 285, 318, 345, 380, 366, 398, 420, 446, 478, 505]
+          }
+        ],
+        equipmentOverview: {
+          utilRate: 92,
+          faultRate: 23,
+          online: 1247,
+          waiting: 523,
+          maintenance: 80,
+          scrapped: 23,
+          deviceCount: 533,
+          productCount: 1247,
+          spareCount: 523,
+          toolCount: 80
+        },
+        chartInstances: {
+          procurementBar: null,
+          productionBar: null,
+          inventoryDonut: null,
+          inventoryTrend: null,
+          utilDonut: null,
+          faultDonut: null
+        }
+      };
+    },
+    computed: {
+      currentMapScatterData() {
+        return this.mapTab === 'factory'
+          ? this.factoryMapScatterData
+          : this.nationMapScatterData;
+      },
+      currentMapLegendCategories() {
+        return this.mapTab === 'factory'
+          ? this.factoryMapLegendCategories
+          : this.nationMapLegendCategories;
+      },
+      leftEquipmentList() {
+        return [
+          { label: '在线设备', value: this.equipmentOverview.online },
+          { label: '待机设备', value: this.equipmentOverview.waiting },
+          { label: '维修设备', value: this.equipmentOverview.maintenance }
+        ];
+      },
+      rightEquipmentList() {
+        return [
+          { label: '生产设备', value: this.equipmentOverview.deviceCount },
+          { label: '产品设备', value: this.equipmentOverview.productCount },
+          { label: '备件库存', value: this.equipmentOverview.spareCount }
+        ];
+      }
+    },
+    created() {
+      this.updateTime();
+      this.clockTimer = setInterval(this.updateTime, 1000);
+      const now = new Date();
+      const start = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 30);
+      this.dateRange = [this.formatDate(start), this.formatDate(now)];
+    },
+    mounted() {
+      this.applyScreenSize();
+      window.addEventListener('resize', this.handleResize);
+      document.addEventListener(
+        'fullscreenchange',
+        this.handleFullscreenChange
+      );
+      document.addEventListener(
+        'webkitfullscreenchange',
+        this.handleFullscreenChange
+      );
+      this.$nextTick(() => {
+        this.isChartReady = true;
+        this.$nextTick(() => {
+          this.initNativeCharts();
+        });
+      });
+    },
+    beforeDestroy() {
+      clearInterval(this.clockTimer);
+      clearTimeout(this.resizeTimer);
+      window.removeEventListener('resize', this.handleResize);
+      document.removeEventListener(
+        'fullscreenchange',
+        this.handleFullscreenChange
+      );
+      document.removeEventListener(
+        'webkitfullscreenchange',
+        this.handleFullscreenChange
+      );
+      Object.values(this.chartInstances).forEach((chart) => chart?.dispose());
+    },
+    methods: {
+      formatDate(date) {
+        const pad = (n) => String(n).padStart(2, '0');
+        return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
+          date.getDate()
+        )}`;
+      },
+      onFullscreen() {
+        this.isFullscreen = !this.isFullscreen;
+      },
+      updateTime() {
+        const now = new Date();
+        const pad = (n) => String(n).padStart(2, '0');
+        this.time = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(
+          now.getSeconds()
+        )}`;
+        this.date = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(
+          now.getDate()
+        )}`;
+        const weeks = [
+          '星期日',
+          '星期一',
+          '星期二',
+          '星期三',
+          '星期四',
+          '星期五',
+          '星期六'
+        ];
+        this.week = weeks[now.getDay()];
+      },
+      handleResize() {
+        clearTimeout(this.resizeTimer);
+        this.resizeTimer = setTimeout(() => {
+          this.applyScreenSize();
+          Object.values(this.chartInstances).forEach((chart) =>
+            chart?.resize()
+          );
+          window.dispatchEvent(new Event('resize'));
+        }, 120);
+      },
+      handleFullscreenChange() {
+        this.$nextTick(() => {
+          setTimeout(() => {
+            this.applyScreenSize();
+            Object.values(this.chartInstances).forEach((chart) =>
+              chart?.resize()
+            );
+            window.dispatchEvent(new Event('resize'));
+          }, 160);
+        });
+      },
+      applyScreenSize() {
+        const isFs = !!(
+          document.fullscreenElement || document.webkitFullscreenElement
+        );
+        const deviceWidth = isFs
+          ? window.innerWidth || document.documentElement.clientWidth
+          : document.documentElement.clientWidth;
+        const deviceHeight = isFs
+          ? window.innerHeight || document.documentElement.clientHeight
+          : document.documentElement.clientHeight;
+        const headerH =
+          (!isFs &&
+            document.querySelector('.ele-admin-header')?.offsetHeight) ||
+          0;
+        const tabsH =
+          (!isFs && document.querySelector('.ele-admin-tabs')?.offsetHeight) ||
+          0;
+        const sidebarW =
+          (!isFs &&
+            document.querySelector('.ele-admin-sidebar')?.offsetWidth) ||
+          0;
+        const h = isFs ? deviceHeight : deviceHeight - headerH - tabsH;
+        const w = isFs ? deviceWidth : deviceWidth - sidebarW;
+        document.querySelectorAll('.rr-container').forEach((el) => {
+          el.style.height = `${h}px`;
+          el.style.width = `${w}px`;
+        });
+        const designWidth = 1920;
+        const designHeight = 1080;
+        const scale = Math.min(w / designWidth, h / designHeight);
+        const baseFontSize = isFs ? Math.max(14, Math.min(18, 16 * scale)) : 16;
+        document.documentElement.style.fontSize = `${baseFontSize}px`;
+      },
+      initNativeCharts() {
+        this.initBarChart(
+          'procurementBar',
+          this.$refs.procurementBarRef,
+          [68, 58, 62, 78, 55, 81, 90, 88, 75, 55, 82, 88],
+          '#1089BB'
+        );
+        this.initBarChart(
+          'productionBar',
+          this.$refs.productionBarRef,
+          [18, 22, 26, 29, 35, 37, 36, 40, 42, 45, 49, 51],
+          '#22d4b8'
+        );
+        this.initInventoryDonutChart();
+        this.initInventoryTrendChart();
+        this.initGaugeChart(
+          'utilDonut',
+          this.$refs.utilDonutRef,
+          92,
+          '#27dfd3'
+        );
+        this.initGaugeChart(
+          'faultDonut',
+          this.$refs.faultDonutRef,
+          23,
+          '#ff834d'
+        );
+      },
+      initBarChart(key, el, data, color) {
+        if (!el) return;
+        this.chartInstances[key]?.dispose();
+        const chart = echarts.init(el);
+        if (key === 'procurementBar') {
+          const topColor = '#0DF1FF';
+          const barW = 22;
+          const diamondW = barW;
+          const diamondH = Math.round(diamondW * 0.42);
+          chart.setOption({
+            backgroundColor: 'transparent',
+            tooltip: {
+              trigger: 'axis',
+              axisPointer: { type: 'shadow', shadowStyle: { color: 'rgba(13,241,255,0.06)' } },
+              backgroundColor: 'rgba(255,255,255,0.96)',
+              borderColor: '#ddd',
+              textStyle: { color: '#333', fontSize: 13 },
+              formatter: (params) => {
+                const p = params.find((s) => s.seriesIndex === 1);
+                return p ? `<b>${p.name}</b><br/>准时到货率 <b>${p.value}%</b>` : '';
+              }
+            },
+            grid: {
+              left: '6%',
+              right: '4%',
+              top: '12%',
+              bottom: '8%',
+              containLabel: true
+            },
+            xAxis: {
+              type: 'category',
+              data: this.monthCategories,
+              axisLine: { lineStyle: { color: 'rgba(32, 105, 168, 0.45)' } },
+              axisTick: { show: false },
+              axisLabel: {
+                color: '#d4ebff',
+                fontSize: 11,
+                margin: 8
+              }
+            },
+            yAxis: {
+              type: 'value',
+              min: 0,
+              max: 100,
+              interval: 20,
+              axisLine: { show: false },
+              axisTick: { show: false },
+              axisLabel: {
+                color: '#b8d4ef',
+                fontSize: 11,
+                formatter: '{value}%'
+              },
+              splitLine: {
+                lineStyle: { color: 'rgba(21, 77, 123, 0.22)' }
+              }
+            },
+            series: [
+              {
+                name: 'bg',
+                type: 'bar',
+                data: new Array(data.length).fill(100),
+                barWidth: barW,
+                barGap: '-100%',
+                silent: true,
+                z: 1,
+                itemStyle: {
+                  color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                    { offset: 0, color: 'rgba(16, 137, 187, 0.1)' },
+                    { offset: 1, color: 'rgba(16, 137, 187, 0.02)' }
+                  ])
+                }
+              },
+              {
+                name: 'value',
+                type: 'bar',
+                data,
+                barWidth: barW,
+                z: 3,
+                itemStyle: {
+                  color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                    { offset: 0, color: 'rgba(13, 241, 255, 0.92)' },
+                    { offset: 0.4, color: 'rgba(16, 137, 187, 0.82)' },
+                    { offset: 1, color: 'rgba(10, 68, 122, 0.72)' }
+                  ])
+                }
+              },
+              {
+                name: 'topCap',
+                type: 'pictorialBar',
+                data,
+                symbol: 'diamond',
+                symbolSize: [diamondW, diamondH],
+                symbolOffset: [0, -(diamondH / 2)],
+                symbolPosition: 'end',
+                z: 5,
+                tooltip: { show: false },
+                itemStyle: {
+                  color: topColor,
+                  shadowBlur: 8,
+                  shadowColor: 'rgba(13, 241, 255, 0.55)'
+                }
+              },
+              {
+                name: 'bottomCap',
+                type: 'pictorialBar',
+                data: new Array(data.length).fill(0.5),
+                symbol: 'diamond',
+                symbolSize: [diamondW, diamondH],
+                symbolOffset: [0, diamondH / 2],
+                symbolPosition: 'start',
+                z: 2,
+                tooltip: { show: false },
+                itemStyle: {
+                  color: 'rgba(10, 68, 122, 0.78)'
+                }
+              }
+            ]
+          });
+          this.chartInstances[key] = chart;
+          return;
+        }
+        chart.setOption({
+          backgroundColor: 'transparent',
+          grid: {
+            left: '8%',
+            right: '4%',
+            top: '10%',
+            bottom: '12%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'category',
+            data: this.monthCategories,
+            axisLine: { lineStyle: { color: '#154d7b' } },
+            axisTick: { show: false },
+            axisLabel: { color: '#b8d4ef', fontSize: 10 }
+          },
+          yAxis: {
+            type: 'value',
+            axisLine: { show: false },
+            axisTick: { show: false },
+            axisLabel: { color: '#b8d4ef', fontSize: 10 },
+            splitLine: { lineStyle: { color: 'rgba(21, 77, 123, 0.28)' } }
+          },
+          series: [
+            {
+              type: 'bar',
+              data,
+              barWidth: '42%',
+              itemStyle: {
+                borderRadius: [6, 6, 0, 0],
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color },
+                  { offset: 1, color: color + '2b' }
+                ])
+              }
+            }
+          ]
+        });
+        this.chartInstances[key] = chart;
+      },
+      initInventoryDonutChart() {
+        if (!this.$refs.inventoryDonutRef) return;
+        this.chartInstances.inventoryDonut?.dispose();
+        const chart = echarts.init(this.$refs.inventoryDonutRef);
+        const pieColors = ['#2d5dbe', '#ffb648', '#3cd8c8', '#7b69ff', '#1fa4df'];
+        const pieData = [
+          { name: '成品数', value: 2533 },
+          { name: '半成品数', value: 1050 },
+          { name: '原材料数', value: 2523 },
+          { name: '备品备件数', value: 58 },
+          { name: '呆滞品数', value: 83 }
+        ];
+        const cw = chart.getWidth();
+        const ch = chart.getHeight();
+        const isSmall = cw < 240 || ch < 160;
+        const valFs = isSmall ? 12 : 14;
+        const nameFs = isSmall ? 10 : 11;
+        chart.setOption({
+          backgroundColor: 'transparent',
+          color: pieColors,
+          tooltip: {
+            trigger: 'item',
+            backgroundColor: 'rgba(8,29,65,0.92)',
+            borderColor: '#124c77',
+            textStyle: { color: '#fff', fontSize: 13 }
+          },
+          series: [
+            {
+              type: 'pie',
+              radius: ['36%', '58%'],
+              center: ['50%', '50%'],
+              padAngle: 2,
+              itemStyle: { borderRadius: 4 },
+              minShowLabelAngle: 2,
+              label: {
+                show: true,
+                position: 'outside',
+                formatter: (p) => `{val|${p.data.value}}\n{name|${p.name}}`,
+                rich: {
+                  val: {
+                    color: '#fff',
+                    fontSize: valFs,
+                    fontWeight: 700,
+                    lineHeight: valFs + 6
+                  },
+                  name: {
+                    color: '#c3dfff',
+                    fontSize: nameFs,
+                    lineHeight: nameFs + 5
+                  }
+                },
+                distanceToLabelLine: 2
+              },
+              labelLine: {
+                show: true,
+                length: 10,
+                length2: 20,
+                smooth: false,
+                lineStyle: { color: '#4da6d8', width: 1.2 }
+              },
+              labelLayout: (params) => {
+                const isLeft = params.labelRect.x < cw / 2;
+                return {
+                  align: isLeft ? 'right' : 'left',
+                  hideOverlap: true
+                };
+              },
+              data: pieData
+            },
+            {
+              type: 'pie',
+              radius: ['30%', '32%'],
+              center: ['50%', '50%'],
+              silent: true,
+              label: { show: false },
+              labelLine: { show: false },
+              data: [{ value: 1, itemStyle: { color: 'rgba(60, 135, 255, 0.18)' } }]
+            }
+          ]
+        });
+        this.chartInstances.inventoryDonut = chart;
+      },
+      initInventoryTrendChart() {
+        if (!this.$refs.inventoryTrendRef) return;
+        this.chartInstances.inventoryTrend?.dispose();
+        const chart = echarts.init(this.$refs.inventoryTrendRef);
+        chart.setOption({
+          backgroundColor: 'transparent',
+          tooltip: {
+            trigger: 'axis',
+            backgroundColor: 'rgba(8,29,65,0.92)',
+            borderColor: '#124c77',
+            textStyle: { color: '#fff', fontSize: 12 },
+            formatter: (params) => {
+              const p = params[0];
+              return p ? `${p.name}&emsp;周转率: <b>${p.value}%</b>` : '';
+            }
+          },
+          grid: {
+            left: '2%',
+            right: '4%',
+            top: '16%',
+            bottom: '10%',
+            containLabel: true
+          },
+          xAxis: {
+            type: 'category',
+            data: ['数据一', '数据二', '数据三', '数据四', '数据五', '数据六', '数据七'],
+            axisLine: { lineStyle: { color: 'rgba(21, 77, 123, 0.6)' } },
+            axisTick: { show: false },
+            axisLabel: { color: '#b8d4ef', fontSize: 10 }
+          },
+          yAxis: {
+            type: 'value',
+            min: 50,
+            max: 100,
+            interval: 10,
+            axisLine: { show: false },
+            axisTick: { show: false },
+            axisLabel: { color: '#b8d4ef', fontSize: 10, formatter: '{value}%' },
+            splitLine: { lineStyle: { color: 'rgba(21, 77, 123, 0.24)' } }
+          },
+          series: [
+            {
+              type: 'line',
+              smooth: 0.3,
+              data: [78, 82, 72, 80, 85, 79, 88],
+              symbol: 'circle',
+              symbolSize: 8,
+              showSymbol: true,
+              lineStyle: { color: '#3c87ff', width: 2.5 },
+              itemStyle: { color: '#3c87ff', borderColor: '#fff', borderWidth: 2 },
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(60, 135, 255, 0.3)' },
+                  { offset: 1, color: 'rgba(60, 135, 255, 0.02)' }
+                ])
+              }
+            }
+          ]
+        });
+        this.chartInstances.inventoryTrend = chart;
+      },
+      initGaugeChart(key, el, value, color) {
+        if (!el) return;
+        this.chartInstances[key]?.dispose();
+        const chart = echarts.init(el);
+        const label = key === 'utilDonut' ? '设备利用率' : '设备故障率';
+        chart.setOption({
+          backgroundColor: 'transparent',
+          series: [
+            {
+              type: 'gauge',
+              center: ['50%', '62%'],
+              radius: '90%',
+              startAngle: 200,
+              endAngle: -20,
+              min: 0,
+              max: 100,
+              pointer: { show: false },
+              progress: {
+                show: true,
+                width: 16,
+                roundCap: true,
+                itemStyle: { color }
+              },
+              axisLine: {
+                lineStyle: {
+                  width: 16,
+                  color: [[1, 'rgba(18, 76, 119, 0.32)']]
+                }
+              },
+              axisTick: { show: false },
+              splitLine: { show: false },
+              axisLabel: {
+                show: true,
+                distance: -32,
+                color: 'rgba(180, 220, 255, 0.6)',
+                fontSize: 10,
+                formatter: (v) => {
+                  if (v === 0 || v === 100) return v + '%';
+                  return '';
+                }
+              },
+              title: {
+                show: true,
+                offsetCenter: [0, '38%'],
+                color: '#c3dfff',
+                fontSize: 14,
+                fontWeight: 400
+              },
+              detail: {
+                valueAnimation: true,
+                offsetCenter: [0, '4%'],
+                color: '#fff',
+                fontSize: 30,
+                fontWeight: 700,
+                formatter: (v) => {
+                  return `{val|${v}}{unit|%}`;
+                },
+                rich: {
+                  val: {
+                    color: '#fff',
+                    fontSize: 30,
+                    fontWeight: 700
+                  },
+                  unit: {
+                    color: 'rgba(255,255,255,0.68)',
+                    fontSize: 14,
+                    fontWeight: 400,
+                    padding: [0, 0, 2, 2]
+                  }
+                }
+              },
+              data: [{ value, name: label }]
+            },
+            {
+              type: 'gauge',
+              center: ['50%', '62%'],
+              radius: '80%',
+              startAngle: 200,
+              endAngle: -20,
+              min: 0,
+              max: 100,
+              pointer: { show: false },
+              progress: { show: false },
+              axisLine: {
+                lineStyle: {
+                  width: 1,
+                  color: [[1, 'rgba(18, 76, 119, 0.18)']]
+                }
+              },
+              axisTick: { show: false },
+              splitLine: { show: false },
+              axisLabel: { show: false },
+              title: { show: false },
+              detail: { show: false }
+            }
+          ]
+        });
+        this.chartInstances[key] = chart;
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .rr-container {
+    color: #fff;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    background: radial-gradient(
+        circle at top center,
+        rgba(30, 113, 255, 0.18),
+        transparent 26%
+      ),
+      radial-gradient(
+        circle at center,
+        rgba(0, 148, 255, 0.08),
+        transparent 40%
+      ),
+      linear-gradient(180deg, #04132e 0%, #051d47 48%, #031229 100%);
+  }
+
+  .rr-header {
+    position: relative;
+    display: grid;
+    grid-template-columns: 1fr auto 1fr;
+    align-items: center;
+    gap: 1rem;
+    min-height: 4.6rem;
+    padding: 0 0.9rem;
+    background: radial-gradient(
+        circle at center top,
+        rgba(37, 118, 255, 0.18),
+        transparent 45%
+      ),
+      linear-gradient(180deg, rgba(8, 33, 78, 0.96), rgba(4, 19, 46, 0.78));
+    border-bottom: 1px solid rgba(59, 132, 255, 0.3);
+  }
+
+  .rr-header::before,
+  .rr-header::after {
+    content: '';
+    position: absolute;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 24rem;
+    height: 0.2rem;
+    border-radius: 999px;
+    background: linear-gradient(
+      90deg,
+      transparent,
+      rgba(95, 182, 255, 0.85),
+      transparent
+    );
+  }
+
+  .rr-header::before {
+    top: 0.25rem;
+  }
+
+  .rr-header::after {
+    bottom: 0.25rem;
+  }
+
+  .rr-header-side {
+    display: flex;
+    align-items: center;
+    gap: 0.75rem;
+    z-index: 1;
+  }
+
+  .rr-header-right {
+    justify-content: flex-end;
+  }
+
+  .rr-header-chip {
+    padding: 0.28rem 0.72rem;
+    font-size: 0.78rem;
+    color: #d8efff;
+    border: 1px solid rgba(79, 168, 255, 0.45);
+    background: linear-gradient(
+      180deg,
+      rgba(12, 74, 160, 0.78),
+      rgba(4, 37, 93, 0.72)
+    );
+    box-shadow: inset 0 0 0.75rem rgba(79, 168, 255, 0.18);
+  }
+
+  .rr-date-picker {
+    width: 16rem;
+  }
+
+  ::v-deep .rr-date-picker.el-date-editor,
+  ::v-deep .rr-date-picker .el-input__inner,
+  ::v-deep .rr-date-picker.el-range-editor.el-input__inner {
+    background-color: #011944;
+    border: 1px solid #0b6fd5;
+    color: #e9f3ff;
+    box-shadow: 0 0 4px rgba(11, 109, 213, 0.28);
+  }
+
+  ::v-deep .rr-date-picker .el-range-input,
+  ::v-deep .rr-date-picker .el-range-separator,
+  ::v-deep .rr-date-picker .el-range__icon {
+    background: transparent;
+    color: #9fc5ff;
+  }
+
+  .rr-title {
+    position: relative;
+    z-index: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    min-width: 33rem;
+    height: 1.88rem;
+    padding: 0 4.4rem 0.02rem;
+    font-family: '优设标题黑';
+    font-size: clamp(1.3rem, 1.7vw, 1.76rem);
+    font-style: italic;
+    letter-spacing: 0.01rem;
+    color: #f3fbff;
+    text-align: center;
+    text-shadow: 0 0 0.14rem rgba(255, 255, 255, 0.22),
+      0 0 0.42rem rgba(80, 184, 255, 0.14);
+    background: radial-gradient(
+        ellipse at 50% 2%,
+        rgba(209, 244, 255, 0.28),
+        rgba(209, 244, 255, 0) 48%
+      ),
+      linear-gradient(
+        90deg,
+        rgba(14, 76, 194, 0.14) 0%,
+        rgba(54, 148, 255, 0.24) 14%,
+        rgba(118, 213, 255, 0.3) 50%,
+        rgba(54, 148, 255, 0.24) 86%,
+        rgba(14, 76, 194, 0.14) 100%
+      ),
+      linear-gradient(
+        180deg,
+        rgba(55, 142, 255, 0.92) 0%,
+        rgba(33, 114, 235, 0.92) 36%,
+        rgba(11, 69, 182, 0.96) 74%,
+        rgba(7, 44, 122, 0.98) 100%
+      );
+    border: 1px solid rgba(102, 188, 255, 0.28);
+    border-top-color: rgba(177, 232, 255, 0.42);
+    border-bottom-color: rgba(80, 155, 255, 0.4);
+    clip-path: polygon(
+      0 0,
+      100% 0,
+      100% 68%,
+      98.8% 80%,
+      93% 100%,
+      7% 100%,
+      1.2% 80%,
+      0 68%
+    );
+    box-shadow: inset 0 0.05rem 0.16rem rgba(223, 248, 255, 0.14),
+      inset 0 -0.16rem 0.34rem rgba(4, 22, 74, 0.34),
+      0 0.05rem 0.18rem rgba(0, 0, 0, 0.12);
+    overflow: visible;
+  }
+
+  .rr-title::before {
+    content: '';
+    position: absolute;
+    left: 50%;
+    top: 0.08rem;
+    width: calc(100% + 3.2rem);
+    height: 0.82rem;
+    transform: translateX(-50%);
+    background: radial-gradient(
+        ellipse at 50% 10%,
+        rgba(196, 241, 255, 0.22),
+        rgba(196, 241, 255, 0) 34%
+      ),
+      linear-gradient(
+        90deg,
+        rgba(20, 83, 210, 0) 0%,
+        rgba(31, 111, 233, 0.03) 14%,
+        rgba(52, 151, 255, 0.08) 24%,
+        rgba(128, 221, 255, 0.18) 50%,
+        rgba(52, 151, 255, 0.08) 76%,
+        rgba(31, 111, 233, 0.03) 86%,
+        rgba(20, 83, 210, 0) 100%
+      );
+    clip-path: polygon(
+      0 82%,
+      10% 58%,
+      22% 28%,
+      78% 28%,
+      90% 58%,
+      100% 82%,
+      88% 100%,
+      12% 100%
+    );
+    opacity: 0.52;
+    z-index: -1;
+    filter: drop-shadow(0 0 0.12rem rgba(59, 162, 255, 0.14));
+  }
+
+  .rr-title::after {
+    content: '';
+    position: absolute;
+    left: 50%;
+    bottom: 0.06rem;
+    width: calc(100% - 4.2rem);
+    height: 0.06rem;
+    transform: translateX(-50%);
+    border-radius: 999px;
+    background: linear-gradient(
+      90deg,
+      rgba(137, 222, 255, 0) 0%,
+      rgba(137, 222, 255, 0.2) 18%,
+      rgba(212, 246, 255, 0.72) 50%,
+      rgba(137, 222, 255, 0.2) 82%,
+      rgba(137, 222, 255, 0) 100%
+    );
+    box-shadow: 0 0 0.14rem rgba(113, 214, 255, 0.12);
+  }
+
+  .rr-time-box {
+    display: flex;
+    align-items: center;
+    gap: 0.6rem;
+    color: #a9d0ff;
+    font-size: 0.82rem;
+  }
+
+  .rr-time {
+    color: #fff;
+    font-size: 1rem;
+    font-weight: 600;
+  }
+
+  .rr-weather {
+    color: #f6d067;
+    font-size: 0.82rem;
+  }
+
+  .rr-fullscreen {
+    color: #7fa7ce;
+    cursor: pointer;
+  }
+
+  .rr-body {
+    flex: 1;
+    min-height: 0;
+    display: grid;
+    grid-template-columns: 1fr 1fr 1fr;
+    gap: 0.6rem;
+    padding: 0.55rem 0.75rem 0.75rem;
+  }
+
+  .rr-side-column {
+    min-height: 0;
+    display: grid;
+    grid-template-rows: minmax(6.5rem, auto) minmax(12.4rem, 1fr) minmax(12.4rem, 1fr);
+    gap: 0.6rem;
+  }
+
+  .rr-panel,
+  .rr-map-panel {
+    position: relative;
+    min-height: 0;
+    overflow: hidden;
+    border: 1px solid rgba(50, 116, 193, 0.55);
+    background: linear-gradient(
+        180deg,
+        rgba(7, 31, 70, 0.82),
+        rgba(3, 18, 41, 0.92)
+      ),
+      linear-gradient(90deg, rgba(39, 127, 255, 0.1), transparent);
+    box-shadow: inset 0 0 1rem rgba(0, 133, 255, 0.08),
+      0 0 1rem rgba(0, 0, 0, 0.18);
+  }
+
+  .rr-panel::before,
+  .rr-map-panel::before {
+    content: '';
+    position: absolute;
+    inset: 0.25rem;
+    border: 1px solid rgba(98, 190, 255, 0.08);
+    pointer-events: none;
+  }
+
+  .rr-panel {
+    display: flex;
+    flex-direction: column;
+    padding: 0;
+  }
+
+  .rr-panel-title {
+    margin-bottom: 0;
+    min-height: 2rem;
+    display: flex;
+    align-items: center;
+    padding: 0.2rem 0.6rem 0.2rem 1.75rem;
+    font-family: '优设标题黑';
+    font-size: 1rem;
+    color: #d6ebff;
+    letter-spacing: 0.06rem;
+    position: relative;
+    background: linear-gradient(180deg, #004085, #003568);
+    border-bottom: 1px solid rgba(18, 76, 119, 0.9);
+    flex-shrink: 0;
+  }
+
+  .rr-panel-title::before {
+    content: '';
+    position: absolute;
+    left: 0.6rem;
+    top: 50%;
+    width: 0.72rem;
+    height: 0.96rem;
+    transform: translateY(-50%);
+    background-image: url('@/assets/renewable_icon_1.svg');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    background-position: center;
+  }
+
+  .rr-panel-sales {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .rr-summary-strip {
+    position: relative;
+    display: flex;
+    flex: 1 1 auto;
+    align-items: center;
+    justify-content: center;
+    min-height: 0;
+    padding: 0.5rem 0.55rem;
+    overflow: hidden;
+    background: radial-gradient(
+        circle at center,
+        rgba(57, 137, 255, 0.06),
+        transparent 55%
+      ),
+      linear-gradient(180deg, rgba(5, 24, 66, 0.18), rgba(5, 24, 66, 0));
+  }
+
+  .rr-summary-item {
+    position: relative;
+    display: grid;
+    grid-template-columns: clamp(2rem, 2.6vw, 2.6rem) minmax(0, 1fr);
+    align-items: center;
+    flex: 1 1 0;
+    max-width: none;
+    min-width: 0;
+    gap: clamp(0.24rem, 0.35vw, 0.4rem);
+    padding: 0 0.15rem;
+  }
+
+  .rr-summary-divider {
+    position: absolute;
+    right: 0;
+    top: 14%;
+    width: 1px;
+    height: 72%;
+    background: linear-gradient(
+      180deg,
+      rgba(58, 126, 209, 0),
+      rgba(58, 126, 209, 0.45),
+      rgba(58, 126, 209, 0)
+    );
+  }
+
+  .rr-summary-icon-box {
+    width: clamp(2rem, 2.6vw, 2.6rem);
+    flex: 0 0 clamp(2rem, 2.6vw, 2.6rem);
+    display: flex;
+    justify-content: center;
+  }
+
+  .rr-summary-icon-wrap {
+    position: relative;
+    width: clamp(2rem, 2.6vw, 2.6rem);
+    height: clamp(2rem, 2.6vw, 2.6rem);
+    flex-shrink: 0;
+  }
+
+  .rr-summary-icon-ring {
+    position: absolute;
+    inset: 0;
+    border-radius: 50%;
+    border: 1px solid rgba(125, 194, 255, 0.45);
+    box-shadow: 0 0 0 0.15rem rgba(41, 118, 255, 0.18),
+      inset 0 0 0.7rem rgba(91, 176, 255, 0.22);
+  }
+
+  .rr-summary-icon {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    width: clamp(1.4rem, 1.8vw, 1.9rem);
+    height: clamp(1.4rem, 1.8vw, 1.9rem);
+    border-radius: 50%;
+    transform: translate(-50%, -50%);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 1.5rem;
+    font-weight: 700;
+    color: #f3fbff;
+    background: radial-gradient(
+      circle at 35% 30%,
+      rgba(124, 198, 255, 0.95),
+      rgba(43, 112, 232, 0.96) 70%
+    );
+    box-shadow: 0 0 1rem rgba(69, 153, 255, 0.42),
+      inset 0 -0.35rem 0.75rem rgba(9, 34, 86, 0.4);
+  }
+
+  .rr-summary-icon-img {
+    width: 60%;
+    height: 60%;
+    object-fit: contain;
+    filter: drop-shadow(0 0 0.35rem rgba(255, 255, 255, 0.16));
+  }
+
+  .rr-summary-content {
+    min-width: 0;
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    justify-content: center;
+    overflow: hidden;
+    text-align: left;
+    z-index: 1;
+  }
+
+  .rr-summary-label {
+    color: #d9ebff;
+    font-size: clamp(0.48rem, 0.58vw, 0.64rem);
+    letter-spacing: 0.02rem;
+    line-height: 1.2;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    text-shadow: 0 0 0.35rem rgba(79, 171, 255, 0.18);
+  }
+
+  .rr-summary-main {
+    display: flex;
+    align-items: baseline;
+    justify-content: flex-start;
+    gap: 0.06rem;
+    margin-top: 0.08rem;
+    width: 100%;
+    min-width: 0;
+    flex-wrap: nowrap;
+    overflow: hidden;
+  }
+
+  .rr-summary-value {
+    color: #fff;
+    font-size: clamp(0.8rem, 1vw, 1.1rem);
+    line-height: 1;
+    font-weight: 700;
+    letter-spacing: 0.01rem;
+    white-space: nowrap;
+    text-shadow: 0 0 0.55rem rgba(255, 255, 255, 0.12);
+  }
+
+  .rr-summary-unit {
+    color: rgba(255, 255, 255, 0.72);
+    font-size: clamp(0.36rem, 0.42vw, 0.48rem);
+    line-height: 1;
+    margin-bottom: 0.02rem;
+    white-space: nowrap;
+  }
+
+  .rr-summary-trend {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    justify-content: flex-end;
+    gap: 0.02rem;
+    min-width: 0;
+    margin-left: 0.08rem;
+    padding-bottom: 0.02rem;
+    font-size: clamp(0.3rem, 0.36vw, 0.4rem);
+    white-space: nowrap;
+    flex-shrink: 1;
+    overflow: hidden;
+  }
+
+  .rr-summary-trend-label {
+    color: #8db2db;
+    line-height: 1.2;
+  }
+
+  .rr-summary-trend-value {
+    font-size: clamp(0.32rem, 0.38vw, 0.42rem);
+    font-weight: 600;
+    line-height: 1.1;
+  }
+
+  .rr-summary-trend.up .rr-summary-trend-value {
+    color: #2bd38e;
+  }
+
+  .rr-summary-trend.warn .rr-summary-trend-value {
+    color: #ff8a65;
+  }
+
+  .rr-chart-panel,
+  .rr-mini-bar-panel,
+  .rr-fill-chart,
+  .rr-native-chart,
+  .rr-map-body {
+    width: 100%;
+    height: 100%;
+    min-height: 0;
+  }
+
+  .rr-chart-panel {
+    flex: 1;
+    min-height: 9rem;
+    padding: 0.55rem 0.7rem 0;
+  }
+
+  .rr-mini-bar-panel {
+    height: 6.2rem;
+    margin-top: 0.2rem;
+    padding: 0 0.7rem 0.55rem;
+  }
+
+  .rr-procurement-body {
+    display: flex;
+    flex: 1;
+    min-height: 0;
+    padding: 0.7rem 0.75rem 0.75rem;
+    gap: 0.75rem;
+  }
+
+  .rr-procurement-pane {
+    min-width: 0;
+    min-height: 0;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .rr-procurement-pane-area {
+    flex: 1.1;
+  }
+
+  .rr-procurement-pane-bar {
+    flex: 0.9;
+  }
+
+  .rr-pane-caption {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 0.5rem;
+    min-height: 1.2rem;
+    padding: 0 0.15rem;
+    color: #cfe6ff;
+    font-size: 0.72rem;
+  }
+
+  .rr-pane-caption-right {
+    justify-content: flex-start;
+  }
+
+  .rr-pane-legend {
+    display: flex;
+    align-items: center;
+    gap: 0.8rem;
+    color: #d6ebff;
+  }
+
+  .rr-legend-item {
+    position: relative;
+    padding-left: 0.9rem;
+    white-space: nowrap;
+  }
+
+  .rr-legend-item::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 50%;
+    width: 0.5rem;
+    height: 0.12rem;
+    transform: translateY(-50%);
+    border-radius: 999px;
+  }
+
+  .rr-legend-item-blue::before {
+    background: #3c87ff;
+    box-shadow: 0 0 0.35rem rgba(60, 135, 255, 0.7);
+  }
+
+  .rr-legend-item-gold::before {
+    background: #e5b15d;
+    box-shadow: 0 0 0.35rem rgba(229, 177, 93, 0.7);
+  }
+
+  .rr-chart-panel-compact {
+    padding: 0.15rem 0 0;
+  }
+
+  .rr-mini-bar-panel-fill {
+    flex: 1;
+    height: auto;
+    min-height: 0;
+    margin-top: 0;
+    padding: 0.15rem 0 0;
+  }
+
+  .rr-inventory-body {
+    flex: 1;
+    min-height: 0;
+    display: flex;
+    gap: 0.4rem;
+    padding: 0.5rem 0.6rem;
+  }
+
+  .rr-inv-left {
+    flex: 0 0 48%;
+    position: relative;
+    min-height: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .rr-inv-right {
+    flex: 1;
+    min-width: 0;
+    min-height: 0;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .rr-inv-chart-wrap {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    min-height: 8rem;
+  }
+
+  .rr-inv-center {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    text-align: center;
+    pointer-events: none;
+  }
+
+  .rr-inv-center-value {
+    display: block;
+    color: #fff;
+    font-size: clamp(1.1rem, 1.5vw, 1.7rem);
+    font-weight: 700;
+    line-height: 1;
+    text-shadow: 0 0 0.6rem rgba(60, 135, 255, 0.3);
+  }
+
+  .rr-inv-center-label {
+    display: block;
+    margin-top: 0.15rem;
+    color: #b4d4f2;
+    font-size: clamp(0.58rem, 0.7vw, 0.78rem);
+  }
+
+  .rr-inv-trend-caption {
+    flex-shrink: 0;
+    color: #d4ebff;
+    font-size: clamp(0.68rem, 0.8vw, 0.88rem);
+    padding: 0.15rem 0.3rem 0;
+    line-height: 1.4;
+  }
+
+  .rr-inv-trend-chart {
+    position: relative;
+    flex: 1;
+    min-height: 0;
+  }
+
+  .rr-map-panel {
+    display: flex;
+    flex-direction: column;
+    padding: 0;
+  }
+
+  .rr-map-head {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 0.75rem;
+    min-height: 2.2rem;
+    padding: 0.35rem 0.75rem 0.2rem;
+  }
+
+  .rr-map-tabs {
+    display: flex;
+    gap: 0.5rem;
+  }
+
+  .rr-tab {
+    min-width: 3.6rem;
+    padding: 0.28rem 0.9rem;
+    text-align: center;
+    font-size: 0.76rem;
+    color: #8fc0ff;
+    border: 1px solid rgba(61, 128, 206, 0.45);
+    background: rgba(5, 28, 62, 0.78);
+    cursor: pointer;
+  }
+
+  .rr-tab.active {
+    color: #fff;
+    background: linear-gradient(180deg, #2d84ff, #1163fb);
+    box-shadow: 0 0 0.75rem rgba(17, 99, 251, 0.3);
+  }
+
+  .rr-map-summary {
+    display: flex;
+    gap: 0.45rem;
+  }
+
+  .rr-map-summary-item {
+    min-width: 4.8rem;
+    padding: 0.3rem 0.55rem;
+    text-align: center;
+    font-size: 0.72rem;
+    color: #a9d0ff;
+    background: rgba(6, 34, 82, 0.68);
+    border: 1px solid rgba(55, 120, 196, 0.4);
+  }
+
+  .rr-map-summary-item strong {
+    display: block;
+    margin-top: 0.15rem;
+    color: #fff;
+    font-size: 1rem;
+  }
+
+  .rr-map-body {
+    flex: 1;
+    padding: 0.2rem 0.35rem 0.35rem;
+  }
+
+  .rr-quality-grid {
+    flex: 1;
+    min-height: 0;
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 0.65rem;
+    padding: 0.75rem;
+  }
+
+  .rr-quality-card {
+    padding: 0.75rem;
+    border: 1px solid rgba(55, 120, 196, 0.4);
+    background: rgba(6, 34, 82, 0.6);
+  }
+
+  .rr-quality-header {
+    display: flex;
+    align-items: center;
+    gap: 0.4rem;
+    color: #cfe6ff;
+    font-size: 0.82rem;
+  }
+
+  .rr-quality-dot {
+    width: 0.5rem;
+    height: 0.5rem;
+    border-radius: 50%;
+    background: #49b2ff;
+    box-shadow: 0 0 0.4rem rgba(73, 178, 255, 0.9);
+  }
+
+  .rr-quality-rate {
+    margin: 0.55rem 0 0.75rem;
+    font-size: 2rem;
+    font-weight: 700;
+    color: #fff;
+  }
+
+  .rr-progress-row {
+    display: flex;
+    justify-content: space-between;
+    margin-top: 0.3rem;
+    font-size: 0.72rem;
+    color: #9fc5ff;
+  }
+
+  .rr-progress-row strong {
+    color: #fff;
+  }
+
+  .rr-progress-track {
+    height: 0.42rem;
+    margin-top: 0.22rem;
+    border-radius: 999px;
+    background: rgba(17, 54, 115, 0.85);
+    overflow: hidden;
+  }
+
+  .rr-progress-fill {
+    display: block;
+    height: 100%;
+    border-radius: inherit;
+  }
+
+  .rr-progress-fill-good {
+    background: linear-gradient(90deg, #21d07a, rgba(33, 208, 122, 0.2));
+  }
+
+  .rr-progress-fill-bad {
+    background: linear-gradient(90deg, #ff8a65, rgba(255, 138, 101, 0.2));
+  }
+
+  .rr-equipment-body {
+    flex: 1;
+    min-height: 0;
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 0.65rem;
+    padding: 0.75rem;
+  }
+
+  .rr-equipment-gauge {
+    display: flex;
+    flex-direction: column;
+    gap: 0.45rem;
+    min-height: 0;
+  }
+
+  .rr-gauge-wrap {
+    position: relative;
+    flex: 1;
+    min-height: 7rem;
+  }
+
+  .rr-equipment-list {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+  }
+
+  .rr-equipment-list li {
+    display: flex;
+    justify-content: space-between;
+    gap: 0.6rem;
+    padding: 0.38rem 0.48rem;
+    margin-top: 0.28rem;
+    font-size: 0.74rem;
+    color: #b9d7ef;
+    background: rgba(8, 35, 79, 0.66);
+    border: 1px solid rgba(39, 99, 170, 0.4);
+  }
+
+  .rr-equipment-list strong {
+    color: #fff;
+  }
+
+  @media (max-width: 1600px) {
+    .rr-side-column {
+      grid-template-rows: minmax(6rem, auto) minmax(11rem, 1fr) minmax(11rem, 1fr);
+    }
+
+    .rr-summary-strip {
+      padding: 0.4rem 0.35rem;
+    }
+
+    .rr-summary-item {
+      gap: 0.2rem;
+      padding: 0 0.1rem;
+      grid-template-columns: 1.9rem minmax(0, 1fr);
+    }
+
+    .rr-summary-icon-box {
+      width: 1.9rem;
+      flex: 0 0 1.9rem;
+    }
+
+    .rr-summary-icon-wrap {
+      width: 1.9rem;
+      height: 1.9rem;
+    }
+
+    .rr-summary-icon {
+      width: 1.35rem;
+      height: 1.35rem;
+    }
+
+    .rr-summary-label {
+      font-size: 0.42rem;
+    }
+
+    .rr-summary-value {
+      font-size: 0.72rem;
+    }
+
+    .rr-summary-unit {
+      font-size: 0.32rem;
+    }
+
+    .rr-summary-trend {
+      font-size: 0.28rem;
+      margin-left: 0.06rem;
+    }
+
+    .rr-summary-trend-value {
+      font-size: 0.3rem;
+    }
+  }
+
+  @media (min-width: 1800px) {
+    .rr-summary-strip {
+      padding: 0.55rem 0.6rem;
+    }
+  }
+
+  @media (max-width: 1280px) {
+    .rr-summary-strip {
+      padding: 0.35rem 0.3rem;
+    }
+
+    .rr-summary-item {
+      gap: 0.16rem;
+      padding: 0 0.06rem;
+      grid-template-columns: 1.75rem minmax(0, 1fr);
+    }
+
+    .rr-summary-icon-box {
+      width: 1.75rem;
+      flex: 0 0 1.75rem;
+    }
+
+    .rr-summary-icon-wrap {
+      width: 1.75rem;
+      height: 1.75rem;
+    }
+
+    .rr-summary-icon {
+      width: 1.2rem;
+      height: 1.2rem;
+    }
+
+    .rr-summary-label {
+      font-size: 0.38rem;
+    }
+
+    .rr-summary-value {
+      font-size: 0.65rem;
+    }
+
+    .rr-summary-unit {
+      font-size: 0.28rem;
+    }
+
+    .rr-summary-trend {
+      font-size: 0.26rem;
+      margin-left: 0.05rem;
+    }
+
+    .rr-summary-trend-value {
+      font-size: 0.28rem;
+    }
+  }
+
+  @media (max-width: 1366px) {
+    .rr-title {
+      min-width: 27rem;
+      height: 1.7rem;
+      padding: 0 3.6rem 0.02rem;
+      letter-spacing: 0;
+    }
+
+    .rr-title::before {
+      width: calc(100% + 2.2rem);
+      height: 0.72rem;
+    }
+
+    .rr-title::after {
+      width: calc(100% - 3.4rem);
+    }
+
+    .rr-body {
+      grid-template-columns: 1fr;
+      grid-template-rows: auto auto auto;
+      overflow: auto;
+    }
+
+    .rr-side-column {
+      grid-template-columns: 1fr;
+      grid-template-rows: repeat(3, minmax(12rem, auto));
+    }
+
+    .rr-map-panel {
+      min-height: 28rem;
+    }
+
+    .rr-map-head {
+      flex-wrap: wrap;
+    }
+
+    .rr-procurement-body,
+    .rr-inventory-body {
+      padding: 0.4rem;
+    }
+
+    .rr-inventory-body {
+      flex-direction: column;
+    }
+
+    .rr-inv-left {
+      flex: 0 0 auto;
+      width: 100%;
+      min-height: 12rem;
+    }
+
+    .rr-inv-right {
+      min-height: 10rem;
+    }
+  }
+
+  @media (max-width: 520px) {
+    .rr-title {
+      min-width: 15.8rem;
+      height: 1.46rem;
+      padding: 0 1.8rem 0;
+      letter-spacing: 0;
+    }
+
+    .rr-title::before {
+      width: calc(100% + 1.2rem);
+      height: 0.56rem;
+    }
+
+    .rr-title::after {
+      width: calc(100% - 2.6rem);
+      bottom: 0.04rem;
+    }
+
+    .rr-summary-strip {
+      justify-content: flex-start;
+      flex-direction: column;
+      gap: 0.6rem;
+    }
+
+    .rr-summary-item {
+      padding: 0;
+      max-width: none;
+      grid-template-columns: 1.75rem minmax(0, 1fr);
+    }
+
+    .rr-summary-icon-box {
+      width: 1.75rem;
+      flex: 0 0 1.75rem;
+    }
+
+    .rr-summary-icon-wrap {
+      width: 1.75rem;
+      height: 1.75rem;
+    }
+
+    .rr-summary-icon {
+      width: 1.2rem;
+      height: 1.2rem;
+    }
+
+    .rr-summary-label {
+      font-size: 0.42rem;
+    }
+
+    .rr-summary-value {
+      font-size: 0.7rem;
+    }
+
+    .rr-summary-unit {
+      font-size: 0.3rem;
+    }
+
+    .rr-summary-divider {
+      display: none;
+    }
+
+    .rr-summary-trend {
+      margin-left: 0.06rem;
+      font-size: 0.28rem;
+    }
+
+    .rr-summary-trend-value {
+      font-size: 0.3rem;
+    }
+
+    .rr-procurement-body {
+      padding: 0.6rem;
+    }
+
+    .rr-inventory-body {
+      padding: 0.4rem;
+    }
+  }
+</style>
+
+<style>
+  .el-icon-_screen-full,
+  .el-icon-_screen-restore {
+    font-size: 1.2rem;
+    cursor: pointer;
+    transition: all 0.3s;
+    color: #7fa7ce;
+  }
+
+  .el-icon-_screen-full:hover,
+  .el-icon-_screen-restore:hover {
+    color: #fff;
+    transform: scale(1.1);
+  }
+</style>

+ 2 - 2
vue.config.js

@@ -36,8 +36,8 @@ module.exports = {
         // target: 'http://192.168.1.139:18086', // 粟
         // target: 'http://192.168.1.132:18086', // 徐1
         // target: 'http://192.168.1.134:18086', //徐2
-        // target: 'http://192.168.1.125:18086',
-        target: 'http://192.168.1.251:18086',
+        target: 'http://192.168.1.125:18086',
+        // target: 'http://192.168.1.251:18086',
         // target: 'http://192.168.1.251:18186', // 测试环境
         changeOrigin: true, // 只有这个值为true的情况下 才表示开启跨域
         pathRewrite: {

Некоторые файлы не были показаны из-за большого количества измененных файлов