优化我的界面

This commit is contained in:
yml2213
2026-08-16 10:43:22 +08:00
parent 10ae3d01ee
commit 005b159215
2 changed files with 1100 additions and 364 deletions
@@ -176,19 +176,6 @@ export default function WorkerProfilePage() {
}
}
function jumpToLedgerSection(nextLedgerType = '') {
setLedgerType(nextLedgerType)
setLedgerPage(1)
setActiveTab('ledger')
}
function jumpToRequestSection(nextRequestType = '', nextStatus = '') {
setRequestType(nextRequestType)
setRequestStatus(nextStatus)
setRequestPage(1)
setActiveTab('requests')
}
function openRechargeModal() {
if (!canUseFinanceActions) {
message.warning('当前账号尚未通过审核,暂时不能发起充值申请')
@@ -226,7 +213,9 @@ export default function WorkerProfilePage() {
setRechargeOpen(false)
rechargeForm.resetFields()
await refreshAll()
jumpToRequestSection('recharge')
setRequestType('recharge')
setRequestPage(1)
setActiveTab('requests')
} catch (error) {
message.error(error instanceof Error ? error.message : '提交充值申请失败')
} finally {
@@ -248,7 +237,9 @@ export default function WorkerProfilePage() {
setWithdrawOpen(false)
withdrawForm.resetFields()
await refreshAll()
jumpToRequestSection('withdraw')
setRequestType('withdraw')
setRequestPage(1)
setActiveTab('requests')
} catch (error) {
message.error(error instanceof Error ? error.message : '提交提现申请失败')
} finally {
@@ -414,6 +405,488 @@ export default function WorkerProfilePage() {
}
return (
<>
{isMobile ? (
<div className="worker-profile-mobile-page">
{!worker && !profileQuery.isLoading ? <Empty description="暂无打手信息" /> : null}
{worker ? (
<>
{/* 沉浸式顶部个人卡片 */}
<div className="worker-profile-mobile-hero">
<div className="worker-profile-mobile-user-row">
<Avatar
size={52}
className="worker-profile-mobile-avatar"
>
{resolveWorkerInitial(worker)}
</Avatar>
<div className="worker-profile-mobile-user-info">
<div className="worker-profile-mobile-name-row">
<strong className="worker-profile-mobile-name">
{worker.displayName || worker.username}
</strong>
</div>
<div className="worker-profile-mobile-tags-row">
<span className="worker-profile-mobile-vip-badge">
{worker.level?.name || '未分级'}
</span>
<Tag color={resolveWorkerStatusColor(worker.status)} className="worker-profile-mobile-tag">
{formatWorkerStatus(worker.status)}
</Tag>
<Tag className="worker-profile-mobile-tag">
{worker.workerType === 'internal' ? '内部打手' : '外部打手'}
</Tag>
</div>
<div className="worker-profile-mobile-account-text">
: {worker.username} {worker.phone ? `· ${worker.phone}` : ''}
</div>
</div>
<Button
type="text"
shape="circle"
icon={<ReloadOutlined />}
className="worker-profile-mobile-refresh-btn"
loading={profileQuery.isFetching || ledgersQuery.isFetching || requestsQuery.isFetching}
onClick={() => refreshAll()}
/>
</div>
{/* 邀请码与等级进度 */}
<div className="worker-profile-mobile-hero-bottom">
<div className="worker-profile-mobile-invite-bar">
<span className="worker-profile-mobile-invite-label">:</span>
<strong className="worker-profile-mobile-invite-code">{worker.inviteCode || '-'}</strong>
{worker.inviteCode ? (
<button
type="button"
className="worker-profile-mobile-copy-btn"
onClick={copyInviteCode}
>
<CopyOutlined />
</button>
) : null}
</div>
{levelProgress && levelProgress.nextThreshold !== null ? (
<div className="worker-profile-mobile-level-box">
<div className="worker-profile-mobile-level-text">
{summary?.acceptedOrderCount || 0} · {Math.max(0, levelProgress.nextThreshold - (summary?.acceptedOrderCount || 0))}
</div>
<Progress
percent={levelProgress.progressPercent}
size="small"
strokeColor={{ '0%': '#f97316', '100%': '#fbbf24' }}
showInfo={false}
/>
</div>
) : (
<div className="worker-profile-mobile-level-text">
{summary?.acceptedOrderCount || 0} ·
</div>
)}
</div>
</div>
{!canUseFinanceActions ? (
<Alert
showIcon
type="warning"
message="当前账号尚未通过审核,充值申请、提现申请和接单功能暂不可用。"
/>
) : null}
{/* 资产卡片 */}
<div className="worker-profile-mobile-wallet-card">
<div className="worker-profile-mobile-wallet-top">
<div className="worker-profile-mobile-wallet-main">
<span className="worker-profile-mobile-wallet-title"></span>
<strong className="worker-profile-mobile-wallet-amount">
{formatMoney(worker.wallet.availableAmount)}
</strong>
</div>
<div className="worker-profile-mobile-wallet-actions">
<Button
type="primary"
size="middle"
icon={<WalletOutlined />}
disabled={!canUseFinanceActions}
className="worker-profile-mobile-recharge-btn"
onClick={openRechargeModal}
>
</Button>
<Button
size="middle"
icon={<BankOutlined />}
disabled={!canUseFinanceActions}
className="worker-profile-mobile-withdraw-btn"
onClick={openWithdrawModal}
>
</Button>
</div>
</div>
<div className="worker-profile-mobile-wallet-grid">
<div className="worker-profile-mobile-wallet-col">
<span className="worker-profile-mobile-sub-label"></span>
<strong className="worker-profile-mobile-sub-val">
{formatMoney(worker.wallet.frozenDepositAmount)}
</strong>
</div>
<div className="worker-profile-mobile-wallet-col">
<span className="worker-profile-mobile-sub-label"></span>
<strong className="worker-profile-mobile-sub-val">
{formatMoney(worker.wallet.pendingUnfreezeAmount)}
</strong>
</div>
<div className="worker-profile-mobile-wallet-col">
<span className="worker-profile-mobile-sub-label"></span>
<strong className="worker-profile-mobile-sub-val">
{formatMoney(worker.wallet.totalSettledAmount)}
</strong>
</div>
</div>
</div>
{/* 快捷操作宫格 */}
<div className="worker-profile-mobile-tools-card">
<button
type="button"
className="worker-profile-mobile-tool-item"
onClick={() => setPasswordOpen(true)}
>
<div className="worker-profile-mobile-tool-icon" style={{ background: '#eff6ff', color: '#3b82f6' }}>
<LockOutlined />
</div>
<span></span>
</button>
<button
type="button"
className="worker-profile-mobile-tool-item"
onClick={() => setContactOpen(true)}
>
<div className="worker-profile-mobile-tool-icon" style={{ background: '#f0fdf4', color: '#16a34a' }}>
<CustomerServiceOutlined />
</div>
<span></span>
</button>
<button
type="button"
className="worker-profile-mobile-tool-item"
disabled={!worker.inviteCode}
onClick={copyInviteCode}
>
<div className="worker-profile-mobile-tool-icon" style={{ background: '#fef3c7', color: '#d97706' }}>
<CopyOutlined />
</div>
<span></span>
</button>
<button
type="button"
className="worker-profile-mobile-tool-item"
onClick={submitLogout}
>
<div className="worker-profile-mobile-tool-icon" style={{ background: '#fef2f2', color: '#ef4444' }}>
<LogoutOutlined />
</div>
<span>退</span>
</button>
</div>
{/* 记录与明细分段滑动页 */}
<div className="worker-profile-mobile-sections-card">
<div className="worker-profile-mobile-tab-nav">
<button
type="button"
className={`worker-profile-mobile-tab-btn ${activeTab === 'ledger' ? 'active' : ''}`}
onClick={() => setActiveTab('ledger')}
>
</button>
<button
type="button"
className={`worker-profile-mobile-tab-btn ${activeTab === 'requests' ? 'active' : ''}`}
onClick={() => setActiveTab('requests')}
>
</button>
<button
type="button"
className={`worker-profile-mobile-tab-btn ${activeTab === 'account' ? 'active' : ''}`}
onClick={() => setActiveTab('account')}
>
</button>
</div>
<div className="worker-profile-mobile-tab-body">
{activeTab === 'ledger' && (
<div className="worker-profile-mobile-tab-pane">
<div className="worker-profile-mobile-filter-row">
<Select
size="small"
value={ledgerType}
style={{ width: 140 }}
options={[
{ value: '', label: '全部流水' },
{ value: 'manual_credit', label: '人工充值' },
{ value: 'withdraw_paid', label: '提现打款' },
{ value: 'deposit_freeze', label: '冻结押金' },
{ value: 'deposit_release', label: '释放押金' },
{ value: 'deposit_pending_unfreeze', label: '押金待解冻' },
{ value: 'deposit_unfreeze', label: '押金已解冻' },
{ value: 'deposit_deduction', label: '扣除押金' },
{ value: 'reward_settlement', label: '结算报酬' },
]}
onChange={(nextType) => {
setLedgerType(nextType)
setLedgerPage(1)
}}
/>
<Button
size="small"
icon={<ReloadOutlined />}
loading={ledgersQuery.isFetching}
onClick={() => ledgersQuery.refetch()}
>
</Button>
</div>
<div className="worker-profile-mobile-records">
{ledgersQuery.isLoading ? (
<div className="worker-hall-loading"><Spin size="large" /></div>
) : (ledgersQuery.data?.data.items || []).length === 0 ? (
<Empty description="暂无钱包流水" />
) : (
(ledgersQuery.data?.data.items || []).map((row) => (
<div key={row.ledgerId} className="worker-profile-record-card">
<div className="worker-profile-record-row-head">
<Tag color={resolveLedgerTagColor(row.ledgerType)}>
{formatLedgerType(row.ledgerType)}
</Tag>
<strong
className={
row.amount >= 0
? 'worker-amount-positive'
: 'worker-amount-negative'
}
style={{ fontSize: 16 }}
>
{row.amount >= 0 ? '+' : ''}
{formatMoney(row.amount)}
</strong>
</div>
<div className="worker-profile-record-row-meta">
<span>: {formatMoney(row.balanceAfter)}</span>
<span>: {formatMoney(row.frozenAfter)}</span>
</div>
{row.note ? (
<div className="worker-profile-record-note">: {row.note}</div>
) : null}
{row.relatedWorkOrderId ? (
<div className="worker-profile-record-sub">
#{row.relatedWorkOrderId}
</div>
) : null}
<div className="worker-profile-record-time">
{formatDateTime(String(row.createdAt || ''))}
</div>
</div>
))
)}
{(ledgersQuery.data?.data.pagination.total || 0) > 0 ? (
<div className="worker-orders-mobile-pagination">
<Pagination
current={ledgersQuery.data?.data.pagination.page || ledgerPage}
pageSize={ledgersQuery.data?.data.pagination.pageSize || ledgerPageSize}
total={ledgersQuery.data?.data.pagination.total || 0}
simple
onChange={(nextPage: number, nextPageSize: number) => {
setLedgerPage(nextPage)
setLedgerPageSize(nextPageSize)
}}
/>
</div>
) : null}
</div>
</div>
)}
{activeTab === 'requests' && (
<div className="worker-profile-mobile-tab-pane">
<div className="worker-profile-mobile-filter-row">
<Space size={6} wrap>
<Select
size="small"
value={requestType}
style={{ width: 110 }}
options={[
{ value: '', label: '全部类型' },
{ value: 'recharge', label: '充值申请' },
{ value: 'withdraw', label: '提现申请' },
]}
onChange={(nextType) => {
setRequestType(nextType)
setRequestPage(1)
}}
/>
<Select
size="small"
value={requestStatus}
style={{ width: 110 }}
options={[
{ value: '', label: '全部状态' },
{ value: 'pending', label: '待处理' },
{ value: 'approved', label: '已通过' },
{ value: 'rejected', label: '已驳回' },
]}
onChange={(nextStatus) => {
setRequestStatus(nextStatus)
setRequestPage(1)
}}
/>
<Button
size="small"
icon={<ReloadOutlined />}
loading={requestsQuery.isFetching}
onClick={() => requestsQuery.refetch()}
/>
</Space>
</div>
<div className="worker-profile-mobile-records">
{requestsQuery.isLoading ? (
<div className="worker-hall-loading"><Spin size="large" /></div>
) : (requestsQuery.data?.data.items || []).length === 0 ? (
<Empty description="暂无申请记录" />
) : (
(requestsQuery.data?.data.items || []).map((row) => (
<div key={row.requestId} className="worker-profile-record-card">
<div className="worker-profile-record-row-head">
<Space size={4}>
<Tag color={row.requestType === 'withdraw' ? 'green' : 'blue'}>
{formatRequestType(row.requestType)}
</Tag>
<Tag color={resolveRequestStatusColor(row.status)}>
{formatRequestStatus(row.status)}
</Tag>
</Space>
<strong style={{ fontSize: 16 }}>{formatMoney(row.amount)}</strong>
</div>
{row.requestType === 'withdraw' ? (
<div className="worker-profile-record-row-meta">
: {formatWithdrawChannel(row.accountChannel)} / {row.accountName || '-'} ({maskAccountNo(row.accountNo)})
</div>
) : (
<div className="worker-profile-record-row-meta">
{renderRechargeRequestSummary(row)}
</div>
)}
{row.note ? (
<div className="worker-profile-record-note">: {row.note}</div>
) : null}
{row.reviewedNote ? (
<div className="worker-profile-record-note" style={{ color: '#d97706' }}>
: {row.reviewedNote}
</div>
) : null}
<div className="worker-profile-record-time">
{formatDateTime(String(row.createdAt || ''))}
</div>
</div>
))
)}
{(requestsQuery.data?.data.pagination.total || 0) > 0 ? (
<div className="worker-orders-mobile-pagination">
<Pagination
current={requestsQuery.data?.data.pagination.page || requestPage}
pageSize={requestsQuery.data?.data.pagination.pageSize || requestPageSize}
total={requestsQuery.data?.data.pagination.total || 0}
simple
onChange={(nextPage: number, nextPageSize: number) => {
setRequestPage(nextPage)
setRequestPageSize(nextPageSize)
}}
/>
</div>
) : null}
</div>
</div>
)}
{activeTab === 'account' && (
<div className="worker-profile-mobile-tab-pane">
<div className="worker-profile-mobile-account-list">
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{worker.username}</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{worker.displayName || '-'}</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{worker.phone || '-'}</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">
<Tag color={resolveWorkerStatusColor(worker.status)}>
{formatWorkerStatus(worker.status)}
</Tag>
</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{worker.level?.name || '-'}</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">
{formatMoney(worker.level?.permissions.depositFreeAmount || 0)}
</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">
{worker.level?.permissions.maxActiveOrders || 0}
</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">
{worker.inviter ? worker.inviter.displayName || worker.inviter.username : '-'}
</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{summary?.acceptedOrderCount || 0} </span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">
{formatMoney(worker.wallet.totalCreditedAmount)}
</span>
</div>
<div className="worker-profile-mobile-account-item">
<span className="worker-profile-mobile-acc-label"></span>
<span className="worker-profile-mobile-acc-val">{formatDateTime(worker.createdAt)}</span>
</div>
</div>
</div>
)}
</div>
</div>
</>
) : null}
</div>
) : (
<section className="page-stack">
<div className="worker-page-head">
<Typography.Title level={3}></Typography.Title>
@@ -677,65 +1150,6 @@ export default function WorkerProfilePage() {
</Space>
}
>
{isMobile ? (
<div className="worker-profile-mobile-records">
{ledgersQuery.isLoading ? (
<div className="worker-hall-loading"><Spin size="large" /></div>
) : (ledgersQuery.data?.data.items || []).length === 0 ? (
<Empty description="暂无钱包流水" />
) : (
(ledgersQuery.data?.data.items || []).map((row) => (
<div key={row.ledgerId} className="worker-profile-record-card">
<div className="worker-profile-record-row-head">
<Tag color={resolveLedgerTagColor(row.ledgerType)}>
{formatLedgerType(row.ledgerType)}
</Tag>
<strong
className={
row.amount >= 0
? 'worker-amount-positive'
: 'worker-amount-negative'
}
style={{ fontSize: 16 }}
>
{row.amount >= 0 ? '+' : ''}
{formatMoney(row.amount)}
</strong>
</div>
<div className="worker-profile-record-row-meta">
<span>: {formatMoney(row.balanceAfter)}</span>
<span>: {formatMoney(row.frozenAfter)}</span>
</div>
{row.note ? (
<div className="worker-profile-record-note">{row.note}</div>
) : null}
{row.relatedWorkOrderId ? (
<div className="worker-profile-record-sub">
#{row.relatedWorkOrderId}
</div>
) : null}
<div className="worker-profile-record-time">
{formatDateTime(String(row.createdAt || ''))}
</div>
</div>
))
)}
{(ledgersQuery.data?.data.pagination.total || 0) > 0 ? (
<div className="worker-orders-mobile-pagination">
<Pagination
current={ledgersQuery.data?.data.pagination.page || ledgerPage}
pageSize={ledgersQuery.data?.data.pagination.pageSize || ledgerPageSize}
total={ledgersQuery.data?.data.pagination.total || 0}
simple
onChange={(nextPage: number, nextPageSize: number) => {
setLedgerPage(nextPage)
setLedgerPageSize(nextPageSize)
}}
/>
</div>
) : null}
</div>
) : (
<Table<WorkerWalletLedger>
rowKey="ledgerId"
size="small"
@@ -746,7 +1160,7 @@ export default function WorkerProfilePage() {
emptyText: ledgersQuery.error
? ledgersQuery.error instanceof Error
? ledgersQuery.error.message
: '读取钱包流水失败'
: '读取资金流水失败'
: '暂无钱包流水',
}}
pagination={{
@@ -761,9 +1175,8 @@ export default function WorkerProfilePage() {
setLedgerPageSize(nextPageSize)
},
}}
scroll={{ x: 920 }}
scroll={{ x: 980 }}
/>
)}
</Card>
),
},
@@ -795,8 +1208,7 @@ export default function WorkerProfilePage() {
{ value: '', label: '全部状态' },
{ value: 'pending', label: '待处理' },
{ value: 'approved', label: '已通过' },
{ value: 'rejected', label: '已拒绝' },
{ value: 'cancelled', label: '已取消' },
{ value: 'rejected', label: '已驳回' },
]}
onChange={(nextStatus) => {
setRequestStatus(nextStatus)
@@ -813,65 +1225,6 @@ export default function WorkerProfilePage() {
</Space>
}
>
{isMobile ? (
<div className="worker-profile-mobile-records">
{requestsQuery.isLoading ? (
<div className="worker-hall-loading"><Spin size="large" /></div>
) : (requestsQuery.data?.data.items || []).length === 0 ? (
<Empty description="暂无申请记录" />
) : (
(requestsQuery.data?.data.items || []).map((row) => (
<div key={row.requestId} className="worker-profile-record-card">
<div className="worker-profile-record-row-head">
<Space size={4}>
<Tag color={row.requestType === 'withdraw' ? 'green' : 'blue'}>
{formatRequestType(row.requestType)}
</Tag>
<Tag color={resolveRequestStatusColor(row.status)}>
{formatRequestStatus(row.status)}
</Tag>
</Space>
<strong style={{ fontSize: 16 }}>{formatMoney(row.amount)}</strong>
</div>
{row.requestType === 'withdraw' ? (
<div className="worker-profile-record-row-meta">
: {formatWithdrawChannel(row.accountChannel)} / {row.accountName || '-'} ({maskAccountNo(row.accountNo)})
</div>
) : (
<div className="worker-profile-record-row-meta">
{renderRechargeRequestSummary(row)}
</div>
)}
{row.note ? (
<div className="worker-profile-record-note">: {row.note}</div>
) : null}
{row.reviewedNote ? (
<div className="worker-profile-record-note" style={{ color: '#d97706' }}>
: {row.reviewedNote}
</div>
) : null}
<div className="worker-profile-record-time">
{formatDateTime(String(row.createdAt || ''))}
</div>
</div>
))
)}
{(requestsQuery.data?.data.pagination.total || 0) > 0 ? (
<div className="worker-orders-mobile-pagination">
<Pagination
current={requestsQuery.data?.data.pagination.page || requestPage}
pageSize={requestsQuery.data?.data.pagination.pageSize || requestPageSize}
total={requestsQuery.data?.data.pagination.total || 0}
simple
onChange={(nextPage: number, nextPageSize: number) => {
setRequestPage(nextPage)
setRequestPageSize(nextPageSize)
}}
/>
</div>
) : null}
</div>
) : (
<Table<WorkerFinanceRequest>
rowKey="requestId"
size="small"
@@ -899,7 +1252,6 @@ export default function WorkerProfilePage() {
}}
scroll={{ x: 980 }}
/>
)}
</Card>
),
},
@@ -907,6 +1259,8 @@ export default function WorkerProfilePage() {
/>
</Space>
) : null}
</section>
)}
<Modal
title="充值申请"
@@ -1195,7 +1549,7 @@ export default function WorkerProfilePage() {
</Typography.Paragraph>
</Space>
</Modal>
</section>
</>
)
}
+385 -3
View File
@@ -3195,7 +3195,7 @@ body {
.worker-profile-mobile-records {
display: flex;
flex-direction: column;
gap: 10px;
gap: 8px;
width: 100%;
}
@@ -3203,10 +3203,10 @@ body {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 12px;
padding: 10px 12px;
display: flex;
flex-direction: column;
gap: 6px;
gap: 4px;
font-size: 12px;
}
@@ -3243,4 +3243,386 @@ body {
margin-top: 2px;
}
/* ==========================================================================
移动端 个人中心 (Worker Profile Mobile Page)
========================================================================== */
.worker-profile-mobile-page {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
box-sizing: border-box;
}
/* 顶部沉浸式个人卡片(明亮温润风格) */
.worker-profile-mobile-hero {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 14px;
color: #0f172a;
box-shadow: 0 1px 6px rgba(15, 23, 42, 0.04);
display: flex;
flex-direction: column;
gap: 10px;
}
.worker-profile-mobile-user-row {
display: flex;
align-items: center;
gap: 12px;
position: relative;
}
.worker-profile-mobile-avatar {
background: linear-gradient(135deg, #ff8c00, #ea580c);
color: #ffffff;
font-weight: 700;
font-size: 20px;
box-shadow: 0 2px 8px rgba(234, 88, 12, 0.25);
flex-shrink: 0;
}
.worker-profile-mobile-user-info {
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
flex: 1;
}
.worker-profile-mobile-name-row {
display: flex;
align-items: center;
gap: 6px;
}
.worker-profile-mobile-name {
font-size: 17px;
font-weight: 700;
color: #0f172a;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.worker-profile-mobile-tags-row {
display: flex;
align-items: center;
gap: 4px;
flex-wrap: wrap;
}
.worker-profile-mobile-vip-badge {
display: inline-flex;
align-items: center;
padding: 1px 6px;
background: linear-gradient(135deg, #fef08a, #facc15);
color: #854d0e;
border-radius: 4px;
font-size: 10px;
font-weight: 700;
line-height: 14px;
}
.worker-profile-mobile-tag {
margin: 0;
font-size: 10px;
padding: 0 4px;
line-height: 16px;
}
.worker-profile-mobile-account-text {
font-size: 11px;
color: #64748b;
}
.worker-profile-mobile-refresh-btn {
color: #64748b;
background: #f1f5f9;
border: none;
width: 28px;
height: 28px;
display: grid;
place-items: center;
flex-shrink: 0;
}
.worker-profile-mobile-refresh-btn:hover,
.worker-profile-mobile-refresh-btn:focus {
color: var(--theme-primary);
background: #e2e8f0;
}
.worker-profile-mobile-hero-bottom {
border-top: 1px solid #f1f5f9;
padding-top: 8px;
display: flex;
flex-direction: column;
gap: 6px;
}
.worker-profile-mobile-invite-bar {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
background: #fff7ed;
border: 1px solid #ffedd5;
border-radius: 6px;
padding: 4px 8px;
}
.worker-profile-mobile-invite-label {
color: #9a3412;
font-size: 11px;
}
.worker-profile-mobile-invite-code {
color: #ea580c;
letter-spacing: 0.5px;
font-weight: 700;
font-size: 13px;
}
.worker-profile-mobile-copy-btn {
border: 1px solid #fdba74;
background: #ffffff;
color: #ea580c;
border-radius: 4px;
padding: 1px 6px;
font-size: 11px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 2px;
margin-left: auto;
}
.worker-profile-mobile-level-box {
display: flex;
flex-direction: column;
gap: 2px;
}
.worker-profile-mobile-level-text {
font-size: 11px;
color: #64748b;
}
/* 资产钱包卡片 */
.worker-profile-mobile-wallet-card {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 14px;
box-shadow: 0 1px 6px rgba(15, 23, 42, 0.04);
display: flex;
flex-direction: column;
gap: 12px;
}
.worker-profile-mobile-wallet-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.worker-profile-mobile-wallet-main {
display: flex;
flex-direction: column;
gap: 2px;
}
.worker-profile-mobile-wallet-title {
font-size: 11px;
color: #64748b;
}
.worker-profile-mobile-wallet-amount {
font-size: 24px;
font-weight: 800;
color: #ea580c;
line-height: 1;
}
.worker-profile-mobile-wallet-actions {
display: flex;
align-items: center;
gap: 8px;
}
.worker-profile-mobile-recharge-btn {
font-weight: 600;
}
.worker-profile-mobile-withdraw-btn {
font-weight: 600;
}
.worker-profile-mobile-wallet-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 4px;
border-top: 1px solid #f1f5f9;
padding-top: 10px;
text-align: center;
}
.worker-profile-mobile-wallet-col {
display: flex;
flex-direction: column;
gap: 2px;
padding: 0 4px;
}
.worker-profile-mobile-wallet-col + .worker-profile-mobile-wallet-col {
border-left: 1px solid #f1f5f9;
}
.worker-profile-mobile-sub-label {
font-size: 11px;
color: #64748b;
}
.worker-profile-mobile-sub-val {
font-size: 14px;
font-weight: 700;
color: #1e293b;
}
/* 快捷操作宫格 */
.worker-profile-mobile-tools-card {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 14px;
padding: 12px 8px;
box-shadow: 0 1px 6px rgba(15, 23, 42, 0.04);
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 4px;
}
.worker-profile-mobile-tool-item {
border: none;
background: transparent;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
cursor: pointer;
padding: 6px 2px;
border-radius: 8px;
transition: background 0.15s ease;
-webkit-tap-highlight-color: transparent;
}
.worker-profile-mobile-tool-item:active {
background: #f8fafc;
transform: scale(0.96);
}
.worker-profile-mobile-tool-icon {
width: 38px;
height: 38px;
border-radius: 10px;
display: grid;
place-items: center;
font-size: 18px;
}
.worker-profile-mobile-tool-item span {
font-size: 11px;
color: #334155;
font-weight: 500;
white-space: nowrap;
}
/* 记录与明细分段滑动卡片 */
.worker-profile-mobile-sections-card {
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 14px;
box-shadow: 0 1px 6px rgba(15, 23, 42, 0.04);
overflow: hidden;
display: flex;
flex-direction: column;
}
.worker-profile-mobile-tab-nav {
display: flex;
border-bottom: 1px solid #e2e8f0;
background: #f8fafc;
}
.worker-profile-mobile-tab-btn {
flex: 1;
border: none;
background: transparent;
padding: 10px 0;
font-size: 13px;
font-weight: 500;
color: #64748b;
cursor: pointer;
position: relative;
transition: all 0.15s ease;
}
.worker-profile-mobile-tab-btn.active {
color: var(--theme-primary);
font-weight: 700;
background: #ffffff;
}
.worker-profile-mobile-tab-btn.active::after {
content: '';
position: absolute;
bottom: 0;
left: 20%;
right: 20%;
height: 2px;
background: var(--theme-primary);
border-radius: 2px;
}
.worker-profile-mobile-tab-body {
padding: 12px;
}
.worker-profile-mobile-filter-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 10px;
}
/* 账号详情列表 */
.worker-profile-mobile-account-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.worker-profile-mobile-account-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 0;
border-bottom: 1px solid #f1f5f9;
font-size: 12px;
}
.worker-profile-mobile-acc-label {
color: #64748b;
}
.worker-profile-mobile-acc-val {
color: #0f172a;
font-weight: 500;
}