Browse Source

add new

master
panda 8 months ago
parent
commit
de345a3625
  1. 448
      src/components/blogs/HomePage.vue
  2. 2
      src/components/blogs/LeftSiteInfo.vue
  3. 84
      src/components/blogs/StatisticCount.vue
  4. 26
      src/components/blogs/header/CarouselImg.vue
  5. 150
      src/components/blogs/header/NavigateMenu.vue
  6. 11
      src/router/blog.ts
  7. 10
      src/stores/index.ts
  8. 57
      src/views/blog/imagemanage/OtherImgView.vue
  9. 56
      src/views/blog/imagemanage/PersonSelfView.vue

448
src/components/blogs/HomePage.vue

@ -1,21 +1,12 @@
<template>
<Simplebar @scroll="handleScroll">
<div class="header">
<!-- 头部导航菜单 -->
<div class="headerMenu" 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>
<NavigateMenu />
<!-- 作者名字 -->
<div class="author" v-if="show_author">{{ author }}</div>
<!-- 轮播 -->
<div class="carousel" v-if="show_carousel">
<a-carousel autoplay>
<div class="img"><img src="/src/assets/images/nav1.png" alt=""></div>
<div class="img"><img src="/src/assets/images/nav10.png" alt=""></div>
<div class="img"><img src="/src/assets/images/nav13.png" alt=""></div>
</a-carousel>
</div>
<CarouselImg />
<!-- 操作按钮滚动 -->
<div class="anchorDown" v-if="show_anchornDown">
<a-button type="link" shape="circle" size="large" @click="downScroll">
@ -24,48 +15,18 @@
</template>
</a-button>
</div>
</div>
<!-- 主要内容区域 -->
<div class="mainContainer" :style="mainCss">
<div class="leftBar">
<!-- <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> -->
<LeftSiteInfo />
<ComLink />
</div>
<RouterView />
<div class="rightBar">
<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>
<StatisticCount />
<a-card hoverable>
<template #cover>
<div class="heatmap" style="border-right: rgba(0, 0, 0, 0.5);">
@ -158,12 +119,10 @@
</Simplebar>
</template>
<script lang="ts" setup>
import { h, reactive, ref, nextTick, toRefs, computed } from 'vue';
import type { MenuProps } from 'ant-design-vue';
import { HomeOutlined, HighlightOutlined, ProfileOutlined, CameraOutlined, UsergroupDeleteOutlined, DownCircleOutlined } from '@ant-design/icons-vue';
import { reactive, ref, nextTick, toRefs } from 'vue';
import { DownCircleOutlined } from '@ant-design/icons-vue';
import Typed from 'typed.js';
import { onMounted, watch } from 'vue';
import { CaretRightOutlined } from '@ant-design/icons-vue';
import 'APlayer/dist/APlayer.min.css';
import APlayer from 'APlayer';
import { get } from "@/tools/request"
@ -174,112 +133,106 @@ import type { classticInterface, labelInterface } from '@/api/admin';
import type { homePageInterface } from '@/api';
import ComLink from './ComLink.vue';
import LeftSiteInfo from "./LeftSiteInfo.vue"
const router = useRouter()
const route = useRoute()
import StatisticCount from "./StatisticCount.vue"
import NavigateMenu from './header/NavigateMenu.vue';
import { homePageStore } from '@/stores';
import CarouselImg from './header/CarouselImg.vue';
const author = ref("SunFree.")
/**
* 隐藏参数
*/
const idShow = reactive({
show_menu: false,
show_carousel: true,
show_author: true,
show_anchornDown: true
})
const { idShow } = homePageStore()
const { show_menu, show_carousel, show_author, show_anchornDown } = toRefs(idShow)
const mainCss = reactive({
marginTop: "0px"
})
const current = ref<string[]>(['home']);
const items = ref<MenuProps['items']>([
{
key: 'home',
icon: () => h(HomeOutlined),
label: '首页',
title: '首页',
// 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: '相册1',
key: 'album1',
},
{
label: '相册2',
key: 'album2',
},
{
label: '相册3',
key: 'album3',
},
{
label: '相册4',
key: 'album4',
},
],
},
{
key: 'chart',
icon: () => h(UsergroupDeleteOutlined),
label: '收支图',
title: '收支图',
},
{
key: 'aboutme',
icon: () => h(UsergroupDeleteOutlined),
label: '关于sunfree',
title: '关于sunfree',
},
]);
const searchValue = ref("")
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();
});
// },
// {
// key: 'blog',
// icon: () => h(HighlightOutlined),
// label: '',
// title: '',
// },
// {
// key: 'diary',
// icon: () => h(ProfileOutlined),
// label: '',
// title: '',
// },
// {
// key: 'album',
// icon: () => h(CameraOutlined),
// label: '',
// title: '',
// children: [
// {
// label: '1',
// key: 'album1',
// },
// {
// label: '2',
// key: 'album2',
// },
// {
// label: '3',
// key: 'album3',
// },
// {
// label: '4',
// key: 'album4',
// },
// ],
// },
// {
// key: 'chart',
// icon: () => h(UsergroupDeleteOutlined),
// label: '',
// title: '',
// },
// {
// key: 'aboutme',
// icon: () => h(UsergroupDeleteOutlined),
// label: 'sunfree',
// title: 'sunfree',
// },
// ]);
// const searchValue = ref("")
// 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();
// });
//
const articleTitle = ref<string>('');
const onSearch = (searchValue: string) => {
console.log('use value', searchValue);
console.log('or use this.value', articleTitle.value);
};
// const articleTitle = ref<string>('');
// const onSearch = (searchValue: string) => {
// console.log('use value', searchValue);
// console.log('or use this.value', articleTitle.value);
// };
/**
* 滚动条操作
@ -375,63 +328,63 @@ const downScroll = () => {
* 右侧栏
*/
//
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 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
},
])
// //
// 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
// },
// ])
//
const heat = ref(null);
@ -577,14 +530,14 @@ const labelList = async () => {
}
onMounted(() => {
// classticList()
blogList()
// blogList()
labelList()
diaryList()
// diaryList()
// comLinkList()
statisticList()
updateCurrentDate();
// updateCurrentDate();
homePageList()
setInterval(updateCurrentDate, 24 * 60 * 60 * 1000);
// setInterval(updateCurrentDate, 24 * 60 * 60 * 1000);
createEcharts(heat, heatMapData);
nextTick(() => {
const authorElement = document.querySelector('.author');
@ -650,54 +603,38 @@ onMounted(() => {
})
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; //
}
});
// 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 }
);
// if (menuItem) {
// current.value = [menuItem.key as string];
// } else {
// current.value = ['home']; // 'home'
// }
// } else {
// current.value = ['home']; // route.name 'home'
// }
// },
// { immediate: true }
// );
</script>
<style scoped>
.headerMenu {
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;
}
/* 作者名称 */
.author {
@ -731,10 +668,6 @@ watch(
}
}
.carousel img {
height: 100vh;
width: 100vw;
}
.anchorDown {
position: absolute;
@ -806,9 +739,6 @@ watch(
margin: 0;
}
.statistic {
text-align: center;
}
.footer {
display: flex;

2
src/components/blogs/LeftSiteInfo.vue

@ -1,7 +1,7 @@
<template>
<a-card hoverable>
<template #cover>
<img alt="example" src="/src/assets/images/头像.jpg" />
<img alt="example" src="http://www.wuruilin.cn/otherimg/头像.jpg" />
</template>
<h1>sunfree</h1>
<div class="cardText"></div>

84
src/components/blogs/StatisticCount.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>

26
src/components/blogs/header/CarouselImg.vue

@ -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>

150
src/components/blogs/header/NavigateMenu.vue

@ -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>

11
src/router/blog.ts

@ -33,9 +33,14 @@ const blogRoute:Array<RouteRecordRaw>=[
component:()=>import("@/views/blog/diarycontent/DiaryDetailView.vue")
},
{
path:"chart",
name:"chart",
component:()=>import("@/views/blog/AmountChartView.vue")
path:"personself",
name:"personself",
component:()=>import("@/views/blog/imagemanage/PersonSelfView.vue")
},
{
path:"otherimg",
name:"otherimg",
component:()=>import("@/views/blog/imagemanage/OtherImgView.vue")
},
{
path:"aboutme",

10
src/stores/index.ts

@ -4,6 +4,15 @@ import { defineStore } from 'pinia'
export const mainWrapperStore = defineStore("mainWrapper", () => {
})
export const homePageStore = defineStore("homePage", () => {
const idShow = reactive({
show_menu: false,
show_carousel: true,
show_author: true,
show_anchornDown: true
})
return {idShow}
})
export const blogStore = defineStore("blog", () => {
const delControl = reactive({
@ -101,6 +110,7 @@ export const labelStore = defineStore("label", () => {
})
export const useAuthStore = defineStore("auth", () => {
const tokenValue = ref("")
function setToken(token: string) {

57
src/views/blog/imagemanage/OtherImgView.vue

@ -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>

56
src/views/blog/imagemanage/PersonSelfView.vue

@ -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>
Loading…
Cancel
Save