Compare commits
3 Commits
45906e6e0f
...
309cce14ab
| Author | SHA1 | Date | |
|---|---|---|---|
| 309cce14ab | |||
| bfcdbec4d2 | |||
| c1a601fbde |
49
.env.example
Normal file
49
.env.example
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Mizuki 博客环境变量配置示例
|
||||||
|
# 复制此文件为 .env 并根据需要填写实际值
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 内容仓库配置 (代码内容分离)
|
||||||
|
# 项目地址:https://github.com/matsuzaka-yuki/Mizuki-Content
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# 是否启用内容分离功能 (true/false)
|
||||||
|
# true: 启用内容分离,从独立仓库同步内容
|
||||||
|
# false: 禁用内容分离,使用本地内容 (默认模式)
|
||||||
|
# 注意: 如果不使用内容分离功能,可以注释掉或设置为 false
|
||||||
|
ENABLE_CONTENT_SYNC=true
|
||||||
|
|
||||||
|
# 内容仓库的 Git URL (仅在 ENABLE_CONTENT_SYNC=true 时需要)
|
||||||
|
# 支持 HTTPS 和 SSH 两种方式:
|
||||||
|
# HTTPS: https://github.com/your-username/Mizuki-Content.git
|
||||||
|
# SSH: git@github.com:your-username/Mizuki-Content.git
|
||||||
|
CONTENT_REPO_URL=https://gitea.namyki.top/namyki/BlogContent.git
|
||||||
|
USE_SUBMODULE=true
|
||||||
|
|
||||||
|
# 内容目录路径 (相对于项目根目录)
|
||||||
|
# 默认: ./content 一般无需改动
|
||||||
|
# CONTENT_DIR=./content
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 自动构建触发配置 (内容仓库更新时)
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# 问题: 内容仓库更新不会自动触发代码仓库的部署
|
||||||
|
# 解决: 配置自动触发机制,推荐使用 Repository Dispatch
|
||||||
|
# 详见: docs/AUTO_BUILD_TRIGGER.md (5 步快速配置)
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 统计与分析
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# Umami API 密钥,用于访问 Umami 统计数据
|
||||||
|
# 如果在 config.ts 中启用了 Umami,建议在此配置 API 密钥
|
||||||
|
#UMAMI_API_KEY=your_umami_api_key_here
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 安全配置
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# bcrypt 盐值轮数,用于加密文章密码
|
||||||
|
# 值越大越安全,但构建时间越长
|
||||||
|
# 推荐值:10-14(默认:12)
|
||||||
|
BCRYPT_SALT_ROUNDS=12
|
||||||
1
content
1
content
Submodule content deleted from fb2a4f05d2
@@ -1,28 +0,0 @@
|
|||||||
// 设备数据配置文件
|
|
||||||
|
|
||||||
export interface Device {
|
|
||||||
name: string;
|
|
||||||
image: string;
|
|
||||||
specs: string;
|
|
||||||
description: string;
|
|
||||||
link: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设备类别类型,支持品牌和自定义类别
|
|
||||||
export type DeviceCategory = {
|
|
||||||
[categoryName: string]: Device[];
|
|
||||||
} & {
|
|
||||||
自定义?: Device[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const devicesData: DeviceCategory = {
|
|
||||||
Xiaomi: [
|
|
||||||
{
|
|
||||||
name: "Xiaomi 14Pro",
|
|
||||||
image: "/images/device/mi14p.jpg",
|
|
||||||
specs: "Black / 12G + 256TB",
|
|
||||||
description: "Xiaomi 14 Pro,超越旗舰,超乎所想。",
|
|
||||||
link: "https://www.mi.com/xiaomi-14-pro",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
// 日记数据配置
|
|
||||||
// 用于管理日记页面的数据
|
|
||||||
|
|
||||||
export interface DiaryItem {
|
|
||||||
id: number;
|
|
||||||
content: string;
|
|
||||||
date: string;
|
|
||||||
images?: string[];
|
|
||||||
location?: string;
|
|
||||||
mood?: string;
|
|
||||||
tags?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例日记数据
|
|
||||||
const diaryData: DiaryItem[] = [
|
|
||||||
// {
|
|
||||||
// id: 1,
|
|
||||||
// content:
|
|
||||||
// "The falling speed of cherry blossoms is five centimeters per second!",
|
|
||||||
// date: "2025-01-15T10:30:00Z",
|
|
||||||
// images: ["/images/diary/sakura.jpg", "/images/diary/1.jpg"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 2,
|
|
||||||
// content:
|
|
||||||
// "The falling speed of cherry blossoms is five centimeters per second!",
|
|
||||||
// date: "2025-01-15T10:30:00Z",
|
|
||||||
// images: ["/images/diary/sakura.jpg", "/images/diary/1.jpg"],
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
|
|
||||||
// 获取日记统计数据
|
|
||||||
export const getDiaryStats = () => {
|
|
||||||
const total = diaryData.length;
|
|
||||||
const hasImages = diaryData.filter(
|
|
||||||
(item) => item.images && item.images.length > 0,
|
|
||||||
).length;
|
|
||||||
const hasLocation = diaryData.filter((item) => item.location).length;
|
|
||||||
const hasMood = diaryData.filter((item) => item.mood).length;
|
|
||||||
|
|
||||||
return {
|
|
||||||
total,
|
|
||||||
hasImages,
|
|
||||||
hasLocation,
|
|
||||||
hasMood,
|
|
||||||
imagePercentage: Math.round((hasImages / total) * 100),
|
|
||||||
locationPercentage: Math.round((hasLocation / total) * 100),
|
|
||||||
moodPercentage: Math.round((hasMood / total) * 100),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取日记列表(按时间倒序)
|
|
||||||
export const getDiaryList = (limit?: number) => {
|
|
||||||
const sortedData = diaryData.sort(
|
|
||||||
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (limit && limit > 0) {
|
|
||||||
return sortedData.slice(0, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取最新的日记
|
|
||||||
export const getLatestDiary = () => {
|
|
||||||
return getDiaryList(1)[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 根据ID获取日记
|
|
||||||
export const getDiaryById = (id: number) => {
|
|
||||||
return diaryData.find((item) => item.id === id);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取包含图片的日记
|
|
||||||
export const getDiaryWithImages = () => {
|
|
||||||
return diaryData.filter((item) => item.images && item.images.length > 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 根据标签筛选日记
|
|
||||||
export const getDiaryByTag = (tag: string) => {
|
|
||||||
return diaryData
|
|
||||||
.filter((item) => item.tags?.includes(tag))
|
|
||||||
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取所有标签
|
|
||||||
export const getAllTags = () => {
|
|
||||||
const tags = new Set<string>();
|
|
||||||
diaryData.forEach((item) => {
|
|
||||||
if (item.tags) {
|
|
||||||
item.tags.forEach((tag) => tags.add(tag));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Array.from(tags).sort();
|
|
||||||
};
|
|
||||||
|
|
||||||
export default diaryData;
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
// 友情链接数据配置
|
|
||||||
// 用于管理友情链接页面的数据
|
|
||||||
|
|
||||||
export interface FriendItem {
|
|
||||||
id: number;
|
|
||||||
title: string;
|
|
||||||
imgurl: string;
|
|
||||||
desc: string;
|
|
||||||
siteurl: string;
|
|
||||||
tags: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 友情链接数据
|
|
||||||
export const friendsData: FriendItem[] = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: "Astro",
|
|
||||||
imgurl: "https://avatars.githubusercontent.com/u/44914786?v=4&s=640",
|
|
||||||
desc: "The web framework for content-driven websites",
|
|
||||||
siteurl: "https://github.com/withastro/astro",
|
|
||||||
tags: ["Framework"],
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// id: 2,
|
|
||||||
// title: "Mizuki Docs",
|
|
||||||
// imgurl:
|
|
||||||
// "http://q.qlogo.cn/headimg_dl?dst_uin=3231515355&spec=640&img_type=jpg",
|
|
||||||
// desc: "Mizuki User Manual",
|
|
||||||
// siteurl: "https://docs.mizuki.mysqil.com",
|
|
||||||
// tags: ["Docs"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 3,
|
|
||||||
// title: "Vercel",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/14985020?v=4&s=640",
|
|
||||||
// desc: "Develop. Preview. Ship.",
|
|
||||||
// siteurl: "https://vercel.com",
|
|
||||||
// tags: ["Hosting", "Cloud"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 4,
|
|
||||||
// title: "Tailwind CSS",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/67109815?v=4&s=640",
|
|
||||||
// desc: "A utility-first CSS framework for rapidly building custom designs",
|
|
||||||
// siteurl: "https://tailwindcss.com",
|
|
||||||
// tags: ["CSS", "Framework"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 5,
|
|
||||||
// title: "TypeScript",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/6154722?v=4&s=640",
|
|
||||||
// desc: "TypeScript is JavaScript with syntax for types",
|
|
||||||
// siteurl: "https://www.typescriptlang.org",
|
|
||||||
// tags: ["Language", "JavaScript"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 6,
|
|
||||||
// title: "React",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/6412038?v=4&s=640",
|
|
||||||
// desc: "A JavaScript library for building user interfaces",
|
|
||||||
// siteurl: "https://reactjs.org",
|
|
||||||
// tags: ["Framework", "JavaScript"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 7,
|
|
||||||
// title: "GitHub",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/9919?v=4&s=640",
|
|
||||||
// desc: "Where the world builds software",
|
|
||||||
// siteurl: "https://github.com",
|
|
||||||
// tags: ["Development", "Platform"],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 8,
|
|
||||||
// title: "MDN Web Docs",
|
|
||||||
// imgurl: "https://avatars.githubusercontent.com/u/7565578?v=4&s=640",
|
|
||||||
// desc: "The web's most comprehensive resource for web developers",
|
|
||||||
// siteurl: "https://developer.mozilla.org",
|
|
||||||
// tags: ["Docs", "Reference"],
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
|
|
||||||
// 获取所有友情链接数据
|
|
||||||
export function getFriendsList(): FriendItem[] {
|
|
||||||
return friendsData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取随机排序的友情链接数据
|
|
||||||
export function getShuffledFriendsList(): FriendItem[] {
|
|
||||||
const shuffled = [...friendsData];
|
|
||||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
|
||||||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
||||||
}
|
|
||||||
return shuffled;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user