diff --git a/frontend/src/composables/usePublishForm.ts b/frontend/src/composables/usePublishForm.ts index dd730fb..f18690f 100644 --- a/frontend/src/composables/usePublishForm.ts +++ b/frontend/src/composables/usePublishForm.ts @@ -120,6 +120,13 @@ export function usePublishForm(options: UsePublishFormOptions) { ]) publishOptions.value = nextPublishOptions salePriceConfig.value = nextSalePriceConfig + + // 默认数字都是0 + for (const item of nextPublishOptions.quantity_items) { + if (quantityValues[item.key] === undefined) { + quantityValues[item.key] = 0 + } + } } catch { publishOptions.value = emptyListingPublishOptions salePriceConfig.value = emptyListingSalePriceConfig @@ -198,6 +205,11 @@ export function usePublishForm(options: UsePublishFormOptions) { revokeAllScreenshotPreviews() selectedSkins.value = [] activeUploadKey.value = 'coin' + + // Also re-initialize quantityValues to 0 + for (const item of publishOptions.value.quantity_items) { + quantityValues[item.key] = 0 + } } async function handleResetDraft() { @@ -427,6 +439,17 @@ export function usePublishForm(options: UsePublishFormOptions) { for (const item of pricing.screenshotSlots.value) { if (isScreenshotRequired(item) && !screenshotFiles[item.key]) return `请上传${item.label}` } + for (const item of pricing.quantityItems.value) { + if (!pricing.isQuantityItemDisabled(item)) { + const val = quantityValues[item.key] + if (val === undefined || val === null || (val as unknown) === '') { + return `请填写${item.label}的数量` + } + if (Number(val) < 0) { + return `${item.label}的数量不能为负数` + } + } + } for (const item of pricing.quantityItems.value) { if (pricing.isQuantityItemDisabled(item) && Number(quantityValues[item.key] || 0) > 0) { return '赛季保险选择 3*3 时不能填写 9格体验卡' diff --git a/frontend/src/views/seller/SellerListingCreateView.css b/frontend/src/views/seller/SellerListingCreateView.css index dce167e..82753a3 100644 --- a/frontend/src/views/seller/SellerListingCreateView.css +++ b/frontend/src/views/seller/SellerListingCreateView.css @@ -13,6 +13,23 @@ min-width: 0; color: var(--color-text-dark); + + :deep(.el-input__wrapper), + :deep(.el-textarea__inner) { + border-radius: var(--radius-8); + box-shadow: 0 0 0 1px var(--color-border) inset; + transition: all 0.2s ease; + } + + :deep(.el-input__wrapper:hover), + :deep(.el-textarea__inner:hover) { + box-shadow: 0 0 0 1px var(--color-orange-primary) inset !important; + } + + :deep(.el-input__wrapper.is-focus), + :deep(.el-textarea__inner:focus) { + box-shadow: 0 0 0 1px var(--color-orange-primary) inset, 0 0 8px rgba(255, 106, 0, 0.15) !important; + } } .publish-layout { @@ -52,7 +69,19 @@ } .panel-input-grid { - align-items: end; + align-items: center; + + & .input-block { + grid-template-columns: auto minmax(0, 1fr); + align-items: center; + gap: 10px; + } + + /* 输入框不需要太长,限制最大宽度 */ + & :deep(.el-input-number), + & :deep(.el-input) { + max-width: 140px; + } } .summary-panel { @@ -101,8 +130,8 @@ .level-btn, .region-btn { &.active { - border-color: #1477ff; - background: #1477ff; + border-color: var(--color-orange-primary); + background: var(--color-orange-primary); color: #fff; } } @@ -127,6 +156,10 @@ &.two { grid-template-columns: repeat(2, minmax(0, 1fr)); + padding: 14px 16px; + border-radius: var(--radius-8); + background: var(--color-bg-gray); + gap: 16px; } @media (max-width: 860px) { @@ -144,6 +177,7 @@ font-size: 13px; font-weight: 800; line-height: 22px; + white-space: nowrap; } & b { @@ -155,12 +189,6 @@ :deep(.el-date-editor) { width: 100%; } - - :deep(.el-input__wrapper), - :deep(.el-textarea__inner) { - border-radius: var(--radius-8); - box-shadow: 0 0 0 1px var(--color-border) inset; - } } .level-panel { @@ -216,8 +244,8 @@ .quantity-header, .quantity-item { display: grid; - grid-template-columns: minmax(160px, 1fr) 90px 112px 112px 92px; - gap: 12px; + grid-template-columns: minmax(180px, 3fr) minmax(80px, 1fr) minmax(100px, 1.2fr) minmax(140px, 1.5fr) minmax(80px, 1fr); + gap: 10px; align-items: center; @media (max-width: 860px) { @@ -235,6 +263,11 @@ @media (max-width: 860px) { display: none; } + + & b { + color: var(--color-danger); + margin-left: 2px; + } } .quantity-item { @@ -244,9 +277,11 @@ opacity: 0.62; } - :deep(.el-input-number) { - width: 100%; - min-width: 0; + /* 强制 el-input-number 所在的 Grid 单元格裁剪溢出 */ + & > :deep(.el-input-number) { + width: 100% !important; + min-width: 0 !important; + overflow: hidden; } } @@ -260,6 +295,11 @@ font-size: 13px; text-overflow: ellipsis; white-space: nowrap; + + & span { + color: var(--color-danger); + margin-right: 2px; + } } & small { @@ -280,7 +320,7 @@ .mode-toggle { display: grid; grid-template-columns: 1fr 1fr; - gap: 6px; + gap: 4px; min-width: 0; & button { @@ -289,6 +329,7 @@ border-radius: var(--radius-8); font-size: 12px; white-space: nowrap; + padding: 0 6px; &:disabled { cursor: not-allowed; @@ -313,16 +354,30 @@ font-size: 12px; font-weight: 800; cursor: pointer; + transition: all 0.2s ease; + + &:hover { + background: #ffe3cd; + border-color: var(--color-orange-primary); + } } .deposit-control { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; + display: flex; gap: 8px; align-items: center; + & :deep(.el-input-number) { + width: 140px !important; + flex: 0 0 140px; + } + @media (max-width: 860px) { - grid-template-columns: 1fr; + width: 100%; + & :deep(.el-input-number) { + width: 100% !important; + flex: 1; + } } } @@ -407,11 +462,6 @@ @media (max-width: 860px) { width: 140px; } - - & :deep(.el-input__wrapper) { - border-radius: var(--radius-8); - box-shadow: 0 0 0 1px var(--color-border) inset; - } } .login-region-panel { @@ -564,10 +614,9 @@ } } -.ratio-mode-grid, -.price-grid { +.ratio-mode-grid { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; @media (max-width: 860px) { @@ -575,12 +624,50 @@ } } +.ratio-custom-card { + display: flex; + flex-direction: column; + justify-content: center; + gap: 6px; + min-height: 72px; + padding: 10px 12px; + border: 1px solid #d6dce5; + border-radius: var(--radius-8); + background: #fff; + transition: all 0.16s ease; + + & strong { + color: #596474; + font-size: 13px; + font-weight: 800; + } + + & :deep(.el-input-number) { + width: 100% !important; + } + + & :deep(.el-input__wrapper) { + background-color: #fff !important; + } + + &.active { + border-color: var(--color-orange-primary); + background: var(--color-bg-orange); + color: var(--color-orange-primary); + + & strong { + color: var(--color-orange-primary); + } + } +} + .ratio-mode-btn { display: grid; gap: 6px; min-height: 72px; padding: 12px; text-align: left; + border-radius: var(--radius-8); & span { color: var(--color-text-sub); @@ -600,8 +687,14 @@ } .price-grid { + display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; margin-top: 14px; + + @media (max-width: 860px) { + grid-template-columns: 1fr; + } } .price-cell { @@ -609,6 +702,13 @@ gap: 6px; min-height: 82px; padding: 14px; + border-left: 4px solid #ccd5e0; + transition: all 0.2s ease; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03); + } & span { color: #6f7a89; @@ -625,6 +725,7 @@ &.accent { background: var(--color-bg-orange); + border-left-color: var(--color-orange-primary); } } @@ -703,5 +804,19 @@ & :deep(.el-button) { width: 100%; margin-left: 0; + border-radius: var(--radius-8); + } + + & :deep(.el-button.btn-publish) { + background-color: var(--color-orange-primary); + border-color: var(--color-orange-primary); + color: #fff; + font-weight: 800; + transition: all 0.2s ease; + + &:hover { + background-color: var(--color-orange-dark); + border-color: var(--color-orange-dark); + } } } diff --git a/frontend/src/views/seller/SellerListingCreateView.vue b/frontend/src/views/seller/SellerListingCreateView.vue index d2c4761..4d61219 100644 --- a/frontend/src/views/seller/SellerListingCreateView.vue +++ b/frontend/src/views/seller/SellerListingCreateView.vue @@ -115,7 +115,7 @@ function selectDailyLoss(value: string | number) {