Initial project commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onPullDownRefresh, onReachBottom, onShow } from "@dcloudio/uni-app";
|
||||
import { getFavorites } from "@/api/favorite";
|
||||
import { extractList } from "@/utils/request";
|
||||
import { checkLogin } from "@/utils/auth";
|
||||
import SpotCard from "@/components/spot-card/spot-card.vue";
|
||||
|
||||
onShow(() => { checkLogin(); });
|
||||
|
||||
const favorites = ref([]);
|
||||
const page = ref(1);
|
||||
const pageSize = 10;
|
||||
const hasMore = ref(true);
|
||||
const loading = ref(false);
|
||||
|
||||
const fetchFavorites = async (reset = false) => {
|
||||
if (loading.value) return;
|
||||
if (!reset && !hasMore.value) return;
|
||||
|
||||
loading.value = true;
|
||||
if (reset) {
|
||||
page.value = 1;
|
||||
hasMore.value = true;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getFavorites({ page: page.value, page_size: pageSize });
|
||||
const list = extractList(res);
|
||||
|
||||
if (reset) {
|
||||
favorites.value = list;
|
||||
} else {
|
||||
favorites.value.push(...list);
|
||||
}
|
||||
|
||||
if (list.length < pageSize) {
|
||||
hasMore.value = false;
|
||||
} else {
|
||||
page.value++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const goDetail = (item) => {
|
||||
const id = item.spot_id || item.spot?.id || item.id;
|
||||
if (id) {
|
||||
uni.navigateTo({ url: `/pages/spot/detail?id=${id}` });
|
||||
}
|
||||
};
|
||||
|
||||
onPullDownRefresh(async () => {
|
||||
await fetchFavorites(true);
|
||||
uni.stopPullDownRefresh();
|
||||
});
|
||||
|
||||
onReachBottom(() => {
|
||||
fetchFavorites();
|
||||
});
|
||||
|
||||
fetchFavorites(true);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="favorites-page">
|
||||
<view class="list">
|
||||
<SpotCard
|
||||
v-for="item in favorites"
|
||||
:key="item.id"
|
||||
:spot="item.spot || item"
|
||||
@click="goDetail(item)"
|
||||
/>
|
||||
|
||||
<view v-if="loading" class="status-tip">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
<view v-else-if="!hasMore && favorites.length > 0" class="status-tip">
|
||||
<text>没有更多了</text>
|
||||
</view>
|
||||
<view v-else-if="!loading && favorites.length === 0" class="empty-state">
|
||||
<uni-icons type="heart-filled" size="48" color="#6366f1" class="empty-icon" />
|
||||
<text class="empty-title">暂无收藏</text>
|
||||
<text class="empty-desc">去发现页浏览并收藏喜欢的取景地吧</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.favorites-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f6fa;
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: 24rpx 32rpx;
|
||||
}
|
||||
|
||||
.status-tip {
|
||||
text-align: center;
|
||||
padding: 40rpx 0;
|
||||
color: #94a3b8;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 160rpx 0;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 96rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.empty-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.empty-desc {
|
||||
font-size: 26rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user