init project

master
fuxiaochun 2023-08-08 12:53:15 +08:00
commit aa8c4990c0
53 changed files with 3064 additions and 0 deletions

26
.gitignore vendored 100755
View File

@ -0,0 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
/dist
# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json

35
README.md 100644
View File

@ -0,0 +1,35 @@
# aigc
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```
### Lint with [ESLint](https://eslint.org/)
```sh
npm run lint
```

14
index.html 100644
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<!-- 临时写死暗黑模式 -->
<html lang="zh-cn" data-theme="dark" class="dark">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>aigc</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

43
package.json 100644
View File

@ -0,0 +1,43 @@
{
"name": "aigc",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"@traptitech/markdown-it-katex": "^3.6.0",
"axios": "^1.4.0",
"echarts": "^5.4.3",
"highlight.js": "^11.8.0",
"lodash-es": "^4.17.21",
"markdown-it": "^13.0.1",
"markdown-it-link-attributes": "^4.0.1",
"pinia": "^2.1.3",
"resize-observer-polyfill": "^1.5.1",
"swiper": "^10.1.0",
"vant": "^4.6.4",
"vue": "^3.3.4",
"vue-router": "^4.2.2"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.2.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue/eslint-config-prettier": "^7.1.0",
"eslint": "^8.39.0",
"eslint-plugin-vue": "^9.11.0",
"prettier": "^2.8.8",
"sass": "^1.63.6",
"sass-loader": "^13.3.2",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.3.9",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-windicss": "^1.9.0",
"windicss": "^3.5.6"
}
}

BIN
public/favicon.ico 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

25
src/App.vue 100644
View File

@ -0,0 +1,25 @@
<script setup>
import { RouterView } from 'vue-router'
import { onMounted } from 'vue'
onMounted(() => {
getRem(750, 16)
window.onload = function () {
getRem(750, 16)
}
window.onresize = function () {
getRem(750, 16)
}
})
const getRem = (pwidth, prem) => {
let html = document.documentElement
let oWidth = window.outerWidth ? window.outerWidth : screen.width
html.style.fontSize = (oWidth / pwidth) * prem + 'px'
}
</script>
<template>
<RouterView />
</template>
<style scoped></style>

View File

@ -0,0 +1,90 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-white);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
height: 100vh;
/* min-height: 100vh; */
color: var(--color-text);
background: var(--color-background);
transition: color 0.5s, background-color 0.5s;
line-height: 1.6;
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* fade-slide */
.fade-slide-leave-active,
.fade-slide-enter-active {
transition: all 0.3s;
}
.fade-slide-enter-from {
transform: translateX(-30px);
opacity: 0;
}
.fade-slide-leave-to {
transform: translateX(30px);
opacity: 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
html.dark {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px
}
.hljs {
color: #abb2bf;
background: #282c34
}
.hljs-keyword,
.hljs-operator,
.hljs-pattern-match {
color: #f92672
}
.hljs-function,
.hljs-pattern-match .hljs-constructor {
color: #61aeee
}
.hljs-function .hljs-params {
color: #a6e22e
}
.hljs-function .hljs-params .hljs-typing {
color: #fd971f
}
.hljs-module-access .hljs-module {
color: #7e57c2
}
.hljs-constructor {
color: #e2b93d
}
.hljs-constructor .hljs-string {
color: #9ccc65
}
.hljs-comment,
.hljs-quote {
color: #b18eb1;
font-style: italic
}
.hljs-doctag,
.hljs-formula {
color: #c678dd
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e06c75
}
.hljs-literal {
color: #56b6c2
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #98c379
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #e6c07b
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #d19a66
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #61aeee
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: 700
}
.hljs-link {
text-decoration: underline
}
}
html {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px;
&::-webkit-scrollbar {
height: 4px;
}
}
.hljs {
color: #383a42;
background: #fafafa
}
.hljs-comment,
.hljs-quote {
color: #a0a1a7;
font-style: italic
}
.hljs-doctag,
.hljs-formula,
.hljs-keyword {
color: #a626a4
}
.hljs-deletion,
.hljs-name,
.hljs-section,
.hljs-selector-tag,
.hljs-subst {
color: #e45649
}
.hljs-literal {
color: #0184bb
}
.hljs-addition,
.hljs-attribute,
.hljs-meta .hljs-string,
.hljs-regexp,
.hljs-string {
color: #50a14f
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
color: #986801
}
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
color: #4078f2
}
.hljs-built_in,
.hljs-class .hljs-title,
.hljs-title.class_ {
color: #c18401
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: 700
}
.hljs-link {
text-decoration: underline
}
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

After

Width:  |  Height:  |  Size: 276 B

View File

@ -0,0 +1,66 @@
@import './base.css';
@import './highlight.scss';
@import './github-markdown.scss';
html,
body {
overflow: visible;
overflow-x: hidden;
}
#app {
height: 100%;
width: 100%;
}
::-webkit-scrollbar {
width: 7px;
height: 8px;
}
::-webkit-scrollbar-track {
background-color: #0000000d;
}
::-webkit-scrollbar-thumb {
border-radius: 2px;
background-color: #9093994d;
box-shadow: inset 0 0 6px #0003;
}
::-webkit-scrollbar-thumb:hover {
background-color: #b6b7b9;
}
/* #app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
} */

View File

View File

@ -0,0 +1,23 @@
<template>
<div class="h-full relative">
<div class="absolute right-15 top-14">
<div class="flex items-center cursor-pointer text-white hover:opacity-70" @click="$emit('onClick')">
<svg-icon class=" text-3xl" name="back"></svg-icon>
<div class="text-lg ml-2">{{ title }}</div>
</div>
</div>
<slot></slot>
</div>
</template>
<script setup>
const props = defineProps({
icon: {
type: String,
default: '',
},
title: {
type: String,
default: '',
},
})
</script>

View File

@ -0,0 +1,93 @@
<template>
<Scrollbar ref="scrollbarRef" class="scroll-container" v-bind="$attrs">
<slot></slot>
</Scrollbar>
</template>
<script>
import { defineComponent, ref, unref, nextTick } from 'vue'
import Scrollbar from '@/components/Scrollbar/index.vue'
import { useScrollTo } from './useScrollTo.js'
export default defineComponent({
name: 'ScrollContainer',
components: { Scrollbar },
setup() {
const scrollbarRef = ref(null)
/**
* Scroll to the specified position
*/
function scrollTo(to, duration = 500) {
const scrollbar = unref(scrollbarRef)
if (!scrollbar) {
return
}
nextTick(() => {
const wrap = unref(scrollbar.wrap)
if (!wrap) {
return
}
const { start } = useScrollTo({
el: wrap,
to,
duration,
})
start()
})
}
function getScrollWrap() {
const scrollbar = unref(scrollbarRef)
if (!scrollbar) {
return null
}
return scrollbar.wrap
}
/**
* Scroll to the bottom
*/
function scrollBottom() {
const scrollbar = unref(scrollbarRef)
if (!scrollbar) {
return
}
nextTick(() => {
const wrap = unref(scrollbar.wrap)
if (!wrap) {
return
}
const scrollHeight = wrap.scrollHeight
const { start } = useScrollTo({
el: wrap,
to: scrollHeight,
})
start()
})
}
return {
scrollbarRef,
scrollTo,
scrollBottom,
getScrollWrap,
}
},
})
</script>
<style lang="scss">
.scroll-container {
width: 100%;
height: 100%;
.scrollbar__wrap {
margin-bottom: 18px !important;
overflow-x: hidden;
}
.scrollbar__view {
box-sizing: border-box;
}
}
</style>

View File

@ -0,0 +1,54 @@
import { isFunction, isUnDef } from '@/utils/is.js'
import { ref, unref } from 'vue'
const easeInOutQuad = (t, b, c, d) => {
t /= d / 2
if (t < 1) {
return (c / 2) * t * t + b
}
t--
return (-c / 2) * (t * (t - 2) - 1) + b
}
const move = (el, amount) => {
el.scrollTop = amount
}
const position = (el) => {
return el.scrollTop
}
export function useScrollTo({ el, to, duration = 500, callback }) {
const isActiveRef = ref(false)
const start = position(el)
const change = to - start
const increment = 20
let currentTime = 0
duration = isUnDef(duration) ? 500 : duration
const animateScroll = function () {
if (!unref(isActiveRef)) {
return
}
currentTime += increment
const val = easeInOutQuad(currentTime, start, change, duration)
move(el, val)
if (currentTime < duration && unref(isActiveRef)) {
requestAnimationFrame(animateScroll)
} else {
if (callback && isFunction(callback)) {
callback()
}
}
}
const run = () => {
isActiveRef.value = true
animateScroll()
}
const stop = () => {
isActiveRef.value = false
}
return { start: run, stop }
}

View File

@ -0,0 +1,109 @@
import {
defineComponent,
h,
computed,
ref,
getCurrentInstance,
onUnmounted,
inject,
} from 'vue';
import { on, off } from '@/utils/domUtils';
import { renderThumbStyle, BAR_MAP } from './util';
export default defineComponent({
name: 'Bar',
props: {
vertical: Boolean,
size: String,
move: Number,
},
setup(props) {
const instance = getCurrentInstance();
const thumb = ref();
const wrap = inject('scroll-bar-wrap', {}) ;
const bar = computed(() => {
return BAR_MAP[props.vertical ? 'vertical' : 'horizontal'];
});
const barStore = ref({});
const cursorDown = ref();
const clickThumbHandler = (e) => {
// prevent click event of right button
if (e.ctrlKey || e.button === 2) {
return;
}
window.getSelection()?.removeAllRanges();
startDrag(e);
barStore.value[bar.value.axis] =
e.currentTarget[bar.value.offset] -
(e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]);
};
const clickTrackHandler = (e) => {
const offset = Math.abs(
e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client],
);
const thumbHalf = thumb.value[bar.value.offset] / 2;
const thumbPositionPercentage =
((offset - thumbHalf) * 100) / instance?.vnode.el?.[bar.value.offset];
wrap.value[bar.value.scroll] =
(thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
};
const startDrag = (e) => {
e.stopImmediatePropagation();
cursorDown.value = true;
on(document, 'mousemove', mouseMoveDocumentHandler);
on(document, 'mouseup', mouseUpDocumentHandler);
document.onselectstart = () => false;
};
const mouseMoveDocumentHandler = (e) => {
if (cursorDown.value === false) return;
const prevPage = barStore.value[bar.value.axis];
if (!prevPage) return;
const offset =
(instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) *
-1;
const thumbClickPosition = thumb.value[bar.value.offset] - prevPage;
const thumbPositionPercentage =
((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset];
wrap.value[bar.value.scroll] =
(thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100;
};
function mouseUpDocumentHandler() {
cursorDown.value = false;
barStore.value[bar.value.axis] = 0;
off(document, 'mousemove', mouseMoveDocumentHandler);
document.onselectstart = null;
}
onUnmounted(() => {
off(document, 'mouseup', mouseUpDocumentHandler);
});
return () =>
h(
'div',
{
class: ['scrollbar__bar', 'is-' + bar.value.key],
onMousedown: clickTrackHandler,
},
h('div', {
ref: thumb,
class: 'scrollbar__thumb',
onMousedown: clickThumbHandler,
style: renderThumbStyle({
size: props.size,
move: props.move,
bar: bar.value,
}),
}),
);
},
});

View File

@ -0,0 +1,215 @@
<template>
<div class="scrollbar">
<div
ref="wrap"
:class="[
wrapClass,
'scrollbar__wrap',
native ? '' : 'scrollbar__wrap--hidden-default',
]"
:style="style"
@scroll="handleScroll"
>
<component
:is="tag"
ref="resize"
:class="['scrollbar__view', viewClass]"
:style="viewStyle"
>
<slot></slot>
</component>
</div>
<template v-if="!native">
<bar :move="moveX" :size="sizeWidth" />
<bar vertical :move="moveY" :size="sizeHeight" />
</template>
</div>
</template>
<script>
import { addResizeListener, removeResizeListener } from '@/utils/event'
import Bar from './bar';
import {
defineComponent,
ref,
onMounted,
onBeforeUnmount,
nextTick,
provide,
computed,
unref,
} from 'vue'
export default defineComponent({
name: 'Scrollbar',
components: { Bar },
props: {
native: {
type: Boolean,
default: false,
},
wrapStyle: {
type: [String, Array],
default: '',
},
wrapClass: {
type: [String, Array],
default: '',
},
viewClass: {
type: [String, Array],
default: '',
},
viewStyle: {
type: [String, Array],
default: '',
},
noresize: Boolean, // container
tag: {
type: String,
default: 'div',
},
},
setup(props) {
const sizeWidth = ref('0')
const sizeHeight = ref('0')
const moveX = ref(0)
const moveY = ref(0)
const wrap = ref()
const resize = ref()
provide('scroll-bar-wrap', wrap);
const style = computed(() => {
if (Array.isArray(props.wrapStyle)) {
return toObject(props.wrapStyle)
}
return props.wrapStyle
})
const handleScroll = () => {
if (!props.native) {
moveY.value = (unref(wrap).scrollTop * 100) / unref(wrap).clientHeight
moveX.value = (unref(wrap).scrollLeft * 100) / unref(wrap).clientWidth
}
}
const update = () => {
if (!unref(wrap)) return
const heightPercentage =
(unref(wrap).clientHeight * 100) / unref(wrap).scrollHeight
const widthPercentage =
(unref(wrap).clientWidth * 100) / unref(wrap).scrollWidth
sizeHeight.value = heightPercentage < 100 ? heightPercentage + '%' : ''
sizeWidth.value = widthPercentage < 100 ? widthPercentage + '%' : ''
}
onMounted(() => {
if (props.native) return
nextTick(update)
if (!props.noresize) {
addResizeListener(unref(resize), update)
addResizeListener(unref(wrap), update)
addEventListener('resize', update)
}
})
onBeforeUnmount(() => {
if (props.native) return
if (!props.noresize) {
removeResizeListener(unref(resize), update)
removeResizeListener(unref(wrap), update)
removeEventListener('resize', update)
}
})
return {
moveX,
moveY,
sizeWidth,
sizeHeight,
style,
wrap,
resize,
update,
handleScroll,
}
},
})
</script>
<style lang="scss">
.scrollbar {
position: relative;
height: 100%;
overflow: hidden;
&__wrap {
height: 100%;
overflow: auto;
position: absolute;
width: 100%;
&--hidden-default {
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
opacity: 0%;
}
}
}
&__thumb {
position: relative;
display: block;
width: 0;
height: 0;
cursor: pointer;
background-color: rgb(144 147 153 / 30%);
border-radius: inherit;
transition: 0.3s background-color;
&:hover {
background-color: rgb(144 147 153 / 50%);
}
}
&__bar {
position: absolute;
right: 2px;
bottom: 2px;
z-index: 1;
border-radius: 4px;
opacity: 0%;
transition: opacity 80ms ease;
&.is-vertical {
top: 2px;
width: 6px;
& > div {
width: 100%;
}
}
&.is-horizontal {
left: 2px;
height: 6px;
& > div {
height: 100%;
}
}
}
}
.scrollbar:active > .scrollbar__bar,
.scrollbar:focus > .scrollbar__bar,
.scrollbar:hover > .scrollbar__bar {
opacity: 100%;
transition: opacity 340ms ease-out;
}
</style>

View File

@ -0,0 +1,50 @@
export const BAR_MAP = {
vertical: {
offset: 'offsetHeight',
scroll: 'scrollTop',
scrollSize: 'scrollHeight',
size: 'height',
key: 'vertical',
axis: 'Y',
client: 'clientY',
direction: 'top',
},
horizontal: {
offset: 'offsetWidth',
scroll: 'scrollLeft',
scrollSize: 'scrollWidth',
size: 'width',
key: 'horizontal',
axis: 'X',
client: 'clientX',
direction: 'left',
},
};
// @ts-ignore
export function renderThumbStyle({ move, size, bar }) {
const style = {};
const translate = `translate${bar.axis}(${move}%)`;
style[bar.size] = size;
style.transform = translate;
style.msTransform = translate;
style.webkitTransform = translate;
return style;
}
function extend(to, _from) {
return Object.assign(to, _from);
}
export function toObject(arr) {
const res = {};
for (let i = 0; i < arr.length; i++) {
if (arr[i]) {
extend(res, arr[i]);
}
}
return res;
}

View File

@ -0,0 +1,57 @@
<template>
<svg
:class="[prefixCls, $attrs.class, spin && 'svg-icon-spin']"
aria-hidden="true"
>
<use :xlink:href="symbolId" />
</svg>
</template>
<script>
import { defineComponent, computed } from 'vue'
export default defineComponent({
name: 'SvgIcon',
props: {
prefix: {
type: String,
default: 'icon',
},
name: {
type: String,
required: true,
},
spin: {
type: Boolean,
default: false,
},
},
setup(props) {
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
const prefixCls = computed(() => `svg-icon`)
return { symbolId, prefixCls }
},
})
</script>
<style lang="scss" scoped>
.svg-icon {
width: 1em;
height: 1em;
display: inline-block;
overflow: hidden;
fill: currentcolor;
vertical-align: -0.15em;
}
.svg-icon-spin {
animation: loadingCircle 1s infinite linear;
}
@keyframes loadingCircle {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@ -0,0 +1,3 @@
const hostAPI = 'http://test-admin.haituaigc.com';
export default hostAPI;

View File

@ -0,0 +1,6 @@
import SvgIcon from '@/components/SvgIcon/index.vue'// svg component
export function registerSvgIcon(app) {
app.component(SvgIcon.name, SvgIcon);
}

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1690348382971" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2433" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M761.6 489.6l-432-435.2c-9.6-9.6-25.6-9.6-35.2 0-9.6 9.6-9.6 25.6 0 35.2l416 416-416 425.6c-9.6 9.6-9.6 25.6 0 35.2s25.6 9.6 35.2 0l432-441.6C771.2 515.2 771.2 499.2 761.6 489.6z" p-id="2434"></path></svg>

After

Width:  |  Height:  |  Size: 538 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690529853834" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2284" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M675.328 117.717333A425.429333 425.429333 0 0 0 512 85.333333C276.352 85.333333 85.333333 276.352 85.333333 512s191.018667 426.666667 426.666667 426.666667 426.666667-191.018667 426.666667-426.666667c0-56.746667-11.093333-112-32.384-163.328a21.333333 21.333333 0 0 0-39.402667 16.341333A382.762667 382.762667 0 0 1 896 512c0 212.074667-171.925333 384-384 384S128 724.074667 128 512 299.925333 128 512 128c51.114667 0 100.8 9.984 146.986667 29.12a21.333333 21.333333 0 0 0 16.341333-39.402667z m-324.693333 373.013334l174.464-174.485334a21.141333 21.141333 0 0 0-0.192-29.973333 21.141333 21.141333 0 0 0-29.973334-0.192l-208.256 208.256a20.821333 20.821333 0 0 0-6.122666 14.976c0.042667 5.418667 2.133333 10.837333 6.314666 14.997333l211.178667 211.2a21.141333 21.141333 0 0 0 29.973333 0.213334 21.141333 21.141333 0 0 0-0.213333-29.973334l-172.629333-172.629333 374.997333 2.602667a20.693333 20.693333 0 0 0 21.034667-21.034667 21.482667 21.482667 0 0 0-21.333334-21.333333l-379.242666-2.624z"
fill="currentColor" p-id="2285"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690269116675" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2291" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M507.168 473.232L716.48 263.936a16 16 0 0 1 22.624 0l11.312 11.312a16 16 0 0 1 0 22.624L541.12 507.168 750.4 716.48a16 16 0 0 1 0 22.624l-11.312 11.312a16 16 0 0 1-22.624 0L507.168 541.12 297.872 750.4a16 16 0 0 1-22.624 0l-11.312-11.312a16 16 0 0 1 0-22.624l209.296-209.312-209.296-209.296a16 16 0 0 1 0-22.624l11.312-11.312a16 16 0 0 1 22.624 0l209.296 209.296z"
fill="currentColor" p-id="2292"></path>
</svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689839410470" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8379" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M518.3 459c-3.2-4.1-9.4-4.1-12.6 0l-112 141.7c-4.1 5.2-0.4 12.9 6.3 12.9h73.9V856c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V613.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 459z" p-id="8380"></path><path d="M811.4 366.7C765.6 245.9 648.9 160 512.2 160S258.8 245.8 213 366.6C127.3 389.1 64 467.2 64 560c0 110.5 89.5 200 199.9 200H304c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8h-40.1c-33.7 0-65.4-13.4-89-37.7-23.5-24.2-36-56.8-34.9-90.6 0.9-26.4 9.9-51.2 26.2-72.1 16.7-21.3 40.1-36.8 66.1-43.7l37.9-9.9 13.9-36.6c8.6-22.8 20.6-44.1 35.7-63.4 14.9-19.2 32.6-35.9 52.4-49.9 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.2c19.9 14 37.5 30.8 52.4 49.9 15.1 19.3 27.1 40.7 35.7 63.4l13.8 36.5 37.8 10C846.1 454.5 884 503.8 884 560c0 33.1-12.9 64.3-36.3 87.7-23.4 23.4-54.5 36.3-87.6 36.3H720c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h40.1C870.5 760 960 670.5 960 560c0-92.7-63.1-170.7-148.6-193.3z" p-id="8381"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1689839520218" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="9374" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M768 384c-19.2 0-32 12.8-32 32l0 377.6c0 25.6-19.2 38.4-38.4 38.4L326.4 832c-25.6 0-38.4-19.2-38.4-38.4L288 416C288 396.8 275.2 384 256 384S224 396.8 224 416l0 377.6c0 57.6 44.8 102.4 102.4 102.4l364.8 0c57.6 0 102.4-44.8 102.4-102.4L793.6 416C800 396.8 787.2 384 768 384z"
fill="currentColor" p-id="9375"></path>
<path
d="M460.8 736l0-320C460.8 396.8 448 384 435.2 384S396.8 396.8 396.8 416l0 320c0 19.2 12.8 32 32 32S460.8 755.2 460.8 736z"
fill="currentColor" p-id="9376"></path>
<path
d="M627.2 736l0-320C627.2 396.8 608 384 588.8 384S563.2 396.8 563.2 416l0 320C563.2 755.2 576 768 588.8 768S627.2 755.2 627.2 736z"
fill="currentColor" p-id="9377"></path>
<path
d="M832 256l-160 0L672 211.2C672 166.4 633.6 128 588.8 128L435.2 128C390.4 128 352 166.4 352 211.2L352 256 192 256C172.8 256 160 268.8 160 288S172.8 320 192 320l640 0c19.2 0 32-12.8 32-32S851.2 256 832 256zM416 211.2C416 198.4 422.4 192 435.2 192l153.6 0c12.8 0 19.2 6.4 19.2 19.2L608 256l-192 0L416 211.2z"
fill="currentColor" p-id="9378"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1689839944498" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="13991" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M957.44 936.96l-199.68-204.8h81.92c30.72 0 51.2-20.48 51.2-51.2s-20.48-51.2-51.2-51.2h-204.8c-5.12 0-15.36 0-20.48 5.12-5.12 0-10.24 5.12-15.36 10.24-5.12 5.12-10.24 10.24-10.24 15.36 0 5.12-5.12 10.24-5.12 20.48v204.8c0 30.72 20.48 51.2 51.2 51.2s51.2-20.48 51.2-51.2v-81.92l204.8 199.68c20.48 20.48 51.2 20.48 71.68 0 15.36-15.36 15.36-46.08-5.12-66.56z"
fill="currentColor" p-id="13992"></path>
<path
d="M445.44 1024H194.56C112.64 1024 51.2 957.44 51.2 880.64V143.36C51.2 66.56 112.64 0 194.56 0h476.16L972.8 276.48v215.04c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2V322.56L629.76 102.4H194.56c-25.6 0-40.96 20.48-40.96 40.96v737.28c0 20.48 15.36 40.96 40.96 40.96h250.88c30.72 0 51.2 20.48 51.2 51.2s-25.6 51.2-51.2 51.2z"
fill="currentColor" p-id="13993"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690270189218" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="3276" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M512 977.454545C255.301818 977.454545 46.545455 768.651636 46.545455 512S255.301818 46.545455 512 46.545455s465.454545 208.802909 465.454545 465.454545-208.802909 465.454545-465.454545 465.454545z m0-861.090909c-218.158545 0-395.636364 177.477818-395.636364 395.636364 0 218.158545 177.477818 395.636364 395.636364 395.636364s395.636364-177.477818 395.636364-395.636364c0-218.158545-177.477818-395.636364-395.636364-395.636364zM414.999273 673.000727V351.045818a34.909091 34.909091 0 0 0-69.818182 0v321.954909a34.909091 34.909091 0 0 0 69.818182 0z m263.773091 0V351.045818a34.909091 34.909091 0 0 0-69.818182 0v321.954909a34.909091 34.909091 0 0 0 69.818182 0z"
fill="currentColor" p-id="3277"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689668597068" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2301" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M960 416V192l-73.056 73.056a447.712 447.712 0 0 0-373.6-201.088C265.92 63.968 65.312 264.544 65.312 512S265.92 960.032 513.344 960.032a448.064 448.064 0 0 0 415.232-279.488 38.368 38.368 0 1 0-71.136-28.896 371.36 371.36 0 0 1-344.096 231.584C308.32 883.232 142.112 717.024 142.112 512S308.32 140.768 513.344 140.768c132.448 0 251.936 70.08 318.016 179.84L736 416h224z" p-id="2302"></path></svg>

After

Width:  |  Height:  |  Size: 728 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690270224102" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="7524" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M553.38 726.62L372.69 545.94c-18.72-18.72-18.72-49.16 0-67.88l180.69-180.69c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L429.25 512l169.38 169.38c12.5 12.5 12.5 32.75 0 45.25-6.25 6.25-14.44 9.38-22.62 9.38s-16.39-3.13-22.63-9.39zM417.62 523.31h0.31-0.31z"
fill="currentColor" p-id="7525"></path>
<path
d="M512 128c211.74 0 384 172.26 384 384S723.74 896 512 896 128 723.74 128 512s172.26-384 384-384m0-64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.58 448-448S759.42 64 512 64z"
fill="currentColor" p-id="7526"></path>
</svg>

After

Width:  |  Height:  |  Size: 898 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690272110347" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="8690" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M950.186667 164.693333a42.666667 42.666667 0 0 0-42.666667-14.293333l-832 192a42.666667 42.666667 0 0 0-21.333333 69.76l134.186666 153.386667-58.026666 213.333333a42.666667 42.666667 0 0 0 66.56 45.653333l405.333333-298.666666a42.666667 42.666667 0 1 0-50.773333-68.693334L244.053333 682.666667l31.786667-116.266667a42.666667 42.666667 0 0 0-9.173333-39.466667l-102.186667-117.333333 680.106667-157.013333L621.226667 768l-85.333334-56.96a42.666667 42.666667 0 1 0-47.36 70.826667l128 85.333333A41.386667 41.386667 0 0 0 640 874.666667a47.786667 47.786667 0 0 0 12.16-1.706667 42.666667 42.666667 0 0 0 26.88-24.106667l277.333333-640a42.666667 42.666667 0 0 0-6.186666-44.16z"
fill="currentColor" p-id="8691"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1689837870587" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2303" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M686.480358 119.560026c0-32.377408 26.325575-58.644655 58.644655-58.644655 32.386618 0 58.645678 26.420743 58.645678 58.644655l0 781.930779c0 32.376385-26.325575 58.644655-58.645678 58.644655-32.385595 0-58.644655-26.419719-58.644655-58.644655L686.480358 119.560026zM217.321072 119.560026c0-32.377408 26.325575-58.644655 58.645678-58.644655 32.385595 0 58.644655 26.420743 58.644655 58.644655l0 781.930779c0 32.376385-26.325575 58.644655-58.644655 58.644655-32.385595 0-58.645678-26.419719-58.645678-58.644655L217.321072 119.560026z"
fill="#currentColor" p-id="2304"></path>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="8.3199462890625" height="8.239997863769531" viewBox="0 0 8.3199462890625 8.239997863769531"
fill="none">
<path id="路径 1" fill-rule="evenodd" style="fill:currentColor" opacity="1"
d="M7.99999 0L0.32 0C0.14 0 0 0.14 0 0.32L0 2.01C0 2.18 0.14 2.32 0.32 2.32C0.499999 2.32 0.639999 2.18 0.639999 2.01L0.639999 0.63L3.84 0.63L3.84 7.6L2.45 7.6C2.28 7.6 2.13 7.74 2.13 7.92C2.13 8.09 2.28 8.24 2.45 8.24L5.85999 8.24C6.03999 8.24 6.17999 8.09 6.17999 7.92C6.17999 7.74 6.03999 7.6 5.85999 7.6L4.47999 7.6L4.47999 0.63L7.67999 0.63L7.67999 2.01C7.67999 2.18 7.81999 2.32 7.99999 2.32C8.16999 2.32 8.31999 2.18 8.31999 2.01L8.31999 0.32C8.31999 0.14 8.16999 0 7.99999 0Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 782 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1691136491391" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="1469" xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="200">
<path
d="M264.789333 627.626667a42.965333 42.965333 0 0 1-60.288 0 41.856 41.856 0 0 1 0-59.648l247.210667-244.608a85.930667 85.930667 0 0 1 120.576 0l247.210667 244.608a41.856 41.856 0 0 1 0 59.648 42.965333 42.965333 0 0 1-60.288 0L512 383.018667 264.789333 627.626667z"
fill="currentColor" p-id="1470"></path>
<path
d="M512 1024c282.752 0 512-229.248 512-512S794.752 0 512 0 0 229.248 0 512s229.248 512 512 512z m0-85.333333C276.352 938.666667 85.333333 747.648 85.333333 512S276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667z"
fill="currentColor" p-id="1471"></path>
</svg>

After

Width:  |  Height:  |  Size: 998 B

View File

@ -0,0 +1,6 @@
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="37px" height="37px">
<image x="0px" y="0px" width="37px" height="37px" xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAlCAQAAABvl+iIAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBxMJLhVeEnOzAAABu0lEQVRIx+2UT0gUYRiHn9ndEBaKNCMhiQ5Wh+iSFIhdKugUCR091KEQokM3QW/RpU7huWNBlzpEYBAZgUGgdYmkg4iJGdEfwkJMN306zOzurDOb2nSK/c1hvvm97/vwve98fMgGnrNuXz9rfUyXw+qkp7Oh9nnfqsbt/jvUHu+Z1HOPbg7V6i1/WU8PPLQxVIv9zteUPvKUA2twNzzwZ1TOi35P7CIQ8WXCv2pLPVSvc6kNHReD1NiiA+bXonp9U3c2JZ86XTf6wcEq6owjZtNrL1nE6xkxZd0p8Jg2zgOwRD+hhqL3Ex4S10H6otVN3gFwmf0AzHE7nFSo4coPCHf602LiqEyo+qryfSKqPVce+wV11vZKQt4ptS/lIB5WtTPmDKkjIjkARoF53lcaWeELMEZSbwGYiTkvgEkgQu0CttSUNAE7U1A7AGiOOa3A1irqn6iBaqAaqP8M9Rko1fjLwMeU/PBOm405X4EfAAUAuoFtdBEQALJKM3CSYhQva4U2AHqYIQ9AiSNAB00sBQJ8Sr3mNqMOpsIGFzIPKoAcV5imPTPqGdcKdLI3Mwh2c6zAXb6xmhmVY/Q3a2Hie2ZcC9EAAAAASUVORK5CYII=" />
</svg>

After

Width:  |  Height:  |  Size: 1003 B

View File

@ -0,0 +1,6 @@
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="41px" height="40px">
<image x="0px" y="0px" width="41px" height="40px" xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAAoCAQAAADJNRvYAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBxMJLhbHGyIJAAADZklEQVRIx62WW4hVZRTHf8cz5TQXbQzyFNGNjDG6gJmTJCkpFfUgptA0RUm9VIQ+SAXRQyDVQwRRPWQwMF0gLYsuM5pgoKQGBmlRgeIUMSmZmuOcGae5nV8P851z9jln784uXPthr/2ttf7fWutba+0PSfVc6JNelU43HWDWfeqArecOcpbTtDiN9gzSUIF8eKegdJDDCMBv5wbyPO6imxYA3mY1zXUt6mRmvacsUkHVEV+udzxZL0oQNtmn6lYf8bQ65XrfUnW/VybYzLYJv3HMtTHCKzysHvZ2EQdVbRFvdrd6wo4Ym7sdcgg3qvqGN1QUzTpH1L02hb2HKopoi6ovmIvYXO2Lqr6H+JTjqu70Obt8wvdD7rpL6q0BclFp5ZWg84nr7HKDveF7Y7HUL3WTvxulXpdGPKiFxFvc7FjE4rQ9XlvdPQv8VZ30PluqchQHidjock+qw65wRlxDZj2jFmI6OQkScVSd9JL4hlzLLCDDS6k6qmjTCGR5LL7Ut6vPqmM2pPbyZ/Vxxx2Im0SXq3nxe/X6lJA3qqPiweiUKge+DNgH9ACdKcO+DfgI2AUsqQ38Q/V+cY56pnx+/+rlXnWh2K7+WB14mzoU+H71jhSQ89Szgf+pLC0G/jCwLfCbK8JIpmXAl4HfFklX2KVXfTRyUAMpvNyhrgj8IvWHaOCNTjjh+SXlo+ryOpCXqccj3/3qdeXAu2hgO+OlkD4FVtYJ+8FIqggp6CwH/rm6OrJjzgl/qePl11oxWm5yygPFwJ92yoLtFXk6pr5mJhHyGXXcORU2efVVM0gYTv0+5Hzneo0r/S78Z+YmQGbCv+iQnc435zxXeSDYNCO+G5l6oxF+d+nAar18J6L3d4TfaXZa4XVrqS/SQXG57Imx2RLtng4/9kQQDPqV96aoy1v9wpOlmb7DO6fXM5bLoJkcjUxynMGqgmnlKK1AB/urJC3kmMkEfzBUXGqIiEfoTzmByjTMkeqldHeifLhgpdqyIVGygIWBK3ABMwHYwJFgkeEQuxIsjX+WWp8eiLdN8nINcJBvyZZ2nvat6Hc7S1jDB/8l8DzQzZuJabmHvnCNraFoEcFiNtGETHExbZziz4TjK9BGjjzHyJJhkufZmgT5F21pzjSGmjlbZCu9+Ox/Au5hovzxDyCmVrQ+22sRAAAAAElFTkSuQmCC" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,6 @@
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="37px" height="36px">
<image x="0px" y="0px" width="37px" height="36px" xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAkCAQAAACkyzstAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfnBxMJLhO3cdaGAAABuUlEQVRIx82TPUscURSG31kWUVjWmLiNUYkoYpNAgmgrQiABy0BAhPwA6zSmSJNCFPsQ8AdIqmAqGwXBVbAQLNUEVIKEpBD8WnXnSeFxd2ZnZxxnDPje4tz73nOeO/cMVyjGWOT1zVlxQCvAJc/To5a50gXP0qGWqKoUDYvCPGYTvy55mwTVzAH1NHR71KqV7rIHlNiw9TFPboeat8I1WvkJlOnivXl/6YiLyvHdipZxEC4A/YgZ838zEAeVZ8cK5hGiwBkAIwgxXunZy5tQObYtdd2ch4Z6ZevpCmw4ClVgy9L+0BKCEnMV2GA4qmgpB57GBlHiawWWD0O9AaDIA49XDyU+AjBFY3ivRlioceqjxGdm4z+caFRgZHRnukNUNmFdn17IleTqm0rpUGP6YLNH16ikFzy0eKpy2l5h0a1a9/8PftJTlZXViibTokbVJUlqS4byXnDX4n6yC97Ptv8nVLkmXunEYsnnngf2fSgn8jD/rhPYl8M7Tdi8Q02SpCP98qG65Ujar54vqUUFSZKrH/Z4vmTVqd6a78gFHElqD/nmHpt1Z9SQptUeNWa1oAbv+06ojBb/AcSXABJRGZ94AAAAAElFTkSuQmCC" />
</svg>

After

Width:  |  Height:  |  Size: 999 B

View File

@ -0,0 +1,15 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1690349868458" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="6238" xmlns:xlink="http://www.w3.org/1999/xlink"
width="128" height="128">
<path
d="M873.411765 150.588235v722.82353H150.588235V150.588235h722.82353m30.117647-60.235294H120.470588c-16.564706 0-30.117647 13.552941-30.117647 30.117647v783.058824c0 16.564706 13.552941 30.117647 30.117647 30.117647h783.058824c16.564706 0 30.117647-13.552941 30.117647-30.117647V120.470588c0-16.564706-13.552941-30.117647-30.117647-30.117647z"
fill="currentColor" p-id="6239"></path>
<path
d="M301.176471 271.058824c16.564706 0 30.117647 13.552941 30.117647 30.117647s-13.552941 30.117647-30.117647 30.117647-30.117647-13.552941-30.117647-30.117647 13.552941-30.117647 30.117647-30.117647m0-60.235295c-49.995294 0-90.352941 40.357647-90.352942 90.352942s40.357647 90.352941 90.352942 90.352941 90.352941-40.357647 90.352941-90.352941-40.357647-90.352941-90.352941-90.352942zM240.941176 602.352941a30.147765 30.147765 0 0 1-19.275294-53.308235l161.430589-134.625882c22.287059-18.672941 54.814118-18.672941 77.101176 0L602.352941 533.082353l161.430588-134.625882a30.117647 30.117647 0 1 1 38.550589 46.381176l-161.430589 134.625882c-22.287059 18.672941-54.814118 18.672941-77.101176 0L421.647059 460.8l-161.430588 134.625882c-5.722353 4.517647-12.348235 6.927059-19.275295 6.927059zM240.941176 813.176471c-16.564706 0-30.117647-13.552941-30.117647-30.117647v-120.470589c0-16.564706 13.552941-30.117647 30.117647-30.117647s30.117647 13.552941 30.117648 30.117647v120.470589c0 16.564706-13.552941 30.117647-30.117648 30.117647z"
fill="currentColor" p-id="6240"></path>
<path
d="M421.647059 813.176471c-16.564706 0-30.117647-13.552941-30.117647-30.117647v-210.82353c0-16.564706 13.552941-30.117647 30.117647-30.117647s30.117647 13.552941 30.117647 30.117647v210.82353c0 16.564706-13.552941 30.117647-30.117647 30.117647zM602.352941 813.176471c-16.564706 0-30.117647-13.552941-30.117647-30.117647v-120.470589c0-16.564706 13.552941-30.117647 30.117647-30.117647s30.117647 13.552941 30.117647 30.117647v120.470589c0 16.564706-13.552941 30.117647-30.117647 30.117647zM783.058824 813.176471c-16.564706 0-30.117647-13.552941-30.117648-30.117647v-210.82353c0-16.564706 13.552941-30.117647 30.117648-30.117647s30.117647 13.552941 30.117647 30.117647v210.82353c0 16.564706-13.552941 30.117647-30.117647 30.117647zM752.941176 361.411765h-150.588235c-16.564706 0-30.117647-13.552941-30.117647-30.117647s13.552941-30.117647 30.117647-30.117647h150.588235c16.564706 0 30.117647 13.552941 30.117648 30.117647s-13.552941 30.117647-30.117648 30.117647zM512 361.411765c-1.807059 0-3.915294-0.301176-6.023529-0.602353a19.154824 19.154824 0 0 1-5.421177-1.807059 22.799059 22.799059 0 0 1-5.421176-2.710588l-4.517647-3.614118c-5.421176-5.722353-8.734118-13.552941-8.734118-21.383529 0-7.830588 3.312941-15.661176 8.734118-21.38353 1.505882-1.204706 3.011765-2.710588 4.517647-3.614117 1.807059-1.204706 3.614118-2.108235 5.421176-2.710589 1.807059-0.903529 3.614118-1.505882 5.421177-1.807058 9.938824-2.108235 20.178824 1.204706 27.407058 8.131764 5.421176 5.722353 8.734118 13.552941 8.734118 21.38353 0 7.830588-3.312941 15.661176-8.734118 21.383529-5.722353 5.421176-13.552941 8.734118-21.383529 8.734118zM752.941176 271.058824h-60.235294c-16.564706 0-30.117647-13.552941-30.117647-30.117648s13.552941-30.117647 30.117647-30.117647h60.235294c16.564706 0 30.117647 13.552941 30.117648 30.117647s-13.552941 30.117647-30.117648 30.117648z"
fill="currentColor" p-id="6241"></path>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

22
src/icons/svgo.yml 100644
View File

@ -0,0 +1,22 @@
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'

34
src/io/cache.js 100755
View File

@ -0,0 +1,34 @@
/**
* [本地缓存]
* @Author: Fu Xiaochun
* @Email: f2e.xiaochun@gmail.com
*/
function factory(engine){
return {
set: (key, data)=>{
if(!key){ return; }
engine.setItem(key, JSON.stringify(data));
},
get: (key)=>{
if(!key){ return; }
let data = engine.getItem(key);
try {
return JSON.parse(data);
} catch (error) {
return data;
}
},
remove: (key)=>{
if(!key){ return; }
engine.removeItem(key);
},
clear: ()=>{
engine.clear();
}
}
}
export const localCache = factory(localStorage);
export const sessionCache = factory(sessionStorage);

56
src/io/http.js 100755
View File

@ -0,0 +1,56 @@
/**
* [axios封装]
* @Author: Fu Xiaochun
* @Email: f2e.xiaochun@gmail.com
*/
import axios from 'axios';
const http = (url = '', data = {}, type = 'POST', otherConfig = {}) => {
let config = Object.assign({ isLoading: true, timeout: 10000 }, otherConfig);
let promise;
type = type.toUpperCase();
return new Promise((resolve, reject) => {
if (type === 'GET') {
promise = axios({
method: type,
url,
params: data,
timeout: config.timeout
});
} else if (['POST', 'DELETE', 'PUT', 'PATCH'].includes(type)) {
promise = axios({
method: type,
url,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Accept': 'application/json; charset=UTF-8',
'isLoading': config.isLoading,
},
data: data,
timeout: config.timeout
});
} else {
promise = Promise.reject('请求方法入参错误:', type);
}
promise.then((response) => {
if (response && response.status >= 200 && response.status < 300 && response.data.status == 0) {
resolve(response.data);
} else {
if(response && response.data && response.data.status == 401){
return false;
}else if (response && response.data) {
reject({ ...response.data, message: response.data.message ? response.data.message : response.data.msg });
} else {
reject('当前系统繁忙,请稍后再试');
}
}
}).catch((error) => {
reject(error);
});
});
};
export default http;

View File

@ -0,0 +1,96 @@
/**
* [axios配置]
* @Author: Fu Xiaochun
* @Email: f2e.xiaochun@gmail.com
*/
import axios from 'axios';
import { localCache } from './cache';
import router from "@/router";
import hostAPI from '@/config/host.config'
import { showToast } from 'vant';
export default function () {
let _token = '';
let requestCount = 0;//请求数量
// axios.defaults.baseURL = '//' + window.location.host;
axios.defaults.baseURL = hostAPI;
// 请求超时时间为10秒
axios.defaults.timeout = 10000;
// 请求发送拦截并在头部加入token
axios.interceptors.request.use(
function (config) {
let nextToken = localCache.get('auth') && localCache.get('auth').token;
let toeknType = localCache.get('auth') && localCache.get('auth').token_type;
if (config.url.indexOf('/auth/login') > -1) {
// 如果为登录接口,重置登录信息
_token = '';
} else if (_token == '') {
// 第一次登录直接从缓存后去token
_token = nextToken;
} else {
// 前后两次调用token不同退出登录防止串token
_token = _token != nextToken ? '' : nextToken;
}
if (_token) {
config.headers['Authorization'] = `${toeknType} ${_token}`; // 存在将token写入请求头
}
// if (config.headers.isLoading !== false) showLoading();
return config;
},
function (error) {
// if (error.config.headers.isLoading !== false) hideLoading();
return Promise.reject(error);
}
);
// 请求结果拦截,根据不同的错误码触发相应操作
axios.interceptors.response.use(
function (response) {
try {
if (response.data.status != 0) {
if (response.data.status == 401 ) {
// token失效
showToast('账号过期或异地登录, 请重新登录');
localCache.remove('auth');
localCache.remove('userInfo');
window.location.pathname='/home';
// router.replace({name: 'Home', params: {auth: 'over'}});
}
}
} catch (e) {
showToast('后台' + response.data.status + '错误返回格式不正确');
}
// if (response.config.headers.isLoading !== false) hideLoading();
return response;
},
function (error) {
// if (error.config.headers.isLoading !== false) hideLoading();
if (error.response) {
switch (error.response.data.status) {
case 401:
// token失效
showToast('账号过期或异地登录, 请重新登录');
localCache.remove('auth');
localCache.remove('userInfo');
window.location.pathname='/home';
break;
case 500:
// 500 服务端请求错误
showToast('接口500错误【' + error.response.data.path + '】');
return Promise.reject(error.response);
case 404:
// 找不到资源
showToast('接口404错误【' + error.response.data.path + '】');
return Promise.reject(error.response);
default:
return Promise.reject(error.response);
}
}
}
);
}

24
src/main.js 100644
View File

@ -0,0 +1,24 @@
import "./assets/css/main.css";
import 'virtual:svg-icons-register';
import 'virtual:windi.css'
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import { registerSvgIcon } from './icons/index.js'
import httpConfig from "./io/httpConfig";
import 'vant/es/toast/style';
httpConfig();
const app = createApp(App);
registerSvgIcon(app);
app.use(createPinia());
app.use(router);
app.mount("#app");

View File

@ -0,0 +1,22 @@
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "Layout",
redirect: "/home",
children: [{
path: "home",
name: "Home",
mate: {
title: "首页-AI助理",
},
component: () => import("@/views/home/index.vue"),
}]
}
],
});
export default router;

View File

@ -0,0 +1,18 @@
import { ref, computed } from "vue";
import { defineStore } from "pinia";
export const useAuthModal = defineStore("authModal", () => {
const isShow = ref(false);
const authModalType = ref('login');
function showAuthModal() {
isShow.value = true;
}
function hideAuthModal(){
isShow.value = false;
}
function setAuthModalType(type){
authModalType.value = type;
}
return { isShow, authModalType, showAuthModal, hideAuthModal, setAuthModalType };
});

View File

@ -0,0 +1,11 @@
import { ref, computed } from "vue";
import { defineStore } from "pinia";
export const useUserInfo = defineStore("userInfo", () => {
const userData = ref({});
function updateUserInfo(data) {
userData.value = data;
}
return { userData, updateUserInfo };
});

18
src/utils/copy.js 100644
View File

@ -0,0 +1,18 @@
export function copyToClip(text) {
return new Promise((resolve, reject) => {
try {
const input = document.createElement('textarea')
input.setAttribute('readonly', 'readonly')
input.value = text
document.body.appendChild(input)
input.select()
if (document.execCommand('copy'))
document.execCommand('copy')
document.body.removeChild(input)
resolve(text)
}
catch (error) {
reject(error)
}
})
}

View File

@ -0,0 +1,172 @@
import { upperFirst } from 'lodash-es'
export function getBoundingClientRect(element) {
if (!element || !element.getBoundingClientRect) {
return 0
}
return element.getBoundingClientRect()
}
function trim(string) {
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '')
}
/* istanbul ignore next */
export function hasClass(el, cls) {
if (!el || !cls) return false
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.')
if (el.classList) {
return el.classList.contains(cls)
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1
}
}
/* istanbul ignore next */
export function addClass(el, cls) {
if (!el) return
let curClass = el.className
const classes = (cls || '').split(' ')
for (let i = 0, j = classes.length; i < j; i++) {
const clsName = classes[i]
if (!clsName) continue
if (el.classList) {
el.classList.add(clsName)
} else if (!hasClass(el, clsName)) {
curClass += ' ' + clsName
}
}
if (!el.classList) {
el.className = curClass
}
}
/* istanbul ignore next */
export function removeClass(el, cls) {
if (!el || !cls) return
const classes = cls.split(' ')
let curClass = ' ' + el.className + ' '
for (let i = 0, j = classes.length; i < j; i++) {
const clsName = classes[i]
if (!clsName) continue
if (el.classList) {
el.classList.remove(clsName)
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ')
}
}
if (!el.classList) {
el.className = trim(curClass)
}
}
/**
* Get the left and top offset of the current element
* left: the distance between the leftmost element and the left side of the document
* top: the distance from the top of the element to the top of the document
* right: the distance from the far right of the element to the right of the document
* bottom: the distance from the bottom of the element to the bottom of the document
* rightIncludeBody: the distance between the leftmost element and the right side of the document
* bottomIncludeBody: the distance from the bottom of the element to the bottom of the document
*
* @description:
*/
export function getViewportOffset(element) {
const doc = document.documentElement
const docScrollLeft = doc.scrollLeft
const docScrollTop = doc.scrollTop
const docClientLeft = doc.clientLeft
const docClientTop = doc.clientTop
const pageXOffset = window.pageXOffset
const pageYOffset = window.pageYOffset
const box = getBoundingClientRect(element)
const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = box
const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0)
const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0)
const offsetLeft = retLeft + pageXOffset
const offsetTop = rectTop + pageYOffset
const left = offsetLeft - scrollLeft
const top = offsetTop - scrollTop
const clientWidth = window.document.documentElement.clientWidth
const clientHeight = window.document.documentElement.clientHeight
return {
left: left,
top: top,
right: clientWidth - rectWidth - left,
bottom: clientHeight - rectHeight - top,
rightIncludeBody: clientWidth - left,
bottomIncludeBody: clientHeight - top,
}
}
export function hackCss(attr, value) {
const prefix = ['webkit', 'Moz', 'ms', 'OT']
const styleObj = {}
prefix.forEach((item) => {
styleObj[`${item}${upperFirst(attr)}`] = value
})
return {
...styleObj,
[attr]: value,
}
}
/* istanbul ignore next */
export function on(
element,
event,
handler,
) {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
/* istanbul ignore next */
export function off(
element,
event,
handler,
) {
if (element && event && handler) {
element.removeEventListener(event, handler, false)
}
}
/* istanbul ignore next */
export function once(el, event, fn) {
const listener = function (self, ...args) {
if (fn) {
fn.apply(this, args)
}
off(el, event, listener)
}
on(el, event, listener)
}
export function useRafThrottle(fn) {
let locked = false
// @ts-ignore
return function (...args) {
if (locked) return
locked = true
window.requestAnimationFrame(() => {
// @ts-ignore
fn.apply(this, args)
locked = false
})
}
}

42
src/utils/event.js 100644
View File

@ -0,0 +1,42 @@
import ResizeObserver from 'resize-observer-polyfill'
const isServer = typeof window === 'undefined'
/* istanbul ignore next */
function resizeHandler(entries) {
for (const entry of entries) {
const listeners = entry.target.__resizeListeners__ || []
if (listeners.length) {
listeners.forEach((fn) => {
fn()
})
}
}
}
/* istanbul ignore next */
export function addResizeListener(element, fn) {
if (isServer) return
if (!element.__resizeListeners__) {
element.__resizeListeners__ = []
element.__ro__ = new ResizeObserver(resizeHandler)
element.__ro__.observe(element)
}
element.__resizeListeners__.push(fn)
}
/* istanbul ignore next */
export function removeResizeListener(element, fn) {
if (!element || !element.__resizeListeners__) return
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1)
if (!element.__resizeListeners__.length) {
element.__ro__.disconnect()
}
}
export function triggerWindowResize() {
const event = document.createEvent('HTMLEvents')
event.initEvent('resize', true, true)
;(event).eventType = 'message'
window.dispatchEvent(event)
}

105
src/utils/is.js 100644
View File

@ -0,0 +1,105 @@
const toString = Object.prototype.toString
export function is(val, type) {
return toString.call(val) === `[object ${type}]`
}
export function isDef(val) {
return typeof val !== 'undefined'
}
export function isUnDef(val) {
return !isDef(val)
}
export function isObject(val) {
return val !== null && is(val, 'Object')
}
export function isEmpty(val) {
if (isArray(val) || isString(val)) {
return val.length === 0
}
if (val instanceof Map || val instanceof Set) {
return val.size === 0
}
if (isObject(val)) {
return Object.keys(val).length === 0
}
return false
}
export function isDate(val) {
return is(val, 'Date')
}
export function isNull(val) {
return val === null
}
export function isNullAndUnDef(val) {
return isUnDef(val) && isNull(val)
}
export function isNullOrUnDef(val) {
return isUnDef(val) || isNull(val)
}
export function isNumber(val) {
return is(val, 'Number')
}
export function isPromise(val) {
return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch)
}
export function isString(val) {
return is(val, 'String')
}
export function isFunction(val) {
return typeof val === 'function'
}
export function isBoolean(val) {
return is(val, 'Boolean')
}
export function isRegExp(val) {
return is(val, 'RegExp')
}
export function isArray(val) {
return val && Array.isArray(val)
}
export function isWindow(val) {
return typeof window !== 'undefined' && is(val, 'Window')
}
export function isElement(val) {
return isObject(val) && !!val.tagName
}
export function isMap(val) {
return is(val, 'Map')
}
export const isServer = typeof window === 'undefined'
export const isClient = !isServer
export function isUrl(path) {
const reg =
/^(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?(\/#\/)?(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/
return reg.test(path)
}
/**
* 验证手机格式
*/
export function isMobile(value) {
return /^1[3-9]\d{9}$/.test(value)
}

View File

@ -0,0 +1,19 @@
<template>
<div>
移动端
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import { showToast } from 'vant';
onMounted(()=>{
showToast('页面初始化');
});
</script>
<style lang="scss" scoped>
</style>

58
vite.config.js 100644
View File

@ -0,0 +1,58 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import WindiCSS from 'vite-plugin-windicss'
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
const path = require('path')
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import hostAPI from './src/config/host.config'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
WindiCSS(),
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')],
symbolId: 'icon-[name]',
}),
Components({
resolvers: [
VantResolver({
importStyle: false, // css in js
}),
],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css: {
preprocessorOptions: {
//define global scss variable
scss: {
additionalData: `@import "@/assets/css/mixin.scss";`
}
}
},
server: {
host: 'localhost',
port: '8080',
open: false,
proxy: {
'/api': {
target: hostAPI,
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, ''),
},
}
},
})

8
windi.config.js 100644
View File

@ -0,0 +1,8 @@
export default {
extend: {
},
plugins: [
require('windicss/plugin/line-clamp'),
],
}