优化打手端我的订单与个人中心界面布局
This commit is contained in:
@@ -9,18 +9,15 @@ import {
|
||||
App,
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
Descriptions,
|
||||
Drawer,
|
||||
Empty,
|
||||
Form,
|
||||
Input,
|
||||
Modal,
|
||||
Row,
|
||||
Segmented,
|
||||
Space,
|
||||
Statistic,
|
||||
Table,
|
||||
Tabs,
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd'
|
||||
@@ -40,24 +37,14 @@ import { formatDateTime } from '@/utils/date-time'
|
||||
|
||||
const STATUS_OPTIONS = [
|
||||
{ value: '', label: '全部订单' },
|
||||
{ value: 'open', label: '已超时' },
|
||||
{ value: 'in_progress', label: '代练中' },
|
||||
{ value: 'pending_acceptance', label: '待验收' },
|
||||
{ value: 'problem', label: '问题单' },
|
||||
{ value: 'open', label: '已超时' },
|
||||
{ value: 'accepted', label: '已验收' },
|
||||
{ value: 'cancelled', label: '已取消' },
|
||||
] as const
|
||||
|
||||
const STATUS_SUMMARY_ITEMS = [
|
||||
{ key: 'all', label: '全部订单', note: '当前账号历史接单总数' },
|
||||
{ key: 'in_progress', label: '代练中', note: '正在执行中的订单' },
|
||||
{ key: 'pending_acceptance', label: '待验收', note: '已提交,等待审核' },
|
||||
{ key: 'problem', label: '问题单', note: '需要补充或重新处理' },
|
||||
{ key: 'open', label: '已超时', note: '超时被系统退回的订单数' },
|
||||
{ key: 'accepted', label: '已验收', note: '已完成并结算的订单' },
|
||||
{ key: 'cancelled', label: '已取消', note: '已结束且不再继续' },
|
||||
] as const
|
||||
|
||||
type AcceptanceFormValues = {
|
||||
note?: string
|
||||
}
|
||||
@@ -171,7 +158,7 @@ export default function WorkerOrdersPage() {
|
||||
const columns: TableColumnsType<WorkOrder> = [
|
||||
{
|
||||
title: '订单信息',
|
||||
minWidth: 320,
|
||||
minWidth: 280,
|
||||
render: (_, row) => (
|
||||
<div className="cell-stack">
|
||||
<Typography.Link onClick={() => setDetailOrder(row)}>
|
||||
@@ -179,12 +166,10 @@ export default function WorkerOrdersPage() {
|
||||
</Typography.Link>
|
||||
<Space size={[6, 6]} wrap>
|
||||
{row.categoryName ? <Tag>{row.categoryName}</Tag> : null}
|
||||
<Typography.Text type="secondary">
|
||||
工单号:{row.workOrderNo}
|
||||
</Typography.Text>
|
||||
{row.myShare ? <Tag color="purple">拼单</Tag> : null}
|
||||
</Space>
|
||||
<Typography.Text type="secondary">
|
||||
订单号:{row.platformOrderId || '-'}
|
||||
{row.workOrderNo} · {row.platformOrderId || '-'}
|
||||
</Typography.Text>
|
||||
<Typography.Text type="secondary">
|
||||
接单时间:{formatDateTime(row.assignedAt)}
|
||||
@@ -192,6 +177,25 @@ export default function WorkerOrdersPage() {
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
width: 170,
|
||||
render: (_, row) => (
|
||||
<div className="cell-stack">
|
||||
<Space wrap size={6}>
|
||||
<Tag color={resolveStatusColor(row.status)}>{formatStatus(row.status)}</Tag>
|
||||
{row.status === 'in_progress' && row.deadlineAt ? (
|
||||
<DeadlineCountdown deadlineAt={row.deadlineAt} />
|
||||
) : null}
|
||||
</Space>
|
||||
{row.status === 'problem' && String(row.problemNote || '').trim() ? (
|
||||
<Typography.Text type="danger" ellipsis>
|
||||
{row.problemNote}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '奖励 / 押金',
|
||||
width: 150,
|
||||
@@ -201,77 +205,46 @@ export default function WorkerOrdersPage() {
|
||||
<Typography.Text type="secondary">
|
||||
冻结押金:{formatMoney(row.freezeDepositAmount)}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '我的拼单',
|
||||
width: 170,
|
||||
render: (_, row) =>
|
||||
row.myShare ? (
|
||||
<div className="cell-stack">
|
||||
<Tag color="purple">
|
||||
{formatSharingShareStatus(row.myShare.status)}
|
||||
</Tag>
|
||||
<Typography.Text>
|
||||
{row.myShare.quantity} 份 × {formatMoney(row.myShare.unitReward)}
|
||||
</Typography.Text>
|
||||
{row.myShare ? (
|
||||
<Typography.Text type="secondary">
|
||||
份额报酬:{formatMoney(row.myShare.shareReward)}
|
||||
{row.myShare.quantity} 份 · 份额 {formatMoney(row.myShare.shareReward)}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
) : (
|
||||
<Typography.Text type="secondary">-</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '当前状态',
|
||||
width: 180,
|
||||
render: (_, row) => (
|
||||
<div className="cell-stack">
|
||||
<Tag color={resolveStatusColor(row.status)}>{formatStatus(row.status)}</Tag>
|
||||
{row.status === 'in_progress' && row.deadlineAt ? (
|
||||
<DeadlineCountdown deadlineAt={row.deadlineAt} />
|
||||
) : null}
|
||||
<Typography.Text type="secondary">
|
||||
{getStatusHint(row.status)}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '验收信息',
|
||||
minWidth: 210,
|
||||
render: (_, row) => (
|
||||
<div className="cell-stack">
|
||||
<ImagePreviewList
|
||||
files={getAcceptanceFiles(row)}
|
||||
imageUrls={getAcceptanceImageUrls(row)}
|
||||
size={46}
|
||||
/>
|
||||
<Typography.Text type="secondary">
|
||||
提交时间:{formatDateTime(getAcceptanceSubmittedAt(row))}
|
||||
</Typography.Text>
|
||||
{row.acceptance?.note ? (
|
||||
<Typography.Text ellipsis>{row.acceptance.note}</Typography.Text>
|
||||
) : (
|
||||
<Typography.Text type="secondary">暂无验收说明</Typography.Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '问题备注',
|
||||
minWidth: 180,
|
||||
render: (_, row) => (
|
||||
<Typography.Text ellipsis>
|
||||
{String(row.problemNote || '').trim() || '-'}
|
||||
</Typography.Text>
|
||||
),
|
||||
minWidth: 200,
|
||||
render: (_, row) => {
|
||||
const submittedAt = getAcceptanceSubmittedAt(row)
|
||||
const hasAcceptance =
|
||||
getAcceptanceFiles(row).length > 0 || getAcceptanceImageUrls(row).length > 0
|
||||
if (!hasAcceptance && !submittedAt) {
|
||||
return <Typography.Text type="secondary">未提交</Typography.Text>
|
||||
}
|
||||
return (
|
||||
<div className="cell-stack">
|
||||
<ImagePreviewList
|
||||
files={getAcceptanceFiles(row)}
|
||||
imageUrls={getAcceptanceImageUrls(row)}
|
||||
size={40}
|
||||
/>
|
||||
<Typography.Text type="secondary">
|
||||
提交时间:{formatDateTime(submittedAt)}
|
||||
</Typography.Text>
|
||||
{row.acceptance?.note ? (
|
||||
<Typography.Text type="secondary" ellipsis>
|
||||
{row.acceptance.note}
|
||||
</Typography.Text>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: 280,
|
||||
width: 260,
|
||||
render: (_, row) => (
|
||||
<Space wrap>
|
||||
<Button icon={<EyeOutlined />} onClick={() => setDetailOrder(row)}>
|
||||
@@ -287,10 +260,7 @@ export default function WorkerOrdersPage() {
|
||||
</Button>
|
||||
) : null}
|
||||
{canCancelOrder(row) ? (
|
||||
<Button
|
||||
danger
|
||||
onClick={() => openCancelModal(row)}
|
||||
>
|
||||
<Button danger onClick={() => openCancelModal(row)}>
|
||||
取消接单
|
||||
</Button>
|
||||
) : null}
|
||||
@@ -312,73 +282,56 @@ export default function WorkerOrdersPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Row gutter={[16, 16]}>
|
||||
{STATUS_SUMMARY_ITEMS.map((item) => (
|
||||
<Col key={item.key} xs={24} sm={12} xl={8} xxl={4}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title={item.label}
|
||||
value={Number(overviewQuery.data?.[item.key] || 0)}
|
||||
suffix="单"
|
||||
loading={overviewQuery.isLoading}
|
||||
/>
|
||||
<Typography.Text type="secondary">{item.note}</Typography.Text>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
|
||||
<Card bordered={false}>
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Space direction="vertical" size={12} style={{ width: '100%' }}>
|
||||
<Space wrap size={12}>
|
||||
<Space.Compact style={{ width: '100%', maxWidth: 520 }}>
|
||||
<Input
|
||||
allowClear
|
||||
value={keywordInput}
|
||||
placeholder="搜索工单号 / 订单号 / 商品名"
|
||||
prefix={<SearchOutlined />}
|
||||
onChange={(event) => {
|
||||
const nextValue = event.target.value
|
||||
setKeywordInput(nextValue)
|
||||
if (!nextValue.trim()) {
|
||||
setKeyword('')
|
||||
setPage(1)
|
||||
}
|
||||
}}
|
||||
onPressEnter={applyKeywordSearch}
|
||||
/>
|
||||
<Button
|
||||
icon={<SearchOutlined />}
|
||||
loading={ordersQuery.isFetching}
|
||||
onClick={applyKeywordSearch}
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
<Typography.Text type="secondary">
|
||||
当前筛选:
|
||||
{STATUS_OPTIONS.find((item) => item.value === status)?.label || '全部订单'}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
<Tabs
|
||||
activeKey={status || 'all'}
|
||||
items={STATUS_OPTIONS.map((item) => {
|
||||
const countKey = item.value || 'all'
|
||||
const count = Number(overviewQuery.data?.[countKey] || 0)
|
||||
return {
|
||||
key: item.value || 'all',
|
||||
label: (
|
||||
<span>
|
||||
{item.label}
|
||||
{count > 0 ? (
|
||||
<span className="worker-order-tab-count">{count}</span>
|
||||
) : null}
|
||||
</span>
|
||||
),
|
||||
}
|
||||
})}
|
||||
onChange={(nextKey) => {
|
||||
const nextStatus = nextKey === 'all' ? '' : nextKey
|
||||
setStatus(nextStatus)
|
||||
setPage(1)
|
||||
}}
|
||||
/>
|
||||
|
||||
<Segmented
|
||||
block
|
||||
value={status || 'all'}
|
||||
options={STATUS_OPTIONS.map((item) => {
|
||||
const countKey = item.value || 'all'
|
||||
return {
|
||||
value: item.value || 'all',
|
||||
label: `${item.label} (${Number(overviewQuery.data?.[countKey] || 0)})`,
|
||||
<Space.Compact style={{ width: '100%', maxWidth: 460 }}>
|
||||
<Input
|
||||
allowClear
|
||||
value={keywordInput}
|
||||
placeholder="搜索工单号 / 订单号 / 商品名"
|
||||
prefix={<SearchOutlined />}
|
||||
onChange={(event) => {
|
||||
const nextValue = event.target.value
|
||||
setKeywordInput(nextValue)
|
||||
if (!nextValue.trim()) {
|
||||
setKeyword('')
|
||||
setPage(1)
|
||||
}
|
||||
})}
|
||||
onChange={(value) => {
|
||||
const nextStatus = String(value) === 'all' ? '' : String(value)
|
||||
setStatus(nextStatus)
|
||||
setPage(1)
|
||||
}}
|
||||
onPressEnter={applyKeywordSearch}
|
||||
/>
|
||||
</Space>
|
||||
<Button
|
||||
icon={<SearchOutlined />}
|
||||
loading={ordersQuery.isFetching}
|
||||
onClick={applyKeywordSearch}
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
|
||||
<Table<WorkOrder>
|
||||
rowKey="workOrderId"
|
||||
@@ -417,7 +370,7 @@ export default function WorkerOrdersPage() {
|
||||
setPageSize(nextPageSize)
|
||||
},
|
||||
}}
|
||||
scroll={{ x: 1160 }}
|
||||
scroll={{ x: 1060 }}
|
||||
/>
|
||||
</Space>
|
||||
</Card>
|
||||
@@ -762,13 +715,3 @@ function resolveStatusColor(status: string) {
|
||||
if (status === 'open') return 'red'
|
||||
return 'blue'
|
||||
}
|
||||
|
||||
function formatSharingShareStatus(status: string) {
|
||||
const labels: Record<string, string> = {
|
||||
joined: '已参与',
|
||||
submitted: '已提交验收',
|
||||
accepted: '已验收',
|
||||
cancelled: '已取消',
|
||||
}
|
||||
return labels[status] || status
|
||||
}
|
||||
|
||||
@@ -2,11 +2,9 @@ import {
|
||||
BankOutlined,
|
||||
CopyOutlined,
|
||||
CustomerServiceOutlined,
|
||||
HistoryOutlined,
|
||||
LockOutlined,
|
||||
LogoutOutlined,
|
||||
ReloadOutlined,
|
||||
SafetyCertificateOutlined,
|
||||
WalletOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
@@ -16,7 +14,6 @@ import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
DatePicker,
|
||||
Descriptions,
|
||||
Empty,
|
||||
@@ -26,10 +23,8 @@ import {
|
||||
InputNumber,
|
||||
Modal,
|
||||
Progress,
|
||||
Row,
|
||||
Select,
|
||||
Space,
|
||||
Statistic,
|
||||
Table,
|
||||
Tabs,
|
||||
Tag,
|
||||
@@ -80,16 +75,6 @@ type PasswordFormValues = {
|
||||
confirmPassword?: string
|
||||
}
|
||||
|
||||
type MetricCardItem = {
|
||||
label: string
|
||||
value: number
|
||||
note: string
|
||||
prefix?: string
|
||||
suffix?: string
|
||||
precision?: number
|
||||
danger?: boolean
|
||||
}
|
||||
|
||||
export default function WorkerProfilePage() {
|
||||
const { message } = App.useApp()
|
||||
const navigate = useNavigate()
|
||||
@@ -510,23 +495,38 @@ export default function WorkerProfilePage() {
|
||||
</Space>
|
||||
</Card>
|
||||
|
||||
<Row gutter={[16, 16]}>
|
||||
{buildMetricCards(worker, summary).map((item) => (
|
||||
<Col key={item.label} xs={24} sm={12} xl={8}>
|
||||
<Card size="small">
|
||||
<Statistic
|
||||
title={item.label}
|
||||
value={item.value}
|
||||
prefix={item.prefix}
|
||||
suffix={item.suffix}
|
||||
precision={item.precision}
|
||||
valueStyle={item.danger ? { color: '#cf1322' } : undefined}
|
||||
/>
|
||||
<Typography.Text type="secondary">{item.note}</Typography.Text>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
<Card size="small" className="worker-profile-wallet-card">
|
||||
<div className="worker-profile-wallet-strip">
|
||||
<div className="worker-profile-wallet-item">
|
||||
<span className="worker-profile-wallet-label">可用余额</span>
|
||||
<strong className="worker-profile-wallet-value">
|
||||
{formatMoney(worker.wallet.availableAmount)}
|
||||
</strong>
|
||||
<small className="worker-profile-wallet-note">可用于抢单冻结或提现申请</small>
|
||||
</div>
|
||||
<div className="worker-profile-wallet-item">
|
||||
<span className="worker-profile-wallet-label">冻结押金</span>
|
||||
<strong className="worker-profile-wallet-value">
|
||||
{formatMoney(worker.wallet.frozenDepositAmount)}
|
||||
</strong>
|
||||
<small className="worker-profile-wallet-note">抢单后冻结,验收后进入待解冻</small>
|
||||
</div>
|
||||
<div className="worker-profile-wallet-item">
|
||||
<span className="worker-profile-wallet-label">待解冻押金</span>
|
||||
<strong className="worker-profile-wallet-value">
|
||||
{formatMoney(worker.wallet.pendingUnfreezeAmount)}
|
||||
</strong>
|
||||
<small className="worker-profile-wallet-note">验收后按配置天数解冻到账</small>
|
||||
</div>
|
||||
<div className="worker-profile-wallet-item">
|
||||
<span className="worker-profile-wallet-label">累计结算</span>
|
||||
<strong className="worker-profile-wallet-value">
|
||||
{formatMoney(worker.wallet.totalSettledAmount)}
|
||||
</strong>
|
||||
<small className="worker-profile-wallet-note">已结算入账的报酬合计</small>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card title="快捷操作" size="small">
|
||||
<Space wrap size={[12, 12]}>
|
||||
@@ -546,18 +546,6 @@ export default function WorkerProfilePage() {
|
||||
>
|
||||
提现申请
|
||||
</Button>
|
||||
<Button
|
||||
icon={<HistoryOutlined />}
|
||||
onClick={() => jumpToLedgerSection()}
|
||||
>
|
||||
查看资金流水
|
||||
</Button>
|
||||
<Button
|
||||
icon={<SafetyCertificateOutlined />}
|
||||
onClick={() => jumpToRequestSection('withdraw')}
|
||||
>
|
||||
查看提现记录
|
||||
</Button>
|
||||
<Button icon={<LockOutlined />} onClick={() => setPasswordOpen(true)}>
|
||||
修改密码
|
||||
</Button>
|
||||
@@ -617,6 +605,15 @@ export default function WorkerProfilePage() {
|
||||
<Descriptions.Item label="已累计完成">
|
||||
{summary?.acceptedOrderCount || 0} 单
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="超时订单">
|
||||
{summary?.timeoutOrderCount || 0} 单
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="累计充值">
|
||||
{formatMoney(worker.wallet.totalCreditedAmount)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="提现中金额">
|
||||
{formatMoney(summary?.pendingWithdrawAmount)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="免押额度">
|
||||
{formatMoney(worker.level?.permissions.depositFreeAmount || 0)}
|
||||
</Descriptions.Item>
|
||||
@@ -1055,66 +1052,6 @@ export default function WorkerProfilePage() {
|
||||
)
|
||||
}
|
||||
|
||||
function buildMetricCards(worker: WorkerUser, summary?: WorkerProfileSummary): MetricCardItem[] {
|
||||
return [
|
||||
{
|
||||
label: '账户余额',
|
||||
value: toYuan(worker.wallet.availableAmount),
|
||||
note: '可用于抢单冻结或提现申请',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '冻结押金',
|
||||
value: toYuan(worker.wallet.frozenDepositAmount),
|
||||
note: '抢单后冻结,验收通过后 3 天自动解冻',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '待解冻押金',
|
||||
value: toYuan(worker.wallet.pendingUnfreezeAmount),
|
||||
note: '验收通过后待 3 天解冻到账的押金',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '累计充值',
|
||||
value: toYuan(worker.wallet.totalCreditedAmount),
|
||||
note: '管理员已处理的累计充值金额',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '累计结算',
|
||||
value: toYuan(worker.wallet.totalSettledAmount),
|
||||
note: '已经结算入账的报酬金额',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '提现中金额',
|
||||
value: toYuan(summary?.pendingWithdrawAmount),
|
||||
note: '待管理员处理的提现申请金额',
|
||||
prefix: '¥',
|
||||
precision: 2,
|
||||
},
|
||||
{
|
||||
label: '累计成单',
|
||||
value: Number(summary?.acceptedOrderCount || 0),
|
||||
note: '已完成并验收通过的工单数量',
|
||||
suffix: '单',
|
||||
},
|
||||
{
|
||||
label: '超时订单',
|
||||
value: Number(summary?.timeoutOrderCount || 0),
|
||||
note: '因任务超时被系统判定失败的工单数量',
|
||||
suffix: '单',
|
||||
danger: Number(summary?.timeoutOrderCount || 0) > 0,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
function resolveAvailableForWithdraw(
|
||||
worker: WorkerUser | undefined,
|
||||
summary: WorkerProfileSummary | undefined,
|
||||
@@ -1137,10 +1074,6 @@ function formatMoney(value: number | undefined) {
|
||||
return `¥${((Number(value || 0) || 0) / 100).toFixed(2)}`
|
||||
}
|
||||
|
||||
function toYuan(value: number | undefined) {
|
||||
return Number(((Number(value || 0) || 0) / 100).toFixed(2))
|
||||
}
|
||||
|
||||
function formatWorkerStatus(status: string) {
|
||||
if (status === 'active') return '已审核'
|
||||
if (status === 'pending_review') return '待审核'
|
||||
|
||||
@@ -1685,6 +1685,91 @@ select {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.worker-order-summary-card {
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.worker-order-summary-card.active {
|
||||
border-color: #1677ff;
|
||||
box-shadow: 0 0 0 1px #1677ff inset;
|
||||
}
|
||||
|
||||
.worker-order-summary-card .ant-statistic-title {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.worker-order-tab-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
padding: 0 5px;
|
||||
margin-left: 6px;
|
||||
border-radius: 9px;
|
||||
background: #f0f0f0;
|
||||
color: #595959;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.worker-order-tabs .ant-tabs-nav {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-card .ant-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-item {
|
||||
min-width: 0;
|
||||
padding: 14px 16px;
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-item + .worker-profile-wallet-item {
|
||||
border-left: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-label {
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-value {
|
||||
color: #0f172a;
|
||||
font-size: 20px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.worker-profile-wallet-note {
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.worker-profile-wallet-strip {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
.worker-profile-wallet-item:nth-child(3) {
|
||||
border-left: 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
.worker-profile-wallet-item:nth-child(4) {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.worker-hall-head-copy {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
|
||||
Reference in New Issue
Block a user