Files
finance-master/apps/finance/src/views/statistics/vip/report.vue

154 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import type { Dayjs } from 'dayjs';
import { onMounted, ref } from 'vue';
import { Loading, Page } from '@vben/common-ui';
// import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, Card, DatePicker, Empty } from 'ant-design-vue';
import dayjs from 'dayjs';
import { statisticsApi } from '#/api/statistics';
const year = ref<Dayjs>(dayjs());
const disabledDate = (date: Dayjs) => date.year() > dayjs().year();
interface Report {
incomes: Record<string, number>;
notyet: number;
already: number;
now: number;
}
interface ReportItem {
type: string;
fee: number;
}
// 报表数据
const list = ref<Report[]>([]);
const loading = ref<boolean>(false);
const getList = async () => {
loading.value = true;
list.value = [];
try {
// 计算查询年份中包含哪些月份, 若为今年则只查询到当前月份,往年则查询所有月份
const monthList =
year.value.year() === dayjs().year()
? Array.from({ length: dayjs().month() + 1 }, (_, i) => (i + 1).toString().padStart(2, '0'))
: Array.from({ length: 12 }, (_, i) => (i + 1).toString().padStart(2, '0'));
for (const month of monthList) {
const data = await statisticsApi.getVipStatistics({
year: year.value.year(),
month,
});
list.value.push({
incomes: {
微信: 0,
支付宝: 0,
银行: 0,
天医币: 0,
...Object.fromEntries(data.incomes.map((item: ReportItem) => [item.type, item.fee])),
},
notyet: data.notyet || 0,
already: data.already || 0,
now: data.now || 0,
});
}
} finally {
loading.value = false;
}
};
// 下载报表
// const downloadReport = async (index: number) => {
// const month = index > 9 ? `${index + 1}` : `0${index + 1}`;
// const date = `${year.value.year()}-${month}`;
// const filename = `天医币报表_${year.value.year()}年${month}月_文件.xlsx`;
// const res = await statisticsApi.downloadReportTianyibi({
// date,
// });
// downloadFileFromBlobPart({
// source: res.data,
// fileName: filename,
// });
// };
// const downloadAllReport = () => {
// list.value.forEach((_, index) => {
// downloadReport(index);
// });
// };
onMounted(() => {
getList();
});
</script>
<template>
<Page auto-content-height>
<Loading class="flex h-full flex-col rounded-md bg-white" :spinning="loading">
<div class="search-form p-4">
<DatePicker
v-model:value="year"
picker="year"
:disabled-date="disabledDate"
@change="getList"
/>
<Button type="primary" class="ml-2" @click="getList">查询</Button>
<!-- <Button type="link" class="ml-2" @click="downloadAllReport">
下载 {{ year.year() }} 年全部天医币报表
</Button> -->
</div>
<div class="h-2 bg-gray-100"></div>
<div class="content relative min-h-2 flex-1 px-3 py-4">
<div
v-if="list.length === 0 && !loading"
class="col-span-3 flex items-center justify-center"
>
<Empty />
</div>
<div v-else class="grid max-h-full grid-cols-3 gap-3 overflow-auto px-1">
<Card v-for="(item, index) in list" :key="index" :title="`${index + 1} 月`" size="small">
<!-- <template #extra>
<Button type="link" @click="downloadReport(index)">下载报表</Button>
</template> -->
<div class="-m-2 text-[16px]">
<div class="flex">
<div class="flex-1 bg-[#F6FFF5] px-2 pb-1">
<div class="p-1 text-center font-bold">收入</div>
<div v-for="(fee, type) in item.incomes" :key="type" class="p-1">
<span class="text-gray-500">{{ type }}</span>
<span class="text-black">{{ fee }}</span>
</div>
</div>
<div class="flex-1 bg-[#FFFBF0] px-2 pb-1">
<div class="p-1 text-center font-bold">摊销</div>
<div class="p-1">
<span class="text-gray-500">已摊销</span>
<span class="text-black">{{ item.already }}</span>
</div>
<div class="p-1">
<span class="text-gray-500">月摊销</span>
<span class="text-black">{{ item.now }}</span>
</div>
<div class="p-1">
<span class="text-gray-500">剩余摊销</span>
<span class="text-black">{{ item.notyet }}</span>
</div>
</div>
</div>
</div>
</Card>
</div>
</div>
</Loading>
</Page>
</template>
<style scoped lang="scss">
:deep(.ant-card-head-title) {
font-size: 16px !important;
}
</style>