修复前端迁移后的类型错误

This commit is contained in:
yml2213
2026-06-04 11:07:34 +08:00
parent eb6aed7e56
commit 75e849a91a
23 changed files with 1561 additions and 29 deletions
@@ -13,7 +13,7 @@ import {
type ScreenshotKey,
} from '@/features/listings/api/listingOptions'
import { createListing } from '@/features/listings/api/listings'
import { usePricingCalculator } from '@/composables/usePricingCalculator'
import { usePricingCalculator } from '@/shared/composables/usePricingCalculator'
import {
buildPublishDraft,
clearRecord,
@@ -21,7 +21,7 @@ import {
readPublishDraft,
removePublishDraft,
writePublishDraft,
} from '@/composables/usePublishDraft'
} from '@/features/seller/composables/usePublishDraft'
import type { PublishForm } from '@/types/publish'
import { commonOnlineTimes, dailyLossOptions, formatNumber, roundRatio } from '@/utils/pricing'
@@ -0,0 +1,391 @@
.publish-page {
max-width: 1180px;
margin: 0 auto;
padding: 24px 20px 40px;
}
.publish-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 300px;
gap: 20px;
}
.form-column,
.summary-column {
min-width: 0;
}
.summary-column {
align-self: start;
position: sticky;
top: 84px;
}
.field-row,
.input-block {
display: grid;
gap: 8px;
}
.field-row + .field-row,
.compact-grid + .field-row,
.level-panel,
.time-preset-panel,
.region-panel,
.ratio-panel,
.price-grid,
.remark {
margin-top: 16px;
}
.field-row label,
.input-block > span,
.quantity-meta strong {
color: #0f172a;
font-size: 14px;
font-weight: 700;
}
.field-row span,
.input-block b,
.quantity-meta span,
.upload-copy span {
color: #ef4444;
}
.field-hint {
margin: 6px 0 0;
color: #64748b;
font-size: 13px;
line-height: 1.6;
}
.compact-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
}
.compact-grid.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.level-panel,
.time-preset-panel,
.region-panel,
.ratio-panel,
.summary-panel {
padding: 16px;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #f8fafc;
}
.level-row,
.time-preset-row,
.region-title,
.skin-title {
display: grid;
gap: 10px;
}
.level-row + .level-row,
.time-preset-row + .time-preset-row,
.skin-group + .skin-group {
margin-top: 14px;
}
.level-options,
.region-grid,
.mode-toggle,
.ratio-mode-grid {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.level-btn,
.region-btn,
.mode-toggle button,
.ratio-mode-btn,
.recommend-button,
.upload-add {
border: 1px solid #dbe3ee;
border-radius: 8px;
background: #fff;
color: #334155;
cursor: pointer;
}
.level-btn,
.region-btn,
.mode-toggle button {
min-height: 32px;
padding: 0 12px;
font-weight: 600;
}
.level-btn.active,
.region-btn.active,
.mode-toggle button.active,
.ratio-mode-btn.active {
border-color: #2563eb;
background: #eff6ff;
color: #1d4ed8;
}
.quantity-table {
display: grid;
gap: 10px;
}
.quantity-header,
.quantity-item {
display: grid;
grid-template-columns: minmax(160px, 1fr) 100px 120px 116px 80px;
gap: 12px;
align-items: center;
}
.quantity-header {
color: #64748b;
font-size: 12px;
font-weight: 700;
}
.quantity-item {
padding: 12px;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #fff;
}
.quantity-item.disabled {
opacity: 0.65;
}
.quantity-meta small,
.quantity-status,
.quantity-price {
color: #64748b;
font-size: 12px;
}
.time-preset-content,
.deposit-control {
display: grid;
grid-template-columns: 160px minmax(0, 1fr);
gap: 10px;
align-items: center;
}
.upload-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.upload-item {
display: grid;
gap: 10px;
padding: 14px;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #fff;
}
.upload-copy {
display: grid;
gap: 4px;
}
.upload-copy strong {
color: #0f172a;
}
.upload-copy small,
.deposit-breakdown {
color: #64748b;
font-size: 12px;
}
.upload-preview {
position: relative;
aspect-ratio: 16 / 9;
overflow: hidden;
border-radius: 8px;
background: #e2e8f0;
}
.upload-preview img {
width: 100%;
height: 100%;
object-fit: cover;
}
.upload-preview button {
position: absolute;
top: 8px;
right: 8px;
}
.upload-add {
display: grid;
min-height: 112px;
place-items: center;
align-content: center;
gap: 6px;
color: #2563eb;
}
.hidden-file {
display: none;
}
.recommend-button {
height: 32px;
padding: 0 10px;
color: #2563eb;
font-weight: 700;
}
.deposit-breakdown {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.ratio-reference {
display: flex;
align-items: center;
justify-content: space-between;
}
.ratio-reference span,
.price-cell span,
.summary-main span,
.summary-list span {
color: #64748b;
font-size: 13px;
}
.ratio-reference strong {
color: #2563eb;
font-size: 22px;
}
.ratio-panel p {
margin: 8px 0 14px;
color: #64748b;
font-size: 13px;
}
.ratio-mode-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.ratio-mode-btn,
.ratio-custom-card {
display: grid;
gap: 6px;
padding: 12px;
border: 1px solid #dbe3ee;
border-radius: 8px;
background: #fff;
text-align: left;
}
.ratio-mode-btn span {
color: #64748b;
font-size: 12px;
}
.price-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.price-cell {
display: grid;
gap: 6px;
padding: 12px;
border-radius: 8px;
background: #f8fafc;
}
.price-cell strong,
.summary-list strong {
color: #0f172a;
}
.price-cell.accent strong,
.summary-main strong {
color: #2563eb;
}
.summary-panel {
background: #fff;
}
.summary-main {
display: grid;
gap: 6px;
padding-bottom: 14px;
border-bottom: 1px solid #e2e8f0;
}
.summary-main strong {
font-size: 28px;
}
.summary-list {
display: grid;
gap: 10px;
margin: 14px 0;
}
.summary-list div {
display: flex;
justify-content: space-between;
gap: 10px;
}
.summary-actions {
display: grid;
gap: 10px;
}
.summary-actions .el-button {
width: 100%;
margin-left: 0;
}
@media (max-width: 960px) {
.publish-layout {
grid-template-columns: 1fr;
}
.summary-column {
position: static;
}
.compact-grid,
.compact-grid.two,
.upload-grid,
.price-grid,
.ratio-mode-grid,
.time-preset-content,
.deposit-control {
grid-template-columns: 1fr;
}
.quantity-header {
display: none;
}
.quantity-item {
grid-template-columns: 1fr;
}
}
@@ -2,7 +2,7 @@
import { Delete, DocumentChecked, Picture, RefreshRight, UploadFilled } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { usePublishForm } from '@/composables/usePublishForm'
import { usePublishForm } from '@/features/seller/composables/usePublishForm'
import OptionChips from './components/OptionChips.vue'
import PublishSection from './components/PublishSection.vue'
@@ -0,0 +1,73 @@
<script setup lang="ts">
const props = withDefaults(
defineProps<{
options: Array<string | number>
modelValue?: string | number
activeValues?: Array<string | number>
keyPrefix?: string
compact?: boolean
suffix?: string
}>(),
{
modelValue: undefined,
activeValues: () => [],
keyPrefix: '',
compact: false,
suffix: '',
},
)
const emit = defineEmits<{
select: [value: string | number]
}>()
function isActive(value: string | number) {
return props.activeValues.includes(value) || props.modelValue === value
}
</script>
<template>
<div class="option-chips" :class="{ compact }">
<button
v-for="option in options"
:key="`${keyPrefix}${option}`"
type="button"
:class="{ active: isActive(option) }"
@click="emit('select', option)"
>
{{ option }}{{ suffix }}
</button>
</div>
</template>
<style scoped>
.option-chips {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.option-chips button {
min-height: 34px;
padding: 0 14px;
border: 1px solid #dbe3ee;
border-radius: 8px;
background: #fff;
color: #334155;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.option-chips.compact button {
min-height: 30px;
padding: 0 10px;
}
.option-chips button.active {
border-color: #2563eb;
background: #eff6ff;
color: #1d4ed8;
}
</style>
@@ -0,0 +1,49 @@
<script setup lang="ts">
defineProps<{
title: string
description?: string
}>()
</script>
<template>
<section class="publish-section">
<header class="publish-section-header">
<h2>{{ title }}</h2>
<p v-if="description">{{ description }}</p>
</header>
<slot />
</section>
</template>
<style scoped>
.publish-section {
padding: 20px;
border: 1px solid #e2e8f0;
border-radius: 8px;
background: #fff;
}
.publish-section + .publish-section {
margin-top: 16px;
}
.publish-section-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 16px;
margin-bottom: 16px;
}
.publish-section-header h2 {
margin: 0;
color: #0f172a;
font-size: 18px;
}
.publish-section-header p {
margin: 0;
color: #64748b;
font-size: 13px;
}
</style>