Browse Source

feat: portal trial

Signed-off-by: carlos <568187512@qq.com>
carlos 2 months ago
parent
commit
9abd7fc188

+ 1 - 0
package.json

@@ -11,6 +11,7 @@
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
   "dependencies": {
   "dependencies": {
+    "@nutui/icons-react": "^1.0.5",
     "@nutui/nutui-react": "^2.7.0",
     "@nutui/nutui-react": "^2.7.0",
     "@unocss/reset": "^0.64.0",
     "@unocss/reset": "^0.64.0",
     "clsx": "^2.1.1",
     "clsx": "^2.1.1",

+ 3 - 0
pnpm-lock.yaml

@@ -8,6 +8,9 @@ importers:
 
 
   .:
   .:
     dependencies:
     dependencies:
+      '@nutui/icons-react':
+        specifier: ^1.0.5
+        version: 1.0.5
       '@nutui/nutui-react':
       '@nutui/nutui-react':
         specifier: ^2.7.0
         specifier: ^2.7.0
         version: 2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
         version: 2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)

+ 44 - 0
src/assets/icons/task/hazard-handle.svg

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="78px" height="78px" viewBox="0 0 78 78" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <rect id="path-1" x="0" y="0" width="54" height="54" rx="14"></rect>
+        <filter x="-40.7%" y="-25.9%" width="181.5%" height="181.5%" filterUnits="objectBoundingBox" id="filter-2">
+            <feOffset dx="0" dy="8" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="6" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.824683601   0 0 0 0 0.856798818   0 0 0 0 0.914147418  0 0 0 0.430097247 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-69.6%" y="-61.8%" width="239.1%" height="223.6%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.188235294   0 0 0 0 0.560784314   0 0 0 0 0.960784314  0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <linearGradient x1="3.0492161%" y1="0%" x2="61.3930169%" y2="65.4215525%" id="linearGradient-4">
+            <stop stop-color="#00B8FF" offset="0%"></stop>
+            <stop stop-color="#3987F3" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-11.000000, -569.000000)">
+            <g id="编组-12" transform="translate(23.000000, 496.000000)">
+                <g id="编组-20" transform="translate(0.000000, 77.000000)">
+                    <g id="矩形">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                        <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
+                    </g>
+                    <rect id="矩形" fill="#D8D8D8" opacity="0" x="13" y="13" width="28" height="29"></rect>
+                    <g id="daishenpi" filter="url(#filter-3)" transform="translate(15.000000, 15.071429)" fill-rule="nonzero">
+                        <path d="M18.1019087,23.735119 L4.8980913,23.735119 C2.19193807,23.735119 0,21.4298458 0,18.5873745 L0,5.1477445 C0,2.30366003 2.19347304,0 4.8980913,0 L18.1019087,0 C20.8080619,0 23,2.30527324 23,5.1477445 L23,18.5857613 C23,21.4298458 20.8080619,23.735119 18.1019087,23.735119 Z" id="路径" fill="url(#linearGradient-4)"></path>
+                        <path d="M11.5,19.9590774 C11.5,23.2362135 14.0743627,25.8928571 17.25,25.8928571 C20.4256373,25.8928571 23,23.2362135 23,19.9590774 C23,16.6819413 20.4256373,14.0252976 17.25,14.0252976 C14.0743627,14.0252976 11.5,16.6819413 11.5,19.9590774 Z" id="路径" fill="#FFFFFF"></path>
+                        <path d="M15.4027987,22.9285714 C14.9044538,22.9285714 14.5,22.5325785 14.5,22.0446586 L14.5,17.8124842 C14.5,17.3245644 14.9044538,16.9285714 15.4027987,16.9285714 C15.9011435,16.9285714 16.3055974,17.3245644 16.3055974,17.8124842 L16.3055974,21.1598619 L19.5972013,21.1598619 C20.0955462,21.1598619 20.5,21.5558549 20.5,22.0437747 C20.5,22.5316946 20.0955462,22.9285714 19.5972013,22.9285714 L15.4027987,22.9285714 Z" id="路径" fill="#3987F3"></path>
+                        <path d="M13.6316636,8.53339223 L6.23197274,8.53339223 C5.38772202,8.53339223 4.70454545,7.83138717 4.70454545,6.96386873 C4.70454545,6.09635029 5.38772202,5.39434524 6.23197274,5.39434524 L13.6316636,5.39434524 C14.4759143,5.39434524 15.1590909,6.09635029 15.1590909,6.96386873 C15.1590909,7.83138717 14.4745258,8.53339223 13.6316636,8.53339223 Z M10.5559805,14.0252976 L6.23197274,14.0252976 C5.38772202,14.0252976 4.70454545,13.3232926 4.70454545,12.4557741 C4.70454545,11.5882557 5.38772202,10.8862506 6.23197274,10.8862506 L10.5559805,10.8862506 C11.4002312,10.8862506 12.0834078,11.5882557 12.0834078,12.4557741 C12.0834078,13.3218657 11.3988427,14.0252976 10.5559805,14.0252976 Z" id="形状" fill="#FFFFFF"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 49 - 0
src/assets/icons/task/hazard-inspect.svg

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="78px" height="78px" viewBox="0 0 78 78" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <rect id="path-1" x="0" y="0" width="54" height="54" rx="14"></rect>
+        <filter x="-40.7%" y="-25.9%" width="181.5%" height="181.5%" filterUnits="objectBoundingBox" id="filter-2">
+            <feOffset dx="0" dy="8" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="6" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.824683601   0 0 0 0 0.856798818   0 0 0 0 0.914147418  0 0 0 0.430097247 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-69.6%" y="-64.0%" width="239.1%" height="228.0%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.188235294   0 0 0 0 0.560784314   0 0 0 0 0.960784314  0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <linearGradient x1="0%" y1="0.361662466%" x2="62.1329358%" y2="65.3100046%" id="linearGradient-4">
+            <stop stop-color="#00B8FF" offset="0%"></stop>
+            <stop stop-color="#3987F3" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="0%" y1="32.1301985%" x2="100%" y2="59.3188223%" id="linearGradient-5">
+            <stop stop-color="#3987F3" offset="0%"></stop>
+            <stop stop-color="#3987F3" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-11.000000, -492.000000)">
+            <g id="编组-8" transform="translate(23.000000, 496.000000)">
+                <g id="矩形">
+                    <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                    <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>
+                </g>
+                <rect id="矩形" fill="#D8D8D8" opacity="0" x="13" y="14" width="28" height="28"></rect>
+                <g id="daishenpi" filter="url(#filter-3)" transform="translate(15.000000, 16.000000)" fill-rule="nonzero">
+                    <path d="M18.1019087,22.9166667 L4.8980913,22.9166667 C2.19193807,22.9166667 0,20.6908856 0,17.9464306 L0,4.97023607 C0,2.22422348 2.19347304,0 4.8980913,0 L18.1019087,0 C20.8080619,0 23,2.22578106 23,4.97023607 L23,17.944873 C23,20.6908856 20.8080619,22.9166667 18.1019087,22.9166667 Z" id="路径" fill="url(#linearGradient-4)"></path>
+                    <path d="M11.5,19.2708333 C11.5,22.4349647 14.0743627,25 17.25,25 C20.4256373,25 23,22.4349647 23,19.2708333 C23,16.106702 20.4256373,13.5416667 17.25,13.5416667 C14.0743627,13.5416667 11.5,16.106702 11.5,19.2708333 Z" id="路径" fill="#FFFFFF"></path>
+                    <g id="编组-4" transform="translate(16.988636, 19.791667) rotate(-360.000000) translate(-16.988636, -19.791667) translate(13.068182, 15.625000)" fill="url(#linearGradient-5)">
+                        <path d="M0.0894453963,2.15319139 L2.63420721,0.0544977936 C2.7905352,-0.0742969351 3.02341556,0.0396368633 3.02341556,0.245213065 L3.02341556,1.6190235 L5.15640623,1.6190235 C5.88083336,1.6190235 7.55531564,1.72222441 7.83976812,3.77633521 C7.85427278,3.88036172 7.7269541,3.94063105 7.65845988,3.86219836 C7.27811549,3.42297531 6.82685944,3.0910812 5.94207525,3.0910812 L3.02341556,3.0910812 L3.02341556,4.44177464 C3.02341556,4.64817645 2.7905352,4.76211025 2.63420721,4.63248991 L0.0894453963,2.53462193 C-0.0298151321,2.43720027 -0.0298151321,2.25143865 0.0894453963,2.15319139 L0.0894453963,2.15319139 Z" id="路径"></path>
+                        <path d="M4.81752114,8.08739286 L4.81752114,6.71401631 L2.68451825,6.71401631 C1.96008697,6.71401631 0.285595088,6.610848 0.00114098093,4.55738596 C-0.0133637611,4.4533923 0.113955641,4.39314201 0.182450256,4.47154992 C0.562796824,4.91063425 1.01405546,5.24242354 1.89884473,5.24242354 L4.81752114,5.24242354 L4.81752114,3.89133135 C4.81752114,3.68582007 5.05040284,3.57109691 5.20673172,3.70067631 L7.75150812,5.79870706 C7.80803094,5.8452351 7.84090909,5.91550227 7.84090909,5.98977477 C7.84090909,6.06404728 7.80803094,6.13431444 7.75150812,6.18084249 L5.20673172,8.27887324 C5.05040284,8.40762729 4.81752114,8.29372948 4.81752114,8.08739286 L4.81752114,8.08739286 Z" id="路径"></path>
+                    </g>
+                    <path d="M13.6316636,8.23913732 L6.23197274,8.23913732 C5.38772202,8.23913732 4.70454545,7.56133934 4.70454545,6.72373533 C4.70454545,5.88613132 5.38772202,5.20833333 6.23197274,5.20833333 L13.6316636,5.20833333 C14.4759143,5.20833333 15.1590909,5.88613132 15.1590909,6.72373533 C15.1590909,7.56133934 14.4745258,8.23913732 13.6316636,8.23913732 Z M10.5559805,13.5416667 L6.23197274,13.5416667 C5.38772202,13.5416667 4.70454545,12.8638687 4.70454545,12.0262647 C4.70454545,11.1886607 5.38772202,10.5108627 6.23197274,10.5108627 L10.5559805,10.5108627 C11.4002312,10.5108627 12.0834078,11.1886607 12.0834078,12.0262647 C12.0834078,12.862491 11.3988427,13.5416667 10.5559805,13.5416667 Z" id="形状" fill="#FFFFFF"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/assets/images/empty.png


+ 24 - 0
src/assets/images/nav-bar/hazard-ball.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="49px" height="49px" viewBox="0 0 49 49" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <linearGradient x1="51.253%" y1="89.022%" x2="37.681%" y2="7.483%" id="linearGradient-1">
+            <stop stop-color="#286DFF" offset="0%"></stop>
+            <stop stop-color="#28E9FF" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-164.000000, -955.000000)">
+            <g id="分组-2" transform="translate(-7.000000, 955.000000)">
+                <g id="编组-36" transform="translate(171.000000, 0.000000)">
+                    <g id="分组-1" fill="url(#linearGradient-1)">
+                        <path d="M49,24.5 C49,38.0309764 38.0309764,49 24.5,49 C10.9690236,49 0,38.0309764 0,24.5 C0,10.9690236 10.9690236,0 24.5,0 C38.0309764,0 49,10.9690236 49,24.5 Z" id="路径"></path>
+                    </g>
+                    <g id="编组" transform="translate(17.000000, 14.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M5.41258781,13.4609588 L0.850934919,13.4609588 C0.255370059,13.4609588 -0.155462043,12.8708094 0.0564706598,12.3202091 L4.58922363,0.541905198 C4.71476652,0.215667043 5.030756,0 5.38340458,0 L13.0322481,0 C13.6357463,0 14.0471451,0.605295774 13.8193458,1.15870102 L11.1801037,7.57180683 L16.1486221,7.57180683 C16.8793365,7.57180683 17.269202,8.42449411 16.7872535,8.96808224 L4.60565693,22.7092498 C4.01349206,23.3773751 2.91557869,22.7984453 3.14536133,21.9393068 L5.41258781,13.4609588 Z" id="路径"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 24 - 0
src/assets/images/nav-bar/home.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="19px" height="20px" viewBox="0 0 19 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="nav-home-icon">
+            <!-- <stop stop-color="#49352F" offset="0%"></stop> -->
+            <stop stop-color="var(--st1)" offset="0%"></stop>
+            <stop stop-color="var(--st2)" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-32.000000, -988.000000)" fill="url(#nav-home-icon)" fill-rule="nonzero">
+            <g id="分组-2" transform="translate(-7.000000, 955.000000)">
+                <g id="画板-1" transform="translate(8.000000, 24.000000)">
+                    <g id="画板-3" transform="translate(28.000000, 6.000000)">
+                        <g id="路径-3" transform="translate(3.000000, 3.000000)">
+                            <path d="M16.7897352,19.9995724 L16.2799562,19.9995724 C15.8296717,19.9995724 14.9828352,19.6168802 14.9828352,19.1443943 C14.9828352,18.6719084 15.3475452,18.2892163 15.7978296,18.2892163 L16.3076086,18.2892163 C16.6274939,18.2892163 16.8878846,18.0100006 16.8878846,17.6666466 L16.8878846,7.25998463 C16.8878846,7.04490734 16.7868253,6.84821638 16.6173065,6.73362252 L9.5,2.37056726 C9.31173629,2.24271813 9.06805296,2.24314572 8.87978925,2.37099484 L2.34116201,6.73276734 C2.17205067,6.8477888 2.07139886,7.04447975 2.07139886,7.25870186 L2.07139886,17.3899375 C2.07139886,17.7332915 2.33178958,18.0125072 2.65167488,18.0125072 L10.7469017,18.0125072 C11.066787,18.0125072 11.3271778,17.7332915 11.3271778,17.3899375 L11.3271778,10.0068166 C11.3271778,9.66346261 11.066787,9.38424697 10.7469017,9.38424697 L7.68496774,9.38424697 C7.36508243,9.38424697 7.18199054,9.69930688 7.18199054,10.0426609 L7.18199054,15.3011509 C7.18199054,15.7736367 6.62632594,16.1563289 6.17604153,16.1563289 C5.72575712,16.1563289 5.2837483,15.7377925 5.2837483,15.2653066 C5.2837483,12.4718432 5.2837483,10.6462397 5.2837483,9.78849612 C5.2837483,8.5018807 6.4661436,7.45514274 7.68496774,7.45514274 L11.1013221,7.45557033 C12.3201462,7.45557033 13.3115869,8.50230829 13.3115869,9.78849612 L13.3115869,17.6670742 C13.3115869,18.9536896 12.3201462,20 11.1013221,20 L2.25832746,19.9995724 C1.03950332,19.9995724 0.0480626175,18.9528344 0.0480626175,17.6666466 L0,7.09690933 C0,6.29988336 0.378972401,5.56656816 1.01426054,5.13513082 L8.02932493,0.37007859 C8.75507745,-0.12293157 9.69313602,-0.123359159 10.4197035,0.368795823 L17.9356394,5.13513082 C18.57215,5.56614057 18.9519374,6.30031095 18.9519374,7.09861968 L19,17.6670742 C19,18.953262 18.0081518,19.9995724 16.7897352,19.9995724 Z" id="路径"></path>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 38 - 0
src/assets/images/nav-bar/my.svg

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>减少用户 8</title>
+    <defs>
+        <rect id="path-1" x="0" y="0" width="24" height="24"></rect>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="nav-my-mask-3">
+            <stop stop-color="var(--st1)" offset="0%"></stop>
+            <stop stop-color="var(--st2)" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="nav-my-mask-4">
+            <stop stop-color="var(--st3)" offset="0%"></stop>
+            <stop stop-color="var(--st4)" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="-237.504689%" x2="50%" y2="358.421942%" id="nav-my-mask-5">
+            <stop stop-color="var(--st5)" offset="0%"></stop>
+            <stop stop-color="var(--st6)" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-284.000000, -985.000000)">
+            <g id="分组-2" transform="translate(-7.000000, 955.000000)">
+                <g id="画板-1" transform="translate(8.000000, 24.000000)">
+                    <g id="画板-4" transform="translate(249.000000, 6.000000)">
+                        <g id="减少用户" transform="translate(34.000000, 0.000000)">
+                            <mask id="mask-2" fill="white">
+                                <use xlink:href="#path-1"></use>
+                            </mask>
+                            <g id="路径"></g>
+                            <path d="M15.9999995,5.99999988 C15.9999995,8.20913907 14.2091393,9.99999988 11.9999995,9.99999988 C9.79086074,9.99999988 7.99999952,8.20913907 7.99999952,5.99999988 C7.99999952,3.79086093 9.79086074,1.99999988 11.9999995,1.99999988 C14.2091393,1.99999988 15.9999995,3.79086093 15.9999995,5.99999988 L15.9999995,5.99999988 Z" id="路径" stroke="url(#nav-my-mask-3)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="0,0" fill-rule="nonzero" mask="url(#mask-2)"></path>
+                            <path d="M21,21.9999995 C21,17.02945 16.97055,12.9999995 12,12.9999995 C7.02945,12.9999995 3,17.02945 3,21.9999995" id="路径" stroke="url(#nav-my-mask-4)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="0,0" fill-rule="nonzero" mask="url(#mask-2)"></path>
+                            <line x1="9.5" y1="19.5" x2="14.5" y2="19.5" id="路径" stroke="url(#nav-my-mask-5)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="0,0" fill-rule="nonzero" mask="url(#mask-2)"></line>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 17 - 0
src/assets/images/nav-bar/risk.svg

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="25px" viewBox="0 0 22 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="nav-risk-icon">
+            <stop stop-color="var(--st1)" offset="0%"></stop>
+            <stop stop-color="var(--st2)" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-251.000000, -985.000000)" fill="url(#nav-risk-icon)" fill-rule="nonzero">
+            <g id="编组" transform="translate(251.566290, 985.625987)">
+                <path d="M9.95656707,0.0734951728 C10.2308528,-0.0127562685 10.8841936,-0.0228189367 11.1641936,0.0418696443 L11.2827651,0.0749326968 L19.6113365,2.90198525 C20.2799079,3.11186376 20.8750878,3.73143661 20.917945,4.44588605 L20.9208021,4.55370035 L20.9208021,14.1407963 C20.9208021,15.6639181 20.5025131,17.029314 19.6777111,18.2383741 C18.2014177,20.4024418 15.3228793,22.3340832 11.3094562,23.5044306 L10.4604011,23.6424329 L9.98090218,23.5806194 C3.63804504,21.7880269 0.0957142857,18.5338697 0,14.3204868 L0,14.1393588 C0,12.0092125 0,10.4116027 0,9.34652956 C0,8.2814564 0,6.68384667 0,4.55370035 C0,3.82918824 0.696641739,3.18805253 1.34664174,2.93648583 L1.4437846,2.90198525 L9.95656707,0.0734951728 Z M10.4337099,2.09865757 L2.10085279,4.71495129 L2.10085279,14.1393588 C2.10085279,17.3450373 4.61370993,19.7787655 9.87085279,21.4146678 L10.1279956,21.4937317 L10.4337099,21.5842957 L10.7408528,21.4937317 C15.9979956,19.9095802 18.5979956,17.5520408 18.7594242,14.449864 L18.7651385,14.2946114 L18.7665671,14.1393588 L18.7665671,4.71495129 L10.4337099,2.09865757 Z M13.1708528,11.1708717 L14.0154812,11.1708717 C14.4918348,11.1708717 14.8779956,11.5570325 14.8779956,12.0333861 C14.8779956,12.5097396 14.4918348,12.8959005 14.0154812,12.8959005 L12.0294242,12.8959005 L12.0294242,12.8959005 L11.4865671,11.4468763 L9.42085279,16.1245794 L7.55799565,12.9433388 L6.8533672,12.9433388 C6.37701364,12.9433388 5.99085279,12.5571779 5.99085279,12.0808244 C5.99085279,11.6044708 6.37701364,11.21831 6.8533672,11.21831 L8.49942422,11.21831 L8.49942422,11.21831 L9.2151385,12.4416429 L11.6151385,7.01211467 L13.1708528,11.1708717 Z" id="形状"></path>
+            </g>
+        </g>
+    </g>
+</svg>

+ 25 - 0
src/assets/images/nav-bar/statistic.svg

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="20px" viewBox="0 0 22 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title></title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="nav-statistics-icon">
+            <stop stop-color="var(--st1)" offset="0%"></stop>
+            <stop stop-color="var(--st2)" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="首页" transform="translate(-103.000000, -987.000000)"  fill="url(#nav-statistics-icon)" fill-rule="nonzero">
+            <g id="分组-2" transform="translate(-7.000000, 955.000000)">
+                <g id="画板-1" transform="translate(8.000000, 24.000000)">
+                    <g id="画板-3" transform="translate(28.000000, 6.000000)">
+                        <g id="画板-2" transform="translate(74.000000, 0.000000)">
+                            <g id="编组" transform="translate(0.000000, 2.000000)">
+                                <path d="M5.42667154,14.527926 L10.9803436,17.5916329 L16.5340156,14.527926 C17.0389196,14.2494828 17.6696411,14.4405658 17.9433351,14.9544654 C18.2167567,15.4686424 18.0291197,16.1109475 17.524488,16.389668 L10.9803436,20 L4.43619907,16.389668 C3.93129504,16.1112249 3.74393043,15.4686424 4.01735204,14.9544654 C4.29104597,14.4402885 4.92176751,14.2492055 5.42667154,14.527926 L5.42667154,14.527926 Z M11.1570872,2.16660197 C11.0481543,2.10087385 10.9125328,2.10087385 10.8035999,2.16660197 L2.81228173,6.98943748 L10.8038722,11.812273 C10.9128052,11.8780011 11.0484266,11.8780011 11.1573595,11.812273 L19.14895,6.98943748 L11.1570872,2.16660197 Z M21.8341462,6.41563376 C21.9426896,6.58657471 22.0002937,6.78587151 22,6.98943748 L22,13.3414918 C22,13.9261115 21.5343084,14.4000751 20.9605043,14.4000751 C20.3861556,14.4000751 19.921012,13.9261115 19.921012,13.3414918 L19.921012,8.98457714 L12.2170044,13.6338017 C11.4544614,14.0938994 10.5062257,14.0938994 9.74368271,13.6338017 L0.64560618,8.14286893 C0.0200589524,7.76514024 -0.186641242,6.94256806 0.184275312,6.30553223 C0.296873167,6.11196486 0.455529704,5.95039449 0.64560618,5.8357287 L9.74368271,0.345073299 C10.5062257,-0.115024433 11.4544614,-0.115024433 12.2170044,0.345073299 L21.3150809,5.8357287 C21.5498314,5.97744629 21.725758,6.18184133 21.8341462,6.41563376 Z" id="形状"></path>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/assets/images/portal/blue@2x.png


BIN
src/assets/images/portal/plan-card.png


BIN
src/assets/images/portal/purple@2x.png


BIN
src/assets/images/portal/risk-card.png


File diff suppressed because it is too large
+ 0 - 0
src/assets/react.svg


+ 70 - 0
src/components/nav-bar/index.tsx

@@ -0,0 +1,70 @@
+import HazardBall from '@/assets/images/nav-bar/hazard-ball.svg?react';
+import HomeIcon from '@/assets/images/nav-bar/home.svg?react';
+import MyIcon from '@/assets/images/nav-bar/my.svg?react';
+import RiskIcon from '@/assets/images/nav-bar/risk.svg?react';
+import StatisticIcon from '@/assets/images/nav-bar/statistic.svg?react';
+
+import clsx from 'clsx';
+import { CSSProperties } from 'react';
+import styles from './nav-bar.module.scss';
+
+const activeColorVar = {
+  '--st1': '#28E3FF',
+  '--st2': '#286EFF',
+} as CSSProperties;
+
+const activeColorVarForMy = {
+  '--st1': '#28DAFF',
+  '--st2': '#28BBFF',
+  '--st3': '#28B4FF',
+  '--st4': '#2875FF',
+  '--st5': '#28DAFF',
+  '--st6': '#2887FF',
+} as CSSProperties;
+
+const inactiveColorVar = {
+  '--st1': '#616161',
+  '--st2': '#616161',
+  '--st3': '#616161',
+  '--st4': '#616161',
+  '--st5': '#616161',
+  '--st6': '#616161',
+} as CSSProperties;
+
+const getNavBarItem = (
+  IconC: React.FC,
+  text: string,
+  isActive: boolean,
+  activeStyle: CSSProperties = activeColorVar
+) => (
+  <div style={isActive ? activeStyle : inactiveColorVar}>
+    <div className={styles.icon}>
+      <IconC />
+    </div>
+    <div className={clsx(styles.text, isActive && styles.active)}>{text}</div>
+  </div>
+);
+
+export default function NavBar() {
+  return (
+    <div className={styles.navBar}>
+      <div className={styles.container}>
+        {getNavBarItem(HomeIcon, '首页', true)}
+        {getNavBarItem(StatisticIcon, '统计', false)}
+
+        <div style={activeColorVar}>
+          <div className={styles.icon}>
+            <span className="relative -top-1/2">
+              <div className={styles.half}>
+                <HazardBall height={50} width={50} />
+              </div>
+            </span>
+          </div>
+          <div className={styles.text}>隐患列表</div>
+        </div>
+        {getNavBarItem(RiskIcon, '风险', false)}
+        {getNavBarItem(MyIcon, '我的', false, activeColorVarForMy)}
+      </div>
+    </div>
+  );
+}

+ 64 - 0
src/components/nav-bar/nav-bar.module.scss

@@ -0,0 +1,64 @@
+.navBar {
+  height: 50px;
+  background: transparent;
+  position: fixed;
+  bottom: 0;
+  width: 100vw;
+  display: flex;
+  align-items: flex-end;
+  user-select: none;
+  pointer-events: none;
+  .container {
+    pointer-events: all;
+    width: 100%;
+    padding: 0 4%;
+    height: 50px;
+    background-color: #ffffff;
+    display: flex;
+    justify-content: space-between;
+    text-align: center;
+    box-shadow: 0px -0.5px 0px 0px rgba(0, 0, 0, 0.1);
+
+    .icon {
+      height: 32px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .text {
+      width: 100%;
+      text-align: center;
+      font-weight: 400;
+      font-size: 12px;
+      color: transparent;
+      background-image: linear-gradient(to bottom, #616161, #616161);
+      // padding-top: 2px;
+      &.active {
+        background-image: linear-gradient(to bottom, #28e3ff, #286eff);
+      }
+      -webkit-background-clip: text;
+      background-clip: text;
+      -webkit-text-fill-color: transparent;
+      line-height: 12px;
+    }
+
+    .half {
+      width: 56px;
+      height: 56px;
+      border-radius: 50%;
+      overflow: hidden;
+      display: inline-block;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      box-shadow: 0px 0.5px 0px 0px rgba(0, 0, 0, 0.1);
+      background: linear-gradient(
+        to bottom,
+        rgba(255, 255, 255, 0) 0,
+        rgba(255, 255, 255, 1) 48%,
+        rgba(255, 255, 255, 1) 52%,
+        rgba(255, 255, 255, 0)
+      );
+    }
+  }
+}

+ 21 - 0
src/components/no-data.tsx

@@ -0,0 +1,21 @@
+import emptyImage from '@/assets/images/empty.png';
+
+interface NoDataProps {
+  className?: string;
+  height?: number;
+  width?: number;
+  text?: string;
+}
+
+function NoData({ className, height = 100, width = 100, text = '暂无数据' }: NoDataProps) {
+  return (
+    <div className={className}>
+      <div>
+        <img src={emptyImage} alt="empty" style={{ height, width }} />
+      </div>
+      <div className="text-center text-sm text-#606060">{text}</div>
+    </div>
+  );
+}
+
+export default NoData;

+ 0 - 5
src/components/portal-header/index.tsx

@@ -1,5 +0,0 @@
-import './portal-header.scss';
-
-export default function PortalHeader() {
-  return <div className="portal-header"></div>;
-}

+ 0 - 0
src/components/portal-header/portal-header.scss


+ 16 - 3
src/components/user-info/index.tsx

@@ -1,17 +1,30 @@
 import SettingIcon from '@/assets/icons/setting.svg?react';
 import SettingIcon from '@/assets/icons/setting.svg?react';
+import { ArrowSize8 } from '@nutui/icons-react';
 import styles from './user-info.module.scss';
 import styles from './user-info.module.scss';
 
 
 export default function UserInfo() {
 export default function UserInfo() {
   return (
   return (
     <div>
     <div>
-      <div className="flex justify-end pr-4">
+      <div className="flex justify-end pr-4 pt-3 -mb-4">
         <SettingIcon height={24} width={24} />
         <SettingIcon height={24} width={24} />
       </div>
       </div>
       <div className={styles.userInfo}>
       <div className={styles.userInfo}>
         <div className={styles.avatar}>
         <div className={styles.avatar}>
-          <img src="https://loremflickr.com/80/80" alt="" />
+          <img className="rounded-full overflow-hidden" src="https://loremflickr.com/80/80" alt="" />
+        </div>
+        <div className={styles.info}>
+          <div className={styles.name}>佟大为</div>
+          <div className={styles.department}>
+            <span>学校</span>
+            <span className="ml-2">
+              <ArrowSize8 height={12} className="relative -top-[2px]" />
+            </span>
+          </div>
+          <div>
+            <span className={styles.tag}>企业管理和法务合约部</span>
+            <span className={styles.tag}>变电巡检工</span>
+          </div>
         </div>
         </div>
-        <div className={styles.info}></div>
       </div>
       </div>
     </div>
     </div>
   );
   );

+ 27 - 0
src/components/user-info/user-info.module.scss

@@ -6,4 +6,31 @@
       height: 70px;
       height: 70px;
     }
     }
   }
   }
+  .info {
+    padding-left: 16px;
+    color: #051d3b;
+    .name {
+      font-size: 20px;
+      line-height: 20px;
+      font-weight: 500;
+      padding-bottom: 8px;
+    }
+    .department {
+      font-size: 14px;
+      display: flex;
+      align-items: center;
+    }
+    .tag {
+      display: inline-block;
+      background-color: #ffffff;
+      color: #3987f3;
+      border-radius: 14px;
+      font-size: 11px;
+      padding: 1px 6px;
+      margin-right: 8px;
+      &:last-child {
+        margin-right: 0;
+      }
+    }
+  }
 }
 }

+ 148 - 4
src/pages/portal/index.tsx

@@ -1,11 +1,155 @@
+import HazardHandleIcon from '@/assets/icons/task/hazard-handle.svg?react';
+import HazardInspectIcon from '@/assets/icons/task/hazard-inspect.svg?react';
+import PlanCardIcon from '@/assets/images/portal/plan-card.png';
+import RiskCardIcon from '@/assets/images/portal/risk-card.png';
+import NavBar from '@/components/nav-bar';
+import NoData from '@/components/no-data';
 import UserInfo from '@/components/user-info';
 import UserInfo from '@/components/user-info';
+import { ArrowSize8 } from '@nutui/icons-react';
+import { Button } from '@nutui/nutui-react';
+import clsx from 'clsx';
 import './portal.scss';
 import './portal.scss';
 
 
 export default function PortalPage() {
 export default function PortalPage() {
   return (
   return (
-    <div className="portal-bg">
-      <UserInfo />
-      <div></div>
-    </div>
+    <>
+      <div className="portal-header-bg">
+        <UserInfo />
+        <div className="grid grid-cols-2 gap-3 px-3 mt-5">
+          <div className="portal-card blue">
+            <div className="title">我发起的</div>
+            <div className="text">
+              <span>今日</span>
+              <span>3</span>
+              <span>条提交记录</span>
+            </div>
+          </div>
+
+          <div className={clsx('portal-card purple', 'point')}>
+            <div className="title">我的审批</div>
+            <div className="text">
+              <span>3</span>
+              <span>条审批待处理</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div className="portal-content-bg pb-8">
+        <div className="p-3">
+          <div className="portal-panel mb-4">
+            <div className="header">我的工作台</div>
+            <div className="content">
+              <div className="grid grid-cols-2 gap-4">
+                <div className="workbench-card blue">
+                  <div>
+                    <div className="title">风险/隐患提交</div>
+                    <div className="vice">隐患副标题标题</div>
+                  </div>
+                  <div>
+                    <img src={RiskCardIcon} alt="" />
+                  </div>
+                </div>
+                <div className="workbench-card orange">
+                  <div>
+                    <div className="title">排查计划</div>
+                    <div className="vice">排查计划副标题</div>
+                  </div>
+                  <div>
+                    <img src={PlanCardIcon} alt="" />
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className="portal-panel mb-4">
+            <div className="header">我的任务</div>
+            <div className="content">
+              <div className="task-item">
+                <div>
+                  <HazardInspectIcon height={78} width={78} />
+                </div>
+                <div className="flex-1 pb-4">
+                  <div className="title">
+                    <span>隐患排查:</span>
+                    <span className="underline">3起</span>
+                  </div>
+                  <div className="deadline">
+                    <span>临期任务:</span>
+                    <span className="underline">1起</span>
+                  </div>
+                </div>
+                <div className="pb-4">
+                  <Button
+                    style={{
+                      margin: 8,
+                      backgroundColor: '#EBF2FF',
+                      borderColor: '#AFCBFF',
+                      color: '#3480FE',
+                    }}
+                  >
+                    去完成
+                  </Button>
+                </div>
+              </div>
+              <div className="task-item">
+                <div>
+                  <HazardHandleIcon height={78} width={78} />
+                </div>
+                <div className="flex-1 pb-4">
+                  <div className="title">
+                    <span>隐患治理:</span>
+                    <span className="underline">7起</span>
+                  </div>
+                  <div className="deadline">
+                    <span>临期任务:</span>
+                    <span className="underline">2起</span>
+                  </div>
+                </div>
+                <div className="pb-4">
+                  <Button
+                    style={{
+                      margin: 8,
+                      backgroundColor: '#EBF2FF',
+                      borderColor: '#AFCBFF',
+                      color: '#3480FE',
+                    }}
+                  >
+                    去完成
+                  </Button>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div className="portal-panel mb-4">
+            <div className="header">
+              <div>风险管控</div>
+              <div>
+                <Button
+                  size="small"
+                  color="#EBF2FF"
+                  style={{
+                    margin: 8,
+                  }}
+                >
+                  <span style={{ color: '#3987F3', fontSize: 12 }}>查看全部</span>
+                  <ArrowSize8 height={10} className="relative -top-[1px]" style={{ color: '#3987F3', fontSize: 12 }} />
+                </Button>
+              </div>
+            </div>
+            <div className="content" style={{ minHeight: 260 }}>
+              <div className="py-3 text-nowrap overflow-y-hidden overflow-x-auto">
+                {['R1', 'R2', 'R2*', 'R3', 'R4'].map(item => (
+                  <button className={clsx('risk-level-button', item === 'R1' && 'active')}>{item}</button>
+                ))}
+              </div>
+              <div className="flex-center pt-8">
+                <NoData height={93} width={128} text="当前暂无风险" />
+              </div>
+            </div>
+          </div>
+        </div>
+        <NavBar />
+      </div>
+    </>
   );
   );
 }
 }

+ 165 - 10
src/pages/portal/portal.scss

@@ -1,15 +1,170 @@
-.portal {
-  background-color: blue;
-}
-.portal-bg {
-  min-height: 100vh;
+.portal-header-bg {
   background: linear-gradient(
   background: linear-gradient(
       180deg,
       180deg,
-      #cfecff 0%,
-      rgba(26, 144, 253, 0.07) 24%,
-      rgba(35, 149, 253, 0.12) 86%,
-      #e9ecfe 100%
+      rgba(26, 144, 253, 0.2) 0%,
+
+      rgba(35, 149, 253, 0.3) 95%,
+      rgba(242, 243, 245, 0.1) 100%
     ),
     ),
-    linear-gradient(0deg, rgba(37, 189, 253, 0.54) 0%, rgba(31, 206, 253, 0.32) 29%, rgba(38, 151, 249, 0.49) 59%);
+    linear-gradient(
+      180deg,
+      rgba(37, 189, 253, 0.54) 0%,
+      rgba(31, 206, 253, 0.32) 29%,
+      rgba(38, 151, 249, 0.49) 59%,
+      rgba(242, 243, 245, 0.1) 100%
+    );
   // background-position: top center;
   // background-position: top center;
 }
 }
+
+.portal-card {
+  border-radius: 10px;
+  height: 80px;
+  position: relative;
+  color: #ffffff;
+  // overflow: hidden;
+  display: flex;
+  flex-direction: column;
+  align-items: start;
+  justify-content: center;
+  padding: 2px 12px 0px;
+  &.blue {
+    background: linear-gradient(54deg, #0958fe 0%, #09e5ff 100%);
+    &::after {
+      background-image: url('../../assets/images/portal/blue@2x.png');
+    }
+  }
+  &.purple {
+    background: linear-gradient(47deg, #6168f5 0%, #a0a5ff 100%);
+    &::after {
+      bottom: -7.5px;
+      background-image: url('../../assets/images/portal/purple@2x.png');
+    }
+  }
+  &:after {
+    content: '';
+    display: block;
+    position: absolute;
+    right: -2px;
+    width: 70px;
+    height: 70px;
+    bottom: -4px;
+    background-size: contain;
+  }
+  .title {
+    font-size: 16px;
+    line-height: 22px;
+    margin-bottom: 3px;
+  }
+  .text {
+    font-size: 12px;
+    line-height: 17px;
+  }
+
+  &.point {
+    &:before {
+      content: '';
+      display: block;
+      position: absolute;
+      right: -5px;
+      width: 14px;
+      height: 14px;
+      border-radius: 50%;
+      background: #ff0000;
+      border: 2px solid #8dc4fa;
+      top: -5px;
+    }
+  }
+}
+
+.portal-content-bg {
+  background-color: #f2f3f5;
+}
+
+.portal-panel {
+  background: #ffffff;
+  border-radius: 10px;
+  .header {
+    height: 48px;
+    border-bottom: 1px solid rgba(153, 153, 153, 0.17);
+    font-weight: 500;
+    font-size: 16px;
+    color: #222222;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 12px;
+  }
+  .content {
+    padding: 6px 12px;
+  }
+}
+
+.workbench-card {
+  border-radius: 10px;
+  padding: 12px;
+  display: flex;
+  justify-content: space-between;
+  &.blue {
+    background: linear-gradient(270deg, #ecf6ff 0%, #ddf2fd 100%);
+    border: 1px solid #0a52b0;
+    --main: #0a52b0;
+    --vice: #7da9e4;
+  }
+  &.orange {
+    background: linear-gradient(270deg, #fef7ef 0%, #feefe7 100%);
+    border: 1px solid #de7e54;
+    --main: #de7e54;
+    --vice: #f1a376;
+  }
+  .title {
+    color: var(--main);
+    font-weight: 500;
+    font-size: 14px;
+    line-height: 24px;
+  }
+  .vice {
+    color: var(--vice);
+    font-weight: 400;
+    font-size: 12px;
+    line-height: 20px;
+  }
+  img {
+    height: 47px;
+  }
+}
+
+.task-item {
+  @apply flex items-center;
+  .title {
+    font-weight: 400;
+    font-size: 16px;
+    color: #243960;
+    line-height: 32px;
+  }
+  .deadline {
+    font-weight: 400;
+    font-size: 14px;
+    color: #566d98;
+    line-height: 24px;
+  }
+}
+
+.risk-level-button {
+  height: 30px;
+  border-radius: 15px;
+  border: 1px solid #f4f4f4;
+  font-weight: 400;
+  font-size: 13px;
+  color: #2e3034;
+  line-height: 30px;
+  padding: 0 22px;
+  margin-right: 8px;
+  &:last-child {
+    margin-right: 0;
+  }
+  &.active {
+    background: #3987f3;
+    border-color: #3987f3;
+    color: #ffffff;
+  }
+}

+ 1 - 0
uno.config.ts

@@ -2,4 +2,5 @@ import { defineConfig, presetUno, transformerDirectives } from 'unocss';
 export default defineConfig({
 export default defineConfig({
   presets: [presetUno()],
   presets: [presetUno()],
   transformers: [transformerDirectives()],
   transformers: [transformerDirectives()],
+  rules: [['flex-center', { display: 'flex', 'justify-content': 'center', 'align-items': 'center' }]],
 });
 });

Some files were not shown because too many files changed in this diff