8/25 dev 权限,sse,账单

This commit is contained in:
Zy
2026-08-27 17:32:23 +08:00
parent b83735e993
commit 2ea75ee5ef
55 changed files with 870 additions and 293 deletions

View File

@@ -4,16 +4,163 @@
<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 label-width="auto" ref="queryFormRef" :model="queryParams" @submit.prevent="handleQuery" :inline="true">
<div class="flex justify-between flex-wrap">
<el-form
:rules="formRules"
label-width="180px"
label-position="right"
ref="queryFormRef"
:model="queryParams"
@submit.prevent="handleQuery"
:inline="true"
>
<div>
<el-form-item label="日期" prop="payTime">
<el-date-picker
v-model="payTime"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@clear="handleClear()"
@update:model-value="(val: string[]) => handleUpdateLeaseDate(val)"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item label="户主" prop="residentName">
<el-input v-model.trim="queryParams.residentName" placeholder="请输入户主姓名"></el-input>
</el-form-item>
<el-form-item label="房号" prop="houseName">
<el-input v-model.trim="queryParams.houseName" placeholder="请输入房号"></el-input>
</el-form-item>
<el-form-item label="">
<div v-show="!isShow" class="flex justify-end">
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
<div @click="toggleShow" class="flex items-center cursor-pointer hover:color-blue" style="margin-left: 10px; font-size: 13px">
<span>展开</span>
<el-icon style="margin-left: 5px"><ArrowDownBold /></el-icon>
</div>
</div>
</el-form-item>
</div>
<div v-show="isShow">
<el-form-item label="现金" prop="cashAmount">
<el-input v-model.trim="queryParams.cashAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="支付宝" prop="alipayAmount">
<el-input v-model.trim="queryParams.alipayAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="宜当付" prop="yiDangFuAmount">
<el-input v-model.trim="queryParams.yiDangFuAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="银联" prop="unionPayAmount">
<el-input v-model.trim="queryParams.unionPayAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="转账" prop="transferAmount">
<el-input v-model.trim="queryParams.transferAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="微信" prop="wechatAmount">
<el-input v-model.trim="queryParams.wechatAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="押金抵顶" prop="depositAmount">
<el-input v-model.trim="queryParams.depositAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="房产抵顶" prop="propertyOffsetAmount">
<el-input v-model.trim="queryParams.propertyOffsetAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="减免优惠" prop="discountAmount">
<el-input v-model.trim="queryParams.discountAmount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
</div>
<div v-show="isShow">
<el-form-item label="水费" prop="waterFee">
<el-input v-model.trim="queryParams.waterFee" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="电费" prop="electricFee">
<el-input v-model.trim="queryParams.electricFee" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item label="押金" prop="deposit">
<el-input v-model.trim="queryParams.deposit" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
</div>
<div v-show="isShow" class="flex justify-between flex-wrap">
<div v-for="(item, index) in queryParamsList" :key="index">
<el-form-item :label="item[ite].label" :prop="item[ite].parameter" v-for="(ite, ind) in Object.keys(item)" :key="ind">
<el-input v-model.trim="queryParams[item[ite].parameter]" :placeholder="item[ite].placeholder"></el-input>
<el-form-item :label="`${item.chargeTypeName} (金额)`">
<el-input v-model.trim="queryParams.chargeTypeFilters[index].amount" placeholder="区间搜索 1000-10000"></el-input>
</el-form-item>
<el-form-item :label="`${item.chargeTypeName} (开始时间)`">
<el-date-picker
v-model="queryParams.chargeTypeFilters[index].startDate"
@update:model-value="
(val: string[]) => {
if (val.length === 0) {
return;
}
queryParams.chargeTypeFilters[index].startDateBegin = val[0];
queryParams.chargeTypeFilters[index].startDateEnd = val[1];
}
"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
@clear="
() => {
queryParams.chargeTypeFilters[index].startDate = '';
queryParams.chargeTypeFilters[index].startDateBegin = '';
queryParams.chargeTypeFilters[index].startDateEnd = '';
}
"
type="datetimerange"
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</el-form-item>
<el-form-item :label="`${item.chargeTypeName} (结束时间)`">
<el-date-picker
v-model="queryParams.chargeTypeFilters[index].endDate"
type="datetimerange"
@update:model-value="
(val: string[]) => {
if (val.length === 0) {
return;
}
queryParams.chargeTypeFilters[index].endDateBegin = val[0];
queryParams.chargeTypeFilters[index].endDateEnd = val[1];
}
"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
@clear="
() => {
queryParams.chargeTypeFilters[index].endDate = '';
queryParams.chargeTypeFilters[index].endDateBegin = '';
queryParams.chargeTypeFilters[index].endDateEnd = '';
}
"
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</el-form-item>
</div>
<div>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</div>
<!-- <div v-show="isShow">-->
<!-- <el-form-item label="经办人" prop="handler">-->
<!-- <el-input v-model.trim="queryParams.handler" placeholder="请输入经办人姓名"></el-input>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备注" prop="remark">-->
<!-- <el-input v-model.trim="queryParams.remark" placeholder="请输入备注"></el-input>-->
<!-- </el-form-item>-->
<!-- </div>-->
<div v-show="isShow" class="flex justify-end">
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
<div @click="toggleShow" class="flex items-center cursor-pointer hover:color-blue" style="margin-left: 10px; font-size: 13px">
<span>收起</span>
<el-icon style="margin-left: 5px"><ArrowUpBold /></el-icon>
</div>
</div>
</el-form>
@@ -33,7 +180,6 @@
</el-col>
</el-row>
</template>
<el-table :row-class-name="handleRowClass" v-loading="loading" border :data="ArrearsDetailList">
<el-table-column label="日期" width="100" align="center" fixed="left" prop="payTime" />
<el-table-column label="房屋信息" align="center" fixed="left">
@@ -90,8 +236,8 @@
</el-table-column>
</template>
</el-table-column>
<el-table-column label="经办人" align="center" prop="handler" />
<el-table-column show-overflow-tooltip width="250" label="备注" align="center" prop="remark" />
<!-- <el-table-column label="经办人" align="center" prop="handler" />-->
<!-- <el-table-column show-overflow-tooltip width="250" label="备注" align="center" prop="remark" />-->
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
@@ -106,6 +252,8 @@ import { ColumnConfig, exportToExcel } from '@/utils/xlsx';
import { listHouseUseType } from '@/api/system/houseUse';
import { getDailyFeeReportDynamicList, getDailyFeeReportList } from '@/api/system/report/dailyFeeReport';
import { Datum } from '@/api/system/report/dailyFeeReport/type';
import { FormRules } from 'element-plus';
import { ArrowDownBold, ArrowUpBold } from '@element-plus/icons-vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const ArrearsDetailList = ref<Datum[]>([]);
@@ -130,41 +278,140 @@ function getHouseUseList() {
});
}
const isShow = ref(false);
function toggleShow() {
isShow.value = !isShow.value;
}
const queryParams = ref({
pageNum: 1,
pageSize: 10
pageSize: 10,
startDate: '',
endDate: '',
residentName: '',
houseName: '',
cashAmount: '',
alipayAmount: '',
yiDangFuAmount: '',
unionPayAmount: '',
transferAmount: '',
wechatAmount: '',
depositAmount: '',
propertyOffsetAmount: '',
discountAmount: '',
waterFee: '',
electricFee: '',
deposit: '',
handler: '',
remark: '',
chargeTypeFilters: []
});
const staticSearchKey = [
'cashAmount',
'alipayAmount',
'yiDangFuAmount',
'unionPayAmount',
'transferAmount',
'wechatAmount',
'depositAmount',
'propertyOffsetAmount',
'discountAmount',
'waterFee',
'electricFee',
'deposit'
];
// 动态生成表单验证规则
const formRules = computed<FormRules>(() => {
const dynamicRules: FormRules = {};
staticSearchKey.forEach((item) => {
dynamicRules[item] = [
{
validator: (_: any, value: string, callback: (error?: any) => void) => {
if (!value || value === '') {
callback();
return;
}
const rangePattern = /^(-?\d+(\.\d{1,2})?)-(-?\d+(\.\d{1,2})?)?$/;
const singlePattern = /^-?\d+(\.\d{1,2})?$/;
const MAX_AMOUNT = 99999999;
if (rangePattern.test(value)) {
const parts = value.split('-');
const min = Number(parts[0]);
const max = parts[1] !== '' ? Number(parts[1]) : null; // 空字符串才是 null
// 校验下限
if (Math.abs(min) > MAX_AMOUNT) {
return callback(new Error(`金额不能超过 ${MAX_AMOUNT}`));
}
// 只有当 max 存在时才校验
if (max !== null) {
if (Math.abs(max) > MAX_AMOUNT) {
return callback(new Error(`金额不能超过 ${MAX_AMOUNT}`));
}
if (min > max) {
return callback(new Error('下限不能大于上限'));
}
}
return callback();
} else if (singlePattern.test(value)) {
const amount = Number(value);
if (Math.abs(amount) > MAX_AMOUNT) {
return callback(new Error(`金额不能超过 ${MAX_AMOUNT}`));
} else {
return callback();
}
} else {
callback(new Error('格式错误,示例: 0-1000、-1000、0-、1000'));
}
},
trigger: 'blur'
}
];
});
return dynamicRules;
});
const payTime = ref([]);
function handleClear() {
payTime.value = [];
queryParams.value.startDate = '';
queryParams.value.endDate = '';
}
function handleUpdateLeaseDate(val: string[]) {
queryParams.value.startDate = val[0];
queryParams.value.endDate = val[1];
}
// 参数列表
const queryParamsList = ref([]);
function getQueryParams() {
getDailyFeeReportDynamicList().then((res) => {
const obj = {};
const list = res.data.map((item) => {
const obj2 = {};
const list = item.field.split(',') ?? [];
console.log(list);
list.forEach((item2) => {
obj[item2] = '';
obj2[item2] = {
label: item.label,
parameter: item2,
placeholder: item.placeholder,
type: item.type,
subField: item.subField
};
});
return obj2;
});
queryParams.value = {
...queryParams.value,
...obj
};
queryParamsList.value = list;
console.log(list);
queryParamsList.value = res.data;
handleAddQuery();
});
}
function handleAddQuery() {
const list = queryParamsList.value.map((item) => {
return {
'chargeTypeName': item.chargeTypeName,
'chargeTypeId': item.chargeTypeId,
'amount': '',
startDate: '',
endDate: '',
'startDateBegin': '',
'startDateEnd': '',
'endDateBegin': '',
'endDateEnd': ''
};
});
queryParamsList.value = list;
queryParams.value.chargeTypeFilters = list;
}
const rowChargeTypesList = ref([]);
@@ -181,7 +428,7 @@ const getList = async () => {
getDailyFeeReportList(search)
.then((res) => {
ArrearsDetailList.value = [...(res.rows ?? [])];
rowChargeTypesList.value = Object.keys(res.rows[0].chargeTypeAmounts);
rowChargeTypesList.value = Object.keys(res.rows[0].chargeTypeAmounts) ?? [];
total.value = res.total;
})
.finally(() => {
@@ -206,9 +453,30 @@ const handleQuery = () => {
const resetQuery = () => {
queryFormRef.value?.resetFields();
queryParams.value = {
endDate: undefined,
startDate: undefined,
pageNum: 1,
pageSize: 10
pageSize: 10,
residentName: '',
houseName: '',
cashAmount: '',
alipayAmount: '',
yiDangFuAmount: '',
unionPayAmount: '',
transferAmount: '',
wechatAmount: '',
depositAmount: '',
propertyOffsetAmount: '',
discountAmount: '',
waterFee: '',
electricFee: '',
deposit: '',
handler: '',
remark: '',
chargeTypeFilters: []
};
handleAddQuery();
handleClear();
handleQuery();
};
/** 导出Excel */
@@ -272,15 +540,15 @@ const handleExport = () => {
? []
: [
{ label: '金额', prop: `chargeTypeAmounts.${item}.amount` },
{ label: '开始时间', prop: `chargeTypeAmounts.${item}.startTime` },
{ label: '截止时间', prop: `chargeTypeAmounts.${item}.endTime` }
{ label: '开始时间', prop: `chargeTypeAmounts.${item}.startDate` },
{ label: '截止时间', prop: `chargeTypeAmounts.${item}.endDate` }
]
};
})
]
},
{ label: '经办人', prop: 'inspectorName' },
{ label: '备注', prop: 'remark' }
}
// { label: '经办人', prop: 'inspectorName' },
// { label: '备注', prop: 'remark' }
];
console.log(columns);
exportToExcel(ArrearsDetailList.value, columns, `日报_${new Date().getTime()}`);