110 lines
3.1 KiB
Vue
110 lines
3.1 KiB
Vue
<script lang="ts" setup>
|
|
import {computed, onMounted, ref} from "vue";
|
|
import {getBlogRecentPost} from "~/api/blog";
|
|
import {getActivity} from "~/api/git"
|
|
|
|
const recentPosts = ref<IPost[] | null>(null);
|
|
const recentActivities = ref<IActivity[] | null>(null);
|
|
const isLoading = ref({
|
|
blog: true,
|
|
git: true
|
|
});
|
|
const isError = ref({
|
|
blog: false,
|
|
git: false
|
|
});
|
|
|
|
const hasPosts = computed(() => (recentPosts.value ?? []).length > 0);
|
|
const hasActivities = computed(() => (recentActivities.value ?? []).length > 0);
|
|
const postsData = computed(() => {
|
|
if (!recentPosts.value) return [];
|
|
if (recentPosts.value.length > 4)
|
|
return recentPosts.value.slice(0, 4)
|
|
return recentPosts.value
|
|
})
|
|
const activitiesData = computed((): IActivity<IContent>[] => {
|
|
if (!Array.isArray(recentActivities.value)) return [];
|
|
return recentActivities.value.map(item => {
|
|
try {
|
|
if (item.op_type === "commit_repo")
|
|
return {
|
|
...item,
|
|
content: JSON.parse(item.content)
|
|
}
|
|
else return null
|
|
} catch (e) {
|
|
return null
|
|
}
|
|
}).filter(item => item !== null)
|
|
})
|
|
|
|
const reloadPosts = async () => {
|
|
try {
|
|
isLoading.value.blog = true
|
|
const postData = await getBlogRecentPost();
|
|
recentPosts.value = postData.data.dataSet
|
|
isLoading.value.blog = false
|
|
} catch (e) {
|
|
isLoading.value.blog = false
|
|
isError.value.blog = true
|
|
}
|
|
}
|
|
|
|
const reloadActivities = async () => {
|
|
try {
|
|
isLoading.value.git = true
|
|
recentActivities.value = await getActivity()
|
|
isLoading.value.git = false
|
|
} catch (e) {
|
|
isLoading.value.git = false
|
|
isError.value.git = true
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await reloadPosts()
|
|
await reloadActivities()
|
|
|
|
emitter.emit('startLoading', false)
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<!-- 个人介绍 -->
|
|
<card-full-screen-intro-card/>
|
|
|
|
<div class="container mx-auto mt-8 xl:max-w-screen-xl">
|
|
<!-- 博客部分 -->
|
|
<section class="w-full px-4 sm:px-0">
|
|
<!-- 标题部分 -->
|
|
<card-title :icon="['fas', 'blog']" main-color="bg-rose-500" sub-color="bg-rose-600" title="最新博文"
|
|
url="/blog/"/>
|
|
|
|
<card-section-card :empty="!hasPosts" :error="isError.blog" :loading="isLoading.blog" @reload="reloadPosts">
|
|
<template v-slot:default>
|
|
<div class="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
|
<card-article-card v-for="item in postsData" :key="item.cid" :post="item"/>
|
|
</div>
|
|
</template>
|
|
</card-section-card>
|
|
</section>
|
|
|
|
<!-- Git部分 -->
|
|
<section class="my-4 w-full px-4 sm:px-0">
|
|
<card-title :icon="['fas', 'code']" main-color="bg-green-500" sub-color="bg-green-600" title="最近活动"
|
|
url="/git/"/>
|
|
|
|
<card-section-card :empty="!hasActivities" :error="isError.git" :loading="isLoading.git" @reload="reloadActivities">
|
|
<template v-slot:default>
|
|
<div class="grid w-full grid-cols-1 gap-4 lg:grid-cols-2">
|
|
<card-git-card v-for="item in activitiesData" :key="item.id" :commit="item"/>
|
|
</div>
|
|
</template>
|
|
</card-section-card>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style> |