优化:初步优化全局代码样式
This commit is contained in:
@@ -13,6 +13,6 @@ English | [中文](./README.md)
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
📝 **This is the charles's personal knowledge repositories website.**
|
📝 **This is the charles's personal technology knowledge repositories website.**
|
||||||
|
|
||||||
🐢 [GitHub Pages](https://blog.charles7c.top) | 🐇 [Gitee Pages](https://charles7c.gitee.io)
|
🐢 [GitHub Pages](https://blog.charles7c.top) | 🐇 [Gitee Pages](https://charles7c.gitee.io)
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
📝 **查尔斯的个人知识库,记录 & 分享个人碎片化、结构化、体系化的知识内容。**
|
📝 **查尔斯的个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。**
|
||||||
|
|
||||||
🐢 [GitHub Pages(完整体验)](https://blog.charles7c.top) | 🐇 [Gitee Pages(无法评论)](https://charles7c.gitee.io)
|
🐢 [GitHub Pages(完整体验)](https://blog.charles7c.top) | 🐇 [Gitee Pages(无法评论)](https://charles7c.gitee.io)
|
||||||
|
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
import { defineConfig } from 'vitepress'
|
import { defineConfig } from 'vitepress';
|
||||||
import { metaData } from './config/constants'
|
import { withMermaid } from 'vitepress-plugin-mermaid';
|
||||||
import { head } from './config/head'
|
import { metaData } from './config/constants';
|
||||||
import { markdown } from './config/markdown'
|
import { head } from './config/head';
|
||||||
import { themeConfig } from './config/theme'
|
import { markdown } from './config/markdown';
|
||||||
import { withMermaid } from 'vitepress-plugin-mermaid'
|
import { themeConfig } from './config/theme';
|
||||||
|
|
||||||
export default withMermaid(
|
export default withMermaid(
|
||||||
defineConfig({
|
defineConfig({
|
||||||
@@ -11,11 +11,11 @@ export default withMermaid(
|
|||||||
title: metaData.title,
|
title: metaData.title,
|
||||||
description: metaData.description,
|
description: metaData.description,
|
||||||
|
|
||||||
cleanUrls: 'without-subfolders',
|
cleanUrls: true,
|
||||||
lastUpdated: true, // 显示最后更新时间
|
lastUpdated: true, // 显示最后更新时间
|
||||||
|
|
||||||
head, // <head>内标签配置
|
head, // <head>内标签配置
|
||||||
markdown: markdown, // Markdown配置
|
markdown: markdown, // Markdown配置
|
||||||
themeConfig // 主题配置
|
themeConfig, // 主题配置
|
||||||
})
|
}),
|
||||||
)
|
);
|
@@ -1,10 +1,10 @@
|
|||||||
const site = 'https://blog.charles7c.top'
|
const site = 'https://blog.charles7c.top';
|
||||||
|
|
||||||
export const metaData = {
|
export const metaData = {
|
||||||
lang: 'zh-CN',
|
lang: 'zh-CN',
|
||||||
locale: 'zh_CN',
|
locale: 'zh_CN',
|
||||||
title: '查尔斯的知识库',
|
title: '查尔斯的知识库',
|
||||||
description: '个人知识库,记录 & 分享个人碎片化、结构化、体系化的知识内容。',
|
description: '个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。',
|
||||||
site,
|
site,
|
||||||
image: `${site}/logo.jpg`
|
image: `${site}/logo.jpg`,
|
||||||
}
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
import type { HeadConfig } from 'vitepress'
|
import type { HeadConfig } from 'vitepress';
|
||||||
import { metaData } from './constants'
|
import { metaData } from './constants';
|
||||||
|
|
||||||
export const head: HeadConfig[] = [
|
export const head: HeadConfig[] = [
|
||||||
['link', { rel: 'icon', href: '/favicon.ico' }],
|
['link', { rel: 'icon', href: '/favicon.ico' }],
|
||||||
@@ -56,4 +56,4 @@ export const head: HeadConfig[] = [
|
|||||||
xhr.open('GET', 'https://api.charles7c.top/blog/pv?pageUrl=' + location.href);
|
xhr.open('GET', 'https://api.charles7c.top/blog/pv?pageUrl=' + location.href);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}`]
|
}`]
|
||||||
]
|
];
|
@@ -1,4 +1,4 @@
|
|||||||
import type { MarkdownOptions } from 'vitepress'
|
import type { MarkdownOptions } from 'vitepress';
|
||||||
|
|
||||||
export const markdown: MarkdownOptions = {
|
export const markdown: MarkdownOptions = {
|
||||||
// Shiki主题, 所有主题参见: https://github.com/shikijs/shiki/blob/main/docs/themes.md
|
// Shiki主题, 所有主题参见: https://github.com/shikijs/shiki/blob/main/docs/themes.md
|
||||||
@@ -11,9 +11,9 @@ export const markdown: MarkdownOptions = {
|
|||||||
// 在所有文档的<h1>标签后添加<ArticleMetadata/>组件
|
// 在所有文档的<h1>标签后添加<ArticleMetadata/>组件
|
||||||
config: (md) => {
|
config: (md) => {
|
||||||
md.renderer.rules.heading_close = (tokens, idx, options, env, slf) => {
|
md.renderer.rules.heading_close = (tokens, idx, options, env, slf) => {
|
||||||
let htmlResult = slf.renderToken(tokens, idx, options, env, slf)
|
let htmlResult = slf.renderToken(tokens, idx, options);
|
||||||
if (tokens[idx].tag === 'h1') htmlResult += `\n<ClientOnly><ArticleMetadata v-if="($frontmatter?.aside ?? true) && ($frontmatter?.showArticleMetadata ?? true)" :article="$frontmatter" /></ClientOnly>`
|
if (tokens[idx].tag === 'h1') htmlResult += `\n<ClientOnly><ArticleMetadata v-if="($frontmatter?.aside ?? true) && ($frontmatter?.showArticleMetadata ?? true)" :article="$frontmatter" /></ClientOnly>`;
|
||||||
return htmlResult
|
return htmlResult;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
};
|
@@ -1,4 +1,4 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import type { DefaultTheme } from 'vitepress';
|
||||||
|
|
||||||
export const nav: DefaultTheme.Config['nav'] = [
|
export const nav: DefaultTheme.Config['nav'] = [
|
||||||
{
|
{
|
||||||
@@ -37,5 +37,5 @@ export const nav: DefaultTheme.Config['nav'] = [
|
|||||||
{ text: '关于我', link: '/about/me', activeMatch: '/about/me' }
|
{ text: '关于我', link: '/about/me', activeMatch: '/about/me' }
|
||||||
],
|
],
|
||||||
activeMatch: '/about/' // // 当前页面处于匹配路径下时, 对应导航菜单将突出显示
|
activeMatch: '/about/' // // 当前页面处于匹配路径下时, 对应导航菜单将突出显示
|
||||||
}
|
},
|
||||||
]
|
];
|
@@ -1,6 +1,6 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import type { DefaultTheme } from 'vitepress';
|
||||||
import { sync } from 'fast-glob'
|
import { sync } from 'fast-glob';
|
||||||
import matter from 'gray-matter'
|
import * as matter from 'gray-matter';
|
||||||
|
|
||||||
export const sidebar: DefaultTheme.Config['sidebar'] = {
|
export const sidebar: DefaultTheme.Config['sidebar'] = {
|
||||||
'/categories/issues/': getItemsByDate("categories/issues"),
|
'/categories/issues/': getItemsByDate("categories/issues"),
|
||||||
@@ -10,7 +10,7 @@ export const sidebar: DefaultTheme.Config['sidebar'] = {
|
|||||||
|
|
||||||
'/courses/java/': getItems("courses/java"),
|
'/courses/java/': getItems("courses/java"),
|
||||||
'/courses/mysql/': getItems("courses/mysql"),
|
'/courses/mysql/': getItems("courses/mysql"),
|
||||||
'/courses/mybatis/': getItems("courses/mybatis")
|
'/courses/mybatis/': getItems("courses/mybatis"),
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,57 +19,56 @@ export const sidebar: DefaultTheme.Config['sidebar'] = {
|
|||||||
* /categories/issues/2022/07/20/xxx.md
|
* /categories/issues/2022/07/20/xxx.md
|
||||||
*
|
*
|
||||||
* @param path 扫描基础路径
|
* @param path 扫描基础路径
|
||||||
* @returns {DefaultTheme.SidebarGroup[]}
|
* @returns {DefaultTheme.SidebarItem[]}
|
||||||
*/
|
*/
|
||||||
function getItemsByDate (path: string) {
|
function getItemsByDate (path: string) {
|
||||||
// 侧边栏年份分组数组
|
// 侧边栏年份分组数组
|
||||||
let yearGroups: DefaultTheme.SidebarGroup[] = []
|
let yearGroups: DefaultTheme.SidebarItem[] = [];
|
||||||
|
|
||||||
// 置顶数组
|
// 置顶数组
|
||||||
let topArticleItems: DefaultTheme.SidebarItem[] = []
|
let topArticleItems: DefaultTheme.SidebarItem[] = [];
|
||||||
|
|
||||||
// 1.获取所有年份目录
|
// 1.获取所有年份目录
|
||||||
sync(`docs/${path}/*`, {
|
sync(`docs/${path}/*`, {
|
||||||
onlyDirectories: true,
|
onlyDirectories: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach(({ name }) => {
|
}).forEach(({ name }) => {
|
||||||
let year = name
|
let year = name;
|
||||||
// 年份数组
|
// 年份数组
|
||||||
let articleItems: DefaultTheme.SidebarItem[] = []
|
let articleItems: DefaultTheme.SidebarItem[] = [];
|
||||||
|
|
||||||
// 2.获取所有月份目录
|
// 2.获取所有月份目录
|
||||||
sync(`docs/${path}/${year}/*`, {
|
sync(`docs/${path}/${year}/*`, {
|
||||||
onlyDirectories: true,
|
onlyDirectories: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach(({ name }) => {
|
}).forEach(({ name }) => {
|
||||||
let month = name
|
let month = name
|
||||||
|
|
||||||
// 3.获取所有日期目录
|
// 3.获取所有日期目录
|
||||||
sync(`docs/${path}/${year}/${month}/*`, {
|
sync(`docs/${path}/${year}/${month}/*`, {
|
||||||
onlyDirectories: true,
|
onlyDirectories: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach(({ name }) => {
|
}).forEach(({ name }) => {
|
||||||
let day = name
|
let day = name;
|
||||||
// 4.获取日期目录下的所有文章
|
// 4.获取日期目录下的所有文章
|
||||||
sync(`docs/${path}/${year}/${month}/${day}/*`, {
|
sync(`docs/${path}/${year}/${month}/${day}/*`, {
|
||||||
onlyFiles: true,
|
onlyFiles: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach((article) => {
|
}).forEach((article) => {
|
||||||
const articleFile = matter.read(`${article.path}`)
|
const articleFile = matter.read(`${article.path}`);
|
||||||
const { data } = articleFile
|
const { data } = articleFile;
|
||||||
if (data.isTop) {
|
if (data.isTop) {
|
||||||
// 向置顶分组前追加标题
|
// 向置顶分组前追加标题
|
||||||
topArticleItems.unshift({
|
topArticleItems.unshift({
|
||||||
text: data.title,
|
text: data.title,
|
||||||
link: `/${path}/${year}/${month}/${day}/${article.name.replace('.md', '')}`
|
link: `/${path}/${year}/${month}/${day}/${article.name.replace('.md', '')}`,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向年份分组前追加标题
|
// 向年份分组前追加标题
|
||||||
articleItems.unshift({
|
articleItems.unshift({
|
||||||
text: data.title,
|
text: data.title,
|
||||||
link: `/${path}/${year}/${month}/${day}/${article.name.replace('.md', '')}`
|
link: `/${path}/${year}/${month}/${day}/${article.name.replace('.md', '')}`,
|
||||||
})
|
});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -77,29 +76,29 @@ function getItemsByDate (path: string) {
|
|||||||
// 添加年份分组
|
// 添加年份分组
|
||||||
yearGroups.unshift({
|
yearGroups.unshift({
|
||||||
text: `${year}年 (${articleItems.length}篇)`,
|
text: `${year}年 (${articleItems.length}篇)`,
|
||||||
|
items: articleItems,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
items: articleItems
|
});
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (topArticleItems.length > 0) {
|
if (topArticleItems.length > 0) {
|
||||||
// 添加置顶分组
|
// 添加置顶分组
|
||||||
yearGroups.unshift({
|
yearGroups.unshift({
|
||||||
text: `📑 我的置顶 (${topArticleItems.length}篇)`,
|
text: `📑 我的置顶 (${topArticleItems.length}篇)`,
|
||||||
|
items: topArticleItems,
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
items: topArticleItems
|
});
|
||||||
})
|
|
||||||
|
|
||||||
// 将最近年份分组展开
|
// 将最近年份分组展开
|
||||||
yearGroups[1].collapsed = false
|
yearGroups[1].collapsed = false;
|
||||||
} else {
|
} else {
|
||||||
// 将最近年份分组展开
|
// 将最近年份分组展开
|
||||||
yearGroups[0].collapsed = false
|
yearGroups[0].collapsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加序号
|
// 添加序号
|
||||||
addOrderNumber(yearGroups)
|
addOrderNumber(yearGroups);
|
||||||
return yearGroups
|
return yearGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,54 +107,54 @@ function getItemsByDate (path: string) {
|
|||||||
* courses/mybatis/01-MyBatis基础/01-xxx.md
|
* courses/mybatis/01-MyBatis基础/01-xxx.md
|
||||||
*
|
*
|
||||||
* @param path 扫描基础路径
|
* @param path 扫描基础路径
|
||||||
* @returns {DefaultTheme.SidebarGroup[]}
|
* @returns {DefaultTheme.SidebarItem[]}
|
||||||
*/
|
*/
|
||||||
function getItems (path: string) {
|
function getItems (path: string) {
|
||||||
// 侧边栏分组数组
|
// 侧边栏分组数组
|
||||||
let groups: DefaultTheme.SidebarGroup[] = []
|
let groups: DefaultTheme.SidebarItem[] = [];
|
||||||
// 侧边栏分组下标题数组
|
// 侧边栏分组下标题数组
|
||||||
let items: DefaultTheme.SidebarItem[] = []
|
let items: DefaultTheme.SidebarItem[] = [];
|
||||||
let total = 0
|
let total = 0;
|
||||||
// 当分组内文章数量少于 2 篇或文章总数显示超过 20 篇时,自动折叠分组
|
// 当分组内文章数量少于 2 篇或文章总数显示超过 20 篇时,自动折叠分组
|
||||||
const groupCollapsedSize = 2
|
const groupCollapsedSize = 2;
|
||||||
const titleCollapsedSize = 20
|
const titleCollapsedSize = 20;
|
||||||
|
|
||||||
// 1.获取所有分组目录
|
// 1.获取所有分组目录
|
||||||
sync(`docs/${path}/*`, {
|
sync(`docs/${path}/*`, {
|
||||||
onlyDirectories: true,
|
onlyDirectories: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach(({ name }) => {
|
}).forEach(({ name }) => {
|
||||||
let groupName = name
|
let groupName = name;
|
||||||
// 2.获取分组下的所有文章
|
// 2.获取分组下的所有文章
|
||||||
sync(`docs/${path}/${groupName}/*`, {
|
sync(`docs/${path}/${groupName}/*`, {
|
||||||
onlyFiles: true,
|
onlyFiles: true,
|
||||||
objectMode: true
|
objectMode: true,
|
||||||
}).forEach((article) => {
|
}).forEach((article) => {
|
||||||
const articleFile = matter.read(`${article.path}`)
|
const articleFile = matter.read(`${article.path}`);
|
||||||
const { data } = articleFile
|
const { data } = articleFile;
|
||||||
// 向前追加标题
|
// 向前追加标题
|
||||||
items.push({
|
items.push({
|
||||||
text: data.title,
|
text: data.title,
|
||||||
link: `/${path}/${groupName}/${article.name.replace('.md', '')}`
|
link: `/${path}/${groupName}/${article.name.replace('.md', '')}`,
|
||||||
})
|
});
|
||||||
total ++
|
total += 1;
|
||||||
})
|
})
|
||||||
|
|
||||||
// 3.向前追加到分组
|
// 3.向前追加到分组
|
||||||
// 当分组内文章数量少于 A 篇或文章总数显示超过 B 篇时,自动折叠分组
|
// 当分组内文章数量少于 A 篇或文章总数显示超过 B 篇时,自动折叠分组
|
||||||
groups.push({
|
groups.push({
|
||||||
text: `${groupName.substring(groupName.indexOf('-') + 1)} (${items.length}篇)`,
|
text: `${groupName.substring(groupName.indexOf('-') + 1)} (${items.length}篇)`,
|
||||||
|
items: items,
|
||||||
collapsed: items.length < groupCollapsedSize || total > titleCollapsedSize,
|
collapsed: items.length < groupCollapsedSize || total > titleCollapsedSize,
|
||||||
items: items
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 4.清空侧边栏分组下标题数组
|
// 4.清空侧边栏分组下标题数组
|
||||||
items = []
|
items = [];
|
||||||
})
|
})
|
||||||
|
|
||||||
// 添加序号
|
// 添加序号
|
||||||
addOrderNumber(groups)
|
addOrderNumber(groups);
|
||||||
return groups
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,10 +163,10 @@ function getItems (path: string) {
|
|||||||
* @param groups 分组数据
|
* @param groups 分组数据
|
||||||
*/
|
*/
|
||||||
function addOrderNumber(groups) {
|
function addOrderNumber(groups) {
|
||||||
for (var i = 0; i < groups.length; i++) {
|
for (let i = 0; i < groups.length; i++) {
|
||||||
for (var j = 0; j < groups[i].items.length; j++) {
|
for (let j = 0; j < groups[i].items.length; j++) {
|
||||||
var items = groups[i].items
|
const items = groups[i].items;
|
||||||
items[j].text = `[${j + 1}] ${items[j].text}`
|
items[j].text = `[${j + 1}] ${items[j].text}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,15 +1,20 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import type { DefaultTheme } from 'vitepress';
|
||||||
import { nav } from './nav'
|
import { nav } from './nav';
|
||||||
import { sidebar } from './sidebar'
|
import { sidebar } from './sidebar';
|
||||||
|
|
||||||
export const themeConfig: DefaultTheme.Config = {
|
export const themeConfig: DefaultTheme.Config = {
|
||||||
nav, // 导航栏配置
|
nav, // 导航栏配置
|
||||||
sidebar, // 侧边栏配置
|
sidebar, // 侧边栏配置
|
||||||
|
|
||||||
logo: '/logo.png',
|
logo: '/logo.png',
|
||||||
outline: 'deep', // 右侧大纲标题层级
|
outline: {
|
||||||
outlineTitle: '目录', // 右侧大纲标题文本配置
|
level: 'deep', // 右侧大纲标题层级
|
||||||
|
label: '目录', // 右侧大纲标题文本配置
|
||||||
|
},
|
||||||
outlineBadges: false, // 是否在大纲中显示 Badge 文本
|
outlineBadges: false, // 是否在大纲中显示 Badge 文本
|
||||||
|
darkModeSwitchLabel: '切换日光/暗黑模式',
|
||||||
|
sidebarMenuLabel: '文章',
|
||||||
|
returnToTopLabel: '返回顶部',
|
||||||
lastUpdatedText: '最后更新', // 最后更新时间文本配置, 需先配置lastUpdated为true
|
lastUpdatedText: '最后更新', // 最后更新时间文本配置, 需先配置lastUpdated为true
|
||||||
// 文档页脚文本配置
|
// 文档页脚文本配置
|
||||||
docFooter: {
|
docFooter: {
|
||||||
@@ -60,10 +65,11 @@ export const themeConfig: DefaultTheme.Config = {
|
|||||||
],
|
],
|
||||||
|
|
||||||
// 自定义扩展: 文章元数据配置
|
// 自定义扩展: 文章元数据配置
|
||||||
|
// @ts-ignore
|
||||||
articleMetadataConfig: {
|
articleMetadataConfig: {
|
||||||
author: '查尔斯', // 文章全局默认作者名称
|
author: '查尔斯', // 文章全局默认作者名称
|
||||||
authorLink: '/about/me', // 点击作者名时默认跳转的链接
|
authorLink: '/about/me', // 点击作者名时默认跳转的链接
|
||||||
showViewCount: true // 是否显示文章阅读数, 需要在 docs/.vitepress/theme/api/config.js 及 interface.js 配置好相应 API 接口
|
showViewCount: true, // 是否显示文章阅读数, 需要在 docs/.vitepress/theme/api/config.js 及 interface.js 配置好相应 API 接口
|
||||||
},
|
},
|
||||||
// 自定义扩展: 文章版权配置
|
// 自定义扩展: 文章版权配置
|
||||||
copyrightConfig: {
|
copyrightConfig: {
|
||||||
|
@@ -15,23 +15,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue';
|
||||||
import DefaultTheme from 'vitepress/theme'
|
import DefaultTheme from 'vitepress/theme';
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress';
|
||||||
import md5 from 'blueimp-md5'
|
import md5 from 'blueimp-md5';
|
||||||
import Copyright from './components/layout/Copyright.vue'
|
import Copyright from './components/layout/Copyright.vue';
|
||||||
import Comment from './components/layout/Comment.vue'
|
import Comment from './components/layout/Comment.vue';
|
||||||
import Footer from './components/layout/Footer.vue'
|
import Footer from './components/layout/Footer.vue';
|
||||||
|
|
||||||
const { Layout } = DefaultTheme
|
const { Layout } = DefaultTheme;
|
||||||
const { page, theme, frontmatter } = useData()
|
const { page, theme, frontmatter } = useData();
|
||||||
const hasSidebar = computed(() => {
|
const hasSidebar = computed(() => {
|
||||||
return (
|
return (
|
||||||
frontmatter.value.aside !== false &&
|
frontmatter.value.aside !== false && frontmatter.value.layout !== 'home'
|
||||||
frontmatter.value.layout !== 'home'
|
)
|
||||||
)
|
});
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
</style>
|
|
@@ -1,24 +1,24 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
|
|
||||||
const createBaseInstance = () => {
|
const createBaseInstance = () => {
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: 'https://api.charles7c.top/blog',
|
baseURL: 'https://api.charles7c.top/blog',
|
||||||
timeout: 3000
|
timeout: 3000,
|
||||||
})
|
});
|
||||||
instance.interceptors.request.use(handleRequest, handleError)
|
instance.interceptors.request.use(handleRequest, handleError);
|
||||||
instance.interceptors.response.use(handleResponse, handleError)
|
instance.interceptors.response.use(handleResponse, handleError);
|
||||||
return instance
|
return instance;
|
||||||
}
|
}
|
||||||
export const request = createBaseInstance()
|
export const request = createBaseInstance();
|
||||||
|
|
||||||
function handleError(e) {
|
function handleError(e) {
|
||||||
throw e
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRequest(request) {
|
function handleRequest(request) {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleResponse(response) {
|
function handleResponse(response) {
|
||||||
return response.data
|
return response.data;
|
||||||
}
|
}
|
@@ -1,3 +1,3 @@
|
|||||||
export * from './interface'
|
export * from './interface';
|
||||||
|
|
||||||
export { default } from './interface'
|
export { default } from './interface';
|
@@ -1,17 +1,17 @@
|
|||||||
import { request } from './config'
|
import { request } from './config';
|
||||||
|
|
||||||
export const getArticleViewCount = (id, pageUrl, call) => {
|
export const getArticleViewCount = (id, pageUrl, call) => {
|
||||||
request.get(`/article/view/${id}?pageUrl=${pageUrl}`, {}).then(result => {
|
request.get(`/article/view/${id}?pageUrl=${pageUrl}`, {}).then(result => {
|
||||||
call(process(result))
|
call(process(result));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function process(result) {
|
function process(result) {
|
||||||
if (result.code === 200) {
|
if (result.code === 200) {
|
||||||
return result.data
|
return result.data;
|
||||||
} else {
|
} else {
|
||||||
console.log(result.msg)
|
console.log(result.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default { getArticleViewCount }
|
export default { getArticleViewCount }
|
@@ -79,142 +79,97 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import articleData from '../../../../article-data.json'
|
import articleData from '../../../../article-data.json';
|
||||||
import { formatDate, getQueryParam, goToLink } from '../utils.ts'
|
import { getQueryParam, goToLink } from '../utils.ts';
|
||||||
|
|
||||||
// 文章原始数据和归档数据
|
// 文章原始数据和归档数据
|
||||||
let $articleData
|
let $articleData;
|
||||||
let archiveData
|
let archiveData;
|
||||||
|
|
||||||
// 要筛选的分类、标签、年份
|
// 要筛选的分类、标签、年份
|
||||||
let $category
|
let $category;
|
||||||
let $tag
|
let $tag;
|
||||||
let $year
|
let $year;
|
||||||
|
|
||||||
initTimeline()
|
/**
|
||||||
|
* 初始化时间轴
|
||||||
|
*/
|
||||||
|
function initTimeline() {
|
||||||
|
$articleData = [];
|
||||||
|
archiveData = {};
|
||||||
|
|
||||||
/**
|
// 如果URL路径有category或tag或year参数, 默认筛选出指定category或tag或year的文章数据
|
||||||
* 初始化时间轴
|
// 例如: /archives?category=Bug万象集
|
||||||
*/
|
// 例如: /archives?tag=JVM
|
||||||
function initTimeline() {
|
// 例如: /archives?year=2020
|
||||||
$articleData = []
|
$category = getQueryParam('category');
|
||||||
archiveData = {}
|
$tag = getQueryParam('tag');
|
||||||
|
$year = getQueryParam('year');
|
||||||
// 如果URL路径有category或tag或year参数, 默认筛选出指定category或tag或year的文章数据
|
if ($category && $category.trim() != '') {
|
||||||
// 例如: /archives?category=Bug万象集
|
for (let i = 0; i < articleData.length; i++) {
|
||||||
// 例如: /archives?tag=JVM
|
let article = articleData[i];
|
||||||
// 例如: /archives?year=2020
|
if (article.categories && article.categories.includes($category)) {
|
||||||
$category = getQueryParam('category')
|
$articleData.push(article);
|
||||||
$tag = getQueryParam('tag')
|
}
|
||||||
$year = getQueryParam('year')
|
|
||||||
if ($category && $category.trim() != '') {
|
|
||||||
for (let i = 0; i < articleData.length; i++) {
|
|
||||||
let article = articleData[i]
|
|
||||||
if (article.categories && article.categories.includes($category)) {
|
|
||||||
$articleData.push(article)
|
|
||||||
}
|
}
|
||||||
}
|
} else if ($tag && $tag.trim() != '') {
|
||||||
} else if ($tag && $tag.trim() != '') {
|
for (let i = 0; i < articleData.length; i++) {
|
||||||
for (let i = 0; i < articleData.length; i++) {
|
let article = articleData[i];
|
||||||
let article = articleData[i]
|
if (article.tags && article.tags.includes($tag)) {
|
||||||
if (article.tags && article.tags.includes($tag)) {
|
$articleData.push(article);
|
||||||
$articleData.push(article)
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if ($year && $year.trim() != '') {
|
||||||
} else if ($year && $year.trim() != '') {
|
for (let i = 0; i < articleData.length; i++) {
|
||||||
for (let i = 0; i < articleData.length; i++) {
|
let article = articleData[i];
|
||||||
let article = articleData[i]
|
if (article.date && new Date(article.date).getFullYear() == $year) {
|
||||||
if (article.date && new Date(article.date).getFullYear() == $year) {
|
$articleData.push(article);
|
||||||
$articleData.push(article)
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$articleData.push(...articleData);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$articleData.push(...articleData)
|
// 文章数据归档处理
|
||||||
|
// 1.对文章数据进行降序排序
|
||||||
|
$articleData.sort((a, b) => b.date.localeCompare(a.date));
|
||||||
|
// 2.按年、月进行归档
|
||||||
|
for (let i = 0; i < $articleData.length; i++) {
|
||||||
|
const article = $articleData[i];
|
||||||
|
let year = (new Date(article.date).getFullYear()) + '年';
|
||||||
|
let month = (new Date(article.date).getMonth() + 1) + '月';
|
||||||
|
|
||||||
|
if (!archiveData[year]) {
|
||||||
|
archiveData[year] = {};
|
||||||
|
}
|
||||||
|
if (!(archiveData[year][month])) {
|
||||||
|
archiveData[year][month] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
archiveData[year][month].push(article);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initTimeline();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取生肖图标
|
||||||
|
*
|
||||||
|
* @param year 年份
|
||||||
|
*/
|
||||||
|
function getChineseZodiac(year) {
|
||||||
|
const arr = ['monkey', 'rooster', 'dog', 'pig', 'rat', 'ox', 'tiger', 'rabbit', 'dragon', 'snake', 'horse', 'goat'];
|
||||||
|
return arr[year % 12];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文章数据归档处理
|
/**
|
||||||
// 1.对文章数据进行降序排序
|
* 获取生肖名称
|
||||||
$articleData.sort((a, b) => b.date.localeCompare(a.date))
|
*
|
||||||
// 2.按年、月进行归档
|
* @param year 年份
|
||||||
for (let i = 0; i < $articleData.length; i++) {
|
*/
|
||||||
const article = $articleData[i]
|
function getChineseZodiacAlias(year) {
|
||||||
let year = (new Date(article.date).getFullYear()) + '年'
|
const arr = ['猴年', '鸡年', '狗年', '猪年', '鼠年', '牛年', '虎年', '兔年', '龙年', '蛇年', '马年', '羊年'];
|
||||||
let month = (new Date(article.date).getMonth() + 1) + '月'
|
return arr[year % 12];
|
||||||
|
|
||||||
if (!archiveData[year]) {
|
|
||||||
archiveData[year] = {}
|
|
||||||
}
|
|
||||||
if (!(archiveData[year][month])) {
|
|
||||||
archiveData[year][month] = []
|
|
||||||
}
|
|
||||||
|
|
||||||
archiveData[year][month].push(article)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取生肖
|
|
||||||
*/
|
|
||||||
function getChineseZodiac(year) {
|
|
||||||
switch(year % 12){
|
|
||||||
case 0:
|
|
||||||
return 'monkey'
|
|
||||||
case 1:
|
|
||||||
return 'rooster'
|
|
||||||
case 2:
|
|
||||||
return 'dog'
|
|
||||||
case 3:
|
|
||||||
return 'pig'
|
|
||||||
case 4:
|
|
||||||
return 'rat'
|
|
||||||
case 5:
|
|
||||||
return 'ox'
|
|
||||||
case 6:
|
|
||||||
return 'tiger'
|
|
||||||
case 7:
|
|
||||||
return 'rabbit'
|
|
||||||
case 8:
|
|
||||||
return 'dragon'
|
|
||||||
case 9:
|
|
||||||
return 'snake'
|
|
||||||
case 10:
|
|
||||||
return 'horse'
|
|
||||||
case 11:
|
|
||||||
return 'goat'
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取生肖名称
|
|
||||||
*/
|
|
||||||
function getChineseZodiacAlias(year) {
|
|
||||||
switch(year % 12){
|
|
||||||
case 0:
|
|
||||||
return '猴年'
|
|
||||||
case 1:
|
|
||||||
return '鸡年'
|
|
||||||
case 2:
|
|
||||||
return '狗年'
|
|
||||||
case 3:
|
|
||||||
return '猪年'
|
|
||||||
case 4:
|
|
||||||
return '鼠年'
|
|
||||||
case 5:
|
|
||||||
return '牛年'
|
|
||||||
case 6:
|
|
||||||
return '虎年'
|
|
||||||
case 7:
|
|
||||||
return '兔年'
|
|
||||||
case 8:
|
|
||||||
return '龙年'
|
|
||||||
case 9:
|
|
||||||
return '蛇年'
|
|
||||||
case 10:
|
|
||||||
return '马年'
|
|
||||||
case 11:
|
|
||||||
return '羊年'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -68,49 +68,49 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, toRefs, onMounted } from 'vue'
|
import { reactive, toRefs, onMounted } from 'vue';
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress';
|
||||||
import md5 from 'blueimp-md5'
|
import md5 from 'blueimp-md5';
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs';
|
||||||
import 'dayjs/locale/zh-cn'
|
import 'dayjs/locale/zh-cn';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
import { goToLink } from '../utils.ts'
|
import { goToLink } from '../utils.ts';
|
||||||
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime);
|
||||||
dayjs.locale('zh-cn')
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
// 定义文章属性
|
// 定义文章属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
article: Object,
|
article: Object,
|
||||||
showCategory: {
|
showCategory: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化文章元数据信息
|
||||||
|
const { theme, page } = useData();
|
||||||
|
const data = reactive({
|
||||||
|
isOriginal: props.article?.isOriginal ?? true,
|
||||||
|
author: props.article?.author ?? theme.value.articleMetadataConfig.author,
|
||||||
|
authorLink: props.article?.authorLink ?? theme.value.articleMetadataConfig.authorLink,
|
||||||
|
showViewCount: theme.value.articleMetadataConfig?.showViewCount ?? false,
|
||||||
|
viewCount: 0,
|
||||||
|
date: new Date(props.article.date),
|
||||||
|
categories: props.article?.categories ?? [],
|
||||||
|
tags: props.article?.tags ?? [],
|
||||||
|
showCategory: props.showCategory
|
||||||
|
});
|
||||||
|
const { isOriginal, author, authorLink, showViewCount, viewCount, date, toDate, categories, tags, showCategory } = toRefs(data);
|
||||||
|
|
||||||
|
if (data.showViewCount) {
|
||||||
|
// 记录并获取文章阅读数(使用文章标题 + 发布时间生成 MD5 值,作为文章的唯一标识)
|
||||||
|
onMounted(() => {
|
||||||
|
$api.getArticleViewCount(md5(props.article.title + props.article.date), location.href, function(viewCountData) {
|
||||||
|
data.viewCount = viewCountData;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// 初始化文章元数据信息
|
|
||||||
const { theme, page } = useData()
|
|
||||||
const data = reactive({
|
|
||||||
isOriginal: props.article?.isOriginal ?? true,
|
|
||||||
author: props.article?.author ?? theme.value.articleMetadataConfig.author,
|
|
||||||
authorLink: props.article?.authorLink ?? theme.value.articleMetadataConfig.authorLink,
|
|
||||||
showViewCount: theme.value.articleMetadataConfig?.showViewCount ?? false,
|
|
||||||
viewCount: 0,
|
|
||||||
date: new Date(props.article.date),
|
|
||||||
categories: props.article?.categories ?? [],
|
|
||||||
tags: props.article?.tags ?? [],
|
|
||||||
showCategory: props.showCategory
|
|
||||||
})
|
|
||||||
const { isOriginal, author, authorLink, showViewCount, viewCount, date, toDate, categories, tags, showCategory } = toRefs(data)
|
|
||||||
|
|
||||||
if (data.showViewCount) {
|
|
||||||
// 记录并获取文章阅读数(使用文章标题 + 发布时间生成 MD5 值,作为文章的唯一标识)
|
|
||||||
onMounted(() => {
|
|
||||||
$api.getArticleViewCount(md5(props.article.title + props.article.date), location.href, function(viewCountData) {
|
|
||||||
data.viewCount = viewCountData
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -58,63 +58,63 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, onMounted } from 'vue'
|
import { computed, ref } from 'vue';
|
||||||
import md5 from 'blueimp-md5'
|
import md5 from 'blueimp-md5';
|
||||||
import articleData from '../../../../article-data.json'
|
import articleData from '../../../../article-data.json';
|
||||||
import { formatDate, getQueryParam } from '../utils.ts'
|
import { getQueryParam } from '../utils.ts';
|
||||||
|
|
||||||
const tags = computed(() => initTags(articleData))
|
const tags = computed(() => initTags(articleData));
|
||||||
/**
|
/**
|
||||||
* 初始化标签数据
|
* 初始化标签数据
|
||||||
* {tagTitle1: [article1, article2, ...}
|
* {tagTitle1: [article1, article2, ...}
|
||||||
*/
|
*/
|
||||||
function initTags(articleData) {
|
function initTags(articleData) {
|
||||||
const tags: any = {}
|
const tags: any = {};
|
||||||
for (let i = 0; i < articleData.length; i++) {
|
for (let i = 0; i < articleData.length; i++) {
|
||||||
const article = articleData[i]
|
const article = articleData[i];
|
||||||
const articleTags = article.tags
|
const articleTags = article.tags;
|
||||||
if (Array.isArray(articleTags)) {
|
if (Array.isArray(articleTags)) {
|
||||||
articleTags.forEach((articleTag) => {
|
articleTags.forEach((articleTag) => {
|
||||||
if (!tags[articleTag]) {
|
if (!tags[articleTag]) {
|
||||||
tags[articleTag] = []
|
tags[articleTag] = [];
|
||||||
}
|
}
|
||||||
tags[articleTag].push(article)
|
tags[articleTag].push(article);
|
||||||
// 文章按发布时间降序排序
|
// 文章按发布时间降序排序
|
||||||
tags[articleTag].sort((a, b) => b.date.localeCompare(a.date))
|
tags[articleTag].sort((a, b) => b.date.localeCompare(a.date));
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击指定Tag后进行选中
|
||||||
|
let selectTag = ref('');
|
||||||
|
const toggleTag = (tagTitle: string) => {
|
||||||
|
if (selectTag.value && selectTag.value == tagTitle) {
|
||||||
|
selectTag.value = null;
|
||||||
|
} else {
|
||||||
|
selectTag.value = tagTitle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tags
|
|
||||||
}
|
|
||||||
|
|
||||||
// 点击指定Tag后进行选中
|
// 如果URL路径有tag参数, 默认选中指定Tag, 例如: /tags?tag=Git
|
||||||
let selectTag = ref('')
|
let tag = getQueryParam('tag');
|
||||||
const toggleTag = (tagTitle: string) => {
|
if (tag && tag.trim() != '') {
|
||||||
if (selectTag.value && selectTag.value == tagTitle) {
|
toggleTag(tag);
|
||||||
selectTag.value = null
|
|
||||||
} else {
|
|
||||||
selectTag.value = tagTitle
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 如果URL路径有tag参数, 默认选中指定Tag, 例如: /tags?tag=Git
|
const dataList = computed(() => initWordCloud(tags));
|
||||||
let tag = getQueryParam('tag')
|
/**
|
||||||
if (tag && tag.trim() != '') {
|
* 初始化词云数据
|
||||||
toggleTag(tag)
|
* [{"name": xx, "value": xx}]
|
||||||
}
|
*/
|
||||||
|
function initWordCloud(tags) {
|
||||||
const dataList = computed(() => initWordCloud(tags))
|
const dataList = [];
|
||||||
/**
|
for (let tag in tags.value) {
|
||||||
* 初始化词云数据
|
dataList.push({"name": tag, "value": tags.value[tag].length});
|
||||||
* [{"name": xx, "value": xx}]
|
}
|
||||||
*/
|
return dataList;
|
||||||
function initWordCloud(tags) {
|
|
||||||
const dataList = []
|
|
||||||
for (let tag in tags.value) {
|
|
||||||
dataList.push({"name": tag, "value": tags.value[tag].length})
|
|
||||||
}
|
}
|
||||||
return dataList
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -3,79 +3,78 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, toRefs, onMounted } from 'vue'
|
import { reactive, toRefs, onMounted } from 'vue';
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress';
|
||||||
import md5 from 'blueimp-md5'
|
import md5 from 'blueimp-md5';
|
||||||
import $ from 'jquery'
|
import $ from 'jquery';
|
||||||
import { Message } from '@arco-design/web-vue'
|
import { Message } from '@arco-design/web-vue';
|
||||||
import '@arco-design/web-vue/es/message/style/css.js'
|
import '@arco-design/web-vue/es/message/style/css.js';
|
||||||
import Gitalk from 'gitalk'
|
import Gitalk from 'gitalk';
|
||||||
import '../../styles/components/gitalk.css'
|
import '../../styles/components/gitalk.css';
|
||||||
|
|
||||||
// 定义属性
|
// 定义属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
commentConfig: Object
|
commentConfig: Object,
|
||||||
})
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
type: props.commentConfig?.type ?? 'gitalk'
|
type: props.commentConfig?.type ?? 'gitalk',
|
||||||
})
|
|
||||||
const { type } = toRefs(data)
|
|
||||||
|
|
||||||
// 初始化评论组件配置
|
|
||||||
const { page } = useData()
|
|
||||||
let gitalk
|
|
||||||
if (type.value && type.value == 'gitalk') {
|
|
||||||
gitalk = new Gitalk({
|
|
||||||
clientID: '1de126ce1fbdbe049709',
|
|
||||||
clientSecret: '035fe49874a43e5cefc28a99b7e40b1925319c62',
|
|
||||||
repo: 'charles7c.github.io',
|
|
||||||
owner: 'Charles7c',
|
|
||||||
admin: ['Charles7c'],
|
|
||||||
id: md5(page.value.relativePath),
|
|
||||||
language: 'zh-CN',
|
|
||||||
distractionFreeMode: false,
|
|
||||||
// 默认: https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
|
|
||||||
proxy: 'https://vercel.charles7c.top/github_access_token'
|
|
||||||
})
|
})
|
||||||
}
|
const { type } = toRefs(data);
|
||||||
|
|
||||||
// 渲染评论组件
|
// 初始化评论组件配置
|
||||||
onMounted(() => {
|
const { page } = useData();
|
||||||
|
let gitalk;
|
||||||
if (type.value && type.value == 'gitalk') {
|
if (type.value && type.value == 'gitalk') {
|
||||||
gitalk.render('comment-container')
|
gitalk = new Gitalk({
|
||||||
|
clientID: '1de126ce1fbdbe049709',
|
||||||
// 如果点赞,先判断有没有登录
|
clientSecret: '035fe49874a43e5cefc28a99b7e40b1925319c62',
|
||||||
let $gc = $('#comment-container');
|
repo: 'charles7c.github.io',
|
||||||
$gc.on('click', '.gt-comment-like', function () {
|
owner: 'Charles7c',
|
||||||
if (!window.localStorage.getItem('GT_ACCESS_TOKEN')) {
|
admin: ['Charles7c'],
|
||||||
Message.warning({
|
id: md5(page.value.relativePath),
|
||||||
content:'点赞前,请您先进行登录',
|
language: 'zh-CN',
|
||||||
closable: true
|
distractionFreeMode: false,
|
||||||
})
|
// 默认: https://cors-anywhere.azm.workers.dev/https://github.com/login/oauth/access_token
|
||||||
|
proxy: 'https://vercel.charles7c.top/github_access_token',
|
||||||
return false
|
});
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
// 提交评论后输入框高度没有重置bug
|
|
||||||
$gc.on('click', '.gt-header-controls .gt-btn-public', function () {
|
|
||||||
let $gt = $('.gt-header-textarea')
|
|
||||||
$gt.css('height', '72px')
|
|
||||||
})
|
|
||||||
// 点击预览时,隐藏评论按钮
|
|
||||||
$gc.on('click', '.gt-header-controls .gt-btn-preview', function () {
|
|
||||||
let pl = $('.gt-header-controls .gt-btn-public');
|
|
||||||
if (pl.hasClass('hide')) {
|
|
||||||
pl.removeClass('hide')
|
|
||||||
} else {
|
|
||||||
// 隐藏
|
|
||||||
pl.addClass('hide')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
// 渲染评论组件
|
||||||
|
onMounted(() => {
|
||||||
|
if (type.value && type.value == 'gitalk') {
|
||||||
|
gitalk.render('comment-container')
|
||||||
|
|
||||||
|
// 如果点赞,先判断有没有登录
|
||||||
|
let $gc = $('#comment-container');
|
||||||
|
$gc.on('click', '.gt-comment-like', function () {
|
||||||
|
if (!window.localStorage.getItem('GT_ACCESS_TOKEN')) {
|
||||||
|
Message.warning({
|
||||||
|
content: '点赞前,请您先进行登录',
|
||||||
|
closable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
// 提交评论后输入框高度没有重置bug
|
||||||
|
$gc.on('click', '.gt-header-controls .gt-btn-public', function () {
|
||||||
|
let $gt = $('.gt-header-textarea')
|
||||||
|
$gt.css('height', '72px')
|
||||||
|
})
|
||||||
|
// 点击预览时,隐藏评论按钮
|
||||||
|
$gc.on('click', '.gt-header-controls .gt-btn-preview', function () {
|
||||||
|
let pl = $('.gt-header-controls .gt-btn-public');
|
||||||
|
if (pl.hasClass('hide')) {
|
||||||
|
pl.removeClass('hide')
|
||||||
|
} else {
|
||||||
|
// 隐藏
|
||||||
|
pl.addClass('hide')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
</style>
|
|
@@ -43,18 +43,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, toRefs } from 'vue'
|
import { reactive, toRefs } from 'vue';
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress';
|
||||||
const { theme, frontmatter } = useData()
|
const { theme, frontmatter } = useData();
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
isOriginal: frontmatter.value?.isOriginal ?? true,
|
isOriginal: frontmatter.value?.isOriginal ?? true,
|
||||||
author: frontmatter.value?.author ?? theme.value.articleMetadataConfig.author,
|
author: frontmatter.value?.author ?? theme.value.articleMetadataConfig.author,
|
||||||
authorLink: frontmatter.value?.authorLink ?? theme.value.articleMetadataConfig.authorLink,
|
authorLink: frontmatter.value?.authorLink ?? theme.value.articleMetadataConfig.authorLink,
|
||||||
articleTitle: frontmatter.value?.articleTitle ?? frontmatter.value.title,
|
articleTitle: frontmatter.value?.articleTitle ?? frontmatter.value.title,
|
||||||
articleLink: frontmatter.value?.articleLink ?? decodeURI(window.location.href)
|
articleLink: frontmatter.value?.articleLink ?? decodeURI(window.location.href),
|
||||||
})
|
});
|
||||||
const { isOriginal, author, authorLink, articleTitle, articleLink } = toRefs(data)
|
const { isOriginal, author, authorLink, articleTitle, articleLink } = toRefs(data);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -68,7 +68,7 @@ const { isOriginal, author, authorLink, articleTitle, articleLink } = toRefs(dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
.copyright .content {
|
.copyright .content {
|
||||||
|
|
||||||
padding: 13px 16px;
|
padding: 13px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,8 +23,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useData } from 'vitepress'
|
import { useData } from 'vitepress';
|
||||||
const { theme } = useData()
|
const { theme } = useData();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import DefaultTheme from 'vitepress/theme'
|
||||||
import MyLayout from './MyLayout.vue'
|
import MyLayout from './MyLayout.vue';
|
||||||
import './styles/vars.css'
|
import './styles/vars.css';
|
||||||
import './styles/custom.css'
|
import './styles/custom.css';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import api from './api/index'
|
import api from './api/index';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...DefaultTheme,
|
...DefaultTheme,
|
||||||
Layout: MyLayout,
|
Layout: MyLayout,
|
||||||
enhanceApp(ctx) {
|
enhanceApp(ctx) {
|
||||||
// extend default theme custom behaviour.
|
// extend default theme custom behaviour.
|
||||||
DefaultTheme.enhanceApp(ctx)
|
DefaultTheme.enhanceApp(ctx);
|
||||||
|
|
||||||
// 全局挂载 API 接口
|
// 全局挂载 API 接口
|
||||||
ctx.app.config.globalProperties.$http = axios
|
ctx.app.config.globalProperties.$http = axios
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.$api = api
|
window.$api = api;
|
||||||
}
|
}
|
||||||
|
|
||||||
// register your custom global components
|
// register your custom global components
|
||||||
|
@@ -1,36 +1,39 @@
|
|||||||
/**
|
/**
|
||||||
* 格式化时间
|
* 格式化时间
|
||||||
|
*
|
||||||
* @param date 待格式化时间
|
* @param date 待格式化时间
|
||||||
* @returns 格式化后的时间(YYYY/MM/dd AM hh:mm)
|
* @returns 格式化后的时间(YYYY/MM/dd AM hh:mm)
|
||||||
*/
|
*/
|
||||||
export function formatDate(date) {
|
export function formatDate(date) {
|
||||||
const formatDate = new Date(date)
|
const formatDate = new Date(date);
|
||||||
return formatDate.toLocaleString('zh', {year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric'})
|
return formatDate.toLocaleString('zh', {year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric'});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取URL路径中的指定参数
|
* 获取 URL 路径中的指定参数
|
||||||
|
*
|
||||||
* @param paramName 参数名
|
* @param paramName 参数名
|
||||||
* @returns 参数值
|
* @returns 参数值
|
||||||
*/
|
*/
|
||||||
export function getQueryParam(paramName) {
|
export function getQueryParam(paramName) {
|
||||||
const reg = new RegExp("(^|&)"+ paramName +"=([^&]*)(&|$)")
|
const reg = new RegExp("(^|&)"+ paramName +"=([^&]*)(&|$)");
|
||||||
let value = decodeURIComponent(window.location.search.substr(1)).match(reg)
|
let value = decodeURIComponent(window.location.search.substr(1)).match(reg);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
return unescape(value[2])
|
return unescape(value[2]);
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跳转到指定链接
|
* 跳转到指定链接
|
||||||
|
*
|
||||||
* @param paramName 参数名
|
* @param paramName 参数名
|
||||||
* @param paramValue 参数值
|
* @param paramValue 参数值
|
||||||
*/
|
*/
|
||||||
export function goToLink(url, paramName, paramValue) {
|
export function goToLink(url, paramName, paramValue) {
|
||||||
if (paramName) {
|
if (paramName) {
|
||||||
window.location.href = url + '?' + paramName + '=' + paramValue
|
window.location.href = url + '?' + paramName + '=' + paramValue;
|
||||||
} else {
|
} else {
|
||||||
window.location.href = url
|
window.location.href = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -8,7 +8,7 @@ lastUpdated: false
|
|||||||
<img width=100% src="../public/img/svg/about-repos-header.svg" alt="头部图" />
|
<img width=100% src="../public/img/svg/about-repos-header.svg" alt="头部图" />
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
📝 <strong>查尔斯的个人知识库,记录 & 分享个人碎片化、结构化、体系化的知识内容。</strong>
|
📝 <strong>查尔斯的个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@@ -2,21 +2,21 @@
|
|||||||
layout: home
|
layout: home
|
||||||
|
|
||||||
title: 查尔斯的知识库
|
title: 查尔斯的知识库
|
||||||
titleTemplate: 个人知识库,记录和分享个人碎片化、结构化、体系化的知识内容
|
titleTemplate: 个人技术知识库,记录和分享个人碎片化、结构化、体系化的技术知识内容
|
||||||
|
|
||||||
hero:
|
hero:
|
||||||
name: 查尔斯的知识库
|
name: 查尔斯的知识库
|
||||||
text: 专注 & 洞察 & 分享
|
text: 专注 & 洞察 & 分享
|
||||||
tagline: 个人知识库,记录 & 分享个人碎片化、结构化、体系化的知识内容。
|
tagline: 个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。
|
||||||
image:
|
image:
|
||||||
src: /logo.png
|
src: /logo.png
|
||||||
alt: Logo
|
alt: Logo
|
||||||
actions:
|
actions:
|
||||||
- theme: brand
|
- theme: brand
|
||||||
text: Get Started
|
text: 快速开始
|
||||||
link: /categories/issues/index
|
link: /categories/issues/index
|
||||||
- theme: alt
|
- theme: alt
|
||||||
text: View on GitHub
|
text: 在 GitHub 查看
|
||||||
link: https://github.com/Charles7c/charles7c.github.io
|
link: https://github.com/Charles7c/charles7c.github.io
|
||||||
|
|
||||||
features:
|
features:
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite';
|
||||||
//import { SearchPlugin } from 'vitepress-plugin-search'
|
import Components from 'unplugin-vue-components/vite';
|
||||||
import Components from 'unplugin-vue-components/vite'
|
import { ArcoResolver } from 'unplugin-vue-components/resolvers';
|
||||||
import { ArcoResolver } from 'unplugin-vue-components/resolvers'
|
// import { SearchPlugin } from 'vitepress-plugin-search';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
//SearchPlugin({
|
// SearchPlugin({
|
||||||
//encode: false,
|
// encode: false,
|
||||||
//tokenize: 'full'
|
// tokenize: 'full',
|
||||||
//}),
|
// }),
|
||||||
Components({
|
Components({
|
||||||
dirs: ['.vitepress/theme/components'],
|
dirs: ['.vitepress/theme/components'],
|
||||||
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||||
resolvers: [ArcoResolver({ sideEffect: true, resolveIcons: true })]
|
resolvers: [ArcoResolver({ sideEffect: true, resolveIcons: true })]
|
||||||
})
|
}),
|
||||||
],
|
],
|
||||||
ssr: { noExternal: ['@arco-design/web-vue'] },
|
ssr: { noExternal: ['@arco-design/web-vue'] },
|
||||||
resolve: {
|
resolve: {
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arco-design/web-vue": "^2.43.2",
|
"@arco-design/web-vue": "^2.43.2",
|
||||||
|
"@types/blueimp-md5": "^2.18.0",
|
||||||
|
"@types/jquery": "^3.5.16",
|
||||||
"flexsearch": "^0.7.31",
|
"flexsearch": "^0.7.31",
|
||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"mermaid": "9.3.0",
|
"mermaid": "9.3.0",
|
||||||
|
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -7,6 +7,8 @@ overrides:
|
|||||||
specifiers:
|
specifiers:
|
||||||
'@antv/g2plot': ^2.4.25
|
'@antv/g2plot': ^2.4.25
|
||||||
'@arco-design/web-vue': ^2.43.2
|
'@arco-design/web-vue': ^2.43.2
|
||||||
|
'@types/blueimp-md5': ^2.18.0
|
||||||
|
'@types/jquery': ^3.5.16
|
||||||
axios: ^1.3.4
|
axios: ^1.3.4
|
||||||
blueimp-md5: ^2.19.0
|
blueimp-md5: ^2.19.0
|
||||||
dayjs: ^1.11.7
|
dayjs: ^1.11.7
|
||||||
@@ -36,6 +38,8 @@ dependencies:
|
|||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@arco-design/web-vue': 2.43.2_vue@3.2.47
|
'@arco-design/web-vue': 2.43.2_vue@3.2.47
|
||||||
|
'@types/blueimp-md5': 2.18.0
|
||||||
|
'@types/jquery': 3.5.16
|
||||||
flexsearch: 0.7.31
|
flexsearch: 0.7.31
|
||||||
markdown-it: 13.0.1
|
markdown-it: 13.0.1
|
||||||
mermaid: 9.3.0
|
mermaid: 9.3.0
|
||||||
@@ -931,6 +935,10 @@ packages:
|
|||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/blueimp-md5/2.18.0:
|
||||||
|
resolution: {integrity: sha512-f4A+++lGZGJvVSgeyMkqA7BEf2BVQli6F+qEykKb49c5ieWQBkfpn6CP5c1IZr2Yi2Ofl6Fj+v0e1fN18Z8Cnw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/d3-timer/2.0.1:
|
/@types/d3-timer/2.0.1:
|
||||||
resolution: {integrity: sha512-TF8aoF5cHcLO7W7403blM7L1T+6NF3XMyN3fxyUolq2uOcFeicG/khQg/dGxiCJWoAcmYulYN7LYSRKO54IXaA==}
|
resolution: {integrity: sha512-TF8aoF5cHcLO7W7403blM7L1T+6NF3XMyN3fxyUolq2uOcFeicG/khQg/dGxiCJWoAcmYulYN7LYSRKO54IXaA==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -943,6 +951,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==}
|
resolution: {integrity: sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/jquery/3.5.16:
|
||||||
|
resolution: {integrity: sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/sizzle': 2.3.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/linkify-it/3.0.2:
|
/@types/linkify-it/3.0.2:
|
||||||
resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==}
|
resolution: {integrity: sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -958,6 +972,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
|
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/sizzle/2.3.3:
|
||||||
|
resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/web-bluetooth/0.0.16:
|
/@types/web-bluetooth/0.0.16:
|
||||||
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
|
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
Reference in New Issue
Block a user