205 lines
4.6 KiB
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> |