create-lumfall 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +24 -17
  2. package/cli.js +179 -24
  3. package/package.json +5 -7
  4. package/templates/basic/README.md +0 -113
  5. package/templates/basic/app/controller/demo.js +0 -28
  6. package/templates/basic/app/extend/README.md +0 -3
  7. package/templates/basic/app/middleware/README.md +0 -2
  8. package/templates/basic/app/middleware.js +0 -13
  9. package/templates/basic/app/pages/home/entry.home.js +0 -4
  10. package/templates/basic/app/pages/home/home.vue +0 -164
  11. package/templates/basic/app/router/demo.js +0 -17
  12. package/templates/basic/app/router-schema/demo.js +0 -29
  13. package/templates/basic/app/service/demo.js +0 -51
  14. package/templates/basic/app/webpack.config.js +0 -4
  15. package/templates/basic/build.js +0 -7
  16. package/templates/basic/config/config.beta.js +0 -4
  17. package/templates/basic/config/config.default.js +0 -32
  18. package/templates/basic/config/config.local.js +0 -4
  19. package/templates/basic/config/config.prod.js +0 -6
  20. package/templates/basic/package.json +0 -31
  21. package/templates/basic/server.js +0 -26
  22. package/templates/document/README.md +0 -145
  23. package/templates/document/app/extend/README.md +0 -6
  24. package/templates/document/app/middleware/README.md +0 -2
  25. package/templates/document/app/middleware.js +0 -2
  26. package/templates/document/app/pages/docs/assets/docs-logo.svg +0 -5
  27. package/templates/document/app/pages/docs/components/doc-layout.vue +0 -144
  28. package/templates/document/app/pages/docs/components/doc-navbar.vue +0 -103
  29. package/templates/document/app/pages/docs/components/doc-search.vue +0 -131
  30. package/templates/document/app/pages/docs/components/doc-sidebar.vue +0 -29
  31. package/templates/document/app/pages/docs/components/doc-toc.vue +0 -21
  32. package/templates/document/app/pages/docs/content.js +0 -28
  33. package/templates/document/app/pages/docs/docs-config.js +0 -154
  34. package/templates/document/app/pages/docs/docs.vue +0 -24
  35. package/templates/document/app/pages/docs/entry.docs.js +0 -26
  36. package/templates/document/app/pages/docs/markdown/highlight.js +0 -30
  37. package/templates/document/app/pages/docs/markdown/index.js +0 -129
  38. package/templates/document/app/pages/docs/search.js +0 -142
  39. package/templates/document/app/pages/docs/styles/docs.less +0 -1091
  40. package/templates/document/app/pages/docs/styles/vars.less +0 -87
  41. package/templates/document/app/pages/docs/theme.js +0 -47
  42. package/templates/document/app/pages/docs/utils.js +0 -58
  43. package/templates/document/app/pages/docs/views/doc-home.vue +0 -56
  44. package/templates/document/app/pages/docs/views/doc-page.vue +0 -147
  45. package/templates/document/app/webpack.config.js +0 -15
  46. package/templates/document/build.js +0 -6
  47. package/templates/document/config/config.beta.js +0 -2
  48. package/templates/document/config/config.default.js +0 -9
  49. package/templates/document/config/config.local.js +0 -2
  50. package/templates/document/config/config.prod.js +0 -2
  51. package/templates/document/docs/advanced/dashboard.md +0 -66
  52. package/templates/document/docs/advanced/health.md +0 -72
  53. package/templates/document/docs/advanced/monitoring.md +0 -60
  54. package/templates/document/docs/advanced/security.md +0 -88
  55. package/templates/document/docs/core/app-instance.md +0 -114
  56. package/templates/document/docs/core/controller-service.md +0 -113
  57. package/templates/document/docs/core/lifecycle.md +0 -60
  58. package/templates/document/docs/core/middleware.md +0 -83
  59. package/templates/document/docs/core/plugins.md +0 -77
  60. package/templates/document/docs/core/router-schema.md +0 -102
  61. package/templates/document/docs/dsl/api-contract.md +0 -88
  62. package/templates/document/docs/dsl/extend.md +0 -311
  63. package/templates/document/docs/dsl/menu.md +0 -101
  64. package/templates/document/docs/dsl/model-project.md +0 -122
  65. package/templates/document/docs/dsl/overview.md +0 -116
  66. package/templates/document/docs/dsl/reference.md +0 -175
  67. package/templates/document/docs/dsl/schema-actions.md +0 -135
  68. package/templates/document/docs/dsl/schema.md +0 -121
  69. package/templates/document/docs/frontend/build.md +0 -118
  70. package/templates/document/docs/frontend/curl.md +0 -75
  71. package/templates/document/docs/frontend/page.md +0 -99
  72. package/templates/document/docs/frontend/widgets.md +0 -151
  73. package/templates/document/docs/guide/config.md +0 -108
  74. package/templates/document/docs/guide/deployment.md +0 -115
  75. package/templates/document/docs/guide/getting-started.md +0 -199
  76. package/templates/document/docs/guide/introduction.md +0 -55
  77. package/templates/document/docs/guide/structure.md +0 -98
  78. package/templates/document/docs/reference/commands.md +0 -70
  79. package/templates/document/docs/reference/faq.md +0 -94
  80. package/templates/document/package.json +0 -36
  81. package/templates/document/scripts/build-static.js +0 -129
  82. package/templates/document/server.js +0 -13
@@ -1,144 +0,0 @@
1
- <template>
2
- <div class="doc-shell">
3
- <DocNavbar
4
- :show-sidebar-toggle="sidebar"
5
- @toggle-sidebar="drawerOpen = !drawerOpen"
6
- @open-search="searchOpen = true"
7
- />
8
-
9
- <div class="doc-body" @click="handleBodyClick">
10
- <DocSidebar v-if="sidebar" class="doc-desktop-sidebar" />
11
-
12
- <!-- 移动端抽屉侧栏 -->
13
- <Transition name="doc-fade">
14
- <div v-if="sidebar && drawerOpen" class="doc-drawer-mask" @click.self="drawerOpen = false">
15
- <DocSidebar class="doc-drawer-sidebar" @navigate="drawerOpen = false" />
16
- </div>
17
- </Transition>
18
-
19
- <main class="doc-main">
20
- <slot />
21
- </main>
22
- </div>
23
-
24
- <DocSearch v-model="searchOpen" />
25
- </div>
26
- </template>
27
-
28
- <script setup>
29
- import { onBeforeUnmount, onMounted, ref, watch } from "vue";
30
- import { useRoute, useRouter } from "vue-router";
31
- import DocNavbar from "./doc-navbar.vue";
32
- import DocSidebar from "./doc-sidebar.vue";
33
- import DocSearch from "./doc-search.vue";
34
-
35
- defineProps({
36
- // 是否显示侧栏(首页不显示)
37
- sidebar: { type: Boolean, default: true },
38
- });
39
-
40
- const route = useRoute();
41
- const router = useRouter();
42
- const drawerOpen = ref(false);
43
- const searchOpen = ref(false);
44
-
45
- // 路由切换时收起移动端抽屉
46
- watch(
47
- () => route.fullPath,
48
- () => {
49
- drawerOpen.value = false;
50
- }
51
- );
52
-
53
- // ---- 全局点击处理:复制代码 / 站内路由 / 锚点平滑滚动 ----
54
- const copyText = (text) => {
55
- if (navigator.clipboard && window.isSecureContext) {
56
- navigator.clipboard.writeText(text);
57
- return;
58
- }
59
- // 非安全上下文(http 部署)回退方案
60
- const textarea = document.createElement("textarea");
61
- textarea.value = text;
62
- textarea.style.position = "fixed";
63
- textarea.style.opacity = "0";
64
- document.body.appendChild(textarea);
65
- textarea.select();
66
- try {
67
- document.execCommand("copy");
68
- } catch (err) {
69
- // 忽略复制失败
70
- }
71
- document.body.removeChild(textarea);
72
- };
73
-
74
- const handleBodyClick = (e) => {
75
- // 1. 代码块复制按钮
76
- const copyBtn = e.target.closest(".doc-code-copy");
77
- if (copyBtn) {
78
- const block = copyBtn.closest(".doc-code-block");
79
- const pre = block && block.querySelector("pre");
80
- if (pre) {
81
- copyText(pre.textContent || "");
82
- copyBtn.textContent = "已复制";
83
- setTimeout(() => {
84
- copyBtn.textContent = "复制";
85
- }, 1500);
86
- }
87
- return;
88
- }
89
-
90
- // 2. 站内文档链接走 SPA 路由,避免整页刷新
91
- const link = e.target.closest("a");
92
- if (!link) {
93
- return;
94
- }
95
- const href = link.getAttribute("href") || "";
96
-
97
- if (href.startsWith("/view/docs")) {
98
- e.preventDefault();
99
- router.push(href);
100
- return;
101
- }
102
-
103
- // 3. 页内锚点:平滑滚动,滚动结束后再更新 URL。
104
- // 注意:带 fragment 的 history.replaceState 会取消 Chrome 正在进行的
105
- // 平滑滚动(无论先后调用),所以必须等 scrollend 之后再写 URL。
106
- if (href.startsWith("#") && href.length > 1) {
107
- const target = document.getElementById(decodeURIComponent(href.slice(1)));
108
- if (target) {
109
- e.preventDefault();
110
- let urlUpdated = false;
111
- const updateUrl = () => {
112
- if (urlUpdated) return;
113
- urlUpdated = true;
114
- history.replaceState(null, "", href);
115
- };
116
- target.scrollIntoView({ behavior: "smooth" });
117
- // 平滑滚动结束(scrollend 支持前用定时器兜底;目标已在视口内时不会滚动)
118
- window.addEventListener("scrollend", updateUrl, { once: true });
119
- setTimeout(updateUrl, 800);
120
- }
121
- }
122
- };
123
-
124
- // 全局快捷键:Ctrl/Cmd + K 或 / 唤起搜索(输入框内按 / 不触发)
125
- const onGlobalKeydown = (e) => {
126
- const isCtrlK = (e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k";
127
- const isSlash =
128
- e.key === "/" &&
129
- !["INPUT", "TEXTAREA"].includes(e.target.tagName) &&
130
- !e.target.isContentEditable;
131
- if (isCtrlK || isSlash) {
132
- e.preventDefault();
133
- searchOpen.value = true;
134
- }
135
- };
136
-
137
- onMounted(() => {
138
- window.addEventListener("keydown", onGlobalKeydown);
139
- });
140
-
141
- onBeforeUnmount(() => {
142
- window.removeEventListener("keydown", onGlobalKeydown);
143
- });
144
- </script>
@@ -1,103 +0,0 @@
1
- <template>
2
- <header class="doc-navbar">
3
- <div class="doc-navbar-left">
4
- <button
5
- v-if="showSidebarToggle"
6
- class="doc-navbar-burger"
7
- type="button"
8
- aria-label="打开目录"
9
- @click="$emit('toggle-sidebar')"
10
- >
11
- <icon-menu />
12
- </button>
13
-
14
- <router-link class="doc-navbar-brand" to="/view/docs">
15
- <img class="doc-navbar-logo" :src="logo" alt="logo" />
16
- <span class="doc-navbar-title">{{ site.title }}</span>
17
- </router-link>
18
-
19
- <nav class="doc-navbar-nav">
20
- <template v-for="item in nav" :key="item.text">
21
- <router-link
22
- v-if="item.path"
23
- :to="item.path"
24
- class="doc-navbar-link"
25
- :class="{ active: isActive(item) }"
26
- >
27
- {{ item.text }}
28
- </router-link>
29
- <a
30
- v-else
31
- :href="item.link"
32
- target="_blank"
33
- rel="noopener noreferrer"
34
- class="doc-navbar-link"
35
- >
36
- {{ item.text }}
37
- </a>
38
- </template>
39
- </nav>
40
- </div>
41
-
42
- <div class="doc-navbar-right">
43
- <button class="doc-search-trigger" type="button" @click="$emit('open-search')">
44
- <icon-search />
45
- <span class="doc-search-trigger-text">搜索文档</span>
46
- <kbd>Ctrl K</kbd>
47
- </button>
48
-
49
- <button
50
- class="doc-icon-btn"
51
- type="button"
52
- :aria-label="isDark ? '切换到亮色' : '切换到暗色'"
53
- @click="handleToggleTheme"
54
- >
55
- <icon-sun-fill v-if="isDark" />
56
- <icon-moon-fill v-else />
57
- </button>
58
-
59
- <a
60
- v-if="site.repo"
61
- class="doc-icon-btn"
62
- :href="site.repo"
63
- target="_blank"
64
- rel="noopener noreferrer"
65
- aria-label="GitHub 仓库"
66
- >
67
- <icon-github />
68
- </a>
69
- </div>
70
- </header>
71
- </template>
72
-
73
- <script setup>
74
- import { computed, ref } from "vue";
75
- import { useRoute } from "vue-router";
76
- import docsConfig from "../docs-config";
77
- import { toggleTheme } from "../theme";
78
- import logo from "../assets/docs-logo.svg";
79
-
80
- defineProps({
81
- showSidebarToggle: { type: Boolean, default: false },
82
- });
83
-
84
- defineEmits(["toggle-sidebar", "open-search"]);
85
-
86
- const route = useRoute();
87
- const site = docsConfig.site;
88
- const nav = docsConfig.nav;
89
- const isDark = ref(document.body.getAttribute("arco-theme") === "dark");
90
-
91
- const handleToggleTheme = () => {
92
- isDark.value = toggleTheme() === "dark";
93
- };
94
-
95
- // 导航高亮:按 path 的前三级(/view/docs/<section>)匹配当前路由
96
- const isActive = (item) => {
97
- if (!item.path) {
98
- return false;
99
- }
100
- const section = item.path.split("/").slice(0, 4).join("/");
101
- return route.path === section || route.path.startsWith(`${section}/`);
102
- };
103
- </script>
@@ -1,131 +0,0 @@
1
- <template>
2
- <Teleport to="body">
3
- <Transition name="doc-fade">
4
- <div v-if="modelValue" class="doc-search-mask" @click.self="close">
5
- <div class="doc-search-panel">
6
- <div class="doc-search-input-row">
7
- <icon-search class="doc-search-icon" />
8
- <input
9
- ref="inputRef"
10
- v-model="keyword"
11
- class="doc-search-input"
12
- type="text"
13
- placeholder="搜索文档,如:配置 / 路由 / 插件"
14
- @keydown="onKeydown"
15
- />
16
- <kbd class="doc-search-kbd">ESC</kbd>
17
- </div>
18
-
19
- <div class="doc-search-results">
20
- <template v-if="keyword.trim()">
21
- <div v-if="!results.length" class="doc-search-empty">
22
- 没有找到与「{{ keyword }}」相关的内容
23
- </div>
24
- <a
25
- v-for="(item, i) in results"
26
- :key="`${item.docPath}-${item.anchor}-${i}`"
27
- class="doc-search-item"
28
- :class="{ active: i === activeIndex }"
29
- @click="go(item)"
30
- @mouseenter="activeIndex = i"
31
- >
32
- <div class="doc-search-item-title" v-html="item.titleHtml"></div>
33
- <div v-if="item.heading" class="doc-search-item-heading">
34
- <icon-right /> {{ item.heading }}
35
- </div>
36
- <div
37
- v-if="item.snippet"
38
- class="doc-search-item-snippet"
39
- v-html="item.snippet"
40
- ></div>
41
- </a>
42
- </template>
43
- <div v-else class="doc-search-empty">
44
- 输入关键词开始搜索,支持标题与正文匹配
45
- </div>
46
- </div>
47
-
48
- <div class="doc-search-footer">
49
- <span><kbd>↑</kbd><kbd>↓</kbd> 选择</span>
50
- <span><kbd>Enter</kbd> 打开</span>
51
- <span><kbd>ESC</kbd> 关闭</span>
52
- </div>
53
- </div>
54
- </div>
55
- </Transition>
56
- </Teleport>
57
- </template>
58
-
59
- <script setup>
60
- import { computed, nextTick, ref, watch } from "vue";
61
- import { useRouter } from "vue-router";
62
- import docsConfig from "../docs-config";
63
- import { searchDocs } from "../search";
64
-
65
- const props = defineProps({
66
- modelValue: { type: Boolean, default: false },
67
- });
68
- const emit = defineEmits(["update:modelValue"]);
69
-
70
- const router = useRouter();
71
- const keyword = ref("");
72
- const activeIndex = ref(0);
73
- const inputRef = ref(null);
74
-
75
- const results = computed(() => {
76
- const list = searchDocs(keyword.value, docsConfig);
77
- if (activeIndex.value >= list.length) {
78
- activeIndex.value = 0;
79
- }
80
- return list;
81
- });
82
-
83
- watch(
84
- () => props.modelValue,
85
- (open) => {
86
- if (open) {
87
- keyword.value = "";
88
- activeIndex.value = 0;
89
- nextTick(() => inputRef.value && inputRef.value.focus());
90
- }
91
- }
92
- );
93
-
94
- watch(keyword, () => {
95
- activeIndex.value = 0;
96
- });
97
-
98
- const close = () => emit("update:modelValue", false);
99
-
100
- const go = (item) => {
101
- close();
102
- const path = `/view/docs/${item.docPath}`;
103
- if (item.anchor) {
104
- router.push({ path, hash: `#${item.anchor}` });
105
- } else {
106
- router.push(path);
107
- }
108
- };
109
-
110
- const onKeydown = (e) => {
111
- if (e.key === "Escape") {
112
- close();
113
- } else if (e.key === "ArrowDown") {
114
- e.preventDefault();
115
- activeIndex.value = (activeIndex.value + 1) % Math.max(results.value.length, 1);
116
- } else if (e.key === "ArrowUp") {
117
- e.preventDefault();
118
- activeIndex.value =
119
- (activeIndex.value - 1 + results.value.length) %
120
- Math.max(results.value.length, 1);
121
- } else if (e.key === "Enter") {
122
- const item = results.value[activeIndex.value];
123
- if (item) {
124
- go(item);
125
- }
126
- }
127
- };
128
-
129
- // 暴露给全局快捷键:layout 或页面可通过 ref 调 open()(本模板用 v-model 控制即可)
130
- defineExpose({ close });
131
- </script>
@@ -1,29 +0,0 @@
1
- <template>
2
- <aside class="doc-sidebar">
3
- <div v-for="group in sidebar" :key="group.text" class="doc-sidebar-group">
4
- <div class="doc-sidebar-group-title">{{ group.text }}</div>
5
- <router-link
6
- v-for="item in group.items"
7
- :key="item.path"
8
- :to="item.path"
9
- class="doc-sidebar-link"
10
- :class="{ active: isActive(item.path) }"
11
- @click="$emit('navigate')"
12
- >
13
- {{ item.text }}
14
- </router-link>
15
- </div>
16
- </aside>
17
- </template>
18
-
19
- <script setup>
20
- import { useRoute } from "vue-router";
21
- import docsConfig from "../docs-config";
22
-
23
- defineEmits(["navigate"]);
24
-
25
- const route = useRoute();
26
- const sidebar = docsConfig.sidebar;
27
-
28
- const isActive = (path) => route.path === path || route.path === `${path}/`;
29
- </script>
@@ -1,21 +0,0 @@
1
- <template>
2
- <div v-if="items.length" class="doc-toc">
3
- <div class="doc-toc-title">页面内容</div>
4
- <a
5
- v-for="item in items"
6
- :key="item.id"
7
- :href="`#${item.id}`"
8
- class="doc-toc-link"
9
- :class="[`level-${item.level}`, { active: item.id === activeId }]"
10
- >
11
- {{ item.text }}
12
- </a>
13
- </div>
14
- </template>
15
-
16
- <script setup>
17
- defineProps({
18
- items: { type: Array, default: () => [] },
19
- activeId: { type: String, default: "" },
20
- });
21
- </script>
@@ -1,28 +0,0 @@
1
- // markdown 文档内容加载器。
2
- // 约定:文档放在项目根目录 docs/ 下(相对本文件 ../../../docs),
3
- // 构建时全部按原始文本打进产物,页面按路径读取并渲染。
4
- // 要调整内容目录位置时,只需要改 require.context 的第一个参数。
5
- const context = require.context("../../../docs", true, /\.md$/);
6
-
7
- const moduleMap = {};
8
-
9
- context.keys().forEach((key) => {
10
- // key 形如 "./guide/introduction.md" → "guide/introduction"
11
- const docPath = key.replace(/^\.\//, "").replace(/\.md$/, "");
12
- const mod = context(key);
13
- moduleMap[docPath] = typeof mod === "string" ? mod : mod.default ?? mod;
14
- });
15
-
16
- /**
17
- * 按 docs/ 相对路径取 markdown 原文
18
- * @param {string} docPath 例如 "guide/introduction"
19
- * @returns {string|undefined}
20
- */
21
- export function getDocSource(docPath) {
22
- return moduleMap[docPath];
23
- }
24
-
25
- /** 全部文档:{ "guide/introduction": "# ...", ... } */
26
- export function getAllDocs() {
27
- return moduleMap;
28
- }
@@ -1,154 +0,0 @@
1
- /**
2
- * 文档站配置 —— 使用本模板时主要改这个文件。
3
- *
4
- * 换成自己的站点只需三步:
5
- * 1. 改本文件的 site / nav / sidebar / hero / footer
6
- * 2. 把 docs/ 目录下的 markdown 换成自己的内容(目录结构随意,两层以内最佳)
7
- * 3. 想改页面挂载路径(/view/docs)时,改 DOCS_BASE 并同步 entry.docs.js 里的路由
8
- */
9
-
10
- // 站内文档的 URL 前缀 = /view/<页面目录名>
11
- const DOCS_BASE = "/view/docs";
12
-
13
- const doc = (path) => `${DOCS_BASE}/${path}`;
14
-
15
- export default {
16
- // 站点信息
17
- site: {
18
- title: "Lumfall",
19
- description: "Lumfall 全栈框架开发文档",
20
- // 右上角仓库链接,不需要就置空
21
- repo: "https://github.com/ikun-Lg/lumfall",
22
- },
23
-
24
- // 顶部导航:path 为站内路由(高亮按第一级 section 匹配),link 为外链
25
- nav: [
26
- { text: "指南", path: doc("guide/introduction") },
27
- { text: "核心概念", path: doc("core/app-instance") },
28
- { text: "DSL", path: doc("dsl/overview") },
29
- { text: "前端", path: doc("frontend/page") },
30
- { text: "进阶", path: doc("advanced/security") },
31
- { text: "参考", path: doc("reference/faq") },
32
- { text: "GitHub", link: "https://github.com/ikun-Lg/lumfall" },
33
- ],
34
-
35
- // 侧边栏分组。items 的 path 必须对应 docs/ 下真实存在的 markdown 文件
36
- // (例如 doc("guide/introduction") 对应 docs/guide/introduction.md)
37
- sidebar: [
38
- {
39
- text: "指南",
40
- items: [
41
- { text: "简介", path: doc("guide/introduction") },
42
- { text: "快速开始", path: doc("guide/getting-started") },
43
- { text: "目录结构与挂载点", path: doc("guide/structure") },
44
- { text: "配置", path: doc("guide/config") },
45
- { text: "构建与部署", path: doc("guide/deployment") },
46
- ],
47
- },
48
- {
49
- text: "核心概念",
50
- items: [
51
- { text: "app 对象与启动流程", path: doc("core/app-instance") },
52
- { text: "Controller 与 Service", path: doc("core/controller-service") },
53
- { text: "路由与参数校验", path: doc("core/router-schema") },
54
- { text: "中间件", path: doc("core/middleware") },
55
- { text: "生命周期", path: doc("core/lifecycle") },
56
- { text: "插件", path: doc("core/plugins") },
57
- ],
58
- },
59
- {
60
- text: "DSL",
61
- items: [
62
- { text: "DSL 总览", path: doc("dsl/overview") },
63
- { text: "Model 与 Project", path: doc("dsl/model-project") },
64
- { text: "菜单项 DSL", path: doc("dsl/menu") },
65
- { text: "schema 模块 DSL", path: doc("dsl/schema") },
66
- { text: "按钮与动态表单", path: doc("dsl/schema-actions") },
67
- { text: "接口契约", path: doc("dsl/api-contract") },
68
- { text: "扩展 DSL", path: doc("dsl/extend") },
69
- { text: "完整模板与注意事项", path: doc("dsl/reference") },
70
- ],
71
- },
72
- {
73
- text: "前端",
74
- items: [
75
- { text: "页面系统", path: doc("frontend/page") },
76
- { text: "前端构建", path: doc("frontend/build") },
77
- { text: "内置组件", path: doc("frontend/widgets") },
78
- { text: "请求工具 curl", path: doc("frontend/curl") },
79
- ],
80
- },
81
- {
82
- text: "进阶",
83
- items: [
84
- { text: "安全策略", path: doc("advanced/security") },
85
- { text: "健康检查", path: doc("advanced/health") },
86
- { text: "请求观测 monitoring", path: doc("advanced/monitoring") },
87
- { text: "Dashboard 与 Model 配置", path: doc("advanced/dashboard") },
88
- ],
89
- },
90
- {
91
- text: "参考",
92
- items: [
93
- { text: "常见错误自查", path: doc("reference/faq") },
94
- { text: "命令与环境速查", path: doc("reference/commands") },
95
- ],
96
- },
97
- ],
98
-
99
- // 首页 hero
100
- hero: {
101
- name: "Lumfall",
102
- tagline: "Koa + Vue 全栈框架,目录即约定,开箱即用",
103
- text: "目录自动加载、四层配置合并、声明式 Dashboard DSL、页面与路由构建、安全策略、健康检查——写配置和业务代码,而不是搭工程。",
104
- actions: [
105
- { text: "快速开始", path: doc("guide/getting-started"), theme: "brand" },
106
- { text: "DSL 设计", path: doc("dsl/overview"), theme: "brand-outline" },
107
- { text: "GitHub", link: "https://github.com/ikun-Lg/lumfall" },
108
- ],
109
- features: [
110
- {
111
- icon: "📐",
112
- title: "声明式 Dashboard DSL",
113
- details:
114
- "Model + Project 两层 DSL 声明管理台;一份字段 schema 驱动搜索栏、表格、表单、详情四个视图,写配置不改代码。",
115
- },
116
- {
117
- icon: "📁",
118
- title: "目录即约定",
119
- details:
120
- "controller / service / router / middleware 按目录自动加载并挂载到 app,新建文件即生效,无需手动注册。",
121
- },
122
- {
123
- icon: "⚙️",
124
- title: "四层配置合并",
125
- details:
126
- "框架与业务的 config 按 _ENV 分层浅合并,支持 JSON Schema 强校验,环境切换只改一个变量。",
127
- },
128
- {
129
- icon: "🧩",
130
- title: "页面系统",
131
- details:
132
- "Vue 3 页面按 entry.<name>.js 自动发现,Webpack 5 多页构建,/view/<name> 直接访问,支持 HMR 热更新。",
133
- },
134
- {
135
- icon: "🛡️",
136
- title: "内置安全策略",
137
- details:
138
- "接口签名校验与 project_key 校验开箱可用,参数校验基于 JSON Schema(Ajv),错误码统一。",
139
- },
140
- {
141
- icon: "💚",
142
- title: "健康检查与观测",
143
- details:
144
- "/health/live 与 /health/ready 内置探针机制;monitoring 提供请求级 trace 观测钩子;插件与生命周期覆盖启动退出。",
145
- },
146
- ],
147
- },
148
-
149
- // 首页与文档页底部
150
- footer: {
151
- text: "基于 lumfall 构建的文档站模板",
152
- // copyright: "© 2026 Your Name",
153
- },
154
- };
@@ -1,24 +0,0 @@
1
- <template>
2
- <a-config-provider :locale="zhCN">
3
- <router-view />
4
- </a-config-provider>
5
- </template>
6
-
7
- <script setup>
8
- import { onMounted } from "vue";
9
- import zhCN from "@arco-design/web-vue/es/locale/lang/zh-cn";
10
- import favicon from "./assets/docs-logo.svg";
11
- import "./styles/vars.less";
12
- import "./styles/docs.less";
13
-
14
- onMounted(() => {
15
- // 框架通用模板没有 favicon 位,这里在运行时注入
16
- if (!document.querySelector('link[rel="icon"]')) {
17
- const link = document.createElement("link");
18
- link.rel = "icon";
19
- link.type = "image/svg+xml";
20
- link.href = favicon;
21
- document.head.appendChild(link);
22
- }
23
- });
24
- </script>
@@ -1,26 +0,0 @@
1
- import boot from "$lumfallBoot";
2
- import Docs from "./docs.vue";
3
- import { initTheme } from "./theme";
4
-
5
- // 尽早应用主题(localStorage / 系统偏好),避免首屏闪白
6
- initTheme();
7
-
8
- // 文档站是单个页面(app/pages/docs),站内路由:
9
- // /view/docs 首页(hero + 特性卡片)
10
- // /view/docs/<path> 文档页(path 对应 docs/<path>.md)
11
- // 页面目录名决定挂载路径(本页是 docs);要改名时同步调整 docs-config.js 里的
12
- // DOCS_BASE 与上面两个路由 path。
13
- boot(Docs, {
14
- routes: [
15
- {
16
- path: "/view/docs",
17
- name: "doc-home",
18
- component: () => import("./views/doc-home.vue"),
19
- },
20
- {
21
- path: "/view/docs/:path(.*)",
22
- name: "doc-page",
23
- component: () => import("./views/doc-page.vue"),
24
- },
25
- ],
26
- });