Files
estate/src/views/system/report/aging.vue
2026-08-12 14:40:52 +08:00

256 lines
8.6 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.
<template>
<div class="p-2 h-full flex flex-col">
<pageHeader></pageHeader>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<div class="flex justify-between">
<div>
<el-form-item label-width="100" label="截至应收账期" prop="villageId">
<el-date-picker
v-model="queryTime"
type="daterange"
@update:model-value="handleQueryTime"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY-MM"
value-format="YYYY-MM"
/>
</el-form-item>
<el-form-item label="小区" prop="villageId">
<el-select v-model="queryParams.villageId" placeholder="请选择">
<el-option v-for="item in villageList" :key="item.villageId" :label="item.villageName" :value="item.villageId" />
</el-select>
</el-form-item>
<el-form-item label="房屋类型" prop="houseUseTypeId">
<el-select v-model="queryParams.houseUseTypeId" placeholder="请选择">
<el-option v-for="item in houseUseList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="账龄区间" prop="agingRange">
<el-select :multiple="true" v-model="queryParams.agingRange" placeholder="请选择">
<el-option v-for="item in [...com_report_age_list]" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</div>
<div>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</div>
</div>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never" class="flex-1">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="5">
<span>账龄分析汇总表</span>
</el-col>
<el-col :span="18"></el-col>
<el-col :span="1">
<el-button type="primary" @click="handleExport">导出</el-button>
</el-col>
</el-row>
</template>
<el-table :span-method="arraySpanMethod" v-loading="loading" border :data="AgingList">
<el-table-column label="截至应收账期" align="center" prop="cutoffPeriod" />
<el-table-column label="小区项目" align="center" prop="villageName" />
<el-table-column label="房屋类型" align="center" prop="houseTypeName" />
<el-table-column label="≤6个月" align="center" prop="amountLe6" />
<el-table-column label="6个月-12个月" align="center" prop="amountM6To12" />
<el-table-column label="1年-2年" align="center" prop="amountY1To2" />
<el-table-column label="2年-3年" align="center" prop="amountY2To3" />
<el-table-column label="3年-4年" align="center" prop="amountY3To4" />
<el-table-column label="4年-5年" align="center" prop="amountY4To5" />
<el-table-column label="5年以上" align="center" prop="amountOver5" />
<el-table-column label="合计" align="center" prop="totalAmount" />
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup name="Arrears" lang="ts">
import pagination from '@/components/Pagination/index.vue';
import pageHeader from '@/components/Pageheader/index.vue';
import { listHouseUseType } from '@/api/system/houseUse';
import { getCommunitylistAPI } from '@/api/system/community';
import { getAgingList } from '@/api/system/report/aging';
import { AgingSummary } from '@/api/system/report/aging/type';
import type { TableColumnCtx } from 'element-plus';
import { exportToExcel } from '@/utils/xlsx';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_report_age_list } = toRefs<any>(proxy?.useDict('com_report_age_list'));
const AgingList = ref<AgingSummary[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const queryTime = ref([]);
function handleQueryTime(val: string[]) {
queryParams.value.periodBegin = val[0];
queryParams.value.periodEnd = val[1];
}
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
periodBegin: '',
periodEnd: '',
villageId: '-1',
houseUseTypeId: '-1',
agingRange: []
}
});
interface SpanMethodProps {
row: AgingSummary;
column: TableColumnCtx<AgingSummary>;
rowIndex: number;
columnIndex: number;
}
// 表格区域合并
const arraySpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
if (rowIndex === AgingList.value.length - 1) {
if (columnIndex === 0) {
return { rowspan: 1, colspan: 3 };
}
if (columnIndex === 1) {
return { rowspan: 0, colspan: 0 };
}
if (columnIndex === 2) {
return { rowspan: 0, colspan: 0 };
}
}
// 普通行不合并
return { rowspan: 1, colspan: 1 };
};
const { queryParams } = toRefs(data);
const houseUseList = ref([]);
function handleQueryHouseUse() {
listHouseUseType().then((res) => {
houseUseList.value = [
{
id: '-1',
name: '全部类型'
},
...res.rows
];
});
}
// 查询小区
const villageList = ref([]);
function getAllVillage() {
getCommunitylistAPI().then((res) => {
villageList.value = [
{
villageId: '-1',
villageName: '全部小区'
},
...res.rows
];
});
}
const getList = async () => {
loading.value = true;
const search = { ...queryParams.value };
// 移除空字符串字段
Object.keys(search).forEach((key) => {
if (search[key] === '-1') {
search[key] = undefined;
}
});
getAgingList(search)
.then((res) => {
AgingList.value = [...res.rows, res.summary];
total.value = res.total;
})
.finally(() => {
loading.value = false;
});
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 导出Excel */
const handleExport = () => {
if (AgingList.value.length === 0) {
proxy?.$modal.msgWarning('没有可导出的数据');
return;
}
// 显示加载提示
loading.value = true;
// 使用 setTimeout 让出主线程避免阻塞UI
setTimeout(() => {
try {
const columns: { label: string; prop: string }[] = [
{ label: '截至应收账期', prop: 'cutoffPeriod' },
{ label: '小区项目', prop: 'villageName' },
{ label: '房屋类型', prop: 'houseTypeName' },
{ label: '≤6个月', prop: 'amountLe6' },
{ label: '6个月-12个月', prop: 'amountM6To12' },
{ label: '1年-2年', prop: 'amountY1To2' },
{ label: '2年-3年', prop: 'amountY2To3' },
{ label: '3年-4年', prop: 'amountY3To4' },
{ label: '4年-5年', prop: 'amountY4To5' },
{ label: '5年以上', prop: 'amountOver5' },
{ label: '合计', prop: 'totalAmount' }
];
const arraySpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
if (rowIndex === AgingList.value.length - 1) {
if (columnIndex === 0) {
return { rowspan: 1, colspan: 3 };
}
if (columnIndex === 1) {
return { rowspan: 0, colspan: 0 };
}
if (columnIndex === 2) {
return { rowspan: 0, colspan: 0 };
}
}
// 普通行不合并
return { rowspan: 1, colspan: 1 };
};
exportToExcel(AgingList.value, columns, `账龄分析汇总_${new Date().getTime()}`, arraySpanMethod);
} catch (error) {
proxy?.$modal.msgError('导出失败,请重试');
console.error('导出错误:', error);
} finally {
loading.value = false;
}
}, 100);
};
onMounted(() => {
getList();
handleQueryHouseUse();
getAllVillage();
});
</script>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
</style>