签入版本

This commit is contained in:
小蚂蚁云
2026-10-25 17:24:27 +08:00
parent 48911cc08f
commit fdbeae092a
1010 changed files with 30682 additions and 95274 deletions
@@ -1,51 +1,47 @@
// import type { DefaultTheme, LocaleSpecificConfig } from "vitepress";
import type { DefaultTheme, LocaleSpecificConfig } from "vitepress";
// export const META_URL = "https://www.rxthink.cn";
// export const META_TITLE = "RXThinkCMF";
// export const META_DESCRIPTION = "Enterprise Admin Framework";
export const META_URL = "https://www.easygoadmin.vip";
export const META_TITLE = "EasyGoAdmin";
export const META_DESCRIPTION = "Enterprise Admin Framework";
// export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
// description: META_DESCRIPTION,
// head: [
// ["meta", { property: "og:url", content: META_URL }],
// ["meta", { property: "og:description", content: META_DESCRIPTION }],
// ["meta", { property: "twitter:url", content: META_URL }],
// ["meta", { property: "twitter:title", content: META_TITLE }],
// ["meta", { property: "twitter:description", content: META_DESCRIPTION }],
// [
// "script",
// {},
// `
// var _hmt = _hmt || [];
// (function() {
// var hm = document.createElement("script");
// hm.src = "https://hm.baidu.com/hm.js?f2662051bbed33ef4673edf8bfe609fe";
// var s = document.getElementsByTagName("script")[0];
// s.parentNode.insertBefore(hm, s);
// })();
// `,
// ],
// ],
//
// themeConfig: {
// editLink: {
// pattern: "https://gitee.com/rxthinkcmf/RXThinkCMF_ThinkPhp8_EleVue",
// text: "Suggest changes to this page",
// },
//
// nav: [
// { text: "Guide", link: "/en/introduction.html" },
// ],
//
// sidebar: {
// "/en/": [
// {
// text: "Introduction",
// items: [
// { text: "About", link: "/en/introduction.html" },
// ],
// },
// ],
// },
// },
// };
export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
description: META_DESCRIPTION,
head: [
["meta", { property: "og:url", content: META_URL }],
["meta", { property: "og:description", content: META_DESCRIPTION }],
["meta", { property: "twitter:url", content: META_URL }],
["meta", { property: "twitter:title", content: META_TITLE }],
["meta", { property: "twitter:description", content: META_DESCRIPTION }],
[
"script",
{},
`
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?f2662051bbed33ef4673edf8bfe609fe";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
`,
],
],
themeConfig: {
editLink: {
pattern: "https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_EleVue",
text: "Suggest changes to this page",
},
nav: [{ text: "Guide", link: "/en/introduction.html" }],
sidebar: {
"/en/": [
{
text: "Introduction",
items: [{ text: "About", link: "/en/introduction.html" }],
},
],
},
},
};
@@ -0,0 +1,5 @@
export declare const SITE_URL: string;
export declare const SITE_DESCRIPTION: string;
export declare function stripNumberPrefix(title: string): string;
export declare function extractDescription(md: string): string;
export declare function extractFaqs(md: string): { q: string; a: string }[];
@@ -0,0 +1,122 @@
/**
* SEO/GEO 共享工具(纯 ESM,零依赖)。
*
* 同时被两类调用方 import:
* 1. VitePress 配置(.ts,esbuild 打包时内联本文件)
* 2. scripts/generate-llms-txt.mjs(Node 直接运行)
*
* 注意:SITE_URL 是全站唯一 URL 真相源。
* docs 子域当前 TLS 证书为腾讯 CDN 默认证书(*.cdn.myqcloud.com,校验失败),
* 故暂用 http;证书修复后只需改这里一处。
*/
export const SITE_URL = "http://docs.goframe.elevue.easygoadmin.vip";
export const SITE_DESCRIPTION =
"EasyGoAdmin 企业级多租户后台管理基座 - GoFrame v2 + Vue3 + ElementPlus";
/**
* 剥离 H1/标题中的章节编号前缀,用于 <title> 与 JSON-LD headline。
* 例:"5.10 字典模块" → "字典模块";"K. 贡献指南" → "贡献指南"。
* 页内 H1 与侧边栏编号保持不变,仅影响 SEO 输出。
*/
export function stripNumberPrefix(title) {
return String(title)
.replace(/^(?:\d+(?:\.\d+)+|[A-Z]\.)\s+/, "")
.trim();
}
/**
* 从页面 Markdown 提取 meta description:
* 1. 首选 `:::tip xxx` 容器内的首句(141/143 页的标准 opener)
* 2. 回退到 H1 后的第一个普通段落
* 输出压缩为单行、去除行内 Markdown,按中文句末标点截断(≤100 字符)。
*/
export function extractDescription(md) {
let body = String(md).replace(/^---[\s\S]*?\n---\s*/, "");
let text = "";
const tip = body.match(/^:::\s*tip[^\n]*\n([\s\S]*?)\n:::/m);
if (tip) {
text = tip[1];
} else {
const afterH1 = body.match(/^# (?!#)(.+)$/m);
if (afterH1) {
const rest = body.slice((afterH1.index ?? 0) + afterH1[0].length);
const para = rest
.split(/\n{2,}/)
.find(
(p) =>
p.trim() &&
!/^\s*#/.test(p) &&
!/^\s*:::/.test(p) &&
!/^\s*```/.test(p) &&
!/^\s*\|/.test(p),
);
text = para || "";
}
}
text = text
.replace(/\s+/g, " ")
.replace(/`([^`]+)`/g, "$1")
.replace(/\*\*([^*]+)\*\*/g, "$1")
.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1")
.trim();
if (!text) return "";
// 按中文句末标点截取首句,上限 100 字符;截断时避免切碎词
const m = text.match(/^.{1,100}?(?:[。!?!?]|$)/);
let out = m ? m[0] : text.slice(0, 100);
if (out.length < text.length && !/[。!?!?]$/.test(out)) {
out = out.replace(/[^\s,、;:,;:]+$/, "");
}
return out.trim() || text.slice(0, 100);
}
function cleanText(s) {
return s
.replace(/^:::[^\n]*$/gm, "")
.replace(/^```[^\n]*$/gm, "")
.replace(/`([^`]+)`/g, "$1")
.replace(/\*\*([^*]+)\*\*/g, "$1")
.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1")
.replace(/\s+/g, " ")
.trim();
}
/**
* 提取页面中的 Q/A 对(用于 FAQPage JSON-LD),支持两种站内格式:
* A. `### Q:问题` 标题式(如 zh/quickstart/faq.md)
* B. `**Q:问题**` 加粗式(如 zh/appendix/faq.md)
* 返回 [{ q, a }];无匹配返回 []。
*/
export function extractFaqs(md) {
const body = String(md).replace(/^---[\s\S]*?\n---\s*/, "");
let faqs = [];
// 格式 A:按 `### Q:` 切块,答案截断到下一个标题
for (const part of body.split(/(?=^###\s*Q[::])/m)) {
const m = part.match(/^###\s*Q[::]\s*([^\n]+)\n+([\s\S]*)/);
if (!m) continue;
let a = m[2];
const cut = a.search(/^#{1,4}\s/m);
if (cut >= 0) a = a.slice(0, cut);
faqs.push({ q: cleanText(m[1]), a: cleanText(a) });
}
// 格式 B:按 `**Q:` 切块
if (!faqs.length) {
for (const part of body.split(/(?=^\*\*Q[::])/m)) {
const m = part.match(/^\*\*Q[::]\s*([^*]+)\*\*\s*\n+([\s\S]*)/);
if (!m) continue;
let a = m[2];
const cut = a.search(/^(?:#{1,4}\s|\*\*Q)/m);
if (cut >= 0) a = a.slice(0, cut);
faqs.push({ q: cleanText(m[1]), a: cleanText(a) });
}
}
return faqs.filter((f) => f.q && f.a);
}
@@ -1,14 +1,22 @@
import { defineConfig } from "vitepress";
import { enConfig } from "./en";
import { createSeoHooks } from "./seo";
import { sharedConfig } from "./shared";
import { zhConfig } from "./zh";
const seo = createSeoHooks(zhConfig.themeConfig?.sidebar);
export default defineConfig({
...sharedConfig,
ignoreDeadLinks: [
(link) => link.includes('localhost'),
],
// SEO:页面级 title/description、canonical/OG/JSON-LD、sitemap+lastmod
transformPageData: seo.transformPageData,
transformHead: seo.transformHead,
sitemap: seo.sitemap,
locales: {
root: { label: "简体中文", lang: "zh-CN", link: "/", ...zhConfig },
// root: { label: "English", lang: "en-US", link: "/", ...enConfig },
@@ -0,0 +1,304 @@
/**
* SEO/GEO 构建期钩子(仅 Node 构建时运行,不进客户端 bundle):
* - transformPageData:每页独立 title(去编号前缀)与 description(取 :::tip 首句)
* - transformHead:canonical / Open Graph / twitter 卡片 / JSON-LD 结构化数据
* - sitemap.transformItems:注入 lastmod(git 最后提交时间)并过滤 404
*
* 由 config/index.ts 通过 createSeoHooks(zhConfig.themeConfig?.sidebar) 挂载。
* 依赖 extract.mjs(纯 ESM,同被 scripts/generate-llms-txt.mjs 复用)。
*/
import fs from "node:fs";
import path from "node:path";
import { execSync } from "node:child_process";
import {
SITE_URL,
extractDescription,
extractFaqs,
stripNumberPrefix,
} from "./extract.mjs";
/** 与 vitepress HeadConfig 同构:[tag, attrs, innerHTML?] */
type HeadTuple = [string, Record<string, any>, string?];
interface SideItem {
text?: string;
link?: string;
items?: SideItem[];
}
interface PageDataLike {
relativePath?: string;
title?: string;
description?: string;
frontmatter?: Record<string, any>;
[k: string]: any;
}
interface TransformCtx {
pageData?: PageDataLike;
title?: string;
description?: string;
content?: string;
siteConfig?: { root?: string; srcDir?: string };
}
const ORG = {
"@type": "Organization",
name: "EasyGoAdmin",
url: "https://www.easygoadmin.vip",
logo: `${SITE_URL}/logo.png`,
sameAs: [
"https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_EleVue",
"https://www.easygoadmin.vip",
],
};
/** 相对路径 → 站内路由(cleanUrls 关闭,正文页带 .html) */
function routeOf(relativePath: string): string {
if (relativePath === "index.md") return "/";
if (relativePath === "404.md") return "/404.html";
return `/${relativePath.replace(/\.md$/, ".html")}`;
}
/** 去掉侧边栏文案前导 emoji/符号,保留 "1.1 项目介绍" 这类编号文字 */
function cleanLabel(s?: string): string {
return (s || "").replace(/^[^\p{L}\p{N}]+/u, "").trim();
}
/** 从侧边栏构建 route → 面包屑文案链(含分组小节) */
function buildCrumbMap(sidebar: unknown): Map<string, string[]> {
const map = new Map<string, string[]>();
const groups: SideItem[] = Array.isArray(sidebar)
? sidebar
: ((sidebar as Record<string, SideItem[]>)?.["/zh/"] ?? []);
const walk = (items: SideItem[], trail: string[]) => {
for (const item of items) {
if (item.link && item.link.startsWith("/")) {
map.set(item.link, [...trail, cleanLabel(item.text)]);
} else if (item.items?.length) {
walk(item.items, [...trail, cleanLabel(item.text)]);
}
}
};
for (const group of groups) {
walk(group.items ?? [], [cleanLabel(group.text)].filter(Boolean));
}
return map;
}
/** 从渲染后的 HTML 提取 H1 纯文本(JSON-LD headline 须与页面 H1 一致) */
function h1OfHtml(html?: string): string {
const m = (html || "").match(/<h1[^>]*>([\s\S]*?)<\/h1>/i);
if (!m) return "";
return m[1]
.replace(/<[^>]+>/g, "")
.replace(/&amp;/g, "&")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.trim();
}
/** 从 Markdown 源提取 H1 纯文本(去除行内 markdown 标记) */
function h1OfMd(md: string): string {
const m = md.match(/^# (?!#)(.+)$/m);
if (!m) return "";
return m[1]
.replace(/`([^`]+)`/g, "$1")
.replace(/\*\*([^*]+)\*\*/g, "$1")
.trim();
}
export function createSeoHooks(sidebar: unknown) {
const crumbs = buildCrumbMap(sidebar);
const projectDirs: string[] = [];
let gitDates: Map<string, string> | null = null;
const readMd = (relativePath: string, srcDir?: string): string => {
try {
return fs.readFileSync(
path.resolve(srcDir || process.cwd(), relativePath),
"utf8",
);
} catch {
return "";
}
};
/**
* 项目内每个文件最后一次 git 提交的 ISO 时间。
* 单次 git log 调用构建全量映射(key = 相对路径,与 pageData.relativePath 一致);
* git 不可用时静默降级(sitemap 无 lastmod、JSON-LD 无 dateModified)。
*/
const getGitDates = (root: string): Map<string, string> => {
if (gitDates) return gitDates;
gitDates = new Map<string, string>();
try {
const out = execSync(
"git log --format=:::%cI --name-only --relative -n 500 -- .",
{
cwd: root,
encoding: "utf8",
maxBuffer: 64 * 1024 * 1024,
stdio: ["ignore", "pipe", "ignore"],
},
);
let current = "";
for (const line of out.split(/\r?\n/)) {
if (line.startsWith(":::")) {
current = line.slice(3).trim();
continue;
}
const file = line.trim();
if (file && current && !gitDates.has(file)) {
gitDates.set(file, current);
}
}
} catch {
// 降级:无 lastmod / dateModified
}
return gitDates;
};
/** 每页独立 title(去 "5.10 " 编号前缀,关键词前置)与 description(:::tip 首句) */
function transformPageData(pageData: PageDataLike, ctx?: any): Record<string, unknown> {
const srcDir: string | undefined = ctx?.siteConfig?.srcDir;
const root: string | undefined = ctx?.siteConfig?.root;
if (root && !projectDirs.includes(root)) projectDirs.push(root);
const out: Record<string, unknown> = {};
const rel = pageData.relativePath;
if (rel && !pageData.frontmatter?.description) {
const desc = extractDescription(readMd(rel, srcDir));
if (desc) out.description = desc;
}
if (pageData.title) {
out.title = stripNumberPrefix(pageData.title);
}
return out;
}
/** 构建期注入 canonical / OG / twitter / JSON-LD */
function transformHead(ctx: TransformCtx): HeadTuple[] {
const rel = ctx?.pageData?.relativePath || "";
if (!rel || rel === "404.md") return [];
const route = routeOf(rel);
const url = `${SITE_URL}${route}`;
const title = ctx.pageData?.title || ctx.title || "";
const desc = ctx.description || "";
const isHome = rel === "index.md";
const image = `${SITE_URL}/logo.png`;
const heads: HeadTuple[] = [
["link", { rel: "canonical", href: url }],
["meta", { property: "og:type", content: isHome ? "website" : "article" }],
["meta", { property: "og:site_name", content: "EasyGoAdmin" }],
["meta", { property: "og:locale", content: "zh_CN" }],
["meta", { property: "og:title", content: title }],
["meta", { property: "og:description", content: desc }],
["meta", { property: "og:url", content: url }],
["meta", { property: "og:image", content: image }],
["meta", { property: "twitter:title", content: title }],
["meta", { property: "twitter:description", content: desc }],
["meta", { property: "twitter:url", content: url }],
["meta", { property: "twitter:image", content: image }],
];
// ---- JSON-LD ----
const root = ctx.siteConfig?.root || projectDirs[0] || process.cwd();
const srcDir = ctx.siteConfig?.srcDir || root;
const lastMod = getGitDates(root).get(rel);
const blocks: Record<string, any>[] = [];
if (isHome) {
blocks.push({
"@context": "https://schema.org",
"@type": "WebSite",
name: "EasyGoAdmin 开发文档",
url: `${SITE_URL}/`,
inLanguage: "zh-CN",
description: desc,
});
blocks.push({ "@context": "https://schema.org", ...ORG });
} else {
const md = readMd(rel, srcDir);
const article: Record<string, any> = {
"@context": "https://schema.org",
"@type": "TechArticle",
headline: h1OfMd(md) || h1OfHtml(ctx.content) || title,
description: desc,
url,
inLanguage: "zh-CN",
mainEntityOfPage: { "@type": "WebPage", "@id": url },
publisher: ORG,
};
if (lastMod) article.dateModified = lastMod;
blocks.push(article);
const trail = crumbs.get(route);
if (trail?.length) {
const items: Record<string, any>[] = [
{ "@type": "ListItem", position: 1, name: "首页", item: `${SITE_URL}/` },
];
trail.forEach((name, i) => {
const node: Record<string, any> = {
"@type": "ListItem",
position: i + 2,
name,
};
if (i === trail.length - 1) node.item = url;
items.push(node);
});
blocks.push({
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: items,
});
}
const faqs = extractFaqs(md);
if (faqs.length) {
blocks.push({
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: faqs.map((f) => ({
"@type": "Question",
name: f.q,
acceptedAnswer: { "@type": "Answer", text: f.a },
})),
});
}
}
// 转义 "<",防止内容中出现 </script> 破坏注入
const json = JSON.stringify(blocks).replace(/</g, "\\u003c");
heads.push(["script", { type: "application/ld+json" }, json]);
return heads;
}
/** sitemap.xml:过滤 404/README,注入 git lastmod */
const sitemap = {
hostname: SITE_URL,
transformItems(items: { url: string; lastmod?: string }[]) {
const root = projectDirs[0] || process.cwd();
const dates = getGitDates(root);
const out: { url: string; lastmod?: string }[] = [];
for (const item of items) {
// ⚠ vitepress 传入的 item.url 是相对路径("404.html"、"zh/x.html"、""),
// 无前导斜杠也无域名——hostname 由 SitemapStream 事后拼接。
if (/(^|\/)404\.html$/.test(item.url)) continue; // 404 页不收录
if (/(^|\/)README\.html$/.test(item.url)) continue; // 仓库 README 非文档页
const p = item.url.replace(/^\//, "");
const rel =
p === "" || p === "index.html" ? "index.md" : p.replace(/\.html$/, ".md");
const lastmod = dates.get(rel);
out.push(lastmod ? { ...item, lastmod } : item);
}
return out;
},
};
return { transformPageData, transformHead, sitemap };
}
@@ -23,6 +23,8 @@ export const slugify = (str: string): string =>
export const sharedConfig = defineConfig({
title: "EasyGoAdmin",
// 页面 <title> 后缀:「字典模块 | EasyGoAdmin 开发文档」(index.md frontmatter 可覆盖)
titleTemplate: "EasyGoAdmin 开发文档",
appearance: "light",
markdown: {
@@ -1,9 +1,8 @@
import type { DefaultTheme, LocaleSpecificConfig } from "vitepress";
export const META_URL = "http://docs.goframe.elevue.easygoadmin.vip/";
export const META_URL = "http://docs.goframe.elevue.easygoadmin.vip";
export const META_TITLE = "EasyGoAdmin GoFrame+ElementPlus 开发文档";
export const META_DESCRIPTION =
"EasyGoAdmin 企业级多租户后台管理基座 - GoFrame v2 + Vue3 + ElementPlus";
export const META_DESCRIPTION = "EasyGoAdmin 企业级多租户后台管理基座 - GoFrame v2 + Vue3 + ElementPlus";
export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
description: META_DESCRIPTION,
@@ -13,6 +12,19 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
["meta", { property: "twitter:url", content: META_URL }],
["meta", { property: "twitter:title", content: META_TITLE }],
["meta", { property: "twitter:description", content: META_DESCRIPTION }],
[
"script",
{},
`
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?09709f15864acfe85b0d8edd6dabcbbc";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
`,
],
],
themeConfig: {
@@ -32,8 +44,149 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
nav: [
{ text: "官网", link: "https://www.easygoadmin.vip" },
{ text: "Gitee 仓库", link: "https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_EleVue" },
{ text: "在线文档", link: "http://docs.goframe.elevue.easygoadmin.vip/" },
{ text: "授权", link: "https://www.easygoadmin.vip/goods/detail/2" },
{
text: "部署文档",
items: [
{
text: "EasyGoAdmin混编版GoFrame+Layui版本",
link: "http://docs.goframe.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+ElementPlus版本",
link: "http://docs.goframe.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+AntDesign版本",
link: "http://docs.goframe.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+NaiveUI版本",
link: "http://docs.goframe.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Gin+Layui版本",
link: "http://docs.gin.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+ElementPlus版本",
link: "http://docs.gin.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+AntDesign版本",
link: "http://docs.gin.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+NaiveUI版本",
link: "http://docs.gin.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Beego+Layui版本",
link: "http://docs.beego.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+ElementPlus版本",
link: "http://docs.beego.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+AntDesign版本",
link: "http://docs.beego.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+NaiveUI版本",
link: "http://docs.beego.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Iris+Layui版本",
link: "http://docs.iris.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+ElementPlus版本",
link: "http://docs.iris.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+AntDesign版本",
link: "http://docs.iris.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+NaiveUI版本",
link: "http://docs.iris.naivevue.easygoadmin.vip",
},
],
},
{
text: "在线演示",
items: [
{
text: "EasyGoAdmin混编版GoFrame+Layui版本",
link: "http://manage.goframe.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+ElementPlus版本",
link: "http://manage.goframe.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+AntDesign版本",
link: "http://manage.goframe.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离GoFrame+NaiveUI版本",
link: "http://manage.goframe.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Gin+Layui版本",
link: "http://manage.gin.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+ElementPlus版本",
link: "http://manage.gin.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+AntDesign版本",
link: "http://manage.gin.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Gin+NaiveUI版本",
link: "http://manage.gin.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Beego+Layui版本",
link: "http://manage.beego.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+ElementPlus版本",
link: "http://manage.beego.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+AntDesign版本",
link: "http://manage.beego.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Beego+NaiveUI版本",
link: "http://manage.beego.naivevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin混编版Iris+Layui版本",
link: "http://manage.iris.layui.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+ElementPlus版本",
link: "http://manage.iris.elevue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+AntDesign版本",
link: "http://manage.iris.antdvue.easygoadmin.vip",
},
{
text: "EasyGoAdmin前后端分离Iris+NaiveUI版本",
link: "http://manage.iris.naivevue.easygoadmin.vip",
},
],
},
{
text: "广告赞助",
link: "/zh/other/sponsor.html",
},
{
text: "相关链接",
items: [
@@ -173,10 +326,10 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
],
},
{
text: "📄 注解系统",
text: "📄 标签系统",
collapsed: false,
items: [
{ text: "📄 5.18 gmeta 注解系统总览", link: "/zh/core/attributes.html" },
{ text: "📄 5.18 gmeta 标签系统总览", link: "/zh/core/gmeta.html" },
],
},
],
@@ -24,8 +24,8 @@ const asideSponsors = computed(() => {
: [
{
name: "Become a sponsor",
url: "https://www.rxthink.cn",
img: "/sponsor/rxthinkcmf.png",
url: "https://www.easygoadmin.vip",
img: "/sponsor/sponsor.png",
},
],
},
@@ -45,8 +45,8 @@ const asideSponsors = computed(() => {
<template>
<VPDocAsideSponsors :data="asideSponsors" />
<a class="banner mp" href="https://www.rxthink.cn" target="_blank">
<img width="22" height="22" src="/sponsor/rxthinkcmf.png" />
<a class="banner mp" href="https://www.easygoadmin.vip" target="_blank">
<img width="22" height="22" src="/sponsor/sponsor.png" />
<span>
<p class="extra-info">赋能开发者</p>
<p class="heading">企业级中台解决方案</p>
@@ -54,8 +54,8 @@ const asideSponsors = computed(() => {
</span>
</a>
<a class="banner cert" href="https://www.rxthink.cn" target="_blank">
<img width="22" height="22" src="/sponsor/rxthinkcmf.png" />
<a class="banner cert" href="https://www.easygoadmin.vip" target="_blank">
<img width="22" height="22" src="/sponsor/sponsor.png" />
<span>
<p class="extra-info">赋能开发者</p>
<p class="heading">企业级中台解决方案</p>
@@ -67,12 +67,12 @@ const isVideoOpen = ref(false);
<div class="watch-more">
{{ translations.watchMoreA[site.lang] }}
<a
:href="mpLink || 'https://www.rxthink.cn'"
:href="mpLink || 'https://www.easygoadmin.vip'"
target="_blank"
rel="noopener"
>
小蚂蚁云
<img src="../../../public/logo.svg" alt="小蚂蚁云" />
EasyGoAdmin
<img src="../../../public/logo.svg" alt="EasyGoAdmin" />
</a>
{{ translations.watchMoreB[site.lang] }}
</div>
@@ -4,35 +4,35 @@
"silver": [
{
"alt": "企业级中台解决方案",
"href": "https://www.rxthink.cn",
"imgSrcDark": "/sponsor/rxthinkcmf.png",
"imgSrcLight": "/sponsor/rxthinkcmf.png"
"href": "https://www.easygoadmin.vip",
"imgSrcDark": "/sponsor/sponsor.png",
"imgSrcLight": "/sponsor/sponsor.png"
},
{
"alt": "企业级中台解决方案",
"href": "https://www.rxthink.cn",
"imgSrcDark": "/sponsor/rxthinkcmf.png",
"imgSrcLight": "/sponsor/rxthinkcmf.png"
"href": "https://www.easygoadmin.vip",
"imgSrcDark": "/sponsor/sponsor.png",
"imgSrcLight": "/sponsor/sponsor.png"
}
],
"bronze": [
{
"alt": "企业级中台解决方案",
"href": "https://www.rxthink.cn",
"imgSrcDark": "/sponsor/rxthinkcmf.png",
"imgSrcLight": "/sponsor/rxthinkcmf.png"
"href": "https://www.easygoadmin.vip",
"imgSrcDark": "/sponsor/sponsor.png",
"imgSrcLight": "/sponsor/sponsor.png"
},
{
"alt": "企业级中台解决方案",
"href": "https://www.rxthink.cn",
"imgSrcDark": "/sponsor/rxthinkcmf.png",
"imgSrcLight": "/sponsor/rxthinkcmf.png"
"href": "https://www.easygoadmin.vip",
"imgSrcDark": "/sponsor/sponsor.png",
"imgSrcLight": "/sponsor/sponsor.png"
},
{
"alt": "企业级中台解决方案",
"href": "https://www.rxthink.cn",
"imgSrcDark": "/sponsor/rxthinkcmf.png",
"imgSrcLight": "/sponsor/rxthinkcmf.png"
"href": "https://www.easygoadmin.vip",
"imgSrcDark": "/sponsor/sponsor.png",
"imgSrcLight": "/sponsor/sponsor.png"
}
]
}
@@ -1,6 +1,8 @@
import { h } from "vue";
import { type Theme, useRoute } from "vitepress";
import DefaultTheme from "vitepress/theme";
import AsideSponsors from "./components/AsideSponsors.vue";
import VideoModuleLink from "./components/VideoModuleLink.vue";
import "./styles/vars.css";
import imageViewer from "vitepress-plugin-image-viewer";
import vImageViewer from "vitepress-plugin-image-viewer/lib/vImageViewer.vue";
@@ -18,6 +20,7 @@ const theme: Theme = {
alt: "EasyGoAdmin",
}),
),
"aside-ads-before": () => h(AsideSponsors),
});
},
setup() {
@@ -25,6 +28,7 @@ const theme: Theme = {
imageViewer(route);
},
enhanceApp({ app }) {
app.component("VideoModuleLink", VideoModuleLink);
app.component("vImageViewer", vImageViewer);
},
};