diff --git a/app.vue b/app.vue
index 05c4dc7..316e3e2 100644
--- a/app.vue
+++ b/app.vue
@@ -3,5 +3,6 @@
+
diff --git a/assets/css/Ni.css b/assets/css/Ni.css
index d302faa..b9bc3f3 100644
--- a/assets/css/Ni.css
+++ b/assets/css/Ni.css
@@ -1,3 +1,12 @@
+@import "../fonts/vfonts/Lato.css";
+@import "../fonts/vfonts/FiraCode.css";
+@import "../icon/startMessage/iconfont.css";
+
+[data-prefix^="Ni"] {
+ font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+}
+
+
/*宽高比*/
.a11 {
aspect-ratio: 1;
@@ -39,10 +48,15 @@
--Ni-theme-color-T3: #e8e8e7;
--Ni-theme-color-T4: #EFEFED;
--Ni-theme-color-T0-10: #37352f11;
+ --Ni-theme-color-T0-40: #37352f44;
+ --Ni-theme-color-T0-60: #37352f66;
--Ni-theme-color-T0-80: #37352f88;
--Ni-theme-color-T0-a0: #37352faa;
--Ni-theme-color-T0-c0: #37352fcc;
- --Ni-theme-color: var(--Ni-theme-color-T0);
+
+ --Ni-theme-color: var(--Ni-theme-color-T1);
+ --Ni-theme-border-color: var(--Ni-theme-color-T0-40);
+ --Ni-theme-border-color-hover: var(--Ni-theme-color-T0-c0);
@@ -66,6 +80,15 @@
--Ni-M-A: 1rem;
/*tertiary*/
+ /*default*/
+ --Ni-button-default-bg-default: #fefefe;
+ --Ni-button-default-bg-hover: #91918e33;
+ --Ni-button-default-bg-click: #37352f33;
+ /*浅色*/
+ --Ni-button-default-bg-default-light: #5f5e5b29;/*29-16*/
+ --Ni-button-default-bg-hover-light: #91918e38;/*38-22*/
+ --Ni-button-default-bg-click-light: #37352f47;/*47-28*/
+
/*primary*/
--Ni-button-primary-bg-default: #5f5e5b;
--Ni-button-primary-bg-hover: #91918e;
diff --git a/assets/fonts/vfonts/FiraCode.css b/assets/fonts/vfonts/FiraCode.css
new file mode 100644
index 0000000..79fd9a1
--- /dev/null
+++ b/assets/fonts/vfonts/FiraCode.css
@@ -0,0 +1,5 @@
+@font-face {
+ font-family: "v-mono";
+ font-weight: 400;
+ src: url("./assets/FiraCode-Regular.woff2");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/FiraSans.css b/assets/fonts/vfonts/FiraSans.css
new file mode 100644
index 0000000..1a11789
--- /dev/null
+++ b/assets/fonts/vfonts/FiraSans.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/FiraSans-Regular.woff2");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 500;
+ src: url("./assets/FiraSans-Medium.woff2");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/IBMPlexMono.css b/assets/fonts/vfonts/IBMPlexMono.css
new file mode 100644
index 0000000..c88ef15
--- /dev/null
+++ b/assets/fonts/vfonts/IBMPlexMono.css
@@ -0,0 +1,5 @@
+@font-face {
+ font-family: "v-mono";
+ font-weight: 400;
+ src: url("./assets/IBMPlexMono-Regular.ttf");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/IBMPlexSans.css b/assets/fonts/vfonts/IBMPlexSans.css
new file mode 100644
index 0000000..3850e13
--- /dev/null
+++ b/assets/fonts/vfonts/IBMPlexSans.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/IBMPlexSans-Regular.ttf");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 500;
+ src: url("./assets/IBMPlexSans-Medium.ttf");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/Inter.css b/assets/fonts/vfonts/Inter.css
new file mode 100644
index 0000000..174dbf6
--- /dev/null
+++ b/assets/fonts/vfonts/Inter.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/Inter-Regular.woff2");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 500;
+ src: url("./assets/Inter-Medium.woff2");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/Lato.css b/assets/fonts/vfonts/Lato.css
new file mode 100644
index 0000000..b77ddb5
--- /dev/null
+++ b/assets/fonts/vfonts/Lato.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/LatoLatin-Regular.woff2");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 600;
+ src: url("./assets/LatoLatin-Semibold.woff2");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/OpenSans.css b/assets/fonts/vfonts/OpenSans.css
new file mode 100644
index 0000000..e634aaf
--- /dev/null
+++ b/assets/fonts/vfonts/OpenSans.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/OpenSans-Regular.ttf");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 600;
+ src: url("./assets/OpenSans-SemiBold.ttf");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/README.md b/assets/fonts/vfonts/README.md
new file mode 100644
index 0000000..5357c78
--- /dev/null
+++ b/assets/fonts/vfonts/README.md
@@ -0,0 +1,44 @@
+# vfonts
+Integreted fonts for easy usage.
+
+## Usage
+```js
+// in your js
+import 'vfonts/{font-name}.css'
+// for available fonts, see the following section
+```
+```css
+/** in your css */
+selector {
+ font-family: v-sans, v-mono, other-fallbacks;
+}
+
+/** for available font weights, see the following section */
+selector {
+ font-weight: 400; /** regular */
+}
+
+selector {
+ font-weight: 500; /** medium */
+}
+```
+
+## Available Fonts
+### `v-sans`
+- `FiraSans.css`
+ - font weight `400`, `500`
+- `IBMPlexSans.css`
+ - font weight `400`, `500`
+- `Inter.css`
+ - font weight `400`, `500`
+- `Lato.css`
+ - font weight `400`, `600`
+- `OpenSans.css`
+ - font weight `400`, `600`
+- `Roboto.css`
+ - font weight `400`, `500`
+- `RobotoSlab.css`
+ - font weight `400`, `500`
+### `v-mono`
+- `FiraCode.css`
+ - font weight `400`
\ No newline at end of file
diff --git a/assets/fonts/vfonts/Roboto.css b/assets/fonts/vfonts/Roboto.css
new file mode 100644
index 0000000..f2bbb7f
--- /dev/null
+++ b/assets/fonts/vfonts/Roboto.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/Roboto-Regular.ttf");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 500;
+ src: url("./assets/Roboto-Medium.ttf");
+}
\ No newline at end of file
diff --git a/assets/fonts/vfonts/RobotoSlab.css b/assets/fonts/vfonts/RobotoSlab.css
new file mode 100644
index 0000000..d2eb8c9
--- /dev/null
+++ b/assets/fonts/vfonts/RobotoSlab.css
@@ -0,0 +1,11 @@
+@font-face {
+ font-family: "v-sans";
+ font-weight: 400;
+ src: url("./assets/RobotoSlab-Regular.ttf");
+}
+
+@font-face {
+ font-family: "v-sans";
+ font-weight: 500;
+ src: url("./assets/RobotoSlab-Medium.ttf");
+}
diff --git a/assets/fonts/vfonts/assets/FiraCode-Regular.woff2 b/assets/fonts/vfonts/assets/FiraCode-Regular.woff2
new file mode 100644
index 0000000..d58667c
Binary files /dev/null and b/assets/fonts/vfonts/assets/FiraCode-Regular.woff2 differ
diff --git a/assets/fonts/vfonts/assets/FiraSans-Medium.woff2 b/assets/fonts/vfonts/assets/FiraSans-Medium.woff2
new file mode 100644
index 0000000..7a1e5fc
Binary files /dev/null and b/assets/fonts/vfonts/assets/FiraSans-Medium.woff2 differ
diff --git a/assets/fonts/vfonts/assets/FiraSans-Regular.woff2 b/assets/fonts/vfonts/assets/FiraSans-Regular.woff2
new file mode 100644
index 0000000..e766e06
Binary files /dev/null and b/assets/fonts/vfonts/assets/FiraSans-Regular.woff2 differ
diff --git a/assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf b/assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf
new file mode 100644
index 0000000..90325c8
Binary files /dev/null and b/assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf differ
diff --git a/assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf b/assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf
new file mode 100644
index 0000000..b278201
Binary files /dev/null and b/assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf differ
diff --git a/assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf b/assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf
new file mode 100644
index 0000000..3b16bfd
Binary files /dev/null and b/assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf differ
diff --git a/assets/fonts/vfonts/assets/Inter-Medium.woff2 b/assets/fonts/vfonts/assets/Inter-Medium.woff2
new file mode 100644
index 0000000..ffb4206
Binary files /dev/null and b/assets/fonts/vfonts/assets/Inter-Medium.woff2 differ
diff --git a/assets/fonts/vfonts/assets/Inter-Regular.woff2 b/assets/fonts/vfonts/assets/Inter-Regular.woff2
new file mode 100644
index 0000000..66691b8
Binary files /dev/null and b/assets/fonts/vfonts/assets/Inter-Regular.woff2 differ
diff --git a/assets/fonts/vfonts/assets/LatoLatin-Regular.woff2 b/assets/fonts/vfonts/assets/LatoLatin-Regular.woff2
new file mode 100644
index 0000000..a4d084b
Binary files /dev/null and b/assets/fonts/vfonts/assets/LatoLatin-Regular.woff2 differ
diff --git a/assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2 b/assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2
new file mode 100644
index 0000000..1861c24
Binary files /dev/null and b/assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2 differ
diff --git a/assets/fonts/vfonts/assets/OpenSans-Regular.ttf b/assets/fonts/vfonts/assets/OpenSans-Regular.ttf
new file mode 100644
index 0000000..2d4da3a
Binary files /dev/null and b/assets/fonts/vfonts/assets/OpenSans-Regular.ttf differ
diff --git a/assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf b/assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf
new file mode 100644
index 0000000..54e7059
Binary files /dev/null and b/assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf differ
diff --git a/assets/fonts/vfonts/assets/Roboto-Medium.ttf b/assets/fonts/vfonts/assets/Roboto-Medium.ttf
new file mode 100644
index 0000000..f714a51
Binary files /dev/null and b/assets/fonts/vfonts/assets/Roboto-Medium.ttf differ
diff --git a/assets/fonts/vfonts/assets/Roboto-Regular.ttf b/assets/fonts/vfonts/assets/Roboto-Regular.ttf
new file mode 100644
index 0000000..2b6392f
Binary files /dev/null and b/assets/fonts/vfonts/assets/Roboto-Regular.ttf differ
diff --git a/assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf b/assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf
new file mode 100644
index 0000000..e4db6f7
Binary files /dev/null and b/assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf differ
diff --git a/assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf b/assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf
new file mode 100644
index 0000000..25b84e4
Binary files /dev/null and b/assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf differ
diff --git a/assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt b/assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
new file mode 100644
index 0000000..6bd9f9f
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
@@ -0,0 +1,93 @@
+Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md b/assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
new file mode 100644
index 0000000..116ec55
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
@@ -0,0 +1 @@
+FiraSans is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt b/assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
new file mode 100644
index 0000000..1eebd32
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
@@ -0,0 +1,93 @@
+Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/Inter-LISCENSE.txt b/assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
new file mode 100644
index 0000000..65ec0f9
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2016-2020 The Inter Project Authors.
+"Inter" is trademark of Rasmus Andersson.
+https://github.com/rsms/inter
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION AND CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/Lato-LISCENSE.md b/assets/fonts/vfonts/font-license/Lato-LISCENSE.md
new file mode 100644
index 0000000..1a4f9a8
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/Lato-LISCENSE.md
@@ -0,0 +1 @@
+Lato is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md b/assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
new file mode 100644
index 0000000..afbd70c
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
@@ -0,0 +1 @@
+Open Sans is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/Roboto-LISCENSE.md b/assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
new file mode 100644
index 0000000..6eda42c
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
@@ -0,0 +1 @@
+Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
\ No newline at end of file
diff --git a/assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md b/assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
new file mode 100644
index 0000000..6eda42c
--- /dev/null
+++ b/assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
@@ -0,0 +1 @@
+Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
\ No newline at end of file
diff --git a/assets/icon/startMessage/demo.css b/assets/icon/startMessage/demo.css
new file mode 100644
index 0000000..a67054a
--- /dev/null
+++ b/assets/icon/startMessage/demo.css
@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+ font-family: "iconfont logo";
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+ font-family: "iconfont logo";
+ font-size: 160px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+ position: relative;
+}
+
+.nav-tabs .nav-more {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ height: 42px;
+ line-height: 42px;
+ color: #666;
+}
+
+#tabs {
+ border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+ cursor: pointer;
+ width: 100px;
+ height: 40px;
+ line-height: 40px;
+ text-align: center;
+ font-size: 16px;
+ border-bottom: 2px solid transparent;
+ position: relative;
+ z-index: 1;
+ margin-bottom: -1px;
+ color: #666;
+}
+
+
+#tabs .active {
+ border-bottom-color: #f00;
+ color: #222;
+}
+
+.tab-container .content {
+ display: none;
+}
+
+/* 页面布局 */
+.main {
+ padding: 30px 100px;
+ width: 960px;
+ margin: 0 auto;
+}
+
+.main .logo {
+ color: #333;
+ text-align: left;
+ margin-bottom: 30px;
+ line-height: 1;
+ height: 110px;
+ margin-top: -50px;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.main .logo a {
+ font-size: 160px;
+ color: #333;
+}
+
+.helps {
+ margin-top: 40px;
+}
+
+.helps pre {
+ padding: 20px;
+ margin: 10px 0;
+ border: solid 1px #e7e1cd;
+ background-color: #fffdef;
+ overflow: auto;
+}
+
+.icon_lists {
+ width: 100% !important;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.icon_lists li {
+ width: 100px;
+ margin-bottom: 10px;
+ margin-right: 20px;
+ text-align: center;
+ list-style: none !important;
+ cursor: default;
+}
+
+.icon_lists li .code-name {
+ line-height: 1.2;
+}
+
+.icon_lists .icon {
+ display: block;
+ height: 100px;
+ line-height: 100px;
+ font-size: 42px;
+ margin: 10px auto;
+ color: #333;
+ -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+ -moz-transition: font-size 0.25s linear, width 0.25s linear;
+ transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+ font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+ /* 通过设置 font-size 来改变图标大小 */
+ width: 1em;
+ /* 图标和文字相邻时,垂直对齐 */
+ vertical-align: -0.15em;
+ /* 通过设置 color 来改变 SVG 的颜色/fill */
+ fill: currentColor;
+ /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+ normalize.css 中也包含这行 */
+ overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+ color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+ color: #666;
+ font-size: 14px;
+ line-height: 1.8;
+}
+
+.highlight {
+ line-height: 1.5;
+}
+
+.markdown img {
+ vertical-align: middle;
+ max-width: 100%;
+}
+
+.markdown h1 {
+ color: #404040;
+ font-weight: 500;
+ line-height: 40px;
+ margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+ color: #404040;
+ margin: 1.6em 0 0.6em 0;
+ font-weight: 500;
+ clear: both;
+}
+
+.markdown h1 {
+ font-size: 28px;
+}
+
+.markdown h2 {
+ font-size: 22px;
+}
+
+.markdown h3 {
+ font-size: 16px;
+}
+
+.markdown h4 {
+ font-size: 14px;
+}
+
+.markdown h5 {
+ font-size: 12px;
+}
+
+.markdown h6 {
+ font-size: 12px;
+}
+
+.markdown hr {
+ height: 1px;
+ border: 0;
+ background: #e9e9e9;
+ margin: 16px 0;
+ clear: both;
+}
+
+.markdown p {
+ margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+ width: 80%;
+}
+
+.markdown ul>li {
+ list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+ margin: 0.6em 0;
+}
+
+.markdown ol>li {
+ list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown code {
+ margin: 0 3px;
+ padding: 0 5px;
+ background: #eee;
+ border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+ font-weight: 600;
+}
+
+.markdown>table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ empty-cells: show;
+ border: 1px solid #e9e9e9;
+ width: 95%;
+ margin-bottom: 24px;
+}
+
+.markdown>table th {
+ white-space: nowrap;
+ color: #333;
+ font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+ border: 1px solid #e9e9e9;
+ padding: 8px 16px;
+ text-align: left;
+}
+
+.markdown>table th {
+ background: #F7F7F7;
+}
+
+.markdown blockquote {
+ font-size: 90%;
+ color: #999;
+ border-left: 4px solid #e9e9e9;
+ padding-left: 0.8em;
+ margin: 1em 0;
+}
+
+.markdown blockquote p {
+ margin: 0;
+}
+
+.markdown .anchor {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ margin-left: 8px;
+}
+
+.markdown .waiting {
+ color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+ opacity: 1;
+ display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+ clear: both;
+}
+
+
+.hljs {
+ display: block;
+ background: white;
+ padding: 0.5em;
+ color: #333333;
+ overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+ color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+ color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+ color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+ color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+ color: #63a35c;
+}
+
+.hljs-tag {
+ color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+ color: #795da3;
+}
+
+.hljs-addition {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.hljs-deletion {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ background: none;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+ white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/assets/icon/startMessage/demo_index.html b/assets/icon/startMessage/demo_index.html
new file mode 100644
index 0000000..ca13ed1
--- /dev/null
+++ b/assets/icon/startMessage/demo_index.html
@@ -0,0 +1,280 @@
+
+
+
+
+ iconfont Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Unicode
+ - Font class
+ - Symbol
+
+
+
查看项目
+
+
+
+
+
+
+ -
+
+
error-fill
+ 
+
+
+ -
+
+
info-fill
+ 
+
+
+ -
+
+
success-fill
+ 
+
+
+ -
+
+
user-defined-fill
+ 
+
+
+
+
+
Unicode 引用
+
+
+
Unicode 是字体在网页端最原始的应用方式,特点是:
+
+ - 支持按字体的方式去动态调整图标大小,颜色等等。
+ - 默认情况下不支持多色,直接添加多色图标会自动去色。
+
+
+ 注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)
+
+
Unicode 使用步骤如下:
+
第一步:拷贝项目下面生成的 @font-face
+
@font-face {
+ font-family: 'startMessage';
+ src: url('iconfont.woff2?t=1745672562595') format('woff2'),
+ url('iconfont.woff?t=1745672562595') format('woff'),
+ url('iconfont.ttf?t=1745672562595') format('truetype');
+}
+
+
第二步:定义使用 iconfont 的样式
+
.startMessage {
+ font-family: "startMessage" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+
第三步:挑选相应图标并获取字体编码,应用于页面
+
+<span class="startMessage">3</span>
+
+
+ "startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+ -
+
+
+ error-fill
+
+ .startMessageerror-fill
+
+
+
+ -
+
+
+ info-fill
+
+ .startMessageinfo-fill
+
+
+
+ -
+
+
+ success-fill
+
+ .startMessagesuccess-fill
+
+
+
+ -
+
+
+ user-defined-fill
+
+ .startMessageuser-defined-fill
+
+
+
+
+
+
font-class 引用
+
+
+
font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。
+
与 Unicode 使用方式相比,具有如下特点:
+
+ - 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
+ - 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 fontclass 代码:
+
<link rel="stylesheet" href="./iconfont.css">
+
+
第二步:挑选相应图标并获取类名,应用于页面:
+
<span class="startMessage startMessagexxx"></span>
+
+
+ "
+ startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+
Symbol 引用
+
+
+
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
+ 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:
+
+ - 支持多色图标了,不再受单色限制。
+ - 通过一些技巧,支持像字体那样,通过
font-size
, color
来调整样式。
+ - 兼容性较差,支持 IE9+,及现代浏览器。
+ - 浏览器渲染 SVG 的性能一般,还不如 png。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 symbol 代码:
+
<script src="./iconfont.js"></script>
+
+
第二步:加入通用 CSS 代码(引入一次就行):
+
<style>
+.icon {
+ width: 1em;
+ height: 1em;
+ vertical-align: -0.15em;
+ fill: currentColor;
+ overflow: hidden;
+}
+</style>
+
+
第三步:挑选相应图标并获取类名,应用于页面:
+
<svg class="icon" aria-hidden="true">
+ <use xlink:href="#icon-xxx"></use>
+</svg>
+
+
+
+
+
+
+
+
+
diff --git a/assets/icon/startMessage/iconfont.css b/assets/icon/startMessage/iconfont.css
new file mode 100644
index 0000000..eec50f9
--- /dev/null
+++ b/assets/icon/startMessage/iconfont.css
@@ -0,0 +1,31 @@
+@font-face {
+ font-family: "startMessageIconFont"; /* Project id 4906634 */
+ src: url('iconfont.woff2?t=1745672562595') format('woff2'),
+ url('iconfont.woff?t=1745672562595') format('woff'),
+ url('iconfont.ttf?t=1745672562595') format('truetype');
+}
+
+.startMessageIconFont {
+ font-family: "startMessageIconFont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.startMessageerror-fill:before {
+ content: "\e839";
+}
+
+.startMessageinfo-fill:before {
+ content: "\e83d";
+}
+
+.startMessagesuccess-fill:before {
+ content: "\e842";
+}
+
+.startMessageuser-defined-fill:before {
+ content: "\e871";
+}
+
diff --git a/assets/icon/startMessage/iconfont.js b/assets/icon/startMessage/iconfont.js
new file mode 100644
index 0000000..a7f7d02
--- /dev/null
+++ b/assets/icon/startMessage/iconfont.js
@@ -0,0 +1 @@
+window._iconfont_svg_string_4906634='',(n=>{var e=(t=(t=document.getElementsByTagName("script"))[t.length-1]).getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var o,i,s,a,l,d=function(e,t){t.parentNode.insertBefore(e,t)};if(e&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}o=function(){var e,t=document.createElement("div");t.innerHTML=n._iconfont_svg_string_4906634,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(e=document.body).firstChild?d(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(o,0):(i=function(){document.removeEventListener("DOMContentLoaded",i,!1),o()},document.addEventListener("DOMContentLoaded",i,!1)):document.attachEvent&&(s=o,a=n.document,l=!1,r(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,c())})}function c(){l||(l=!0,s())}function r(){try{a.documentElement.doScroll("left")}catch(e){return void setTimeout(r,50)}c()}})(window);
\ No newline at end of file
diff --git a/assets/icon/startMessage/iconfont.json b/assets/icon/startMessage/iconfont.json
new file mode 100644
index 0000000..3a0ac2e
--- /dev/null
+++ b/assets/icon/startMessage/iconfont.json
@@ -0,0 +1,37 @@
+{
+ "id": "4906634",
+ "name": "startMessage",
+ "font_family": "startMessage",
+ "css_prefix_text": "startMessage",
+ "description": "",
+ "glyphs": [
+ {
+ "icon_id": "34452976",
+ "name": "error-fill",
+ "font_class": "error-fill",
+ "unicode": "e839",
+ "unicode_decimal": 59449
+ },
+ {
+ "icon_id": "34453007",
+ "name": "info-fill",
+ "font_class": "info-fill",
+ "unicode": "e83d",
+ "unicode_decimal": 59453
+ },
+ {
+ "icon_id": "34453063",
+ "name": "success-fill",
+ "font_class": "success-fill",
+ "unicode": "e842",
+ "unicode_decimal": 59458
+ },
+ {
+ "icon_id": "34453306",
+ "name": "user-defined-fill",
+ "font_class": "user-defined-fill",
+ "unicode": "e871",
+ "unicode_decimal": 59505
+ }
+ ]
+}
diff --git a/assets/icon/startMessage/iconfont.ttf b/assets/icon/startMessage/iconfont.ttf
new file mode 100644
index 0000000..9144766
Binary files /dev/null and b/assets/icon/startMessage/iconfont.ttf differ
diff --git a/assets/icon/startMessage/iconfont.woff b/assets/icon/startMessage/iconfont.woff
new file mode 100644
index 0000000..96c6993
Binary files /dev/null and b/assets/icon/startMessage/iconfont.woff differ
diff --git a/assets/icon/startMessage/iconfont.woff2 b/assets/icon/startMessage/iconfont.woff2
new file mode 100644
index 0000000..e40d913
Binary files /dev/null and b/assets/icon/startMessage/iconfont.woff2 differ
diff --git a/components/Logo.vue b/components/Logo.vue
index 60a0690..e20e7bf 100644
--- a/components/Logo.vue
+++ b/components/Logo.vue
@@ -27,7 +27,7 @@
align-items: center;
.logoContent{
position: relative;
- padding: 5px 20px;
+ padding: 2.5px 20px;
& > div{
position: relative;
}
diff --git a/components/Ni/BaseNotificationContainer.vue b/components/Ni/BaseNotificationContainer.vue
index 24b3848..2740862 100644
--- a/components/Ni/BaseNotificationContainer.vue
+++ b/components/Ni/BaseNotificationContainer.vue
@@ -3,7 +3,7 @@
-
+
diff --git a/components/Ni/Button.vue b/components/Ni/Button.vue
index 3b4a51e..29c0dd0 100644
--- a/components/Ni/Button.vue
+++ b/components/Ni/Button.vue
@@ -4,7 +4,7 @@ const props = defineProps({
// 按钮类型
type: String,
default: 'default',
- validator: (value: string) => ['default', 'tertiary', 'primary', 'info', 'success', 'warning', 'error'].includes(value)
+ validator: (value: string) => ['default', 'primary', 'info', 'success', 'warning', 'error'].includes(value)
},
strong: {
// 加粗
@@ -34,7 +34,13 @@ const props = defineProps({
default: false,
}
})
-consola.info(toValue(props))
+const emit = defineEmits(['click']);
+
+const handleClick = () => {
+ if (!props.disabled && !props.loading) {
+ emit('click');
+ }
+};
const typeS = ref(props.type);
const strong = ref(props.strong);
const grade = ref(props.grade);
@@ -57,6 +63,7 @@ const NiButtonClass = computed(() => {
grade.value == 'light' ? 'light' : '',
grade.value == 'halfTransparent' ? 'halfTransparent' : '',
grade.value == 'transparent' ? 'transparent' : '',
+ typeS.value == 'default' ? 'defaultType' : '',
].join(' ');
})
const style = computed(() => {
@@ -86,10 +93,11 @@ const style = computed(() => {
})
-
+
@@ -118,10 +126,10 @@ const style = computed(() => {
align-items: center;
background-color: var(--NiButton-bg-default);
color: var(--NiButton-color-default);
+ border: 1px solid var(--NiButton-bg-default);
padding: var(--Ni-button-padding);
width: fit-content;
height: var(--Ni-button-height);
- border: 1px solid var(--NiButton-bg-default);
cursor: pointer;
transition: color .3s ease-in-out, background-color .3s ease-in-out, border-color .3s ease-in-out, width .3s ease-in-out;
//height: var(--Ni-button-height);
@@ -139,6 +147,21 @@ const style = computed(() => {
border: 1px solid var(--NiButton-bg-click);
}
}
+.NiButton.defaultType{
+ background-color: rgba(0, 0, 0, 0);
+ color: var(--Ni-theme-color-T1);
+ border: 1px solid var(--Ni-theme-border-color);
+ &:hover {
+ background-color: rgba(0, 0, 0, 0);
+ color: var(--Ni-theme-color-T2);
+ border: 1px solid var(--Ni-theme-border-color-hover);
+ }
+ &:active {
+ background-color: rgba(0, 0, 0, 0);
+ color: var(--Ni-theme-color-T0);
+ border: 1px solid var(--Ni-theme-color-T0);
+ }
+}
.NiButton.disabled{
opacity: var(--Ni-button-disable-opacity);
cursor: not-allowed;
diff --git a/components/Ni/Form.vue b/components/Ni/Form.vue
new file mode 100644
index 0000000..9605a5e
--- /dev/null
+++ b/components/Ni/Form.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Ni/FormItem.vue b/components/Ni/FormItem.vue
new file mode 100644
index 0000000..0413fc8
--- /dev/null
+++ b/components/Ni/FormItem.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Ni/Input.vue b/components/Ni/Input.vue
new file mode 100644
index 0000000..6f9a0ff
--- /dev/null
+++ b/components/Ni/Input.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Ni/Message.vue b/components/Ni/Message.vue
new file mode 100644
index 0000000..7790fb0
--- /dev/null
+++ b/components/Ni/Message.vue
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ msg.content }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/Ni/Popup.vue b/components/Ni/Popup.vue
index 44a5a34..c3d4895 100644
--- a/components/Ni/Popup.vue
+++ b/components/Ni/Popup.vue
@@ -80,7 +80,7 @@ onMounted(() => {
-
+
{
@@ -138,7 +140,6 @@ onMounted(() => {
position: relative;
will-change: transform; /* 提前告知浏览器会变化的属性 will-change: transform, opacity; 优化性能*/
--width: 600px;
- aspect-ratio: 1/0.618;
max-width: 80vw;
max-height: 80vh;
width: var(--width);
@@ -149,6 +150,18 @@ onMounted(() => {
background-color: var(--Ni-content-bg-color);
display: flex;
flex-direction: column;
+
+ @media (min-width: 768px){
+ &{
+ aspect-ratio: 1/0.618;
+ }
+ }
+
+ @media (max-width: 767px){
+ &{
+ height: auto;
+ }
+ }
}
// 弹窗头
.NiPopupContainer>header{
@@ -184,6 +197,7 @@ onMounted(() => {
user-select: none;
color: var(--Ni-theme-color);
margin-left: .7rem;
+ font-size: 1.2rem;
&:before{
content: ' ';
@@ -238,4 +252,5 @@ onMounted(() => {
animation-direction: reverse;/* 反向播放时 */
}
+
\ No newline at end of file
diff --git a/components/Ni/Space.vue b/components/Ni/Space.vue
new file mode 100644
index 0000000..a5d6ee1
--- /dev/null
+++ b/components/Ni/Space.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/composables/useNiMessage.ts b/composables/useNiMessage.ts
new file mode 100644
index 0000000..2b62f01
--- /dev/null
+++ b/composables/useNiMessage.ts
@@ -0,0 +1,50 @@
+// composables/useMessage.ts
+interface Message {
+ id: number
+ content: string
+ messageType: string
+ close: () => void
+ pause: () => void
+ resume: () => void
+}
+
+const messages = reactive
([])
+
+export const useNiMessage = () => {
+ const createMessage = (content: string, messageType: string) => {
+ const id = Date.now()
+ let timeout: NodeJS.Timeout | null = null
+
+ const close = () => {
+ const index = messages.findIndex(msg => msg.id === id)
+ if (index > -1) messages.splice(index, 1)
+ }
+
+ const startTimer = () => {
+ timeout = setTimeout(close, 3000)
+ }
+
+ const message: Message = {
+ id,
+ content,
+ messageType,
+ close,
+ pause: () => timeout && clearTimeout(timeout),
+ resume: () => startTimer()
+ }
+
+ messages.unshift(message) // 新消息显示在最上方
+ startTimer()
+
+ return message
+ }
+
+ return {
+ messages,
+ log: (data: string) => createMessage(data, 'log'),
+ info: (data: string) => createMessage(data, 'info'),
+ warning: (data: string) => createMessage(data, 'warning'),
+ error: (data: string) => createMessage(data, 'error'),
+ success: (data: string) => createMessage(data, 'success'),
+ }
+}
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 59bc395..3a85009 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -2,146 +2,154 @@
// 每次热更新都会执行defineNuxtConfig
import {exec} from "node:child_process";
import open, {apps} from "open";
-import type {AddressInfo} from "node:net";
export default defineNuxtConfig({
- compatibilityDate: '2024-11-01',
- devtools: { enabled: true },
- modules: ['@nuxt/eslint'],
- devServer: {
- host: '0.0.0.0',
- port: 3000,
- },
- features: {
- devLogs: 'silent' // 这是默认值,确保它没有被设置为 true,日志区分server和client, false为不在client打印
- },
- css: [
- '~/assets/css/style.css',
- '~/assets/css/font.css',
- '~/assets/css/value.css',
- '~/assets/css/iconfont.css',
- '~/assets/css/transitions.css',
- '~/assets/css/Ni.css',
- ],
- app:{
- head:{
- link: [
- {
- // LXGW WenKai 落霞孤鹜
- rel: "stylesheet",
- href: 'https://chinese-fonts-cdn.deno.dev/packages/lxgwwenkai/dist/LXGWWenKai-Regular/result.css'
+ vite: {
+ esbuild: {
+ target: 'esnext' // 或 'es2020'
},
- {
- // Huiwen-mincho 汇文明朝体
- rel: "stylesheet",
- href: 'https://chinese-fonts-cdn.deno.dev/packages/hwmct/dist/%E6%B1%87%E6%96%87%E6%98%8E%E6%9C%9D%E4%BD%93/result.css'
- // article {
- // font-family:'Huiwen-mincho';
- // font-weight:'400'
- // };
+ optimizeDeps: {
+ esbuildOptions: {
+ target: 'esnext'
+ }
+ }
+ },
+ compatibilityDate: '2024-11-01',
+ devtools: {enabled: true},
+ modules: ['@nuxt/eslint'],
+ devServer: {
+ host: '0.0.0.0',
+ port: 3000,
+ },
+ features: {
+ devLogs: 'silent' // 这是默认值,确保它没有被设置为 true,日志区分server和client, false为不在client打印
+ },
+ css: [
+ '~/assets/css/style.css',
+ '~/assets/css/font.css',
+ '~/assets/css/value.css',
+ '~/assets/css/iconfont.css',
+ '~/assets/css/transitions.css',
+ '~/assets/css/Ni.css',
+ ],
+ app: {
+ head: {
+ link: [
+ {
+ // LXGW WenKai 落霞孤鹜
+ rel: "stylesheet",
+ href: 'https://chinese-fonts-cdn.deno.dev/packages/lxgwwenkai/dist/LXGWWenKai-Regular/result.css'
+ },
+ {
+ // Huiwen-mincho 汇文明朝体
+ rel: "stylesheet",
+ href: 'https://chinese-fonts-cdn.deno.dev/packages/hwmct/dist/%E6%B1%87%E6%96%87%E6%98%8E%E6%9C%9D%E4%BD%93/result.css'
+ // article {
+ // font-family:'Huiwen-mincho';
+ // font-weight:'400'
+ // };
+ },
+ ]
+ },
+ layoutTransition: {
+ name: 'indexFade',
+ mode: 'out-in',
+ type: 'transition', // 明确指定动画类型
+ duration: {
+ enter: 300,
+ leave: 300
+ },
+ appear: true
},
- ]
},
- layoutTransition:{
- name: 'indexFade',
- mode: 'out-in',
- type: 'transition', // 明确指定动画类型
- duration: {
- enter: 300,
- leave: 300
- },
- appear: true
+ hooks: {
+ 'listen': (server, listener) => {
+ const {address, url} = listener
+ startBroswer(address.address, url)
+ },
},
- },
- hooks: {
- 'listen': (server) => {
- startBroswer(server.address())
+ runtimeConfig: {
+ redis: {
+ host: process.env.REDIS_HOST || '127.0.0.1',
+ port: Number(process.env.REDIS_PORT) || 6379,
+ connectName: 'star-writ',
+ database: Number(process.env.REDIS_DB) || 9,
+ username: 'default',
+ password: process.env.REDIS_PASSWORD || 'Hxl1314521',
+ },
+ mysql: {
+ host: process.env.DB_HOST || '127.0.0.1',
+ port: Number(process.env.DB_PORT) || 3306,
+ user: process.env.DB_USER || 'root',
+ password: process.env.DB_PASSWORD,
+ database: process.env.DB_NAME || 'yuheng',
+ // ssl:
+ // process.env.NODE_ENV === 'production'
+ // ? {
+ // rejectUnauthorized: false,
+ // servername: '', // 明确置空servername参数
+ // }
+ // : null,
+ },
+ jwt: {
+ secret: process.env.JWT_SECRET || 'Hxl1314521',
+ accessExpiresIn: process.env.JWT_ACCESS_EXPIRES || '20m',
+ refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES || '14d',
+ whitelist: [
+ '/user/login',
+ '/user/register',
+ '/user/refreshToken',
+ '/',
+ // '/module',
+ '/docs*',
+ '/docs/json'
+ ],
+ },
+ defaultToken: {
+ username: process.env.USERNAME || 'expressgy',
+ nickname: process.env.PASSWORD || 'Nie',
+ userId: '1'
+ }
},
- },
- runtimeConfig: {
- redis: {
- host: process.env.REDIS_HOST || '127.0.0.1',
- port: Number(process.env.REDIS_PORT) || 6379,
- connectName: 'star-writ',
- database: Number(process.env.REDIS_DB) || 9,
- username: 'default',
- password: process.env.REDIS_PASSWORD || 'Hxl1314521',
- },
- mysql:{
- host: process.env.DB_HOST || '127.0.0.1',
- port: Number(process.env.DB_PORT) || 3306,
- user: process.env.DB_USER || 'root',
- password: process.env.DB_PASSWORD,
- database: process.env.DB_NAME || 'yuheng',
- // ssl:
- // process.env.NODE_ENV === 'production'
- // ? {
- // rejectUnauthorized: false,
- // servername: '', // 明确置空servername参数
- // }
- // : null,
- },
- jwt: {
- secret: process.env.JWT_SECRET || 'Hxl1314521',
- accessExpiresIn: process.env.JWT_ACCESS_EXPIRES || '20m',
- refreshExpiresIn: process.env.JWT_REFRESH_EXPIRES || '14d',
- whitelist: [
- '/user/login',
- '/user/register',
- '/user/refreshToken',
- '/',
- // '/module',
- '/docs*',
- '/docs/json'
- ],
- },
- defaultToken: {
- username: process.env.USERNAME || 'expressgy',
- nickname: process.env.PASSWORD || 'Nie',
- userId: '1'
- }
- },
})
// 首次启动浏览器
-async function startBroswer(address: AddressInfo | string | null) {
- if(!process.env.START){
- if (address && typeof address !== 'string') {
- console.log('Hooks: Listen')
- const host = address.address === '::' ? 'localhost' : address.address
- const port = address.port
- const url = `http://${host}:${port}`;
- try {
- await open(url, {
- app: {
- name: apps.chrome,
- arguments: [
- '--remote-debugging-port=9222',
- '--auto-open-devtools-for-tabs'
- ]
- }
- });
- } catch (e) {
- console.error((e as Error).message)
- switch (process.platform) {
- case 'win32':
- console.log('Windows 系统');
- exec(`start ${url}`)
- break;
- case 'darwin':
- console.log('macOS 系统');
- exec(`open ${url}`)
- break;
- case 'linux':
- console.log('Linux 系统');
- exec(`xdg-open ${url}`)
- break;
- default:
- console.log('其他系统:', process.platform);
+async function startBroswer(address: string, url: string) {
+ if (!process.env.START) {
+ const host = address === '::' ? 'localhost' : address
+ const port = url.split(':')[2]
+ const rrealUrl = `http://${host}:${port}`;
+ console.info(`Listening on ${rrealUrl}`);
+ try {
+ await open(rrealUrl, {
+ app: {
+ name: apps.chrome,
+ arguments: [
+ '--remote-debugging-port=9222',
+ '--auto-open-devtools-for-tabs'
+ ]
+ }
+ });
+ } catch (e) {
+ console.error((e as Error).message)
+ switch (process.platform) {
+ case 'win32':
+ console.log('Windows 系统');
+ exec(`start ${url}`)
+ break;
+ case 'darwin':
+ console.log('macOS 系统');
+ exec(`open ${url}`)
+ break;
+ case 'linux':
+ console.log('Linux 系统');
+ exec(`xdg-open ${url}`)
+ break;
+ default:
+ console.log('其他系统:', process.platform);
+ }
}
- }
- process.env.START = String(true)
+ process.env.START = String(true)
}
- }
}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1f02ab9..3b74bf7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"mysql2": "^3.14.0",
"nuxt": "^3.16.2",
"redis": "^4.7.0",
+ "rfdc": "^1.4.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"vueuc": "^0.4.64"
@@ -14054,7 +14055,7 @@
},
"node_modules/rfdc": {
"version": "1.4.1",
- "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
"license": "MIT"
},
diff --git a/package.json b/package.json
index 88401b0..06ecc7f 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"mysql2": "^3.14.0",
"nuxt": "^3.16.2",
"redis": "^4.7.0",
+ "rfdc": "^1.4.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"vueuc": "^0.4.64"
diff --git a/pages/home/blog/index.vue b/pages/home/blog/index.vue
index 0e97a25..fb33611 100644
--- a/pages/home/blog/index.vue
+++ b/pages/home/blog/index.vue
@@ -1,4 +1,9 @@
@@ -48,16 +81,16 @@ onMounted(() => {
@@ -274,33 +232,36 @@ onMounted(() => {
position: relative;
font-size: 1rem;
display: flex;
- & > div{
- position: relative;
- }
+
& > div.addIcon{
+ position: relative;
font-size: 1rem;
margin-right: .5rem;
}
& > div.text{
- height: 100%;
+ position: relative;
flex: 1;
+ min-width: 0;// 关键
display: flex;
align-items: center;
+ overflow: hidden;
}
& > div.barBox{
margin-left: .2rem;
height: 0;
width: 0;
opacity: 0;
+ overflow: hidden;
display: flex;
+ transition: opacity .3s;
+ & > div.bar{
+ opacity: 1;
+ }
}
&:hover div.barBox{
height: 100% !important;
width: auto !important;
opacity: 1 !important;
- & > div.bar{
- opacity: 1;
- }
}
}
}
diff --git a/pages/index.vue b/pages/index.vue
index e71cbfa..0d71fd7 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -8,7 +8,6 @@ const leaveTime = ref(false)
// 离开前路由拦截
onBeforeRouteLeave((to, from, next) => {
leaveTime.value = true
- consola.error('leave')
setTimeout(() => {
next(true)
}, 1000)
diff --git a/server/api/blog/blogMenu/index.post.ts b/server/api/blog/blogMenu/index.post.ts
index 9ce077a..d0bb3a8 100644
--- a/server/api/blog/blogMenu/index.post.ts
+++ b/server/api/blog/blogMenu/index.post.ts
@@ -1,11 +1,19 @@
-export default defineEventHandler(async event => {
- const requAuth = event.context.auth
- const body = await readBody(event)
- if(!requAuth.isTrue) {
- // 判断为正常登录
- throw createError({
+import {BlogMenuDB} from "~/server/services/blog/blogMenu";
+import consola from "consola";
- })
- }
- return 'Hello blog/blogMenu.post'
+export default defineEventHandler(async event => {
+ // 获取登录信息
+ const headerAuth = event.context.auth
+ // 获取参数
+ const body = await readBody(event)
+ // 初始化DB
+ body.id = event.context.getId()
+ const blogMenuDB = new BlogMenuDB(event)
+ const resd = await blogMenuDB.insertBlogMenu(body, headerAuth)
+ consola.info(body, resd)
+ // if(!requAuth.isTrue) {
+ // // 判断为正常登录
+ // }
+
+ return resd
})
diff --git a/server/api/hello.ts b/server/api/hello.ts
index 935448e..199f520 100644
--- a/server/api/hello.ts
+++ b/server/api/hello.ts
@@ -2,10 +2,11 @@ import consola from "consola";
export default defineEventHandler(async event => {
// console.log(await event.context.redis.get('SI HI'))
- consola.info('API')
- consola.info('API TimeOut')
- const result = await event.context.redis.get('SI HI');
- return {
- 'SI HI': result
- }
+ // consola.info('API')
+ // consola.info('API TimeOut')
+ // const result = await event.context.redis.get('SI HI');
+ // return {
+ // 'SI HI': result
+ // }
+ return 's'
})
diff --git a/server/plugins/redis.ts b/server/plugins/redis.ts
index bff0a76..ddc77b9 100644
--- a/server/plugins/redis.ts
+++ b/server/plugins/redis.ts
@@ -2,6 +2,7 @@ import { createClient } from 'redis';
import consola from 'consola'
export default defineNitroPlugin(async (nitroApp) => {
+ return
const {redis: config} = useRuntimeConfig()
consola.info('Redis ...');
const redisConnect = createClient({
@@ -17,8 +18,8 @@ export default defineNitroPlugin(async (nitroApp) => {
});
redisConnect.on('error', (err) => {
- console.log(err)
- consola.error('Redis error: ', err);
+ // console.log(err)
+ // consola.error('Redis error: ', err);
});
// 连接到 Redis
diff --git a/server/plugins/snowflake.ts b/server/plugins/snowflake.ts
new file mode 100644
index 0000000..b35d938
--- /dev/null
+++ b/server/plugins/snowflake.ts
@@ -0,0 +1,22 @@
+export default defineNitroPlugin(nitroApp => {
+
+ nitroApp.hooks.hook('request', async (event) => {
+ event.context.getId = generateEnhancedId
+ })
+})
+const EPOCH = 1609459200000;
+let sequence = 0;
+
+function generateEnhancedId(): string {
+ const now = Date.now();
+ const timestamp = now - EPOCH;
+
+ // 10 位序列号(支持 1024 个 ID/ms)
+ sequence = (sequence + 1) % 0x400;
+
+ // 组合成 64 位 ID
+ const high = (timestamp << 14) | sequence;
+ const low = Math.floor(Math.random() * 0x100000000);
+
+ return ((BigInt(high) << 32n) | BigInt(low)).toString();
+}
\ No newline at end of file
diff --git a/server/services/blog/blogMenu.ts b/server/services/blog/blogMenu.ts
index f399b7c..4145de1 100644
--- a/server/services/blog/blogMenu.ts
+++ b/server/services/blog/blogMenu.ts
@@ -35,6 +35,6 @@ export class BlogMenuDB {
.from(blogMenu)
.where(
and(eq(blogMenu.createdBy, headerAuth.userId), eq(blogMenu.deleted, 0), headerAuth.isTrue ? undefined : eq(blogMenu.public, 1))
- ).orderBy(asc(blogMenu.sort), desc(blogMenu.createdAt));
+ ).orderBy(asc(blogMenu.sort), asc(blogMenu.createdAt));
}
}
\ No newline at end of file