- 云产品选择器新增地区标签页、分组数量及全部选项,自动跟随当前线路所属地区 - 将线路和型号改为紧凑选择按钮,精简型号名称的公共前缀并保留完整名称提示 - 物理服务器目录改为规格列表,支持行内展开、收起线路详情及进入定制页 - 新增商品起价升降序排序,将无有效价格的商品置于末尾 - 将规格筛选改为下拉选项,移动端支持展开更多筛选并显示已选条件数量 - 统一云服务器与物理服务器的横向配置表单,优化磁盘、带宽、镜像选择及移动端布局 - 限制桌面端配置汇总栏高度,使清单内部滚动并保持价格和购买按钮可见 - 统一产品分类标签页与胶囊按钮样式,补充查看全部产品入口 - 将产品选择器和物理服务器目录重构为 script setup、声明式模板及 scoped 样式,删除旧样式文件与相关引用
This commit is contained in:
12 files changed
+2121
-2312
No files matched your search
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -44,3 +44,195 @@
|
|||||||
max-width: 470px;
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -179,3 +179,166 @@
|
|||||||
width: 125px;
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,3 +15,18 @@ h2[data-v-ef3931f0] {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 2rem;
|
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);
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1515,22 +1515,25 @@ video {
|
|||||||
}
|
}
|
||||||
.config-summary {
|
.config-summary {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 7px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.config-summary-row {
|
.config-summary-row {
|
||||||
grid-template-columns: 68px minmax(0, 1fr);
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
font-size: 1rem;
|
font-size: 0.9375rem;
|
||||||
line-height: 1.429rem;
|
line-height: 1.429rem;
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
.config-summary-row dt {
|
.config-summary-row dt {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
max-width: 7em;
|
||||||
color: var(--p-text-muted-color);
|
color: var(--p-text-muted-color);
|
||||||
overflow-wrap: anywhere;
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.config-summary-row dd {
|
.config-summary-row dd {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
@@ -1719,9 +1722,32 @@ video {
|
|||||||
}
|
}
|
||||||
/* 视口条件 (width>=1024px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */
|
/* 视口条件 (width>=1024px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */
|
||||||
@media (width>=1024px) {
|
@media (width>=1024px) {
|
||||||
|
/* 汇总栏高度限制在视口内,配置清单内部滚动,价格与购买按钮始终可见。 */
|
||||||
.config-summary-wrap {
|
.config-summary-wrap {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: calc(var(--console-top-offset, 56px) + 20px);
|
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) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */
|
/* 视口条件 (width<1200px) 下的响应式覆盖;保留相对基础规则的层叠顺序。 */
|
||||||
|
|||||||
@@ -225,6 +225,7 @@
|
|||||||
color: var(--p-primary-color);
|
color: var(--p-primary-color);
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
align-self: center;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
font-size: 1.375rem;
|
font-size: 1.375rem;
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -446,3 +447,79 @@ button[data-v-a6c63d86]:focus-visible {
|
|||||||
flex-wrap: wrap;
|
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;
|
||||||
|
}
|
||||||
@@ -1,453 +1,407 @@
|
|||||||
<script>
|
<script setup>
|
||||||
/**
|
/**
|
||||||
* 云商品分组与分页选择器:groups/products/库存文案由父级提供,不直接请求接口。
|
* 云商品分组与分页选择器:groups/products/库存文案由父级提供,不直接请求接口。
|
||||||
* 分组、商品、重试和分页分别发出意图事件;disabled 将购买提交期间的选择锁定。
|
* 分组按名称归入地区标签页;分组、商品、重试和分页分别发出意图事件;disabled 将购买提交期间的选择锁定。
|
||||||
*/
|
*/
|
||||||
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
|
import { computed, ref, useId, watch } from "vue";
|
||||||
import "~/assets/styles/CloudProductPicker.CAm9rmUl.css";
|
|
||||||
import { toDisplayString } from "vue";
|
|
||||||
import { renderList } from "vue";
|
|
||||||
import { useId } from "vue";
|
|
||||||
import { normalizeClass } from "vue";
|
|
||||||
import { createBlock } from "vue";
|
|
||||||
import { withCtx } from "vue";
|
|
||||||
import { createCommentVNode } from "vue";
|
|
||||||
import { createElementBlock } from "vue";
|
|
||||||
import { Fragment } from "vue";
|
|
||||||
import { createElementVNode } from "vue";
|
|
||||||
import { createTextVNode } from "vue";
|
|
||||||
import { unref } from "vue";
|
|
||||||
import { defineComponent } from "vue";
|
|
||||||
import { createVNode } from "vue";
|
|
||||||
import { openBlock } from "vue";
|
|
||||||
import { NuxtLink } from "#components";
|
import { NuxtLink } from "#components";
|
||||||
import button from "openvue/button";
|
import Button from "openvue/button";
|
||||||
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
|
import Message from "openvue/message";
|
||||||
import message from "openvue/message";
|
import Paginator from "openvue/paginator";
|
||||||
import { n as product_name_n } from "~/lib/product-name.js";
|
import Skeleton from "openvue/skeleton";
|
||||||
import paginator from "openvue/paginator";
|
import ProductGroupLabel, {
|
||||||
import skeleton from "openvue/skeleton";
|
n as parseGroupLabel,
|
||||||
import ProductGroupLabel from "~/components/ProductGroupLabel.vue";
|
} from "~/components/ProductGroupLabel.vue";
|
||||||
var C = {
|
import { n as displayProductName } from "~/lib/product-name.js";
|
||||||
class: `cloud-product-picker`,
|
|
||||||
},
|
const props = defineProps({
|
||||||
w = [`aria-labelledby`],
|
groups: { type: Array, default: () => [] },
|
||||||
T = [`id`],
|
activeGroup: {},
|
||||||
E = {
|
products: { type: Array, default: () => [] },
|
||||||
class: `zone-options`,
|
selectedId: {},
|
||||||
role: `group`,
|
loading: Boolean,
|
||||||
"aria-label": `产品专区`,
|
productLoading: Boolean,
|
||||||
},
|
error: {},
|
||||||
D = [`aria-pressed`, `disabled`, `onClick`],
|
errorSource: {},
|
||||||
O = {
|
total: {},
|
||||||
key: 2,
|
page: {},
|
||||||
class: `catalog-empty`,
|
disabled: Boolean,
|
||||||
},
|
soldOut: Function,
|
||||||
k = [`aria-labelledby`],
|
stockLabel: Function,
|
||||||
A = [`id`],
|
});
|
||||||
j = {
|
const emit = defineEmits([
|
||||||
key: 2,
|
"choose-group",
|
||||||
class: `catalog-empty`,
|
"choose-product",
|
||||||
},
|
"retry-groups",
|
||||||
M = {
|
"retry-products",
|
||||||
key: 3,
|
"paginate",
|
||||||
class: `product-options`,
|
]);
|
||||||
role: `group`,
|
const id = useId();
|
||||||
"aria-label": `选择云服务器产品`,
|
|
||||||
},
|
// 按名称关键字归类;港澳台与海外优先匹配,避免“香港BGP”之类被省份规则误判。
|
||||||
N = [`aria-pressed`, `disabled`, `onClick`],
|
const REGIONS = [
|
||||||
P = {
|
[
|
||||||
key: 0,
|
"华东",
|
||||||
},
|
/上海|江苏|浙江|安徽|福建|江西|山东|华东|宿迁|金华|宁波|温州|绍兴|镇江|盐城|扬州|常州|无锡|徐州|泉州|厦门|福州|芜湖|九江|济南|杭州|南京|苏州/,
|
||||||
F = {
|
],
|
||||||
key: 1,
|
["华南", /广东|广西|海南|华南|深圳|广州|佛山|东莞|海口|南宁/],
|
||||||
},
|
["华中", /湖北|湖南|河南|华中|襄阳|十堰|武汉|郑州|新乡|长沙/],
|
||||||
I = Object.assign(
|
["华北", /北京|天津|河北|山西|内蒙|华北|石家庄|太原/],
|
||||||
_plugin_vue_export_helper_t(
|
["西南", /四川|重庆|云南|贵州|西藏|西南|成都|昆明|德阳|贵阳/],
|
||||||
defineComponent({
|
["西北", /陕西|甘肃|青海|宁夏|新疆|西北|西安|咸阳|兰州/],
|
||||||
__name: `CloudProductPicker`,
|
["东北", /辽宁|吉林|黑龙江|东北|沈阳|鞍山|大连|长春|哈尔滨/],
|
||||||
props: {
|
];
|
||||||
groups: {},
|
const ABROAD = [
|
||||||
activeGroup: {},
|
["港澳台", /香港|澳门|台湾/],
|
||||||
products: {},
|
[
|
||||||
selectedId: {},
|
"海外",
|
||||||
loading: {
|
/美国|日本|韩国|新加坡|越南|马来|泰国|菲律宾|印尼|印度|德国|英国|法国|荷兰|俄罗斯|欧洲|洛杉矶|硅谷|东京|首尔|海外/,
|
||||||
type: Boolean,
|
],
|
||||||
},
|
];
|
||||||
productLoading: {
|
const REGION_ORDER = [...REGIONS, ...ABROAD]
|
||||||
type: Boolean,
|
.map(([name]) => name)
|
||||||
},
|
.concat("其他");
|
||||||
error: {},
|
|
||||||
errorSource: {},
|
function regionOf(group) {
|
||||||
total: {},
|
const name = parseGroupLabel(group.name).name;
|
||||||
page: {},
|
for (const [region, pattern] of [...ABROAD, ...REGIONS])
|
||||||
disabled: {
|
if (pattern.test(name)) return region;
|
||||||
type: Boolean,
|
return "其他";
|
||||||
},
|
}
|
||||||
soldOut: {
|
|
||||||
type: Function,
|
const regions = computed(() => {
|
||||||
},
|
const buckets = new Map();
|
||||||
stockLabel: {
|
for (const group of props.groups) {
|
||||||
type: Function,
|
const region = regionOf(group);
|
||||||
},
|
if (!buckets.has(region)) buckets.set(region, []);
|
||||||
},
|
buckets.get(region).push(group);
|
||||||
emits: [
|
}
|
||||||
`choose-group`,
|
return REGION_ORDER.filter((name) => buckets.has(name)).map((name) => ({
|
||||||
`choose-product`,
|
name,
|
||||||
`retry-groups`,
|
groups: buckets.get(name),
|
||||||
`retry-products`,
|
}));
|
||||||
`paginate`,
|
});
|
||||||
],
|
const activeGroupRegion = computed(() => {
|
||||||
setup(f, { emit: _ }) {
|
const group = props.groups.find((g) => g.id === props.activeGroup);
|
||||||
let I = _,
|
return group ? regionOf(group) : regions.value[0]?.name;
|
||||||
L = useId();
|
});
|
||||||
return (n, _) => {
|
const chosenRegion = ref(null);
|
||||||
let R = skeleton,
|
watch(
|
||||||
z = button,
|
() => props.activeGroup,
|
||||||
B = message,
|
() => (chosenRegion.value = null),
|
||||||
V = ProductGroupLabel,
|
);
|
||||||
H = NuxtLink,
|
const currentRegion = computed(
|
||||||
U = paginator;
|
() => chosenRegion.value ?? activeGroupRegion.value ?? "all",
|
||||||
return (
|
);
|
||||||
openBlock(),
|
const visibleGroups = computed(() =>
|
||||||
createElementBlock(`div`, C, [
|
currentRegion.value === "all"
|
||||||
createElementVNode(
|
? props.groups
|
||||||
`section`,
|
: (regions.value.find((r) => r.name === currentRegion.value)?.groups ??
|
||||||
{
|
props.groups),
|
||||||
class: `selection-section`,
|
);
|
||||||
"aria-labelledby": `${unref(L)}-lines-title`,
|
// 同一分组下的商品名称通常共享“地区 | 运营商(”前缀,只显示差异部分,完整名称放在 title 中。
|
||||||
},
|
const productLabels = computed(() => {
|
||||||
[
|
const names = props.products.map((p) => displayProductName(p.name));
|
||||||
createElementVNode(
|
const plain = { labels: names };
|
||||||
`h3`,
|
if (names.length < 2) return plain;
|
||||||
{
|
let prefix = names[0];
|
||||||
id: `${unref(L)}-lines-title`,
|
for (const name of names)
|
||||||
},
|
while (!name.startsWith(prefix)) prefix = prefix.slice(0, -1);
|
||||||
`选择线路`,
|
const boundary = prefix.match(/^.*[((\s||·\-_/]/);
|
||||||
8,
|
prefix = boundary ? boundary[0] : "";
|
||||||
T,
|
if (prefix.length < 2 || names.some((n) => n.length <= prefix.length))
|
||||||
),
|
return plain;
|
||||||
f.loading
|
const opensParen = /[((]$/.test(prefix);
|
||||||
? (openBlock(),
|
return {
|
||||||
createBlock(R, {
|
labels: names.map((name) => {
|
||||||
key: 0,
|
const rest = name.slice(prefix.length).trim();
|
||||||
height: `110px`,
|
return opensParen ? rest.replace(/[))]$/, "") : rest;
|
||||||
}))
|
}),
|
||||||
: (openBlock(),
|
};
|
||||||
createElementBlock(
|
});
|
||||||
Fragment,
|
|
||||||
{
|
|
||||||
key: 1,
|
|
||||||
},
|
|
||||||
[
|
|
||||||
f.error && f.errorSource === `groups`
|
|
||||||
? (openBlock(),
|
|
||||||
createBlock(
|
|
||||||
B,
|
|
||||||
{
|
|
||||||
key: 0,
|
|
||||||
severity: `error`,
|
|
||||||
closable: !1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: withCtx(() => [
|
|
||||||
createTextVNode(
|
|
||||||
toDisplayString(f.error),
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
createVNode(
|
|
||||||
z,
|
|
||||||
{
|
|
||||||
label: `重新加载线路`,
|
|
||||||
severity: `secondary`,
|
|
||||||
text: ``,
|
|
||||||
disabled: f.disabled,
|
|
||||||
onClick: (_[0] ||= (e) =>
|
|
||||||
I(`retry-groups`)),
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
8,
|
|
||||||
[`disabled`],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
_: 1,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
: f.groups.length
|
|
||||||
? (openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
Fragment,
|
|
||||||
{
|
|
||||||
key: 1,
|
|
||||||
},
|
|
||||||
[
|
|
||||||
(_[3] ||= createElementVNode(
|
|
||||||
`div`,
|
|
||||||
{
|
|
||||||
class: `selection-label`,
|
|
||||||
},
|
|
||||||
`产品专区`,
|
|
||||||
-1,
|
|
||||||
)),
|
|
||||||
createElementVNode(`div`, E, [
|
|
||||||
(openBlock(!0),
|
|
||||||
createElementBlock(
|
|
||||||
Fragment,
|
|
||||||
null,
|
|
||||||
renderList(
|
|
||||||
f.groups,
|
|
||||||
(e) => (
|
|
||||||
openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
`button`,
|
|
||||||
{
|
|
||||||
key: e.id,
|
|
||||||
type: `button`,
|
|
||||||
class: normalizeClass([
|
|
||||||
`zone-option`,
|
|
||||||
{
|
|
||||||
active:
|
|
||||||
f.activeGroup === e.id,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
"aria-pressed":
|
|
||||||
f.activeGroup === e.id,
|
|
||||||
disabled: f.disabled,
|
|
||||||
onClick: (t) =>
|
|
||||||
I(`choose-group`, e.id),
|
|
||||||
},
|
|
||||||
[
|
|
||||||
createVNode(
|
|
||||||
V,
|
|
||||||
{
|
|
||||||
name: e.name,
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
8,
|
|
||||||
[`name`],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
10,
|
|
||||||
D,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
128,
|
|
||||||
)),
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
64,
|
|
||||||
))
|
|
||||||
: (openBlock(),
|
|
||||||
createElementBlock(`div`, O, [
|
|
||||||
(_[5] ||= createElementVNode(
|
|
||||||
`i`,
|
|
||||||
{
|
|
||||||
class: `pi pi-box`,
|
|
||||||
"aria-hidden": `true`,
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
-1,
|
|
||||||
)),
|
|
||||||
(_[6] ||= createElementVNode(
|
|
||||||
`p`,
|
|
||||||
null,
|
|
||||||
`暂未提供可选的云服务器线路`,
|
|
||||||
-1,
|
|
||||||
)),
|
|
||||||
createVNode(
|
|
||||||
H,
|
|
||||||
{
|
|
||||||
to: `/products`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: withCtx(() => [
|
|
||||||
...(_[4] ||= [
|
|
||||||
createTextVNode(`浏览产品`, -1),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
_: 1,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
])),
|
|
||||||
],
|
|
||||||
64,
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
8,
|
|
||||||
w,
|
|
||||||
),
|
|
||||||
f.groups.length
|
|
||||||
? (openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
`section`,
|
|
||||||
{
|
|
||||||
key: 0,
|
|
||||||
class: `selection-section`,
|
|
||||||
"aria-labelledby": `${unref(L)}-products-title`,
|
|
||||||
},
|
|
||||||
[
|
|
||||||
createElementVNode(
|
|
||||||
`h3`,
|
|
||||||
{
|
|
||||||
id: `${unref(L)}-products-title`,
|
|
||||||
class: `products-title`,
|
|
||||||
},
|
|
||||||
`产品`,
|
|
||||||
8,
|
|
||||||
A,
|
|
||||||
),
|
|
||||||
f.productLoading && !f.products.length
|
|
||||||
? (openBlock(),
|
|
||||||
createBlock(R, {
|
|
||||||
key: 0,
|
|
||||||
height: `110px`,
|
|
||||||
}))
|
|
||||||
: f.error && f.errorSource === `products`
|
|
||||||
? (openBlock(),
|
|
||||||
createBlock(
|
|
||||||
B,
|
|
||||||
{
|
|
||||||
key: 1,
|
|
||||||
severity: `error`,
|
|
||||||
closable: !1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
default: withCtx(() => [
|
|
||||||
createTextVNode(
|
|
||||||
toDisplayString(f.error),
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
createVNode(
|
|
||||||
z,
|
|
||||||
{
|
|
||||||
label: `重新加载商品`,
|
|
||||||
severity: `secondary`,
|
|
||||||
text: ``,
|
|
||||||
disabled: f.disabled,
|
|
||||||
onClick: (_[1] ||= (e) =>
|
|
||||||
I(`retry-products`)),
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
8,
|
|
||||||
[`disabled`],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
_: 1,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
: !f.products.length && !f.error
|
|
||||||
? (openBlock(),
|
|
||||||
createElementBlock(`div`, j, [
|
|
||||||
...(_[7] ||= [
|
|
||||||
createElementVNode(
|
|
||||||
`p`,
|
|
||||||
null,
|
|
||||||
`该专区暂无可售产品`,
|
|
||||||
-1,
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
]))
|
|
||||||
: (openBlock(),
|
|
||||||
createElementBlock(`div`, M, [
|
|
||||||
(openBlock(!0),
|
|
||||||
createElementBlock(
|
|
||||||
Fragment,
|
|
||||||
null,
|
|
||||||
renderList(
|
|
||||||
f.products,
|
|
||||||
(t) => (
|
|
||||||
openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
`button`,
|
|
||||||
{
|
|
||||||
key: t.id,
|
|
||||||
type: `button`,
|
|
||||||
class: normalizeClass([
|
|
||||||
`product-option`,
|
|
||||||
{
|
|
||||||
active: f.selectedId === t.id,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
"aria-pressed":
|
|
||||||
f.selectedId === t.id,
|
|
||||||
disabled:
|
|
||||||
f.disabled || f.soldOut(t),
|
|
||||||
onClick: (e) =>
|
|
||||||
I(`choose-product`, t.id),
|
|
||||||
},
|
|
||||||
[
|
|
||||||
createElementVNode(
|
|
||||||
`strong`,
|
|
||||||
null,
|
|
||||||
toDisplayString(
|
|
||||||
unref(product_name_n)(t.name),
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
f.soldOut(t)
|
|
||||||
? (openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
`span`,
|
|
||||||
P,
|
|
||||||
toDisplayString(
|
|
||||||
f.stockLabel(t),
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
))
|
|
||||||
: (openBlock(),
|
|
||||||
createElementBlock(
|
|
||||||
`span`,
|
|
||||||
F,
|
|
||||||
toDisplayString(
|
|
||||||
f.selectedId === t.id
|
|
||||||
? `当前配置`
|
|
||||||
: `查看可选配置`,
|
|
||||||
),
|
|
||||||
1,
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
10,
|
|
||||||
N,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
128,
|
|
||||||
)),
|
|
||||||
])),
|
|
||||||
f.total > 24
|
|
||||||
? (openBlock(),
|
|
||||||
createBlock(
|
|
||||||
U,
|
|
||||||
{
|
|
||||||
key: 4,
|
|
||||||
first: (f.page - 1) * 24,
|
|
||||||
rows: 24,
|
|
||||||
totalRecords: f.total,
|
|
||||||
disabled: f.disabled,
|
|
||||||
onPage: (_[2] ||= (e) => I(`paginate`, e)),
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
8,
|
|
||||||
[`first`, `totalRecords`, `disabled`],
|
|
||||||
))
|
|
||||||
: createCommentVNode(``, !0),
|
|
||||||
],
|
|
||||||
8,
|
|
||||||
k,
|
|
||||||
))
|
|
||||||
: createCommentVNode(``, !0),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[[`__scopeId`, `data-v-a438862d`]],
|
|
||||||
),
|
|
||||||
{
|
|
||||||
__name: `CloudProductPicker`,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
export {};
|
|
||||||
export default I;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<section class="cloud-product-picker" :aria-labelledby="`${id}-title`">
|
||||||
|
<h2 :id="`${id}-title`" class="section-title">选择产品</h2>
|
||||||
|
|
||||||
|
<div class="picker-row">
|
||||||
|
<span :id="`${id}-lines-title`" class="picker-label">线路</span>
|
||||||
|
<div class="picker-control">
|
||||||
|
<Skeleton v-if="loading" height="88px" />
|
||||||
|
<Message
|
||||||
|
v-else-if="error && errorSource === 'groups'"
|
||||||
|
severity="error"
|
||||||
|
:closable="false"
|
||||||
|
>
|
||||||
|
{{ error }}
|
||||||
|
<Button
|
||||||
|
label="重新加载线路"
|
||||||
|
severity="secondary"
|
||||||
|
text
|
||||||
|
:disabled="disabled"
|
||||||
|
@click="emit('retry-groups')"
|
||||||
|
/>
|
||||||
|
</Message>
|
||||||
|
<template v-else-if="groups.length">
|
||||||
|
<div
|
||||||
|
v-if="regions.length > 1"
|
||||||
|
class="choice-tabs"
|
||||||
|
role="group"
|
||||||
|
aria-label="地区"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
v-for="region in regions"
|
||||||
|
:key="region.name"
|
||||||
|
type="button"
|
||||||
|
class="choice-tab"
|
||||||
|
:class="{ active: currentRegion === region.name }"
|
||||||
|
:aria-pressed="currentRegion === region.name"
|
||||||
|
@click="chosenRegion = region.name"
|
||||||
|
>
|
||||||
|
{{ region.name }}<small>{{ region.groups.length }}</small>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="choice-tab"
|
||||||
|
:class="{ active: currentRegion === 'all' }"
|
||||||
|
:aria-pressed="currentRegion === 'all'"
|
||||||
|
@click="chosenRegion = 'all'"
|
||||||
|
>
|
||||||
|
全部<small>{{ groups.length }}</small>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="choice-chips"
|
||||||
|
role="group"
|
||||||
|
:aria-labelledby="`${id}-lines-title`"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
v-for="group in visibleGroups"
|
||||||
|
:key="group.id"
|
||||||
|
type="button"
|
||||||
|
class="choice-chip"
|
||||||
|
:class="{ active: activeGroup === group.id }"
|
||||||
|
:aria-pressed="activeGroup === group.id"
|
||||||
|
:disabled="disabled"
|
||||||
|
@click="emit('choose-group', group.id)"
|
||||||
|
>
|
||||||
|
<ProductGroupLabel :name="group.name" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-else class="catalog-empty">
|
||||||
|
<i class="pi pi-box" aria-hidden="true" />
|
||||||
|
<p>暂未提供可选的云服务器线路</p>
|
||||||
|
<NuxtLink to="/products">浏览产品</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="groups.length" class="picker-row">
|
||||||
|
<span :id="`${id}-products-title`" class="picker-label">型号</span>
|
||||||
|
<div class="picker-control">
|
||||||
|
<Skeleton v-if="productLoading && !products.length" height="34px" />
|
||||||
|
<Message
|
||||||
|
v-else-if="error && errorSource === 'products'"
|
||||||
|
severity="error"
|
||||||
|
:closable="false"
|
||||||
|
>
|
||||||
|
{{ error }}
|
||||||
|
<Button
|
||||||
|
label="重新加载商品"
|
||||||
|
severity="secondary"
|
||||||
|
text
|
||||||
|
:disabled="disabled"
|
||||||
|
@click="emit('retry-products')"
|
||||||
|
/>
|
||||||
|
</Message>
|
||||||
|
<p v-else-if="!products.length && !error" class="picker-empty">
|
||||||
|
该专区暂无可售产品
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="choice-chips"
|
||||||
|
role="group"
|
||||||
|
:aria-labelledby="`${id}-products-title`"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
v-for="(product, index) in products"
|
||||||
|
:key="product.id"
|
||||||
|
type="button"
|
||||||
|
class="choice-chip"
|
||||||
|
:class="{ active: selectedId === product.id }"
|
||||||
|
:aria-pressed="selectedId === product.id"
|
||||||
|
:title="displayProductName(product.name)"
|
||||||
|
:disabled="disabled || soldOut(product)"
|
||||||
|
@click="emit('choose-product', product.id)"
|
||||||
|
>
|
||||||
|
{{ productLabels.labels[index] }}
|
||||||
|
<small v-if="soldOut(product)">{{ stockLabel(product) }}</small>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<Paginator
|
||||||
|
v-if="total > 24"
|
||||||
|
:first="(page - 1) * 24"
|
||||||
|
:rows="24"
|
||||||
|
:total-records="total"
|
||||||
|
:disabled="disabled"
|
||||||
|
@page="emit('paginate', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.cloud-product-picker {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.cloud-product-picker > .section-title {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.picker-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 88px minmax(0, 1fr);
|
||||||
|
align-items: start;
|
||||||
|
gap: 8px 16px;
|
||||||
|
}
|
||||||
|
.picker-label {
|
||||||
|
color: var(--p-text-muted-color);
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
.picker-control {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.picker-empty {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--p-text-muted-color);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统一选择控件:与物理服务器筛选、商品目录分类使用同一套标签页与胶囊按钮规格。 */
|
||||||
|
.choice-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
overflow-x: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
border-bottom: 1px solid var(--p-content-border-color);
|
||||||
|
}
|
||||||
|
.choice-tabs::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.choice-tab {
|
||||||
|
flex: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 4px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
padding: 6px 12px 8px;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
background: none;
|
||||||
|
color: var(--p-text-muted-color);
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.choice-tab small {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.choice-tab:hover {
|
||||||
|
color: var(--p-text-color);
|
||||||
|
}
|
||||||
|
.choice-tab.active {
|
||||||
|
border-bottom-color: var(--p-primary-color);
|
||||||
|
color: var(--p-primary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.choice-chips {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.choice-chip {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 34px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
border: 1px solid var(--p-content-border-color);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--p-content-background);
|
||||||
|
color: var(--p-text-color);
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
text-align: left;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.choice-chip small {
|
||||||
|
color: var(--p-text-muted-color);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
.choice-chip:hover:not(:disabled) {
|
||||||
|
border-color: var(--p-primary-color);
|
||||||
|
}
|
||||||
|
.choice-chip.active {
|
||||||
|
border-color: var(--p-primary-color);
|
||||||
|
box-shadow: inset 0 0 0 1px var(--p-primary-color);
|
||||||
|
background: var(--p-highlight-background);
|
||||||
|
color: var(--p-highlight-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.choice-chip:disabled {
|
||||||
|
opacity: 0.55;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.choice-chip:focus-visible,
|
||||||
|
.choice-tab:focus-visible {
|
||||||
|
outline: 2px solid var(--p-primary-color);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
.choice-chip :deep(.product-group-badge) {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
background: none;
|
||||||
|
color: inherit;
|
||||||
|
opacity: 0.6;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.catalog-empty {
|
||||||
|
padding: 28px;
|
||||||
|
border: 1px solid var(--p-content-border-color);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--p-content-background);
|
||||||
|
color: var(--p-text-muted-color);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.catalog-empty i {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
.catalog-empty a {
|
||||||
|
color: var(--p-primary-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
@media (width < 640px) {
|
||||||
|
.picker-row {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.picker-label {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -596,7 +596,7 @@ var N = {
|
|||||||
},
|
},
|
||||||
he = {
|
he = {
|
||||||
key: 0,
|
key: 0,
|
||||||
class: `panel`,
|
class: `panel storage-panel`,
|
||||||
},
|
},
|
||||||
ge = {
|
ge = {
|
||||||
key: 0,
|
key: 0,
|
||||||
@@ -648,6 +648,9 @@ var N = {
|
|||||||
Oe = {
|
Oe = {
|
||||||
class: `form-row`,
|
class: `form-row`,
|
||||||
},
|
},
|
||||||
|
Pe1 = {
|
||||||
|
class: `form-inline`,
|
||||||
|
},
|
||||||
ke = Object.assign(
|
ke = Object.assign(
|
||||||
_plugin_vue_export_helper_t(
|
_plugin_vue_export_helper_t(
|
||||||
defineComponent({
|
defineComponent({
|
||||||
@@ -1018,124 +1021,131 @@ var N = {
|
|||||||
`基础配置`,
|
`基础配置`,
|
||||||
-1,
|
-1,
|
||||||
)),
|
)),
|
||||||
createElementVNode(`div`, L, [
|
createElementVNode(`div`, Pe1, [
|
||||||
(r[18] ||= createElementVNode(
|
createElementVNode(`div`, L, [
|
||||||
`label`,
|
(r[18] ||= createElementVNode(
|
||||||
null,
|
`label`,
|
||||||
`区域`,
|
null,
|
||||||
-1,
|
`区域`,
|
||||||
)),
|
-1,
|
||||||
createVNode(
|
)),
|
||||||
b,
|
createVNode(
|
||||||
{
|
b,
|
||||||
label: `区域`,
|
{
|
||||||
disabled: unref(W),
|
label: `区域`,
|
||||||
modelValue: unref(A).line_id,
|
compact: ``,
|
||||||
"onUpdate:modelValue": (r[1] ||= (e) =>
|
disabled: unref(W),
|
||||||
(unref(A).line_id = e)),
|
modelValue: unref(A).line_id,
|
||||||
options: (unref(D).line_list || []).map(
|
"onUpdate:modelValue": (r[1] ||= (e) =>
|
||||||
(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,
|
label: e.name,
|
||||||
value: e.id,
|
value: e.id,
|
||||||
}),
|
})),
|
||||||
),
|
onChange: Qe,
|
||||||
onChange: Xe,
|
},
|
||||||
},
|
null,
|
||||||
null,
|
8,
|
||||||
8,
|
[`disabled`, `modelValue`, `options`],
|
||||||
[`disabled`, `modelValue`, `options`],
|
),
|
||||||
),
|
]),
|
||||||
]),
|
]),
|
||||||
createElementVNode(`div`, R, [
|
createElementVNode(`div`, Pe1, [
|
||||||
(r[19] ||= createElementVNode(
|
createElementVNode(`div`, z, [
|
||||||
`label`,
|
(r[20] ||= createElementVNode(
|
||||||
null,
|
`label`,
|
||||||
`线路`,
|
null,
|
||||||
-1,
|
`CPU`,
|
||||||
)),
|
-1,
|
||||||
createVNode(
|
)),
|
||||||
b,
|
createVNode(
|
||||||
{
|
b,
|
||||||
label: `线路`,
|
{
|
||||||
disabled: unref(W),
|
label: `CPU`,
|
||||||
modelValue: unref(A).network_id,
|
disabled: unref(W),
|
||||||
"onUpdate:modelValue": (r[2] ||= (e) =>
|
"model-value":
|
||||||
(unref(A).network_id = e)),
|
Number(unref(A).cpu_num) || null,
|
||||||
options: (
|
options: unref(ke).map((e) => ({
|
||||||
unref(D).network_list || []
|
label: `${e} 核`,
|
||||||
).map((e) => ({
|
value: e,
|
||||||
label: e.name,
|
})),
|
||||||
value: e.id,
|
compact: ``,
|
||||||
})),
|
"onUpdate:modelValue":
|
||||||
onChange: Qe,
|
unref(S).selectCpu,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
8,
|
8,
|
||||||
[`disabled`, `modelValue`, `options`],
|
[
|
||||||
),
|
`disabled`,
|
||||||
]),
|
`model-value`,
|
||||||
createElementVNode(`div`, z, [
|
`options`,
|
||||||
(r[20] ||= createElementVNode(
|
`onUpdate:modelValue`,
|
||||||
`label`,
|
],
|
||||||
null,
|
),
|
||||||
`CPU`,
|
]),
|
||||||
-1,
|
createElementVNode(`div`, me, [
|
||||||
)),
|
(r[21] ||= createElementVNode(
|
||||||
createVNode(
|
`label`,
|
||||||
b,
|
null,
|
||||||
{
|
`内存`,
|
||||||
label: `CPU`,
|
-1,
|
||||||
disabled: unref(W),
|
)),
|
||||||
"model-value":
|
createVNode(
|
||||||
Number(unref(A).cpu_num) || null,
|
b,
|
||||||
options: unref(ke).map((e) => ({
|
{
|
||||||
label: `${e} 核`,
|
label: `内存`,
|
||||||
value: e,
|
disabled: unref(W),
|
||||||
})),
|
"model-value":
|
||||||
compact: ``,
|
Number(unref(A).memory) || null,
|
||||||
"onUpdate:modelValue": unref(S).selectCpu,
|
options: unref(Ae).map((e) => ({
|
||||||
},
|
label: `${e} GB`,
|
||||||
null,
|
value: e,
|
||||||
8,
|
})),
|
||||||
[
|
compact: ``,
|
||||||
`disabled`,
|
"onUpdate:modelValue":
|
||||||
`model-value`,
|
unref(S).selectMemory,
|
||||||
`options`,
|
},
|
||||||
`onUpdate:modelValue`,
|
null,
|
||||||
],
|
8,
|
||||||
),
|
[
|
||||||
]),
|
`disabled`,
|
||||||
createElementVNode(`div`, me, [
|
`model-value`,
|
||||||
(r[21] ||= createElementVNode(
|
`options`,
|
||||||
`label`,
|
`onUpdate:modelValue`,
|
||||||
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)
|
unref(X) || unref(H)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
|||||||
import "~/assets/styles/ProductCustomFields.B2QMnPil.css";
|
import "~/assets/styles/ProductCustomFields.B2QMnPil.css";
|
||||||
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
|
import "~/assets/styles/OsIcon.CAi4Iz2S.css";
|
||||||
import "~/assets/styles/CommonConfig.Cfik-oMe.css";
|
import "~/assets/styles/CommonConfig.Cfik-oMe.css";
|
||||||
import "~/assets/styles/CloudProductPicker.CAm9rmUl.css";
|
|
||||||
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
|
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
|
||||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||||
import "~/assets/styles/cloud-server.CcwlOXJ0.css";
|
import "~/assets/styles/cloud-server.CcwlOXJ0.css";
|
||||||
@@ -42,6 +41,7 @@ import { unref } from "vue";
|
|||||||
import { defineComponent } from "vue";
|
import { defineComponent } from "vue";
|
||||||
import { createVNode } from "vue";
|
import { createVNode } from "vue";
|
||||||
import { openBlock } from "vue";
|
import { openBlock } from "vue";
|
||||||
|
import { NuxtLink } from "#components";
|
||||||
import { useRoute } from "#app";
|
import { useRoute } from "#app";
|
||||||
import { useRouter } from "#app";
|
import { useRouter } from "#app";
|
||||||
import { useHead } from "#app";
|
import { useHead } from "#app";
|
||||||
@@ -323,12 +323,17 @@ var ge = {
|
|||||||
return (
|
return (
|
||||||
openBlock(),
|
openBlock(),
|
||||||
createElementBlock(`div`, ge, [
|
createElementBlock(`div`, ge, [
|
||||||
(r[4] ||= createElementVNode(
|
createElementVNode(`header`, { class: `order-head` }, [
|
||||||
`h2`,
|
createElementVNode(`h2`, null, `创建云服务器实例`),
|
||||||
null,
|
createVNode(
|
||||||
`创建云服务器实例`,
|
NuxtLink,
|
||||||
-1,
|
{ to: `/products` },
|
||||||
)),
|
{
|
||||||
|
default: withCtx(() => [createTextVNode(`查看全部产品`)]),
|
||||||
|
_: 1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
unref(D) && unref(B)
|
unref(D) && unref(B)
|
||||||
? (openBlock(),
|
? (openBlock(),
|
||||||
createBlock(
|
createBlock(
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
* 物理服务器定制入口:只接受有效商品 ID 且模块为 mf_dcim/remf_dcim,避免把其他类型商品交给物理服务器配置器。
|
* 物理服务器定制入口:只接受有效商品 ID 且模块为 mf_dcim/remf_dcim,避免把其他类型商品交给物理服务器配置器。
|
||||||
*/
|
*/
|
||||||
import { definePageMeta } from "#imports";
|
import { definePageMeta } from "#imports";
|
||||||
import "~/assets/styles/dedicated-server.CiJfMYtk.css";
|
|
||||||
import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css";
|
import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css";
|
||||||
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
||||||
import "~/assets/styles/ProductCustomFields.B2QMnPil.css";
|
import "~/assets/styles/ProductCustomFields.B2QMnPil.css";
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user