写添加菜单
This commit is contained in:
parent
fd361f332c
commit
3d5b72aea1
1
app.vue
1
app.vue
@ -3,5 +3,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
<NiMessage/>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
|
@ -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 {
|
.a11 {
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
@ -39,10 +48,15 @@
|
|||||||
--Ni-theme-color-T3: #e8e8e7;
|
--Ni-theme-color-T3: #e8e8e7;
|
||||||
--Ni-theme-color-T4: #EFEFED;
|
--Ni-theme-color-T4: #EFEFED;
|
||||||
--Ni-theme-color-T0-10: #37352f11;
|
--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-80: #37352f88;
|
||||||
--Ni-theme-color-T0-a0: #37352faa;
|
--Ni-theme-color-T0-a0: #37352faa;
|
||||||
--Ni-theme-color-T0-c0: #37352fcc;
|
--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;
|
--Ni-M-A: 1rem;
|
||||||
/*tertiary*/
|
/*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*/
|
/*primary*/
|
||||||
--Ni-button-primary-bg-default: #5f5e5b;
|
--Ni-button-primary-bg-default: #5f5e5b;
|
||||||
--Ni-button-primary-bg-hover: #91918e;
|
--Ni-button-primary-bg-hover: #91918e;
|
||||||
|
5
assets/fonts/vfonts/FiraCode.css
Normal file
5
assets/fonts/vfonts/FiraCode.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "v-mono";
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("./assets/FiraCode-Regular.woff2");
|
||||||
|
}
|
11
assets/fonts/vfonts/FiraSans.css
Normal file
11
assets/fonts/vfonts/FiraSans.css
Normal file
@ -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");
|
||||||
|
}
|
5
assets/fonts/vfonts/IBMPlexMono.css
Normal file
5
assets/fonts/vfonts/IBMPlexMono.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "v-mono";
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("./assets/IBMPlexMono-Regular.ttf");
|
||||||
|
}
|
11
assets/fonts/vfonts/IBMPlexSans.css
Normal file
11
assets/fonts/vfonts/IBMPlexSans.css
Normal file
@ -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");
|
||||||
|
}
|
11
assets/fonts/vfonts/Inter.css
Normal file
11
assets/fonts/vfonts/Inter.css
Normal file
@ -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");
|
||||||
|
}
|
11
assets/fonts/vfonts/Lato.css
Normal file
11
assets/fonts/vfonts/Lato.css
Normal file
@ -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");
|
||||||
|
}
|
11
assets/fonts/vfonts/OpenSans.css
Normal file
11
assets/fonts/vfonts/OpenSans.css
Normal file
@ -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");
|
||||||
|
}
|
44
assets/fonts/vfonts/README.md
Normal file
44
assets/fonts/vfonts/README.md
Normal file
@ -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`
|
11
assets/fonts/vfonts/Roboto.css
Normal file
11
assets/fonts/vfonts/Roboto.css
Normal file
@ -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");
|
||||||
|
}
|
11
assets/fonts/vfonts/RobotoSlab.css
Normal file
11
assets/fonts/vfonts/RobotoSlab.css
Normal file
@ -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");
|
||||||
|
}
|
BIN
assets/fonts/vfonts/assets/FiraCode-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraCode-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/FiraSans-Medium.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraSans-Medium.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/FiraSans-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/FiraSans-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexMono-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/IBMPlexSans-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Inter-Medium.woff2
Normal file
BIN
assets/fonts/vfonts/assets/Inter-Medium.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Inter-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/Inter-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/LatoLatin-Regular.woff2
Normal file
BIN
assets/fonts/vfonts/assets/LatoLatin-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2
Normal file
BIN
assets/fonts/vfonts/assets/LatoLatin-Semibold.woff2
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/OpenSans-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf
Normal file
BIN
assets/fonts/vfonts/assets/OpenSans-SemiBold.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Roboto-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/Roboto-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/Roboto-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf
Normal file
BIN
assets/fonts/vfonts/assets/RobotoSlab-Medium.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf
Normal file
BIN
assets/fonts/vfonts/assets/RobotoSlab-Regular.ttf
Normal file
Binary file not shown.
93
assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
Normal file
93
assets/fonts/vfonts/font-license/FiraCode-LISCENSE.txt
Normal file
@ -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.
|
1
assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/FiraSans-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
FiraSans is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
|
93
assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
Normal file
93
assets/fonts/vfonts/font-license/IBMPlex-LISCENSE.txt
Normal file
@ -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.
|
94
assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
Normal file
94
assets/fonts/vfonts/font-license/Inter-LISCENSE.txt
Normal file
@ -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.
|
1
assets/fonts/vfonts/font-license/Lato-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/Lato-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Lato is licensed under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL).
|
1
assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/OpenSans-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Open Sans is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
1
assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/Roboto-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
1
assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
Normal file
1
assets/fonts/vfonts/font-license/RobotoSlab-LISCENSE.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Roboto is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
539
assets/icon/startMessage/demo.css
Normal file
539
assets/icon/startMessage/demo.css
Normal file
@ -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;
|
||||||
|
}
|
280
assets/icon/startMessage/demo_index.html
Normal file
280
assets/icon/startMessage/demo_index.html
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>iconfont Demo</title>
|
||||||
|
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
|
||||||
|
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
|
||||||
|
<link rel="stylesheet" href="demo.css">
|
||||||
|
<link rel="stylesheet" href="iconfont.css">
|
||||||
|
<script src="iconfont.js"></script>
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
|
||||||
|
<!-- 代码高亮 -->
|
||||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||||
|
<style>
|
||||||
|
.main .logo {
|
||||||
|
margin-top: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo .sub-title {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
font-size: 22px;
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(-45deg, #3967FF, #B500FE);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main">
|
||||||
|
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
|
||||||
|
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
|
||||||
|
|
||||||
|
</a></h1>
|
||||||
|
<div class="nav-tabs">
|
||||||
|
<ul id="tabs" class="dib-box">
|
||||||
|
<li class="dib active"><span>Unicode</span></li>
|
||||||
|
<li class="dib"><span>Font class</span></li>
|
||||||
|
<li class="dib"><span>Symbol</span></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=4906634" target="_blank" class="nav-more">查看项目</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="tab-container">
|
||||||
|
<div class="content unicode" style="display: block;">
|
||||||
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage"></span>
|
||||||
|
<div class="name">error-fill</div>
|
||||||
|
<div class="code-name">&#xe839;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage"></span>
|
||||||
|
<div class="name">info-fill</div>
|
||||||
|
<div class="code-name">&#xe83d;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage"></span>
|
||||||
|
<div class="name">success-fill</div>
|
||||||
|
<div class="code-name">&#xe842;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage"></span>
|
||||||
|
<div class="name">user-defined-fill</div>
|
||||||
|
<div class="code-name">&#xe871;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<div class="article markdown">
|
||||||
|
<h2 id="unicode-">Unicode 引用</h2>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
|
||||||
|
<ul>
|
||||||
|
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
|
||||||
|
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
|
||||||
|
</ul>
|
||||||
|
<blockquote>
|
||||||
|
<p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>Unicode 使用步骤如下:</p>
|
||||||
|
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
|
||||||
|
<pre><code class="language-css"
|
||||||
|
>@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');
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||||
|
<pre><code class="language-css"
|
||||||
|
>.startMessage {
|
||||||
|
font-family: "startMessage" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
|
||||||
|
<pre>
|
||||||
|
<code class="language-html"
|
||||||
|
><span class="startMessage">&#x33;</span>
|
||||||
|
</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>"startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content font-class">
|
||||||
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage startMessageerror-fill"></span>
|
||||||
|
<div class="name">
|
||||||
|
error-fill
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.startMessageerror-fill
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage startMessageinfo-fill"></span>
|
||||||
|
<div class="name">
|
||||||
|
info-fill
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.startMessageinfo-fill
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage startMessagesuccess-fill"></span>
|
||||||
|
<div class="name">
|
||||||
|
success-fill
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.startMessagesuccess-fill
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon startMessage startMessageuser-defined-fill"></span>
|
||||||
|
<div class="name">
|
||||||
|
user-defined-fill
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.startMessageuser-defined-fill
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<div class="article markdown">
|
||||||
|
<h2 id="font-class-">font-class 引用</h2>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
|
||||||
|
<p>与 Unicode 使用方式相比,具有如下特点:</p>
|
||||||
|
<ul>
|
||||||
|
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
|
||||||
|
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
|
||||||
|
</ul>
|
||||||
|
<p>使用步骤如下:</p>
|
||||||
|
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
|
||||||
|
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||||
|
<pre><code class="language-html"><span class="startMessage startMessagexxx"></span>
|
||||||
|
</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>"
|
||||||
|
startMessage" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content symbol">
|
||||||
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#startMessageerror-fill"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">error-fill</div>
|
||||||
|
<div class="code-name">#startMessageerror-fill</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#startMessageinfo-fill"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">info-fill</div>
|
||||||
|
<div class="code-name">#startMessageinfo-fill</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#startMessagesuccess-fill"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">success-fill</div>
|
||||||
|
<div class="code-name">#startMessagesuccess-fill</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#startMessageuser-defined-fill"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">user-defined-fill</div>
|
||||||
|
<div class="code-name">#startMessageuser-defined-fill</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
<div class="article markdown">
|
||||||
|
<h2 id="symbol-">Symbol 引用</h2>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
|
||||||
|
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
|
||||||
|
<ul>
|
||||||
|
<li>支持多色图标了,不再受单色限制。</li>
|
||||||
|
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
|
||||||
|
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
|
||||||
|
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
|
||||||
|
</ul>
|
||||||
|
<p>使用步骤如下:</p>
|
||||||
|
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
|
||||||
|
<pre><code class="language-html"><script src="./iconfont.js"></script>
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
|
||||||
|
<pre><code class="language-html"><style>
|
||||||
|
.icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
fill: currentColor;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||||
|
<pre><code class="language-html"><svg class="icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-xxx"></use>
|
||||||
|
</svg>
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.tab-container .content:first').show()
|
||||||
|
|
||||||
|
$('#tabs li').click(function (e) {
|
||||||
|
var tabContent = $('.tab-container .content')
|
||||||
|
var index = $(this).index()
|
||||||
|
|
||||||
|
if ($(this).hasClass('active')) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
$('#tabs li').removeClass('active')
|
||||||
|
$(this).addClass('active')
|
||||||
|
|
||||||
|
tabContent.hide().eq(index).fadeIn()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
31
assets/icon/startMessage/iconfont.css
Normal file
31
assets/icon/startMessage/iconfont.css
Normal file
@ -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";
|
||||||
|
}
|
||||||
|
|
1
assets/icon/startMessage/iconfont.js
Normal file
1
assets/icon/startMessage/iconfont.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
window._iconfont_svg_string_4906634='<svg><symbol id="startMessageerror-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m129.29219 233.447619l-129.267809 129.29219-129.316571-129.29219-51.736381 51.736381 129.316571 129.267809-129.316571 129.316571 51.736381 51.736381L512 563.687619l129.29219 129.316571 51.736381-51.73638L563.687619 512l129.316571-129.29219-51.73638-51.736381z" ></path></symbol><symbol id="startMessageinfo-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m36.571429 341.333333h-73.142858v292.571428h73.142858V438.857143z m0-121.904762h-73.142858v73.142857h73.142858v-73.142857z" ></path></symbol><symbol id="startMessagesuccess-fill" viewBox="0 0 1024 1024"><path d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m193.194667 218.331428L447.21981 581.315048l-103.936-107.812572-52.662858 50.761143 156.379429 162.230857 310.662095-319.683047-52.467809-50.956191z" ></path></symbol><symbol id="startMessageuser-defined-fill" viewBox="0 0 1024 1024"><path d="M512 134.095238c212.089905 0 377.904762 148.187429 377.904762 354.279619 0 56.56381-17.871238 98.986667-64.926476 117.857524-18.358857 7.338667-36.230095 8.704-56.173715 6.802286-6.144-0.585143-12.263619-1.462857-19.407238-2.681905l-22.186666-4.022857c-29.842286-5.12-43.032381-3.900952-56.783238 5.144381-5.851429 3.876571-11.995429 9.411048-18.456381 17.066666-18.041905 21.382095-20.358095 38.034286-11.117715 73.289143l3.120762 11.166476 4.559238 15.408762 2.730667 9.654857c1.584762 5.851429 2.852571 11.093333 3.900952 16.335239 4.705524 23.844571 4.559238 45.29981-4.461714 67.535238C629.808762 873.569524 582.851048 889.904762 512 889.904762c-208.700952 0-377.904762-169.20381-377.904762-377.904762 0-208.700952 169.20381-377.904762 377.904762-377.904762z m-27.306667 509.44a73.142857 73.142857 0 1 0-144.847238 20.358095 73.142857 73.142857 0 0 0 144.847238-20.358095z m-33.913904-241.444571a73.142857 73.142857 0 1 0-144.871619 20.358095 73.142857 73.142857 0 0 0 144.871619-20.358095zM692.175238 368.152381a73.142857 73.142857 0 1 0-144.847238 20.358095 73.142857 73.142857 0 0 0 144.847238-20.358095z" ></path></symbol></svg>',(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("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}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);
|
37
assets/icon/startMessage/iconfont.json
Normal file
37
assets/icon/startMessage/iconfont.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
assets/icon/startMessage/iconfont.ttf
Normal file
BIN
assets/icon/startMessage/iconfont.ttf
Normal file
Binary file not shown.
BIN
assets/icon/startMessage/iconfont.woff
Normal file
BIN
assets/icon/startMessage/iconfont.woff
Normal file
Binary file not shown.
BIN
assets/icon/startMessage/iconfont.woff2
Normal file
BIN
assets/icon/startMessage/iconfont.woff2
Normal file
Binary file not shown.
@ -27,7 +27,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
.logoContent{
|
.logoContent{
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 5px 20px;
|
padding: 2.5px 20px;
|
||||||
& > div{
|
& > div{
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div data-prefix="Ni">
|
||||||
<slot/>
|
<slot/>
|
||||||
<div id="NiBaseNotificationContainer"></div>
|
<div id="NiBaseNotificationContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ const props = defineProps({
|
|||||||
// 按钮类型
|
// 按钮类型
|
||||||
type: String,
|
type: String,
|
||||||
default: 'default',
|
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: {
|
strong: {
|
||||||
// 加粗
|
// 加粗
|
||||||
@ -34,7 +34,13 @@ const props = defineProps({
|
|||||||
default: false,
|
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 typeS = ref(props.type);
|
||||||
const strong = ref(props.strong);
|
const strong = ref(props.strong);
|
||||||
const grade = ref(props.grade);
|
const grade = ref(props.grade);
|
||||||
@ -57,6 +63,7 @@ const NiButtonClass = computed(() => {
|
|||||||
grade.value == 'light' ? 'light' : '',
|
grade.value == 'light' ? 'light' : '',
|
||||||
grade.value == 'halfTransparent' ? 'halfTransparent' : '',
|
grade.value == 'halfTransparent' ? 'halfTransparent' : '',
|
||||||
grade.value == 'transparent' ? 'transparent' : '',
|
grade.value == 'transparent' ? 'transparent' : '',
|
||||||
|
typeS.value == 'default' ? 'defaultType' : '',
|
||||||
].join(' ');
|
].join(' ');
|
||||||
})
|
})
|
||||||
const style = computed(() => {
|
const style = computed(() => {
|
||||||
@ -86,10 +93,11 @@ const style = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template data-prefix="Ni">
|
||||||
<div class="NiButton"
|
<div class="NiButton"
|
||||||
:style
|
:style
|
||||||
:class="NiButtonClass"
|
:class="NiButtonClass"
|
||||||
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<slot name="icons"/>
|
<slot name="icons"/>
|
||||||
<span v-if="loading" class="sxIconFont" :class="loading && 'loading'"></span>
|
<span v-if="loading" class="sxIconFont" :class="loading && 'loading'"></span>
|
||||||
@ -118,10 +126,10 @@ const style = computed(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: var(--NiButton-bg-default);
|
background-color: var(--NiButton-bg-default);
|
||||||
color: var(--NiButton-color-default);
|
color: var(--NiButton-color-default);
|
||||||
|
border: 1px solid var(--NiButton-bg-default);
|
||||||
padding: var(--Ni-button-padding);
|
padding: var(--Ni-button-padding);
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
height: var(--Ni-button-height);
|
height: var(--Ni-button-height);
|
||||||
border: 1px solid var(--NiButton-bg-default);
|
|
||||||
cursor: pointer;
|
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;
|
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);
|
//height: var(--Ni-button-height);
|
||||||
@ -139,6 +147,21 @@ const style = computed(() => {
|
|||||||
border: 1px solid var(--NiButton-bg-click);
|
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{
|
.NiButton.disabled{
|
||||||
opacity: var(--Ni-button-disable-opacity);
|
opacity: var(--Ni-button-disable-opacity);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
23
components/Ni/Form.vue
Normal file
23
components/Ni/Form.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
// 表单数据
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rules:{
|
||||||
|
// 表单数据
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="NiForm" data-prefix="Ni">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
69
components/Ni/FormItem.vue
Normal file
69
components/Ni/FormItem.vue
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
name:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: String,
|
||||||
|
default: '8',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const itemLabel = ref('')
|
||||||
|
const itemName = ref('')
|
||||||
|
const itemLabelWidth = ref('8')
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
itemLabel.value = props.label
|
||||||
|
itemName.value = props.name
|
||||||
|
itemLabelWidth.value = props.labelWidth
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="NiFormItem" data-prefix="Ni">
|
||||||
|
<div class="content">
|
||||||
|
<div class="formLabel" :style="{width: itemLabelWidth+'em'}">
|
||||||
|
<span>{{itemLabel}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="formValue"><slot/></div>
|
||||||
|
</div>
|
||||||
|
<div class="feedback"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.NiFormItem{
|
||||||
|
position: relative;
|
||||||
|
height: 3.6rem;
|
||||||
|
padding: .5rem 0;
|
||||||
|
|
||||||
|
& > div.content{
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
height: 2.4rem;
|
||||||
|
|
||||||
|
&>div.formLabel{
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--Ni-theme-color);
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&>div.formValue{
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > div.feedback{
|
||||||
|
position: relative;
|
||||||
|
height: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
118
components/Ni/Input.vue
Normal file
118
components/Ni/Input.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: { // v-model 默认接收的属性
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
clear: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
// 按钮类型
|
||||||
|
type: String,
|
||||||
|
default: 'text',
|
||||||
|
validator: (value: string) => ['text', 'password'].includes(value)
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
// 禁用
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
showPasswordOn: {
|
||||||
|
// 查看密码的事件
|
||||||
|
type: String,
|
||||||
|
default: 'click',
|
||||||
|
validator: (value: string) => ['click', 'mouseDown'].includes(value)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const emit = defineEmits([
|
||||||
|
'update:modelValue', // v-model 必须
|
||||||
|
'focus', // 聚焦事件
|
||||||
|
'blur' // 失焦事件
|
||||||
|
])
|
||||||
|
const inputRef = ref(null)
|
||||||
|
const clear = ref(props.clear)
|
||||||
|
const type = ref(props.type)
|
||||||
|
const disabled = ref(props.disabled)
|
||||||
|
const showPasswordOn = ref(props.showPasswordOn)
|
||||||
|
watchEffect(() => {
|
||||||
|
clear.value = props.clear;
|
||||||
|
type.value = props.type;
|
||||||
|
disabled.value = props.disabled;
|
||||||
|
showPasswordOn.value = props.showPasswordOn
|
||||||
|
})
|
||||||
|
// 输入事件处理
|
||||||
|
const handleInput = (event) => {
|
||||||
|
emit('update:modelValue', event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聚焦事件透传
|
||||||
|
const handleFocus = (event) => {
|
||||||
|
emit('focus', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 失焦事件透传
|
||||||
|
const handleBlur = (event) => {
|
||||||
|
emit('blur', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法(可选)
|
||||||
|
defineExpose({
|
||||||
|
focus: () => inputRef.value.focus(),
|
||||||
|
blur: () => inputRef.value.blur()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="NiInput" data-prefix="Ni">
|
||||||
|
<div class="before">
|
||||||
|
<slot name="before"></slot>
|
||||||
|
</div>
|
||||||
|
<div class="inputMain">
|
||||||
|
<!-- 透传所有原生属性 v-bind="$attrs" -->
|
||||||
|
<input type="text" ref="inputRef"
|
||||||
|
class="ni-input"
|
||||||
|
:value="modelValue"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@input="handleInput"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@blur="handleBlur"></div>
|
||||||
|
<div class="show-password"></div>
|
||||||
|
<div class="after">
|
||||||
|
<slot name="after"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.NiInput {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& > div.inputMain {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
height: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid var(--Ni-theme-border-color);
|
||||||
|
padding: .2rem .5rem;
|
||||||
|
border-radius: var(--Ni-border-radius);
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: border 0.3s ease-in-out;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--Ni-theme-border-color-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
129
components/Ni/Message.vue
Normal file
129
components/Ni/Message.vue
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<!-- components/MessageContainer.vue -->
|
||||||
|
<script setup>
|
||||||
|
const {messages} = useNiMessage()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<teleport to="#teleports">
|
||||||
|
<TransitionGroup name="niMessage" tag="div" class="NiMessage" data-prefix="Ni">
|
||||||
|
<div class="niMessageContent" v-for="msg in messages" :key="msg.id" @mouseenter="msg.pause()"
|
||||||
|
@mouseleave="msg.resume()">
|
||||||
|
<div class="niMessageIcon">
|
||||||
|
<div v-if="msg.messageType == 'log'" class="startMessageIconFont messageLog">
|
||||||
|
<NiLogo/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="msg.messageType == 'info'" class="startMessageIconFont messageInfo"></div>
|
||||||
|
<div v-else-if="msg.messageType == 'success'" class="startMessageIconFont messageSuccess">
|
||||||
|
</div>
|
||||||
|
<div v-else-if="msg.messageType == 'warning'" class="startMessageIconFont messageWarning">
|
||||||
|
</div>
|
||||||
|
<div v-else-if="msg.messageType == 'error'" class="startMessageIconFont messageError"></div>
|
||||||
|
</div>
|
||||||
|
<div class="niMessageBody">
|
||||||
|
{{ msg.content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TransitionGroup>
|
||||||
|
</teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// 动画
|
||||||
|
.niMessage-enter-active, .niMessage-leave-active {
|
||||||
|
transition: all .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.niMessage-enter-from, .niMessage-leave-to {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.NiMessage {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column; /* 新消息在上方 */
|
||||||
|
gap: 10px;
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: none; /* 容器不阻挡点击 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.niMessageContent {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: var(--Ni-content-padding);
|
||||||
|
transition: all 0.3s;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
border-radius: var(--Ni-border-radius);
|
||||||
|
background: #fefefe;
|
||||||
|
cursor: pointer;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
pointer-events: auto; /* 单个消息可交互 */
|
||||||
|
max-width: min(1000px, 80vw);
|
||||||
|
& > div.niMessageIcon {
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: .8rem;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.messageLog {
|
||||||
|
font-size: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.messageInfo {
|
||||||
|
color: var(--Ni-button-info-bg-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.messageSuccess {
|
||||||
|
color: var(--Ni-button-success-bg-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.messageWarning {
|
||||||
|
color: var(--Ni-button-warning-bg-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.messageError {
|
||||||
|
color: var(--Ni-button-error-bg-default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > div.niMessageBody {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 入场动画 */
|
||||||
|
.nimessage-enter-active {
|
||||||
|
animation: slideIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 离场动画 */
|
||||||
|
.nimessage-leave-active {
|
||||||
|
transition: opacity 0.3s ease-out;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nimessage-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideIn {
|
||||||
|
from {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -80,7 +80,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<teleport to="#teleports">
|
<teleport to="#teleports">
|
||||||
<Transition name="NiPopup">
|
<Transition name="NiPopup" data-prefix="Ni">
|
||||||
<div
|
<div
|
||||||
v-if="visible"
|
v-if="visible"
|
||||||
ref="NiPopup"
|
ref="NiPopup"
|
||||||
@ -93,7 +93,7 @@ onMounted(() => {
|
|||||||
<div ref="NiPopupContainer" :style="{ '--width': width + 'px' }" class="NiPopupContainer">
|
<div ref="NiPopupContainer" :style="{ '--width': width + 'px' }" class="NiPopupContainer">
|
||||||
<header>
|
<header>
|
||||||
<div class="logo"><NiLogo/></div>
|
<div class="logo"><NiLogo/></div>
|
||||||
<div class="title"><slot name="title">标题</slot></div>
|
<div class="title"><slot name="header">标题</slot></div>
|
||||||
<div class="closeBar"></div>
|
<div class="closeBar"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class="headerLine"></div>
|
<div class="headerLine"></div>
|
||||||
@ -104,7 +104,9 @@ onMounted(() => {
|
|||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="button">
|
<div class="button">
|
||||||
<div><slot name="footer"/></div>
|
<NiSpace>
|
||||||
|
<slot name="footer"/>
|
||||||
|
</NiSpace>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@ -138,7 +140,6 @@ onMounted(() => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
will-change: transform; /* 提前告知浏览器会变化的属性 will-change: transform, opacity; 优化性能*/
|
will-change: transform; /* 提前告知浏览器会变化的属性 will-change: transform, opacity; 优化性能*/
|
||||||
--width: 600px;
|
--width: 600px;
|
||||||
aspect-ratio: 1/0.618;
|
|
||||||
max-width: 80vw;
|
max-width: 80vw;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
width: var(--width);
|
width: var(--width);
|
||||||
@ -149,6 +150,18 @@ onMounted(() => {
|
|||||||
background-color: var(--Ni-content-bg-color);
|
background-color: var(--Ni-content-bg-color);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
@media (min-width: 768px){
|
||||||
|
&{
|
||||||
|
aspect-ratio: 1/0.618;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px){
|
||||||
|
&{
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 弹窗头
|
// 弹窗头
|
||||||
.NiPopupContainer>header{
|
.NiPopupContainer>header{
|
||||||
@ -184,6 +197,7 @@ onMounted(() => {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
color: var(--Ni-theme-color);
|
color: var(--Ni-theme-color);
|
||||||
margin-left: .7rem;
|
margin-left: .7rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
&:before{
|
&:before{
|
||||||
content: ' ';
|
content: ' ';
|
||||||
@ -238,4 +252,5 @@ onMounted(() => {
|
|||||||
animation-direction: reverse;/* 反向播放时 */
|
animation-direction: reverse;/* 反向播放时 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
28
components/Ni/Space.vue
Normal file
28
components/Ni/Space.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
gap: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const gapWith = ref('1');
|
||||||
|
watch(() => props.gap, (value) => {
|
||||||
|
gapWith.value = value
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="NiSpace" data-prefix="Ni" :style="{ '--width': gapWith + 'rem' }" >
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.NiSpace {
|
||||||
|
position: relative;
|
||||||
|
--NiSpace-gap: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--NiSpace-gap) /* 行和列之间的间距 */
|
||||||
|
}
|
||||||
|
</style>
|
50
composables/useNiMessage.ts
Normal file
50
composables/useNiMessage.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// composables/useMessage.ts
|
||||||
|
interface Message {
|
||||||
|
id: number
|
||||||
|
content: string
|
||||||
|
messageType: string
|
||||||
|
close: () => void
|
||||||
|
pause: () => void
|
||||||
|
resume: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = reactive<Message[]>([])
|
||||||
|
|
||||||
|
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'),
|
||||||
|
}
|
||||||
|
}
|
266
nuxt.config.ts
266
nuxt.config.ts
@ -2,146 +2,154 @@
|
|||||||
// 每次热更新都会执行defineNuxtConfig
|
// 每次热更新都会执行defineNuxtConfig
|
||||||
import {exec} from "node:child_process";
|
import {exec} from "node:child_process";
|
||||||
import open, {apps} from "open";
|
import open, {apps} from "open";
|
||||||
import type {AddressInfo} from "node:net";
|
|
||||||
|
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
compatibilityDate: '2024-11-01',
|
vite: {
|
||||||
devtools: { enabled: true },
|
esbuild: {
|
||||||
modules: ['@nuxt/eslint'],
|
target: 'esnext' // 或 'es2020'
|
||||||
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'
|
|
||||||
},
|
},
|
||||||
{
|
optimizeDeps: {
|
||||||
// Huiwen-mincho 汇文明朝体
|
esbuildOptions: {
|
||||||
rel: "stylesheet",
|
target: 'esnext'
|
||||||
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'
|
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:{
|
hooks: {
|
||||||
name: 'indexFade',
|
'listen': (server, listener) => {
|
||||||
mode: 'out-in',
|
const {address, url} = listener
|
||||||
type: 'transition', // 明确指定动画类型
|
startBroswer(address.address, url)
|
||||||
duration: {
|
},
|
||||||
enter: 300,
|
|
||||||
leave: 300
|
|
||||||
},
|
|
||||||
appear: true
|
|
||||||
},
|
},
|
||||||
},
|
runtimeConfig: {
|
||||||
hooks: {
|
redis: {
|
||||||
'listen': (server) => {
|
host: process.env.REDIS_HOST || '127.0.0.1',
|
||||||
startBroswer(server.address())
|
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) {
|
async function startBroswer(address: string, url: string) {
|
||||||
if(!process.env.START){
|
if (!process.env.START) {
|
||||||
if (address && typeof address !== 'string') {
|
const host = address === '::' ? 'localhost' : address
|
||||||
console.log('Hooks: Listen')
|
const port = url.split(':')[2]
|
||||||
const host = address.address === '::' ? 'localhost' : address.address
|
const rrealUrl = `http://${host}:${port}`;
|
||||||
const port = address.port
|
console.info(`Listening on ${rrealUrl}`);
|
||||||
const url = `http://${host}:${port}`;
|
try {
|
||||||
try {
|
await open(rrealUrl, {
|
||||||
await open(url, {
|
app: {
|
||||||
app: {
|
name: apps.chrome,
|
||||||
name: apps.chrome,
|
arguments: [
|
||||||
arguments: [
|
'--remote-debugging-port=9222',
|
||||||
'--remote-debugging-port=9222',
|
'--auto-open-devtools-for-tabs'
|
||||||
'--auto-open-devtools-for-tabs'
|
]
|
||||||
]
|
}
|
||||||
}
|
});
|
||||||
});
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error((e as Error).message)
|
||||||
console.error((e as Error).message)
|
switch (process.platform) {
|
||||||
switch (process.platform) {
|
case 'win32':
|
||||||
case 'win32':
|
console.log('Windows 系统');
|
||||||
console.log('Windows 系统');
|
exec(`start ${url}`)
|
||||||
exec(`start ${url}`)
|
break;
|
||||||
break;
|
case 'darwin':
|
||||||
case 'darwin':
|
console.log('macOS 系统');
|
||||||
console.log('macOS 系统');
|
exec(`open ${url}`)
|
||||||
exec(`open ${url}`)
|
break;
|
||||||
break;
|
case 'linux':
|
||||||
case 'linux':
|
console.log('Linux 系统');
|
||||||
console.log('Linux 系统');
|
exec(`xdg-open ${url}`)
|
||||||
exec(`xdg-open ${url}`)
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
console.log('其他系统:', process.platform);
|
||||||
console.log('其他系统:', process.platform);
|
}
|
||||||
}
|
}
|
||||||
}
|
process.env.START = String(true)
|
||||||
process.env.START = String(true)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
3
package-lock.json
generated
3
package-lock.json
generated
@ -16,6 +16,7 @@
|
|||||||
"mysql2": "^3.14.0",
|
"mysql2": "^3.14.0",
|
||||||
"nuxt": "^3.16.2",
|
"nuxt": "^3.16.2",
|
||||||
"redis": "^4.7.0",
|
"redis": "^4.7.0",
|
||||||
|
"rfdc": "^1.4.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"vueuc": "^0.4.64"
|
"vueuc": "^0.4.64"
|
||||||
@ -14054,7 +14055,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/rfdc": {
|
"node_modules/rfdc": {
|
||||||
"version": "1.4.1",
|
"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==",
|
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
"mysql2": "^3.14.0",
|
"mysql2": "^3.14.0",
|
||||||
"nuxt": "^3.16.2",
|
"nuxt": "^3.16.2",
|
||||||
"redis": "^4.7.0",
|
"redis": "^4.7.0",
|
||||||
|
"rfdc": "^1.4.1",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"vueuc": "^0.4.64"
|
"vueuc": "^0.4.64"
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import rfdc from "rfdc";
|
||||||
|
import type {blogMenu} from "~/drizzle/schema";
|
||||||
|
const clone = rfdc()
|
||||||
|
const niMessage = useNiMessage()
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'home',
|
layout: 'home',
|
||||||
pageTransition: {
|
pageTransition: {
|
||||||
@ -6,39 +11,67 @@ definePageMeta({
|
|||||||
mode: 'out-in',
|
mode: 'out-in',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
// 菜单数据类型
|
||||||
|
type InsertBlogMenu = typeof blogMenu.$inferInsert;
|
||||||
// 菜单数据
|
// 菜单数据
|
||||||
const menuList = ref([]);
|
const originalBlogMenuLis = shallowRef([])
|
||||||
|
const blogMenuPidMap = ref(new Map)
|
||||||
|
const blogMenuList = ref<InsertBlogMenu[]>([]);
|
||||||
|
// blog菜单对象
|
||||||
|
const blogMenuObject = ref<InsertBlogMenu>(null);
|
||||||
// 菜单折叠
|
// 菜单折叠
|
||||||
const menuCollapseStatus = ref(true)
|
const menuCollapseStatus = ref(true)
|
||||||
// blog信息弹窗状态
|
// blog信息弹窗状态
|
||||||
const blogInfoPopupStatus = ref(false)
|
const blogInfoPopupStatus = ref(false)
|
||||||
const blogInfoPopupStatus2 = ref(false)
|
|
||||||
|
|
||||||
const getMenuListFetch = async () => {
|
// 格式化菜单数据
|
||||||
const { data, pending, error } = await useFetch('/api/blog/blogMenu');
|
const formatBlogMenuListToPidMap = (blogMenuList: Array<InsertBlogMenu>) => {
|
||||||
if (error.value) {
|
const list = clone(blogMenuList)
|
||||||
consola.error('数据获取失败:', error.value);
|
const pidObj: Record<string, InsertBlogMenu[]> = {};
|
||||||
|
for(const menuItem of list){
|
||||||
|
if(pidObj[menuItem.pid]){
|
||||||
|
pidObj[menuItem.pid].push(menuItem)
|
||||||
|
}else{
|
||||||
|
pidObj[menuItem.pid] = [menuItem]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
menuList.value = data.value?.filter(i => i.pid === '0')
|
Object.keys(pidObj).forEach(key => {
|
||||||
|
blogMenuPidMap.value.set(key, pidObj[key]);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const sendMessage = async () => {
|
// 获取blog菜单数据
|
||||||
// nMessage.success('??')
|
const getMenuListFetch = async () => {
|
||||||
|
const { data, error } = await useFetch('/api/blog/blogMenu');
|
||||||
|
if (error.value) {
|
||||||
|
throw error.value;
|
||||||
|
}
|
||||||
|
originalBlogMenuLis.value = data.value;
|
||||||
|
formatBlogMenuListToPidMap(data.value);
|
||||||
|
blogMenuList.value = blogMenuPidMap.value.get('0')
|
||||||
}
|
}
|
||||||
const handleCloseBefore = (s) => {
|
// 新增blog事件
|
||||||
consola.info('要关闭啦', s)
|
const handleCreateBlogMenuItemEvent = (pid: string) => {
|
||||||
|
blogMenuObject.value = {
|
||||||
|
pid,
|
||||||
|
name: '',
|
||||||
|
desc: ''
|
||||||
|
}
|
||||||
|
blogInfoPopupStatus.value = true;
|
||||||
|
}
|
||||||
|
// 确认新增
|
||||||
|
const handleCreateBlogMenuItemAck = async () => {
|
||||||
|
consola.info(blogMenuObject.value)
|
||||||
|
const resd= await $fetch('/api/blog/blogMenu',{
|
||||||
|
method: 'POST',
|
||||||
|
body: blogMenuObject.value
|
||||||
|
});
|
||||||
|
consola.info(resd);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
loading.value = true
|
|
||||||
}, 5000)
|
|
||||||
|
|
||||||
// SSR运行
|
// SSR运行
|
||||||
await getMenuListFetch()
|
await getMenuListFetch()
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
consola.log(menuList.value)
|
consola.log(blogMenuList.value)
|
||||||
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -48,16 +81,16 @@ onMounted(() => {
|
|||||||
<div class="blogMenuContainer">
|
<div class="blogMenuContainer">
|
||||||
<header class="contentBox">
|
<header class="contentBox">
|
||||||
<div class="title">博客目录</div>
|
<div class="title">博客目录</div>
|
||||||
<div class="bar add star-blogIconFont awaitShow a11 allCenter"></div>
|
<div class="bar add star-blogIconFont awaitShow a11 allCenter" @click="handleCreateBlogMenuItemEvent('0')"></div>
|
||||||
<div class="bar star-blogIconFont awaitShow a11 allCenter" @click="menuCollapseStatus = !menuCollapseStatus"></div>
|
<div class="bar star-blogIconFont awaitShow a11 allCenter" @click="menuCollapseStatus = !menuCollapseStatus"></div>
|
||||||
</header>
|
</header>
|
||||||
<div class="line"/>
|
<div class="line"/>
|
||||||
<div class="blogMenuContent">
|
<div class="blogMenuContent">
|
||||||
<div class="contentBox blogMenuItem" v-for="(item, index) in menuList" :key="item.id">
|
<div class="contentBox blogMenuItem" v-for="(item, index) in blogMenuList" :key="item.id">
|
||||||
<div class="addIcon star-blogIconFont a11 allCenter"></div>
|
<div class="addIcon star-blogIconFont a11 allCenter"></div>
|
||||||
<div class="text oneLineOverMore">{{item.name}}</div>
|
<div class="text"><div class="oneLineOverMore">{{item.name}}</div></div>
|
||||||
<div class="barBox" :class="item.pid === '0' && 'awaistShows'">
|
<div class="barBox" :class="item.pid === '0' && 'awaistShows'">
|
||||||
<div class="star-blogIconFont bar a11 allCenter"></div>
|
<div class="star-blogIconFont bar a11 allCenter" @click="handleCreateBlogMenuItemEvent(item.pid)"></div>
|
||||||
<div class="star-blogIconFont bar a11 allCenter"></div>
|
<div class="star-blogIconFont bar a11 allCenter"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -72,101 +105,26 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div @click="blogInfoPopupStatus = !blogInfoPopupStatus">点击</div>
|
|
||||||
<div>默认</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton loading type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton strong type="info">info按钮</NiButton>
|
|
||||||
<NiButton loading type="success">success按钮</NiButton>
|
|
||||||
<NiButton type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>grade 虚线边框</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" loading type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" strong type="info">info按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" loading type="success">success按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton grade="dotted" type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>grade 浅色</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton grade="light" type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton grade="light" loading type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton grade="light" strong type="info">info按钮</NiButton>
|
|
||||||
<NiButton grade="light" loading type="success">success按钮</NiButton>
|
|
||||||
<NiButton grade="light" type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton grade="light" type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>grade halfTransparent</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" loading type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" strong type="info">info按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" loading type="success">success按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton grade="halfTransparent" type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>grade Transparent</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" loading type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" strong type="info">info按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" loading type="success">success按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton grade="transparent" type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>disable</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton disabled type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton disabled type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton loading disabled type="info">info按钮</NiButton>
|
|
||||||
<NiButton disabled type="success">success按钮</NiButton>
|
|
||||||
<NiButton disabled type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton disabled type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>半圆角</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>默认按钮</NiButton>
|
|
||||||
<NiButton angle="round" type="tertiary">tertiary按钮</NiButton>
|
|
||||||
<NiButton angle="round" type="primary">primary按钮</NiButton>
|
|
||||||
<NiButton :loading="loading" angle="round" type="info">info按钮</NiButton>
|
|
||||||
<NiButton angle="round" type="success">success按钮</NiButton>
|
|
||||||
<NiButton angle="round" type="warning">warning按钮</NiButton>
|
|
||||||
<NiButton angle="round" type="error">error按钮</NiButton>
|
|
||||||
</div>
|
|
||||||
<div>圆角</div>
|
|
||||||
<div>
|
|
||||||
<NiButton>A</NiButton>
|
|
||||||
<NiButton angle="circle" type="tertiary">B</NiButton>
|
|
||||||
<NiButton angle="circle" type="primary">C</NiButton>
|
|
||||||
<NiButton :loading="loading" angle="circle" type="info">D</NiButton>
|
|
||||||
<NiButton loading angle="circle" type="success">E</NiButton>
|
|
||||||
<NiButton loading angle="circle" type="warning">F</NiButton>
|
|
||||||
<NiButton angle="circle" type="error">G</NiButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<div class="right"></div>
|
<div class="right"></div>
|
||||||
<NiPopup v-model:status="blogInfoPopupStatus" width="900" @handleClose="handleCloseBefore">
|
<NiPopup v-model:status="blogInfoPopupStatus">
|
||||||
<div @click="blogInfoPopupStatus2 = true">关闭</div>
|
<template #header>博客菜单</template>
|
||||||
|
<NiForm :data="blogMenuObject">
|
||||||
|
<NiFormItem label="博客名称" name="name" label-width="6">
|
||||||
|
<NiInput v-model="blogMenuObject.name"></NiInput>
|
||||||
|
</NiFormItem>
|
||||||
|
<NiFormItem label="博客描述" name="name" label-width="6">
|
||||||
|
<NiInput v-model="blogMenuObject.desc"></NiInput>
|
||||||
|
</NiFormItem>
|
||||||
|
<div>{{ blogMenuObject.name }}</div>
|
||||||
|
<div>{{ blogMenuObject.desc }}</div>
|
||||||
|
</NiForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
关闭
|
<NiButton @click="blogInfoPopupStatus = false">取消</NiButton>
|
||||||
|
<NiButton type="primary" @click="handleCreateBlogMenuItemAck">确认</NiButton>
|
||||||
</template>
|
</template>
|
||||||
</NiPopup>
|
</NiPopup>
|
||||||
<NiPopup v-model:status="blogInfoPopupStatus2">
|
|
||||||
<div @click="blogInfoPopupStatus2 = false">
|
|
||||||
</div>
|
|
||||||
</NiPopup>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -274,33 +232,36 @@ onMounted(() => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
& > div{
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
& > div.addIcon{
|
& > div.addIcon{
|
||||||
|
position: relative;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
& > div.text{
|
& > div.text{
|
||||||
height: 100%;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-width: 0;// 关键
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
& > div.barBox{
|
& > div.barBox{
|
||||||
margin-left: .2rem;
|
margin-left: .2rem;
|
||||||
height: 0;
|
height: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
transition: opacity .3s;
|
||||||
|
& > div.bar{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&:hover div.barBox{
|
&:hover div.barBox{
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
& > div.bar{
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ const leaveTime = ref(false)
|
|||||||
// 离开前路由拦截
|
// 离开前路由拦截
|
||||||
onBeforeRouteLeave((to, from, next) => {
|
onBeforeRouteLeave((to, from, next) => {
|
||||||
leaveTime.value = true
|
leaveTime.value = true
|
||||||
consola.error('leave')
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
next(true)
|
next(true)
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
export default defineEventHandler(async event => {
|
import {BlogMenuDB} from "~/server/services/blog/blogMenu";
|
||||||
const requAuth = event.context.auth
|
import consola from "consola";
|
||||||
const body = await readBody(event)
|
|
||||||
if(!requAuth.isTrue) {
|
|
||||||
// 判断为正常登录
|
|
||||||
throw createError({
|
|
||||||
|
|
||||||
})
|
export default defineEventHandler(async event => {
|
||||||
}
|
// 获取登录信息
|
||||||
return 'Hello blog/blogMenu.post'
|
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
|
||||||
})
|
})
|
||||||
|
@ -2,10 +2,11 @@ import consola from "consola";
|
|||||||
|
|
||||||
export default defineEventHandler(async event => {
|
export default defineEventHandler(async event => {
|
||||||
// console.log(await event.context.redis.get('SI HI'))
|
// console.log(await event.context.redis.get('SI HI'))
|
||||||
consola.info('API')
|
// consola.info('API')
|
||||||
consola.info('API TimeOut')
|
// consola.info('API TimeOut')
|
||||||
const result = await event.context.redis.get('SI HI');
|
// const result = await event.context.redis.get('SI HI');
|
||||||
return {
|
// return {
|
||||||
'SI HI': result
|
// 'SI HI': result
|
||||||
}
|
// }
|
||||||
|
return 's'
|
||||||
})
|
})
|
||||||
|
@ -2,6 +2,7 @@ import { createClient } from 'redis';
|
|||||||
import consola from 'consola'
|
import consola from 'consola'
|
||||||
|
|
||||||
export default defineNitroPlugin(async (nitroApp) => {
|
export default defineNitroPlugin(async (nitroApp) => {
|
||||||
|
return
|
||||||
const {redis: config} = useRuntimeConfig()
|
const {redis: config} = useRuntimeConfig()
|
||||||
consola.info('Redis ...');
|
consola.info('Redis ...');
|
||||||
const redisConnect = createClient({
|
const redisConnect = createClient({
|
||||||
@ -17,8 +18,8 @@ export default defineNitroPlugin(async (nitroApp) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
redisConnect.on('error', (err) => {
|
redisConnect.on('error', (err) => {
|
||||||
console.log(err)
|
// console.log(err)
|
||||||
consola.error('Redis error: ', err);
|
// consola.error('Redis error: ', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 连接到 Redis
|
// 连接到 Redis
|
||||||
|
22
server/plugins/snowflake.ts
Normal file
22
server/plugins/snowflake.ts
Normal file
@ -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();
|
||||||
|
}
|
@ -35,6 +35,6 @@ export class BlogMenuDB {
|
|||||||
.from(blogMenu)
|
.from(blogMenu)
|
||||||
.where(
|
.where(
|
||||||
and(eq(blogMenu.createdBy, headerAuth.userId), eq(blogMenu.deleted, 0), headerAuth.isTrue ? undefined : eq(blogMenu.public, 1))
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user