优化财务管理整个ui
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import { Document, DocumentChecked, Refresh, Search, View } from '@element-plus/icons-vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
|
||||
import {
|
||||
@@ -18,6 +18,7 @@ const details = ref<FinanceDetail[]>([])
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(20)
|
||||
const total = ref(0)
|
||||
|
||||
const filters = reactive({
|
||||
start_date: defaultStartDate(),
|
||||
end_date: defaultEndDate(),
|
||||
@@ -65,8 +66,8 @@ async function handlePageChange() {
|
||||
await loadDetails()
|
||||
}
|
||||
|
||||
function moneyCent(value: number) {
|
||||
return formatCentWithSymbol(value)
|
||||
function moneyCent(value: number | undefined | null) {
|
||||
return formatCentWithSymbol(value || 0)
|
||||
}
|
||||
|
||||
function financeStatusLabel(status: string) {
|
||||
@@ -80,7 +81,7 @@ function financeStatusLabel(status: string) {
|
||||
return map[status] || status
|
||||
}
|
||||
|
||||
function financeStatusType(status: string) {
|
||||
function financeStatusType(status: string): 'success' | 'danger' | 'warning' | 'info' {
|
||||
if (status === 'normal') return 'success'
|
||||
if (status === 'settlement_diff' || status === 'refund_failed') return 'danger'
|
||||
if (status === 'refund_pending' || status === 'offline_settlement_pending') return 'warning'
|
||||
@@ -113,12 +114,6 @@ function offlineSettlementStatusLabel(status: string) {
|
||||
return map[status] || status || '-'
|
||||
}
|
||||
|
||||
function shortDateTime(value?: string) {
|
||||
if (!value) return '-'
|
||||
const text = formatDateTime(value)
|
||||
return text.replace(/^\d{4}-/, '')
|
||||
}
|
||||
|
||||
function defaultStartDate() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() - 29)
|
||||
@@ -131,317 +126,600 @@ function defaultEndDate() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="page finance-details-page">
|
||||
<div class="page-header-row">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Finance Details</p>
|
||||
<h1>财务明细</h1>
|
||||
<p>按订单核对收款、退款、平台收入、号主应得与钱包入账/线下结算。</p>
|
||||
</div>
|
||||
<div class="toolbar-actions">
|
||||
<el-button @click="resetFilters">重置</el-button>
|
||||
<el-button type="primary" :icon="Search" :loading="loading" @click="loadDetails">
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form class="filter-panel finance-filter-panel" label-position="top">
|
||||
<el-form-item label="日期类型">
|
||||
<el-select v-model="filters.date_type" class="full-control">
|
||||
<el-option label="结算日期" value="settled" />
|
||||
<el-option label="线下打款日期" value="offline_settled" />
|
||||
<el-option label="下单日期" value="created" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker
|
||||
v-model="filters.start_date"
|
||||
class="full-control"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker
|
||||
v-model="filters.end_date"
|
||||
class="full-control"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单号">
|
||||
<el-input v-model="filters.order_no" clearable placeholder="按订单号筛选" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户 ID">
|
||||
<el-input v-model="filters.user_id" clearable placeholder="租客或号主 ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="订单状态">
|
||||
<el-select
|
||||
v-model="filters.order_status"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="待支付" value="pending_payment" />
|
||||
<el-option label="使用中" value="renting" />
|
||||
<el-option label="待结账" value="pending_checkout_confirm" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已关闭" value="closed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算状态">
|
||||
<el-select
|
||||
v-model="filters.settlement_status"
|
||||
clearable
|
||||
placeholder="全部结算"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="未结算" value="unsettled" />
|
||||
<el-option label="已结算" value="settled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算模式">
|
||||
<el-select
|
||||
v-model="filters.settlement_mode"
|
||||
clearable
|
||||
placeholder="全部模式"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="号主钱包" value="owner_wallet" />
|
||||
<el-option label="平台代管" value="platform_managed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="线下状态">
|
||||
<el-select
|
||||
v-model="filters.offline_settlement_status"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="待线下结算" value="pending" />
|
||||
<el-option label="已线下结算" value="settled" />
|
||||
<el-option label="无需线下结算" value="none" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" class="table-panel finance-details-table">
|
||||
<div class="finance-grid-header">
|
||||
<div>订单</div>
|
||||
<div>状态</div>
|
||||
<div>租客/号主</div>
|
||||
<div class="amount-cell">收款</div>
|
||||
<div class="amount-cell">已退</div>
|
||||
<div class="amount-cell">退中</div>
|
||||
<div class="amount-cell">净入</div>
|
||||
<div class="amount-cell">平台</div>
|
||||
<div class="amount-cell">应得</div>
|
||||
<div class="amount-cell">入账/线下</div>
|
||||
<div class="amount-cell">差异</div>
|
||||
</div>
|
||||
|
||||
<div v-if="details.length > 0" class="finance-grid-body">
|
||||
<div v-for="row in details" :key="row.order_id" class="finance-grid-row">
|
||||
<div class="order-cell">
|
||||
<RouterLink class="order-no" :to="adminPath(`orders/${row.order_id}`)">
|
||||
{{ row.order_no }}
|
||||
</RouterLink>
|
||||
<span class="cell-muted">结算 {{ shortDateTime(row.settled_at) }}</span>
|
||||
<div class="finance-page-container">
|
||||
<!-- 页面头部卡片 -->
|
||||
<header class="page-header-card">
|
||||
<div class="header-main">
|
||||
<div class="title-group">
|
||||
<div class="eyebrow-tag">
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>FINANCE DETAILS</span>
|
||||
</div>
|
||||
<h1 class="page-title">财务明细</h1>
|
||||
<p class="page-subtitle">
|
||||
按订单维度精细核对收款、退款、平台利润扣费、号主应得与实际入账差异。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="status-stack">
|
||||
<span>{{ orderStatusLabel(row.order_status) }}</span>
|
||||
<small
|
||||
>{{ settlementStatusLabel(row.settlement_status) }} ·
|
||||
{{ settlementModeLabel(row) }}</small
|
||||
>
|
||||
<small v-if="isPlatformManaged(row)">
|
||||
{{ offlineSettlementStatusLabel(row.offline_settlement_status) }}
|
||||
</small>
|
||||
<el-tag size="small" :type="financeStatusType(row.finance_status)">
|
||||
{{ financeStatusLabel(row.finance_status) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
|
||||
<div class="party-cell">
|
||||
<span>租 {{ row.renter_phone || row.renter_nickname || row.renter_id }}</span>
|
||||
<span>主 {{ row.owner_phone || row.owner_nickname || row.owner_id }}</span>
|
||||
</div>
|
||||
|
||||
<span class="amount-text amount-cell">{{ moneyCent(row.paid_amount_cent) }}</span>
|
||||
<span class="amount-text amount-cell muted-amount">
|
||||
{{ moneyCent(row.refunded_amount_cent) }}
|
||||
</span>
|
||||
<span class="amount-text amount-cell muted-amount">
|
||||
{{ moneyCent(row.refunding_amount_cent) }}
|
||||
</span>
|
||||
<span class="amount-text amount-cell">{{ moneyCent(row.channel_net_amount_cent) }}</span>
|
||||
<span class="amount-text amount-cell">{{
|
||||
moneyCent(row.checkout_platform_fee_cent)
|
||||
}}</span>
|
||||
<span class="amount-text amount-cell">{{
|
||||
moneyCent(row.checkout_owner_income_cent)
|
||||
}}</span>
|
||||
<span class="amount-text amount-cell">{{
|
||||
moneyCent(row.owner_effective_settlement_amount_cent)
|
||||
}}</span>
|
||||
<span
|
||||
class="amount-text amount-cell"
|
||||
:class="{
|
||||
'amount-danger':
|
||||
Math.abs(row.settlement_diff_amount_cent) >= SETTLEMENT_DIFF_THRESHOLD_CENT,
|
||||
}"
|
||||
>
|
||||
{{ moneyCent(row.settlement_diff_amount_cent) }}
|
||||
</span>
|
||||
<div class="toolbar-actions">
|
||||
<el-button :icon="Refresh" @click="resetFilters">重置</el-button>
|
||||
<el-button type="primary" :icon="Search" :loading="loading" @click="loadDetails">
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<el-empty v-else :image-size="80" description="暂无财务明细" />
|
||||
</div>
|
||||
<!-- 筛选面板卡片 -->
|
||||
<section class="section-card filter-card">
|
||||
<el-form class="filter-grid" label-position="top" @keyup.enter="loadDetails">
|
||||
<el-form-item label="日期类型">
|
||||
<el-select v-model="filters.date_type" class="full-control">
|
||||
<el-option label="结算日期" value="settled" />
|
||||
<el-option label="线下打款日期" value="offline_settled" />
|
||||
<el-option label="下单日期" value="created" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<AdminTablePagination
|
||||
v-if="total > 0"
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="currentPageSize"
|
||||
:total="total"
|
||||
:loading="loading"
|
||||
@page-change="handlePageChange"
|
||||
/>
|
||||
</section>
|
||||
<el-form-item label="开始日期">
|
||||
<el-date-picker
|
||||
v-model="filters.start_date"
|
||||
class="full-control"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
:clearable="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="结束日期">
|
||||
<el-date-picker
|
||||
v-model="filters.end_date"
|
||||
class="full-control"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
:clearable="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="订单号">
|
||||
<el-input v-model="filters.order_no" clearable placeholder="按订单号检索" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户 ID">
|
||||
<el-input v-model="filters.user_id" clearable placeholder="租客或号主 ID" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="订单状态">
|
||||
<el-select
|
||||
v-model="filters.order_status"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="待支付" value="pending_payment" />
|
||||
<el-option label="使用中" value="renting" />
|
||||
<el-option label="待结账" value="pending_checkout_confirm" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已关闭" value="closed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="结算状态">
|
||||
<el-select
|
||||
v-model="filters.settlement_status"
|
||||
clearable
|
||||
placeholder="全部结算"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="未结算" value="unsettled" />
|
||||
<el-option label="已结算" value="settled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="结算模式">
|
||||
<el-select
|
||||
v-model="filters.settlement_mode"
|
||||
clearable
|
||||
placeholder="全部模式"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="号主钱包" value="owner_wallet" />
|
||||
<el-option label="平台代管" value="platform_managed" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="线下状态">
|
||||
<el-select
|
||||
v-model="filters.offline_settlement_status"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
class="full-control"
|
||||
>
|
||||
<el-option label="待线下结算" value="pending" />
|
||||
<el-option label="已线下结算" value="settled" />
|
||||
<el-option label="无需线下结算" value="none" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</section>
|
||||
|
||||
<!-- 财务明细数据表格 -->
|
||||
<section class="section-card table-section-card">
|
||||
<div class="table-card-header">
|
||||
<div class="table-header-title">
|
||||
<el-icon class="header-icon"><DocumentChecked /></el-icon>
|
||||
<span>订单财务流水台账</span>
|
||||
</div>
|
||||
<span class="count-badge">共 {{ total }} 条订单明细</span>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
class="custom-enterprise-table"
|
||||
:data="details"
|
||||
stripe
|
||||
empty-text="暂无财务明细记录"
|
||||
>
|
||||
<!-- 订单标识 -->
|
||||
<el-table-column label="订单信息" min-width="190" fixed="left">
|
||||
<template #default="{ row }">
|
||||
<div class="order-cell">
|
||||
<RouterLink class="order-no-link" :to="adminPath(`orders/${row.order_id}`)">
|
||||
{{ row.order_no }}
|
||||
</RouterLink>
|
||||
<small class="time-sub">结算 {{ formatDateTime(row.settled_at) || '-' }}</small>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 状态复合列 -->
|
||||
<el-table-column label="订单与结算状态" min-width="170">
|
||||
<template #default="{ row }">
|
||||
<div class="status-stack">
|
||||
<div class="status-row">
|
||||
<span class="order-status-badge">{{ orderStatusLabel(row.order_status) }}</span>
|
||||
<el-tag size="small" :type="financeStatusType(row.finance_status)" effect="plain">
|
||||
{{ financeStatusLabel(row.finance_status) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<small class="settle-desc">
|
||||
{{ settlementStatusLabel(row.settlement_status) }} ·
|
||||
{{ settlementModeLabel(row) }}
|
||||
</small>
|
||||
<small v-if="isPlatformManaged(row)" class="offline-desc">
|
||||
{{ offlineSettlementStatusLabel(row.offline_settlement_status) }}
|
||||
</small>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 交易双方 -->
|
||||
<el-table-column label="交易双方" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<div class="parties-cell">
|
||||
<div class="party-line">
|
||||
<span class="role-badge renter">租</span>
|
||||
<span class="party-info">{{
|
||||
row.renter_phone || row.renter_nickname || `UID ${row.renter_id}`
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="party-line">
|
||||
<span class="role-badge owner">主</span>
|
||||
<span class="party-info">{{
|
||||
row.owner_phone || row.owner_nickname || `UID ${row.owner_id}`
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 收款 -->
|
||||
<el-table-column label="收款金额" min-width="120" align="right">
|
||||
<template #default="{ row }">
|
||||
<span class="amount-val flow-amount">{{ moneyCent(row.paid_amount_cent) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 退款情况 -->
|
||||
<el-table-column label="已退 / 退中" min-width="130" align="right">
|
||||
<template #default="{ row }">
|
||||
<div class="refund-stack">
|
||||
<span v-if="row.refunded_amount_cent > 0" class="refund-text">
|
||||
退 {{ moneyCent(row.refunded_amount_cent) }}
|
||||
</span>
|
||||
<span v-else class="zero-text">0.0</span>
|
||||
|
||||
<span v-if="row.refunding_amount_cent > 0" class="refunding-text">
|
||||
中 {{ moneyCent(row.refunding_amount_cent) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 渠道净流入 -->
|
||||
<el-table-column label="渠道净流入" min-width="125" align="right">
|
||||
<template #default="{ row }">
|
||||
<span class="amount-val net-amount">{{
|
||||
moneyCent(row.channel_net_amount_cent)
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 平台利润 -->
|
||||
<el-table-column label="平台收益" min-width="125" align="right">
|
||||
<template #default="{ row }">
|
||||
<strong class="amount-val profit-amount">
|
||||
{{ moneyCent(row.checkout_platform_fee_cent) }}
|
||||
</strong>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 号主应得 -->
|
||||
<el-table-column label="号主应得" min-width="125" align="right">
|
||||
<template #default="{ row }">
|
||||
<span class="amount-val">{{ moneyCent(row.checkout_owner_income_cent) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 实际入账 / 线下 -->
|
||||
<el-table-column label="实际结算" min-width="130" align="right">
|
||||
<template #default="{ row }">
|
||||
<span class="amount-val success-val">
|
||||
{{ moneyCent(row.owner_effective_settlement_amount_cent) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 结算差异 -->
|
||||
<el-table-column label="结算差异" min-width="120" align="right">
|
||||
<template #default="{ row }">
|
||||
<el-tag
|
||||
v-if="Math.abs(row.settlement_diff_amount_cent) >= SETTLEMENT_DIFF_THRESHOLD_CENT"
|
||||
type="danger"
|
||||
size="small"
|
||||
class="diff-tag"
|
||||
>
|
||||
{{ moneyCent(row.settlement_diff_amount_cent) }}
|
||||
</el-tag>
|
||||
<span v-else class="amount-val zero-diff">
|
||||
{{ moneyCent(row.settlement_diff_amount_cent) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 操作 -->
|
||||
<el-table-column label="操作" width="90" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<RouterLink :to="adminPath(`orders/${row.order_id}`)" class="action-link">
|
||||
<el-icon><View /></el-icon>
|
||||
<span>查看</span>
|
||||
</RouterLink>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<AdminTablePagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="currentPageSize"
|
||||
:total="total"
|
||||
@change="handlePageChange"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.finance-details-page {
|
||||
--finance-muted: #7f8aa3;
|
||||
.finance-page-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
padding: 0 4px 32px;
|
||||
}
|
||||
|
||||
.finance-details-page :deep(.page-header-row) {
|
||||
margin-bottom: 18px;
|
||||
/* ================= 头部卡片 ================= */
|
||||
.page-header-card {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 24px 28px;
|
||||
box-shadow:
|
||||
0 1px 3px rgba(15, 23, 42, 0.04),
|
||||
0 4px 12px rgba(15, 23, 42, 0.02);
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
}
|
||||
|
||||
.finance-details-page :deep(.page-header h1) {
|
||||
font-size: 28px;
|
||||
.header-main {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.finance-filter-panel {
|
||||
grid-template-columns: repeat(9, minmax(100px, 1fr));
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
padding: 14px 16px;
|
||||
.title-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.finance-filter-panel :deep(.el-form-item__label) {
|
||||
margin-bottom: 4px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.finance-filter-panel :deep(.el-input__wrapper),
|
||||
.finance-filter-panel :deep(.el-select__wrapper) {
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.finance-details-table {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.finance-grid-header,
|
||||
.finance-grid-row {
|
||||
display: grid;
|
||||
grid-template-columns: 15% 9% 16% repeat(8, 7.5%);
|
||||
.eyebrow-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.8px;
|
||||
color: #4f46e5;
|
||||
background: #eef2ff;
|
||||
padding: 3px 10px;
|
||||
border-radius: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
margin: 0;
|
||||
font-size: 13.5px;
|
||||
color: #64748b;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* ================= 筛选面板 ================= */
|
||||
.section-card {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 22px 24px;
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
box-shadow:
|
||||
0 1px 3px rgba(15, 23, 42, 0.04),
|
||||
0 4px 12px rgba(15, 23, 42, 0.02);
|
||||
}
|
||||
|
||||
.filter-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 14px 16px;
|
||||
}
|
||||
|
||||
.filter-grid :deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.filter-grid :deep(.el-form-item__label) {
|
||||
padding-bottom: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.full-control {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.finance-grid-header {
|
||||
border-bottom: 1px solid #edf1f7;
|
||||
color: #7f8aa3;
|
||||
/* ================= 表格卡片 ================= */
|
||||
.table-section-card {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-header-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
color: #4f46e5;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.count-badge {
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.35;
|
||||
text-transform: none;
|
||||
font-weight: 600;
|
||||
color: #4f46e5;
|
||||
background: #eef2ff;
|
||||
padding: 3px 10px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.finance-grid-header > div,
|
||||
.finance-grid-row > div,
|
||||
.finance-grid-row > span {
|
||||
min-width: 0;
|
||||
padding: 8px 7px;
|
||||
.table-container {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.finance-grid-row {
|
||||
border-bottom: 1px solid #edf1f7;
|
||||
.custom-enterprise-table :deep(.el-table__header-wrapper th) {
|
||||
background-color: #f8fafc !important;
|
||||
color: #475569;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.finance-grid-row:last-child {
|
||||
border-bottom: 0;
|
||||
.custom-enterprise-table :deep(.el-table__body-wrapper td) {
|
||||
padding: 12px 0;
|
||||
font-size: 13px;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.order-cell,
|
||||
.status-stack,
|
||||
.party-cell {
|
||||
.order-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
color: #364152;
|
||||
font-weight: 650;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.order-no-link {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
font-size: 12.5px;
|
||||
font-weight: 700;
|
||||
color: #3b82f6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.cell-muted,
|
||||
.status-stack small,
|
||||
.party-cell span {
|
||||
color: var(--finance-muted);
|
||||
.order-no-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.time-sub {
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.status-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.status-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.order-status-badge {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.status-stack > span {
|
||||
color: #364152;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.party-cell span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.settle-desc {
|
||||
font-size: 11.5px;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.amount-text {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: #344054;
|
||||
.offline-desc {
|
||||
font-size: 11px;
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
.parties-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.party-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.role-badge {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.role-badge.renter {
|
||||
background: #eff6ff;
|
||||
color: #3b82f6;
|
||||
}
|
||||
|
||||
.role-badge.owner {
|
||||
background: #f5f3ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
.party-info {
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.amount-cell {
|
||||
text-align: right;
|
||||
.amount-val {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.muted-amount {
|
||||
color: #667085;
|
||||
.flow-amount {
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.amount-danger {
|
||||
color: #dc2626;
|
||||
.net-amount {
|
||||
color: #0891b2;
|
||||
}
|
||||
|
||||
.profit-amount {
|
||||
color: #059669;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
|
||||
.success-val {
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.refund-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.refund-text {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.refunding-text {
|
||||
font-size: 11px;
|
||||
color: #f59e0b;
|
||||
}
|
||||
|
||||
.zero-text {
|
||||
font-size: 12px;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
.diff-tag {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@media (max-width: 1440px) {
|
||||
.finance-filter-panel {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
.zero-diff {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.action-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12.5px;
|
||||
color: #3b82f6;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
padding: 4px 8px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.action-link:hover {
|
||||
background: #eff6ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user