Compare commits

..

No commits in common. 'master' and '2.0.0' have entirely different histories.

@ -1,12 +1,6 @@
# 页面标题
VITE_APP_TITLE = 管理中心
VITE_APP_TITLE = 某某系统
VITE_APP_COPY = Copyright © 2023 xxx.xxx.cn All Rights Reserved.
# 默认主题色,用户可用后台自行调节
VITE_APP_COLOR = "#20a0f1"
# 默认主题 light | dark
VITE_APP_THEME = "dark"
# 管理端暗黑主题色
VITE_APP_ADMIN_DARK = "#222"
# 管理端明亮主题色
VITE_APP_ADMIN_LIGHT = "#EfEfEf"
VITE_APP_COLOR = #257fbd

@ -14,40 +14,34 @@
"url": "https://gitee.com/JavaLionLi/RuoYi-Vue-Plus-UI.git"
},
"dependencies": {
"@microsoft/fetch-event-source": "2.0.1",
"@element-plus/icons-vue": "2.3.1",
"@element-plus/icons-vue": "^2.3.1",
"@vueup/vue-quill": "1.1.0",
"@vueuse/components": "^12.7.0",
"@vueuse/core": "^12.7.0",
"@vueuse/core": "9.5.0",
"axios": "0.27.2",
"crypto-js": "4.2.0",
"echarts": "5.4.0",
"element-plus": "2.9.2",
"element-plus": "^2.8.4",
"file-saver": "2.0.5",
"fuse.js": "6.6.2",
"js-cookie": "3.0.1",
"highlight.js": "^11.11.1",
"jsencrypt": "3.3.1",
"mescroll.js": "1.4.2",
"mitt": "3.0.1",
"normalize.css": "^8.0.1",
"mescroll.js": "^1.4.2",
"mitt": "^3.0.1",
"nprogress": "0.2.0",
"pinia": "2.0.22",
"pinia-plugin-persist": "1.0.0",
"spark-md5": "3.0.2",
"vue": "3.5.13",
"pinia-plugin-persist": "^1.0.0",
"spark-md5": "^3.0.2",
"vue": "3.2.45",
"vue-cropper": "1.0.3",
"vue-router": "4.1.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "4.6.2",
"@vitejs/plugin-vue": "3.1.0",
"@vue/compiler-sfc": "3.2.45",
"postcss-plugin-px2rem": "0.8.1",
"sass": "1.56.1",
"unplugin-auto-import": "0.11.4",
"vite": "5.4.11",
"vite": "3.2.7",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-setup-extend": "0.4.0"
}
}
}

File diff suppressed because it is too large Load Diff

@ -1,172 +0,0 @@
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { getToken } from '@/utils/auth'
/**
* @description: 创建sse连接
*/
class ServerSentEvents {
static defaultConfig = {
base: import.meta.env.VITE_APP_BASE_API, // 基础地址
url: '/sse', // 地址
data: undefined, // 请求正文
params: undefined, // 请求参数
method: 'get', // 提交方式
auth: true, // 是否携带token
json: true, // 是否返回json
returnData: false, // json数据是否返回data属性
reconnect: true, //是否重连
headers: {
'Content-Type': 'application/json'
},
onopen: () => { },
onmessage: () => { },
onerror: () => { },
onclose: () => { }
}
constructor(config) {
if (config) {
this.setConfig(config)
this.init()
}
}
static get(url, onmessage, config = {}) {
config.onmessage = onmessage
config.url = url
return new ServerSentEvents(config)
}
static post(url, data, onmessage, config = {}) {
config.onmessage = onmessage
config.url = url
config.method = 'post'
config.data = data
return new ServerSentEvents(config)
}
setConfig(config) {
this.config = {
ctrl: new AbortController(),
...ServerSentEvents.defaultConfig,
...config
}
}
init() {
if (this.config.auth) {
this.config.headers.Authorization = 'Bearer ' + getToken()
}
let url = this.config.url
// 如果url不含协议
if (url.indexOf("//") == -1) {
url = this.config.base + url
}
if (this.config.params) {
if (url.indexOf("?") > -1) {
url += '&' + this.params(this.config.params)
} else {
url += '?' + this.params(this.config.params)
}
}
let body = undefined
if (this.config.data && (this.config.method === 'post' || this.config.method === 'put')) {
if (this.config.data.constructor == URLSearchParams) {
this.config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
body = this.params(this.config.data).toString()
} else if (this.config.data.constructor == FormData) {
this.config.headers['Content-Type'] = 'multipart/form-data'
body = this.config.data
} else {
body = JSON.stringify(body)
}
}
this.config._url = url
this.config._body = body
console.debug(this.config)
this.send()
}
send() {
fetchEventSource(this.config._url, {
method: this.config.method,
headers: this.config.headers,
body: this.config._body,
signal: this.config.ctrl.signal,
onopen: this.config.onopen,
onmessage: (msg) => {
if (this.config.json) {
let data = JSON.parse(msg.data)
if (this.config.returnData) {
data = data.data
}
this.config.onmessage(data)
} else {
this.config.onmessage(msg)
}
},
onclose: () => {
console.info('onclose')
this.abort()
this.config.onclose()
if (this.config.reconnect) {
this.send()
}
},
onerror: (err) => {
console.error(err)
this.abort()
this.config.onerror(err)
}
})
}
abort() {
if (this.config.ctrl && !this.config.reconnect) {
try {
this.config.ctrl.abort()
} catch (e) {
console.error(e)
}
}
}
close() {
this.abort()
}
params(param) {
if (param == null || param == "") {
return new URLSearchParams();
}
if (param.constructor == Array) {
let param1 = new URLSearchParams();
for (let obj of param) {
param1.append(obj.name, obj.value);
}
param = param1;
} else if (param.constructor == Object) {
let param1 = new URLSearchParams();
for (let name in param) {
param1.append(name, param[name]);
}
param = param1;
} else {
if (param.constructor == HTMLFormElement) {
param = new FormData(param);
}
if (param.constructor == FormData || param.constructor == String) {
param = new URLSearchParams(param);
}
}
return param;
}
}
export default ServerSentEvents

@ -11,7 +11,7 @@ body {
--left-img: url(../images/login.png);
background-image: linear-gradient(-25deg, #FFF0 30%, #FFF2 50%, #FFF0 70%), linear-gradient(to top, var(--bg),var(--bg));
background-color: var(--bg);
width: 100%;
height: 100%;
font-size: var(--size);
@ -19,17 +19,6 @@ body {
justify-content: center;
align-items: center;
overflow: hidden;
position: relative;
&::before {
content: '';
position: absolute;
inset: 0;
background-image: radial-gradient(circle, #0001 .1em, #0000 1em,#0000 100%);
background-size: 2em 2em;
filter: url(#WEffectNoiseBgFilter);
transform: scale(2);
}
&>.w-login-outer {
position: relative;
@ -45,24 +34,13 @@ body {
box-shadow: 0 0 1em #0003;
&> :first-child {
background-image: var(--left-img), linear-gradient(to bottom,var(--el-color-primary-light-9) 15%, var(--el-color-primary-light-8) 50%, var(--el-color-primary-light-3));
background-size: 70% auto, 100% 100%;
background-position: center center;
background-repeat: no-repeat;
position: relative;
box-shadow: -.3em 0 .6em #0001 inset;
background-image: radial-gradient(circle, #FFFFFF16 1px, #FFF0 1px,#FFF0 100%) ,linear-gradient(to bottom, var(--el-color-primary-light-9) 15%, var(--el-color-primary-light-8) 50%, var(--el-color-primary-light-3));
background-size: 5px 5px, auto;
overflow: hidden;
opacity: .85;
&::after {
position: absolute;
inset: 0;
content:'';
background-image: var(--left-img);
background-size: 70% auto;
background-position: center;
background-repeat: no-repeat;
z-index: 2;
}
&::before {
position: absolute;
@ -71,21 +49,12 @@ body {
top: calc(50% - 2em);
box-shadow: -.3em .3em .6em #0001;
transform: scaleX(.8) rotate(45deg);
z-index: 3;
width: 4em;
height: 4em;
content: '';
}
&>div {
position: absolute;
inset: 0;
z-index: 1;
background-color: #0000;
background-image: radial-gradient(circle, #FFFFFF16 1px, #FFF0 1px,#FFF0 100%);
background-size: 5px 5px;
}
}
.w-login-form {
@ -165,24 +134,54 @@ body {
}
&>.h2 {
margin-top: 0.7em;
margin-top: 0.6em;
display: flex;
justify-content: space-between;
align-items: center;
color: var(--primary-color);
* {
font-size: .8rem;
& label:has(input[type="checkbox"]) {
margin-top: .3em;
font-size: .9em;
--color: #aaa;
color: var(--color);
display: flex;
justify-content: flex-start;
align-items: center;
cursor: pointer;
font-weight: normal;
&::before {
content: "";
background-color: var(--color);
border: .13em solid var(--color);
box-sizing: border-box;
padding: .17em;
background-clip: content-box;
height: 1em;
width: 1em;
margin-right: .3em;
border-radius: 2em;
}
&>input[type="checkbox"] {
display: none;
}
}
&>div>div, a {
& label:has(input[type="checkbox"]:checked) {
--color: var(--primary-color);
}
& label:hover {
filter: brightness(0.8);
}
& a {
color: var(--primary-color);
text-decoration: none;
&:hover {
filter: brightness(1.1);
}
&:active {
filter: brightness(.9);
filter: brightness(0.7);
}
}
}

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M156.608 487.86c1.156-1.138 2.649-1.623 3.919-2.56l306.667-301.569c13.195-12.97 34.586-12.97 47.78 0a32.836 32.836 0 010 46.988L263.303 478.21h579.204c18.978 0 34.362 15.129 34.362 33.79 0 18.662-15.384 33.793-34.362 33.793H263.302L514.974 793.28a32.832 32.832 0 010 46.985c-13.195 12.974-34.587 12.974-47.781 0L160.526 538.703c-1.27-.94-2.763-1.422-3.92-2.562-6.334-6.23-9.24-14.34-9.476-22.503.237-11.437 3.143-19.547 9.478-25.779zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 563 B

@ -1 +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="1569915748289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M768.35456 416a256 256 0 1 0-512 0 192 192 0 1 0 0 384v64a256 256 0 0 1-58.88-505.216 320.128 320.128 0 0 1 629.76 0A256.128 256.128 0 0 1 768.35456 864v-64a192 192 0 0 0 0-384z m-512 384h64v64H256.35456v-64z m448 0h64v64h-64v-64z" p-id="3063"></path><path d="M539.04256 845.248V512.192a32.448 32.448 0 0 0-32-32.192c-17.664 0-32 14.912-32 32.192v333.056l-36.096-36.096a32.192 32.192 0 0 0-45.056 0.192 31.616 31.616 0 0 0-0.192 45.056l90.88 90.944a31.36 31.36 0 0 0 22.528 9.088 30.08 30.08 0 0 0 22.4-9.088l90.88-90.88a32.192 32.192 0 0 0-0.192-45.12 31.616 31.616 0 0 0-45.056-0.192l-36.096 36.096z" p-id="3064"></path></svg>
<?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="1569915748289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M768.35456 416a256 256 0 1 0-512 0 192 192 0 1 0 0 384v64a256 256 0 0 1-58.88-505.216 320.128 320.128 0 0 1 629.76 0A256.128 256.128 0 0 1 768.35456 864v-64a192 192 0 0 0 0-384z m-512 384h64v64H256.35456v-64z m448 0h64v64h-64v-64z" fill="#333333" p-id="3063"></path><path d="M539.04256 845.248V512.192a32.448 32.448 0 0 0-32-32.192c-17.664 0-32 14.912-32 32.192v333.056l-36.096-36.096a32.192 32.192 0 0 0-45.056 0.192 31.616 31.616 0 0 0-0.192 45.056l90.88 90.944a31.36 31.36 0 0 0 22.528 9.088 30.08 30.08 0 0 0 22.4-9.088l90.88-90.88a32.192 32.192 0 0 0-0.192-45.12 31.616 31.616 0 0 0-45.056-0.192l-36.096 36.096z" fill="#333333" p-id="3064"></path></svg>

Before

Width:  |  Height:  |  Size: 1005 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M576 192v128h64V160a32 32 0 00-32-32H96a32 32 0 00-32 32v704a32 32 0 0032 32h512a32 32 0 0032-32V704h-64v128H128V192h448z"/><path d="M718.848 336.256L862.528 480H384v64h478.528l-143.68 143.744 45.248 45.248 198.336-198.4a32 32 0 000-45.248l-198.4-198.336-45.184 45.248z"/></svg>

Before

Width:  |  Height:  |  Size: 395 B

@ -1 +0,0 @@
<?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="1738984125918" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4325" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 0a512 512 0 1 0 512 512A512.602869 512.602869 0 0 0 512 0zM93.170627 512A419.541854 419.541854 0 0 1 512 93.170627v837.877971A419.541854 419.541854 0 0 1 93.170627 512z" p-id="4326"></path></svg>

Before

Width:  |  Height:  |  Size: 533 B

@ -1,11 +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="1575802846045"
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2750"
xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<defs>
<style type="text/css"></style>
</defs>
<path
d="M868.593046 403.832442c-30.081109-28.844955-70.037123-44.753273-112.624057-44.753273L265.949606 359.079168c-42.554188 0-82.510202 15.908318-112.469538 44.690852-30.236652 28.782533-46.857191 67.222007-46.857191 108.198258l0 294.079782c0 40.977273 16.619516 79.414701 46.702672 108.136859 29.959336 28.844955 70.069869 44.814672 112.624057 44.814672l490.019383 0c42.585911 0 82.696444-15.969717 112.624057-44.814672 30.082132-28.844955 46.579875-67.222007 46.579875-108.136859L915.172921 511.968278C915.171897 471.053426 898.675178 432.677397 868.593046 403.832442zM841.821309 806.049083c0 22.098297-8.882298 42.772152-25.099654 58.306964-16.154935 15.661701-37.81935 24.203238-60.752666 24.203238L265.949606 888.559285c-22.934339 0-44.567032-8.54256-60.877509-24.264637-16.186657-15.474436-25.067932-36.148291-25.067932-58.246589L180.004165 511.968278c0-22.035876 8.881274-42.772152 25.192775-58.307987 16.186657-15.536858 37.81935-24.139793 60.753689-24.139793l490.019383 0c22.933315 0 44.597731 8.602935 60.752666 24.139793 16.21838 15.535835 25.099654 36.272112 25.099654 58.307987L841.822332 806.049083zM510.974136 135.440715c114.914216 0 208.318536 89.75214 208.318536 200.055338l73.350588 0c0-149.113109-126.366036-270.496667-281.669124-270.496667-155.333788 0-281.699824 121.383558-281.699824 270.496667l73.350588 0C302.623877 225.193879 396.059919 135.440715 510.974136 135.440715zM474.299865 747.244792l73.350588 0L547.650453 629.576859l-73.350588 0L474.299865 747.244792z"
p-id="2751"></path>
</svg>
<?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="1575802846045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2750" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M868.593046 403.832442c-30.081109-28.844955-70.037123-44.753273-112.624057-44.753273L265.949606 359.079168c-42.554188 0-82.510202 15.908318-112.469538 44.690852-30.236652 28.782533-46.857191 67.222007-46.857191 108.198258l0 294.079782c0 40.977273 16.619516 79.414701 46.702672 108.136859 29.959336 28.844955 70.069869 44.814672 112.624057 44.814672l490.019383 0c42.585911 0 82.696444-15.969717 112.624057-44.814672 30.082132-28.844955 46.579875-67.222007 46.579875-108.136859L915.172921 511.968278C915.171897 471.053426 898.675178 432.677397 868.593046 403.832442zM841.821309 806.049083c0 22.098297-8.882298 42.772152-25.099654 58.306964-16.154935 15.661701-37.81935 24.203238-60.752666 24.203238L265.949606 888.559285c-22.934339 0-44.567032-8.54256-60.877509-24.264637-16.186657-15.474436-25.067932-36.148291-25.067932-58.246589L180.004165 511.968278c0-22.035876 8.881274-42.772152 25.192775-58.307987 16.186657-15.536858 37.81935-24.139793 60.753689-24.139793l490.019383 0c22.933315 0 44.597731 8.602935 60.752666 24.139793 16.21838 15.535835 25.099654 36.272112 25.099654 58.307987L841.822332 806.049083zM510.974136 135.440715c114.914216 0 208.318536 89.75214 208.318536 200.055338l73.350588 0c0-149.113109-126.366036-270.496667-281.669124-270.496667-155.333788 0-281.699824 121.383558-281.699824 270.496667l73.350588 0C302.623877 225.193879 396.059919 135.440715 510.974136 135.440715zM474.299865 747.244792l73.350588 0L547.650453 629.576859l-73.350588 0L474.299865 747.244792z" p-id="2751"></path></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M965.829 166.057l-64.458 50.4C813.486 104.114 676.8 32 523.314 32 258.286 32 43.771 246.286 43.43 511.429 43.086 776.8 258.057 992 523.314 992c207.2 0 383.772-131.429 450.972-315.543 1.714-4.8-.8-10.171-5.6-11.771l-64.8-22.286a9.143 9.143 0 00-11.543 5.486c-2.057 5.714-4.343 11.428-6.743 17.028-19.771 46.857-48.114 88.915-84.229 125.029a394.023 394.023 0 01-124.914 84.343c-48.343 20.457-99.886 30.857-152.914 30.857-53.143 0-104.572-10.4-152.914-30.857a390.286 390.286 0 01-124.915-84.343 391.04 391.04 0 01-84.228-125.029c-20.457-48.457-30.857-99.885-30.857-153.028s10.4-104.572 30.857-153.029C181.257 312 209.6 269.943 245.714 233.83c36.115-36.115 78.172-64.458 124.915-84.343 48.342-20.457 99.885-30.857 152.914-30.857 53.143 0 104.571 10.4 152.914 30.857a390.286 390.286 0 01124.914 84.343 393.912 393.912 0 0131.772 35.885l-68.8 53.715a9.143 9.143 0 003.428 16.114l200.686 49.143c5.714 1.371 11.314-2.972 11.314-8.8l.915-206.743c-.115-7.543-8.915-11.772-14.857-7.086z"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M692.315 1023.925c-5.353-.768-10.712-1.562-16.065-2.305-24.26-3.385-45.779-12.973-65.03-28.089-22.698-17.82-38.17-40.475-47.108-67.84-4.485-13.729-6.652-27.833-6.677-42.13-.163-106.23-.088-212.458-.088-318.687v-7.533h7.215c107.778 0 215.562-.337 323.34.219 29.376.15 56.166 10.044 79.895 27.901 17.751 13.355 31.48 29.982 41.33 49.676 7.946 15.897 13.124 32.75 13.686 50.75.031.988.725 1.956 1.112 2.936v202.458c-.387 1.174-.918 2.317-1.143 3.517-1.886 10.23-2.83 20.737-5.74 30.662-8.208 27.958-24.754 50.47-47.503 68.458-18.994 15.022-40.5 24.342-64.535 27.702-5.353.75-10.7 1.537-16.053 2.305H692.315zM1023.931 333.94c-.774 4.772-1.586 9.544-2.317 14.322-3.698 24.192-13.348 45.71-28.539 64.88-12.192 15.39-27.008 27.714-44.254 36.77-14.291 7.503-29.57 13.037-45.853 14.236-13.255.974-26.584 1.218-39.882 1.23-99.452.094-198.904.05-298.362.05h-7.377v-6.79c0-107.209-.324-214.418.2-321.622.156-31.674 10.931-60.238 31.044-85.154 22.436-27.795 51.693-43.655 86.266-50.607 2.323-.468 4.666-.837 6.996-1.249h217.586c.78.388 1.524.906 2.348 1.137 12.549 3.435 25.535 5.747 37.577 10.475 23.648 9.288 42.605 25.147 57.521 45.728 13.011 17.952 21.537 37.796 24.741 59.826.7 4.785 1.537 9.544 2.312 14.316-.007 67.478-.007 134.962-.007 202.452zM0 683.008c1.537-7.12 2.873-14.291 4.66-21.343 4.915-19.432 13.872-36.803 26.533-52.406 17.583-21.668 39.633-36.621 66.085-45.203 13.686-4.441 27.758-6.684 42.143-6.69 105.842-.031 211.683-.019 317.525-.019h8.489v6.265c0 110.302.243 220.603-.219 330.898-.081 19.926-6.852 38.59-16.521 56.228-7.758 14.148-17.527 26.547-29.42 37.172-18.463 16.49-39.82 27.758-64.28 32.442-7.276 1.393-14.778 1.624-22.167 2.467-.818.094-1.574.731-2.361 1.112H134.993c-1.175-.387-2.336-1.099-3.517-1.112-19.182-.28-37.184-5.446-54.11-14.016-17.134-8.676-32.219-20.069-44.58-35.122-13.117-15.966-22.76-33.58-28.039-53.505-2.005-7.577-3.173-15.378-4.722-23.074C0 825.734 0 754.371 0 683.008M139.59 605.1zM340.923-.006c7.314 1.549 14.71 2.78 21.924 4.71 19.926 5.334 37.565 14.94 53.524 28.101 16.908 13.941 29.076 31.237 37.89 50.969 6.701 15.01 11.105 30.8 11.117 47.39.088 108.952.044 217.91.044 326.863v7.395h-6.196c-109.927 0-219.847.244-329.774-.212-21.38-.088-41.593-7.127-59.838-18.308-10-6.134-19.894-13.054-28.14-21.318-14.034-14.06-25.309-30.319-32.242-49.301-4.198-11.48-7.583-23.061-8.208-35.335-.018-.412-.662-.8-1.018-1.193V125.661c.388-.781.95-1.524 1.125-2.349 2.123-9.981 3.179-20.325 6.458-29.907 8.932-26.09 24.922-47.452 46.653-64.385C68.102 18.22 83.28 9.8 100.539 5.634c7.976-1.924 15.977-3.76 23.966-5.64h216.418m-13.03 46.815zm89.658 77.74z"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

@ -1 +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="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" p-id="1941"></path></svg>
<?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="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -20,16 +20,10 @@ label {
}
html {
font-size: 1vw;
height: 100%;
box-sizing: border-box;
}
@media screen and (max-width:1400px) {
html {
font-size: 14px;
}
}
#app {
height: 100%;
}
@ -208,288 +202,87 @@ fieldset {
border: var(--el-border-color) 1px solid;
}
@layer {
.w-abs {
position: absolute;
inset: 0;
}
.w-lines {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.w-flex {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
position: relative;
}
.w-flex-column {
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
/* 印章效果 */
.w-seal {
position: absolute;
display: flex;
line-height: 1;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 6em;
height: 6em;
border-radius: 10em;
border: .25em solid currentColor;
background-color: #FFF;
z-index: 1;
transform: rotate(-25deg);
padding: 0;
&>div {
border: .13em solid currentColor;
padding: .3em 0;
width: 4.3em;
text-align: center;
font-weight: bold;
}
&::before {
content: "";
position: absolute;
width: 5em;
height: 5em;
border: .15em solid currentColor;
border-radius: 10em;
}
&::after {
content: "";
position: absolute;
width: 3.5em;
height: 3.5em;
border: .15em solid currentColor;
border-color: currentColor #0000 currentColor #0000;
border-radius: 10em;
}
}
.w-loading {
display: inline-block;
width: 1em;
height: 1em;
border-radius: 1em;
border: solid .2em currentColor;
mask-image: conic-gradient(from 0deg, #0000 0%, #000 75%, #000 83%, #0000 85%);
animation: w-am-loading 1s ease infinite;
}
.w-inner-loading {
pointer-events: none;
user-select: none;
position: relative;
display: flex;
justify-content: center;
align-items: center;
&::before {
content: '';
position: absolute;
inset: 0;
background-color: var(--bg-color, #0003);
backdrop-filter: blur(.1em);
}
&::after {
position: absolute;
content: '';
font-size: var(--size, 1em);
display: block;
width: 1em;
height: 1em;
border-radius: 1em;
border: solid .2em var(--loading-color, currentColor);
mask-image: conic-gradient(from 0deg, #0000 0%, #000 75%, #000 83%, #0000 85%);
animation: w-am-loading 1s ease infinite;
}
}
@keyframes w-am-loading {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@property --border-gradient-angle {
syntax: "<angle>";
inherits: true;
initial-value: 0turn;
}
.w-border-light,
.w-border-light-1,
.w-border-light-2,
.w-border-light-3 {
position: relative;
border: none !important;
animation-play-state: inherit;
--border: .1em solid #0000;
--border-light-color: #FFF9;
--time: 5s;
&::before {
content: '';
pointer-events: none;
position: absolute;
inset: 0;
border: var(--border);
border-radius: inherit;
}
&::after {
content: '';
pointer-events: none;
position: absolute;
inset: 0;
border: var(--border);
border-color: var(--border-light-color);
border-radius: inherit;
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000, #000 10%, #0000 11%, #0000 50%, #000 60%, #0000 61%);
animation: am-frame var(--time) infinite linear;
animation-play-state: inherit;
}
}
.w-border-light-1::after {
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000, #000 10%, #0000 11%);
}
.w-border-light-3::after {
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000,#0000 23%, #000 33%, #0000 34%,#0000 56%,#000 66%,#0000 67%, #0000 89%, #000 99%, #0000 100%);
}
@keyframes am-frame {
0% {
--border-gradient-angle: 0turn;
}
100% {
--border-gradient-angle: 1turn;
}
}
.w-part-hide {
--top: 1em;
--bottom: 1em;
mask-image: linear-gradient(to bottom,#0000 0%,#000 var(--top),#000 calc(100% - var(--bottom)), #0000 100%);
}
.w-lines {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.w-flex {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
position: relative;
}
.w-flex-column {
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.w-radio,
.w-checkbox {
--btn-color-inner: var(--btn-color, currentColor);
--opacity: .6;
transition: all .3s;
cursor: pointer;
display: flex;
align-items: center;
&::before {
content: '';
font-size: var(--btn-size, inherit);
width: 1.5em;
height: 1.5em;
opacity: var(--opacity);
box-sizing: border-box;
border: solid .1em var(--btn-color-inner);
margin-right: .2em;
border-radius: .2em;
background-color: var(--btn-bg-color-inner, #0000);
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNzA5NzA3MjQ5OTg3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQyODUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTg0My42OTM5NTkgMjkzLjYwOTA2MSA0MjUuMjU1ODY5IDcxMi4wNTYzNjIgMTg2LjE0NTAyNiA0NzIuOTQ3NTY2IDY2LjU3OTg4MyA1OTIuNTA0NTIyIDQyNS4yNTU4NjkgOTUxLjE2NTE1OCA5NjMuMjYwMTI2IDQxMy4xNzQyMDRaIiBwLWlkPSI0Mjg2IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+");
background-size: 1em 1em;
background-repeat: no-repeat;
background-position: var(--background-position-inner, center -1em);
transition: all .3s;
overflow: hidden;
transform: scale(.8);
}
&.selected {
--btn-color-inner: var(--selected-btn-color, var(--el-color-primary));
--opacity: 1;
--btn-bg-color-inner: var(--selected-btn-color, var(--el-color-primary));
--background-position-inner: center 0.1em;
color: var(--selected-text-color, currentColor);
}
}
.w-loading {
display: inline-block;
width: 1em;
height: 1em;
border-radius: 1em;
border: .2em solid currentColor;
border-top-color: #0000;
animation: w-am-loading 1s infinite;
}
.w-radio::before {
border-radius: 1em;
}
@keyframes w-am-loading {
from {
transform: rotate(0deg);
}
@property --data-num {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
to {
transform: rotate(360deg);
}
}
.w-breathing {
--filter: brightness(110%);
--transform: scale(1.1);
--time: 1.3s;
--data-num: 0;
--data-num-to: 1;
animation: w-am-breathing var(--time) infinite linear;
animation-play-state: inherit;
}
.w-radio,
.w-checkbox {
--btn-color-inner: var(--btn-color,currentColor);
--opacity: .6;
transition: all .3s;
cursor: pointer;
&::before {
content: '';
font-size: var(--btn-size,inherit);
width: 1em;
height: 1em;
opacity: var(--opacity);
box-sizing: border-box;
border: solid 1px var(--btn-color-inner);
margin-right: .2em;
border-radius: .2em;
background-color: var(--btn-bg-color-inner,#0000);
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNzA5NzA3MjQ5OTg3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQyODUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTg0My42OTM5NTkgMjkzLjYwOTA2MSA0MjUuMjU1ODY5IDcxMi4wNTYzNjIgMTg2LjE0NTAyNiA0NzIuOTQ3NTY2IDY2LjU3OTg4MyA1OTIuNTA0NTIyIDQyNS4yNTU4NjkgOTUxLjE2NTE1OCA5NjMuMjYwMTI2IDQxMy4xNzQyMDRaIiBwLWlkPSI0Mjg2IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+");
background-size: .65em .65em;
background-repeat: no-repeat;
background-position: var(--background-position-inner,center -1em);
transition: all .3s;
overflow: hidden;
}
&.selected {
--btn-color-inner: var(--selected-btn-color, var(--w-main));
--opacity: 1;
--btn-bg-color-inner: var(--selected-btn-color, var(--w-main));
--background-position-inner: center .1em;
color: var(--selected-text-color, currentColor);
}
@keyframes w-am-breathing {
0% {
filter: none;
transform: none;
}
45% {
filter: var(--filter);
transform: var(--transform);
--data-num: var(--data-num-to);
}
}
90% {
filter: none;
transform: none;
}
}
}
.w-radio::before {
border-radius: 1em;
}

@ -8,7 +8,7 @@
}
.sidebarHide {
margin-left: 0 !important;
margin-left: 0!important;
}
.sidebar-container {
@ -24,39 +24,9 @@
left: 0;
z-index: 1001;
overflow: hidden;
text-shadow: .1em .1em 0 #000;
&.theme-light {
text-shadow: .1em .1em 0 #FFF;
li {
&::before {
background-color: #FFF5;
}
}
}
// -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35);
// box-shadow: 2px 0 6px rgba(0,21,41,.35);
&::before {
content: '';
position: absolute;
inset: 0;
// background-color: red;
background-image: radial-gradient(circle, var(--noise-color, #FFFFFF06) .5rem, #0000 1rem, #0000 100%);
background-size: 2rem 2rem;
filter: url(#WEffectNoiseBgFilter);
transform: scale(2);
}
&.theme-light::before {
--noise-color: #00000006;
}
// reset element-ui css
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
@ -100,8 +70,7 @@
width: 100% !important;
}
.el-menu-item,
.menu-title {
.el-menu-item, .menu-title {
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
@ -119,15 +88,10 @@
}
}
& .theme-dark .is-active>.el-sub-menu__title {
& .theme-dark .is-active > .el-sub-menu__title {
color: $base-menu-color-active !important;
}
// .el-menu-item.is-active {
// --el-menu-active-color: #FFF;
// }
& .nest-menu .el-sub-menu>.el-sub-menu__title,
& .el-sub-menu .el-menu-item {
min-width: $base-sidebar-width !important;
@ -137,51 +101,14 @@
}
}
& .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title:not(.is-active),
& .theme-dark .el-sub-menu .el-menu-item:not(.is-active) {
& .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
& .theme-dark .el-sub-menu .el-menu-item {
background-color: $base-sub-menu-background !important;
&:hover {
background-color: $base-sub-menu-hover !important;
}
}
.router-link-active.router-link-exact-active {
position: relative;
background-color: var(--el-menu-active-color);
&::before {
content: '';
position: absolute;
inset: 0;
background-image: linear-gradient(to bottom, #0000 50%, #0003);
}
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
border: solid .5rem #0000;
border-right-color: #f7f7f7;
top: 50%;
transform: translateY(-50%);
right: 0;
}
.el-menu-item.is-active {
position: relative;
color: var(--my-menu-active-color, #FFF);
background-color: none !important;
&:hover {
background-color: none !important;
}
}
}
}
.hideSidebar {
@ -220,7 +147,6 @@
}
.el-menu--collapse {
.el-sub-menu {
&>.el-sub-menu__title {
&>span {
@ -230,7 +156,6 @@
visibility: hidden;
display: inline-block;
}
&>i {
height: 0;
width: 0;
@ -297,7 +222,6 @@
max-height: 100vh;
overflow-y: auto;
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
@ -311,7 +235,4 @@
border-radius: 20px;
}
}
}
}

@ -9,20 +9,17 @@ $yellow: #FEC171;
$panGreen: #30B08F;
//
$base-menu-color: #FFFC;
$base-menu-color-active: #FFFE;
// $base-menu-background: hsl(210, 63%, 30%);
// $base-menu-background: #222;
$base-menu-background: #0000;
$base-logo-title-color: #FFFE;
$base-menu-color: #bfcbd9;
$base-menu-color-active: #f4f4f5;
$base-menu-background: hsl(210, 63%, 30%);
$base-logo-title-color: #ffffff;
$base-menu-light-color: #0009;
// $base-menu-light-background: #F1F1F1;
$base-menu-light-background: #0000;
$base-logo-light-title-color: #000C;
$base-menu-light-color: rgba(0, 0, 0, 0.7);
$base-menu-light-background: #ffffff;
$base-logo-light-title-color: #001529;
$base-sub-menu-background: #0006;
$base-sub-menu-hover: #0001;
$base-sub-menu-background: hsl(210, 63%, 25%);
$base-sub-menu-hover: hsl(210, 63%, 20%);
//
/**

@ -1,228 +0,0 @@
<template>
<div class="w-code">
<w-icon icon-class="clipboard" @click="copy" />
<pre><code ref="codeRef" :class="props.language?['language-'+props.language]:[]"><slot></slot></code></pre>
</div>
</template>
<script setup>
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';
import { ElMessage } from 'element-plus'
import { onMounted } from 'vue';
const props = defineProps({
language: {
type: String,
default: ''
}
})
const codeRef = ref(null);
const copy = () => {
navigator.clipboard.writeText(codeRef.value.textContent).then(() => {
ElMessage.success('复制成功');
})
}
onMounted(() => {
hljs.highlightElement(codeRef.value);
})
const getCode = () => {
return codeRef.value.textContent;
}
const setCode = (code) => {
if(props.language){
codeRef.value.innerHTML = hljs.highlight(code, { language: props.language }).value;
}else{
codeRef.value.innerHTML = hljs.highlightAuto(code).value;
}
}
defineExpose({
copy,
getCode,
setCode,
})
</script>
<style lang="scss">
.w-code {
background-color: #0001;
margin: 1em;
padding: 0em;
border: solid 1px #0002;
border-radius: .5em;
position: relative;
&>:first-child {
position: absolute;
right: .5em;
top: .5em;
cursor: pointer;
opacity: 0;
transition: all .3s;
}
&:hover>:first-child {
opacity: 0.7;
&:hover {
opacity: 1;
}
&:active {
opacity: .85;
}
}
.hljs {
background: #0000 !important;
}
}
.dark {
pre code.hljs {
display: block;
overflow-x: auto;
padding: 1em
}
code.hljs {
padding: 3px 5px
}
/*!
Theme: GitHub Dark
Description: Dark theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-dark
Current colors taken from GitHub's CSS
*/
.hljs {
color: #c9d1d9;
background: #0d1117
}
.hljs-doctag,
.hljs-keyword,
.hljs-meta .hljs-keyword,
.hljs-template-tag,
.hljs-template-variable,
.hljs-type,
.hljs-variable.language_ {
/* prettylights-syntax-keyword */
color: #ff7b72
}
.hljs-title,
.hljs-title.class_,
.hljs-title.class_.inherited__,
.hljs-title.function_ {
/* prettylights-syntax-entity */
color: #d2a8ff
}
.hljs-attr,
.hljs-attribute,
.hljs-literal,
.hljs-meta,
.hljs-number,
.hljs-operator,
.hljs-variable,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-id {
/* prettylights-syntax-constant */
color: #79c0ff
}
.hljs-regexp,
.hljs-string,
.hljs-meta .hljs-string {
/* prettylights-syntax-string */
color: #a5d6ff
}
.hljs-built_in,
.hljs-symbol {
/* prettylights-syntax-variable */
color: #ffa657
}
.hljs-comment,
.hljs-code,
.hljs-formula {
/* prettylights-syntax-comment */
color: #8b949e
}
.hljs-name,
.hljs-quote,
.hljs-selector-tag,
.hljs-selector-pseudo {
/* prettylights-syntax-entity-tag */
color: #7ee787
}
.hljs-subst {
/* prettylights-syntax-storage-modifier-import */
color: #c9d1d9
}
.hljs-section {
/* prettylights-syntax-markup-heading */
color: #1f6feb;
font-weight: bold
}
.hljs-bullet {
/* prettylights-syntax-markup-list */
color: #f2cc60
}
.hljs-emphasis {
/* prettylights-syntax-markup-italic */
color: #c9d1d9;
font-style: italic
}
.hljs-strong {
/* prettylights-syntax-markup-bold */
color: #c9d1d9;
font-weight: bold
}
.hljs-addition {
/* prettylights-syntax-markup-inserted */
color: #aff5b4;
background-color: #033a16
}
.hljs-deletion {
/* prettylights-syntax-markup-deleted */
color: #ffdcd7;
background-color: #67060c
}
.hljs-char.escape_,
.hljs-link,
.hljs-params,
.hljs-property,
.hljs-punctuation,
.hljs-tag {
/* purposely ignored */
}
}
</style>

@ -6,7 +6,7 @@
</div>
<input ref="fileInputRef" v-if="!props.disabled" :accept="props.accept" @change="fileInputChange" type="file"
style="position: absolute; top:-100vh;" :multiple="props.max != 1" />
<div class="list" v-if="props.list">
<div class="list">
<slot :list="list">
<div v-for="(item, index) in data" :key="index" class="item"
:class="{ error: item.error, abort: item.abort, border: props.border }"
@ -16,7 +16,7 @@
<a v-else :href="baseUrl + base + 'download?' + request.params({ url: item.url, key: uploadKey }).toString()"
target="_blank">{{ item.name }}</a>
<div v-if="item.uploading && !item.abort" class="btn" @click="item.uploading.abort()"></div>
<div v-if="item.url && !props.disabled" @click="remove(item)" class="btn"></div>
<div v-if="item.url && !props.disabled" @click="item.remove()" class="btn"></div>
</div>
</slot>
</div>
@ -55,14 +55,10 @@ const props = defineProps({
getUploadKey: {
type: Function,
default: async () => {
let r = await request.get("/uploadKey")
let r = await request.get("/file/upload/getUploadKey")
return r.data
}
},
before: {
type: Function,
default: (file) => { return true }
},
/**
* 上传路径前缀
*/
@ -135,10 +131,6 @@ const props = defineProps({
border: {
type: Boolean,
default: true
},
list: {
type: Boolean,
default: true
}
})
@ -155,21 +147,6 @@ const mv = computed({
emit("change", value)
}
})
watch(mv, () => {
if (props.max == 1) {
data.value = []
if (mv.value) {
data.value = [{ url: mv.value ,ext: getExt(mv.value), name: getName(mv.value) }]
}
} else {
data.value = []
if (mv.value) {
data.value = mv.value.map(a => ({ url: a ,ext: getExt(a), name: getName(a)}))
}
}
})
const uploading = computed({
get() {
return props.uploading
@ -204,7 +181,11 @@ onMounted(async () => {
data.value = mv.value.map(a => ({ url: a, ext: getExt(a), name: getName(a) }))
}
}
for (let one of data.value) {
one.remove = () => {
remove(one)
}
}
})
const remove = (one) => {
@ -260,9 +241,6 @@ const fileInputChange = () => {
}
const addUploadFile = async (file) => {
if (!props.before(file)) {
return
}
if (props.max > 1 && props.max == data.value.length) {
ElMessage.error('最多只允许上传' + props.max + '个文件')
return
@ -309,12 +287,7 @@ const uploadFiles = async () => {
for (let i = 0; i < props.threadNum; i++) {
a.push(doOne())
}
Promise.all(a).then((r) => {
if (props.max == 1) {
mv.value = data.value.filter(a => 'url' in a).map(a => a.url)[0]
} else {
mv.value = data.value.filter(a => 'url' in a).map(a => a.url)
}
Promise.all(a).then(() => {
}).finally(() => {
data.value = data.value.filter(a => !a.error && !a.abort)
doing.value = false
@ -350,6 +323,9 @@ const uploadFile = async (index, retry = 0) => {
}
}
one.remove = () => {
remove(one)
}
if (one.raw.size <= props.chunksize) {
@ -375,7 +351,11 @@ const uploadFile = async (index, retry = 0) => {
delete one.raw
delete one.uploading
one.url = r.data
if (props.max == 1) {
mv.value = r.data
} else {
mv.value = data.value.filter(a => 'url' in a).map(a => a.url)
}
} else {
delete one.uploading
await uploadFile(index, retry)
@ -417,7 +397,11 @@ const uploadFileBig = async (one) => {
delete one.raw
delete one.uploading
one.url = r.data
if (props.max == 1) {
mv.value = r.data
} else {
mv.value = data.value.filter(a => 'url' in a).map(a => a.url)
}
} else {
one.error = true
request.post(base + 'multipartUploadAbort?uploadId=' + one.uploading.uploadId)
@ -443,7 +427,7 @@ const uploadChunk = async (one, chunksList, index, uploadId, retry = 0) => {
one.uploading.loaded = props.chunksize * index + event.loaded
}
try {
let r = await request.post(base + "multipartUpload?r=" + index + '' + Math.random(), formData, {
let r = await request.post(base + "multipartUpload?r="+index+''+ Math.random(), formData, {
onUploadProgress,
timeout: 600000,
showLoading: false,
@ -476,7 +460,7 @@ const chunkFile = (file, chunksize) => {
return chunksList;
}
defineExpose({ open, reloadUploadKey,addUploadFile })
defineExpose({ open, reloadUploadKey })
</script>
<style lang="scss" scoped>
.doing {
@ -561,8 +545,6 @@ defineExpose({ open, reloadUploadKey,addUploadFile })
background-position: -14em center;
font-size: .4em;
margin-right: .5em;
flex-flow: 1;
flex-shrink: 1;
&.icon-dir {
background-position: 0 center;

@ -1,53 +0,0 @@
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" :fill="color" />
</svg>
</template>
<script>
export default defineComponent({
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
},
color: {
type: String,
default: ''
},
},
setup(props) {
return {
iconName: computed(() => `#icon-${props.iconClass}`),
svgClass: computed(() => {
if (props.className) {
return `svg-icon ${props.className}`
}
return 'svg-icon'
})
}
}
})
</script>
<style scope lang="scss">
.sub-el-icon,
.nav-icon {
display: inline-block;
font-size: 15px;
margin-right: 12px;
position: relative;
}
.svg-icon {
width: 1em;
height: 1em;
position: relative;
fill: currentColor;
vertical-align: -2px;
}
</style>

@ -6,7 +6,7 @@
</div>
<input ref="fileInputRef" v-if="!props.disabled" accept="image/*" @change="fileInputChange" type="file"
style="position: absolute; top:-100vh;" :multiple="props.max != 1" />
<div class="list" :class="{ noEffect: props.noEffect }" v-if="props.list">
<div class="list">
<slot :list="data">
<div v-for="(item, index) in data" :key="index" class="item" :class="{ error: item.error, abort: item.abort }"
:style="{ '--ps': item.uploading ? (item.uploading?.loaded || 0) * 100 / (item.uploading?.total || 1) + '%' : '100%' }"
@ -38,7 +38,7 @@
</svg>
</div>
<div v-if="item.url && !props.disabled" @click.stop="remove(item)" class="btn">
<div v-if="item.url && !props.disabled" @click.stop="item.remove()" class="btn">
<svg t="1729755512665" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2491" width="200" height="200">
<path
@ -55,7 +55,7 @@
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed, getCurrentInstance, watch } from 'vue'
import { ref, onMounted, onUnmounted, computed, getCurrentInstance } from 'vue'
import { request } from '@/utils'
import { ElMessage } from 'element-plus'
@ -95,14 +95,10 @@ const props = defineProps({
getUploadKey: {
type: Function,
default: async () => {
let r = await request.get("/uploadKey")
let r = await request.get("/file/upload/getUploadKey")
return r.data
}
},
before: {
type: Function,
default: (file) => { return true }
},
/**
* 上传路径前缀
*/
@ -161,14 +157,6 @@ const props = defineProps({
watermark: {
type: Boolean,
default: true
},
noEffect: {
type: Boolean,
default: false
},
list: {
type: Boolean,
default: true
}
@ -221,21 +209,12 @@ onMounted(async () => {
data.value = mv.value.map(a => ({ url: a }))
}
}
console.debug(proxy.$refs.imgRef)
})
watch(mv, () => {
if (props.max == 1) {
data.value = []
if (mv.value) {
data.value = [{ url: mv.value }]
}
} else {
data.value = []
if (mv.value) {
data.value = mv.value.map(a => ({ url: a }))
for (let one of data.value) {
one.remove = () => {
remove(one)
}
}
console.debug(proxy.$refs.imgRef)
})
const remove = (one) => {
@ -293,10 +272,7 @@ const fileInputChange = () => {
}
const addUploadFile = async (file) => {
if (!props.before(file)) {
return
}
console.debug(file)
if (props.max > 1 && props.max == data.value.length) {
ElMessage.error('最多只允许上传' + props.max + '个文件')
return
@ -344,7 +320,7 @@ const uploadFiles = async () => {
console.debug('end')
}).finally(() => {
data.value = data.value.filter(a => !a.error && !a.abort)
console.debug('finally', data.value)
console.debug('finally')
doing.value = false
uploading.value = false
})
@ -376,6 +352,10 @@ const uploadFile = async (index, retry = 0) => {
one.uploading.controller.abort()
}
one.remove = () => {
remove(one)
}
let formData = new FormData()
@ -419,7 +399,7 @@ const uploadFile = async (index, retry = 0) => {
}
defineExpose({ open, reloadUploadKey, addUploadFile })
defineExpose({ open, reloadUploadKey })
</script>
<style lang="scss" scoped>
.doing {
@ -442,14 +422,6 @@ defineExpose({ open, reloadUploadKey, addUploadFile })
display: flex;
flex-wrap: wrap;
&.noEffect {
--image-border-radius: 0;
--image-margin: 0;
--image-border: none;
--image-box-shadow: none;
}
.item {
width: var(--image-size, 10em);
@ -457,15 +429,16 @@ defineExpose({ open, reloadUploadKey, addUploadFile })
position: relative;
overflow: hidden;
border-radius: var(--image-border-radius, .4em);
margin: var(--image-margin, .5em .5em 0 0);
border-radius: .4em;
margin-top: .5em;
margin-right: .5em;
padding: 0;
border: var(--image-border, #FFF solid 2px);
box-shadow: var(--image-box-shadow, 0 0 .2em #0005);
border: #FFF solid 2px;
box-shadow: 0 0 .2em #0005;
cursor: pointer;
img {
object-fit: var(--image-fit, cover);
object-fit: cover;
width: 100%;
height: 100%;
object-position: center;
@ -551,4 +524,4 @@ defineExpose({ open, reloadUploadKey, addUploadFile })
}
}
</style>
</style>

@ -1,5 +1,5 @@
<template>
<el-image-viewer v-if="imgShow" @close="imgShow=false" ref="imgRef" :url-list="img" />
<el-image-viewer v-if="imgShow" @close="imgShow=false" ref="imgRef" :url-list="[img]" />
</template>
<script setup>
@ -7,18 +7,13 @@ import { ref, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance();
const img = ref([]);
const img = ref("");
const imgShow = ref(false);
const open = async (src) => {
if(Array.isArray(src)){
img.value = src;
}else{
img.value = [src];
}
img.value = src;
imgShow.value = true
await proxy.$nextTick();
}

@ -1,77 +0,0 @@
<template>
<div class="w-tags-input">
<el-tag v-for="(tag, index) in model" :key="index" closable :disable-transitions="false" :type="props.type"
@close="handleClose(index)">
{{ index }} : {{ tag }}
</el-tag>
<el-input v-if="inputVisible" ref="inputRef" v-model="inputValue" :style="{ width: props.placeholder.length * 2 + 1 + 'em' }"
size="small" placeholder="key : value" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" />
<el-button v-else class="button-new-tag" size="small" @click="showInput">
{{ props.placeholder }}
</el-button>
</div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
import { nextTick, ref } from 'vue'
const model = defineModel({
type: Object,
required: true
});
const props = defineProps({
/**
* 输入提示
*/
placeholder: {
type: String,
default: "新增配置项",
},
type: {
type: String,
default: 'primary'
}
});
const inputValue = ref('')
const inputVisible = ref(false);
const inputRef = ref(undefined);
const handleClose = (index) => {
delete model.value[index];
};
const showInput = () => {
inputVisible.value = true
nextTick(() => {
inputRef.value?.input?.focus();
})
}
const handleInputConfirm = () => {
if (inputValue.value) {
if (inputValue.value.indexOf(":")>0) {
model.value[inputValue.value.split(':')[0].trim()] = inputValue.value.split(':')[1].trim();
} else {
ElMessage.error('输入格式错误');
}
}
inputVisible.value = false
inputValue.value = ''
}
</script>
<style lang="scss" scoped>
.w-tags-input {
display: flex;
flex-wrap: wrap;
&>* {
margin: 0 1em 1em 0;
}
}
</style>

@ -1,136 +0,0 @@
<template>
<div class="w-switch" :class="{ 'w-switch-on': props.modelValue, 'disabled': props.disabled }" @click="handleChange">
<div>
<slot name="off">{{ props.offText }}</slot>
</div>
<div>
<slot name="on">{{ props.onText }}</slot>
</div>
<div></div>
</div>
</template>
<script setup>
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
onText: {
type: String,
default: 'ON'
},
offText: {
type: String,
default: "OFF"
},
disabled: {
type: Boolean,
default: false
}
})
const emit = defineEmits(["change", "update:modelValue"])
const handleChange = () => {
if (props.disabled) {
return;
}
let d = !props.modelValue;
emit("update:modelValue", d);
emit("change", d);
}
</script>
<style lang="scss" scoped>
.w-switch {
position: relative;
min-width: 5em;
line-height: 1;
display: flex;
box-sizing: border-box;
overflow: hidden;
border-radius: 2em;
height: 2em;
color: #FFF;
--off-color: #ccc;
--on-color: #13ce66;
&.disabled {
filter: grayscale(.5);
&::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
cursor: not-allowed;
}
}
&>div {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 2em;
background-color: var(--off-color);
display: flex;
justify-content: center;
align-items: center;
padding: 0 .5em;
transition: all .5s;
&:nth-child(1) {
padding-left: 2em;
}
&:nth-child(2) {
background-color: var(--on-color);
padding-right: 2em;
opacity: 0;
}
&:nth-child(3) {
left: 0;
top: 0;
width: 2em;
height: 2em;
background-color: #FFF;
padding: .3em;
background-clip: content-box;
border-radius: 2em;
}
}
&.w-switch-on>div {
&:nth-child(1) {
opacity: 0;
}
&:nth-child(2) {
opacity: 1;
}
&:nth-child(3) {
left: calc(100% - 2em);
}
}
}
</style>

@ -1,83 +0,0 @@
<template>
<div class="w-tags-input">
<el-tag
v-for="(tag, index) in model"
:key="index"
closable
:disable-transitions="false"
:type="props.type"
@close="handleClose(index)"
>
{{ tag }}
</el-tag>
<el-input
v-if="inputVisible"
ref="inputRef"
v-model="inputValue"
:style="{width:props.placeholder.length+1+'em'}"
size="small"
@keyup.enter="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else class="button-new-tag" size="small" @click="showInput">
{{ props.placeholder }}
</el-button>
</div>
</template>
<script setup>
import { nextTick, ref } from 'vue'
const model = defineModel({
type: Array,
required: true
});
const props = defineProps({
/**
* 输入提示
*/
placeholder: {
type: String,
default: "新增分组",
},
type:{
type:String,
default:'primary'
}
});
const inputValue = ref('')
const inputVisible = ref(false);
const inputRef = ref(undefined);
const handleClose = (index) => {
model.value.splice(index, 1);
};
const showInput = () => {
inputVisible.value = true
nextTick(() => {
inputRef.value?.input?.focus();
})
}
const handleInputConfirm = () => {
if (inputValue.value) {
model.value.push(inputValue.value)
}
inputVisible.value = false
inputValue.value = ''
}
</script>
<style lang="scss" scoped>
.w-tags-input {
display: flex;
flex-wrap: wrap;
& > * {
margin: 0 1em 1em 0;
}
}
</style>

@ -1,51 +1,36 @@
<template>
<div style="width: 100%;">
<el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
:on-error="handleUploadError" class="editor-img-uploader" name="file" :show-file-list="false" :headers="headers"
style="display: none" ref="uploadRef" v-if="type == 'url'">
<div>
<el-upload
:action="uploadUrl"
:before-upload="handleBeforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
class="editor-img-uploader"
name="file"
:show-file-list="false"
:headers="headers"
style="display: none"
ref="uploadRef"
v-if="type == 'url'"
>
</el-upload>
<div class="editor">
<div v-if="!source">
<quill-editor ref="myQuillEditor" v-model:content="content" contentType="html"
@textChange="(e) => $emit('update:modelValue', content)" :options="options" :style="styles" />
</div>
<el-input v-if="source" class="source-textarea" :style="{ height: height + 'px',width:'100%' }" type="textarea"
v-model="content" />
<div style="padding-top: .2em; display: flex; justify-content: flex-end;">
<el-radio-group v-model="source" @change="changeSource">
<el-radio-button label="编辑视图" :value="false" />
<el-radio-button label="源码视图" :value="true" />
</el-radio-group>
</div>
<quill-editor
ref="myQuillEditor"
v-model:content="content"
contentType="html"
@textChange="(e) => $emit('update:modelValue', content)"
:options="options"
:style="styles"
/>
</div>
</div>
</template>
<script setup>
import { QuillEditor, Quill } from '@vueup/vue-quill';
// import ImageResize from 'quill-image-resize-module';
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import { getToken } from "@/utils/auth";
import { ref, computed, onMounted, getCurrentInstance } from 'vue'
// Quill.register(ImageResize)
onMounted(async () => {
await proxy.$nextTick()
height.value = myQuillEditor.value.editor.clientHeight + 42;
})
const changeSource = () => {
if (!source.value) {
console.debug(myQuillEditor.value.editor.clientHeight);
}
}
const props = defineProps({
/* 编辑器的内容 */
@ -76,23 +61,12 @@ const props = defineProps({
type: {
type: String,
default: "url",
},
server: {
type: String,
default: "/system/oss/upload"
},
source: {
type: Boolean,
default: false,
}
});
const source = ref(props.source);
const height = ref(props.height || props.minHeight || 100);
const { proxy } = getCurrentInstance();
//
const uploadUrl = computed(() => import.meta.env.VITE_APP_BASE_API + props.server);
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/system/oss/upload");
const headers = ref({ Authorization: "Bearer " + getToken() });
const myQuillEditor = ref();
@ -106,14 +80,14 @@ const options = ref({
container: [
["bold", "italic", "underline", "strike"], // 线 线
["blockquote", "code-block"], //
[{ list: "ordered" }, { list: "bullet" }], //
[{ list: "ordered" }, { list: "bullet"} ], //
[{ indent: "-1" }, { indent: "+1" }], //
[{ size: ["small", false, "large", "huge"] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], //
[{ align: [] }], //
["clean"], //
["link", "image"] //
["link", "image", "video"] //
],
handlers: {
image: function (value) {
@ -158,7 +132,7 @@ function handleUploadSuccess(res, file) {
//
let length = quill.selection.savedRange.index;
// res
quill.insertEmbed(length, "image", res.data);
quill.insertEmbed(length, "image", res.data.url);
//
quill.setSelection(length + 1);
proxy.$modal.closeLoading();
@ -190,20 +164,16 @@ function handleUploadError(err) {
</script>
<style>
.editor,
.ql-toolbar {
.editor, .ql-toolbar {
white-space: pre-wrap !important;
line-height: normal !important;
}
.quill-img {
display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px;
content: "保存";
@ -218,17 +188,14 @@ function handleUploadError(err) {
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
content: "32px";
@ -238,32 +205,26 @@ function handleUploadError(err) {
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
content: "标题6";
@ -273,21 +234,12 @@ function handleUploadError(err) {
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: "等宽字体";
}
.source-textarea textarea.el-textarea__inner {
resize: none;
height: 100%;
width: 100%;
}
</style>

@ -1,11 +1,13 @@
<template>
<div v-if="env == 'development'">
<svg-icon icon-class="bug" @click="router.push({ path: '/test/index' })" />
<div>
<svg-icon icon-class="github" @click="goto" />
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
const router = useRouter();
const env = import.meta.env.VITE_APP_ENV;
const url = ref('https://gitee.com/JavaLionLi/RuoYi-Vue-Plus');
function goto() {
window.open(url.value)
}
</script>

@ -15,9 +15,6 @@
<el-tooltip content="文档地址" effect="dark" placement="bottom">
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
</el-tooltip> -->
<el-tooltip content="示例代码" effect="dark" placement="bottom">
<ruo-yi-git class="right-menu-item hover-effect" />
</el-tooltip>
<screenfull id="screenfull" class="right-menu-item hover-effect" />
@ -110,7 +107,7 @@ function setLayout() {
height: 50px;
overflow: hidden;
position: relative;
background: #0000;
background: #fff;
// box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {

@ -80,7 +80,7 @@
<script setup>
import variables from '@/assets/styles/variables.module.scss'
import 'element-plus/theme-chalk/index.css'
import originElementPlus from 'element-plus/theme-chalk/index.css'
import axios from 'axios'
import { ElLoading, ElMessage } from 'element-plus'
import { useDynamicTitle } from '@/utils/dynamicTitle'

@ -44,8 +44,8 @@ const sideTheme = computed(() => settingsStore.sideTheme);
.sidebar-logo-container {
position: relative;
width: 100%;
height: 4.5rem;
line-height: 4.5rem;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;

@ -1,27 +1,15 @@
<template>
<div style="box-shadow: 0 0 .5rem #0001;" :class="[showLogo?'has-logo':'no-logo',sideTheme]"
:style="{ backgroundColor: sideTheme === 'theme-dark' ? `var(--admin-menu-bg-dark,${adminDark})` : `var(--admin-menu-bg-light,${adminlight})` }">
<svg style="display: none;">
<defs>
<filter id="WEffectNoiseBgFilter" color-interpolation-filters="linearRGB" filterUnits="objectBoundingBox"
primitiveUnits="userSpaceOnUse">
<feTurbulence type="turbulence" baseFrequency="1 1" numOctaves="100" seed="100" stitchTiles="stitch"
x="-100%" y="-100%" width="300%" height="300%" result="turbulence" />
<feDisplacementMap in="SourceGraphic" in2="turbulence" scale="200" xChannelSelector="R" yChannelSelector="A"
x="-100%" y="-100%" width="300%" height="300%" result="displacementMap" />
</filter>
</defs>
</svg>
<div style="box-shadow: 0 0 .5rem #0001;" :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="sideTheme === 'theme-dark' && isCollapse?`var(--admin-menu-bg-dark,${adminDark})`:'#0000'"
:background-color="sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground"
:text-color="sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor"
:unique-opened="true"
:active-text-color="theme"
:collapse-transition="true"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item
@ -54,10 +42,6 @@ const sideTheme = computed(() => settingsStore.sideTheme);
const theme = computed(() => settingsStore.theme);
const isCollapse = computed(() => !appStore.sidebar.opened);
const adminDark = import.meta.env.VITE_APP_ADMIN_DARK;
const adminlight = import.meta.env.VITE_APP_ADMIN_LIGHT;
const activeMenu = computed(() => {
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set

@ -245,7 +245,7 @@ function handleScroll() {
.tags-view-container {
height: 34px;
width: 100%;
background: #0000;
background: #fff;
border-bottom: 1px solid #d8dce5;
// box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
.tags-view-wrapper {
@ -276,8 +276,9 @@ function handleScroll() {
height: 39px;
padding-top: 3px;
font-size: 13px;
background-color: #42b983;
color: #fff;
border-color: #42b983;
&::before {
content: "";
background: #fff;

@ -3,7 +3,7 @@
<div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
<div :class="{ 'fixed-header': fixedHeader }" style="background-image: linear-gradient(to top, #EEE, #FFF 70%);">
<div :class="{ 'fixed-header': fixedHeader }">
<navbar @setLayout="setLayout" />
<tags-view v-if="needTagsView" />
</div>

@ -6,7 +6,7 @@ import ElementPlus from 'element-plus'
// import locale from 'element-plus/lib/locale/lang/zh-cn' // 中文语言
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import 'normalize.css' // CSS重置样式
import '@/assets/styles/index.scss' // global css
import App from './App'
import { store, useSettingsStore } from './store'

@ -1,4 +1,4 @@
import { createWebHistory, createWebHashHistory, createRouter } from 'vue-router'
import { createWebHistory,createWebHashHistory, createRouter } from 'vue-router'
/* Layout */
import Layout from '@/layout'
@ -24,17 +24,6 @@ import Layout from '@/layout'
}
*/
const env = import.meta.env.VITE_APP_ENV;
const children = []
if (env == 'development') {
const files = import.meta.glob('@/views/test/*.vue');//异步导入
for (let fileName in files) {
let moduleName = fileName.replace(/^.*\/(\w+)\.vue$/, "$1");
children.push({ path: moduleName, component: files[fileName] })
}
}
console.debug(children)
// 公共路由
export const constantRoutes = [
{
@ -94,20 +83,9 @@ export const constantRoutes = [
meta: { title: '个人中心', icon: 'user' }
}
]
}, {
path: '/test',
component: () => import('@/views/test'),
hidden: true,
redirect: '/test/index',
children
}
]
// 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [
{
@ -151,6 +129,20 @@ export const dynamicRoutes = [
meta: { title: '字典数据', activeMenu: '/system/dict' }
}
]
},
{
path: '/system/oss-config',
component: Layout,
hidden: true,
permissions: ['monitor:job:list'],
children: [
{
path: 'index',
component: () => import('@/views/system/oss/config'),
name: 'OssConfig',
meta: { title: '配置管理', activeMenu: '/system/oss'}
}
]
}
]

@ -6,7 +6,7 @@ export default {
/**
* 侧边栏主题 深色主题theme-dark浅色主题theme-light
*/
sideTheme: 'theme-'+import.meta.env.VITE_APP_THEME,
sideTheme: 'theme-light',
/**
* 是否系统布局配置
*/

@ -1,60 +0,0 @@
import CryptoJS from 'crypto-js/crypto-js'
const bufferChunkSize = 1024 * 1024 * 5;
export const fileHash = (file, config={}) => {
config = {
algo: 'MD5',
enc: 'Hex',
onProgress: (a,b)=>{console.debug(a,b)}
,...config
}
return new Promise((resolve, reject) => {
if(file==null || file.size==0){
resolve(null)
return
}
const hash = CryptoJS.algo[config.algo].create()
let count = 0;
const reader = new FileReader()
// 以流的方式读取文件
function readChunk(start, end) {
const slice = file.slice(start, end)
reader.readAsArrayBuffer(slice);
}
// 递归读取文件的每个分块
function processChunk(offset) {
const start = offset;
const end = Math.min(start + bufferChunkSize, file.size)
count = end
readChunk(start, end)
}
// 当读取完整个文件后,计算哈希值并返回
reader.onloadend = function () {
const arrayBuffer = reader.result
const wordArray = CryptoJS.lib.WordArray.create(arrayBuffer)
// 更新哈希对象
hash.update(wordArray)
config.onProgress(count,file.size)
if (count < file.size) {
// 继续处理下一个分块
processChunk(count)
}
else {
// 计算哈希值并返回
const ret = hash.finalize()
resolve(ret.toString(CryptoJS.enc.Hex))
}
}
config.onProgress(count,file.size)
// 开始处理文件内容分块
processChunk(0)
})
}

@ -1,75 +0,0 @@
export { fileHash } from './fileHash'
import CryptoJS from 'crypto-js/crypto-js'
import { encrypt, decrypt } from '../jsencrypt'
const AESKey = "d34xsfljkwSD}2cv32$#%dfdgvcJH{PIOPeopir1KSHD"
/**
* Base64编码
* @param {String} str
* @returns
*/
const Base64Encode = (str) => CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))
/**
* Base64解码
* @param {String} str
* @returns
*/
const Base64Decode = (str) => CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(str))
/**
* 消息摘要md5加密
* @param {String} str
* @returns
*/
const md5 = (str) => CryptoJS.enc.Hex.stringify(CryptoJS.MD5(str))
/**
* 消息摘要sha256加密
* @param {String} str
* @returns
*/
const sha256 = (str) => CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(str))
/**
* 对称加密AES
* @param {String} str
* @returns
*/
const aesEncrypt = (str) => CryptoJS.AES.encrypt(str, AESKey).toString()
/**
* 对称解密AES
* @param {String} str
* @returns
*/
const aesDecrypt = (str) => CryptoJS.AES.decrypt(str, AESKey).toString(CryptoJS.enc.Utf8)
export { CryptoJS, Base64Encode, Base64Decode, md5, sha256, encrypt, decrypt, aesEncrypt, aesDecrypt }
// let str = "https://evoai.cn"
// let strEncode = Base64Encode(str)
// console.debug("Base64Encode", strEncode)
// console.debug("Base64Decode", Base64Decode(strEncode))
// console.debug("md5", md5(str))
// console.debug("sha256", sha256(str))
// strEncode = encrypt(str);
// console.debug("encrypt", strEncode)
// console.debug("decrypt", decrypt(strEncode))
// strEncode = aesEncrypt(str)
// console.debug("aesEncrypt", strEncode)
// console.debug("aesDecrypt", aesDecrypt(strEncode))
// console.debug("Hex.stringify",Hex.stringify(str));
// console.debug("Hex.parse",Hex.parse(Hex.stringify(str)));
// var words = CryptoJS.enc.Base64.parse("SGVsbG8sIFdvcmxkIQ==");
// console.debug(words)

@ -36,12 +36,7 @@ const getUploadKey =async () => {
<li>属性saveSrc是否保存图片原文件如果true则下载时下载原图zip文件否则下载大图片默认false </li>
<li>属性saveMin是否保存缩略图如果true则列表时显示缩略图否则显示大图默认true </li>
<li>属性watermark是否添加水印默认true </li>
<li>属性noEffect是否无效果本质设置css属性默认false </li>
<li>css属性--image-size图片显示大小默认 10em </li>
<li>css属性--image-border-radius图片显示圆角默认 .4em</li>
<li>css属性--image-margin图片外边距默认 .5em .5em 0 0</li>
<li>css属性--image-border图片边框默认 #FFF solid 2px </li>
<li>css属性--image-box-shadow图片阴影默认 0 0 .2em #0005</li>
<li>插槽button上传按钮插槽</li>
<li>插槽default图片列表插槽作用域list不建议定义</li>
<li>事件changemodelValue发送了变化</li>
@ -151,7 +146,7 @@ const { proxy } = getCurrentInstance()
const data = ref(['/files/default/2024/10/24/2nhdirb2ujey/5mb.txt'])
const uploading = ref(false)
const imgs = ref(['/files/default/2024/10/24/d0wt3m3j4tud.webp'])
const imgs = ref(['/files/default/2024/10/24/f99pkzpyc0bt.webp'])
const imging = ref(false)
</script>
<style lang="scss" scoped>

@ -1,20 +1,8 @@
<template>
<div class="w-login-content">
<svg style="display: none;">
<defs>
<filter id="WEffectNoiseBgFilter" color-interpolation-filters="linearRGB" filterUnits="objectBoundingBox"
primitiveUnits="userSpaceOnUse">
<feTurbulence type="turbulence" baseFrequency=".1 .1" numOctaves="100" seed="100" stitchTiles="stitch"
x="-100%" y="-100%" width="300%" height="300%" result="turbulence" />
<feDisplacementMap in="SourceGraphic" in2="turbulence" scale="200" xChannelSelector="R" yChannelSelector="A"
x="-100%" y="-100%" width="300%" height="300%" result="displacementMap" />
</filter>
</defs>
</svg>
<div class="w-login-outer">
<div>
</div>
<div></div>
<div class="w-login-form">
<div>你好!<br />欢迎登录{{ title }}</div>
<div><input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号" /></div>
@ -27,8 +15,8 @@
<img :src="codeUrl" @click="getCode" />
</div>
<div class="h2">
<div><div :class="{selected:loginForm.rememberMe}" @click="loginForm.rememberMe=!loginForm.rememberMe;" class="w-checkbox">记住密码</div></div>
<div ><a href="javascript:void(0);" @click="ElMessageBox.alert('请联系管理员');">?</a></div>
<div><label><input type="checkbox" v-model="loginForm.rememberMe" />记住我</label></div>
<div v-if="false"><a href="javascript:void(0);" @click="ElMessageBox.alert('请联系管理员');">?</a></div>
</div>
<el-button :loading="loading" class="btn" size="large" type="primary" @click.prevent="handleLogin">
<span v-if="!loading"> </span>
@ -37,7 +25,6 @@
<div class="copy">{{ copy }} </div>
</div>
</div>
</div>
</template>
@ -56,7 +43,6 @@ import { ElMessage, ElMessageBox } from "element-plus";
const title = import.meta.env.VITE_APP_TITLE;
const copy = import.meta.env.VITE_APP_COPY;
const color = import.meta.env.VITE_APP_COLOR;
console.debug("login", title, copy, color);
onMounted(() => {
useSettingsStore().title = "登录"
@ -110,16 +96,16 @@ function login() {
}
function handleLogin() {
if (!loginForm.value.username) {
if(!loginForm.value.username){
ElMessage.error("请输入帐号");
return;
}
if (!loginForm.value.password) {
if(!loginForm.value.password){
ElMessage.error("请输入帐号");
return;
}
if (captchaEnabled.value) {
if (!loginForm.value.code) {
if(captchaEnabled.value){
if(!loginForm.value.code) {
ElMessage.error("请输入验证码");
return;
}

@ -29,10 +29,10 @@
<el-switch v-model="row.enabled" @change="handleEnabled(row)" />
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="220" align="center">
<el-table-column label="操作" fixed="right" width="200" align="center">
<template #default="{ row }">
<el-button-group>
<el-button type="success" link @click="proxy.$refs.runRef.open(taskList, row);">手动运行</el-button>
<el-button type="default" link @click="proxy.$refs.runRef.open(taskList, row);">运行</el-button>
<el-button type="default" link @click="subCron(row);"></el-button>
<el-button type="primary" link @click="proxy.$refs.editRef.open(taskList, row);">修改</el-button>
<el-button type="danger" link @click="handleDelete(row)"></el-button>

@ -1,5 +1,4 @@
import request from '@/utils/request'
import SSE from '@/api/SSE'
const base = '/system/cron/'
@ -18,6 +17,4 @@ export const logPage = (params) => request.get(base + 'log-page', { params })
export const current = (group = 0) => request.get(base + 'current-' + group)
export const start = (cronId, taskId, paramEls) => request.post(base + "/start", request.params({ cronId, taskId, paramEls }))
export const doSSE = (groupId = 0, callback) => SSE.post(base + 'sse-' + groupId, {}, callback, { returnData: false })
export const start = (cronId, taskId, paramEls) => request.post(base + "/start", request.params({ cronId, taskId, paramEls }))

@ -1,61 +1,26 @@
<template>
<div class="xf-root">
<div class="search-form">
<el-select
v-model="search.taskId"
style="width: 10em; display: block"
clearable
placeholder="任务"
>
<el-option
v-for="item in taskList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-select v-model="search.taskId" style="width: 10em; display: block;" clearable placeholder="任务">
<el-option v-for="item in taskList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select
v-model="search.ok"
style="width: 6em; display: block"
clearable
placeholder="成败"
>
<el-select v-model="search.ok" style="width: 6em; display: block;" clearable placeholder="成败">
<el-option label="成功" :value="true" />
<el-option label="失败" :value="false" />
</el-select>
<div style="width: 20em">
<el-date-picker
v-model="daterange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</div>
<div style="width: 20em;"><el-date-picker v-model="daterange" value-format="YYYY-MM-DD" type="daterange"
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" /></div>
<el-button type="default" @click="handleSearch"></el-button>
<el-badge
:value="cList.length"
style="margin-left: auto; margin-right: 1em"
>
<el-button
:disabled="cList.length == 0"
type="primary"
plain
@click="cShow = true"
>运行中</el-button
>
<el-badge :value="cList.length" style="margin-left: auto; margin-right: 1em;">
<el-button :disabled="cList.length == 0" type="primary" plain @click="cShow = true">运行中</el-button>
</el-badge>
<el-button
type="primary"
@click="proxy.$refs.cronListRef.open(taskList, query.groupId)"
>定时任务</el-button
>
<el-button type="primary" @click="proxy.$refs.cronListRef.open(taskList, query.groupId);">定时任务</el-button>
</div>
<el-table :data="list" border stripe height="100%" v-loading="loading">
<el-table-column label="任务名称" align="left">
<template #default="{ row }">
{{ taskList.find((a) => a.id == row.taskId)?.name || "未知任务" }}
{{ taskList.find(a => a.id == row.taskId)?.name || '未知任务' }}
</template>
</el-table-column>
<el-table-column label="执行结果" align="left">
@ -65,7 +30,7 @@
<template #reference>
<el-button type="success" link>执行成功</el-button>
</template>
<div style="width: 100%; height: 400px; overflow: auto">
<div style="width: 100%; height: 400px; overflow: auto;">
<pre>{{ row.ex }}</pre>
</div>
</el-popover>
@ -73,11 +38,9 @@
<template v-else>
<el-popover placement="bottom" :width="800" trigger="hover">
<template #reference>
<el-button type="danger" link>{{
row.msg || "未知异常"
}}</el-button>
<el-button type="danger" link>{{ row.msg || '未知异常' }}</el-button>
</template>
<div style="width: 100%; height: 400px; overflow: auto">
<div style="width: 100%; height: 400px; overflow: auto;">
<pre>{{ row.ex }}</pre>
</div>
</el-popover>
@ -86,13 +49,15 @@
</el-table-column>
<el-table-column label="参数" align="center" width="100">
<template #default="{ row }">
<template v-if="!row.params"> </template>
<template v-if="!row.params">
</template>
<template v-else>
<el-popover placement="bottom" :width="300" trigger="hover">
<template #reference>
{{ JSON.parse(row.params).length }}个参数
</template>
<div style="width: 100%; height: 200px; overflow: auto">
<div style="width: 100%; height: 200px; overflow: auto;">
<pre>{{ JSON.stringify(JSON.parse(row.params), null, 2) }}</pre>
</div>
</el-popover>
@ -100,70 +65,36 @@
</template>
</el-table-column>
<el-table-column
label="启动时间"
align="center"
width="170"
prop="startTime"
/>
<el-table-column label="启动时间" align="center" width="170" prop="startTime" />
<el-table-column label="耗时" align="center" width="100">
<template #default="{ row }">
{{ times(row) }}
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:page-sizes="[10, 20, 50]"
:total="total"
v-model:page="query.current"
v-model:limit="query.size"
@pagination="loadPage"
/>
<pagination v-show="total > 0" :page-sizes="[10, 20, 50]" :total="total" v-model:page="query.current"
v-model:limit="query.size" @pagination="loadPage" />
<w-cron-list ref="cronListRef" />
<el-drawer
direction="rtl"
size="40%"
title="正在运行的任务"
v-model="cShow"
>
<el-drawer direction="rtl" size="40%" title="正在运行的任务" v-model="cShow">
<el-collapse :modelValue="0" accordion>
<el-collapse-item v-for="row in cList" :key="row.id">
<template #title>
<div
style="
display: grid;
width: 100%;
grid-template-columns: 2fr 1fr 1fr;
"
>
<div style="font-weight: bold; text-align: left">
{{
taskList.find((a) => a.id == row.taskId)?.name || "未知任务"
}}
</div>
<div>
{{
row.startTime.toDate("yyyy-MM-dd HH:mm:ss").format("HH:mm:ss")
}}
</div>
<div
style="
display: flex;
align-items: center;
justify-content: center;
"
>
<div class="w-loading" style="margin-right: 0.5em"></div>
运行中
<div style="display: grid; width: 100%; grid-template-columns: 2fr 1fr 1fr; ">
<div style="font-weight: bold; text-align: left;"> {{ taskList.find(a => a.id == row.taskId)?.name ||
'未知任务' }}</div>
<div>{{ row.startTime.toDate("yyyy-MM-dd HH:mm:ss").format("HH:mm:ss") }}</div>
<div style="display: flex; align-items: center; justify-content: center;">
<div class="w-loading" style="margin-right: .5em;"></div> 运行中
</div>
</div>
</template>
<div style="width: 100%; height: 400px; overflow: auto">
<div style="width: 100%; height: 400px; overflow: auto;">
<pre>{{ row.ex }}</pre>
</div>
</el-collapse-item>
@ -172,23 +103,15 @@
</div>
</template>
<script setup>
import WCronList from "./components/WCronList.vue";
import {
ref,
getCurrentInstance,
watch,
onMounted,
computed,
onUnmounted,
} from "vue";
import { ElLoading, ElMessage } from "element-plus";
import * as api from "./cron";
import WCronList from './components/WCronList.vue'
import { ref, getCurrentInstance, watch, onMounted, computed, onUnmounted } from 'vue'
import { ElLoading, ElMessage } from 'element-plus'
import * as api from './cron'
const daterange = computed({
get() {
return search.value.beginDate
? [search.value.beginDate, search.value.endDate]
: [];
return search.value.beginDate ? [search.value.beginDate, search.value.endDate] : []
},
set(value) {
if (value && value[0]) {
@ -198,17 +121,13 @@ const daterange = computed({
search.value.beginDate = "";
search.value.endDate = "";
}
},
});
}
})
const { proxy } = getCurrentInstance();
const { proxy } = getCurrentInstance()
const times = (a) =>
(
(a.endTime.toDate("yyyy-MM-dd HH:mm:ss") -
a.startTime.toDate("yyyy-MM-dd HH:mm:ss")) /
1000
).toTime();
const times = (a) => ((a.endTime.toDate("yyyy-MM-dd HH:mm:ss") - a.startTime.toDate("yyyy-MM-dd HH:mm:ss")) / 1000).toTime()
//
const search = ref({});
@ -216,7 +135,7 @@ const search = ref({});
const query = ref({
current: 1,
size: 10,
orderBy: "endTime desc",
orderBy: 'endTime desc'
});
//
@ -234,64 +153,57 @@ const loadPage = async () => {
list.value = r.data?.records || [];
total.value = Number(r.data?.total || 0);
loading.value = false;
};
}
//
const handleSearch = () => {
query.value = { ...query.value, ...search.value };
query.value.current = 1;
loadPage();
};
}
const taskList = ref([]);
const taskList = ref([])
const init = async () => {
let r = await api.list(proxy.$route.query.group || 0);
taskList.value = r.data;
let r = await api.list(proxy.$route.query.group || 0)
taskList.value = r.data
query.value.groupId = proxy.$route.query.group || 0
handleSearch()
}
query.value.groupId = proxy.$route.query.group || 0;
handleSearch();
};
const cList = ref([]);
const cShow = ref(false);
const cList = ref([])
const cShow = ref(false)
watch(
() => cList.value.length,
() => {
() => cList.value.length, () => {
handleSearch();
if (cList.value.length == 0) {
cShow.value = false;
}
}
);
)
let sse = null;
let timer = null;
onMounted(async () => {
await proxy.$nextTick();
await init();
let r = await api.current(query.value.groupId);
cList.value = r.data;
sse = api.doSSE(query.value.groupId, (data) => {
if (data.action == "list") {
cList.value = data.data;
} else if (data.action == "log") {
let item = cList.value.find((item) => item.id == data.data.logId);
if (item) {
if (item.ex) {
item.ex += "\n" + (data.data.ex || "");
} else {
item.ex = data.data.ex || "";
}
}
}
});
});
await proxy.$nextTick()
await init()
timer = window.setInterval(async () => {
let r = await api.current(query.value.groupId)
cList.value = r.data
}, 500);
})
onUnmounted(() => {
sse.close();
});
window.clearInterval(timer)
})
</script>
<style lang="scss" scoped>
.xf-root {
@ -301,11 +213,11 @@ onUnmounted(() => {
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 0 0 0.3rem 0;
padding: 0 0 .3rem 0;
position: relative;
& > * {
margin: 0 0.5rem 0.5rem 0;
&>* {
margin: 0 .5rem .5rem 0;
display: flex;
align-items: center;
}

@ -0,0 +1,382 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="配置key" prop="configKey">
<el-input
v-model="queryParams.configKey"
placeholder="配置key"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="桶名称" prop="bucketName">
<el-input
v-model="queryParams.bucketName"
placeholder="请输入桶名称"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="是否默认" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 200px">
<el-option key="0" label="是" value="0"/>
<el-option key="1" label="否" value="1"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['system:oss:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:oss:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ossConfigList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主建" align="center" prop="ossConfigId" v-if="columns[0].visible"/>
<el-table-column label="配置key" align="center" prop="configKey" v-if="columns[1].visible" />
<el-table-column label="访问站点" align="center" prop="endpoint" v-if="columns[2].visible" width="200" />
<el-table-column label="自定义域名" align="center" prop="domain" v-if="columns[3].visible" width="200" />
<el-table-column label="桶名称" align="center" prop="bucketName" v-if="columns[4].visible" />
<el-table-column label="前缀" align="center" prop="prefix" v-if="columns[5].visible" />
<el-table-column label="域" align="center" prop="region" v-if="columns[6].visible" />
<el-table-column label="桶权限类型" align="center" prop="accessPolicy" v-if="columns[7].visible" >
<template #default="scope">
<el-tag type="warning" v-if="scope.row.accessPolicy === '0'">private</el-tag>
<el-tag type="success" v-if="scope.row.accessPolicy === '1'">public</el-tag>
<el-tag type="info" v-if="scope.row.accessPolicy === '2'">custom</el-tag>
</template>
</el-table-column>
<el-table-column label="是否默认" align="center" prop="status" v-if="columns[8].visible">
<template #default="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:oss:edit']"></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改对象存储配置对话框 -->
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
<el-form ref="ossConfigRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="配置key" prop="configKey">
<el-input v-model="form.configKey" placeholder="请输入配置key" />
</el-form-item>
<el-form-item label="访问站点" prop="endpoint">
<el-input v-model="form.endpoint" placeholder="请输入访问站点" />
</el-form-item>
<el-form-item label="自定义域名" prop="domain">
<el-input v-model="form.domain" placeholder="请输入自定义域名" />
</el-form-item>
<el-form-item label="accessKey" prop="accessKey">
<el-input v-model="form.accessKey" placeholder="请输入accessKey" />
</el-form-item>
<el-form-item label="secretKey" prop="secretKey">
<el-input v-model="form.secretKey" placeholder="请输入秘钥" show-password />
</el-form-item>
<el-form-item label="桶名称" prop="bucketName">
<el-input v-model="form.bucketName" placeholder="请输入桶名称" />
</el-form-item>
<el-form-item label="前缀" prop="prefix">
<el-input v-model="form.prefix" placeholder="请输入前缀" />
</el-form-item>
<el-form-item label="是否HTTPS">
<el-radio-group v-model="form.isHttps">
<el-radio
v-for="dict in sys_yes_no"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="桶权限类型">
<el-radio-group v-model="form.accessPolicy">
<el-radio label="0">private</el-radio>
<el-radio label="1">public</el-radio>
<el-radio label="2">custom</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="域" prop="region">
<el-input v-model="form.region" placeholder="请输入域" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="OssConfig">
import {
listOssConfig,
getOssConfig,
delOssConfig,
addOssConfig,
updateOssConfig,
changeOssConfigStatus
} from "@/api/system/ossConfig";
const { proxy } = getCurrentInstance();
const { sys_yes_no } = proxy.useDict("sys_yes_no");
const ossConfigList = ref([]);
const open = ref(false);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
//
const columns = ref([
{ key: 0, label: `主建`, visible: true },
{ key: 1, label: `配置key`, visible: false },
{ key: 2, label: `访问站点`, visible: true },
{ key: 3, label: `自定义域名`, visible: true },
{ key: 4, label: `桶名称`, visible: true },
{ key: 5, label: `前缀`, visible: true },
{ key: 6, label: ``, visible: true },
{ key: 7, label: `桶权限类型`, visible: true },
{ key: 8, label: `状态`, visible: true }
]);
const data = reactive({
form: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
configKey: undefined,
bucketName: undefined,
status: undefined,
},
rules: {
configKey: [
{ required: true, message: "configKey不能为空", trigger: "blur" },
],
accessKey: [
{ required: true, message: "accessKey不能为空", trigger: "blur" },
{
min: 2,
max: 200,
message: "accessKey长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
secretKey: [
{ required: true, message: "secretKey不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "secretKey长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
bucketName: [
{ required: true, message: "bucketName不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "bucketName长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
endpoint: [
{ required: true, message: "endpoint不能为空", trigger: "blur" },
{
min: 2,
max: 100,
message: "endpoint名称长度必须介于 2 和 100 之间",
trigger: "blur",
},
],
accessPolicy:[
{ required: true, message: "accessPolicy不能为空", trigger: "blur" }
]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询对象存储配置列表 */
function getList() {
loading.value = true;
listOssConfig(queryParams.value).then((response) => {
ossConfigList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 表单重置 */
function reset() {
form.value = {
ossConfigId: undefined,
configKey: undefined,
accessKey: undefined,
secretKey: undefined,
bucketName: undefined,
prefix: undefined,
endpoint: undefined,
domain: undefined,
isHttps: "N",
accessPolicy: "1",
region: undefined,
status: "1",
remark: undefined,
};
proxy.resetForm("ossConfigRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
/** 选择条数 */
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.ossConfigId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加对象存储配置";
}
/** 修改按钮操作 */
function handleUpdate(row) {
loading.value = true;
reset();
const ossConfigId = row.ossConfigId || ids.value;
getOssConfig(ossConfigId).then((response) => {
loading.value = false;
form.value = response.data;
open.value = true;
title.value = "修改对象存储配置";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["ossConfigRef"].validate(valid => {
if (valid) {
buttonLoading.value = true;
if (form.value.ossConfigId != null) {
updateOssConfig(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
}).finally(() => {
buttonLoading.value = false;
});
} else {
addOssConfig(this.form).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
}).finally(() => {
buttonLoading.value = false;
});
}
}
});
}
/** 用户状态修改 */
function handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
proxy.$modal.confirm('确认要"' + text + '""' + row.configKey + '"配置吗?').then(() => {
return changeOssConfigStatus(row.ossConfigId, row.status, row.configKey);
}).then(() => {
getList()
proxy.$modal.msgSuccess(text + "成功");
}).catch(function () {
row.status = row.status === "0" ? "1" : "0";
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const ossConfigIds = row.ossConfigId || ids.value;
proxy.$modal.confirm('是否确认删除OSS配置编号为"' + ossConfigIds + '"的数据项?').then(() => {
loading.value = true;
return delOssConfig(ossConfigIds);
}).then(() => {
loading.value = false;
getList();
proxy.$modal.msgSuccess("删除成功");
}).finally(() => {
loading.value = false;
});
}
getList();
</script>

@ -0,0 +1,374 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="文件名" prop="fileName">
<el-input
v-model="queryParams.fileName"
placeholder="请输入文件名"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="原名" prop="originalName">
<el-input
v-model="queryParams.originalName"
placeholder="请输入原名"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="文件后缀" prop="fileSuffix">
<el-input
v-model="queryParams.fileSuffix"
placeholder="请输入文件后缀"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
></el-date-picker>
</el-form-item>
<el-form-item label="上传人" prop="createBy">
<el-input
v-model="queryParams.createBy"
placeholder="请输入上传人"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="服务商" prop="service">
<el-input
v-model="queryParams.service"
placeholder="请输入服务商"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleFile"
v-hasPermi="['system:oss:upload']"
>上传文件</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleImage"
v-hasPermi="['system:oss:upload']"
>上传图片</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:oss:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
:type="previewListResource ? 'danger' : 'warning'"
plain
@click="handlePreviewListResource(!previewListResource)"
v-hasPermi="['system:oss:edit']"
>预览开关 : {{previewListResource ? "禁用" : "启用"}}</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Operation"
@click="handleOssConfig"
v-hasPermi="['system:oss:list']"
>配置管理</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="ossList" @selection-change="handleSelectionChange"
:header-cell-class-name="handleHeaderClass"
@header-click="handleHeaderCLick"
v-if="showTable">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="对象存储主键" align="center" prop="ossId" v-if="false"/>
<el-table-column label="文件名" align="center" prop="fileName" />
<el-table-column label="原名" align="center" prop="originalName" />
<el-table-column label="文件后缀" align="center" prop="fileSuffix" />
<el-table-column label="文件展示" align="center" prop="url">
<template #default="scope">
<ImagePreview
v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)"
:width="100" :height="100"
:src="scope.row.url"
:preview-src-list="[scope.row.url]"/>
<span v-text="scope.row.url"
v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180" sortable="custom">
<template #default="scope">
<span>{{ scope.row.createTime}}</span>
</template>
</el-table-column>
<el-table-column label="上传人" align="center" prop="createBy" />
<el-table-column label="服务商" align="center" prop="service" sortable="custom"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleDownload(scope.row)" v-hasPermi="['system:oss:download']"></el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:oss:remove']"></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改OSS对象存储对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="ossRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文件名">
<fileUpload v-model="form.file" v-if="type === 0"/>
<imageUpload v-model="form.file" v-if="type === 1"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Oss">
import { listOss, delOss } from "@/api/system/oss";
import ImagePreview from "@/components/ImagePreview/index.vue";
const router = useRouter();
const { proxy } = getCurrentInstance();
const ossList = ref([]);
const open = ref(false);
const showTable = ref(true);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const type = ref(0);
const previewListResource = ref(true);
const daterangeCreateTime = ref([]);
//
const defaultSort = ref({prop: 'createTime', order: 'desc'});
const data = reactive({
form: {},
//
queryParams: {
pageNum: 1,
pageSize: 10,
fileName: undefined,
originalName: undefined,
fileSuffix: undefined,
url: undefined,
createTime: undefined,
createBy: undefined,
service: undefined
},
rules: {
file: [
{ required: true, message: "文件不能为空", trigger: "blur" }
]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询OSS对象存储列表 */
function getList() {
loading.value = true;
proxy.getConfigKey("sys.oss.previewListResource").then(response => {
previewListResource.value = response.msg === undefined ? true : response.msg === 'true';
});
listOss(proxy.addDateRange(queryParams.value, daterangeCreateTime.value, "CreateTime")).then(response => {
ossList.value = response.rows;
total.value = response.total;
loading.value = false;
showTable.value = true;
});
}
function checkFileSuffix(fileSuffix) {
let arr = ["png", "jpg", "jpeg","webp","gif"];
return arr.some(type => {
return fileSuffix.indexOf(type) > -1;
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 表单重置 */
function reset() {
form.value = {
file: undefined,
};
proxy.resetForm("ossRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
showTable.value = false;
daterangeCreateTime.value = [];
proxy.resetForm("queryRef");
queryParams.value.orderByColumn = defaultSort.value.prop;
queryParams.value.isAsc = defaultSort.value.order;
handleQuery();
}
/** 选择条数 */
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.ossId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
//
function handleHeaderClass({column}) {
column.order = column.multiOrder
}
//
function handleHeaderCLick(column) {
if (column.sortable !== 'custom') {
return
}
switch (column.multiOrder) {
case 'descending':
column.multiOrder = 'ascending';
break;
case 'ascending':
column.multiOrder = '';
break;
default:
column.multiOrder = 'descending';
break;
}
handleOrderChange(column.property, column.multiOrder)
}
function handleOrderChange(prop, order) {
let orderByArr = queryParams.value.orderByColumn ? queryParams.value.orderByColumn.split(",") : [];
let isAscArr = queryParams.value.isAsc ? queryParams.value.isAsc.split(",") : [];
let propIndex = orderByArr.indexOf(prop)
if (propIndex !== -1) {
if (order) {
//
isAscArr[propIndex] = order;
} else {
//ordernull
isAscArr.splice(propIndex, 1);//
orderByArr.splice(propIndex, 1);//
}
} else {
//
orderByArr.push(prop);
isAscArr.push(order);
}
//
queryParams.value.orderByColumn = orderByArr.join(",");
queryParams.value.isAsc = isAscArr.join(",");
getList();
}
/** 任务日志列表查询 */
function handleOssConfig() {
router.push('/system/oss-config/index')
}
/** 文件按钮操作 */
function handleFile() {
reset();
open.value = true;
title.value = "上传文件";
type.value = 0;
}
/** 图片按钮操作 */
function handleImage() {
reset();
open.value = true;
title.value = "上传图片";
type.value = 1;
}
/** 提交按钮 */
function submitForm() {
open.value = false;
getList();
}
/** 下载按钮操作 */
function handleDownload(row) {
proxy.$download.oss(row.ossId)
}
/** 用户状态修改 */
function handlePreviewListResource(previewListResource) {
let text = previewListResource ? "启用" : "停用";
proxy.$modal.confirm('确认要"' + text + '""预览列表图片"配置吗?').then(() => {
return proxy.updateConfigByKey("sys.oss.previewListResource", previewListResource);
}).then(() => {
getList()
proxy.$modal.msgSuccess(text + "成功");
}).catch(function () {
previewListResource.value = previewListResource.value !== true;
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const ossIds = row.ossId || ids.value;
proxy.$modal.confirm('是否确认删除OSS对象存储编号为"' + ossIds + '"的数据项?').then(() => {
loading.value = true;
return delOss(ossIds);
}).then(() => {
loading.value = false;
getList();
proxy.$modal.msgSuccess("删除成功");
}).finally(() => {
loading.value = false;
});
}
getList();
</script>

@ -1,103 +0,0 @@
<template>
<div class="w-test">
<div>
<div>
<router-link to="/">系统首页</router-link>
<router-link v-for="(path,index) in list" :to="'./'+path" :key="index">{{ path }}</router-link>
</div>
</div>
<div>
<div>
<router-view />
</div>
</div>
</div>
</template>
<script setup>
const list = ref([]);
let files = import.meta.glob("./test/*.vue");
for (let fileName in files) {
let moduleName = fileName.replace(/^.*\/(\w+)\.vue$/, "$1");
if (moduleName == "index") {
continue;
}
list.value.push(moduleName);
}
list.value.sort((a, b) => a.localeCompare(b));
list.value.unshift("index");
</script>
<style lang="scss" scoped>
.w-test {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 10rem 1fr;
gap: 2rem;
& > div {
position: relative;
& > div {
position: absolute;
width: 100%;
height: 100%;
}
&:last-child > div {
overflow: auto;
}
&:first-child {
background-image: linear-gradient(to right, #fff 70%, #0001);
& > div {
padding: 1rem 0;
& > a {
display: flex;
font-size: 0.9rem;
position: relative;
height: 2rem;
align-items: center;
justify-content: center;
transition: all 0.5s;
margin: 0.3rem 0;
color: var(--el-color-primary-dark-2);
border: solid 0.1rem #0000;
&:not(.router-link-exact-active):hover {
background-color: #fff;
color: var(--el-color-primary-dark-3);
border: solid 0.1rem var(--el-color-primary-dark-3);
transform: scale(0.95);
}
&::after {
content: "";
position: absolute;
box-sizing: border-box;
right: 0rem;
width: 1rem;
height: 2rem;
border: solid 1rem #0000;
border-right-width: 0;
border-left-color: var(--c, #0000);
transition: all 0.5s;
}
&.router-link-exact-active {
--c: var(--el-color-primary-dark-2);
background-color: var(--c);
color: #fff;
transform: scale(1.05);
&:hover {
--c: var(--el-color-primary-dark-3);
}
&::after {
right: -1rem;
}
}
}
}
}
}
}
</style>

@ -1,51 +0,0 @@
<template>
<div style="font-size: .7rem;">
<h1>图标</h1>
<w-code language="html">{{ `<w-icon icon-class="404" />
<w-icon icon-class="404" class-name="icon-test" color="var(--el-color-error)" style="font-size: 10em; color: var(--el-color-primary);" />
.icon-test {
color: var(--el-color-success);
font-size: 5em;
}
` }}</w-code>
<w-icon icon-class="404" />
<w-icon icon-class="404" class-name="icon-test" color="var(--el-color-error)" style="font-size: 10em; color: var(--el-color-primary);" />
<h2>使用说明</h2>
<ol style="margin: 1em 2em;">
<li>icon-class: 必填图片类别自定义的图片请放入/src/assets/icons/目录下</li>
<li>color: 图标颜色,优先级高本质定义svg的fill属性</li>
<li>class-name: 使用的css类名可以定义颜色和字体大小</li>
<li>style: 可以定义定义颜色和字体大小</li>
</ol>
<div class="w-flex icons">
<div v-for="item in icons" :key="item" class="w-flex-column">
<w-icon :icon-class="item" />
{{ item }}
</div>
</div>
</div>
</template>
<script setup>
import icons from "@/components/IconSelect/requireIcons";
</script>
<style lang="scss" scoped>
.icon-test {
color: var(--el-color-success);
font-size: 5em;
}
.icons {
flex-wrap: wrap;
justify-content: flex-start;
padding: 2em;
& > div {
padding: 2em;
svg {
width: 5em;
height: 5em;
margin-bottom: 0.5em;
color: var(--w-main);
}
}
}
</style>

@ -1,11 +0,0 @@
<template>
<div>
<h1>示例首页</h1>
<div>直接在@/views/test/下创建vue文件</div>
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>

@ -1,9 +0,0 @@
<template>
<div></div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>

@ -1,168 +0,0 @@
<template>
<div style="margin: 1rem;">
<el-tabs type="border-card">
<el-tab-pane label="图片上传组件">
<div style="padding: 1rem;">
<div>
图片上传组件说明
<ol style="font-size: .8rem; line-height: 1.8;">
<li>基础用法 &lt;w-image-uploader v-model="value" :getUploadKey="getUploadKey" max="1"
v-model:uploading="uploading" /&gt;</li>
<li>属性getUploadKey获取上传凭证的方法需要使用者提供开发模式下提供:<br />
前端示例<br />
<pre class="code">
const getUploadKey =async () => {
let r = await request.get("/file/upload/getUploadKey")
return r.data
} </pre>
后端示例<br />
<pre class="code"> @GetMapping("getUploadKey")
public R getUploadKey() {
return R.ok().setData(FileUtils.getUploadKey());
}</pre>
</li>
<li>属性v-model双向绑定上传的文件URL,max=1是类型为String,否则为Array</li>
<li>属性v-model:uploading双向绑定是否上传中,PS: 上传完成后才允许业务表单提交</li>
<li>属性max允许上传的文件数量0表示没有限制,默认0</li>
<li>属性prefix上传路径前缀默认default</li>
<li>属性disabled禁止上传图片预览模式 默认false</li>
<li>属性text按钮文字默认上传图片</li>
<li>属性maxSize允许上传的文件最大大小,0表示不限制默认0</li>
<li>属性threadNum并行上传数量默认2</li>
<li>属性retry重试次数默认3 </li>
<li>属性saveSrc是否保存图片原文件如果true则下载时下载原图zip文件否则下载大图片默认false </li>
<li>属性saveMin是否保存缩略图如果true则列表时显示缩略图否则显示大图默认true </li>
<li>属性watermark是否添加水印默认true </li>
<li>属性noEffect是否无效果本质设置css属性默认false </li>
<li>属性list是否显示列表默认true</li>
<li>属性before文件添加之前的方法返回true则继续</li>
<li>css属性--image-size图片显示大小默认 10em </li>
<li>css属性--image-border-radius图片显示圆角默认 .4em</li>
<li>css属性--image-margin图片外边距默认 .5em .5em 0 0</li>
<li>css属性--image-border图片边框默认 #FFF solid 2px </li>
<li>css属性--image-box-shadow图片阴影默认 0 0 .2em #0005</li>
<li>插槽button上传按钮插槽</li>
<li>插槽default图片列表插槽作用域list不建议定义</li>
<li>事件changemodelValue发送了变化</li>
</ol>
</div>
<el-divider>单图片上传</el-divider>
<w-image-uploader v-model="imgs[0]" saveSrc max="1" v-model:uploading="imging" />
<pre>绑定值{{ imgs[0] }}</pre>
<div>{{ imging ? '上传中' : '没有上传' }}
<w-image-view ref="imgView" />
<el-button @click="proxy.$refs.imgView.open(imgs[0])"></el-button>
</div>
<el-divider>9张图片上传</el-divider>
<div style="width: 50em;"><w-image-uploader v-model="imgs[1]" saveSrc max="9" text="9张图片上传"
style="--image-size:15em;" /></div>
<pre>绑定值{{ imgs[1] }}</pre>
<el-divider>预览模式</el-divider>
<w-image-uploader style="width: 35em;" disabled :modelValue="[
'/files/default/2024/10/24/d0wt3m3j4tud.webp',
'/files/default/2024/10/24/4x53htt9v8j1.webp',
'/files/default/2024/10/24/1trnacdjxeoju.webp',
'/files/default/2024/10/24/742tvr5pq526.webp',
'/files/default/2024/10/24/1dg74ibgi0xbj.webp',
'/files/default/2024/10/24/1bgesfnixpfvt.webp',
'/files/default/2024/10/24/h1legy4o8tko.webp',
'/files/default/2024/10/24/9xe6yyoed9dj.webp'
]" />
</div>
</el-tab-pane>
<el-tab-pane label="文件上传组件">
<div style="padding: 1rem;">
<div>
文件上传组件说明
<ol style="font-size: .8rem; line-height: 1.8;">
<li>基础用法 &lt;w-file-uploader v-model="value" :getUploadKey="getUploadKey" max="1"
v-model:uploading="uploading" /&gt;</li>
<li>大小大于chunksize的大文件上传会自动分片上传</li>
<li>属性getUploadKey获取上传凭证的方法需要使用者提供开发模式下提供:<br />
前端示例<br />
<pre class="code">
const getUploadKey =async () => {
let r = await request.get("/file/upload/getUploadKey")
return r.data
} </pre>
后端示例<br />
<pre class="code"> @GetMapping("getUploadKey")
public R getUploadKey() {
return R.ok().setData(FileUtils.getUploadKey());
}</pre>
</li>
<li>属性v-model双向绑定上传的文件URL,max=1是类型为String,否则为Array</li>
<li>属性v-model:uploading双向绑定是否上传中,PS: 上传完成后才允许业务表单提交</li>
<li>属性max允许上传的文件数量0表示没有限制,默认0</li>
<li>属性prefix上传路径前缀默认default</li>
<li>属性keepFilename是否保留文件名, 默认true</li>
<li>属性disabled禁止上传文件预览模式 默认false</li>
<li>属性text按钮文字默认上传文件</li>
<li>属性accept允许上传的文件扩展名列表默认'' ,office:'.doc,.docx,.ppt,.pptx,.xls,.xlsx'</li>
<li>属性maxSize允许上传的文件最大大小,0表示不限制默认0</li>
<li>属性threadNum并行上传数量默认2</li>
<li>属性retry重试次数默认3 </li>
<li>属性chunksize分片大小默认5Mb不建议修改</li>
<li>属性list是否显示列表默认true</li>
<li>属性border文件项是否显示边框默认true</li>
<li>属性before文件添加之前的方法返回true则继续</li>
<li>插槽button上传按钮插槽</li>
<li>插槽default文件列表作用域list不建议定义</li>
<li>事件changemodelValue发送了变化</li>
</ol>
</div>
<el-divider>单文件上传</el-divider>
<w-file-uploader v-model="data[0]" max="1" v-model:uploading="uploading" />
<pre>绑定值{{ data[0] }}</pre>
<div>{{ uploading ? '上传中' : '没有上传' }}</div>
<el-divider>预览模式</el-divider>
<w-file-uploader v-model="data[0]" max="1" :border="false" disabled />
<el-divider>单word文件小于10kb上传</el-divider>
<w-file-uploader v-model="data[1]" max="1" accept=".docx,.doc" text="单word文件小于10kb上传" :max-size="10240" />
<pre>绑定值{{ data[1] }}</pre>
<el-divider>多文件上传</el-divider>
<w-file-uploader v-model="data[2]" max="2" />
<pre>绑定值{{ data[2] }}</pre>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup>
import { ref, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const data = ref(['/files/default/2024/10/24/2nhdirb2ujey/5mb.txt'])
const uploading = ref(false)
const imgs = ref(['/files/default/2024/10/24/d0wt3m3j4tud.webp'])
const imging = ref(false)
</script>
<style lang="scss" scoped>
.code {
border: solid 1px #0001;
margin: .5rem;
padding: .5rem;
border-radius: .3rem;
}
</style>

@ -1,20 +1,11 @@
import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import createVitePlugins from './vite/plugins'
import px2rem from 'postcss-plugin-px2rem'
// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
return {
build: {
target: 'es2020',
},
optimizeDeps: {
esbuildOptions: {
target: 'es2020',
},
},
// 部署生产环境和开发环境下的URL。
// 默认情况下vite 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
@ -34,9 +25,9 @@ export default defineConfig(({ mode, command }) => {
// vite 相关配置
server: {
hmr: true,
port: 8888,
port: 80,
host: true,
open: false,
open: true,
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
@ -49,7 +40,7 @@ export default defineConfig(({ mode, command }) => {
changeOrigin: true
},
'/files': {
target: 'http://192.168.3.56:9000',
target: 'http://192.168.3.222:9000',
changeOrigin: true
}
}
@ -58,18 +49,6 @@ export default defineConfig(({ mode, command }) => {
css: {
postcss: {
plugins: [
px2rem({
rootValue: 19.2, //换算基数, 默认100 ,也就是1440px 这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多少px了
unitPrecision: 5, //允许REM单位增长到的十进制数字其实就是精度控制
// propWhiteList: [], // 默认值是一个空数组,这意味着禁用白名单并启用所有属性。
// propBlackList: [], // 黑名单
// exclude:false, //默认false可以reg利用正则表达式排除某些文件夹的方法例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem请把此属性设为默认值
// selectorBlackList: [], //要忽略并保留为px的选择器
// ignoreIdentifier: false, //boolean/string忽略单个属性的方法启用ignoreidentifier后replace将自动设置为true。
// replace: true, // 布尔值替换包含REM的规则而不是添加回退。
mediaQuery: false, //布尔值允许在媒体查询中转换px
minPixelValue: 0 //设置要替换的最小像素值(3px会被转rem)。 默认 0
}),
{
postcssPlugin: 'internal:charset-removal',
AtRule: {

@ -1,34 +0,0 @@
# Dependencies
node_modules/
# Logs
logs/
*.log
# Environment files
.env*
# IDE files
.vscode/
.idea/
# OS generated files
.DS_Store
Thumbs.db
# Build outputs
dist/
build/
# PM2 logs
.pm2/
# Docker
.dockerignore
# pnpm
pnpm-lock.yaml
# Temporary files
*.tmp
*.temp

@ -1,35 +0,0 @@
# Use the official Node.js image as the base image
FROM node:22.16.0 AS builder
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json (if available) to the working directory
COPY package*.json ./
# Install the application dependencies
RUN npm install
# Copy the rest of the application code to the working directory
COPY . .
# Production stage
FROM node:22.16.0-alpine AS production
# Set the working directory inside the container
WORKDIR /app
# Copy dependencies from builder stage
COPY --from=builder /app/node_modules ./node_modules
# Copy application code from builder stage
COPY --from=builder /app/. .
# Install pm2 globally
RUN npm install -g pm2
# Expose the port that the application listens on
EXPOSE 3000
# Define the command to run the application in production mode with pm2.json config
CMD ["pm2", "start", "pm2.json", "--no-daemon"]

@ -1,3 +0,0 @@
# 内部授权服务器
为内部第三方提供授权restful-api,如:emqx,zlmediakit

@ -1,27 +0,0 @@
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const username = process.env.AUTH_USERNAME || 'admin';
const password = process.env.AUTH_PASSWORD || '3.1415926'
const authUrl = process.env.AUTH_URL || 'http://127.0.0.1:8080'
// Middleware to parse JSON bodies
app.use(express.json());
app.use(express.urlencoded({extended: true}));
// RESTful routes
app.get('/', (req, res) => {
res.json({message: 'Welcome to the auth-inner-server API'});
});
app.post('/emqx-login', (req, res) => {
if (req.body.username === username && req.body.password === password) {
res.json({is_superuser: true, result: 'allow'});
} else {
res.json({is_superuser: false, result: 'deny'});
}
})
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});

@ -1,24 +0,0 @@
{
"name": "auth-inner-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"prod": "pm2 start index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.21.2",
"pm2": "^6.0.8"
},
"devDependencies": {
"nodemon": "^3.1.10"
},
"engines": {
"node": "22.16.0"
}
}

@ -1,25 +0,0 @@
{
"apps": [
{
"name": "auth-inner-server",
"script": "index.js",
"watch": [
"app"
],
"ignore_watch": [
"app/public"
],
"log_date_format": "YYYY-MM-DD HH:mm Z",
"error_file": "./logs/pm2-err.log",
"out_file": "./logs/pm2-out.log",
"merge_logs": true,
"exec_mode": "fork",
"max_memory_restart": "200M",
"autorestart": true,
"env": {
"NODE_ENV": "prd"
},
"instances": 1
}
]
}

File diff suppressed because one or more lines are too long

24
bi-ui/.gitignore vendored

@ -1,24 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -1,3 +0,0 @@
# 铁建智慧园区大屏
vite + vue3 + vue-router + pinia + axios + element-plus

5
bi-ui/env/.env vendored

@ -1,5 +0,0 @@
VITE_BASE_API='/api'
VITE_APP_NAME='智慧能源综合管控平台'
VITE_APP_CONTEXT_PATH="/bi/"
VITE_DEFAULT_USER="bi"
VITE_DEFAULT_PASSWORD="w8N9m8qQ+Z+skmrpPDl11TyJGTLX9hdwiA8DaeGxrS5peXwzcIwLiUUyzGJKUy/+BGZaSF40Y7fzUpjkAHvhwF9a7uZyzZlOhO+XSUUTgyj7bFNQCaYXFqb+ZAFpBWczopm95i/krFDfgiS4AmRv2Bb0wkegV5z071EjiCfOuPA="

@ -1,2 +0,0 @@
VITE_BASE_API='https://mock.apifox.cn/m1/2563668-0-default'
VITE_APP_NAME='测试大屏'

@ -1,2 +0,0 @@
VITE_BASE_API='http://127.0.0.1:4523/m1/2563668-0-default'
VITE_APP_NAME='铁建大屏'

@ -1,144 +0,0 @@
<!DOCTYPE html>
<html class="dark">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title></title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
body,
#app {
min-height: 100vh;
background-color: #FFF;
margin: 0;
padding: 0;
user-select: none;
overflow: hidden;
border: none;
}
.loader {
width: 20em;
height: 20em;
font-size: 1.5vmin;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.loader .face {
position: absolute;
border-radius: 50%;
border-style: solid;
animation: animate 3s linear infinite;
}
.loader .face:nth-child(1) {
width: 100%;
height: 100%;
color: #0d9be0;
border-color: currentColor transparent transparent currentColor;
border-width: 0.2em 0.2em 0em .2em;
--deg: -45deg;
animation-direction: normal;
}
.loader .face:nth-child(2) {
width: 90%;
height: 90%;
color: #7bc528;
border-color: currentColor currentColor transparent transparent;
border-width: 0.2em 0em 0em 0.2em;
--deg: -135deg;
animation-direction: reverse;
}
.loader .face .circle {
position: absolute;
width: 50%;
height: 0.1em;
top: 50%;
left: 50%;
background-color: #0000;
transform: rotate(var(--deg));
transform-origin: left;
}
.loader .face .circle::before {
position: absolute;
top: -.5em;
right: -0.45em;
content: '';
width: .6em;
height: .6em;
background-color: currentColor;
border-radius: 50%;
box-shadow: 0 0 .5em .15em currentColor;
}
@keyframes animate {
to {
transform: rotate(1turn);
}
}
.loader-root {
position: absolute;
inset: 0;
user-select: none;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #00000001;
background-image: radial-gradient(#FFF, #ccc);
}
.loader-title {
margin: 4vmin 0 10vmin;
font-size: 3vmin;
color: #666;
text-shadow: .2vmin .2vmin 0 #fff;
letter-spacing: .3vmin;
}
.loader .logo img {
width: 13vmin;
height: 13vmin;
}
.loader .logo {
background-image: linear-gradient(to bottom, #FFF, #aaa);
padding: 3vmin;
border-radius: 50%;
box-shadow: 0 0 .5vmin #fff inset, 0 0 2vmin #0006;
}
</style>
</head>
<body style="margin:0;padding:0;user-select: none; overflow: hidden; border:none;">
<div id="app">
<div class="loader-root">
<div class="loader">
<div class="face">
<div class="circle"></div>
</div>
<div class="face">
<div class="circle"></div>
</div>
<div class="logo"><img src="/logo.png" loading="lazy"></div>
</div>
<div class="loader-title">正在加载系统资源,请耐心等待...</div>
</div>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

@ -1,15 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
// 使@vscode
"@/*": ["src/*"]
},
// prettier
"experimentalDecorators": true,
// .jsx
"jsx": "preserve"
},
// IDE
"exclude": ["node_modules", "dist", "build"]
}

@ -1,50 +0,0 @@
{
"name": "large-screen-energylab",
"private": true,
"version": "0.0.1",
"scripts": {
"run:prop": "vite --mode prop",
"run:dev": "vite --mode dev",
"run:mock": "vite --mode mock",
"run:cloud": "vite --mode cloud",
"build:dev": "vite build --mode dev",
"build:cloud": "vite build --mode cloud",
"build:prop": "vite build --mode prop",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "2.3.1",
"@microsoft/fetch-event-source": "2.0.1",
"@vueuse/components": "^12.7.0",
"@vueuse/core": "^12.7.0",
"axios": "0.27.2",
"crypto-js": "4.2.0",
"echarts": "5.4.2",
"element-plus": "2.9.2",
"file-saver": "2.0.5",
"highlight.js": "^11.11.1",
"jsencrypt": "^3.3.2",
"mescroll.js": "1.4.2",
"mitt": "3.0.1",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pinia": "2.0.22",
"pinia-plugin-persist": "1.0.0",
"spark-md5": "3.0.2",
"swiper": "9.4.1",
"vue": "3.5.13",
"vue-cropper": "1.0.3",
"vue-router": "4.2.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "4.6.2",
"@vue/compiler-sfc": "3.2.45",
"postcss-plugin-px2rem": "0.8.1",
"sass": "1.84.0",
"unplugin-auto-import": "0.11.4",
"vite": "5.4.11",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-setup-extend": "0.4.0"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

@ -1,28 +0,0 @@
<script setup>
import { onMounted, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
//
(parent || window).postMessage("loading.hide", "*");
</script>
<template>
<div>
<Transition name="fade" mode="out-in">
<router-view></router-view>
</Transition>
</div>
</template>
<style lang="scss" scoped>
.loading {
position: fixed;
width: 100vw;
height: 100vh;
background: #000;
top: 0;
left: 0;
z-index: 9999;
}
</style>

@ -1,9 +0,0 @@
import mitt from 'mitt';
/**
* 穿件全局事件总线
* @type {Emitter<Record<EventType, unknown>>}
*/
const emitter = mitt();
export default emitter;

@ -1,7 +0,0 @@
import { request,params } from "@/api";
export const doLogin = (username,password)=>request.post("/login-pwd",params({username,password}),{
showLoading:true,
token:false
})

@ -1,169 +0,0 @@
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { useAuthStore } from '@/store'
/**
* @description: 创建sse连接
*/
class ServerSentEvents {
static defaultConfig = {
base: import.meta.env.VITE_BASE_API, // 基础地址
url: '/sse', // 地址
data: undefined, // 请求正文
params: undefined, // 请求参数
method: 'get', // 提交方式
auth: true, // 是否携带token
json: true, // 是否返回json
returnData: false, // json数据是否返回data属性
reconnect: true, //是否重连
headers: {
'Content-Type': 'application/json'
},
onopen: () => { },
onmessage: () => { },
onerror: () => { },
onclose: () => { }
}
constructor(config) {
if (config) {
this.setConfig(config)
this.init()
}
}
static get(url, onmessage = () => { }, config = {}) {
config.onmessage = onmessage
config.url = url
return new ServerSentEvents(config)
}
static post(url, data, onmessage = () => { }, config = {}) {
config.onmessage = onmessage
config.url = url
config.method = 'post'
config.data = data
return new ServerSentEvents(config)
}
setConfig(config) {
this.config = {
ctrl: new AbortController(),
...ServerSentEvents.defaultConfig,
...config
}
}
init() {
if (this.config.auth) {
this.config.headers.Authorization = 'Bearer ' + useAuthStore().token
}
let url = this.config.url
// 如果url不含协议
if (url.indexOf("//") == -1) {
url = this.config.base + url
}
if (this.config.params) {
if (url.indexOf("?") > -1) {
url += '&' + this.params(this.config.params)
} else {
url += '?' + this.params(this.config.params)
}
}
let body = undefined
if (this.config.data && (this.config.method === 'post' || this.config.method === 'put')) {
if (this.config.data.constructor == URLSearchParams) {
this.config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
body = this.params(this.config.data).toString()
} else if (this.config.data.constructor == FormData) {
this.config.headers['Content-Type'] = 'multipart/form-data'
body = this.config.data
} else {
body = JSON.stringify(body)
}
}
this.config._url = url
this.config._body = body
console.debug(this.config)
this.send()
}
send() {
fetchEventSource(this.config._url, {
method: this.config.method,
headers: this.config.headers,
body: this.config._body,
signal: this.config.ctrl.signal,
onopen: this.config.onopen,
onmessage: (msg) => {
if (this.config.json) {
let data = JSON.parse(msg.data)
if (this.config.returnData) {
data = data.data
}
this.config.onmessage(data)
} else {
this.config.onmessage(msg)
}
},
onclose: () => {
console.info('onclose')
this.abort()
this.config.onclose()
if (this.config.reconnect) {
this.send()
}
},
onerror: (err) => {
console.error(err)
this.abort()
this.config.onerror(err)
}
})
}
abort() {
if (this.config.ctrl && !this.config.reconnect) {
try {
this.config.ctrl.abort()
} catch (e) {
console.error(e)
}
}
}
params(param) {
if (param == null || param == "") {
return new URLSearchParams();
}
if (param.constructor == Array) {
let param1 = new URLSearchParams();
for (let obj of param) {
param1.append(obj.name, obj.value);
}
param = param1;
} else if (param.constructor == Object) {
let param1 = new URLSearchParams();
for (let name in param) {
param1.append(name, param[name]);
}
param = param1;
} else {
if (param.constructor == HTMLFormElement) {
param = new FormData(param);
}
if (param.constructor == FormData || param.constructor == String) {
param = new URLSearchParams(param);
}
}
return param;
}
}
export default ServerSentEvents

@ -1,4 +0,0 @@
export { request, params, formData } from './request'
export { doLogin } from './AuthApi'
import SSE from './SSE'
export { SSE }

@ -1,153 +0,0 @@
import { ElLoading, ElMessage } from 'element-plus'
import axios from 'axios'
import { useAuthStore } from '@/store';//导入用户仓库
const env = import.meta.env
import { useRouter,useRoute } from 'vue-router';
console.debug('env',env,env.VITE_BASE_API)
const instance = axios.create({
baseURL: env.VITE_BASE_API,
timeout: 30000,
showLoading: false,
showError: true,
token: true,//控制是否需要携带请求头令牌
returnData: true,//返回
});
let loading = null;
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
//如果需要携带请求头令牌,则从用户仓库中获取token设置请求头x-token中
if (config.token) {
let authStore = useAuthStore();
if (authStore.isLogin) {
config.headers["Authorization"] = "Bearer "+authStore.token;
}
}
if (config.showLoading) {
loading = ElLoading.service({
fullscreen: true,
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.1)',
});
}
// 在发送请求之前做些什么
return config;
}, function (error) {
if (loading != null) {
loading.close();
loading = null;
}
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
// 对响应数据做点什么
if (loading != null) {
loading.close();
loading = null;
}
// console.debug(response);
//对错误信息进行全局提示
if (response.config.showError) {
if ("code" in response.data) {
// if (!response.data.ok) {
// ElMessage.error(response.data.message);
// }
if (response.data.code != 200) {
ElMessage.error(response.data.msg || response.data.message);
if(response.data.code == 401) {
let authStore = useAuthStore();
authStore.logout();
useRouter().push({path:'/login', query: { to: encodeURIComponent(useRoute().fullPath) }});
}
}
}
}
// console.debug(response)
if (response.config.returnData) {
return response.data;
} else {
return response;
}
}, function (error) {
if (loading != null) {
loading.close();
loading = null;
}
// 对响应错误做点什么
ElMessage.error("响应错误:" + error.message);
return Promise.reject(error);
});
/**
* 格式化参数成URLSearchParams
* @param {String|Array|Object|HTMLFormElement|FormData|URLSearchParams} param
* @return {URLSearchParams}
*/
instance.params = function (param) {
if (param == null || param == "") {
return new URLSearchParams();
}
if (param.constructor == Array) {
let param1 = new URLSearchParams();
for (let obj of param) {
param1.append(obj.name, obj.value);
}
param = param1;
} else if (param.constructor == Object) {
let param1 = new URLSearchParams();
for (let name in param) {
param1.append(name, param[name]);
}
param = param1;
} else {
if (param.constructor == HTMLFormElement) {
param = new FormData(param);
}
if (param.constructor == FormData || param.constructor == String) {
param = new URLSearchParams(param);
}
}
return param;
}
instance.formData = function (param) {
if (param == null || param == "") {
return new FormData();
}
if (param.constructor == Array) {
let param1 = new FormData();
for (let obj of param) {
param1.append(obj.name, obj.value);
}
return param1;
}
if (param.constructor == Object) {
let param1 = new FormData();
for (let name in param) {
param1.append(name, param[name]);
}
return param1;
}
if (param.constructor == HTMLFormElement) {
return new FormData(param);
}
return new FormData();
}
export const request = instance;
export const params = instance.params;
export const formData = instance.formData;

@ -1,5 +0,0 @@
:root,
html,
html.dark {
@include varELColor($el-colors, -$w-step);
}

@ -1,3 +0,0 @@
:root,html {
@include varELColor($el-colors, $w-step);
}

@ -1,110 +0,0 @@
@use "sass:color";
@use "sass:map";
/*
*/
$w-size: .85vw;
/**
:
1. 使css,2:
1.1. /,()css
1.2. css,virtualHost
2. $css:$w-z-index -> --w-z-index
3. ,$colorsmain,
3.1. --w-main:
3.2. --w-main-light: + $w-step
3.3. --w-main-light-1: + $w-step * 2
3.4. --w-main-light-2: + $w-step * 3
3.5. --w-main-dark: - $w-step
3.6. --w-main-dark-1: - $w-step * 2
3.7. --w-main-dark-2: - $w-step * 3
3.8. --w-main-h:
3.9. --w-main-s:
3.10. --w-main-l:
3.11. $w-step--w-step,
4.:
4.1. 使csshsl: hsl(var(--w-main-h),var(--w-main-s),calc(var(--w-main-l) + 50%))
4.2. 使csshsla: hsl(var(--w-main-h),var(--w-main-s),var(--w-main-l),.5)
4.3. 使css,scss,使
4.4. ,\\\,
*/
//
$w-step: 5;
// z
$w-z-index: 100;
// z
$w-z-index-top: 1000;
$colors: (
"main": hsl(185, 80%, 50%),
"text": hsl(185, 80%, 5%),
"bg": #F8F8F8,
"primary": #3c9cff,
"warn": #eaa339,
"success": #5ac725,
"info": #999,
"error": #f56c6c,
"danger": #f56c6c
);
$dark-colors: (
"main": map.get($colors, "main"),
"text": map.get($colors, "bg"),
"bg": map.get($colors, "text"),
"primary": map.get($colors, "primary"),
"warn": map.get($colors, "warn"),
"success": map.get($colors, "success"),
"info": map.get($colors, "info"),
"error": map.get($colors, "error"),
"danger": map.get($colors, "danger")
);
$el-colors: (
"primary":"main",
"warn": "warn",
"success": "success",
"info": "info",
"error": "error",
"danger": "danger"
);
@mixin varColor($map, $step) {
@each $name , $value in $map {
$s: color.channel($value, "saturation", $space: hsl);
$h: color.channel($value, "hue", $space: hsl);
$l: color.channel($value, "lightness", $space: hsl);
--w-#{$name}-h: #{$h};
--w-#{$name}-s: #{$s};
--w-#{$name}-l: #{$l};
--w-#{$name}: hsl(var(--w-#{$name}-h), var(--w-#{$name}-s), var(--w-#{$name}-l));
//
@for $n from 1 through 6 {
@if $n == 1 {
--w-#{$name}-light: hsl(var(--w-#{$name}-h), var(--w-#{$name}-s), calc(var(--w-#{$name}-l) + #{$n} * var(--w-step) * 1%));
--w-#{$name}-dark: hsl(var(--w-#{$name}-h), var(--w-#{$name}-s), calc(var(--w-#{$name}-l) - #{$n} * var(--w-step) * 1%));
} @else {
--w-#{$name}-light-#{$n - 1}: hsl(var(--w-#{$name}-h), var(--w-#{$name}-s), calc(var(--w-#{$name}-l) + #{$n} * var(--w-step) * 1%));
--w-#{$name}-dark-#{$n - 1}: hsl(var(--w-#{$name}-h), var(--w-#{$name}-s), calc(var(--w-#{$name}-l) - #{$n} * var(--w-step) * 1%));
}
}
}
}
@mixin varELColor($map, $step) {
@each $name , $value in $map {
--el-color-#{$name}: hsl(var(--w-#{$value}-h), var(--w-#{$value}-s), var(--w-#{$value}-l));
@for $n from 1 through 9 {
--el-color-#{$name}-light-#{$n}: hsl(var(--w-#{$value}-h), var(--w-#{$value}-s), calc(var(--w-#{$value}-l) + #{$n} * var(--w-step) * 1%));
--el-color-#{$name}-dark-#{$n}: hsl(var(--w-#{$value}-h), var(--w-#{$value}-s), calc(var(--w-#{$value}-l) - #{$n} * var(--w-step) * 1%));
}
}
}

@ -1,333 +0,0 @@
/*
main.js
*/
@font-face {
font-family: led;
src: url(../fonts/led.ttf);
}
@font-face {
font-family: num;
src: url(../fonts/num.ttf);
}
@layer {
:root,
.w-var {
--w-step: #{$w-step};
--w-z-index: #{$w-z-index};
--w-z-index-top: #{$w-z-index-top};
--w-size: #{$w-size};
@include varColor($colors, $w-step);
}
.dark {
--w-step: #{-$w-step};
@include varColor($dark-colors, -$w-step);
}
* {
font-family: Segoe UI, Segoe UI Midlevel, Segoe WP, Arial, sans-serif;
box-sizing: border-box;
padding: 0;
margin: 0;
border: none;
outline: none;
color: inherit;
}
html {
font-size: var(--w-size);
color: var(--w-text);
background-color: var(--w-bg);
}
.w-abs {
position: absolute;
}
.w-lines {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.w-flex {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
position: relative;
}
.w-flex-column {
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
/* 印章效果 */
.w-seal {
position: absolute;
display: flex;
line-height: 1;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 6em;
height: 6em;
border-radius: 10em;
border: .25em solid currentColor;
background-color: #FFF;
z-index: 1;
transform: rotate(-25deg);
padding: 0;
&>div {
border: .13em solid currentColor;
padding: .3em 0;
width: 4.3em;
text-align: center;
font-weight: bold;
}
&::before {
content: "";
position: absolute;
width: 5em;
height: 5em;
border: .15em solid currentColor;
border-radius: 10em;
}
&::after {
content: "";
position: absolute;
width: 3.5em;
height: 3.5em;
border: .15em solid currentColor;
border-color: currentColor #0000 currentColor #0000;
border-radius: 10em;
}
}
.w-loading {
display: inline-block;
width: 1em;
height: 1em;
border-radius: 1em;
border: solid .2em currentColor;
mask-image: conic-gradient(from 0deg, #0000 0%, #000 75%, #000 83%, #0000 85%);
animation: w-am-loading 1s ease infinite;
}
.w-inner-loading {
pointer-events: none;
user-select: none;
position: relative;
display: flex;
justify-content: center;
align-items: center;
&::before {
content: '';
position: absolute;
inset: 0;
background-color: var(--bg-color, #0003);
backdrop-filter: blur(.1em);
}
&::after {
position: absolute;
content: '';
font-size: var(--size, 1em);
display: block;
width: 1em;
height: 1em;
border-radius: 1em;
border: solid .2em var(--loading-color, currentColor);
mask-image: conic-gradient(from 0deg, #0000 0%, #000 75%, #000 83%, #0000 85%);
animation: w-am-loading 1s ease infinite;
}
}
@keyframes w-am-loading {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@property --border-gradient-angle {
syntax: "<angle>";
inherits: true;
initial-value: 0turn;
}
.w-border-light,
.w-border-light-1,
.w-border-light-2,
.w-border-light-3 {
position: relative;
border: none !important;
animation-play-state: inherit;
--border: .2em solid var(--w-main-dark-3);
--border-light-color: #FFF9;
--time: 5s;
&::before {
content: '';
pointer-events: none;
position: absolute;
inset: 0;
border: var(--border);
border-radius: inherit;
}
&::after {
content: '';
pointer-events: none;
position: absolute;
inset: 0;
border: var(--border);
border-color: var(--border-light-color);
border-radius: inherit;
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000, #000 10%, #0000 11%, #0000 50%, #000 60%, #0000 61%);
animation: am-frame var(--time) infinite linear;
animation-play-state: inherit;
}
}
.w-border-light-1::after {
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000, #000 10%, #0000 11%);
}
.w-border-light-3::after {
mask-image: conic-gradient(from var(--border-gradient-angle) at 50% 50%, #0000,#0000 23%, #000 33%, #0000 34%,#0000 56%,#000 66%,#0000 67%, #0000 89%, #000 99%, #0000 100%);
}
@keyframes am-frame {
0% {
--border-gradient-angle: 0turn;
}
100% {
--border-gradient-angle: 1turn;
}
}
.w-part-hide {
--top: 1em;
--bottom: 1em;
mask-image: linear-gradient(to bottom,#0000 0%,#000 var(--top),#000 calc(100% - var(--bottom)), #0000 100%);
}
.w-radio,
.w-checkbox {
--btn-color-inner: var(--btn-color, currentColor);
--opacity: .6;
transition: all .3s;
cursor: pointer;
&::before {
content: '';
display: inline-block;
font-size: var(--btn-size, inherit);
width: 1em;
height: 1em;
opacity: var(--opacity);
box-sizing: border-box;
border: solid 1px var(--btn-color-inner);
margin-right: .2em;
border-radius: .2em;
background-color: var(--btn-bg-color-inner, #0000);
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNzA5NzA3MjQ5OTg3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQyODUiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTg0My42OTM5NTkgMjkzLjYwOTA2MSA0MjUuMjU1ODY5IDcxMi4wNTYzNjIgMTg2LjE0NTAyNiA0NzIuOTQ3NTY2IDY2LjU3OTg4MyA1OTIuNTA0NTIyIDQyNS4yNTU4NjkgOTUxLjE2NTE1OCA5NjMuMjYwMTI2IDQxMy4xNzQyMDRaIiBwLWlkPSI0Mjg2IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+");
background-size: .65em .65em;
background-repeat: no-repeat;
background-position: var(--background-position-inner, center -1em);
transition: all .3s;
overflow: hidden;
}
&.selected {
--btn-color-inner: var(--selected-btn-color, var(--w-main));
--opacity: 1;
--btn-bg-color-inner: var(--selected-btn-color, var(--w-main));
--background-position-inner: center .1em;
color: var(--selected-text-color, currentColor);
}
}
.w-radio::before {
border-radius: 1em;
}
@property --data-num {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
.w-breathing {
--filter: brightness(110%);
--transform: scale(1.1);
--time: 1.3s;
--data-num: 0;
--data-num-to: 1;
animation: w-am-breathing var(--time) infinite linear;
animation-play-state: inherit;
}
@keyframes w-am-breathing {
0% {
filter: none;
transform: none;
}
45% {
filter: var(--filter);
transform: var(--transform);
--data-num: var(--data-num-to);
}
90% {
filter: none;
transform: none;
}
}
}

Binary file not shown.

Binary file not shown.

@ -1 +0,0 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -1 +0,0 @@
<svg class="prefix__icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M156.608 487.86c1.156-1.138 2.649-1.623 3.919-2.56l306.667-301.569c13.195-12.97 34.586-12.97 47.78 0a32.836 32.836 0 010 46.988L263.303 478.21h579.204c18.978 0 34.362 15.129 34.362 33.79 0 18.662-15.384 33.793-34.362 33.793H263.302L514.974 793.28a32.832 32.832 0 010 46.985c-13.195 12.974-34.587 12.974-47.781 0L160.526 538.703c-1.27-.94-2.763-1.422-3.92-2.562-6.334-6.23-9.24-14.34-9.476-22.503.237-11.437 3.143-19.547 9.478-25.779zm0 0"/></svg>

Before

Width:  |  Height:  |  Size: 563 B

@ -1 +0,0 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@ -1 +0,0 @@
<?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="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg>

Before

Width:  |  Height:  |  Size: 954 B

@ -1 +0,0 @@
<?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="1588670460195" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 307.712c13.824 0 25.088-11.264 25.088-25.088 0-100.352 81.92-182.272 182.272-182.272s182.272 81.408 182.272 182.272c0 13.824 11.264 25.088 25.088 25.088s25.088-11.264 24.576-25.088c0-127.488-103.936-231.936-231.936-231.936S205.824 154.624 205.824 282.624c-0.512 14.336 10.752 25.088 24.576 25.088z m564.736 234.496c-11.264 0-21.504 2.048-31.232 6.144 0-44.544-40.448-81.92-88.064-81.92-14.848 0-28.16 3.584-39.936 10.24-13.824-28.16-44.544-48.128-78.848-48.128-12.288 0-24.576 2.56-35.328 7.68V284.16c0-45.568-37.888-81.92-84.48-81.92s-84.48 36.864-84.48 81.92v348.672l-69.12-112.64c-18.432-28.16-58.368-36.864-91.136-19.968-26.624 14.336-46.592 47.104-30.208 88.064 3.072 8.192 76.8 205.312 171.52 311.296 0 0 28.16 24.576 43.008 58.88 4.096 9.728 13.312 15.36 22.528 15.36 3.072 0 6.656-0.512 9.728-2.048 12.288-5.12 18.432-19.968 12.8-32.256-19.456-44.544-53.76-74.752-53.76-74.752C281.6 768 209.408 573.44 208.384 570.88c-5.12-12.8-2.56-20.992 7.168-26.112 9.216-4.608 21.504-4.608 26.112 2.56l113.152 184.32c4.096 8.704 12.8 14.336 22.528 14.336 13.824 0 25.088-10.752 25.088-25.088V284.16c0-17.92 15.36-32.256 34.816-32.256s34.816 14.336 34.816 32.256v284.16c0 13.824 10.24 25.088 24.576 25.088 13.824 0 25.088-11.264 25.088-25.088v-57.344c0-17.92 15.36-32.768 34.816-32.768 19.968 0 37.376 15.36 37.376 32.768v95.232c0 7.168 3.072 13.312 7.68 17.92 4.608 4.608 10.752 7.168 17.92 7.168 13.824 0 24.576-11.264 24.576-25.088V547.84c0-18.432 13.824-32.256 32.256-32.256 20.48 0 38.912 15.36 38.912 32.256v95.232c0 13.824 11.264 25.088 25.088 25.088s24.576-11.264 25.088-25.088v-18.944c0-18.944 12.8-32.256 30.72-32.256 18.432 0 22.528 18.944 22.528 31.744 0 1.024-11.776 99.84-50.688 173.056-30.72 58.368-45.056 112.128-51.2 146.944-2.56 13.312 6.656 26.112 19.968 28.672 1.536 0 3.072 0.512 4.608 0.512 11.776 0 22.016-8.192 24.064-20.48 5.632-31.232 18.432-79.36 46.08-132.608 43.52-81.92 55.808-186.88 56.32-193.536-0.512-50.688-29.696-83.968-72.704-83.968z"></path></path></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@ -1 +0,0 @@
<?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="1576153230908" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="971" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M772.87036133 734.06115723c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714843H475.90991211c-56.60705567 0-102.66723633-46.06018067-102.66723633-102.66723633V600.82446289h305.859375c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012S827.9942627 467.50537109 772.87036133 467.50537109c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714844H373.24267578V401.01062011h321.92687989c55.12390137 0 99.94812012-44.82421875 99.94812011-99.94812011V190.07312011C795.11767578 134.94921875 750.29345703 90.125 695.16955567 90.125H251.12963867C196.0057373 90.125 151.18151855 134.94921875 151.18151855 190.07312011V301.0625c0 55.12390137 44.82421875 99.94812012 99.94812012 99.94812012h55.53588867v296.96044921c0 93.35632325 75.97045898 169.32678223 169.32678224 169.32678223h203.19213866c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012s-44.90661622-99.86572266-100.03051758-99.86572265z m0-199.89624024c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857423s-14.91394043 33.28857422-33.28857422 33.28857421-33.28857422-14.91394043-33.28857422-33.28857421 14.91394043-33.28857422 33.28857422-33.28857422zM217.75866699 301.0625V190.07312011c0-18.37463379 14.91394043-33.28857422 33.28857423-33.28857421h444.03991698c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857422V301.0625c0 18.37463379-14.91394043 33.28857422-33.28857422 33.28857422H251.12963867c-18.37463379 0-33.37097168-14.91394043-33.37097168-33.28857422z m555.11169434 566.23535156c-18.37463379 0-33.28857422-14.91394043-33.28857422-33.28857422 0-18.37463379 14.91394043-33.28857422 33.28857422-33.28857422s33.28857422 14.91394043 33.28857422 33.28857422c0.08239747 18.29223633-14.91394043 33.28857422-33.28857422 33.28857422z" p-id="972"></path></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

@ -1 +0,0 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg>

Before

Width:  |  Height:  |  Size: 179 B

@ -1 +0,0 @@
<?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="1575982282951" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="902" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M828.40625 90.125H195.59375C137.375 90.125 90.125 137.375 90.125 195.59375v632.8125c0 58.21875 47.25 105.46875 105.46875 105.46875h632.8125c58.21875 0 105.46875-47.25 105.46875-105.46875V195.59375c0-58.21875-47.25-105.46875-105.46875-105.46875z m52.734375 738.28125c0 29.16-23.57015625 52.734375-52.734375 52.734375H195.59375c-29.109375 0-52.734375-23.574375-52.734375-52.734375V195.59375c0-29.109375 23.625-52.734375 52.734375-52.734375h632.8125c29.16 0 52.734375 23.625 52.734375 52.734375v632.8125z" p-id="903"></path><path d="M421.52890625 709.55984375a36.28125 36.28125 0 0 1-27.55265625-12.66890625L205.17453125 476.613125a36.28546875 36.28546875 0 0 1 55.10109375-47.22890625l164.986875 192.4846875 342.16171875-298.48078125a36.2896875 36.2896875 0 0 1 47.70984375 54.68765625L445.3859375 700.6203125a36.3234375 36.3234375 0 0 1-23.85703125 8.93953125z" p-id="904"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

@ -1 +0,0 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg>

Before

Width:  |  Height:  |  Size: 971 B

@ -1 +0,0 @@
<?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="1546567861908" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2422" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M318.577778 819.2L17.066667 512l301.511111-307.2 45.511111 45.511111L96.711111 512l267.377778 261.688889zM705.422222 819.2l-45.511111-45.511111L927.288889 512l-267.377778-261.688889 45.511111-45.511111L1006.933333 512zM540.785778 221.866667l55.751111 11.150222L483.157333 802.133333l-55.751111-11.093333z" p-id="2423"></path></svg>

Before

Width:  |  Height:  |  Size: 717 B

@ -1 +0,0 @@
<?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="1577252187056" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2508" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M747.59340925 691.12859384c11.51396329 0.25305413 22.43746719-0.21087818 40.74171707-1.51832482 29.35428085-2.10878421 35.84933734-2.36183835 46.47761114-0.8856895 24.71495444 3.37405491 41.12129828 21.76265671 32.47528161 47.95376084-85.57447632 258.19957947-442.00123984 249.76444099-628.67084683 50.73735554-153.47733892-159.33976008-153.09775772-414.41833795 0.92786545-573.42069196 159.71934128-162.67163983 424.03439521-166.59397897 565.78689185 0.63263534 80.38686649 94.81095318 108.34934958 169.16669549 89.11723508 230.57450162-15.01454608 47.99593598-50.61082928 77.68762207-119.77896259 114.63352789-4.89237973 2.65706845-29.35428085 15.52065436-35.84933652 19.02123633-46.94154346 25.30541465-63.51659033 41.20565021-62.20914449 58.45550757 2.95229856 39.13904114 24.16667102 52.7196135 70.98168823 53.81618115z m44.41100207 50.10472101c-19.82257471 1.43397372-32.05352527 1.940082-45.63409763 1.6448519-70.34905207-1.60267593-115.98314969-30.91478165-121.38163769-101.64341492-3.45840683-46.05585397 24.7571304-73.13264758 89.24376132-107.96976837 6.7902866-3.66928501 31.37871396-16.57504688 36.06021551-19.06341229 57.69634516-30.83042972 85.15271997-53.73183005 94.76877722-84.47790866 12.77923398-40.78389304-9.10994898-98.94417051-79.24812286-181.6507002-121.17075953-142.97559219-350.14258521-139.60153647-489.2380134 2.06660824-134.49827774 138.84237405-134.79350784 362.12048163-0.42175717 501.637667 158.53842169 168.99799328 451.9968783 181.18676788 534.57688175-11.80919339-4.68150156 0.2952301-10.71262573 0.67481131-18.72600705 1.26527069z" p-id="2509"></path><path d="M346.03865637 637.18588562a78.82636652 78.82636652 0 0 0 78.32025825-79.29029883c0-43.69401562-35.005823-79.29029883-78.32025825-79.29029882a78.82636652 78.82636652 0 0 0-78.36243338 79.29029882c0 43.69401562 35.005823 79.29029883 78.36243338 79.29029883z m0-51.7495729a27.07679361 27.07679361 0 0 1-26.5706845-27.54072593c0-15.30977536 11.97789643-27.54072593 26.5706845-27.54072592 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072592a27.07679361 27.07679361 0 0 1-26.57068533 27.54072593zM475.7289063 807.11174353a78.82636652 78.82636652 0 0 0 78.3624334-79.29029882c0-43.69401562-34.96364785-79.29029883-78.32025825-79.29029883a78.82636652 78.82636652 0 0 0-78.32025742 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029882z m0-51.74957208a27.07679361 27.07679361 0 0 1-26.57068532-27.54072674c0-15.30977536 12.06224753-27.54072593 26.57068532-27.54072593 14.59278892 0 26.57068533 12.23095057 26.57068453 27.54072593a27.07679361 27.07679361 0 0 1-26.57068453 27.54072674zM601.24376214 377.21492718a78.82636652 78.82636652 0 0 0 78.32025742-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025742-79.29029882a78.82636652 78.82636652 0 0 0-78.32025823 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025824 79.29029883z m1e-8-51.74957208a27.07679361 27.07679361 0 0 1-26.57068534-27.54072675c0-15.30977536 11.97789643-27.54072593 26.57068534-27.54072591 14.55061295 0 26.57068533 12.23095057 26.57068451 27.54072592a27.07679361 27.07679361 0 0 1-26.57068451 27.54072674zM378.80916809 433.85687983a78.82636652 78.82636652 0 0 0 78.32025824-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025824-79.29029802a78.82636652 78.82636652 0 0 0-78.32025742 79.29029802c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029883z m0-51.74957209a27.07679361 27.07679361 0 0 1-26.57068451-27.54072674c0-15.30977536 11.97789643-27.54072593 26.57068451-27.54072593 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072593a27.07679361 27.07679361 0 0 1-26.57068533 27.54072674z" p-id="2510"></path></svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

@ -1 +0,0 @@
<?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="1575804206892" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3145" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M826.56 470.016c-32.896 0-64.384 12.288-89.984 35.52l0-104.96c0-62.208-50.496-112.832-112.64-113.088L623.936 287.04 519.552 287.104C541.824 262.72 554.56 230.72 554.56 197.12c0-73.536-59.904-133.44-133.504-133.44-73.472 0-133.376 59.904-133.376 133.44 0 32.896 12.224 64.256 35.52 89.984L175.232 287.104l0 0.576C113.728 288.704 64 338.88 64 400.576l0.32 0 0.32 116.48C60.864 544.896 70.592 577.728 100.8 588.48c12.736 4.608 37.632 7.488 60.864-25.28 12.992-18.368 34.24-29.248 56.64-29.248 38.336 0 69.504 31.104 69.504 69.312 0 38.4-31.168 69.504-69.504 69.504-22.656 0-44.032-11.264-57.344-30.4C138.688 610.112 112.576 615.36 102.464 619.136c-29.824 10.752-39.104 43.776-38.144 67.392l0 160.384L64 846.912C64 909.248 114.752 960 177.216 960l446.272 0c62.4 0 113.152-50.752 113.152-113.152l0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.536 0 133.44-59.904 133.44-133.504C960 529.92 900.096 470.016 826.56 470.016zM826.56 672.896c-22.72 0-44.032-11.264-57.344-30.4-22.272-32.384-48.448-27.136-58.56-23.36-29.824 10.752-39.04 43.776-38.08 67.392l0 160.384c0 27.136-22.016 49.152-49.152 49.152L177.216 896.064C150.08 896 128 873.984 128 846.848l0.32 0 0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.6 0 133.504-59.904 133.504-133.504 0-73.472-59.904-133.376-133.504-133.376-32.896 0-64.32 12.288-89.984 35.52l0-104.96L128 400.512c0-27.072 22.08-49.152 49.216-49.152L177.216 351.04 334.656 350.72c3.776 0.512 7.616 0.832 11.52 0.832 24.896 0 50.752-10.816 60.032-37.056 4.544-12.736 7.424-37.568-25.344-60.736C362.624 240.768 351.68 219.52 351.68 197.12c0-38.272 31.104-69.44 69.376-69.44 38.336 0 69.504 31.168 69.504 69.44 0 22.72-11.264 44.032-30.528 57.472C427.968 276.736 433.088 302.784 436.8 313.024c10.752 29.888 43.072 39.232 67.392 38.08l119.232 0 0 0.384c27.136 0 49.152 22.08 49.152 49.152l0.256 116.48c-3.776 27.84 6.016 60.736 36.224 71.488 12.736 4.608 37.632 7.488 60.8-25.28 13.056-18.368 34.24-29.248 56.704-29.248C864.832 534.016 896 565.12 896 603.392 896 641.728 864.832 672.896 826.56 672.896z" p-id="3146"></path></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

@ -1 +0,0 @@
<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

@ -1 +0,0 @@
<?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="1579774833889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1376" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M887.466667 192.853333h-100.693334V119.466667c0-10.24-6.826667-17.066667-17.066666-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H303.786667V119.466667c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H168.96c-46.08 0-85.333333 37.546667-85.333333 85.333334V836.266667c0 46.08 37.546667 85.333333 85.333333 85.333333H887.466667c46.08 0 85.333333-37.546667 85.333333-85.333333V278.186667c0-47.786667-37.546667-85.333333-85.333333-85.333334z m-718.506667 34.133334h100.693333v66.56c0 10.24 6.826667 17.066667 17.066667 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56h450.56v66.56c0 10.24 6.826667 17.066667 17.066666 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56H887.466667c27.306667 0 51.2 22.186667 51.2 51.2v88.746666H117.76v-88.746666c0-29.013333 22.186667-51.2 51.2-51.2zM887.466667 887.466667H168.96c-27.306667 0-51.2-22.186667-51.2-51.2V401.066667H938.666667V836.266667c0 27.306667-22.186667 51.2-51.2 51.2z" p-id="1377"></path><path d="M858.453333 493.226667H327.68c-10.24 0-17.066667 6.826667-17.066667 17.066666v114.346667h-116.053333c-10.24 0-17.066667 6.826667-17.066667 17.066667v133.12c0 10.24 6.826667 17.066667 17.066667 17.066666H460.8c10.24 0 17.066667-6.826667 17.066667-17.066666v-114.346667h380.586666c10.24 0 17.066667-6.826667 17.066667-17.066667v-133.12c0-10.24-6.826667-17.066667-17.066667-17.066666z m-413.013333 34.133333v97.28h-98.986667v-97.28h98.986667z m-230.4 131.413333h98.986667v98.986667h-98.986667v-98.986667z m131.413333 97.28v-97.28h98.986667v97.28h-98.986667z m133.12-228.693333h97.28v98.986667h-97.28v-98.986667z m131.413334 0h98.986666v98.986667h-98.986666v-98.986667z m230.4 97.28h-98.986667v-98.986667h98.986667v98.986667z" p-id="1378"></path></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

@ -1 +0,0 @@
<?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="1577186573535" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1068" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M479.85714249 608.42857168h64.28571502c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285751s-12.85714249-32.14285751-32.14285664-32.14285664h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285662s12.85714249 32.14285751 32.14285664 32.14285753z m-2e-8 122.14285665h64.28571504c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285665s-12.85714249-32.14285751-32.14285664-32.14285751h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285751s12.85714249 32.14285751 32.14285664 32.14285664z m353.57142921-559.28571416h-128.57142921v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285664-32.14285753s-32.14285751 12.85714249-32.14285751 32.14285753v32.14285664h-257.14285665v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285752-32.14285753s-32.14285751 12.85714249-32.14285664 32.14285753v32.14285664h-128.57142919c-70.71428585 0-128.57142832 57.85714249-128.57142832 122.14285751v501.42857081c0 70.71428585 57.85714249 128.57142832 128.57142832 122.14285751h642.85714335c70.71428585 0 128.57142832-57.85714249 128.57142833-122.14285751v-501.42857081c0-70.71428585-57.85714249-122.14285753-128.57142833-122.14285751z m64.28571415 623.57142832c0 32.14285751-32.14285751 64.28571415-64.28571416 64.28571504h-642.85714335c-32.14285751 0-64.28571415-25.71428583-64.28571417-64.28571504v-372.85714249h771.42857168v372.85714249z m0-437.14285664h-771.42857168v-64.28571417c0-32.14285751 32.14285751-64.28571415 64.28571417-64.28571415h128.57142919v32.14285664c0 19.28571417 12.85714249 32.14285751 32.14285664 32.14285751s32.14285751-12.85714249 32.14285753-32.14285751v-32.14285664h257.14285665v32.14285664c0 19.28571417 12.85714249 32.14285751 32.1428575 32.14285751s32.14285751-12.85714249 32.14285664-32.14285751v-32.14285664h128.57142921c32.14285751 0 64.28571415 25.71428583 64.28571415 64.28571415v64.28571417z m-610.71428583 372.85714247h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285664s-12.85714249-32.14285751-32.14285753-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285751s12.85714249 32.14285751 32.14285751 32.14285665z m385.71428583-122.14285664h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285751s-12.85714249-32.14285751-32.14285751-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285664s12.85714249 32.14285751 32.14285753 32.14285751z m-385.71428583 0h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285751s-12.85714249-32.14285751-32.14285753-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285664s12.85714249 32.14285751 32.14285751 32.14285751z m385.71428583 122.14285665h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285665s-12.85714249-32.14285751-32.14285751-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285751s12.85714249 32.14285751 32.14285753 32.14285665z" p-id="1069"></path></svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

@ -1 +0,0 @@
<?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="1566035680909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3601" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1002.0848 744.672l-33.568 10.368c0.96 7.264 2.144 14.304 2.144 21.76 0 7.328-1.184 14.432-2.368 21.568l33.792 10.56c7.936 2.24 14.496 7.616 18.336 14.752 3.84 7.328 4.672 15.808 1.952 23.552-5.376 16-23.168 24.672-39.936 19.68l-34.176-10.624c-7.136 12.8-15.776 24.672-26.208 35.2l20.8 27.488a28.96 28.96 0 0 1 5.824 22.816 29.696 29.696 0 0 1-12.704 19.616 32.544 32.544 0 0 1-44.416-6.752l-20.8-27.552c-13.696 6.56-28.192 11.2-43.008 13.888v33.632c0 16.736-14.112 30.432-31.648 30.432-17.6 0-31.872-13.696-31.872-30.432v-33.632a167.616 167.616 0 0 1-42.88-13.888l-20.928 27.552c-10.72 13.76-30.08 16.64-44.288 6.752a29.632 29.632 0 0 1-12.704-19.616 29.28 29.28 0 0 1 5.696-22.816l20.896-27.808a166.72 166.72 0 0 1-27.008-34.688l-33.376 10.432c-16.8 5.184-34.56-3.552-39.936-19.616a29.824 29.824 0 0 1 20.224-38.24l33.472-10.432c-0.8-7.264-2.016-14.304-2.016-21.824 0-7.36 1.184-14.496 2.304-21.632l-33.792-10.368c-16.672-5.376-25.632-22.496-20.224-38.432 5.376-16 23.136-24.672 39.936-19.68l34.016 10.752c7.328-12.672 15.84-24.8 26.336-35.328l-20.8-27.552a29.44 29.44 0 0 1 6.944-42.432 32.704 32.704 0 0 1 44.384 6.752l20.832 27.616c13.696-6.432 28.224-11.2 43.104-13.952v-33.568c0-16.736 14.048-30.432 31.648-30.432 17.536 0 31.808 13.568 31.808 30.432v33.504c15.072 2.688 29.344 7.808 42.848 14.016l20.992-27.616a32.48 32.48 0 0 1 44.224-6.752 29.568 29.568 0 0 1 7.136 42.432l-21.024 27.808c10.432 10.432 19.872 21.888 27.04 34.752l33.376-10.432c16.768-5.12 34.56 3.68 39.936 19.68 5.536 15.936-3.712 33.056-20.32 38.304z m-206.016-74.432c-61.344 0-111.136 47.808-111.136 106.56 0 58.88 49.792 106.496 111.136 106.496 61.312 0 111.104-47.616 111.104-106.496 0-58.752-49.792-106.56-111.104-106.56z" p-id="3602"></path><path d="M802.7888 57.152h-76.448c0-22.08-21.024-38.24-42.848-38.24H39.3968a39.68 39.68 0 0 0-39.36 40.032v795.616s41.888 120.192 110.752 120.192H673.2848a227.488 227.488 0 0 1-107.04-97.44H117.6368s-40.608-13.696-40.608-41.248l470.304-0.256 1.664 3.36a227.68 227.68 0 0 1-12.64-73.632c0-60.576 24-118.624 66.88-161.44a228.352 228.352 0 0 1 123.552-63.392l-3.2 0.288 2.144-424.672h38.208l0.576 421.024c27.04 0 52.672 4.8 76.64 13.344V101.536c0.032 0-6.304-44.384-38.368-44.384zM149.7648 514.336H72.3888v-77.408H149.7648v77.408z m0-144.32H72.3888v-77.44H149.7648v77.44z m0-137.248H72.3888v-77.44H149.7648v77.44z m501.856 281.568H206.0848v-77.408h445.536v77.408z m0-144.32H206.0848v-77.44h445.536v77.44z m0-137.248H206.0848v-77.44h445.536v77.44z" p-id="3603"></path></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

@ -1 +0,0 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg>

Before

Width:  |  Height:  |  Size: 418 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save