feat(order-service): 增加提交资料确认与核对摘要
This commit is contained in:
@@ -40,8 +40,8 @@ import {
|
||||
saveAdminOrderServiceProfile,
|
||||
type AdminOrderServiceAutoPublishJob,
|
||||
type AdminOrderServiceProfile,
|
||||
type OrderServiceAnnouncement,
|
||||
type OrderServiceField,
|
||||
type OrderServiceMaterialConfirmation,
|
||||
} from '@/services/admin/worker-platform'
|
||||
import { uploadFile } from '@/services/files'
|
||||
import type { UploadedFile } from '@/types/worker-platform'
|
||||
@@ -72,7 +72,7 @@ type OrderServiceFormValues = {
|
||||
successText: string
|
||||
screenshots: ScreenshotForm
|
||||
autoPublish: AutoPublishForm
|
||||
announcement: OrderServiceAnnouncement
|
||||
materialConfirmation: OrderServiceMaterialConfirmation
|
||||
}
|
||||
|
||||
const DEFAULT_SCREENSHOTS: ScreenshotForm = {
|
||||
@@ -90,15 +90,13 @@ const DEFAULT_AUTO_PUBLISH: AutoPublishForm = {
|
||||
retryMax: 3,
|
||||
}
|
||||
|
||||
const DEFAULT_ANNOUNCEMENT: OrderServiceAnnouncement = {
|
||||
const DEFAULT_MATERIAL_CONFIRMATION: OrderServiceMaterialConfirmation = {
|
||||
enabled: true,
|
||||
title: '公告',
|
||||
content: '由于个人资料填写错误,导致的赠送错误,店铺概不负责!',
|
||||
fontSize: 14,
|
||||
color: '#8a4b00',
|
||||
backgroundColor: '#fff7e6',
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'left',
|
||||
title: '提交资料确认',
|
||||
content:
|
||||
'请确认资料填写准确无误。资料提交后不能修改,因个人资料填写错误导致的赠送错误,店铺概不负责!',
|
||||
confirmText: '确认提交',
|
||||
cancelText: '返回检查',
|
||||
}
|
||||
|
||||
export default function OrderServicePanel() {
|
||||
@@ -154,7 +152,8 @@ export default function OrderServicePanel() {
|
||||
(file: File, scene: string) => uploadFile(file, scene, 'admin'),
|
||||
[],
|
||||
)
|
||||
const announcementPreview = Form.useWatch('announcement', form) || DEFAULT_ANNOUNCEMENT
|
||||
const materialConfirmationPreview =
|
||||
Form.useWatch('materialConfirmation', form) || DEFAULT_MATERIAL_CONFIRMATION
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedCategoryId !== null || categories.length === 0) return
|
||||
@@ -174,7 +173,7 @@ export default function OrderServicePanel() {
|
||||
successText: nextProfile?.successText || '资料已提交,请等待处理',
|
||||
screenshots: nextProfile?.screenshots || DEFAULT_SCREENSHOTS,
|
||||
autoPublish: nextProfile?.autoPublish || DEFAULT_AUTO_PUBLISH,
|
||||
announcement: nextProfile?.announcement || DEFAULT_ANNOUNCEMENT,
|
||||
materialConfirmation: nextProfile?.materialConfirmation || DEFAULT_MATERIAL_CONFIRMATION,
|
||||
})
|
||||
setFields(normalizeFieldOrder(nextProfile?.fields || []))
|
||||
setGuideImage(nextProfile?.guideImage || null)
|
||||
@@ -247,7 +246,7 @@ export default function OrderServicePanel() {
|
||||
fields: normalizedFields,
|
||||
screenshots: values.screenshots,
|
||||
autoPublish: values.autoPublish,
|
||||
announcement: values.announcement,
|
||||
materialConfirmation: values.materialConfirmation,
|
||||
submitText: values.submitText,
|
||||
successText: values.successText,
|
||||
})
|
||||
@@ -528,13 +527,15 @@ export default function OrderServicePanel() {
|
||||
<section className="order-service-section">
|
||||
<div className="order-service-section-head">
|
||||
<div>
|
||||
<Text strong>页面公告</Text>
|
||||
<Text type="secondary">显示在客户资料页顶部,可自定义内容和文字样式。</Text>
|
||||
<Text strong>提交资料确认</Text>
|
||||
<Text type="secondary">
|
||||
客户点击提交时弹窗确认,可自定义提示内容和按钮文字。
|
||||
</Text>
|
||||
</div>
|
||||
<Space size={8}>
|
||||
<Text type="secondary">显示公告</Text>
|
||||
<Text type="secondary">启用确认</Text>
|
||||
<Form.Item
|
||||
name={['announcement', 'enabled']}
|
||||
name={['materialConfirmation', 'enabled']}
|
||||
valuePropName="checked"
|
||||
noStyle
|
||||
>
|
||||
@@ -543,63 +544,33 @@ export default function OrderServicePanel() {
|
||||
</Space>
|
||||
</div>
|
||||
<Row gutter={[12, 0]}>
|
||||
<Col xs={24} md={10}>
|
||||
<Form.Item label="公告标题" name={['announcement', 'title']}>
|
||||
<Input maxLength={30} placeholder="例如:公告" />
|
||||
<Col xs={24} md={12}>
|
||||
<Form.Item label="确认标题" name={['materialConfirmation', 'title']}>
|
||||
<Input maxLength={40} placeholder="例如:提交资料确认" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col xs={12} md={4}>
|
||||
<Form.Item label="字号" name={['announcement', 'fontSize']}>
|
||||
<InputNumber
|
||||
min={12}
|
||||
max={24}
|
||||
addonAfter="px"
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
<Col xs={12} md={6}>
|
||||
<Form.Item label="确认按钮" name={['materialConfirmation', 'confirmText']}>
|
||||
<Input maxLength={12} placeholder="确认提交" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col xs={12} md={5}>
|
||||
<Form.Item label="文字颜色" name={['announcement', 'color']}>
|
||||
<Input type="color" className="order-service-color-input" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col xs={12} md={5}>
|
||||
<Form.Item label="背景颜色" name={['announcement', 'backgroundColor']}>
|
||||
<Input type="color" className="order-service-color-input" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col xs={12} md={4}>
|
||||
<Form.Item label="字重" name={['announcement', 'fontWeight']}>
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'normal', label: '正常' },
|
||||
{ value: 'bold', label: '加粗' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col xs={12} md={4}>
|
||||
<Form.Item label="对齐" name={['announcement', 'textAlign']}>
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'left', label: '左对齐' },
|
||||
{ value: 'center', label: '居中' },
|
||||
]}
|
||||
/>
|
||||
<Col xs={12} md={6}>
|
||||
<Form.Item label="取消按钮" name={['materialConfirmation', 'cancelText']}>
|
||||
<Input maxLength={12} placeholder="返回检查" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item label="公告内容" name={['announcement', 'content']}>
|
||||
<Form.Item label="确认内容" name={['materialConfirmation', 'content']}>
|
||||
<Input.TextArea
|
||||
autoSize={{ minRows: 2, maxRows: 5 }}
|
||||
autoSize={{ minRows: 3, maxRows: 6 }}
|
||||
maxLength={500}
|
||||
showCount
|
||||
placeholder="请输入需要客户注意的公告内容"
|
||||
placeholder="请输入客户提交资料前需要确认的内容"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<AnnouncementPreview announcement={announcementPreview} />
|
||||
<MaterialConfirmationPreview confirmation={materialConfirmationPreview} />
|
||||
</section>
|
||||
|
||||
<section className="order-service-section">
|
||||
@@ -903,28 +874,30 @@ function resolveProfileStatus(profile: AdminOrderServiceProfile | undefined) {
|
||||
return { label: '已归档', tone: 'muted' }
|
||||
}
|
||||
|
||||
function AnnouncementPreview({ announcement }: { announcement: OrderServiceAnnouncement }) {
|
||||
function MaterialConfirmationPreview({
|
||||
confirmation,
|
||||
}: {
|
||||
confirmation: OrderServiceMaterialConfirmation
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`order-service-announcement-preview${announcement.enabled ? '' : ' is-disabled'}`}
|
||||
style={{
|
||||
color: announcement.color,
|
||||
backgroundColor: announcement.backgroundColor,
|
||||
textAlign: announcement.textAlign,
|
||||
}}
|
||||
className={`order-service-confirmation-preview${confirmation.enabled ? '' : ' is-disabled'}`}
|
||||
>
|
||||
<Text strong className="order-service-announcement-preview-title">
|
||||
{announcement.title || '公告'}
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
fontSize: announcement.fontSize,
|
||||
fontWeight: announcement.fontWeight,
|
||||
}}
|
||||
>
|
||||
{announcement.content || '公告内容'}
|
||||
<strong>{confirmation.title || '提交资料确认'}</strong>
|
||||
<div className="order-service-confirmation-preview-summary">
|
||||
<span>商品:示例商品</span>
|
||||
<span>游戏账号:customer@example.com</span>
|
||||
<span>区服:安卓</span>
|
||||
<span>截图:2 张</span>
|
||||
</div>
|
||||
{!announcement.enabled ? <span>当前已关闭,不会在客户页显示</span> : null}
|
||||
<div className="order-service-confirmation-preview-content">
|
||||
{confirmation.content || '提交资料确认内容'}
|
||||
</div>
|
||||
<div className="order-service-confirmation-preview-actions">
|
||||
<span>{confirmation.cancelText || '返回检查'}</span>
|
||||
<span className="is-primary">{confirmation.confirmText || '确认提交'}</span>
|
||||
</div>
|
||||
{!confirmation.enabled ? <small>当前已关闭,点击提交将直接提交资料</small> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ function resolveErrorTitle(code: string) {
|
||||
}
|
||||
|
||||
export default function OrderServicePage() {
|
||||
const { message } = App.useApp()
|
||||
const { message, modal } = App.useApp()
|
||||
const navigate = useNavigate()
|
||||
const { orderNo: routeOrderNo } = useParams<{ orderNo?: string }>()
|
||||
const orderNo = String(routeOrderNo || '').trim()
|
||||
@@ -68,6 +68,7 @@ export default function OrderServicePage() {
|
||||
const [submittingId, setSubmittingId] = useState(0)
|
||||
const [screenshotsByOrder, setScreenshotsByOrder] = useState<Record<number, UploadedFile[]>>({})
|
||||
const submittingRef = useRef(false)
|
||||
const confirmationOpenRef = useRef(false)
|
||||
const requestSeqRef = useRef(0)
|
||||
const loadedOrderRef = useRef('')
|
||||
|
||||
@@ -146,9 +147,10 @@ export default function OrderServicePage() {
|
||||
void navigate(`/o/${encodeURIComponent(nextOrderNo)}`)
|
||||
}
|
||||
|
||||
async function handleSubmit(item: OrderServiceItem, values: Record<string, unknown>) {
|
||||
if (!orderNo || submittingRef.current) return
|
||||
function handleSubmit(item: OrderServiceItem, values: Record<string, unknown>) {
|
||||
if (!orderNo || submittingRef.current || confirmationOpenRef.current) return
|
||||
const screenshots = screenshotsByOrder[item.workOrderId] ?? item.screenshots ?? []
|
||||
const normalizedValues = normalizeFormFieldValues(item, values)
|
||||
const screenshotRule = item.screenshotsRule
|
||||
if (
|
||||
screenshotRule?.enabled &&
|
||||
@@ -159,12 +161,51 @@ export default function OrderServicePage() {
|
||||
return
|
||||
}
|
||||
|
||||
const confirmation = item.materialConfirmation
|
||||
if (!confirmation?.enabled) {
|
||||
void submitMaterial(item, normalizedValues, screenshots)
|
||||
return
|
||||
}
|
||||
|
||||
confirmationOpenRef.current = true
|
||||
modal.confirm({
|
||||
title: confirmation.title || '提交资料确认',
|
||||
content: (
|
||||
<MaterialConfirmationSummary
|
||||
item={item}
|
||||
platformOrderId={orderNo}
|
||||
values={normalizedValues}
|
||||
screenshots={screenshots}
|
||||
notice={
|
||||
confirmation.content ||
|
||||
'请确认资料填写准确无误。资料提交后不能修改,因个人资料填写错误导致的赠送错误,店铺概不负责!'
|
||||
}
|
||||
/>
|
||||
),
|
||||
okText: confirmation.confirmText || '确认提交',
|
||||
cancelText: confirmation.cancelText || '返回检查',
|
||||
centered: true,
|
||||
maskClosable: false,
|
||||
width: 560,
|
||||
onOk: () => submitMaterial(item, normalizedValues, screenshots),
|
||||
afterClose: () => {
|
||||
confirmationOpenRef.current = false
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async function submitMaterial(
|
||||
item: OrderServiceItem,
|
||||
fields: Record<string, string>,
|
||||
screenshots: UploadedFile[],
|
||||
) {
|
||||
if (!orderNo || submittingRef.current) return
|
||||
submittingRef.current = true
|
||||
setSubmittingId(item.workOrderId)
|
||||
try {
|
||||
const response = await submitOrderServiceMaterial(orderNo, {
|
||||
workOrderId: item.workOrderId,
|
||||
fields: normalizeFormFieldValues(item, values),
|
||||
fields,
|
||||
screenshots,
|
||||
})
|
||||
setSubmittedNames((current) => [
|
||||
@@ -261,31 +302,6 @@ export default function OrderServicePage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{pageConfig?.announcement?.enabled && pageConfig.announcement.content ? (
|
||||
<section
|
||||
aria-label={pageConfig.announcement.title || '页面公告'}
|
||||
className="collect-link-announcement"
|
||||
style={{
|
||||
color: pageConfig.announcement.color,
|
||||
backgroundColor: pageConfig.announcement.backgroundColor,
|
||||
textAlign: pageConfig.announcement.textAlign,
|
||||
}}
|
||||
>
|
||||
<strong className="collect-link-announcement-title">
|
||||
{pageConfig.announcement.title || '公告'}
|
||||
</strong>
|
||||
<div
|
||||
className="collect-link-announcement-content"
|
||||
style={{
|
||||
fontSize: pageConfig.announcement.fontSize,
|
||||
fontWeight: pageConfig.announcement.fontWeight,
|
||||
}}
|
||||
>
|
||||
{pageConfig.announcement.content}
|
||||
</div>
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
{submittedNames.length > 0 ? (
|
||||
<Alert
|
||||
type="success"
|
||||
@@ -509,6 +525,66 @@ function renderFieldInput(field: NonNullable<OrderServiceItem['fields']>[number]
|
||||
return <Input autoComplete="off" placeholder={placeholder} />
|
||||
}
|
||||
|
||||
function MaterialConfirmationSummary({
|
||||
item,
|
||||
platformOrderId,
|
||||
values,
|
||||
screenshots,
|
||||
notice,
|
||||
}: {
|
||||
item: OrderServiceItem
|
||||
platformOrderId: string
|
||||
values: Record<string, string>
|
||||
screenshots: UploadedFile[]
|
||||
notice: string
|
||||
}) {
|
||||
const screenshotRule = item.screenshotsRule
|
||||
return (
|
||||
<div className="collect-link-confirm">
|
||||
<div className="collect-link-confirm-meta">
|
||||
<span>{item.productName || item.categoryName || '订单商品'}</span>
|
||||
<span>订单号:{platformOrderId}</span>
|
||||
</div>
|
||||
|
||||
{item.fields && item.fields.length > 0 ? (
|
||||
<div className="collect-link-confirm-fields">
|
||||
{item.fields.map((field) => {
|
||||
const value = String(values[field.key] || '').trim()
|
||||
return (
|
||||
<div className="collect-link-confirm-field" key={field.key}>
|
||||
<span>{field.label}</span>
|
||||
<strong className={value ? '' : 'is-empty'}>{value || '未填写'}</strong>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{screenshotRule?.enabled ? (
|
||||
<div className="collect-link-confirm-screenshots">
|
||||
<div>
|
||||
<span>{screenshotRule.label || '截图'}</span>
|
||||
<strong>{screenshots.length} 张</strong>
|
||||
</div>
|
||||
{screenshots.length > 0 ? (
|
||||
<div className="collect-link-confirm-images">
|
||||
{screenshots.map((file) => (
|
||||
<img
|
||||
key={file.objectKey}
|
||||
alt={file.filename || '已上传截图'}
|
||||
src={file.thumbnailUrl || file.url}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="collect-link-confirm-content">{notice}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function normalizeFormFieldValues(item: OrderServiceItem, values: Record<string, unknown>) {
|
||||
const fields = new Map((item.fields || []).map((field) => [field.key, field]))
|
||||
return Object.fromEntries(
|
||||
|
||||
@@ -1120,15 +1120,12 @@ export type OrderServiceField = {
|
||||
sortOrder?: number
|
||||
}
|
||||
|
||||
export type OrderServiceAnnouncement = {
|
||||
export type OrderServiceMaterialConfirmation = {
|
||||
enabled: boolean
|
||||
title: string
|
||||
content: string
|
||||
fontSize: number
|
||||
color: string
|
||||
backgroundColor: string
|
||||
fontWeight: 'normal' | 'bold'
|
||||
textAlign: 'left' | 'center'
|
||||
confirmText: string
|
||||
cancelText: string
|
||||
}
|
||||
|
||||
export type AdminOrderServiceProfile = {
|
||||
@@ -1152,7 +1149,7 @@ export type AdminOrderServiceProfile = {
|
||||
requireVoucherConsume: boolean
|
||||
retryMax: number
|
||||
}
|
||||
announcement: OrderServiceAnnouncement
|
||||
materialConfirmation: OrderServiceMaterialConfirmation
|
||||
submitText: string
|
||||
successText: string
|
||||
status: 'draft' | 'published' | 'archived' | string
|
||||
@@ -1199,7 +1196,7 @@ export function saveAdminOrderServiceProfile(payload: {
|
||||
requireVoucherConsume: boolean
|
||||
retryMax: number
|
||||
}
|
||||
announcement: OrderServiceAnnouncement
|
||||
materialConfirmation: OrderServiceMaterialConfirmation
|
||||
submitText?: string
|
||||
successText?: string
|
||||
}) {
|
||||
|
||||
@@ -576,15 +576,12 @@ export type OrderServiceScreenshots = {
|
||||
helpText?: string
|
||||
}
|
||||
|
||||
export type OrderServiceAnnouncement = {
|
||||
export type OrderServiceMaterialConfirmation = {
|
||||
enabled: boolean
|
||||
title: string
|
||||
content: string
|
||||
fontSize: number
|
||||
color: string
|
||||
backgroundColor: string
|
||||
fontWeight: 'normal' | 'bold'
|
||||
textAlign: 'left' | 'center'
|
||||
confirmText: string
|
||||
cancelText: string
|
||||
}
|
||||
|
||||
export type OrderServiceItem = {
|
||||
@@ -600,7 +597,7 @@ export type OrderServiceItem = {
|
||||
message: string
|
||||
canSubmit: boolean
|
||||
blockedReason: '' | 'already_submitted' | 'status' | 'assigned' | 'shares'
|
||||
announcement?: OrderServiceAnnouncement
|
||||
materialConfirmation?: OrderServiceMaterialConfirmation
|
||||
fields?: OrderServiceField[]
|
||||
values?: Record<string, string>
|
||||
screenshots?: UploadedFile[]
|
||||
|
||||
@@ -1843,31 +1843,64 @@
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.order-service-color-input {
|
||||
height: 32px;
|
||||
padding: 2px 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.order-service-announcement-preview {
|
||||
.order-service-confirmation-preview {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid rgba(138, 75, 0, 0.16);
|
||||
border-left-width: 4px;
|
||||
border-radius: 9px;
|
||||
gap: 10px;
|
||||
max-width: 560px;
|
||||
padding: 16px;
|
||||
color: #1f2937;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06);
|
||||
}
|
||||
|
||||
.order-service-announcement-preview-title {
|
||||
color: inherit !important;
|
||||
.order-service-confirmation-preview-content {
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
line-height: 1.65;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.order-service-announcement-preview.is-disabled {
|
||||
.order-service-confirmation-preview-summary {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
padding: 10px 12px;
|
||||
color: #334155;
|
||||
font-size: 12px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid #edf2f7;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.order-service-confirmation-preview-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding-top: 6px;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.order-service-confirmation-preview-actions span {
|
||||
padding: 3px 11px;
|
||||
color: #475569;
|
||||
font-size: 12px;
|
||||
border: 1px solid #dbe2ea;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.order-service-confirmation-preview-actions .is-primary {
|
||||
color: #ffffff;
|
||||
background: #1677ff;
|
||||
border-color: #1677ff;
|
||||
}
|
||||
|
||||
.order-service-confirmation-preview.is-disabled {
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.order-service-announcement-preview > span:last-child {
|
||||
.order-service-confirmation-preview > small {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
|
||||
@@ -515,21 +515,104 @@
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.collect-link-announcement {
|
||||
padding: 12px 14px;
|
||||
border: 1px solid rgba(138, 75, 0, 0.16);
|
||||
border-left-width: 4px;
|
||||
.collect-link-confirm {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
max-height: 58vh;
|
||||
padding-top: 4px;
|
||||
padding-right: 4px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.collect-link-confirm-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 4px 16px;
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-meta span:first-child {
|
||||
color: #0f172a;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.collect-link-confirm-fields {
|
||||
overflow: hidden;
|
||||
border: 1px solid #e8edf4;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
.collect-link-announcement-title {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
.collect-link-confirm-field {
|
||||
display: grid;
|
||||
grid-template-columns: 110px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
padding: 9px 12px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
}
|
||||
|
||||
.collect-link-announcement-content {
|
||||
line-height: 1.65;
|
||||
.collect-link-confirm-field:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.collect-link-confirm-field span,
|
||||
.collect-link-confirm-screenshots span {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.collect-link-confirm-field strong,
|
||||
.collect-link-confirm-screenshots strong {
|
||||
color: #0f172a;
|
||||
font-weight: 500;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.collect-link-confirm-field strong.is-empty {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.collect-link-confirm-screenshots {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
font-size: 13px;
|
||||
background: #f8fafc;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-screenshots > div:first-child {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-images {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-images img {
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
object-fit: cover;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dbe3ee;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-content {
|
||||
padding: 10px 12px;
|
||||
color: #8a4b00;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
background: #fff7e6;
|
||||
border: 1px solid #ffe7ba;
|
||||
border-radius: 9px;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@@ -687,6 +770,11 @@
|
||||
.collect-link-success-products {
|
||||
padding: 10px 16px;
|
||||
}
|
||||
|
||||
.collect-link-confirm-field {
|
||||
grid-template-columns: 88px minmax(0, 1fr);
|
||||
padding: 8px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 兑换中心 (Redeem Page) ===== */
|
||||
|
||||
Reference in New Issue
Block a user