8 changed files with 308 additions and 122 deletions
-
5src/api/admin.ts
-
30src/api/index.ts
-
BINsrc/assets/front/Testimonia-3zp8X.ttf
-
61src/components/blogs/ComLink.vue
-
157src/components/blogs/HomePage.vue
-
91src/components/blogs/LeftSiteInfo.vue
-
57src/views/blog/AboutMe.vue
-
29src/views/blog/AmountChartView.vue
@ -1,19 +1,19 @@ |
|||
// 公共api
|
|||
import type { blogInterface,diaryInterface } from "./admin"; |
|||
export interface indexInterface { |
|||
modaOpen: boolean, |
|||
title: string, |
|||
} |
|||
modaOpen: boolean, |
|||
title: string, |
|||
} |
|||
// 前台首页
|
|||
export interface homePageInterface { |
|||
id: number; |
|||
blogtitle?: string; // 博客标题,可选字段
|
|||
blogcontent?: string; // 博客内容,可选字段
|
|||
diarytitle?: string; // 日记标题,可选字段
|
|||
diarycontent?: string; // 日记内容,可选字段
|
|||
imglink: string; // 图片链接
|
|||
typename: string; // 类型名称
|
|||
create_at: string; // 创建时间
|
|||
update_at?: string; // 更新时间,可选字段
|
|||
wordcount?: number; // 字数统计,可选字段
|
|||
labelnames?: string[]; // 标签名称数组,可选字段
|
|||
id: number; |
|||
blogtitle?: string; // 博客标题,可选字段
|
|||
blogcontent?: string; // 博客内容,可选字段
|
|||
diarytitle?: string; // 日记标题,可选字段
|
|||
diarycontent?: string; // 日记内容,可选字段
|
|||
imglink: string; // 图片链接
|
|||
typename: string; // 类型名称
|
|||
create_at: string; // 创建时间
|
|||
update_at?: string; // 更新时间,可选字段
|
|||
wordcount?: number; // 字数统计,可选字段
|
|||
labelnames?: string[]; // 标签名称数组,可选字段
|
|||
} |
@ -0,0 +1,61 @@ |
|||
<template> |
|||
<a-card hoverable title="常用链接"> |
|||
<div class="button-group"> |
|||
<a-button type="dashed" v-for="comlink in comlinklist" :key="comlink.id" |
|||
@click="comLinkClick(comlink.linkurl)">{{ |
|||
comlink.linktext |
|||
}}</a-button> |
|||
</div> |
|||
</a-card> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import router from '@/router'; |
|||
import type { comLinkInterface } from '@/api/admin'; |
|||
import { ref, onMounted } from 'vue'; |
|||
import { get } from '@/tools/request'; |
|||
const comLinkClick = (url: string) => { |
|||
if (url.startsWith('http://') || url.startsWith('https://')) { |
|||
window.open(url, "_blank"); // 使用 window.location.href 打开外部链接 |
|||
} else { |
|||
router.push(url); // 否则使用 Vue Router 的 push 方法导航 |
|||
} |
|||
} |
|||
const comlinklist = ref<comLinkInterface[]>([]) |
|||
const comLinkList = async () => { |
|||
try { |
|||
await get("/comlinks/list").then(response => { |
|||
if (response) { |
|||
comlinklist.value = response.data.data.map((item: any, index: any) => ({ |
|||
key: (index + 1).toString(), |
|||
id: item.id, |
|||
linktext: item.linktext, |
|||
linkurl: item.linkurl, |
|||
descr: item.descr |
|||
})); |
|||
} else { |
|||
console.log("the interface request data does not exist!") |
|||
} |
|||
}) |
|||
} catch (error) { |
|||
console.error("Failed to fetch data", error); |
|||
} |
|||
} |
|||
onMounted(() => { |
|||
comLinkList() |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.button-group { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.button-group>* { |
|||
width: 40%; |
|||
margin: 12px; |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,91 @@ |
|||
<template> |
|||
<a-card hoverable> |
|||
<template #cover> |
|||
<img alt="example" src="/src/assets/images/头像.jpg" /> |
|||
</template> |
|||
<h1>sunfree</h1> |
|||
<div class="cardText"></div> |
|||
<div class="button-group"> |
|||
<a-button v-for="(button, index) in buttons" :key="index" shape="circle" size="large" |
|||
@click="handleClick(button.url)"> |
|||
<component :is="button.icon" /> |
|||
</a-button> |
|||
</div> |
|||
<div class="fold-panel"> |
|||
<a-collapse v-model:activeKey="activeKey" :bordered="false" expandIconPosition="end"> |
|||
<template #expandIcon="{ isActive }"> |
|||
<caret-right-outlined :rotate="isActive ? 90 : 0" /> |
|||
</template> |
|||
<a-collapse-panel v-for="classtic in classticlist" :key=classtic.id :header=classtic.header |
|||
:style="customStyle"> |
|||
<p>{{ classtic.text }}</p> |
|||
</a-collapse-panel> |
|||
</a-collapse> |
|||
</div> |
|||
</a-card> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { ref, onMounted } from 'vue'; |
|||
import iconComponents from "@/assets/index"; |
|||
import { get } from '@/tools/request'; |
|||
import type { classticInterface } from '@/api/admin'; |
|||
import { CaretRightOutlined } from '@ant-design/icons-vue'; |
|||
const buttons = ref([ |
|||
{ icon: iconComponents.CravatarLined, url: 'https://cravatar.cn/' }, |
|||
{ icon: iconComponents.QQLined, url: '/qqcode' }, |
|||
{ icon: iconComponents.WechatLined, url: '/wechatcode' }, |
|||
{ icon: iconComponents.MusicLined, url: 'https://music.163.com/#/playlist?id=160266689' }, |
|||
{ icon: iconComponents.GitHubLined, url: 'https://gitee.com/c_panda' }, |
|||
]); |
|||
const classticlist = ref<classticInterface[]>([]) |
|||
const classticList = async () => { |
|||
try { |
|||
await get("/classtics/list").then(response => { |
|||
if (response) { |
|||
classticlist.value = response.data.data.map((item: any, index: any) => ({ |
|||
key: (index + 1).toString(), |
|||
header: item.header, |
|||
text: item.text, |
|||
descr: item.descr |
|||
})); |
|||
} else { |
|||
console.log("the interface request data does not exist!") |
|||
} |
|||
}) |
|||
} catch (error) { |
|||
console.error("Failed to fetch data", error); |
|||
} |
|||
} |
|||
const activeKey = ref(['']); |
|||
const handleClick = (url: string) => { |
|||
window.open(url) |
|||
} |
|||
const customStyle = 'background: #F5F5F5;border-radius: 4px;margin-bottom: 12px;border: 0;overflow: hidden'; |
|||
onMounted(() => { |
|||
classticList() |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
img { |
|||
/* 图片自适应容器并保持宽高比例 */ |
|||
aspect-ratio: 1/1; |
|||
} |
|||
|
|||
h1 { |
|||
text-align: center; |
|||
font-family: Georgia, 'Times New Roman', Times, serif; |
|||
} |
|||
|
|||
.cardText { |
|||
min-height: 60px; |
|||
text-align: center; |
|||
} |
|||
|
|||
.button-group { |
|||
display: flex; |
|||
margin: 0 12px 24px 12px; |
|||
justify-content: space-between; |
|||
} |
|||
</style> |
@ -1,14 +1,59 @@ |
|||
<template> |
|||
<div class="aboutme">这是关于我的内容</div> |
|||
<div id="blogDetail"> |
|||
<a-card> |
|||
<v-md-preview :text="aboutMe"/> |
|||
</a-card> |
|||
</div> |
|||
|
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
<script setup lang="ts"> |
|||
import { ref } from 'vue'; |
|||
const aboutMe = ref(`# 关于我 |
|||
|
|||
<p style="text-align:center;"> |
|||
<img src="https://via.placeholder.com/150" alt="头像" style="border-radius:50%;"> |
|||
</p> |
|||
|
|||
<p style="text-align:center; font-size:1.5em; font-weight:bold;">SunFree</p> |
|||
|
|||
## 简介 |
|||
|
|||
大家好,我是SunFree,目前是一名软件工程师。热爱编程,喜欢学习新技术,并且在自动化测试方面都有丰富的经验。 |
|||
|
|||
## 技能 |
|||
|
|||
- **编程语言:** JavaScript, TypeScript, Python |
|||
- **前端框架:** Vue.js |
|||
- **后端框架:** FastAPI |
|||
- **数据库:** MySQL |
|||
|
|||
## 爱好 |
|||
|
|||
- **编程:** 我喜欢在空闲时间编写各种小工具和应用程序。 |
|||
- **音乐:** 我喜欢听音乐,尤其是古典音乐和流行音乐。 |
|||
- **旅行:** 我喜欢探索新的地方,体验不同的文化。 |
|||
|
|||
## 联系我 |
|||
|
|||
<p style="text-align:center;"> |
|||
<a href="mailto:your-email@example.com" style="margin-right:15px;"> |
|||
<img src="https://img.icons8.com/color/48/000000/email.png" alt="Email"> |
|||
</a> |
|||
<a href="https://github.com/your-github" target="_blank" style="margin-right:15px;"> |
|||
<img src="https://img.icons8.com/ios-glyphs/48/000000/github.png" alt="GitHub"> |
|||
</a> |
|||
<a href="https://www.linkedin.com/in/your-linkedin" target="_blank"> |
|||
<img src="https://img.icons8.com/color/48/000000/linkedin.png" alt="LinkedIn"> |
|||
</a> |
|||
</p> |
|||
`); |
|||
</script> |
|||
|
|||
<style> |
|||
.aboutme { |
|||
width: 45%; |
|||
margin: 0 24px; |
|||
|
|||
<style scoped> |
|||
#blogDetail { |
|||
width: 45%; |
|||
margin: 0 24px; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue