diff --git a/deploy/nginx/nginx.conf b/deploy/nginx/nginx.conf
index 2a599a07eb406d1fc0585da43e628bb52526476c..d71e7e69e43d8910d846fce50eefe391c0ae5d45 100644
--- a/deploy/nginx/nginx.conf
+++ b/deploy/nginx/nginx.conf
@@ -159,7 +159,7 @@ http {
proxy_pass https://dsapi.test.osinfra.cn/;
}
-
+
location /25.03/ {
proxy_set_header X-Forwarded-For $http_x_real_ip;
proxy_http_version 1.1;
@@ -167,7 +167,7 @@ http {
proxy_ssl_protocols TLSv1.2;
proxy_ssl_verify off;
- proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/;
+ proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080;
}
location /zh/25.03/ {
@@ -177,7 +177,7 @@ http {
proxy_ssl_protocols TLSv1.2;
proxy_ssl_verify off;
- proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/zh/;
+ proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080;
}
location /en/25.03/ {
@@ -187,7 +187,7 @@ http {
proxy_ssl_protocols TLSv1.2;
proxy_ssl_verify off;
- proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/en/;
+ proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080;
}
location ^~ /docs/24.03_LTS_SP1/ {
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index 67ac107052aa9fb8e849cb5020c7cc94a1085bed..9130d0f76d560056be6833ca50b06eaf1e7f373e 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -1,4 +1,5 @@
import hljs from 'highlight.js';
+import type Markdown from 'markdown-it';
export default {
base: '/',
@@ -65,7 +66,7 @@ export default {
return `
${code}
`;
}
},
- config: (md) => {
+ config: (md: Markdown) => {
md.renderer.rules.code_inline = (tokens, idx) => {
const content = tokens[idx].content;
// 转义
@@ -83,6 +84,22 @@ export default {
}
return escapedContent;
};
+
+ // 标题处理
+ md.renderer.rules.heading_open = function (tokens, idx, options, _, self) {
+ const aIndex = tokens[idx].attrIndex('id');
+ const id = tokens[idx].attrs?.[aIndex]?.[1];
+ const tag = tokens[idx].tag;
+ const render = self.renderToken(tokens, idx, options);
+
+ // 自定义标题的 HTML 结构
+ return `${render}${tag === 'h1' || tag === 'h2' ? `` : ''}`;
+ };
+
+ md.renderer.rules.heading_close = function (tokens, idx, options, _, self) {
+ const tag = tokens[idx].tag;
+ return `${tag === 'h1' || tag === 'h2' ? '' : ''}${self.renderToken(tokens, idx, options)}`;
+ };
},
},
};
diff --git a/docs/.vitepress/src/assets/svg-icons/icon-link.svg b/docs/.vitepress/src/assets/svg-icons/icon-link.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4c9e24db6cd352b1f8c6720a6cbb06817129450c
--- /dev/null
+++ b/docs/.vitepress/src/assets/svg-icons/icon-link.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/docs/.vitepress/src/assets/svg-icons/icon-pin.svg b/docs/.vitepress/src/assets/svg-icons/icon-pin.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0f940828ec55359a3811db85f15bcfea07284e35
--- /dev/null
+++ b/docs/.vitepress/src/assets/svg-icons/icon-pin.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/docs/.vitepress/src/components/markdown/MarkdownTitle.vue b/docs/.vitepress/src/components/markdown/MarkdownTitle.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3f2408dd14530da56ebe193d0e68f3b1bb7a7606
--- /dev/null
+++ b/docs/.vitepress/src/components/markdown/MarkdownTitle.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copy link
+
+
+
+
+
diff --git a/docs/.vitepress/src/composables/useClipboard.ts b/docs/.vitepress/src/composables/useClipboard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8d05472ebde3a0d1cfa34bd90fd22f9d535ce68b
--- /dev/null
+++ b/docs/.vitepress/src/composables/useClipboard.ts
@@ -0,0 +1,19 @@
+import Clipboard from 'clipboard';
+interface ClipboardJSExtended extends ClipboardJS {
+ onClick: (event: MouseEvent) => void;
+}
+
+export const useClipboard = (options: { text: string; target: MouseEvent; success?: Function; error?: Function }) => {
+ const clipboard = new Clipboard(options.target.currentTarget as Element, {
+ text: () => options.text,
+ }) as ClipboardJSExtended;
+ clipboard.on('success', (e) => {
+ options?.success && options?.success(e);
+ clipboard.destroy();
+ });
+ clipboard.on('error', (e) => {
+ options?.error && options?.error(e);
+ clipboard.destroy();
+ });
+ clipboard.onClick(options.target);
+};
diff --git a/docs/.vitepress/src/layouts/LayoutDoc.vue b/docs/.vitepress/src/layouts/LayoutDoc.vue
index 69c4f32d2f34561df7d29319d02af27eb4c1af78..407c7838315f4aafabb026153730deaece21b40f 100644
--- a/docs/.vitepress/src/layouts/LayoutDoc.vue
+++ b/docs/.vitepress/src/layouts/LayoutDoc.vue
@@ -186,7 +186,7 @@ const onScrollAnchor = () => {
const top = getOffsetTop(target, scrollContainer.value);
- if (top < 100) {
+ if (top < 110) {
distances.push({
item,
top,
@@ -219,7 +219,7 @@ const onScrollNodeAnchor = useDebounceFn(() => {
for (let i = 0; i < idArr.length; i++) {
const top = getOffsetTop(idArr[i], nodeScrollContainer.value);
- if (top < 130) {
+ if (top < 120) {
distances.push({
index: i,
top,
diff --git a/docs/.vitepress/src/utils/scroll-to.ts b/docs/.vitepress/src/utils/scroll-to.ts
index da33dc6971f11f5476be48188104df082da2928b..02b93afb49f7b485c168d4909fc25ed636ce51f3 100644
--- a/docs/.vitepress/src/utils/scroll-to.ts
+++ b/docs/.vitepress/src/utils/scroll-to.ts
@@ -101,7 +101,7 @@ export function scrollTo(y: number, opts: ScrollTopOptions) {
}
-export async function scrollIntoView(target: HTMLElement, scrollContainer: HTMLElement, targetOffset = 120) {
+export async function scrollIntoView(target: HTMLElement, scrollContainer: HTMLElement, targetOffset = 100) {
const { scrollTop } = getScroll(scrollContainer);
const offsetTop = getOffsetTop(target, scrollContainer);
const y = scrollTop + offsetTop - targetOffset;
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
index 10dfc89a8d1fc04f7e658bc01d6c95697deb1553..a89af7a20159407c49153b181d8fb016bdfaf2ed 100644
--- a/docs/.vitepress/theme/index.ts
+++ b/docs/.vitepress/theme/index.ts
@@ -16,6 +16,7 @@ import '@/assets/style/global.scss';
import '@/assets/style/element-plus/index.scss';
import VueDOMPurifyHTML from 'vue-dompurify-html';
+import MarkdownTitle from '@/components/markdown/MarkdownTitle.vue';
export default {
Layout,
@@ -31,5 +32,7 @@ export default {
Object.keys(directives).forEach((directive) => {
app.directive(directive, directives[directive]);
});
+ // 注册组件
+ app.component('MarkdownTitle', MarkdownTitle);
},
};
diff --git a/package.json b/package.json
index 545efb457b6ce0e99cd0cd07ed59ceb07ad81c12..ebbaedac8c253f10b6526a2103598b1f50a5ee56 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"@opensig/opendesign": "0.0.68",
"@vueuse/core": "9.12.0",
"axios": "1.7.4",
+ "clipboard": "2.0.11",
"element-plus": "2.3.12",
"gray-matter": "4.0.3",
"highlight.js": "11.9.0",
@@ -39,6 +40,7 @@
"@types/highlight.js": "^10.1.0",
"@types/js-cookie": "^3.0.6",
"@types/lodash-es": "^4.17.12",
+ "@types/markdown-it": "^14.1.2",
"@types/node": "^18.18.10",
"@vitejs/plugin-basic-ssl": "^1.1.0",
"@vitejs/plugin-vue": "^4.4.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 402aa24eaa25cb7cf0ccbeef119b9b76d578b79e..15e88ac4a5a55786045b2fcc39788ad06d2ee725 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -24,11 +24,14 @@ importers:
axios:
specifier: 1.6.7
version: 1.6.7
+ clipboard:
+ specifier: 2.0.11
+ version: 2.0.11
element-plus:
specifier: 2.3.12
version: 2.3.12(vue@3.3.4)
gray-matter:
- specifier: ^4.0.3
+ specifier: 4.0.3
version: 4.0.3
highlight.js:
specifier: 11.9.0
@@ -37,7 +40,7 @@ importers:
specifier: 3.0.5
version: 3.0.5
lodash-es:
- specifier: ^4.17.21
+ specifier: 4.17.21
version: 4.17.21
pinia:
specifier: 2.1.6
@@ -70,6 +73,9 @@ importers:
'@types/lodash-es':
specifier: ^4.17.12
version: 4.17.12
+ '@types/markdown-it':
+ specifier: ^14.1.2
+ version: 14.1.2
'@types/node':
specifier: ^18.18.10
version: 18.19.70
@@ -1205,6 +1211,9 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
+ clipboard@2.0.11:
+ resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
+
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@@ -1288,6 +1297,9 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
+ delegate@3.2.0:
+ resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
+
dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@@ -1546,6 +1558,9 @@ packages:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
+ good-listener@1.2.2:
+ resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
+
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
@@ -2055,6 +2070,9 @@ packages:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}
+ select@1.1.2:
+ resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
+
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -2150,6 +2168,9 @@ packages:
text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ tiny-emitter@2.1.0:
+ resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+
tinyexec@0.3.2:
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
@@ -3615,6 +3636,12 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ clipboard@2.0.11:
+ dependencies:
+ good-listener: 1.2.2
+ select: 1.1.2
+ tiny-emitter: 2.1.0
+
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
@@ -3679,6 +3706,8 @@ snapshots:
delayed-stream@1.0.0: {}
+ delegate@3.2.0: {}
+
dequal@2.0.3: {}
devlop@1.1.0:
@@ -4001,6 +4030,10 @@ snapshots:
merge2: 1.4.1
slash: 3.0.0
+ good-listener@1.2.2:
+ dependencies:
+ delegate: 3.2.0
+
graceful-fs@4.2.11: {}
graphemer@1.4.0: {}
@@ -4495,6 +4528,8 @@ snapshots:
extend-shallow: 2.0.1
kind-of: 6.0.3
+ select@1.1.2: {}
+
semver@6.3.1: {}
semver@7.6.3: {}
@@ -4580,6 +4615,8 @@ snapshots:
text-table@0.2.0: {}
+ tiny-emitter@2.1.0: {}
+
tinyexec@0.3.2: {}
to-regex-range@5.0.1: