1050 lines
24 KiB
Vue
1050 lines
24 KiB
Vue
<template>
|
||
<view class="call-page">
|
||
<!-- 自定义导航栏 -->
|
||
<wd-navbar :bordered="false"
|
||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(10px) !important;"
|
||
safeAreaInsetTop fixed placeholder>
|
||
<template #left>
|
||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||
@click="toPages({type:'nav'})"></text>
|
||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||
@click="toPages({type:'home'})"></text>
|
||
<text class="li-text-42">物业费催缴</text>
|
||
</view>
|
||
</template>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<template #right>
|
||
<view class="li-mr-180 li-flex li-items-center">
|
||
<view class="community-switch li-flex li-items-center" @click="showCommunityPicker = true">
|
||
<text class="li-text-30 li-text-primary li-mr-10">{{activeCommunity.name}}</text>
|
||
<text class="ri-arrow-down-s-line li-text-30"></text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<!-- #endif -->
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<template #right>
|
||
<view class="li-mr-25 li-flex li-items-center">
|
||
<view class="community-switch li-flex li-items-center" @click="showCommunityPicker = true">
|
||
<text class="li-text-30 li-text-primary li-mr-10">{{activeCommunity.name}}</text>
|
||
<text class="ri-arrow-down-s-line li-text-30"></text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<!-- #endif -->
|
||
</wd-navbar>
|
||
<!-- 导航栏背景 -->
|
||
<view class="nav-bg-layer"></view>
|
||
|
||
<!-- 页面内容 -->
|
||
<view class="content">
|
||
<!-- 小区信息 -->
|
||
<view class="community-card li-mx-40 li-mt-40">
|
||
<view class="community-header li-p-30">
|
||
<view class="li-flex li-justify-between li-items-center">
|
||
<text
|
||
class="community-name li-text-42 li-font-bold li-text-white">{{activeCommunity.name}}</text>
|
||
<view class="li-px-20 li-py-10 li-bg-rgba(255,255,255,0.3) li-rd-30" @click="handleRefresh">
|
||
<text class="li-text-28 li-text-white">刷新数据</text>
|
||
</view>
|
||
</view>
|
||
<view class="li-flex li-items-center li-mt-20">
|
||
<text class="li-text-28 li-text-white li-opacity-80">{{activeCommunity.address}}</text>
|
||
</view>
|
||
<view class="li-flex li-items-center li-mt-10">
|
||
<text class="li-text-28 li-text-white li-opacity-80">欠费总量:</text>
|
||
<text class="li-text-32 li-text-white li-font-bold">{{activeCommunity.totalUnpaid}}</text>
|
||
</view>
|
||
</view>
|
||
<view class="community-footer li-p-30 li-bg-white">
|
||
<view class="li-flex li-items-center">
|
||
<text class="li-text-28 li-text-#666">物业管理中心:</text>
|
||
<text class="li-text-28 li-text-#333">{{activeCommunity.managementAddress}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="building-selector-container li-mt-30">
|
||
<view class="building-sidebar-layout">
|
||
<!-- 左侧楼栋侧边导航 -->
|
||
<view class="sidebar-container">
|
||
<wd-sidebar v-model="activeBuilding" custom-class="building-sidebar">
|
||
<wd-sidebar-item v-for="item in buildingList" :key="item.id" :value="item.id"
|
||
:label="item.name" :badge="getBuildingUnpaidCount(item.id)"
|
||
:badge-props="{ type: 'primary', bgColor: '#ff4d4f' }" />
|
||
</wd-sidebar>
|
||
</view>
|
||
|
||
<!-- 右侧单元与房屋内容 -->
|
||
<view class="content-container">
|
||
<!-- 单元选择 -->
|
||
<view class="unit-selector li-px-30 li-py-20">
|
||
<view class="li-mb-20">
|
||
<text class="li-text-30 li-font-bold">{{getActiveBuilding().name}}</text>
|
||
</view>
|
||
<view class="unit-buttons li-flex li-flex-wrap">
|
||
<view v-for="unit in unitList" :key="unit.value"
|
||
class="unit-button li-flex-center li-mr-20 li-mb-20"
|
||
:class="activeUnitId === String(unit.value) ? 'unit-button-active' : ''"
|
||
@click="activeUnitId = String(unit.value)">
|
||
<text class="unit-text"
|
||
:class="activeUnitId === String(unit.value) ? 'unit-text-active' : ''">{{unit.label}}</text>
|
||
<view v-if="getUnitUnpaidCount(unit.value) > 0" class="unit-badge">
|
||
{{getUnitUnpaidCount(unit.value)}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 楼层和房屋数据 -->
|
||
<view class="house-list li-px-30 li-pb-40">
|
||
<view v-for="(floor, floorIndex) in floorHouseList" :key="floorIndex"
|
||
class="floor-item li-mb-20">
|
||
<view class="floor-header li-py-15 li-px-30">
|
||
<text class="li-text-30 li-font-bold li-text-#333">{{floor.floor}}层</text>
|
||
</view>
|
||
<view class="house-grid">
|
||
<view v-for="(house, houseIndex) in floor.houses" :key="houseIndex"
|
||
class="house-card" @click="showHouseDetailFunc(house)">
|
||
<view class="house-card-inner">
|
||
<view class="house-icon li-flex-center">
|
||
<text class="ri-building-2-line li-text-60 li-text-#3e9bff"></text>
|
||
<!-- 欠费标记 -->
|
||
<view v-if="house.unpaid > 0" class="unpaid-badge">{{house.unpaid}}
|
||
</view>
|
||
</view>
|
||
<view class="house-info li-mt-15">
|
||
<text
|
||
class="li-text-30 li-font-bold li-text-#333 li-text-center">{{house.number}}</text>
|
||
<view class="li-flex li-items-center li-justify-center li-mt-5">
|
||
<text class="li-text-24"
|
||
:class="house.unpaid > 0 ? 'li-text-#ff4d4f' : 'li-text-#52c41a'">
|
||
{{house.unpaid > 0 ? house.unpaid + '笔欠费' : '无欠费'}}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view v-if="floorHouseList.length === 0"
|
||
class="empty-state li-py-100 li-flex-center li-flex-col">
|
||
<text class="ri-file-list-3-line li-text-100 li-text-#ccc"></text>
|
||
<text class="li-text-30 li-text-#999 li-mt-20">该单元暂无数据</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 小区选择器 -->
|
||
<!-- <wd-picker v-model="showCommunityPicker" :columns="communityList" title="选择小区"
|
||
v-model:value="selectedCommunity" @confirm="handleCommunityConfirm" label-key="name" value-key="id" /> -->
|
||
|
||
<!-- 房屋详情弹窗 -->
|
||
<wd-popup v-model="showHouseDetail" position="bottom">
|
||
<view class="house-detail" :style="{ height: '60vh' }">
|
||
<view class="detail-header li-p-30 li-bottom-border">
|
||
<view class="li-flex li-justify-between li-items-center">
|
||
<text class="li-text-36 li-font-bold">{{selectedHouse.number}}</text>
|
||
<text class="ri-close-line li-text-50 li-text-#999" @click="showHouseDetail = false"></text>
|
||
</view>
|
||
<view class="li-flex li-items-center li-mt-10">
|
||
<text class="li-text-28 li-text-#666">{{activeCommunity.name}} {{getActiveBuilding().name}}
|
||
{{activeUnit}}单元</text>
|
||
</view>
|
||
</view>
|
||
<scroll-view scroll-y class="detail-content-scroll">
|
||
<view class="detail-content li-p-30">
|
||
<view v-if="selectedHouse.unpaid > 0">
|
||
<view class="li-flex li-justify-between li-items-center li-mb-20">
|
||
<text class="li-text-32 li-font-bold">欠费账单</text>
|
||
<text class="li-text-28 li-text-#3e9bff">共 {{selectedHouse.unpaid}} 笔</text>
|
||
</view>
|
||
<view v-for="(bill, index) in selectedHouse.bills" :key="index"
|
||
class="bill-item li-p-30 li-mb-20">
|
||
<view class="li-flex li-items-center li-justify-between">
|
||
<text class="li-text-30 li-font-bold">{{bill.type}}</text>
|
||
<text class="li-text-30 li-text-#ff4d4f">¥{{bill.amount}}</text>
|
||
</view>
|
||
<view class="li-flex li-items-center li-mt-15">
|
||
<text class="li-text-26 li-text-#999">账单期间:</text>
|
||
<text class="li-text-26 li-text-#666">{{bill.period}}</text>
|
||
</view>
|
||
<view class="li-flex li-items-center li-mt-10">
|
||
<text class="li-text-26 li-text-#999">逾期时间:</text>
|
||
<text class="li-text-26 li-text-#666">{{bill.overdueTime}}</text>
|
||
</view>
|
||
<view class="li-flex li-justify-between li-items-center li-mt-20">
|
||
<wd-button size="small" type="info" plain
|
||
@click="callOwner(selectedHouse)">电话催缴</wd-button>
|
||
<wd-button size="small" type="primary"
|
||
@click="sendReminder(selectedHouse)">发送通知</wd-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="empty-bills li-py-60 li-flex-center li-flex-col">
|
||
<text class="ri-check-double-line li-text-100 li-text-#52c41a"></text>
|
||
<text class="li-text-30 li-text-#666 li-mt-20">该住户暂无欠费</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</wd-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
ref,
|
||
reactive,
|
||
computed,
|
||
onMounted,
|
||
watch
|
||
} from 'vue';
|
||
import {
|
||
onLoad
|
||
} from '@dcloudio/uni-app';
|
||
import {
|
||
useNavigation
|
||
} from '@/hooks/useNavigation';
|
||
import {
|
||
useToast
|
||
} from '@/uni_modules/wot-design-uni';
|
||
|
||
const Toast = useToast();
|
||
|
||
// 使用导航composable
|
||
const {
|
||
hasMultiplePages,
|
||
isTabBarPage,
|
||
checkRouteStack
|
||
} = useNavigation();
|
||
|
||
// 小区列表
|
||
const communityList = ref([
|
||
[{
|
||
id: '1',
|
||
name: '九仙花苑'
|
||
},
|
||
{
|
||
id: '2',
|
||
name: '阳光花园小区'
|
||
},
|
||
{
|
||
id: '3',
|
||
name: '翠湖庭院'
|
||
},
|
||
{
|
||
id: '4',
|
||
name: '金色家园'
|
||
}
|
||
]
|
||
]);
|
||
|
||
// 当前选中的小区
|
||
const selectedCommunity = ref('1');
|
||
const showCommunityPicker = ref(false);
|
||
|
||
// 获取当前选中的小区数据
|
||
const activeCommunity = computed(() => {
|
||
const communityData = {
|
||
'1': {
|
||
id: '1',
|
||
name: '九仙花苑',
|
||
address: '福建省-福州市-鼓楼区',
|
||
managementAddress: '东街道33号社区中心',
|
||
totalUnpaid: 3624
|
||
},
|
||
'2': {
|
||
id: '2',
|
||
name: '阳光花园小区',
|
||
address: '福建省-福州市-台江区',
|
||
managementAddress: '茶亭街道15号物业中心',
|
||
totalUnpaid: 1856
|
||
},
|
||
'3': {
|
||
id: '3',
|
||
name: '翠湖庭院',
|
||
address: '福建省-福州市-晋安区',
|
||
managementAddress: '王庄街道8号物业中心',
|
||
totalUnpaid: 2145
|
||
},
|
||
'4': {
|
||
id: '4',
|
||
name: '金色家园',
|
||
address: '福建省-福州市-仓山区',
|
||
managementAddress: '城门镇1号物业中心',
|
||
totalUnpaid: 1023
|
||
}
|
||
};
|
||
return communityData[selectedCommunity.value];
|
||
});
|
||
|
||
// 楼栋列表
|
||
const buildingList = ref([{
|
||
id: '1',
|
||
name: '1号楼'
|
||
},
|
||
{
|
||
id: '2',
|
||
name: '2号楼'
|
||
},
|
||
{
|
||
id: '3',
|
||
name: '3号楼'
|
||
},
|
||
{
|
||
id: '5',
|
||
name: '5号楼'
|
||
},
|
||
{
|
||
id: '6',
|
||
name: '6号楼'
|
||
},
|
||
{
|
||
id: '7',
|
||
name: '7号楼'
|
||
},
|
||
{
|
||
id: '8',
|
||
name: '8号楼'
|
||
},
|
||
{
|
||
id: '9',
|
||
name: '9号楼'
|
||
},
|
||
{
|
||
id: '10',
|
||
name: '10号楼'
|
||
},
|
||
{
|
||
id: '11',
|
||
name: '11号楼'
|
||
},
|
||
{
|
||
id: '12',
|
||
name: '12号楼'
|
||
}
|
||
]);
|
||
|
||
// 单元列表
|
||
const unitList = ref([{
|
||
value: 1,
|
||
label: '1单元'
|
||
},
|
||
{
|
||
value: 2,
|
||
label: '2单元'
|
||
},
|
||
{
|
||
value: 3,
|
||
label: '3单元'
|
||
},
|
||
{
|
||
value: 4,
|
||
label: '4单元'
|
||
},
|
||
{
|
||
value: 5,
|
||
label: '5单元'
|
||
},
|
||
{
|
||
value: 6,
|
||
label: '6单元'
|
||
}
|
||
]);
|
||
|
||
// 当前选中的楼栋
|
||
const activeBuilding = ref('1');
|
||
// 当前选中的单元 (使用字符串类型)
|
||
const activeUnitId = ref('1');
|
||
// 兼容原有的数字类型单元ID
|
||
const activeUnit = computed(() => parseInt(activeUnitId.value));
|
||
|
||
// 监听activeUnit变化,更新floorHouseList
|
||
watch(activeUnit, (newVal) => {
|
||
console.log('activeUnit changed to', newVal);
|
||
});
|
||
|
||
// 房屋数据
|
||
const houseData = reactive({
|
||
// 1号楼 1单元数据
|
||
'1-1': [{
|
||
floor: '1',
|
||
houses: [{
|
||
id: '1-1-101',
|
||
number: '1-1001',
|
||
unpaid: 0,
|
||
owner: '张先生',
|
||
phone: '13812345678',
|
||
bills: []
|
||
},
|
||
{
|
||
id: '1-1-102',
|
||
number: '1-1002',
|
||
unpaid: 3,
|
||
owner: '刘女士',
|
||
phone: '13812345679',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '水费',
|
||
amount: '124.50',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}
|
||
]
|
||
},
|
||
{
|
||
id: '1-1-103',
|
||
number: '1-1003',
|
||
unpaid: 2,
|
||
owner: '陈先生',
|
||
phone: '13812345680',
|
||
bills: [{
|
||
type: '电费',
|
||
amount: '356.80',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}]
|
||
},
|
||
{
|
||
id: '1-1-104',
|
||
number: '1-1004',
|
||
unpaid: 0,
|
||
owner: '林女士',
|
||
phone: '13812345681',
|
||
bills: []
|
||
},
|
||
{
|
||
id: '1-1-105',
|
||
number: '1-1005',
|
||
unpaid: 4,
|
||
owner: '黄先生',
|
||
phone: '13812345682',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '水费',
|
||
amount: '124.50',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '电费',
|
||
amount: '356.80',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}
|
||
]
|
||
},
|
||
{
|
||
id: '1-1-106',
|
||
number: '1-1006',
|
||
unpaid: 1,
|
||
owner: '张先生',
|
||
phone: '13812345683',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
floor: '2',
|
||
houses: [{
|
||
id: '1-1-201',
|
||
number: '2-1002',
|
||
unpaid: 0,
|
||
owner: '李女士',
|
||
phone: '13812345679',
|
||
bills: []
|
||
}]
|
||
},
|
||
{
|
||
floor: '3',
|
||
houses: [{
|
||
id: '1-1-301',
|
||
number: '3-1003',
|
||
unpaid: 0,
|
||
owner: '王先生',
|
||
phone: '13812345680',
|
||
bills: []
|
||
}]
|
||
},
|
||
{
|
||
floor: '4',
|
||
houses: [{
|
||
id: '1-1-401',
|
||
number: '4-1004',
|
||
unpaid: 6,
|
||
owner: '赵女士',
|
||
phone: '13812345681',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '水费',
|
||
amount: '124.50',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '电费',
|
||
amount: '356.80',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '停车费',
|
||
amount: '300.00',
|
||
period: '2023-11-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '垃圾处理费',
|
||
amount: '45.00',
|
||
period: '2023-10-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '维修基金',
|
||
amount: '120.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}
|
||
]
|
||
}]
|
||
},
|
||
{
|
||
floor: '5',
|
||
houses: [{
|
||
id: '1-1-501',
|
||
number: '5-1005',
|
||
unpaid: 0,
|
||
owner: '钱先生',
|
||
phone: '13812345682',
|
||
bills: []
|
||
}]
|
||
},
|
||
{
|
||
floor: '6',
|
||
houses: [{
|
||
id: '1-1-601',
|
||
number: '6-1006',
|
||
unpaid: 6,
|
||
owner: '孙女士',
|
||
phone: '13812345683',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '水费',
|
||
amount: '124.50',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '电费',
|
||
amount: '356.80',
|
||
period: '2023-12-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '停车费',
|
||
amount: '300.00',
|
||
period: '2023-11-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '垃圾处理费',
|
||
amount: '45.00',
|
||
period: '2023-10-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
},
|
||
{
|
||
type: '维修基金',
|
||
amount: '120.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}
|
||
]
|
||
}]
|
||
}
|
||
],
|
||
// 1号楼 2单元数据
|
||
'1-2': [{
|
||
floor: '1',
|
||
houses: [{
|
||
id: '1-2-101',
|
||
number: '1-2001',
|
||
unpaid: 3,
|
||
owner: '周先生',
|
||
phone: '13812345684',
|
||
bills: [{
|
||
type: '物业费',
|
||
amount: '568.00',
|
||
period: '2023-07-01 至 2023-12-31',
|
||
overdueTime: '2024-01-15'
|
||
}]
|
||
}]
|
||
},
|
||
{
|
||
floor: '2',
|
||
houses: [{
|
||
id: '1-2-201',
|
||
number: '2-2002',
|
||
unpaid: 0,
|
||
owner: '吴女士',
|
||
phone: '13812345685',
|
||
bills: []
|
||
}]
|
||
}
|
||
],
|
||
// 添加5单元和6单元的空数据
|
||
'1-4': [],
|
||
'1-5': [],
|
||
'1-6': []
|
||
});
|
||
|
||
// 获取当前楼栋单元的房屋列表
|
||
const floorHouseList = computed(() => {
|
||
const key = `${activeBuilding.value}-${activeUnit.value}`;
|
||
return houseData[key] || [];
|
||
});
|
||
|
||
// 获取当前选中的楼栋对象
|
||
const getActiveBuilding = () => {
|
||
return buildingList.value.find(item => item.id === activeBuilding.value) || {
|
||
id: '',
|
||
name: ''
|
||
};
|
||
};
|
||
|
||
// 获取单元欠费数量
|
||
const getUnitUnpaidCount = (unit) => {
|
||
const key = `${activeBuilding.value}-${unit}`;
|
||
if (!houseData[key]) return 0;
|
||
|
||
return houseData[key].reduce((total, floor) => {
|
||
return total + floor.houses.filter(house => house.unpaid > 0).length;
|
||
}, 0);
|
||
};
|
||
|
||
// 房屋详情弹窗
|
||
const showHouseDetail = ref(false);
|
||
const selectedHouse = ref({
|
||
id: '',
|
||
number: '',
|
||
unpaid: 0,
|
||
owner: '',
|
||
phone: '',
|
||
bills: []
|
||
});
|
||
|
||
// 显示房屋详情
|
||
const showHouseDetailFunc = (house) => {
|
||
selectedHouse.value = house;
|
||
showHouseDetail.value = true;
|
||
};
|
||
|
||
// 电话催缴
|
||
const callOwner = (house) => {
|
||
uni.makePhoneCall({
|
||
phoneNumber: house.phone,
|
||
success: () => {
|
||
console.log('拨打电话成功');
|
||
},
|
||
fail: () => {
|
||
Toast.fail('拨打电话失败');
|
||
}
|
||
});
|
||
};
|
||
|
||
// 发送通知
|
||
const sendReminder = (house) => {
|
||
Toast.success('已发送催缴通知');
|
||
setTimeout(() => {
|
||
showHouseDetail.value = false;
|
||
}, 1500);
|
||
};
|
||
|
||
// 小区选择确认
|
||
const handleCommunityConfirm = (selected) => {
|
||
selectedCommunity.value = selected[0].id;
|
||
};
|
||
|
||
// 刷新数据
|
||
const handleRefresh = () => {
|
||
Toast.success('数据已刷新');
|
||
};
|
||
|
||
// 页面跳转
|
||
const toPages = (item) => {
|
||
switch (item.type) {
|
||
case 'nav':
|
||
uni.navigateBack({
|
||
delta: 1
|
||
});
|
||
break;
|
||
case 'home':
|
||
uni.switchTab({
|
||
url: '/pages/index/index'
|
||
});
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
};
|
||
|
||
// 生命周期钩子
|
||
onLoad(() => {
|
||
checkRouteStack();
|
||
});
|
||
|
||
// 获取楼栋的欠费住户数量
|
||
const getBuildingUnpaidCount = (buildingId) => {
|
||
let count = 0;
|
||
// 遍历该楼栋的所有单元
|
||
unitList.value.forEach(unit => {
|
||
const key = `${buildingId}-${unit.value}`;
|
||
if (!houseData[key]) return;
|
||
|
||
count += houseData[key].reduce((total, floor) => {
|
||
return total + floor.houses.filter(house => house.unpaid > 0).length;
|
||
}, 0);
|
||
});
|
||
|
||
return count > 0 ? count : '';
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
page {
|
||
background-color: #F7F8FA;
|
||
}
|
||
|
||
.call-page {
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.nav-bg-layer {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: calc(var(--status-bar-height) + 88rpx);
|
||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||
z-index: 10;
|
||
backdrop-filter: blur(10px);
|
||
-webkit-backdrop-filter: blur(10px);
|
||
}
|
||
|
||
.content {
|
||
padding-bottom: constant(safe-area-inset-bottom);
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
.community-switch {
|
||
height: 60rpx;
|
||
padding: 10rpx 20rpx 0;
|
||
border-radius: 30rpx;
|
||
background-color: rgba(62, 155, 255, 0.1);
|
||
}
|
||
|
||
.community-card {
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||
|
||
.community-header {
|
||
background: linear-gradient(135deg, #3e9bff, #2374e1);
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -50%;
|
||
right: -20%;
|
||
width: 400rpx;
|
||
height: 400rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
z-index: 0;
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: -30%;
|
||
left: -10%;
|
||
width: 300rpx;
|
||
height: 300rpx;
|
||
border-radius: 50%;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
z-index: 0;
|
||
}
|
||
}
|
||
|
||
.community-footer {
|
||
border-radius: 0 0 20rpx 20rpx;
|
||
}
|
||
}
|
||
|
||
.building-selector-container {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.building-sidebar-layout {
|
||
display: flex;
|
||
height: calc(100vh - 400rpx);
|
||
}
|
||
|
||
.sidebar-container {
|
||
width: 180rpx;
|
||
flex-shrink: 0;
|
||
height: 100%;
|
||
background-color: #f8f8f8;
|
||
}
|
||
|
||
.content-container {
|
||
flex: 1;
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.building-sidebar {
|
||
height: 100%;
|
||
}
|
||
|
||
::v-deep .wd-sidebar-item {
|
||
font-size: 28rpx;
|
||
padding: 30rpx 20rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
::v-deep .wd-sidebar-item--active {
|
||
background-color: #fff;
|
||
color: #3e9bff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.unit-selector {
|
||
background-color: #fff;
|
||
padding: 30rpx;
|
||
}
|
||
|
||
.unit-buttons {
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.unit-button {
|
||
position: relative;
|
||
width: 140rpx;
|
||
height: 80rpx;
|
||
background-color: #f7f8fa;
|
||
border-radius: 12rpx;
|
||
transition: all 0.2s;
|
||
|
||
&-active {
|
||
background: rgba(62, 155, 255, 0.1);
|
||
border: 1px solid rgba(62, 155, 255, 0.3);
|
||
}
|
||
|
||
.unit-text {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
font-weight: 500;
|
||
|
||
&-active {
|
||
color: #3e9bff;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.unit-badge {
|
||
position: absolute;
|
||
top: -10rpx;
|
||
right: -10rpx;
|
||
min-width: 36rpx;
|
||
height: 36rpx;
|
||
border-radius: 18rpx;
|
||
background-color: #ff4d4f;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 8rpx;
|
||
box-shadow: 0 2rpx 6rpx rgba(255, 77, 79, 0.3);
|
||
}
|
||
|
||
&:active {
|
||
opacity: 0.8;
|
||
transform: scale(0.98);
|
||
}
|
||
}
|
||
|
||
.floor-item {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
margin-bottom: 30rpx;
|
||
|
||
.floor-header {
|
||
background-color: #f5f7fa;
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||
}
|
||
}
|
||
|
||
.house-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.house-card {
|
||
width: 33.33%;
|
||
padding: 10rpx;
|
||
box-sizing: border-box;
|
||
|
||
@media screen and (max-width: 768rpx) {
|
||
width: 33.33%;
|
||
}
|
||
|
||
@media screen and (max-width: 580rpx) {
|
||
width: 50%;
|
||
}
|
||
|
||
&-inner {
|
||
background-color: #fff;
|
||
border-radius: 12rpx;
|
||
padding: 15rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
border: 1px solid rgba(0, 0, 0, 0.03);
|
||
transition: all 0.2s;
|
||
height: 180rpx;
|
||
justify-content: center;
|
||
|
||
&:active {
|
||
background-color: #f9f9f9;
|
||
transform: scale(0.98);
|
||
}
|
||
}
|
||
|
||
.house-icon {
|
||
position: relative;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
background-color: #eef6ff;
|
||
border-radius: 40rpx;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.unpaid-badge {
|
||
position: absolute;
|
||
top: -10rpx;
|
||
right: -10rpx;
|
||
min-width: 40rpx;
|
||
height: 40rpx;
|
||
border-radius: 20rpx;
|
||
background-color: #ff4d4f;
|
||
color: #fff;
|
||
font-size: 22rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 10rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(255, 77, 79, 0.3);
|
||
}
|
||
|
||
.house-info {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
|
||
.li-text-30 {
|
||
font-size: 28rpx;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
max-width: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.house-detail {
|
||
height: 100%;
|
||
border-radius: 24rpx 24rpx 0 0;
|
||
overflow: hidden;
|
||
background-color: #fff;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.detail-header {
|
||
padding-top: constant(safe-area-inset-top);
|
||
padding-top: env(safe-area-inset-top);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.detail-content-scroll {
|
||
flex: 1;
|
||
height: calc(100% - 120rpx);
|
||
}
|
||
|
||
.detail-content {
|
||
padding-bottom: constant(safe-area-inset-bottom);
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
.bill-item {
|
||
background-color: #f9f9f9;
|
||
border-radius: 16rpx;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.li-bottom-border {
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||
}
|
||
}
|
||
|
||
.empty-state {
|
||
min-height: 300rpx;
|
||
}
|
||
|
||
::v-deep .wd-navbar__placeholder {
|
||
height: calc(var(--status-bar-height) + 88rpx) !important;
|
||
padding-top: constant(safe-area-inset-top) !important;
|
||
padding-top: env(safe-area-inset-top) !important;
|
||
}
|
||
</style> |