134 lines
3.1 KiB
Vue
134 lines
3.1 KiB
Vue
|
<template>
|
|||
|
<div class="conference-list">
|
|||
|
<a-list
|
|||
|
:grid="{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 4, xxl: 4 }"
|
|||
|
:data-source="conferenceList"
|
|||
|
:loading="loading"
|
|||
|
class="conference-list-content"
|
|||
|
v-infinite-scroll="loadMore"
|
|||
|
:infinite-scroll-disabled="disabled"
|
|||
|
:infinite-scroll-distance="10"
|
|||
|
>
|
|||
|
<template #renderItem="{ item }">
|
|||
|
<a-list-item>
|
|||
|
<a-card :title="item.name" :bordered="false" class="conference-card">
|
|||
|
<template #cover>
|
|||
|
<img
|
|||
|
alt="会议室图片"
|
|||
|
:src="item.image || '/placeholder-image.jpg'"
|
|||
|
style="height: 200px; object-fit: cover;"
|
|||
|
/>
|
|||
|
</template>
|
|||
|
<a-card-meta :title="item.name">
|
|||
|
<template #description>
|
|||
|
<div class="conference-info">
|
|||
|
<p>容纳人数:{{ item.capacity }}人</p>
|
|||
|
<p>位置:{{ item.location }}</p>
|
|||
|
<p>设备:{{ item.facilities }}</p>
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
</a-card-meta>
|
|||
|
<div class="card-actions">
|
|||
|
<a-button type="primary" @click="handleReservation(item)">
|
|||
|
去预约
|
|||
|
</a-button>
|
|||
|
</div>
|
|||
|
</a-card>
|
|||
|
</a-list-item>
|
|||
|
</template>
|
|||
|
</a-list>
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
|
|||
|
<script lang="ts" setup>
|
|||
|
import { ref, computed } from 'vue';
|
|||
|
import { requestClient } from '../../../../api/request';
|
|||
|
|
|||
|
interface ConferenceRoom {
|
|||
|
id: string;
|
|||
|
name: string;
|
|||
|
capacity: number;
|
|||
|
location: string;
|
|||
|
facilities: string;
|
|||
|
image?: string;
|
|||
|
}
|
|||
|
|
|||
|
const pageSize = 20;
|
|||
|
const currentPage = ref(1);
|
|||
|
const loading = ref(false);
|
|||
|
const conferenceList = ref<ConferenceRoom[]>([]);
|
|||
|
const noMore = ref(false);
|
|||
|
|
|||
|
const disabled = computed(() => loading.value || noMore.value);
|
|||
|
|
|||
|
const fetchConferenceList = async (page: number) => {
|
|||
|
try {
|
|||
|
loading.value = true;
|
|||
|
const res = await requestClient.get<{
|
|||
|
list: ConferenceRoom[];
|
|||
|
total: number;
|
|||
|
}>('/property/conference/list', {
|
|||
|
params: {
|
|||
|
pageSize,
|
|||
|
pageNum: page,
|
|||
|
},
|
|||
|
});
|
|||
|
|
|||
|
if (page === 1) {
|
|||
|
conferenceList.value = res.list;
|
|||
|
} else {
|
|||
|
conferenceList.value = [...conferenceList.value, ...res.list];
|
|||
|
}
|
|||
|
|
|||
|
noMore.value = conferenceList.value.length >= res.total;
|
|||
|
} finally {
|
|||
|
loading.value = false;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const loadMore = async () => {
|
|||
|
if (disabled.value) return;
|
|||
|
currentPage.value++;
|
|||
|
await fetchConferenceList(currentPage.value);
|
|||
|
};
|
|||
|
|
|||
|
const handleReservation = (room: ConferenceRoom) => {
|
|||
|
// TODO: 实现预约逻辑
|
|||
|
console.log('预约会议室:', room);
|
|||
|
};
|
|||
|
|
|||
|
// 初始加载
|
|||
|
fetchConferenceList(1);
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
.conference-list {
|
|||
|
padding: 16px;
|
|||
|
height: 100%;
|
|||
|
overflow: hidden;
|
|||
|
|
|||
|
.conference-list-content {
|
|||
|
height: calc(100vh - 120px);
|
|||
|
overflow-y: auto;
|
|||
|
}
|
|||
|
|
|||
|
.conference-card {
|
|||
|
transition: all 0.3s;
|
|||
|
|
|||
|
&:hover {
|
|||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|||
|
}
|
|||
|
|
|||
|
.conference-info {
|
|||
|
p {
|
|||
|
margin-bottom: 8px;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
.card-actions {
|
|||
|
margin-top: 16px;
|
|||
|
text-align: right;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|