From e3ad73d3970a33c3bdeae152894bef681a5bc2a0 Mon Sep 17 00:00:00 2001 From: cneicy Date: Sun, 8 Nov 2026 18:54:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(products):=20=E6=94=B9=E7=89=88=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E9=80=89=E8=B4=AD=E7=95=8C=E9=9D=A2=E5=B9=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9C=B0=E5=8C=BA=E7=AD=9B=E9=80=89=E4=B8=8E?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 云产品选择器新增地区标签页、分组数量及全部选项,自动跟随当前线路所属地区 - 将线路和型号改为紧凑选择按钮,精简型号名称的公共前缀并保留完整名称提示 - 物理服务器目录改为规格列表,支持行内展开、收起线路详情及进入定制页 - 新增商品起价升降序排序,将无有效价格的商品置于末尾 - 将规格筛选改为下拉选项,移动端支持展开更多筛选并显示已选条件数量 - 统一云服务器与物理服务器的横向配置表单,优化磁盘、带宽、镜像选择及移动端布局 - 限制桌面端配置汇总栏高度,使清单内部滚动并保持价格和购买按钮可见 - 统一产品分类标签页与胶囊按钮样式,补充查看全部产品入口 - 将产品选择器和物理服务器目录重构为 script setup、声明式模板及 scoped 样式,删除旧样式文件与相关引用 --- .../styles/CloudProductPicker.CAm9rmUl.css | 128 - app/assets/styles/KkyEcsConfig.BFaAwQPZ.css | 192 ++ app/assets/styles/MfDcimConfig.BhC_eZ0V.css | 163 ++ app/assets/styles/cloud-server.CcwlOXJ0.css | 15 + .../styles/dedicated-server.CiJfMYtk.css | 398 --- app/assets/styles/entry.Cs9kvuGi.css | 34 +- app/assets/styles/products.CrccEo2m.css | 77 + app/components/config/CloudProductPicker.vue | 850 +++--- app/components/config/KkyEcsConfig.vue | 242 +- app/pages/products/cloud-server.vue | 19 +- .../products/dedicated-server/customize.vue | 1 - app/pages/products/dedicated-server/index.vue | 2314 ++++++++--------- 12 files changed, 2121 insertions(+), 2312 deletions(-) delete mode 100644 app/assets/styles/CloudProductPicker.CAm9rmUl.css delete mode 100644 app/assets/styles/dedicated-server.CiJfMYtk.css diff --git a/app/assets/styles/CloudProductPicker.CAm9rmUl.css b/app/assets/styles/CloudProductPicker.CAm9rmUl.css deleted file mode 100644 index 139377f..0000000 --- a/app/assets/styles/CloudProductPicker.CAm9rmUl.css +++ /dev/null @@ -1,128 +0,0 @@ -/* 云商品选择器:区域/商品选项、选中状态及空目录提示。 */ -/* 导入方:app/components/config/CloudProductPicker.vue、app/pages/products/cloud-server.vue。 */ -.cloud-product-picker[data-v-a438862d] { - flex-direction: column; - gap: 24px; - min-width: 0; - display: flex; -} -.selection-section[data-v-a438862d] { - min-width: 0; -} -.selection-section h3[data-v-a438862d] { - border-bottom: 1px solid var(--p-content-border-color); - margin: 0 0 21px; - padding-bottom: 15px; - font-size: 1rem; - font-weight: 400; -} -.selection-section .products-title[data-v-a438862d] { - border: 0; - margin-bottom: 8px; - padding-bottom: 0; -} -.selection-label[data-v-a438862d] { - margin-bottom: 8px; -} -.zone-options[data-v-a438862d] { - grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: 14px; - display: grid; -} -.product-options[data-v-a438862d] { - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 14px; - display: grid; -} -/* 允许连续长文本换行,防止IP、密钥或用户输入撑破当前容器;不会修改原始数据。 */ -.product-option[data-v-a438862d], -.zone-option[data-v-a438862d] { - border: 1px solid var(--p-content-border-color); - background: var(--p-content-background); - min-width: 0; - min-height: 60px; - color: var(--p-text-color); - text-align: left; - cursor: pointer; - overflow-wrap: anywhere; - border-radius: var(--radius-md); - flex-direction: column; - gap: 10px; - padding: 17px 14px; - display: flex; - box-shadow: 0 1px 3px #0000001a; -} -.zone-option[data-v-a438862d] { - justify-content: center; - font-weight: 600; -} -.product-option[data-v-a438862d] { - gap: 0; - padding: 0; - overflow: hidden; -} -.product-option strong[data-v-a438862d] { - background: color-mix( - in srgb, - var(--p-primary-color) 8%, - var(--p-content-background) - ); - padding: 14px; - font-weight: 600; - display: block; -} -.product-option span[data-v-a438862d] { - color: var(--p-text-muted-color); - padding: 14px; - font-size: 0.875rem; -} -.active[data-v-a438862d] { - outline: 2px solid var(--p-primary-color); - outline-offset: -1px; - background: color-mix( - in srgb, - var(--p-primary-color) 7%, - var(--p-content-background) - ); - color: var(--p-primary-700); -} -.product-option[data-v-a438862d]:disabled, -.zone-option[data-v-a438862d]:disabled { - opacity: 0.55; - cursor: not-allowed; -} -/* 键盘操作的可见焦点:不要只保留鼠标 hover 效果而移除此反馈。 */ -.product-option[data-v-a438862d]:focus-visible, -.zone-option[data-v-a438862d]:focus-visible { - outline: 2px solid var(--p-primary-color); - outline-offset: 3px; -} -.catalog-empty[data-v-a438862d] { - text-align: center; - color: var(--p-text-muted-color); - border: 1px solid var(--p-content-border-color); - background: var(--p-content-background); - border-radius: var(--radius-md); - padding: 28px; -} -.catalog-empty i[data-v-a438862d] { - font-size: 1.75rem; -} -.catalog-empty a[data-v-a438862d] { - color: var(--p-primary-color); - text-decoration: none; -} -/* 视口条件 (width<768px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ -@media (width<768px) { - .product-options[data-v-a438862d], - .zone-options[data-v-a438862d] { - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 8px; - } -} -/* 视口条件 (width<=390px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ -@media (width<=390px) { - .product-options[data-v-a438862d] { - grid-template-columns: minmax(0, 1fr); - } -} diff --git a/app/assets/styles/KkyEcsConfig.BFaAwQPZ.css b/app/assets/styles/KkyEcsConfig.BFaAwQPZ.css index abea8b1..aee7fbc 100644 --- a/app/assets/styles/KkyEcsConfig.BFaAwQPZ.css +++ b/app/assets/styles/KkyEcsConfig.BFaAwQPZ.css @@ -44,3 +44,195 @@ max-width: 470px; } } +/* 横向表单:左列标签、右列控件,所有控件左缘对齐;字段分组容器不参与布局。 */ +.form-inline[data-v-e8ce6418] { + display: contents; +} +.config-page .config-options .form-row[data-v-e8ce6418] { + grid-template-columns: 88px minmax(0, 1fr); + align-items: start; + gap: 8px 16px; + margin-bottom: 0; + display: grid; +} +.config-page .config-options .form-row > label[data-v-e8ce6418], +.config-page .storage-field[data-v-e8ce6418] .storage-label, +.config-page .bandwidth-field[data-v-e8ce6418] .bandwidth-label { + color: var(--p-text-muted-color); + margin: 0; + font-size: 0.9375rem; + font-weight: 400; + line-height: 36px; +} +.config-page .config-options .form-row[data-v-e8ce6418] > :not(label) { + grid-column: 2; +} +.config-page .config-options .form-row > .storage-field[data-v-e8ce6418], +.config-page .config-options .form-row > .bandwidth-field[data-v-e8ce6418] { + grid-column: 1 / -1; +} +.config-options > .panel[data-v-e8ce6418] { + flex-direction: column; + gap: 16px; + display: flex; +} +.config-options > .panel > .section-title[data-v-e8ce6418] { + margin-bottom: 6px; +} +.config-page .config-options .image-groups[data-v-e8ce6418] { + margin-bottom: 0; +} +.config-page .storage-panel .form-row > label[data-v-e8ce6418], +.config-page .storage-field[data-v-e8ce6418] .storage-label { + line-height: 46px; +} +.config-page .storage-system[data-v-e8ce6418] { + width: auto; +} +.config-page .traffic-package-value[data-v-e8ce6418] { + min-height: 36px; + width: auto; + justify-self: start; + padding: 6px 14px; +} + +/* 磁盘:系统盘与各数据盘统一为单行卡片,列宽一致便于对齐。 */ +.config-page .storage-field[data-v-e8ce6418] { + grid-template-columns: 88px minmax(0, 1fr); + align-items: start; + gap: 16px; + display: grid; +} +.config-page .storage-field[data-v-e8ce6418] .storage-card { + grid-template-columns: 48px 150px minmax(80px, 1fr) auto 30px; + grid-template-areas: "type cap slider desc remove"; + grid-column: 2; + align-items: center; + gap: 16px; + min-height: 46px; + padding: 4px 12px; + border: 1px solid var(--p-content-border-color); + background: var(--p-content-background); + box-shadow: none; + display: grid; +} +.config-page .storage-field[data-v-e8ce6418] .storage-card-header { + display: contents; +} +.config-page .storage-field[data-v-e8ce6418] .storage-card-header strong { + grid-area: type; + color: var(--p-text-color); + font-size: 0.9375rem; + font-weight: 600; +} +.config-page .storage-field[data-v-e8ce6418] .storage-remove { + grid-area: remove; + margin: 0; +} +.config-page .storage-field[data-v-e8ce6418] .storage-capacity { + grid-area: cap; +} +.config-page + .storage-field[data-v-e8ce6418] + .storage-capacity + .p-inputnumber-input { + min-height: 34px; + padding: 6px 10px; +} +.config-page .storage-field[data-v-e8ce6418] .storage-slider { + grid-area: slider; + margin: 0; +} +.config-page .storage-field[data-v-e8ce6418] .storage-description { + grid-area: desc; + color: var(--p-text-muted-color); + white-space: nowrap; + font-size: 0.8125rem; +} +.config-page .config-options .storage-disks[data-v-e8ce6418] { + grid-template-columns: minmax(0, 1fr); + gap: 8px; +} +.storage-disks[data-v-e8ce6418] > .storage-field { + display: block; +} +.storage-disks > .storage-add[data-v-e8ce6418] { + min-height: 40px; + flex-direction: row; + gap: 8px; + padding: 8px 14px; + border-width: 1px; + font-size: 0.9375rem; +} +.config-page .config-options .form-row > .hint[data-v-e8ce6418] { + font-size: 0.8125rem; +} + +/* 带宽:标签、数值输入和滑块同一行。 */ +.config-page .bandwidth-field[data-v-e8ce6418] { + grid-template-columns: 88px 150px minmax(80px, 1fr); + align-items: center; + gap: 16px; + max-width: none; + display: grid; +} +.config-page + .bandwidth-field[data-v-e8ce6418] + .bandwidth-capacity + .p-inputnumber-input { + min-height: 34px; + padding: 6px 10px; +} +.config-page .bandwidth-field[data-v-e8ce6418] > .bandwidth-slider { + width: auto; + max-width: 360px; + margin: 0 8px 0 0; +} + +.config-page .image-groups[data-v-e8ce6418] { + grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); + gap: 10px; +} +.config-page .image-groups[data-v-e8ce6418] .image-group { + min-height: 48px; + gap: 10px; + padding: 8px 12px; + font-size: 0.9375rem; + box-shadow: none; +} + +@media (width<640px) { + .config-page .config-options .form-row[data-v-e8ce6418], + .config-page .storage-field[data-v-e8ce6418] { + grid-template-columns: minmax(0, 1fr); + gap: 6px; + } + .config-page .config-options .form-row[data-v-e8ce6418] > :not(label), + .config-page .storage-field[data-v-e8ce6418] .storage-card { + grid-column: 1; + } + .config-page .config-options .form-row > label[data-v-e8ce6418], + .config-page .storage-field[data-v-e8ce6418] .storage-label, + .config-page .bandwidth-field[data-v-e8ce6418] .bandwidth-label { + line-height: 1.5; + } + .config-page .storage-field[data-v-e8ce6418] .storage-card { + grid-template-columns: 40px minmax(0, 1fr) 30px; + grid-template-areas: + "type cap remove" + "slider slider slider" + "desc desc desc"; + gap: 10px 12px; + padding: 10px 12px; + } + .config-page .bandwidth-field[data-v-e8ce6418] { + grid-template-columns: 120px minmax(0, 1fr); + gap: 6px 16px; + } + .config-page .bandwidth-field[data-v-e8ce6418] .bandwidth-label { + grid-column: 1 / -1; + } + .config-page .image-groups[data-v-e8ce6418] { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} diff --git a/app/assets/styles/MfDcimConfig.BhC_eZ0V.css b/app/assets/styles/MfDcimConfig.BhC_eZ0V.css index 8896c89..e62683e 100644 --- a/app/assets/styles/MfDcimConfig.BhC_eZ0V.css +++ b/app/assets/styles/MfDcimConfig.BhC_eZ0V.css @@ -179,3 +179,166 @@ width: 125px; } } +/* 横向表单:左列标签、右列控件,与云服务器配置页保持一致;基础规格卡片内的字段不受影响。 */ +.config-options > .panel[data-v-b5ff32bb] { + flex-direction: column; + gap: 16px; + display: flex; +} +.config-options > .panel > .section-title[data-v-b5ff32bb] { + margin-bottom: 6px; +} +.config-options > .panel > .dcim-base[data-v-b5ff32bb] { + margin-bottom: 0; +} +.config-page .config-options > .panel > .form-row[data-v-b5ff32bb] { + grid-template-columns: 88px minmax(0, 1fr); + align-items: start; + gap: 8px 16px; + margin-bottom: 0; + display: grid; +} +.config-page .config-options > .panel > .form-row > label[data-v-b5ff32bb], +.config-page .config-options > .panel > .form-row > span[id][data-v-b5ff32bb], +.config-page .storage-grid > .storage-field[data-v-b5ff32bb] .storage-label { + color: var(--p-text-muted-color); + margin: 0; + font-size: 0.9375rem; + font-weight: 400; + line-height: 36px; +} +.config-page + .config-options + > .panel + > .form-row[data-v-b5ff32bb] + > :where(:not(label, span[id])) { + grid-column: 2; +} +.config-page + .config-options + > .panel + > .form-row[data-v-b5ff32bb]:has(> .network-slider) { + grid-template-columns: 88px 150px minmax(80px, 360px); + align-items: center; +} +.config-page + .config-options + > .panel + > .form-row + > .network-slider[data-v-b5ff32bb] { + grid-column: 3; + max-width: none; + margin: 0 8px; +} +.config-page + .config-options + > .panel + > .form-row + > .p-inputnumber[data-v-b5ff32bb] { + max-width: none; +} + +/* 硬盘:每块盘一行,标签在左列。 */ +.config-page .storage-grid[data-v-b5ff32bb] { + grid-template-columns: minmax(0, 1fr); + gap: 12px; +} +.config-page .storage-grid > .storage-field[data-v-b5ff32bb] { + grid-template-columns: 88px minmax(0, 1fr); + align-items: start; + gap: 16px; + display: grid; +} +.config-page .storage-grid > .storage-field[data-v-b5ff32bb] .storage-label { + line-height: 44px; +} +.config-page .storage-grid > .storage-field[data-v-b5ff32bb] .storage-card { + border: 1px solid var(--p-content-border-color); + background: var(--p-content-background); + box-shadow: none; + flex-flow: wrap; + align-items: center; + gap: 8px 20px; + min-height: 44px; + padding: 6px 14px; +} +.config-page + .storage-grid + > .storage-field[data-v-b5ff32bb] + .storage-card-header + strong { + color: var(--p-text-color); + font-size: 0.9375rem; + font-weight: 600; +} +.config-page + .storage-grid + > .storage-field[data-v-b5ff32bb] + .storage-description { + color: var(--p-text-muted-color); + margin-left: auto; + font-size: 0.8125rem; +} +.config-page .storage-grid .disk-quantity[data-v-b5ff32bb] { + flex-direction: row; + align-items: center; + gap: 8px; +} +.config-page .storage-grid .disk-quantity[data-v-b5ff32bb] .p-inputnumber { + width: 150px; +} + +@media (width<640px) { + .config-page .config-options > .panel > .form-row[data-v-b5ff32bb], + .config-page .storage-grid > .storage-field[data-v-b5ff32bb] { + grid-template-columns: minmax(0, 1fr); + gap: 6px; + } + .config-page + .config-options + > .panel + > .form-row[data-v-b5ff32bb]:has(> .network-slider) { + grid-template-columns: 130px minmax(0, 1fr); + gap: 6px 16px; + } + .config-page .config-options > .panel > .form-row > label[data-v-b5ff32bb] { + grid-column: 1 / -1; + } + .config-page + .config-options + > .panel + > .form-row[data-v-b5ff32bb] + > :where(:not(label, span[id])) { + grid-column: 1; + } + .config-page + .config-options + > .panel + > .form-row + > .network-slider[data-v-b5ff32bb] { + grid-column: 2; + } + .config-page .config-options > .panel > .form-row > label[data-v-b5ff32bb], + .config-page .config-options > .panel > .form-row > span[id][data-v-b5ff32bb], + .config-page .storage-grid > .storage-field[data-v-b5ff32bb] .storage-label { + line-height: 1.5; + } +} +.config-page .config-options .image-groups[data-v-b5ff32bb] { + grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); + gap: 10px; + margin-bottom: 0; +} +.config-page .config-options .image-groups[data-v-b5ff32bb] .image-group, +.config-page .config-options .image-group[data-v-b5ff32bb] { + min-height: 48px; + gap: 10px; + padding: 8px 12px; + font-size: 0.9375rem; + box-shadow: none; +} +@media (width<640px) { + .config-page .config-options .image-groups[data-v-b5ff32bb] { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} diff --git a/app/assets/styles/cloud-server.CcwlOXJ0.css b/app/assets/styles/cloud-server.CcwlOXJ0.css index 8061e86..f194475 100644 --- a/app/assets/styles/cloud-server.CcwlOXJ0.css +++ b/app/assets/styles/cloud-server.CcwlOXJ0.css @@ -15,3 +15,18 @@ h2[data-v-ef3931f0] { font-weight: 500; line-height: 2rem; } +.order-head[data-v-ef3931f0] { + justify-content: space-between; + align-items: center; + gap: 14px; + display: flex; +} +.order-head a[data-v-ef3931f0] { + color: var(--p-text-muted-color); + white-space: nowrap; + font-size: 0.875rem; + text-decoration: none; +} +.order-head a[data-v-ef3931f0]:hover { + color: var(--p-primary-color); +} diff --git a/app/assets/styles/dedicated-server.CiJfMYtk.css b/app/assets/styles/dedicated-server.CiJfMYtk.css deleted file mode 100644 index ef23d01..0000000 --- a/app/assets/styles/dedicated-server.CiJfMYtk.css +++ /dev/null @@ -1,398 +0,0 @@ -/* 独立服务器目录:筛选面板、硬件规格、线路选择与购买入口。 */ -/* 导入方:app/pages/products/dedicated-server/customize.vue、app/pages/products/dedicated-server/index.vue。 */ -.dedicated-catalog[data-v-e16eb167] { - width: 100%; - max-width: 1280px; - margin: 0 auto; - padding-bottom: 28px; -} -.catalog-head[data-v-e16eb167] { - justify-content: space-between; - align-items: center; - gap: 14px; - margin-bottom: 35px; - display: flex; -} -.catalog-head h1[data-v-e16eb167] { - margin: 0; - font-size: 1.375rem; - font-weight: 400; -} -.catalog-head a[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 0.875rem; - text-decoration: none; -} -.catalog-layout[data-v-e16eb167] { - grid-template-columns: 304px minmax(0, 1fr); - align-items: start; - gap: 21px; - display: grid; -} -.catalog-layout.has-selection[data-v-e16eb167] { - grid-template-columns: 240px minmax(0, 1fr) minmax(0, 1fr); -} -h2[data-v-e16eb167] { - border-bottom: 1px solid var(--p-content-border-color); - margin: 0 0 14px; - padding: 0 0 14px; - font-size: 1rem; - font-weight: 400; - line-height: 1.5rem; -} -.filter-panel[data-v-e16eb167], -.hardware-card[data-v-e16eb167] { - border: 1px solid var(--p-content-border-color); - background: var(--p-content-background); - border-radius: var(--radius-md); - box-shadow: 0 1px 3px #0000001a; -} -.filter-panel[data-v-e16eb167] { - padding: 0 16px 7px; -} -details[data-v-e16eb167] { - border-bottom: 1px solid var(--p-content-border-color); -} -summary[data-v-e16eb167] { - cursor: pointer; - justify-content: space-between; - padding: 16px 0; - font-weight: 500; - list-style: none; - display: flex; -} -summary[data-v-e16eb167]::-webkit-details-marker { - display: none; -} -summary > i[data-v-e16eb167] { - align-self: center; - font-size: 0.875rem; -} -details[open] > summary > i[data-v-e16eb167] { - transform: rotate(180deg); -} -.price-range[data-v-e16eb167] { - align-items: center; - gap: 7px; - margin: 7px 0 12px; - display: flex; -} -.price-range[data-v-e16eb167] .p-inputnumber { - flex: 1; - width: 0; -} -.price-range[data-v-e16eb167] input { - width: 100%; - min-width: 0; -} -.filter-panel small[data-v-e16eb167] { - color: var(--p-text-muted-color); - padding-bottom: 14px; - font-size: 0.8125rem; - line-height: 1.6; - display: block; -} -.filter-options[data-v-e16eb167] { - flex-wrap: wrap; - gap: 7px; - padding-bottom: 14px; - display: flex; -} -.filter-options button[data-v-e16eb167] { - border: 1px solid var(--p-content-border-color); - color: var(--p-text-color); - cursor: pointer; - background: 0 0; - border-radius: var(--radius-sm); - padding: 4px 7px; - font-size: 0.875rem; -} -.filter-options button.active[data-v-e16eb167] { - border-color: var(--p-primary-color); - background: var(--p-highlight-background); - color: var(--p-highlight-color); -} -.filter-empty[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 0.875rem; -} -.catalog-lines[data-v-e16eb167], -.catalog-products[data-v-e16eb167] { - min-width: 0; -} -.hardware-card[data-v-e16eb167] { - margin-bottom: 14px; - padding: 17px 15px; -} -.hardware-card.selected[data-v-e16eb167] { - outline: 2px solid var(--p-primary-color); - background: var(--p-highlight-background); -} -.hardware-card h3[data-v-e16eb167] { - margin: 0 0 24px; - font-size: 1.125rem; - font-weight: 600; -} -.hardware-body[data-v-e16eb167] { - grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto; - align-items: center; - gap: 21px; - display: grid; -} -.hardware-spec[data-v-e16eb167] { - align-items: center; - gap: 14px; - min-width: 0; - display: flex; -} -.hardware-spec i[data-v-e16eb167], -.line-specs i[data-v-e16eb167] { - color: var(--p-primary-color); -} -.hardware-spec > div[data-v-e16eb167] { - flex-direction: column; - min-width: 0; - display: flex; -} -.hardware-spec span[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 0.875rem; -} -/* 允许连续长文本换行,防止IP、密钥或用户输入撑破当前容器;不会修改原始数据。 */ -.hardware-spec strong[data-v-e16eb167] { - overflow-wrap: anywhere; - font-size: 1rem; - font-weight: 500; -} -.hardware-spec small[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 0.8125rem; -} -.hardware-buy[data-v-e16eb167] { - background: var(--p-content-hover-background); - border-radius: var(--radius-md); - align-items: center; - gap: 10px; - padding: 4px; - display: flex; -} -.hardware-buy > span[data-v-e16eb167] { - text-align: right; - flex-direction: column; - display: flex; -} -.hardware-buy strong[data-v-e16eb167] { - white-space: nowrap; - font-size: 1.25rem; -} -.hardware-buy small[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: max(11px, 0.625rem); -} -.hardware-buy[data-v-e16eb167] button { - min-width: 112px; -} -.hardware-card footer[data-v-e16eb167] { - color: var(--p-text-muted-color); - justify-content: space-between; - gap: 14px; - margin-top: 24px; - font-size: 0.875rem; - display: flex; -} -.has-selection .hardware-body[data-v-e16eb167] { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} -.has-selection .hardware-buy[data-v-e16eb167] { - grid-column: 1/-1; - justify-self: end; - margin-top: 7px; -} -.has-selection .hardware-card h3[data-v-e16eb167] { - margin-bottom: 21px; -} -.catalog-state[data-v-e16eb167] { - text-align: center; - border: 1px solid var(--p-content-border-color); - background: var(--p-content-background); - border-radius: var(--radius-md); - flex-direction: column; - align-items: center; - gap: 14px; - min-height: 260px; - padding: 70px 21px; - display: flex; -} -.catalog-state > i[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 2rem; -} -.catalog-state h3[data-v-e16eb167] { - margin: 0; - font-size: 1.125rem; -} -.catalog-state p[data-v-e16eb167] { - color: var(--p-text-muted-color); - margin: 0; - font-size: 0.9375rem; -} -.line-heading[data-v-e16eb167] { - border-bottom: 1px solid var(--p-content-border-color); - justify-content: space-between; - align-items: center; - min-height: 36px; - margin-bottom: 14px; - display: flex; -} -.line-heading h2[data-v-e16eb167] { - border: 0; - margin: 0; - padding: 0; -} -.line-panel[data-v-e16eb167] { - border: 1px solid var(--p-content-border-color); - background: var(--p-highlight-background); - border-radius: var(--radius-md); - padding: 0 17px; -} -.line-card[data-v-e16eb167] { - border-bottom: 1px solid var(--p-content-border-color); - padding: 17px 0; -} -.line-card[data-v-e16eb167]:last-child { - border: 0; -} -.line-tags[data-v-e16eb167] { - flex-wrap: wrap; - gap: 8px; - margin-bottom: 21px; - display: flex; -} -.line-specs[data-v-e16eb167] { - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 14px; - display: grid; -} -.line-specs > div[data-v-e16eb167] { - align-items: center; - gap: 10px; - min-width: 0; - display: flex; -} -.line-specs span[data-v-e16eb167] { - color: var(--p-text-muted-color); - font-size: 0.875rem; -} -.line-specs strong[data-v-e16eb167] { - color: var(--p-text-color); - font-size: 1rem; - font-weight: 500; - display: block; -} -.line-action[data-v-e16eb167] { - justify-content: flex-end; - align-items: center; - gap: 10px; - margin-top: 21px; - display: flex; -} -.line-action .line-order-link[data-v-e16eb167] { - white-space: nowrap; - flex-shrink: 0; - justify-content: center; - align-items: center; - gap: 7px; - min-width: 112px; - text-decoration: none; - display: inline-flex; -} -/* 允许连续长文本换行,防止IP、密钥或用户输入撑破当前容器;不会修改原始数据。 */ -.line-action > span[data-v-e16eb167] { - overflow-wrap: anywhere; - min-width: 0; - color: var(--p-text-muted-color); - font-size: 0.8125rem; -} -.line-empty[data-v-e16eb167] { - padding: 21px; - font-size: 0.9375rem; -} -.filter-options button[data-v-e16eb167]:focus-visible, -summary[data-v-e16eb167]:focus-visible { - outline: 2px solid var(--p-primary-color); - outline-offset: 3px; -} -/* 视口条件 (width>=1024px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ -@media (width>=1024px) { - .catalog-lines[data-v-e16eb167] { - position: sticky; - top: calc(var(--console-top-offset, 56px) + 20px); - } -} -/* 视口条件 (width<1200px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ -@media (width<1200px) { - .catalog-layout[data-v-e16eb167] { - grid-template-columns: 240px minmax(0, 1fr); - } - .hardware-body[data-v-e16eb167] { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - .hardware-buy[data-v-e16eb167] { - grid-column: 1/-1; - justify-self: end; - } - .catalog-layout.has-selection[data-v-e16eb167] { - grid-template-columns: 200px minmax(0, 1fr); - } - .catalog-lines[data-v-e16eb167] { - grid-area: 1/2; - position: static; - } - .has-selection .catalog-products[data-v-e16eb167] { - grid-column: 2; - } - .has-selection .catalog-filters[data-v-e16eb167] { - grid-row: 1 / span 2; - } -} -/* 视口条件 (width<768px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ -@media (width<768px) { - .catalog-head[data-v-e16eb167] { - margin-bottom: 28px; - } - .catalog-layout[data-v-e16eb167], - .catalog-layout.has-selection[data-v-e16eb167] { - flex-direction: column; - gap: 28px; - display: flex; - } - .catalog-filters[data-v-e16eb167], - .catalog-lines[data-v-e16eb167], - .catalog-products[data-v-e16eb167] { - width: 100%; - } - .catalog-lines[data-v-e16eb167] { - order: -1; - } - .catalog-head h1[data-v-e16eb167] { - font-size: 1.375rem; - } - .hardware-body[data-v-e16eb167] { - gap: 14px; - } - .line-action[data-v-e16eb167] { - flex-wrap: wrap; - } - .line-specs[data-v-e16eb167] { - gap: 8px; - } - .line-specs > div[data-v-e16eb167] { - gap: 6px; - } - .line-specs strong[data-v-e16eb167] { - font-size: 0.875rem; - } - .catalog-state[data-v-e16eb167] { - padding: 42px 14px; - } -} diff --git a/app/assets/styles/entry.Cs9kvuGi.css b/app/assets/styles/entry.Cs9kvuGi.css index 31ba733..a3c55aa 100644 --- a/app/assets/styles/entry.Cs9kvuGi.css +++ b/app/assets/styles/entry.Cs9kvuGi.css @@ -1515,22 +1515,25 @@ video { } .config-summary { flex-direction: column; - gap: 10px; + gap: 7px; margin: 0; display: flex; } .config-summary-row { - grid-template-columns: 68px minmax(0, 1fr); + grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: 12px; - font-size: 1rem; + font-size: 0.9375rem; line-height: 1.429rem; display: grid; } .config-summary-row dt { min-width: 0; + max-width: 7em; color: var(--p-text-muted-color); - overflow-wrap: anywhere; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } .config-summary-row dd { text-align: right; @@ -1719,9 +1722,32 @@ video { } /* 视口条件 (width>=1024px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ @media (width>=1024px) { + /* 汇总栏高度限制在视口内,配置清单内部滚动,价格与购买按钮始终可见。 */ .config-summary-wrap { position: sticky; top: calc(var(--console-top-offset, 56px) + 20px); + max-height: calc(100vh - var(--console-top-offset, 56px) - 40px); + flex-direction: column; + display: flex; + } + .config-summary-wrap > .config-column-title { + flex: none; + } + .config-page .config-summary-wrap > .config-checkout { + flex-direction: column; + min-height: 0; + display: flex; + } + .config-summary-wrap .config-checkout > * { + flex: none; + } + .config-summary-wrap .config-checkout > .config-summary { + flex: 0 1 auto; + min-height: 72px; + margin-right: -6px; + padding-right: 6px; + overflow-y: auto; + scrollbar-width: thin; } } /* 视口条件 (width<1200px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */ diff --git a/app/assets/styles/products.CrccEo2m.css b/app/assets/styles/products.CrccEo2m.css index a16cb33..d733330 100644 --- a/app/assets/styles/products.CrccEo2m.css +++ b/app/assets/styles/products.CrccEo2m.css @@ -225,6 +225,7 @@ color: var(--p-primary-color); border-radius: var(--radius-md); flex-shrink: 0; + align-self: center; place-items: center; font-size: 1.375rem; display: grid; @@ -446,3 +447,79 @@ button[data-v-a6c63d86]:focus-visible { flex-wrap: wrap; } } +/* 分类导航:一级为下划线标签页,二级为小号胶囊按钮,徽标弱化为辅助文字;分类区不再单独成卡片。 */ +.catalog-categories[data-v-a6c63d86] { + background: none; + border: 0; + border-radius: 0; + padding: 0; +} +.catalog-categories h2[data-v-a6c63d86] { + clip-path: inset(50%); + white-space: nowrap; + width: 1px; + height: 1px; + margin: -1px; + position: absolute; + overflow: hidden; +} +.category-options:not(.secondary-categories)[data-v-a6c63d86] { + border-bottom: 1px solid var(--p-content-border-color); + flex-wrap: nowrap; + gap: 2px; + overflow-x: auto; + scrollbar-width: none; +} +.category-options:not(.secondary-categories) button[data-v-a6c63d86] { + color: var(--p-text-muted-color); + white-space: nowrap; + background: none; + border: 0; + border-bottom: 2px solid transparent; + border-radius: 0; + flex: none; + margin-bottom: -1px; + padding: 6px 12px 8px; + font-size: 0.9375rem; +} +.category-options:not(.secondary-categories) button[data-v-a6c63d86]:hover { + color: var(--p-text-color); +} +.category-options:not(.secondary-categories) button.active[data-v-a6c63d86] { + border-bottom-color: var(--p-primary-color); + color: var(--p-primary-color); + background: none; + font-weight: 500; +} +.category-options.secondary-categories[data-v-a6c63d86] { + border-top: 0; + gap: 8px; + margin-top: 12px; + padding-top: 0; +} +.category-options.secondary-categories button[data-v-a6c63d86] { + min-height: 34px; + padding: 5px 12px; + font-size: 0.875rem; + line-height: 1.4; +} +.category-options.secondary-categories button[data-v-a6c63d86]:hover { + color: var(--p-text-color); +} +.category-options.secondary-categories button.active[data-v-a6c63d86] { + box-shadow: inset 0 0 0 1px var(--p-primary-color); + color: var(--p-highlight-color); + font-weight: 500; +} +.category-options[data-v-a6c63d86] .product-group-badge { + color: inherit; + opacity: 0.6; + background: none; + border: 0; + padding: 0; + font-size: 0.75rem; + font-weight: 400; +} +.category-options[data-v-a6c63d86] .product-group-label { + gap: 2px 6px; +} diff --git a/app/components/config/CloudProductPicker.vue b/app/components/config/CloudProductPicker.vue index 8a36c11..f6e0f36 100644 --- a/app/components/config/CloudProductPicker.vue +++ b/app/components/config/CloudProductPicker.vue @@ -1,453 +1,407 @@ - + + + + diff --git a/app/components/config/KkyEcsConfig.vue b/app/components/config/KkyEcsConfig.vue index e96b3dc..8256a8d 100644 --- a/app/components/config/KkyEcsConfig.vue +++ b/app/components/config/KkyEcsConfig.vue @@ -596,7 +596,7 @@ var N = { }, he = { key: 0, - class: `panel`, + class: `panel storage-panel`, }, ge = { key: 0, @@ -648,6 +648,9 @@ var N = { Oe = { class: `form-row`, }, + Pe1 = { + class: `form-inline`, + }, ke = Object.assign( _plugin_vue_export_helper_t( defineComponent({ @@ -1018,124 +1021,131 @@ var N = { `基础配置`, -1, )), - createElementVNode(`div`, L, [ - (r[18] ||= createElementVNode( - `label`, - null, - `区域`, - -1, - )), - createVNode( - b, - { - label: `区域`, - disabled: unref(W), - modelValue: unref(A).line_id, - "onUpdate:modelValue": (r[1] ||= (e) => - (unref(A).line_id = e)), - options: (unref(D).line_list || []).map( - (e) => ({ + createElementVNode(`div`, Pe1, [ + createElementVNode(`div`, L, [ + (r[18] ||= createElementVNode( + `label`, + null, + `区域`, + -1, + )), + createVNode( + b, + { + label: `区域`, + compact: ``, + disabled: unref(W), + modelValue: unref(A).line_id, + "onUpdate:modelValue": (r[1] ||= (e) => + (unref(A).line_id = e)), + options: (unref(D).line_list || []).map( + (e) => ({ + label: e.name, + value: e.id, + }), + ), + onChange: Xe, + }, + null, + 8, + [`disabled`, `modelValue`, `options`], + ), + ]), + createElementVNode(`div`, R, [ + (r[19] ||= createElementVNode( + `label`, + null, + `线路`, + -1, + )), + createVNode( + b, + { + label: `线路`, + compact: ``, + disabled: unref(W), + modelValue: unref(A).network_id, + "onUpdate:modelValue": (r[2] ||= (e) => + (unref(A).network_id = e)), + options: ( + unref(D).network_list || [] + ).map((e) => ({ label: e.name, value: e.id, - }), - ), - onChange: Xe, - }, - null, - 8, - [`disabled`, `modelValue`, `options`], - ), + })), + onChange: Qe, + }, + null, + 8, + [`disabled`, `modelValue`, `options`], + ), + ]), ]), - createElementVNode(`div`, R, [ - (r[19] ||= createElementVNode( - `label`, - null, - `线路`, - -1, - )), - createVNode( - b, - { - label: `线路`, - disabled: unref(W), - modelValue: unref(A).network_id, - "onUpdate:modelValue": (r[2] ||= (e) => - (unref(A).network_id = e)), - options: ( - unref(D).network_list || [] - ).map((e) => ({ - label: e.name, - value: e.id, - })), - onChange: Qe, - }, - null, - 8, - [`disabled`, `modelValue`, `options`], - ), - ]), - createElementVNode(`div`, z, [ - (r[20] ||= createElementVNode( - `label`, - null, - `CPU`, - -1, - )), - createVNode( - b, - { - label: `CPU`, - disabled: unref(W), - "model-value": - Number(unref(A).cpu_num) || null, - options: unref(ke).map((e) => ({ - label: `${e} 核`, - value: e, - })), - compact: ``, - "onUpdate:modelValue": unref(S).selectCpu, - }, - null, - 8, - [ - `disabled`, - `model-value`, - `options`, - `onUpdate:modelValue`, - ], - ), - ]), - createElementVNode(`div`, me, [ - (r[21] ||= createElementVNode( - `label`, - null, - `内存`, - -1, - )), - createVNode( - b, - { - label: `内存`, - disabled: unref(W), - "model-value": - Number(unref(A).memory) || null, - options: unref(Ae).map((e) => ({ - label: `${e} GB`, - value: e, - })), - compact: ``, - "onUpdate:modelValue": - unref(S).selectMemory, - }, - null, - 8, - [ - `disabled`, - `model-value`, - `options`, - `onUpdate:modelValue`, - ], - ), + createElementVNode(`div`, Pe1, [ + createElementVNode(`div`, z, [ + (r[20] ||= createElementVNode( + `label`, + null, + `CPU`, + -1, + )), + createVNode( + b, + { + label: `CPU`, + disabled: unref(W), + "model-value": + Number(unref(A).cpu_num) || null, + options: unref(ke).map((e) => ({ + label: `${e} 核`, + value: e, + })), + compact: ``, + "onUpdate:modelValue": + unref(S).selectCpu, + }, + null, + 8, + [ + `disabled`, + `model-value`, + `options`, + `onUpdate:modelValue`, + ], + ), + ]), + createElementVNode(`div`, me, [ + (r[21] ||= createElementVNode( + `label`, + null, + `内存`, + -1, + )), + createVNode( + b, + { + label: `内存`, + disabled: unref(W), + "model-value": + Number(unref(A).memory) || null, + options: unref(Ae).map((e) => ({ + label: `${e} GB`, + value: e, + })), + compact: ``, + "onUpdate:modelValue": + unref(S).selectMemory, + }, + null, + 8, + [ + `disabled`, + `model-value`, + `options`, + `onUpdate:modelValue`, + ], + ), + ]), ]), ]), unref(X) || unref(H) diff --git a/app/pages/products/cloud-server.vue b/app/pages/products/cloud-server.vue index 096df8f..a14127c 100644 --- a/app/pages/products/cloud-server.vue +++ b/app/pages/products/cloud-server.vue @@ -15,7 +15,6 @@ import "~/assets/styles/PromoCodeField.qFEkB6Hm.css"; import "~/assets/styles/ProductCustomFields.B2QMnPil.css"; import "~/assets/styles/OsIcon.CAi4Iz2S.css"; import "~/assets/styles/CommonConfig.Cfik-oMe.css"; -import "~/assets/styles/CloudProductPicker.CAm9rmUl.css"; import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css"; import "~/assets/styles/PaymentDialog.BNFKQF1U.css"; import "~/assets/styles/cloud-server.CcwlOXJ0.css"; @@ -42,6 +41,7 @@ import { unref } from "vue"; import { defineComponent } from "vue"; import { createVNode } from "vue"; import { openBlock } from "vue"; +import { NuxtLink } from "#components"; import { useRoute } from "#app"; import { useRouter } from "#app"; import { useHead } from "#app"; @@ -323,12 +323,17 @@ var ge = { return ( openBlock(), createElementBlock(`div`, ge, [ - (r[4] ||= createElementVNode( - `h2`, - null, - `创建云服务器实例`, - -1, - )), + createElementVNode(`header`, { class: `order-head` }, [ + createElementVNode(`h2`, null, `创建云服务器实例`), + createVNode( + NuxtLink, + { to: `/products` }, + { + default: withCtx(() => [createTextVNode(`查看全部产品`)]), + _: 1, + }, + ), + ]), unref(D) && unref(B) ? (openBlock(), createBlock( diff --git a/app/pages/products/dedicated-server/customize.vue b/app/pages/products/dedicated-server/customize.vue index 8416647..3e25f57 100644 --- a/app/pages/products/dedicated-server/customize.vue +++ b/app/pages/products/dedicated-server/customize.vue @@ -3,7 +3,6 @@ * 物理服务器定制入口:只接受有效商品 ID 且模块为 mf_dcim/remf_dcim,避免把其他类型商品交给物理服务器配置器。 */ import { definePageMeta } from "#imports"; -import "~/assets/styles/dedicated-server.CiJfMYtk.css"; import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css"; import "~/assets/styles/PromoCodeField.qFEkB6Hm.css"; import "~/assets/styles/ProductCustomFields.B2QMnPil.css"; diff --git a/app/pages/products/dedicated-server/index.vue b/app/pages/products/dedicated-server/index.vue index c2f6309..4fd2dbf 100644 --- a/app/pages/products/dedicated-server/index.vue +++ b/app/pages/products/dedicated-server/index.vue @@ -1,1222 +1,1116 @@ - + + + +