jcloud/dashboard/src2/pages/BillingBalances.vue

205 lines
4.6 KiB
Vue

<template>
<div class="p-5">
<ObjectList :options="options">
<template #header-right>
<Button
icon="download"
appearance="primary"
@click="exportToCsv"
:loading="exporting"
>
导出
</Button>
</template>
</ObjectList>
</div>
</template>
<script>
import ObjectList from '../components/ObjectList.vue';
import { Button, createResource } from 'jingrow-ui';
import { unparse } from 'papaparse';
export default {
name: 'BillingBalances',
props: ['tab'],
components: {
ObjectList,
Button
},
data() {
return {
exporting: false
};
},
computed: {
options() {
return {
pagetype: 'Balance Transaction',
fields: ['type', 'source', 'invoice', 'description'],
columns: [
{
label: '时间',
fieldname: 'creation',
format(value) {
return new Date(value).toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}).replace(/\//g, '-');
}
},
{
label: '描述',
fieldname: 'description',
format(value, row) {
if (value !== null && value !== undefined) {
return value;
}
if (row.type === 'Applied To Invoice' && row.invoice) {
return `冲抵发票 ${row.invoice}`;
}
if (row.source === 'Prepaid Credits') {
return '余额充值';
}
if (row.source === 'Free Credits') {
return '赠送余额';
}
return row.amount < 0 ? row.type : row.source;
}
},
{
label: '金额',
fieldname: 'amount',
align: 'right',
format: this.formatCurrency
},
{
label: '余额',
fieldname: 'ending_balance',
align: 'right',
format: this.formatCurrency
}
],
filters: {
pagestatus: 1,
team: this.$team.name
},
orderBy: 'creation desc'
};
}
},
created() {
// 创建导出资源
this.exportResource = createResource({
url: 'jcloud.api.billing.get_balance_transactions',
onSuccess: this.handleExportSuccess,
onError: this.handleExportError
});
},
methods: {
formatCurrency(value) {
if (value === 0) {
return '';
}
return this.$format.userCurrency(value);
},
formatDate(dateString) {
return new Date(dateString).toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}).replace(/\//g, '-');
},
exportToCsv() {
this.exporting = true;
this.exportResource.submit({
page: 1,
page_size: 1000
});
},
handleExportSuccess(response) {
const transactions = response.transactions || [];
// 定义CSV字段
const fields = [
'时间',
'描述',
'金额',
'余额'
];
// 准备数据
const csvData = transactions.map(row => {
// 优先使用原始描述,如果存在的话
let description = row.description;
// 如果描述不存在,则使用备用逻辑
if (!description) {
if (row.type === 'Applied To Invoice' && row.invoice) {
description = `冲抵发票 ${row.invoice}`;
} else if (row.source === 'Prepaid Credits') {
description = '余额充值';
} else if (row.source === 'Free Credits') {
description = '赠送余额';
} else {
description = row.amount < 0 ? row.type : row.source;
}
}
return [
this.formatDate(row.creation),
description,
row.amount,
row.ending_balance
];
});
// 添加表头
csvData.unshift(fields);
// 生成CSV
let csv = unparse(csvData);
// 添加BOM以支持中文
csv = '\uFEFF' + csv;
// 触发下载
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
const today = new Date().toISOString().split('T')[0];
const filename = `余额记录-${today}.csv`;
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
this.exporting = false;
},
handleExportError(error) {
console.error('导出数据失败:', error);
this.exporting = false;
}
}
};
</script>
<style scoped>
/* 添加悬浮效果 */
.flex-col:hover {
background-color: #f0f0f0; /* 可按需调整颜色 */
}
/* 允许内容复制 */
.flex-col * {
user-select: text;
}
</style>