添加最近活动
This commit is contained in:
parent
186086c0bd
commit
c0a7097fd2
@ -2,12 +2,15 @@ import {request} from "@/utils/network.ts";
|
||||
|
||||
const TOKEN = "fb8aec429ea7d0a36f7238dbffda9d2d66c7b045"
|
||||
|
||||
export async function getActivity() {
|
||||
export async function getActivity(): Promise<IActivity[]> {
|
||||
return request({
|
||||
url: '/git/api/v1/users/cantyonion/activities/feeds',
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: ` ${TOKEN}`
|
||||
Authorization: ` ${TOKEN}`,
|
||||
},
|
||||
params: {
|
||||
limit: 4
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<div class="mb-4 flex justify-between text-2xl font-bold text-white">
|
||||
<div :class="mainColor" class="flex w-max items-center justify-center overflow-hidden rounded-2xl bg-rose-500">
|
||||
<div :class="[mainColor]" class="flex w-max items-center justify-center overflow-hidden rounded-2xl">
|
||||
<div :class="[subColor]" class="flex h-full w-14 items-center justify-center rounded-2xl px-4 py-2 text-center">
|
||||
<font-awesome-icon :icon="icon"/>
|
||||
</div>
|
||||
|
76
src/components/card/GitCard.vue
Normal file
76
src/components/card/GitCard.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<script lang="ts" setup>
|
||||
import {FontAwesomeIcon} from "@fortawesome/vue-fontawesome";
|
||||
import {computed} from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
commit: IActivity<IContent>
|
||||
}>()
|
||||
|
||||
const icon = computed(() => {
|
||||
switch (props.commit.op_type) {
|
||||
case "merge_pull_request":
|
||||
return ['fas', 'code-merge']
|
||||
case "create_repo":
|
||||
return ['fab', 'git-alt']
|
||||
case "commit_repo":
|
||||
default:
|
||||
return ['fas', 'code-commit']
|
||||
}
|
||||
})
|
||||
|
||||
const time = computed(() => timeDifference(props.commit.created))
|
||||
|
||||
const timeDifference = (dateString: string): string => {
|
||||
const targetDate = new Date(dateString);
|
||||
const currentDate = new Date();
|
||||
|
||||
const diffInMillis = currentDate.getTime() - targetDate.getTime();
|
||||
|
||||
const minutes = Math.floor(diffInMillis / (1000 * 60));
|
||||
const hours = Math.floor(diffInMillis / (1000 * 60 * 60));
|
||||
const days = Math.floor(diffInMillis / (1000 * 60 * 60 * 24));
|
||||
const months = Math.floor(diffInMillis / (1000 * 60 * 60 * 24 * 30));
|
||||
const years = Math.floor(diffInMillis / (1000 * 60 * 60 * 24 * 365));
|
||||
|
||||
if (minutes < 60) {
|
||||
return `${minutes} 分钟前`;
|
||||
} else if (hours < 24) {
|
||||
return `${hours} 小时前`;
|
||||
} else if (days < 30) {
|
||||
return `${days} 天前`;
|
||||
} else if (months < 12) {
|
||||
return `${months} 个月前`;
|
||||
} else {
|
||||
return `${years} 年前`;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container relative flex h-36 w-full overflow-hidden rounded-2xl hover:shadow-md transition-all">
|
||||
<!-- 提交图标 -->
|
||||
<div class="flex h-36 w-36 items-center justify-center bg-pink-300 text-5xl text-white">
|
||||
<font-awesome-icon :icon="icon"/>
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div class="flex-1 bg-white p-4 overflow-hidden">
|
||||
<div class="text-2xl font-bold mr-12 truncate">
|
||||
仓库:{{ commit.repo.name }}
|
||||
</div>
|
||||
<span class="text-xl">{{ commit.content.HeadCommit.Message }}</span>
|
||||
<span class="absolute top-0 right-0 m-4 bg-gray-300 px-2 rounded hidden sm:block">
|
||||
{{ commit.content.HeadCommit.Sha1.slice(0, 10) }}
|
||||
</span>
|
||||
|
||||
<span class="absolute bottom-0 right-0 m-4 bg-gray-300 px-2 rounded">
|
||||
<font-awesome-icon :icon="['far', 'clock']" class="mr-1 text-sm"/>
|
||||
{{ time }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -22,7 +22,7 @@ const handleReload = () => {
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-else class="w-full">
|
||||
<!-- 错误处理 -->
|
||||
<div v-if="error" class="flex h-56 flex-col items-center justify-center" @click="handleReload">
|
||||
<span class="mb-4 text-8xl">❌</span>
|
||||
|
@ -15,11 +15,11 @@ import {
|
||||
faChevronRight,
|
||||
faCodeCommit
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {faWeibo, faQq, faGithubAlt, faSteamSymbol} from '@fortawesome/free-brands-svg-icons'
|
||||
import {faWeibo, faQq, faGithubAlt, faSteamSymbol, faGitAlt} from '@fortawesome/free-brands-svg-icons'
|
||||
|
||||
library.add(
|
||||
faClock, faXmark, faBlog, faGauge, faCodeBranch, faCloud, faWeibo, faQq, faGithubAlt, faSteamSymbol, faChevronRight,
|
||||
faCodeCommit
|
||||
faCodeCommit, faGitAlt
|
||||
)
|
||||
|
||||
createApp(App).use(router).component('font-awesome-icon', FontAwesomeIcon).mount('#app')
|
||||
|
27
src/types/git.d.ts
vendored
Normal file
27
src/types/git.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
declare interface IActivity<T = string> {
|
||||
id: string;
|
||||
content: T
|
||||
op_type: string
|
||||
repo: {
|
||||
name: string
|
||||
html_url: string
|
||||
}
|
||||
created: string
|
||||
}
|
||||
|
||||
declare interface IContent {
|
||||
Commits: ICommit[]
|
||||
HeadCommit: ICommit
|
||||
CompareURL: string
|
||||
Len: number
|
||||
}
|
||||
|
||||
declare interface ICommit {
|
||||
Sha1: string,
|
||||
Message: string,
|
||||
AuthorEmail: string,
|
||||
AuthorName: string,
|
||||
CommitterEmail: string,
|
||||
CommitterName: string,
|
||||
Timestamp: string
|
||||
}
|
@ -6,8 +6,11 @@ import NavBar from "@/components/nav/NavBar.vue";
|
||||
import IntroCard from "@/components/card/IntroCard.vue";
|
||||
import CardTitle from "@/components/card/CardTitle.vue";
|
||||
import SectionCard from "@/components/card/SectionCard.vue";
|
||||
import {getActivity} from "@/api/git.ts";
|
||||
import GitCard from "@/components/card/GitCard.vue";
|
||||
|
||||
const recentPosts = ref<IPost[] | null>(null);
|
||||
const recentActivities = ref<IActivity[] | null>(null);
|
||||
const isLoading = ref({
|
||||
blog: true,
|
||||
git: true
|
||||
@ -18,12 +21,21 @@ const isError = ref({
|
||||
});
|
||||
|
||||
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 (!recentActivities.value) return [];
|
||||
return recentActivities.value.map(obj => ({
|
||||
...obj,
|
||||
content: JSON.parse(obj.content)
|
||||
}))
|
||||
})
|
||||
|
||||
|
||||
const reloadPosts = async () => {
|
||||
try {
|
||||
@ -37,15 +49,21 @@ const reloadPosts = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const reloadActivities = async () => {
|
||||
try {
|
||||
const postData = await getBlogRecentPost();
|
||||
recentPosts.value = postData.data.dataSet
|
||||
isLoading.value.blog = false
|
||||
isLoading.value.git = true
|
||||
recentActivities.value = await getActivity()
|
||||
console.log(recentActivities.value)
|
||||
isLoading.value.git = false
|
||||
} catch (e) {
|
||||
isLoading.value.blog = false
|
||||
isError.value.blog = true
|
||||
isLoading.value.git = false
|
||||
isError.value.git = true
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await reloadPosts()
|
||||
await reloadActivities()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -75,6 +93,14 @@ onMounted(async () => {
|
||||
<section class="my-4 w-full px-4 sm:px-0">
|
||||
<card-title :icon="['fas', 'code-commit']" main-color="bg-green-500" sub-color="bg-green-600" title="最近活动"
|
||||
url="/git/"/>
|
||||
|
||||
<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">
|
||||
<git-card v-for="item in activitiesData" :key="item.id" :commit="item"/>
|
||||
</div>
|
||||
</template>
|
||||
</section-card>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user