2025-03-03 19:59:03 +08:00
|
|
|
|
<template>
|
|
|
|
|
<div class="home-container">
|
|
|
|
|
<el-main>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
<!-- 左侧正文 -->
|
|
|
|
|
<el-col :span="16">
|
|
|
|
|
<el-card>
|
2025-03-05 10:36:42 +08:00
|
|
|
|
<p>某校 SE 专业学生,前 CChOer 。</p>
|
|
|
|
|
<p>什么都会一点。</p>
|
|
|
|
|
<p>
|
2025-03-05 10:57:21 +08:00
|
|
|
|
可以通过这个邮箱联系我:
|
2025-03-05 10:36:42 +08:00
|
|
|
|
<a href="mailto:admin@kisechan.space">admin@kisechan.space</a>
|
|
|
|
|
</p>
|
2025-03-05 12:28:48 +08:00
|
|
|
|
<hr />
|
2025-03-05 10:12:08 +08:00
|
|
|
|
<div class="github-calendar-container">
|
2025-03-06 08:26:05 +08:00
|
|
|
|
<h3>My Github Contributions</h3>
|
2025-03-06 14:11:21 +08:00
|
|
|
|
<div id="github-graph"></div>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
</div>
|
2025-03-06 08:26:05 +08:00
|
|
|
|
<hr />
|
|
|
|
|
<div class="rss-feed-container">
|
|
|
|
|
<h3>Latest Blog Posts</h3>
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
<el-col v-for="item in feedItems" :key="item.link" :span="24">
|
|
|
|
|
<el-card class="blog-card" shadow="hover">
|
|
|
|
|
<div class="blog-header">
|
2025-03-06 15:40:09 +08:00
|
|
|
|
<i class="fa-solid fa-newspaper"></i>
|
2025-03-06 08:26:05 +08:00
|
|
|
|
<a :href="item.link" target="_blank" class="blog-title">{{
|
|
|
|
|
item.title
|
|
|
|
|
}}</a>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="blog-meta">
|
2025-03-06 15:40:09 +08:00
|
|
|
|
<i class="fa-solid fa-clock-rotate-left"></i>
|
2025-03-06 08:26:05 +08:00
|
|
|
|
<span class="update-time">
|
|
|
|
|
{{ formatDate(item.pubDate) }}
|
|
|
|
|
</span>
|
|
|
|
|
<span class="tags">
|
2025-03-06 15:40:09 +08:00
|
|
|
|
<i class="fa-solid fa-tags"></i>
|
2025-03-06 08:26:05 +08:00
|
|
|
|
<el-tag
|
|
|
|
|
v-for="(tag, index) in item.tags"
|
|
|
|
|
:key="index"
|
|
|
|
|
size="small"
|
|
|
|
|
type="info"
|
|
|
|
|
class="tag"
|
|
|
|
|
>
|
|
|
|
|
{{ tag }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
2025-03-06 14:11:21 +08:00
|
|
|
|
<div class="read-more-container">
|
2025-03-06 15:40:09 +08:00
|
|
|
|
<el-tooltip
|
|
|
|
|
content="前往博客查看更多文章"
|
|
|
|
|
placement="top"
|
|
|
|
|
class="read-more-tooltip"
|
|
|
|
|
>
|
|
|
|
|
<el-card
|
|
|
|
|
class="read-more-card"
|
|
|
|
|
shadow="hover"
|
|
|
|
|
@click="goToBlog"
|
|
|
|
|
>
|
|
|
|
|
<div class="read-more-content">
|
|
|
|
|
<span>Read More</span>
|
|
|
|
|
<i class="fa-brands fa-readme"></i>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-tooltip>
|
2025-03-06 14:11:21 +08:00
|
|
|
|
</div>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
|
|
<!-- 右侧作者信息 -->
|
2025-03-05 12:28:48 +08:00
|
|
|
|
<el-col class="right-column" :span="8">
|
2025-03-05 10:12:08 +08:00
|
|
|
|
<div class="author-info">
|
|
|
|
|
<el-avatar :size="120" :src="avatarUrl" />
|
2025-03-05 12:28:48 +08:00
|
|
|
|
<h2>Hello</h2>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
<i>"Non est ad astra mollis e trris via."</i>
|
|
|
|
|
</div>
|
2025-03-05 12:28:48 +08:00
|
|
|
|
<div class="social-icons">
|
|
|
|
|
<a href="https://github.com/Kisechan" target="_blank">
|
|
|
|
|
<i class="fab fa-github"></i>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="https://www.zhihu.com/people/ptkise" target="_blank">
|
|
|
|
|
<i class="fab fa-zhihu"></i>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="https://space.bilibili.com/174541536" target="_blank">
|
|
|
|
|
<i class="fab fa-bilibili"></i>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="https://blog.kisechan.space" target="_blank">
|
|
|
|
|
<i class="fa-solid fa-blog"></i>
|
|
|
|
|
</a>
|
|
|
|
|
<a href="mailto:admin@kisechan.space" target="_blank">
|
|
|
|
|
<i class="fa-solid fa-envelope"></i>
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
2025-03-05 22:23:00 +08:00
|
|
|
|
<div class="footer-content">
|
|
|
|
|
<p>
|
|
|
|
|
<a href="https://icp.gov.moe/?keyword=20251453" target="_blank"
|
|
|
|
|
>萌ICP备20251453号</a
|
|
|
|
|
>
|
|
|
|
|
</p>
|
|
|
|
|
<p>
|
|
|
|
|
© 2025 By
|
|
|
|
|
<a
|
|
|
|
|
href="https://github.com/Kisechan"
|
|
|
|
|
target="_blank"
|
|
|
|
|
rel="nofollow noopener"
|
|
|
|
|
><strong>Kisechan</strong></a
|
|
|
|
|
>
|
|
|
|
|
</p>
|
|
|
|
|
<p style="font-size: 0.75em">
|
|
|
|
|
Made With <a href="https://cn.vuejs.org/">Vue3</a> &
|
|
|
|
|
<a href="https://element-plus.org/zh-CN/">Element Plus</a>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
2025-03-03 19:59:03 +08:00
|
|
|
|
</el-main>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-03-05 10:12:08 +08:00
|
|
|
|
import avatarUrl from "@/assets/avatar.png";
|
2025-03-06 13:45:39 +08:00
|
|
|
|
import { ref, onMounted, onUnmounted } from "vue";
|
2025-03-05 10:12:08 +08:00
|
|
|
|
|
2025-03-05 18:37:37 +08:00
|
|
|
|
const isLoaded = ref(false);
|
2025-03-06 08:26:05 +08:00
|
|
|
|
const feedItems = ref([]);
|
2025-03-06 13:45:39 +08:00
|
|
|
|
const githubCalendarInstance = ref(null); // 提升到组件作用域
|
|
|
|
|
|
2025-03-05 18:37:37 +08:00
|
|
|
|
const loadGitHubCalendar = async () => {
|
2025-03-06 13:45:39 +08:00
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 100)); // 延迟 100ms
|
|
|
|
|
const calendarElement = document.getElementById("github-graph");
|
|
|
|
|
if (!calendarElement) {
|
|
|
|
|
console.error("Element #github-graph not found");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 18:37:37 +08:00
|
|
|
|
const GitHubCalendar = await import("github-calendar");
|
2025-03-06 14:11:21 +08:00
|
|
|
|
githubCalendarInstance.value = GitHubCalendar.default(
|
|
|
|
|
calendarElement,
|
|
|
|
|
"Kisechan",
|
|
|
|
|
{
|
|
|
|
|
responsive: true,
|
|
|
|
|
tooltips: true,
|
|
|
|
|
global_stats: false,
|
|
|
|
|
}
|
|
|
|
|
);
|
2025-03-05 18:37:37 +08:00
|
|
|
|
isLoaded.value = true;
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-06 13:45:39 +08:00
|
|
|
|
const cleanupGitHubCalendar = () => {
|
|
|
|
|
const calendarElement = document.getElementById("github-graph");
|
|
|
|
|
if (calendarElement) {
|
|
|
|
|
calendarElement.innerHTML = ""; // 清空日历内容
|
|
|
|
|
}
|
|
|
|
|
if (githubCalendarInstance.value) {
|
|
|
|
|
githubCalendarInstance.value = null; // 清理实例
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-06 08:26:05 +08:00
|
|
|
|
const fetchRSSFeed = async () => {
|
2025-03-06 13:45:39 +08:00
|
|
|
|
const rssUrl = "https://blog.kisechan.space/atom.xml";
|
2025-03-06 08:26:05 +08:00
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(rssUrl);
|
|
|
|
|
const str = await response.text();
|
|
|
|
|
const data = new window.DOMParser().parseFromString(str, "text/xml");
|
|
|
|
|
const items = data.querySelectorAll("entry");
|
|
|
|
|
|
2025-03-06 13:45:39 +08:00
|
|
|
|
feedItems.value = Array.from(items)
|
2025-03-06 14:11:21 +08:00
|
|
|
|
.map((item) => ({
|
2025-03-06 13:45:39 +08:00
|
|
|
|
title: item.querySelector("title").textContent,
|
|
|
|
|
link: item.querySelector("link").getAttribute("href"),
|
|
|
|
|
pubDate: item.querySelector("updated").textContent,
|
2025-03-06 14:11:21 +08:00
|
|
|
|
tags: Array.from(item.querySelectorAll("category")).map((category) =>
|
|
|
|
|
category.getAttribute("term")
|
2025-03-06 13:45:39 +08:00
|
|
|
|
),
|
|
|
|
|
}))
|
|
|
|
|
.slice(0, 6); // 只取前 6 篇文章
|
2025-03-06 08:26:05 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error fetching RSS Feed:", error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formatDate = (dateString) => {
|
|
|
|
|
const date = new Date(dateString);
|
|
|
|
|
return date.toLocaleDateString();
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-06 14:11:21 +08:00
|
|
|
|
const goToBlog = () => {
|
|
|
|
|
window.open("https://blog.kisechan.space", "_blank");
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-05 18:37:37 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
loadGitHubCalendar();
|
2025-03-06 08:26:05 +08:00
|
|
|
|
fetchRSSFeed();
|
2025-03-05 10:12:08 +08:00
|
|
|
|
});
|
2025-03-06 13:45:39 +08:00
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
cleanupGitHubCalendar();
|
|
|
|
|
});
|
2025-03-03 19:59:03 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
2025-03-05 10:12:08 +08:00
|
|
|
|
<style scoped>
|
|
|
|
|
.home-container {
|
|
|
|
|
padding: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.author-info {
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.el-avatar {
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.github-calendar-container {
|
|
|
|
|
margin: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#github-graph {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 800px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
2025-03-05 12:28:48 +08:00
|
|
|
|
|
|
|
|
|
.social-icons a {
|
|
|
|
|
color: #303133;
|
|
|
|
|
margin: 0 10px;
|
|
|
|
|
font-size: 24px;
|
2025-03-05 18:37:37 +08:00
|
|
|
|
transition: color 0.3s ease, transform 0.3s ease;
|
2025-03-05 12:28:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.social-icons a:hover {
|
|
|
|
|
color: rgb(159.5, 206.5, 255);
|
2025-03-05 18:37:37 +08:00
|
|
|
|
transform: scale(1.2);
|
2025-03-05 12:28:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-03-05 12:50:42 +08:00
|
|
|
|
.social-icons {
|
2025-03-05 12:28:48 +08:00
|
|
|
|
max-width: 1200px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.right-column {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2025-03-06 08:26:05 +08:00
|
|
|
|
gap: 24px;
|
2025-03-05 12:28:48 +08:00
|
|
|
|
}
|
2025-03-05 22:23:00 +08:00
|
|
|
|
|
|
|
|
|
.footer-content {
|
|
|
|
|
max-width: 1200px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
2025-03-06 08:26:05 +08:00
|
|
|
|
|
|
|
|
|
.rss-feed-container {
|
|
|
|
|
max-width: 800px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-card {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-card:hover {
|
|
|
|
|
transform: translateY(-5px);
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-title {
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: #303133;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-title:hover {
|
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.blog-meta {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
color: #606266;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.update-time,
|
|
|
|
|
.tags {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-right: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
margin-right: 5px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.tag {
|
|
|
|
|
margin-left: 5px;
|
|
|
|
|
}
|
2025-03-06 14:11:21 +08:00
|
|
|
|
|
|
|
|
|
.read-more-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end; /* 靠右排版 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.read-more-card {
|
2025-03-06 15:40:09 +08:00
|
|
|
|
display: flex; /* 使用 flexbox */
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
justify-content: center; /* 水平居中 */
|
2025-03-06 14:11:21 +08:00
|
|
|
|
cursor: pointer;
|
2025-03-06 15:40:09 +08:00
|
|
|
|
width: 135px; /* 调整宽度 */
|
|
|
|
|
height: 35px; /* 调整高度 */
|
|
|
|
|
padding: 6px; /* 调整内边距 */
|
2025-03-06 14:11:21 +08:00
|
|
|
|
text-align: center;
|
|
|
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-06 15:40:09 +08:00
|
|
|
|
.read-more-card:hover,
|
|
|
|
|
.read-more-tooltip {
|
2025-03-06 14:11:21 +08:00
|
|
|
|
transform: translateY(-5px);
|
|
|
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.read-more-content {
|
2025-03-06 15:40:09 +08:00
|
|
|
|
display: flex; /* 使用 flexbox */
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
justify-content: center; /* 水平居中 */
|
|
|
|
|
gap: 2px;
|
|
|
|
|
font-size: 0.85em; /* 调整字体大小 */
|
2025-03-06 14:11:21 +08:00
|
|
|
|
color: #409eff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.read-more-icon {
|
|
|
|
|
color: #409eff;
|
|
|
|
|
transition: transform 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.read-more-card:hover .read-more-icon {
|
|
|
|
|
transform: translateX(5px);
|
|
|
|
|
}
|
|
|
|
|
</style>
|