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> |