feat: 添加租户列表接口,优化租户相关功能;更新前端租户列表和收藏功能
This commit is contained in:
@@ -1,3 +1,49 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { contentApi } from '../../api/content';
|
||||
|
||||
const contents = ref([]);
|
||||
const searchKeyword = ref('');
|
||||
const loading = ref(true);
|
||||
const page = ref(1);
|
||||
const hasMore = ref(false);
|
||||
|
||||
const fetchContents = async (append = false) => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
page: page.value,
|
||||
limit: 10,
|
||||
sort: 'latest',
|
||||
keyword: searchKeyword.value
|
||||
};
|
||||
const res = await contentApi.list(params);
|
||||
if (append) {
|
||||
contents.value.push(...(res.items || []));
|
||||
} else {
|
||||
contents.value = res.items || [];
|
||||
}
|
||||
hasMore.value = (res.total > contents.value.length);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
page.value = 1;
|
||||
fetchContents();
|
||||
};
|
||||
|
||||
const loadMore = () => {
|
||||
page.value++;
|
||||
fetchContents(true);
|
||||
};
|
||||
|
||||
onMounted(() => fetchContents());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mx-auto max-w-screen-xl py-8">
|
||||
<!-- Hero Banner -->
|
||||
@@ -30,13 +76,19 @@
|
||||
|
||||
<!-- Filter Bar -->
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center gap-8 border-b border-slate-200 pb-4 mb-4">
|
||||
<button
|
||||
class="text-lg font-bold text-primary-600 border-b-2 border-primary-600 -mb-4.5 pb-4 px-2">推荐</button>
|
||||
<button
|
||||
class="text-lg font-medium text-slate-500 hover:text-slate-800 -mb-4.5 pb-4 px-2 transition-colors">最新</button>
|
||||
<button
|
||||
class="text-lg font-medium text-slate-500 hover:text-slate-800 -mb-4.5 pb-4 px-2 transition-colors">热门</button>
|
||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6 border-b border-slate-200 pb-4">
|
||||
<div class="flex items-center gap-8">
|
||||
<button class="text-lg font-bold text-primary-600 border-b-2 border-primary-600 -mb-4.5 pb-4 px-2">推荐</button>
|
||||
<button class="text-lg font-medium text-slate-500 hover:text-slate-800 -mb-4.5 pb-4 px-2 transition-colors">最新</button>
|
||||
<button class="text-lg font-medium text-slate-500 hover:text-slate-800 -mb-4.5 pb-4 px-2 transition-colors">热门</button>
|
||||
</div>
|
||||
|
||||
<!-- Global Search -->
|
||||
<div class="relative">
|
||||
<i class="pi pi-search absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"></i>
|
||||
<input type="text" v-model="searchKeyword" @keyup.enter="handleSearch" placeholder="搜索全站内容..."
|
||||
class="h-10 pl-10 pr-4 rounded-full border border-slate-200 bg-slate-50 text-sm focus:bg-white focus:border-primary-500 focus:outline-none w-full md:w-64 transition-all">
|
||||
</div>
|
||||
</div>
|
||||
<!-- Tags -->
|
||||
<div class="flex flex-wrap gap-3">
|
||||
@@ -94,10 +146,11 @@
|
||||
</router-link>
|
||||
|
||||
<!-- Load More -->
|
||||
<div class="pt-4 text-center">
|
||||
<button
|
||||
class="px-8 py-3 bg-white border border-slate-200 rounded-full text-slate-600 hover:bg-slate-50 hover:text-primary-600 font-medium transition-all shadow-sm">
|
||||
点击加载更多内容
|
||||
<div class="pt-4 text-center" v-if="hasMore">
|
||||
<button @click="loadMore" :disabled="loading"
|
||||
class="px-8 py-3 bg-white border border-slate-200 rounded-full text-slate-600 hover:bg-slate-50 hover:text-primary-600 font-medium transition-all shadow-sm disabled:opacity-50">
|
||||
<span v-if="loading">加载中...</span>
|
||||
<span v-else>点击加载更多内容</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -198,4 +251,34 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { contentApi } from '../api/content';
|
||||
|
||||
const contents = ref([]);
|
||||
const searchKeyword = ref('');
|
||||
const loading = ref(true);
|
||||
|
||||
const fetchContents = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
limit: 20,
|
||||
sort: 'latest',
|
||||
keyword: searchKeyword.value
|
||||
};
|
||||
const res = await contentApi.list(params);
|
||||
contents.value = res.items || [];
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleSearch = () => {
|
||||
fetchContents();
|
||||
};
|
||||
|
||||
onMounted(fetchContents);
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user