Files
TakeoutSaaS.TenantUI/apps/web-antd/src/views/finance/settlement/components/SettlementTableCard.vue

132 lines
3.3 KiB
Vue

<script setup lang="ts">
/**
* 文件职责:到账查询列表表格与展开明细。
*/
import type { TablePaginationConfig, TableProps } from 'ant-design-vue';
import type { FinanceSettlementDetailStateMap } from '../types';
import type { FinanceSettlementListItemDto } from '#/api/finance';
import { computed } from 'vue';
import { Table } from 'ant-design-vue';
import {
formatCurrency,
getSettlementRowKey,
resolveChannelDotClass,
} from '../composables/settlement-page/helpers';
import SettlementDetailTable from './SettlementDetailTable.vue';
interface PaginationState {
page: number;
pageSize: number;
total: number;
}
interface Props {
detailStates: FinanceSettlementDetailStateMap;
expandedRowKeys: string[];
loading: boolean;
pagination: PaginationState;
rows: FinanceSettlementListItemDto[];
}
const props = defineProps<Props>();
const emit = defineEmits<{
(event: 'expand', expanded: boolean, row: FinanceSettlementListItemDto): void;
(event: 'pageChange', page: number, pageSize: number): void;
}>();
const columns: TableProps['columns'] = [
{
title: '到账日期',
dataIndex: 'arrivedDate',
width: 170,
},
{
title: '支付渠道',
dataIndex: 'channelText',
width: 190,
},
{
title: '交易笔数',
dataIndex: 'transactionCount',
width: 130,
},
{
title: '到账金额',
dataIndex: 'arrivedAmount',
align: 'right',
width: 180,
},
];
const expandable = computed(() => ({
expandedRowKeys: props.expandedRowKeys,
onExpand: (expanded: boolean, row: FinanceSettlementListItemDto) => {
emit('expand', expanded, row);
},
}));
function handleTableChange(next: TablePaginationConfig) {
emit('pageChange', Number(next.current || 1), Number(next.pageSize || 20));
}
function resolveDetailState(row: FinanceSettlementListItemDto) {
return (
props.detailStates[getSettlementRowKey(row)] ?? {
loading: false,
items: [],
}
);
}
</script>
<template>
<div class="fst-table-card">
<Table
:row-key="getSettlementRowKey"
:columns="columns"
:data-source="props.rows"
:loading="props.loading"
:pagination="{
current: props.pagination.page,
pageSize: props.pagination.pageSize,
total: props.pagination.total,
showSizeChanger: true,
pageSizeOptions: ['20', '50', '100'],
showTotal: (total: number) => `共 ${total} 条`,
}"
:expandable="expandable"
@change="handleTableChange"
>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'channelText'">
<span class="fst-channel-icon">
<span
class="fst-channel-dot"
:class="resolveChannelDotClass(String(record.channel))"
></span>
{{ record.channelText }}
</span>
</template>
<template v-else-if="column.dataIndex === 'arrivedAmount'">
<span class="fst-amount">{{
formatCurrency(Number(record.arrivedAmount || 0))
}}</span>
</template>
</template>
<template #expandedRowRender="{ record }">
<SettlementDetailTable
:loading="resolveDetailState(record).loading"
:items="resolveDetailState(record).items"
/>
</template>
</Table>
</div>
</template>