修复卖家发布页样式和全天时间选择
This commit is contained in:
@@ -187,6 +187,7 @@ export function usePublishForm(options: UsePublishFormOptions) {
|
|||||||
const draft = readPublishDraft(options.draftKey)
|
const draft = readPublishDraft(options.draftKey)
|
||||||
if (!draft) return
|
if (!draft) return
|
||||||
Object.assign(form, draft.form)
|
Object.assign(form, draft.form)
|
||||||
|
normalizeOnlineTime()
|
||||||
clearRecord(quantityValues)
|
clearRecord(quantityValues)
|
||||||
clearRecord(quantityModes)
|
clearRecord(quantityModes)
|
||||||
clearRecord(screenshotFiles)
|
clearRecord(screenshotFiles)
|
||||||
@@ -212,6 +213,13 @@ export function usePublishForm(options: UsePublishFormOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeOnlineTime() {
|
||||||
|
if (form.online_start === '全天' || form.online_end === '全天') {
|
||||||
|
form.online_start = '00:00'
|
||||||
|
form.online_end = '23:59'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleResetDraft() {
|
async function handleResetDraft() {
|
||||||
try {
|
try {
|
||||||
await options.confirmReset?.()
|
await options.confirmReset?.()
|
||||||
@@ -370,6 +378,7 @@ export function usePublishForm(options: UsePublishFormOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
|
normalizeOnlineTime()
|
||||||
const error = validateForm()
|
const error = validateForm()
|
||||||
if (error) {
|
if (error) {
|
||||||
options.notifyWarning(error)
|
options.notifyWarning(error)
|
||||||
|
|||||||
@@ -0,0 +1,686 @@
|
|||||||
|
.mobile-publish {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 100dvh;
|
||||||
|
background: #f4f6f8;
|
||||||
|
padding-bottom: calc(56px + env(safe-area-inset-bottom));
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 48px;
|
||||||
|
padding: 0 12px;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #eceff3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-header h1 {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
display: grid;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
place-items: center;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
color: #25282d;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-spacer {
|
||||||
|
width: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-body {
|
||||||
|
padding: 12px 14px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
padding: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #edf0f4;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #171a1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-hint {
|
||||||
|
margin: -2px 0 8px;
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-field {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-field :deep(.van-field__label) {
|
||||||
|
width: 88px;
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-field :deep(.van-field__control) {
|
||||||
|
color: #20242a;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-label,
|
||||||
|
.backend-hint-target.has-hint,
|
||||||
|
.upload-title.has-hint {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 100%;
|
||||||
|
line-height: 1.35;
|
||||||
|
cursor: help;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-label::before,
|
||||||
|
.backend-hint-target.has-hint::before,
|
||||||
|
.upload-title.has-hint::before,
|
||||||
|
.hint-label::after,
|
||||||
|
.backend-hint-target.has-hint::after,
|
||||||
|
.upload-title.has-hint::after {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 20;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.16s ease, visibility 0.16s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-label::before,
|
||||||
|
.backend-hint-target.has-hint::before,
|
||||||
|
.upload-title.has-hint::before {
|
||||||
|
content: "";
|
||||||
|
top: 50%;
|
||||||
|
left: calc(100% + 2px);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
border: 6px solid transparent;
|
||||||
|
border-right-color: rgba(32, 36, 42, 0.96);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-label::after,
|
||||||
|
.backend-hint-target.has-hint::after,
|
||||||
|
.upload-title.has-hint::after {
|
||||||
|
content: attr(data-hint);
|
||||||
|
top: 50%;
|
||||||
|
left: calc(100% + 14px);
|
||||||
|
width: min(242px, calc(100vw - 136px));
|
||||||
|
max-height: 156px;
|
||||||
|
overflow: auto;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(32, 36, 42, 0.96);
|
||||||
|
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.18);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.45;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-label:hover::before,
|
||||||
|
.hint-label:focus-visible::before,
|
||||||
|
.backend-hint-target.has-hint:hover::before,
|
||||||
|
.backend-hint-target.has-hint:focus-visible::before,
|
||||||
|
.upload-title.has-hint:hover::before,
|
||||||
|
.upload-title.has-hint:focus-visible::before,
|
||||||
|
.hint-label:hover::after,
|
||||||
|
.hint-label:focus-visible::after,
|
||||||
|
.backend-hint-target.has-hint:hover::after,
|
||||||
|
.backend-hint-target.has-hint:focus-visible::after,
|
||||||
|
.upload-title.has-hint:hover::after,
|
||||||
|
.upload-title.has-hint:focus-visible::after {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group,
|
||||||
|
.multi-chip-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group.small {
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-btn {
|
||||||
|
min-height: 28px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
border: 1px solid #d7dce3;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #fff;
|
||||||
|
color: #5c6470;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-btn.active {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
background: #ff6a00;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-row,
|
||||||
|
.result-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-field-group {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-field-group .publish-field {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-preset-chips {
|
||||||
|
padding: 0 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-panel {
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 58px minmax(0, 1fr);
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-label {
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-label span {
|
||||||
|
margin-right: 2px;
|
||||||
|
color: #ee0a24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-options {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-btn {
|
||||||
|
min-width: 0;
|
||||||
|
height: 30px;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid #d7dce3;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: #fff;
|
||||||
|
color: #5c6470;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-btn.active {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
background: #ff6a00;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 92px;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: stretch;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-row.disabled {
|
||||||
|
opacity: 0.62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 72px;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta strong {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta span {
|
||||||
|
margin-right: 2px;
|
||||||
|
color: #ee0a24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta small {
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-input {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border: 1px solid #e0e5ec;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
color: #20242a;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-input:focus {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-input:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 6px;
|
||||||
|
min-height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button {
|
||||||
|
border: 1px solid #d7dce3;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
color: #606873;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button.active {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
background: #fff3ea;
|
||||||
|
color: #e65f00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-groups {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-group {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-group-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-group-title small {
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-panel {
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-title small {
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-btn {
|
||||||
|
min-width: 0;
|
||||||
|
height: 28px;
|
||||||
|
padding: 0 2px;
|
||||||
|
border: 1px solid #d7dce3;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: #fff;
|
||||||
|
color: #5c6470;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-btn.active {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
background: #ff6a00;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-line {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 86px;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 76px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #edf0f4;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-meta {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-meta strong {
|
||||||
|
color: #242830;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-meta span {
|
||||||
|
color: #f04438;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-meta small {
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add,
|
||||||
|
.upload-preview {
|
||||||
|
width: 76px;
|
||||||
|
height: 76px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
border: 1px dashed #c7cdd6;
|
||||||
|
background: #fff;
|
||||||
|
color: #7b8490;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-preview {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #e8ecf1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-preview img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-preview button {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px 0 0;
|
||||||
|
background: rgba(0, 0, 0, 0.62);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-field :deep(.van-field__control) {
|
||||||
|
color: #ff6a00;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-panel {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deposit-recommend-btn {
|
||||||
|
min-height: 32px;
|
||||||
|
margin: -2px 0 10px 88px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border: 1px solid #ffba86;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: #fff7f0;
|
||||||
|
color: #e65f00;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-reference {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
min-height: 48px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-reference span {
|
||||||
|
color: #30343a;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-reference strong {
|
||||||
|
color: #ff6a00;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-range {
|
||||||
|
margin: 0;
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn {
|
||||||
|
display: grid;
|
||||||
|
gap: 5px;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 74px;
|
||||||
|
padding: 12px 8px;
|
||||||
|
border: 1px solid #d7dce3;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
color: #30343a;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn strong,
|
||||||
|
.ratio-mode-btn span {
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn strong {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn span {
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn.active {
|
||||||
|
border-color: #ff6a00;
|
||||||
|
background: #fff7f0;
|
||||||
|
color: #ff6a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn.active span {
|
||||||
|
color: #ff6a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.58;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-input-field {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-input-hint {
|
||||||
|
margin: -2px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-price-field :deep(.van-field__control) {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-breakdown-hint {
|
||||||
|
margin: -2px 0 10px;
|
||||||
|
color: #858c96;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-actions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 92px minmax(0, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset-btn,
|
||||||
|
.submit-btn {
|
||||||
|
height: 44px;
|
||||||
|
width: 100%;
|
||||||
|
border: none !important;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset-btn {
|
||||||
|
border: 1px solid #d7dce3 !important;
|
||||||
|
background: #fff !important;
|
||||||
|
color: #4b5563 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
background: #ff6a00 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media (min-width: 430px) {
|
||||||
|
.time-row {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 370px) {
|
||||||
|
.level-options,
|
||||||
|
.region-grid {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,666 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { showDialog, showToast } from 'vant'
|
||||||
|
import MobileBottomNav from '@/components/MobileBottomNav.vue'
|
||||||
|
|
||||||
|
import { usePublishForm } from '@/features/seller/composables/usePublishForm'
|
||||||
|
|
||||||
|
const {
|
||||||
|
commonOnlineTimes,
|
||||||
|
dailyLossOptions,
|
||||||
|
formatNumber,
|
||||||
|
router,
|
||||||
|
loading,
|
||||||
|
uploading,
|
||||||
|
fileInput,
|
||||||
|
activeUploadKey,
|
||||||
|
form,
|
||||||
|
quantityValues,
|
||||||
|
quantityModes,
|
||||||
|
screenshotFiles,
|
||||||
|
selectedSkins,
|
||||||
|
serverOptions,
|
||||||
|
faceOptions,
|
||||||
|
rankOptions,
|
||||||
|
insuranceOptions,
|
||||||
|
levelOptions,
|
||||||
|
loginMethodOptions,
|
||||||
|
regionOptions,
|
||||||
|
banRecordOptions,
|
||||||
|
skinGroups,
|
||||||
|
quantityItems,
|
||||||
|
screenshotSlots,
|
||||||
|
priceConfig,
|
||||||
|
fireLevelPlaceholder,
|
||||||
|
coinMAmount,
|
||||||
|
dailyLossMAmount,
|
||||||
|
calculatedDefaultSaleRatio,
|
||||||
|
maxAcceleratedSaleRatio,
|
||||||
|
calculatedCoinBasePrice,
|
||||||
|
calculatedConsumablePrice,
|
||||||
|
calculatedSellerPrice,
|
||||||
|
calculatedRatioText,
|
||||||
|
calculatedDefaultSaleRatioText,
|
||||||
|
saleRatioRangeText,
|
||||||
|
acceleratedSaleRatioPlaceholder,
|
||||||
|
recommendedDepositAmount,
|
||||||
|
hasAcceleratedSaleRatioInput,
|
||||||
|
isQuantityItemDisabled,
|
||||||
|
handleResetDraft,
|
||||||
|
toggleSkin,
|
||||||
|
toggleRegion,
|
||||||
|
triggerUpload,
|
||||||
|
handleScreenshotUpload,
|
||||||
|
removeScreenshot,
|
||||||
|
getScreenshotPreviewURL,
|
||||||
|
handleFireLevelInput,
|
||||||
|
handleAcceleratedSaleRatioInput,
|
||||||
|
useRecommendedDeposit,
|
||||||
|
setQuantityMode,
|
||||||
|
clampAcceleratedSaleRatioInput,
|
||||||
|
useReferenceSaleRatio,
|
||||||
|
useMaxAcceleratedSaleRatio,
|
||||||
|
handleSubmit,
|
||||||
|
isScreenshotRequired,
|
||||||
|
} = usePublishForm({
|
||||||
|
draftKey: 'hfb.mobile.publish.draft',
|
||||||
|
submitSuccessPath: '/m/profile',
|
||||||
|
async confirmReset() {
|
||||||
|
await showDialog({
|
||||||
|
title: '重置发布内容',
|
||||||
|
message: '将清空当前填写内容和本地草稿。',
|
||||||
|
confirmButtonText: '重置',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
showCancelButton: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
notifySuccess: (message) => showToast({ message, icon: 'passed' }),
|
||||||
|
notifyWarning: (message) => showToast({ message, icon: 'warning-o' }),
|
||||||
|
notifyError: (message) => showToast({ message, icon: 'cross' }),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function selectRadio<T extends string>(value: T, setter: (value: T) => void) {
|
||||||
|
setter(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAllDayOnline() {
|
||||||
|
return form.online_start === '00:00' && form.online_end === '23:59'
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOnlineStartPresetActive(value: string) {
|
||||||
|
return !isAllDayOnline() && form.online_start === value
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOnlineEndPresetActive(value: string) {
|
||||||
|
return !isAllDayOnline() && form.online_end === value
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAllDayOnline() {
|
||||||
|
form.online_start = '00:00'
|
||||||
|
form.online_end = '23:59'
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOnlineStart(value: string) {
|
||||||
|
form.online_start = value
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOnlineEnd(value: string) {
|
||||||
|
form.online_end = value
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<main class="mobile-publish">
|
||||||
|
<header class="page-header">
|
||||||
|
<button class="back-btn" type="button" @click="router.back()">
|
||||||
|
<van-icon name="arrow-left" :size="20" />
|
||||||
|
</button>
|
||||||
|
<h1>发布账号</h1>
|
||||||
|
<span class="header-spacer"></span>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="form-body">
|
||||||
|
<div class="form-section">
|
||||||
|
<h2 class="section-title">基础资料</h2>
|
||||||
|
|
||||||
|
<van-field label="区服" required class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in serverOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.server_region === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.server_region = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<van-field label="是否本人人脸" class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in faceOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.face_owner === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.face_owner = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<van-field
|
||||||
|
v-model="form.haf_coin_amount"
|
||||||
|
label="哈夫币/M"
|
||||||
|
type="digit"
|
||||||
|
required
|
||||||
|
placeholder="只填写仓库右上角纯币数额,总资产不计算在内;100M 写 100"
|
||||||
|
class="publish-field"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<van-field label="段位" required class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in rankOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.rank_level === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.rank_level = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<van-field
|
||||||
|
v-model="form.secret_kd"
|
||||||
|
label="绝密KD"
|
||||||
|
type="number"
|
||||||
|
placeholder="填写绝密KD,如果数据对不上买家可以申请退款"
|
||||||
|
class="publish-field"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
:model-value="form.fire_level"
|
||||||
|
label="烽火等级"
|
||||||
|
type="digit"
|
||||||
|
required
|
||||||
|
:placeholder="fireLevelPlaceholder"
|
||||||
|
class="publish-field"
|
||||||
|
@update:model-value="handleFireLevelInput"
|
||||||
|
/>
|
||||||
|
<van-field label="赛季保险" required class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in insuranceOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.season_insurance === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.season_insurance = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<div class="level-panel">
|
||||||
|
<div class="level-row">
|
||||||
|
<div class="level-label"><span>*</span>体力</div>
|
||||||
|
<div class="level-options">
|
||||||
|
<button
|
||||||
|
v-for="opt in levelOptions"
|
||||||
|
:key="`stamina-${opt}`"
|
||||||
|
type="button"
|
||||||
|
class="level-btn"
|
||||||
|
:class="{ active: form.stamina_level === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.stamina_level = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-row">
|
||||||
|
<div class="level-label"><span>*</span>负重</div>
|
||||||
|
<div class="level-options">
|
||||||
|
<button
|
||||||
|
v-for="opt in levelOptions"
|
||||||
|
:key="`load-${opt}`"
|
||||||
|
type="button"
|
||||||
|
class="level-btn"
|
||||||
|
:class="{ active: form.load_level === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.load_level = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h2 class="section-title">额外消耗品</h2>
|
||||||
|
<div
|
||||||
|
v-for="item in quantityItems"
|
||||||
|
:key="item.key"
|
||||||
|
class="quantity-row"
|
||||||
|
:class="{ disabled: isQuantityItemDisabled(item) }"
|
||||||
|
>
|
||||||
|
<div class="quantity-card">
|
||||||
|
<div class="quantity-meta">
|
||||||
|
<strong
|
||||||
|
class="backend-hint-target"
|
||||||
|
:class="{ 'has-hint': Boolean(item.placeholder) }"
|
||||||
|
:data-hint="item.placeholder"
|
||||||
|
:tabindex="item.placeholder ? 0 : -1"
|
||||||
|
>
|
||||||
|
<span>*</span>{{ item.label }}
|
||||||
|
</strong>
|
||||||
|
<small>{{ isQuantityItemDisabled(item) ? "3*3 已包含,不能填写" : item.price }}</small>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
v-model="quantityValues[item.key]"
|
||||||
|
type="number"
|
||||||
|
inputmode="numeric"
|
||||||
|
min="0"
|
||||||
|
placeholder="0"
|
||||||
|
class="quantity-input"
|
||||||
|
:disabled="isQuantityItemDisabled(item)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="mode-toggle">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
:class="{ active: quantityModes[item.key] === '赠送' }"
|
||||||
|
:disabled="isQuantityItemDisabled(item)"
|
||||||
|
@click="setQuantityMode(item, '赠送')"
|
||||||
|
>
|
||||||
|
赠送
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
:class="{ active: (quantityModes[item.key] || '收费') === '收费' }"
|
||||||
|
:disabled="isQuantityItemDisabled(item)"
|
||||||
|
@click="setQuantityMode(item, '收费')"
|
||||||
|
>
|
||||||
|
收费
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h2 class="section-title">皮肤与交接</h2>
|
||||||
|
<div class="skin-groups">
|
||||||
|
<div v-for="group in skinGroups" :key="group.key" class="skin-group">
|
||||||
|
<div class="skin-group-title">
|
||||||
|
<span>{{ group.title }}</span>
|
||||||
|
<small>
|
||||||
|
{{
|
||||||
|
group.options.filter((skin) => selectedSkins.includes(skin))
|
||||||
|
.length
|
||||||
|
}} 项
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="multi-chip-group">
|
||||||
|
<button
|
||||||
|
v-for="skin in group.options"
|
||||||
|
:key="skin"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: selectedSkins.includes(skin) }"
|
||||||
|
@click="toggleSkin(skin)"
|
||||||
|
>
|
||||||
|
{{ skin }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-field label="上号方式" class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in loginMethodOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.login_method === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.login_method = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<p class="field-hint">
|
||||||
|
优先推荐【账密登录】,出售速度约为扫码的数倍,两种方式安全性一致,账密登录更便捷,请自行衡量
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="time-row">
|
||||||
|
<div class="time-field-group">
|
||||||
|
<van-field
|
||||||
|
v-model="form.online_start"
|
||||||
|
label="在线开始"
|
||||||
|
type="time"
|
||||||
|
class="publish-field time-field"
|
||||||
|
/>
|
||||||
|
<div class="radio-group small time-preset-chips">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: isAllDayOnline() }"
|
||||||
|
@click="selectAllDayOnline"
|
||||||
|
>
|
||||||
|
全天
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-for="opt in commonOnlineTimes"
|
||||||
|
:key="`start-${opt}`"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: isOnlineStartPresetActive(opt) }"
|
||||||
|
@click="selectOnlineStart(opt)"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="time-field-group">
|
||||||
|
<van-field
|
||||||
|
v-model="form.online_end"
|
||||||
|
label="在线结束"
|
||||||
|
type="time"
|
||||||
|
class="publish-field time-field"
|
||||||
|
/>
|
||||||
|
<div class="radio-group small time-preset-chips">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: isAllDayOnline() }"
|
||||||
|
@click="selectAllDayOnline"
|
||||||
|
>
|
||||||
|
全天
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-for="opt in commonOnlineTimes"
|
||||||
|
:key="`end-${opt}`"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: isOnlineEndPresetActive(opt) }"
|
||||||
|
@click="selectOnlineEnd(opt)"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="field-hint">
|
||||||
|
此在线时间指的是百分百能够联系上您的时间,若是在此期间联系不上您导致无法上号会扣除您的部分订单金额或上架押金,在线时长太短可能无法上架,请预留充足时间用于扫码以及冻结人脸,请谨慎填写
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<van-field label="封禁记录" required class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="opt in banRecordOptions"
|
||||||
|
:key="opt"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: form.ban_record === opt }"
|
||||||
|
@click="selectRadio(opt, (value) => (form.ban_record = value))"
|
||||||
|
>
|
||||||
|
{{ opt }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
|
||||||
|
<div class="region-panel">
|
||||||
|
<div class="region-title">
|
||||||
|
<span>常用登录地区</span>
|
||||||
|
<small>已选 {{ form.common_regions.length }}</small>
|
||||||
|
</div>
|
||||||
|
<div class="region-grid">
|
||||||
|
<button
|
||||||
|
v-for="region in regionOptions"
|
||||||
|
:key="region"
|
||||||
|
type="button"
|
||||||
|
class="region-btn"
|
||||||
|
:class="{ active: form.common_regions.includes(region) }"
|
||||||
|
@click="toggleRegion(region)"
|
||||||
|
>
|
||||||
|
{{ region }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="field-hint">
|
||||||
|
推荐勾选账号常用登录地,便于同地区玩家租用,可大幅减少账号触发异地登录保护。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h2 class="section-title">截图材料</h2>
|
||||||
|
<div class="upload-list">
|
||||||
|
<div v-for="slot in screenshotSlots" :key="slot.key" class="upload-line">
|
||||||
|
<div class="upload-meta">
|
||||||
|
<strong
|
||||||
|
class="upload-title"
|
||||||
|
:class="{ 'has-hint': Boolean(slot.hint) }"
|
||||||
|
:data-hint="slot.hint"
|
||||||
|
:tabindex="slot.hint ? 0 : -1"
|
||||||
|
>
|
||||||
|
{{ slot.label }}<span v-if="isScreenshotRequired(slot)">*</span>
|
||||||
|
</strong>
|
||||||
|
<small>{{ slot.hint }}</small>
|
||||||
|
</div>
|
||||||
|
<div v-if="screenshotFiles[slot.key]" class="upload-preview">
|
||||||
|
<img :src="getScreenshotPreviewURL(slot.key)" :alt="slot.label" />
|
||||||
|
<button type="button" @click="removeScreenshot(slot.key)">移除</button>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
v-else
|
||||||
|
type="button"
|
||||||
|
class="upload-add"
|
||||||
|
:disabled="uploading"
|
||||||
|
@click="triggerUpload(slot.key)"
|
||||||
|
>
|
||||||
|
<van-icon name="photograph" :size="22" color="#999" />
|
||||||
|
<span>{{ uploading && activeUploadKey === slot.key ? "上传中" : "上传" }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
ref="fileInput"
|
||||||
|
type="file"
|
||||||
|
accept="image/jpeg,image/png,image/webp"
|
||||||
|
style="display: none"
|
||||||
|
@change="handleScreenshotUpload"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h2 class="section-title">押金与价格</h2>
|
||||||
|
<van-field
|
||||||
|
v-model="form.deposit_amount"
|
||||||
|
label="押金"
|
||||||
|
type="number"
|
||||||
|
required
|
||||||
|
:placeholder="priceConfig.deposit_placeholder"
|
||||||
|
suffix="元"
|
||||||
|
class="publish-field"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span class="hint-label" :data-hint="priceConfig.deposit_placeholder" tabindex="0">押金</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<button class="deposit-recommend-btn" type="button" @click="useRecommendedDeposit">
|
||||||
|
推荐押金 ¥{{ recommendedDepositAmount }}
|
||||||
|
</button>
|
||||||
|
<van-field label="每日损耗" required class="publish-field">
|
||||||
|
<template #input>
|
||||||
|
<div class="radio-group">
|
||||||
|
<button
|
||||||
|
v-for="loss in dailyLossOptions"
|
||||||
|
:key="loss"
|
||||||
|
type="button"
|
||||||
|
class="radio-btn"
|
||||||
|
:class="{ active: dailyLossMAmount === loss }"
|
||||||
|
@click="form.daily_loss_m = loss"
|
||||||
|
>
|
||||||
|
{{ loss }}M/天
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<p class="field-hint">
|
||||||
|
比例调整:在默认10M/天,每增加10M,出租比例相应+1,请根据实际需求合理设置,感谢您的配合。
|
||||||
|
</p>
|
||||||
|
<div class="ratio-panel">
|
||||||
|
<div class="ratio-reference">
|
||||||
|
<span>参考比例</span>
|
||||||
|
<strong>{{ calculatedDefaultSaleRatioText }}</strong>
|
||||||
|
</div>
|
||||||
|
<p class="ratio-range">{{ saleRatioRangeText }},比例越高出租速度越快,自行选择。</p>
|
||||||
|
<div class="ratio-mode-grid">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="ratio-mode-btn"
|
||||||
|
:class="{ active: !hasAcceleratedSaleRatioInput() }"
|
||||||
|
:disabled="calculatedDefaultSaleRatio <= 0"
|
||||||
|
@click="useReferenceSaleRatio"
|
||||||
|
>
|
||||||
|
<strong>参考比例</strong>
|
||||||
|
<span>
|
||||||
|
{{
|
||||||
|
calculatedDefaultSaleRatio > 0
|
||||||
|
? `1元=${formatNumber(calculatedDefaultSaleRatio)}万`
|
||||||
|
: "自动计算"
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="ratio-mode-btn"
|
||||||
|
:class="{ active: hasAcceleratedSaleRatioInput() }"
|
||||||
|
:disabled="maxAcceleratedSaleRatio <= 0"
|
||||||
|
@click="useMaxAcceleratedSaleRatio"
|
||||||
|
>
|
||||||
|
<strong>加速比例</strong>
|
||||||
|
<span>
|
||||||
|
{{
|
||||||
|
maxAcceleratedSaleRatio > 0
|
||||||
|
? `1元=${formatNumber(calculatedDefaultSaleRatio)}~${formatNumber(maxAcceleratedSaleRatio)}万`
|
||||||
|
: "自动计算"
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<van-field
|
||||||
|
:model-value="form.accelerated_sale_ratio"
|
||||||
|
label="自定比例"
|
||||||
|
type="number"
|
||||||
|
:placeholder="acceleratedSaleRatioPlaceholder"
|
||||||
|
class="publish-field ratio-input-field"
|
||||||
|
@update:model-value="handleAcceleratedSaleRatioInput"
|
||||||
|
@blur="clampAcceleratedSaleRatioInput"
|
||||||
|
/>
|
||||||
|
<p class="field-hint ratio-input-hint">
|
||||||
|
留空使用参考比例;填写后范围为参考比例到参考比例+10,请根据实际需求合理设置。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="result-grid">
|
||||||
|
<van-field
|
||||||
|
:model-value="calculatedRatioText"
|
||||||
|
label="卖家比例"
|
||||||
|
readonly
|
||||||
|
:placeholder="priceConfig.ratio_description"
|
||||||
|
class="publish-field result-field"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span class="hint-label" :data-hint="priceConfig.ratio_description" tabindex="0">卖家比例</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
:model-value="calculatedCoinBasePrice ? `¥${calculatedCoinBasePrice}` : ''"
|
||||||
|
label="纯币基础价"
|
||||||
|
readonly
|
||||||
|
required
|
||||||
|
:placeholder="priceConfig.price_placeholder"
|
||||||
|
class="publish-field result-field"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span class="hint-label" :data-hint="priceConfig.price_placeholder" tabindex="0">纯币基础价</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
:model-value="`¥${calculatedConsumablePrice}`"
|
||||||
|
label="额外消耗品"
|
||||||
|
readonly
|
||||||
|
class="publish-field result-field"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
:model-value="calculatedSellerPrice ? `¥${calculatedSellerPrice}` : ''"
|
||||||
|
label="卖家价格"
|
||||||
|
readonly
|
||||||
|
required
|
||||||
|
:placeholder="priceConfig.price_placeholder"
|
||||||
|
class="publish-field result-field total-price-field"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="price-breakdown-hint">
|
||||||
|
卖家价格 = 纯币基础价 + 额外消耗品。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<van-field
|
||||||
|
v-model="form.remark"
|
||||||
|
label="备注"
|
||||||
|
type="textarea"
|
||||||
|
rows="3"
|
||||||
|
autosize
|
||||||
|
placeholder="如有一些不可使用的物资,请在此备注,并且在买家下单后,主动在群聊处,再次提醒买家"
|
||||||
|
class="publish-field"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="publish-actions">
|
||||||
|
<van-button
|
||||||
|
round
|
||||||
|
class="reset-btn"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="handleResetDraft"
|
||||||
|
>
|
||||||
|
重置
|
||||||
|
</van-button>
|
||||||
|
<van-button
|
||||||
|
type="primary"
|
||||||
|
round
|
||||||
|
class="submit-btn"
|
||||||
|
:loading="loading"
|
||||||
|
loading-text="发布中..."
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
保存发布
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<MobileBottomNav />
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped src="./MobileSellerListingCreateView.css"></style>
|
||||||
@@ -1,182 +1,401 @@
|
|||||||
|
/* 发布页局部设计变量 / Publish page local design tokens */
|
||||||
.publish-page {
|
.publish-page {
|
||||||
max-width: 1180px;
|
--color-bg-gray: #f7f9fc;
|
||||||
margin: 0 auto;
|
--color-bg-orange: #fff7f0;
|
||||||
|
--color-orange-primary: #ff6a00;
|
||||||
|
--color-orange-dark: #e65f00;
|
||||||
|
--color-text-main: #303743;
|
||||||
|
--color-text-sub: #7f8895;
|
||||||
|
--color-text-dark: #20242a;
|
||||||
|
--color-border: #dfe5ee;
|
||||||
|
--color-border-light: #edf0f4;
|
||||||
|
--color-danger: #f04438;
|
||||||
|
--radius-8: 8px;
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
padding: 24px 20px 40px;
|
padding: 24px 20px 40px;
|
||||||
|
color: var(--color-text-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-page :deep(.el-input-number),
|
||||||
|
.publish-page :deep(.el-input),
|
||||||
|
.publish-page :deep(.el-date-editor) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-page :deep(.el-input__wrapper),
|
||||||
|
.publish-page :deep(.el-textarea__inner) {
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
box-shadow: 0 0 0 1px var(--color-border) inset;
|
||||||
|
transition: box-shadow 0.2s ease, background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-page :deep(.el-input__wrapper:hover),
|
||||||
|
.publish-page :deep(.el-textarea__inner:hover) {
|
||||||
|
box-shadow: 0 0 0 1px var(--color-orange-primary) inset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-page :deep(.el-input__wrapper.is-focus),
|
||||||
|
.publish-page :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 {
|
.publish-layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) 300px;
|
grid-template-columns: minmax(760px, 1fr) 300px;
|
||||||
gap: 20px;
|
align-items: start;
|
||||||
|
gap: 24px;
|
||||||
|
max-width: 1580px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-column,
|
.form-column {
|
||||||
.summary-column {
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-column :deep(.form-section) {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-column {
|
.panel-field-row,
|
||||||
align-self: start;
|
.panel-input-grid,
|
||||||
position: sticky;
|
.level-row,
|
||||||
top: 84px;
|
.login-method-row,
|
||||||
}
|
.quantity-item,
|
||||||
|
.skin-group,
|
||||||
.field-row,
|
|
||||||
.input-block {
|
|
||||||
display: grid;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-row + .field-row,
|
|
||||||
.compact-grid + .field-row,
|
|
||||||
.level-panel,
|
|
||||||
.time-preset-panel,
|
|
||||||
.region-panel,
|
.region-panel,
|
||||||
.ratio-panel,
|
.ratio-panel,
|
||||||
.price-grid,
|
.time-preset-row,
|
||||||
.remark {
|
.price-cell {
|
||||||
margin-top: 16px;
|
padding: 12px;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
background: var(--color-bg-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-row label,
|
.field-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 112px minmax(0, 1fr);
|
||||||
|
gap: 14px;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-row > label,
|
||||||
.input-block > span,
|
.input-block > span,
|
||||||
.quantity-meta strong {
|
.quantity-meta strong {
|
||||||
color: #0f172a;
|
color: var(--color-text-main);
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
font-weight: 700;
|
font-weight: 800;
|
||||||
|
line-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-row span,
|
.field-row label span,
|
||||||
.input-block b,
|
.input-block b,
|
||||||
.quantity-meta span,
|
.quantity-meta span,
|
||||||
.upload-copy span {
|
.upload-copy span {
|
||||||
color: #ef4444;
|
color: var(--color-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-hint {
|
.field-hint {
|
||||||
margin: 6px 0 0;
|
grid-column: 2;
|
||||||
color: #64748b;
|
margin: 0;
|
||||||
font-size: 13px;
|
color: var(--color-text-sub);
|
||||||
line-height: 1.6;
|
font-size: 12px;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-method-row .field-hint {
|
||||||
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact-grid {
|
.compact-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
gap: 14px;
|
gap: 16px;
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact-grid.two {
|
.compact-grid.two {
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
padding: 14px 16px;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
background: var(--color-bg-gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-input-grid {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-input-grid .input-block {
|
||||||
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-input-grid :deep(.el-input-number),
|
||||||
|
.panel-input-grid :deep(.el-input) {
|
||||||
|
max-width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-block {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-block > span {
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-panel,
|
.level-panel,
|
||||||
.time-preset-panel,
|
.time-preset-panel,
|
||||||
.region-panel,
|
.skin-groups {
|
||||||
.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;
|
display: grid;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-row + .level-row,
|
.level-row {
|
||||||
.time-preset-row + .time-preset-row,
|
display: grid;
|
||||||
.skin-group + .skin-group {
|
grid-template-columns: 72px minmax(0, 1fr);
|
||||||
margin-top: 14px;
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-options,
|
.level-row strong {
|
||||||
.region-grid,
|
font-size: 13px;
|
||||||
.mode-toggle,
|
}
|
||||||
.ratio-mode-grid {
|
|
||||||
display: flex;
|
.level-row strong span {
|
||||||
flex-wrap: wrap;
|
color: var(--color-danger);
|
||||||
gap: 8px;
|
}
|
||||||
|
|
||||||
|
.level-options {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||||
|
gap: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-btn,
|
.level-btn,
|
||||||
.region-btn,
|
.region-btn,
|
||||||
.mode-toggle button,
|
.mode-toggle button,
|
||||||
.ratio-mode-btn,
|
.ratio-mode-btn {
|
||||||
.recommend-button,
|
border: 1px solid #d6dce5;
|
||||||
.upload-add {
|
|
||||||
border: 1px solid #dbe3ee;
|
|
||||||
border-radius: 8px;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #334155;
|
color: #596474;
|
||||||
|
font-weight: 800;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease, transform 0.16s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-btn,
|
.level-btn,
|
||||||
.region-btn,
|
.region-btn {
|
||||||
.mode-toggle button {
|
min-width: 0;
|
||||||
min-height: 32px;
|
}
|
||||||
padding: 0 12px;
|
|
||||||
font-weight: 600;
|
.level-btn {
|
||||||
|
height: 30px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-btn {
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.level-btn.active,
|
.level-btn.active,
|
||||||
.region-btn.active,
|
.region-btn.active {
|
||||||
.mode-toggle button.active,
|
border-color: var(--color-orange-primary);
|
||||||
.ratio-mode-btn.active {
|
background: var(--color-orange-primary);
|
||||||
border-color: #2563eb;
|
color: #fff;
|
||||||
background: #eff6ff;
|
|
||||||
color: #1d4ed8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-table {
|
.quantity-table {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-header,
|
.quantity-header,
|
||||||
.quantity-item {
|
.quantity-item {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(160px, 1fr) 100px 120px 116px 80px;
|
grid-template-columns: minmax(180px, 3fr) minmax(80px, 1fr) minmax(100px, 1.2fr) minmax(140px, 1.5fr) minmax(80px, 1fr);
|
||||||
gap: 12px;
|
gap: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-header {
|
.quantity-header {
|
||||||
color: #64748b;
|
min-height: 30px;
|
||||||
|
padding: 0 12px;
|
||||||
|
color: #7b8492;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-header b {
|
||||||
|
margin-left: 2px;
|
||||||
|
color: var(--color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-item {
|
||||||
|
min-height: 58px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-item.disabled {
|
||||||
|
opacity: 0.62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-item > :deep(.el-input-number) {
|
||||||
|
width: 100% !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta {
|
||||||
|
display: grid;
|
||||||
|
min-width: 0;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta strong {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta span {
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-meta small,
|
||||||
|
.quantity-price,
|
||||||
|
.quantity-status {
|
||||||
|
color: var(--color-text-sub);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-item {
|
.quantity-price,
|
||||||
padding: 12px;
|
.quantity-status {
|
||||||
border: 1px solid #e2e8f0;
|
white-space: nowrap;
|
||||||
border-radius: 8px;
|
|
||||||
background: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-item.disabled {
|
.mode-toggle {
|
||||||
opacity: 0.65;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quantity-meta small,
|
|
||||||
.quantity-status,
|
|
||||||
.quantity-price {
|
|
||||||
color: #64748b;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-preset-content,
|
|
||||||
.deposit-control {
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 160px minmax(0, 1fr);
|
grid-template-columns: 1fr 1fr;
|
||||||
gap: 10px;
|
gap: 4px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button {
|
||||||
|
height: 30px;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0 6px;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button.active,
|
||||||
|
.ratio-mode-btn.active {
|
||||||
|
border-color: var(--color-orange-primary);
|
||||||
|
background: var(--color-bg-orange);
|
||||||
|
color: var(--color-orange-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mode-toggle button:disabled,
|
||||||
|
.ratio-mode-btn:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.58;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-group {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-title,
|
||||||
|
.region-title {
|
||||||
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skin-title {
|
||||||
|
min-height: 34px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-title span {
|
||||||
|
color: var(--color-text-sub);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-preset-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 88px minmax(0, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-preset-row strong {
|
||||||
|
color: var(--color-text-main);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-preset-content {
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-preset-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 7px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-chip {
|
||||||
|
min-height: 30px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border: 1px solid #d6dce5;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: #fff;
|
||||||
|
color: #596474;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-chip.active {
|
||||||
|
border-color: var(--color-orange-primary);
|
||||||
|
background: var(--color-orange-primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-input {
|
||||||
|
width: 118px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-region-panel {
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(8, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-grid {
|
.upload-grid {
|
||||||
@@ -187,34 +406,63 @@
|
|||||||
|
|
||||||
.upload-item {
|
.upload-item {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 10px;
|
grid-template-columns: minmax(0, 1fr) 96px;
|
||||||
padding: 14px;
|
gap: 12px;
|
||||||
border: 1px solid #e2e8f0;
|
align-items: center;
|
||||||
border-radius: 8px;
|
min-height: 112px;
|
||||||
background: #fff;
|
padding: 12px;
|
||||||
|
border: 1px solid var(--color-border-light);
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
background: var(--color-bg-gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-copy {
|
.upload-copy {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 4px;
|
min-width: 0;
|
||||||
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-copy strong {
|
.upload-copy strong {
|
||||||
color: #0f172a;
|
color: #232a35;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-copy small,
|
.upload-copy small {
|
||||||
.deposit-breakdown {
|
color: var(--color-text-sub);
|
||||||
color: #64748b;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add,
|
||||||
|
.upload-preview {
|
||||||
|
width: 96px;
|
||||||
|
height: 88px;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
align-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
border: 1px dashed #c7ceda;
|
||||||
|
background: #fff;
|
||||||
|
color: #727d8d;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-add:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.58;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-preview {
|
.upload-preview {
|
||||||
position: relative;
|
position: relative;
|
||||||
aspect-ratio: 16 / 9;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 8px;
|
background: #e8edf4;
|
||||||
background: #e2e8f0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-preview img {
|
.upload-preview img {
|
||||||
@@ -225,119 +473,239 @@
|
|||||||
|
|
||||||
.upload-preview button {
|
.upload-preview button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
right: 6px;
|
||||||
right: 8px;
|
bottom: 6px;
|
||||||
}
|
|
||||||
|
|
||||||
.upload-add {
|
|
||||||
display: grid;
|
display: grid;
|
||||||
min-height: 112px;
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
align-content: center;
|
border: none;
|
||||||
gap: 6px;
|
border-radius: var(--radius-8);
|
||||||
color: #2563eb;
|
background: rgba(17, 24, 39, 0.72);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden-file {
|
.hidden-file {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deposit-control {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deposit-control :deep(.el-input-number) {
|
||||||
|
width: 140px !important;
|
||||||
|
flex: 0 0 140px;
|
||||||
|
}
|
||||||
|
|
||||||
.recommend-button {
|
.recommend-button {
|
||||||
|
flex: 0 0 auto;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding: 0 10px;
|
padding: 0 12px;
|
||||||
color: #2563eb;
|
border: 1px solid #ffba86;
|
||||||
font-weight: 700;
|
border-radius: var(--radius-8);
|
||||||
|
background: var(--color-bg-orange);
|
||||||
|
color: var(--color-orange-dark);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.2s ease, background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommend-button:hover {
|
||||||
|
border-color: var(--color-orange-primary);
|
||||||
|
background: #ffe3cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deposit-breakdown {
|
.deposit-breakdown {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deposit-breakdown span {
|
||||||
|
min-height: 24px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--color-bg-orange);
|
||||||
|
color: var(--color-orange-dark);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-panel {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-panel p {
|
||||||
|
margin: 8px 0 14px;
|
||||||
|
color: var(--color-text-sub);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratio-reference {
|
.ratio-reference {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
min-height: 52px;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratio-reference span,
|
.ratio-reference span {
|
||||||
.price-cell span,
|
color: var(--color-text-main);
|
||||||
.summary-main span,
|
|
||||||
.summary-list span {
|
|
||||||
color: #64748b;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratio-reference strong {
|
.ratio-reference strong {
|
||||||
color: #2563eb;
|
color: var(--color-orange-primary);
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
font-weight: 900;
|
||||||
|
|
||||||
.ratio-panel p {
|
|
||||||
margin: 8px 0 14px;
|
|
||||||
color: #64748b;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratio-mode-grid {
|
.ratio-mode-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ratio-mode-btn,
|
.ratio-mode-btn,
|
||||||
.ratio-custom-card {
|
.ratio-custom-card {
|
||||||
display: grid;
|
min-height: 72px;
|
||||||
gap: 6px;
|
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border: 1px solid #dbe3ee;
|
border-radius: var(--radius-8);
|
||||||
border-radius: 8px;
|
|
||||||
background: #fff;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ratio-mode-btn {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
.ratio-mode-btn span {
|
.ratio-mode-btn span {
|
||||||
color: #64748b;
|
color: var(--color-text-sub);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
border: 1px solid #d6dce5;
|
||||||
|
background: #fff;
|
||||||
|
transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card strong {
|
||||||
|
color: #596474;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card :deep(.el-input-number) {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card :deep(.el-input__wrapper) {
|
||||||
|
background-color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card.active {
|
||||||
|
border-color: var(--color-orange-primary);
|
||||||
|
background: var(--color-bg-orange);
|
||||||
|
color: var(--color-orange-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ratio-custom-card.active strong {
|
||||||
|
color: var(--color-orange-primary);
|
||||||
|
}
|
||||||
|
|
||||||
.price-grid {
|
.price-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-cell {
|
.price-cell {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 12px;
|
min-height: 82px;
|
||||||
border-radius: 8px;
|
padding: 14px;
|
||||||
background: #f8fafc;
|
border-left: 4px solid #ccd5e0;
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-cell strong,
|
.price-cell:hover {
|
||||||
.summary-list strong {
|
transform: translateY(-2px);
|
||||||
color: #0f172a;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-cell.accent strong,
|
.price-cell span,
|
||||||
.summary-main strong {
|
.summary-main span,
|
||||||
color: #2563eb;
|
.summary-list span {
|
||||||
|
color: #6f7a89;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-cell strong {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
color: var(--color-orange-primary);
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-cell.accent {
|
||||||
|
border-left-color: var(--color-orange-primary);
|
||||||
|
background: var(--color-bg-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-column {
|
||||||
|
--summary-sticky-top: clamp(148px, 22vh, 240px);
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
position: sticky;
|
||||||
|
top: var(--summary-sticky-top);
|
||||||
|
align-self: start;
|
||||||
|
max-height: calc(100vh - var(--summary-sticky-top) - 24px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-panel {
|
.summary-panel {
|
||||||
|
padding: 16px;
|
||||||
|
max-height: inherit;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
border: 1px solid #e6ebf2;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
box-shadow: 0 12px 34px rgba(20, 34, 56, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-main {
|
.summary-main {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 6px;
|
gap: 8px;
|
||||||
padding-bottom: 14px;
|
padding: 16px;
|
||||||
border-bottom: 1px solid #e2e8f0;
|
border-radius: var(--radius-8);
|
||||||
|
background: var(--color-bg-orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-main strong {
|
.summary-main strong {
|
||||||
font-size: 28px;
|
color: var(--color-orange-primary);
|
||||||
|
font-size: 34px;
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-list {
|
.summary-list {
|
||||||
@@ -349,7 +717,16 @@
|
|||||||
.summary-list div {
|
.summary-list div {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 10px;
|
gap: 12px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid #eef2f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-list strong {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
color: var(--color-text-dark);
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-actions {
|
.summary-actions {
|
||||||
@@ -357,18 +734,46 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-actions .el-button {
|
.summary-actions :deep(.el-button) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
border-radius: var(--radius-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
.summary-actions :deep(.el-button.btn-publish) {
|
||||||
|
border-color: var(--color-orange-primary);
|
||||||
|
background-color: var(--color-orange-primary);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 800;
|
||||||
|
transition: border-color 0.2s ease, background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-actions :deep(.el-button.btn-publish:hover) {
|
||||||
|
border-color: var(--color-orange-dark);
|
||||||
|
background-color: var(--color-orange-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1120px) {
|
||||||
.publish-layout {
|
.publish-layout {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
max-width: 920px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.summary-column {
|
.summary-column {
|
||||||
position: static;
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 860px) {
|
||||||
|
.field-row,
|
||||||
|
.time-preset-row,
|
||||||
|
.quantity-header,
|
||||||
|
.quantity-item {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-hint {
|
||||||
|
grid-column: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact-grid,
|
.compact-grid,
|
||||||
@@ -376,16 +781,42 @@
|
|||||||
.upload-grid,
|
.upload-grid,
|
||||||
.price-grid,
|
.price-grid,
|
||||||
.ratio-mode-grid,
|
.ratio-mode-grid,
|
||||||
.time-preset-content,
|
|
||||||
.deposit-control {
|
.deposit-control {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-input-grid .input-block {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-input-grid :deep(.el-input-number),
|
||||||
|
.panel-input-grid :deep(.el-input) {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
.quantity-header {
|
.quantity-header {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quantity-item {
|
.upload-item {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.upload-add,
|
||||||
|
.upload-preview {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deposit-control {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deposit-control :deep(.el-input-number) {
|
||||||
|
width: 100% !important;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.region-grid {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,23 @@ function toggleSkinOption(value: string | number) {
|
|||||||
function selectDailyLoss(value: string | number) {
|
function selectDailyLoss(value: string | number) {
|
||||||
form.daily_loss_m = Number(value)
|
form.daily_loss_m = Number(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAllDayOnline() {
|
||||||
|
return form.online_start === '00:00' && form.online_end === '23:59'
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAllDayOnline() {
|
||||||
|
form.online_start = '00:00'
|
||||||
|
form.online_end = '23:59'
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOnlineStart(value: string | number) {
|
||||||
|
form.online_start = String(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOnlineEnd(value: string | number) {
|
||||||
|
form.online_end = String(value)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -262,14 +279,19 @@ function selectDailyLoss(value: string | number) {
|
|||||||
placeholder="开始时间"
|
placeholder="开始时间"
|
||||||
class="time-input"
|
class="time-input"
|
||||||
/>
|
/>
|
||||||
|
<div class="time-preset-actions">
|
||||||
|
<button type="button" class="time-chip" :class="{ active: isAllDayOnline() }" @click="selectAllDayOnline">
|
||||||
|
全天
|
||||||
|
</button>
|
||||||
<OptionChips
|
<OptionChips
|
||||||
:options="commonOnlineTimes"
|
:options="commonOnlineTimes"
|
||||||
:model-value="form.online_start"
|
:model-value="isAllDayOnline() ? '' : form.online_start"
|
||||||
key-prefix="start-"
|
key-prefix="start-"
|
||||||
@select="form.online_start = String($event)"
|
@select="selectOnlineStart"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="time-preset-row">
|
<div class="time-preset-row">
|
||||||
<strong>在线结束</strong>
|
<strong>在线结束</strong>
|
||||||
<div class="time-preset-content">
|
<div class="time-preset-content">
|
||||||
@@ -280,15 +302,20 @@ function selectDailyLoss(value: string | number) {
|
|||||||
placeholder="结束时间"
|
placeholder="结束时间"
|
||||||
class="time-input"
|
class="time-input"
|
||||||
/>
|
/>
|
||||||
|
<div class="time-preset-actions">
|
||||||
|
<button type="button" class="time-chip" :class="{ active: isAllDayOnline() }" @click="selectAllDayOnline">
|
||||||
|
全天
|
||||||
|
</button>
|
||||||
<OptionChips
|
<OptionChips
|
||||||
:options="commonOnlineTimes"
|
:options="commonOnlineTimes"
|
||||||
:model-value="form.online_end"
|
:model-value="isAllDayOnline() ? '' : form.online_end"
|
||||||
key-prefix="end-"
|
key-prefix="end-"
|
||||||
@select="form.online_end = String($event)"
|
@select="selectOnlineEnd"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<p class="field-hint">请填写能稳定联系上您的时间,便于扫码、冻结人脸和订单交接。</p>
|
<p class="field-hint">请填写能稳定联系上您的时间,便于扫码、冻结人脸和订单交接。</p>
|
||||||
|
|
||||||
<div v-if="banRecordOptions.length" class="field-row">
|
<div v-if="banRecordOptions.length" class="field-row">
|
||||||
|
|||||||
@@ -18,22 +18,29 @@ const props = withDefaults(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value: string | number]
|
||||||
select: [value: string | number]
|
select: [value: string | number]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
function isActive(value: string | number) {
|
function isActive(value: string | number) {
|
||||||
return props.activeValues.includes(value) || props.modelValue === value
|
return props.activeValues.includes(value) || props.modelValue === value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectValue(value: string | number) {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
emit('select', value)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="option-chips" :class="{ compact }">
|
<div class="chip-group" :class="{ compact }">
|
||||||
<button
|
<button
|
||||||
v-for="option in options"
|
v-for="option in options"
|
||||||
:key="`${keyPrefix}${option}`"
|
:key="`${keyPrefix}${option}`"
|
||||||
type="button"
|
type="button"
|
||||||
|
class="chip"
|
||||||
:class="{ active: isActive(option) }"
|
:class="{ active: isActive(option) }"
|
||||||
@click="emit('select', option)"
|
@click="selectValue(option)"
|
||||||
>
|
>
|
||||||
{{ option }}{{ suffix }}
|
{{ option }}{{ suffix }}
|
||||||
</button>
|
</button>
|
||||||
@@ -41,33 +48,34 @@ function isActive(value: string | number) {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.option-chips {
|
.chip-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 7px;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-chips button {
|
.chip-group.compact {
|
||||||
min-height: 34px;
|
align-items: center;
|
||||||
padding: 0 14px;
|
min-height: 32px;
|
||||||
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 {
|
.chip {
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
padding: 0 10px;
|
padding: 0 12px;
|
||||||
|
border: 1px solid #d6dce5;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: #fff;
|
||||||
|
color: #596474;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-chips button.active {
|
.chip.active {
|
||||||
border-color: #2563eb;
|
border-color: #ff6a00;
|
||||||
background: #eff6ff;
|
background: #ff6a00;
|
||||||
color: #1d4ed8;
|
color: #fff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,44 +6,44 @@ defineProps<{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="publish-section">
|
<section class="form-section">
|
||||||
<header class="publish-section-header">
|
<header class="section-heading">
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
<p v-if="description">{{ description }}</p>
|
<span v-if="description">{{ description }}</span>
|
||||||
</header>
|
</header>
|
||||||
<slot />
|
<slot />
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.publish-section {
|
.form-section {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px solid #e2e8f0;
|
border: 1px solid #e6ebf2;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
box-shadow: 0 12px 34px rgba(20, 34, 56, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-section + .publish-section {
|
.section-heading {
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.publish-section-header {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
margin-bottom: 16px;
|
min-height: 28px;
|
||||||
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-section-header h2 {
|
.section-heading h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #0f172a;
|
color: #171b24;
|
||||||
font-size: 18px;
|
font-size: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-section-header p {
|
.section-heading span {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #64748b;
|
color: #7b8492;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export const mobileRoutes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: '/m/seller/listings/create',
|
path: '/m/seller/listings/create',
|
||||||
name: 'mobile-seller-listing-create',
|
name: 'mobile-seller-listing-create',
|
||||||
component: () => import('@/features/seller/views/SellerListingCreateView.vue'),
|
component: () => import('@/features/seller/views/MobileSellerListingCreateView.vue'),
|
||||||
meta: { layout: 'blank', requiresAuth: true, requiresRealname: true },
|
meta: { layout: 'blank', requiresAuth: true, requiresRealname: true },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ export function getOnlineTimeText(item: Listing) {
|
|||||||
const start = (onlineTime as Record<string, unknown>).start;
|
const start = (onlineTime as Record<string, unknown>).start;
|
||||||
const end = (onlineTime as Record<string, unknown>).end;
|
const end = (onlineTime as Record<string, unknown>).end;
|
||||||
if (typeof start !== "string" || typeof end !== "string" || !start || !end) return "";
|
if (typeof start !== "string" || typeof end !== "string" || !start || !end) return "";
|
||||||
|
if (start === "全天" || end === "全天" || (start === "00:00" && end === "23:59")) return "全天";
|
||||||
return `${start.replace(":00", "")}-${end.replace(":00", "")}点`;
|
return `${start.replace(":00", "")}-${end.replace(":00", "")}点`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ export function getOnlineTimeText(item: Listing) {
|
|||||||
const start = (onlineTime as Record<string, unknown>).start;
|
const start = (onlineTime as Record<string, unknown>).start;
|
||||||
const end = (onlineTime as Record<string, unknown>).end;
|
const end = (onlineTime as Record<string, unknown>).end;
|
||||||
if (typeof start !== "string" || typeof end !== "string" || !start || !end) return "";
|
if (typeof start !== "string" || typeof end !== "string" || !start || !end) return "";
|
||||||
|
if (start === "全天" || end === "全天" || (start === "00:00" && end === "23:59")) return "全天";
|
||||||
return `${start.replace(":00", "")}-${end.replace(":00", "")}点`;
|
return `${start.replace(":00", "")}-${end.replace(":00", "")}点`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user