first commit

This commit is contained in:
2025-09-22 01:39:01 +08:00
commit 8af3499484
1466 changed files with 126409 additions and 0 deletions

View File

@@ -0,0 +1,231 @@
import type { DefaultTheme } from 'vitepress';
import { defineConfig } from 'vitepress';
import { version } from '../../../package.json';
export const en = defineConfig({
description: 'Vben Admin & Enterprise level management system framework',
lang: 'en-US',
themeConfig: {
darkModeSwitchLabel: 'Theme',
darkModeSwitchTitle: 'Switch to Dark Mode',
docFooter: {
next: 'Next Page',
prev: 'Previous Page',
},
editLink: {
pattern:
'https://github.com/vbenjs/vue-vben-admin/edit/main/docs/src/:path',
text: 'Edit this page on GitHub',
},
footer: {
copyright: `Copyright © 2020-${new Date().getFullYear()} Vben`,
message: 'Released under the MIT License.',
},
langMenuLabel: 'Language',
lastUpdated: {
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium',
},
text: 'Last updated on',
},
lightModeSwitchTitle: 'Switch to Light Mode',
nav: nav(),
outline: {
label: 'Navigate',
},
returnToTopLabel: 'Back to top',
sidebar: {
'/en/commercial/': {
base: '/en/commercial/',
items: sidebarCommercial(),
},
'/en/guide/': { base: '/en/guide/', items: sidebarGuide() },
},
},
});
function sidebarGuide(): DefaultTheme.SidebarItem[] {
return [
{
collapsed: false,
text: 'Introduction',
items: [
{
link: 'introduction/vben',
text: 'About Vben Admin',
},
{
link: 'introduction/why',
text: 'Why Choose Us?',
},
{ link: 'introduction/quick-start', text: 'Quick Start' },
{ link: 'introduction/thin', text: 'Lite Version' },
],
},
{
text: 'Basics',
items: [
{ link: 'essentials/concept', text: 'Basic Concepts' },
{ link: 'essentials/development', text: 'Local Development' },
{ link: 'essentials/route', text: 'Routing and Menu' },
{ link: 'essentials/settings', text: 'Configuration' },
{ link: 'essentials/icons', text: 'Icons' },
{ link: 'essentials/styles', text: 'Styles' },
{ link: 'essentials/external-module', text: 'External Modules' },
{ link: 'essentials/build', text: 'Build and Deployment' },
{ link: 'essentials/server', text: 'Server Interaction and Data Mock' },
],
},
{
text: 'Advanced',
items: [
{ link: 'in-depth/login', text: 'Login' },
{ link: 'in-depth/theme', text: 'Theme' },
{ link: 'in-depth/access', text: 'Access Control' },
{ link: 'in-depth/locale', text: 'Internationalization' },
{ link: 'in-depth/features', text: 'Common Features' },
{ link: 'in-depth/check-updates', text: 'Check Updates' },
{ link: 'in-depth/loading', text: 'Global Loading' },
{ link: 'in-depth/ui-framework', text: 'UI Framework Switching' },
],
},
{
text: 'Engineering',
items: [
{ link: 'project/standard', text: 'Standards' },
{ link: 'project/cli', text: 'CLI' },
{ link: 'project/dir', text: 'Directory Explanation' },
{ link: 'project/test', text: 'Unit Testing' },
{ link: 'project/tailwindcss', text: 'Tailwind CSS' },
{ link: 'project/changeset', text: 'Changeset' },
{ link: 'project/vite', text: 'Vite Config' },
],
},
{
text: 'Others',
items: [
{ link: 'other/project-update', text: 'Project Update' },
{ link: 'other/remove-code', text: 'Remove Code' },
{ link: 'other/faq', text: 'FAQ' },
],
},
];
}
function sidebarCommercial(): DefaultTheme.SidebarItem[] {
return [
{
link: 'community',
text: 'Community',
},
{
link: 'technical-support',
text: 'Technical-support',
},
{
link: 'customized',
text: 'Customized',
},
];
}
function nav(): DefaultTheme.NavItem[] {
return [
{
activeMatch: '^/en/(guide|components)/',
text: 'Doc',
items: [
{
activeMatch: '^/en/guide/',
link: '/en/guide/introduction/vben',
text: 'Guide',
},
// {
// activeMatch: '^/en/components/',
// link: '/en/components/introduction',
// text: 'Components',
// },
{
text: 'Historical Versions',
items: [
{
link: 'https://doc.vvbin.cn',
text: '2.x Version Documentation',
},
],
},
],
},
{
text: 'Demo',
items: [
{
text: 'Vben Admin',
items: [
{
link: 'https://www.vben.pro',
text: 'Demo Version',
},
{
link: 'https://ant.vben.pro',
text: 'Ant Design Vue Version',
},
{
link: 'https://naive.vben.pro',
text: 'Naive Version',
},
{
link: 'https://ele.vben.pro',
text: 'Element Plus Version',
},
],
},
{
text: 'Others',
items: [
{
link: 'https://vben.vvbin.cn',
text: 'Vben Admin 2.x',
},
],
},
],
},
{
text: version,
items: [
{
link: 'https://github.com/vbenjs/vue-vben-admin/releases',
text: 'Changelog',
},
{
link: 'https://github.com/orgs/vbenjs/projects/5',
text: 'Roadmap',
},
{
link: 'https://github.com/vbenjs/vue-vben-admin/blob/main/.github/contributing.md',
text: 'Contribution',
},
],
},
{
link: '/commercial/technical-support',
text: '🦄 Tech Support',
},
{
link: '/sponsor/personal',
text: '✨ Sponsor',
},
{
link: '/commercial/community',
text: '👨‍👦‍👦 Community',
},
// {
// link: '/friend-links/',
// text: '🤝 Friend Links',
// },
];
}

View File

@@ -0,0 +1,25 @@
import { withPwa } from '@vite-pwa/vitepress';
import { defineConfigWithTheme } from 'vitepress';
import { en } from './en.mts';
import { shared } from './shared.mts';
import { zh } from './zh.mts';
export default withPwa(
defineConfigWithTheme({
...shared,
locales: {
en: {
label: 'English',
lang: 'en',
link: '/en/',
...en,
},
root: {
label: '简体中文',
lang: 'zh-CN',
...zh,
},
},
}),
);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,143 @@
import type { MarkdownEnv, MarkdownRenderer } from 'vitepress';
import crypto from 'node:crypto';
import { readdirSync } from 'node:fs';
import { join } from 'node:path';
export const rawPathRegexp =
// eslint-disable-next-line regexp/no-super-linear-backtracking, regexp/strict
/^(.+?(?:\.([\da-z]+))?)(#[\w-]+)?(?: ?{(\d+(?:[,-]\d+)*)? ?(\S+)?})? ?(?:\[(.+)])?$/;
function rawPathToToken(rawPath: string) {
const [
filepath = '',
extension = '',
region = '',
lines = '',
lang = '',
rawTitle = '',
] = (rawPathRegexp.exec(rawPath) || []).slice(1);
const title = rawTitle || filepath.split('/').pop() || '';
return { extension, filepath, lang, lines, region, title };
}
export const demoPreviewPlugin = (md: MarkdownRenderer) => {
md.core.ruler.after('inline', 'demo-preview', (state) => {
const insertComponentImport = (importString: string) => {
const index = state.tokens.findIndex(
(i) => i.type === 'html_block' && i.content.match(/<script setup>/g),
);
if (index === -1) {
const importComponent = new state.Token('html_block', '', 0);
importComponent.content = `<script setup>\n${importString}\n</script>\n`;
state.tokens.splice(0, 0, importComponent);
} else {
if (state.tokens[index]) {
const content = state.tokens[index].content;
state.tokens[index].content = content.replace(
'</script>',
`${importString}\n</script>`,
);
}
}
};
// Define the regular expression to match the desired pattern
const regex = /<DemoPreview[^>]*\sdir="([^"]*)"/g;
// Iterate through the Markdown content and replace the pattern
state.src = state.src.replaceAll(regex, (_match, dir) => {
const componentDir = join(process.cwd(), 'src', dir).replaceAll(
'\\',
'/',
);
let childFiles: string[] = [];
let dirExists = true;
try {
childFiles =
readdirSync(componentDir, {
encoding: 'utf8',
recursive: false,
withFileTypes: false,
}) || [];
} catch {
dirExists = false;
}
if (!dirExists) {
return '';
}
const uniqueWord = generateContentHash(componentDir);
const ComponentName = `DemoComponent_${uniqueWord}`;
insertComponentImport(
`import ${ComponentName} from '${componentDir}/index.vue'`,
);
const { path: _path } = state.env as MarkdownEnv;
const index = state.tokens.findIndex((i) => i.content.match(regex));
if (!state.tokens[index]) {
return '';
}
const firstString = 'index.vue';
childFiles = childFiles.sort((a, b) => {
if (a === firstString) return -1;
if (b === firstString) return 1;
return a.localeCompare(b, 'en', { sensitivity: 'base' });
});
state.tokens[index].content =
`<DemoPreview files="${encodeURIComponent(JSON.stringify(childFiles))}" ><${ComponentName}/>
`;
const _dummyToken = new state.Token('', '', 0);
const tokenArray: Array<typeof _dummyToken> = [];
childFiles.forEach((filename) => {
// const slotName = filename.replace(extname(filename), '');
const templateStart = new state.Token('html_inline', '', 0);
templateStart.content = `<template #${filename}>`;
tokenArray.push(templateStart);
const resolvedPath = join(componentDir, filename);
const { extension, filepath, lang, lines, title } =
rawPathToToken(resolvedPath);
// Add code tokens for each line
const token = new state.Token('fence', 'code', 0);
token.info = `${lang || extension}${lines ? `{${lines}}` : ''}${
title ? `[${title}]` : ''
}`;
token.content = `<<< ${filepath}`;
(token as any).src = [resolvedPath];
tokenArray.push(token);
const templateEnd = new state.Token('html_inline', '', 0);
templateEnd.content = '</template>';
tokenArray.push(templateEnd);
});
const endTag = new state.Token('html_inline', '', 0);
endTag.content = '</DemoPreview>';
tokenArray.push(endTag);
state.tokens.splice(index + 1, 0, ...tokenArray);
// console.log(
// state.md.renderer.render(state.tokens, state?.options ?? [], state.env),
// );
return '';
});
});
};
function generateContentHash(input: string, length: number = 10): string {
// 使用 SHA-256 生成哈希值
const hash = crypto.createHash('sha256').update(input).digest('hex');
// 将哈希值转换为 Base36 编码,并取指定长度的字符作为结果
return Number.parseInt(hash, 16).toString(36).slice(0, length);
}

View File

@@ -0,0 +1,172 @@
import type { PwaOptions } from '@vite-pwa/vitepress';
import type { HeadConfig } from 'vitepress';
import { resolve } from 'node:path';
import {
viteArchiverPlugin,
viteVxeTableImportsPlugin,
} from '@vben/vite-config';
import {
GitChangelog,
GitChangelogMarkdownSection,
} from '@nolebase/vitepress-plugin-git-changelog/vite';
import tailwind from 'tailwindcss';
import { defineConfig, postcssIsolateStyles } from 'vitepress';
import {
groupIconMdPlugin,
groupIconVitePlugin,
} from 'vitepress-plugin-group-icons';
import { demoPreviewPlugin } from './plugins/demo-preview';
import { search as zhSearch } from './zh.mts';
export const shared = defineConfig({
appearance: 'dark',
head: head(),
markdown: {
preConfig(md) {
md.use(demoPreviewPlugin);
md.use(groupIconMdPlugin);
},
},
pwa: pwa(),
srcDir: 'src',
themeConfig: {
i18nRouting: true,
logo: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
search: {
options: {
locales: {
...zhSearch,
},
},
provider: 'local',
},
siteTitle: 'Vben Admin',
socialLinks: [
{ icon: 'github', link: 'https://github.com/vbenjs/vue-vben-admin' },
],
},
title: 'Vben Admin',
vite: {
build: {
chunkSizeWarningLimit: Infinity,
minify: 'terser',
},
css: {
postcss: {
plugins: [
tailwind(),
postcssIsolateStyles({ includeFiles: [/vp-doc\.css/] }),
],
},
preprocessorOptions: {
scss: {
api: 'modern',
},
},
},
json: {
stringify: true,
},
plugins: [
GitChangelog({
mapAuthors: [
{
mapByNameAliases: ['Vben'],
name: 'vben',
username: 'anncwb',
},
{
name: 'vince',
username: 'vince292007',
},
{
name: 'Li Kui',
username: 'likui628',
},
],
repoURL: () => 'https://github.com/vbenjs/vue-vben-admin',
}),
GitChangelogMarkdownSection(),
viteArchiverPlugin({ outputDir: '.vitepress' }),
groupIconVitePlugin(),
await viteVxeTableImportsPlugin(),
],
server: {
fs: {
allow: ['../..'],
},
host: true,
port: 6173,
},
ssr: {
external: ['@vue/repl'],
},
},
});
function head(): HeadConfig[] {
return [
['meta', { content: 'Vbenjs Team', name: 'author' }],
[
'meta',
{
content: 'vben, vitejs, vite, shacdn-ui, vue',
name: 'keywords',
},
],
['link', { href: '/favicon.ico', rel: 'icon', type: 'image/svg+xml' }],
[
'meta',
{
content:
'width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no',
name: 'viewport',
},
],
['meta', { content: 'vben admin docs', name: 'keywords' }],
['link', { href: '/favicon.ico', rel: 'icon' }],
// [
// 'script',
// {
// src: 'https://cdn.tailwindcss.com',
// },
// ],
];
}
function pwa(): PwaOptions {
return {
includeManifestIcons: false,
manifest: {
description:
'Vben Admin is a modern admin dashboard template based on Vue 3. ',
icons: [
{
sizes: '192x192',
src: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/pwa-icon-192.png',
type: 'image/png',
},
{
sizes: '512x512',
src: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/pwa-icon-512.png',
type: 'image/png',
},
],
id: '/',
name: 'Vben Admin Doc',
short_name: 'vben_admin_doc',
theme_color: '#ffffff',
},
outDir: resolve(process.cwd(), '.vitepress/dist'),
registerType: 'autoUpdate',
workbox: {
globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
},
};
}

View File

@@ -0,0 +1,358 @@
import type { DefaultTheme } from 'vitepress';
import { defineConfig } from 'vitepress';
import { version } from '../../../package.json';
export const zh = defineConfig({
description: 'Vben Admin & 企业级管理系统框架',
lang: 'zh-Hans',
themeConfig: {
darkModeSwitchLabel: '主题',
darkModeSwitchTitle: '切换到深色模式',
docFooter: {
next: '下一页',
prev: '上一页',
},
editLink: {
pattern:
'https://github.com/vbenjs/vue-vben-admin/edit/main/docs/src/:path',
text: '在 GitHub 上编辑此页面',
},
footer: {
copyright: `Copyright © 2020-${new Date().getFullYear()} Vben`,
message: '基于 MIT 许可发布.',
},
langMenuLabel: '多语言',
lastUpdated: {
formatOptions: {
dateStyle: 'short',
timeStyle: 'medium',
},
text: '最后更新于',
},
lightModeSwitchTitle: '切换到浅色模式',
nav: nav(),
outline: {
label: '页面导航',
},
returnToTopLabel: '回到顶部',
sidebar: {
'/commercial/': { base: '/commercial/', items: sidebarCommercial() },
'/components/': { base: '/components/', items: sidebarComponents() },
'/guide/': { base: '/guide/', items: sidebarGuide() },
},
sidebarMenuLabel: '菜单',
},
});
function sidebarGuide(): DefaultTheme.SidebarItem[] {
return [
{
collapsed: false,
text: '简介',
items: [
{
link: 'introduction/vben',
text: '关于 Vben Admin',
},
{
link: 'introduction/why',
text: '为什么选择我们?',
},
{ link: 'introduction/quick-start', text: '快速开始' },
{ link: 'introduction/thin', text: '精简版本' },
{
base: '/',
link: 'components/introduction',
text: '组件文档',
},
],
},
{
text: '基础',
items: [
{ link: 'essentials/concept', text: '基础概念' },
{ link: 'essentials/development', text: '本地开发' },
{ link: 'essentials/route', text: '路由和菜单' },
{ link: 'essentials/settings', text: '配置' },
{ link: 'essentials/icons', text: '图标' },
{ link: 'essentials/styles', text: '样式' },
{ link: 'essentials/external-module', text: '外部模块' },
{ link: 'essentials/build', text: '构建与部署' },
{ link: 'essentials/server', text: '服务端交互与数据Mock' },
],
},
{
text: '深入',
items: [
{ link: 'in-depth/login', text: '登录' },
// { link: 'in-depth/layout', text: '布局' },
{ link: 'in-depth/theme', text: '主题' },
{ link: 'in-depth/access', text: '权限' },
{ link: 'in-depth/locale', text: '国际化' },
{ link: 'in-depth/features', text: '常用功能' },
{ link: 'in-depth/check-updates', text: '检查更新' },
{ link: 'in-depth/loading', text: '全局loading' },
{ link: 'in-depth/ui-framework', text: '组件库切换' },
],
},
{
text: '工程',
items: [
{ link: 'project/standard', text: '规范' },
{ link: 'project/cli', text: 'CLI' },
{ link: 'project/dir', text: '目录说明' },
{ link: 'project/test', text: '单元测试' },
{ link: 'project/tailwindcss', text: 'Tailwind CSS' },
{ link: 'project/changeset', text: 'Changeset' },
{ link: 'project/vite', text: 'Vite Config' },
],
},
{
text: '其他',
items: [
{ link: 'other/project-update', text: '项目更新' },
{ link: 'other/remove-code', text: '移除代码' },
{ link: 'other/faq', text: '常见问题' },
],
},
];
}
function sidebarCommercial(): DefaultTheme.SidebarItem[] {
return [
{
link: 'community',
text: '交流群',
},
{
link: 'technical-support',
text: '技术支持',
},
{
link: 'customized',
text: '定制开发',
},
];
}
function sidebarComponents(): DefaultTheme.SidebarItem[] {
return [
{
text: '组件',
items: [
{
link: 'introduction',
text: '介绍',
},
],
},
{
collapsed: false,
text: '布局组件',
items: [
{
link: 'layout-ui/page',
text: 'Page 页面',
},
],
},
{
collapsed: false,
text: '通用组件',
items: [
{
link: 'common-ui/vben-api-component',
text: 'ApiComponent Api组件包装器',
},
{
link: 'common-ui/vben-alert',
text: 'Alert 轻量提示框',
},
{
link: 'common-ui/vben-modal',
text: 'Modal 模态框',
},
{
link: 'common-ui/vben-drawer',
text: 'Drawer 抽屉',
},
{
link: 'common-ui/vben-form',
text: 'Form 表单',
},
{
link: 'common-ui/vben-vxe-table',
text: 'Vxe Table 表格',
},
{
link: 'common-ui/vben-count-to-animator',
text: 'CountToAnimator 数字动画',
},
{
link: 'common-ui/vben-ellipsis-text',
text: 'EllipsisText 省略文本',
},
],
},
];
}
function nav(): DefaultTheme.NavItem[] {
return [
{
activeMatch: '^/(guide|components)/',
text: '文档',
items: [
{
activeMatch: '^/guide/',
link: '/guide/introduction/vben',
text: '指南',
},
{
activeMatch: '^/components/',
link: '/components/introduction',
text: '组件',
},
{
text: '历史版本',
items: [
{
link: 'https://doc.vvbin.cn',
text: '2.x版本文档',
},
],
},
],
},
{
text: '演示',
items: [
{
text: 'Vben Admin',
items: [
{
link: 'https://www.vben.pro',
text: '演示版本',
},
{
link: 'https://ant.vben.pro',
text: 'Ant Design Vue 版本',
},
{
link: 'https://naive.vben.pro',
text: 'Naive 版本',
},
{
link: 'https://ele.vben.pro',
text: 'Element Plus版本',
},
],
},
{
text: '其他',
items: [
{
link: 'https://vben.vvbin.cn',
text: 'Vben Admin 2.x',
},
],
},
],
},
{
text: version,
items: [
{
link: 'https://github.com/vbenjs/vue-vben-admin/releases',
text: '更新日志',
},
{
link: 'https://github.com/orgs/vbenjs/projects/5',
text: '路线图',
},
{
link: 'https://github.com/vbenjs/vue-vben-admin/blob/main/.github/contributing.md',
text: '贡献',
},
],
},
{
link: '/commercial/technical-support',
text: '🦄 技术支持',
},
{
link: '/sponsor/personal',
text: '✨ 赞助',
},
{
link: '/commercial/community',
text: '👨‍👦‍👦 交流群',
// items: [
// {
// link: 'https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&appChannel=share&inviteCode=22ySzj7pKiw&businessType=9&from=246610&biz=ka&mainSourceId=share&subSourceId=others&jumpsource=shorturl#/pc',
// text: 'QQ频道',
// },
// {
// link: 'https://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=mjZmlhgVzzUxvdxllB6C1vHpX8O8QRL0&authKey=DBdFbBwERmfaKY95JvRWqLCJIRGJAmKyZbrpzZ41EKDMZ5SR6MfbjOBaaNRN73fr&noverify=0&group_code=4286109',
// text: 'QQ群',
// },
// {
// link: 'https://discord.gg/VU62jTecad',
// text: 'Discord',
// },
// ],
},
// {
// link: '/friend-links/',
// text: '🤝 友情链接',
// },
];
}
export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
root: {
placeholder: '搜索文档',
translations: {
button: {
buttonAriaLabel: '搜索文档',
buttonText: '搜索文档',
},
modal: {
errorScreen: {
helpText: '你可能需要检查你的网络连接',
titleText: '无法获取结果',
},
footer: {
closeText: '关闭',
navigateText: '切换',
searchByText: '搜索提供者',
selectText: '选择',
},
noResultsScreen: {
noResultsText: '无法找到相关结果',
reportMissingResultsLinkText: '点击反馈',
reportMissingResultsText: '你认为该查询应该有结果?',
suggestedQueryText: '你可以尝试查询',
},
searchBox: {
cancelButtonAriaLabel: '取消',
cancelButtonText: '取消',
resetButtonAriaLabel: '清除查询条件',
resetButtonTitle: '清除查询条件',
},
startScreen: {
favoriteSearchesTitle: '收藏',
noRecentSearchesText: '没有搜索历史',
recentSearchesTitle: '搜索历史',
removeFavoriteSearchButtonTitle: '从收藏中移除',
removeRecentSearchButtonTitle: '从搜索历史中移除',
saveRecentSearchButtonTitle: '保存至搜索历史',
},
},
},
},
};