xieyonghong преди 3 години
родител
ревизия
90bab1ca57
променени са 65 файла, в които са добавени 1333 реда и са изтрити 303 реда
  1. BIN
      public/images/cloud/dueros-doc1.png
  2. BIN
      public/images/cloud/dueros-doc2.png
  3. BIN
      public/images/cloud/dueros-doc3.png
  4. 57 0
      public/images/device/device-number.svg
  5. 67 0
      public/images/device/device-product.svg
  6. BIN
      public/images/home/content1.png
  7. 57 0
      public/images/home/top-1.svg
  8. 67 0
      public/images/home/top-2.svg
  9. 57 0
      public/images/media/dashboard-1.svg
  10. 62 0
      public/images/media/dashboard-2.svg
  11. 115 0
      public/images/media/dashboard-3.svg
  12. 81 0
      public/images/media/dashboard-4.svg
  13. 2 1
      src/app.tsx
  14. 3 3
      src/components/ProTableCard/CardItems/DataCollect/channel.tsx
  15. 4 1
      src/components/ProTableCard/CardItems/cascade.tsx
  16. 8 0
      src/components/ProTableCard/index.less
  17. 8 0
      src/pages/DataCollect/Channel/index.tsx
  18. 6 8
      src/pages/DataCollect/Collector/components/Device/Save/index.tsx
  19. 17 11
      src/pages/DataCollect/Collector/components/Point/index.tsx
  20. 53 28
      src/pages/DataCollect/Collector/components/Tree/index.tsx
  21. 15 1
      src/pages/DataCollect/Collector/index.tsx
  22. 8 7
      src/pages/Northbound/DuerOS/Detail/Doc.tsx
  23. 2 2
      src/pages/device/DashBoard/index.tsx
  24. 126 62
      src/pages/device/Firmware/Task/Detail/index.tsx
  25. 1 1
      src/pages/device/Firmware/Task/Save/index.tsx
  26. 29 26
      src/pages/device/Firmware/Task/index.tsx
  27. 1 1
      src/pages/device/Firmware/index.tsx
  28. 111 29
      src/pages/device/Instance/Detail/ChildDevice/index.tsx
  29. 9 7
      src/pages/device/Instance/Detail/EdgeMap/mapTable/index.tsx
  30. 4 3
      src/pages/device/Instance/Detail/EdgeMap/mapTree/index.tsx
  31. 24 6
      src/pages/device/Instance/Detail/MapChannel/index.tsx
  32. 8 4
      src/pages/device/Instance/Detail/Parsing/index.tsx
  33. 1 1
      src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx
  34. 30 7
      src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx
  35. 34 10
      src/pages/device/Instance/Detail/Running/Property/index.tsx
  36. 17 7
      src/pages/device/Instance/Detail/Tags/Edit.tsx
  37. 1 0
      src/pages/device/Instance/Detail/Tags/index.tsx
  38. 1 1
      src/pages/device/components/Metadata/Base/index.tsx
  39. 8 8
      src/pages/edge/Resource/Issue/Result.tsx
  40. 1 1
      src/pages/home/components/CardStatics.tsx
  41. 1 1
      src/pages/home/components/Statistics.tsx
  42. 2 2
      src/pages/home/comprehensive/index.tsx
  43. 1 1
      src/pages/home/device/index.tsx
  44. 30 0
      src/pages/iot-card/CardManagement/SaveModal.tsx
  45. 2 2
      src/pages/iot-card/CardManagement/index.tsx
  46. 2 0
      src/pages/iot-card/CardManagement/service.ts
  47. 12 3
      src/pages/iot-card/Platform/index.tsx
  48. 2 0
      src/pages/media/Cascade/index.tsx
  49. 4 4
      src/pages/media/DashBoard/index.tsx
  50. 2 2
      src/pages/media/Home/index.tsx
  51. 8 0
      src/pages/media/Stream/index.tsx
  52. 4 5
      src/pages/notice/Config/Detail/doc/AliyunVoice.tsx
  53. 8 9
      src/pages/notice/Config/Detail/index.tsx
  54. 119 0
      src/pages/notice/Config/Detail/regionId.ts
  55. 7 4
      src/pages/notice/Template/Detail/index.tsx
  56. 2 0
      src/pages/rule-engine/Instance/Save/index.tsx
  57. 1 2
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/ObjModel.tsx
  58. 5 0
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/ReadProperty.tsx
  59. 3 2
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/TypeModel.tsx
  60. 11 2
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/WriteProperty.tsx
  61. 4 1
      src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx
  62. 3 4
      src/pages/system/Department/Assets/deivce/index.tsx
  63. 4 4
      src/pages/system/Department/Assets/product/index.tsx
  64. 0 18
      src/pages/system/Menu/Setting/baseMenu.ts
  65. 1 1
      src/pages/system/User/Save/index.tsx

BIN
public/images/cloud/dueros-doc1.png


BIN
public/images/cloud/dueros-doc2.png


BIN
public/images/cloud/dueros-doc3.png


+ 57 - 0
public/images/device/device-number.svg

@@ -0,0 +1,57 @@
+<svg width="92" height="91" viewBox="0 0 92 91" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.56306 81.9135L45.5027 58.4234L86.4422 81.9135L86.4422 91.0396L45.5026 113.996L4.56314 91.0397L4.56306 81.9135Z" fill="white"/>
+<path d="M4.92969 82.5615L46.2592 105.436V114.254L4.92969 91.3798V82.5615Z" fill="url(#paint0_linear_2942_6715)"/>
+<path d="M87.0684 82.5615L45.7389 105.436V114.254L87.0684 91.3798V82.5615Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="5.41211" y1="22.7676" x2="5.41211" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="45.9277" y1="4.57666" x2="45.9277" y2="36.6577" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="86.0352" y1="22.7676" x2="86.0351" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M45.3579 0L41.6543 3.70362L45.3579 7.40725L49.0615 3.70362L45.3579 0ZM45.3579 1.85181L43.506 3.70362L45.3579 5.55543L47.2097 3.70362L45.3579 1.85181Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1196 20.4336L82.416 24.1372L86.1196 27.8408L89.8233 24.1372L86.1196 20.4336ZM86.1196 22.2854L84.2678 24.1372L86.1196 25.989L87.9714 24.1372L86.1196 22.2854Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.8423 20.4336L1.13867 24.1372L4.8423 27.8408L8.54592 24.1372L4.8423 20.4336ZM4.84224 22.2854L2.99042 24.1372L4.84224 25.989L6.69405 24.1372L4.84224 22.2854Z" fill="#4980F7"/>
+</g>
+<path d="M86.4213 83.2303V38.2187L45.5017 15.4351L4.58203 38.2187V83.2303L45.5017 105.458L86.4213 83.2303Z" fill="white"/>
+<path d="M45.5017 16.0073L85.9213 38.5126V82.9329L45.5017 104.889L5.08203 82.9329V38.5126L45.5017 16.0073Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M86.0533 38.3097L45.502 15.5583V60.2017L86.0533 81.93V38.3097Z" fill="url(#paint1_linear_2942_6715)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M5.2168 82.5623L45.5015 60.2822L87.096 82.5623L87.096 82.5224L46.1564 105.479L5.2168 82.5623Z" fill="url(#paint2_linear_2942_6715)"/>
+<rect x="44.4785" y="15.8469" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58203" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58203" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<path d="M46.558 30.875L71.116 43.0039L46.558 54.9314L22 43.0039L46.558 30.875Z" fill="url(#paint3_linear_2942_6715)"/>
+<path d="M71.1166 43.0073L46.5586 54.9348V90.2174L71.1166 78.29V43.0073Z" fill="url(#paint4_linear_2942_6715)"/>
+<path d="M46.558 54.9348L22 43.0073V78.29L46.558 90.2174V54.9348Z" fill="url(#paint5_linear_2942_6715)"/>
+<path d="M50.0664 58.5516L68.5096 49.731V52.1366L50.0664 60.9573V58.5516Z" fill="#DFE7FF"/>
+<path d="M50.0664 69.7733L68.5096 60.9526V63.3583L50.0664 72.1789V69.7733Z" fill="#DFE7FF"/>
+<path d="M50.0664 81.0074L68.5096 72.1868V74.5924L50.0664 83.4131V81.0074Z" fill="#DFE7FF"/>
+<ellipse cx="25.9816" cy="51.4576" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 51.4576)" fill="#D0DBFF"/>
+<ellipse cx="25.9816" cy="62.6795" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 62.6795)" fill="#D0DBFF"/>
+<ellipse cx="25.9816" cy="73.9012" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 73.9012)" fill="#D0DBFF"/>
+<defs>
+<linearGradient id="paint0_linear_2942_6715" x1="8.51207" y1="91.3851" x2="42.5572" y2="109.717" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2942_6715" x1="65.7776" y1="15.5583" x2="65.7776" y2="81.93" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2942_6715" x1="25.6761" y1="62.0627" x2="66.6355" y2="103.022" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2942_6715" x1="46.558" y1="30.875" x2="46.558" y2="90.214" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#ADC6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2942_6715" x1="50.7446" y1="57.0796" x2="67.4916" y2="57.2512" gradientUnits="userSpaceOnUse">
+<stop stop-color="#A0B8FF"/>
+<stop offset="0.963422" stop-color="#6A8DFF"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2942_6715" x1="26.186" y1="57.0796" x2="42.933" y2="57.2512" gradientUnits="userSpaceOnUse">
+<stop stop-color="#92B2FF"/>
+<stop offset="1" stop-color="#ADC2FE"/>
+</linearGradient>
+</defs>
+</svg>

+ 67 - 0
public/images/device/device-product.svg

@@ -0,0 +1,67 @@
+<svg width="92" height="91" viewBox="0 0 92 91" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.56306 81.9135L45.5027 58.4234L86.4422 81.9135L86.4422 91.0396L45.5026 113.996L4.56314 91.0397L4.56306 81.9135Z" fill="white"/>
+<path d="M4.92871 82.5615L46.2582 105.436V114.254L4.92871 91.3798V82.5615Z" fill="url(#paint0_linear_2942_6631)"/>
+<path d="M87.0684 82.5615L45.7389 105.436V114.254L87.0684 91.3798V82.5615Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="5.41309" y1="22.7676" x2="5.41308" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="45.9287" y1="4.57666" x2="45.9287" y2="36.6577" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="86.0371" y1="22.7676" x2="86.0371" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M45.3589 0L41.6553 3.70362L45.3589 7.40725L49.0625 3.70362L45.3589 0ZM45.3588 1.85181L43.507 3.70362L45.3588 5.55543L47.2106 3.70362L45.3588 1.85181Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1216 20.4336L82.418 24.1372L86.1216 27.8408L89.8252 24.1372L86.1216 20.4336ZM86.1215 22.2854L84.2697 24.1372L86.1215 25.989L87.9733 24.1372L86.1215 22.2854Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.84327 20.4336L1.13965 24.1372L4.84327 27.8408L8.5469 24.1372L4.84327 20.4336ZM4.84321 22.2854L2.9914 24.1372L4.84321 25.989L6.69502 24.1372L4.84321 22.2854Z" fill="#4980F7"/>
+</g>
+<path d="M86.4223 83.2303V38.2187L45.5026 15.4351L4.58301 38.2187V83.2303L45.5026 105.458L86.4223 83.2303Z" fill="white"/>
+<path d="M45.5026 16.0073L85.9223 38.5126V82.9329L45.5026 104.889L5.08301 82.9329V38.5126L45.5026 16.0073Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M86.0543 38.3097L45.5029 15.5583V60.2017L86.0543 81.93V38.3097Z" fill="url(#paint1_linear_2942_6631)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M5.21777 82.5623L45.5025 60.2822L87.097 82.5623L87.0969 82.5224L46.1574 105.479L5.21777 82.5623Z" fill="url(#paint2_linear_2942_6631)"/>
+<rect x="44.4795" y="15.8469" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58301" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58301" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<path d="M15.7725 44.9007L45.4099 31L74.2605 44.9007L45.4099 60.8997L15.7725 44.9007Z" fill="url(#paint3_linear_2942_6631)"/>
+<path d="M30.46 45.431L45.0793 38.6025L59.3105 45.431L45.0793 53.2901L30.46 45.431Z" fill="url(#paint4_linear_2942_6631)"/>
+<path d="M15.7725 76.3798V44.906L45.4099 60.9054V95.0015L15.7725 76.3798Z" fill="#D7DBFB"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M28.9119 58.7642L21.3242 54.7348L21.3243 54.022L29.5442 58.4481L30.4927 61.0579L35.39 63.9437L35.3901 64.7039L29.9063 61.5846L28.9119 58.7642Z" fill="url(#paint5_linear_2942_6631)"/>
+<path d="M21.3242 72.4324V58.2209V55.6917L28.5957 59.4855L29.228 62.0147L38.3964 67.0729V82.5476L21.3242 72.4324Z" fill="url(#paint6_linear_2942_6631)"/>
+<path d="M74.2607 75.8548L45.4102 95.0011V60.905L74.2607 44.906V75.8548Z" fill="url(#paint7_linear_2942_6631)"/>
+<path d="M66.6541 72.9249L53.0156 82.1472V65.7239L66.6541 58.0176V72.9249Z" fill="url(#paint8_linear_2942_6631)"/>
+<defs>
+<linearGradient id="paint0_linear_2942_6631" x1="8.5111" y1="91.3851" x2="42.5562" y2="109.717" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2942_6631" x1="65.7786" y1="15.5583" x2="65.7786" y2="81.93" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2942_6631" x1="25.6771" y1="62.0627" x2="66.6365" y2="103.022" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2942_6631" x1="45.0165" y1="31" x2="45.0165" y2="60.8997" gradientUnits="userSpaceOnUse">
+<stop stop-color="#ADC6FF"/>
+<stop offset="1" stop-color="#ADC6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2942_6631" x1="44.8852" y1="37.9337" x2="44.8852" y2="52.9485" gradientUnits="userSpaceOnUse">
+<stop stop-color="#7699FD" stop-opacity="0.38"/>
+<stop offset="1" stop-color="#7699FD"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2942_6631" x1="23.3602" y1="56.3189" x2="28.4977" y2="68.2627" gradientUnits="userSpaceOnUse">
+<stop stop-color="#007C52"/>
+<stop offset="1" stop-color="#007C52" stop-opacity="0.25"/>
+</linearGradient>
+<linearGradient id="paint6_linear_2942_6631" x1="24.2342" y1="63.6968" x2="35.8758" y2="63.8426" gradientUnits="userSpaceOnUse">
+<stop stop-color="#6F9AFE"/>
+<stop offset="1" stop-color="#A6BDFF"/>
+</linearGradient>
+<linearGradient id="paint7_linear_2942_6631" x1="74.3178" y1="60.1441" x2="45.7442" y2="82.4264" gradientUnits="userSpaceOnUse">
+<stop stop-color="#97B6FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint8_linear_2942_6631" x1="55.3404" y1="65.21" x2="64.6407" y2="65.3136" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B9CBFF"/>
+<stop offset="0.963422" stop-color="#6A8DFF"/>
+</linearGradient>
+</defs>
+</svg>

BIN
public/images/home/content1.png


+ 57 - 0
public/images/home/top-1.svg

@@ -0,0 +1,57 @@
+<svg width="92" height="91" viewBox="0 0 92 91" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.56306 81.9135L45.5027 58.4234L86.4422 81.9135L86.4422 91.0396L45.5026 113.996L4.56314 91.0397L4.56306 81.9135Z" fill="white"/>
+<path d="M4.92969 82.5615L46.2592 105.436V114.254L4.92969 91.3798V82.5615Z" fill="url(#paint0_linear_2942_6715)"/>
+<path d="M87.0684 82.5615L45.7389 105.436V114.254L87.0684 91.3798V82.5615Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="5.41211" y1="22.7676" x2="5.41211" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="45.9277" y1="4.57666" x2="45.9277" y2="36.6577" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="86.0352" y1="22.7676" x2="86.0351" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M45.3579 0L41.6543 3.70362L45.3579 7.40725L49.0615 3.70362L45.3579 0ZM45.3579 1.85181L43.506 3.70362L45.3579 5.55543L47.2097 3.70362L45.3579 1.85181Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1196 20.4336L82.416 24.1372L86.1196 27.8408L89.8233 24.1372L86.1196 20.4336ZM86.1196 22.2854L84.2678 24.1372L86.1196 25.989L87.9714 24.1372L86.1196 22.2854Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.8423 20.4336L1.13867 24.1372L4.8423 27.8408L8.54592 24.1372L4.8423 20.4336ZM4.84224 22.2854L2.99042 24.1372L4.84224 25.989L6.69405 24.1372L4.84224 22.2854Z" fill="#4980F7"/>
+</g>
+<path d="M86.4213 83.2303V38.2187L45.5017 15.4351L4.58203 38.2187V83.2303L45.5017 105.458L86.4213 83.2303Z" fill="white"/>
+<path d="M45.5017 16.0073L85.9213 38.5126V82.9329L45.5017 104.889L5.08203 82.9329V38.5126L45.5017 16.0073Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M86.0533 38.3097L45.502 15.5583V60.2017L86.0533 81.93V38.3097Z" fill="url(#paint1_linear_2942_6715)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M5.2168 82.5623L45.5015 60.2822L87.096 82.5623L87.096 82.5224L46.1564 105.479L5.2168 82.5623Z" fill="url(#paint2_linear_2942_6715)"/>
+<rect x="44.4785" y="15.8469" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58203" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58203" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<path d="M46.558 30.875L71.116 43.0039L46.558 54.9314L22 43.0039L46.558 30.875Z" fill="url(#paint3_linear_2942_6715)"/>
+<path d="M71.1166 43.0073L46.5586 54.9348V90.2174L71.1166 78.29V43.0073Z" fill="url(#paint4_linear_2942_6715)"/>
+<path d="M46.558 54.9348L22 43.0073V78.29L46.558 90.2174V54.9348Z" fill="url(#paint5_linear_2942_6715)"/>
+<path d="M50.0664 58.5516L68.5096 49.731V52.1366L50.0664 60.9573V58.5516Z" fill="#DFE7FF"/>
+<path d="M50.0664 69.7733L68.5096 60.9526V63.3583L50.0664 72.1789V69.7733Z" fill="#DFE7FF"/>
+<path d="M50.0664 81.0074L68.5096 72.1868V74.5924L50.0664 83.4131V81.0074Z" fill="#DFE7FF"/>
+<ellipse cx="25.9816" cy="51.4576" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 51.4576)" fill="#D0DBFF"/>
+<ellipse cx="25.9816" cy="62.6795" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 62.6795)" fill="#D0DBFF"/>
+<ellipse cx="25.9816" cy="73.9012" rx="1.60376" ry="2.0047" transform="rotate(-29.2048 25.9816 73.9012)" fill="#D0DBFF"/>
+<defs>
+<linearGradient id="paint0_linear_2942_6715" x1="8.51207" y1="91.3851" x2="42.5572" y2="109.717" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2942_6715" x1="65.7776" y1="15.5583" x2="65.7776" y2="81.93" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2942_6715" x1="25.6761" y1="62.0627" x2="66.6355" y2="103.022" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2942_6715" x1="46.558" y1="30.875" x2="46.558" y2="90.214" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#ADC6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2942_6715" x1="50.7446" y1="57.0796" x2="67.4916" y2="57.2512" gradientUnits="userSpaceOnUse">
+<stop stop-color="#A0B8FF"/>
+<stop offset="0.963422" stop-color="#6A8DFF"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2942_6715" x1="26.186" y1="57.0796" x2="42.933" y2="57.2512" gradientUnits="userSpaceOnUse">
+<stop stop-color="#92B2FF"/>
+<stop offset="1" stop-color="#ADC2FE"/>
+</linearGradient>
+</defs>
+</svg>

+ 67 - 0
public/images/home/top-2.svg

@@ -0,0 +1,67 @@
+<svg width="92" height="91" viewBox="0 0 92 91" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.56306 81.9135L45.5027 58.4234L86.4422 81.9135L86.4422 91.0396L45.5026 113.996L4.56314 91.0397L4.56306 81.9135Z" fill="white"/>
+<path d="M4.92871 82.5615L46.2582 105.436V114.254L4.92871 91.3798V82.5615Z" fill="url(#paint0_linear_2942_6631)"/>
+<path d="M87.0684 82.5615L45.7389 105.436V114.254L87.0684 91.3798V82.5615Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="5.41309" y1="22.7676" x2="5.41308" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="45.9287" y1="4.57666" x2="45.9287" y2="36.6577" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="86.0371" y1="22.7676" x2="86.0371" y2="64.6693" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M45.3589 0L41.6553 3.70362L45.3589 7.40725L49.0625 3.70362L45.3589 0ZM45.3588 1.85181L43.507 3.70362L45.3588 5.55543L47.2106 3.70362L45.3588 1.85181Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1216 20.4336L82.418 24.1372L86.1216 27.8408L89.8252 24.1372L86.1216 20.4336ZM86.1215 22.2854L84.2697 24.1372L86.1215 25.989L87.9733 24.1372L86.1215 22.2854Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.84327 20.4336L1.13965 24.1372L4.84327 27.8408L8.5469 24.1372L4.84327 20.4336ZM4.84321 22.2854L2.9914 24.1372L4.84321 25.989L6.69502 24.1372L4.84321 22.2854Z" fill="#4980F7"/>
+</g>
+<path d="M86.4223 83.2303V38.2187L45.5026 15.4351L4.58301 38.2187V83.2303L45.5026 105.458L86.4223 83.2303Z" fill="white"/>
+<path d="M45.5026 16.0073L85.9223 38.5126V82.9329L45.5026 104.889L5.08301 82.9329V38.5126L45.5026 16.0073Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M86.0543 38.3097L45.5029 15.5583V60.2017L86.0543 81.93V38.3097Z" fill="url(#paint1_linear_2942_6631)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M5.21777 82.5623L45.5025 60.2822L87.097 82.5623L87.0969 82.5224L46.1574 105.479L5.21777 82.5623Z" fill="url(#paint2_linear_2942_6631)"/>
+<rect x="44.4795" y="15.8469" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58301" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="4.58301" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="37.9421" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<rect x="84.375" y="80.9075" width="2.04598" height="2.04598" rx="1.02299" fill="#5995F5"/>
+<path d="M15.7725 44.9007L45.4099 31L74.2605 44.9007L45.4099 60.8997L15.7725 44.9007Z" fill="url(#paint3_linear_2942_6631)"/>
+<path d="M30.46 45.431L45.0793 38.6025L59.3105 45.431L45.0793 53.2901L30.46 45.431Z" fill="url(#paint4_linear_2942_6631)"/>
+<path d="M15.7725 76.3798V44.906L45.4099 60.9054V95.0015L15.7725 76.3798Z" fill="#D7DBFB"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M28.9119 58.7642L21.3242 54.7348L21.3243 54.022L29.5442 58.4481L30.4927 61.0579L35.39 63.9437L35.3901 64.7039L29.9063 61.5846L28.9119 58.7642Z" fill="url(#paint5_linear_2942_6631)"/>
+<path d="M21.3242 72.4324V58.2209V55.6917L28.5957 59.4855L29.228 62.0147L38.3964 67.0729V82.5476L21.3242 72.4324Z" fill="url(#paint6_linear_2942_6631)"/>
+<path d="M74.2607 75.8548L45.4102 95.0011V60.905L74.2607 44.906V75.8548Z" fill="url(#paint7_linear_2942_6631)"/>
+<path d="M66.6541 72.9249L53.0156 82.1472V65.7239L66.6541 58.0176V72.9249Z" fill="url(#paint8_linear_2942_6631)"/>
+<defs>
+<linearGradient id="paint0_linear_2942_6631" x1="8.5111" y1="91.3851" x2="42.5562" y2="109.717" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2942_6631" x1="65.7786" y1="15.5583" x2="65.7786" y2="81.93" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2942_6631" x1="25.6771" y1="62.0627" x2="66.6365" y2="103.022" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2942_6631" x1="45.0165" y1="31" x2="45.0165" y2="60.8997" gradientUnits="userSpaceOnUse">
+<stop stop-color="#ADC6FF"/>
+<stop offset="1" stop-color="#ADC6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2942_6631" x1="44.8852" y1="37.9337" x2="44.8852" y2="52.9485" gradientUnits="userSpaceOnUse">
+<stop stop-color="#7699FD" stop-opacity="0.38"/>
+<stop offset="1" stop-color="#7699FD"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2942_6631" x1="23.3602" y1="56.3189" x2="28.4977" y2="68.2627" gradientUnits="userSpaceOnUse">
+<stop stop-color="#007C52"/>
+<stop offset="1" stop-color="#007C52" stop-opacity="0.25"/>
+</linearGradient>
+<linearGradient id="paint6_linear_2942_6631" x1="24.2342" y1="63.6968" x2="35.8758" y2="63.8426" gradientUnits="userSpaceOnUse">
+<stop stop-color="#6F9AFE"/>
+<stop offset="1" stop-color="#A6BDFF"/>
+</linearGradient>
+<linearGradient id="paint7_linear_2942_6631" x1="74.3178" y1="60.1441" x2="45.7442" y2="82.4264" gradientUnits="userSpaceOnUse">
+<stop stop-color="#97B6FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint8_linear_2942_6631" x1="55.3404" y1="65.21" x2="64.6407" y2="65.3136" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B9CBFF"/>
+<stop offset="0.963422" stop-color="#6A8DFF"/>
+</linearGradient>
+</defs>
+</svg>

+ 57 - 0
public/images/media/dashboard-1.svg

@@ -0,0 +1,57 @@
+<svg width="102" height="103" viewBox="0 0 102 103" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.46232 91.4268L50.8865 65.3636L96.3107 91.4268L96.3107 101.553L50.8865 127.023L5.46241 101.553L5.46232 91.4268Z" fill="white"/>
+<path d="M5.86816 92.1472L51.725 117.527V127.311L5.86816 101.931V92.1472Z" fill="url(#paint0_linear_2905_7008)"/>
+<path d="M97.0059 92.1472L51.1491 117.527V127.311L97.0059 101.931V92.1472Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="6.2959" y1="25.8047" x2="6.29589" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="51.25" y1="5.62109" x2="51.25" y2="41.2163" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="95.751" y1="25.8047" x2="95.751" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M50.7275 0.542969L46.6182 4.6523L50.7275 8.76162L54.8368 4.6523L50.7275 0.542969ZM50.7274 2.59763L48.6728 4.6523L50.7274 6.70696L52.7821 4.6523L50.7274 2.59763Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M95.955 23.2148L91.8457 27.3242L95.955 31.4335L100.064 27.3242L95.955 23.2148ZM95.955 25.2695L93.9003 27.3242L95.955 29.3788L98.0096 27.3242L95.955 25.2695Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.77339 23.2148L1.66406 27.3242L5.77339 31.4335L9.88272 27.3242L5.77339 23.2148ZM5.77332 25.2695L3.71866 27.3242L5.77332 29.3788L7.82799 27.3242L5.77332 25.2695Z" fill="#4980F7"/>
+</g>
+<path d="M96.2885 92.8877V42.9454L50.8864 17.666L5.48438 42.9454V92.8877L50.8864 117.551L96.2885 92.8877Z" fill="white"/>
+<path d="M50.8864 18.2383L95.7885 43.2393V92.5903L50.8864 116.982L5.98438 92.5903V43.2393L50.8864 18.2383Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M95.8802 43.0448L50.8867 17.8013V67.3349L95.8802 91.4434V43.0448Z" fill="url(#paint1_linear_2905_7008)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M6.18848 92.147L50.8861 67.4263L97.0369 92.147L97.0369 92.1027L51.6127 117.574L6.18848 92.147Z" fill="url(#paint2_linear_2905_7008)"/>
+<rect x="49.751" y="18.1223" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<path d="M49.0716 34.875L75.1432 47.7514L49.0716 60.414L23 47.7514L49.0716 34.875Z" fill="url(#paint3_linear_2905_7008)"/>
+<path d="M75.1429 47.7551L49.0713 60.4177V97.875L75.1429 85.2124V47.7551Z" fill="url(#paint4_linear_2905_7008)"/>
+<path d="M49.0716 60.4177L23 47.7551V85.2124L49.0716 97.875V60.4177Z" fill="url(#paint5_linear_2905_7008)"/>
+<path d="M52.7959 64.2574L72.3758 54.8931V57.447L52.7959 66.8113V64.2574Z" fill="#DFE7FF"/>
+<path d="M52.7959 76.1707L72.3758 66.8064V69.3603L52.7959 78.7246V76.1707Z" fill="#DFE7FF"/>
+<path d="M52.7959 88.0975L72.3758 78.7332V81.2871L52.7959 90.6514V88.0975Z" fill="#DFE7FF"/>
+<ellipse cx="27.2268" cy="56.7264" rx="1.7026" ry="2.12825" transform="rotate(-29.2048 27.2268 56.7264)" fill="#D0DBFF"/>
+<ellipse cx="27.2268" cy="68.6397" rx="1.7026" ry="2.12825" transform="rotate(-29.2048 27.2268 68.6397)" fill="#D0DBFF"/>
+<ellipse cx="27.2268" cy="80.5531" rx="1.7026" ry="2.12825" transform="rotate(-29.2048 27.2268 80.5531)" fill="#D0DBFF"/>
+<defs>
+<linearGradient id="paint0_linear_2905_7008" x1="9.84297" y1="101.937" x2="47.6175" y2="122.278" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2905_7008" x1="73.3834" y1="17.8013" x2="73.3834" y2="91.4434" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2905_7008" x1="28.8889" y1="69.4018" x2="74.3352" y2="114.848" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2905_7008" x1="49.0716" y1="34.875" x2="49.0716" y2="97.8713" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#ADC6FF" stop-opacity="0"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2905_7008" x1="53.5153" y1="62.6947" x2="71.2945" y2="62.8769" gradientUnits="userSpaceOnUse">
+<stop stop-color="#A0B8FF"/>
+<stop offset="0.963422" stop-color="#6A8DFF"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2905_7008" x1="27.444" y1="62.6947" x2="45.2232" y2="62.8769" gradientUnits="userSpaceOnUse">
+<stop stop-color="#92B2FF"/>
+<stop offset="1" stop-color="#ADC2FE"/>
+</linearGradient>
+</defs>
+</svg>

+ 62 - 0
public/images/media/dashboard-2.svg

@@ -0,0 +1,62 @@
+<svg width="102" height="103" viewBox="0 0 102 103" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.46232 91.4266L50.8865 65.3634L96.3107 91.4266L96.3107 101.552L50.8865 127.023L5.46241 101.553L5.46232 91.4266Z" fill="white"/>
+<path d="M5.86816 92.147L51.725 117.527V127.311L5.86816 101.931V92.147Z" fill="url(#paint0_linear_2905_7076)"/>
+<path d="M97.0059 92.147L51.1491 117.527V127.311L97.0059 101.931V92.147Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="6.2959" y1="25.8047" x2="6.29589" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="51.25" y1="5.62109" x2="51.25" y2="41.2163" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="95.751" y1="25.8047" x2="95.751" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M50.7275 0.542969L46.6182 4.6523L50.7275 8.76162L54.8368 4.6523L50.7275 0.542969ZM50.7274 2.59763L48.6728 4.6523L50.7274 6.70696L52.7821 4.6523L50.7274 2.59763Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M95.955 23.2148L91.8457 27.3242L95.955 31.4335L100.064 27.3242L95.955 23.2148ZM95.955 25.2695L93.9003 27.3242L95.955 29.3788L98.0096 27.3242L95.955 25.2695Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.77339 23.2148L1.66406 27.3242L5.77339 31.4335L9.88272 27.3242L5.77339 23.2148ZM5.77332 25.2695L3.71866 27.3242L5.77332 29.3788L7.82799 27.3242L5.77332 25.2695Z" fill="#4980F7"/>
+</g>
+<path d="M96.2885 92.8877V42.9454L50.8864 17.666L5.48438 42.9454V92.8877L50.8864 117.551L96.2885 92.8877Z" fill="white"/>
+<path d="M50.8864 18.2383L95.7885 43.2393V92.5903L50.8864 116.982L5.98438 92.5903V43.2393L50.8864 18.2383Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M95.8802 43.0448L50.8867 17.8013V67.3349L95.8802 91.4434V43.0448Z" fill="url(#paint1_linear_2905_7076)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M6.18848 92.147L50.8861 67.4263L97.0369 92.147L97.0369 92.1027L51.6127 117.574L6.18848 92.147Z" fill="url(#paint2_linear_2905_7076)"/>
+<rect x="49.751" y="18.1223" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<ellipse cx="51.0389" cy="71.5299" rx="7.79765" ry="7.93003" fill="url(#paint3_radial_2905_7076)"/>
+<path d="M41.2949 39.6127L50.8459 33.9258L60.3968 39.6127L50.8459 45.2996L41.2949 39.6127Z" fill="url(#paint4_linear_2905_7076)"/>
+<path d="M60.3976 39.6167L50.8467 45.3036L50.8467 54.1514L50.8467 65.5252L60.3976 59.8383V39.6167Z" fill="#588AFF"/>
+<path d="M50.8429 45.1647L41.292 39.4778V59.6994L50.8429 65.3863L50.8429 54.0125L50.8429 45.1647Z" fill="#8BA9FF"/>
+<path d="M18.8426 79.3315L28.4609 84.8999L35.9954 80.476L45.681 74.7891L36.0627 69.2207L18.8426 79.3315Z" fill="url(#paint5_linear_2905_7076)"/>
+<path d="M28.4609 84.9015L28.3936 96.1567L45.6136 86.0459L45.6809 74.7907L35.9954 80.4776L28.4609 84.9015Z" fill="#588AFF"/>
+<path d="M28.3936 96.1551L18.7753 90.5868L18.8426 79.3315L28.4609 84.8999L28.3936 96.1551Z" fill="#8BA9FF"/>
+<path d="M83.0421 79.3315L73.4239 84.8999L65.8894 80.476L56.2038 74.7891L65.8221 69.2207L83.0421 79.3315Z" fill="url(#paint6_linear_2905_7076)"/>
+<path d="M73.4912 96.1551L83.1095 90.5868L83.0421 79.3315L73.4239 84.8999L73.4912 96.1551Z" fill="#588AFF"/>
+<path d="M73.4239 84.9015L73.4912 96.1567L56.2711 86.0459L56.2038 74.7907L65.8894 80.4776L73.4239 84.9015Z" fill="#8BA9FF"/>
+<defs>
+<linearGradient id="paint0_linear_2905_7076" x1="9.84297" y1="101.937" x2="47.6175" y2="122.277" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2905_7076" x1="73.3834" y1="17.8013" x2="73.3834" y2="91.4434" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2905_7076" x1="28.8889" y1="69.4018" x2="74.3352" y2="114.848" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<radialGradient id="paint3_radial_2905_7076" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(46.5525 68.446) rotate(31.6324) scale(9.66012 9.66815)">
+<stop stop-color="#ADC6FF"/>
+<stop offset="1" stop-color="#5079FF"/>
+</radialGradient>
+<linearGradient id="paint4_linear_2905_7076" x1="50.8459" y1="33.9258" x2="50.8459" y2="65.5212" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#DAE5FF"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2905_7076" x1="18.7753" y1="90.5868" x2="45.9055" y2="75.1846" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#C9D8FA"/>
+</linearGradient>
+<linearGradient id="paint6_linear_2905_7076" x1="83.1095" y1="90.5868" x2="55.9793" y2="75.1846" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C5D7FF"/>
+<stop offset="1" stop-color="#C9D8FA"/>
+</linearGradient>
+</defs>
+</svg>

Файловите разлики са ограничени, защото са твърде много
+ 115 - 0
public/images/media/dashboard-3.svg


+ 81 - 0
public/images/media/dashboard-4.svg

@@ -0,0 +1,81 @@
+<svg width="102" height="103" viewBox="0 0 102 103" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5.46232 91.4268L50.8865 65.3636L96.3107 91.4268L96.3107 101.553L50.8865 127.023L5.46241 101.553L5.46232 91.4268Z" fill="white"/>
+<path d="M5.86816 92.1472L51.725 117.527V127.311L5.86816 101.931V92.1472Z" fill="url(#paint0_linear_2905_7195)"/>
+<path d="M97.0059 92.1472L51.1491 117.527V127.311L97.0059 101.931V92.1472Z" fill="#B8BFD5"/>
+<g opacity="0.7">
+<line x1="6.2959" y1="25.8047" x2="6.29589" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="51.25" y1="5.62109" x2="51.25" y2="41.2163" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<line x1="95.751" y1="25.8047" x2="95.751" y2="72.2964" stroke="#4980F7" stroke-opacity="0.2" stroke-width="2" stroke-dasharray="3 3"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M50.7275 0.542969L46.6182 4.6523L50.7275 8.76162L54.8368 4.6523L50.7275 0.542969ZM50.7274 2.59763L48.6728 4.6523L50.7274 6.70696L52.7821 4.6523L50.7274 2.59763Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M95.955 23.2148L91.8457 27.3242L95.955 31.4335L100.064 27.3242L95.955 23.2148ZM95.955 25.2695L93.9003 27.3242L95.955 29.3788L98.0096 27.3242L95.955 25.2695Z" fill="#4980F7"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.77339 23.2148L1.66406 27.3242L5.77339 31.4335L9.88272 27.3242L5.77339 23.2148ZM5.77332 25.2695L3.71866 27.3242L5.77332 29.3788L7.82799 27.3242L5.77332 25.2695Z" fill="#4980F7"/>
+</g>
+<path d="M96.2885 92.8877V42.9454L50.8864 17.666L5.48438 42.9454V92.8877L50.8864 117.551L96.2885 92.8877Z" fill="white"/>
+<path d="M50.8864 18.2383L95.7885 43.2393V92.5903L50.8864 116.982L5.98438 92.5903V43.2393L50.8864 18.2383Z" stroke="#5995F5" stroke-opacity="0.3"/>
+<path d="M95.8802 43.0448L50.8867 17.8013V67.3349L95.8802 91.4434V43.0448Z" fill="url(#paint1_linear_2905_7195)" fill-opacity="0.1"/>
+<path opacity="0.6" d="M6.18848 92.147L50.8861 67.4263L97.0369 92.147L97.0369 92.1027L51.6127 117.574L6.18848 92.147Z" fill="url(#paint2_linear_2905_7195)"/>
+<rect x="49.751" y="18.1223" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="5.48438" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="42.6394" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<rect x="94.0176" y="90.3096" width="2.2701" height="2.2701" rx="1.13505" fill="#5995F5"/>
+<path d="M71.8312 78.3524C71.8312 79.7743 71.4021 81.1386 70.6141 82.4048C67.7216 87.0531 59.9941 90.3789 50.9156 90.3789C41.8372 90.3789 34.1096 87.0531 31.2171 82.4048C30.4292 81.1386 30 79.7743 30 78.3524C30 71.7104 39.3642 66.3259 50.9156 66.3259C62.467 66.3259 71.8312 71.7104 71.8312 78.3524Z" fill="url(#paint3_linear_2905_7195)"/>
+<path d="M50.9156 98.4828C62.467 98.4828 71.8312 93.0984 71.8312 86.4564V78.3516C71.8312 79.7735 71.4021 81.1378 70.6141 82.404C67.7216 87.0522 59.9941 90.378 50.9156 90.378C41.8372 90.378 34.1096 87.0522 31.2171 82.404C30.4292 81.1378 30 79.7735 30 78.3516V86.4564C30 93.0984 39.3642 98.4828 50.9156 98.4828Z" fill="url(#paint4_linear_2905_7195)"/>
+<ellipse cx="50.6478" cy="85.7272" rx="2.18592" ry="1.98187" fill="url(#paint5_linear_2905_7195)"/>
+<ellipse cx="34.8002" cy="77.5512" rx="2.18592" ry="1.98187" fill="url(#paint6_linear_2905_7195)"/>
+<ellipse cx="66.7689" cy="77.5512" rx="2.18592" ry="1.98187" fill="url(#paint7_linear_2905_7195)"/>
+<ellipse cx="50.6478" cy="69.8715" rx="2.18592" ry="1.98187" fill="url(#paint8_linear_2905_7195)"/>
+<path d="M71.8312 48.546C71.8312 49.9679 71.4021 51.3322 70.6141 52.5984C67.7216 57.2467 59.9941 60.5725 50.9156 60.5725C41.8372 60.5725 34.1096 57.2467 31.2171 52.5984C30.4292 51.3322 30 49.9679 30 48.546C30 41.904 39.3642 36.5195 50.9156 36.5195C62.467 36.5195 71.8312 41.904 71.8312 48.546Z" fill="url(#paint9_linear_2905_7195)"/>
+<path d="M50.9156 68.6806C62.467 68.6806 71.8312 63.2962 71.8312 56.6541V48.5493C71.8312 49.9712 71.4021 51.3355 70.6141 52.6017C67.7216 57.25 59.9941 60.5758 50.9156 60.5758C41.8372 60.5758 34.1096 57.25 31.2171 52.6017C30.4292 51.3355 30 49.9712 30 48.5493V56.6541C30 63.2962 39.3642 68.6806 50.9156 68.6806Z" fill="url(#paint10_linear_2905_7195)"/>
+<path d="M60.2388 42.2703L55.4036 54.166L41.5039 45.4076L60.2388 42.2703Z" fill="url(#paint11_linear_2905_7195)"/>
+<defs>
+<linearGradient id="paint0_linear_2905_7195" x1="9.84297" y1="101.937" x2="47.6175" y2="122.278" gradientUnits="userSpaceOnUse">
+<stop stop-color="#C9D8FF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint1_linear_2905_7195" x1="73.3834" y1="17.8013" x2="73.3834" y2="91.4434" gradientUnits="userSpaceOnUse">
+<stop offset="0.0667851" stop-color="#7A9EF4"/>
+<stop offset="1" stop-color="#EFF1F9"/>
+</linearGradient>
+<linearGradient id="paint2_linear_2905_7195" x1="28.8889" y1="69.4018" x2="74.3352" y2="114.848" gradientUnits="userSpaceOnUse">
+<stop offset="0.0001" stop-color="#A0B4FF"/>
+<stop offset="1" stop-color="#B5C4FD" stop-opacity="0.01"/>
+</linearGradient>
+<linearGradient id="paint3_linear_2905_7195" x1="50.9156" y1="64.8615" x2="50.9156" y2="97.7358" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B7CDFF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint4_linear_2905_7195" x1="37.1303" y1="84.3522" x2="65.6118" y2="85.5179" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9DB7FF"/>
+<stop offset="1" stop-color="#5B8BFD"/>
+</linearGradient>
+<linearGradient id="paint5_linear_2905_7195" x1="50.6478" y1="83.5649" x2="50.6478" y2="87.6169" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B0C8FF"/>
+<stop offset="1" stop-color="#88A4F4"/>
+</linearGradient>
+<linearGradient id="paint6_linear_2905_7195" x1="34.8002" y1="75.3888" x2="34.8002" y2="79.4409" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B0C8FF"/>
+<stop offset="1" stop-color="#88A4F4"/>
+</linearGradient>
+<linearGradient id="paint7_linear_2905_7195" x1="66.7689" y1="75.3888" x2="66.7689" y2="79.4409" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B0C8FF"/>
+<stop offset="1" stop-color="#88A4F4"/>
+</linearGradient>
+<linearGradient id="paint8_linear_2905_7195" x1="50.6478" y1="67.7091" x2="50.6478" y2="71.7612" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B0C8FF"/>
+<stop offset="1" stop-color="#88A4F4"/>
+</linearGradient>
+<linearGradient id="paint9_linear_2905_7195" x1="50.9156" y1="35.0551" x2="50.9156" y2="67.9294" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B7CDFF"/>
+<stop offset="1" stop-color="white"/>
+</linearGradient>
+<linearGradient id="paint10_linear_2905_7195" x1="37.1303" y1="54.55" x2="65.6118" y2="55.7157" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9DB7FF"/>
+<stop offset="1" stop-color="#5B8BFD"/>
+</linearGradient>
+<linearGradient id="paint11_linear_2905_7195" x1="50.8714" y1="41.7285" x2="50.8714" y2="53.8894" gradientUnits="userSpaceOnUse">
+<stop stop-color="#B0C8FF"/>
+<stop offset="1" stop-color="#88A4F4"/>
+</linearGradient>
+</defs>
+</svg>

+ 2 - 1
src/app.tsx

@@ -187,7 +187,8 @@ export const request: RequestConfig = {
       response.status === 400 ||
       response.status === 500 ||
       response.status === 404 ||
-      response.status === 403
+      response.status === 403 ||
+      response.status === 504
     ) {
       // 添加clone() 避免后续其它地方用response.text()时报错
       response

+ 3 - 3
src/components/ProTableCard/CardItems/DataCollect/channel.tsx

@@ -30,13 +30,13 @@ export default (props: ChannelCardProps) => {
       showMask={false}
       statusNames={{
         running: StatusColorEnum.success,
-        disabled: StatusColorEnum.processing,
+        disabled: StatusColorEnum.error,
         partialError: StatusColorEnum.warning,
-        failed: StatusColorEnum.error,
+        failed: StatusColorEnum.processing,
         stopped: StatusColorEnum.default,
       }}
     >
-      <div className={'pro-table-card-item'}>
+      <div className={'pro-table-card-item'} onClick={props?.onClick}>
         <div className={'card-item-avatar'}>
           <img
             width={88}

+ 4 - 1
src/components/ProTableCard/CardItems/cascade.tsx

@@ -37,7 +37,10 @@ export default (props: CascadeCardProps) => {
           </div>
           <div>通道数量: {props?.count || 0}</div>
           <div style={{ display: 'flex', width: '100%' }}>
-            <Badge status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'} />
+            <Badge
+              style={{ marginRight: 5 }}
+              status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'}
+            />
             {/*<div*/}
             {/*  style={{*/}
             {/*    width: '90%',*/}

+ 8 - 0
src/components/ProTableCard/index.less

@@ -270,6 +270,14 @@
           background-color: rgba(#e50012, 0.1);
         }
 
+        &.default {
+          background-color: rgba(229, 229, 229);
+        }
+
+        &.processing {
+          background-color: rgba(36, 178, 118, 0.1);
+        }
+
         .card-state-content {
           transform: skewX(-45deg);
         }

+ 8 - 0
src/pages/DataCollect/Channel/index.tsx

@@ -13,6 +13,8 @@ import ChannelCard from '@/components/ProTableCard/CardItems/DataCollect/channel
 import { DeleteOutlined, EditOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import Save from '@/pages/DataCollect/Channel/Save';
+import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
+import useHistory from '@/hooks/route/useHistory';
 
 const ChannelModel = model<{
   visible: boolean;
@@ -36,6 +38,8 @@ export default observer(() => {
     pageIndex: 0,
     total: 0,
   });
+  const history = useHistory();
+
   const columns: ProColumns<ChannelItem>[] = [
     {
       title: '通道名称',
@@ -280,6 +284,10 @@ export default observer(() => {
                         <DeleteOutlined />
                       </PermissionButton>,
                     ]}
+                    onClick={() => {
+                      const url = getMenuPathByCode(MENUS_CODE['DataCollect/Collector']);
+                      history.push(url, { channelId: record.id });
+                    }}
                   />
                 </Col>
               ))}

+ 6 - 8
src/pages/DataCollect/Collector/components/Device/Save/index.tsx

@@ -55,14 +55,12 @@ export default (props: Props) => {
             if (value) {
               const dt = channelListRef.current.find((item) => item.id === value);
               channelRef.current = dt;
-              if (dt?.provider && dt?.provider === 'MODBUS_TCP') {
-                f.setFieldState('configuration.unitId', (state) => {
-                  state.visible = true;
-                });
-                f.setFieldState('configuration.endian', (state) => {
-                  state.visible = true;
-                });
-              }
+              f.setFieldState('configuration.unitId', (state) => {
+                state.visible = dt?.provider && dt?.provider === 'MODBUS_TCP';
+              });
+              f.setFieldState('configuration.endian', (state) => {
+                state.visible = dt?.provider && dt?.provider === 'MODBUS_TCP';
+              });
             }
           });
           onFieldReact('circuitBreaker.type', async (field, f) => {

+ 17 - 11
src/pages/DataCollect/Collector/components/Point/index.tsx

@@ -102,7 +102,7 @@ const PointCard = observer((props: PointCardProps) => {
         setPropertyValue({ ...propertyValue });
       });
   };
-  const handleSearch = (params: any) => {
+  const handleSearch = async (params: any) => {
     if (subRef.current) {
       subRef.current?.unsubscribe();
     }
@@ -111,8 +111,8 @@ const PointCard = observer((props: PointCardProps) => {
     PointModel.list = [];
     setLoading(true);
     setParam(params);
-    service
-      .queryPoint({
+    if (props.data?.id) {
+      const resp = await service.queryPoint({
         ...params,
         terms: [
           ...params?.terms,
@@ -123,14 +123,20 @@ const PointCard = observer((props: PointCardProps) => {
           },
         ],
         sorts: [{ name: 'id', order: 'desc' }],
-      })
-      .then((resp) => {
-        if (resp.status === 200) {
-          setDataSource(resp.result);
-          subscribeProperty((resp.result?.data || []).map((item: any) => item.id));
-        }
-        setLoading(false);
       });
+      if (resp.status === 200) {
+        setDataSource(resp.result);
+        subscribeProperty((resp.result?.data || []).map((item: any) => item.id));
+      }
+    } else {
+      setDataSource({
+        data: [],
+        pageSize: 12,
+        pageIndex: 0,
+        total: 0,
+      });
+    }
+    setLoading(false);
   };
 
   useEffect(() => {
@@ -235,7 +241,7 @@ const PointCard = observer((props: PointCardProps) => {
       >
         <div>
           <div style={{ height: '100%', paddingBottom: 48 }}>
-            {props.data?.id !== '*' && (
+            {props.data?.id !== '*' && props.data?.id && (
               <div style={{ width: '100%', display: 'flex', justifyContent: 'flex-start' }}>
                 <PermissionButton
                   isPermission={permission.add}

+ 53 - 28
src/pages/DataCollect/Collector/components/Tree/index.tsx

@@ -24,15 +24,20 @@ const TreeModel = model<{
   param: any;
   visible: boolean;
   current: any;
+  search: string;
 }>({
   selectedKeys: ['*'],
   dataSource: [],
   loading: true,
-  param: {},
+  param: {
+    terms: [],
+  },
   visible: false,
   current: {},
+  search: '',
 });
 interface Props {
+  channelId?: string;
   change: (data?: any) => void;
 }
 
@@ -41,33 +46,50 @@ export default observer((props: Props) => {
   const { permission } = PermissionButton.usePermission('DataCollect/Collector');
   const intl = useIntl();
 
-  const handleSearch = (params: any) => {
+  const handleSearch = async (params: any) => {
     TreeModel.loading = true;
     TreeModel.param = params;
-    service
-      .queryCollector({ ...params, paging: false, sorts: [{ name: 'createTime', order: 'desc' }] })
-      .then((resp) => {
-        if (resp.status === 200) {
-          if (params.terms) {
-            TreeModel.dataSource = resp.result;
-          } else {
-            TreeModel.dataSource = [
-              {
-                id: '*',
-                name: '全部',
-                children: resp.result,
-              },
-            ];
-          }
-          props.change(TreeModel.dataSource[0]);
-        }
-        TreeModel.loading = false;
-      });
+    const resp = await service.queryCollector({
+      ...params,
+      paging: false,
+      sorts: [{ name: 'createTime', order: 'desc' }],
+    });
+    if (resp.status === 200) {
+      if (TreeModel?.search || props?.channelId) {
+        TreeModel.dataSource = resp.result;
+      } else {
+        TreeModel.dataSource = [
+          {
+            id: '*',
+            name: '全部',
+            children: resp.result,
+          },
+        ];
+      }
+      TreeModel.selectedKeys = [TreeModel.dataSource?.[0]?.id] || [];
+      props.change(TreeModel.dataSource?.[0]);
+    }
+    TreeModel.loading = false;
   };
 
   useEffect(() => {
-    handleSearch(TreeModel.param);
-  }, [TreeModel.param]);
+    if (props.channelId) {
+      TreeModel.param = {
+        terms: [
+          {
+            column: 'channelId',
+            value: props?.channelId,
+          },
+        ],
+      };
+      handleSearch(TreeModel.param);
+    } else {
+      TreeModel.param = {
+        terms: [],
+      };
+      handleSearch(TreeModel.param);
+    }
+  }, [props.channelId]);
 
   const getState = (record: any) => {
     if (record) {
@@ -99,13 +121,15 @@ export default observer((props: Props) => {
           placeholder="请输入名称"
           allowClear
           onSearch={(val) => {
+            TreeModel.search = val;
             if (val) {
               TreeModel.param = {
                 terms: [{ column: 'name', value: `%${val}%`, termType: 'like' }],
               };
             } else {
-              TreeModel.param = {};
+              TreeModel.param = { terms: [] };
             }
+            handleSearch(TreeModel.param);
           }}
           style={{ width: '100%' }}
         />
@@ -133,6 +157,7 @@ export default observer((props: Props) => {
             height={500}
             selectedKeys={TreeModel.selectedKeys}
             defaultExpandAll
+            autoExpandParent
             switcherIcon={<DownOutlined />}
             fieldNames={{
               title: 'name',
@@ -196,7 +221,7 @@ export default observer((props: Props) => {
                                   runningState: 'running',
                                 });
                           if (resp.status === 200) {
-                            TreeModel.param = {};
+                            TreeModel.param = { terms: [] };
                             handleSearch(TreeModel.param);
                             onlyMessage('操作成功');
                           } else {
@@ -218,7 +243,7 @@ export default observer((props: Props) => {
                         onConfirm={async () => {
                           const resp = await service.removeCollector(i.id);
                           if (resp.status === 200) {
-                            TreeModel.param = {};
+                            TreeModel.param = { terms: [] };
                             handleSearch(TreeModel.param);
                             onlyMessage('操作成功');
                           }
@@ -242,7 +267,7 @@ export default observer((props: Props) => {
               </div>
             )}
             treeData={TreeModel.dataSource}
-          ></Tree>
+          />
         ) : (
           <Empty />
         )}
@@ -255,7 +280,7 @@ export default observer((props: Props) => {
           }}
           reload={() => {
             TreeModel.visible = false;
-            TreeModel.param = {};
+            TreeModel.param = { terms: [] };
             handleSearch(TreeModel.param);
           }}
         />

+ 15 - 1
src/pages/DataCollect/Collector/index.tsx

@@ -5,28 +5,42 @@ import CollectorTree from './components/Tree';
 import { observer } from '@formily/reactive-react';
 import { model } from '@formily/reactive';
 import Point from './components/Point';
+import { useEffect } from 'react';
+import useLocations from '@/hooks/route/useLocation';
 
 export const DataCollectModel = model<{
   provider: 'OPC_UA' | 'MODBUS_TCP';
   data: any;
   reload: boolean;
   refresh: boolean;
+  channelId: string;
 }>({
   provider: 'MODBUS_TCP',
   data: {},
   reload: false,
   refresh: false,
+  channelId: '',
 });
 
 export default observer(() => {
+  const location = useLocations();
+
+  useEffect(() => {
+    if (location.state?.channelId) {
+      DataCollectModel.channelId = location.state.channelId;
+    } else {
+      DataCollectModel.channelId = '';
+    }
+  }, [location.state]);
   return (
     <PageContainer>
       <Card bordered={false} bodyStyle={{ paddingTop: 0 }}>
         <div className={styles.container}>
           <div className={styles.left}>
             <CollectorTree
+              channelId={DataCollectModel.channelId}
               change={(data) => {
-                DataCollectModel.provider = data.provider;
+                DataCollectModel.provider = data?.provider;
                 DataCollectModel.data = data || {};
               }}
             />

+ 8 - 7
src/pages/Northbound/DuerOS/Detail/Doc.tsx

@@ -1,5 +1,6 @@
-import { InfoCircleFilled } from '@ant-design/icons';
-import { Alert, Image } from 'antd';
+// import { InfoCircleFilled } from '@ant-design/icons';
+// import { Alert, Image } from 'antd';
+import { Image } from 'antd';
 
 const image = require('/public/images/cloud/dueros-doc.jpg');
 const image1 = require('/public/images/cloud/dueros-doc1.png');
@@ -33,26 +34,26 @@ const Doc = () => {
         <div>物联网平台的登录地址。注意需要为https。</div>
         <div>请复制并填写: https://{location.host}/#/user/login</div>
         <h1>Client_Id</h1>
-        <div>请填写物联网平台-第三方平台的clientId。</div>
+        <div>请填写系统管理-应用管理中的clientId。</div>
         <div className={'image'}>
           <Image width="100%" src={image1} />
         </div>
         <h1>回调地址</h1>
-        <div>请复制DuerOS平台中的值,填写到第三方平台-redirectUrl中</div>
-        <div>
+        <div>请复制DuerOS平台中的值,填写到系统管理-应用管理中-redirectUrl中。</div>
+        {/* <div>
           <Alert
             icon={<InfoCircleFilled style={{ fontSize: 16, marginTop: 5 }} />}
             description="注:需要将OAth2设置为开启状态。"
             showIcon
           />
-        </div>
+        </div> */}
         <div className={'image'}>
           <Image width="100%" src={image2} />
         </div>
         <h1>Token地址</h1>
         <div>请复制并填写:HTTPS://{location.host}/api/v1/token</div>
         <h1>ClientSecret</h1>
-        <div>请复制物联网平台-第三方平台中的secureKey,填写到DuerOS平台。</div>
+        <div>请复制系统管理-应用管理中的secureKey,填写到DuerOS平台。</div>
         <div className={'image'}>
           <Image width="100%" src={image3} />
         </div>

+ 2 - 2
src/pages/device/DashBoard/index.tsx

@@ -397,7 +397,7 @@ const DeviceBoard = () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/device/device-product.png')} />
+            <img src={require('/public/images/device/device-product.svg')} />
           </DashBoardTopCard.Item>
           <DashBoardTopCard.Item
             title={'设备数量'}
@@ -416,7 +416,7 @@ const DeviceBoard = () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/device/device-number.png')} />
+            <img src={require('/public/images/device/device-number.svg')} />
           </DashBoardTopCard.Item>
           <DashBoardTopCard.Item
             title={'当前在线'}

+ 126 - 62
src/pages/device/Firmware/Task/Detail/index.tsx

@@ -1,9 +1,8 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import { observer } from '@formily/react';
-import { Badge, Card, message, Popconfirm } from 'antd';
+import { Badge, Card, message } from 'antd';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { Tooltip } from 'antd';
 import { useEffect, useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { RedoOutlined, SearchOutlined } from '@ant-design/icons';
@@ -15,6 +14,8 @@ import styles from './index.less';
 import { model } from '@formily/reactive';
 import { useParams } from 'umi';
 import Details from './Details/index';
+import { PermissionButton } from '@/components';
+import usePermissions from '@/hooks/permission';
 
 const colorMap = new Map();
 colorMap.set('waiting', '#FF9000');
@@ -47,6 +48,7 @@ const Detail = observer(() => {
   const params = useParams<any>();
   const [visible, setVisible] = useState<boolean>(false);
   const [reason, setReason] = useState<string>('');
+  const { permission } = usePermissions('device/Firmware');
 
   const buttonImg = require('/public/images/firmware/button.png');
 
@@ -273,44 +275,81 @@ const Detail = observer(() => {
       render: (text: any, record: any) =>
         record?.state?.value === 'failed'
           ? [
-              <a
+              // <a
+              //   onClick={() => {
+              //     setVisible(true);
+              //     setReason(record?.errorReason || '');
+              //   }}
+              //   key="link"
+              // >
+              //   <Tooltip
+              //     title={intl.formatMessage({
+              //       id: 'pages.data.option.detail',
+              //       defaultMessage: '查看',
+              //     })}
+              //     key={'detail'}
+              //   >
+              //     <SearchOutlined />
+              //   </Tooltip>
+              // </a>,
+              <PermissionButton
+                key="link"
+                type={'link'}
+                style={{ padding: 0 }}
+                isPermission={permission.update}
+                tooltip={{
+                  title: '重试',
+                }}
                 onClick={() => {
                   setVisible(true);
                   setReason(record?.errorReason || '');
                 }}
-                key="link"
               >
-                <Tooltip
-                  title={intl.formatMessage({
-                    id: 'pages.data.option.detail',
-                    defaultMessage: '查看',
-                  })}
-                  key={'detail'}
-                >
-                  <SearchOutlined />
-                </Tooltip>
-              </a>,
+                <SearchOutlined />
+              </PermissionButton>,
               <>
                 {state.info?.mode?.value === 'push' ? (
-                  <Popconfirm
-                    key="refresh"
-                    onConfirm={async () => {
-                      const resp = await service.startOneTask([record.id]);
-                      if (resp.status === 200) {
-                        message.success('操作成功!');
-                        handleSearch();
-                        actionRef.current?.reload?.();
-                      }
+                  <PermissionButton
+                    key="patch"
+                    type={'link'}
+                    style={{ padding: 0 }}
+                    isPermission={permission.update}
+                    tooltip={{
+                      title: '重试',
+                    }}
+                    popConfirm={{
+                      title: '确认重试',
+                      onConfirm: async () => {
+                        const resp = await service.startOneTask([record.id]);
+                        if (resp.status === 200) {
+                          message.success('操作成功!');
+                          handleSearch();
+                          actionRef.current?.reload?.();
+                        }
+                      },
                     }}
-                    title={'确认重试'}
                   >
-                    <a>
-                      <Tooltip title={'重试'} key={'refresh'}>
-                        <RedoOutlined />
-                      </Tooltip>
-                    </a>
-                  </Popconfirm>
-                ) : null}
+                    <RedoOutlined />
+                  </PermissionButton>
+                ) : // <Popconfirm
+                //   key="refresh"
+                //   onConfirm={async () => {
+                //     const resp = await service.startOneTask([record.id]);
+                //     if (resp.status === 200) {
+                //       message.success('操作成功!');
+                //       handleSearch();
+                //       actionRef.current?.reload?.();
+                //     }
+                //   }}
+                //   title={'确认重试'}
+                // >
+                //   <a>
+                //     <Tooltip title={'重试'} key={'refresh'}>
+                //       <RedoOutlined />
+                //     </Tooltip>
+                //   </a>
+                // </Popconfirm>
+                null}
               </>,
             ]
           : [],
@@ -326,44 +365,69 @@ const Detail = observer(() => {
               <div className={styles.firmwareDetailCard}>
                 <div className={styles.firmwareDetailCardHeader}>
                   <div className={styles.firmwareDetailCardTitle}>
-                    <Badge color={colorMap.get(item.key)} />
+                    <Badge color={colorMap.get(item.key)} style={{ marginRight: 5 }} />
                     {item.name}
                   </div>
                   <div className={styles.firmwareDetailCardRight}>
                     {item.key === 'error' && state.info?.mode?.value === 'push' && (
-                      <Popconfirm
-                        title="确认批量重试"
-                        onConfirm={async () => {
-                          const resp = await service.startTask(params.id, ['failed']);
-                          if (resp.status === 200) {
-                            message.success('操作成功!');
-                            queryFailed();
-                            actionRef.current?.reload?.();
-                          }
+                      // <Popconfirm
+                      //   title="确认批量重试"
+                      //   onConfirm={async () => {
+                      //     const resp = await service.startTask(params.id, ['failed']);
+                      //     if (resp.status === 200) {
+                      //       message.success('操作成功!');
+                      //       queryFailed();
+                      //       actionRef.current?.reload?.();
+                      //     }
+                      //   }}
+                      // >
+                      //   <a>批量重试</a>
+                      // </Popconfirm>
+                      <PermissionButton
+                        key="patch"
+                        type={'link'}
+                        style={{ padding: 0 }}
+                        isPermission={permission.update}
+                        tooltip={{
+                          title: '批量重试',
+                        }}
+                        popConfirm={{
+                          title: '确认批量重试',
+                          onConfirm: async () => {
+                            const resp = await service.startTask(params.id, ['failed']);
+                            if (resp.status === 200) {
+                              message.success('操作成功!');
+                              queryFailed();
+                              actionRef.current?.reload?.();
+                            }
+                          },
                         }}
                       >
-                        <a>批量重试</a>
-                      </Popconfirm>
+                        批量重试
+                      </PermissionButton>
                     )}
-                    <div className={styles.firmwareDetailCardRefresh}>
-                      <img
-                        style={{ width: '100%' }}
-                        src={buttonImg}
-                        onClick={() => {
-                          if (item.key === 'waiting') {
-                            queryWaiting();
-                          } else if (item.key === 'finish') {
-                            querySuccess();
-                          } else if (item.key === 'loading') {
-                            queryProcessing();
-                          } else if (item.key === 'canceled') {
-                            queryCancel();
-                          } else {
-                            queryFailed();
-                          }
-                        }}
-                      />
-                    </div>
+                    <PermissionButton
+                      key="patch1"
+                      style={{ padding: 0, backgroundColor: 'inherit', border: 0 }}
+                      isPermission={permission.update}
+                      onClick={() => {
+                        if (item.key === 'waiting') {
+                          queryWaiting();
+                        } else if (item.key === 'finish') {
+                          querySuccess();
+                        } else if (item.key === 'loading') {
+                          queryProcessing();
+                        } else if (item.key === 'canceled') {
+                          queryCancel();
+                        } else {
+                          queryFailed();
+                        }
+                      }}
+                    >
+                      <div className={styles.firmwareDetailCardRefresh}>
+                        <img style={{ width: '100%' }} src={buttonImg} />
+                      </div>
+                    </PermissionButton>
                   </div>
                 </div>
                 <div

+ 1 - 1
src/pages/device/Firmware/Task/Save/index.tsx

@@ -23,7 +23,7 @@ const Save = (props: Props) => {
   const devices = useRef<DeviceInstance[]>([]);
 
   useEffect(() => {
-    console.log(data);
+    // console.log(data);
     if (data && data.id) {
       setMode(data.mode.value);
     }

+ 29 - 26
src/pages/device/Firmware/Task/index.tsx

@@ -1,7 +1,7 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { message, Popconfirm, Tooltip } from 'antd';
+import { message, Tooltip } from 'antd';
 import { useRef, useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import {
@@ -131,7 +131,7 @@ const Task = observer(() => {
           key={'api'}
           type={'link'}
           style={{ padding: 0 }}
-          isPermission={true}
+          isPermission={permission.view}
           tooltip={{
             title: '详情',
           }}
@@ -142,29 +142,39 @@ const Task = observer(() => {
         >
           <AIcon type={'icon-details'} />
         </PermissionButton>,
-        <a
+        <PermissionButton
+          key="link"
+          type={'link'}
+          style={{ padding: 0 }}
+          isPermission={permission.view}
+          tooltip={{
+            title: '查看',
+          }}
           onClick={() => {
             state.visible = true;
             state.current = record;
           }}
-          key="link"
         >
-          <Tooltip title="查看" key={'detail'}>
-            <EyeOutlined />
-          </Tooltip>
-        </a>,
+          <EyeOutlined />
+        </PermissionButton>,
         <UpgradeBtn data={record} actions={actionRef.current} key="btn" />,
-        <a key="delete">
-          <Popconfirm
-            title={
+        <PermissionButton
+          key="delete"
+          type={'link'}
+          style={{ padding: 0 }}
+          isPermission={permission.delete}
+          tooltip={{
+            title: '删除',
+          }}
+          popConfirm={{
+            title:
               record.waiting > 0 || record.processing > 0
                 ? '删除将导致正在进行的任务终止,确定要删除吗?'
                 : intl.formatMessage({
                     id: 'pages.data.option.remove.tips',
                     defaultMessage: '确认删除?',
-                  })
-            }
-            onConfirm={async () => {
+                  }),
+            onConfirm: async () => {
               const resp = await service.deleteTask(record.id);
               if (resp.status === 200) {
                 onlyMessage(
@@ -177,18 +187,11 @@ const Task = observer(() => {
               } else {
                 message.error(resp?.message || '删除失败!');
               }
-            }}
-          >
-            <Tooltip
-              title={intl.formatMessage({
-                id: 'pages.data.option.remove',
-                defaultMessage: '删除',
-              })}
-            >
-              <DeleteOutlined />
-            </Tooltip>
-          </Popconfirm>
-        </a>,
+            },
+          }}
+        >
+          <DeleteOutlined />
+        </PermissionButton>,
       ],
     },
   ];

+ 1 - 1
src/pages/device/Firmware/index.tsx

@@ -126,7 +126,7 @@ const Firmware = observer(() => {
         <PermissionButton
           style={{ padding: 0 }}
           type="link"
-          isPermission={permission.action}
+          isPermission={permission.view}
           key="upgrade"
           onClick={() => {
             //缓存路由参数

+ 111 - 29
src/pages/device/Instance/Detail/ChildDevice/index.tsx

@@ -1,7 +1,7 @@
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
 import type { LogItem } from '@/pages/device/Instance/Detail/Log/typings';
-import { Badge, Button, Card, Popconfirm, Tooltip } from 'antd';
+import { Badge, Card, Tooltip } from 'antd';
 import { DisconnectOutlined, EditOutlined, SearchOutlined } from '@ant-design/icons';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { InstanceModel, service } from '@/pages/device/Instance';
@@ -14,6 +14,7 @@ import { getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import { useDomFullHeight } from '@/hooks';
 import { onlyMessage } from '@/utils/util';
 import SaveChild from './SaveChild';
+import PermissionButton from '../../../../../components/PermissionButton';
 
 const statusMap = new Map();
 statusMap.set('online', 'success');
@@ -32,6 +33,7 @@ const ChildDevice = (props: Props) => {
   const [bindKeys, setBindKeys] = useState<any[]>([]);
   const [childVisible, setChildVisible] = useState<boolean>(false);
   const [current, setCurrent] = useState<any>({});
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
 
   const { minHeight } = useDomFullHeight(`.device-detail-childDevice`);
 
@@ -149,30 +151,63 @@ const ChildDevice = (props: Props) => {
             <SearchOutlined />
           </Tooltip>
         </Link>,
-        <a key="unbind">
-          <Popconfirm
-            onConfirm={() => {
+        // <a key="unbind">
+        //   <Popconfirm
+        //     onConfirm={() => {
+        //       unBindSingleDevice(record.id);
+        //     }}
+        //     title={'确认解绑吗?'}
+        //   >
+        //     <Tooltip title={'解绑'}>
+        //       <DisconnectOutlined />
+        //     </Tooltip>
+        //   </Popconfirm>
+        // </a>,
+        <PermissionButton
+          key="unbind"
+          type={'link'}
+          popConfirm={{
+            title: '确认解绑吗?',
+            onConfirm: async () => {
               unBindSingleDevice(record.id);
-            }}
-            title={'确认解绑吗?'}
-          >
-            <Tooltip title={'解绑'}>
-              <DisconnectOutlined />
-            </Tooltip>
-          </Popconfirm>
-        </a>,
+            },
+          }}
+          tooltip={{
+            title: devicePermission.update ? '解绑' : '暂无权限,请联系管理员',
+          }}
+          style={{ padding: 0 }}
+          isPermission={devicePermission.update}
+        >
+          <DisconnectOutlined />
+        </PermissionButton>,
         <>
           {props.data.accessProvider === 'official-edge-gateway' && (
-            <a
+            // <a
+            //   onClick={() => {
+            //     setCurrent(record);
+            //     setChildVisible(true);
+            //   }}
+            // >
+            //   <Tooltip title={'编辑'} key={'edit'}>
+            //     <EditOutlined />
+            //   </Tooltip>
+            // </a>
+            <PermissionButton
+              key={'edit'}
+              type={'link'}
               onClick={() => {
                 setCurrent(record);
                 setChildVisible(true);
               }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '编辑' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0 }}
+              isPermission={devicePermission.update}
             >
-              <Tooltip title={'编辑'} key={'edit'}>
-                <EditOutlined />
-              </Tooltip>
-            </a>
+              <EditOutlined />
+            </PermissionButton>
           )}
         </>,
       ],
@@ -227,32 +262,79 @@ const ChildDevice = (props: Props) => {
             toolBarRender={() => [
               <>
                 {props.data.accessProvider === 'official-edge-gateway' && (
-                  <Button
+                  // <Button
+                  //   onClick={() => {
+                  //     // actionRef.current?.reset?.();
+                  //     setCurrent({});
+                  //     setChildVisible(true);
+                  //   }}
+                  //   key="save"
+                  //   type="primary"
+                  // >
+                  //   新增并绑定
+                  // </Button>
+                  <PermissionButton
+                    key={'edit'}
+                    type={'primary'}
                     onClick={() => {
-                      // actionRef.current?.reset?.();
                       setCurrent({});
                       setChildVisible(true);
                     }}
-                    key="save"
-                    type="primary"
+                    tooltip={{
+                      placement: 'top',
+                      title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                    }}
+                    isPermission={devicePermission.update}
                   >
                     新增并绑定
-                  </Button>
+                  </PermissionButton>
                 )}
               </>,
-              <Button
+              // <Button
+              //   onClick={() => {
+              //     setVisible(true);
+              //     actionRef.current?.reset?.();
+              //   }}
+              //   key="bind"
+              //   type="primary"
+              // >
+              //   绑定
+              // </Button>,
+              <PermissionButton
+                key={'bind'}
+                type={'primary'}
                 onClick={() => {
                   setVisible(true);
                   actionRef.current?.reset?.();
                 }}
-                key="bind"
-                type="primary"
+                tooltip={{
+                  placement: 'top',
+                  title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                }}
+                isPermission={devicePermission.update}
               >
                 绑定
-              </Button>,
-              <Popconfirm key="unbind" onConfirm={handleUnBind} title={'确认解绑吗?'}>
-                <Button>批量解绑</Button>
-              </Popconfirm>,
+              </PermissionButton>,
+              // <Popconfirm key="unbind" onConfirm={handleUnBind} title={'确认解绑吗?'}>
+              //   <Button>批量解绑</Button>
+              // </Popconfirm>,
+              <PermissionButton
+                key={'unbind'}
+                type={'primary'}
+                popConfirm={{
+                  title: '确认解绑吗?',
+                  onConfirm: async () => {
+                    handleUnBind();
+                  },
+                }}
+                tooltip={{
+                  placement: 'top',
+                  title: devicePermission.update ? '' : '暂无权限,请联系管理员',
+                }}
+                isPermission={devicePermission.update}
+              >
+                批量解绑
+              </PermissionButton>,
             ]}
             pagination={{
               pageSize: 10,

+ 9 - 7
src/pages/device/Instance/Detail/EdgeMap/mapTable/index.tsx

@@ -6,7 +6,7 @@ import { createForm, Field, FormPath, onFieldReact } from '@formily/core';
 import type { Response } from '@/utils/typings';
 import { FormProvider, createSchemaField } from '@formily/react';
 import { action } from '@formily/reactive';
-import { Badge, Button, Tooltip } from 'antd';
+import { Badge, Tooltip } from 'antd';
 import { useEffect, useState } from 'react';
 import MapTree from '../mapTree';
 import './index.less';
@@ -29,6 +29,7 @@ const MapTable = (props: Props) => {
   const [visible, setVisible] = useState<boolean>(false);
   const [channelList, setChannelList] = useState<any>([]);
   const [deviceData, setDeviceData] = useState<any>({});
+  const { permission } = PermissionButton.usePermission('device/Instance');
 
   const remove = async (params: any) => {
     const res = await service.removeMap(edgeId, {
@@ -61,7 +62,7 @@ const MapTable = (props: Props) => {
     const index = ArrayTable.useIndex?.();
     return (
       <PermissionButton
-        isPermission={true}
+        isPermission={permission.update}
         style={{ padding: 0 }}
         disabled={!record(index)?.id}
         tooltip={{
@@ -411,7 +412,7 @@ const MapTable = (props: Props) => {
     // console.log(metaData, 1111111);
     service.edgeChannel(edgeId).then((res) => {
       if (res.status === 200) {
-        const list = res.result?.[0].map((item: any) => ({
+        const list = res.result?.[0]?.map((item: any) => ({
           label: item.name,
           value: item.id,
           provider: item.provider,
@@ -425,8 +426,9 @@ const MapTable = (props: Props) => {
     <div>
       <div className="top-button">
         {props.title && <TitleComponent data={props.title} />}
-        <Button
+        <PermissionButton
           style={{ marginRight: 10 }}
+          isPermission={permission.update}
           onClick={async () => {
             setVisible(true);
             const value = await props.formRef?.validateFields();
@@ -442,8 +444,8 @@ const MapTable = (props: Props) => {
           }}
         >
           批量映射
-        </Button>
-        <Button
+        </PermissionButton>
+        <PermissionButton
           type="primary"
           onClick={async () => {
             if (props.formRef) {
@@ -461,7 +463,7 @@ const MapTable = (props: Props) => {
           }}
         >
           保存
-        </Button>
+        </PermissionButton>
       </div>
       <div>
         <FormProvider form={form}>

+ 4 - 3
src/pages/device/Instance/Detail/EdgeMap/mapTree/index.tsx

@@ -60,10 +60,11 @@ const MapTree = (props: Props) => {
         metadataId: metaData.find((i: any) => i.name === element.name)?.metadataId,
         provider: data.find((it: any) => it.id === item.parentId).provider,
       }));
-      params.push(...array);
+      if (array) {
+        params.push(...array);
+      }
     });
     const filterParms = params.filter((item) => !!item.metadataId);
-    console.log(metaData);
     console.log('filterParms', filterParms);
     if (deviceId) {
       if (filterParms && filterParms.length !== 0) {
@@ -104,7 +105,7 @@ const MapTree = (props: Props) => {
       if (res.status === 200) {
         // console.log(res.result?.[0], 'data');
         setData(res.result?.[0]);
-        setExpandedKey([res.result?.[0].id]);
+        setExpandedKey([res.result?.[0]?.id]);
       }
     });
   }, []);

+ 24 - 6
src/pages/device/Instance/Detail/MapChannel/index.tsx

@@ -1,7 +1,7 @@
 import useDomFullHeight from '@/hooks/document/useDomFullHeight';
 import { createForm, Field, FormPath, onFieldReact } from '@formily/core';
 import { FormProvider, createSchemaField } from '@formily/react';
-import { Badge, Button, Card, Spin, Tooltip } from 'antd';
+import { Badge, Card, Spin, Tooltip } from 'antd';
 import { useEffect, useState } from 'react';
 import { FormItem, ArrayTable, Editable, Select } from '@formily/antd';
 import PermissionButton from '@/components/PermissionButton';
@@ -21,6 +21,7 @@ interface Props {
 export const service = new Service();
 
 const MapChannel = (props: Props) => {
+  const { permission } = PermissionButton.usePermission('device/Instance');
   const { data, type } = props;
   const { minHeight } = useDomFullHeight('.metadataMap');
   const [empty, setEmpty] = useState<boolean>(false);
@@ -53,7 +54,7 @@ const MapChannel = (props: Props) => {
     const index = ArrayTable.useIndex?.();
     return (
       <PermissionButton
-        isPermission={true}
+        isPermission={permission.update}
         style={{ padding: 0 }}
         disabled={!record(index)?.id}
         tooltip={{
@@ -449,15 +450,16 @@ const MapChannel = (props: Props) => {
       ) : (
         <>
           <div className="top-button">
-            <Button
+            <PermissionButton
               style={{ marginRight: 10 }}
+              isPermission={permission.update}
               onClick={async () => {
                 setVisible(true);
               }}
             >
               批量映射
-            </Button>
-            <Button
+            </PermissionButton>
+            <PermissionButton
               type="primary"
               onClick={async () => {
                 setLoading(true);
@@ -468,9 +470,25 @@ const MapChannel = (props: Props) => {
                   save(array);
                 }
               }}
+              key={'edit'}
+              isPermission={permission.update}
             >
               保存
-            </Button>
+            </PermissionButton>
+            {/* <Button
+              type="primary"
+              onClick={async () => {
+                setLoading(true);
+                const value: any = await form.submit();
+                const arr = value.requestList.filter((i: any) => i.channelId);
+                if (arr && arr.length !== 0) {
+                  const array = value.requestList.filter((item: any) => item.channelId);
+                  save(array);
+                }
+              }}
+            >
+              保存
+            </Button> */}
           </div>
           <Spin spinning={loading}>
             <div className="array-table">

+ 8 - 4
src/pages/device/Instance/Detail/Parsing/index.tsx

@@ -185,26 +185,30 @@ const Parsing = (props: Props) => {
                   {topTitle === 'rest' ? (
                     <>
                       当前数据解析内容已脱离产品影响,
-                      <a
+                      <PermissionButton
+                        type="link"
+                        isPermission={permission.update}
                         onClick={() => {
                           rest(props.data.productId, props.data.id);
                         }}
                       >
                         重置
-                      </a>
+                      </PermissionButton>
                       后将继承产品数据解析内容
                     </>
                   ) : (
                     <>
                       当前数据解析内容继承自产品,
-                      <a
+                      <PermissionButton
+                        type="link"
+                        isPermission={permission.update}
                         style={readOnly ? {} : { color: '#a6a6a6' }}
                         onClick={() => {
                           setReadOnly(false);
                         }}
                       >
                         修改
-                      </a>
+                      </PermissionButton>
                       后将脱离产品影响。
                     </>
                   )}

+ 1 - 1
src/pages/device/Instance/Detail/Running/Property/FileComponent/index.tsx

@@ -33,7 +33,7 @@ export const getType = (url: string) => {
   let t: string = '';
   [...imgList, ...videoList, ...fileList].map((item) => {
     const str = item.slice(1, item.length);
-    if (url.indexOf(str) !== -1) {
+    if (url && String(url).indexOf(str) !== -1) {
       if (imgList.includes(item)) {
         t = 'img';
       } else if (videoList.includes(item)) {

+ 30 - 7
src/pages/device/Instance/Detail/Running/Property/PropertyCard.tsx

@@ -16,6 +16,7 @@ import Indicators from './Indicators';
 import './PropertyCard.less';
 import FileComponent from './FileComponent';
 import { onlyMessage } from '@/utils/util';
+import PermissionButton from '../../../../../../components/PermissionButton';
 
 interface Props {
   data: Partial<PropertyMetadata>;
@@ -26,6 +27,7 @@ const Property = (props: Props) => {
   const { data, value } = props;
 
   const params = useParams<{ id: string }>();
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
 
   const [loading, setLoading] = useState<boolean>(false);
   const refreshProperty = async () => {
@@ -53,13 +55,20 @@ const Property = (props: Props) => {
         </div>
         <Space style={{ fontSize: 12 }}>
           {data.expands?.type?.includes('write') && (
-            <Tooltip placement="top" title="设置属性至设备">
-              <EditOutlined
-                onClick={() => {
-                  setEditVisible(true);
-                }}
-              />
-            </Tooltip>
+            <PermissionButton
+              key={'edit'}
+              onClick={() => {
+                setEditVisible(true);
+              }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '设置属性至设备' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0, border: 'none', backgroundColor: 'inherit' }}
+              isPermission={devicePermission.update}
+            >
+              <EditOutlined />
+            </PermissionButton>
           )}
           {(data.expands?.metrics || []).length > 0 &&
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
@@ -72,6 +81,20 @@ const Property = (props: Props) => {
                   }}
                 />
               </Tooltip>
+              // <PermissionButton
+              //   key={'metrics'}
+              //   onClick={() => {
+              //     setIndicatorVisible(true);
+              //   }}
+              //   tooltip={{
+              //     placement: "top",
+              //     title: devicePermission.update ? "指标" : '暂无权限,请联系管理员'
+              //   }}
+              //   style={{ padding: 0, border: "none", backgroundColor: 'inherit' }}
+              //   isPermission={devicePermission.update}
+              // >
+              //   <ClockCircleOutlined  />
+              // </PermissionButton>
             )}
           {data.expands?.type?.includes('read') && (
             <Tooltip placement="top" title="获取最新属性值">

+ 34 - 10
src/pages/device/Instance/Detail/Running/Property/index.tsx

@@ -21,6 +21,7 @@ import PropertyTable from './PropertyTable';
 import { onlyMessage } from '@/utils/util';
 import Indicators from './Indicators';
 import { Empty } from '@/components';
+import PermissionButton from '../../../../../../components/PermissionButton';
 
 interface Props {
   data: Partial<PropertyMetadata>[];
@@ -51,6 +52,7 @@ const Property = (props: Props) => {
     pageSize: 8,
     currentPage: 0,
   });
+  const devicePermission = PermissionButton.usePermission('device/Instance').permission;
   const [indicatorVisible, setIndicatorVisible] = useState<boolean>(false);
   const [loading, setLoading] = useState<boolean>(true);
 
@@ -94,16 +96,22 @@ const Property = (props: Props) => {
       render: (text: any, record: any) => (
         <Space size="middle">
           {record.expands?.type?.includes('write') && (
-            <Tooltip placement="top" title="设置属性至设备">
-              <a
-                onClick={() => {
-                  setVisible(true);
-                  setCurrentInfo(record);
-                }}
-              >
-                <EditOutlined />
-              </a>
-            </Tooltip>
+            <PermissionButton
+              type={'link'}
+              onClick={() => {
+                setVisible(true);
+                setCurrentInfo(record);
+              }}
+              tooltip={{
+                placement: 'top',
+                title: devicePermission.update ? '设置属性至设备' : '暂无权限,请联系管理员',
+              }}
+              style={{ padding: 0 }}
+              key={'edit'}
+              isPermission={devicePermission.update}
+            >
+              <EditOutlined />
+            </PermissionButton>
           )}
           {(record.expands?.metrics || []).length > 0 &&
             ['int', 'long', 'float', 'double', 'string', 'boolean', 'date'].includes(
@@ -119,6 +127,22 @@ const Property = (props: Props) => {
                   <ClockCircleOutlined />
                 </a>
               </Tooltip>
+              // <PermissionButton
+              //   type={'link'}
+              //   onClick={() => {
+              //     setVisible(true);
+              //     setCurrentInfo(record);
+              //   }}
+              //   tooltip={{
+              //     placement: "top",
+              //     title: devicePermission.update ? "指标" : '暂无权限,请联系管理员'
+              //   }}
+              //   style={{ padding: 0 }}
+              //   key={'edit'}
+              //   isPermission={devicePermission.update}
+              // >
+              //   <ClockCircleOutlined />
+              // </PermissionButton>
             )}
           {record.expands?.type?.includes('read') && (
             <Tooltip placement="top" title="获取最新属性值">

+ 17 - 7
src/pages/device/Instance/Detail/Tags/Edit.tsx

@@ -258,18 +258,28 @@ const Edit = (props: Props) => {
           props.close();
         } else {
           const list = (values?.tags || [])
-            .filter((item: any) => item?.key)
+            .filter((item: any) => item?.key && item?.value)
             .map((i: any) => {
               const { dataType, ...extra } = i;
               return { ...extra };
             });
-          const resp = await service.saveTags(InstanceModel.detail?.id || '', list);
-          if (resp.status === 200) {
-            props.refresh();
-            // InstanceModel.detail = { ...InstanceModel.detail, tags: values.tags };
-            onlyMessage('操作成功!');
-            props.close();
+          if (list.length) {
+            // 填值
+            const resp = await service.saveTags(InstanceModel.detail?.id || '', list);
+            if (resp.status === 200) {
+              onlyMessage('操作成功!');
+            }
           }
+          const _list = (values?.tags || []).filter((item: any) => item?.key && !item?.value);
+          if (_list.length) {
+            // 删除值
+            _list.map(async (item: any) => {
+              if (item.id) {
+                await service.delTags(InstanceModel.detail?.id || '', item.id);
+              }
+            });
+          }
+          props.refresh();
         }
       }}
     >

+ 1 - 0
src/pages/device/Instance/Detail/Tags/index.tsx

@@ -68,6 +68,7 @@ const Tags = () => {
       {visible && (
         <Edit
           refresh={() => {
+            setVisible(false);
             getDetail();
           }}
           close={() => {

+ 1 - 1
src/pages/device/components/Metadata/Base/index.tsx

@@ -99,7 +99,7 @@ const BaseMetadata = observer((props: Props) => {
           <EditOutlined />
         </PermissionButton>,
         <PermissionButton
-          isPermission={props.permission.update}
+          isPermission={props.permission.delete}
           type="link"
           key={'delete'}
           style={{ padding: 0 }}

+ 8 - 8
src/pages/edge/Resource/Issue/Result.tsx

@@ -24,13 +24,13 @@ const Publish = (props: Props) => {
     const errMessages: any[] = [];
     const _terms = {
       deviceId: (props.list || []).map((item) => item.id),
-      // params: {
-      name: props.data.name,
-      targetId: props.data.targetId,
-      targetType: props.data.targetType,
-      category: props.data.category,
-      metadata: encodeURIComponent(props.data?.metadata || ''),
-      // }
+      params: JSON.stringify({
+        name: props.data.name,
+        targetId: props.data.targetId,
+        targetType: props.data.targetType,
+        category: props.data.category,
+        metadata: encodeURIComponent(props.data?.metadata || ''),
+      }),
     };
     const url = new URLSearchParams();
     Object.keys(_terms).forEach((key) => {
@@ -45,7 +45,7 @@ const Publish = (props: Props) => {
     const source = new EventSourcePolyfill(
       `/${
         SystemConst.API_BASE
-      }/edge/operations/entity-template-save/invoke/_batch?:X_Access_Token=${Token.get()}&${url.toString()}`,
+      }/edge/operations/entity-template-save/invoke/_batch?:X_Access_Token=${Token.get()}&${url}`,
     );
     source.onmessage = (e: any) => {
       const res = JSON.parse(e.data);

+ 1 - 1
src/pages/home/components/CardStatics.tsx

@@ -18,7 +18,7 @@ interface StatisticsProps {
   title: string;
 }
 
-const defaultImage = require('/public/images/home/top-1.png');
+const defaultImage = require('/public/images/home/top-1.svg');
 
 const CardStatistics = (props: StatisticsProps) => {
   return (

+ 1 - 1
src/pages/home/components/Statistics.tsx

@@ -17,7 +17,7 @@ interface StatisticsProps {
   title: string;
 }
 
-const defaultImage = require('/public/images/home/top-1.png');
+const defaultImage = require('/public/images/home/top-1.svg');
 
 const Statistics = (props: StatisticsProps) => {
   return (

+ 2 - 2
src/pages/home/comprehensive/index.tsx

@@ -150,13 +150,13 @@ const Comprehensive = () => {
                 {
                   name: '产品数量',
                   value: productCount,
-                  children: require('/public/images/home/top-2.png'),
+                  children: require('/public/images/home/top-2.svg'),
                   permission: productMessage,
                 },
                 {
                   name: '设备数量',
                   value: deviceCount,
-                  children: require('/public/images/home/top-1.png'),
+                  children: require('/public/images/home/top-1.svg'),
                   permission: deviceMessage,
                 },
               ]}

+ 1 - 1
src/pages/home/device/index.tsx

@@ -102,7 +102,7 @@ const Device = () => {
             {
               name: '产品数量',
               value: productCount,
-              children: require('/public/images/home/top-2.png'),
+              children: require('/public/images/home/top-2.svg'),
               permission: productMessage,
             },
             {

+ 30 - 0
src/pages/iot-card/CardManagement/SaveModal.tsx

@@ -35,8 +35,10 @@ const Save = (props: SaveType) => {
 
   const submit = async () => {
     const formData = await form.validateFields();
+
     if (formData) {
       setLoading(true);
+
       const resp =
         props.type === 'add' ? await service.add(formData) : await service.edit(formData);
       setLoading(false);
@@ -46,6 +48,20 @@ const Save = (props: SaveType) => {
       }
     }
   };
+
+  const isValidateId = async (id: string) => {
+    const res = await service.validateId(id);
+    if (res.status === 200) {
+      if (res.result?.passed) {
+        return '';
+      } else {
+        return res.result.reason;
+      }
+    } else {
+      return '请输入输入正确的ICCID';
+    }
+  };
+
   return (
     <Modal
       title={props.type === 'add' ? '新增' : '编辑'}
@@ -80,6 +96,20 @@ const Save = (props: SaveType) => {
           rules={[
             { required: true, message: '请输入ICCID' },
             { max: 64, message: '最多可输入64个字符' },
+            () => ({
+              async validator(_, value) {
+                if (value) {
+                  const validateId = await isValidateId(value);
+                  if (validateId === '') {
+                    return Promise.resolve();
+                  } else {
+                    return Promise.reject(new Error(`${validateId}`));
+                  }
+                } else {
+                  return Promise.reject(new Error('请输入输入正确的ICCID'));
+                }
+              },
+            }),
           ]}
         >
           <Input placeholder={'请输入ICCID'} disabled={props.type === 'edit'} />

+ 2 - 2
src/pages/iot-card/CardManagement/index.tsx

@@ -205,7 +205,7 @@ const CardManagementNode = () => {
           <PermissionButton
             style={{ padding: 0 }}
             type="link"
-            isPermission={true}
+            isPermission={permission.view}
             key="view"
             onClick={() => {
               const url = getMenuPathByParams('iot-card/CardManagement/Detail', record.id);
@@ -221,7 +221,7 @@ const CardManagementNode = () => {
             type="link"
             key="bindDevice"
             style={{ padding: 0 }}
-            isPermission={permission.delete}
+            isPermission={permission.bind}
             tooltip={{ title: record.deviceId ? '解绑设备' : '绑定设备' }}
             popConfirm={
               record.deviceId

+ 2 - 0
src/pages/iot-card/CardManagement/service.ts

@@ -74,6 +74,8 @@ class Service extends BaseService<CardManagement> {
     this.POST(`${basePath}/network/flow/_query/${beginTime}/${endTime}`, data);
   // 查询对应状态物联卡数量
   queryState = (status: string) => this.GET(`${this.uri}/${status}/state/_count`);
+  //验证iccid
+  validateId = (id: string) => this.GET(`${this.uri}/id/_validate?id=${id}`);
 }
 
 export default Service;

+ 12 - 3
src/pages/iot-card/Platform/index.tsx

@@ -203,9 +203,18 @@ const Platform = () => {
             </PermissionButton>
           </>
         }
-        request={async (params) =>
-          service.getList({ ...params, sorts: [{ name: 'createTime', order: 'desc' }] })
-        }
+        request={async (params: any) => {
+          delete params?.total;
+          const res = await service.getList({
+            ...params,
+            sorts: [{ name: 'createTime', order: 'desc' }],
+          });
+          return {
+            code: res.status,
+            result: res.result,
+            status: res.status,
+          };
+        }}
       />
     </PageContainer>
   );

+ 2 - 0
src/pages/media/Cascade/index.tsx

@@ -274,6 +274,8 @@ const Cascade = () => {
               if (resp?.status === 200) {
                 onlyMessage('操作成功!');
                 actionRef.current?.reset?.();
+              } else {
+                onlyMessage('操作失败!', 'error');
               }
             },
           }}

+ 4 - 4
src/pages/media/DashBoard/index.tsx

@@ -226,7 +226,7 @@ export default () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/media/dashboard-1.png')} />
+            <img src={require('/public/images/media/dashboard-1.svg')} />
           </DashBoardTopCard.Item>
           <DashBoardTopCard.Item
             title={'通道数量'}
@@ -245,7 +245,7 @@ export default () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/media/dashboard-2.png')} />
+            <img src={require('/public/images/media/dashboard-2.svg')} />
           </DashBoardTopCard.Item>
           <DashBoardTopCard.Item
             title={'录像数量'}
@@ -258,7 +258,7 @@ export default () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/media/dashboard-3.png')} />
+            <img src={require('/public/images/media/dashboard-3.svg')} />
           </DashBoardTopCard.Item>
           <DashBoardTopCard.Item
             title={
@@ -278,7 +278,7 @@ export default () => {
             ]}
             span={6}
           >
-            <img src={require('/public/images/media/dashboard-4.png')} />
+            <img src={require('/public/images/media/dashboard-4.svg')} />
           </DashBoardTopCard.Item>
         </DashBoardTopCard>
         <DashBoard

+ 2 - 2
src/pages/media/Home/index.tsx

@@ -109,12 +109,12 @@ export default () => {
               {
                 name: '设备数量',
                 value: deviceTotal || 0,
-                children: require('/public/images/home/top-1.png'),
+                children: require('/public/images/home/top-1.svg'),
               },
               {
                 name: '通道数量',
                 value: channelTotal || 0,
-                children: require('/public/images/home/top-2.png'),
+                children: require('/public/images/home/top-2.svg'),
               },
             ]}
             extra={

+ 8 - 0
src/pages/media/Stream/index.tsx

@@ -194,6 +194,14 @@ const Stream = () => {
                           </PermissionButton>,
                           <PermissionButton
                             isPermission={permission.delete}
+                            tooltip={
+                              item?.state?.value === 'enabled'
+                                ? {
+                                    title: '正常的流媒体服务不能删除',
+                                  }
+                                : undefined
+                            }
+                            disabled={item?.state?.value === 'enabled'}
                             popConfirm={{
                               title: '确认删除',
                               onConfirm: () => {

+ 4 - 5
src/pages/notice/Config/Detail/doc/AliyunVoice.tsx

@@ -19,14 +19,13 @@ const AliyunVoice = () => {
       <h1>2.通知配置说明</h1>
       <div>
         <h2>1、RegionID</h2>
-        <div>
-          阿里云内部给每台机器设置的唯一编号。请根据购买的阿里云服务器阿里云地域和可用区对照表地址:https://help.aliyun.com/document_detail/40654.html?spm=a2c6h.13066369.0.0.54a174710O7rWH
-        </div>
+        <div>阿里云服务地域与对应的RegionID。请根据购买的阿里云服务器地域进行选择。</div>
       </div>
       <h2>2、AccesskeyID/Secret</h2>
       <div>
-        <div>用于程序通知方式调用云服务费API的用户标识和秘钥公众号开发者身份的密码</div>
-        <div>获取路径:“阿里云管理控制台”--“用户头像”--“”--“AccessKey管理”--“查看”</div>
+        <div>
+          用于程序通知方式调用云服务费API的用户标识和秘钥获取路径:“阿里云管理控制台”--“用户头像”--“”--“AccessKey管理”--“查看”
+        </div>
       </div>
       <div className={'image'}>
         <Image width="100%" src={accessKey} />

+ 8 - 9
src/pages/notice/Config/Detail/index.tsx

@@ -37,6 +37,7 @@ import FAutoComplete from '@/components/FAutoComplete';
 import Webhook from './doc/Webhook';
 // import { useModel } from '@@/plugin-model/useModel';
 import { typeArray } from '@/components/ProTableCard/CardItems/noticeTemplate';
+import RegionIdList from './regionId';
 
 export const docMap = {
   weixin: {
@@ -402,16 +403,11 @@ const Detail = observer(() => {
                 title: 'RegionId',
                 required: true,
                 'x-component-props': {
-                  placeholder: '请输入regionId',
+                  placeholder: '请选择regionId',
                 },
-                'x-component': 'Input',
+                'x-component': 'Select',
                 'x-decorator': 'FormItem',
-                'x-validator': [
-                  {
-                    max: 64,
-                    message: '最多可输入64个字符',
-                  },
-                ],
+                enum: RegionIdList,
               },
               accessKeyId: {
                 title: 'AccessKeyId',
@@ -695,7 +691,10 @@ const Detail = observer(() => {
         'x-decorator': 'FormItem',
         'x-component': 'Input.TextArea',
         'x-component-props': {
-          rows: 4,
+          rows: 5,
+          placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         'x-validator': [
           {

+ 119 - 0
src/pages/notice/Config/Detail/regionId.ts

@@ -0,0 +1,119 @@
+//  数据来源 https://help.aliyun.com/document_detail/188196.html
+export default [
+  /** 公共云 */
+  //中国地区(包含中国香港、中国澳门,不包含中国台湾)
+  {
+    value: 'cn-qingdao',
+    label: '华北1(青岛)',
+  },
+  {
+    value: 'cn-beijing',
+    label: '华北2(北京)',
+  },
+  {
+    value: 'cn-zhangjiakou',
+    label: '华北3(张家口)',
+  },
+  {
+    value: 'cn-huhehaote',
+    label: '华北5(呼和浩特)',
+  },
+  {
+    value: 'cn-wulanchabu',
+    label: '华北6(乌兰察布)',
+  },
+  {
+    value: 'cn-hangzhou',
+    label: '华东1(杭州)',
+  },
+  {
+    value: 'cn-shanghai',
+    label: '华东2(上海)',
+  },
+  {
+    value: 'cn-nanjing',
+    label: '华东5 (南京-本地地域)',
+  },
+  {
+    value: 'cn-fuzhou',
+    label: '华东6(福州-本地地域)',
+  },
+  {
+    value: 'cn-shenzhen',
+    label: '华南1(深圳)',
+  },
+  {
+    value: 'cn-heyuan',
+    label: '华南2(河源)',
+  },
+  {
+    value: 'cn-guangzhou',
+    label: '华南3(广州)',
+  },
+  {
+    value: 'cn-chengdu',
+    label: '西南1(成都)',
+  },
+  {
+    value: 'cn-hongkong',
+    label: '中国香港',
+  },
+
+  //其他国家和地区
+  {
+    value: 'ap-southeast-1',
+    label: '新加坡',
+  },
+  {
+    value: 'ap-southeast-2',
+    label: '澳大利亚(悉尼)',
+  },
+  {
+    value: 'ap-southeast-3',
+    label: '马来西亚(吉隆坡)',
+  },
+  {
+    value: 'ap-southeast-5',
+    label: '印度尼西亚(雅加达)',
+  },
+  {
+    value: 'ap-southeast-6',
+    label: '菲律宾(马尼拉)',
+  },
+  {
+    value: 'ap-southeast-7',
+    label: '泰国(曼谷)',
+  },
+  {
+    value: 'ap-south-1',
+    label: '印度(孟买)',
+  },
+  {
+    value: 'ap-northeast-1',
+    label: '日本(东京)',
+  },
+  {
+    value: 'ap-northeast-2',
+    label: '韩国(首尔)',
+  },
+  {
+    value: 'us-west-1',
+    label: '美国(硅谷)',
+  },
+  {
+    value: 'us-east-1',
+    label: '美国(弗吉尼亚)',
+  },
+  {
+    value: 'eu-central-1',
+    label: '德国(法兰克福)',
+  },
+  {
+    value: 'eu-west-1',
+    label: '英国(伦敦)',
+  },
+  {
+    value: 'me-east-1',
+    label: '阿联酋(迪拜)',
+  },
+];

+ 7 - 4
src/pages/notice/Template/Detail/index.tsx

@@ -174,7 +174,7 @@ const Detail = observer(() => {
               state1.dataSource = typeList[value];
             });
           });
-          onFieldValueChange('provider', (field, form1) => {
+          onFieldValueChange('provider', async (field, form1) => {
             const value = field.value;
             if (field.modified) {
               form1.setValuesIn('configId', null);
@@ -182,10 +182,10 @@ const Detail = observer(() => {
             }
             const _type = field.query('type').value();
             // 设置绑定配置的数据
+            const _list = await getConfig(_type, value);
             form1.setFieldState('configId', async (state1) => {
-              state1.dataSource = await getConfig(_type, value);
+              state1.dataSource = _list;
             });
-            console.log(_type, value);
             if (_type === 'email') {
               setProviderItem('embedded');
             } else {
@@ -1637,7 +1637,10 @@ const Detail = observer(() => {
         'x-decorator': 'FormItem',
         'x-component': 'Input.TextArea',
         'x-component-props': {
-          rows: 4,
+          rows: 5,
+          placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         'x-validator': [
           {

+ 2 - 0
src/pages/rule-engine/Instance/Save/index.tsx

@@ -74,6 +74,8 @@ const Save = (props: Props) => {
         'x-component-props': {
           rows: 5,
           placeholder: '请输入说明',
+          showCount: true,
+          maxLength: 200,
         },
         'x-validator': [
           {

+ 1 - 2
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/ObjModel.tsx

@@ -24,8 +24,7 @@ export default (props: Props) => {
       zIndex={1050}
       onCancel={() => props.close()}
       onOk={() => {
-        props.ok(JSON.parse(value));
-        console.log(value, JSON.parse(value));
+        props.ok(value);
       }}
     >
       <div

+ 5 - 0
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/ReadProperty.tsx

@@ -20,6 +20,11 @@ export default (props: ReadPropertyProps) => {
         return false;
       })}
       fieldNames={{ label: 'name', value: 'id' }}
+      filterOption={(input: string, option: any) =>
+        option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
+      }
+      showSearch
+      allowClear
       style={{ width: '100%' }}
       onSelect={(key: any, option: any) => {
         // console.log(key,option)

+ 3 - 2
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/TypeModel.tsx

@@ -325,10 +325,11 @@ export default observer((props: Props) => {
             setObjVisable(false);
           }}
           ok={(param) => {
+            console.log('------', param);
             if (props.onChange) {
-              props.onChange(JSON.stringify(param));
+              props.onChange(JSON.parse(param));
             }
-            setValue(JSON.stringify(param));
+            setValue(param);
             setObjVisable(false);
           }}
         />

+ 11 - 2
src/pages/rule-engine/Scene/Save/action/DeviceOutput/actions/WriteProperty.tsx

@@ -18,7 +18,7 @@ interface Props {
 
 export default (props: Props) => {
   const [propertiesId, setPropertiesId] = useState<string | undefined>(undefined);
-  const [propertiesValue, setPropertiesValue] = useState(undefined);
+  const [propertiesValue, setPropertiesValue] = useState<any>(undefined);
   const [propertiesType, setPropertiesType] = useState('');
   const [source, setSource] = useState<string>('fixed');
   const textRef = useRef<any>('');
@@ -92,6 +92,11 @@ export default (props: Props) => {
             return false;
           })}
           fieldNames={{ label: 'name', value: 'id' }}
+          filterOption={(input: string, option: any) =>
+            option.name.toLowerCase().indexOf(input.toLowerCase()) >= 0
+          }
+          showSearch
+          allowClear
           style={{ width: '100%' }}
           placeholder={'请选择属性'}
           onChange={(e, option) => {
@@ -111,7 +116,11 @@ export default (props: Props) => {
       {propertiesId && (
         <Col span={12}>
           <TypeModel
-            value={propertiesValue}
+            value={
+              typeof propertiesValue === 'object'
+                ? JSON.stringify(propertiesValue)
+                : propertiesValue
+            }
             label={label}
             type={propertiesType}
             name={props.name}

+ 4 - 1
src/pages/rule-engine/Scene/Save/action/DeviceOutput/index.tsx

@@ -142,7 +142,10 @@ export default observer((props: Props) => {
     if (_type === 'WRITE_PROPERTY') {
       _options.type = '设置';
       _options.properties = DeviceModel.propertiesName;
-      _options.propertiesValue = DeviceModel.propertiesValue;
+      _options.propertiesValue =
+        typeof DeviceModel.propertiesValue === 'object'
+          ? JSON.stringify(DeviceModel.propertiesValue)
+          : DeviceModel.propertiesValue;
       _options.columns = DeviceModel.columns;
       _options.otherColumns = DeviceModel.columns;
       const cur: any = Object.values(value.message.properties)?.[0];

+ 3 - 4
src/pages/system/Department/Assets/deivce/index.tsx

@@ -201,7 +201,7 @@ export default observer((props: { parentId: string }) => {
             setPermissions(record.grantedPermissions!);
             setUpdateVisible(true);
           }}
-          isPermission={permission.edit}
+          isPermission={permission.assert}
         >
           <EditOutlined />
         </PermissionButton>,
@@ -434,8 +434,7 @@ export default observer((props: { parentId: string }) => {
                 onClick={(e) => {
                   e?.stopPropagation();
                 }}
-                // isPermission={permission.bind}
-                isPermission={permission.assert}
+                isPermission={permission.bind}
               >
                 <DisconnectOutlined />
               </PermissionButton>,
@@ -475,7 +474,7 @@ export default observer((props: { parentId: string }) => {
                 defaultMessage: '批量解绑',
               }),
             }}
-            isPermission={permission.assert}
+            isPermission={permission.bind}
           >
             {intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',

+ 4 - 4
src/pages/system/Department/Assets/product/index.tsx

@@ -184,8 +184,7 @@ export default observer((props: { parentId: string }) => {
               singleUnBind(record.id);
             },
           }}
-          // isPermission={permission.bind}
-          isPermission={permission.assert}
+          isPermission={permission.bind}
         >
           <DisconnectOutlined />
         </PermissionButton>,
@@ -415,7 +414,8 @@ export default observer((props: { parentId: string }) => {
                   setPermissions(record.grantedPermissions!);
                   setUpdateVisible(true);
                 }}
-                isPermission={permission.edit}
+                // isPermission={permission.edit}
+                isPermission={permission.assert}
               >
                 <EditOutlined />
               </PermissionButton>,
@@ -477,7 +477,7 @@ export default observer((props: { parentId: string }) => {
                 defaultMessage: '批量解绑',
               }),
             }}
-            isPermission={permission.assert}
+            isPermission={permission.bind}
           >
             {intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',

+ 0 - 18
src/pages/system/Menu/Setting/baseMenu.ts

@@ -1469,24 +1469,6 @@ export default [
                 ],
               },
               {
-                id: 'action',
-                name: '启/禁用',
-                permissions: [
-                  {
-                    permission: 'firmware-manager',
-                    actions: ['query'],
-                  },
-                  {
-                    permission: 'device-instance',
-                    actions: ['query'],
-                  },
-                  {
-                    permission: 'firmware-upgrade-task-manager',
-                    actions: ['query', 'deploy'],
-                  },
-                ],
-              },
-              {
                 id: 'delete',
                 name: '删除',
                 permissions: [

+ 1 - 1
src/pages/system/User/Save/index.tsx

@@ -490,7 +490,7 @@ const Save = (props: Props) => {
       onOk={save}
       width="35vw"
       permissionCode={'system/User'}
-      permission={['update']}
+      permission={['update', 'add']}
     >
       <Form form={form} layout="vertical">
         <SchemaField schema={schema} scope={{ useAsyncDataSource, getRole, getOrg }} />