From 2c9740dcf724d0dff640cb5547b2cc49c1c38862 Mon Sep 17 00:00:00 2001
From: Han <1655466387@qq.com>
Date: Mon, 17 Feb 2025 18:34:21 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 22 +---
README.md | 69 +++++++++++
package.json | 4 +-
public/assets/font/index.css | 23 ++++
public/assets/images/footer/astro.svg | 2 +
public/assets/images/footer/copyright.svg | 1 +
public/assets/images/footer/hananalytics.svg | 1 +
public/assets/images/footer/icp.svg | 1 +
public/assets/images/footer/ing.svg | 1 +
public/assets/images/footer/sitemap.svg | 1 +
public/assets/images/footer/theme.svg | 2 +
src/components/Aside.astro | 4 +-
src/components/Comment.astro | 19 ++-
src/components/Footer.astro | 17 +++
src/components/Pagination.astro | 4 +-
src/config.ts | 6 +-
.../Cloudflare优选IP➕DnsPod的DDNS自动切换.md | 0
...cs访问分析Web统计托管于(Cloudflare Pages).md | 0
.../{2024/12 => }/【开源】Tarot-塔罗牌占卜.md | 0
...雨重山无限存储图床托管于(Cloudflare Pages).md | 0
.../基于AI的微博动态心情分析【开源】.md | 0
...开源项目WebWatermark图片添加水印在线小助手.md | 0
src/layouts/Layout.astro | 9 ++
src/page_data/Link.ts | 19 +++
src/page_data/Talking.ts | 31 +++++
src/pages/about/index.astro | 4 +-
src/pages/article/[...article].astro | 10 +-
src/pages/links/index.astro | 9 +-
src/pages/message/index.astro | 4 +-
src/pages/talking/index.astro | 9 +-
src/scripts/Links.ts | 7 +-
src/scripts/Talking.ts | 10 +-
src/styles/Base.less | 3 +-
src/styles/Footer.less | 116 ++++++++++++++++++
src/styles/Layout.less | 3 +-
src/styles/components/ArticleCard.less | 1 +
src/styles/components/Header.less | 2 +-
src/utils/index.ts | 62 ++++++----
38 files changed, 389 insertions(+), 87 deletions(-)
create mode 100644 public/assets/images/footer/astro.svg
create mode 100644 public/assets/images/footer/copyright.svg
create mode 100644 public/assets/images/footer/hananalytics.svg
create mode 100644 public/assets/images/footer/icp.svg
create mode 100644 public/assets/images/footer/ing.svg
create mode 100644 public/assets/images/footer/sitemap.svg
create mode 100644 public/assets/images/footer/theme.svg
create mode 100644 src/components/Footer.astro
rename src/content/blog/{2024/08 => }/Cloudflare优选IP➕DnsPod的DDNS自动切换.md (100%)
rename src/content/blog/{2024/09 => }/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md (100%)
rename src/content/blog/{2024/12 => }/【开源】Tarot-塔罗牌占卜.md (100%)
rename src/content/blog/{2024/07 => }/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md (100%)
rename src/content/blog/{2024/09 => }/基于AI的微博动态心情分析【开源】.md (100%)
rename src/content/blog/{2024/11 => }/推荐一个开源项目WebWatermark图片添加水印在线小助手.md (100%)
create mode 100644 src/page_data/Link.ts
create mode 100644 src/page_data/Talking.ts
create mode 100644 src/styles/Footer.less
diff --git a/.gitignore b/.gitignore
index b5a7453..5b97f1e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,24 +25,4 @@ test/
/public/hanplayer
/public/MineWeb
-/public/other
-/src/content/blog/*
-!/src/content/blog
-/src/content/blog/2024/*
-!/src/content/blog/2024
-/src/content/blog/2024/07/*
-!/src/content/blog/2024/07
-/src/content/blog/2024/08/*
-!/src/content/blog/2024/08
-/src/content/blog/2024/09/*
-!/src/content/blog/2024/09
-/src/content/blog/2024/11/*
-!/src/content/blog/2024/11
-/src/content/blog/2024/12/*
-!/src/content/blog/2024/12
-!/src/content/blog/2024/07/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md
-!/src/content/blog/2024/08/Cloudflare优选IP➕DnsPod的DDNS自动切换.md
-!/src/content/blog/2024/09/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md
-!/src/content/blog/2024/09/基于AI的微博动态心情分析【开源】.md
-!/src/content/blog/2024/11/推荐一个开源项目WebWatermark图片添加水印在线小助手.md
-!/src/content/blog/2024/12/【开源】Tarot-塔罗牌占卜.md
\ No newline at end of file
+/public/other
\ No newline at end of file
diff --git a/README.md b/README.md
index 57fae63..6e7874b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,71 @@
# vhAstro-Theme
一款简约的 Astro 主题
+
+# Astro Starter Kit: Blog
+
+```sh
+npm create astro@latest -- --template blog
+```
+
+[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/blog)
+[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/blog)
+[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/blog/devcontainer.json)
+
+> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
+
+
+
+Features:
+
+- ✅ Minimal styling (make it your own!)
+- ✅ 100/100 Lighthouse performance
+- ✅ SEO-friendly with canonical URLs and OpenGraph data
+- ✅ Sitemap support
+- ✅ RSS Feed support
+- ✅ Markdown & MDX support
+
+## 🚀 Project Structure
+
+Inside of your Astro project, you'll see the following folders and files:
+
+```text
+├── public/
+├── src/
+│ ├── components/
+│ ├── content/
+│ ├── layouts/
+│ └── pages/
+├── astro.config.mjs
+├── README.md
+├── package.json
+└── tsconfig.json
+```
+
+Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
+
+There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
+
+The `src/content/` directory contains "collections" of related Markdown and MDX documents. Use `getCollection()` to retrieve posts from `src/content/blog/`, and type-check your frontmatter using an optional schema. See [Astro's Content Collections docs](https://docs.astro.build/en/guides/content-collections/) to learn more.
+
+Any static assets, like images, can be placed in the `public/` directory.
+
+## 🧞 Commands
+
+All commands are run from the root of the project, from a terminal:
+
+| Command | Action |
+| :------------------------ | :----------------------------------------------- |
+| `npm install` | Installs dependencies |
+| `npm run dev` | Starts local dev server at `localhost:4321` |
+| `npm run build` | Build your production site to `./dist/` |
+| `npm run preview` | Preview your build locally, before deploying |
+| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
+| `npm run astro -- --help` | Get help using the Astro CLI |
+
+## 👀 Want to learn more?
+
+Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
+
+## Credit
+
+This theme is based off of the lovely [Bear Blog](https://github.com/HermanMartinus/bearblog/).
diff --git a/package.json b/package.json
index cfac89f..5665edb 100644
--- a/package.json
+++ b/package.json
@@ -12,12 +12,12 @@
"@astrojs/mdx": "^4.0.8",
"@astrojs/rss": "^4.0.11",
"@astrojs/sitemap": "^3.2.1",
- "astro": "^5.2.5",
+ "astro": "^5.3.0",
"dayjs": "^1.11.13",
"dplayer": "^1.27.1",
"hls.js": "^1.5.20",
"nprogress": "^0.2.0",
- "overlayscrollbars": "^2.10.1",
+ "overlayscrollbars": "^2.11.0",
"remark-directive": "^3.0.1",
"twikoo": "1.6.41",
"unist-util-visit": "^5.0.0",
diff --git a/public/assets/font/index.css b/public/assets/font/index.css
index b70ae65..c39e174 100644
--- a/public/assets/font/index.css
+++ b/public/assets/font/index.css
@@ -1,4 +1,27 @@
+/*
+@import url('./HarmonyOS_Sans_Regular/result.css');
+@import url('./NotoSans/result.css'); */
@import url('./SFMono-Regular/result.css');
+
+/* @import url('./HarmonyOS_Sans/100/global/result.css');
+@import url('./HarmonyOS_Sans/100/sc/result.css');
+@import url('./HarmonyOS_Sans/200/global/result.css');
+@import url('./HarmonyOS_Sans/200/sc/result.css');
+@import url('./HarmonyOS_Sans/300/global/result.css');
+@import url('./HarmonyOS_Sans/300/sc/result.css');
+@import url('./HarmonyOS_Sans/400/global/result.css');
+@import url('./HarmonyOS_Sans/400/sc/result.css');
+@import url('./HarmonyOS_Sans/500/global/result.css');
+@import url('./HarmonyOS_Sans/500/sc/result.css');
+@import url('./HarmonyOS_Sans/600/global/result.css');
+@import url('./HarmonyOS_Sans/600/sc/result.css');
+@import url('./HarmonyOS_Sans/700/global/result.css');
+@import url('./HarmonyOS_Sans/700/sc/result.css');
+@import url('./HarmonyOS_Sans/800/global/result.css');
+@import url('./HarmonyOS_Sans/800/sc/result.css');
+@import url('./HarmonyOS_Sans/900/global/result.css');
+@import url('./HarmonyOS_Sans/900/sc/result.css'); */
+
@import url('./MiSans/100/result.css');
@import url('./MiSans/200/result.css');
@import url('./MiSans/300/result.css');
diff --git a/public/assets/images/footer/astro.svg b/public/assets/images/footer/astro.svg
new file mode 100644
index 0000000..ff8d63b
--- /dev/null
+++ b/public/assets/images/footer/astro.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/public/assets/images/footer/copyright.svg b/public/assets/images/footer/copyright.svg
new file mode 100644
index 0000000..1a09db1
--- /dev/null
+++ b/public/assets/images/footer/copyright.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/footer/hananalytics.svg b/public/assets/images/footer/hananalytics.svg
new file mode 100644
index 0000000..6e7bf46
--- /dev/null
+++ b/public/assets/images/footer/hananalytics.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/footer/icp.svg b/public/assets/images/footer/icp.svg
new file mode 100644
index 0000000..66c2969
--- /dev/null
+++ b/public/assets/images/footer/icp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/footer/ing.svg b/public/assets/images/footer/ing.svg
new file mode 100644
index 0000000..81c7f50
--- /dev/null
+++ b/public/assets/images/footer/ing.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/footer/sitemap.svg b/public/assets/images/footer/sitemap.svg
new file mode 100644
index 0000000..c7ef393
--- /dev/null
+++ b/public/assets/images/footer/sitemap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/footer/theme.svg b/public/assets/images/footer/theme.svg
new file mode 100644
index 0000000..0c3e8ff
--- /dev/null
+++ b/public/assets/images/footer/theme.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/components/Aside.astro b/src/components/Aside.astro
index 70d7d69..c32ead8 100644
--- a/src/components/Aside.astro
+++ b/src/components/Aside.astro
@@ -1,7 +1,7 @@
---
// 获取用户配置数据
import SITE_CONFIG from "../config";
-import { fmtTime, fmtDate } from "../utils/index";
+import { fmtDate } from "../utils/index";
const { Avatar, Author, Motto, WebSites } = SITE_CONFIG;
// 获取文章数据
import { getCategories, getTags, getRecommendArticles } from "../utils/getPostInfo";
@@ -78,7 +78,7 @@ import "../styles/components/Aside.less";
{(await i).title}
-
+
))
diff --git a/src/components/Comment.astro b/src/components/Comment.astro
index 72ac99d..56a9d1b 100644
--- a/src/components/Comment.astro
+++ b/src/components/Comment.astro
@@ -3,20 +3,19 @@ import "../styles/components/Comment.less";
---
-
diff --git a/src/components/Footer.astro b/src/components/Footer.astro
new file mode 100644
index 0000000..a96df71
--- /dev/null
+++ b/src/components/Footer.astro
@@ -0,0 +1,17 @@
+---
+import { fmtDate } from "../utils/index";
+// 页面内容的元数据
+import SITE_CONFIG from "../config";
+const { CreateTime } = SITE_CONFIG;
+// 基础 样式
+import "../styles/Footer.less";
+---
+
+
diff --git a/src/components/Pagination.astro b/src/components/Pagination.astro
index 800b766..23f29a5 100644
--- a/src/components/Pagination.astro
+++ b/src/components/Pagination.astro
@@ -23,7 +23,7 @@ import "../styles/components/Pagination.less";
}
{
- (!data.next || !data.last) && (
+ (!data.next || !data.last) && data.prev && (
@@ -33,7 +33,7 @@ import "../styles/components/Pagination.less";
{
- (!data.prev || !data.first) && (
+ (!data.prev || !data.first) && data.next && (
diff --git a/src/config.ts b/src/config.ts
index 995efad..8efccfd 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -38,7 +38,7 @@ export default {
// 博客音乐组件解析接口
vhMusicApi: 'https://meting-dd.2333332.xyz/api',
// 评论组件 Twikoo
- Twikoo: {
- envId: "https://twikoo.vvhan.com/.netlify/functions/twikoo",
- }
+ Twikoo: { envId: 'https://twikoo.vvhan.com/.netlify/functions/twikoo' },
+ // Han Analytics 统计(https://github.com/uxiaohan/HanAnalytics)
+ HanAnalytics: { enable: true, server: 'https://analytics.vvhan.com', siteId: 'Hello-HanHexoBlog' }
}
\ No newline at end of file
diff --git a/src/content/blog/2024/08/Cloudflare优选IP➕DnsPod的DDNS自动切换.md b/src/content/blog/Cloudflare优选IP➕DnsPod的DDNS自动切换.md
similarity index 100%
rename from src/content/blog/2024/08/Cloudflare优选IP➕DnsPod的DDNS自动切换.md
rename to src/content/blog/Cloudflare优选IP➕DnsPod的DDNS自动切换.md
diff --git a/src/content/blog/2024/09/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md b/src/content/blog/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md
similarity index 100%
rename from src/content/blog/2024/09/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md
rename to src/content/blog/【开源】HanAnalytics访问分析Web统计托管于(Cloudflare Pages).md
diff --git a/src/content/blog/2024/12/【开源】Tarot-塔罗牌占卜.md b/src/content/blog/【开源】Tarot-塔罗牌占卜.md
similarity index 100%
rename from src/content/blog/2024/12/【开源】Tarot-塔罗牌占卜.md
rename to src/content/blog/【开源】Tarot-塔罗牌占卜.md
diff --git a/src/content/blog/2024/07/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md b/src/content/blog/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md
similarity index 100%
rename from src/content/blog/2024/07/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md
rename to src/content/blog/【开源】骤雨重山无限存储图床托管于(Cloudflare Pages).md
diff --git a/src/content/blog/2024/09/基于AI的微博动态心情分析【开源】.md b/src/content/blog/基于AI的微博动态心情分析【开源】.md
similarity index 100%
rename from src/content/blog/2024/09/基于AI的微博动态心情分析【开源】.md
rename to src/content/blog/基于AI的微博动态心情分析【开源】.md
diff --git a/src/content/blog/2024/11/推荐一个开源项目WebWatermark图片添加水印在线小助手.md b/src/content/blog/推荐一个开源项目WebWatermark图片添加水印在线小助手.md
similarity index 100%
rename from src/content/blog/2024/11/推荐一个开源项目WebWatermark图片添加水印在线小助手.md
rename to src/content/blog/推荐一个开源项目WebWatermark图片添加水印在线小助手.md
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index da60c2c..095eb69 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -5,6 +5,8 @@ const { title, keywords, description, activeNav } = Astro.props;
import Head from "../components/Head.astro";
// 顶部 Header
import Header from "../components/Header.astro";
+// 底部 Footer
+import Footer from "../components/Footer.astro";
// 返回顶部
import BackTop from "../components/BackTop.astro";
// 手机端侧边栏
@@ -24,6 +26,7 @@ import "../styles/Layout.less";
+
diff --git a/src/pages/message/index.astro b/src/pages/message/index.astro
index 9efa8ff..dc99196 100644
--- a/src/pages/message/index.astro
+++ b/src/pages/message/index.astro
@@ -1,7 +1,7 @@
---
// 页面 Info
import SITE_CONFIG from "../../config";
-const { Description } = SITE_CONFIG;
+const { Description, Twikoo } = SITE_CONFIG;
// Aside组件
import Aside from "../../components/Aside.astro";
// 公共 Layout
@@ -17,7 +17,7 @@ import Comment from "../../components/Comment.astro";
留言板 🌸
快友之事莫若谈。
-
+ {Twikoo.envId && }
diff --git a/src/pages/talking/index.astro b/src/pages/talking/index.astro
index 96de86c..107bcd7 100644
--- a/src/pages/talking/index.astro
+++ b/src/pages/talking/index.astro
@@ -1,7 +1,7 @@
---
// 页面 Info
import SITE_CONFIG from "../../config";
-const { Description } = SITE_CONFIG;
+const { Description, Twikoo } = SITE_CONFIG;
// Aside组件
import Aside from "../../components/Aside.astro";
// 公共 Layout
@@ -20,7 +20,7 @@ import "../../styles/Talking.less";
记录美好生活.
-
+ {Twikoo.envId && }
@@ -29,6 +29,9 @@ import "../../styles/Talking.less";
import updateRouter from "../../utils/updateRouter";
import TalkingInit from "../../scripts/Talking";
// 进入页面时初始化
- updateRouter("afterMount", TalkingInit);
+ // 数据源
+ import TALKING_DATA from "../../page_data/Talking";
+ const { api, data } = TALKING_DATA;
+ updateRouter("afterMount", () => TalkingInit(api || data));
diff --git a/src/scripts/Links.ts b/src/scripts/Links.ts
index 9aa1ca1..3da7bfc 100644
--- a/src/scripts/Links.ts
+++ b/src/scripts/Links.ts
@@ -4,12 +4,15 @@ import { $GET } from '../utils/index'
// 图片懒加载
import vhLzImgInit from "../scripts/vhLazyImg";
-const LinksInit = async () => {
+const LinksInit = async (data: any) => {
const linksDOM = document.querySelector('.vh-container>.vh-links>main')
if (!linksDOM) return;
vh.showLoading();
try {
- const res = await $GET('https://tools-api.vvhan.com/blog/link');
+ let res = data;
+ if (typeof data === 'string') {
+ res = await $GET(data);
+ }
linksDOM.innerHTML = res.map((i: any) => `
`).join('');
// 图片懒加载
vhLzImgInit();
diff --git a/src/scripts/Talking.ts b/src/scripts/Talking.ts
index f26935e..3c67bb2 100644
--- a/src/scripts/Talking.ts
+++ b/src/scripts/Talking.ts
@@ -1,5 +1,6 @@
import vh from 'vh-plugin'
+import { fmtDate } from '../utils/index'
import { $GET } from '../utils/index'
// 图片懒加载
import vhLzImgInit from "../scripts/vhLazyImg";
@@ -8,13 +9,16 @@ import "../../public/assets/js/view-image.min.js";
declare const ViewImage: any;
// 灯箱JS初始化======
-const TalkingInit = async () => {
+const TalkingInit = async (data: any) => {
const talkingDOM = document.querySelector('.vh-container>.vh-talking>main')
if (!talkingDOM) return;
vh.showLoading();
try {
- const res = await $GET('https://tools-api.vvhan.com/blog/feeling');
- talkingDOM.innerHTML = res.map((i: any) => `![]()
.𝙃𝙖𝙣
`).join('');
+ let res = data;
+ if (typeof data === 'string') {
+ res = await $GET(data);
+ }
+ talkingDOM.innerHTML = res.map((i: any) => `![]()
.𝙃𝙖𝙣
`).join('');
// 图片懒加载
vhLzImgInit();
// 灯箱JS初始化======
diff --git a/src/styles/Base.less b/src/styles/Base.less
index a6e52bc..bb13f35 100644
--- a/src/styles/Base.less
+++ b/src/styles/Base.less
@@ -3,7 +3,8 @@
:root {
--vh-animation-delay: 0ms;
--vh-padding-top: calc(66px + 1rem);
- --vh-back-top: calc((calc(100vw - 2rem) - min((100vw - 2rem), 1388px)) / 2 + 1rem);
+ --vh-main-max-width: 1388px;
+ --vh-back-top: calc((calc(100vw - 2rem) - min((100vw - 2rem), var(--vh-main-max-width))) / 2 + 1rem);
}
h1,
diff --git a/src/styles/Footer.less b/src/styles/Footer.less
new file mode 100644
index 0000000..d608730
--- /dev/null
+++ b/src/styles/Footer.less
@@ -0,0 +1,116 @@
+.vh-footer {
+ margin-top: 1.68rem;
+ box-sizing: border-box;
+ padding: 2.6rem 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: max-content;
+ background: rgba(255, 255, 255, 0.1);
+ backdrop-filter: saturate(100%) blur(2px);
+ user-select: none;
+
+ &>main {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ gap: 0.618rem;
+ width: 100%;
+ max-width: var(--vh-main-max-width);
+ height: max-content;
+
+ &>p {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 0.618rem;
+ line-height: 1;
+
+ &>a {
+ line-height: 1;
+ }
+
+ &>span {
+ box-sizing: border-box;
+ padding-left: 0.28rem;
+ display: flex;
+ align-items: center;
+ width: max-content;
+ height: 1.25rem;
+ background: #25C2A0;
+ font-size: 0.68rem;
+ border-radius: 0.18rem;
+ overflow: hidden;
+
+ &>cite,
+ &>em {
+ box-sizing: border-box;
+ padding: 0 0.618rem;
+ width: max-content;
+ height: 100%;
+ line-height: 1.25rem;
+ color: #fff;
+ font-style: normal;
+ }
+
+ &>cite {
+ padding-left: 0.28rem;
+ }
+
+ &>em {
+ background: #5D5D5D;
+ }
+
+ &>svg {
+ width: 0.88rem;
+ height: 0.88rem;
+ }
+ }
+ }
+ }
+
+ &>section {
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ gap: 0.88rem;
+ width: 100%;
+ height: max-content;
+
+ p {
+ line-height: 1;
+
+ a {
+ line-height: 1;
+ }
+ }
+
+ &.text {
+ &>p {
+
+ font-size: 0.88rem;
+
+ &>a {
+ color: #94A3B8;
+ transition: opacity 0.16s ease-in-out;
+
+ &:hover {
+ opacity: 0.88;
+ }
+ }
+ }
+ }
+
+ &.icon {
+ &>p {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 1rem;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/styles/Layout.less b/src/styles/Layout.less
index 9926b3e..b68948c 100644
--- a/src/styles/Layout.less
+++ b/src/styles/Layout.less
@@ -16,13 +16,12 @@ body {
flex-direction: column;
gap: 1rem;
width: 100%;
- max-width: 1388px;
+ max-width: var(--vh-main-max-width);
height: max-content;
&>section.vh-container {
position: relative;
box-sizing: border-box;
- padding-bottom: 5.66rem;
display: flex;
flex-direction: row-reverse;
gap: 1.8rem;
diff --git a/src/styles/components/ArticleCard.less b/src/styles/components/ArticleCard.less
index 9b86d91..5ca24c3 100644
--- a/src/styles/components/ArticleCard.less
+++ b/src/styles/components/ArticleCard.less
@@ -6,6 +6,7 @@ section.article-list {
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
gap: 1.6rem;
width: 100%;
+ height: max-content;
overflow: hidden;
&>.vh-article-item {
diff --git a/src/styles/components/Header.less b/src/styles/components/Header.less
index cc90554..503dcbf 100644
--- a/src/styles/components/Header.less
+++ b/src/styles/components/Header.less
@@ -24,7 +24,7 @@ header.vh-header {
justify-content: space-between;
width: 100%;
height: 80%;
- max-width: 1388px;
+ max-width: var(--vh-main-max-width);
a,
span.nav-btn-item {
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 0e2b039..0b09cc5 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -4,41 +4,55 @@ const getDescription = (post: any, num: number = 150) => (post.rendered ? post.r
//处理时间
const fmtTime = (time: any, fmt: string = 'MMMM D, YYYY') => dayjs(time).format(fmt)
// 处理日期
-const fmtDate = (time: any) => {
- const past = dayjs(time);
- const now = dayjs();
- const duration = now.diff(past, 'seconds');
- if (duration < 60) {
- return `${duration} 秒前`;
- } else if (duration < 60 * 60) {
- const minutes = Math.floor(duration / 60);
- return `${minutes} 分钟前`;
- } else if (duration < 60 * 60 * 24) {
- const hours = Math.floor(duration / (60 * 60));
- return `${hours} 小时前`;
- } else if (duration < 60 * 60 * 24 * 30) {
- const days = Math.floor(duration / (60 * 60 * 24));
- return `${days} 天前`;
- } else if (duration < 60 * 60 * 24 * 30 * 12) {
- const months = Math.floor(duration / (60 * 60 * 24 * 30));
- return `${months} 个月前`;
- } else {
- const years = Math.floor(duration / (60 * 60 * 24 * 30 * 12));
- return `${years} 年前`;
- }
+const fmtDate = (time: string | Date) => {
+ const now = dayjs()
+ const past = dayjs(time)
+ // 计算时间差组件
+ const years = now.diff(past, 'year')
+ const months = now.diff(past.add(years, 'year'), 'month')
+ const days = now.diff(past.add(years, 'year').add(months, 'month'), 'day')
+ const hours = now.diff(past, 'hour')
+ const minutes = now.diff(past, 'minute')
+ const seconds = now.diff(past, 'second')
+ // 构建时间差描述
+ return [
+ years && `${years}年`,
+ months && `${months}月`,
+ days && `${days}天`,
+ !years && !months && hours && `${hours}小时`,
+ !years && !months && !days && minutes && `${minutes}分钟`,
+ !years && !months && !days && !hours && `${seconds}秒`
+ ].filter(Boolean).join('')
}
+
// 处理页码展示
const fmtPage = (page: string | undefined) => page ? page.replace(/\//g, '') : null
// 加载外部脚本
-const LoadScript = (src: string): Promise => {
+const LoadScript = (
+ src: string,
+ attrs?: Array<{ k: string; v: string | boolean }>
+): Promise => {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = src;
+ // 添加自定义属性
+ if (attrs?.length) {
+ attrs.forEach(({ k, v }) => {
+ // 处理不同值类型
+ const value = typeof v === "boolean"
+ ? (v ? "" : null) // 布尔值处理为 HTML 标准属性格式
+ : String(v); // 其他类型转为字符串
+
+ if (value !== null) {
+ script.setAttribute(k, value);
+ }
+ });
+ }
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Failed to load script: ${src}`));
document.head.appendChild(script);
});
-}
+};
// 加载外部CSS
const LoadStyle = (href: string): Promise => {
return new Promise((resolve, reject) => {