chore: 删除award
3
src/assets/icons/CCrop.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M24 18H20V7C20 6.20435 19.6839 5.44129 19.1213 4.87868C18.5587 4.31607 17.7956 4 17 4H6V0H4V4H0V6H4V17C4 17.7956 4.31607 18.5587 4.87868 19.1213C5.44129 19.6839 6.20435 20 7 20H18V24H20V20H24V18ZM7 18C6.73478 18 6.48043 17.8946 6.29289 17.7071C6.10536 17.5196 6 17.2652 6 17V6H17C17.2652 6 17.5196 6.10536 17.7071 6.29289C17.8946 6.48043 18 6.73478 18 7V18H7Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 495 B |
3
src/assets/icons/CPublish.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 8H12C11.2647 8 10.6667 8.598 10.6667 9.33333C10.6667 10.0687 10.0687 10.6667 9.33333 10.6667H6.66667C5.93133 10.6667 5.33333 10.0687 5.33333 9.33333C5.33333 8.598 4.73533 8 4 8H2C0.897333 8 0 8.89733 0 10V12.6667C0 14.5047 1.49533 16 3.33333 16H12.6667C14.5047 16 16 14.5047 16 12.6667V10C16 8.89733 15.1027 8 14 8ZM14.6667 12.6667C14.6667 13.7693 13.7693 14.6667 12.6667 14.6667H3.33333C2.23067 14.6667 1.33333 13.7693 1.33333 12.6667V10C1.33333 9.632 1.632 9.33333 2 9.33333L4 9.332V9.33333C4 10.804 5.196 12 6.66667 12H9.33333C10.804 12 12 10.804 12 9.33333H14C14.368 9.33333 14.6667 9.632 14.6667 10V12.6667ZM4.862 3.52867C4.60133 3.268 4.60133 2.84667 4.862 2.586L7.05733 0.390667C7.31467 0.133333 7.65267 0.004 7.99067 0.002L8 0L8.00933 0.002C8.348 0.004 8.68533 0.133333 8.94267 0.390667L11.138 2.586C11.3987 2.84667 11.3987 3.268 11.138 3.52867C11.008 3.65867 10.8373 3.724 10.6667 3.724C10.496 3.724 10.3253 3.65867 10.1953 3.52867L8.66667 2V6.66667C8.66667 7.03533 8.36867 7.33333 8 7.33333C7.63133 7.33333 7.33333 7.03533 7.33333 6.66667V2L5.80467 3.52867C5.544 3.78933 5.12267 3.78933 4.862 3.52867Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
3
src/assets/icons/CSave.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.024 2.74801L13.252 0.976013C12.9432 0.665575 12.576 0.419466 12.1714 0.251935C11.7669 0.0844031 11.3332 -0.00122304 10.8953 1.31975e-05H3.33333C2.4496 0.00107177 1.60237 0.352601 0.97748 0.977493C0.352588 1.60239 0.00105857 2.44962 0 3.33335L0 12.6667C0.00105857 13.5504 0.352588 14.3976 0.97748 15.0225C1.60237 15.6474 2.4496 15.999 3.33333 16H12.6667C13.5504 15.999 14.3976 15.6474 15.0225 15.0225C15.6474 14.3976 15.9989 13.5504 16 12.6667V5.10468C16.0012 4.66684 15.9156 4.2331 15.7481 3.82858C15.5805 3.42405 15.3344 3.05678 15.024 2.74801ZM11.3333 1.38668V2.00001C11.3333 2.53045 11.1226 3.03915 10.7475 3.41423C10.3725 3.7893 9.86377 4.00001 9.33333 4.00001H6.66667C6.13623 4.00001 5.62753 3.7893 5.25245 3.41423C4.87738 3.03915 4.66667 2.53045 4.66667 2.00001V1.33335H10.8953C11.0429 1.33466 11.1898 1.35255 11.3333 1.38668ZM14.6667 12.6667C14.6667 13.1971 14.456 13.7058 14.0809 14.0809C13.7058 14.456 13.1971 14.6667 12.6667 14.6667H3.33333C2.8029 14.6667 2.29419 14.456 1.91912 14.0809C1.54405 13.7058 1.33333 13.1971 1.33333 12.6667V3.33335C1.33333 2.80291 1.54405 2.29421 1.91912 1.91913C2.29419 1.54406 2.8029 1.33335 3.33333 1.33335V2.00001C3.33439 2.88374 3.68592 3.73097 4.31081 4.35587C4.93571 4.98076 5.78294 5.33229 6.66667 5.33335H9.33333C10.1717 5.33074 10.9781 5.01179 11.5914 4.44026C12.2047 3.86872 12.5797 3.08674 12.6413 2.25068L14.0813 3.69068C14.455 4.0666 14.6653 4.57468 14.6667 5.10468V12.6667Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 198 B |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="22" height="12" viewBox="0 0 22 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M1 1L11 11L21 1" stroke="#585858" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 492 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 913 B |
@@ -1,4 +0,0 @@
|
|||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M19.6144 18.7388L5.16736 4.29184C4.95412 4.0786 4.60838 4.0786 4.39514 4.29184C4.18189 4.50509 4.18189 4.85082 4.39514 5.06407L18.8421 19.5111C19.0554 19.7243 19.4011 19.7243 19.6144 19.5111C19.8276 19.2978 19.8276 18.9521 19.6144 18.7388Z" fill="#232323"/>
|
|
||||||
<path d="M5.15908 19.5378L19.6061 5.09079C19.8193 4.87755 19.8193 4.53181 19.6061 4.31857C19.3928 4.10533 19.0471 4.10533 18.8339 4.31857L4.38685 18.7656C4.17361 18.9788 4.17361 19.3246 4.38685 19.5378C4.6001 19.751 4.94583 19.751 5.15908 19.5378Z" fill="#232323"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 443 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 35 KiB |
@@ -1,9 +0,0 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<rect width="20" height="20" rx="2.79453" fill="url(#pattern0_226_198)"/>
|
|
||||||
<defs>
|
|
||||||
<pattern id="pattern0_226_198" patternContentUnits="objectBoundingBox" width="1" height="1">
|
|
||||||
<use xlink:href="#image0_226_198" transform="scale(0.0104167)"/>
|
|
||||||
</pattern>
|
|
||||||
<image id="image0_226_198" width="96" height="96" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAKcUlEQVR4AeydSewlRR3H3xtHUXAZdz2YGQ+aeDDiCYgCMxwENFGMMdF4cDx48gB6VOOuiR4UPWlkGSAsBxK2BMI6wxYgLMOSEJYAQ9jXGbZh58/n0/Oq6ffmLd3Vr1/369f/1PfV0lW/qvr+flVdr7pe/9f1Cv6tra1tAseDU8FDYDdYVWffd9L584CcbCpIZy+3AqhgK9hOBQ+BE8FWYIUb8FfV2feD6fxxQE40SBXyU+K53EwFQPpmIOmnInEz6Nx0BlTINjkDMxUxUQEU3gDUqlavpU+vtrs6yoCcqYh/waMjZfR6Eh+rAApYWOKPT3J1H2UYOIHCTktySnDY7aeADPkOpeHcXSyWAcnfPuB2SMaQAsjgUNHyLTCUsYuUZkBOXS3JcSpsSAGk/gGYEa9zFTDgrPL7rNxUAVi/y8puzs+yU034BLhOV5OpAqhrSDPEO1cdAy7pE+mJAtCI1r86U0/S9Vo/3E1IviMkCqApqzj1rNHvebl3EFRUnkbfW4f1a/neHJDRuUgGipJvNe4wbHQEfM/YCmCUpP6gz1rvs4QfBXeDO8GN4HpwNdgxgiuJXwvM8zD+XvA+EOQRzO2OUwHpHTl3seXLOEp+tgevEbkX3ADOBaeD/4C/gz8O4PJc/I74b8Ffwb/BNeAZEOsOVgFOQbEClqGc5Gudwva+zccT4H5wIXBF8n/8k8Apot/vnw0uAtvBDnD1ANfi3wguBeeQ92LwJIh1m9uuAMkfJedVErT2M/G1dBXgtHI7ca35Zfy8bg8Z3wCxboMKGPpqHCupoeW0eqEiXqSNEn0G/n/B/7DiK8Gt4FHwNNgL3uTaRMeiRXnhugqYmj9knOAnCphwrVXJr9Abb6qn4Z8FbgLeePGKORSkMkOh9xPQiPHiXKnCcVVWXipLkCuc56jR6cZ53rn9Okh8EbxFeuJGrDpJy/nh6idn1vHZ2qiAbE93E7kMuLrZmSWdtNSRnlVamr6IwAIVUHl3AonO0Ya9mUr8yRB8BdgVWoDFN6bfjWlIICfSl/BsUW+4flnS+h/IXjCMMpyaDNaOtihAqxeB0FsInA0uhOys5WfzcLl+1xYFBCb9kuXUcx8JD0J+eqMl3iM+OlJMrhVtUECW1Kdh83JwPrgLJG6ecz6ysqNIhSd1xH60QQHZvr9E5A7ghpqbZAR7Wn5Vc74jrJTsNigga5H39Ho992ueZLqRHKL53IhlTyyE3OyI+xgZ/TKGF+faoAB7rhVq8Y8QeQEUcnnJHyP046R9AES7tijgeRi4DdwM0t3JPMSaR6sWlO0RPwB8AXwVHAGOBFuAD1AOxz8UHAN+TP5jwOdAtGuLAtzhfBwWJD/dnQykkj7WQWJ2+pJ8404r36TAT8BvgIcV/oQfng34LODXxH2MeyT+p0G0a4sCvPk6/wuXobkIUUEik/nrhH8AfgF+Dr4FtgAVcgS+4aPwDweHgI3gQOD9JntvIGmfm/XZFgVIgN9+heFZ/R66zkhw2vksiZJ67MD/BH5e56acoydv/jRfWxTgDfgxrHk3iNmfl3wt22nHeX19ytC+wCzrjiJf0W1RgFav9dunGDjvf42CXwGj5JPUiybYwtPQFgVo9bnn/jGEuJx0/nfaqYzsMfXm/4nSuMINSpM0Edsky5b6QhVbcVtGQGz/Qzl5yCpg1pwfypX2rbi0kBYIkHC/TYeuOCJCuFJ/mRUgaYGc6GXgQICEi0G0l5Ud0irxl1kBWUJcuZTpi+QrIytzIeEyja6igVpediqYVoekhesuQV0JhXhR32Ws36ZDuazskDbNt93Trk+81jQF2NCYznj6Id0D6imlGFSeSixW6r3cGk1Muxu3DNXynM89SOXJYw9Q+XD9KvrqjwfDSWXTPJ18Keme0bwE3404vChnWc95eopCmR5d9OBtqC/4tuEKavCQ1058z5h6uNc223aSirkmjgB74Kk1j4b7Q3F3Hz2R7K5k2JH0lLI7lV4zj3k912nZGPgoU3L/SeG/AevzNHSoL/jW607oP8jjQV6V4PFEonGuqQrQsi5hX+cc4EnkG/B90uVJ5YCrBmk34T8M9rKpth7ktkTy+gOV9ZR9BewC1nMNvrLDyehQn76n6m7muqeqt0G5I0FjIRjnmqoA52Tn9aK9ehtycs/F5HXujn2w7j3H+4ZtLdrONH9TFWDn0keLWGouq4bQ3OQHBmLKDNrjvF+4vlBv8JuqANuVbg3EkBQ6WJF/AHLdQRVpO0kr7Oxo4UILKKDFa2ELqCqqChXwGUoKwwTjXFMVENebxZXSOD5EdaLUN+hOAbAY4bT6T1LuU6A7lgIJi3ZhBHyQig3jxbk5joC4BixpKUeAx1GE4ehudAqIo06rP4iiwjDBONdUBbi+Tr8gDdbdcT2sppRLT+8BrR0BKsAt4mroi5A6YgQuk53/RStXQXbqI4GnvF/ERkgKxSf65ge5ZoGRNnwYoZ4lso2tnIIc4n7LpJ+FnJtrWmeRQkXzK9v1/0cNlEUu7ZetJKL85ylzLNb5Q3A0OAx4UtkTygFHkRZOK28kfCBWWnQzbs0ylD0IKOMQfGUqO5yItj7r/gbXTPe86Hdp35dBaddUBXhz8yDsr+ih++9/wXd/3mcCwtPKPgvwmYCnlD04axmyRTm/UHnS2Xd8hvp8BmBdwvCfkezzAOv8DmGNBK+ca5oC3B725uvyzre4HEr3JNdzmyrEV+sITyd77Wiu/wh8G5Q5py+ZHspVlmdDD0OedVhXgPWrJNvzJa47/7tSc8FANM41TQG2J+am5gtHymwJeM/xeGJRFm1vzD0krUcBaaQhgTwd0upEaLIKkMQQL+pbNnvTz8qeJqs/7WKea01UQJ52qyQR8vpUyukrxIv6Eq6MUC4rO6RV4i+rAkbJcC4eTSsSVwFlZRSpL83bFgWkHVq2QKeAmjXWKaBTQM0M1Fx9NwI6BdTMQM3VdyOgU0DNDNRc/XKOgJpJm2f1nQLmyWaErE4BEaTNs0ingHmyGSGrU0AEafMsogJK/cRmno1ZQVl7OgXUq/VdKsBfANbbjNWtPVGA/zlidSmot+c7HAEX1NuGla79gnX9ft+XW3fT0OLt4Ha5dwRYtf/aQ38KuktzZsAfmO97VQGa8EfHjoQ519GJm8CAPwpPjD6MAPP9zI8OC2HAY5ZJRakCGAXeB5JhkVzpPqpi4ES4TqzfClIFGAEeQu2WpRBRkXOal+NU/JAC0IzbEt/nqhnxOjdHBuR0y4DjVOyQAkwlQ5KRsD5eY52n2ULjYg70hrL6fT6yMrKyuVTaOatI/n6c7qcAqxoowReZLss9wZ80je2L/ckBFaCMHFkLZ5HDseQraWKjUcIe8EsyuTraT3Ok1+0kLbThKQK+uQovyr1OKV/ahJe4rOwkIeJDzjbLIXBqHytiogJCbgpvA18kriIcSgQb4zwRnby4mxb5PwTwopxlfUmUilBmlJBBIVeTW+UM+CavQfJ4b6YCQjGEqQinJZXhT3n8T0UqZKJ2Q9kKfa1ey3UESF5sVZb1lWe+/cp3FaVyZgTsu5buF1k52QRPTjfpMnNG+d67AAAA///vdBW6AAAABklEQVQDAJAXvRKwmZ6CAAAAAElFTkSuQmCC"/>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 930 KiB |
|
Before Width: | Height: | Size: 262 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 198 KiB |
@@ -1,10 +0,0 @@
|
|||||||
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_226_195)">
|
|
||||||
<path d="M-0.00195312 1.4335C-0.00195312 0.641696 0.656004 0 1.46782 0H18.5422C19.354 0 20.0119 0.641696 20.0119 1.4335V18.5804C20.0119 19.3722 19.354 20.0139 18.5422 20.0139H1.46782C0.656004 20.0139 -0.00195312 19.3722 -0.00195312 18.5804V1.4335ZM6.18109 16.7541V7.71661H3.17776V16.7541H6.18109ZM4.68005 6.482C5.72703 6.482 6.37873 5.78902 6.37873 4.92092C6.35996 4.03405 5.72828 3.35983 4.70006 3.35983C3.67185 3.35983 3.00013 4.0353 3.00013 4.92092C3.00013 5.78902 3.65183 6.482 4.66003 6.482H4.68005ZM10.8193 16.7541V11.7069C10.8193 11.4367 10.8393 11.1665 10.9194 10.9739C11.1358 10.4347 11.6299 9.87561 12.4605 9.87561C13.5475 9.87561 13.9815 10.7037 13.9815 11.9195V16.7541H16.9848V11.5705C16.9848 8.79361 15.5038 7.50271 13.5274 7.50271C11.9338 7.50271 11.2196 8.37832 10.8193 8.995V9.02627H10.7993L10.8193 8.995V7.71661H7.81723C7.85475 8.5647 7.81723 16.7541 7.81723 16.7541H10.8193Z" fill="white"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_226_195">
|
|
||||||
<rect width="20.0139" height="20.0139" rx="1.55252" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,12 +0,0 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_226_203)">
|
|
||||||
<path d="M20 17C20 18.6569 18.6569 20 17 20H3C1.34307 20 0 18.6569 0 17V3C0 1.34313 1.34313 0 3 0H17C18.6569 0 20 1.34313 20 3V17Z" fill="white"/>
|
|
||||||
<path d="M13.3881 7.45803C11.7739 7.54236 10.3702 8.03169 9.2306 9.13723C8.0792 10.2542 7.55366 11.6228 7.69726 13.3195C7.06633 13.2414 6.49166 13.1554 5.91373 13.1067C5.71413 13.0899 5.47726 13.1138 5.3082 13.2092C4.747 13.5258 4.20906 13.8834 3.57133 14.282C3.68833 13.7528 3.76406 13.2894 3.89813 12.8437C3.99673 12.5161 3.95106 12.3338 3.64926 12.1204C1.71153 10.7523 0.894728 8.70496 1.50599 6.59703C2.07153 4.64703 3.46033 3.46443 5.3474 2.84796C7.92313 2.00663 10.8177 2.86483 12.3839 4.90976C12.9495 5.64843 13.2964 6.47749 13.3881 7.45803ZM5.95893 6.80123C5.9738 6.41569 5.63973 6.06836 5.24293 6.05676C4.83666 6.04483 4.50253 6.35529 4.49066 6.75563C4.47866 7.16136 4.789 7.48649 5.1982 7.49689C5.60386 7.50716 5.94393 7.19629 5.95893 6.80123ZM9.835 6.05649C9.43673 6.06383 9.1002 6.40303 9.10726 6.79009C9.11453 7.19129 9.44466 7.50516 9.8542 7.50023C10.2648 7.49529 10.5762 7.17809 10.5723 6.76843C10.5689 6.36629 10.2403 6.04909 9.835 6.05649Z" fill="#232323"/>
|
|
||||||
<path d="M17.0146 17.5216C16.5035 17.294 16.0346 16.9525 15.5354 16.9004C15.0381 16.8484 14.5154 17.1353 13.9951 17.1885C12.4104 17.3506 10.9907 16.909 9.82001 15.8264C7.59355 13.767 7.91168 10.6094 10.4876 8.92184C12.777 7.42197 16.1345 7.92197 17.7487 10.0031C19.1573 11.8191 18.9917 14.2298 17.2721 15.7554C16.7745 16.1969 16.5955 16.5602 16.9148 17.1423C16.9737 17.2498 16.9804 17.3858 17.0146 17.5216ZM11.1963 11.8883C11.5217 11.8886 11.7897 11.634 11.802 11.3126C11.815 10.9723 11.5413 10.6869 11.2006 10.6855C10.8632 10.684 10.5806 10.9734 10.5924 11.3086C10.6035 11.6288 10.8733 11.8879 11.1963 11.8883ZM14.9471 10.6868C14.6314 10.6846 14.3631 10.9431 14.3502 11.2621C14.3365 11.6032 14.6017 11.8834 14.9393 11.8842C15.2658 11.8854 15.5239 11.6384 15.5357 11.3134C15.5483 10.9715 15.2831 10.6892 14.9471 10.6868Z" fill="#232323"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_226_203">
|
|
||||||
<rect width="20" height="20" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 811 B |
BIN
src/assets/images/test.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
@@ -1,69 +1,64 @@
|
|||||||
import {
|
import { createRouter, createWebHistory, RouteRecordRaw, createWebHashHistory } from "vue-router"
|
||||||
createRouter,
|
import store from "@/store"
|
||||||
createWebHistory,
|
import { Https } from "@/tool/https"
|
||||||
RouteRecordRaw,
|
import { getCookie, setCookie } from "@/tool/cookie"
|
||||||
createWebHashHistory,
|
|
||||||
} from "vue-router";
|
|
||||||
import store from "@/store";
|
|
||||||
import { Https } from "@/tool/https";
|
|
||||||
import { getCookie, setCookie } from "@/tool/cookie";
|
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
// redirect重定向
|
// redirect重定向
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
redirect: "/Square",
|
redirect: "/Square"
|
||||||
// redirect: "/upgrade"
|
// redirect: "/upgrade"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Login.vue"),
|
component: () => import("@/views/Login.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/canvasExample",
|
path: "/canvasExample",
|
||||||
name: "canvasExample",
|
name: "canvasExample",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/component/Canvas/canvasExample.vue"),
|
component: () => import("@/component/Canvas/canvasExample.vue")
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/schoolLogin",
|
path: "/schoolLogin",
|
||||||
name: "schoolLogin",
|
name: "schoolLogin",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Login.vue"), // 使用通用登录组件
|
component: () => import("@/views/Login.vue") // 使用通用登录组件
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/enterpriseLogin",
|
path: "/enterpriseLogin",
|
||||||
name: "enterpriseLogin",
|
name: "enterpriseLogin",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Login.vue"), // 使用通用登录组件
|
component: () => import("@/views/Login.vue") // 使用通用登录组件
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/test",
|
path: "/test",
|
||||||
name: "test1",
|
name: "test1",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/test.vue"),
|
component: () => import("@/views/test.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/register",
|
path: "/register",
|
||||||
name: "register",
|
name: "register",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Register.vue"),
|
component: () => import("@/views/Register.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/register/:lang",
|
path: "/register/:lang",
|
||||||
name: "registerLang",
|
name: "registerLang",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Register.vue"),
|
component: () => import("@/views/Register.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/upgrade",
|
path: "/upgrade",
|
||||||
name: "upgrade",
|
name: "upgrade",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/Upgrade.vue"),
|
component: () => import("@/views/Upgrade.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/home",
|
path: "/home",
|
||||||
@@ -74,8 +69,8 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: "tools",
|
path: "tools",
|
||||||
name: "tools",
|
name: "tools",
|
||||||
meta: { enter: "all",cache:true },
|
meta: { enter: "all", cache: true },
|
||||||
component: () => import("@/views/HomeView/Tools.vue"),
|
component: () => import("@/views/HomeView/Tools.vue")
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// path: "homePage",
|
// path: "homePage",
|
||||||
@@ -87,13 +82,13 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
path: "library",
|
path: "library",
|
||||||
name: "library",
|
name: "library",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeView/library.vue"),
|
component: () => import("@/views/HomeView/library.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "history",
|
path: "history",
|
||||||
name: "history",
|
name: "history",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeView/history.vue"),
|
component: () => import("@/views/HomeView/history.vue")
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// path: "history/:type/:id",
|
// path: "history/:type/:id",
|
||||||
@@ -104,32 +99,32 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: "history/:id",
|
path: "history/:id",
|
||||||
name: "designPage",
|
name: "designPage",
|
||||||
meta: { enter: "all",cache:true },
|
meta: { enter: "all", cache: true },
|
||||||
component: () => import("@/component/home/design/index.vue"),
|
component: () => import("@/component/home/design/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "works",
|
path: "works",
|
||||||
name: "works",
|
name: "works",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeView/Works.vue"),
|
component: () => import("@/views/HomeView/Works.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "events",
|
path: "events",
|
||||||
name: "events",
|
name: "events",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeView/Events.vue"),
|
component: () => import("@/views/HomeView/Events.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "cloud",
|
path: "cloud",
|
||||||
name: "cloud",
|
name: "cloud",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeView/cloudGeneration.vue"),
|
component: () => import("@/views/HomeView/cloudGeneration.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "eventsDetail",
|
path: "eventsDetail",
|
||||||
name: "eventsDetail",
|
name: "eventsDetail",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/component/Events/eventsDetail.vue"),
|
component: () => import("@/component/Events/eventsDetail.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "account",
|
path: "account",
|
||||||
@@ -141,105 +136,114 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
path: "",
|
path: "",
|
||||||
name: "accountChil",
|
name: "accountChil",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
redirect: "/home/account/frontPage",
|
redirect: "/home/account/frontPage"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "frontPage",
|
path: "frontPage",
|
||||||
name: "frontPage",
|
name: "frontPage",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/component/Account/frontPage.vue"),
|
component: () => import("@/component/Account/frontPage.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "accountMessage",
|
path: "accountMessage",
|
||||||
name: "accountMessage",
|
name: "accountMessage",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/component/Account/accountMessage.vue"),
|
component: () => import("@/component/Account/accountMessage.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "accountFollowFans",
|
path: "accountFollowFans",
|
||||||
name: "accountFollowFans",
|
name: "accountFollowFans",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () =>
|
component: () => import("@/component/Account/accountFollowFans.vue")
|
||||||
import("@/component/Account/accountFollowFans.vue"),
|
}
|
||||||
},
|
]
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "otherUsers",
|
path: "otherUsers",
|
||||||
name: "otherUsers",
|
name: "otherUsers",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/component/Account/otherUsers.vue"),
|
component: () => import("@/component/Account/otherUsers.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "becomeSeller",
|
path: "becomeSeller",
|
||||||
name: "becomeSeller",
|
name: "becomeSeller",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/BecomeSeller/index.vue"),
|
component: () => import("@/views/SellerDashboard/BecomeSeller/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "seller",
|
path: "seller",
|
||||||
name: "seller",
|
name: "seller",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/index.vue"),
|
component: () => import("@/views/SellerDashboard/index.vue"),
|
||||||
children:[
|
children: [
|
||||||
{
|
{
|
||||||
path: "brandProfile",
|
path: "brandProfile",
|
||||||
name: "brandProfile",
|
name: "brandProfile",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "myListings",
|
path: "myListings",
|
||||||
name: "myListings",
|
name: "myListings",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
children:[
|
children: [
|
||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
name: "myListingsChild",
|
name: "myListingsChild",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
redirect: "/home/seller/myListings/index",
|
redirect: "/home/seller/myListings/index"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "index",
|
path: "index",
|
||||||
name: "myListingsIndex",
|
name: "myListingsIndex",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/MyListings/index.vue"),
|
component: () =>
|
||||||
|
import("@/views/SellerDashboard/MyListings/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "select",
|
path: "select",
|
||||||
name: "myListingsSelect",
|
name: "myListingsSelect",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/MyListingCreateSelect/index.vue"),
|
component: () =>
|
||||||
|
import("@/views/SellerDashboard/MyListingCreateSelect/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "select/:id",
|
path: "select/:id",
|
||||||
name: "myListingsSelectItem",
|
name: "myListingsSelectItem",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/MyListingCreateSelectItem/index.vue"),
|
component: () =>
|
||||||
|
import("@/views/SellerDashboard/MyListingCreateSelectItem/index.vue")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "edit-detail",
|
||||||
|
name: "EditDetail",
|
||||||
|
meta: { enter: "all" },
|
||||||
|
component: () =>
|
||||||
|
import("@/views/SellerDashboard/MyListings/EditDetail/index.vue")
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "myOrders",
|
path: "myOrders",
|
||||||
name: "myOrders",
|
name: "myOrders",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: "settings",
|
||||||
name: "settings",
|
name: "settings",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue")
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/Square",
|
path: "/Square",
|
||||||
name: "HomeRecommend",
|
name: "HomeRecommend",
|
||||||
meta: { enter: "all" },
|
meta: { enter: "all" },
|
||||||
component: () => import("@/views/HomeRecommend.vue"),
|
component: () => import("@/views/HomeRecommend.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/administrator",
|
path: "/administrator",
|
||||||
@@ -251,165 +255,157 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
path: "allUser",
|
path: "allUser",
|
||||||
name: "allUser",
|
name: "allUser",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/allUser.vue"),
|
component: () => import("@/component/Administrator/allUser.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "coupons",
|
path: "coupons",
|
||||||
name: "coupons",
|
name: "coupons",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/coupons/index.vue"),
|
component: () => import("@/component/Administrator/coupons/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "testClickData",
|
path: "testClickData",
|
||||||
name: "testClickData",
|
name: "testClickData",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/TestClickData.vue"),
|
component: () => import("@/component/Administrator/TestClickData.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "trialApproval",
|
path: "trialApproval",
|
||||||
name: "trialApproval",
|
name: "trialApproval",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/trialApproval.vue"),
|
component: () => import("@/component/Administrator/trialApproval.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "questionnaire",
|
path: "questionnaire",
|
||||||
name: "questionnaire",
|
name: "questionnaire",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/questionnaire.vue"),
|
component: () => import("@/component/Administrator/questionnaire.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentActiveChart",
|
path: "recentActiveChart",
|
||||||
name: "recentActiveChart",
|
name: "recentActiveChart",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/recentActiveChart.vue")
|
||||||
import("@/component/Administrator/recentActiveChart.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentActiveUser",
|
path: "recentActiveUser",
|
||||||
name: "recentActiveUser",
|
name: "recentActiveUser",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/recentActiveUser.vue")
|
||||||
import("@/component/Administrator/recentActiveUser.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentActiveUserChart",
|
path: "recentActiveUserChart",
|
||||||
name: "recentActiveUserChart",
|
name: "recentActiveUserChart",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/recentActiveUserChart.vue")
|
||||||
import("@/component/Administrator/recentActiveUserChart.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentNewUser",
|
path: "recentNewUser",
|
||||||
name: "recentNewUser",
|
name: "recentNewUser",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/recentNewUser.vue"),
|
component: () => import("@/component/Administrator/recentNewUser.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentNewUserChart",
|
path: "recentNewUserChart",
|
||||||
name: "recentNewUserChart",
|
name: "recentNewUserChart",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/recentNewUserChart.vue")
|
||||||
import("@/component/Administrator/recentNewUserChart.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "trialUserCountry",
|
path: "trialUserCountry",
|
||||||
name: "trialUserCountry",
|
name: "trialUserCountry",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/trialUserCountry.vue")
|
||||||
import("@/component/Administrator/trialUserCountry.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "trialUserConversionRateChart",
|
path: "trialUserConversionRateChart",
|
||||||
name: "trialUserConversionRateChart",
|
name: "trialUserConversionRateChart",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/component/Administrator/trialUserConversionRateChart.vue"),
|
import("@/component/Administrator/trialUserConversionRateChart.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "trialAllUser",
|
path: "trialAllUser",
|
||||||
name: "trialAllUser",
|
name: "trialAllUser",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () => import("@/component/Administrator/trialAllUser.vue"),
|
component: () => import("@/component/Administrator/trialAllUser.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "affiliateAudit",
|
path: "affiliateAudit",
|
||||||
name: "affiliateAudit",
|
name: "affiliateAudit",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>import("@/component/Administrator/affiliate/affiliateAudit/affiliateAudit.vue"),
|
component: () =>
|
||||||
|
import("@/component/Administrator/affiliate/affiliateAudit/affiliateAudit.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "affiliateReferral",
|
path: "affiliateReferral",
|
||||||
name: "affiliateReferral",
|
name: "affiliateReferral",
|
||||||
meta: {
|
meta: {
|
||||||
enter: 3,
|
enter: 3
|
||||||
},
|
},
|
||||||
component: () =>import("@/component/Administrator/affiliate/affiliateReferral/index.vue"),
|
component: () =>
|
||||||
|
import("@/component/Administrator/affiliate/affiliateReferral/index.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "TransactionTable",
|
path: "TransactionTable",
|
||||||
name: "TransactionTable",
|
name: "TransactionTable",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/component/Administrator/Transaction/TransactionTable.vue"),
|
import("@/component/Administrator/Transaction/TransactionTable.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "organization",
|
path: "organization",
|
||||||
name: "organization",
|
name: "organization",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/organization/organization.vue")
|
||||||
import("@/component/Administrator/organization/organization.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "subscriptionPlan",
|
path: "subscriptionPlan",
|
||||||
name: "subscriptionPlan",
|
name: "subscriptionPlan",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/subscriptionPlan.vue")
|
||||||
import("@/component/Administrator/subscriptionPlan.vue"),
|
|
||||||
},
|
},
|
||||||
//企业版教育管理员页面
|
//企业版教育管理员页面
|
||||||
{
|
{
|
||||||
path: "allUserSE",
|
path: "allUserSE",
|
||||||
name: "allUserSE",
|
name: "allUserSE",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/SE/allUser/index.vue")
|
||||||
import("@/component/Administrator/SE/allUser/index.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "testClickDataSE",
|
path: "testClickDataSE",
|
||||||
name: "testClickDataSE",
|
name: "testClickDataSE",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/SE/designDetailList/index.vue")
|
||||||
import("@/component/Administrator/SE/designDetailList/index.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "recentActiveChartSE",
|
path: "recentActiveChartSE",
|
||||||
name: "recentActiveChartSE",
|
name: "recentActiveChartSE",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () => import("@/component/Administrator/SE/recentActiveChart.vue")
|
||||||
import("@/component/Administrator/SE/recentActiveChart.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "generateFrequencySE",
|
path: "generateFrequencySE",
|
||||||
name: "generateFrequencySE",
|
name: "generateFrequencySE",
|
||||||
meta: { enter: 3 },
|
meta: { enter: 3 },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/component/Administrator/SE/getGenerateFrequency/index.vue"),
|
import("@/component/Administrator/SE/getGenerateFrequency/index.vue")
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/paySucceed",
|
path: "/paySucceed",
|
||||||
name: "paySucceed",
|
name: "paySucceed",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/paySucceed.vue"),
|
component: () => import("@/views/paySucceed.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/affiliate",
|
path: "/affiliate",
|
||||||
name: "affiliate",
|
name: "affiliate",
|
||||||
meta: {
|
meta: {
|
||||||
enter: 2,
|
enter: 2
|
||||||
},
|
},
|
||||||
component: () => import("@/views/affiliate/affiliatePage.vue"),
|
component: () => import("@/views/affiliate/affiliatePage.vue"),
|
||||||
children: [
|
children: [
|
||||||
@@ -417,114 +413,90 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
path: "",
|
path: "",
|
||||||
name: "defaultAffiliateHome",
|
name: "defaultAffiliateHome",
|
||||||
meta: {
|
meta: {
|
||||||
enter: 2,
|
enter: 2
|
||||||
},
|
},
|
||||||
component: () => import("@/component/affiliate/home.vue"),
|
component: () => import("@/component/affiliate/home.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/affiliateHome",
|
path: "/affiliateHome",
|
||||||
name: "affiliateHome",
|
name: "affiliateHome",
|
||||||
meta: {
|
meta: {
|
||||||
enter: 2,
|
enter: 2
|
||||||
},
|
},
|
||||||
component: () => import("@/component/affiliate/home.vue"),
|
component: () => import("@/component/affiliate/home.vue")
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/affiliateRegister",
|
path: "/affiliateRegister",
|
||||||
name: "affiliateRegister",
|
name: "affiliateRegister",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/affiliate/affiliateRegister.vue"),
|
component: () => import("@/views/affiliate/affiliateRegister.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/feedbackSurvey",
|
path: "/feedbackSurvey",
|
||||||
name: "feedbackSurvey",
|
name: "feedbackSurvey",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/feedbackSurvey.vue"),
|
component: () => import("@/views/feedbackSurvey.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/feedbackSurveyCN",
|
path: "/feedbackSurveyCN",
|
||||||
name: "feedbackSurveyCN",
|
name: "feedbackSurveyCN",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/feedbackSurveyCN.vue"),
|
component: () => import("@/views/feedbackSurveyCN.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/email3-1EN",
|
path: "/email3-1EN",
|
||||||
name: "email3-1EN",
|
name: "email3-1EN",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/emailPage/email3-1EN.vue"),
|
component: () => import("@/views/emailPage/email3-1EN.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/email3-1CN",
|
path: "/email3-1CN",
|
||||||
name: "email3-1CN",
|
name: "email3-1CN",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/emailPage/email3-1CN.vue"),
|
component: () => import("@/views/emailPage/email3-1CN.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/404",
|
path: "/404",
|
||||||
name: "404",
|
name: "404",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/404.vue"),
|
component: () => import("@/views/404.vue")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/userManual",
|
path: "/userManual",
|
||||||
name: "userManual",
|
name: "userManual",
|
||||||
meta: {
|
meta: {
|
||||||
enter: "all",
|
enter: "all"
|
||||||
},
|
},
|
||||||
component: () => import("@/views/userManual.vue"),
|
component: () => import("@/views/userManual.vue")
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/award",
|
|
||||||
name: "award",
|
|
||||||
meta: {
|
|
||||||
enter: "all",
|
|
||||||
},
|
|
||||||
component: () => import("@/views/AwardPage/container.vue"),
|
|
||||||
children:[
|
|
||||||
{
|
|
||||||
path:'',
|
|
||||||
name:'AwardIndex',
|
|
||||||
component:()=>import('@/views/AwardPage/index.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path:'index',
|
|
||||||
name:'AwardIndexAlt',
|
|
||||||
component:()=>import('@/views/AwardPage/index.vue')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path:'contestants',
|
|
||||||
name:'Contestants',
|
|
||||||
component:()=>import('@/views/AwardPage/apply.vue')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/:catchAll(.*)",
|
path: "/:catchAll(.*)",
|
||||||
redirect: "/404",
|
redirect: "/404"
|
||||||
},
|
}
|
||||||
];
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
// history: createWebHashHistory(),
|
// history: createWebHashHistory(),
|
||||||
routes,
|
routes
|
||||||
});
|
})
|
||||||
// 刷新保存数据-
|
// 刷新保存数据-
|
||||||
let state: any = store.state;
|
let state: any = store.state
|
||||||
// window.addEventListener("beforeunload", (e) => {
|
// window.addEventListener("beforeunload", (e) => {
|
||||||
// localStorage.setItem(
|
// localStorage.setItem(
|
||||||
// "vuex_setUserDetail",
|
// "vuex_setUserDetail",
|
||||||
@@ -540,114 +512,110 @@ let state: any = store.state;
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
let setMurmur = (id: any) => {
|
let setMurmur = (id: any) => {
|
||||||
let murmurStr: any = localStorage.getItem("murmurStr");
|
let murmurStr: any = localStorage.getItem("murmurStr")
|
||||||
// let isSxis = false
|
// let isSxis = false
|
||||||
let data = {
|
let data = {
|
||||||
browserIdentifiers: murmurStr,
|
browserIdentifiers: murmurStr,
|
||||||
id: id,
|
id: id
|
||||||
};
|
}
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
Https.axiosPost(Https.httpUrls.noLoginRequired, data)
|
Https.axiosPost(Https.httpUrls.noLoginRequired, data)
|
||||||
.then((rv) => {
|
.then((rv) => {
|
||||||
let isTest = rv.systemUser == 3 ? true : false;
|
let isTest = rv.systemUser == 3 ? true : false
|
||||||
let isBeginner = rv?.isBeginner == 1 ? true : false;
|
let isBeginner = rv?.isBeginner == 1 ? true : false
|
||||||
setCookie("isMurmur", true);
|
setCookie("isMurmur", true)
|
||||||
setCookie("token", rv.token);
|
setCookie("token", rv.token)
|
||||||
setCookie("isTest", isTest);
|
setCookie("isTest", isTest)
|
||||||
setCookie("isBeginner", isBeginner);
|
setCookie("isBeginner", isBeginner)
|
||||||
setCookie("isBeginnerNum", 0); //从第一步开始,机器人开始的话就是从第二部开始
|
setCookie("isBeginnerNum", 0) //从第一步开始,机器人开始的话就是从第二部开始
|
||||||
setCookie("userInfo", JSON.stringify(rv));
|
setCookie("userInfo", JSON.stringify(rv))
|
||||||
let userid = {
|
let userid = {
|
||||||
ueserId: rv.userId,
|
ueserId: rv.userId,
|
||||||
systemUser: rv.systemUser,
|
systemUser: rv.systemUser
|
||||||
};
|
}
|
||||||
store.commit("upUserDetail", userid);
|
store.commit("upUserDetail", userid)
|
||||||
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
|
sessionStorage.setItem("isTimeOne", JSON.stringify(false)) //是否需要公告 提示 弹窗
|
||||||
let randomNum: any =
|
let randomNum: any = Math.floor(Math.random() * 9000000000000000) + 1000000000000000
|
||||||
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
|
sessionStorage.setItem("sessionId", randomNum)
|
||||||
sessionStorage.setItem("sessionId", randomNum);
|
router.push("/home")
|
||||||
router.push("/home");
|
|
||||||
})
|
})
|
||||||
.catch((res) => {
|
.catch((res) => {
|
||||||
// router.push('/Square')
|
// router.push('/Square')
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const setViewsIncrease = (value: any) => {
|
const setViewsIncrease = (value: any) => {
|
||||||
sessionStorage.setItem("affiliateRef", value);
|
sessionStorage.setItem("affiliateRef", value)
|
||||||
let data = {
|
let data = {
|
||||||
id: value,
|
id: value
|
||||||
};
|
}
|
||||||
Https.axiosGet(Https.httpUrls.viewsIncrease, { params: data }).then(
|
Https.axiosGet(Https.httpUrls.viewsIncrease, { params: data }).then((rv) => {})
|
||||||
(rv) => {}
|
}
|
||||||
);
|
let upgradeList = ["/feedbackSurvey", "/feedbackSurveyCN", "emailVerify"] //指定页面系统维护也可以访问
|
||||||
};
|
|
||||||
let upgradeList = ["/feedbackSurvey", "/feedbackSurveyCN", "emailVerify"]; //指定页面系统维护也可以访问
|
|
||||||
function isTimeRangePassed(timeRange) {
|
function isTimeRangePassed(timeRange) {
|
||||||
const [startStr, endStr] = timeRange.split(' - ');
|
const [startStr, endStr] = timeRange.split(" - ")
|
||||||
const startTime = new Date(startStr).getTime();
|
const startTime = new Date(startStr).getTime()
|
||||||
const endTime = new Date(endStr).getTime();
|
const endTime = new Date(endStr).getTime()
|
||||||
const currentTime = new Date().getTime();
|
const currentTime = new Date().getTime()
|
||||||
|
|
||||||
if (currentTime < startTime) {
|
if (currentTime < startTime) {
|
||||||
return 'not_started'; // 未开始
|
return "not_started" // 未开始
|
||||||
} else if (currentTime >= startTime && currentTime <= endTime) {
|
} else if (currentTime >= startTime && currentTime <= endTime) {
|
||||||
return 'in_progress'; // 进行中
|
return "in_progress" // 进行中
|
||||||
} else {
|
} else {
|
||||||
return 'ended'; // 已结束
|
return "ended" // 已结束
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
router.beforeEach((to: any, from, next) => {
|
router.beforeEach((to: any, from, next) => {
|
||||||
store.commit("set_view_loading", true);
|
store.commit("set_view_loading", true)
|
||||||
//系统维护时间
|
//系统维护时间
|
||||||
const time = '2026-01-23T21:00:00 - 2026-01-23T22:00:00';
|
const time = "2026-01-23T21:00:00 - 2026-01-23T22:00:00"
|
||||||
if (isTimeRangePassed(time) == 'in_progress') {
|
if (isTimeRangePassed(time) == "in_progress") {
|
||||||
// 系统维护
|
// 系统维护
|
||||||
const toName = to.name === 'upgrade';
|
const toName = to.name === "upgrade"
|
||||||
if(to.query.status == 'admin'){
|
if (to.query.status == "admin") {
|
||||||
localStorage.setItem('isAdminVisit', 'true')
|
localStorage.setItem("isAdminVisit", "true")
|
||||||
}
|
}
|
||||||
const isAdminVisit = localStorage.getItem('isAdminVisit') == 'true'
|
const isAdminVisit = localStorage.getItem("isAdminVisit") == "true"
|
||||||
if(upgradeList.indexOf(to.path) > -1 || isAdminVisit){
|
if (upgradeList.indexOf(to.path) > -1 || isAdminVisit) {
|
||||||
next();
|
next()
|
||||||
}else{
|
} else {
|
||||||
if (toName) {
|
if (toName) {
|
||||||
next();
|
next()
|
||||||
} else {
|
} else {
|
||||||
next({ name: 'upgrade' });
|
next({ name: "upgrade" })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem('isAdminVisit', 'false')
|
localStorage.setItem("isAdminVisit", "false")
|
||||||
|
|
||||||
// 机房用户
|
// 机房用户
|
||||||
let herfData = window.location.search.substring(1);
|
let herfData = window.location.search.substring(1)
|
||||||
if (herfData.split("=")[0] == "noLogin" && to.name != "homePage") {
|
if (herfData.split("=")[0] == "noLogin" && to.name != "homePage") {
|
||||||
setMurmur(herfData.split("=")[1]);
|
setMurmur(herfData.split("=")[1])
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let affiliateRef = sessionStorage.getItem("affiliateRef");
|
let affiliateRef = sessionStorage.getItem("affiliateRef")
|
||||||
if (to.query.order) sessionStorage.setItem("orderId", to.query.order); //记录是否点击跳转订单链接
|
if (to.query.order) sessionStorage.setItem("orderId", to.query.order) //记录是否点击跳转订单链接
|
||||||
if (to.query.ref && affiliateRef != to.query.ref)
|
if (to.query.ref && affiliateRef != to.query.ref) setViewsIncrease(to.query.ref)
|
||||||
setViewsIncrease(to.query.ref);
|
|
||||||
|
|
||||||
var vuex_systemList: any = sessionStorage.getItem("vuex_systemList");
|
var vuex_systemList: any = sessionStorage.getItem("vuex_systemList")
|
||||||
if (to.meta.enter == "all") {
|
if (to.meta.enter == "all") {
|
||||||
next();
|
next()
|
||||||
} else if (
|
} else if (
|
||||||
(state.UserHabit?.userDetail?.systemList?.indexOf(to.meta.enter) > -1) || (vuex_systemList?.indexOf(to.meta.enter))
|
state.UserHabit?.userDetail?.systemList?.indexOf(to.meta.enter) > -1 ||
|
||||||
|
vuex_systemList?.indexOf(to.meta.enter)
|
||||||
) {
|
) {
|
||||||
next();
|
next()
|
||||||
} else {
|
} else {
|
||||||
next("/404");
|
next("/404")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if(systemUser == 0){//游客用户只能进入这两个页面
|
// if(systemUser == 0){//游客用户只能进入这两个页面
|
||||||
});
|
})
|
||||||
router.afterEach((to, from) => {
|
router.afterEach((to, from) => {
|
||||||
store.commit("set_view_loading", false);
|
store.commit("set_view_loading", false)
|
||||||
});
|
})
|
||||||
export default router;
|
export default router
|
||||||
|
|||||||
@@ -1,529 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="apply-container flex flex-col"
|
|
||||||
id="apply"
|
|
||||||
ref="applyRef"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="title animation-element"
|
|
||||||
ref="applyTitleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.howToApply') }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="sub-title animation-element"
|
|
||||||
ref="applySubTitleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.stepByStep') }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="requirments-list flex flex-col"
|
|
||||||
ref="reqListRef"
|
|
||||||
>
|
|
||||||
<div class="top flex">
|
|
||||||
<div
|
|
||||||
class="item-box animation-element"
|
|
||||||
v-for="(item, index) in leftRequirment"
|
|
||||||
:key="item.type"
|
|
||||||
:ref="el => { if(el) itemRefs[index] = el }"
|
|
||||||
:style="{ background: item.background || '#fff' }"
|
|
||||||
>
|
|
||||||
<div class="item-header flex flex-center">
|
|
||||||
<div class="item-title">{{ $t(item.type) }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="context-container flex flex-center">
|
|
||||||
<div
|
|
||||||
class="context"
|
|
||||||
v-for="el in item.desc"
|
|
||||||
>
|
|
||||||
{{ $t(el) }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="list"
|
|
||||||
v-if="item.listTitle"
|
|
||||||
>
|
|
||||||
<div class="list-title">{{ $t(item.listTitle) }}</div>
|
|
||||||
<ul class="list-items">
|
|
||||||
<li
|
|
||||||
class="list-item"
|
|
||||||
v-for="el in item.list"
|
|
||||||
>
|
|
||||||
{{ $t(el) }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="bottom flex">
|
|
||||||
<div class="step-3 flex flex-col animation-element" ref="step3Ref">
|
|
||||||
<div class="header">{{ $t('AwardsPage.step3Title') }}</div>
|
|
||||||
<div class="content flex">
|
|
||||||
<div class="content-left flex flex-col space-between">
|
|
||||||
<div class="content-item">
|
|
||||||
<div class="item-header flex align-center">
|
|
||||||
<div class="point"></div>
|
|
||||||
<div>{{ $t('AwardsPage.processVideo') }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="desc-wrapper flex flex-col space-between">
|
|
||||||
<div class="item-desc">
|
|
||||||
{{ $t('AwardsPage.processVideoDesc') }}
|
|
||||||
</div>
|
|
||||||
<ul class="desc-lists">
|
|
||||||
<div class="desc-lists-title">
|
|
||||||
{{ $t('AwardsPage.videoRequirements') }}
|
|
||||||
</div>
|
|
||||||
<li>{{ $t('AwardsPage.videoFormat') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.videoResolution') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.videoDuration') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.videoSize') }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content-item">
|
|
||||||
<div class="item-header flex align-center">
|
|
||||||
<div class="point"></div>
|
|
||||||
<div>{{ $t('AwardsPage.fileName') }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="item-desc indent">
|
|
||||||
{{ $t('AwardsPage.fileNameDesc') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content-right">
|
|
||||||
<div class="content-item flex flex-col">
|
|
||||||
<div class="item-header flex align-center">
|
|
||||||
<div class="point"></div>
|
|
||||||
<div>{{ $t('AwardsPage.designPortfolio') }}</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="desc-wrapper flex-1 flex flex-col space-between"
|
|
||||||
>
|
|
||||||
<ul class="desc-lists">
|
|
||||||
<div class="desc-lists-title">
|
|
||||||
<p>
|
|
||||||
{{ $t('AwardsPage.submitPdf') }}
|
|
||||||
</p>
|
|
||||||
<p>{{ $t('AwardsPage.requiredStructure') }}</p>
|
|
||||||
</div>
|
|
||||||
<li>{{ $t('AwardsPage.pdfDesignTitle') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.pdfMoodboard') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.pdfConcept') }}</li>
|
|
||||||
<div>{{ $t('AwardsPage.pdfConceptDesc') }}</div>
|
|
||||||
</ul>
|
|
||||||
<ul class="desc-lists">
|
|
||||||
<div class="desc-lists-title">
|
|
||||||
<p>{{ $t('AwardsPage.pdfRequirements') }}</p>
|
|
||||||
</div>
|
|
||||||
<li>{{ $t('AwardsPage.pdfMaxPages') }}</li>
|
|
||||||
<li>{{ $t('AwardsPage.pdfMaxSize') }}</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('AwardsPage.pdfLanguage') }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="step-4 animation-element" ref="step4Ref">
|
|
||||||
<div class="header flex flex-col flex-center">
|
|
||||||
<p>{{ $t('AwardsPage.step4Title') }}</p>
|
|
||||||
<p class="sub-title">{{ $t('AwardsPage.step4Subtitle') }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="content-item">
|
|
||||||
<div class="desc-wrapper flex-1 flex flex-col space-between">
|
|
||||||
<ul class="desc-lists">
|
|
||||||
<div class="desc-lists-title">
|
|
||||||
{{ $t('AwardsPage.step4Desc') }}
|
|
||||||
</div>
|
|
||||||
<li>{{ $t('AwardsPage.finalistPieces') }}</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('AwardsPage.finalistBasedOn') }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('AwardsPage.finalistShipping') }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const leftRequirment = ref([
|
|
||||||
{
|
|
||||||
type: 'AwardsPage.step1Title',
|
|
||||||
desc: ['AwardsPage.step1Desc']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'AwardsPage.step2Title',
|
|
||||||
desc: ['AwardsPage.step2Desc'],
|
|
||||||
listTitle: 'AwardsPage.step2ListTitle',
|
|
||||||
list: [
|
|
||||||
'AwardsPage.step2List[0]',
|
|
||||||
'AwardsPage.step2List[1]',
|
|
||||||
'AwardsPage.step2List[2]'
|
|
||||||
],
|
|
||||||
background: '#F9F9F9'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const applyRef = ref()
|
|
||||||
const applyTitleRef = ref()
|
|
||||||
const applySubTitleRef = ref()
|
|
||||||
const reqListRef = ref()
|
|
||||||
const itemRefs = ref<HTMLElement[]>([])
|
|
||||||
const step3Ref = ref()
|
|
||||||
const step4Ref = ref()
|
|
||||||
|
|
||||||
const hasPlayedAnim = ref(false)
|
|
||||||
let timeline: gsap.core.Timeline | null = null
|
|
||||||
|
|
||||||
let observer: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
const setupApplyInitialState = () => {
|
|
||||||
// 设置标题和副标题的初始状态
|
|
||||||
const titleEls = [applyTitleRef.value, applySubTitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
if (titleEls.length) {
|
|
||||||
gsap.set(titleEls, {
|
|
||||||
opacity: 0,
|
|
||||||
scale: 0,
|
|
||||||
transformOrigin: '50% 50%'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置步骤元素的初始状态
|
|
||||||
const allStepElements: HTMLElement[] = []
|
|
||||||
if (itemRefs.value && itemRefs.value.length > 0) {
|
|
||||||
allStepElements.push(...itemRefs.value)
|
|
||||||
}
|
|
||||||
if (step3Ref.value) {
|
|
||||||
allStepElements.push(step3Ref.value as HTMLElement)
|
|
||||||
}
|
|
||||||
if (step4Ref.value) {
|
|
||||||
allStepElements.push(step4Ref.value as HTMLElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allStepElements.length > 0) {
|
|
||||||
gsap.set(allStepElements, {
|
|
||||||
opacity: 0,
|
|
||||||
y: 50
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const initAnimations = () => {
|
|
||||||
if (hasPlayedAnim.value) return
|
|
||||||
|
|
||||||
timeline = gsap.timeline({
|
|
||||||
defaults: { ease: 'back.out(1.7)' }
|
|
||||||
})
|
|
||||||
|
|
||||||
if (applyTitleRef.value && applySubTitleRef.value) {
|
|
||||||
timeline.to([applyTitleRef.value, applySubTitleRef.value], {
|
|
||||||
scale: 1,
|
|
||||||
opacity: 1,
|
|
||||||
duration: 0.6,
|
|
||||||
stagger: 0.1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const allStepElements: HTMLElement[] = []
|
|
||||||
if (itemRefs.value && itemRefs.value.length > 0) {
|
|
||||||
allStepElements.push(...itemRefs.value)
|
|
||||||
}
|
|
||||||
if (step3Ref.value) {
|
|
||||||
allStepElements.push(step3Ref.value as HTMLElement)
|
|
||||||
}
|
|
||||||
if (step4Ref.value) {
|
|
||||||
allStepElements.push(step4Ref.value as HTMLElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allStepElements.length > 0) {
|
|
||||||
timeline.to(allStepElements, {
|
|
||||||
opacity: 1,
|
|
||||||
y: 0,
|
|
||||||
duration: 0.6,
|
|
||||||
stagger: 0.2
|
|
||||||
}, '>')
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPlayedAnim.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
setupApplyInitialState()
|
|
||||||
observer = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
initAnimations()
|
|
||||||
observer?.disconnect()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
threshold: 0.3,
|
|
||||||
rootMargin: '0px 0px -100px 0px'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Start observing the component root element
|
|
||||||
if (applyRef.value) {
|
|
||||||
observer.observe(applyRef.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
// Cleanup animation timeline
|
|
||||||
if (timeline) {
|
|
||||||
timeline.kill()
|
|
||||||
}
|
|
||||||
// Cleanup IntersectionObserver
|
|
||||||
if (observer) {
|
|
||||||
observer.disconnect()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.animation-element{
|
|
||||||
will-change: opacity transform;
|
|
||||||
}
|
|
||||||
.apply-container {
|
|
||||||
flex: 1;
|
|
||||||
height: 143.3rem;
|
|
||||||
background: url('@/assets/images/award/apply_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
padding: 12.7rem 21.4rem 12rem;
|
|
||||||
.title {
|
|
||||||
text-align: center;
|
|
||||||
color: #232323;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 4rem;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
.sub-title {
|
|
||||||
text-align: center;
|
|
||||||
color: #b10000;
|
|
||||||
font-size: 3rem;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
margin-bottom: 8.2rem;
|
|
||||||
}
|
|
||||||
.requirments-list {
|
|
||||||
flex: 1;
|
|
||||||
row-gap: 8.2rem;
|
|
||||||
.top {
|
|
||||||
height: 27.4rem;
|
|
||||||
color: #585858;
|
|
||||||
column-gap: 4.6rem;
|
|
||||||
.item-box {
|
|
||||||
height: 27.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-box {
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
&:nth-of-type(1) {
|
|
||||||
width: 47rem;
|
|
||||||
flex-grow: initial;
|
|
||||||
}
|
|
||||||
&:nth-of-type(2) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.item-header {
|
|
||||||
background-color: #424242;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
height: 7.8rem;
|
|
||||||
.item-title {
|
|
||||||
color: #fff;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
text-align: center;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.context-container {
|
|
||||||
margin-top: 4rem;
|
|
||||||
column-gap: 7rem;
|
|
||||||
.list {
|
|
||||||
font-family: 'Instrument';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.context {
|
|
||||||
// margin-top: 4rem;
|
|
||||||
// width: 46.8rem;
|
|
||||||
text-align: center;
|
|
||||||
color: #585858;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 3rem;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
// padding-left: 5.6rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.bottom {
|
|
||||||
column-gap: 4.6rem;
|
|
||||||
height: 63.4rem;
|
|
||||||
.step-3 {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.step-3,
|
|
||||||
.step-4 {
|
|
||||||
.header {
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
text-align: center;
|
|
||||||
height: 7.4rem;
|
|
||||||
line-height: 7.4rem;
|
|
||||||
color: #fff;
|
|
||||||
background-color: #b10000;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
padding: 4rem;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
column-gap: 6.4rem;
|
|
||||||
background: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
#ffe8e8 0%,
|
|
||||||
#feefef 25%,
|
|
||||||
#f9f9f9 100%
|
|
||||||
);
|
|
||||||
flex: 1;
|
|
||||||
.content-left {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-item {
|
|
||||||
.item-header {
|
|
||||||
column-gap: 2rem;
|
|
||||||
color: #585858;
|
|
||||||
font-family: 'InstrumentBold';
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
.point {
|
|
||||||
width: 1.2rem;
|
|
||||||
height: 1.2rem;
|
|
||||||
background-color: #b10000;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-desc {
|
|
||||||
font-family: 'Instrument';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
color: #585858;
|
|
||||||
&.indent {
|
|
||||||
padding-left: 3.8rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
padding-top: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.desc-wrapper {
|
|
||||||
margin-top: 3rem;
|
|
||||||
/* 基线行高变量,供子元素计算方块垂直偏移以对齐首行 */
|
|
||||||
--desc-line-height: 3rem;
|
|
||||||
font-family: 'Instrument';
|
|
||||||
font-weight: 400;
|
|
||||||
color: #585858;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
row-gap: 3rem;
|
|
||||||
.desc-lists {
|
|
||||||
/* 使用自定义方块代替浏览器 marker,保证大小为 1rem 并与文字垂直居中 */
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: none;
|
|
||||||
li {
|
|
||||||
list-style: none;
|
|
||||||
/* 使内容对齐到首行顶部,方块通过 margin-top 调整到首行中间 */
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 1rem;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0.4rem 0;
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
/* 固定为 1rem 方块 */
|
|
||||||
width: 0.5rem;
|
|
||||||
height: 0.5rem;
|
|
||||||
background-color: #585858;
|
|
||||||
flex: 0 0 0.5rem;
|
|
||||||
border-radius: 0;
|
|
||||||
/* 让方块垂直居中于第一行文字:(line-height - square)/2 */
|
|
||||||
margin-top: calc(
|
|
||||||
(var(--desc-line-height, 3rem) - 1rem) / 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.content-right {
|
|
||||||
.content-item {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.step-4 {
|
|
||||||
width: 45.1rem;
|
|
||||||
.header {
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
background-color: #424242;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
height: 7.8rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
line-height: 1.5;
|
|
||||||
.sub-title {
|
|
||||||
font-family: 'Poppins';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
color: #fff;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="bloom flex flex-col align-center">
|
|
||||||
<div
|
|
||||||
class="title"
|
|
||||||
ref="titleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.bloomYourCreativity') }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="season"
|
|
||||||
ref="subtitleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.themeOf2026') }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="desc"
|
|
||||||
ref="textRef"
|
|
||||||
>
|
|
||||||
<p class="section-1">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.regular1') }}
|
|
||||||
<span class="arial-bold">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.bold1') }}
|
|
||||||
</span>
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.regular2') }}
|
|
||||||
<span class="arial-bold">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.bold2') }}
|
|
||||||
</span>
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.regular3') }}
|
|
||||||
<span class="arial-bold">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.bold3') }}
|
|
||||||
</span>
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.regular4') }}
|
|
||||||
<span class="arial-bold">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.bold4') }}
|
|
||||||
</span>
|
|
||||||
{{ $t('AwardsPage.bloomText.desc1.regular5') }}
|
|
||||||
</p>
|
|
||||||
<p class="section-2">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc2.regular1') }}
|
|
||||||
<span class="arial-bold">
|
|
||||||
{{ $t('AwardsPage.bloomText.desc2.bold1') }}
|
|
||||||
</span>
|
|
||||||
{{ $t('AwardsPage.bloomText.desc2.regular2') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const titleRef = ref<HTMLElement | null>(null)
|
|
||||||
const subtitleRef = ref<HTMLElement | null>(null)
|
|
||||||
const textRef = ref<HTMLElement | null>(null)
|
|
||||||
|
|
||||||
const hasPlayedBloomAnim = ref(false)
|
|
||||||
let bloomObserver: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
const setupBloomInitialState = () => {
|
|
||||||
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
if (titleEls.length) {
|
|
||||||
gsap.set(titleEls, {
|
|
||||||
opacity: 0,
|
|
||||||
// start larger than final size, then animate down to scale:1
|
|
||||||
scale: 1.6,
|
|
||||||
transformOrigin: '50% 50%'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textRef.value) {
|
|
||||||
// start below and hidden
|
|
||||||
gsap.set(textRef.value, {
|
|
||||||
opacity: 0,
|
|
||||||
y: 60
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const playBloomAnimation = () => {
|
|
||||||
if (hasPlayedBloomAnim.value) return
|
|
||||||
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
const textEl = textRef.value
|
|
||||||
if (!titleEls.length || !textEl) return
|
|
||||||
|
|
||||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
|
||||||
|
|
||||||
tl.to(titleEls, {
|
|
||||||
opacity: 1,
|
|
||||||
scale: 1,
|
|
||||||
duration: 0.9,
|
|
||||||
ease: 'back.out(1.6)',
|
|
||||||
stagger: 0.12
|
|
||||||
})
|
|
||||||
|
|
||||||
tl.to(
|
|
||||||
textEl,
|
|
||||||
{
|
|
||||||
opacity: 1,
|
|
||||||
y: -12,
|
|
||||||
scale: 1.05,
|
|
||||||
duration: 0.3,
|
|
||||||
ease: 'power2.out'
|
|
||||||
},
|
|
||||||
'-=0.3'
|
|
||||||
)
|
|
||||||
tl.to(
|
|
||||||
textEl,
|
|
||||||
{
|
|
||||||
y: 0,
|
|
||||||
scale: 1,
|
|
||||||
duration: 0.18,
|
|
||||||
ease: 'bounce.out'
|
|
||||||
},
|
|
||||||
'+=0.08'
|
|
||||||
)
|
|
||||||
|
|
||||||
hasPlayedBloomAnim.value = true
|
|
||||||
bloomObserver?.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
setupBloomInitialState()
|
|
||||||
if ('IntersectionObserver' in window) {
|
|
||||||
bloomObserver = new IntersectionObserver(
|
|
||||||
entries => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
playBloomAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{ threshold: 0.3 }
|
|
||||||
)
|
|
||||||
if (titleRef.value) {
|
|
||||||
bloomObserver.observe(titleRef.value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// fallback
|
|
||||||
playBloomAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
bloomObserver?.disconnect()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.arial-bold {
|
|
||||||
font-family: 'ArialBold';
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.bloom {
|
|
||||||
height: 108rem;
|
|
||||||
padding-top: 12.8rem;
|
|
||||||
font-family: 'Poppins';
|
|
||||||
background: url('@/assets/images/award/bloom_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
.title {
|
|
||||||
font-size: 4rem;
|
|
||||||
color: #232323;
|
|
||||||
margin-bottom: 2.4rem;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
margin-bottom: 2.2rem;
|
|
||||||
}
|
|
||||||
.season {
|
|
||||||
font-size: 3rem;
|
|
||||||
color: #c7342c;
|
|
||||||
margin-bottom: 6.6rem;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
color: #585858;
|
|
||||||
text-align: center;
|
|
||||||
padding: 0 21.5rem;
|
|
||||||
line-height: 4.5rem;
|
|
||||||
margin-bottom: 12.3rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
.section-2 {
|
|
||||||
margin-top: 4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="judges-container flex flex-col align-center">
|
|
||||||
<div class="title" ref="judgesTitleRef">{{ $t('AwardsPage.panelOfJudges') }}</div>
|
|
||||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
|
||||||
<div class="sub-title" ref="judgesSubTitleRef">{{ $t('AwardsPage.expertise') }}</div>
|
|
||||||
<div class="judgement-list" ref="judgementListRef">
|
|
||||||
<div
|
|
||||||
class="judgement-item flex flex-col align-center"
|
|
||||||
v-for="item in judgements"
|
|
||||||
:key="item.name"
|
|
||||||
>
|
|
||||||
<img :src="item.picture" class="picture" />
|
|
||||||
<div class="name">{{ $t(item.name) }}</div>
|
|
||||||
<div class="desc">{{ $t(item.desc) }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { onBeforeUnmount, onMounted, nextTick, ref } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
import jae from '@/assets/images/award/jae.png'
|
|
||||||
import diego from '@/assets/images/award/diego.png'
|
|
||||||
import gregory from '@/assets/images/award/gregory.png'
|
|
||||||
import vincenzo from '@/assets/images/award/vincenzo.png'
|
|
||||||
import tim from '@/assets/images/award/tim.png'
|
|
||||||
import desmond from '@/assets/images/award/desmond.png'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const judgements = [
|
|
||||||
{
|
|
||||||
picture: jae,
|
|
||||||
name: 'Jae Hyuk Lim',
|
|
||||||
desc: 'AwardsPage.judgesHat.jae'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
picture: diego,
|
|
||||||
name: 'Diego Dultzin Lacoste',
|
|
||||||
desc: 'AwardsPage.judgesHat.diego'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
picture: gregory,
|
|
||||||
name: 'Gregory de la Hogue Moran',
|
|
||||||
desc: 'AwardsPage.judgesHat.gregory'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
picture: vincenzo,
|
|
||||||
name: 'Vincenzo La Torre',
|
|
||||||
desc: 'AwardsPage.judgesHat.vincenzo'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
picture: tim,
|
|
||||||
name: 'Tim Lim',
|
|
||||||
desc: 'AwardsPage.judgesHat.tim'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
picture: desmond,
|
|
||||||
name: 'Desmond Lim',
|
|
||||||
desc: 'AwardsPage.judgesHat.desmond'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const judgesTitleRef = ref<HTMLElement | null>(null)
|
|
||||||
const judgesSubTitleRef = ref<HTMLElement | null>(null)
|
|
||||||
const judgementListRef = ref<HTMLElement | null>(null)
|
|
||||||
const hasPlayedJudgementAnim = ref(false)
|
|
||||||
let judgementObserver: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
const setupJudgementInitialState = () => {
|
|
||||||
const titleEls = [judgesTitleRef.value, judgesSubTitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
if (titleEls.length) {
|
|
||||||
gsap.set(titleEls, {
|
|
||||||
opacity: 0,
|
|
||||||
scale: 0,
|
|
||||||
transformOrigin: '50% 50%'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const items =
|
|
||||||
judgementListRef.value?.querySelectorAll<HTMLElement>('.judgement-item')
|
|
||||||
if (items?.length) {
|
|
||||||
gsap.set(items, {
|
|
||||||
opacity: 0,
|
|
||||||
clipPath: 'inset(0 0 100% 0)'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const playJudgementAnimation = () => {
|
|
||||||
if (hasPlayedJudgementAnim.value) return
|
|
||||||
const titleEls = [judgesTitleRef.value, judgesSubTitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
const listEl = judgementListRef.value
|
|
||||||
if (!titleEls.length || !listEl) return
|
|
||||||
|
|
||||||
const items = Array.from(
|
|
||||||
listEl.querySelectorAll<HTMLElement>('.judgement-item')
|
|
||||||
)
|
|
||||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
|
||||||
|
|
||||||
tl.to(titleEls, {
|
|
||||||
opacity: 1,
|
|
||||||
scale: 1,
|
|
||||||
duration: 0.4,
|
|
||||||
ease: 'back.out(1.6)',
|
|
||||||
stagger: 0.1
|
|
||||||
})
|
|
||||||
if (items.length) {
|
|
||||||
const firstRow = items.slice(0, 3)
|
|
||||||
const secondRow = items.slice(3)
|
|
||||||
|
|
||||||
if (firstRow.length) {
|
|
||||||
tl.to(
|
|
||||||
firstRow,
|
|
||||||
{
|
|
||||||
opacity: 1,
|
|
||||||
clipPath: 'inset(0% 0% 0% 0%)',
|
|
||||||
duration: 0.45,
|
|
||||||
stagger: 0.05
|
|
||||||
},
|
|
||||||
'-=0.2'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondRow.length) {
|
|
||||||
tl.to(
|
|
||||||
secondRow,
|
|
||||||
{
|
|
||||||
opacity: 1,
|
|
||||||
clipPath: 'inset(0% 0% 0% 0%)',
|
|
||||||
duration: 0.45,
|
|
||||||
stagger: 0.05
|
|
||||||
},
|
|
||||||
'+=0.1'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPlayedJudgementAnim.value = true
|
|
||||||
judgementObserver?.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
setupJudgementInitialState()
|
|
||||||
if ('IntersectionObserver' in window) {
|
|
||||||
judgementObserver = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
playJudgementAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{ threshold: 0.3 }
|
|
||||||
)
|
|
||||||
if (judgementListRef.value) {
|
|
||||||
judgementObserver.observe(judgementListRef.value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Fallback: play immediately if IntersectionObserver unsupported
|
|
||||||
playJudgementAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
judgementObserver?.disconnect()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.judges-container {
|
|
||||||
height: 147.4rem;
|
|
||||||
background: url('@/assets/images/award/judges_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
padding-top: 12.8rem;
|
|
||||||
.title {
|
|
||||||
color: #232323;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
margin: 2.4rem 0 2.2rem;
|
|
||||||
}
|
|
||||||
.sub-title {
|
|
||||||
color: #b10000;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 3rem;
|
|
||||||
margin-bottom: 12rem;
|
|
||||||
}
|
|
||||||
.judgement-list {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
column-gap: 23.22rem;
|
|
||||||
row-gap: 8rem;
|
|
||||||
padding: 0 25rem 0 26.6rem;
|
|
||||||
div{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.judgement-item {
|
|
||||||
overflow: hidden;
|
|
||||||
.picture {
|
|
||||||
width: 20.2rem;
|
|
||||||
height: 26rem;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
margin: 3rem 0 2.4rem;
|
|
||||||
color: #232323;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
color: #585858;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,276 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="prizes-container container flex align-center space-between"
|
|
||||||
ref="prizesRef"
|
|
||||||
>
|
|
||||||
<div class="left flex flex-col flex-center">
|
|
||||||
<div
|
|
||||||
class="title"
|
|
||||||
ref="prizesTitleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.awardPrizes') }}
|
|
||||||
</div>
|
|
||||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
|
||||||
<div
|
|
||||||
class="desc"
|
|
||||||
ref="prizesSubTitleRef"
|
|
||||||
>
|
|
||||||
{{ $t('AwardsPage.recognition') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="right"
|
|
||||||
ref="prizesRightRef"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="prize-item flex flex-col flex-center"
|
|
||||||
:class="{ smaller: item.smaller }"
|
|
||||||
v-for="item in prizes"
|
|
||||||
:key="item.name"
|
|
||||||
>
|
|
||||||
<div class="prize-money">
|
|
||||||
{{ $t(item.money) }}
|
|
||||||
</div>
|
|
||||||
<div class="prize-name">{{ $t(item.name) }}</div>
|
|
||||||
<div class="prize-desc flex flex-col flex-center">
|
|
||||||
<div
|
|
||||||
class="desc-item"
|
|
||||||
v-for="el in item.desc"
|
|
||||||
>
|
|
||||||
{{ $t(el) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
isZh: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const prizes = [
|
|
||||||
{
|
|
||||||
money: 'AwardsPage.grandMoney',
|
|
||||||
name: 'AwardsPage.grandAwards',
|
|
||||||
desc: [
|
|
||||||
'AwardsPage.cashAward',
|
|
||||||
'AwardsPage.awardCertificate',
|
|
||||||
'AwardsPage.globalMediaExposure'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
money: 'AwardsPage.goldMoney',
|
|
||||||
name: 'AwardsPage.goldAwards',
|
|
||||||
desc: [
|
|
||||||
'AwardsPage.cashAward',
|
|
||||||
'AwardsPage.awardCertificate',
|
|
||||||
'AwardsPage.globalMediaExposure'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
money: 'AwardsPage.silverMoney',
|
|
||||||
name: 'AwardsPage.silverAwards',
|
|
||||||
desc: [
|
|
||||||
'AwardsPage.cashAward',
|
|
||||||
'AwardsPage.awardCertificate',
|
|
||||||
'AwardsPage.globalMediaExposure'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
money: 'AwardsPage.awardCertification',
|
|
||||||
name: 'AwardsPage.finalists',
|
|
||||||
desc: ['AwardsPage.TravelAllowance', 'AwardsPage.globalMediaExposure'],
|
|
||||||
smaller: !props.isZh
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const prizesRef = ref<HTMLElement | null>(null)
|
|
||||||
const prizesTitleRef = ref<HTMLElement | null>(null)
|
|
||||||
const prizesSubTitleRef = ref<HTMLElement | null>(null)
|
|
||||||
const prizesRightRef = ref<HTMLElement | null>(null)
|
|
||||||
const hasPlayedPrizesAnim = ref(false)
|
|
||||||
let prizesObserver: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
const setupPrizesInitialState = () => {
|
|
||||||
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
if (titleEls.length) {
|
|
||||||
gsap.set(titleEls, {
|
|
||||||
opacity: 0,
|
|
||||||
scale: 0,
|
|
||||||
transformOrigin: '50% 50%'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (prizesRightRef.value) {
|
|
||||||
gsap.set(prizesRightRef.value, {
|
|
||||||
'opacity': 0,
|
|
||||||
'y': 40,
|
|
||||||
'scale': 1.08,
|
|
||||||
'--prize-row-gap': '2rem',
|
|
||||||
'--prize-col-gap': '2rem'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const playPrizesAnimation = () => {
|
|
||||||
if (hasPlayedPrizesAnim.value) return
|
|
||||||
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
|
||||||
Boolean
|
|
||||||
) as HTMLElement[]
|
|
||||||
|
|
||||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
|
||||||
if (titleEls.length) {
|
|
||||||
tl.to(titleEls, {
|
|
||||||
opacity: 1,
|
|
||||||
scale: 1,
|
|
||||||
duration: 0.6,
|
|
||||||
ease: 'back.out(1.6)',
|
|
||||||
stagger: 0.1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (prizesRightRef.value) {
|
|
||||||
tl.to(
|
|
||||||
prizesRightRef.value,
|
|
||||||
{
|
|
||||||
'opacity': 1,
|
|
||||||
'y': 0,
|
|
||||||
'scale': 1,
|
|
||||||
'--prize-row-gap': '4.2rem',
|
|
||||||
'--prize-col-gap': '4.4rem',
|
|
||||||
'duration': 0.55,
|
|
||||||
'ease': 'back.out(1.4)'
|
|
||||||
},
|
|
||||||
titleEls.length ? '-=0.15' : 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPlayedPrizesAnim.value = true
|
|
||||||
prizesObserver?.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
setupPrizesInitialState()
|
|
||||||
if ('IntersectionObserver' in window) {
|
|
||||||
prizesObserver = new IntersectionObserver(
|
|
||||||
entries => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
playPrizesAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{ threshold: 0.25 }
|
|
||||||
)
|
|
||||||
if (prizesRef.value) prizesObserver.observe(prizesRef.value)
|
|
||||||
} else {
|
|
||||||
playPrizesAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
prizesObserver?.disconnect()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.prizes-container {
|
|
||||||
background: url('@/assets/images/award/prizes_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
padding: 0 21.4rem 0 34.2rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
.left {
|
|
||||||
row-gap: 3.6rem;
|
|
||||||
.title {
|
|
||||||
text-align: center;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 4rem;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
text-align: center;
|
|
||||||
color: #f95750;
|
|
||||||
font-family: 'Poppins';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
// height: 45.4rem;
|
|
||||||
// padding: 4.6rem 6.1rem 4.6rem 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
grid-template-rows: repeat(2, 1fr);
|
|
||||||
row-gap: var(--prize-row-gap, 4.2rem);
|
|
||||||
column-gap: var(--prize-col-gap, 4.4rem);
|
|
||||||
// flex: 1;
|
|
||||||
.prize-item {
|
|
||||||
width: 35.5rem;
|
|
||||||
height: 32.8rem;
|
|
||||||
color: #fff;
|
|
||||||
padding: 4.5rem 0 4.8rem 0;
|
|
||||||
justify-content: space-between;
|
|
||||||
background: url('@/assets/images/award/first_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
&:nth-of-type(2) {
|
|
||||||
background: url('@/assets/images/award/second_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
&:nth-of-type(3) {
|
|
||||||
background: url('@/assets/images/award/grand_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
&:nth-of-type(4) {
|
|
||||||
background: url('@/assets/images/award/certification_bg.png')
|
|
||||||
no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
&.smaller {
|
|
||||||
.prize-money {
|
|
||||||
font-size: 3.6rem;
|
|
||||||
line-height: 3.8rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.prize-money {
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 4rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 7.6rem;
|
|
||||||
&.smaller {
|
|
||||||
font-size: 3.6rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.prize-name {
|
|
||||||
font-family: 'PoppinsMedium';
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2.8rem;
|
|
||||||
}
|
|
||||||
.prize-desc {
|
|
||||||
color: #e0e0e0;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
height: 8.9rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="selection-container container flex flex-col align-center"
|
|
||||||
ref="selectionRef"
|
|
||||||
>
|
|
||||||
<div class="title">{{ $t('AwardsPage.selectionCriteria') }}</div>
|
|
||||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
|
||||||
<div class="sub-title">{{ $t('AwardsPage.evaluation') }}</div>
|
|
||||||
<div class="criteria-list flex" ref="criteriaListRef">
|
|
||||||
<div
|
|
||||||
class="item flex flex-col align-center"
|
|
||||||
v-for="item in criteriaList"
|
|
||||||
:key="item.name"
|
|
||||||
>
|
|
||||||
<img :src="item.icon" class="icon" :style="item.style" />
|
|
||||||
<div class="name">{{ $t(item.name) }}</div>
|
|
||||||
<div class="desc">{{ $t(item.desc) }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
import criteria1 from '@/assets/images/award/criteria_1.png'
|
|
||||||
import criteria2 from '@/assets/images/award/criteria_2.png'
|
|
||||||
import criteria3 from '@/assets/images/award/criteria_3.png'
|
|
||||||
import criteria4 from '@/assets/images/award/criteria_4.png'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const criteriaList = ref([
|
|
||||||
{
|
|
||||||
icon: criteria1,
|
|
||||||
name: 'AwardsPage.originality',
|
|
||||||
desc: 'AwardsPage.originalityDesc',
|
|
||||||
style: { width: '13rem', height: '17rem' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: criteria2,
|
|
||||||
name: 'AwardsPage.creativity',
|
|
||||||
desc: 'AwardsPage.creativityDesc',
|
|
||||||
style: { width: '16rem', height: '18rem' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: criteria3,
|
|
||||||
name: 'AwardsPage.aidaIntegration',
|
|
||||||
desc: 'AwardsPage.aidaIntegrationDesc',
|
|
||||||
style: { width: '16rem', height: '18rem' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: criteria4,
|
|
||||||
name: 'AwardsPage.execution',
|
|
||||||
desc: 'AwardsPage.executionDesc',
|
|
||||||
style: { width: '18.8rem', height: '18rem' }
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const selectionRef = ref<HTMLElement | null>(null)
|
|
||||||
const criteriaListRef = ref<HTMLElement | null>(null)
|
|
||||||
const hasPlayedSelectionAnim = ref(false)
|
|
||||||
let selectionObserver: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
const setupSelectionInitialState = () => {
|
|
||||||
const items =
|
|
||||||
criteriaListRef.value?.querySelectorAll<HTMLElement>('.item') ?? []
|
|
||||||
if (items.length) {
|
|
||||||
gsap.set(items, {
|
|
||||||
opacity: 0,
|
|
||||||
scale: 0,
|
|
||||||
transformOrigin: '50% 50%'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const playSelectionAnimation = () => {
|
|
||||||
if (hasPlayedSelectionAnim.value) return
|
|
||||||
const items =
|
|
||||||
criteriaListRef.value?.querySelectorAll<HTMLElement>('.item') ?? []
|
|
||||||
if (!items.length) return
|
|
||||||
|
|
||||||
gsap.to(items, {
|
|
||||||
opacity: 1,
|
|
||||||
scale: 1,
|
|
||||||
duration: 0.6,
|
|
||||||
ease: 'back.out(1.6)',
|
|
||||||
stagger: 0.3
|
|
||||||
})
|
|
||||||
|
|
||||||
hasPlayedSelectionAnim.value = true
|
|
||||||
selectionObserver?.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
nextTick(() => {
|
|
||||||
setupSelectionInitialState()
|
|
||||||
if ('IntersectionObserver' in window) {
|
|
||||||
selectionObserver = new IntersectionObserver(
|
|
||||||
(entries) => {
|
|
||||||
entries.forEach((entry) => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
playSelectionAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{ threshold: 0.25 }
|
|
||||||
)
|
|
||||||
if (selectionRef.value) {
|
|
||||||
selectionObserver.observe(selectionRef.value)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
playSelectionAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
selectionObserver?.disconnect()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.selection-container {
|
|
||||||
background: url('@/assets/images/award/selection_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
padding-top: 9.3rem;
|
|
||||||
.title {
|
|
||||||
color: #fff;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
margin: 2.3rem 0 2.3rem;
|
|
||||||
}
|
|
||||||
.sub-title {
|
|
||||||
color: #f95750;
|
|
||||||
font-family: 'Popins';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 3rem;
|
|
||||||
margin-bottom: 11.8rem;
|
|
||||||
}
|
|
||||||
.criteria-list {
|
|
||||||
column-gap: 6rem;
|
|
||||||
.item {
|
|
||||||
height: 44rem;
|
|
||||||
width: 32.2rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
&:nth-of-type(3) {
|
|
||||||
background: url('@/assets/images/award/criteria_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
.icon {
|
|
||||||
width: 18.8rem;
|
|
||||||
height: 18rem;
|
|
||||||
}
|
|
||||||
.name {
|
|
||||||
font-family: 'PoppinsMedium';
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2.8rem;
|
|
||||||
color: #fff;
|
|
||||||
margin: 2rem 0 5rem;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
color: #e0e0e0;
|
|
||||||
text-align: center;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="blocks-list flex"
|
|
||||||
ref="root"
|
|
||||||
:class="{ 'in-view': inView }"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="block-item flex flex-col flex-center"
|
|
||||||
v-for="(item, idx) in blocksList"
|
|
||||||
:key="item.number"
|
|
||||||
:style="{ '--delay': `${idx * 0.18}s` }"
|
|
||||||
>
|
|
||||||
<div class="number">{{ $t(item.number) }}</div>
|
|
||||||
<div class="label">{{ $t(item.label) }}</div>
|
|
||||||
<div class="line"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const blocksList = ref([
|
|
||||||
{
|
|
||||||
number: 'AwardsPage.totalCashPrizes',
|
|
||||||
label: 'AwardsPage.totalCashPrizesLabel'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: 'AwardsPage.globalMediaExpose',
|
|
||||||
label: 'AwardsPage.globalMediaExposeLabel'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: 'AwardsPage.networkingOpportunities',
|
|
||||||
label: 'AwardsPage.networkingOpportunitiesLabel'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
number: 'AwardsPage.awardCeremonyHongKong',
|
|
||||||
label: 'AwardsPage.awardCeremonyLabel'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
const root = ref<HTMLElement | null>(null)
|
|
||||||
const inView = ref(false)
|
|
||||||
let io: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
io = new IntersectionObserver(
|
|
||||||
entries => {
|
|
||||||
for (const entry of entries) {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
// 延迟 0.5s 后触发动画并断开观察
|
|
||||||
setTimeout(() => {
|
|
||||||
inView.value = true
|
|
||||||
}, 500)
|
|
||||||
if (io) {
|
|
||||||
io.disconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ threshold: 0.05 }
|
|
||||||
)
|
|
||||||
if (root.value) {
|
|
||||||
io.observe(root.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
io?.disconnect()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.blocks-list {
|
|
||||||
height: 31.4rem;
|
|
||||||
background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%);
|
|
||||||
|
|
||||||
.block-item {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
color: #fff;
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
white-space: pre-line;
|
|
||||||
row-gap: 3rem;
|
|
||||||
/* text scale-in animations */
|
|
||||||
.number {
|
|
||||||
font-size: 3.6rem;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
transform: scale(0);
|
|
||||||
opacity: 0;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
.label {
|
|
||||||
font-size: 2.4rem;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
transform: scale(0);
|
|
||||||
opacity: 0;
|
|
||||||
will-change: transform, opacity;
|
|
||||||
}
|
|
||||||
/* vertical line grows top -> bottom */
|
|
||||||
.line {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
/* 固定 top 为最终高度的一半位置,这样 height 从 0 -> 27.4rem 时会从上向下增长 */
|
|
||||||
top: calc(50% - 13.7rem);
|
|
||||||
width: 0.1rem;
|
|
||||||
height: 0;
|
|
||||||
background-color: #8d8d8d;
|
|
||||||
will-change: height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 当组件进入视口并且等待 0.5s 后,.in-view 会加入根节点,下面规则触发动画 */
|
|
||||||
.in-view .block-item .number {
|
|
||||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
|
||||||
animation-delay: var(--delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
.in-view .block-item .label {
|
|
||||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
|
||||||
animation-delay: calc(var(--delay) + 0.12s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.in-view .block-item .line {
|
|
||||||
animation: growLine 0.7s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
|
||||||
animation-delay: calc(var(--delay) + 0.18s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keyframes */
|
|
||||||
@keyframes scaleIn {
|
|
||||||
from {
|
|
||||||
transform: scale(0);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: scale(1);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes growLine {
|
|
||||||
from {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
height: 27.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="success-container flex flex-col align-center">
|
|
||||||
<img
|
|
||||||
:src="info.icon"
|
|
||||||
alt=""
|
|
||||||
class="icon-img"
|
|
||||||
/>
|
|
||||||
<div class="title">{{ $t(info.title) }}</div>
|
|
||||||
<div class="desc">
|
|
||||||
{{ $t(info.desc) }}
|
|
||||||
<!-- <div>
|
|
||||||
Please review your submitted information in the AiDA in-platform message.
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
You may edit it if needed. Competition updates and results will be sent
|
|
||||||
via email.
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import successIcon from '@/assets/images/award/successful.png'
|
|
||||||
import expiredIcon from '@/assets/images/award/expired.png'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const props = defineProps({
|
|
||||||
isExpired: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const info = computed(() => {
|
|
||||||
if (props.isExpired) {
|
|
||||||
return {
|
|
||||||
icon: expiredIcon,
|
|
||||||
title: 'AwardsPage.deadlinePassed',
|
|
||||||
desc: 'AwardsPage.deadlinePassedDesc'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
icon: successIcon,
|
|
||||||
title: 'AwardsPage.submissionSuccessful',
|
|
||||||
desc: 'AwardsPage.submissionSuccessfulDesc'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.success-container {
|
|
||||||
margin: 0 21.5rem;
|
|
||||||
padding: 10.6rem 27.3rem 0;
|
|
||||||
height: 50rem;
|
|
||||||
position: relative;
|
|
||||||
top: -16.8rem;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
.icon-img {
|
|
||||||
width: 12rem;
|
|
||||||
height: 12rem;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 3rem;
|
|
||||||
color: #232323;
|
|
||||||
text-align: center;
|
|
||||||
margin: 2rem 0 4rem;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
color: #585858;
|
|
||||||
font-family: Arial;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,370 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
ref="containerRef"
|
|
||||||
class="timeline-container container flex flex-col align-center"
|
|
||||||
>
|
|
||||||
<div class="timeline-title">{{ $t('AwardsPage.competitionTimeline') }}</div>
|
|
||||||
<div class="desc">{{ $t('AwardsPage.shapingTheFuture') }}</div>
|
|
||||||
<div
|
|
||||||
class="timeline-point"
|
|
||||||
ref="timelineRef"
|
|
||||||
>
|
|
||||||
<!-- 顶部标签行 -->
|
|
||||||
<div class="grid-row labels-row">
|
|
||||||
<div
|
|
||||||
class="grid-cell label-cell"
|
|
||||||
v-for="item in points"
|
|
||||||
:key="'label-' + item.time"
|
|
||||||
>
|
|
||||||
<div class="main-label">{{ $t(item.label) }}</div>
|
|
||||||
<div
|
|
||||||
class="sub-label"
|
|
||||||
v-if="item.subLabel"
|
|
||||||
>
|
|
||||||
{{ $t(item.subLabel) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 图标行 -->
|
|
||||||
<div class="grid-row icons-row">
|
|
||||||
<div class="timeline-line"></div>
|
|
||||||
<div
|
|
||||||
class="grid-cell icon-cell"
|
|
||||||
v-for="item in points"
|
|
||||||
:key="'icon-' + item.time"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/point.png"
|
|
||||||
class="point-icon"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 时间行 -->
|
|
||||||
<div class="grid-row times-row">
|
|
||||||
<div
|
|
||||||
class="grid-cell time-cell"
|
|
||||||
v-for="item in points"
|
|
||||||
:key="'time-' + item.time"
|
|
||||||
>
|
|
||||||
{{ $t(item.time) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 描述行 -->
|
|
||||||
<div class="grid-row descs-row">
|
|
||||||
<div
|
|
||||||
class="grid-cell desc-cell"
|
|
||||||
v-for="item in points"
|
|
||||||
:key="'desc-' + item.time"
|
|
||||||
>
|
|
||||||
<div class="txt">
|
|
||||||
{{ $t(item.desc) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onBeforeUnmount, onMounted, ref, computed } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { gsap } from 'gsap'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const containerRef = ref<HTMLElement | null>(null)
|
|
||||||
const timelineRef = ref<HTMLElement | null>(null)
|
|
||||||
const hasAnimated = ref(false)
|
|
||||||
|
|
||||||
const points = ref([
|
|
||||||
{
|
|
||||||
label: 'AwardsPage.timelineApplicationLabel',
|
|
||||||
subLabel: 'AwardsPage.timelineDeadlineLabel',
|
|
||||||
time: 'AwardsPage.timeJul15',
|
|
||||||
desc: 'AwardsPage.applicationDeadlineDesc'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'AwardsPage.twentyFinalistsAnnounced',
|
|
||||||
subLabel: 'AwardsPage.announcedLabel',
|
|
||||||
time: 'AwardsPage.timeAug30',
|
|
||||||
desc: 'AwardsPage.twentyFinalistsDesc'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'AwardsPage.finalistSubmission',
|
|
||||||
subLabel: 'AwardsPage.submissionLabel',
|
|
||||||
time: 'AwardsPage.timeSept30',
|
|
||||||
desc: 'AwardsPage.finalistSubmissionDesc'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'AwardsPage.receivingOutfits',
|
|
||||||
subLabel: 'AwardsPage.fromFinalistsLabel',
|
|
||||||
time: 'AwardsPage.timeOctober',
|
|
||||||
desc: 'AwardsPage.receivingOutfitsDesc'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'AwardsPage.awardCeremony',
|
|
||||||
subLabel: 'AwardsPage.ceremonyLabel',
|
|
||||||
time: 'AwardsPage.timeNov12',
|
|
||||||
desc: 'AwardsPage.awardCeremonyDesc'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const playAnimation = () => {
|
|
||||||
if (!containerRef.value || hasAnimated.value) return
|
|
||||||
const title = containerRef.value.querySelector('.timeline-title')
|
|
||||||
const subtitle = containerRef.value.querySelector('.desc')
|
|
||||||
const line = containerRef.value.querySelector('.timeline-line')
|
|
||||||
const timeline = containerRef.value.querySelector('.timeline-point')
|
|
||||||
|
|
||||||
const tl = gsap.timeline()
|
|
||||||
|
|
||||||
// 我们使用一个统一的开始 label,使横线、timeline 裁剪与所有文字同时启动,
|
|
||||||
// 点图标在它们完成后立即开始。
|
|
||||||
tl.addLabel('start')
|
|
||||||
|
|
||||||
// 整体 timeline 的裁剪展开(与 start 同步)
|
|
||||||
if (timeline) {
|
|
||||||
tl.fromTo(
|
|
||||||
timeline,
|
|
||||||
{
|
|
||||||
clipPath: 'inset(0 100% 0 0)'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
clipPath: 'inset(0 0% 0 0)',
|
|
||||||
duration: 1.3,
|
|
||||||
ease: 'power1.out'
|
|
||||||
},
|
|
||||||
'start'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 线条动画(与 start 同步)
|
|
||||||
if (line) {
|
|
||||||
tl.from(
|
|
||||||
line,
|
|
||||||
{
|
|
||||||
scaleX: 0,
|
|
||||||
transformOrigin: '0% 50%',
|
|
||||||
duration: 1.3,
|
|
||||||
ease: 'power1.out'
|
|
||||||
},
|
|
||||||
'start'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标题与副标题(与 start 同步)
|
|
||||||
if (title && subtitle) {
|
|
||||||
tl.from(
|
|
||||||
[title, subtitle],
|
|
||||||
{
|
|
||||||
scaleX: 0,
|
|
||||||
autoAlpha: 0.5,
|
|
||||||
transformOrigin: '50% 50%',
|
|
||||||
duration: 0.6,
|
|
||||||
stagger: 0.1,
|
|
||||||
ease: 'power2.out'
|
|
||||||
},
|
|
||||||
'start'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 行内文字(标签、时间、描述、图标)与 start 同步开始
|
|
||||||
const textItems = containerRef.value.querySelectorAll('.grid-cell')
|
|
||||||
if (textItems && textItems.length) {
|
|
||||||
tl.from(
|
|
||||||
textItems,
|
|
||||||
{
|
|
||||||
// autoAlpha: 0.5,
|
|
||||||
duration: 0.7,
|
|
||||||
stagger: 0.08,
|
|
||||||
ease: 'power2.out'
|
|
||||||
},
|
|
||||||
'start'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasAnimated.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let observer: IntersectionObserver | null = null
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await nextTick()
|
|
||||||
if (!containerRef.value) return
|
|
||||||
observer = new IntersectionObserver(
|
|
||||||
entries => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
playAnimation()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{ threshold: 0.3 }
|
|
||||||
)
|
|
||||||
observer.observe(containerRef.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
if (observer && containerRef.value) {
|
|
||||||
observer.unobserve(containerRef.value)
|
|
||||||
}
|
|
||||||
observer = null
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.timeline-container {
|
|
||||||
background: url('@/assets/images/award/timeline_bg.png') no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
position: relative;
|
|
||||||
padding: 12.8rem 0 15.9rem;
|
|
||||||
width: 100%;
|
|
||||||
color: #fff;
|
|
||||||
.timeline-title {
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 4rem;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
margin: 2.4rem 0 2.2rem 0;
|
|
||||||
}
|
|
||||||
.desc {
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #f95750;
|
|
||||||
}
|
|
||||||
.timeline-point {
|
|
||||||
overflow: hidden;
|
|
||||||
will-change: clip-path;
|
|
||||||
flex: 1;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 11rem;
|
|
||||||
padding: 0 13.8rem;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
// 主网格布局:5列
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
grid-template-rows: auto auto auto auto;
|
|
||||||
grid-column-gap: 0;
|
|
||||||
grid-row-gap: 0;
|
|
||||||
|
|
||||||
// 所有 grid 子行的通用样式
|
|
||||||
.grid-row {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-cell {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 图标行
|
|
||||||
.icons-row {
|
|
||||||
align-items: center;
|
|
||||||
height: 6.4rem;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin-bottom: 1.6rem;
|
|
||||||
|
|
||||||
.timeline-line {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: -22rem;
|
|
||||||
right: -21.2rem;
|
|
||||||
height: 0.15rem;
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
rgba(199, 52, 44, 0) 0%,
|
|
||||||
rgba(199, 52, 44, 0.719626) 25.96%,
|
|
||||||
#c7342c 51.44%,
|
|
||||||
rgba(199, 52, 44, 0.762376) 75.96%,
|
|
||||||
rgba(199, 52, 44, 0) 100%
|
|
||||||
);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-cell {
|
|
||||||
position: relative;
|
|
||||||
.point-icon {
|
|
||||||
width: 6.4rem;
|
|
||||||
height: 6.4rem;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标签行
|
|
||||||
.labels-row {
|
|
||||||
margin-bottom: 8rem;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
.label-cell {
|
|
||||||
flex-direction: column;
|
|
||||||
color: #fff;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.8rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 6rem;
|
|
||||||
|
|
||||||
// .sub-label {
|
|
||||||
// font-family: 'Arial';
|
|
||||||
// font-weight: 400;
|
|
||||||
// font-size: 1.4rem;
|
|
||||||
// color: rgba(255, 255, 255, 0.8);
|
|
||||||
// margin-top: 0.4rem;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间行
|
|
||||||
.times-row {
|
|
||||||
margin-bottom: 6rem;
|
|
||||||
z-index: 2;
|
|
||||||
position: relative;
|
|
||||||
.time-cell {
|
|
||||||
color: #f95750;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2.8rem;
|
|
||||||
line-height: 4.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 描述行
|
|
||||||
.descs-row {
|
|
||||||
.desc-cell {
|
|
||||||
.txt {
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
color: #e0e0e0;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 31.2rem;
|
|
||||||
min-height: 10.2rem;
|
|
||||||
white-space: pre-line;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="upload-status">
|
|
||||||
<div class="upload-status-item">
|
|
||||||
<div class="upload-status-item-icon">
|
|
||||||
<img
|
|
||||||
v-if="status === 'uploading'"
|
|
||||||
src="@/assets/images/award/progress.png"
|
|
||||||
alt=""
|
|
||||||
class="progress-icon"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="status === 'success'"
|
|
||||||
src="@/assets/images/award/successful.png"
|
|
||||||
alt=""
|
|
||||||
class="progress-icon successful-icon"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="text">{{ $t(text) }}</div>
|
|
||||||
<div class="tips">{{ $t(tips) }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, watch } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const props = defineProps<{
|
|
||||||
status: string
|
|
||||||
type: 'pdf' | 'video'
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const textMap: Record<string, string> = {
|
|
||||||
idle: '',
|
|
||||||
uploading: 'AwardsPage.uploadInProgress',
|
|
||||||
success:'AwardsPage.uploadSuccess',
|
|
||||||
error: 'AwardsPage.fileUploadFailed'
|
|
||||||
}
|
|
||||||
|
|
||||||
const tips = computed(() => {
|
|
||||||
if (props.type === 'pdf') {
|
|
||||||
return 'AwardsPage.pdfFileTip'
|
|
||||||
} else if (props.type === 'video') {
|
|
||||||
return 'AwardsPage.videoFileTip'
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const text = computed(() => {
|
|
||||||
return textMap[props.status] ?? textMap.uploading
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<style scoped lang="less">
|
|
||||||
.upload-status {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
.upload-status-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
.progress-icon {
|
|
||||||
width: 12rem;
|
|
||||||
height: 12rem;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
font-family: Arial;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #585858;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
}
|
|
||||||
.tips{
|
|
||||||
font-family: Arial;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="captcha">
|
|
||||||
<input
|
|
||||||
v-for="(c, index) in getCtData"
|
|
||||||
:key="index"
|
|
||||||
type="text"
|
|
||||||
v-model="getCtData[index]"
|
|
||||||
ref="inputRefs"
|
|
||||||
inputmode="numeric"
|
|
||||||
pattern="[0-9]*"
|
|
||||||
@input="e => onInput(e.target.value, index)"
|
|
||||||
@keydown="e => onKeydown(e, index)"
|
|
||||||
@keypress="e => onKeypress(e)"
|
|
||||||
@focus="onFocus"
|
|
||||||
@pause="onPause"
|
|
||||||
:disabled="loading"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, watch, onMounted } from 'vue'
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
ct: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Emits {
|
|
||||||
(e: 'sendCaptcha', password: string): void
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
|
||||||
const emit = defineEmits<Emits>()
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const timeout = ref<NodeJS.Timeout | null>(null)
|
|
||||||
const inputRefs = ref<HTMLInputElement[]>([])
|
|
||||||
|
|
||||||
const getCtData = computed({
|
|
||||||
get: () => props.ct,
|
|
||||||
set: (value: string[]) => {
|
|
||||||
// 这里需要特殊处理,因为computed通常是只读的
|
|
||||||
// 但原代码中直接修改了getCtData,所以这里需要emit一个事件或者使用其他方式
|
|
||||||
// 由于这是父组件传来的props,我们需要通过emit通知父组件更新
|
|
||||||
props.ct.splice(0, props.ct.length, ...value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const ctSize = computed(() => getCtData.value.length)
|
|
||||||
|
|
||||||
const cIndex = computed(() => {
|
|
||||||
let i = getCtData.value.findIndex(item => item === '')
|
|
||||||
i = (i + ctSize.value) % ctSize.value
|
|
||||||
return i
|
|
||||||
})
|
|
||||||
|
|
||||||
const lastCode = computed(() => getCtData.value[ctSize.value - 1])
|
|
||||||
|
|
||||||
watch(cIndex, () => {
|
|
||||||
resetCaret()
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(lastCode, (newVal, oldVal) => {
|
|
||||||
if (newVal && newVal !== oldVal) {
|
|
||||||
inputRefs.value[ctSize.value - 1]?.blur()
|
|
||||||
sendCaptcha()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
resetCaret()
|
|
||||||
})
|
|
||||||
|
|
||||||
const onInput = (val: string, index: number) => {
|
|
||||||
if (timeout.value) {
|
|
||||||
clearTimeout(timeout.value)
|
|
||||||
}
|
|
||||||
timeout.value = setTimeout(() => {
|
|
||||||
val = String(val).replace(/\D/g, '')
|
|
||||||
getCtData.value[index] = val
|
|
||||||
if (index === ctSize.value - 1) {
|
|
||||||
getCtData.value[ctSize.value - 1] = val[0] // 最后一个码,只允许输入一个字符。
|
|
||||||
} else if (val.length > 1) {
|
|
||||||
let i = index
|
|
||||||
for (i = index; i < ctSize.value && i - index < val.length; i++) {
|
|
||||||
getCtData.value[i] = val[i - index]
|
|
||||||
}
|
|
||||||
resetCaret()
|
|
||||||
} else if (!(val + '')) {
|
|
||||||
getCtData.value[index] = ''
|
|
||||||
}
|
|
||||||
}, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onPause = () => {}
|
|
||||||
|
|
||||||
const resetCaret = () => {
|
|
||||||
inputRefs.value[ctSize.value - 1]?.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
const onFocus = () => {
|
|
||||||
// 监听 focus 事件,将光标重定位到"第一个空白符的位置"。
|
|
||||||
let index = getCtData.value.findIndex(item => item === '')
|
|
||||||
index = (index + ctSize.value) % ctSize.value
|
|
||||||
inputRefs.value[index]?.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
const onKeypress = (e: KeyboardEvent) => {
|
|
||||||
// 只允许输入数字0-9
|
|
||||||
const char = String.fromCharCode((e as any).which)
|
|
||||||
if (!/[0-9]/.test(char)) {
|
|
||||||
e.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onKeydown = (e: KeyboardEvent, index: number) => {
|
|
||||||
// 处理删除键
|
|
||||||
if (e.key === 'Backspace' || e.key === 'Delete') {
|
|
||||||
const val = (e.target as HTMLInputElement).value
|
|
||||||
if (val === '') {
|
|
||||||
// 删除上一个input里的值,并对其focus。
|
|
||||||
if (index > 0) {
|
|
||||||
getCtData.value[index - 1] = ''
|
|
||||||
inputRefs.value[index - 1]?.focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 阻止其他非数字字符
|
|
||||||
else if (
|
|
||||||
e.key &&
|
|
||||||
!/[0-9]/.test(e.key) &&
|
|
||||||
![
|
|
||||||
'Backspace',
|
|
||||||
'Delete',
|
|
||||||
'Tab',
|
|
||||||
'Enter',
|
|
||||||
'ArrowLeft',
|
|
||||||
'ArrowRight',
|
|
||||||
'ArrowUp',
|
|
||||||
'ArrowDown'
|
|
||||||
].includes(e.key)
|
|
||||||
) {
|
|
||||||
e.preventDefault()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const sendCaptcha = () => {
|
|
||||||
const password = getCtData.value.map(item => item).join('')
|
|
||||||
emit('sendCaptcha', password)
|
|
||||||
}
|
|
||||||
|
|
||||||
const reset = () => {
|
|
||||||
// 重置。一般是验证码错误时触发。
|
|
||||||
getCtData.value = getCtData.value.map(() => '')
|
|
||||||
resetCaret()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暴露reset方法给父组件使用
|
|
||||||
defineExpose({
|
|
||||||
reset
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.captcha {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
width: 6rem;
|
|
||||||
height: 6rem;
|
|
||||||
border: 0.2rem solid #e6e6e6;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
line-height: 6rem;
|
|
||||||
outline: none;
|
|
||||||
background-color: #f6f6f4;
|
|
||||||
}
|
|
||||||
input:last-of-type {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
input:disabled {
|
|
||||||
color: #000;
|
|
||||||
background-color: #f6f6f4;
|
|
||||||
}
|
|
||||||
.msg {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="award-container">
|
|
||||||
<div class="header-wrapper">
|
|
||||||
<div class="header flex align-center space-between">
|
|
||||||
<div class="header-left">
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/code_create_logo.png"
|
|
||||||
class="logo"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="header-right flex align-center"
|
|
||||||
@click="handleBtnClick"
|
|
||||||
>
|
|
||||||
<div class="text">{{ btnText }}</div>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/arrow.png"
|
|
||||||
alt=""
|
|
||||||
class="arrow"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="header-placeholder"></div>
|
|
||||||
</div>
|
|
||||||
<router-view />
|
|
||||||
<div class="footer flex space-between align-center">
|
|
||||||
<div class="social-list flex">
|
|
||||||
<a
|
|
||||||
href="https://xhslink.com/m/5Ony2FapizV"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/xiaohongshu.svg"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://www.linkedin.com/company/code-create-limited"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/linkdin.svg"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://www.facebook.com/CodeCreateAI"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/facebook.svg"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://www.tiktok.com/@aida_codecreate"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/tiktok.svg"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="javascript:void(0)"
|
|
||||||
@click="showQRcode = true"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/weichat.svg"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="copyright">© Code-Create 2026</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="qrcode-mask flex flex-center"
|
|
||||||
v-if="showQRcode"
|
|
||||||
>
|
|
||||||
<div class="code-wrapper flex flex-col align-center">
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/close.svg"
|
|
||||||
class="close-icon"
|
|
||||||
@click="handleCloseQRcode"
|
|
||||||
/>
|
|
||||||
<div class="code-title">{{ $t('AwardsPage.wechatTitle') }}</div>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/qrcode.jpg"
|
|
||||||
class="qrcode"
|
|
||||||
/>
|
|
||||||
<div class="tips">{{ $t('AwardsPage.wechatDesc') }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, watch, onMounted } from 'vue'
|
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { getCookie } from '@/tool/cookie'
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
const router = useRouter()
|
|
||||||
const { locale } = useI18n()
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 初始化语言设置
|
|
||||||
const loginLanguage = localStorage.getItem('loginLanguage')
|
|
||||||
if (loginLanguage) {
|
|
||||||
locale.value = loginLanguage
|
|
||||||
} else {
|
|
||||||
const userLanguage = getCookie('language')
|
|
||||||
if (userLanguage) {
|
|
||||||
locale.value = userLanguage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const showQRcode = ref(false)
|
|
||||||
const handleCloseQRcode = () => {
|
|
||||||
showQRcode.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
type BtnType = 'index' | 'form'
|
|
||||||
const btnType = ref<BtnType>('index')
|
|
||||||
const btnText = computed(() => {
|
|
||||||
if (btnType.value === 'index') {
|
|
||||||
return locale.value === 'CHINESE_SIMPLIFIED' ? '提交申请' : 'Submit your Application'
|
|
||||||
}
|
|
||||||
if (btnType.value === 'form') {
|
|
||||||
return locale.value === 'CHINESE_SIMPLIFIED' ? '赛事介绍' : 'Back to Introduction'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => route.path,
|
|
||||||
val => {
|
|
||||||
if (val.includes('contestants')) {
|
|
||||||
btnType.value = 'form'
|
|
||||||
} else {
|
|
||||||
btnType.value = 'index'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const handleBtnClick = () => {
|
|
||||||
if (btnType.value === 'index') {
|
|
||||||
router.push('/award/contestants')
|
|
||||||
} else {
|
|
||||||
router.push('/award/index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.award-container {
|
|
||||||
overflow: auto;
|
|
||||||
height: 100vh;
|
|
||||||
// 隐藏滚动条箭头,只显示滚动条本体
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
scrollbar-width: none;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
}
|
|
||||||
.header-wrapper {
|
|
||||||
.header-placeholder {
|
|
||||||
height: 8rem;
|
|
||||||
}
|
|
||||||
.header {
|
|
||||||
height: 8rem;
|
|
||||||
background-color: #232323;
|
|
||||||
padding-left: 21.5rem;
|
|
||||||
padding-right: 8.6rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 9;
|
|
||||||
.header-left {
|
|
||||||
.logo {
|
|
||||||
width: 13rem;
|
|
||||||
height: 5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.header-right {
|
|
||||||
column-gap: 1rem;
|
|
||||||
cursor: pointer;
|
|
||||||
.text {
|
|
||||||
font-size: 1.6rem;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.arrow {
|
|
||||||
width: 2.4rem;
|
|
||||||
height: 2.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
height: 10rem;
|
|
||||||
padding-left: 21.5rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-right: 22rem;
|
|
||||||
background-color: #232323;
|
|
||||||
.social-list {
|
|
||||||
column-gap: 2rem;
|
|
||||||
img {
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.copyright {
|
|
||||||
color: #fff;
|
|
||||||
font-family: 'Arial';
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.qrcode-mask {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.45);
|
|
||||||
.code-wrapper {
|
|
||||||
width: 60rem;
|
|
||||||
height: 49.4rem;
|
|
||||||
background-color: #fff;
|
|
||||||
position: relative;
|
|
||||||
border-radius: 0.8rem;
|
|
||||||
padding-top: 6rem;
|
|
||||||
.close-icon {
|
|
||||||
width: 2.4rem;
|
|
||||||
height: 2.4rem;
|
|
||||||
position: absolute;
|
|
||||||
top: 2rem;
|
|
||||||
right: 2rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.code-title {
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 3rem;
|
|
||||||
color: #232323;
|
|
||||||
}
|
|
||||||
.qrcode {
|
|
||||||
width: 25.8rem;
|
|
||||||
height: 25.8rem;
|
|
||||||
margin: 3rem 0 1rem;
|
|
||||||
}
|
|
||||||
.tips {
|
|
||||||
font-family: Arial;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
color: #585858;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="award-page"
|
|
||||||
:class="{ 'is-zh': isZh }"
|
|
||||||
>
|
|
||||||
<div class="banner">
|
|
||||||
<video
|
|
||||||
:src="bannerUrl"
|
|
||||||
autoplay
|
|
||||||
muted
|
|
||||||
loop
|
|
||||||
class="banner-video"
|
|
||||||
playsinline
|
|
||||||
webkit-playsinline
|
|
||||||
x5-playsinline
|
|
||||||
></video>
|
|
||||||
<div
|
|
||||||
class="submit-btn flex flex-center"
|
|
||||||
@click="handleSubmitApplication"
|
|
||||||
>
|
|
||||||
<div>{{ $t('AwardsPage.submitApplication') }}</div>
|
|
||||||
<img
|
|
||||||
src="@/assets/images/award/arrow_right.png"
|
|
||||||
alt=""
|
|
||||||
class="arrow"
|
|
||||||
/>
|
|
||||||
<div class="ddl">{{ $t('AwardsPage.applicationDeadline') }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Slogan />
|
|
||||||
<Bloom />
|
|
||||||
<TimeLine />
|
|
||||||
<JudgesSection />
|
|
||||||
<PrizesSection :is-zh="isZh" />
|
|
||||||
<ApplySection />
|
|
||||||
<SelectionSection />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import JudgesSection from './components/JudgesSection.vue'
|
|
||||||
import SelectionSection from './components/SelectionSection.vue'
|
|
||||||
import ApplySection from './components/ApplySection.vue'
|
|
||||||
import PrizesSection from './components/PrizesSection.vue'
|
|
||||||
import TimeLine from './components/TimeLine.vue'
|
|
||||||
import Bloom from './components/Bloom.vue'
|
|
||||||
import Slogan from './components/Slogan.vue'
|
|
||||||
|
|
||||||
import banner from '@/assets/images/award/banner.mp4'
|
|
||||||
import bannerZh from '@/assets/images/award/banner_chinese.mp4'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const { locale } = useI18n()
|
|
||||||
|
|
||||||
const isZh = computed(() => {
|
|
||||||
return locale.value === 'CHINESE_SIMPLIFIED'
|
|
||||||
})
|
|
||||||
|
|
||||||
const bannerUrl = computed(() => {
|
|
||||||
return isZh.value ? bannerZh : banner
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleSubmitApplication = () => {
|
|
||||||
router.push('/award/contestants')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.container {
|
|
||||||
height: 97rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 2.4rem;
|
|
||||||
height: 2.4rem;
|
|
||||||
}
|
|
||||||
.banner {
|
|
||||||
height: 100rem;
|
|
||||||
// background: url('@/assets/images/award/banner.png') no-repeat;
|
|
||||||
// background-size: cover;
|
|
||||||
position: relative;
|
|
||||||
.banner-video {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
.submit-btn {
|
|
||||||
width: 41rem;
|
|
||||||
height: 6.394rem;
|
|
||||||
line-height: 6.394rem;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 3.2rem;
|
|
||||||
background-color: rgba(35, 35, 35, 0.7);
|
|
||||||
box-shadow: inset 0 0 1119px 0 rgba(255, 255, 255, 0.3),
|
|
||||||
inset -0.8px -2.4px 1.6px 0.4px rgba(255, 255, 255, 0.1),
|
|
||||||
inset 0.8px 2.4px 1.6px 0 rgba(255, 255, 255, 0.3);
|
|
||||||
color: #fff;
|
|
||||||
font-family: 'PoppinsBold';
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 2.4rem;
|
|
||||||
column-gap: 3.2rem;
|
|
||||||
position: absolute;
|
|
||||||
left: 42.1rem;
|
|
||||||
bottom: 15.7rem;
|
|
||||||
backdrop-filter: blur(5px);
|
|
||||||
cursor: pointer;
|
|
||||||
.arrow {
|
|
||||||
width: 3.83rem;
|
|
||||||
height: 3.83rem;
|
|
||||||
}
|
|
||||||
.ddl {
|
|
||||||
position: absolute;
|
|
||||||
bottom: -4rem;
|
|
||||||
left: 0;
|
|
||||||
text-align: center;
|
|
||||||
width: 41rem;
|
|
||||||
font-family: 'ArialBold';
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 2rem;
|
|
||||||
line-height: 2.2rem;
|
|
||||||
color: #232323e5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-zh {
|
|
||||||
.submit-btn {
|
|
||||||
padding: 0 7.5rem;
|
|
||||||
height: 7.8rem;
|
|
||||||
border-radius: 7.74rem;
|
|
||||||
column-gap: 3.8rem;
|
|
||||||
// justify-content: space-between;
|
|
||||||
&,
|
|
||||||
.ddl {
|
|
||||||
width: 35.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -2,12 +2,11 @@
|
|||||||
<div class="brand-profile-index">brand-profile-index</div>
|
<div class="brand-profile-index">brand-profile-index</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup></script>
|
||||||
</script>
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.seller-dashboard-index {
|
.seller-dashboard-index {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
88
src/views/SellerDashboard/MyListings/EditDetail/index.vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<div class="edit-detail-wrapper">
|
||||||
|
<seller-header
|
||||||
|
title="Edit Listing Details"
|
||||||
|
:breadcrumbs="[
|
||||||
|
{ title: 'My Listings', name: 'myListingsIndex' },
|
||||||
|
{ title: 'Select Collection', name: 'myListingsSelect' },
|
||||||
|
{ title: 'Select Sketch', name: 'myListingsSelectItem' },
|
||||||
|
{ title: 'Edit Listing Details', name: 'EditDetail' }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<div class="operate-menu flex">
|
||||||
|
<div class="menu-btn flex align-center save">
|
||||||
|
<span>Save Draft</span>
|
||||||
|
<SvgIcon name="CSave" color="#000000" size="16" />
|
||||||
|
</div>
|
||||||
|
<div class="menu-btn flex align-center publish">
|
||||||
|
<span>Publish</span>
|
||||||
|
<SvgIcon name="CPublish" color="#ffffff" size="16" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</seller-header>
|
||||||
|
<div class="edit-detail-content flex space-between">
|
||||||
|
<div class="left">
|
||||||
|
<div class="main-image-container flex">
|
||||||
|
<div class="sketch"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue"
|
||||||
|
import SellerHeader from "../../seller-header.vue"
|
||||||
|
|
||||||
|
const currentIndex = ref(0)
|
||||||
|
const selectList = ref([
|
||||||
|
{
|
||||||
|
sketch: "",
|
||||||
|
mainProductImage: "",
|
||||||
|
cover: "",
|
||||||
|
productImage: [],
|
||||||
|
apparelSketch: [],
|
||||||
|
productName: "",
|
||||||
|
price: "",
|
||||||
|
desc: '',
|
||||||
|
gender: '',
|
||||||
|
category:''
|
||||||
|
}
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.c-svg {
|
||||||
|
width: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-detail-wrapper {
|
||||||
|
.menu-btn {
|
||||||
|
height: 6rem;
|
||||||
|
border: 0.15rem solid #000000;
|
||||||
|
border-radius: 4rem;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 6rem;
|
||||||
|
padding: 0 2rem;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
column-gap: 0.8rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate-menu {
|
||||||
|
column-gap: 2rem;
|
||||||
|
|
||||||
|
.publish {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-detail-content {
|
||||||
|
padding-right: 6.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||