feat(projects): 添加文件grid布局和List布局

This commit is contained in:
黄磊 2025-03-01 10:26:21 -05:00
parent f331b33b0a
commit a6cb692b9a
24 changed files with 681 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,14 @@
<svg t="1642407662269" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="19932" width="200" height="200">
<path d="M847.872 240.128v688c0 26.56-21.408 48-48 48h-576c-26.56 0-48-21.44-48-48v-832c0-26.592 21.44-48 48-48h432z"
fill="#E9EDED" p-id="19933"></path>
<path d="M160 768.128v160c0 35.456 28.544 64 64 64h576c35.456 0 64-28.544 64-64v-160H160z" fill="#4BBFEB"
p-id="19934"></path>
<path d="M847.872 240.128h-144c-26.56 0-48-21.44-48-48v-144" fill="#4BBFEB" p-id="19935"></path>
<path
d="M432.256 320.128c-35.2 0-64 28.8-64 64v32c0 18.016-14.016 32-32 32a16 16 0 0 0-15.936 12.992 16 16 0 0 0 0 0.064 16 16 0 0 0 4.736 14.56 16 16 0 0 0 2.496 1.92 16 16 0 0 0 4.448 1.92 16 16 0 0 0 3.136 0.48 16 16 0 0 0 1.12 0.064c17.984 0 32 13.984 32 32v32c0 35.2 28.8 64 64 64a16 16 0 1 0 0-32c-18.016 0-32-13.984-32-32v-32c0-19.136-8.736-36.256-22.208-48a63.68 63.68 0 0 0 22.208-48v-32c0-18.016 13.984-32 32-32a16 16 0 1 0 0-32z m157.856 0a16 16 0 0 0 1.632 32c18.016 0 32 13.984 32 32v32c0 19.168 8.736 36.224 22.208 48-13.44 11.744-22.208 28.864-22.208 48v32c0 18.016-13.984 32-32 32a16 16 0 1 0 0 32c35.2 0 64-28.8 64-64v-32c0-18.016 14.016-32 32-32a16 16 0 0 0 10.368-3.616 16 16 0 0 0 1.216-1.152 16 16 0 0 0-11.584-27.232c-17.984 0-32-13.984-32-32v-32c0-35.2-28.8-64-64-64a16 16 0 0 0-1.6 0z"
fill="#4BBFEB" p-id="19936"></path>
<path
d="M334.496 800.128a16 16 0 0 0-3.36 0.672c-41.664 3.712-75.008 37.44-75.008 79.328 0 42.08 33.696 75.904 75.616 79.296a16 16 0 0 0 4.64 0.704h32a16 16 0 1 0 0-32h-29.824c-28.544 0-50.432-21.44-50.432-48s21.888-48 50.432-48h29.568a16 16 0 1 0 0-32h-32a16 16 0 0 0-1.6 0z m128 0a16 16 0 0 0-1.984 0.384c-24.64 1.92-44.384 22.528-44.384 47.616 0 25.28 20.064 46.08 44.992 47.68a16 16 0 0 0 3.008 0.32h32c9.152 0 16 6.848 16 16 0 9.152-6.848 16-16 16h-64a16 16 0 1 0 0 32h64a16 16 0 0 0 3.296-0.384 48.096 48.096 0 0 0 44.704-47.616c0-25.152-19.84-45.888-44.576-47.68a16 16 0 0 0-3.424-0.32h-32a15.616 15.616 0 0 1-16-16c0-9.152 6.848-16 16-16h64a16 16 0 1 0 0-32h-62.88a16 16 0 0 0-1.12 0 16 16 0 0 0-1.6 0z m159.744 0a16 16 0 0 0-1.984 0.384c-24.64 1.92-44.384 22.528-44.384 47.616 0 25.28 20.096 46.08 44.992 47.68a16 16 0 0 0 3.008 0.32h32c9.152 0 16 6.848 16 16 0 9.152-6.848 16-16 16h-64a16 16 0 1 0 0 32h64a16 16 0 0 0 3.328-0.384 48.096 48.096 0 0 0 44.672-47.616c0-25.152-19.84-45.888-44.544-47.68a16 16 0 0 0-3.456-0.32h-32a15.616 15.616 0 0 1-16-16c0-9.152 6.848-16 16-16h64a16 16 0 1 0 0-32h-62.88a16 16 0 0 0-1.12 0 16 16 0 0 0-1.6 0z"
fill="#E9EDED" p-id="19937"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1627885889837" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="17560" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M0 139.636364a46.545455 46.545455 0 0 1 46.545455-46.545455h354.897454a51.2 51.2 0 0 1 47.057455 31.034182L473.6 182.679273 977.454545 182.690909a46.545455 46.545455 0 0 1 46.545455 46.545455v546.909091a46.545455 46.545455 0 0 1-46.545455 46.545454H46.545455a46.545455 46.545455 0 0 1-46.545455-46.545454V139.636364z" fill="#FFA000" p-id="17561"></path><path d="M0 276.945455m46.545455 0l930.90909 0q46.545455 0 46.545455 46.545454l0 558.545455q0 46.545455-46.545455 46.545454l-930.90909 0q-46.545455 0-46.545455-46.545454l0-558.545455q0-46.545455 46.545455-46.545454Z" fill="#FFCA28" p-id="17562"></path></svg>

After

Width:  |  Height:  |  Size: 989 B

View File

@ -0,0 +1,11 @@
<svg t="1642407332637" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6055"
width="200" height="200">
<path
d="M967.111111 281.6V910.222222c0 62.577778-51.2 113.777778-113.777778 113.777778H170.666667c-62.577778 0-113.777778-51.2-113.777778-113.777778V113.777778c0-62.577778 51.2-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
fill="#62C558" p-id="6056"></path>
<path d="M685.511111 224.711111V0L967.111111 281.6H742.4c-31.288889 0-56.888889-25.6-56.888889-56.888889"
fill="#2A8121" p-id="6057"></path>
<path
d="M682.666667 724.024889L638.691556 768 341.333333 470.670222 385.308444 426.666667zM454.087111 611.128889l44.088889 44.088889L385.422222 768 341.333333 723.911111zM682.666667 470.755556l-113.066667 113.066666-44.088889-44.088889L638.577778 426.666667z"
fill="#FFFFFF" p-id="6058"></path>
</svg>

After

Width:  |  Height:  |  Size: 904 B

View File

@ -0,0 +1,14 @@
<svg t="1642407647664" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="19787" width="200" height="200">
<path d="M847.872 240.128v688c0 26.56-21.408 48-48 48h-576c-26.56 0-48-21.44-48-48v-832c0-26.592 21.44-48 48-48h432z"
fill="#E9EDED" p-id="19788"></path>
<path d="M160 768.128v160c0 35.456 28.544 64 64 64h576c35.456 0 64-28.544 64-64v-160H160z" fill="#F05542"
p-id="19789"></path>
<path d="M847.872 240.128h-144c-26.56 0-48-21.44-48-48v-144" fill="#F05542" p-id="19790"></path>
<path
d="M432.736 384.064a16 16 0 0 0-10.976 4.8l-96.96 95.776a16 16 0 0 0-0.416 0.416 16 16 0 0 0 1.664 23.808l95.68 94.56a16 16 0 1 0 22.528-22.72l-85.568-84.576 85.568-84.48a16 16 0 0 0-11.52-27.584z m157.824 0a16 16 0 0 0-11.008 27.552l85.504 84.48-85.504 84.576a16 16 0 1 0 22.496 22.752l95.648-94.56a16 16 0 0 0 5.44-17.504 16 16 0 0 0-1.28-2.912 16 16 0 0 0-0.608-1.12 16 16 0 0 0-0.192-0.256 16 16 0 0 0-0.192-0.256 16 16 0 0 0-0.8-0.992 16 16 0 0 0-0.192-0.256 16 16 0 0 0-0.864-0.96 16 16 0 0 0-0.064 0l-0.64-0.544a16 16 0 0 0-0.48-0.512l-95.776-94.688a16 16 0 0 0-11.488-4.8z"
fill="#F05542" p-id="19791"></path>
<path
d="M654.88 799.744a16 16 0 0 0-11.84 6.624L608 853.312l-35.136-46.944-0.128 0.064a16 16 0 0 0-13.056-6.368 16 16 0 0 0-15.744 16.192v127.68a16 16 0 1 0 32 0v-80.128l15.936 21.248a16 16 0 0 0 28.864 4.448l19.2-25.6v80.032a16 16 0 1 0 32 0v-126.816a16 16 0 0 0-15.424-17.376 16 16 0 0 0-1.632 0z m-383.136 0.32a16 16 0 0 0-15.744 16.192V943.936a16 16 0 1 0 32 0v-47.808h64v47.808a16 16 0 1 0 32 0v-61.312a16 16 0 0 0 0-5.12v-61.248a16 16 0 0 0-16.256-16.192 16 16 0 0 0-15.744 16.192v47.872H288v-47.872a16 16 0 0 0-16.256-16.192z m192 0a16 16 0 0 0-1.6 0.064H432a16 16 0 1 0 0 32h16v111.808a16 16 0 1 0 32 0v-111.808h16a16 16 0 1 0 0-32h-30.304a16 16 0 0 0-1.92-0.064z m255.936 0a16 16 0 0 0-15.744 16.192v126.496a16 16 0 0 0 0.64 5.824 16 16 0 0 0 0 0.064 16 16 0 0 0 0.096 0.416 16 16 0 0 0 0.448 1.12 16 16 0 0 0 0.864 1.824 16 16 0 0 0 0.64 0.992 16 16 0 0 0 0.192 0.32 16 16 0 0 0 0.736 0.96 16 16 0 0 0 0.832 0.864 16 16 0 0 0 0.352 0.416 16 16 0 0 0 0.832 0.704 16 16 0 0 0 0.448 0.384 16 16 0 0 0 0.352 0.32 16 16 0 0 0 1.12 0.736 16 16 0 0 0 2.464 1.248 16 16 0 0 0 0.864 0.32 16 16 0 0 0 5.376 0.864h63.552a16 16 0 1 0 0-32h-47.808v-111.872a16 16 0 0 0-16.256-16.192z"
fill="#E9EDED" p-id="19792"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1737021113160" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11349" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M146.879977 0A52.335992 52.335992 0 0 0 95.999985 51.167992v921.647856a49.039992 49.039992 0 0 0 15.279998 35.791994A49.839992 49.839992 0 0 0 146.863977 1023.99984h746.287883a48.559992 48.559992 0 0 0 35.567995-15.359998A50.719992 50.719992 0 0 0 943.999853 972.815848V290.015955L655.679898 0H146.847977h0.016z" fill="#3662EC" p-id="11350"></path><path d="M943.999853 287.999955H706.84789A52.127992 52.127992 0 0 1 655.999898 237.199963V0l287.951955 287.999955H943.999853z" fill="#FFFFFF" fill-opacity=".7" p-id="11351"></path><path d="M172.223973 751.999883h45.823993v-78.335988h62.71999V751.999883h45.567993V561.279912h-45.567993v72.703989h-62.71999V561.279912h-45.823993V751.999883z m235.007963 0h45.823993v-152.575977h51.711992V561.279912h-148.991977v38.143994h51.455992V751.999883z m126.975981 0h40.959993v-65.27999c0-18.943997-3.583999-47.359993-5.887999-66.04799h1.024l15.359997 45.567993 25.855996 69.631989h25.087997l25.599996-69.631989 15.871997-45.567993h1.28c-2.56 18.687997-6.143999 47.103993-6.143999 66.04799V751.999883h41.727993V561.279912H665.279896l-29.183995 82.431987c-3.583999 11.007998-6.655999 23.039996-10.495999 34.559995h-1.28c-3.583999-11.519998-6.655999-23.551996-10.495998-34.559995l-30.207995-82.431987h-49.407992V751.999883z m224.511964 0h120.063982v-38.399994h-74.239989v-152.319977H758.719881V751.999883z" fill="#FFFFFF" p-id="11352"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,14 @@
<svg t="1642408007951" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="50023" width="200" height="200">
<path d="M847.872 240.128v688c0 26.56-21.408 48-48 48h-576c-26.56 0-48-21.44-48-48v-832c0-26.592 21.44-48 48-48h432z"
fill="#E9EDED" p-id="50024"></path>
<path d="M160 768.128v160c0 35.456 28.544 64 64 64h576c35.456 0 64-28.544 64-64v-160H160z" fill="#25B39E"
p-id="50025"></path>
<path d="M847.872 240.128h-144c-26.56 0-48-21.44-48-48v-144" fill="#25B39E" p-id="50026"></path>
<path
d="M432.256 320.128c-35.2 0-64 28.8-64 64v32c0 18.016-14.016 32-32 32a16 16 0 0 0-3.2 0.256 16 16 0 0 0-12.384 11.232 16 16 0 0 0-0.352 1.504 16 16 0 0 0 0 0.064 16 16 0 0 0 15.936 18.944c17.984 0 32 13.984 32 32v32c0 35.2 28.8 64 64 64a16 16 0 1 0 0-32c-18.016 0-32-13.984-32-32v-32c0-19.136-8.736-36.256-22.208-48a63.68 63.68 0 0 0 22.208-48v-32c0-18.016 13.984-32 32-32a16 16 0 1 0 0-32z m157.856 0a16 16 0 0 0 1.632 32c18.016 0 32 13.984 32 32v32c0 19.168 8.736 36.224 22.208 48-13.44 11.744-22.208 28.864-22.208 48v32c0 18.016-13.984 32-32 32a16 16 0 1 0 0 32c35.2 0 64-28.8 64-64v-32c0-18.016 14.016-32 32-32a16 16 0 0 0 10.368-3.616 16 16 0 0 0 1.216-1.152 16 16 0 0 0-11.584-27.232c-17.984 0-32-13.984-32-32v-32c0-35.2-28.8-64-64-64a16 16 0 0 0-1.6 0zM512 367.936a32 32 0 0 0-32 32 32 32 0 0 0 32 32 32 32 0 0 0 32-32 32 32 0 0 0-32-32z m0 96a32 32 0 0 0-32 32 32 32 0 0 0 16.256 27.872l-14.4 28.864a16 16 0 1 0 28.64 14.272l24-48.256a32 32 0 0 0 9.44-21.504 16 16 0 0 0 0-0.192 32 32 0 0 0 0.064-1.056 32 32 0 0 0-32-32z"
fill="#25B39E" p-id="50027"></path>
<path
d="M335.872 800a16 16 0 0 0-15.744 16.256V912c0 9.152-6.848 16-16 16a15.616 15.616 0 0 1-16-16 16 16 0 0 0-16.256-16.192 16 16 0 0 0-15.744 16.192c0 26.304 21.696 48 48 48 24.768 0 45.12-19.296 47.488-43.52a16 16 0 0 0 0.512-4.224v-96a16 16 0 0 0-16.256-16.256z m94.4 0.128a16 16 0 0 0-2.016 0.384c-24.64 1.92-44.384 22.528-44.384 47.616 0 25.28 20.096 46.08 44.992 47.68a16 16 0 0 0 3.008 0.32h32c9.152 0 16 6.848 16 16 0 9.152-6.848 16-16 16h-64a16 16 0 1 0 0 32h64a16 16 0 0 0 3.328-0.384 48.096 48.096 0 0 0 44.672-47.616c0-25.152-19.84-45.888-44.544-47.68a16 16 0 0 0-3.456-0.32h-30.88a16 16 0 0 0-1.12 0 15.616 15.616 0 0 1-16-16c0-9.152 6.848-16 16-16h64a16 16 0 1 0 0-32h-62.88a16 16 0 0 0-1.12 0 16 16 0 0 0-1.6 0z"
fill="#E9EDED" p-id="50028"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1737020719380" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5937" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M153.6 0h514.5856L972.8 307.9424V921.6a102.4 102.4 0 0 1-102.4 102.4H153.6a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4z" fill="#39AFD1" p-id="5938"></path><path d="M665.6 0l307.2 307.2h-204.8a102.4 102.4 0 0 1-102.4-102.4V0z" fill="#298099" p-id="5939"></path><path d="M639.1552 384h-62.2592l-70.528 228.224L435.84 384h-62.2592L307.2 715.9552h58.112l45.6192-232.3712 70.5536 224.0768h49.792l66.3808-224.0768 49.7664 232.3712h58.0864L639.1296 384h0.0256z" fill="#FFFFFF" p-id="5940"></path></svg>

After

Width:  |  Height:  |  Size: 850 B

View File

@ -0,0 +1,11 @@
<svg t="1642407248989" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5608"
width="200" height="200">
<path
d="M967.111111 281.6V910.222222c0 62.577778-51.2 113.777778-113.777778 113.777778H170.666667c-62.577778 0-113.777778-51.2-113.777778-113.777778V113.777778c0-62.577778 51.2-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
fill="#D23B41" p-id="5609"></path>
<path d="M685.511111 224.711111V0L967.111111 281.6H742.4c-31.288889 0-56.888889-25.6-56.888889-56.888889"
fill="#9C171C" p-id="5610"></path>
<path
d="M680.277333 662.698667c-11.889778-1.194667-23.751111-3.640889-35.640889-9.728 10.666667-2.133333 20.110222-2.133333 30.776889-2.133334 23.751111 0 28.330667 5.774222 28.330667 9.443556-6.997333 2.417778-15.246222 3.356444-23.466667 2.417778z m-120.945777-15.530667c-25.884444 5.802667-54.556444 14.336-80.440889 23.779556v-2.446223l-2.446223 1.223111c13.084444-26.197333 25.002667-53.333333 35.640889-80.753777l0.938667 1.223111 1.194667-2.133334c13.112889 20.110222 29.866667 40.220444 47.530666 57.884445h-3.640889l1.223112 1.223111zM497.777778 417.450667c1.223111-1.223111 3.669333-1.223111 4.551111-1.223111h3.697778a96.739556 96.739556 0 0 1-1.251556 61.553777c-8.220444-18.915556-11.861333-40.220444-6.997333-60.330666zM352.142222 770.275556l-3.669333 1.223111a96.768 96.768 0 0 1 42.666667-34.417778c-9.443556 15.502222-22.556444 27.392-38.997334 33.194667z m324.494222-155.107556c-25.002667 0-49.664 3.669333-74.666666 8.248889a353.365333 353.365333 0 0 1-73.415111-94.776889c20.110222-66.417778 21.333333-111.217778 5.774222-132.551111a39.253333 39.253333 0 0 0-30.748445-15.502222c-15.246222-1.223111-29.582222 6.087111-36.579555 18.887111-21.333333 35.640889 9.443556 105.415111 23.779555 134.058666-16.782222 50.887111-36.864 99.328-63.089777 146.858667-112.412444 48.440889-114.858667 77.994667-114.858667 88.661333 0 13.084444 7.310222 26.197333 20.110222 32 4.864 3.640889 11.889778 4.835556 17.976889 4.835556 29.582222 0 64-33.194667 100.551111-98.389333 46.307556-18.887111 92.615111-34.133333 141.084445-44.8a153.941333 153.941333 0 0 0 87.722666 35.356444c20.110222 0 59.107556 0 59.107556-40.220444 1.223111-15.530667-6.997333-41.443556-62.748445-42.666667z"
fill="#FFFFFF" p-id="5611"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,12 @@
<svg t="1642407349568" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6204"
width="200" height="200">
<path
d="M967.111111 281.6V910.222222c0 62.577778-51.2 113.777778-113.777778 113.777778H170.666667c-62.577778 0-113.777778-51.2-113.777778-113.777778V113.777778c0-62.577778 51.2-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
fill="#F16C41" p-id="6205"></path>
<path d="M685.511111 224.711111V0L967.111111 281.6H742.4c-31.288889 0-56.888889-25.6-56.888889-56.888889"
fill="#CD4B29" p-id="6206"></path>
<path
d="M525.880889 648.135111a88.32 88.32 0 0 1-68.750222-32.995555 87.04 87.04 0 0 1-19.626667-55.381334c0-21.048889 7.253333-40.248889 19.626667-55.381333a88.234667 88.234667 0 0 1 68.750222-32.995556 88.490667 88.490667 0 0 1 88.376889 88.376889 88.519111 88.519111 0 0 1-88.376889 88.376889m0-235.690667c-24.945778 0-48.327111 6.087111-68.750222 17.294223a143.075556 143.075556 0 0 0-58.88 56.945777v146.119112a143.132444 143.132444 0 0 0 58.88 56.974222c20.423111 11.178667 43.804444 17.265778 68.750222 17.265778a147.342222 147.342222 0 0 0 147.285333-147.285334 147.342222 147.342222 0 0 0-147.285333-147.342222"
fill="#FFFFFF" p-id="6207"></path>
<path d="M398.222222 824.888889h58.908445V412.444444H398.222222z" fill="#FFFFFF" p-id="6208"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,16 @@
<svg t="1642407407406" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6649"
width="200" height="200">
<path
d="M967.111111 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H170.666667c-62.862222 0-113.777778-50.915556-113.777778-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
fill="#FFC63A" p-id="6650"></path>
<path d="M685.511111 167.822222V0L967.111111 281.6H799.288889c-62.862222 0-113.777778-50.915556-113.777778-113.777778"
fill="#DD9F08" p-id="6651"></path>
<path
d="M436.565333 68.437333h68.437334V0h-68.437334zM505.002667 136.874667h68.437333V68.437333h-68.437333zM436.565333 205.312h68.437334V136.874667h-68.437334zM505.002667 273.749333h68.437333V205.312h-68.437333z"
fill="#FFFFFF" p-id="6652"></path>
<path d="M436.565333 342.158222h68.437334V273.720889h-68.437334zM505.002667 410.624h68.437333V342.186667h-68.437333z"
fill="#FFFFFF" p-id="6653"></path>
<path
d="M436.565333 479.032889h68.437334v-68.437333h-68.437334zM505.002667 547.470222h68.437333v-68.437333h-68.437333zM470.784 762.225778h68.437333v-68.437334h-68.437333v68.437334z m-34.218667-136.874667v136.874667c0 18.915556 15.331556 34.218667 34.218667 34.218666h68.437333c18.915556 0 34.218667-15.303111 34.218667-34.218666v-136.874667h-136.874667z"
fill="#FFFFFF" p-id="6654"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,13 @@
<svg t="1642407280584" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5757"
width="200" height="200">
<path
d="M967.111111 281.6V910.222222c0 62.577778-51.2 113.777778-113.777778 113.777778H170.666667c-62.577778 0-113.777778-51.2-113.777778-113.777778V113.777778c0-62.577778 51.2-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
fill="#4F6BF6" p-id="5758"></path>
<path d="M581.262222 755.626667h59.363556L739.555556 439.04h-59.335112z" fill="#FFFFFF" p-id="5759"></path>
<path d="M685.511111 224.711111V0L967.111111 281.6H742.4c-31.288889 0-56.888889-25.6-56.888889-56.888889"
fill="#243EBB" p-id="5760"></path>
<path
d="M640.625778 755.626667h-59.363556l-98.929778-277.020445h59.335112zM442.737778 755.626667h-59.363556L284.444444 439.04h59.335112z"
fill="#FFFFFF" p-id="5761"></path>
<path d="M383.374222 755.626667h59.363556l98.929778-277.020445h-59.335112z" fill="#FFFFFF" p-id="5762"></path>
</svg>

After

Width:  |  Height:  |  Size: 1007 B

View File

@ -0,0 +1 @@
<svg t="1642421944380" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="865" width="200" height="200"><path d="M97.9 376h828.4v269.2H97.9z" fill="#F95F5D" p-id="866"></path><path d="M926.3 376V161.5c0-26.6-23.8-50.3-52.1-50.3H149.9c-28.3 0-52.1 23.7-52.1 50.3V376h828.5z m0 0" fill="#55C7F7" p-id="867"></path><path d="M97.9 645.2v214.5c0 26.6 23.6 50.3 51.7 50.3h725c28.1 0 51.7-23.7 51.7-50.3V645.2H97.9z m0 0" fill="#7ECF3B" p-id="868"></path><path d="M421.8 111.2h184.9V910H421.8z" fill="#FDAF42" p-id="869"></path><path d="M606.7 457.4v112.4H413V457.4h193.7m31.1-45.9H381.9c-4.4 0-11.8 4.4-11.8 11.8v179c0 4.4 4.4 11.8 11.8 11.8h255.9c4.4 0 11.8-4.4 11.8-11.8v-179c-2.9-8.8-7.4-11.8-11.8-11.8z m0 0" fill="#FFFFFF" p-id="870"></path></svg>

After

Width:  |  Height:  |  Size: 787 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1740735523131" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8626" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M862 902c0 16.569-13.431 30-30 30H192c-16.569 0-30-13.431-30-30V122c0-16.569 13.431-30 30-30h476l194 194v616z" fill="#4895FF" p-id="8627"></path><path d="M862 286H698c-16.569 0-30-13.431-30-30V92" fill="#FFFFFF" fill-opacity=".296" p-id="8628"></path><path d="M290 349m37 0l224.931 0q37 0 37 37l0 0q0 37-37 37l-224.931 0q-37 0-37-37l0 0q0-37 37-37Z" fill="#FFFFFF" p-id="8629"></path><path d="M290 511m37 0l370 0q37 0 37 37l0 0q0 37-37 37l-370 0q-37 0-37-37l0 0q0-37 37-37Z" fill="#FFFFFF" p-id="8630"></path><path d="M290 673m37 0l370 0q37 0 37 37l0 0q0 37-37 37l-370 0q-37 0-37-37l0 0q0-37 37-37Z" fill="#FFFFFF" p-id="8631"></path></svg>

After

Width:  |  Height:  |  Size: 973 B

View File

@ -0,0 +1,12 @@
<svg t="1657792062684" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="34419" width="200" height="200">
<path
d="M0 128a51.2 51.2 0 0 1 51.2-51.2h350.24a51.2 51.2 0 0 1 47.0592 31.0336L473.6 166.4h499.2a51.2 51.2 0 0 1 51.2 51.2v537.6a51.2 51.2 0 0 1-51.2 51.2H51.2a51.2 51.2 0 0 1-51.2-51.2V128z"
fill="#FFA000" p-id="34420"></path>
<path
d="M89.6 249.6m51.2 0l742.4 0q51.2 0 51.2 51.2l0 460.8q0 51.2-51.2 51.2l-742.4 0q-51.2 0-51.2-51.2l0-460.8q0-51.2 51.2-51.2Z"
fill="#FFFFFF" p-id="34421"></path>
<path
d="M0 332.8m51.2 0l921.6 0q51.2 0 51.2 51.2l0 512q0 51.2-51.2 51.2l-921.6 0q-51.2 0-51.2-51.2l0-512q0-51.2 51.2-51.2Z"
fill="#FFCA28" p-id="34422"></path>
</svg>

After

Width:  |  Height:  |  Size: 756 B

18
src/service/api/pan.ts Normal file
View File

@ -0,0 +1,18 @@
import { request } from '../request';
/** 网盘上传地址 */
export const simpleUploadURL = `${import.meta.env.VITE_SERVICE_BASE_URL}/pan/upload`;
/** 获取首页文件列表 */
export const fetchGetFileList = () => {
return request({
url: '/pan/filelist'
});
};
/** 删除文件 */
export const fetchDeleteFile = (id: string) => {
return request({
url: `/pan/file/${id}`,
method: 'delete'
});
};

26
src/typings/app.d.ts vendored
View File

@ -263,6 +263,32 @@ declare namespace App {
/** The global dropdown key */ /** The global dropdown key */
type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll'; type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll';
/** 文件类型 */
type FileItem = {
/** 文件唯一标识 */
id: string;
/** 文件类型 */
type?: string;
/** 文件名 */
name: string;
/** 拓展名 */
extendName: string;
/** 文件路径 */
src: string;
/** 文件修改时间 */
updateTime: string;
/** 是否是目录 */
isDir: boolean;
/** 是否是公共目录 */
isPublic?: boolean;
/** 文件路径 */
filePath: string;
/** 文件大小 */
size: number;
/** 任意属性只能有一个 */
[propName: string]: any;
};
} }
/** /**

View File

@ -0,0 +1,182 @@
<script setup lang="ts">
import { nextTick, ref } from 'vue';
import { useSvgIcon } from '@/hooks/common/icon';
import { fetchDeleteFile } from '@/service/api/pan';
import FileImage from './file-image.vue';
defineOptions({
name: 'FileGrid'
});
interface Props {
data?: App.Global.FileItem[];
selectedFileIds?: string[];
isBatchMode?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
data: () => [], //
selectedFileIds: () => [], // id
isBatchMode: false //
});
const emit = defineEmits<{
(e: 'click', record: App.Global.FileItem): void;
(e: 'select', record: App.Global.FileItem): void;
(e: 'refresh'): void;
}>();
const showDropdown = ref(false);
const activeItemId = ref('');
const xRef = ref(0);
const yRef = ref(0);
const { SvgIconVNode } = useSvgIcon();
//
const FileDropdownOptions = [
{
label: '下载',
key: 'download',
icon: SvgIconVNode({ icon: 'ic:baseline-file-download', fontSize: 18 })
},
{
label: '分享',
key: 'share',
icon: SvgIconVNode({ icon: 'ic:baseline-share', fontSize: 18 })
},
{
label: '删除',
key: 'delete',
icon: SvgIconVNode({ icon: 'ic:baseline-delete-forever', fontSize: 18 })
},
{
type: 'divider',
key: 'd1'
},
{
label: '重命名',
key: 'rename',
icon: SvgIconVNode({ icon: 'ic:round-drive-file-rename-outline', fontSize: 18 })
},
{
label: '移动到',
key: 'move',
icon: SvgIconVNode({ icon: 'ic:round-move-down', fontSize: 18 })
},
{
label: '复制到',
key: 'copy',
icon: SvgIconVNode({ icon: 'ic:round-content-copy', fontSize: 18 })
}
];
//
const getFileName = (item: App.Global.FileItem) => {
return `${item.name}${item.extendName ? `.${item.extendName}` : ''}`;
};
//
const handleClickFile = (item: App.Global.FileItem) => {
emit('click', item);
};
//
const handleCheckFile = (item: App.Global.FileItem) => {
emit('select', item);
};
//
const onClickoutside = () => {
showDropdown.value = false;
};
const handleContextMenu = (e: MouseEvent, item: App.Global.FileItem) => {
e.preventDefault();
showDropdown.value = false;
nextTick().then(() => {
showDropdown.value = true;
xRef.value = e.clientX;
yRef.value = e.clientY;
activeItemId.value = item.id;
});
};
//
const handleSelect = async (key: string) => {
if (key === 'delete') {
//
window.$dialog?.error({
title: '删除文件',
content: '确定要删除该文件吗?',
positiveText: '确定',
negativeText: '取消',
maskClosable: false,
onMaskClick: () => {
window.$message?.info('点击了遮罩层,不能关闭窗口,请点击确定或者取消');
},
onPositiveClick: async () => {
const { error } = await fetchDeleteFile(activeItemId.value);
if (!error) {
// window.$message?.success(`${res.msg}`);
window.$message?.success('删除成功');
emit('refresh');
}
}
});
} else {
window.$message?.success(`点击了${key}`);
}
};
</script>
<template>
<div class="mt-12px flex-1 overflow-hidden">
<NGrid cols="4 s:4 m:5 l:7 xl:8 2xl:9" x-gap="12" y-gap="12" item-responsive responsive="screen">
<NGridItem v-for="item in props.data" :key="item.id">
<div class="pos-relative size-full flex-center hover:bg-primary-100" @click.stop="handleClickFile(item)">
<section
class="pos-relative z-1 h-full max-w-100px w-76% flex-col-center overflow-hidden"
@contextmenu="e => handleContextMenu(e, item)"
>
<div
class="mt-15px h-60px w-full flex-x-center transform-gpu cursor-pointer overflow-hidden transition-transform duration-200 ease-in-out active:scale-90 hover:scale-110"
>
<FileImage :data="item"></FileImage>
</div>
<p class="mt-8px w-full overflow-hidden text-ellipsis whitespace-nowrap px-0 py-5px text-center text-12px">
{{ getFileName(item) }}
</p>
</section>
<!--勾选模式-->
<section
v-show="props.isBatchMode"
class="absolute inset-0 z-9 cursor-pointer"
:class="{
'bg-[rgba(0,0,0,0.1)]': !props.selectedFileIds.includes(item.id),
'bg-none': props.selectedFileIds.includes(item.id)
}"
>
<NCheckbox
:model-value="props.selectedFileIds.includes(item.id)"
class="absolute left-1 top-1 pl-0"
@change="handleCheckFile(item)"
/>
</section>
</div>
</NGridItem>
</NGrid>
<NDropdown
placement="bottom-start"
trigger="manual"
:x="xRef"
:y="yRef"
:options="FileDropdownOptions"
:show="showDropdown"
:on-clickoutside="onClickoutside"
@select="handleSelect"
/>
</div>
</template>
<style scoped></style>

View File

@ -0,0 +1,70 @@
<script setup lang="ts">
import { computed } from 'vue';
defineOptions({
name: 'FileImage'
});
interface Props {
data: App.Global.FileItem;
}
interface FileExtendNameIconMap {
[key: string]: string;
}
/** 文件类型图标 Map 映射 */
const FileIcon: FileExtendNameIconMap = {
mp3: 'file-music',
mp4: 'file-video',
dir: 'file-dir',
ppt: 'file-ppt',
doc: 'file-wps',
docx: 'file-wps',
xls: 'file-excel',
xlsx: 'file-excel',
txt: 'file-txt',
rar: 'file-rar',
zip: 'file-zip',
html: 'file-html2',
css: 'file-css2',
md: 'file-markdown',
js: 'file-js2',
py: 'file-python',
other: 'file-other' //
};
const props = withDefaults(defineProps<Props>(), {});
/** 图片类型 */
const ImageTypes = ['jpg', 'png', 'gif', 'jpeg'];
//
const isImage = computed(() => {
if (!props.data || props.data.isDir) {
return false; //
}
const extendName = props.data.extendName?.toLowerCase() || '';
return ImageTypes.includes(extendName);
});
//
const getFileImg = computed<string>(() => {
const extendName = props.data.extendName.toLowerCase();
if (props.data?.isDir) {
return FileIcon.dir;
}
if (ImageTypes.includes(extendName)) {
return props.data.src;
}
if (!Object.keys(FileIcon).includes(extendName)) {
return FileIcon.other;
}
return FileIcon[extendName];
});
</script>
<template>
<img v-if="isImage" class="h-full w-auto object-cover transition-all duration-300" :src="props.data.src" />
<SvgIcon v-else :local-icon="getFileImg" class="h-full w-auto object-cover transition-all duration-300" />
</template>
<style scoped></style>

View File

@ -0,0 +1,214 @@
<script setup lang="tsx">
import { type DataTableColumn, NButton, NPopover, NTag } from 'naive-ui';
import type { ComputedRef } from 'vue';
import { computed, nextTick, ref } from 'vue';
import { useSvgIcon } from '@/hooks/common/icon';
import { useThemeStore } from '@/store/modules/theme';
import FileImage from './file-image.vue';
defineOptions({
name: 'FileList'
});
interface Props {
data?: App.Global.FileItem[];
selectedFileIds?: string[];
isBatchMode?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
data: () => [], //
selectedFileIds: () => [],
isBatchMode: false //
});
const emit = defineEmits<{
(e: 'click', record: App.Global.FileItem): void;
(e: 'select', record: App.Global.FileItem): void;
}>();
const themeStore = useThemeStore();
const { SvgIconVNode } = useSvgIcon();
const showDropdown = ref(false);
const activeItemId = ref('');
const xRef = ref(0);
const yRef = ref(0);
const handleContextMenu = (e: MouseEvent, item: App.Global.FileItem) => {
e.preventDefault();
showDropdown.value = false;
nextTick().then(() => {
showDropdown.value = true;
xRef.value = e.clientX;
yRef.value = e.clientY;
activeItemId.value = item.id;
});
};
//
const onClickoutside = () => {
showDropdown.value = false;
};
const fileColumns: ComputedRef<DataTableColumn[]> = computed(() => {
const columns: DataTableColumn[] = [
{
title: '名称',
key: 'name',
render: row => {
return (
<section
class="flex-y-center cursor-pointer"
onContextmenu={e => handleContextMenu(e, row as App.Global.FileItem)}
>
<div class="mr-10px h-30px w-30px">
<FileImage data={row as App.Global.FileItem} />
</div>
<span>{row.name}</span>
</section>
);
}
},
{
title: '文件大小kb',
key: 'size',
width: 150,
align: 'center'
},
{
title: '扩展名',
key: 'extendName',
width: 100,
align: 'center',
render: row => {
//
if (!row.extendName) return null;
return (
<NTag
size={'small'}
bordered={false}
color={{
color: themeStore.darkMode ? 'rgba(142, 81, 218, 0.2)' : 'rgb(245, 232, 255)',
textColor: themeStore.darkMode ? 'rgb(142, 81, 218)' : 'rgb(114, 46, 209)'
}}
>
{row.extendName}
</NTag>
);
}
},
{
title: '修改时间',
key: 'updateTime',
width: 200,
align: 'center'
},
{
title: '操作',
key: 'action',
width: 120,
align: 'center',
render: () => {
return (
<NPopover trigger={'click'} placement={'bottom'}>
{{
trigger: () => (
<NButton text={true} size={'small'}>
{{
icon: SvgIconVNode({ icon: 'icon-park-outline:more' })
}}
</NButton>
)
}}
</NPopover>
);
}
}
];
// isBatchMode true
if (props.isBatchMode) {
columns.unshift({
type: 'selection'
});
}
return columns;
});
//
const FileDropdownOptions = [
{
label: '下载',
key: 'download',
icon: SvgIconVNode({ icon: 'ic:baseline-file-download', fontSize: 18 })
},
{
label: '分享',
key: 'share',
icon: SvgIconVNode({ icon: 'ic:baseline-share', fontSize: 18 })
},
{
label: '删除',
key: 'delete',
icon: SvgIconVNode({ icon: 'ic:baseline-delete-forever', fontSize: 18 })
},
{
type: 'divider',
key: 'd1'
},
{
label: '重命名',
key: 'rename',
icon: SvgIconVNode({ icon: 'ic:round-drive-file-rename-outline', fontSize: 18 })
},
{
label: '移动到',
key: 'move',
icon: SvgIconVNode({ icon: 'ic:round-move-down', fontSize: 18 })
},
{
label: '复制到',
key: 'copy',
icon: SvgIconVNode({ icon: 'ic:round-content-copy', fontSize: 18 })
}
];
const rowProps = (row: App.Global.FileItem) => {
return {
onClick: () => {
emit('click', row);
},
onSelect: () => {
emit('select', row);
}
};
};
</script>
<template>
<div>
<NDataTable
:row-key="row => row.id"
:columns="fileColumns"
:data="props.data"
:bordered="false"
:checked-row-keys="selectedFileIds"
:scroll-x="750"
:row-props="rowProps"
class="sm:h-full"
/>
<NDropdown
placement="bottom-start"
trigger="manual"
:x="xRef"
:y="yRef"
:options="FileDropdownOptions"
:show="showDropdown"
:on-clickoutside="onClickoutside"
/>
</div>
</template>
<style scoped></style>

View File

@ -72,12 +72,10 @@ const fileMenuOptions = [
</template> </template>
<NMenu v-model:value="selectedKey" :options="fileMenuOptions"></NMenu> <NMenu v-model:value="selectedKey" :options="fileMenuOptions"></NMenu>
</NCard> </NCard>
<div v-show="showPersent" class="mt-10px box-border"> <div v-show="showPersent" class="mt-10px box-border flex-center">
<NCard :bordered="false"> <NCard :bordered="false" class="flex-y-center">
<NSpace justify="center"> <NProgress type="circle" :percentage="30" :stroke-width="5" />
<NProgress type="circle" :percentage="30" :stroke-width="5" /> <NStatistic label="剩余容量 / 总容量" value="512GB / 1T"></NStatistic>
<NStatistic label="剩余容量 / 总容量" value="512GB / 1T"></NStatistic>
</NSpace>
</NCard> </NCard>
</div> </div>
</div> </div>

View File

@ -1,8 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { useSvgIcon } from '@/hooks/common/icon'; import { useSvgIcon } from '@/hooks/common/icon';
import { usePanStore } from '@/store/modules/pan'; import { usePanStore } from '@/store/modules/pan';
import { fetchGetFileList } from '@/service/api/pan';
import FilePath from '../components/file-path.vue'; import FilePath from '../components/file-path.vue';
import FileGrid from '../components/file-grid.vue';
import FileList from '../components/file-list.vue';
defineOptions({ defineOptions({
name: 'FileMain' name: 'FileMain'
}); });
@ -14,6 +18,9 @@ const isBatchMode = ref<boolean>(false);
// //
const show = ref(false); const show = ref(false);
//
const fileList = ref<App.Global.FileItem[]>([]);
// //
const currentMode = computed(() => panStore.fileShowMode); const currentMode = computed(() => panStore.fileShowMode);
@ -27,7 +34,7 @@ const uploadOptions = [
{ {
key: 'file', key: 'file',
label: '上传文件', label: '上传文件',
icon: SvgIconVNode({ localIcon: 'upload-file', fontSize: 20 }), icon: SvgIconVNode({ localIcon: 'upload-file', fontSize: 25 }),
props: { props: {
onClick: () => { onClick: () => {
// handleFileUpload(); // handleFileUpload();
@ -47,6 +54,19 @@ const uploadOptions = [
} }
} }
]; ];
//
async function getListData() {
const { data: fileListData, error } = await fetchGetFileList();
if (!error) {
fileList.value = fileListData;
}
}
onMounted(async () => {
//
await getListData();
});
</script> </script>
<template> <template>
@ -125,11 +145,27 @@ const uploadOptions = [
</NButtonGroup> </NButtonGroup>
</NSpace> </NSpace>
</NSpace> </NSpace>
<div>
<!--文件列表--宫格模式--> <NSpin :show="show" class="box-border h-full flex-col px-0 py-16px">
<NSpin :show="show" class="box-border flex-col px-0 py-16px"> <!--文件列表--宫格模式-->
<FileGrid /> <FileGrid
</NSpin> v-show="fileList.length > 0 && currentMode === 'grid'"
:data="fileList"
:is-batch-mode="isBatchMode"
/>
<!-- 文件列表-列表模式 -->
<FileList v-show="fileList.length && currentMode === 'list'" :data="fileList" :is-batch-mode="isBatchMode" />
<NCard
v-show="!fileList.length"
size="huge"
class="h-full flex-center gap-12px"
content-style="height: 100%; display: flex; flex-direction: column"
>
<img class="h-200px" src="@/assets/imgs/no-items-tip.png" />
<span class="text-20px">目前该目录下面啥也没有</span>
</NCard>
</NSpin>
</div>
</NCard> </NCard>
</div> </div>
</template> </template>