9 changed files with 604 additions and 286 deletions
-
448src/components/blogs/HomePage.vue
-
2src/components/blogs/LeftSiteInfo.vue
-
84src/components/blogs/StatisticCount.vue
-
26src/components/blogs/header/CarouselImg.vue
-
150src/components/blogs/header/NavigateMenu.vue
-
11src/router/blog.ts
-
10src/stores/index.ts
-
57src/views/blog/imagemanage/OtherImgView.vue
-
56src/views/blog/imagemanage/PersonSelfView.vue
@ -0,0 +1,84 @@ |
|||
<template> |
|||
<a-card hoverable> |
|||
<div class="statistic"> |
|||
<a-row> |
|||
<a-col :span="8" v-for="statistic in statistics" :key="statistic.id"> |
|||
<a-statistic :title=statistic.title :value=statistic.counts /> |
|||
</a-col> |
|||
</a-row> |
|||
</div> |
|||
</a-card> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { reactive, ref, computed, onMounted } from 'vue'; |
|||
import { get } from '@/tools/request'; |
|||
const createData = new Date('2024-07-12'); |
|||
const currentDate = ref(new Date()); |
|||
const getDateOnly = (date: Date) => { |
|||
return new Date(date.getFullYear(), date.getMonth(), date.getDate()); |
|||
}; |
|||
|
|||
// 计算相差的天数 |
|||
const daysDifference = computed(() => { |
|||
const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 |
|||
const diffTime = Math.abs(getDateOnly(currentDate.value).getTime() - getDateOnly(createData).getTime()); |
|||
return Math.floor(diffTime / oneDay); // 使用Math.floor确保是整天数 |
|||
}); |
|||
const diaryTotal = ref(); |
|||
const blogTotal = ref(); |
|||
const diaryList = async () => { |
|||
try { |
|||
const response = await get('/diarys/list'); |
|||
diaryTotal.value = response.data.data.total; // 更新总数 |
|||
} catch (error) { |
|||
console.error('Failed to fetch data', error); |
|||
} |
|||
}; |
|||
const blogList = async () => { |
|||
try { |
|||
const response = await get("/blogs/list"); |
|||
if (response) { |
|||
blogTotal.value = response.data.data.total; |
|||
} else { |
|||
console.log("bloglist is not exits") |
|||
} |
|||
} catch (error) { |
|||
console.log("bloglist is error") |
|||
} |
|||
|
|||
} |
|||
|
|||
// 更新当前时间 |
|||
const updateCurrentDate = () => { |
|||
currentDate.value = new Date(); |
|||
}; |
|||
const statistics = reactive([ |
|||
{ |
|||
id: "1", |
|||
title: "DAYS", |
|||
counts: daysDifference |
|||
}, |
|||
{ |
|||
id: "2", |
|||
title: "DIARYS", |
|||
counts: diaryTotal |
|||
}, |
|||
{ |
|||
id: "3", |
|||
title: "BLOGS", |
|||
counts: blogTotal |
|||
}, |
|||
]) |
|||
onMounted(() => { |
|||
diaryList() |
|||
blogList() |
|||
setInterval(updateCurrentDate, 24 * 60 * 60 * 1000); |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.statistic { |
|||
text-align: center; |
|||
} |
|||
</style> |
@ -0,0 +1,26 @@ |
|||
<template> |
|||
<div class="carousel" v-if="show_carousel"> |
|||
<a-carousel autoplay> |
|||
<div class="img" v-for="imgdata in imgdatas"><img :src="imgdata" alt=""></div> |
|||
</a-carousel> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { homePageStore } from '@/stores'; |
|||
import { toRefs } from 'vue'; |
|||
const { idShow } = homePageStore() |
|||
const { show_carousel } = toRefs(idShow) |
|||
const imgdatas: string[] = [ |
|||
"/src/assets/images/nav1.png", |
|||
"/src/assets/images/nav10.png", |
|||
"/src/assets/images/nav13.png" |
|||
] |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.carousel img { |
|||
height: 100vh; |
|||
width: 100vw; |
|||
} |
|||
</style> |
@ -0,0 +1,150 @@ |
|||
<template> |
|||
<div class="menu" v-if="show_menu"> |
|||
<a-menu v-model:selectedKeys="current" mode="horizontal" :items="items" style="border-bottom: none;" |
|||
@click="jumpMenu" /> |
|||
<a-input-search v-model:value="searchValue" placeholder="search" style="width: 200px" @search="onSearch" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { ref, h, toRefs,watch,onMounted } from 'vue'; |
|||
import { HomeOutlined, HighlightOutlined, ProfileOutlined, CameraOutlined, UsergroupDeleteOutlined } from '@ant-design/icons-vue'; |
|||
import type { MenuProps } from 'ant-design-vue'; |
|||
import router from '@/router'; |
|||
import { useRouter } from 'vue-router'; |
|||
const route=useRouter() |
|||
import { homePageStore } from '@/stores'; |
|||
const { idShow } = homePageStore() |
|||
const { show_menu } = toRefs(idShow) |
|||
const current = ref<string[]>(['home']); |
|||
const items = ref<MenuProps['items']>([ |
|||
{ |
|||
key: 'home', |
|||
icon: () => h(HomeOutlined), |
|||
label: '首页', |
|||
title: '首页', |
|||
|
|||
}, |
|||
{ |
|||
key: 'blog', |
|||
icon: () => h(HighlightOutlined), |
|||
label: '博客', |
|||
title: '博客', |
|||
}, |
|||
{ |
|||
key: 'diary', |
|||
icon: () => h(ProfileOutlined), |
|||
label: '日记', |
|||
title: '日记', |
|||
}, |
|||
{ |
|||
key: 'album', |
|||
icon: () => h(CameraOutlined), |
|||
label: '相册', |
|||
title: '相册', |
|||
children: [ |
|||
{ |
|||
label: '个人', |
|||
key: 'personself', |
|||
}, |
|||
{ |
|||
label: '其他', |
|||
key: 'otherimg', |
|||
}, |
|||
], |
|||
}, |
|||
{ |
|||
key: 'chart', |
|||
icon: () => h(UsergroupDeleteOutlined), |
|||
label: '收支图', |
|||
title: '收支图', |
|||
}, |
|||
{ |
|||
key: 'aboutme', |
|||
icon: () => h(UsergroupDeleteOutlined), |
|||
label: '关于sunfree', |
|||
title: '关于sunfree', |
|||
}, |
|||
]); |
|||
const searchValue = ref("") |
|||
const articleTitle = ref<string>(''); |
|||
const onSearch = (searchValue: string) => { |
|||
console.log('use value', searchValue); |
|||
console.log('or use this.value', articleTitle.value); |
|||
}; |
|||
const jumpMenu = ({ key }: { key: string }) => { |
|||
router.push(`/${key}`) |
|||
}; |
|||
const updateCarouselVisibility = (routeName: any) => { |
|||
handleScrollEnabled.value = false; |
|||
if (scrollbar.value) { |
|||
scrollbar.value.scrollTop = 0; |
|||
} |
|||
if (routeName === 'home') { |
|||
handleScrollEnabled.value = true; |
|||
show_carousel.value = true; |
|||
show_menu.value = false |
|||
} else { |
|||
show_menu.value = true; |
|||
show_author.value = false; |
|||
show_carousel.value = false; |
|||
show_anchornDown.value = false; |
|||
mainCss.marginTop = '48px'; |
|||
} |
|||
}; |
|||
router.beforeEach((to, _, next) => { |
|||
updateCarouselVisibility(to.name); |
|||
next(); |
|||
}); |
|||
watch( |
|||
() => route.name, |
|||
(newRouteName) => { |
|||
updateCarouselVisibility(newRouteName); |
|||
|
|||
if (newRouteName) { |
|||
// 尝试从菜单项中找到与当前路由名称匹配的项 |
|||
const menuItem = items.value?.find((item: any) => { |
|||
// 这里可以根据实际情况来匹配路由名称或路径 |
|||
// 例如,可以根据 route.name 或 route.path 来匹配 |
|||
if (newRouteName === 'blogdetail') { |
|||
return item.key === 'blog'; // 匹配博客详情页,选中博客菜单 |
|||
} else if (newRouteName === 'diarydetail') { |
|||
return item.key === 'diary'; // 匹配日记详情页,选中日记菜单 |
|||
} else { |
|||
return item.key === newRouteName; // 默认匹配路由名称 |
|||
} |
|||
}); |
|||
|
|||
if (menuItem) { |
|||
current.value = [menuItem.key as string]; |
|||
} else { |
|||
current.value = ['home']; // 找不到对应的菜单项,默认选中 'home' |
|||
} |
|||
} else { |
|||
current.value = ['home']; // 如果 route.name 不存在,默认选中 'home' |
|||
} |
|||
}, |
|||
{ immediate: true } |
|||
); |
|||
const scrollbar = ref<Element | null>(null); |
|||
onMounted(()=>{ |
|||
scrollbar.value = document.querySelector('.simplebar-content-wrapper'); |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.menu { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 100%; |
|||
height: 48px; |
|||
border-bottom: 1px solid rgba(5, 5, 5, 0.06); |
|||
position: fixed; |
|||
background-color: white; |
|||
transform: translateX(-50%); |
|||
top: 0; |
|||
left: 50%; |
|||
z-index: 999; |
|||
} |
|||
</style> |
@ -0,0 +1,57 @@ |
|||
<template> |
|||
<div class="otherimg"> |
|||
<a-card hoverable> |
|||
<a-image-preview-group> |
|||
<div class="img"> |
|||
<a-image :style="imageStyle" v-for="img in imgurl" :src="img" /> |
|||
</div> |
|||
</a-image-preview-group> |
|||
</a-card> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { get } from '@/tools/request'; |
|||
import { ref, computed, onMounted } from 'vue'; |
|||
const imageWidthPercentage = 45 / 3.5; // 45% divided by 2 = 22.5% |
|||
const imageStyle = computed(() => { |
|||
const width = `${imageWidthPercentage}vw`; |
|||
const height = `${(5 / 5) * imageWidthPercentage}vw`; |
|||
|
|||
return { |
|||
width, |
|||
height, |
|||
border: '2px solid #ddd', // Border style |
|||
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', // Shadow effect |
|||
transition: 'transform 0.3s ease, box-shadow 0.3s ease' |
|||
}; |
|||
}); |
|||
const imgurl = ref([]) |
|||
const baseurl = "http://www.wuruilin.cn" |
|||
const imgList = async () => { |
|||
await get("photos/listfiles", |
|||
{ album_key: "otherimg" } |
|||
|
|||
).then((response) => { |
|||
const imglist = response.data.files |
|||
imgurl.value = imglist.map((path: string) => `${baseurl}/${path}`); |
|||
}) |
|||
} |
|||
onMounted(() => { |
|||
imgList() |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.otherimg { |
|||
width: 45%; |
|||
margin: 0 24px; |
|||
} |
|||
|
|||
.img { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
flex-wrap: wrap; |
|||
gap: 24px; |
|||
} |
|||
</style> |
@ -0,0 +1,56 @@ |
|||
<template> |
|||
<div class="personself"> |
|||
<a-card hoverable> |
|||
<a-image-preview-group> |
|||
<div class="img"> |
|||
<a-image :style="imageStyle" v-for="img in imgurl" :src="img" /> |
|||
</div> |
|||
</a-image-preview-group> |
|||
</a-card> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang='ts'> |
|||
import { get } from '@/tools/request'; |
|||
import { ref, computed, onMounted } from 'vue'; |
|||
const imageWidthPercentage = 45 / 2.5; // 45% divided by 2 = 22.5% |
|||
const imageStyle = computed(() => { |
|||
const width = `${imageWidthPercentage}vw`; |
|||
const height = `${(3 / 5) * imageWidthPercentage}vw`; |
|||
return { |
|||
width, |
|||
height, |
|||
border: '2px solid #ddd', // Border style |
|||
boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', // Shadow effect |
|||
transition: 'transform 0.3s ease, box-shadow 0.3s ease' |
|||
}; |
|||
}); |
|||
const imgurl = ref([]) |
|||
const baseurl = "http://www.wuruilin.cn" |
|||
const imgList = async () => { |
|||
await get("photos/listfiles", |
|||
{ album_key: "personself" } |
|||
|
|||
).then((response) => { |
|||
const imglist = response.data.files |
|||
imgurl.value = imglist.map((path: string) => `${baseurl}/${path}`); |
|||
}) |
|||
} |
|||
onMounted(() => { |
|||
imgList() |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.personself { |
|||
width: 45%; |
|||
margin: 0 24px; |
|||
} |
|||
|
|||
.img { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
flex-wrap: wrap; |
|||
gap: 24px; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue