Parcourir la source

feat(移动端): 在首页添加套餐展示组件

- 新增移动端专用的 PlansSection 组件,包含响应式布局和视觉样式
- 创建共享的 plans 数据工具文件,统一管理套餐信息
- 重构桌面端 PlansSection 组件,改用数据驱动渲染
- 添加三个套餐对应的图标资源文件
reaper il y a 1 mois
Parent
commit
fc4cce5539

+ 63 - 0
app/assets/svg/home/plan-icon1.svg

@@ -0,0 +1,63 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="20" height="20" rx="5" fill="url(#paint0_linear_1096_3393)"/>
+<foreignObject x="-1.75" y="-1.75" width="23.5" height="23.5"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.5px);clip-path:url(#bgblur_0_1096_3393_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_iiiii_1096_3393)" data-figma-bg-blur-radius="3">
+<rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4" fill="#1A1A1A" style="mix-blend-mode:plus-lighter"/>
+</g>
+<g filter="url(#filter1_d_1096_3393)">
+<path d="M8.91747 5.875C9.39859 5.04167 10.6014 5.04167 11.0825 5.875L14.5466 11.875C15.0278 12.7083 14.4264 13.75 13.4641 13.75H6.5359C5.57365 13.75 4.97224 12.7083 5.45337 11.875L8.91747 5.875Z" fill="white"/>
+</g>
+<defs>
+<filter id="filter0_iiiii_1096_3393" x="-1.75" y="-1.75" width="23.5" height="23.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="2.75"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0.5 0"/>
+<feBlend mode="plus-darker" in2="shape" result="effect1_innerShadow_1096_3393"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.25" operator="erode" in="SourceAlpha" result="effect2_innerShadow_1096_3393"/>
+<feOffset/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 1 0"/>
+<feBlend mode="overlay" in2="effect1_innerShadow_1096_3393" result="effect2_innerShadow_1096_3393"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect3_innerShadow_1096_3393"/>
+<feOffset dx="-0.5" dy="-0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect2_innerShadow_1096_3393" result="effect3_innerShadow_1096_3393"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect4_innerShadow_1096_3393"/>
+<feOffset dx="0.5" dy="0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect3_innerShadow_1096_3393" result="effect4_innerShadow_1096_3393"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.875" operator="dilate" in="SourceAlpha" result="effect5_innerShadow_1096_3393"/>
+<feOffset dx="0.75" dy="0.75"/>
+<feGaussianBlur stdDeviation="0.0625"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0"/>
+<feBlend mode="normal" in2="effect4_innerShadow_1096_3393" result="effect5_innerShadow_1096_3393"/>
+</filter>
+<clipPath id="bgblur_0_1096_3393_clip_path" transform="translate(1.75 1.75)"><rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4"/>
+</clipPath><filter id="filter1_d_1096_3393" x="5.2832" y="5.25" width="10.4336" height="9.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dx="0.5" dy="0.5"/>
+<feGaussianBlur stdDeviation="0.25"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.590144 0 0 0 0 0.254808 0 0 0 0 1 0 0 0 0.5 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1096_3393"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1096_3393" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_1096_3393" x1="-9.33888e-09" y1="10" x2="24.9417" y2="10.6368" gradientUnits="userSpaceOnUse">
+<stop stop-color="#A39DFF"/>
+<stop offset="1" stop-color="#7D46FF"/>
+</linearGradient>
+</defs>
+</svg>

+ 63 - 0
app/assets/svg/home/plan-icon2.svg

@@ -0,0 +1,63 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="20" height="20" rx="5" fill="url(#paint0_linear_1096_3428)"/>
+<foreignObject x="-1.75" y="-1.75" width="23.5" height="23.5"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.5px);clip-path:url(#bgblur_0_1096_3428_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_iiiii_1096_3428)" data-figma-bg-blur-radius="3">
+<rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4" fill="#1A1A1A" style="mix-blend-mode:plus-lighter"/>
+</g>
+<g filter="url(#filter1_d_1096_3428)">
+<path d="M9.36307 4.77441C9.65653 4.30242 10.3435 4.30242 10.6369 4.77441L11.8492 6.72416C11.9524 6.89023 12.1165 7.0094 12.3063 7.05628L14.5352 7.6067C15.0748 7.73995 15.2871 8.39326 14.9289 8.81821L13.4492 10.5737C13.3231 10.7232 13.2605 10.916 13.2746 11.111L13.4399 13.401C13.4799 13.9553 12.9241 14.3591 12.4093 14.1497L10.2825 13.2849C10.1014 13.2112 9.89863 13.2112 9.71748 13.2849L7.5907 14.1497C7.07586 14.3591 6.52012 13.9553 6.56013 13.401L6.72543 11.111C6.73951 10.916 6.67686 10.7232 6.55083 10.5737L5.07111 8.81821C4.71291 8.39326 4.92518 7.73995 5.46475 7.6067L7.69369 7.05628C7.88353 7.0094 8.04756 6.89023 8.15081 6.72416L9.36307 4.77441Z" fill="white"/>
+</g>
+<defs>
+<filter id="filter0_iiiii_1096_3428" x="-1.75" y="-1.75" width="23.5" height="23.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="2.75"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0.5 0"/>
+<feBlend mode="plus-darker" in2="shape" result="effect1_innerShadow_1096_3428"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.25" operator="erode" in="SourceAlpha" result="effect2_innerShadow_1096_3428"/>
+<feOffset/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 1 0"/>
+<feBlend mode="overlay" in2="effect1_innerShadow_1096_3428" result="effect2_innerShadow_1096_3428"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect3_innerShadow_1096_3428"/>
+<feOffset dx="-0.5" dy="-0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect2_innerShadow_1096_3428" result="effect3_innerShadow_1096_3428"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect4_innerShadow_1096_3428"/>
+<feOffset dx="0.5" dy="0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect3_innerShadow_1096_3428" result="effect4_innerShadow_1096_3428"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.875" operator="dilate" in="SourceAlpha" result="effect5_innerShadow_1096_3428"/>
+<feOffset dx="0.75" dy="0.75"/>
+<feGaussianBlur stdDeviation="0.0625"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0"/>
+<feBlend mode="normal" in2="effect4_innerShadow_1096_3428" result="effect5_innerShadow_1096_3428"/>
+</filter>
+<clipPath id="bgblur_0_1096_3428_clip_path" transform="translate(1.75 1.75)"><rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4"/>
+</clipPath><filter id="filter1_d_1096_3428" x="3.89453" y="4.41992" width="12.2109" height="11.7852" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="1"/>
+<feGaussianBlur stdDeviation="0.5"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.490196 0 0 0 0 0.27451 0 0 0 0 1 0 0 0 1 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1096_3428"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1096_3428" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_1096_3428" x1="-9.33888e-09" y1="10" x2="24.9417" y2="10.6368" gradientUnits="userSpaceOnUse">
+<stop stop-color="#A39DFF"/>
+<stop offset="1" stop-color="#7D46FF"/>
+</linearGradient>
+</defs>
+</svg>

+ 78 - 0
app/assets/svg/home/plan-icon3.svg

@@ -0,0 +1,78 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="20" height="20" rx="5" fill="url(#paint0_linear_1096_3466)"/>
+<foreignObject x="-1.75" y="-1.75" width="23.5" height="23.5"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.5px);clip-path:url(#bgblur_0_1096_3466_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_iiiii_1096_3466)" data-figma-bg-blur-radius="3">
+<rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4" fill="#1A1A1A" style="mix-blend-mode:plus-lighter"/>
+</g>
+<g clip-path="url(#clip1_1096_3466)" filter="url(#filter1_d_1096_3466)">
+<g filter="url(#filter2_d_1096_3466)">
+<path d="M10.125 13.4978H11.125V7.27081C11.125 7.14159 11.2571 7.05446 11.3759 7.10536L14.322 8.36784C14.412 8.40643 14.4887 8.47058 14.5426 8.55236C14.5964 8.63413 14.6251 8.72992 14.625 8.82784V13.4978H15.445C15.5444 13.4978 15.625 13.5784 15.625 13.6778V14.3178C15.625 14.4173 15.5444 14.4978 15.445 14.4978H4.805C4.70559 14.4978 4.625 14.4173 4.625 14.3178V13.6778C4.625 13.5784 4.70559 13.4978 4.805 13.4978H5.625V6.82284C5.62499 6.7261 5.65304 6.63144 5.70576 6.55032C5.75847 6.4692 5.83359 6.40512 5.922 6.36584L9.7735 4.65434C9.81153 4.63745 9.85317 4.63032 9.89465 4.63359C9.93613 4.63686 9.97614 4.65043 10.011 4.67307C10.046 4.69572 10.0747 4.72672 10.0946 4.76326C10.1145 4.7998 10.1249 4.84073 10.125 4.88234V13.4978Z" fill="white"/>
+</g>
+</g>
+<defs>
+<filter id="filter0_iiiii_1096_3466" x="-1.75" y="-1.75" width="23.5" height="23.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset/>
+<feGaussianBlur stdDeviation="2.75"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0 0.94902 0 0 0 0.5 0"/>
+<feBlend mode="plus-darker" in2="shape" result="effect1_innerShadow_1096_3466"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.25" operator="erode" in="SourceAlpha" result="effect2_innerShadow_1096_3466"/>
+<feOffset/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 0 0.6 0 0 0 1 0"/>
+<feBlend mode="overlay" in2="effect1_innerShadow_1096_3466" result="effect2_innerShadow_1096_3466"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect3_innerShadow_1096_3466"/>
+<feOffset dx="-0.5" dy="-0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect2_innerShadow_1096_3466" result="effect3_innerShadow_1096_3466"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="effect4_innerShadow_1096_3466"/>
+<feOffset dx="0.5" dy="0.5"/>
+<feGaussianBlur stdDeviation="0.125"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 0 0.701961 0 0 0 1 0"/>
+<feBlend mode="plus-lighter" in2="effect3_innerShadow_1096_3466" result="effect4_innerShadow_1096_3466"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="0.875" operator="dilate" in="SourceAlpha" result="effect5_innerShadow_1096_3466"/>
+<feOffset dx="0.75" dy="0.75"/>
+<feGaussianBlur stdDeviation="0.0625"/>
+<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0"/>
+<feBlend mode="normal" in2="effect4_innerShadow_1096_3466" result="effect5_innerShadow_1096_3466"/>
+</filter>
+<clipPath id="bgblur_0_1096_3466_clip_path" transform="translate(1.75 1.75)"><rect x="1.25" y="1.25" width="17.5" height="17.5" rx="4"/>
+</clipPath><filter id="filter1_d_1096_3466" x="3.125" y="4" width="14" height="14" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="1"/>
+<feGaussianBlur stdDeviation="0.5"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.378157 0 0 0 0 0.0528846 0 0 0 0 1 0 0 0 1 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1096_3466"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1096_3466" result="shape"/>
+</filter>
+<filter id="filter2_d_1096_3466" x="3.625" y="4.63281" width="13" height="11.8652" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="1"/>
+<feGaussianBlur stdDeviation="0.5"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.485376 0 0 0 0 0.231047 0 0 0 0 0.942308 0 0 0 1 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1096_3466"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1096_3466" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_1096_3466" x1="6.125" y1="-4.375" x2="25.375" y2="22.375" gradientUnits="userSpaceOnUse">
+<stop stop-color="#6186FF"/>
+<stop offset="1" stop-color="#8622FF"/>
+</linearGradient>
+<clipPath id="clip1_1096_3466">
+<rect width="12" height="12" fill="white" transform="translate(4.125 4)"/>
+</clipPath>
+</defs>
+</svg>

+ 12 - 61
app/components/PlansSection.vue

@@ -1,74 +1,25 @@
+<script setup>
+import { plans } from '~/utils/plans'
+</script>
+
 <template>
   <section class="plans-section">
     <div class="plans-cards">
-      <div class="plan-card">
-        <div class="plan-name">Lite Plan</div>
-        <div class="plan-desc">适合项目上线初期集成</div>
-        <div class="old-price">
-          <del>$1500</del>
-          <span>节省20.04%</span>
-        </div>
-        <div class="plan-price">$999</div>
-        <div class="plan-actions">
-          <button class="btn-primary">立即选择</button>
-        </div>
-        <div class="plan-title">
-          <div class="plan-cs">详细参数</div>
-          <ul class="plan-features">
-            <li>防护目标数:3个</li>
-            <li>峰值设备数:200</li>
-            <li>智能BGP线路</li>
-            <li>带宽峰值:20M</li>
-            <li>DDoS防御:无上限</li>
-            <li>CC防御:100%</li>
-          </ul>
-        </div>
-      </div>
-
-      <div class="plan-card">
-        <div class="plan-name">Basic Plan</div>
-        <div class="plan-desc">最经济实惠的个人开发者套餐</div>
-        <div class="old-price">
-          <del>$2500</del>
-          <span>节省20.04%</span>
-        </div>
-        <div class="plan-price">$1999</div>
-        <div class="plan-actions">
-          <button class="btn-primary">立即选择</button>
-        </div>
-        <div class="plan-title">
-          <div class="plan-cs">详细参数</div>
-          <ul class="plan-features">
-            <li>防护目标数:10个</li>
-            <li>峰值设备数:2000</li>
-            <li>智能CN2/BGP线路</li>
-            <li>带宽峰值:50M</li>
-            <li>DDoS防御:无上限</li>
-            <li>CC防御:100%</li>
-          </ul>
-        </div>
-      </div>
-
-      <div class="plan-card">
-        <div class="plan-name">Standard Plan</div>
-        <div class="plan-desc">企业入门级畅销精选套餐</div>
+      <div v-for="(plan, index) in plans" :key="index" class="plan-card">
+        <div class="plan-name">{{ plan.name }}</div>
+        <div class="plan-desc">{{ plan.desc }}</div>
         <div class="old-price">
-          <del>$6000</del>
-          <span>节省16.68%</span>
+          <del>{{ plan.oldPrice }}</del>
+          <span>{{ plan.save }}</span>
         </div>
-        <div class="plan-price">$4999</div>
+        <div class="plan-price">{{ plan.price }}</div>
         <div class="plan-actions">
-          <button class="btn-primary ghost">立即选择</button>
+          <button class="btn-primary" :class="plan.buttonClass">立即选择</button>
         </div>
         <div class="plan-title">
           <div class="plan-cs">详细参数</div>
           <ul class="plan-features">
-            <li>防护目标数:15个</li>
-            <li>峰值设备数:10000</li>
-            <li>智能CN2/BGP线路</li>
-            <li>带宽峰值:80M</li>
-            <li>DDoS防御:无上限</li>
-            <li>CC防御:100%</li>
+            <li v-for="(feature, fIndex) in plan.features" :key="fIndex">{{ feature }}</li>
           </ul>
         </div>
       </div>

+ 180 - 0
app/components/mobile/home/PlansSection.vue

@@ -0,0 +1,180 @@
+<template>
+  <section class="mb-plans">
+    <div class="mb-plans-list">
+      <article v-for="plan in plans" :key="plan.name" class="mb-plan-card">
+        <header class="card-head">
+          <img width="20" height="20" :src="plan.icon" alt="icon" />
+          <div class="head-text">
+            <div class="plan-name">{{ plan.name }}</div>
+            <div class="plan-desc">{{ plan.desc }}</div>
+          </div>
+        </header>
+        <div class="price-row">
+          <div class="price">{{ plan.price }}</div>
+          <div class="price-meta">
+            <del class="old-price">{{ plan.oldPrice }}</del>
+            <span class="save-badge">{{ plan.save }}</span>
+          </div>
+        </div>
+        <div class="divider" aria-hidden="true" />
+        <ul class="features">
+          <li v-for="(feature, idx) in plan.features" :key="idx" class="feature-item">{{ feature }}</li>
+        </ul>
+      </article>
+    </div>
+  </section>
+</template>
+<script setup>
+import { plans } from '~/utils/plans'
+</script>
+<style lang="scss" scoped>
+.mb-plans {
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.mb-plans-list {
+  display: flex;
+  flex-direction: column;
+  gap: 14px;
+}
+
+.mb-plan-card {
+  border-radius: 20px;
+  border: 1px solid rgba(198, 186, 255, 0.3);
+  background: linear-gradient(180deg, rgba(165, 101, 255, 0.22) 0%, rgba(3, 0, 20, 0.55) 100%);
+  backdrop-filter: blur(20px);
+  padding: 12px;
+  box-sizing: border-box;
+}
+
+.card-head {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.head-text {
+  min-width: 0;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.plan-name {
+  color: #FFF;
+  font-size: 20px;
+  font-weight: 700;
+  line-height: 20px;
+}
+
+.plan-desc {
+  color: #FFF;
+  font-size: 12px;
+  font-weight: 400;
+  line-height: 12px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.price-row {
+  margin-top: 12px;
+  display: flex;
+  align-items: flex-end;
+  justify-content: space-between;
+  gap: 12px;
+}
+
+.price {
+  font-size: 36px;
+  font-weight: 700;
+  line-height: 40px;
+  color: #ffffff;
+  letter-spacing: -0.5px;
+  white-space: nowrap;
+}
+
+.price-meta {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  min-width: 0;
+}
+
+.old-price {
+  font-size: 12px;
+  font-weight: 500;
+  line-height: 12px;
+  color: rgba(255, 255, 255, 0.45);
+  white-space: nowrap;
+}
+
+.save-badge {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  height: 22px;
+  padding: 0 10px;
+  border-radius: 999px;
+  background: #7d46ff;
+  color: #ffffff;
+  font-size: 12px;
+  font-weight: 500;
+  line-height: 12px;
+  white-space: nowrap;
+}
+
+.divider {
+  height: 1px;
+  width: 100%;
+  background: rgba(198, 186, 255, 0.22);
+  margin: 12px 0 14px;
+}
+
+.features {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 1fr));
+  column-gap: 14px;
+  row-gap: 10px;
+}
+
+.feature-item {
+  position: relative;
+  padding-left: 20px;
+  font-size: 12px;
+  font-weight: 400;
+  line-height: 16px;
+  color: rgba(255, 255, 255, 0.65);
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+
+  &::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 14px;
+    height: 14px;
+    border-radius: 50%;
+    background: rgba(163, 157, 255, 1);
+  }
+
+  &::after {
+    content: '✓';
+    position: absolute;
+    left: 4px;
+    top: 50%;
+    transform: translateY(-50%);
+    color: #ffffff;
+    font-size: 9px;
+    font-weight: 700;
+    line-height: 1;
+  }
+}
+</style>

+ 7 - 0
app/pages/mobile/index.vue

@@ -12,12 +12,14 @@
         <ProductTabs class="mb-tabs-positioner" />
       </div>
     </section>
+    <PlansSection class="mb-plans-section" />
   </section>
 </template>
 
 <script setup>
 import homeVideo from '~/assets/video/home.webm'
 import ProductTabs from '~/components/mobile/home/ProductTabs.vue'
+import PlansSection from '~/components/mobile/home/PlansSection.vue'
 </script>
 
 <style scoped lang="scss">
@@ -84,5 +86,10 @@ import ProductTabs from '~/components/mobile/home/ProductTabs.vue'
       z-index: 1
     }
   }
+
+  .mb-plans-section {
+    margin-top: 18px;
+    padding-bottom: 20px;
+  }
 }
 </style>

+ 36 - 0
app/utils/plans.js

@@ -0,0 +1,36 @@
+import icon1 from '~/assets/svg/home/plan-icon1.svg'
+import icon2 from '~/assets/svg/home/plan-icon2.svg'
+import icon3 from '~/assets/svg/home/plan-icon3.svg'
+
+export const plans = [
+  {
+    name: 'Lite Plan',
+    desc: '适合项目上线初期集成',
+    oldPrice: '$1500',
+    save: '节省20.04%',
+    price: '$999',
+    buttonClass: '',
+    features: ['防护目标数:3个', '峰值设备数:200', '智能BGP线路', '带宽峰值:20M', 'DDoS防御:无上限', 'CC防御:100%'],
+    icon: icon1
+  },
+  {
+    name: 'Basic Plan',
+    desc: '最经济实惠的个人开发者套餐',
+    oldPrice: '$2500',
+    save: '节省20.04%',
+    price: '$1999',
+    buttonClass: '',
+    features: ['防护目标数:10个', '峰值设备数:2000', '智能CN2/BGP线路', '带宽峰值:50M', 'DDoS防御:无上限', 'CC防御:100%'],
+    icon: icon2
+  },
+  {
+    name: 'Standard Plan',
+    desc: '企业入门级畅销精选套餐',
+    oldPrice: '$6000',
+    save: '节省16.68%',
+    price: '$4999',
+    buttonClass: 'ghost',
+    features: ['防护目标数:15个', '峰值设备数:10000', '智能CN2/BGP线路', '带宽峰值:80M', 'DDoS防御:无上限', 'CC防御:100%'],
+    icon: icon3
+  }
+]