feat(worker): 彻底重构售后问题单与工单仲裁中心视觉与交互体验
This commit is contained in:
@@ -1,4 +1,16 @@
|
||||
import { ReloadOutlined } from '@ant-design/icons'
|
||||
import {
|
||||
AlertOutlined,
|
||||
AuditOutlined,
|
||||
CheckCircleFilled,
|
||||
CheckCircleOutlined,
|
||||
ClockCircleOutlined,
|
||||
CloseCircleOutlined,
|
||||
DollarCircleOutlined,
|
||||
FormOutlined,
|
||||
ReloadOutlined,
|
||||
SafetyCertificateOutlined,
|
||||
UserOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import {
|
||||
App,
|
||||
@@ -122,6 +134,7 @@ export default function WorkerAfterSalesPage() {
|
||||
}
|
||||
return counts
|
||||
}, [allCases])
|
||||
|
||||
const afterSalesCases = useMemo(
|
||||
() =>
|
||||
allCases
|
||||
@@ -140,27 +153,109 @@ export default function WorkerAfterSalesPage() {
|
||||
isMobile ? 'worker-after-sales-page worker-after-sales-mobile' : 'worker-after-sales-page'
|
||||
}
|
||||
>
|
||||
{/* 待办紧急提醒横幅 */}
|
||||
{pendingCount > 0 ? (
|
||||
<Alert
|
||||
className="worker-after-sales-reminder"
|
||||
type="warning"
|
||||
showIcon
|
||||
message={`你有 ${pendingCount} 条售后单待提交说明,请尽快处理,逾期可能影响结算与等级`}
|
||||
/>
|
||||
<div className="worker-as-pending-alert">
|
||||
<div className="worker-as-alert-left">
|
||||
<span className="worker-as-alert-icon-wrap">
|
||||
<AlertOutlined />
|
||||
</span>
|
||||
<div className="worker-as-alert-text">
|
||||
<div className="worker-as-alert-title">
|
||||
您有 <strong>{pendingCount}</strong> 笔售后单待提交说明
|
||||
</div>
|
||||
<div className="worker-as-alert-desc">
|
||||
买家已发起售后投诉,请尽快提交完成凭据或情况答辩,逾期可能影响您的资金与接单等级。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
className="worker-as-alert-btn"
|
||||
onClick={() => setStatusFilter('awaiting_worker_response')}
|
||||
>
|
||||
立即处理待办 ({pendingCount})
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* 4卡片争议处理概览网格 */}
|
||||
<div className="worker-as-kpi-grid">
|
||||
<div
|
||||
className={`worker-as-kpi-card is-awaiting ${statusFilter === 'awaiting_worker_response' ? 'is-active' : ''}`}
|
||||
onClick={() =>
|
||||
setStatusFilter(
|
||||
statusFilter === 'awaiting_worker_response' ? 'all' : 'awaiting_worker_response',
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="worker-as-kpi-icon-wrap amber">
|
||||
<AlertOutlined />
|
||||
</div>
|
||||
<div className="worker-as-kpi-info">
|
||||
<div className="worker-as-kpi-label">
|
||||
待我举证
|
||||
{pendingCount > 0 && <span className="worker-as-kpi-pulse-dot" />}
|
||||
</div>
|
||||
<div className="worker-as-kpi-value">{countByFilter.awaiting_worker_response || 0}</div>
|
||||
<div className="worker-as-kpi-sub">
|
||||
{pendingCount > 0 ? `${pendingCount} 笔需紧急说明` : '暂无待处理'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`worker-as-kpi-card is-review ${statusFilter === 'under_review' ? 'is-active' : ''}`}
|
||||
onClick={() => setStatusFilter(statusFilter === 'under_review' ? 'all' : 'under_review')}
|
||||
>
|
||||
<div className="worker-as-kpi-icon-wrap blue">
|
||||
<AuditOutlined />
|
||||
</div>
|
||||
<div className="worker-as-kpi-info">
|
||||
<div className="worker-as-kpi-label">平台仲裁中</div>
|
||||
<div className="worker-as-kpi-value">{countByFilter.under_review || 0}</div>
|
||||
<div className="worker-as-kpi-sub">客服公正审核中</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`worker-as-kpi-card is-recovery ${statusFilter === 'recovery_pending' ? 'is-active' : ''}`}
|
||||
onClick={() =>
|
||||
setStatusFilter(statusFilter === 'recovery_pending' ? 'all' : 'recovery_pending')
|
||||
}
|
||||
>
|
||||
<div className="worker-as-kpi-icon-wrap rose">
|
||||
<DollarCircleOutlined />
|
||||
</div>
|
||||
<div className="worker-as-kpi-info">
|
||||
<div className="worker-as-kpi-label">待追缴/扣款</div>
|
||||
<div className="worker-as-kpi-value">{countByFilter.recovery_pending || 0}</div>
|
||||
<div className="worker-as-kpi-sub">存在待追缴或抵扣款</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`worker-as-kpi-card is-closed ${statusFilter === 'closed' ? 'is-active' : ''}`}
|
||||
onClick={() => setStatusFilter(statusFilter === 'closed' ? 'all' : 'closed')}
|
||||
>
|
||||
<div className="worker-as-kpi-icon-wrap emerald">
|
||||
<CheckCircleFilled />
|
||||
</div>
|
||||
<div className="worker-as-kpi-info">
|
||||
<div className="worker-as-kpi-label">已结案归档</div>
|
||||
<div className="worker-as-kpi-value">{countByFilter.closed || 0}</div>
|
||||
<div className="worker-as-kpi-sub">历史完结记录</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 桌面端与移动端顶部筛选与控制栏 */}
|
||||
<div className="worker-after-sales-desktop-header">
|
||||
<div className="worker-after-sales-header-left">
|
||||
<Typography.Title level={3} className="worker-after-sales-heading">
|
||||
售后问题单
|
||||
售后维权与工单仲裁
|
||||
</Typography.Title>
|
||||
{pendingCount > 0 ? (
|
||||
<span className="worker-after-sales-alert-pill">
|
||||
<span className="worker-after-sales-pulse-dot" />
|
||||
{pendingCount} 条待提交说明
|
||||
</span>
|
||||
) : (
|
||||
<span className="worker-after-sales-normal-pill">无待办售后单</span>
|
||||
)}
|
||||
<span className="worker-as-total-badge">共 {allCases.length} 笔工单记录</span>
|
||||
</div>
|
||||
|
||||
<div className="worker-after-sales-header-center">
|
||||
@@ -197,7 +292,9 @@ export default function WorkerAfterSalesPage() {
|
||||
</div>
|
||||
|
||||
{afterSalesCasesQuery.isLoading ? (
|
||||
<Typography.Text type="secondary">加载中…</Typography.Text>
|
||||
<div className="worker-as-loading-state">
|
||||
<Typography.Text type="secondary">正在加载售后问题单…</Typography.Text>
|
||||
</div>
|
||||
) : afterSalesCasesQuery.isError ? (
|
||||
<Alert
|
||||
type="error"
|
||||
@@ -206,10 +303,12 @@ export default function WorkerAfterSalesPage() {
|
||||
description="请刷新后重试;若问题持续存在,请联系客服。"
|
||||
/>
|
||||
) : afterSalesCases.length === 0 ? (
|
||||
<Empty
|
||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||
description="暂无售后问题单,请保持验收资料真实完整"
|
||||
/>
|
||||
<div className="worker-as-empty-card">
|
||||
<Empty
|
||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||
description="暂无匹配的售后问题单,请保持验收资料真实完整"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="worker-after-sales-list">
|
||||
{afterSalesCases.map((item) => (
|
||||
@@ -260,180 +359,294 @@ function WorkerAfterSalesItem({
|
||||
Number(item.recoveryAmount || 0) > 0 ||
|
||||
Number(item.pendingDepositDeductionAmount || 0) > 0 ||
|
||||
Number(item.availableDeductionAmount || 0) > 0 ||
|
||||
Number(item.debtAmount || 0) > 0
|
||||
Number(item.debtAmount || 0) > 0 ||
|
||||
Number(item.refundedAmount || 0) > 0
|
||||
|
||||
return (
|
||||
<>
|
||||
<article
|
||||
className={`worker-after-sales-item${item.status === 'awaiting_worker_response' ? ' is-awaiting' : ''}`}
|
||||
>
|
||||
<div className="worker-after-sales-item-head">
|
||||
<Space size={6} wrap>
|
||||
<Tag color={resolveWorkerAfterSalesStatusColor(item.status)}>
|
||||
<article className={`worker-as-case-card is-status-${item.status}`}>
|
||||
{/* 卡片头部:状态、问题类型、工单标题、订单单号 */}
|
||||
<div className="worker-as-card-header">
|
||||
<div className="worker-as-card-header-left">
|
||||
<span className={`worker-as-status-badge is-${item.status}`}>
|
||||
<span className="worker-as-status-dot" />
|
||||
{formatWorkerAfterSalesStatus(item.status)}
|
||||
</Tag>
|
||||
<Tag color={resolveWorkerAfterSalesProblemTypeColor(item.problemType)}>
|
||||
</span>
|
||||
<Tag
|
||||
color={resolveWorkerAfterSalesProblemTypeColor(item.problemType)}
|
||||
className="worker-as-problem-tag"
|
||||
>
|
||||
{formatWorkerAfterSalesProblemType(item.problemType)}
|
||||
</Tag>
|
||||
</Space>
|
||||
<Typography.Text strong ellipsis={{ tooltip: item.productName || item.caseNo }}>
|
||||
{item.productName || item.caseNo}
|
||||
</Typography.Text>
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||
发起 {formatDateTime(item.createdAt)}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
<Space size={12} wrap className="worker-after-sales-item-meta">
|
||||
<Typography.Text
|
||||
type="secondary"
|
||||
style={{ fontSize: 12 }}
|
||||
copyable={{ text: item.workOrderNo || item.caseNo }}
|
||||
>
|
||||
工单号 {item.workOrderNo || item.caseNo}
|
||||
</Typography.Text>
|
||||
<Typography.Text
|
||||
type="secondary"
|
||||
style={{ fontSize: 12 }}
|
||||
copyable={{ text: item.caseNo }}
|
||||
>
|
||||
售后单号 {item.caseNo}
|
||||
</Typography.Text>
|
||||
{item.shareQuantity ? (
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||
拼单 {item.shareQuantity} 份
|
||||
<Typography.Text
|
||||
strong
|
||||
className="worker-as-product-title"
|
||||
ellipsis={{ tooltip: item.productName || item.caseNo }}
|
||||
>
|
||||
{item.productName || item.caseNo}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
</Space>
|
||||
|
||||
<div className="worker-after-sales-block">
|
||||
<div className="worker-after-sales-block-label">投诉内容</div>
|
||||
<Typography.Paragraph style={{ marginBottom: item.complaintFiles.length ? 8 : 0 }}>
|
||||
{item.complaintNote || '-'}
|
||||
</Typography.Paragraph>
|
||||
{item.complaintFiles.length > 0 ? (
|
||||
<ImagePreviewList files={item.complaintFiles} size={48} maxVisible={5} />
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{item.workerResponse || item.workerResponseFiles.length > 0 ? (
|
||||
<div className="worker-after-sales-block is-mine">
|
||||
<div className="worker-after-sales-block-label">
|
||||
我提交的说明{item.respondedAt ? ` · ${formatDateTime(item.respondedAt)}` : ''}
|
||||
</div>
|
||||
{item.workerResponse ? (
|
||||
<Typography.Paragraph
|
||||
style={{ marginBottom: item.workerResponseFiles.length ? 8 : 0 }}
|
||||
>
|
||||
{item.workerResponse}
|
||||
</Typography.Paragraph>
|
||||
) : null}
|
||||
{item.workerResponseFiles.length > 0 ? (
|
||||
<ImagePreviewList files={item.workerResponseFiles} size={48} maxVisible={5} />
|
||||
{item.shareQuantity ? (
|
||||
<Tag className="worker-as-share-tag">拼单 {item.shareQuantity} 份</Tag>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{resolutionLabel || item.resolutionNote || hasRecoveryDetail ? (
|
||||
<div className="worker-after-sales-block is-result">
|
||||
<div className="worker-after-sales-block-label">处理结果</div>
|
||||
<Space direction="vertical" size={6} style={{ width: '100%' }}>
|
||||
{resolutionLabel ? (
|
||||
<Space size={8} wrap>
|
||||
<Tag color={resolveWorkerAfterSalesResolutionColor(item.resolutionAction)}>
|
||||
{resolutionLabel}
|
||||
</Tag>
|
||||
{item.resolvedAt ? (
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||
{formatDateTime(item.resolvedAt)}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
</Space>
|
||||
) : null}
|
||||
{item.resolutionNote ? (
|
||||
<Typography.Paragraph style={{ marginBottom: 0 }}>
|
||||
{item.resolutionNote}
|
||||
</Typography.Paragraph>
|
||||
) : null}
|
||||
{hasRecoveryDetail ? (
|
||||
<Space size={12} wrap>
|
||||
{Number(item.recoveryAmount || 0) > 0 ? (
|
||||
<Typography.Text type="danger" strong>
|
||||
追缴 {formatMoney(item.recoveryAmount)}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
{Number(item.pendingDepositDeductionAmount || 0) > 0 ? (
|
||||
<Typography.Text type="secondary">
|
||||
待解冻资金抵扣 {formatMoney(item.pendingDepositDeductionAmount)}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
{Number(item.availableDeductionAmount || 0) > 0 ? (
|
||||
<Typography.Text type="secondary">
|
||||
余额抵扣 {formatMoney(item.availableDeductionAmount)}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
{Number(item.debtAmount || 0) > 0 ? (
|
||||
<Typography.Text type="danger" strong>
|
||||
待追缴 {formatMoney(item.debtAmount)},后续验收报酬将自动抵扣
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
{Number(item.refundedAmount || 0) > 0 ? (
|
||||
<Typography.Text type="success" strong>
|
||||
已退还追缴 {formatMoney(item.refundedAmount)} 至可用余额
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
</Space>
|
||||
) : null}
|
||||
</Space>
|
||||
</div>
|
||||
) : item.status === 'under_review' ? (
|
||||
<Typography.Text type="secondary">已提交说明,等待客服处理</Typography.Text>
|
||||
) : null}
|
||||
|
||||
{item.status === 'awaiting_worker_response' ? (
|
||||
<div className="worker-after-sales-item-actions">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setFiles([])
|
||||
form.resetFields()
|
||||
setResponseOpen(true)
|
||||
<div className="worker-as-card-header-right">
|
||||
<span className="worker-as-meta-time">
|
||||
<ClockCircleOutlined style={{ marginRight: 4 }} />
|
||||
发起 {formatDateTime(item.createdAt)}
|
||||
</span>
|
||||
<Typography.Text
|
||||
className="worker-as-meta-code"
|
||||
type="secondary"
|
||||
copyable={{
|
||||
text: item.workOrderNo || item.caseNo,
|
||||
tooltips: ['复制工单号', '已复制'],
|
||||
}}
|
||||
>
|
||||
提交说明
|
||||
</Button>
|
||||
工单 {item.workOrderNo || item.caseNo}
|
||||
</Typography.Text>
|
||||
<Typography.Text
|
||||
className="worker-as-meta-code"
|
||||
type="secondary"
|
||||
copyable={{ text: item.caseNo, tooltips: ['复制售后单号', '已复制'] }}
|
||||
>
|
||||
售后单 {item.caseNo}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 主体对比区域:买家投诉诉求 vs 打手答辩举证 (并排双列) */}
|
||||
<div className="worker-as-card-body">
|
||||
{/* 左列:买家投诉诉求 */}
|
||||
<div className="worker-as-col worker-as-buyer-col">
|
||||
<div className="worker-as-col-header">
|
||||
<div className="worker-as-avatar-pill buyer">
|
||||
<UserOutlined />
|
||||
</div>
|
||||
<span className="worker-as-col-title">买家投诉诉求</span>
|
||||
</div>
|
||||
<div className="worker-as-box buyer-box">
|
||||
<div className="worker-as-box-text">
|
||||
{item.complaintNote ? (
|
||||
<p className="worker-as-complaint-text">{item.complaintNote}</p>
|
||||
) : (
|
||||
<p className="worker-as-empty-text">买家未填写文字描述</p>
|
||||
)}
|
||||
</div>
|
||||
{item.complaintFiles.length > 0 && (
|
||||
<div className="worker-as-box-files">
|
||||
<div className="worker-as-files-label">
|
||||
买家举证材料 ({item.complaintFiles.length}):
|
||||
</div>
|
||||
<ImagePreviewList files={item.complaintFiles} size={54} maxVisible={6} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右列:打手答辩与举证 */}
|
||||
<div className="worker-as-col worker-as-worker-col">
|
||||
<div className="worker-as-col-header">
|
||||
<div className="worker-as-avatar-pill worker">
|
||||
<SafetyCertificateOutlined />
|
||||
</div>
|
||||
<span className="worker-as-col-title">我的答辩与说明</span>
|
||||
{item.respondedAt && (
|
||||
<span className="worker-as-col-subtitle">
|
||||
提交于 {formatDateTime(item.respondedAt)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{item.workerResponse || item.workerResponseFiles.length > 0 ? (
|
||||
<div className="worker-as-box worker-box">
|
||||
<div className="worker-as-box-text">
|
||||
{item.workerResponse ? (
|
||||
<p className="worker-as-worker-text">{item.workerResponse}</p>
|
||||
) : null}
|
||||
</div>
|
||||
{item.workerResponseFiles.length > 0 && (
|
||||
<div className="worker-as-box-files">
|
||||
<div className="worker-as-files-label">
|
||||
补救举证材料 ({item.workerResponseFiles.length}):
|
||||
</div>
|
||||
<ImagePreviewList files={item.workerResponseFiles} size={54} maxVisible={6} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : item.status === 'awaiting_worker_response' ? (
|
||||
<div className="worker-as-box awaiting-cta-box">
|
||||
<div className="worker-as-cta-content">
|
||||
<div className="worker-as-cta-icon-wrap">
|
||||
<AlertOutlined className="worker-as-cta-icon" />
|
||||
</div>
|
||||
<div className="worker-as-cta-info">
|
||||
<h4 className="worker-as-cta-title">等待您提交说明材料</h4>
|
||||
<p className="worker-as-cta-desc">
|
||||
买家已发起售后申诉,请针对上述问题提交文字说明或补救凭据,以便平台客服公允判定。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
className="worker-as-submit-btn"
|
||||
icon={<FormOutlined />}
|
||||
onClick={() => {
|
||||
setFiles([])
|
||||
form.resetFields()
|
||||
setResponseOpen(true)
|
||||
}}
|
||||
>
|
||||
立即提交说明与凭据
|
||||
</Button>
|
||||
</div>
|
||||
) : item.status === 'under_review' ? (
|
||||
<div className="worker-as-box neutral-state-box">
|
||||
<ClockCircleOutlined className="worker-as-neutral-icon" />
|
||||
<p className="worker-as-neutral-text">
|
||||
未补充文字材料,平台客服正在结合买家举证与订单原始验收凭据进行裁决审核。
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="worker-as-box neutral-state-box is-closed">
|
||||
<CheckCircleOutlined className="worker-as-neutral-icon" />
|
||||
<p className="worker-as-neutral-text">本工单已结案(未补充答辩记录)</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 底部横幅:平台仲裁裁决与资金明细 */}
|
||||
{resolutionLabel ||
|
||||
item.resolutionNote ||
|
||||
hasRecoveryDetail ||
|
||||
item.status === 'under_review' ? (
|
||||
<div
|
||||
className={`worker-as-resolution-banner ${item.status === 'under_review' && !resolutionLabel ? 'is-pending' : ''}`}
|
||||
>
|
||||
<div className="worker-as-resolution-head">
|
||||
<div className="worker-as-resolution-head-left">
|
||||
<span className="worker-as-gavel-icon">
|
||||
<AuditOutlined />
|
||||
</span>
|
||||
<span className="worker-as-resolution-title">平台仲裁判定</span>
|
||||
{resolutionLabel ? (
|
||||
<Tag
|
||||
color={resolveWorkerAfterSalesResolutionColor(item.resolutionAction)}
|
||||
className="worker-as-resolution-tag"
|
||||
>
|
||||
{item.resolutionAction === 'upheld' && (
|
||||
<CloseCircleOutlined style={{ marginRight: 4 }} />
|
||||
)}
|
||||
{item.resolutionAction === 'not_upheld' && (
|
||||
<CheckCircleOutlined style={{ marginRight: 4 }} />
|
||||
)}
|
||||
{resolutionLabel}
|
||||
</Tag>
|
||||
) : item.status === 'under_review' ? (
|
||||
<Tag color="blue" className="worker-as-resolution-tag">
|
||||
客服审核中
|
||||
</Tag>
|
||||
) : null}
|
||||
{item.resolvedAt ? (
|
||||
<span className="worker-as-resolution-time">
|
||||
裁决时间:{formatDateTime(item.resolvedAt)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.resolutionNote && (
|
||||
<div className="worker-as-resolution-note">
|
||||
<span className="note-label">判定说明:</span>
|
||||
<span className="note-content">{item.resolutionNote}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{hasRecoveryDetail && (
|
||||
<div className="worker-as-financial-breakdown">
|
||||
<span className="financial-label">资金处理明细:</span>
|
||||
<div className="financial-chips-wrap">
|
||||
{Number(item.recoveryAmount || 0) > 0 && (
|
||||
<span className="financial-chip is-recovery">
|
||||
<span className="chip-name">追缴金额</span>
|
||||
<span className="chip-amount">{formatMoney(item.recoveryAmount)}</span>
|
||||
</span>
|
||||
)}
|
||||
{Number(item.pendingDepositDeductionAmount || 0) > 0 && (
|
||||
<span className="financial-chip is-deposit">
|
||||
<span className="chip-name">待解冻资金抵扣</span>
|
||||
<span className="chip-amount">
|
||||
{formatMoney(item.pendingDepositDeductionAmount)}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{Number(item.availableDeductionAmount || 0) > 0 && (
|
||||
<span className="financial-chip is-available">
|
||||
<span className="chip-name">余额抵扣</span>
|
||||
<span className="chip-amount">
|
||||
{formatMoney(item.availableDeductionAmount)}
|
||||
</span>
|
||||
</span>
|
||||
)}
|
||||
{Number(item.debtAmount || 0) > 0 && (
|
||||
<span className="financial-chip is-debt">
|
||||
<span className="chip-name">待追缴欠款</span>
|
||||
<span className="chip-amount">{formatMoney(item.debtAmount)}</span>
|
||||
<span className="chip-hint">(后续报酬自动抵扣)</span>
|
||||
</span>
|
||||
)}
|
||||
{Number(item.refundedAmount || 0) > 0 && (
|
||||
<span className="financial-chip is-refunded">
|
||||
<span className="chip-name">退还追缴</span>
|
||||
<span className="chip-amount">{formatMoney(item.refundedAmount)}</span>
|
||||
<span className="chip-hint">(已入可用余额)</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</article>
|
||||
|
||||
{/* 提交说明材料弹窗 */}
|
||||
<Modal
|
||||
title={`售后说明 · ${item.productName || item.caseNo}`}
|
||||
title={`提交售后说明 · ${item.productName || item.caseNo}`}
|
||||
open={responseOpen}
|
||||
width={isMobile ? '92%' : 560}
|
||||
width={isMobile ? '94%' : 580}
|
||||
onCancel={() => setResponseOpen(false)}
|
||||
onOk={() => form.submit()}
|
||||
okText="提交说明"
|
||||
okText="确认提交说明"
|
||||
destroyOnHidden
|
||||
className="worker-as-submit-modal"
|
||||
>
|
||||
<Alert
|
||||
type="warning"
|
||||
showIcon
|
||||
message="请针对售后问题说明情况或提交补救材料,原验收资料不可在此修改。"
|
||||
style={{ marginBottom: 12 }}
|
||||
message="请针对售后问题如实说明情况或提交补救凭证。原订单验收资料不可在此修改。"
|
||||
style={{ marginBottom: 14 }}
|
||||
/>
|
||||
<div className="worker-after-sales-block">
|
||||
<div className="worker-after-sales-block-label">
|
||||
投诉内容 · {formatWorkerAfterSalesProblemType(item.problemType)}
|
||||
|
||||
{/* 弹窗内展示买家投诉内容供参考 */}
|
||||
<div className="worker-as-modal-buyer-summary">
|
||||
<div className="modal-summary-title">
|
||||
<UserOutlined style={{ marginRight: 6, color: '#ef4444' }} />
|
||||
买家投诉内容 · {formatWorkerAfterSalesProblemType(item.problemType)}
|
||||
</div>
|
||||
<Typography.Paragraph style={{ marginBottom: item.complaintFiles.length ? 8 : 0 }}>
|
||||
{item.complaintNote || '-'}
|
||||
</Typography.Paragraph>
|
||||
{item.complaintFiles.length > 0 ? (
|
||||
<ImagePreviewList files={item.complaintFiles} size={44} maxVisible={4} />
|
||||
) : null}
|
||||
<div className="modal-summary-content">
|
||||
{item.complaintNote || '(买家未填写文字描述)'}
|
||||
</div>
|
||||
{item.complaintFiles.length > 0 && (
|
||||
<div className="modal-summary-files">
|
||||
<ImagePreviewList files={item.complaintFiles} size={46} maxVisible={4} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Form form={form} layout="vertical" onFinish={submit} style={{ marginTop: 12 }}>
|
||||
|
||||
<Form form={form} layout="vertical" onFinish={submit} style={{ marginTop: 14 }}>
|
||||
<Form.Item
|
||||
label="说明"
|
||||
label="我的说明与答辩"
|
||||
name="response"
|
||||
extra="说明与补救材料至少填写一项"
|
||||
rules={[
|
||||
@@ -441,7 +654,7 @@ function WorkerAfterSalesItem({
|
||||
validator: (_, value) =>
|
||||
String(value || '').trim() || files.length > 0
|
||||
? Promise.resolve()
|
||||
: Promise.reject(new Error('请填写说明或至少上传一张图片')),
|
||||
: Promise.reject(new Error('请填写说明或至少上传一张补救材料图片')),
|
||||
},
|
||||
]}
|
||||
>
|
||||
@@ -449,10 +662,10 @@ function WorkerAfterSalesItem({
|
||||
rows={4}
|
||||
maxLength={2000}
|
||||
showCount
|
||||
placeholder="请说明当时的处理情况"
|
||||
placeholder="请详细客观说明当时订单处理情况、与买家沟通情况或补救事实…"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="补救材料图片">
|
||||
<Form.Item label="补救举证材料图片 (支持粘贴直接上传)">
|
||||
<ImageUpload
|
||||
scene="worker-acceptance"
|
||||
scope="worker"
|
||||
|
||||
+796
-142
@@ -2791,24 +2791,247 @@ body {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
/* ===== 售后问题单(打手端) ===== */
|
||||
/* ===== 售后争议与工单仲裁中心 (打手端) ===== */
|
||||
|
||||
.worker-after-sales-page {
|
||||
max-width: 1240px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
gap: 16px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.worker-after-sales-reminder {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.worker-after-sales-toolbar {
|
||||
/* 待办紧急提醒横幅 */
|
||||
.worker-as-pending-alert {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
padding: 14px 20px;
|
||||
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
|
||||
border: 1px solid #fde68a;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 4px 14px -2px rgba(245, 158, 11, 0.12);
|
||||
}
|
||||
|
||||
.worker-as-alert-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.worker-as-alert-icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
background: #f59e0b;
|
||||
color: #ffffff;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
|
||||
}
|
||||
|
||||
.worker-as-alert-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #92400e;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.worker-as-alert-title strong {
|
||||
font-size: 17px;
|
||||
color: #b45309;
|
||||
}
|
||||
|
||||
.worker-as-alert-desc {
|
||||
font-size: 13px;
|
||||
color: #b45309;
|
||||
margin-top: 2px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.worker-as-alert-btn {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
|
||||
border: none !important;
|
||||
font-weight: 600 !important;
|
||||
height: 38px !important;
|
||||
padding: 0 18px !important;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: 0 2px 8px rgba(217, 119, 6, 0.25) !important;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 4卡片争议处理概览网格 */
|
||||
.worker-as-kpi-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.worker-as-kpi-card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 14px;
|
||||
padding: 16px 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.03);
|
||||
}
|
||||
|
||||
.worker-as-kpi-card:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: #cbd5e1;
|
||||
box-shadow: 0 6px 16px -2px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.worker-as-kpi-card.is-active {
|
||||
border-color: #2563eb;
|
||||
background: linear-gradient(135deg, #eff6ff 0%, #ffffff 100%);
|
||||
box-shadow: 0 4px 14px rgba(37, 99, 235, 0.12);
|
||||
}
|
||||
|
||||
.worker-as-kpi-icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 12px;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-as-kpi-icon-wrap.amber {
|
||||
background: #fffbeb;
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
.worker-as-kpi-icon-wrap.blue {
|
||||
background: #eff6ff;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.worker-as-kpi-icon-wrap.rose {
|
||||
background: #fff1f2;
|
||||
color: #e11d48;
|
||||
}
|
||||
|
||||
.worker-as-kpi-icon-wrap.emerald {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
.worker-as-kpi-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.worker-as-kpi-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.worker-as-kpi-pulse-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: #ef4444;
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
||||
animation: worker-after-sales-pulse 2s infinite cubic-bezier(0.4, 0, 0.6, 1);
|
||||
}
|
||||
|
||||
@keyframes worker-after-sales-pulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
||||
}
|
||||
70% {
|
||||
transform: scale(1);
|
||||
box-shadow: 0 0 0 6px rgba(239, 68, 68, 0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.worker-as-kpi-value {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
line-height: 1.2;
|
||||
margin: 2px 0;
|
||||
font-feature-settings: 'tnum';
|
||||
}
|
||||
|
||||
.worker-as-kpi-sub {
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 头部筛选工具栏 */
|
||||
.worker-after-sales-desktop-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
background: #ffffff;
|
||||
padding: 14px 20px;
|
||||
border-radius: 14px;
|
||||
border: 1px solid #e2e8f0;
|
||||
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
.worker-after-sales-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-after-sales-heading.ant-typography {
|
||||
margin: 0 !important;
|
||||
font-size: 18px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #0f172a !important;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.worker-as-total-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #64748b;
|
||||
background: #f1f5f9;
|
||||
padding: 2px 9px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.worker-after-sales-header-center {
|
||||
flex: 1;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.worker-after-sales-segmented {
|
||||
background: #f1f5f9;
|
||||
padding: 3px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.worker-after-sales-filter-count {
|
||||
@@ -2823,72 +3046,596 @@ body {
|
||||
color: #1677ff;
|
||||
font-size: 11px;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.worker-after-sales-header-right {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-as-loading-state,
|
||||
.worker-as-empty-card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 14px;
|
||||
padding: 48px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 售后列表与卡片 */
|
||||
.worker-after-sales-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.worker-after-sales-item {
|
||||
.worker-as-case-card {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-left: 3px solid #cbd5e1;
|
||||
border-radius: 14px;
|
||||
padding: 14px 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px -2px rgba(15, 23, 42, 0.04);
|
||||
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.worker-after-sales-item.is-awaiting {
|
||||
border-left-color: #fa8c16;
|
||||
background: #fffdf8;
|
||||
.worker-as-case-card:hover {
|
||||
border-color: #cbd5e1;
|
||||
box-shadow: 0 8px 24px -4px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.worker-after-sales-item-head {
|
||||
.worker-as-case-card.is-status-awaiting_worker_response {
|
||||
border-left: 4px solid #f59e0b;
|
||||
}
|
||||
|
||||
.worker-as-case-card.is-status-under_review {
|
||||
border-left: 4px solid #3b82f6;
|
||||
}
|
||||
|
||||
.worker-as-case-card.is-status-recovery_pending {
|
||||
border-left: 4px solid #ef4444;
|
||||
}
|
||||
|
||||
.worker-as-case-card.is-status-closed {
|
||||
border-left: 4px solid #10b981;
|
||||
}
|
||||
|
||||
/* 卡片顶部元数据条 */
|
||||
.worker-as-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px 10px;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding: 12px 18px;
|
||||
background: #fafbfc;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.worker-as-card-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.worker-after-sales-item-meta {
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.worker-after-sales-block {
|
||||
background: #f8fafc;
|
||||
border: 1px solid #eef2f7;
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.worker-after-sales-block.is-mine {
|
||||
background: #f6ffed;
|
||||
border-color: #e6f4dc;
|
||||
}
|
||||
|
||||
.worker-after-sales-block.is-result {
|
||||
background: #fff7e6;
|
||||
border-color: #ffe7ba;
|
||||
}
|
||||
|
||||
.worker-after-sales-block-label {
|
||||
.worker-as-status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.worker-as-status-badge.is-awaiting_worker_response {
|
||||
background: #fffbeb;
|
||||
color: #b45309;
|
||||
border: 1px solid #fde68a;
|
||||
}
|
||||
|
||||
.worker-as-status-badge.is-under_review {
|
||||
background: #eff6ff;
|
||||
color: #1d4ed8;
|
||||
border: 1px solid #bfdbfe;
|
||||
}
|
||||
|
||||
.worker-as-status-badge.is-recovery_pending {
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
|
||||
.worker-as-status-badge.is-closed {
|
||||
background: #ecfdf5;
|
||||
color: #047857;
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
.worker-as-status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
.worker-as-problem-tag {
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.worker-as-product-title {
|
||||
font-size: 15px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #0f172a !important;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
.worker-as-share-tag {
|
||||
background: #f1f5f9 !important;
|
||||
color: #475569 !important;
|
||||
border: 1px solid #e2e8f0 !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 11px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.worker-as-card-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.worker-as-meta-time {
|
||||
font-size: 12px;
|
||||
color: #94a3b8;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.worker-as-meta-code {
|
||||
font-size: 12px !important;
|
||||
color: #64748b !important;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.worker-as-meta-code:hover {
|
||||
border-color: #cbd5e1;
|
||||
color: #0f172a !important;
|
||||
}
|
||||
|
||||
/* 主体对比区域 (双列并排) */
|
||||
.worker-as-card-body {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
.worker-as-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.worker-as-col-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.worker-as-avatar-pill {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.worker-as-avatar-pill.buyer {
|
||||
background: #fee2e2;
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.worker-as-avatar-pill.worker {
|
||||
background: #dcfce7;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.worker-as-col-title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.worker-as-col-subtitle {
|
||||
font-size: 12px;
|
||||
color: #94a3b8;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.worker-as-box {
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
min-height: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.worker-as-box.buyer-box {
|
||||
background: #fafbfc;
|
||||
border-color: #e2e8f0;
|
||||
}
|
||||
|
||||
.worker-as-box.worker-box {
|
||||
background: #f0fdf4;
|
||||
border-color: #bbf7d0;
|
||||
}
|
||||
|
||||
.worker-as-complaint-text {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #1e293b;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.worker-as-worker-text {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #14532d;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.worker-as-empty-text {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
color: #94a3b8;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.worker-as-box-files {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
padding-top: 10px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.worker-as-files-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.worker-after-sales-item.is-awaiting .worker-after-sales-item-actions {
|
||||
/* 待提交答辩 CTA 提示框 */
|
||||
.worker-as-box.awaiting-cta-box {
|
||||
background: #fffdf5;
|
||||
border: 1.5px dashed #f59e0b;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.worker-after-sales-mobile .worker-after-sales-toolbar .ant-segmented {
|
||||
overflow-x: auto;
|
||||
.worker-as-cta-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.worker-as-cta-icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
background: #fef3c7;
|
||||
color: #d97706;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-as-cta-title {
|
||||
margin: 0 0 2px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.worker-as-cta-desc {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #b45309;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.worker-as-submit-btn {
|
||||
background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
|
||||
border: none !important;
|
||||
font-weight: 600 !important;
|
||||
height: 36px !important;
|
||||
padding: 0 20px !important;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: 0 2px 6px rgba(217, 119, 6, 0.25) !important;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
/* 审核中 / 结案中性状态框 */
|
||||
.worker-as-box.neutral-state-box {
|
||||
background: #f8fafc;
|
||||
border: 1px dashed #cbd5e1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.worker-as-neutral-icon {
|
||||
font-size: 18px;
|
||||
color: #94a3b8;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-as-neutral-text {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部仲裁裁决横幅 */
|
||||
.worker-as-resolution-banner {
|
||||
background: #f8fafc;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding: 14px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.worker-as-resolution-banner.is-pending {
|
||||
background: #f0f9ff;
|
||||
border-top-color: #bae6fd;
|
||||
}
|
||||
|
||||
.worker-as-resolution-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.worker-as-resolution-head-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.worker-as-gavel-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 6px;
|
||||
background: #1e293b;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.worker-as-resolution-title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.worker-as-resolution-tag {
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.worker-as-resolution-time {
|
||||
font-size: 12px;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.worker-as-resolution-note {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.worker-as-resolution-note .note-label {
|
||||
font-weight: 600;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.worker-as-resolution-note .note-content {
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
/* 资金处理明细标签 */
|
||||
.worker-as-financial-breakdown {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.worker-as-financial-breakdown .financial-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.financial-chips-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.financial-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.financial-chip .chip-name {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.financial-chip .chip-amount {
|
||||
font-weight: 800;
|
||||
font-feature-settings: 'tnum';
|
||||
}
|
||||
|
||||
.financial-chip .chip-hint {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.financial-chip.is-recovery {
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
|
||||
.financial-chip.is-deposit {
|
||||
background: #fff7ed;
|
||||
color: #ea580c;
|
||||
border: 1px solid #ffedd5;
|
||||
}
|
||||
|
||||
.financial-chip.is-available {
|
||||
background: #f1f5f9;
|
||||
color: #475569;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.financial-chip.is-debt {
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
border: 1px solid #f87171;
|
||||
}
|
||||
|
||||
.financial-chip.is-refunded {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
border: 1px solid #a7f3d0;
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.worker-as-modal-buyer-summary {
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 10px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.worker-as-modal-buyer-summary .modal-summary-title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #334155;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.worker-as-modal-buyer-summary .modal-summary-content {
|
||||
font-size: 13px;
|
||||
color: #1e293b;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.worker-as-modal-buyer-summary .modal-summary-files {
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 992px) {
|
||||
.worker-as-kpi-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.worker-as-kpi-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.worker-as-kpi-card {
|
||||
padding: 12px 14px;
|
||||
gap: 10px;
|
||||
}
|
||||
.worker-as-kpi-icon-wrap {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.worker-as-kpi-value {
|
||||
font-size: 18px;
|
||||
}
|
||||
.worker-as-pending-alert {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.worker-as-alert-btn {
|
||||
width: 100%;
|
||||
}
|
||||
.worker-after-sales-desktop-header {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.worker-after-sales-header-center {
|
||||
max-width: 100%;
|
||||
}
|
||||
.worker-as-card-body {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 14px;
|
||||
}
|
||||
.worker-as-card-header {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
.worker-as-product-title {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
@@ -3360,99 +4107,6 @@ body {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ===== 售后问题单 桌面端头部 ===== */
|
||||
.worker-after-sales-desktop-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px;
|
||||
background: #ffffff;
|
||||
padding: 14px 20px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
.worker-after-sales-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.worker-after-sales-heading.ant-typography {
|
||||
margin: 0 !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #0f172a !important;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.worker-after-sales-alert-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #dc2626;
|
||||
background: #fef2f2;
|
||||
border: 1px solid #fecaca;
|
||||
padding: 2px 10px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.worker-after-sales-pulse-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: #ef4444;
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
||||
animation: worker-after-sales-pulse 2s infinite cubic-bezier(0.4, 0, 0.6, 1);
|
||||
}
|
||||
|
||||
@keyframes worker-after-sales-pulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
||||
}
|
||||
70% {
|
||||
transform: scale(1);
|
||||
box-shadow: 0 0 0 6px rgba(239, 68, 68, 0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.worker-after-sales-normal-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #059669;
|
||||
background: #ecfdf5;
|
||||
border: 1px solid #a7f3d0;
|
||||
padding: 2px 10px;
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.worker-after-sales-header-center {
|
||||
flex: 1;
|
||||
max-width: 480px;
|
||||
}
|
||||
|
||||
.worker-after-sales-segmented {
|
||||
background: #f1f5f9;
|
||||
padding: 3px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.worker-after-sales-header-right {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ===== 个人中心 桌面端 Hero 与 钱包网格 ===== */
|
||||
.worker-profile-hero-card {
|
||||
background: #ffffff;
|
||||
|
||||
Reference in New Issue
Block a user