初始化

This commit is contained in:
hezhidong
2025-03-28 09:30:07 +08:00
parent 1c1fa4da9e
commit bb20d0b25d
122 changed files with 38659 additions and 63 deletions
+24
View File
@@ -0,0 +1,24 @@
<template>
<div class="content-box" style="height: 100%">
<iframe
src="http://124.221.156.158:3031/#/ScreenPage"
frameborder="0"
class="full-iframe"
></iframe>
</div>
</template>
<style lang="scss" scoped>
.content-box {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
background-color: #fff;
}
.full-iframe {
// margin-top: 2.5%;
width: 100%;
height: 100%;
}
</style>
View File
+1
View File
@@ -0,0 +1 @@
<template>数据统计</template>
+456
View File
@@ -0,0 +1,456 @@
<template>
<div class="col-center">
<svg
width="400px"
height="300px"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle opacity=".3" cx="33.329" cy="107.131" r="5.356" fill="#4060c7" />
<path
d="M373.107 238.514h-13.863c-1.471-7.141-2.584-21.424 4.726-21.424 7.309 0 9.137 14.283 9.137 21.424Z"
fill="#E2E5EC"
/>
<path
d="M364.151 221.816c.84 1.785 2.52 7.499 2.52 16.068"
stroke="#FFFEFE"
stroke-width="1.26"
stroke-linecap="round"
/>
<path
d="M355.958 238.514H341.78c1.786-4.096 6.365-12.162 10.398-11.657 4.032.504 4.2 7.981 3.78 11.657Z"
fill="#E2E5EC"
/>
<path
d="M349.657 232.843c-.525 1.576-1.575 5.041-1.575 6.302"
stroke="#FFFEFE"
stroke-width="1.26"
stroke-linecap="round"
/>
<path
opacity=".6"
d="M34.84 201.221c-40.337-44.164 20.284-44.435 23.447-67.198 7.684-55.319 57.32-93.027 111.792-79.099 73.24 18.719 67.033 76.611 129.865 64.354 80.714-15.706 114.15 37.333 51.403 94.438-32.732 29.792 19.258 25.667 19.258 25.667l-294.482 1.022c-34.78-30.41 7.822-1.098-17.836-10.077-32.063-11.201 3.097-.046-23.447-29.107Z"
fill="url(#a)"
/>
<path
d="M22.301 239.144h350.356M376.932 239.144h5.986"
stroke="#011650"
stroke-width="1.26"
stroke-linecap="round"
/>
<path
d="M50.177 238.514h-25.34C18.878 228.2 9.95 207.011 21.901 204.77c14.938-2.8 18.806 16.005 18.806 18.406 7.682-2.454 9.514 9.203 9.47 15.338Z"
fill="#E2E5EC"
/>
<path
d="M25.966 212.639c1.823 2.934 6.037 11.17 10.198 24.615M43.572 227.177l-3.334 6.936"
stroke="#fff"
stroke-width="1.26"
stroke-linecap="round"
/>
<path
d="M128.521 238.514h-15.157v-13.863h-45.49c-4.55 0-7.6-4.673-5.768-8.838l50.548-114.947a10.083 10.083 0 0 1 9.229-6.023h.336a6.301 6.301 0 0 1 6.302 6.301v109.3h25.425a7.103 7.103 0 0 1 7.103 7.103 7.103 7.103 0 0 1-7.103 7.104h-25.425v13.863Zm-15.157-109.101-34.98 81.031h34.98v-81.031ZM160.419 167.918c0-18.586 3.76-34.942 11.279-49.067 7.637-14.126 16.39-21.189 26.26-21.189 9.869 0 18.622 7.063 26.259 21.189 7.636 14.125 11.455 30.543 11.455 49.253s-3.819 35.128-11.455 49.254c-7.637 14.125-16.39 21.188-26.259 21.188-9.87 0-18.623-7.063-26.26-21.188-7.519-14.126-11.279-30.606-11.279-49.44Zm16.214-1.074c0 17.223 2.232 32.051 6.697 41.964 4.465 9.789 9.34 14.683 14.628 14.683 5.287 0 10.162-4.894 14.627-14.683 4.582-9.913 6.873-23.543 6.873-40.89 0-17.719-2.291-31.348-6.873-40.889-4.465-9.541-9.34-14.312-14.627-14.312-5.288 0-10.163 4.771-14.628 14.312s-6.697 21.972-6.697 39.815ZM308.986 238.514H293.83v-13.863h-45.9c-4.557 0-7.607-4.688-5.761-8.854L293.11 100.84a10.083 10.083 0 0 1 9.218-5.997h.357a6.301 6.301 0 0 1 6.301 6.301v109.3h22.856a7.103 7.103 0 0 1 7.103 7.103 7.103 7.103 0 0 1-7.103 7.104h-22.856v13.863ZM293.83 129.413l-35.227 81.031h35.227v-81.031Z"
fill="#CDDAFE"
/>
<mask
id="b"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="61"
y="94"
width="278"
height="145"
>
<path
d="M128.521 238.514h-15.156v-13.863h-45.49c-4.55 0-7.6-4.673-5.769-8.838l53.198-120.97h13.217v115.601h25.425a7.103 7.103 0 1 1 0 14.207h-25.425v13.863Zm-15.156-109.101-34.98 81.031h34.98v-81.031ZM160.42 167.918c0-18.586 3.76-34.942 11.279-49.067 7.637-14.126 16.39-21.189 26.259-21.189s18.622 7.063 26.259 21.189c7.637 14.125 11.455 30.543 11.455 49.253s-3.818 35.128-11.455 49.254c-7.637 14.125-16.39 21.188-26.259 21.188s-18.622-7.063-26.259-21.188c-7.519-14.126-11.279-30.606-11.279-49.44Zm16.214.186c0 17.223 2.232 30.791 6.696 40.704 4.465 9.789 9.341 14.683 14.628 14.683 5.287 0 10.163-4.894 14.628-14.683 4.582-9.913 6.873-23.543 6.873-40.89 0-17.719-2.291-31.348-6.873-40.889-4.465-9.541-9.341-14.312-14.628-14.312-5.287 0-10.163 4.771-14.628 14.312-4.464 9.541-6.696 23.232-6.696 41.075ZM308.986 238.514H293.83v-13.863h-45.9c-4.557 0-7.607-4.688-5.761-8.854l53.6-120.954h13.217v115.601h22.856a7.104 7.104 0 1 1 0 14.207h-22.856v13.863ZM293.83 129.413l-35.227 81.031h35.227v-81.031Z"
fill="#CDDAFE"
/>
</mask>
<g mask="url(#b)">
<ellipse
opacity=".8"
cx="198.741"
cy="177.076"
rx="44.11"
ry="63.329"
transform="rotate(-180 198.741 177.076)"
fill="url(#c)"
/>
<ellipse
cx="197.48"
cy="201.651"
rx="44.11"
ry="57.027"
fill="url(#d)"
/>
<ellipse
opacity=".6"
cx="54.998"
cy="195.995"
rx="44.11"
ry="58.603"
transform="rotate(22.14 54.998 195.995)"
fill="url(#e)"
/>
<ellipse
opacity=".6"
cx="247.196"
cy="226.466"
rx="19.626"
ry="58.603"
transform="rotate(22.14 247.196 226.466)"
fill="url(#f)"
/>
<path
d="m71.138 224.966 7.561-14.808h34.658v14.808h-42.22Z"
fill="#8BD9FC"
/>
<mask
id="g"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="71"
y="210"
width="43"
height="15"
>
<path
d="m71.138 224.966 7.561-14.808h34.658v14.808h-42.22Z"
fill="#8BD9FC"
/>
</mask>
<g mask="url(#g)">
<ellipse
rx="20.794"
ry="31.822"
transform="matrix(-1 0 0 1 74.603 213.624)"
fill="url(#h)"
style="mix-blend-mode: multiply"
opacity=".6"
/>
</g>
<path
d="m251.042 225.281 7.715-15.123h35.134v15.123h-42.849Z"
fill="#8BD9FC"
/>
<mask
id="i"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="251"
y="210"
width="43"
height="16"
>
<path
d="m251.042 225.281 7.715-15.123h35.134v15.123h-42.849Z"
fill="#8BD9FC"
/>
</mask>
<g mask="url(#i)">
<ellipse
rx="20.794"
ry="31.822"
transform="matrix(-1 0 0 1 255.453 213.624)"
fill="url(#j)"
style="mix-blend-mode: multiply"
opacity=".6"
/>
</g>
<path
d="M128.48 210.158h25.521a7.248 7.248 0 0 1 0 14.493H128.48v-14.493ZM309.014 210.158h23a7.248 7.248 0 0 1 0 14.493h-23v-14.493Z"
fill="#8BD9FC"
/>
<path
d="M128.48 224.651v-14.178l6.932 14.178h-6.932ZM309.014 224.651v-14.178l6.932 14.178h-6.932Z"
fill="#6DBADD"
/>
<path
d="m113.042 129.815 15.438-29.931v29.931h-15.438Z"
fill="url(#k)"
/>
<path
d="m293.891 129.815 15.123-29.616.315 29.616h-15.438Z"
fill="url(#l)"
/>
<path
d="M114.016 94.493c.371 4.57-2.625 17.776-11.171 34.503-10.683 20.91-39.795 91.472-41.474 97.545-1.343 4.859 2.267 4.876 3.78 0 .997-3.211 25.43-63.343 35.139-77.657 12.137-17.893 13.825-42.923 19.528-54.095 5.703-11.172 7.848-4.138 9.239-2.677 1.266 1.33 1.996-21.022-1.682-9.29-4.958 8.871-18.931 70.821-28.511 81.651-7.247 8.191-23.031 41.427-19.85 45.685M295.753 91.063c.371 4.57-2.453 19.504-10.999 36.232-10.683 20.91-39.967 89.743-41.646 95.817-1.343 4.859 2.268 4.876 3.781 0 .996-3.211 25.429-63.343 35.138-77.657 12.137-17.893 13.825-42.923 19.528-54.095 5.703-11.172 7.848-4.138 9.239-2.677 1.266 1.33 1.997-21.022-1.682-9.29-4.958 8.871-19.819 71.415-29.399 82.244-7.247 8.192-31.223 60.647-28.041 64.905"
stroke="#fff"
stroke-width=".441"
/>
<circle
opacity=".3"
cx="208.192"
cy="118.788"
r="4.411"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="214.179"
cy="130.446"
r=".945"
fill="#758CD6"
/>
<circle opacity=".3" cx="214.494" cy="109.966" r=".63" fill="#758CD6" />
<circle
opacity=".3"
cx="229.932"
cy="132.336"
r="1.575"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="230.877"
cy="147.144"
r="1.26"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="218.905"
cy="138.952"
r="5.041"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="227.727"
cy="117.528"
r="6.301"
fill="#758CD6"
/>
</g>
<path
d="M373.918 77.64c1.524.761 2.221 2.468-.367 2.835m-2.469 0c-6.617-.63-26.781-6.617-35.288-14.808"
stroke="#F6BCD1"
stroke-width=".945"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M363.836 56.53c-12.099-4.538-18.484 3.15-20.165 7.56.42.841 2.836 4.412 10.082 7.563 7.031 3.056 13.863 3.36 16.699 3.15 1.575-4.2 2.458-13.737-6.616-18.274Z"
fill="#F6BCD1"
/>
<path
d="M359.424 61.57c-1.105-.553-2.835-.82-4.096 2.206-.504 1.26.21 3.045.631 3.78-1.051 0-3.214.378-3.466 1.89 0 .316 0 .63 1.575 1.261 1.26.504 2.416 1.05 2.836 1.26.21.105.567.378.315.63-.209.21-.577.144-.816.056l-.129-.056c.035.018.079.038.129.056l1.698.728c.065.235.249.226.378.162l-.378-.162c-.041-.149-.034-.394.063-.784.315-1.26.945-3.465-.945-4.41.63 0 2.52-.316 3.151-2.521.63-2.206.315-3.466-.946-4.096Z"
fill="#fff"
/>
<path
d="M341.466 61.255c-3.256-.525-9.263-.82-9.768 2.206-.504 3.024 7.247 9.767 20.795 14.808 15.159 5.64 25.881 5.986 26.781 2.835.9-3.15-1.891-5.04-4.726-6.616"
stroke="#F6BCD1"
stroke-width="1.26"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
stroke="#F6BCD1"
stroke-width=".945"
stroke-linecap="round"
stroke-linejoin="round"
d="m374.516 60.215-1.764 1.323M372.642 57.963l-1.103 1.91M375.965 62.988h-2.205"
/>
<path
d="m344.616 81.61-6.301 4.726M356.235 85.748v9.095"
stroke="#F6BCD1"
stroke-width="1.26"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M182.185 184.416c3.269 2.569 13.913 20.531 18.973 29.19l-14.887 7.882c-1.07-1.265-4.32-6.072-7.589-9.341 1.167 3.269 2.53 18.584 2.919 25.103a3067.97 3067.97 0 0 0-16.347 3.211c-1.634-2.101-2.335-22.476-9.049-29.774l-3.502-3.21 2.043-11.677 20.141-14.886c1.07.097 4.028.934 7.298 3.502Z"
fill="#5783FC"
/>
<path
d="m192.438 232.212 23.315-11.599c-1.459-2.336-5.546-1.752-7.881-1.752-1.868 0-5.254-3.503-6.714-5.254l-15.179 7.589 6.459 11.016Z"
fill="#020641"
/>
<path
stroke="#fff"
stroke-width=".584"
d="m199.869 217.319 3.503-1.751M200.584 218.747l3.956-2.012"
/>
<path
d="M164.688 250.454h27.129c-.247-2.743-4.157-4.067-6.241-5.122-1.667-.843-3.756-5.86-4.267-8.081l-16.054 3.211-.567 9.992Z"
fill="#020641"
/>
<path
stroke="#fff"
stroke-width=".584"
d="m179.258 241.452 3.884-.505M179.464 243.036l4.398-.603"
/>
<path
d="M118.55 210.104c-6.538-.934-7.005-11.481-6.422-16.638l63.051-14.303v1.751l-9.341 5.254-1.751 4.087 3.211 1.459 1.167 4.087c-2.53-.195-8.29.175-11.092 3.211-2.802 3.036-1.946 9.049-1.168 11.676-9.827.194-31.116.35-37.655-.584Z"
fill="#5783FC"
/>
<path
d="M178.098 211.272c-4.379-3.795-7.998-11.968-9.049-14.595-.584-1.46-1.557-3.99-1.751-4.963-.682-.194-2.161-.7-2.628-1.167"
stroke="#000"
stroke-width=".584"
stroke-linecap="round"
/>
<path
d="m175.179 183.011-13.271 9.341h-14.173c-1.09 0-1.586-1.361-.751-2.062l4.843-4.068 11.649-2.627 1.648-9.2a2.916 2.916 0 0 1 1.799-2.199l10.73-4.249a.584.584 0 0 1 .784.672l-3.258 14.392Z"
fill="#66DED2"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M133.145 156.739a8.174 8.174 0 1 0-6.196-13.502 4.086 4.086 0 1 0-1.642 7.651 8.175 8.175 0 0 0 7.838 5.851Z"
fill="#FC466F"
/>
<path
d="M146.281 140.685c0-6.305-5.449-5.741-8.173-4.67-3.211-3.503-7.298 1.167-8.174 2.335-1.751 0-2.627.292-3.794 1.459-.934.934-1.168 3.114-1.168 4.087.876.194 2.627.759 2.627 1.459-.233 1.401.292 1.946.584 2.044.876 0 1.053-1.408 1.46-2.627.875-2.628 5.254-.973 7.005 0 3.211 1.264 9.633 2.218 9.633-4.087Z"
fill="#202020"
/>
<path
d="M131.686 158.199c-12.61-1.635-18.682 6.519-20.141 10.8-1.168 3.016-3.62 10.45-4.087 16.055-.584 7.005 1.46 12.551 14.011 13.427 10.042.701 21.115-4.573 25.396-7.297l4.962-7.59c4.184-1.946 12.085-5.955 10.217-6.422-1.869-.467-8.757-.973-11.968-1.167-.487-.876-1.81-3.503-3.211-7.006-1.752-4.378-5.838-9.633-15.179-10.8Z"
fill="#011650"
/>
<path
d="M146.865 191.184c-1.635-4.204-1.071-10.217-.584-12.552 8.465-.876 10.8 0 11.676.292.233-.701 1.459-1.46 3.211-1.752 1.751-.292 3.503.584 3.503.584l-1.46 7.59c-.194.097-.7.233-1.167 0 .467 2.802-.973 3.113-1.752 2.919-.584.291-2.043.875-3.211.875-2.919.876-4.378-.292-4.962-.875-.584-.584-1.46-.876-2.043 0-.584.875-2.044 2.043-3.211 2.919Z"
fill="#FC466F"
/>
<path
d="m125.264 169 .292 11.092c4.379-.487 14.362-1.46 19.265-1.46M141.027 167.832c.876 1.751 2.627 5.429 2.627 6.13"
stroke="#fff"
stroke-width=".584"
stroke-linecap="round"
/>
<path
d="M153.287 182.427c1.167.973 3.502 3.62 3.502 6.422M157.081 180.967c1.07.973 3.153 3.737 2.919 7.006M158.833 179.799c.973.973 2.977 3.211 3.21 4.379M162.627 179.507c.389.487 1.168 1.635 1.168 2.336"
stroke="#000"
stroke-width=".584"
stroke-linecap="round"
/>
<ellipse
cx="170.801"
cy="178.34"
rx=".876"
ry="1.751"
transform="rotate(7.122 170.801 178.34)"
fill="#fff"
/>
<path
d="m180.931 155.117 4.196-2.427c.538-.311 1.154.264.881.823l-1.492 3.053 2.348 2.433a.63.63 0 0 1-.187 1.009l-5.155 2.401c-.629.293-1.201-.497-.725-1.003l2.289-2.435-2.331-2.915a.63.63 0 0 1 .176-.939ZM174.853 143.68l2.382-2.976c.191-.239.575-.086.549.218l-.223 2.684 2.233 1.029a.31.31 0 0 1 .094.495l-3.207 3.349c-.236.246-.637-.013-.51-.329l1.078-2.672-2.31-1.338a.308.308 0 0 1-.086-.46Z"
fill="#5783FC"
/>
<defs>
<linearGradient
id="a"
x1="201.893"
y1="108.609"
x2="201.893"
y2="240.405"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#F7F4FD" />
<stop offset="1" stop-color="#F7F4FD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="c"
x1="186.768"
y1="113.747"
x2="182.306"
y2="188.099"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#ABE7FF" />
<stop offset="1" stop-color="#ADE4FF" stop-opacity="0" />
</linearGradient>
<linearGradient
id="d"
x1="194.645"
y1="251.117"
x2="202.045"
y2="197.234"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#A4BCFE" />
<stop offset="1" stop-color="#B0C5FD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="e"
x1="47.309"
y1="221.217"
x2="99.469"
y2="200.52"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#92AFFD" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="f"
x1="247.196"
y1="240.392"
x2="272.201"
y2="230.641"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#92AFFD" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="h"
x1="28.671"
y1="18.904"
x2="3.896"
y2="20.454"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#92AFFD" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="j"
x1="28.671"
y1="18.904"
x2="3.896"
y2="20.454"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#6DBADD" />
<stop offset="1" stop-color="#8BD9FC" stop-opacity="0" />
</linearGradient>
<linearGradient
id="k"
x1="120.761"
y1="94.843"
x2="120.761"
y2="129.815"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#7793DE" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="l"
x1="301.61"
y1="94.843"
x2="301.61"
y2="129.815"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#7793DE" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<el-button type="primary" @click="backUrl()">返回首页</el-button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const backUrl = () => {
router.push({
name: 'home',
query: {
// ...route.query,
},
})
}
</script>
+470
View File
@@ -0,0 +1,470 @@
<template>
<div class="col-center">
<svg
width="400px"
height="300px"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M371.128 249.745h-13.805c-1.464-7.112-2.573-21.335 4.706-21.335s9.099 14.223 9.099 21.335Z"
fill="#E2E5EC"
/>
<path
d="M362.209 233.116c.837 1.778 2.51 7.467 2.51 16.002"
stroke="#fff"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
d="M352.797 249.745h-14.119c1.778-4.079 6.338-12.111 10.354-11.609 4.016.502 4.183 7.948 3.765 11.609Z"
fill="#E2E5EC"
/>
<path
d="M347.777 244.097c-.523 1.569-1.569 5.02-1.569 6.275"
stroke="#fff"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
opacity=".6"
d="M369.442 211.845c40.308-44.132-20.269-44.402-23.43-67.15-7.679-55.278-57.279-92.958-111.711-79.04-73.187 18.705-66.984 76.555-129.771 64.306-80.655-15.694-112.281 27.948-49.58 85.012 32.708 29.77-21.03 35.007-21.03 35.007L328.19 251c34.754-30.387-7.816-1.097 17.823-10.069 32.039-11.193-3.095-.046 23.43-29.086Z"
fill="url(#a)"
/>
<path
d="M23.044 249.745h348.891M376.192 249.745h5.962"
stroke="#011650"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
d="M115.867 160.108c10.348 0 18.894 3.771 25.637 11.312 6.86 7.541 10.29 17.987 10.29 31.339 0 12.857-3.895 23.797-11.685 32.822-7.674 9.024-17.964 13.537-30.869 13.537-10.697 0-18.952-3.524-24.765-10.57-5.814-7.047-8.72-15.144-8.72-24.292 0-9.148 14.432-11.26 14.998 0 0 7.252 1.686 11.188 5.058 14.649 3.488 3.462 7.964 5.192 13.429 5.192 7.441 0 13.719-2.719 18.835-8.159 5.116-5.563 7.674-13.289 7.674-23.179 0-9.396-1.919-16.319-5.755-20.769-3.837-4.574-8.546-6.861-14.127-6.861-5.697 0-10.522.927-14.475 2.781-3.837 1.731-6.453 4.265-7.849 7.603H79.94l4.186-73.961 49.941-4.119c5.475-.451 9.86 4.463 8.79 9.852a8.27 8.27 0 0 1-7.194 6.608l-38.98 4.348-2.093 38.172c6.976-4.203 14.068-6.305 21.277-6.305ZM164.874 178.652c0-18.544 3.721-34.862 11.162-48.955 7.557-14.093 16.219-21.14 25.986-21.14 9.766 0 18.428 7.047 25.986 21.14 7.557 14.093 11.336 30.473 11.336 49.14 0 18.668-3.779 35.048-11.336 49.141-7.558 14.093-16.22 21.14-25.986 21.14-9.767 0-18.429-7.047-25.986-21.14-7.441-14.093-11.162-30.535-11.162-49.326Zm16.045.185c0 17.184 2.209 30.721 6.627 40.611 4.419 9.766 9.244 14.649 14.476 14.649 5.232 0 10.057-4.883 14.475-14.649 4.535-9.89 6.802-23.489 6.802-40.796 0-17.678-2.267-31.277-6.802-40.796-4.418-9.519-9.243-14.279-14.475-14.279-5.232 0-10.057 4.76-14.476 14.279-4.418 9.519-6.627 23.18-6.627 40.981ZM254.168 178.652c0-18.544 3.721-34.862 11.162-48.955 7.557-14.093 16.219-21.14 25.986-21.14 9.766 0 18.428 7.047 25.986 21.14 7.557 14.093 11.336 30.473 11.336 49.14 0 18.668-3.779 35.048-11.336 49.141-7.558 14.093-16.22 21.14-25.986 21.14-9.767 0-18.429-7.047-25.986-21.14-7.441-14.093-11.162-30.535-11.162-49.326Zm16.045.185c0 17.184 2.209 30.721 6.627 40.611 4.419 9.766 9.244 14.649 14.476 14.649 5.232 0 10.057-4.883 14.475-14.649 4.535-9.89 6.802-23.489 6.802-40.796 0-17.678-2.267-31.277-6.802-40.796-4.418-9.519-9.243-14.279-14.475-14.279-5.232 0-10.057 4.76-14.476 14.279-4.418 9.519-6.627 23.18-6.627 40.981Z"
fill="#C9D7FF"
/>
<mask
id="b"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="75"
y="107"
width="254"
height="143"
>
<path
d="M115.867 160.108c10.348 0 18.894 3.771 25.637 11.312 6.86 7.541 10.29 17.987 10.29 31.339 0 12.857-3.895 23.797-11.685 32.822-7.674 9.024-17.964 13.537-30.869 13.537-10.697 0-18.952-3.524-24.765-10.57-5.814-7.047-8.72-15.144-8.72-24.292 0-9.148 14.432-11.26 14.998 0 .566 11.259 1.686 11.188 5.058 14.649 3.488 3.462 7.964 5.192 13.429 5.192 7.441 0 13.719-2.719 18.835-8.159 5.116-5.563 7.674-13.289 7.674-23.179 0-9.396-1.919-16.319-5.755-20.769-3.837-4.574-8.546-6.861-14.127-6.861-5.697 0-10.522.927-14.475 2.781-3.837 1.731-6.453 4.265-7.849 7.603H79.94l4.186-73.961 49.941-4.119c5.475-.451 9.86 4.463 8.79 9.852a8.27 8.27 0 0 1-7.194 6.608l-38.98 4.348-2.093 38.172c6.976-4.203 14.068-6.305 21.277-6.305ZM164.874 178.652c0-18.544 3.721-34.862 11.162-48.955 7.557-14.093 16.219-21.14 25.986-21.14 9.766 0 18.428 7.047 25.986 21.14 7.557 14.093 11.336 30.473 11.336 49.14 0 18.668-3.779 35.048-11.336 49.141-7.558 14.093-16.22 21.14-25.986 21.14-9.767 0-18.429-7.047-25.986-21.14-7.441-14.093-11.162-30.535-11.162-49.326Zm16.045.185c0 17.184 2.209 30.721 6.627 40.611 4.419 9.766 9.244 14.649 14.476 14.649 5.232 0 10.057-4.883 14.475-14.649 4.535-9.89 6.802-23.489 6.802-40.796 0-17.678-2.267-31.277-6.802-40.796-4.418-9.519-9.243-14.279-14.475-14.279-5.232 0-10.057 4.76-14.476 14.279-4.418 9.519-6.627 23.18-6.627 40.981ZM254.168 178.652c0-18.544 3.721-34.862 11.162-48.955 7.557-14.093 16.219-21.14 25.986-21.14 9.766 0 18.428 7.047 25.986 21.14 7.557 14.093 11.336 30.473 11.336 49.14 0 18.668-3.779 35.048-11.336 49.141-7.558 14.093-16.22 21.14-25.986 21.14-9.767 0-18.429-7.047-25.986-21.14-7.441-14.093-11.162-30.535-11.162-49.326Zm16.045.185c0 17.184 2.209 30.721 6.627 40.611 4.419 9.766 9.244 14.649 14.476 14.649 5.232 0 10.057-4.883 14.475-14.649 4.535-9.89 6.802-23.489 6.802-40.796 0-17.678-2.267-31.277-6.802-40.796-4.418-9.519-9.243-14.279-14.475-14.279-5.232 0-10.057 4.76-14.476 14.279-4.418 9.519-6.627 23.18-6.627 40.981Z"
fill="#B0C4FE"
/>
</mask>
<g mask="url(#b)">
<ellipse
opacity=".6"
cx="84.54"
cy="179.779"
rx="43.925"
ry="31.689"
fill="url(#c)"
/>
<ellipse
opacity=".8"
cx="196.235"
cy="162.836"
rx="43.925"
ry="56.789"
fill="url(#d)"
/>
<ellipse
cx="301.028"
cy="197.976"
rx="43.925"
ry="56.789"
fill="url(#e)"
/>
<ellipse
cx="208.158"
cy="197.976"
rx="43.925"
ry="56.789"
fill="url(#f)"
/>
<path
d="m97.717 109.498-.941 18.825 44.866-5.02 3.452-16.942-47.377 3.137Z"
fill="#8BD9FC"
/>
<ellipse
opacity=".6"
cx="137.25"
cy="118.284"
rx="20.708"
ry="31.689"
fill="url(#g)"
/>
<path
opacity=".2"
d="m126.896 127.696 5.878-13.664c1.55-3.258 3.901-2.815 7.059-.139 2.987 2.531 8.587 8.219 11.03 10.561"
stroke="#000"
stroke-width=".941"
/>
<circle
opacity=".3"
cx="172.39"
cy="139.932"
r="4.393"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="178.351"
cy="151.541"
r=".941"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="178.665"
cy="131.147"
r=".628"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="168.938"
cy="165.974"
r="1.569"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="196.235"
cy="121.108"
r="1.255"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="183.058"
cy="160.012"
r="5.02"
fill="#758CD6"
/>
<circle
opacity=".3"
cx="191.842"
cy="131.775"
r="6.275"
fill="#758CD6"
/>
<path
d="m93.324 186.681 1.569-20.707c4.706-6.066 15.813-17.947 22.59-16.943 8.471 1.255 21.963 11.923 30.748 16.001 8.785 4.079 4.706 14.433 7.216 20.08 2.51 5.648 0 29.493 0 43.926 0 14.432-5.961 15.06-16.001 20.08-10.04 5.02-29.179 5.02-40.16 3.765-10.982-1.255-14.433-7.217-20.708-11.923-6.275-4.706-10.354-17.57-12.236-25.414-1.883-7.844 5.96-12.236 8.785-13.177 2.823-.942 18.51 4.078 20.08 7.53 1.569 3.451 11.922 13.491 13.805 13.491 1.506 0 11.922 1.255 16.942 1.883 2.092-6.38 6.338-19.453 6.589-20.708.251-1.255-1.987-11.4-3.137-16.315l-13.492-5.961-22.59 4.392Z"
fill="#CDDAFE"
/>
<rect
x="116.755"
y="136.972"
width="38.651"
height="30.409"
rx="1.883"
transform="rotate(-9.889 116.755 136.972)"
fill="url(#h)"
/>
<ellipse
cx="72.617"
cy="235.94"
rx="43.925"
ry="31.375"
fill="url(#i)"
/>
<path
d="m97.09 184.798-2.51-18.511-1.255 21.963 3.765-3.452Z"
fill="#91A4D7"
style="mix-blend-mode: multiply"
/>
<path
d="m102.11 128.951-4.393-19.139-.941 19.139h5.334Z"
fill="#6DBADD"
/>
<path
d="M86.422 107.302c1.568 4.288 2.196 17.758-1.57 36.081-4.705 22.904-2.823 38.592-2.823 44.867 0 5.02 6.066 3.765 8.471 4.392.105-3.346-8.345-13.177-2.823-29.492 6.902-20.394 1.882-44.867 4.392-57.103 2.51-12.236 6.435-6.054 8.158-5.02 1.568.941-3.66-20.708-4.08-8.471-2.404 9.831-1.254 69.652-4.078 83.771-1.651 8.256 2.092 22.486 6.275 25.728"
stroke="#fff"
stroke-width=".439"
/>
</g>
<path
d="M328.679 179.346c0-1.973-.042-3.921-.127-5.843m-4.746-27.924c1.821 5.757 3.131 11.823 3.931 18.198"
stroke="#5783FC"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
d="m121.707 131.292 8.678-16.152c2.165-3.291 4.408-3.664 8.382-.74 3.756 2.766 10.878 9.072 13.973 11.657"
stroke="#000"
stroke-width="1.122"
/>
<rect
x="118.638"
y="131.323"
width="38.651"
height="30.409"
rx="1.883"
transform="rotate(-9.889 118.638 131.323)"
fill="#E4E4ED"
/>
<mask
id="j"
style="mask-type: alpha"
maskUnits="userSpaceOnUse"
x="118"
y="124"
width="44"
height="37"
>
<rect
x="118.638"
y="131.323"
width="38.651"
height="30.409"
rx="1.883"
transform="rotate(-9.889 118.638 131.323)"
fill="#F0F3FA"
/>
</mask>
<g mask="url(#j)">
<circle
cx="153.152"
cy="151.414"
r="11.226"
transform="rotate(-9.889 153.152 151.414)"
fill="#7DB5FF"
/>
<circle
r="1.847"
transform="scale(1 -1) rotate(9.889 863.109 762.065)"
fill="#7DB5FF"
/>
<path
stroke="#E01E67"
stroke-width=".748"
stroke-linecap="round"
d="m125.215 138.74 13.542-2.36M126.191 144.339l13.542-2.36"
/>
</g>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M268.084 141.814a6.589 6.589 0 1 0-6.559-5.956 2.51 2.51 0 0 0 2.349 4.436 6.564 6.564 0 0 0 4.21 1.52Z"
fill="#FC466F"
/>
<path
d="M270.594 129.578c2.761-1.757 2.614-3.242 2.196-3.765-.753-1.004-1.987-.418-2.51 0-.418.418-1.631 1.255-3.137 1.255-1.883 0-3.765 1.255-4.707 1.883-2.51-3.452-5.333-4.393-9.098-2.824-3.012 1.255-3.347 5.334-3.138 7.216-2.719-.418-8.158.063-8.158 5.334 0 6.589 5.02 6.275 10.354 5.647 5.334-.627 7.217-5.02 7.53-7.53.314-2.51-.941-4.392-.627-5.02.314-.627.941-.313 1.255.314-.251 1.757.104 3.661.314 4.393l2.51-.942c.418.314 1.38.565 1.882-.941.628-1.882 1.883-2.824 5.334-5.02Z"
fill="#000"
/>
<path
d="m273.418 149.062-5.962.628-3.451-.628-1.255-4.738c.523-.104 2.657.191 5.648.628 4.078.596 5.02 1.255 5.961 2.196l-.941 1.914Z"
fill="#FC466F"
/>
<path
d="M236.708 205.82c5.02-10.542 8.995-23.427 10.354-28.551 7.635.313 23.28.941 24.786.941 1.883 3.765 8.158 18.825 10.041 24.786 1.506 4.769 6.275 23.009 8.471 31.062-4.184 1.359-13.052 4.329-15.06 5.333-.942-7.216-13.178-39.532-14.433-42.356-1.255 3.137-7.844 19.452-11.295 23.845-2.761 3.514-7.425 12.341-9.412 16.315l-14.433-6.589c1.569-3.869 5.961-14.244 10.981-24.786Z"
fill="#5783FC"
/>
<path
d="M264.946 189.504c-.418.419-1.632 1.255-3.138 1.255 0 2.51-.313 4.707-.941 6.275"
stroke="#000"
stroke-width=".628"
stroke-linecap="round"
/>
<path
d="m277.496 248.804-2.197-9.727 15.06-5.02a4.778 4.778 0 0 0 4.393 3.765c3.012.251 4.602 2.824 5.02 4.079l-22.276 6.903ZM241.728 249.745l-20.08-10.668 4.392-8.471c4.079 1.778 12.613 5.585 14.119 6.589-1.255 3.451.942 5.334 1.883 7.53.753 1.757.104 4.079-.314 5.02Z"
fill="#020641"
/>
<path
stroke="#fff"
stroke-width=".628"
d="m287.082 237.542 3.765-1.883M287.85 239.077l4.252-2.163M236.531 237.425l3.858 1.685M235.844 238.998l4.384 1.88"
/>
<path
d="m243.925 159.698-9.727-10.353c4.393-3.765 8.158-5.02 15.06-5.648 5.522-.502 11.714.209 14.119.628.105 1.359 1.13 4.204 4.393 4.706 3.263.502 5.333-1.464 5.961-2.51 1.778 1.464 5.898 5.396 8.157 9.412 2.259 4.016 5.334 4.184 6.589 3.765.209 4.079.69 12.55.941 13.805-12.863.942-15.687-5.02-17.883-8.471-2.761 3.765-.314 10.563 1.255 13.491-8.472-.209-25.791-.69-27.297-.941-.627-6.275 4.393-18.825 5.648-21.649-3.263-.251-6.171 2.406-7.216 3.765Z"
fill="#011650"
/>
<path
d="M296.321 145.266h4.392"
stroke="#5783FC"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
d="M298.203 165.66c-3.012 4.016-7.321 6.275-9.099 6.902l-.627-12.864c.941-.418 3.137-1.757 4.392-3.765 1.569-2.51 1.883-5.647 4.393-8.785 2.51-3.137 7.216-4.392 9.413-4.392 2.196 0 3.765.941 3.765 1.882 0 .753-1.255.523-1.883.314.209.105.628.565.628 1.569 0 1.255-.314 1.882-.628 2.196.314.628.628.941.314 2.196-.314 1.255-1.569 2.51-2.824 2.51s-2.51 2.197-3.451 3.765c-.941 1.569-.628 3.452-4.393 8.472ZM231.688 164.091c-2.761-8.534.523-13.387 2.51-14.746 2.51 2.614 7.781 8.094 8.785 9.098-1.882 3.765 1.255 6.903 2.824 6.903 1.255 0 2.196-1.046 2.51-1.569.209-.418.941-1.38 2.196-1.882 1.569-.628 2.51 0 2.824.313.251.251.314.942.314 1.255.209-.104.753-.125 1.255.628.502.753.418 1.36.313 1.569.105.104.314.376.314.627.314.628-.314 1.569-.627 1.883-.314.313-.942.941-1.255 1.568-.314.628-3.138 2.824-5.02 4.707-1.506 1.506-3.138 1.673-3.765 1.568-3.243-.418-10.417-3.388-13.178-11.922Z"
fill="#FC466F"
/>
<path
d="M252.709 163.463c-1.15.105-3.514.816-3.765 2.824M254.278 165.659c-.837-.104-2.698.44-3.451 3.452"
stroke="#000"
stroke-width=".628"
stroke-linecap="round"
/>
<path
d="M275.3 150.6c0 3.451 0 7.843-3.765 12.55"
stroke="#fff"
stroke-width=".628"
stroke-linecap="round"
/>
<path
d="M304.165 143.697c.209.941-.063 2.886-2.824 3.137.942.942 1.255 3.138 0 4.393M307.302 145.893c-1.045.418-3.012 1.632-2.51 3.138.314.941 2.197.313 2.824 0-1.568.941-2.824 1.882-2.196 3.451"
stroke="#000"
stroke-width=".628"
stroke-linecap="round"
/>
<path
d="M305.733 145.266h7.53"
stroke="#5783FC"
stroke-width="1.255"
stroke-linecap="round"
/>
<path
stroke="#F6BCD1"
stroke-width="1.255"
stroke-linecap="round"
stroke-linejoin="round"
d="M23.671 80.319h96.008M41.87 82.829l14.432 11.788-14.432 11.788 14.432 11.788-14.432 11.788 14.432 11.788-14.432 11.788 14.432 11.788-14.432 11.788 14.432 11.788-14.432 11.788 14.432 11.789-14.432 11.788 14.432 11.788-14.432 11.788"
/>
<path
d="m56.616 50.826.372-.505a.628.628 0 0 0-1 .505h.628Zm.627 198.291V50.827h-1.255v198.29h1.255Zm-1-197.786 39.533 29.18.745-1.01-39.533-29.18-.745 1.01Z"
fill="#F6BCD1"
/>
<path
d="m41.242 80.633 15.373-13.805M41.242 249.117V80.947M122.146 83.853l10.668 26.983"
stroke="#F6BCD1"
stroke-width="1.255"
/>
<path
d="M50.804 249.118H25.569c-5.933-10.272-14.823-31.372-2.922-33.603 14.875-2.789 18.727 15.938 18.727 18.329 7.65-2.444 9.474 9.164 9.43 15.274Z"
fill="#E2E5EC"
/>
<path
d="M26.694 223.351c1.816 2.922 6.012 11.124 10.156 24.512M44.226 237.828l-3.32 6.907"
stroke="#fff"
stroke-width="1.255"
stroke-linecap="round"
/>
<circle
cx="121.249"
cy="81.888"
r="2.824"
fill="#fff"
stroke="#F6BCD1"
stroke-width="1.255"
/>
<circle
cx="133.798"
cy="112.008"
r="2.196"
fill="#fff"
stroke="#F6BCD1"
stroke-width="1.255"
/>
<circle opacity=".3" cx="374.76" cy="123.303" r="5.334" fill="#8BD9FC" />
<defs>
<linearGradient
id="a"
x1="202.51"
y1="119.301"
x2="202.51"
y2="251"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#F7F4FD" />
<stop offset="1" stop-color="#F7F4FD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="c"
x1="84.54"
y1="187.309"
x2="102.424"
y2="158.444"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#92AFFD" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="d"
x1="184.312"
y1="106.047"
x2="180.707"
y2="172.767"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#ABE7FF" />
<stop offset="1" stop-color="#ADE4FF" stop-opacity="0" />
</linearGradient>
<linearGradient
id="e"
x1="298.204"
y1="247.235"
x2="305.574"
y2="193.577"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#A4BCFE" />
<stop offset="1" stop-color="#B0C5FD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="f"
x1="205.334"
y1="247.235"
x2="212.704"
y2="193.577"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#A4BCFE" />
<stop offset="1" stop-color="#B0C5FD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="g"
x1="142.583"
y1="96.948"
x2="119.437"
y2="93.029"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#C9D7FF" />
<stop offset="1" stop-color="#C9D7FF" stop-opacity="0" />
</linearGradient>
<linearGradient
id="h"
x1="108.697"
y1="176.472"
x2="131.959"
y2="148.997"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#7793DE" />
<stop offset="1" stop-color="#92AFFD" stop-opacity="0" />
</linearGradient>
<linearGradient
id="i"
x1="66.342"
y1="212.095"
x2="103.79"
y2="225.01"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#A6E6D3" stop-opacity=".4" />
<stop offset="1" stop-color="#A6E6D3" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<el-button type="primary" @click="backUrl">返回首页</el-button>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const backUrl = () => {
router.push({
name: 'home',
query: {
// ...route.query,
},
})
}
</script>
+53
View File
@@ -0,0 +1,53 @@
<template>
<el-card class="box-card col-center" shadow="never">
<div class="box-card-title">图片上传 🍱🍱🍱🍱🍱</div>
<el-upload
v-model:file-list="fileList"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<el-icon><Plus /></el-icon>
</el-upload>
<el-image-viewer v-if="dialogVisible" @close="imageView" style="width: 100px; height: 100px" :url-list="[dialogImageUrl]" />
</el-card>
</template>
<script setup>
import { reactive, ref } from "vue";
import { Plus } from "@element-plus/icons-vue";
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const pictureUpload = ref(null);
const fileList = ref([]);
const handleRemove = (file) => {
console.log(file);
};
const imageView = () => {
dialogVisible.value = false;
};
const handlePictureCardPreview = (file) => {
console.log(file.url);
dialogImageUrl.value = file.url;
dialogVisible.value = true;
};
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
padding-bottom: 20px;
}
}
.el-image-viewer__canvas {
img {
width: 120px !important;
height: auto !important;
}
}
</style>
+75
View File
@@ -0,0 +1,75 @@
<template>
<el-card class="box-card col-center" shadow="never">
<div class="box-card-title">数字动画 🍝🍝🍝🍝</div>
<div class="number-grow-warp">
<span ref="numberGrow" :data-time="time" class="number-grow" :data-value="number">0</span>
</div>
</el-card>
</template>
<script setup>
/* 需求说明:
1.数字不需要千位符,但是为了防止以后要有 所以加了个参数判断,默认是没有的
2.数字整数变动
3.组件改为行内元素,能更好的兼容页面样式
4.第二次数字变动在上次的数字累加
5.添加监听器防止页面不更新的情况
*/
import { onMounted, reactive, ref, watch } from "vue";
const time = reactive(6000);
const thousandSign = ref(false);
const number = ref(997052786868686);
const oldValue = ref(6868686);
const numberGrow = ref(null);
const setNumberGrow = (ele) => {
let value = number.value - oldValue.value;
let step = (value * 10) / (time * 100);
let current = 0;
let start = oldValue.value;
let t = setInterval(function () {
start += step;
if (start > number.value) {
clearInterval(t);
start = number.value;
t = null;
}
if (current === start) {
return;
}
current = parseInt(start);
oldValue.value = current;
if (thousandSign.value) {
ele.innerHTML = current.toString().replace(/(\d)(?=(?:\d{3}[+]?)+$)/g, "$1,");
} else {
ele.innerHTML = current.toString();
}
}, 10);
};
watch(number.value, (newV, oldV) => {
setNumberGrow(numberGrow.value);
// gsap.to(this, { duration: 0.5, tweened: Number(n) || 0 });
});
// watch: {
// number(n) {
// gsap.to(this, { duration: 0.5, tweened: Number(n) || 0 })
// }
// }
onMounted(() => {
setNumberGrow(numberGrow.value);
});
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
margin-bottom: 20px;
}
}
.number-grow-warp {
transform: translateZ(0);
}
</style>
+20
View File
@@ -0,0 +1,20 @@
<template>
<div class="content-box" style="height: 100%">
<iframe src="https://cn.bing.com/" frameborder="0" class="full-iframe"></iframe>
</div>
</template>
<style lang="scss" scoped>
.content-box {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
background-color: #fff;
}
.full-iframe {
// margin-top: 2.5%;
width: 100%;
height: 100%;
}
</style>
+87
View File
@@ -0,0 +1,87 @@
<template>
<el-card class="box-card" shadow="never">
<div class="box-card-title">文件上传 🍱🍱🍱🍱🍱</div>
<el-upload
class="upload-demo"
drag
multiple
:show-file-list="true"
:limit="excelLimit"
:http-request="uploadExcel"
:before-upload="beforeExcelUpload"
:on-exceed="handleExceed"
:on-success="excelUploadSuccess"
:on-error="excelUploadError"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>或点击上传</em></div>
<template #tip>
<div class="el-upload__tip">请上传 .xls , .xlsx 标准格式文件</div>
</template>
</el-upload>
</el-card>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { ElNotification } from 'element-plus'
// 最大文件数
const excelLimit = ref(1)
// 文件上传
const uploadExcel = (param) => {}
const beforeExcelUpload = (file) => {
const isExcel =
file.type === 'application/vnd.ms-excel' ||
file.type ===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
const isLt5M = file.size / 1024 / 1024 < 5
if (!isExcel)
ElNotification({
message: '上传文件只能是 xls / xlsx 格式!',
type: 'warning',
})
if (!isLt5M)
ElNotification({
message: '上传文件大小不能超过 5MB',
type: 'warning',
})
return isExcel && isLt5M
}
// 文件数超出提示
const handleExceed = () => {
ElNotification({
message: '最多只能上传一个文件!',
type: 'warning',
})
}
// 上传错误提示
const excelUploadError = () => {
ElNotification({
message: '导入数据失败,请您重新上传!',
type: 'error',
})
}
// 上传成功提示
const excelUploadSuccess = () => {
ElNotification({
message: '导入数据成功!',
type: 'success',
})
}
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
padding-bottom: 20px;
}
}
.upload-demo {
width: 50%;
}
</style>
+61
View File
@@ -0,0 +1,61 @@
<template>
<el-card class="box-card col-center" shadow="never">
<div class="box-card-title">引导页 🍮🍯🍳🍔</div>
<el-button type="primary" @click.prevent.stop="guide">开启指引</el-button>
</el-card>
</template>
<script setup>
import Driver from "driver.js";
import "driver.js/dist/driver.min.css";
const guide = () => {
const driver = new Driver({
allowClose: false,
doneBtnText: "结束",
closeBtnText: "关闭",
nextBtnText: "下一步",
prevBtnText: "上一步",
});
driver.defineSteps(steps);
driver.start();
};
const steps = [
{
element: "#collapseIcon",
popover: {
title: "Collapse Icon",
description: "Open && Close sidebar",
position: "right",
},
},
{
element: "#breadcrumb",
popover: {
title: "Breadcrumb",
description: "Indicate the current page location",
position: "right",
},
},
{
element: "#fullscreen",
popover: {
title: "Full Screen",
description: "Full Screen, Exit The Full Screen Page",
position: "left",
},
},
];
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
margin-bottom: 20px;
}
}
</style>
+45
View File
@@ -0,0 +1,45 @@
const setWaterCanvas = (str1, color) => {
console.log(color);
const id = "1.23452384164.123412415";
if (document.getElementById(id) !== null) {
document.body.removeChild(document.getElementById(id));
}
const can = document.createElement("canvas");
can.width = 120;
can.height = 80;
const cans = can.getContext("2d");
cans.rotate((-20 * Math.PI) / 180); // 水印旋转角度
cans.font = "15px Vedana";
cans.fillStyle = color;
cans.textAlign = "center";
cans.textBaseline = "Middle";
cans.fillText(str1, can.width / 2, can.height);
const div = document.createElement("div");
div.id = id;
div.style.pointerEvents = "none";
div.style.top = "40px";
div.style.left = "0px";
div.style.opacity = "0.15";
div.style.position = "fixed";
div.style.zIndex = "100000";
div.style.width = document.documentElement.clientWidth + "px";
div.style.height = document.documentElement.clientHeight + "px";
div.style.background = "url(" + can.toDataURL("image/png") + ") left top repeat";
document.body.appendChild(div);
return id;
};
// 创建水印
export function setWatermark(str1, color) {
let id = setWaterCanvas(str1, color);
if (document.getElementById(id) === null) {
id = setWaterCanvas(str1, color);
}
}
// 清除水印
export function clear() {
const id = "1.23452384164.123412415";
if (document.getElementById(id) !== null) {
document.body.removeChild(document.getElementById(id));
}
}
+24
View File
@@ -0,0 +1,24 @@
<template>
<el-card>
<div class="card-title">markdown编辑器🍬🍬🍬🍭🍭🍭<span @click="gotoUrl">[文档链接]</span></div>
<v-md-editor model="text" height="80vh"></v-md-editor>
</el-card>
</template>
<script setup>
import { ref } from "vue";
const text = ref("");
const gotoUrl = () => {
window.open("https://ckang1229.gitee.io/vue-markdown-editor/zh/#%E4%BB%8B%E7%BB%8D", "_blank");
};
</script>
<style lang="scss" scoped>
.card-title {
padding-bottom: 10px;
font-size: 18px;
font-weight: bold;
span {
color: #673ab7;
cursor: pointer;
}
}
</style>
+84
View File
@@ -0,0 +1,84 @@
<template>
<el-card :shadow="never" class="col-center">
<div class="p10">密码强度🍓🍇🍈🍉</div>
<el-form
label-position="left"
label-width="100px"
:model="formLabelAlign"
style="width: 460px"
>
<el-form-item label="请输入密码">
<el-input
v-model="formLabelAlign.passsword"
:prefix-icon="Lock"
type="password"
show-password
/>
</el-form-item>
<el-form-item label="密码强度">
<el-progress
v-show="formLabelAlign.passsword"
:percentage="percentage"
style="width: 460px"
:status="status"
/>
</el-form-item>
</el-form>
</el-card>
</template>
<script setup>
import { reactive, ref, watch } from 'vue'
const formLabelAlign = reactive({
passsword: '',
})
let percentage = ref(0)
let status = ref('exception')
const checkStrong = (sValue) => {
var modes = 0
if (sValue.length < 1) return modes
if (/\d/.test(sValue)) modes++ //数字
if (/[a-z]/.test(sValue)) modes++ //小写
if (/[A-Z]/.test(sValue)) modes++ //大写
if (/\W/.test(sValue)) modes++ //特殊字符
switch (modes) {
case 1:
return 1
break
case 2:
return 2
break
case 3:
case 4:
return sValue.length < 10 ? 3 : 4
break
}
return modes
}
const statusChange = (modes) => {
if (modes == 1) {
percentage.value = 25
status.value = 'exception'
} else if (modes == 2) {
percentage.value = 50
status.value = 'exception'
} else if (modes == 3) {
percentage.value = 75
status.value = 'warning'
} else {
percentage.value = 100
status.value = 'success'
}
}
watch(
() => formLabelAlign.passsword,
(newValue, oldValue) => {
let modes = checkStrong(newValue)
console.log(modes)
statusChange(modes)
}
)
</script>
+278
View File
@@ -0,0 +1,278 @@
<template>
<el-card class="clo-center">
<div class="p10">验证组件🍨🍨🍨🍧🍧🍧</div>
<el-form label-position="left" inline label-width="100px" :model="formLabelAlign">
<el-form-item label="请输入验证码" style="margin-right: 0">
<el-input v-model="formLabelAlign.code" />
</el-form-item>
<el-form-item>
<div class="s-canvas">
<canvas @click="upDataCode" ref="canvasRef" :width="contentWidth" :height="contentHeight"></canvas></div
></el-form-item>
</el-form>
<div className="sliderContent">
<div className="imgDev" style="width: 500px">
<canvas id="canvasImg" width="500" height="auto"></canvas>
<canvas className="slider" id="sliderBlock" :width="500" :height="280" :style="{ left: sildLeft + 'px' }"></canvas>
<!-- <el-slider class="moveSlider" @change="changeValue1" v-model="value1" /> -->
</div>
</div>
<div class="moveSlider" :style="{ background: verifyResult ? '#859baa' : '#f7f8fa', color: verifyResult ? '#fff' : '606266' }">
{{ verifyResult ? "解锁成功" : "滑动解锁" }}
<div class="slider" @mousedown="sliderMove" ref="slider">
<el-icon v-if="verifyResult" class="icon-style" style="color: #859baa"><Select /></el-icon>
<el-icon v-else class="icon-style"><DArrowRight /></el-icon>
</div>
</div>
</el-card>
</template>
<script setup>
import { DArrowRight, Select } from "@element-plus/icons-vue";
import { onMounted, reactive, ref } from "vue";
const contentWidth = ref(100);
const contentHeight = ref(32);
const sliderWidth = ref();
const sliderHeight = ref();
const sildLeft = ref(0);
const value1 = ref(0);
const sildY = ref();
const sildX = ref();
const verifyResult = ref(false);
const formLabelAlign = reactive({
code: "",
});
const identifyCodes = ref("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
const identifyCode = ref("1234");
const canvasRef = ref(null);
// 生成随机数
const randomNum = (min, max) => {
return Math.floor(Math.random() * (max - min) + min);
};
const randomColor = (min, max) => {
var r = randomNum(min, max);
var g = randomNum(min, max);
var b = randomNum(min, max);
return "rgb(" + r + "," + g + "," + b + ")";
};
const drawPic = () => {
let ctx = canvasRef.value.getContext("2d");
ctx.fillStyle = randomColor(180, 230); //填充颜色
ctx.fillRect(0, 0, contentWidth.value, contentHeight.value); //填充位置
// drawLine(ctx);
let imgCode = "";
// 随机产生字符串,并且随机旋转
for (let i = 0; i < 4; i++) {
const text = identifyCodes.value[randomNum(0, identifyCodes.value.length)];
const deg = randomNum(-30, 30);
imgCode += text;
ctx.font = randomNum(18, 40) + "px Simhei"; //填充字体
ctx.textBaseline = "top";
ctx.fillStyle = randomColor(80, 150);
drawDot(ctx);
ctx.save(); //保存
ctx.translate(30 * i + 15, 15);
ctx.rotate((deg * Math.PI) / 180); //随机的旋转
ctx.fillText(text, -15 + 5, -15); //
ctx.restore(); //清除
}
drawLine(ctx);
return imgCode;
};
const drawLine = (ctx) => {
for (let i = 0; i < 5; i++) {
ctx.strokeStyle = randomColor(0, 255);
ctx.beginPath();
ctx.moveTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value));
ctx.lineTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value));
ctx.stroke();
}
};
const drawDot = (ctx) => {
for (let i = 0; i < 20; i++) {
ctx.fillStyle = randomColor(0, 255);
ctx.beginPath();
ctx.arc(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value), 1, 0, 2 * Math.PI);
ctx.fill();
}
};
onMounted(() => {
drawPic();
loadImage();
});
const upDataCode = () => {
identifyCode.value = "";
makeCode(identifyCodes.value, 4);
};
const makeCode = (val, l) => {
for (let i = 1; i < val.length && i <= l; i++) {
identifyCode.value += identifyCodes.value[Math.floor(Math.random() * (identifyCodes.value.length - 0) + 0)];
}
console.log(identifyCode.value);
drawPic();
};
// 拼图
const loadImage = () => {
//加载图片
let mainDom = document.getElementById("canvasImg");
let bg = mainDom.getContext("2d");
let imgSrc =
"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202001%2F30%2F20200130003214_3GJWF.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663755123&t=0f35d18b29de642d5af549a5ec7062e5";
let img = document.createElement("img");
img.src = imgSrc;
img.onload = () => {
mainDom.height = (img.height / img.width) * mainDom.width;
bg.drawImage(img, 0, 0, mainDom.width, mainDom.height);
let r = 10; //半圆的半径
let w = 60; //滑块的宽度
let x = randomNum(85, mainDom.width - w - r - 2); //保证缺口完全展示,不会隐藏
let y = randomNum(16, mainDom.height - w - r - 2);
sildY.value = y;
sildX.value = x;
bg.lineWidth = 1;
bg.strokeStyle = "white";
bg.beginPath();
bg.moveTo(x, y);
//top
bg.arc(x + w / 2, y, r, -Math.PI, 0, true);
bg.lineTo(x + w, y);
//right
bg.arc(x + w, y + w / 2, r, 1.5 * Math.PI, 0.5 * Math.PI, false);
bg.lineTo(x + w, y + w);
//bottom
bg.arc(x + w / 2, y + w, r, 0, Math.PI, false);
bg.lineTo(x, y + w);
//left
bg.arc(x, y + w / 2, r, 0.5 * Math.PI, 1.5 * Math.PI, true);
bg.lineTo(x, y);
bg.stroke();
bg.fillStyle = "rgba(0, 0, 0, 0.4)"; //设置背景颜色
bg.fill();
sliderContent(img);
};
};
const sliderContent = (img) => {
let r = 10; //半圆的半径
let w = 60; //滑块的宽度
let mainDom = document.getElementById("sliderBlock");
let ctx = mainDom.getContext("2d");
//index.store.ts
let x = sildLeft.value;
let y = sildY.value;
let PI = Math.PI;
ctx.lineWidth = 1;
//绘制
ctx.beginPath();
//left
ctx.moveTo(x, y);
//top
ctx.arc(x + w / 2, y, r, -PI, 0, true);
ctx.lineTo(x + w, y);
//right
ctx.arc(x + w, y + w / 2, r, 1.5 * PI, 0.5 * PI, false);
ctx.lineTo(x + w, y + w);
//bottom
ctx.arc(x + w / 2, y + w, r, 0, PI, false);
ctx.lineTo(x, y + w);
//left
ctx.arc(x, y + w / 2, r, 0.5 * PI, 1.5 * PI, true);
ctx.lineTo(x, y);
ctx.shadowBlur = 10;
ctx.shadowColor = "black";
ctx.stroke();
ctx.clip();
console.log(img);
ctx.drawImage(img, -sildX.value + sildLeft.value, 0, 500, 280);
// console.log(ctx)
};
const sliderMove = (event) => {
let disX = 0;
const iconWidth = 60;
const ele = document.querySelector(".moveSlider .slider");
const startX = event.clientX || event.touches[0].pageX;
const MaxX = 500 - iconWidth;
if (verifyResult.value) {
return false;
}
// 开始移动
const onMove = (e) => {
const endX = e.clientX || e.touches[0].pageX;
disX = endX - startX;
if (disX <= 0) {
disX = 0;
}
if (disX >= MaxX - iconWidth) {
disX = MaxX;
}
sildLeft.value = disX;
ele.style.transition = ".1s all";
ele.style.transform = `translateX(${disX}px)`;
console.log(ele.style.transform);
};
const onEnd = () => {
if (disX > sildX.value - 5 && disX < sildX.value + 5) {
verifyResult.value = true;
} else {
ele.style.transition = ".5s all";
ele.style.transform = "translateX(0)";
}
document.removeEventListener("mousemove", onMove);
document.removeEventListener("mouseup", onEnd);
};
document.addEventListener("mousemove", onMove);
document.addEventListener("mouseup", onEnd);
};
</script>
<style lang="scss" scoped>
.s-canvas {
height: 38px;
}
.s-canvas canvas {
margin-top: 1px;
margin-left: 8px;
}
.sliderContent {
margin-top: 20px;
position: relative;
.slider {
position: absolute;
}
}
.moveSlider {
width: 500px;
height: 32px;
background-color: #f7f8fa;
font-size: 14px;
line-height: 32px;
text-align: center;
color: #606266;
position: relative;
border: 1px solid #e4e7ed;
.slider {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 32px;
background-color: #fff;
cursor: pointer;
.icon-style {
margin-top: 6px;
font-size: 20px;
text-align: center;
}
}
}
</style>
+66
View File
@@ -0,0 +1,66 @@
<template>
<el-card class="box-card col-center" shadow="never">
<span class="box-card-title">富文本编辑器 🍰🍰🍰🍩🍩🍩</span>
<div class="wangeditor-box">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
class="editor-txt"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</el-card>
</template>
<script setup>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
const editorRef = shallowRef()
// 内容 HTML
const valueHtml = ref('<p>hello</p>')
// 模拟 ajax 异步获取内容
onMounted(() => {
setTimeout(() => {
valueHtml.value = '<p>富文本编辑器</p>'
}, 1500)
})
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...' }
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.wangeditor-box {
border: 1px solid #f0f2f5;
margin-top: 20px;
}
.editor-txt {
height: 75vh !important;
overflow-y: hidden;
text-align: left;
}
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<template>
<el-row>
<el-col>
<el-card shadow="never">
<div class="p10">水印组件🍬🍬🍬🍭🍭🍭</div>
<el-form :inline="true" ref="formRef" :model="numberValidateForm" label-width="100px" class="demo-ruleForm">
<el-form-item
label="水印名称"
prop="text"
:rules="[
{ required: true, message: 'age is required' },
{ type: 'text', message: '请输入水印名称' },
]"
>
<el-input v-model="numberValidateForm.text" type="text" autocomplete="off" />
</el-form-item>
<el-form-item label="选择水印颜色" prop="color">
<el-color-picker v-model="numberValidateForm.color" show-alpha />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(formRef)">创建</el-button>
<el-button @click="resetForm(formRef)">取消</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
</el-row>
</template>
<script setup>
import { reactive } from "vue";
import { setWatermark, clear } from "./index.js";
const numberValidateForm = reactive({
text: "",
color: "#4060c7",
});
const submitForm = () => {
console.log(numberValidateForm.color);
setWatermark(numberValidateForm.text, numberValidateForm.color);
};
const resetForm = () => {
numberValidateForm.text = "";
numberValidateForm.color = "";
clear();
};
</script>
+1
View File
@@ -0,0 +1 @@
<template>关于我</template>
+39
View File
@@ -0,0 +1,39 @@
<template>
<el-card>
<span class="box-card-title">拖拽🍻🍻🍻🍵🍵🍵</span>
<div class="box-card-content">
<div v-draggable class="drag-box flx-center text">我可以拖拽哦~</div>
<div
v-draggable
class="drag-box flx-center text"
style="background: #eba300; width: 200px; height: 200px"
>
我可以拖拽哦~
</div>
</div>
</el-card>
</template>
<script setup></script>
<style lang="scss" scoped>
.box-card-title {
padding: 10px;
// display: block;
}
.box-card-content {
width: 100%;
height: 80vh;
background-color: #fff;
position: relative;
.drag-box {
position: absolute;
top: 110px;
width: 300px;
height: 300px;
color: #fff;
background: #bad80a;
}
}
</style>
+17
View File
@@ -0,0 +1,17 @@
<template>
<el-card shadow="never">
<div>复制指令 🍤🍤🍤🍤🍤🍤</div>
<br />
<el-input v-model="input3" placeholder="复制指令 🍤🍤🍤🍤🍤" style="width: 100%">
<template #append>
<el-button :icon="CopyDocument" v-copy="input3">复制</el-button>
</template>
</el-input>
</el-card>
</template>
<script setup>
import { ref } from "vue";
import { CopyDocument } from "@element-plus/icons-vue";
const input3 = ref("复制内容复制内容复制内容复制内容复制内容");
</script>
+14
View File
@@ -0,0 +1,14 @@
<template>
<el-card shadow="never">
<div class="card-title">防抖指令 🍍🍓🍓🍓🍓</div>
<br />
<el-button type="primary" v-debounce="debounceClick">防抖按钮(1秒后执行)</el-button>
</el-card>
</template>
<script setup>
import { ElMessage } from "element-plus";
const debounceClick = () => {
ElMessage.success("我是防抖指令");
};
</script>
+14
View File
@@ -0,0 +1,14 @@
<template>
<el-card shadow="never">
<div class="card-title">长按指令 🍍🍓🍓🍓🍓</div>
<br />
<el-button type="primary" v-longPress="debounceClick">长按指令</el-button>
</el-card>
</template>
<script setup>
import { ElMessage } from "element-plus";
const debounceClick = () => {
ElMessage.success("我是长按指令");
};
</script>
+14
View File
@@ -0,0 +1,14 @@
<template>
<el-card shadow="never">
<div class="card-title">节流指令 🍍🍓🍓🍓🍓</div>
<br />
<el-button type="primary" v-throttle="throttleClick">节流指令</el-button>
</el-card>
</template>
<script setup>
import { ElMessage } from 'element-plus'
const throttleClick = () => {
ElMessage.success('我是节流指令')
}
</script>
+163
View File
@@ -0,0 +1,163 @@
<template>
<el-card style="height: 85vh">
<div id="histogram" style="width: 100%; height: 80vh"></div>
</el-card>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted } from 'vue'
const getHistorgram = () => {
document.getElementById('histogram').setAttribute('_echarts_instance_', '')
var chartDom = document.getElementById('histogram')
var myChart = echarts.init(chartDom)
let app = {}
var option
const categories = (function () {
let now = new Date()
let res = []
let len = 10
while (len--) {
res.unshift(now.toLocaleTimeString().replace(/^\D*/, ''))
now = new Date(+now - 2000)
}
return res
})()
const categories2 = (function () {
let res = []
let len = 10
while (len--) {
res.push(10 - len - 1)
}
return res
})()
const data = (function () {
let res = []
let len = 10
while (len--) {
res.push(Math.round(Math.random() * 1000))
}
return res
})()
const data2 = (function () {
let res = []
let len = 0
while (len < 10) {
res.push(+(Math.random() * 10 + 5).toFixed(1))
len++
}
return res
})()
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#283b56',
},
},
},
// legend: {},
// toolbox: {
// show: true,
// feature: {
// dataView: { readOnly: false },
// restore: {},
// saveAsImage: {},
// },
// },
dataZoom: {
show: false,
start: 0,
end: 100,
},
xAxis: [
{
type: 'category',
boundaryGap: true,
data: categories,
},
{
type: 'category',
boundaryGap: true,
data: categories2,
},
],
yAxis: [
{
type: 'value',
scale: true,
name: '价格',
max: 30,
min: 0,
boundaryGap: [0.2, 0.2],
},
{
type: 'value',
scale: true,
name: '订单数',
max: 1200,
min: 0,
boundaryGap: [0.2, 0.2],
},
],
series: [
{
name: 'Dynamic Bar',
type: 'bar',
xAxisIndex: 1,
yAxisIndex: 1,
data: data,
},
{
name: 'Dynamic Line',
type: 'line',
data: data2,
},
],
}
app.count = 11
setInterval(function () {
let axisData = new Date().toLocaleTimeString().replace(/^\D*/, '')
data.shift()
data.push(Math.round(Math.random() * 1000))
data2.shift()
data2.push(+(Math.random() * 10 + 5).toFixed(1))
categories.shift()
categories.push(axisData)
categories2.shift()
categories2.push(app.count++)
myChart.setOption({
xAxis: [
{
data: categories,
},
{
data: categories2,
},
],
series: [
{
data: data,
},
{
data: data2,
},
],
})
}, 2100)
option && myChart.setOption(option)
window.onresize = () => {
myChart.resize()
}
}
onMounted(() => {
setTimeout(() => {
getHistorgram()
}, 1000)
})
</script>
+88
View File
@@ -0,0 +1,88 @@
<template>
<el-card style="height: 85vh">
<div id="line" style="width: 100%; height: 80vh"></div>
</el-card>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted } from 'vue'
const getHistorgram = () => {
document.getElementById('line').setAttribute('_echarts_instance_', '')
var chartDom = document.getElementById('line')
var myChart = echarts.init(chartDom)
let app = {}
var option = {
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} °C',
},
},
series: [
{
name: 'Highest',
type: 'line',
data: [10, 11, 13, 11, 12, 12, 9],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Lowest',
type: 'line',
data: [1, -2, 2, 5, 3, 2, 0],
markPoint: {
data: [{ name: '周最低', value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: 'average', name: 'Avg' },
[
{
symbol: 'none',
x: '90%',
yAxis: 'max',
},
{
symbol: 'circle',
label: {
position: 'start',
formatter: 'Max',
},
type: 'max',
name: '最高点',
},
],
],
},
},
],
}
option && myChart.setOption(option)
window.onresize = () => {
myChart.resize()
}
}
onMounted(() => {
setTimeout(() => {
getHistorgram()
}, 1000)
})
</script>
+40
View File
@@ -0,0 +1,40 @@
<template>
<el-card>
<div id="container">111</div>
</el-card>
</template>
<script setup>
import { onMounted } from "vue";
const initMap = () => {
var map = new BMapGL.Map("container"); // 创建地图实例
var point = new BMapGL.Point(116.404, 39.915); // 创建点坐标
var marker = new BMapGL.Marker(point); // 创建标注
map.addOverlay(marker);
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true);
var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件
map.addControl(scaleCtrl);
var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件
map.addControl(zoomCtrl);
var cityCtrl = new BMapGL.CityListControl(); // 添加城市列表控件
map.addControl(cityCtrl);
map.addEventListener("click", function (e) {
// 拿到点击地图上这一点的经纬度
// alert(e.point.lng + ", " + e.point.lat);
// 让地图中心平滑移动到点击的点
map.panTo(new BMap.Point(e.point.lng, e.point.lat));
});
};
onMounted(() => {
// initMap();
});
</script>
<style lang="scss" scoped>
#container {
width: 100%;
height: 85vh;
}
</style>
+44
View File
@@ -0,0 +1,44 @@
<template>
<el-card>
<div id="gaodeMap">111</div>
</el-card>
</template>
<script setup>
import { nextTick, onMounted } from "vue";
const initGaoMap = () => {
var map = new AMap.Map("gaodeMap", {
zoom: 11, //级别
center: [116.397428, 39.90923], //中心点坐标
viewMode: "2D", //使用3D视图
});
// 在图面添加工具条控件,工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
map.addControl(new AMap.ToolBar());
// 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺
map.addControl(new AMap.Scale());
// 在图面添加鹰眼控件,在地图右下角显示地图的缩略图
map.addControl(new AMap.HawkEye({ isOpen: true }));
// 在图面添加类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
// map.addControl(new AMap.MapType())
// 在图面添加定位控件,用来获取和展示用户主机所在的经纬度位置
// map.addControl(new AMap.Geolocation())
map.setFitView();
};
onMounted(() => {
nextTick(() => {
// initGaoMap()
});
});
</script>
<style lang="scss" scoped>
#gaodeMap {
width: 100%;
height: 85vh;
}
</style>
+70
View File
@@ -0,0 +1,70 @@
<template>
<el-card style="height: 85vh">
<div id="radar" style="width: 100%; height: 80vh"></div>
</el-card>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted } from 'vue'
const getHistorgram = () => {
document.getElementById('radar').setAttribute('_echarts_instance_', '')
var chartDom = document.getElementById('radar')
var myChart = echarts.init(chartDom)
let app = {}
var option = {
color: ['#33ccff ', '#ff99cc'],
radar: {
// shape: 'circle',
indicator: [
{ name: '体重', max: 6500 },
{ name: '打败', max: 16000 },
{ name: '完成目标', max: 30000 },
{ name: '身体年龄', max: 38000 },
{ name: '运动量', max: 52000 },
// { name: 'Marketing', max: 25000 },
],
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [
{
value: [4200, 3000, 20000, 35000, 50000, 18000],
name: 'Allocated Budget',
},
{
value: [5000, 14000, 28000, 26000, 42000, 21000],
name: 'Actual Spending',
areaStyle: {
color: new echarts.graphic.RadialGradient(0.1, 0.6, 1, [
{
color: 'rgba(255, 145, 124, 0.1)',
offset: 0,
},
{
color: '#ff99cc ',
offset: 1,
},
]),
},
},
],
},
],
}
option && myChart.setOption(option)
window.onresize = () => {
myChart.resize()
}
}
onMounted(() => {
setTimeout(() => {
getHistorgram()
}, 1000)
})
</script>
+142
View File
@@ -0,0 +1,142 @@
<template>
<el-card>
<!-- <Row> 更多查看<a href="https://vueflow.dev/">Vue Flow官方文档</a> </Row> -->
<div class="mt-4">
<el-button type="primary" @click="resetTransform">重置</el-button>
<el-button type="success" @click="updatePos">修改属性</el-button>
<el-button type="success" @click="toggleclass">修改样式</el-button>
<el-button type="warning" @click="logToObject">查看属性</el-button>
</div>
<VueFlow v-model="elements" class="vue-flow-content">
<Background />
<MiniMap />
<Controls />
</VueFlow>
</el-card>
<el-dialog
v-model="dialogVisible"
title="流程图属性"
width="70%"
:before-close="handleClose"
>
<span>{{ dialogContent }}</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false"
>确认</el-button
>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ElMessage, ElMessageBox } from 'element-plus'
import '@braks/vue-flow/dist/style.css'
import '@braks/vue-flow/dist/theme-default.css'
import {
Background,
Controls,
MiniMap,
VueFlow,
isNode,
useVueFlow,
} from '@braks/vue-flow'
import { ref } from 'vue'
// import { Message } from 'view-ui-plus'
const dialogVisible = ref(false)
const dialogContent = ref('')
const elementsDefault = [
{
id: '1',
type: 'input',
label: '自律',
position: { x: 250, y: 5 },
class: 'node-light',
},
{
id: '2',
label: '控玩玩手机的时间',
position: { x: 100, y: 100 },
class: 'node-light',
},
{
id: '3',
label: '养成良好生活习惯',
position: { x: 400, y: 100 },
class: 'node-light',
},
{
id: '4',
label: '培养阅读习惯',
position: { x: 400, y: 200 },
class: 'node-light',
},
{ id: 'e1-2', source: '1', target: '2', animated: true },
{ id: 'e1-3', source: '1', target: '3' },
]
const elements = ref(elementsDefault)
const {
onPaneReady,
onNodeDragStop,
onConnect,
addEdges,
setTransform,
toObject,
} = useVueFlow({
defaultZoom: 1.5,
minZoom: 0.2,
maxZoom: 4,
})
onPaneReady(({ fitView }) => {
fitView()
})
onNodeDragStop((e) => console.log('drag stop', e))
onConnect((params) => addEdges([params]))
const updatePos = () => {
elements.value.forEach((el) => {
if (isNode(el)) {
el.position = {
x: Math.random() * 400,
y: Math.random() * 400,
}
}
})
}
const logToObject = () => {
dialogVisible.value = true
dialogContent.value = JSON.stringify(toObject())
// Message.info(JSON.stringify(toObject()))
}
const resetTransform = () => {
elements.value = elementsDefault
setTransform({ x: 0, y: 0, zoom: 1 })
}
const toggleclass = () =>
elements.value.forEach(
(el) => (el.class = el.class === 'node-light' ? 'node-dark' : 'node-light')
)
</script>
<style lang="scss" scoped>
.vue-flow-content {
height: 80vh;
.node-light {
background: none;
}
.node-dark {
background: #eeeeee;
}
}
.mt-4 {
float: right;
text-align: right;
margin-bottom: 20px;
}
</style>
+67
View File
@@ -0,0 +1,67 @@
<template>
<el-card>
<div class="card-title">添加input 🍯🍯🍯🍯🍯🍯</div>
<el-input v-model="input1" placeholder="请输入域名">
<template #prepend>Http://</template>
</el-input>
<el-input v-model="input1" placeholder="请输入..." class="mt10">
<template #prepend>
<el-select v-model="select" placeholder="" style="width: 115px">
<el-option label="邮箱" value="1" />
<el-option label="wexin" value="2" />
<el-option label="Tel" value="3" />
</el-select>
</template>
</el-input>
<el-input v-model="input1" placeholder="请输入..." class="mt10">
<template #append>.com</template>
</el-input>
<el-input v-model="input1" placeholder="请输入..." class="mt10">
<template #prepend>
<el-select v-model="select" placeholder="Select2" style="width: 115px">
<el-option label="分类一" value="1" />
<el-option label="分类二" value="2" />
<el-option label="分类三" value="3" /> </el-select
></template>
<template #append><el-button :icon="Search" /></template>
</el-input>
<el-input
class="mt10"
v-for="item in inputList"
:key="item"
:v-model="item"
placeholder="请输入"
>
<template #append
><el-button @click="deleteHanle(item)">Delete</el-button></template
>
</el-input>
<el-button icon="Plus" class="mt10 w100" @click="addInput()"
>添加</el-button
>
</el-card>
</template>
<script setup>
import { Search, Plus } from '@element-plus/icons-vue'
import { ref } from 'vue'
const input1 = ref('')
const inputList = ref([])
const select = ref('1')
const Select2 = ref('1')
const addInput = () => {
inputList.value.push('')
}
const deleteHanle = (item) => {
inputList.value.splice(inputList.value[item], 1)
}
</script>
<style lang="scss" scoped>
.card-title {
padding-bottom: 20px;
font-size: 18px;
text-align: center;
}
</style>
+79
View File
@@ -0,0 +1,79 @@
<template>
<el-card class="col-center">
<el-form :model="form" label-width="120px">
<el-form-item label="活动名称">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="活动日期">
<el-col :span="11">
<el-date-picker
v-model="form.date1"
type="date"
placeholder="开始日期"
style="width: 100%"
/>
</el-col>
<el-col :span="2" class="开启活动">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-time-picker
v-model="form.date2"
placeholder="结束日期"
style="width: 100%"
/>
</el-col>
</el-form-item>
<el-form-item label="活动状态">
<el-switch v-model="form.delivery" />
</el-form-item>
<el-form-item label="活动类型">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type" />
<el-checkbox label="Promotion activities" name="type" />
<el-checkbox label="Offline activities" name="type" />
<el-checkbox label="Simple brand exposure" name="type" />
</el-checkbox-group>
</el-form-item>
<el-form-item label="活动资源">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor" />
<el-radio label="Venue" />
</el-radio-group>
</el-form-item>
<el-form-item label="活动描述">
<el-input v-model="form.desc" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
// do not use same name with ref
const form = reactive({
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: '',
})
const onSubmit = () => {
console.log('submit!')
}
</script>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+109
View File
@@ -0,0 +1,109 @@
<template>
<el-card class="box-card" shadow="never"> 卡片列表 🍓🍇🍈🍉 </el-card>
<el-row
class="mt10"
style="height: 75vh; overflow: auto"
v-infinite-scroll="load"
>
<el-col :span="6" v-for="item in listData" :key="item" offset="1">
<el-card shadow="hover" class="card-lists">
<!-- <div
class="item-state-pos"
:style="{
backgroundColor:
item.pay_state == '1002'
? '#6C88D5'
: item.pay_state == '1003'
? '#fa4a1e'
: '#00AA5A',
}"
>
{{
item.pay_state == '1001'
? '已支付'
: item.pay_state == '1002'
? '待支付'
: '未支付'
}}
</div> -->
<div class="item-state-pos">
<el-icon><MoreFilled /></el-icon>
</div>
<div class="item-title">
<img src="../../assets/images/avart.jpg" alt="" />{{ item.title }}
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">发行日期</div>
<div class="cot-txt">{{ item.date }}</div>
</div>
<div class="cot">
<div class="cot-tit">客户姓名</div>
<div class="cot-txt">{{ item.user_name }}</div>
</div>
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">
金额 <span>{{ item.number }}</span>
</div>
</div>
<div class="cot">
<div class="cot-tit">
状态
<span
:class="[
item.pay_state == '1002'
? 'type suc-type'
: item.pay_state == '1003'
? 'type'
: 'type error-type',
]"
>{{
item.pay_state == '1001'
? '已支付'
: item.pay_state == '1002'
? '待支付'
: '未支付'
}}</span
>
</div>
</div>
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">详情</div>
<div class="cot-txt one-cut-txt">{{ item.content }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</template>
<script setup>
import { cardlists } from '../../api/modules/index.js'
import { onMounted, ref } from 'vue'
const listData = ref([])
const load = () => {
cardlists().then((res) => {
listData.value = listData.value.concat(res.data.data)
})
// count.value += 2
}
const getListData = () => {
cardlists().then((res) => {
listData.value = res.data.data
})
}
onMounted(() => {
getListData()
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
+80
View File
@@ -0,0 +1,80 @@
<template>
<el-card class="box-card" shadow="never"> 基础列表 🍓🍇🍈🍉 </el-card>
<div v-infinite-scroll="load" class="infinite-list" style="overflow: auto">
<div class="barlist flx-row" v-for="i in listData" :key="i">
<div class="item-img">
<img src="../../assets/images/avart.jpg" alt="" />
</div>
<div class="item-left">
<div class="name">{{ i.createUser }}</div>
<div class="subname">{{ i.email }}</div>
</div>
<div class="item-left">
<div class="name">{{ i.title }}</div>
<div class="subname">{{ i.createTime }}发票已发出</div>
</div>
<div class="item-right">{{ i.number }}</div>
<div
class="item-state flx-row"
:style="{
backgroundColor:
i.pay_state == '1002'
? '#6C88D5'
: i.pay_state == '1003'
? '#fa4a1e'
: '#00AA5A',
}"
>
<span>{{
i.pay_state == '1001'
? '已支付'
: i.pay_state == '1002'
? '待支付'
: '未支付'
}}</span>
</div>
</div>
<!-- <div v-for="i in listData" :key="i" class="infinite-list-item">
<div class="infinite-list-item-top">
{{ i.title }}
</div>
<div class="infinite-list-item-main flx-row">
<div style="flex: 1">创建人{{ i.createUser }}</div>
<div style="flex: 1">发布时间{{ i.createTime }}</div>
</div>
</div>-->
</div>
</template>
<script setup>
import { Newslist } from '../../api/modules/index.js'
import { onMounted, ref } from 'vue'
const listData = ref([])
const load = () => {
Newslist().then((res) => {
listData.value = listData.value.concat(res.data.data)
})
// count.value += 2
}
const getListData = () => {
Newslist().then((res) => {
listData.value = res.data.data
})
}
onMounted(() => {
getListData()
})
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
margin-bottom: 20px;
}
}
@import './index.scss';
</style>
+157
View File
@@ -0,0 +1,157 @@
.infinite-list {
height: 72vh;
padding: 0;
margin: 0;
list-style: none;
}
.infinite-list {
margin-top: 20px;
width: 100%;
height: 100%;
.barlist {
margin-bottom: 10px;
background-color: #fff;
padding: 10px;
border-radius: 2px;
.item-img {
margin-right: 10px;
img {
width: 34px;
height: 34px;
border-radius: 50%;
}
}
.item-left {
flex: 1;
display: flex;
flex-direction: column;
.name {
font-size: 16px;
}
.subname {
font-size: 14px;
color: rgba(83, 88, 117, 1);
}
}
.item-state {
margin-left: 20px;
span {
display: inline-block;
color: #fff;
font-size: 12px;
letter-spacing: 1px;
padding: 5px 10px;
border-radius: 6px;
// background-color: #1250FC;
}
}
}
}
.card-lists {
margin: 10px;
position: relative;
.item-state-pos {
position: absolute;
right: 0;
top: 10px;
// background-color: #1250FC;
color: #6C88D5;
font-size: 14px;
padding: 5px 10px;
border-radius: 0 0 0 20px;
}
.item-title {
img {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 5px;
vertical-align: text-top;
}
font-size: 16px;
font-weight: 600;
color: rgba(15, 18, 34, 1);
text-align: left;
vertical-align: top;
margin-bottom: 15px;
}
.item-content {
margin-bottom: 5px;
.cot {
flex: 1;
.cot-tit {
font-size: 14px;
font-weight: 400;
color: rgba(83, 88, 117, 1);
padding-bottom: 5px;
span {
font-size: 14px;
color: rgba(15, 18, 34, 1);
&.type {
font-size: 10px;
padding: 5px 10px;
font-weight: 500;
line-height: 0px;
color: #fa4a1e;
text-align: left;
border-radius: 6px;
background: #fa4a1e14;
&.error-type {
color: #4060c7;
background: #e8f3ff;
}
&.suc-type {
color: #48ac4c;
background: #e2ffef;
}
}
}
}
.cot-txt {
font-size: 14px;
font-weight: 400;
color: rgba(15, 18, 34, 1);
}
}
}
.item-bottom {
flex-flow: row-reverse;
}
}
.infinite-list .infinite-list-item+.list-item {
margin-top: 10px;
}
.mt-4 {
float: right;
text-align: right;
}
+259
View File
@@ -0,0 +1,259 @@
<template>
<el-card class="box-card" shadow="never">
<div class="flx-row">
搜索列表 🍓🍇🍈🍉
<el-input
type="text"
placeholder="请输入关键字..."
style="width: 300px; margin-left: 10px"
v-model="searchValue"
>
<template #append>
<el-button type="primary" :icon="Search" />
</template>
</el-input>
<div style="flex: 1"></div>
<div class="img" @click="checkList('1001')">
<svg
t="1663432921802"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4971"
data-spm-anchor-id="a313x.7781069.0.i30"
width="20"
height="20"
:fill="colorType == '1001' ? '#1250FC' : '#888888'"
>
<path
d="M849.1 128 174.9 128c-25.9 0-46.9 21-46.9 46.9l0 34.2c0 25.9 21 46.9 46.9 46.9l674.2 0c25.9 0 46.9-21 46.9-46.9l0-34.2C896 149 875 128 849.1 128z"
p-id="4972"
></path>
<path
d="M849.1 768 174.9 768c-25.9 0-46.9 21-46.9 46.9l0 34.2c0 25.9 21 46.9 46.9 46.9l674.2 0c25.9 0 46.9-21 46.9-46.9l0-34.2C896 789 875 768 849.1 768z"
p-id="4973"
></path>
<path
d="M849.1 448 174.9 448c-25.9 0-46.9 21-46.9 46.9l0 34.2c0 25.9 21 46.9 46.9 46.9l674.2 0c25.9 0 46.9-21 46.9-46.9l0-34.2C896 469 875 448 849.1 448z"
p-id="4974"
></path>
</svg>
</div>
<div class="img" @click="checkList('1002')">
<svg
t="1663433235072"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5148"
width="23"
height="23"
:fill="colorType == '1002' ? '#1250FC' : '#888888'"
>
<path
d="M433.1 480 174.9 480c-25.9 0-46.9-21-46.9-46.9L128 174.9c0-25.9 21-46.9 46.9-46.9l258.2 0c25.9 0 46.9 21 46.9 46.9l0 258.2C480 459 459 480 433.1 480z"
p-id="5149"
></path>
<path
d="M433.1 896 174.9 896c-25.9 0-46.9-21-46.9-46.9L128 590.9c0-25.9 21-46.9 46.9-46.9l258.2 0c25.9 0 46.9 21 46.9 46.9l0 258.2C480 875 459 896 433.1 896z"
p-id="5150"
></path>
<path
d="M849.1 480 590.9 480c-25.9 0-46.9-21-46.9-46.9L544 174.9c0-25.9 21-46.9 46.9-46.9l258.2 0c25.9 0 46.9 21 46.9 46.9l0 258.2C896 459 875 480 849.1 480z"
p-id="5151"
></path>
<path
d="M849.1 896 590.9 896c-25.9 0-46.9-21-46.9-46.9L544 590.9c0-25.9 21-46.9 46.9-46.9l258.2 0c25.9 0 46.9 21 46.9 46.9l0 258.2C896 875 875 896 849.1 896z"
p-id="5152"
></path>
</svg>
</div>
</div>
</el-card>
<div
v-infinite-scroll="load"
class="infinite-list"
style="overflow: auto"
v-if="colorType == 1001"
>
<div class="barlist flx-row" v-for="i in listData" :key="i">
<div class="item-img">
<img src="../../assets/images/avart.jpg" alt="" />
</div>
<div class="item-left">
<div class="name">{{ i.createUser }}</div>
<div class="subname">{{ i.email }}</div>
</div>
<div class="item-left">
<div class="name">{{ i.title }}</div>
<div class="subname">{{ i.createTime }}发票已发出</div>
</div>
<div class="item-right">{{ i.number }}</div>
<div
class="item-state flx-row"
:style="{
backgroundColor:
i.pay_state == '1002'
? '#6C88D5'
: i.pay_state == '1003'
? '#fa4a1e'
: '#00AA5A',
}"
>
<span>{{
i.pay_state == '1001'
? '已支付'
: i.pay_state == '1002'
? '待支付'
: '未支付'
}}</span>
</div>
</div>
</div>
<el-row
class="mt10"
style="height: 75vh; overflow: auto"
v-infinite-scroll="load"
v-if="colorType == 1002"
>
<el-col :span="6" v-for="item in cardlist" :key="item" offset="1">
<el-card shadow="hover" class="card-lists">
<!-- <div
class="item-state-pos"
:style="{
backgroundColor:
item.pay_state == '1002'
? '#6C88D5'
: item.pay_state == '1003'
? '#fa4a1e'
: '#00AA5A',
}"
>
{{
item.pay_state == '1001'
? '已支付'
: item.pay_state == '1002'
? '待支付'
: '未支付'
}}
</div> -->
<div class="item-state-pos">
<el-icon><MoreFilled /></el-icon>
</div>
<div class="item-title">
<img src="../../assets/images/avart.jpg" alt="" />{{ item.title }}
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">发行日期</div>
<div class="cot-txt">{{ item.date }}</div>
</div>
<div class="cot">
<div class="cot-tit">客户姓名</div>
<div class="cot-txt">{{ item.user_name }}</div>
</div>
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">
金额 <span>{{ item.number }}</span>
</div>
</div>
<div class="cot">
<div class="cot-tit">
状态
<span
:class="[
item.pay_state == '1002'
? 'type suc-type'
: item.pay_state == '1003'
? 'type'
: 'type error-type',
]"
>{{
item.pay_state == '1001'
? '已支付'
: item.pay_state == '1002'
? '待支付'
: '未支付'
}}</span
>
</div>
</div>
</div>
<div class="item-content flx-row">
<div class="cot">
<div class="cot-tit">详情</div>
<div class="cot-txt one-cut-txt">{{ item.content }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</template>
<script setup>
import { ElMessage } from 'element-plus'
import { Newslist, cardlists } from '../../api/modules/index.js'
import { Search, Plus } from '@element-plus/icons-vue'
import { onMounted, ref } from 'vue'
const listData = ref([])
const cardlist = ref([])
const searchValue = ref('')
const colorType = ref('1001')
const load = () => {
if (colorType == '1002') {
cardlists().then((res) => {
cardlist.value = res.data.data
})
} else {
Newslist().then((res) => {
listData.value = listData.value.concat(res.data.data)
})
}
// count.value += 2
}
const getListData = () => {
Newslist().then((res) => {
listData.value = res.data.data
})
cardlists().then((res) => {
cardlist.value = res.data.data
})
}
const checkList = (type) => {
colorType.value = type
if (type == 1001) {
ElMessage({
message: '单列展示,切换成功!',
type: 'success',
})
} else {
ElMessage({
message: '多列展示,切换成功!',
type: 'success',
})
}
}
onMounted(() => {
getListData()
})
</script>
<style lang="scss" scoped>
.box-card {
width: 100%;
.box-card-title {
margin-bottom: 20px;
}
}
@import './index.scss';
</style>
+172
View File
@@ -0,0 +1,172 @@
<template>
<div id="main" style="width: 100%; height: 100%"></div>
</template>
<script setup name="GMVnearly">
import * as echarts from 'echarts'
import { onMounted } from 'vue'
const getEcharts = () => {
var chartDom = document.getElementById('main')
var myChart = echarts.init(chartDom)
const option = {
tooltip: {
//鼠标悬停时显示对应数据
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
title: {
text: '出入库情况',
top: '8px',
left: '10px',
bottom: '8px',
textStyle: {
color: '#191e24',
fontSize: '14',
},
},
legend: {
// 图例
data: ['出库', '入库'],
top: 8,
right: 16, // 修改位置
icon: 'circle', //原型
textStyle: {
color: '#191e2480', //字体颜色
},
},
grid: {
// 上下左右 边距
top: '8%',
left: '3%',
right: '3%',
bottom: '8%',
top: '15%',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisTick: { show: false },
data: [
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
],
axisLine: {
// 轴线的颜色以及宽度
lineStyle: {
color: '#A6A6A628',
},
},
axisLabel: {
// 轴文字的配置
show: true,
textStyle: {
color: '#191e2480',
},
},
splitLine: {
// 分割线配置
lineStyle: {
color: '#A6A6A628',
// type: "dashed", // 虚线
},
},
},
],
yAxis: [
{
min: 0, // 最小值
max: 500, //最大值
// splitNumber: 3, //划分3格
type: 'value',
axisLine: {
// 轴线的颜色以及宽度
show: false,
},
axisLabel: {
// 轴文字的配置
show: true,
// textStyle: {
// color: "#fff",
// },
},
splitLine: {
// 分割线配置
lineStyle: {
color: '#A6A6A628',
// type: "dashed",
},
},
},
],
series: [
{
name: '出库',
type: 'bar',
barWidth: 10, // 柱图宽度
barGap: '30%',
// label: labelOption,
emphasis: {
focus: 'series',
},
data: [320, 332, 401, 334, 390, 320, 332, 301, 334, 390, 320, 332],
// ↓ 这里可以改变渐变色的方向
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: '#6E48E6',
},
{
offset: 1,
color: '#3AA6FA ',
},
]),
},
{
name: '入库',
type: 'bar',
barWidth: 10, // 柱图宽度
// label: labelOption,
emphasis: {
focus: 'series',
},
data: [220, 182, 191, 234, 290, 220, 182, 191, 234, 290, 220, 182],
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: '#9DDD92',
},
{
offset: 1,
color: '#10BFAA',
},
]),
},
],
}
option && myChart.setOption(option)
window.onresize = () => {
myChart.resize()
}
}
onMounted(() => {
setTimeout(() => {
getEcharts()
}, 1000)
})
</script>
+149
View File
@@ -0,0 +1,149 @@
<template>
<div id="linenearly" style="width: 100%; height: 100%"></div>
</template>
<script setup name="GMVnearly">
import * as echarts from 'echarts'
import { onMounted } from 'vue'
const getEcharts = () => {
var chartDom = document.getElementById('linenearly')
var myChart = echarts.init(chartDom)
const option = {
tooltip: {
//鼠标悬停时显示对应数据
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
color: ['#87A2E8FF', '#74CCCCFF'],
title: {
text: '近一年的DAU/DNU',
top: '8px',
left: '10px',
bottom: '8px',
textStyle: {
color: '#191e24',
fontSize: '14',
},
},
legend: {
// 图例
data: ['DAU', 'DNU'],
top: 8,
right: 16, // 修改位置
icon: 'circle', //原型
textStyle: {
color: '#191e2480', //字体颜色
},
},
grid: {
// 上下左右 边距
top: '8%',
left: '3%',
right: '3%',
bottom: '8%',
top: '15%',
containLabel: true,
},
xAxis: [
{
type: 'category',
axisTick: { show: false },
data: [
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
],
axisLine: {
// 轴线的颜色以及宽度
lineStyle: {
color: '#A6A6A628',
},
},
axisLabel: {
// 轴文字的配置
show: true,
textStyle: {
color: '#191e2480',
},
},
splitLine: {
// 分割线配置
lineStyle: {
color: '#A6A6A628',
// type: "dashed", // 虚线
},
},
},
],
yAxis: [
{
min: 0, // 最小值
// splitNumber: 3, //划分3格
type: 'value',
axisLine: {
// 轴线的颜色以及宽度
show: false,
},
axisLabel: {
// 轴文字的配置
show: true,
// textStyle: {
// color: "#fff",
// },
},
splitLine: {
// 分割线配置
lineStyle: {
color: '#A6A6A628',
// type: "dashed",
},
},
},
],
series: [
{
name: 'DAU',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [120, 132, 101, 134, 90, 230, 210, 134, 90, 230, 210, 230],
},
{
name: 'DNU',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series',
},
data: [120, 132, 101, 134, 90, 230, 210, 134, 90, 230, 210, 290],
},
],
}
option && myChart.setOption(option)
window.onresize = () => {
myChart.resize()
}
}
onMounted(() => {
setTimeout(() => {
getEcharts()
}, 1000)
})
</script>
+303
View File
@@ -0,0 +1,303 @@
<template>
<el-row class="data-lists">
<el-col :span="9" :class="{ shake: disabled }"
><div class="data-item-one flx-row">
<div class="item-left">
<img src="../../assets/home.png" alt="" srcset="" />
</div>
<div class="item-right">
<div class="item-right-top">
<div class="tit">本期活动GMX</div>
<div class="num">1523.53w</div>
</div>
<div class="line"></div>
<div class="item-right-bottom flx-row">
<div class="item">
<div class="tit">类目一</div>
<div class="num">53w</div>
</div>
<div class="item">
<div class="tit">类目一</div>
<div class="num">53w</div>
</div>
<div class="item">
<div class="tit">类目一</div>
<div class="num">53w</div>
</div>
</div>
</div>
</div></el-col
>
<el-col :span="9" :class="{ shake: disabled }"
><div class="data-item-two">
<div class="item">
<div class="item-des flx-row">
<img src="../../assets/icon1.png" alt="" />
<div class="right">
<div class="num">934.7w <span>29.74</span></div>
<div class="txt">今日DAU</div>
</div>
</div>
</div>
<div class="item">
<div class="item-des flx-row" style="margin-right: 0px">
<img src="../../assets/icon2.png" alt="" />
<div class="right">
<div class="num">264.7w <span>29.74</span></div>
<div class="txt">今日DAU</div>
</div>
</div>
</div>
<div class="item">
<div class="item-des flx-row">
<div class="right border-right-1px">
<div class="num">24.93w</div>
<div class="txt">今日DAU</div>
</div>
<div class="right">
<div class="num">984.52w</div>
<div class="txt">总用户数</div>
</div>
</div>
</div>
<div class="item">
<div class="item-des flx-row" style="margin-right: 0px">
<div class="right border-right-1px">
<div class="num">84.52w</div>
<div class="txt">GPS</div>
</div>
<div class="right">
<div class="num">84.52w</div>
<div class="txt">特权</div>
</div>
</div>
</div>
</div></el-col
>
<el-col :span="6" :class="{ shakeRight: disabled }">
<div class="data-item-three">
<div class="tit">待处理</div>
<div class="content">
<div class="item">
<div class="item-data">
<div class="tit">退款申请</div>
<div class="num">89 <span></span></div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">退款申请</div>
<div class="num">89 <span></span></div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">退款申请</div>
<div class="num">89 <span></span></div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">退款申请</div>
<div class="num">89 <span></span></div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
</div>
</div>
</el-col>
</el-row>
<el-row class="dataLayer">
<el-col :span="18">
<div class="flx-row">
<div class="datalayer-echarts" :class="{ shake: disabled }">
<GMVnearly></GMVnearly>
</div>
<div class="datalayer-echarts" :class="{ shake: disabled }">
<linenearly></linenearly>
</div>
</div>
<div class="table-data" :class="{ shake: disabled }">
<div class="tit">主题页列表</div>
<div class="table-box">
<el-table
:data="tableData"
:header-cell-style="{
background: '#FAFBFDFF',
fontWeight: '400',
fontSize: '14px',
padding: '0',
fontHeight: '36px',
height: '36px',
}"
:row-style="{
fontWeight: '400',
fontSize: '14px',
padding: '0',
fontHeight: '44px',
height: '44px',
}"
>
<el-table-column
v-for="item in options"
:key="item.type"
:prop="item.props"
:label="item.label"
:width="item.width"
:align="item.align"
show-overflow-tooltip
:fixed="item.fixed"
>
<template v-slot:default="scope" v-if="item.props === 'type'">
<span class="type" v-if="scope.row[item.props] == true"
>外部链接</span
>
<span
class="type error-type"
v-if="scope.row[item.props] == false"
>内部链接</span
>
</template>
<template v-slot:default="scope" v-if="item.props === 'state'">
<span v-if="scope.row[item.props] == true">
<i class="state"></i>已上线</span
>
<span v-if="scope.row[item.props] == false">
<i class="state error-state"></i>已下线</span
>
</template>
<template v-slot:default="scope" v-if="item.props === 'actions'">
<el-icon class="icon-edit" @click="editorClick(scope.row)"
><Edit
/></el-icon>
<el-popconfirm
confirm-button-text="确认"
cancel-button-text="取消"
:icon="InfoFilled"
icon-color="#626AEF"
title="确认删除该主题?"
@confirm="DeleteItem(index)"
>
<template #reference>
<el-icon class="icon-dele"><Delete /></el-icon>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="data-item-three" :class="{ shakeRight: disabled }">
<div class="tit">常用功能</div>
<div class="content">
<div class="item">
<div class="item-data flx-row">
<div class="tit">
<el-icon><Histogram /></el-icon>订单列表
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data flx-row">
<div class="tit">
<el-icon><Avatar /></el-icon>用户列表
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">
<el-icon><HomeFilled /></el-icon>首页配置
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">
<el-icon><PictureFilled /></el-icon>主题配置
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">
<el-icon><Menu /></el-icon>活动管理
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
<div class="item">
<div class="item-data">
<div class="tit">
<el-icon><Tools /></el-icon>退款申请
</div>
<el-icon class="icon"><ArrowRight /></el-icon>
</div>
</div>
</div>
</div>
<div class="notice">
<div class="notice-news">
<img src="../../assets/homebg.jpeg" alt="" />
<div class="txt one-cut-txt">
查看更多查看更多查看更多查看更查看更多查看更多查看更多查看更
</div>
</div>
</div>
<div class="data-item-three" :class="{ shakeRight: disabled }">
<div class="tit">公告栏</div>
<div class="notice-lists">
<div class="item one-cut-txt" v-for="item in notList" :key="item.id">
<span class="type">通知</span> {{ item.text }}
</div>
</div>
</div>
</el-col>
</el-row>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import GMVnearly from './components/GMVnearly.vue'
import linenearly from './components/linenearly.vue'
import { options } from './options.js'
import { homeList, noticeLists } from '../../api/modules/index.js'
const tableData = ref([])
const notList = ref([])
const disabled = ref(false)
const DeleteItem = (index) => {
tableData.value.splice(index, 1)
}
const initData = () => {
homeList().then((res) => {
tableData.value = res.data.data
})
noticeLists().then((res) => {
notList.value = res.data.data
})
}
onMounted(() => {
initData()
disabled.value = true
setTimeout(() => {
disabled.value = false
}, 1500)
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
+390
View File
@@ -0,0 +1,390 @@
.data-lists {
width: 100%;
.el-col {
height: 100%;
}
.data-item-one {
background: #2969ff;
margin-right: 10px;
padding: 10px;
height: 156px;
border-radius: 6px;
color: #fff;
.item-left {}
.item-right {
padding-left: 20px;
padding-right: 10px;
flex: 1;
.item-right-top {
margin-bottom: 10px;
.tit {
padding-bottom: 5px;
}
.num {
font-size: 24px;
font-weight: 700;
text-align: left;
}
}
.line {
width: 100%;
height: 2px;
background-color: #fff;
opacity: 0.1;
}
.item-right-bottom {
margin-top: 10px;
.item {
flex: 1;
.tit {
font-size: 14px;
padding-bottom: 5px;
}
.num {
font-size: 18px;
font-weight: bold;
}
}
}
}
}
.data-item-two {
height: 176px;
margin-right: 10px;
display: flex;
flex-wrap: wrap;
.item {
height: 50%;
width: 50%;
.item-des {
margin-right: 8px;
margin-bottom: 8px;
background-color: #fff;
padding: 20px;
border-radius: 6px;
&:nth-child(2n) {
margin-right: 0px;
}
.right {
flex: 1;
padding-left: 22px;
.num {
font-size: 18px;
font-weight: 700;
letter-spacing: 0px;
span {
font-size: 12px;
color: rgba(30, 189, 94, 1);
}
}
.txt {
padding-top: 8px;
font-size: 12px;
font-weight: 400;
color: rgba(0, 0, 0, 0.3);
}
}
}
}
}
.data-item-three {
padding: 10px;
height: 156px;
margin-bottom: 10px;
background-color: #fff;
border-radius: 6px;
.tit {
font-size: 14px;
padding-bottom: 5px;
}
.content {
display: flex;
flex-wrap: wrap;
.item {
width: 50%;
height: 50%;
.item-data {
margin: 5px;
opacity: 1;
padding: 10px;
border-radius: 6px;
background: #fafafcff;
position: relative;
.icon {
position: absolute;
right: 16px;
top: 40%;
color: rgba(25, 30, 36, 0.5);
font-size: 14px;
}
.tit {
font-size: 12px;
font-weight: 400;
color: rgba(25, 30, 36, 0.5);
padding-bottom: 5px;
}
.num {
color: #0052d9;
font-size: 14px;
font-weight: 700;
span {
color: #666;
font-weight: 400;
color: rgba(25, 30, 36, 0.5);
}
}
}
}
}
}
}
.dataLayer {
.datalayer-echarts {
flex: 1;
height: 260px;
margin-right: 10px;
margin-bottom: 10px;
background-color: #fff;
border-radius: 6px;
}
.table-data {
border-radius: 6px;
margin-right: 10px;
background-color: #fff;
padding-bottom: 10px;
.tit {
padding: 10px 10px 0 10px;
font-size: 14px;
font-weight: bold;
letter-spacing: 1px;
}
.table-box {
margin: 10px;
.el-table {
width: 100%;
height: 360px;
.type {
font-size: 10px;
padding: 5px 10px;
font-weight: 500;
line-height: 0px;
color: #fa4a1e;
text-align: left;
border-radius: 6px;
background: #fa4a1e14;
&.error-type {
color: #4060c7;
background: #e8f3ff;
}
}
.state {
display: inline-block;
width: 8px;
height: 8px;
background-color: #4060c7;
border-radius: 50%;
margin-right: 5px;
&.error-state {
background-color: #fa4a1e;
}
}
}
}
}
.data-item-three {
padding: 10px;
// height: 156px;
margin-bottom: 10px;
background-color: #fff;
border-radius: 6px;
.tit {
font-size: 14px;
padding-bottom: 5px;
}
.content {
display: flex;
flex-wrap: wrap;
.item {
width: 50%;
height: 50%;
.item-data {
margin: 5px;
opacity: 1;
padding: 10px;
border-radius: 6px;
background: #fafafcff;
position: relative;
align-items: center;
.icon {
position: absolute;
right: 16px;
top: 40%;
color: rgba(25, 30, 36, 0.5);
font-size: 14px;
}
.tit {
font-size: 12px;
font-weight: 400;
color: rgba(25, 30, 36, 0.5);
padding-bottom: 5px;
display: flex;
align-items: center;
.el-icon {
font-size: 20px;
color: rgba(25, 30, 36, 0.5);
margin-right: 5px;
}
}
}
}
}
}
.notice {
width: 100%;
height: 152px;
background-color: #fff;
border-radius: 6px;
overflow: hidden;
margin-bottom: 10px;
.notice-news {
width: 100%;
height: 100%;
position: relative;
img {
width: 100%;
object-fit: cover;
}
.txt {
position: absolute;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.3);
font-size: 14px;
color: #fff;
padding: 10px;
}
}
}
.notice-lists {
height: 260px;
overflow: scroll;
.item {
font-size: 14px;
padding: 10px;
color: #666;
.type {
font-size: 10px;
padding: 5px 10px;
font-weight: 500;
line-height: 0px;
color: #fa4a1e;
text-align: left;
border-radius: 6px;
background: #fa4a1e14;
&.error-type {
color: #4060c7;
background: #e8f3ff;
}
}
}
}
}
.border-right-1px {
border-right: 1px solid #eae3e3;
}
.icon-edit {
font-size: 20px;
color: #2f60c2;
margin: 0 10px;
}
.icon-dele {
font-size: 20px;
color: #ff5722;
}
.shake {
animation: shake 0.5s linear;
}
.shakeRight {
animation: shakeRight 0.5s linear;
}
@keyframes shake {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes shakeRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
+9
View File
@@ -0,0 +1,9 @@
<template>
<el-card>
<div>欢迎使用💐🌸💮🏵🌹🌺🌻</div>
</el-card>
</template>
<script setup></script>
<style lang="scss" scoped></style>
+82
View File
@@ -0,0 +1,82 @@
export const options = [
{
label: "名称",
props: "name",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "主题页id",
props: "title_id",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "类型",
props: "type",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "商品数",
props: "number",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "总订单数",
props: "order_number",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "今日GMV",
props: "GWV_number",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "状态",
props: "state",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "操作",
props: "actions",
width: "auto",
align: "left",
show: true,
fixed: "right",
itemEdit: "itemEdit",
sortable: false,
},
];
+99
View File
@@ -0,0 +1,99 @@
.login-container {
width: 100vw;
height: 100vh;
// background-color: #6c88d5;
background-image: url('../../assets/bg.png');
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
.login-box {
width: 96%;
height: 94%;
background-color: hsla(0, 0%, 100%, 0.85);
border-radius: 10px;
padding: 0 8% 0 50px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-around;
.login-left {
width: 800px;
color: #6E736FFF;
.title {
font-size: 48px;
font-weight: 400;
letter-spacing: 0px;
color: rgba(47, 57, 78, 1);
text-align: left;
}
img {
width: 735px;
height: 465px;
}
}
.login-form {
width: 400px;
height: 260px;
padding: 10px 40px 35px 40px;
border-radius: 10px;
-webkit-box-shadow: 2px 3px 7px rgb(0 0 0 / 20%);
box-shadow: 2px 3px 7px rgb(0 0 0 / 20%);
.login-logo {
display: flex;
align-items: center;
justify-content: center;
// margin-bottom: 45px;
.login-icon {
width: 60px;
// height: 52px;
}
.logo-text {
font-weight: bold;
font-size: 32px;
padding-left: 25px;
white-space: nowrap;
color: #2d51e6;
}
}
.el-form-item {
margin-bottom: 20px;
}
.flx-row {
span {
font-size: 14px;
color: #2d51e6;
}
.img {
flex: 1;
text-align: center;
}
}
.login-btn {
margin-top: 20px;
padding-bottom: 20px;
display: flex;
justify-content: space-between;
width: 100%;
white-space: nowrap;
.el-button {
width: 185px;
}
}
}
}
}
+221
View File
@@ -0,0 +1,221 @@
<template>
<div class="login-container flx-center">
<div class="login-box">
<div class="login-left">
<div class="title">后台数据管理模板</div>
<div class="sub">后台数据管理</div>
<img src="../../assets/login.png" alt="" />
</div>
<div class="login-form">
<div class="login-logo">
<img class="login-icon" src="../../assets/logo.png" alt="" />
<p class="logo-text">欢迎登录</p>
</div>
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" size="large">
<el-form-item prop="username">
<el-input
:prefix-icon="User"
v-model="loginForm.username"
placeholder="用户名"
>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
:prefix-icon="Lock"
type="password"
show-password
v-model="loginForm.password"
placeholder="密码"
>
</el-input>
</el-form-item>
<!-- <div class="flx-row">
<el-checkbox
style="flex: 1"
v-model="loginForm.checked"
label="记住我"
size="large"
/>
<span>忘记密码</span>
</div> -->
</el-form>
<div class="login-btn">
<el-button
:icon="CircleClose"
round
@click="resetForm(loginFormRef)"
size="large"
>重置</el-button
>
<el-button
:icon="UserFilled"
round
@click="login(loginFormRef)"
size="large"
type="primary"
:loading="loading"
>
登录
</el-button>
</div>
<!-- <el-divider>其他方式登录 </el-divider>
<div class="flx-row">
<span class="img"
><svg
focusable="false"
class=""
data-icon="github"
width="25px"
height="25px"
fill="#888888"
aria-hidden="true"
viewBox="64 64 896 896"
>
<path
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
></path></svg></span
><span class="img"
><svg
focusable="false"
class=""
data-icon="wechat"
width="25px"
height="25px"
fill="#888888"
aria-hidden="true"
viewBox="64 64 896 896"
>
<path
d="M690.1 377.4c5.9 0 11.8.2 17.6.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6a21.5 21.5 0 019.1 17.6c0 2.4-.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-.1 17.8-.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8zm-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1zm-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1zm586.8 415.6c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7a9 9 0 006.4-2.6 9 9 0 002.6-6.4c0-2.2-.9-4.4-1.4-6.6-.3-1.2-7.6-28.3-12.2-45.3-.5-1.9-.9-3.8-.9-5.7.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9zm179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9a36.08 36.08 0 01-36 35.9z"
></path></svg></span
><span class="img"
><svg
focusable="false"
class=""
data-icon="alipay-circle"
width="25px"
height="25px"
fill="#888888"
aria-hidden="true"
viewBox="64 64 896 896"
>
<path
d="M308.6 545.7c-19.8 2-57.1 10.7-77.4 28.6-61 53-24.5 150 99 150 71.8 0 143.5-45.7 199.8-119-80.2-38.9-148.1-66.8-221.4-59.6zm460.5 67c100.1 33.4 154.7 43 166.7 44.8A445.9 445.9 0 00960 512c0-247.4-200.6-448-448-448S64 264.6 64 512s200.6 448 448 448c155.9 0 293.2-79.7 373.5-200.5-75.6-29.8-213.6-85-286.8-120.1-69.9 85.7-160.1 137.8-253.7 137.8-158.4 0-212.1-138.1-137.2-229 16.3-19.8 44.2-38.7 87.3-49.4 67.5-16.5 175 10.3 275.7 43.4 18.1-33.3 33.4-69.9 44.7-108.9H305.1V402h160v-56.2H271.3v-31.3h193.8v-80.1s0-13.5 13.7-13.5H557v93.6h191.7v31.3H557.1V402h156.4c-15 61.1-37.7 117.4-66.2 166.8 47.5 17.1 90.1 33.3 121.8 43.9z"
></path></svg></span
><span class="img"
><svg
focusable="false"
class=""
data-icon="google-circle"
width="25px"
height="25px"
fill="#888888"
aria-hidden="true"
viewBox="64 64 896 896"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm167 633.6C638.4 735 583 757 516.9 757c-95.7 0-178.5-54.9-218.8-134.9C281.5 589 272 551.6 272 512s9.5-77 26.1-110.1c40.3-80.1 123.1-135 218.8-135 66 0 121.4 24.3 163.9 63.8L610.6 401c-25.4-24.3-57.7-36.6-93.6-36.6-63.8 0-117.8 43.1-137.1 101-4.9 14.7-7.7 30.4-7.7 46.6s2.8 31.9 7.7 46.6c19.3 57.9 73.3 101 137 101 33 0 61-8.7 82.9-23.4 26-17.4 43.2-43.3 48.9-74H516.9v-94.8h230.7c2.9 16.1 4.4 32.8 4.4 50.1 0 74.7-26.7 137.4-73 180.1z"
></path></svg></span
><span class="img"
><svg
focusable="false"
class=""
data-icon="twitter-circle"
width="25px"
height="25px"
fill="#888888"
aria-hidden="true"
viewBox="64 64 896 896"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm215.3 337.7c.3 4.7.3 9.6.3 14.4 0 146.8-111.8 315.9-316.1 315.9-63 0-121.4-18.3-170.6-49.8 9 1 17.6 1.4 26.8 1.4 52 0 99.8-17.6 137.9-47.4-48.8-1-89.8-33-103.8-77 17.1 2.5 32.5 2.5 50.1-2a111 111 0 01-88.9-109v-1.4c14.7 8.3 32 13.4 50.1 14.1a111.13 111.13 0 01-49.5-92.4c0-20.7 5.4-39.6 15.1-56a315.28 315.28 0 00229 116.1C492 353.1 548.4 292 616.2 292c32 0 60.8 13.4 81.1 35 25.1-4.7 49.1-14.1 70.5-26.7-8.3 25.7-25.7 47.4-48.8 61.1 22.4-2.4 44-8.6 64-17.3-15.1 22.2-34 41.9-55.7 57.6z"
></path></svg
></span>
</div> -->
</div>
</div>
</div>
</template>
<script setup name="login">
import axios from "axios";
import { useStore } from "vuex"; // 引入useStore 方法
import { CircleClose, UserFilled, Lock, User, Iphone } from "@element-plus/icons-vue";
import { Base64 } from "js-base64";
import { reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
const loginFormRef = ref();
const loading = ref(false);
const router = useRouter();
const loginForm = reactive({
username: "",
password: "",
checked: false,
});
const loginRules = reactive({
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
});
const globalStore = useStore(); // 该方法用于返回store 实例
const login = (formEl) => {
if (!formEl) return;
formEl.validate((valid) => {
if (valid) {
loading.value = true;
console.log(globalStore);
if (loginForm.checked) {
let password = Base64.encode(loginForm.password); // base64加密
setCookie(loginForm.username, password, 7);
} else {
setCookie("", "", -1);
}
globalStore.dispatch("user/login", loginForm);
} else {
console.log("error submit!");
return false;
}
});
};
const setCookie = (userId, password, days) => {
let date = new Date(); // 获取时间
date.setTime(date.getTime() + 24 * 60 * 60 * 1000 * days); // 保存的天数
// 字符串拼接cookie
window.document.cookie =
"userId" + "=" + userId + ";path=/;expires=" + date.toGMTString();
window.document.cookie =
"password" + "=" + password + ";path=/;expires=" + date.toGMTString();
};
// 读取cookie 将用户名和密码回显到input框中
const getCookie = () => {
if (document.cookie.length > 0) {
let arr = document.cookie.split("; "); //分割成一个个独立的“key=value”的形式
for (let i = 0; i < arr.length; i++) {
let arr2 = arr[i].split("="); // 再次切割,arr2[0]为key值,arr2[1]为对应的value
if (arr2[0] === "userId") {
loginForm.username = arr2[1];
} else if (arr2[0] === "password") {
loginForm.password = Base64.decode(arr2[1]); // base64解密
loginForm.checked = true;
}
}
}
};
const resetForm = (formEl) => {
if (!formEl) return;
formEl.resetFields();
};
</script>
<style scoped lang="scss">
@import "./index.scss";
</style>
+29
View File
@@ -0,0 +1,29 @@
.el-row {
margin-bottom: 20px;
}
.el-row:last-child {
margin-bottom: 0;
}
.el-col {
border-radius: 4px;
background-color: #fff;
/* margin-right: 20px; */
height: 100%;
}
.material-header {
padding: 10px;
color: #666;
border-bottom: 2px solid #f0f2f5;
.tit {
flex: 1;
}
}
.material-content {
padding: 10px;
}
+29
View File
@@ -0,0 +1,29 @@
<template>
<el-row style="height: 90vh">
<el-col :span="6" style="border-right: 10px solid #f0f2f5">
<div class="material-header flx-row">
<div class="tit">目录</div>
<div>
<el-icon><MoreFilled /></el-icon>
</div>
</div>
</el-col>
<el-col :span="18">
<div class="material-header flx-row">
<div class="tit">我的文件</div>
<div>
<el-icon><MoreFilled /></el-icon>
</div>
</div>
<div class="material-content">
<div class="flx-row">
<div class="item"></div>
</div>
</div>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
@import './index.scss';
</style>
+297
View File
@@ -0,0 +1,297 @@
<template>
<el-card shadow="never" class="henader-card">
<div class="flx-row">
<el-form :inline="true" :model="queryData" style="flex: 1">
<el-input placeholder="请输入搜索内容" v-model="queryData.keyWord">
</el-input>
<el-date-picker
class="ml20"
v-model="queryData.date"
type="datetimerange"
:shortcuts="shortcuts"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</el-form>
<div class="flex-right">
<el-button type="primary" :icon="Search" @click="initData" class="ml20"
>搜索</el-button
>
<el-button type="primary" @click="dialogVisibleShow">+添加</el-button>
</div>
</div>
</el-card>
<el-card shadow="never">
<el-table
:data="tableData"
:header-cell-style="{ backgroundColor: '#ecf5ff' }"
border
stripe
style="width: 100%"
>
<el-table-column
v-for="item in options"
:key="item.type"
:prop="item.props"
:label="item.label"
:width="item.width"
:align="item.align"
show-overflow-tooltip
:fixed="item.fixed"
>
<template v-slot:default="scope" v-if="item.props === 'actions'">
<el-icon class="icon-view" @click="ItemView(scope.row)"
><View
/></el-icon>
<el-icon class="icon-edit" @click="editorClick(scope.row)"
><Edit
/></el-icon>
<el-popconfirm
confirm-button-text="确认"
cancel-button-text="取消"
:icon="InfoFilled"
icon-color="#626AEF"
title="确认删除该用户?"
@confirm="DeleteItem(index)"
>
<template #reference>
<el-icon class="icon-dele"><Delete /></el-icon>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination
small
background
:page-size="queryData.size"
layout="prev, pager, next"
:total="total"
class="mt-4"
@current-change="handleCurrentChange"
/>
</el-card>
<el-dialog
v-model="dialogVisible"
:title="`${dialogData.title}用户`"
:width="dialogWidth"
:hide-required-asterisk="dialogData.isView"
draggable
>
<el-form
:model="dialogData.FormData"
:rules="rules"
ref="FormRef"
class="demo-ruleForm"
>
<el-form-item
label="用户名"
:label-width="formLabelWidth"
prop="username"
>
<el-input v-model="dialogData.FormData.username" autocomplete="off" />
</el-form-item>
<el-form-item label="邮箱" :label-width="formLabelWidth" prop="email">
<el-input v-model="dialogData.FormData.email" autocomplete="off" />
</el-form-item>
<el-form-item label="地址" :label-width="formLabelWidth" prop="address">
<el-input v-model="dialogData.FormData.address" type="textarea" />
</el-form-item>
<el-form-item label="备注" :label-width="formLabelWidth" prop="content">
<el-input v-model="dialogData.FormData.content" type="textarea" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="onSubmit()">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {
Search,
Edit,
Delete,
UserFilled,
InfoFilled,
View,
} from '@element-plus/icons-vue'
import {
getUserList,
addUserList,
listUpdate,
} from '../../../api/modules/index.js'
import { options } from './options.js'
import { onMounted, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { getDateTime } from '../../../utils/index.js'
const queryData = ref({
keyWord: '',
page: 1,
size: 10,
})
const FormRef = ref()
const formLabelWidth = '140px'
const dialogData = reactive({
isView: true,
title: '添加',
FormData: {
username: '',
email: '',
address: '',
content: '',
},
})
const dialogWidth = ref('0')
const rules = reactive({
username: [{ required: true, message: '请填写用户姓名', trigger: 'change' }],
email: [{ required: true, message: '请填写邮箱', trigger: 'change' }],
address: [{ required: true, message: '请填写居住地址', trigger: 'change' }],
content: [{ required: true, message: '请填写备注信息', trigger: 'change' }],
})
const oldTableData = ref([])
const dialogVisible = ref(false)
const tableData = ref([])
const total = ref(0)
const initData = () => {
getUserList(queryData.value).then((res) => {
total.value = res.data.data.total
tableData.value = res.data.data.userList
})
}
const dialogVisibleShow = () => {
dialogData.FormData = {
username: '',
email: '',
address: '',
content: '',
}
dialogVisible.value = true
}
const onSubmit = () => {
FormRef.value.validate(async (valid) => {
if (!valid) return
try {
if (dialogData.FormData.id) {
listUpdate(dialogData.FormData).then((res) => {
console.log('编辑数据成功')
console.log(ElMessage)
ElMessage({
message: '编辑用户成功',
type: 'success',
})
tableData.value = res.data.data
})
} else {
dialogData.FormData.date = getDateTime('')
addUserList(dialogData.FormData)
.then((res) => {
ElMessage({
message: '添加用户成功',
type: 'success',
})
dialogData.FormData.id = res.data.data.id
tableData.value.unshift(dialogData.FormData)
})
.catch((err) => {})
}
dialogVisible.value = false
} catch (error) {
console.log(error)
}
})
}
const handleCurrentChange = (val) => {
queryData.value.page = val
initData(queryData.value)
}
const editorClick = (item) => {
dialogVisible.value = true
dialogData.FormData = item
console.log(dialogData.FormData)
dialogData.isView = false
dialogData.title = '编辑'
}
const ItemView = (item) => {
dialogVisible.value = true
dialogData.FormData = item
dialogData.isView = false
dialogData.title = ''
}
const DeleteItem = (index) => {
console.log(index)
tableData.value.splice(index, 1)
}
const cancelEvent = () => {
console.log('cancel!')
}
const setDialogWidth = () => {
console.log(document.body.clientWidth)
var val = document.body.clientWidth
const def = 800 // 默认宽度
if (val < def) {
dialogWidth.value = '100%'
} else {
dialogWidth.value = def + 'px'
}
}
onMounted(() => {
setDialogWidth()
window.onresize = () => {
return (() => {
setDialogWidth()
})()
}
initData()
})
</script>
<style lang="scss" scoped>
.henader-card {
margin-bottom: 20px;
}
.icon-view {
font-size: 20px;
color: #673ab7;
margin: 0 10px;
}
.icon-edit {
font-size: 20px;
color: #2f60c2;
margin: 0 10px;
}
.icon-dele {
font-size: 20px;
color: #ff5722;
}
.mt-4 {
float: right;
text-align: right;
margin-top: 20px;
margin-bottom: 20px;
}
.el-button--text {
margin-right: 15px;
}
.el-select {
width: 300px;
}
.el-input {
width: 300px;
}
.dialog-footer button:first-child {
margin-right: 10px;
}
</style>
+39
View File
@@ -0,0 +1,39 @@
export const options = [{
label: '用户名',
props: 'username',
width: 'auto',
align: 'left'
},
{
label: '邮箱',
props: 'email',
width: 'auto',
align: 'left'
},
{
label: '创建时间',
props: 'date',
width: 'auto',
align: 'left'
},
{
label: '地址',
props: 'address',
width: 'auto',
align: 'left'
},
{
label: '备注',
props: 'content',
width: 'auto',
align: 'left',
show: true
},
{
label: '操作',
props: 'actions',
width: '150',
align: 'center',
fixed: 'right',
}
]
+34
View File
@@ -0,0 +1,34 @@
<template>
<el-card>
<el-button type="primary" @click="importExcel">导入Excel</el-button>
</el-card>
<filesUpload ref="importRef" @gatewayData="gatewayData"></filesUpload>
<el-card class="mt10">
<el-table :data="tableData" border size="small"></el-table>
</el-card>
</template>
<script setup>
import { ref } from 'vue'
// import XLSX from 'xlsx'
import filesUpload from '../../../components/filesUpload.vue'
const importRef = ref('')
const tableData = ref([])
const importExcel = () => {
let params = {}
importRef.value.acceptParams(params)
console.log(importRef.value.acceptParams(params))
}
const gatewayData = (params) => {
console.log(params)
}
</script>
<style lang="scss" scoped>
.mt-4 {
float: right;
text-align: right;
margin-bottom: 20px;
}
</style>
+248
View File
@@ -0,0 +1,248 @@
<template>
<el-card>
<el-button type="primary" class="mt-4" @click="dialogVisibleHanle"
>编辑表格</el-button
>
</el-card>
<el-card class="mt10">
<el-table
:data="tableData"
:header-cell-style="{ backgroundColor: '#ecf5ff' }"
border
stripe
style="width: 100%"
>
<el-table-column
v-for="item in columnData"
:key="item.props"
:prop="item.props"
:label="item.label"
:width="item.width"
v-show="item.show"
:fixed="item.fixed"
:align="item.align"
show-overflow-tooltip
></el-table-column>
</el-table>
<el-pagination
class="mt10 mt-4"
v-model:currentPage="queryData.page"
v-model:page-size="queryData.size"
:page-sizes="[10]"
:disabled="disabled"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
<el-dialog
v-model="dialogVisible"
title="编辑列表"
width="80%"
:before-close="handleClose"
>
<el-table
class="t1"
row-key="id"
ref="dragTable"
:data="tableDialog"
:row-class-name="tableRowClassName"
:header-cell-style="{ backgroundColor: '#ecf5ff' }"
border
stripe
style="width: 100%"
>
<el-table-column
v-for="item in DialogColumn"
:key="item.props"
:prop="item.props"
:label="item.label"
>
<template v-slot:default="scope" v-if="item.props === 'label'">
<el-input v-model.trim="scope.row.label"></el-input>
</template>
<template v-slot:default="scope" v-if="item.props === 'width'">
<el-input v-model.trim="scope.row.width"></el-input>
</template>
<template v-slot:default="scope" v-if="item.props === 'align'">
<el-select
v-model="scope.row[scope.column.property]"
placeholder="Select"
>
<el-option
v-for="i in optionsType"
:key="i.value"
:label="i.label"
:value="i.value"
/>
</el-select>
</template>
<template v-slot:default="scope" v-if="item.props === 'show'">
<el-switch v-model="scope.row.show" />
</template>
<template v-slot:default="scope" v-if="item.props === 'fiexd'">
<el-select v-model="scope.row.fixed" placeholder="Select">
<el-option
v-for="i in fiexdType"
:key="i.value"
:label="i.label"
:value="i.value"
/>
</el-select>
</template>
</el-table-column>
</el-table>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogSubmit">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { nextTick, onMounted, reactive, ref } from 'vue'
import { getUserList } from '../../../api/modules/index.js'
import { options } from './options.js'
import Sortable from 'sortablejs'
const tableData = ref([])
const id = ref('')
const tableDialog = ref([])
const optionsType = ref([
{ value: 'left', label: '右对齐' },
{ value: 'right', label: '左对齐' },
{ value: 'center', label: '居中' },
])
const fiexdType = ref([
{ value: true, label: '是' },
{ value: false, label: '否' },
])
const DialogColumn = ref([
{
label: '表头',
props: 'label',
},
{
label: '对应列的宽度',
props: 'width',
},
{
label: '对齐方式',
props: 'align',
},
{
label: '是否显示',
props: 'show',
},
{
label: '列是否固定',
props: 'fiexd',
},
])
const columnData = ref(JSON.parse(JSON.stringify(options)))
const disabled = ref(false)
const dialogVisible = ref(false)
const total = ref(0)
const queryData = ref({
keyWord: '',
page: 1,
size: 10,
})
const initData = () => {
getUserList(queryData.value).then((res) => {
total.value = res.data.data.total
tableData.value = res.data.data.userList
})
}
const handleSizeChange = (val) => {
console.log(val)
}
const handleCurrentChange = (val) => {
queryData.value.page = val
initData(queryData.value)
}
const handleClose = () => {}
const dialogVisibleHanle = () => {
console.log(tableData.value)
console.log(columnData)
tableDialog.value = columnData.value
console.log(tableDialog.value)
dialogVisible.value = true
nextTick(() => {
initSortable('t1')
})
}
const dialogSubmit = () => {
console.log(tableDialog.value)
dialogVisible.value = false
console.log(columnData.value)
}
onMounted(() => {
console.log(columnData.value)
initData()
})
const initSortable = (className) => {
console.log(className)
// 获取表格row的父节点
const table = document.querySelector(
'.' + className + ' .el-table__body-wrapper tbody'
)
// 创建拖拽实例
console.log(table)
console.log(Sortable)
let dragTable = Sortable.create(table, {
animation: 150, //动画
// disabled: false, // 拖拽不可用? false 启用(刚刚渲染表格的时候起作用,后面不起作用)
// handle: ".move", //指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
// filter: ".disabled", //指定不可拖动的类名(el-table中可通过row-class-name设置行的class
// dragClass: "dragClass", //设置拖拽样式类名
// ghostClass: "ghostClass", //设置拖拽停靠样式类名
// chosenClass: "chosenClass", //设置选中样式类名
// 开始拖动事件
onStart: () => {
console.log('开始拖动')
},
// 结束拖动事件
onEnd: ({ newIndex, oldIndex }) => {
console.log('结束拖动', `拖动前索引${oldIndex}---拖动后索引${newIndex}`)
const currRow = tableDialog.value.splice(oldIndex, 1)[0]
tableDialog.value.splice(newIndex, 0, currRow)
console.log('结束拖动', tableDialog.value)
},
})
}
function tableRowClassName({ row }) {
if (row.disabled) {
return 'disabled'
}
return ''
}
</script>
<style lang="scss" scoped>
.mt-4 {
float: right;
text-align: right;
margin-bottom: 20px;
}
.dragClass {
background: rgba($color: #41c21a, $alpha: 0.5) !important;
}
// 停靠
.ghostClass {
background: rgba($color: #6cacf5, $alpha: 0.5) !important;
}
// 选择
.chosenClass:hover > td {
background: rgba($color: #f56c6c, $alpha: 0.5) !important;
}
</style>
+41
View File
@@ -0,0 +1,41 @@
export const options = [{
label: "用户名",
props: "username",
width: "auto",
align: "left",
show: true,
fixed: false,
},
{
label: "邮箱",
props: "email",
width: "auto",
align: "left",
show: true,
fixed: false,
},
{
label: "创建时间",
props: "date",
width: "auto",
align: "left",
show: true,
fixed: false,
},
{
label: "地址",
props: "address",
width: "auto",
align: "left",
show: true,
fixed: false,
},
{
label: "备注",
props: "content",
width: "auto",
align: "left",
show: true,
fixed: false,
},
];
+175
View File
@@ -0,0 +1,175 @@
<template>
<el-card class="flx-row-right">
<!-- <el-button type="primary" v-print="'#printMe'">打印</el-button> -->
<el-button type="primary" @click="scrollHanlde">滑动加载</el-button>
<el-button type="primary" @click="isShowPagHandle">分页加载</el-button>
<el-button type="primary" @click="educeExcel">导出表格</el-button>
</el-card>
<el-card class="mt10" id="printMe">
<el-table id="mutipleTable" :data="tableData" :header-cell-style="{ backgroundColor: '#ecf5ff' }" border stripe style="width: 100%" :height="heightTbale">
<el-table-column v-for="item in columnData" :key="item.props" :sortable="item.sortable" :prop="item.props" :label="item.label" :width="item.width" :fixed="item.fixed" :align="item.align">
<template v-slot:default="scope" v-if="item.props !== 'actions'">
<el-input v-model="scope.row[item.props]" v-if="scope.row.itemEdit"></el-input>
<div v-else class="one-cut-txt">{{ scope.row[item.props] }}</div>
</template>
<template v-slot:default="scope" v-if="item.props === 'actions'">
<el-icon class="icon-edit" @click="itemEditHanld(scope.row)"><Finished v-if="scope.row.itemEdit" /><Edit v-else /></el-icon>
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消" :icon="InfoFilled" icon-color="#626AEF" title="确认删除该用户?" @confirm="DeleteItem(index)" @cancel="cancelEvent">
<template #reference>
<el-icon class="icon-dele"><Delete /></el-icon>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination v-if="isShowPag" small background layout="prev, pager, next" :total="60" class="mt-4 mt10" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</el-card>
</template>
<script setup>
import print from "vue3-print-nb";
import * as XLSX from "xlsx";
import { Edit, Delete, InfoFilled, View } from "@element-plus/icons-vue";
import { nextTick, onMounted, reactive, ref } from "vue";
import { orderLists } from "../../../api/modules/index.js";
import { options } from "./options.js";
const tableData = ref([]);
const oldTableData = ref([]);
const tabclickIndex = ref();
const columnData = ref(JSON.parse(JSON.stringify(options)));
const disabled = ref(false);
const dialogVisible = ref(false);
const total = ref(0);
const queryData = ref({
keyWord: "",
page: 1,
size: 10,
});
const heightTbale = ref("auto");
const isShowPag = ref(true);
const scrollHanlde = () => {
heightTbale.value = "75vh";
isShowPag.value = false;
oldTableData.value = [];
queryData.value.page = 1;
queryData.value.size = 15;
initData();
// let table = mutipleTable.value._value.layout.table.refs.bodyWrapper;
let table = document.getElementById("mutipleTable");
table.addEventListener(
"scroll",
(res) => {
console.log("/监听表格滚动事件");
loadmore(res);
},
true
);
};
const isShowPagHandle = () => {
isShowPag.value = true;
heightTbale.value = "auto";
queryData.value.page = 1;
queryData.value.size = 10;
initData();
};
const cancelEvent = (val) => {
console.log("取消");
};
const initData = () => {
orderLists(queryData.value).then((res) => {
console.log(res.data.data);
// total.value = res.data.data.total
if (queryData.value.size == 10) {
tableData.value = res.data.data;
} else {
tableData.value = res.data.data.slice(queryData.value.page - 1, queryData.value.size);
oldTableData.value = res.data.data;
}
});
};
const itemEditHanld = (item) => {
item.itemEdit = !item.itemEdit;
// // console.log(JSON.stringify(item));
// tabclickIndex.value = item;
};
const handleSizeChange = (val) => {
console.log(val);
};
const handleCurrentChange = (val) => {
queryData.value.page = val;
initData(queryData.value);
};
const handleClose = () => {};
const dialogVisibleHanle = () => {
console.log("滑动加载");
};
const educeExcel = () => {
console.log("导出表格");
const data = XLSX.utils.json_to_sheet(tableData.value); //此处tableData.value为表格的数据
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, data, "test-data"); //test-data为自定义的sheet表名
XLSX.writeFile(wb, "测试.xlsx"); //test.xlsx为自定义的文件名
};
// https://www.zcool.com.cn/work/ZMzUzMDA0MDQ=.html
onMounted(() => {
console.log(columnData.value);
initData();
});
const loadmore = (res) => {
// 再距离底部20px的时候滚动加载下一条
if (res.target.scrollTop && res.target.scrollHeight - 2 <= res.target.scrollTop + res.target.clientHeight) {
console.log(queryData.value.page);
queryData.value.page++;
if (queryData.value.page > 5) return;
tableData.value = tableData.value.concat(
// res.data.data
oldTableData.value.slice(queryData.value.size * queryData.value.page - queryData.value.size, queryData.value.size * queryData.value.page)
);
}
};
const vPrint = (event) => {
event.print;
};
</script>
<style lang="scss" scoped>
.mt-4 {
float: right;
text-align: right;
margin-bottom: 20px;
}
.dragClass {
background: rgba($color: #41c21a, $alpha: 0.5) !important;
}
// 停靠
.ghostClass {
background: rgba($color: #6cacf5, $alpha: 0.5) !important;
}
// 选择
.chosenClass:hover > td {
background: rgba($color: #f56c6c, $alpha: 0.5) !important;
}
.icon-view {
font-size: 20px;
color: #673ab7;
margin: 0 10px;
}
.icon-edit {
font-size: 20px;
color: #2f60c2;
margin: 0 10px;
}
.icon-dele {
font-size: 20px;
color: #ff5722;
}
</style>
+122
View File
@@ -0,0 +1,122 @@
export const options = [
{
label: "序号",
props: "goodsId",
width: "60",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "机构代码",
props: "code",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "机构名",
props: "title",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "商品名称",
props: "goodsname",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "商品条码",
props: "commodity",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "规格",
props: "sku",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "品牌",
props: "brand",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "销售数量",
props: "number",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "剩余库存",
props: "inventory",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "成本价",
props: "costPrice",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "成本金额",
props: "amount",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "操作",
props: "actions",
width: "auto",
align: "left",
show: true,
fixed: "right",
itemEdit: "itemEdit",
sortable: false,
},
];
+208
View File
@@ -0,0 +1,208 @@
<template>
<el-card>
<div class="mt-4">
<el-button type="primary" @click="handleExpand">折叠全部</el-button>
<el-button type="primary" @click="handleOpen">展开全部</el-button>
</div>
</el-card>
<el-card class="mt10">
<el-table
ref="table"
:data="tableData"
:header-cell-style="{ backgroundColor: '#ecf5ff' }"
border
stripe
style="width: 100%"
>
<el-table-column type="expand">
<template #default="props">
<div class="m10">
<div class="expand-title">机构信息</div>
<el-table
:header-cell-style="{ backgroundColor: '#FAFAFA' }"
:data="props.row.ItemData"
border
style="border-bottom: none"
>
<el-table-column
v-for="ctx in ItemData"
:key="ctx.props"
:sortable="ctx.sortable"
:prop="ctx.props"
:label="ctx.label"
:width="ctx.width"
:fixed="ctx.fixed"
:align="ctx.align"
show-overflow-tooltip
>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column
v-for="item in columnData"
:key="item.props"
:sortable="item.sortable"
:prop="item.props"
:label="item.label"
:width="item.width"
:fixed="item.fixed"
:align="item.align"
show-overflow-tooltip
>
<template v-slot:default="scope" v-if="item.props !== 'actions'">
<el-input
v-model="scope.row[item.props]"
v-if="scope.row.itemEdit"
></el-input>
<div v-else class="one-cut-txt">{{ scope.row[item.props] }}</div>
</template>
<template v-slot:default="scope" v-if="item.props === 'actions'">
<el-icon class="icon-edit" @click="itemEditHanld(scope.row)"
><Finished v-if="scope.row.itemEdit" /><Edit v-else
/></el-icon>
<el-popconfirm
confirm-button-text="确认"
cancel-button-text="取消"
:icon="InfoFilled"
icon-color="#626AEF"
title="确认删除该数据?"
@confirm="DeleteItem(index)"
>
<template #reference>
<el-icon class="icon-dele"><Delete /></el-icon>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-pagination
small
background
layout="prev, pager, next"
:total="50"
class="mt-4 mt10"
@current-change="handleCurrentChange"
/>
</el-card>
</template>
<script setup>
import * as XLSX from 'xlsx'
import {
Edit,
Delete,
InfoFilled,
View,
ArrowDownBold,
Plus,
} from '@element-plus/icons-vue'
import { nextTick, onMounted, reactive, ref } from 'vue'
import { orderLists } from '../../../api/modules/index.js'
import { options, ItemData } from './options.js'
const tableData = ref([])
const table = ref()
const tabclickIndex = ref()
const isExpand = ref(false)
const columnData = ref(JSON.parse(JSON.stringify(options)))
const disabled = ref(false)
const dialogVisible = ref(false)
const total = ref(0)
const formInline = ref({})
const queryData = ref({
keyWord: '',
page: 1,
size: 10,
})
const initData = () => {
orderLists(queryData.value).then((res) => {
console.log(res.data.data)
// total.value = res.data.data.total
tableData.value = res.data.data
})
}
const itemEditHanld = (item) => {
item.itemEdit = !item.itemEdit
// // console.log(JSON.stringify(item));
// tabclickIndex.value = item;
}
const handleSizeChange = (val) => {
console.log(val)
}
const handleSelectionChange = (val) => {}
const handleCurrentChange = (val) => {
queryData.value.size = 10
queryData.value.page = val
initData(queryData.value)
}
const handleClose = () => {}
const dialogVisibleHanle = () => {
console.log('滑动加载')
}
const handleExpand = () => {
isExpand.value = false
tableData.value.forEach((item) => {
table.value.toggleRowExpansion(item, isExpand.value)
})
}
const handleOpen = () => {
isExpand.value = true
tableData.value.forEach((item) => {
table.value.toggleRowExpansion(item, isExpand.value)
})
}
// https://www.zcool.com.cn/work/ZMzUzMDA0MDQ=.html
onMounted(() => {
console.log(columnData.value)
initData()
})
</script>
<style lang="scss" scoped>
.mt-4 {
float: right;
text-align: right;
margin-bottom: 20px;
}
.demo-form-inline {
}
.dragClass {
background: rgba($color: #41c21a, $alpha: 0.5) !important;
}
// 停靠
.ghostClass {
background: rgba($color: #6cacf5, $alpha: 0.5) !important;
}
// 选择
.chosenClass:hover > td {
background: rgba($color: #f56c6c, $alpha: 0.5) !important;
}
.icon-view {
font-size: 20px;
color: #673ab7;
margin: 0 10px;
}
.icon-edit {
font-size: 20px;
color: #2f60c2;
margin: 0 10px;
}
.icon-dele {
font-size: 20px;
color: #ff5722;
}
.btn-color {
background: #fff;
color: #4c60cc;
}
.expand-title {
padding: 10px;
color: #919399;
font-weight: 600;
}
</style>
+163
View File
@@ -0,0 +1,163 @@
export const options = [{
label: "序号",
props: "goodsId",
width: "60",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "机构代码",
props: "code",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "机构名",
props: "title",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "商品名称",
props: "goodsname",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "商品条码",
props: "commodity",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "规格",
props: "sku",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "品牌",
props: "brand",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "销售数量",
props: "number",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "剩余库存",
props: "inventory",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "成本价",
props: "costPrice",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "成本金额",
props: "amount",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: true,
},
{
label: "操作",
props: "actions",
width: "auto",
align: "left",
show: true,
fixed: "right",
itemEdit: "itemEdit",
sortable: false,
},
];
export const ItemData = [{
label: "地址信息",
props: "address",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "联系方式",
props: "email",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "营业状态",
props: "state",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
{
label: "销售额",
props: "salenumber",
width: "auto",
align: "left",
show: true,
fixed: false,
itemEdit: "itemEdit",
sortable: false,
},
];
+7
View File
@@ -0,0 +1,7 @@
<template>
<div>roles</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>
+9
View File
@@ -0,0 +1,9 @@
<template>
<el-card>
<div>💐🌸💮🏵🌹🌺🌻</div>
</el-card>
</template>
<script setup></script>
<style lang="scss" scoped></style>
+24
View File
@@ -0,0 +1,24 @@
<template>
<el-card class="col-center">
<div>视频播放器🍲🍲🍲🍲🍲🍲🍲</div>
<div class="mt10 myVideo">
<VideoJs :videoSrc="data.videoSrc" autoPlay />
</div>
</el-card>
</template>
<script setup>
import { reactive } from 'vue'
// //找到你的组件地址引入进来
import VideoJs from '../../components/VideoPlay.vue'
const data = reactive({
videoSrc:
'https://prod-streaming-video-msn-com.akamaized.net/178161a4-26a5-4f84-96d3-6acea1909a06/2213bcd0-7d15-4da0-a619-e32d522572c0.mp4',
})
</script>
<style lang="scss" scoped>
.myVideo {
width: 50vw;
height: auto;
}
</style>