Browse Source

add new

master
panda 8 months ago
parent
commit
65a1cef200
  1. BIN
      src/assets/image.png
  2. 6
      src/assets/index.ts
  3. 92
      src/components/blogs/HomePage.vue
  4. 210
      src/components/blogs/ceshi.vue
  5. 13
      src/views/blog/blogcontent/BlogDetailView.vue
  6. 64
      src/views/blog/blogcontent/BlogListView.vue

BIN
src/assets/image.png

After

Width: 62  |  Height: 67  |  Size: 11 KiB

6
src/assets/index.ts

@ -3,7 +3,7 @@ import { createFromIconfontCN } from '@ant-design/icons-vue';
function createIconComponent(iconType: string) {
const IconComponent = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4513281_qhbaqfo6egj.js', // 在 iconfont.cn 上生成
scriptUrl: '//at.alicdn.com/t/c/font_4513281_1cb6b9dny0i.js', // 在 iconfont.cn 上生成
});
return defineComponent({
@ -32,6 +32,10 @@ const iconComponents = {
YanJingLined: createIconComponent('icon-yanjing'),
XieZiLined: createIconComponent('icon-xiezi'),
CravatarLined: createIconComponent('icon-cravatar'),
GongAnLined: createIconComponent('icon-gonganbeian'),
IcpLined: createIconComponent('icon-wsmp-icprecord'),
BanQuanLined: createIconComponent('icon-banquan'),
}

92
src/components/blogs/HomePage.vue

@ -104,6 +104,54 @@
</div>
</div>
<div class="footer">
<div class="miit">
<a-space wrap>
<a-text>
<component :is=iconComponents.BanQuanLined />
<span>Copyright © 2024</span>
</a-text>
<a-button type="link" href="/home">
<component :is=iconComponents.TitleOutLined />
<span>SunFree</span>
</a-button>
<a-button type="link" href="https://beian.miit.gov.cn/">
<component :is=iconComponents.IcpLined />
<span>苏ICP备2024067473号-1</span>
</a-button>
<a-button type="link" href="https://beian.mps.gov.cn/#/query/webSearch">
<component :is=iconComponents.GongAnLined />
<span>苏公网安备32021402003003号</span>
</a-button>
</a-space>
</div>
<div class="badge">
<a-space wrap>
<a-button type="link" class="badge-button" href="https://cn.vuejs.org/">
<span class="tag-nav">front-end</span>
<span class="tag-main-first">Vue.js</span>
</a-button>
<a-button type="link" class="badge-button" href="https://fastapi.tiangolo.com/zh/">
<span class="tag-nav">back-end</span>
<span class="tag-main-second">FastAPI</span>
</a-button>
<a-button type="link" class="badge-button" href="https://www.antdv.com/docs/vue/introduce-cn/">
<span class="tag-nav">UI</span>
<span class="tag-main-third">Ant Design Vue</span>
</a-button>
<a-button type="link" class="badge-button" href="https://cloud.tencent.com/">
<span class="tag-nav">VPS</span>
<span class="tag-main-fourth">tencent cloud</span>
</a-button>
</a-space>
</div>
<div>
</div>
<div></div>
</div>
</Simplebar>
</template>
<script lang="ts" setup>
@ -121,7 +169,6 @@ import { useRouter, useRoute } from 'vue-router';
import iconComponents from "@/assets/index";
import type { classticInterface } from '@/api/admin';
import type { comLinkInterface } from '@/api/admin/index';
const router = useRouter()
const route = useRoute()
const author = ref("SunFree.")
@ -684,4 +731,47 @@ watch(
.statistic {
text-align: center;
}
.footer {
display: flex;
flex-direction: column;
align-items: center;
}
.footer a {
color: #6e5555;
}
.footer .badge {
margin: 48px 0;
}
.footer .miit {
margin: 48px 0 0 0;
}
.footer .badge .tag-nav {
background-color: #505050;
}
.footer .miit span{
padding: 0 6px;
}
.footer .badge span {
padding: 0 6px;
color: white;
}
.footer .badge .tag-main-first {
background-color: rgb(3, 3, 250);
}
.footer .badge .tag-main-second {
background-color: rgb(235, 15, 228);
}
.footer .badge .tag-main-third {
background-color: rgb(10, 207, 39);
}
.footer .badge .tag-main-fourth {
background-color: rgb(229, 131, 12);
}
</style>

210
src/components/blogs/ceshi.vue

@ -1,189 +1,45 @@
<template>
<div>
<div
v-for="anchor in titles"
:style="{ padding: `10px 0 10px ${anchor.indent}px` }"
@click="handleAnchorClick(anchor)"
:key="anchor.lineIndex"
>
<a style="cursor: pointer">{{ anchor.title }}</a>
<div v-for="blog in bloglist" :key="blog.id">
<!-- 在这里展示你的博客内容 -->
<h2>{{ blog.blogtitle }}</h2>
<p>{{ blog.blogcontent }}</p>
</div>
<v-md-preview :text="text" ref="preview" />
<a-pagination v-model:current="current" v-if="dataLoaded" :total="total" :page-size="pageSize" @change="onPageChange"
show-less-items />
</div>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
const text = `
# heading 1
contentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontent
## heading 2
contentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontent
### heading 3
contentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontentcontentcontentcontent
contentcontentcontent
contentcontentcontent
contentcontentcontent
`;
const preview = ref<any>(null);
const titles = ref<{ title: string; lineIndex: string; indent: number }[]>([]);
onMounted(() => {
const anchors = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
const titlesArray = Array.from(anchors).filter((title) => !!title.innerText.trim());
if (!titlesArray.length) {
titles.value = [];
return;
}
const hTags = Array.from(new Set(titlesArray.map((title) => title.tagName))).sort();
titles.value = titlesArray.map((el) => ({
title: el.innerText,
lineIndex: el.getAttribute('data-v-md-line') || '', //
indent: 20 * (parseInt(el.tagName.substring(1)) - 1) //
}));
import type { blogInterface } from '@/api/admin';
import { get } from '@/tools/request';
const current = ref(1);
const total = ref();
const pageSize = ref(5);
const bloglist = ref<blogInterface[]>([])
const dataLoaded = ref(false);
const fetchData = async (page: number, pageSize: number) => {
try {
const response = await get('/blogs/list', {
page,
page_size: pageSize,
});
bloglist.value = response.data.data.blogs;
total.value = response.data.data.total;
} catch (error) {
console.error('Failed to fetch data', error);
}
};
function handleAnchorClick(anchor: { title: string; lineIndex: string }) {
if (preview.value) {
const heading = preview.value.$el.querySelector(`[data-v-md-line="${anchor.lineIndex}"]`);
const onPageChange = (page: number) => {
current.value = page;
fetchData(page, pageSize.value);
};
if (heading) {
preview.value.scrollToTarget({
target: heading,
scrollContainer: window,
top: 60,
onMounted(() => {
fetchData(current.value, pageSize.value);
});
} else {
console.error(`Heading element not found for lineIndex: ${anchor.lineIndex}`);
}
} else {
console.error('Preview component not initialized.');
}
}
</script>

13
src/views/blog/blogcontent/BlogDetailView.vue

@ -1,11 +1,14 @@
<template>
<div id="blogDetail">
<div v-for="anchor in titles" :style="{ padding: `4px 0 4px ${anchor.indent * 20}px` }"
<!-- <div v-for="anchor in titles" :style="{ padding: `4px 0 4px ${anchor.indent * 20}px` }"
@click="handleAnchorClick(anchor)" :key="anchor.lineIndex">
<a style="cursor: pointer">{{ anchor.title }}</a>
</div>
</div> -->
<a-card>
<v-md-preview v-if="text.blogcontent" :text="text.blogcontent" v-bind="previewProps" />
</a-card>
</div>
</template>
<script setup lang="ts">
@ -18,6 +21,10 @@ const text = ref({
blogtitle: "",
blogcontent: ""
});
const titles = ref<{ title: string; lineIndex: string; indent: number }[]>([]);
// Props for v-md-preview component
@ -88,6 +95,6 @@ onMounted(async () => {
<style scoped>
#blogDetail {
width: 45%;
margin: 0 24px;
}
</style>

64
src/views/blog/blogcontent/BlogListView.vue

@ -48,6 +48,16 @@
</a-card>
</a-badge-ribbon>
</div>
<div id="pagination">
<a-pagination v-model:current="current" v-if="dataLoaded" v-model:page-size="pageSizeRef"
:page-size-options="pageSizeOptions" :total="total" show-size-changer @change="onShowSizeChange">
<template #buildOptionText="props">
<span v-if="props.value !== '50'">{{ props.value }}/</span>
<span v-else>全部</span>
</template>
</a-pagination>
</div>
</div>
</template>
@ -62,39 +72,43 @@ const randomColor = () => {
const labelColor = ref(["processing", "success", "error", "warning", "magenta", "red", "volcano", "orange", "gold", "lime", "green", "cyan", "blue", "geekblue", "purple"])
return labelColor.value[Math.floor(Math.random() * labelColor.value.length)];
}
const dataLoaded = ref(false);
//
const pageSizeOptions = ref<string[]>(['10', '20', '30', '40', '50']);
const current = ref(1);
const total = ref();
const pageSizeRef = ref(10);
const bloglist = ref<blogInterface[]>([])
const blogList = async () => {
const onShowSizeChange = (page: number) => {
current.value = page;
blogList(page, pageSizeRef.value)
};
const blogList = async (page: number, pageSize: number) => {
try {
const response = await get("/blogs/list");
if (response) {
bloglist.value = response.data.data.map((items: any, index: any) => ({
key: (index + 1).toString(),
id: items.id,
blogtitle: items.blogtitle,
create_at: dayjs(items.create_at).format('YYYY-MM-DD HH:mm:ss'),
update_at: dayjs(items.update_at).format('YYYY-MM-DD HH:mm:ss'),
readnum: items.readnum,
readminite: (items.blogcontent.length/150).toFixed(2),
wordcount: items.blogcontent.length,
img: items.img,
blogcontent: items.blogcontent,
typename: items.typename,
labelnames: items.labelnames
}))
} else {
console.log("bloglist is not exits")
}
const response = await get('/blogs/list', {
page,
page_size: pageSize,
});
console.log(response)
bloglist.value = response.data.data.blogs;
total.value = response.data.data.total; //
pageSizeRef.value = pageSize; // response.data.data.page_size
dataLoaded.value = true
} catch (error) {
console.log("bloglist is error")
console.error('Failed to fetch data', error);
}
};
}
const readMore = (id: any) => {
router.push(`/blog/${id}`)
}
onMounted(() => {
blogList();
blogList(current.value, pageSizeRef.value);
});
</script>
@ -192,4 +206,8 @@ onMounted(() => {
margin-left: 24px;
}
#pagination{
display: flex;
justify-content: right;
}
</style>
Loading…
Cancel
Save