42 Commits

Author SHA1 Message Date
meilin.huang
7eb4d064ea feat: 机器脚本新增分配、组件属性类型不匹配警告调整 2025-06-16 20:13:03 +08:00
meilin.huang
cc66fcddf5 refactor: 动态路由调整&分隔面板使用element自带组件 2025-06-09 21:18:55 +08:00
meilin.huang
aac4c2b42b fix: 机器计划任务、数据库迁移任务初始化问题修复 2025-06-01 20:39:54 +08:00
meilin.huang
7a17042276 refactor: pool get options支持不创建连接 2025-05-29 20:24:48 +08:00
Coder慌
42fbfd3c47 !136 fix: 连接池修复
Merge pull request !136 from zongyangleo/dev_0529
2025-05-29 04:39:31 +00:00
zongyangleo
e273ade0b0 fix: 连接池修复 2025-05-29 11:38:29 +08:00
meilin.huang
bcaa4563ac fix: ssh tunnel检测导致死锁问题调整 2025-05-27 22:56:54 +08:00
meilin.huang
e0c01d4561 fix: 移除隧道连接时检测是否正在使用 2025-05-26 22:33:51 +08:00
meilin.huang
d6280ea280 refactor: 使用泛型重构参数绑定等 2025-05-24 16:22:54 +08:00
meilin.huang
666b191b6c fix: some issue 2025-05-23 17:26:12 +08:00
meilin.huang
778cb7f4de reafctor: pool 2025-05-22 23:29:50 +08:00
zongyangleo
142bbd265d !134 feat: 新增支持es和连接池
* feat: 各连接,支持连接池
* feat:支持es
2025-05-21 04:42:30 +00:00
meilin.huang
f676ec9e7b feat: flow design & page query refactor 2025-05-20 21:04:47 +08:00
meilin.huang
44d379a016 otp: 样式优化 2025-04-26 17:37:09 +08:00
meilin.huang
2170509d92 refactor: code optimization 2025-04-23 20:36:32 +08:00
meilin.huang
798ab7d18b style: fix 2025-04-20 21:01:01 +08:00
meilin.huang
abd2b4bac0 refactor: 引入tailwind css & 后端部分非公共包位置调整 2025-04-18 22:07:37 +08:00
meilin.huang
585cbbed23 fix: i18n特殊字符调整 2025-04-16 12:09:55 +08:00
meilin.huang
1b40d345eb feat: message notify 2025-04-15 21:42:31 +08:00
zongyangleo
3c0292b56e !132 fix:
* fix: 表结构同步修复
* fix: 达梦低权限兼容,pgsql bool值转换
2025-03-17 11:12:52 +00:00
meilin.huang
bc21ba7c1e fix: some issue 2025-03-11 12:42:20 +08:00
meilin.huang
c7c3fd7f7e refactor: form rules refactor 2025-03-05 12:47:52 +08:00
meilin.huang
547e31eae6 refactor: pacakge version upgrade 2025-02-27 19:40:31 +08:00
meilin.huang
6072bcb111 fix: fixed some issues 2025-02-20 17:07:13 +08:00
meilin.huang
aa393590b2 feat: 系统升级支持数据库自动迁移,避免手动执行升级脚本 2025-02-13 21:11:23 +08:00
zongyangleo
efb2b7368c !131 fix: 数据迁移bug
* fix: 数据迁移bug
2025-01-24 11:08:59 +00:00
meilin.huang
30ea36a722 feat: 机器新增支持加密方法等 2025-01-18 13:43:01 +08:00
zongyangleo
5a6e9d81a7 !130 fix: 数据迁移、数据同步bug修复
* fix: 数据迁移、数据同步bug修复
2025-01-17 03:53:15 +00:00
meilin.huang
8d24c2a4fa refactor: 数据同步优化 & 标签树支持双击展开节点 & mysql支持with语句 2025-01-10 12:05:00 +08:00
meilin.huang
1be7a0ec79 fix: machine file & i18n & icon 2025-01-07 21:02:27 +08:00
meilin.huang
f30841209c refactor: icon use refactor 2024-12-29 18:21:50 +08:00
meilin.huang
e4d949a64b fix: machine file bug 2024-12-26 12:17:58 +08:00
zongyangleo
3f6fb5afef !129 fix: db 相关bug
* fix: db 相关bug
2024-12-26 04:11:28 +00:00
meilin.huang
68f553f4b0 refactor: remove router、ioc is adjusted to inject by type 2024-12-16 23:29:18 +08:00
meilin.huang
7f2a49ba3c fix: 机器文件内容写入导致内容清空、feat: ioc支持根据类型注入 2024-12-13 12:15:24 +08:00
meilin.huang
e56788af3e refactor: dbm 2024-12-08 13:04:23 +08:00
meilin.huang
ebc89e056f fix: fixed some minor issues 2024-11-28 20:11:16 +08:00
zongyangleo
d07cd74a8c !127 fix: 达梦特殊字段类型覆盖解析
* fix: 达梦特殊字段类型覆盖解析
2024-11-28 10:44:49 +00:00
meilin.huang
6cc15ebeda feat: tag refactor & other 2024-11-26 17:32:44 +08:00
zongyangleo
2b712cd548 !126 feat: 解析达梦特殊字段
* feat: 解析达梦特殊字段
2024-11-26 04:04:09 +00:00
meilin.huang
cda2963e1c fix: i18n & other optimizations 2024-11-23 17:23:18 +08:00
meilin.huang
bffa9c2676 fix: i18n 2024-11-21 20:12:16 +08:00
874 changed files with 28282 additions and 18556 deletions

View File

@@ -1,5 +1,5 @@
# 构建前端资源
FROM m.daocloud.io/docker.io/node:18-bookworm-slim as fe-builder
FROM m.daocloud.io/docker.io/node:18-bookworm-slim AS fe-builder
WORKDIR /mayfly
@@ -10,7 +10,7 @@ RUN yarn config set registry 'https://registry.npmmirror.com' && \
yarn build
# 构建后端资源
FROM m.daocloud.io/docker.io/golang:1.23 as be-builder
FROM m.daocloud.io/docker.io/golang:1.23 AS be-builder
ENV GOPROXY https://goproxy.cn
WORKDIR /mayfly

View File

@@ -1,4 +1,4 @@
# 🌈mayfly-go
# 🌈Dromara mayfly-go
<p align="center">
<a href="./README_EN.md">English</a> |
@@ -15,11 +15,14 @@
<img src="https://img.shields.io/github/stars/dromara/mayfly-go.svg?style=social" alt="github star"/>
<img src="https://img.shields.io/github/forks/dromara/mayfly-go.svg?style=social" alt="github fork"/>
</a>
<a href="https://github.com/dromara/mayfly-go" target="_blank">
<img src="https://gitcode.com/dromara/mayfly-go/star/badge.svg" alt="github star"/>
</a>
<a href="https://hub.docker.com/r/mayflygo/mayfly-go/tags" target="_blank">
<img src="https://img.shields.io/docker/pulls/mayflygo/mayfly-go.svg?label=docker%20pulls&color=fac858" alt="docker pulls"/>
</a>
<a href="https://github.com/golang/go" target="_blank">
<img src="https://img.shields.io/badge/Golang-1.22%2B-yellow.svg" alt="golang"/>
<img src="https://img.shields.io/badge/Golang-1.24%2B-yellow.svg" alt="golang"/>
</a>
<a href="https://cn.vuejs.org" target="_blank">
<img src="https://img.shields.io/badge/Vue-3.x-green.svg" alt="vue">
@@ -28,7 +31,7 @@
## 前言
web 版 **linux(终端[终端回放、命令过滤] 文件 脚本 进程 计划任务)。数据库mysql postgres oracle sqlserver 达梦 高斯 sqlite数据操作、数据同步数据迁移。redis(单机 哨兵 集群)。mongo 等集工单流程审批于一体的统一管理操作平台。**
Web 版 **统一管理操作平台**,集成了对 Linux 系统的全面操作支持(包括终端管理[终端回放、命令过滤]文件管理、脚本执行、进程监控及计划任务设置),同时提供了多种数据库(如 MySQL、PostgreSQL、Oracle、SQL Server达梦高斯、SQLite 等)的数据操作、数据同步数据迁移功能。此外,还支持 Redis单机哨兵集群模式)、 MongoDB 、Es 的操作管理,并结合工单流程审批功能,为企业提供一站式的运维与管理解决方案。
## 开发语言与主要框架
@@ -106,4 +109,11 @@ http://go.mayfly.run
## 💌 支持作者
如果觉得项目不错,或者已经在使用了,希望你可以去 <a target="_blank" href="https://github.com/dromara/mayfly-go">Github</a> <a target="_blank" href="https://gitee.com/dromara/mayfly-go">Gitee</a> 帮我点个 ⭐ Star这将是对我极大的鼓励与支持。
如果觉得项目不错,或者已经在使用了,希望你可以去 <a target="_blank" href="https://github.com/dromara/mayfly-go">Github</a><a target="_blank" href="https://gitee.com/dromara/mayfly-go">Gitee</a><a target="_blank" href="https://gitcode.com/dromara/mayfly-go">Gitcode</a> 帮我点个 ⭐ Star这将是对我极大的鼓励与支持。
> 喝杯咖啡 ☕️ 或者来杯奶茶 🧋,让作者更有精神,写出更棒的代码!
<img class="no-margin" src="https://foruda.gitee.com/images/1744113367791412282/36a3c23b_1240250.png" alt="微信打赏" width="200" height="200">
> **特别感谢:**
> 赞助金额达 199 元以上加微信wx-error可受邀进入付费交流群享受更快、更优先的技术支持与交流服务

View File

@@ -1,4 +1,4 @@
# 🌈mayfly-go
# 🌈Dromara mayfly-go
<p align="center">
<a href="./README.md">中文介绍</a> |
@@ -28,7 +28,7 @@
## Preface
Browser-based management platform. **linux(Terminal [terminal playback, command filtering], file, script, process, cronjob), database (mysql, postgres, oracle, sqlserver, Dameng, gauss, sqlite) data operation, data synchronization, data migration, redis(standlone, sentinel, cluster), mongo and other unified management and operation platforms that integrate work order process approval.**
Web-based **Unified Management and Operation Platform**, integrating comprehensive operation support for Linux systems (including terminal management [terminal playback, command filtering], file management, script execution, process monitoring, and cronjob settings). It also provides data operation, data synchronization, and data migration for multiple databases (such as MySQL, PostgreSQL, Oracle, SQL Server, Dameng, Gauss, SQLite, etc.). Additionally, it supports Redis operations (standalone, sentinel, and cluster modes) and MongoDB、Es management, combined with work order process approval functionality to offer enterprises an all-in-one solution for operations and management.
## Development languages and major frameworks

View File

@@ -56,6 +56,7 @@ function build() {
if [ "${os}" == "windows" ];then
execFileName="${execFileName}.exe"
fi
go mod tidy
CGO_ENABLE=0 GOOS=${os} GOARCH=${arch} go build -ldflags=-w -o ${execFileName} main.go
if [ -d ${toFolder} ] ; then
@@ -74,14 +75,13 @@ function build() {
# fi
if [ "${copyDocScript}" == "1" ] ; then
echo_green "Copy resources such as scripts [config.yml.example、mayfly-go.sql、mayfly-go.sqlite、readme.txt、startup.sh、shutdown.sh]"
echo_green "Copy resources such as scripts [config.yml.example、readme.txt、startup.sh、shutdown.sh]"
cp ${server_folder}/config.yml.example ${toFolder}
mv ${toFolder}/config.yml.example ${toFolder}/config.yml
cp ${server_folder}/readme.txt ${toFolder}
cp ${server_folder}/readme_cn.txt ${toFolder}
cp ${server_folder}/readme_en.txt ${toFolder}
cp ${server_folder}/resources/script/startup.sh ${toFolder}
cp ${server_folder}/resources/script/shutdown.sh ${toFolder}
cp ${server_folder}/resources/script/sql/mayfly-go.sql ${toFolder}
cp ${server_folder}/resources/data/mayfly-go.sqlite ${toFolder}
fi
echo_yellow ">>>>>>>>>>>>>>>>>>> ${os}-${arch} - Bundle build complete <<<<<<<<<<<<<<<<<<<<\n"

View File

@@ -14,18 +14,18 @@ services:
restart: always
server:
image: ccr.ccs.tencentyun.com/mayfly/mayfly-go:v1.8.5
image: ccr.ccs.tencentyun.com/mayfly/mayfly-go:latest
build:
context: .
dockerfile: Dockerfile
container_name: mayfly-go-server
ports:
- "8888:8888"
- "18888:18888"
environment:
TZ: Asia/Shanghai
WAIT_HOSTS: mysql:3306
volumes:
- ./server/config.yml.example:/mayfly/config.yml
- ./server/config.yml:/mayfly/config.yml
depends_on:
- mysql
restart: always

View File

@@ -11,7 +11,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
extends: ['plugin:vue/vue3-essential', 'plugin:vue/essential', 'eslint:recommended'],
extends: ['plugin:vue/essential', 'eslint:recommended'],
plugins: ['vue', '@typescript-eslint'],
overrides: [
{
@@ -35,9 +35,8 @@ module.exports = {
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-redeclare': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
'@typescript-eslint/no-unused-vars': [2],
'@typescript-eslint/no-unused-vars': 'off',
'vue/custom-event-name-casing': 'off',
'vue/attributes-order': 'off',
'vue/one-component-per-file': 'off',
@@ -53,6 +52,7 @@ module.exports = {
'vue/no-arrow-functions-in-watch': 'off',
'vue/no-template-key': 'off',
'vue/no-v-html': 'off',
'vue/no-unused-vars': 'off',
'vue/comment-directive': 'off',
'vue/no-parsing-error': 'off',
'vue/no-deprecated-v-on-native-modifier': 'off',
@@ -67,7 +67,7 @@ module.exports = {
'generator-star-spacing': 'off',
'no-unreachable': 'off',
'no-multiple-template-root': 'off',
'no-unused-vars': 'error',
'no-unused-vars': 'off',
'no-v-model-argument': 'off',
'no-case-declarations': 'off',
// 'no-console': 'error',

View File

@@ -11,58 +11,62 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^11.2.0",
"asciinema-player": "^3.8.1",
"@logicflow/core": "^2.0.16",
"@logicflow/extension": "^2.0.21",
"@vueuse/core": "^13.3.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-search": "^0.15.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/xterm": "^5.5.0",
"asciinema-player": "^3.10.0",
"axios": "^1.6.2",
"clipboard": "^2.0.11",
"cropperjs": "^1.6.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"echarts": "^5.5.1",
"element-plus": "^2.8.8",
"echarts": "^5.6.0",
"element-plus": "^2.10.2",
"js-base64": "^3.7.7",
"jsencrypt": "^3.3.2",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"monaco-editor": "^0.52.0",
"monaco-sql-languages": "^0.12.2",
"monaco-themes": "^0.4.4",
"monaco-editor": "^0.52.2",
"monaco-sql-languages": "^0.15.0",
"monaco-themes": "^0.4.5",
"nprogress": "^0.2.0",
"pinia": "^2.2.6",
"qrcode.vue": "^3.5.1",
"pinia": "^3.0.3",
"qrcode.vue": "^3.6.0",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.3",
"splitpanes": "^3.1.5",
"sql-formatter": "^15.4.5",
"sortablejs": "^1.15.6",
"sql-formatter": "^15.6.1",
"trzsz": "^1.1.5",
"uuid": "^9.0.1",
"vue": "^3.5.13",
"vue-i18n": "^10.0.4",
"vue-router": "^4.4.5",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0",
"xterm-addon-search": "^0.13.0",
"xterm-addon-web-links": "^0.9.0"
"vue": "^3.5.16",
"vue-i18n": "^11.1.5",
"vue-router": "^4.5.1",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.9",
"@types/crypto-js": "^4.2.2",
"@types/lodash": "^4.14.178",
"@types/node": "^18.14.0",
"@types/nprogress": "^0.2.0",
"@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"@vitejs/plugin-vue": "^5.2.0",
"@vue/compiler-sfc": "^3.5.13",
"code-inspector-plugin": "^0.4.5",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/compiler-sfc": "^3.5.16",
"autoprefixer": "^10.4.21",
"code-inspector-plugin": "^0.20.9",
"dotenv": "^16.3.1",
"eslint": "^8.35.0",
"eslint-plugin-vue": "^9.28.0",
"prettier": "^3.2.5",
"sass": "^1.81.0",
"typescript": "^5.6.3",
"vite": "^5.4.11",
"vue-eslint-parser": "^9.4.3"
"eslint": "^9.27.0",
"eslint-plugin-vue": "^10.2.0",
"postcss": "^8.5.4",
"prettier": "^3.5.3",
"sass": "^1.89.2",
"tailwindcss": "^4.1.9",
"typescript": "^5.8.2",
"vite": "npm:rolldown-vite@latest",
"vite-plugin-progress": "0.0.7",
"vue-eslint-parser": "^10.1.3"
},
"browserslist": [
"> 1%",

View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -1,13 +1,13 @@
<template>
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
<div class="h100">
<div class="h-full">
<el-watermark
:zIndex="10000000"
:width="210"
v-if="themeConfig.isWatermark"
:font="{ color: 'rgba(180, 180, 180, 0.3)' }"
:content="themeConfig.watermarkText"
class="h100"
class="!h-full"
>
<router-view v-show="themeConfig.lockScreenTime !== 0" />
</el-watermark>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-db-dm" viewBox="0 0 1024 1024"><path d="M335.303111 324.096c0 48.071111-46.819556 198.542222 145.635556 218.794667 84.081778 18.773333 105.585778 60.643556 98.304 186.026666a397.653333 397.653333 0 0 1-1.365334 30.264889c-29.468444 15.473778-50.232889 24.803556-62.350222 27.989334 1.934222-17.351111 21.617778-154.339556-18.659555-186.254223-40.277333-31.857778-68.266667-35.783111-109.795556-41.244444-20.081778-2.673778-51.484444-19.512889-75.264-34.133333-23.779556-14.563556-37.660444-42.780444-41.870222-69.176889-2.844444-17.635556-3.640889-43.121778-2.503111-76.458667 15.303111-17.066667 37.944889-35.726222 67.868444-55.751111z m80.554667-46.193778c-1.308444 17.408-28.444444 168.391111 49.436444 204.231111 28.444444 13.141333 40.391111 18.204444 60.472889 22.926223 20.081778 4.721778 70.940444 11.491556 91.989333 32.768 8.533333 8.533333 21.390222 23.04 28.558223 41.415111 10.467556 27.022222 13.255111 65.422222 13.255111 105.187555v30.037334c-22.698667 17.009778-41.870222 28.842667-57.685334 35.669333 0-20.366222 7.281778-115.882667-11.889777-155.192889-19.171556-39.253333-39.708444-57.742222-73.841778-62.293333-34.133333-4.551111-89.144889-18.659556-111.104-37.148445-22.016-18.432-50.801778-46.193778-50.801778-92.899555 0-31.118222 0.739556-61.041778 2.218667-89.827556 22.072889-16.099556 41.870222-27.704889 59.392-34.872889z m81.863111-36.522666c-2.161778 34.474667-7.338667 116.736 9.159111 159.459555 16.497778 42.723556 51.370667 66.56 89.713778 73.159111 38.343111 6.542222 106.496 29.127111 123.448889 69.973334 15.473778 37.148444 17.066667 59.335111 17.294222 77.539555v32.654222c-21.048889 19.171556-39.651556 34.133333-55.864889 44.942223 0-56.149333-0.170667-109.624889-16.497778-141.084445-16.270222-31.402667-37.717333-50.232889-84.423111-61.098667-46.648889-10.922667-95.459556-15.587556-124.928-53.703111-19.683556-25.372444-26.794667-67.299556-21.447111-125.781333l4.835556-49.550222c19.342222-10.467556 38.912-19.342222 58.709333-26.510222z" fill="#E8130D" ></path><path d="M235.804444 406.243556c2.275556 35.896889 5.176889 60.017778 8.760889 72.362666 10.126222 34.816 39.025778 60.928 51.939556 68.721778 20.935111 12.686222 61.895111 29.923556 93.240889 34.133333 20.878222 2.730667 43.406222 9.443556 67.697778 20.081778 22.755556 15.018667 34.474667 29.582222 35.271111 43.804445 4.835556 91.420444-9.216 122.311111-15.303111 154.453333-69.632 42.552889-357.432889 46.933333-363.349334-117.532445-3.982222-109.681778 36.579556-201.671111 121.742222-276.024888z m641.308445-133.632c63.374222 92.16 29.297778 209.749333-102.172445 352.824888a188.245333 188.245333 0 0 0-3.356444-32.085333c-16.327111-72.704-45.511111-104.106667-81.294222-117.304889-35.84-13.255111-139.832889-14.506667-160.028445-87.779555a415.459556 415.459556 0 0 1 6.599111-164.010667c161.848889-45.454222 275.285333-29.297778 340.252445 48.355556z" fill="#1D2683" ></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-gauss" viewBox="0 0 1024 1024"><path d="M936.789333 493.2608H562.961067a58.026667 58.026667 0 0 0-58.0608 58.0608v296.8576a58.026667 58.026667 0 0 0 58.0608 58.0608h373.828266a58.026667 58.026667 0 0 0 58.0608-58.0608v-296.8576a58.094933 58.094933 0 0 0-58.0608-58.0608z m-216.029866 305.902933c-16.725333 16.725333-45.021867 29.320533-79.496534 29.320534-67.208533 0-115.985067-47.069867-115.985066-129.297067 0-81.851733 50.4832-131.003733 117.0432-131.003733 35.464533 0 59.357867 15.701333 74.683733 31.744l-21.504 25.258666c-12.253867-12.629333-27.648-22.528-51.848533-22.528-46.728533 0-77.789867 36.1472-77.789867 95.197867 0 59.6992 27.648 96.187733 79.496533 96.187733 15.325867 0 30.685867-4.437333 39.560534-12.288v-59.016533h-49.800534v-32.426667h85.640534v108.8512z m124.6208 24.8832h-67.208534v-251.0848h65.160534c77.073067 0 121.105067 42.666667 121.105066 124.5184 0 81.544533-44.032 126.5664-119.057066 126.5664z" fill="#417CB7" ></path><path d="M840.6016 605.047467h-22.869333v186.606933h22.869333c53.896533 0 82.909867-31.709867 82.909867-94.139733 0-62.805333-28.9792-92.4672-82.909867-92.4672z" fill="#417CB7" ></path><path d="M409.565867 117.794133c-72.157867 0-114.4832 59.869867-114.4832 143.2576 0 131.1744 201.250133 394.069333 201.250133 394.069334V218.794667c0.068267 0 2.048-101.000533-86.766933-101.000534zM180.974933 259.584c-27.648-5.632-87.1424 21.7088-87.1424 139.093333 0 137.3184 368.264533 278.357333 368.264534 278.357334S246.101333 272.7936 180.974933 259.584zM93.525333 686.933333c93.5936 53.384533 346.487467 27.409067 346.487467 27.409067S85.981867 497.425067 47.274667 497.493333c-33.314133 0.068267-29.457067 146.2272 46.250666 189.44z m152.2688 154.385067c71.304533 0 183.944533-98.6112 183.944534-98.6112H125.2352s32.529067 98.6112 120.558933 98.6112z m366.592-723.524267c-88.951467 0-86.903467 101.000533-86.903466 101.000534v266.478933c9.966933-8.2944 21.7088-14.165333 34.474666-14.165333h87.620267c42.222933-73.5232 79.291733-153.838933 79.291733-210.056534-0.1024-83.319467-42.359467-143.2576-114.4832-143.2576z m228.488534 141.789867c-32.3584 6.519467-101.819733 109.499733-163.703467 211.524267h219.921067c18.944-23.7568 30.958933-48.128 30.958933-72.430934 0.034133-117.384533-59.528533-144.6912-87.176533-139.093333z" fill="#C91E1D" ></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-kingbase" viewBox="0 0 1024 1024"><path d="M295.808 424.32V128h158.016v214.72L896 128v148.16L453.824 508.352 896 731.968V896l-442.176-215.168V896H295.808V590.976L128 512z" fill="#CF152D" ></path></svg>

After

Width:  |  Height:  |  Size: 250 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-mariadb" viewBox="0 0 1088 1024"><path d="M1016.64 171.84c-15.68 0.64-10.88 5.12-45.12 13.44-34.56 8.64-76.8 5.76-113.92 21.44-111.04 46.4-133.44 205.76-234.24 262.72-75.52 42.56-151.68 46.08-219.84 67.52-45.12 14.08-94.08 42.88-135.04 78.08-31.68 27.2-32.32 51.2-65.6 85.44-35.2 36.48-140.48 0.64-188.16 56.64 15.36 15.36 22.08 19.84 52.48 15.68-6.4 11.84-43.2 21.76-35.84 39.36 7.68 18.24 96.96 30.72 177.92-18.24 37.76-22.72 67.84-55.68 126.72-63.68 76.16-10.24 163.84 6.4 251.84 19.2-13.12 39.04-39.36 64.96-60.48 96-6.4 7.04 13.12 7.68 35.52 3.52 40.32-9.92 69.12-17.92 99.52-35.52 37.12-21.76 42.88-77.44 88.64-89.28 25.6 39.04 94.72 48.32 137.6 16.96-37.76-10.56-48-90.88-35.52-126.4 12.16-33.6 24-87.04 36.16-131.2 13.12-47.68 17.92-107.52 33.6-131.84 23.68-36.48 49.92-48.96 72.64-69.44 22.72-20.48 43.52-40.64 42.88-87.68 0.32-14.72-7.36-23.04-21.76-22.72z" fill="#002B64" ></path><path d="M47.68 808.96c57.92 8.32 92.8 0 139.2-20.16 39.36-16.96 77.44-52.48 124.16-67.52 68.48-22.08 143.68 0 216.64 4.48 17.92 0.96 35.52 0.96 53.12-0.96 27.2-16.64 26.56-79.36 53.12-85.12-0.64 88-36.8 140.48-74.56 191.68 79.36-14.08 127.04-59.84 159.04-121.28 9.6-18.56 17.92-38.72 25.28-59.52 11.52 8.64 4.8 35.2 10.56 49.6 54.72-30.4 86.08-100.16 106.88-170.56 24-81.28 33.92-163.84 49.28-187.84 15.04-23.36 38.72-38.08 60.16-53.12 24.32-16.96 46.08-34.88 49.92-67.52-25.6-2.24-31.68-8.32-35.52-21.44-12.8 7.36-24.64 8.96-38.08 9.28-11.52 0.32-24.32-0.32-40 1.28-128.96 13.12-145.28 155.2-227.84 235.84-6.08 5.76-12.48 11.2-19.52 16.32-28.8 21.44-64.32 36.8-96.96 49.28-52.8 20.16-103.04 21.76-152.64 39.04-36.48 12.8-73.28 31.36-103.36 51.84-6.72 5.44-13.76 10.56-20.16 16-17.6 14.4-29.12 30.4-40.32 46.72-11.52 16.96-22.72 34.24-39.36 50.88-27.52 26.88-129.6 8-165.76 32.64-4.16 2.88-7.36 6.08-9.28 10.24 19.52 8.96 32.64 3.52 55.36 6.08 2.88 21.12-46.72 33.92-39.36 43.84zM828.48 654.4c1.6 24.64 15.68 73.6 28.48 85.44-24.64 6.08-67.2-3.84-78.08-21.44 5.44-25.28 34.56-48.32 49.6-64z" fill="#FFFFFF" ></path><path d="M864.64 263.68c18.24 15.68 56.64 3.2 49.6-28.48-28.48-2.24-44.8 7.36-49.6 28.48zM991.68 226.88c-4.8 10.24-14.08 23.36-14.08 49.28 0 4.48-3.52 7.36-3.52 0.64 0.32-25.28 7.04-36.16 14.08-50.56 3.52-6.08 5.44-3.52 3.52 0.64z" fill="#002B64" ></path><path d="M986.88 223.04c-5.76 9.6-19.52 27.52-21.76 53.12-0.32 4.48-4.16 7.04-3.52 0.32 2.56-25.28 13.44-40.96 21.76-54.72 3.84-5.44 5.76-2.88 3.52 1.28zM982.4 217.92c-6.4 9.28-27.84 30.4-32.32 56-0.64 4.48-4.48 6.72-3.52 0 4.48-24.96 22.72-44.48 32.32-57.28 4.48-5.12 6.08-2.56 3.52 1.28z" fill="#002B64" ></path><path d="M978.56 212.48c-7.68 8.32-32.96 35.2-40.96 59.84-1.28 4.16-5.44 6.08-3.52-0.32 8-24 30.08-49.92 41.28-61.44 4.8-4.8 6.08-1.6 3.2 1.92z" fill="#002B64" ></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1 @@
<svg id="icon-op-mysql" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M856.368 169.2H577.76a24 24 0 0 0 0 48h278.608a45.968 45.968 0 0 1 45.92 45.92v557.216a45.968 45.968 0 0 1-45.92 45.92h-253.6a1524.576 1524.576 0 0 1-68.304-57.328 24 24 0 1 0-32.096 35.696c8.304 7.456 16.704 14.752 24.784 21.632H299.136a45.968 45.968 0 0 1-45.92-45.92v-41.76a24 24 0 0 0-48 0v41.76a94.032 94.032 0 0 0 93.92 93.92h557.232a94.032 94.032 0 0 0 93.92-93.92V263.088a94.048 94.048 0 0 0-93.92-93.888z" fill="#666666" ></path><path d="M298.496 796.88a24 24 0 0 0 37.312-15.456 895.808 895.808 0 0 1 26.656-102.72 1102.672 1102.672 0 0 0 41.2 57.088 24 24 0 1 0 38-29.328 1078.192 1078.192 0 0 1-65.6-95.36 24 24 0 0 0-43.008 4.352c-1.024 2.816-20.272 56-34.48 112-27.088-39.632-57.504-121.008-6.544-259.984a24 24 0 0 0-6.016-25.696 341.856 341.856 0 0 1-78.8-120.336 233.216 233.216 0 0 0-42.288-76.064c-41.056-49.312-46.944-78.16-40.896-85.504 10.176-12.368 70.528 15.184 119.568 54.544a24 24 0 0 0 26 2.64c1.008-0.496 102.656-50.608 231.184 62.864a664.256 664.256 0 0 1 144.336 194.672 24.112 24.112 0 0 0 25.6 13.76c0.88-0.144 77.744-10.8 151.664 77.584-110.144 19.2-115.2 36.976-118.4 48a24 24 0 0 0 5.744 23.168c32.288 33.792 119.328 136.144 133.984 203.2a24 24 0 0 0 23.424 18.88 24.576 24.576 0 0 0 5.136-0.544 24 24 0 0 0 18.32-28.576c-15.472-70.752-87.888-160.368-124.72-202.416a921.184 921.184 0 0 1 102.72-20.448 24 24 0 0 0 16.608-36.96c-75.616-114.816-165.488-129.6-203.536-130.24a699.504 699.504 0 0 0-149.056-196.048C408.176 134.08 301.008 155.2 262.656 168.288 144.784 77.92 98.624 115.328 87.072 129.344c-26.8 32.48-12.992 81.856 41.04 146.752a185.744 185.744 0 0 1 33.6 60.496 377.6 377.6 0 0 0 80.144 128.768c-79.152 233.728 50.944 327.552 56.64 331.52z" fill="#1771B9" ></path><path d="M290.048 282.288a24.528 24.528 0 0 0-6.896 16.96 24 24 0 0 0 6.896 16.96 24.128 24.128 0 0 0 34.064 0 24.096 24.096 0 0 0 6.88-16.96 24.512 24.512 0 0 0-6.88-16.96 24.944 24.944 0 0 0-34.064 0z" fill="#1771B9" ></path><path d="M477.408 757.232a15.904 15.904 0 0 0-2.896-3.52 24.608 24.608 0 0 0-33.92 0 16.528 16.528 0 0 0-3.04 3.52 36.896 36.896 0 0 0-2.24 4.16c-0.48 1.44-0.944 3.04-1.264 4.48a24.464 24.464 0 0 0-0.496 4.8 24.992 24.992 0 0 0 1.76 9.12 26.336 26.336 0 0 0 5.28 7.84 22.4 22.4 0 0 0 7.68 5.12 23.008 23.008 0 0 0 9.28 1.92 24.256 24.256 0 0 0 16.96-7.04 22.704 22.704 0 0 0 5.12-7.84 22.208 22.208 0 0 0 1.92-9.12 21.92 21.92 0 0 0-1.92-9.28 20.8 20.8 0 0 0-2.224-4.16z" fill="#666666" ></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-oracle" viewBox="0 0 1024 1024"><path d="M700.245333 188.245333h-376.32a323.754667 323.754667 0 0 0-0.341333 647.509334h376.661333a323.754667 323.754667 0 0 0 0-647.509334z m-8.234666 533.418667H332.202667a209.706667 209.706667 0 0 1 0-419.328h359.808a209.664 209.664 0 1 1 0 419.328z" fill="#C74634" ></path></svg>

After

Width:  |  Height:  |  Size: 364 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-sqlite" viewBox="0 0 1024 1024"><path d="M757.589333 85.248c-93.44 79.872-177.92 267.861333-194.218666 317.738667-16.042667 49.066667-18.56 73.173333-18.730667 82.645333v2.901333a11.946667 11.946667 0 0 0 0.256 2.133334c12.544 0 28.202667 51.925333 24.576 51.925333-2.389333 0-11.776-11.776-28.16-35.328l-7.765333 50.602667 20.010666 30.08c5.632 8.405333-5.632 36.906667-8.661333 21.418666-2.048-10.325333-10.666667-23.893333-25.898667-40.704-4.992 35.626667-7.296 53.504-6.997333 53.632 19.626667 7.637333 36.437333 33.450667 32.853333 131.84-0.981333 28.245333 1.877333 75.776 8.704 142.506667l-0.128-0.682667L170.666667 896a85.333333 85.333333 0 0 1-85.333334-85.333333V170.666667a85.333333 85.333333 0 0 1 85.333334-85.333334z" fill="#0082CE" ></path><path d="M544.853333 754.133333c3.584-98.389333-13.226667-124.202667-32.853333-131.84-0.298667-0.128 2.005333-18.005333 6.997333-53.632 15.232 16.810667 23.893333 30.378667 25.898667 40.704 3.029333 15.488 14.293333-13.013333 8.661333-21.418666l-20.053333-30.08 7.808-50.602667c16.384 23.552 25.770667 35.328 28.16 35.328 3.626667 0-12.032-51.925333-24.576-51.925333-0.085333 0.085333-3.584-20.181333 18.474667-87.68 22.016-67.456 168.789333-387.498667 293.802666-351.146667 125.013333 36.394667 46.08 267.178667 29.866667 312.661333-16.128 45.482667-65.578667 117.248-84.992 133.888-12.928 11.093333-47.786667 30.933333-104.448 59.477334l87.552-27.093334c-40.362667 73.301333-69.546667 114.090667-87.552 122.368-27.050667 12.458667-76.970667 61.824-108.885333 100.992-9.898667-67.968 32.256-179.328 88.704-292.864 53.034667-106.752 118.826667-215.082667 163.242666-299.221333-49.92 70.826667-133.12 196.864-178.218666 288.896-64.512 131.712-83.584 229.888-92.970667 303.189333-10.624 83.029333-7.168 160.768 10.282667 233.301334h-10.24c-18.773333-89.941333-27.008-167.722667-24.618667-233.301334z" fill="#024A64" ></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-vastbase" viewBox="0 0 1024 1024"><path d="M22.528 553.984c-1.024 0-1.024-1.024-1.024-1.024 1.024 0 1.024 1.024 1.024 1.024z" fill="#FEA000" ></path><path d="M391.168 413.696v4.096c-1.024 10.24-6.144 20.48-13.312 27.648-6.144 6.144-14.336 11.264-23.552 12.288-1.024 0-2.048 0-4.096 1.024h-3.072H67.584c-25.6 0-46.08-20.48-46.08-46.08 0-12.288 5.12-23.552 13.312-32.768 8.192-8.192 19.456-13.312 32.768-13.312H266.24L166.912 194.56c-12.288-21.504-5.12-50.176 16.384-62.464 7.168-4.096 15.36-6.144 22.528-6.144 15.36 0 30.72 8.192 39.936 22.528l135.168 233.472 4.096 8.192c4.096 8.192 6.144 15.36 6.144 23.552zM529.408 360.448c-1.024 0-2.048 1.024-2.048 1.024s-1.024 1.024-2.048 1.024c-10.24 4.096-20.48 5.12-30.72 2.048-8.192-2.048-16.384-7.168-22.528-14.336-1.024 0-1.024-1.024-2.048-2.048s-1.024-2.048-2.048-3.072l-1.024-1.024-138.24-240.64C315.392 81.92 323.584 53.248 345.088 40.96c11.264-6.144 23.552-7.168 34.816-4.096 11.264 3.072 21.504 10.24 27.648 21.504l99.328 172.032 99.328-172.032c12.288-21.504 40.96-29.696 62.464-16.384 7.168 4.096 13.312 10.24 16.384 16.384 8.192 13.312 8.192 30.72 0 46.08L549.888 336.896l-4.096 8.192c-4.096 6.144-9.216 12.288-16.384 15.36zM645.12 453.632c-1.024 0-1.024-1.024-2.048-1.024s-1.024-1.024-1.024-1.024c-9.216-6.144-14.336-15.36-17.408-25.6-2.048-8.192-2.048-18.432 1.024-26.624 0-1.024 1.024-2.048 1.024-4.096 0-1.024 1.024-2.048 2.048-3.072 0 0 0-1.024 1.024-1.024l139.264-240.64c12.288-21.504 40.96-29.696 62.464-16.384 11.264 6.144 18.432 16.384 21.504 27.648 3.072 11.264 2.048 23.552-5.12 34.816L747.52 367.616h198.656c25.6 0 46.08 20.48 46.08 46.08 0 8.192-2.048 16.384-6.144 22.528-8.192 13.312-22.528 22.528-39.936 22.528H667.648c-8.192 0-16.384-2.048-22.528-5.12zM391.168 596.992v-2.048-2.048c-1.024-10.24-6.144-20.48-13.312-27.648-6.144-6.144-14.336-11.264-23.552-12.288-1.024 0-2.048 0-4.096-1.024h-3.072H67.584c-25.6 0-46.08 20.48-46.08 46.08 0 12.288 5.12 23.552 13.312 32.768 8.192 8.192 19.456 13.312 32.768 13.312H266.24l-99.328 172.032c-12.288 21.504-5.12 50.176 16.384 62.464 7.168 4.096 15.36 6.144 22.528 6.144 15.36 0 30.72-8.192 39.936-22.528l135.168-233.472 4.096-8.192c4.096-9.216 6.144-16.384 6.144-23.552zM529.408 649.216c-1.024 0-2.048-1.024-2.048-1.024s-1.024-1.024-2.048-1.024c-10.24-4.096-20.48-5.12-30.72-2.048-8.192 2.048-16.384 7.168-22.528 14.336-1.024 1.024-2.048 2.048-2.048 3.072-1.024 1.024-1.024 2.048-2.048 3.072l-1.024 1.024-138.24 239.616c-12.288 21.504-5.12 50.176 16.384 62.464 11.264 6.144 23.552 7.168 34.816 4.096 11.264-3.072 21.504-10.24 27.648-21.504l99.328-172.032L606.208 952.32c12.288 21.504 40.96 29.696 62.464 16.384 7.168-4.096 13.312-10.24 16.384-16.384 8.192-13.312 8.192-30.72 0-46.08L549.888 672.768l-4.096-7.168c-4.096-7.168-9.216-12.288-16.384-16.384zM645.12 557.056c-1.024 0-1.024 1.024-2.048 1.024s-1.024 1.024-1.024 1.024c-9.216 6.144-14.336 15.36-17.408 25.6-2.048 8.192-2.048 18.432 1.024 26.624 0 1.024 1.024 2.048 1.024 4.096 0 1.024 1.024 2.048 2.048 3.072 0 0 0 1.024 1.024 1.024L766.976 860.16c12.288 21.504 40.96 29.696 62.464 16.384 11.264-6.144 18.432-16.384 21.504-27.648 3.072-11.264 2.048-23.552-5.12-34.816L747.52 642.048h198.656c25.6 0 46.08-20.48 46.08-46.08 0-8.192-2.048-16.384-6.144-22.528-8.192-13.312-22.528-22.528-39.936-22.528H667.648c-8.192 0-16.384 2.048-22.528 6.144z" fill="#FE9500" ></path></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M96.426667 649.173333H712.96a137.173333 137.173333 0 0 0 0-274.346666H96.426667c-12.8 43.52-19.626667 89.514667-19.626667 137.173333s6.826667 93.696 19.626667 137.173333z" fill="#07A5DE" p-id="6101"></path><path d="M563.2 25.6A486.4 486.4 0 0 0 125.354667 299.946667H837.546667c52.096 0 97.450667-29.013333 120.661333-71.808A485.76 485.76 0 0 0 563.2 25.6z" fill="#EFBF19" p-id="6102"></path><path d="M942.421333 816.64a137.258667 137.258667 0 0 0-129.749333-92.586667H125.312A486.4 486.4 0 0 0 563.2 998.4c153.344 0 290.090667-70.954667 379.221333-181.76z" fill="#3EBEB1" p-id="6103"></path><path d="M506.197333 649.173333c12.8-43.52 19.626667-89.514667 19.626667-137.173333s-6.826667-93.696-19.626667-137.173333H96.469333c-12.8 43.52-19.626667 89.514667-19.626666 137.173333s6.826667 93.696 19.626666 137.173333h409.728z" fill="#231F20" p-id="6104"></path><path d="M477.269333 724.053333H125.354667a488.533333 488.533333 0 0 0 175.957333 197.888 488.533333 488.533333 0 0 0 175.957333-197.930666z" fill="#019B8F" p-id="6105"></path><path d="M301.312 102.058667a488.533333 488.533333 0 0 1 175.957333 197.930666H125.354667a488.533333 488.533333 0 0 1 175.957333-197.930666z" fill="#D8A22A" p-id="6106"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M465.664 679.168c105.301333 0.597333 172.970667 1.066667 202.922667 1.450667 20.48 0.256 36.181333 0.426667 47.274666 0.469333h3.84c45.824 0 84.096 8.533333 114.901334 25.258667 31.189333 16.938667 54.826667 42.368 70.826666 76.245333l1.152 2.517333a24.106667 24.106667 0 0 1-1.621333 3.413334c-46.336 67.84-101.034667 116.565333-164.096 146.346666-63.146667 29.824-134.613333 40.704-214.485333 32.469334-159.232-16.384-283.477333-106.24-372.352-269.994667a5.973333 5.973333 0 0 1 3.584-8.618667c13.653333-3.968 27.733333-6.528 41.941333-7.594666 91.306667-1.365333 170.538667-1.877333 238.165333-1.962667h27.946667z m44.885333 63.829333l-0.64 1.152c-3.754667 6.485333-9.386667 15.36-16.128 25.6l-2.645333 3.925334-1.578667 2.346666c-21.205333 31.445333-51.072 72.234667-70.784 94.464 64.853333 34.304 133.162667 45.44 227.157334 27.52 95.146667-18.090667 145.450667-52.565333 175.829333-114.090666-5.034667-10.581333-14.592-19.285333-31.488-27.733334-12.8-6.4-32.426667-11.050667-58.752-14.250666l-221.013333 1.066666z m-257.578666-5.546666l1.237333 1.536c21.504 26.112 67.712 72.277333 96.896 95.786666 15.146667-14.08 29.098667-29.397333 41.642667-45.824 13.952-18.261333 24.149333-32.64 35.370666-52.821333l-175.146666 1.322667z m471.296-360.874667c38.229333 5.077333 67.626667 18.944 88.448 41.301333 20.736 22.229333 33.024 52.992 36.565333 92.373334 3.626667 39.722667-5.76 71.808-27.733333 96.426666-20.906667 23.381333-53.461333 40.106667-97.877334 49.706667l-2.645333 0.597333-2.816 0.554667H144.725333a8.021333 8.021333 0 0 1-7.893333-6.485333 1545.173333 1545.173333 0 0 1-0.298667-1.578667c-12.373333-62.378667-18.517333-106.666667-18.517333-132.906667 0-38.570667 5.888-81.962667 17.706667-130.261333l1.066666-4.394667a7.082667 7.082667 0 0 1 6.826667-5.333333h580.650667zM197.546667 442.88l-0.853334 2.688c-7.509333 24.064-12.544 44.330667-12.117333 70.954667 0 30.293333 5.418667 54.272 13.653333 81.664h283.050667l0.341333-2.218667 0.469334-3.2c3.541333-24.448 4.010667-47.701333 4.010666-76.544 0-30.805333-1.066667-51.541333-6.4-75.264l-282.154666 1.92z m493.397333-3.029333l-131.797333 1.024 0.512 2.474666c4.48 22.357333 6.741333 43.861333 6.741333 73.216 0 30.421333-2.432 53.76-7.552 79.189334l134.826667-0.170667 1.962666-0.213333c28.16-2.901333 49.194667-7.210667 62.421334-23.04 11.52-13.866667 17.152-32.469333 17.152-55.765334 0-24.746667-6.272-42.624-19.456-54.826666-13.653333-12.714667-34.474667-19.2-61.994667-21.674667l-2.816-0.213333z m49.877333-342.784c63.104 29.824 117.845333 78.592 164.181334 146.346666l1.536 2.304a23.466667 23.466667 0 0 1-1.066667 3.669334c-16 33.92-39.594667 59.306667-70.784 76.245333-30.805333 16.768-69.12 25.258667-114.986667 25.258667-11.178667 0-28.16 0.213333-50.944 0.469333-45.098667 0.597333-112.597333 1.408-202.965333 1.493333h-14.122667c-70.613333 0-154.453333-0.512-251.733333-1.962666a207.061333 207.061333 0 0 1-42.24-7.594667 5.973333 5.973333 0 0 1-3.626667-8.618667C242.986667 170.922667 367.146667 81.066667 526.378667 64.682667c79.829333-8.277333 151.296 2.56 214.4 32.426666z m-102.101333 28.501333c-85.205333-15.36-143.957333-4.010667-213.717333 27.221333 11.648 13.312 26.410667 33.621333 40.874666 55.04l1.578667 2.389334 2.56 3.754666 3.498667 5.376 2.346666 3.584 1.237334 1.877334c18.688 28.757333 35.157333 56.746667 41.728 70.613333h213.674666l2.474667-0.298667 2.56-0.341333c21.290667-2.986667 38.144-10.794667 55.978667-19.754667 17.408-8.576 30.122667-18.304 40.106666-29.866666-49.493333-63.018667-108.586667-104.106667-194.901333-119.594667zM367.744 186.453333c-12.458667 10.069333-34.304 29.44-56.192 50.048l-1.706667 1.621334-3.328 3.157333-3.498666 3.328-1.877334 1.792-2.048 2.005333c-17.322667 16.64-33.578667 33.109333-44.501333 45.909334l179.797333-1.536-1.109333-1.877334a3067.264 3067.264 0 0 1-12.672-21.418666l-11.776-20.053334-2.474667-4.053333-2.56-4.266667-1.152-2.005333-1.237333-2.005333c-12.458667-20.693333-24.917333-40.405333-33.706667-50.645334z" fill="#2c2c2c" p-id="5739"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M916 983.5c0 22.4-16.5 40.5-36.8 40.5H139.3c-20.4 0-36.9-18.1-36.9-40.5v-943c0-22.4 16.5-40.5 36.9-40.5H724l192 214.2v769.3z" fill="#6367F0" ></path><path d="M712.6 0v186.5c0.8 25 21.3 44.6 45.8 43.8H916L712.6 0z" fill="#4F52C0" ></path><path d="M659.2 357.1v266.6c-0.8 27.6-23.3 49.7-50.8 49.7-28.1 0-50.8-22.9-50.8-51.2s22.8-51.2 50.8-51.2c9.8 0 19 2.8 26.8 7.7V386.1l-240.4 26.1v271.6c-0.4 27.9-23 50.4-50.8 50.4-28.1 0-50.8-22.9-50.8-51.2 0-28.3 22.8-51.2 50.8-51.2 9.8 0 19 2.8 26.8 7.7V386.1c0-14 11.1-25.2 24-25.2l237.6-28h1.9c12.8-1 24.9 10.2 24.9 24.2z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M984.32 277.12L708.48 32.64a96.64 96.64 0 0 0-64-24.32h-384a97.92 97.92 0 0 0-95.36 97.28v812.8a97.92 97.92 0 0 0 97.28 97.28h656.64a97.28 97.28 0 0 0 97.28-97.28V349.44a97.28 97.28 0 0 0-32-72.32z m-308.48-188.16l229.76 204.16h-229.76z m243.2 862.72H262.4a33.28 33.28 0 0 1-33.28-33.28V105.6a33.28 33.28 0 0 1 33.28-33.28h349.44v256a32 32 0 0 0 32 32h308.48v561.28a33.28 33.28 0 0 1-33.28 30.08z" fill="#EEAC00" ></path><path d="M6.4 419.84m64 0l609.92 0q64 0 64 64l0 238.72q0 64-64 64l-609.92 0q-64 0-64-64l0-238.72q0-64 64-64Z" fill="#EEAC00" ></path><path d="M216.32 501.12a99.2 99.2 0 0 1 33.92 64h-47.36a50.56 50.56 0 0 0-19.2-34.56 60.16 60.16 0 0 0-39.04-11.52 56.96 56.96 0 0 0-46.08 21.76 99.2 99.2 0 0 0-16.64 64 97.28 97.28 0 0 0 16.64 64 53.76 53.76 0 0 0 46.08 21.76 54.4 54.4 0 0 0 59.52-53.12h46.72A115.84 115.84 0 0 1 215.68 704a110.08 110.08 0 0 1-71.68 22.4A103.68 103.68 0 0 1 64 689.92a128 128 0 0 1-31.36-87.04A128 128 0 0 1 64 517.12a104.32 104.32 0 0 1 83.84-36.48 116.48 116.48 0 0 1 68.48 20.48zM476.8 553.6h-46.08a42.88 42.88 0 0 0-16.64-25.6 64 64 0 0 0-36.48-8.32 64 64 0 0 0-32.64 6.4 21.76 21.76 0 0 0-12.16 20.48c0 7.68 6.4 14.72 18.56 20.48a344.32 344.32 0 0 0 46.72 14.08 208 208 0 0 1 58.88 21.76 54.4 54.4 0 0 1 27.52 48.64c0 48.64-34.56 73.6-103.04 73.6s-97.92-27.52-103.04-81.28h46.72a53.12 53.12 0 0 0 16.64 33.28 67.84 67.84 0 0 0 38.4 8.96c37.12 0 55.68-10.24 55.68-31.36a30.08 30.08 0 0 0-21.12-26.88 325.76 325.76 0 0 0-46.08-13.44 181.12 181.12 0 0 1-57.6-19.84 53.12 53.12 0 0 1-26.88-46.72 56.32 56.32 0 0 1 26.24-49.28 115.2 115.2 0 0 1 67.84-17.92c60.16 0 93.44 24.32 98.56 72.96zM709.76 553.6h-46.08a42.88 42.88 0 0 0-16.64-25.6 64 64 0 0 0-36.48-8.32 64 64 0 0 0-32.64 6.4 21.76 21.76 0 0 0-12.16 20.48c0 7.68 5.76 14.72 18.56 20.48a344.32 344.32 0 0 0 46.72 14.08 215.68 215.68 0 0 1 58.88 21.76 55.68 55.68 0 0 1 27.52 48.64c0 48.64-34.56 73.6-103.04 73.6S516.48 697.6 512 643.84h46.72a53.12 53.12 0 0 0 16.64 33.28 67.84 67.84 0 0 0 38.4 8.96c37.12 0 55.68-10.24 55.68-31.36a30.08 30.08 0 0 0-21.12-26.88 325.76 325.76 0 0 0-46.72-13.44 181.12 181.12 0 0 1-57.6-19.84 53.12 53.12 0 0 1-26.88-46.72 56.32 56.32 0 0 1 26.24-49.28 115.2 115.2 0 0 1 67.84-17.92c60.16 0 92.8 24.32 98.56 72.96z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M205.799024 64.936585H664.850732l231.773658 231.773659v638.376585c0 13.79353-11.18208 24.97561-24.97561 24.97561H205.799024c-13.79353 0-24.97561-11.18208-24.975609-24.97561V89.912195c0-13.79353 11.18208-24.97561 24.975609-24.97561z m448.70681 24.97561H205.799024v845.174634H871.64878V307.055141L654.505834 89.912195z" fill="#B7B7BD" ></path><path d="M664.850732 64.936585l-10.989269 23.477074v196.807804c0 13.79353 11.18208 24.97561 24.97561 24.97561h194.310244L896.62439 296.710244 664.850732 64.936585z m13.986341 49.306849L849.815102 285.221463H678.837073V114.243434z" fill="#B7B7BD" ></path><path d="M255.250732 571.441951m9.990244 0l555.457561 0q9.990244 0 9.990243 9.990244l0 0q0 9.990244-9.990243 9.990244l-555.457561 0q-9.990244 0-9.990244-9.990244l0 0q0-9.990244 9.990244-9.990244Z" fill="#B7B7BD" ></path><path d="M255.250732 707.309268m9.990244 0l555.457561 0q9.990244 0 9.990243 9.990244l0 0q0 9.990244-9.990243 9.990244l-555.457561 0q-9.990244 0-9.990244-9.990244l0 0q0-9.990244 9.990244-9.990244Z" fill="#B7B7BD" ></path><path d="M255.250732 639.37561m9.990244 0l555.457561 0q9.990244 0 9.990243 9.990244l0 0q0 9.990244-9.990243 9.990244l-555.457561 0q-9.990244 0-9.990244-9.990244l0 0q0-9.990244 9.990244-9.990244Z" fill="#B7B7BD" ></path><path d="M255.250732 774.243902m9.990244 0l555.457561 0q9.990244 0 9.990243 9.990244l0 0q0 9.990244-9.990243 9.990244l-555.457561 0q-9.990244 0-9.990244-9.990244l0 0q0-9.990244 9.990244-9.990244Z" fill="#B7B7BD" ></path><path d="M255.250732 842.177561m9.990244 0l555.457561 0q9.990244 0 9.990243 9.990244l0 0q0 9.990244-9.990243 9.990244l-555.457561 0q-9.990244 0-9.990244-9.990244l0 0q0-9.990244 9.990244-9.990244Z" fill="#B7B7BD" ></path><path d="M67.434146 193.810732m15.984391 0l286.72 0q15.98439 0 15.98439 15.98439l0 286.72q0 15.98439-15.98439 15.98439l-286.72 0q-15.98439 0-15.984391-15.98439l0-286.72q0-15.98439 15.984391-15.98439Z" fill="#00C090" ></path><path d="M242.569116 353.23904l89.224866 84.502478c4.337764 4.107988 4.523582 10.954302 0.415595 15.291067-4.107988 4.337764-10.954302 4.523582-15.291068 0.415595l-89.224866-84.502479-84.502478 89.224867c-4.107988 4.337764-10.954302 4.523582-15.291067 0.415594-4.337764-4.107988-4.523582-10.954302-0.415595-15.291067l84.502478-89.224867-89.224866-84.502478c-4.337764-4.107988-4.523582-10.954302-0.415594-15.291067 4.107988-4.337764 10.954302-4.523582 15.291067-0.415594l89.224867 84.502478 84.502478-89.224867c4.107988-4.337764 10.954302-4.523582 15.291067-0.415594 4.337764 4.107988 4.523582 10.954302 0.415594 15.291068l-84.502478 89.224866z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M888.494817 313.882803l-198.019982-198.019982c-7.992021-7.992021-20.957311-7.992021-28.949332 0s-7.992021 20.947078 0 28.939099l163.084309 163.084309-215.794811 0L608.814999 42.686195c0-11.307533-9.15859-20.466124-20.466124-20.466124l-408.094512 0c-11.307533 0-20.466124 9.15859-20.466124 20.466124l0 938.62761c0 11.2973 9.15859 20.466124 20.466124 20.466124l693.76067 0c11.307533 0 20.466124-9.168824 20.466124-20.466124l0-652.961452C894.481158 322.92883 892.332215 317.720202 888.494817 313.882803zM853.54891 960.847681l-652.828422 0L200.720488 63.152319l367.162264 0 0 265.200034c0 11.307533 9.168824 20.466124 20.466124 20.466124l265.200034 0L853.54891 960.847681z" ></path></svg>

After

Width:  |  Height:  |  Size: 758 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M908.611316 239.2926l2.721684 711.518222c0 16.437893-13.204209 29.642101-29.642101 29.642102h-687.831489c-16.451366 0-29.655575-13.204209-29.655575-29.642102V73.027359c0-16.437893 13.204209-29.642101 29.642102-29.642102l522.468983-1.077894L675.1124 0H195.274147A69.497254 69.497254 0 0 0 125.709525 69.59157v884.843673A69.48378 69.48378 0 0 0 195.274147 1023.999865H880.235741a69.497254 69.497254 0 0 0 69.59157-69.564622V281.586489l-41.215995-42.307363z" fill="#D6473B" fill-opacity=".4" ></path><path d="M675.125873 206.21471a75.506516 75.506516 0 0 0 75.533464 75.533463h199.343132L675.125873 0v206.21471z" fill="#EF6A63" ></path><path d="M532.34526 481.104779H109.972263A96.48504 96.48504 0 0 1 13.47375 384.606265V320.808379A96.471566 96.471566 0 0 1 109.972263 224.296392H532.34526a96.471566 96.471566 0 0 1 96.498514 96.511987v63.797886a96.48504 96.48504 0 0 1-96.498514 96.498514" fill="#FA4E4E" ></path><path d="M479.568846 274.890069h35.422312v124.335142h55.120834v40.663573h-90.543146V274.890069z m-151.269032 0h46.443783l17.89305 100.298092 17.893051-100.298092h46.457257v164.998715H428.058958v-125.776825l-22.218102 125.776825h-26.206312l-22.24505-125.776825v125.776825H328.488445V274.890069h-0.188631z m-123.082089 0h107.546933v40.663574H276.614768v124.173457h-35.422311V315.553643h-36.14989v-40.663574h0.175158z m-125.049247 0h35.422311v57.653887h38.669469V274.863122h35.610942v165.012189h-35.610942V373.221004H115.604263v66.694728h-35.435785V274.876595z" fill="#FFFFFF" ></path><path d="M442.704851 590.61887l-2.344421-2.357895a18.687998 18.687998 0 0 0-26.583575 0l-121.263142 121.29009a18.728419 18.728419 0 0 0-5.537683 13.352419 18.728419 18.728419 0 0 0 5.524209 13.379366l121.276616 121.276616c7.410525 7.410525 19.159576 7.410525 26.583575 0l2.344421-2.357894c7.410525-7.410525 7.410525-19.159576 0-26.556628l-105.727986-105.74146 105.727986-105.714513c7.410525-7.410525 7.410525-19.334734 0-26.570101M587.102306 584.111081l-3.233684-1.266526a18.714945 18.714945 0 0 0-24.063997 11.210104L470.905269 838.0361a18.701471 18.701471 0 0 0 11.19663 24.03705l3.260631 1.266526a18.701471 18.701471 0 0 0 24.037049-11.210104l88.926304-243.981441c3.422315-9.754946-1.455158-20.614734-11.210103-24.03705M778.671123 709.537591l-121.263142-121.263142a18.66105 18.66105 0 0 0-26.570102 0l-2.344421 2.344421c-7.410525 7.410525-7.410525 19.159576 0 26.556628l105.714513 105.74146-105.714513 105.714512a18.66105 18.66105 0 0 0 0 26.583575l2.344421 2.344421c7.410525 7.410525 19.159576 7.410525 26.570102 0l121.263142-121.263142c3.73221-3.745684 5.564631-8.569262 5.537683-13.379366a18.728419 18.728419 0 0 0-5.52421-13.379367" fill="#EF6A63" ></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M533.987556 352V135.992889H231.992889V888.035556h560.014222V394.012444H576a42.012444 42.012444 0 0 1-42.012444-42.012444z m-133.973334 50.005333a39.992889 39.992889 0 1 1 0 79.985778 39.992889 39.992889 0 0 1 0-79.985778z m295.992889 294.001778H328.106667a7.964444 7.964444 0 0 1-6.314667-12.913778l99.811556-127.203555a7.964444 7.964444 0 0 1 12.600888 0l41.102223 52.423111 77.795555-99.214222a8.135111 8.135111 0 0 1 12.686222 0l136.533334 173.994666a7.964444 7.964444 0 0 1-6.314667 12.913778z" fill="#E6F7FF" ></path><path d="M854.584889 288.597333L639.431111 73.386667c-6.001778-5.973333-14.108444-9.386667-22.613333-9.386667H192c-17.692444 0-32 14.307556-32 32v832c0 17.692444 14.307556 32 32 32h640c17.692444 0 32-14.307556 32-32v-616.675556c0-8.533333-3.413333-16.725333-9.386667-22.727111z m-252.586667-150.784l188.188445 188.188445h-188.188445V137.813333z m190.008889 750.193778H231.992889V135.964444h301.994667v216.007112a42.012444 42.012444 0 0 0 42.012444 42.012444h216.007111v493.994667z" fill="#1890FF" ></path><path d="M553.102222 509.098667l-77.795555 99.214222-41.102223-52.423111a7.992889 7.992889 0 0 0-12.600888 0l-99.783112 127.203555a7.964444 7.964444 0 0 0 6.286223 12.913778h367.900444a7.964444 7.964444 0 0 0 6.286222-12.913778l-136.476444-173.994666a8.106667 8.106667 0 0 0-12.714667 0z m-193.109333-67.100445a39.992889 39.992889 0 1 0 80.014222 0 39.992889 39.992889 0 0 0-80.014222 0z" fill="#1890FF" ></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M984.96 277.12L709.12 32.64a96.64 96.64 0 0 0-64-24.32H263.68a97.92 97.92 0 0 0-97.92 97.28v812.8a97.92 97.92 0 0 0 97.92 97.28h656a97.28 97.28 0 0 0 97.28-97.28V349.44a97.28 97.28 0 0 0-32-72.32z m-308.48-188.16l229.76 204.16h-229.76z m243.2 862.72H263.68a33.28 33.28 0 0 1-33.92-33.28V105.6a33.28 33.28 0 0 1 33.92-33.28h348.8v256a32 32 0 0 0 32 32h308.48v561.28a33.28 33.28 0 0 1-33.28 30.08z" fill="#286AB3" ></path><path d="M7.04 419.84m64 0l609.92 0q64 0 64 64l0 238.72q0 64-64 64l-609.92 0q-64 0-64-64l0-238.72q0-64 64-64Z" fill="#286AB3" ></path><path d="M296.96 479.36h37.76v167.68a96 96 0 0 1-17.28 64 81.28 81.28 0 0 1-64 22.4 73.6 73.6 0 0 1-55.68-20.48 81.28 81.28 0 0 1-19.84-56.96v-8.32h37.76v7.68c0 30.08 12.8 44.8 38.4 44.8a39.04 39.04 0 0 0 32-12.8 64 64 0 0 0 9.6-39.68zM536.96 492.8a76.8 76.8 0 0 1 29.44 59.52h-37.12A53.12 53.12 0 0 0 512 517.76a71.04 71.04 0 0 0-42.24-10.88 84.48 84.48 0 0 0-39.68 5.12 29.44 29.44 0 0 0 0 53.76 320 320 0 0 0 42.88 15.36 387.2 387.2 0 0 1 64 23.68 64 64 0 0 1 32 53.76 60.16 60.16 0 0 1-26.24 51.84 118.4 118.4 0 0 1-72.32 19.2 128 128 0 0 1-71.04-17.92 87.68 87.68 0 0 1-33.28-69.12h37.12a64 64 0 0 0 21.12 42.24 76.16 76.16 0 0 0 46.08 11.52 92.8 92.8 0 0 0 44.8-9.6 30.08 30.08 0 0 0 16.64-26.24 37.76 37.76 0 0 0-19.84-30.72c-5.76 0-22.4-8.32-49.28-16.64a429.44 429.44 0 0 1-56.96-20.48 53.76 53.76 0 0 1-28.16-49.28 57.6 57.6 0 0 1 27.52-51.2 110.72 110.72 0 0 1 64-17.92 107.52 107.52 0 0 1 67.84 18.56z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M590.222 73.956l268.8 268.299v533.834c0 37.7-30.566 68.267-68.266 68.267H233.244c-37.7 0-68.266-30.567-68.266-68.267V142.222c0-37.7 30.566-68.266 68.266-68.266h356.978zM578.458 102.4H233.244a39.822 39.822 0 0 0-39.799 38.457l-0.023 1.365V876.09a39.822 39.822 0 0 0 38.457 39.8l1.365 0.022h557.512a39.822 39.822 0 0 0 39.799-38.457l0.023-1.365V354.054L578.458 102.4z" ></path><path d="M854.756 370.648H639.613c-45.528 0-82.551-36.431-83.507-81.738l-0.017-1.792V73.956h28.444v213.162c0 29.895 23.82 54.232 53.516 55.063l1.564 0.023h215.143v28.444zM85.333 489.244h853.334q28.444 0 28.444 28.445v284.444q0 28.445-28.444 28.445H85.333q-28.444 0-28.444-28.445V517.69q0-28.445 28.444-28.445z" ></path><path d="M366.564 756.622v-65.28c0-18.944-3.584-47.36-5.888-66.048h1.024l15.36 45.568 25.856 69.632h25.088l25.6-69.632 15.872-45.568h1.28c-2.56 18.688-6.144 47.104-6.144 66.048v65.28h41.728v-190.72h-49.664l-29.184 82.432c-3.584 11.008-6.656 23.04-10.496 34.56h-1.28c-3.584-11.52-6.656-23.552-10.496-34.56l-30.208-82.432h-49.408v190.72h40.96z m240.896 0c55.552 0 93.952-29.952 93.952-96.256s-38.4-94.464-96.512-94.464h-54.784v190.72h57.344z m-5.376-36.864h-6.144V602.51h6.144c30.72 0 52.48 12.544 52.48 57.856s-21.76 59.392-52.48 59.392z" ></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z" fill="#B7B7BD" ></path><path d="M665 64l-11 23.5v197c0 13.807 11.193 25 25 25h194.5L897 296 665 64z m14 49.355L850.145 284.5H679V113.355z" fill="#B7B7BD" ></path><path d="M255 571m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 707m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 639m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 774m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 842m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M67 193m16 0l287 0q16 0 16 16l0 287q0 16-16 16l-287 0q-16 0-16-16l0-287q0-16 16-16Z" fill="#FF4867" ></path><path d="M314.229 459.289c-21.407 0-40.606-36.765-50.708-60.673-16.991-7.098-35.722-13.728-53.918-18.014-15.92 10.514-43.014 26.251-63.818 26.251-12.911 0-22.21-6.496-25.622-17.813-2.609-9.309-0.4-15.738 2.409-19.22 5.485-7.5 16.79-11.317 33.715-11.317 13.714 0 31.107 2.41 50.507 7.098 12.51-8.907 25.22-19.22 36.525-30.135-5.017-23.84-10.503-62.48 3.412-80.294 6.89-8.505 17.393-11.318 30.103-7.5 13.914 4.017 19.199 12.522 20.804 19.22 5.887 23.237-20.804 54.578-38.8 72.994 4.015 15.938 9.3 32.747 15.721 48.15 25.822 11.518 56.527 28.728 60.006 47.48 1.405 6.495-0.602 12.522-5.887 17.813-4.549 3.75-9.365 5.96-14.45 5.96z m-31.647-52.419c12.785 26.402 24.975 38.862 31.4 38.862 0.995 0 2.386-0.404 4.373-2.02 2.385-2.425 2.385-4.041 1.988-5.523-1.325-6.937-12.124-18.32-37.761-31.319z m-126.377-35.247c-16.73 0-21.33 4.093-22.73 6.003-0.399 0.614-1.599 2.455-0.399 7.23 1 4.092 3.8 8.458 12.464 8.458 10.865 0 26.595-6.207 44.857-17.325-13.063-2.933-24.594-4.366-34.192-4.366z m67.632-1.765c10.845 2.983 22.09 6.827 32.535 10.803-3.792-9.809-6.853-20.015-9.448-29.824-7.651 6.561-15.436 12.99-23.087 19.021zM265.9 259.556c-3.827 0-6.513 1.409-8.93 4.024-7.118 8.917-7.924 31.38-2.418 60.144 20.884-22.26 32.232-42.711 29.411-53.64-0.402-1.61-1.611-6.504-11.348-9.32-2.686-0.805-4.7-1.208-6.715-1.208z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z" fill="#B7B7BD" ></path><path d="M665 64l-11 23.5v197c0 13.807 11.193 25 25 25h194.5L897 296 665 64z m14 49.355L850.145 284.5H679V113.355z" fill="#B7B7BD" ></path><path d="M255 571m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 707m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 639m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 774m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 842m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M67 193m16 0l287 0q16 0 16 16l0 287q0 16-16 16l-287 0q-16 0-16-16l0-287q0-16 16-16Z" fill="#FF7A64" ></path><path d="M314 312.055c0 16.701-8.014 25.218-26.96 27.787H129c-5.523 0-10 4.477-10 10V451.5c0 5.523 4.477 10 10 10s10-4.477 10-10v-91.658h148.694a10 10 0 0 0 1.264-0.08C317.98 356.065 334 339.393 334 312.055c0-26.83-15.298-44.972-43.677-52.703a10 10 0 0 0-2.629-0.352H129c-5.523 0-10 4.477-10 10s4.477 10 10 10h157.317C305.466 284.553 314 295.032 314 312.055z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M202.666667 938.666667h618.666666a10.666667 10.666667 0 0 0 10.666667-10.666667V298.666667H650.666667c-17.642667 0-32-14.357333-32-32V85.333333H202.666667a10.666667 10.666667 0 0 0-10.666667 10.666667v832a10.666667 10.666667 0 0 0 10.666667 10.666667z" fill="#FFFFFF" ></path><path d="M827.584 277.333333L640 89.749333V266.666667a10.666667 10.666667 0 0 0 10.666667 10.666666h176.917333z" fill="#FFFFFF" ></path><path d="M843.957333 263.541333L653.792 73.376A31.765333 31.765333 0 0 0 631.168 64H202.666667c-17.642667 0-32 14.357333-32 32v832c0 17.642667 14.357333 32 32 32h618.666666c17.642667 0 32-14.357333 32-32V286.165333c0-8.533333-3.338667-16.576-9.376-22.624zM640 89.749333L827.584 277.333333H650.666667a10.666667 10.666667 0 0 1-10.666667-10.666666V89.749333zM821.333333 938.666667H202.666667a10.666667 10.666667 0 0 1-10.666667-10.666667V96a10.666667 10.666667 0 0 1 10.666667-10.666667h416v181.333334c0 17.642667 14.357333 32 32 32h181.333333v629.333333a10.666667 10.666667 0 0 1-10.666667 10.666667z" fill="#605E5C" opacity=".64" ></path><path d="M757.333333 650.666667H266.666667a10.666667 10.666667 0 1 1 0-21.333334h490.666666a10.666667 10.666667 0 1 1 0 21.333334z m0-64H266.666667a10.666667 10.666667 0 1 1 0-21.333334h490.666666a10.666667 10.666667 0 1 1 0 21.333334z m0-64H266.666667a10.666667 10.666667 0 1 1 0-21.333334h490.666666a10.666667 10.666667 0 1 1 0 21.333334z m0-64H266.666667a10.666667 10.666667 0 1 1 0-21.333334h490.666666a10.666667 10.666667 0 1 1 0 21.333334z m0 256H266.666667a10.666667 10.666667 0 1 1 0-21.333334h490.666666a10.666667 10.666667 0 1 1 0 21.333334z" fill="#C8C6C4" ></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M166.054054 0h513.660541a27.675676 27.675676 0 0 1 19.483675 8.025946l205.907027 204.025081a27.675676 27.675676 0 0 1 8.192 19.64973V968.648649a55.351351 55.351351 0 0 1-55.351351 55.351351H166.054054a55.351351 55.351351 0 0 1-55.351351-55.351351V55.351351a55.351351 55.351351 0 0 1 55.351351-55.351351z" fill="#3370FF" ></path><path d="M691.103135 2.449297a27.675676 27.675676 0 0 1 8.095135 5.562811l205.907027 204.038919a27.675676 27.675676 0 0 1 6.199352 9.354378H746.454486a55.351351 55.351351 0 0 1-55.351351-55.351351V2.449297z" fill="#154DCE" ></path><path d="M290.594595 484.324324a27.675676 27.675676 0 0 1 27.675675-27.675675h276.756757a27.675676 27.675676 0 0 1 27.675676 27.675675v276.756757a27.675676 27.675676 0 0 1-27.675676 27.675676H318.27027a27.675676 27.675676 0 0 1-27.675675-27.675676V484.324324z m110.702702 27.675676h-41.513513a13.837838 13.837838 0 0 0-13.837838 13.837838v41.513513a13.837838 13.837838 0 0 0 13.837838 13.837838h41.513513a13.837838 13.837838 0 0 0 13.837838-13.837838v-41.513513a13.837838 13.837838 0 0 0-13.837838-13.837838z m249.081081 41.513514l65.812757-37.611244A20.756757 20.756757 0 0 1 747.243243 533.932973v177.539459a20.756757 20.756757 0 0 1-31.052108 18.030703L650.378378 691.891892V553.513514z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M205.5 64H665l232 232v639c0 13.807-11.193 25-25 25H205.5c-13.807 0-25-11.193-25-25V89c0-13.807 11.193-25 25-25z m449.145 25H205.5v846H872V306.355L654.645 89z" fill="#B7B7BD" ></path><path d="M665 64l-11 23.5v197c0 13.807 11.193 25 25 25h194.5L897 296 665 64z m14 49.355L850.145 284.5H679V113.355z" fill="#B7B7BD" ></path><path d="M67 193m16 0l287 0q16 0 16 16l0 287q0 16-16 16l-287 0q-16 0-16-16l0-287q0-16 16-16Z" fill="#4297FC" ></path><path d="M255 571m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 707m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 639m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 774m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M255 842m10 0l556 0q10 0 10 10l0 0q0 10-10 10l-556 0q-10 0-10-10l0 0q0-10 10-10Z" fill="#B7B7BD" ></path><path d="M315.269 451.314c7.015 7.61 19.731 2.651 19.731-7.693V271h-22.737v143.524l-76.9-83.418c-4.503-4.885-12.223-4.885-16.726 0l-76.9 83.418V271H119v172.62c0 10.345 12.716 15.303 19.731 7.694L227 355.564l88.269 95.75z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M908.611316 239.279126l2.721684 711.518223c0 16.451366-13.204209 29.655575-29.642101 29.655575h-687.831489c-16.46484 0-29.655575-13.204209-29.655575-29.642102V73.000411c0-16.437893 13.204209-29.628628 29.642102-29.628627l522.468983-1.104842L675.1124 0H195.287621A69.48378 69.48378 0 0 0 125.709525 69.578096v884.843673A69.497254 69.497254 0 0 0 195.287621 1023.999865H880.235741a69.510728 69.510728 0 0 0 69.59157-69.578096V281.573016l-41.215995-42.29389z" fill="#D6473B" fill-opacity=".4" ></path><path d="M675.1124 206.21471a75.51999 75.51999 0 0 0 75.546937 75.546937h199.343132L675.1124 0v206.21471z" fill="#EF6A63" ></path><path d="M532.34526 481.091305H109.985737A96.498514 96.498514 0 0 1 13.47375 384.592792V320.781431A96.498514 96.498514 0 0 1 109.985737 224.269444H532.34526a96.48504 96.48504 0 0 1 96.498514 96.511987v63.811361a96.48504 96.48504 0 0 1-96.498514 96.498513" fill="#FA4E4E" ></path><path d="M463.11748 274.890069h49.340625v124.335142h77.177253v40.663573h-126.517878V274.890069z m-211.442498 0h65.064412l25.114944 100.298092 24.95326-100.298092h64.862307v164.998715h-40.474942v-125.776825l-31.258943 125.776825H323.233709l-31.083785-125.776825v125.776825h-40.474942V274.890069z m-184.185239 0h54.433677l28.348628 50.782309 27.486312-50.795783h53.867782L181.89478 354.762059l54.393256 85.126725H180.816886l-31.609259-52.951572-31.636207 52.951572H62.625743l55.134309-86.029462-50.256836-78.969253z" fill="#FFFFFF" ></path><path d="M249.869508 715.129169c11.735577-0.175158 21.328839-2.70821 28.725891-7.585683 7.410525-4.877473 12.287998-11.573893 14.821051-19.887155 2.533052-8.48842 3.799578-22.945681 3.974736-43.358311 0.188632-20.426103 0.552421-33.980627 1.455158-40.488415 1.441684-10.293893 3.974736-18.607155 7.774315-24.751155 3.772631-6.332631 8.299788-11.210104 13.918314-15.009682 5.41642-3.786105 12.449683-6.494315 21.126734-8.501894 5.793683-1.253052 15.373472-1.805473 28.564206-1.805473h12.826946v28.927996h-7.033262c-15.925893 0-26.583575 2.344421-31.636207 6.858104-5.254736 4.527157-7.774315 14.821051-7.774314 30.719996 0 32.175154-0.902737 52.412625-2.533053 60.725887-2.70821 13.204209-7.410525 23.147786-14.093471 30.356207-6.682946 7.06021-17.165471 13.39284-31.272417 18.997892 16.815156 5.591578 29.103154 14.282103 36.688837 25.829049 7.585683 11.587367 11.398735 30.544838 11.398735 56.926308 0 23.861892 0.350316 38.130521 0.889263 42.671153 1.28 8.313262 4.351999 14.079998 9.215999 17.515787 5.079578 3.260631 14.821051 4.877473 29.278312 4.877473h7.06021v28.927996h-12.826946c-15.009682 0-25.855997-0.902737-32.538943-2.883368-9.754946-2.910315-17.89305-7.410525-24.400839-13.743156-6.507789-6.332631-10.657683-14.282103-12.47663-24.03705-1.980631-9.76842-2.883368-25.492207-3.058526-47.521677-0.188632-22.069892-1.455158-37.241258-3.98821-45.743152a35.301048 35.301048 0 0 0-14.821051-20.062314c-7.397052-4.877473-16.97684-7.410525-28.725891-7.774314v-30.181049h-0.538947zM773.254702 667.41886H457.70106a30.046312 30.046312 0 0 1-30.005891-30.005891v-5.578105a30.059786 30.059786 0 0 1 30.005891-30.019364h315.553642a30.059786 30.059786 0 0 1 30.005891 30.019364v5.578105c0.161684 16.639998-13.379367 30.005891-30.005891 30.005891M773.254702 785.623476H457.70106a30.046312 30.046312 0 0 1-30.005891-30.005891v-5.605052a30.046312 30.046312 0 0 1 30.005891-30.005891h315.553642a30.059786 30.059786 0 0 1 30.005891 30.005891v5.605052c0.161684 16.437893-13.379367 30.005891-30.005891 30.005891M773.254702 903.63946H457.70106a30.046312 30.046312 0 0 1-30.005891-30.005891v-5.605052a30.046312 30.046312 0 0 1 30.005891-30.00589h315.553642a30.046312 30.046312 0 0 1 30.005891 30.00589v5.605052c0.161684 16.626524-13.379367 30.005891-30.005891 30.005891" fill="#EF6A63" ></path></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M90.898002 585.183559V40.413248A38.577551 38.577551 0 0 1 131.267476 0.094972H727.798775v182.827384c0 20.223135 15.871322 36.529638 35.377687 36.529638h176.939636v365.680368l-849.192497 0.051197z" fill="#FFDBD9" ></path><path d="M728.105961 0.222966l212.266126 219.382622h-176.888438a35.966462 35.966462 0 0 1-35.377688-36.555237V0.222966z" fill="#F58072" ></path><path d="M969.55484 585.183559c22.859823 0.076797 41.342233 19.199179 41.291034 42.878167v353.060107A42.1102 42.1102 0 0 1 969.631636 1024H61.459261a42.1102 42.1102 0 0 1-41.291035-42.878167V628.010529a42.238194 42.238194 0 0 1 41.291035-42.82697h908.06998zM325.819159 213.385054a17.279261 17.279261 0 1 1 0 34.60972 34.046545 34.046545 0 0 0-34.404929 31.230665l-0.153593 3.404655v34.558522a69.168243 69.168243 0 0 1-23.986175 51.888982 69.117045 69.117045 0 0 1 23.806982 46.769201l0.179193 5.119781v34.635319a34.097742 34.097742 0 0 0 34.558522 34.558523 17.279261 17.279261 0 0 1 0 34.558522 69.398633 69.398633 0 0 1-69.040248-64.816429l-0.127995-4.351814v-34.558522c0-19.531965-15.103354-34.635319-34.558522-34.686518a17.279261 17.279261 0 0 1 0-34.558522c18.303218 0 32.817797-13.388228 34.456127-31.179467l0.153593-3.379056v-34.635319a69.373034 69.373034 0 0 1 69.117045-69.168243z m377.814249 0a69.373034 69.373034 0 0 1 70.780974 64.176456l0.179192 5.068584v34.558522a34.174539 34.174539 0 0 0 34.558523 34.609721 17.279261 17.279261 0 1 1 0 34.558522c-18.303218 0-32.817797 13.388228-34.456127 31.230665l-0.153594 3.404655v34.60972c0 38.014375-31.10267 69.117045-69.117045 69.117045a17.30486 17.30486 0 1 1 0-34.60972 34.046545 34.046545 0 0 0 34.404929-31.179467l0.153594-3.379056v-34.558522c0.102396-19.967146 8.857221-38.935935 23.986174-51.965779a69.01465 69.01465 0 0 1-23.806982-46.718003l-0.179192-5.119781v-34.635319c0-19.455168-15.103354-34.558523-34.63532-34.558523a17.279261 17.279261 0 0 1-18.175223-16.434497 17.279261 17.279261 0 0 1 16.460097-18.175223z m-300.35196 179.704317a34.584122 34.584122 0 1 1 0 69.168243 34.584122 34.584122 0 0 1 0-69.168243z m111.867217 0a34.584122 34.584122 0 1 1 0 69.168243 34.584122 34.584122 0 0 1 0-69.168243z m111.81602 0a34.584122 34.584122 0 1 1 0 69.168243 34.584122 34.584122 0 0 1 0-69.168243z" fill="#F05542" ></path><path d="M197.978224 929.284049v-92.488846l76.131146-160.095556H221.529218l-25.240521 61.437374c-7.167694 18.789597-14.693772 36.529638-22.527037 55.984806h-1.382341c-7.833265-19.455168-14.668173-37.19521-21.835867-55.984806l-25.26612-61.437374H71.698823l75.772761 160.095556V929.284049h50.50664z m117.422181 0l17.740041-64.842028h81.916498l17.765641 64.842028h52.887339L404.484596 676.699647h-59.389461L264.202593 929.284049h51.197812z m88.751406-104.110749H344.071179l7.500479-27.646818c7.526078-26.264477 15.026558-54.935252 21.503081-82.58207h1.382341c7.500479 27.288433 14.335387 56.317592 22.168652 82.58207l7.526079 27.646818z m156.665302 104.110749v-105.467491c0-23.883779-4.095825-59.056675-6.502122-82.940454h1.382341l20.12074 59.389461 39.268721 106.158661h29.00356l38.910337-106.158661 20.479124-59.389461h1.356742c-2.380698 23.883779-6.143737 59.056675-6.143737 82.940454v105.467491h46.07803v-252.584402h-55.959208l-41.982205 118.113351c-5.478166 15.692129-9.906776 32.408215-15.359343 48.791514H629.754966c-5.119781-16.3833-9.906776-33.099385-15.359343-48.791514l-43.006162-118.113351h-55.984807V929.284049h45.412459z m398.984543 0v-42.314991h-102.395622v-210.269411H806.899393V929.284049h152.902263z" fill="#FFFFFF" ></path></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M672 64H192a64 64 0 0 0-64 64v768a64 64 0 0 0 64 64h640a64 64 0 0 0 64-64V288L672 64zM832 896H192V128h192v64h64V128h192l192 192v576zM448 256V192h64v64H448zM384 256h64v64H384V256z m64 128V320h64v64H448zM384 384h64v64H384V384z m64 128V448h64v64H448zM384 593.92A128 128 0 0 0 320 704v64h256v-64a128 128 0 0 0-128-128V512H384v81.92zM512 640v64H384v-64h128z" ></path></svg>

After

Width:  |  Height:  |  Size: 442 B

View File

@@ -0,0 +1,114 @@
const allSvgIcons = import.meta.glob('./**/*.svg', { eager: true, query: 'raw' });
const iconNames = [];
/**
* 获取本地图标
* @returns 本地图标
*/
export function getLocalIcons() {
return iconNames;
}
function convertSvgToSymbol(svgString, symbolId) {
// 创建一个 DOMParser 实例
const parser = new DOMParser();
// 解析 SVG 字符串为文档对象
const doc = parser.parseFromString(svgString, 'image/svg+xml');
// 获取外层的 <svg> 元素
const svgElement = doc.querySelector('svg');
// 创建一个新的 <symbol> 元素
const symbolElement = document.createElementNS('http://www.w3.org/2000/svg', 'symbol');
// 设置 <symbol> 元素的 id 属性
symbolElement.setAttribute('id', symbolId);
// 复制 <svg> 元素的 viewBox 属性到 <symbol> 元素
if (svgElement.hasAttribute('viewBox')) {
symbolElement.setAttribute('viewBox', svgElement.getAttribute('viewBox'));
}
// 将 <svg> 元素的所有子节点复制到 <symbol> 元素中
while (svgElement.firstChild) {
symbolElement.appendChild(svgElement.firstChild);
}
// 创建一个临时的 div 元素来存储 <symbol> 元素的内容
const tempDiv = document.createElement('div');
tempDiv.appendChild(symbolElement);
// 返回 <symbol> 标签的内容
return tempDiv.innerHTML;
}
// iconfont 代码
(function (c) {
let svgsymbols = '<svg>';
// 初始化icons
for (const path in allSvgIcons) {
// ./df/input.svg
// 转为 df/input
const name = path.replace('.svg', '').replace(/^\.\//, '');
iconNames.push(`icon ${name}`);
svgsymbols += convertSvgToSymbol(allSvgIcons[path].default, name);
}
svgsymbols += '</svg>';
var t = (t = document.getElementsByTagName('script'))[t.length - 1],
a = t.getAttribute('data-injectcss'),
t = t.getAttribute('data-disable-injectsvg');
if (!t) {
var l,
e,
i,
o,
n,
h = function (t, a) {
a.parentNode.insertBefore(t, a);
};
if (a && !c.__iconfont__svg__cssinject__) {
c.__iconfont__svg__cssinject__ = !0;
try {
document.write(
'<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>'
);
} catch (t) {
console && console.log(t);
}
}
(l = function () {
var t,
a = document.createElement('div');
(a.innerHTML = svgsymbols),
(a = a.getElementsByTagName('svg')[0]) &&
(a.setAttribute('aria-hidden', 'true'),
(a.style.position = 'absolute'),
(a.style.width = 0),
(a.style.height = 0),
(a.style.overflow = 'hidden'),
(a = a),
(t = document.body).firstChild ? h(a, t.firstChild) : t.appendChild(a));
}),
document.addEventListener
? ~['complete', 'loaded', 'interactive'].indexOf(document.readyState)
? setTimeout(l, 0)
: ((e = function () {
document.removeEventListener('DOMContentLoaded', e, !1), l();
}),
document.addEventListener('DOMContentLoaded', e, !1))
: document.attachEvent &&
((i = l),
(o = c.document),
(n = !1),
s(),
(o.onreadystatechange = function () {
'complete' == o.readyState && ((o.onreadystatechange = null), d());
}));
}
function d() {
n || ((n = !0), i());
}
function s() {
try {
o.documentElement.doScroll('left');
} catch (t) {
return void setTimeout(s, 50);
}
d();
}
})(window);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-fuhao-zhongwen" viewBox="0 0 1024 1024"><path d="M512 960C264.576 960 64 759.424 64 512S264.576 64 512 64s448 200.576 448 448-200.576 448-448 448z m0-64c212.064 0 384-171.936 384-384S724.064 128 512 128 128 299.936 128 512s171.936 384 384 384z m-32.96-566.464c0-9.856 2.08-16.576 6.272-20.16 4.16-3.584 11.2-5.376 21.056-5.376 9.28 0 16.128 1.792 20.608 5.376 4.48 3.584 6.72 10.304 6.72 20.16v56.448h110.208c11.04 0 19.936 0.512 26.656 1.568 6.72 1.056 11.936 3.36 15.68 6.944 3.744 3.584 6.272 8.64 7.616 15.232 1.344 6.56 2.016 15.232 2.016 25.984v135.744c0 9.856-0.608 17.984-1.792 24.416a26.976 26.976 0 0 1-7.392 15.008c-3.744 3.584-8.96 6.112-15.68 7.616-6.72 1.504-15.616 2.24-26.656 2.24H533.696v92.288c0 7.776-1.92 13.952-5.824 18.592-3.872 4.64-11.04 6.944-21.504 6.944-11.648 0-19.104-1.92-22.4-5.824-3.296-3.872-4.928-10.592-4.928-20.16v-91.84H371.072c-10.752 0-19.488-0.736-26.208-2.24a31.168 31.168 0 0 1-15.68-7.84 28.192 28.192 0 0 1-7.392-15.232c-1.184-6.4-1.792-14.4-1.792-23.968V435.264c0-10.144 0.608-18.432 1.792-24.864a26.976 26.976 0 0 1 7.392-15.008 30.816 30.816 0 0 1 15.68-7.392 138.24 138.24 0 0 1 26.208-2.016H479.04v-56.448z m-94.528 109.76c-4.48 0-7.328 0.736-8.512 2.24-1.184 1.504-1.792 5.216-1.792 11.2v99.008c0 7.168 0.672 11.584 2.016 13.216 1.344 1.632 4.544 2.464 9.632 2.464h93.184V439.296h-94.528z m149.184 0v128.128h95.424c5.984 0 9.568-0.896 10.752-2.688 1.184-1.792 1.792-6.112 1.792-12.992v-99.008c0-5.664-0.96-9.344-2.912-10.976-1.92-1.632-6.336-2.464-13.216-2.464h-91.84z" ></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-fuhao-yingwen" viewBox="0 0 1024 1024"><path d="M512 960C264.576 960 64 759.424 64 512S264.576 64 512 64s448 200.576 448 448-200.576 448-448 448z m0-64c212.064 0 384-171.936 384-384S724.064 128 512 128 128 299.936 128 512s171.936 384 384 384z m103.04-428.32v7.232c10.464-13.856 21.952-24.032 34.432-30.528 12.48-6.496 26.784-9.728 42.976-9.728 15.744 0 29.824 3.424 42.24 10.272 12.384 6.848 21.632 16.576 27.776 29.12 3.936 7.264 6.496 15.136 7.648 23.616 1.152 8.448 1.76 19.232 1.76 32.352v111.136c0 11.968-2.752 20.992-8.224 27.136a27.264 27.264 0 0 1-21.312 9.184 27.52 27.52 0 0 1-21.664-9.408c-5.536-6.272-8.32-15.232-8.32-26.88v-99.552c0-19.68-2.72-34.752-8.192-45.184-5.472-10.432-16.384-15.648-32.704-15.648-10.656 0-20.352 3.2-29.12 9.536-8.736 6.336-15.136 15.04-19.2 26.144-2.944 8.896-4.384 25.504-4.384 49.856v74.816c0 12.096-2.816 21.184-8.448 27.232a28.352 28.352 0 0 1-21.76 9.088 27.04 27.04 0 0 1-21.216-9.408c-5.536-6.272-8.32-15.232-8.32-26.88V468.576c0-11.392 2.496-19.872 7.456-25.504 4.96-5.6 11.744-8.416 20.32-8.416 5.28 0 10.016 1.248 14.24 3.712a26.624 26.624 0 0 1 10.176 11.168c2.56 4.96 3.84 11.008 3.84 18.144z m-112.736-66.272H355.968v78.72H490.72c9.92 0 17.312 2.24 22.208 6.72a22.688 22.688 0 0 1 7.328 17.6 23.552 23.552 0 0 1-7.232 17.824c-4.8 4.576-12.256 6.88-22.304 6.88H355.968v91.2h151.36c10.24 0 17.92 2.4 23.104 7.136a24.416 24.416 0 0 1 7.744 18.912c0 7.584-2.56 13.76-7.744 18.496-5.184 4.736-12.864 7.104-23.104 7.104H330.816c-14.144 0-24.32-3.136-30.528-9.408-6.176-6.272-9.28-16.416-9.28-30.4V391.136c0-9.344 1.376-16.96 4.16-22.88a25.792 25.792 0 0 1 12.992-12.896c5.92-2.688 13.44-4.032 22.656-4.032h171.52c10.336 0 18.016 2.272 23.04 6.88a23.296 23.296 0 0 1 7.552 18.048 23.552 23.552 0 0 1-7.552 18.24c-5.024 4.608-12.704 6.912-23.04 6.912z" ></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="icon-tag-view-active" viewBox="0 0 1024 1024"><path fill="currentColor" d="M469.333 788.48c-141.653 0-256.853-115.2-256.853-256.853s115.2-256.854 256.853-256.854 256.854 115.2 256.854 256.854-115.2 256.853-256.854 256.853z m0-488.448c-127.658 0-231.594 103.936-231.594 231.595S341.675 763.22 469.333 763.22s231.595-103.936 231.595-231.594-103.936-231.595-231.595-231.595z" ></path><path fill="currentColor" d="M469.333 371.541c88.406 0 160.086 71.68 160.086 160.086s-71.68 160.085-160.086 160.085-160.085-71.68-160.085-160.085 71.68-160.086 160.085-160.086z" ></path></svg>

After

Width:  |  Height:  |  Size: 619 B

View File

@@ -0,0 +1 @@
<svg t="1737075628303" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10200" width="48" height="48"><path d="M335.36 395.776c0 91.648 69.632 167.424 157.184 179.712v206.336c0 16.384 14.336 30.72 30.72 30.72s30.72-14.336 30.72-30.72v-91.648h71.68c16.384 0 30.72-14.336 30.72-30.72s-14.336-30.72-30.72-30.72h-71.68V573.44c81.92-16.384 144.896-89.6 144.896-177.664 0-99.84-81.92-181.76-181.76-181.76S335.36 295.424 335.36 395.776zM517.12 274.944c67.584 0 120.32 53.248 120.32 120.32 0 67.584-53.248 120.32-120.32 120.32S396.288 462.848 396.288 395.776 449.536 274.944 517.12 274.944z" p-id="10201"></path><path d="M900.608 152.576L522.752 30.208c-6.144-2.048-12.288-2.048-18.432 0L126.976 152.576c-12.288 4.096-20.48 16.384-20.48 28.672v477.696c2.048 16.384 24.576 159.232 396.288 332.8 4.096 2.048 8.192 2.048 12.288 2.048 4.096 0 8.192 0 12.288-2.048 369.664-173.568 394.24-316.416 396.288-332.8V181.248c-2.56-12.288-10.752-24.576-23.04-28.672z m-40.96 502.272c-2.048 10.24-36.864 126.464-347.136 275.456-312.32-148.992-345.088-265.216-347.136-275.456V203.776l347.136-114.176 347.136 114.176v451.072z" p-id="10202"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg t="1737074876174" class="icon" viewBox="0 0 1026 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8851" width="48" height="48"><path d="M392.92 608.306a224.526 224.526 0 1 1 224.527-224.527 224.526 224.526 0 0 1-224.526 224.527z m0-384.902a160.376 160.376 0 1 0 160.377 160.375A160.376 160.376 0 0 0 392.92 223.404z" p-id="8852"></path><path d="M713.673 864.907h-64.15a256.601 256.601 0 0 0-513.204 0H72.17a320.752 320.752 0 0 1 641.504 0zM665.56 576.231v-64.15a144.338 144.338 0 1 0-38.01-283.706l-16.839-61.905a208.489 208.489 0 1 1 54.849 409.76z" p-id="8853"></path><path d="M954.236 800.757h-64.15A224.526 224.526 0 0 0 665.56 576.23v-64.15a288.677 288.677 0 0 1 288.676 288.676z" p-id="8854"></path></svg>

After

Width:  |  Height:  |  Size: 728 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M740.144 619.728a24 24 0 0 0-29.744 16.352c-18.176 62.56-52.272 109.392-98.56 135.472a24 24 0 0 0 11.808 44.896 23.712 23.712 0 0 0 11.744-3.088c57.456-32.352 99.328-89.024 121.104-163.872a24 24 0 0 0-16.352-29.76z" fill="#666666" ></path><path d="M410.208 764.016c-61.856-41.952-98.768-128.112-98.768-230.4 0-154.656 154.224-337.344 206.4-394.768 43.792 48.112 159.296 184.224 195.504 318.704a24.032 24.032 0 0 0 46.4-12.48c-48-178.496-217.6-350.944-224.832-358.208a24.736 24.736 0 0 0-34.08 0c-9.696 9.776-237.392 241.696-237.392 446.752 0 118.304 44.8 219.312 119.84 270.192a24 24 0 1 0 26.928-39.712z" fill="#666666" ></path><path d="M517.936 557.68a24 24 0 0 0-24 24v338.336a24 24 0 0 0 48 0V581.68a24 24 0 0 0-24-24z" fill="#1771B9" ></path><path d="M760.048 541.104a42.832 42.832 0 0 0-1.28-4.48 36.8 36.8 0 0 0-2.224-4.16 21.856 21.856 0 0 0-3.04-3.52 24.608 24.608 0 0 0-33.92 0 30.192 30.192 0 0 0-3.04 3.52 20.272 20.272 0 0 0-2.096 4.16 25.488 25.488 0 0 0-1.44 4.48 24.384 24.384 0 0 0-0.464 4.8 23.024 23.024 0 0 0 1.904 9.12 24.624 24.624 0 0 0 5.136 7.84 23.04 23.04 0 0 0 7.824 5.12 22.288 22.288 0 0 0 9.136 1.92 24 24 0 0 0 16.96-7.04 28.112 28.112 0 0 0 5.264-7.84 25.328 25.328 0 0 0 1.776-9.12 24.496 24.496 0 0 0-0.496-4.8z" fill="#666666" ></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M475.19999999 84.5568c202.7008 0 362.6496 71.0912 373.50400001 163.6608l0.40959999 4.5568h0.5632v232.2432H795.19999999V364.288c-63.1552 48.3328-175.5648 80.5888-307.5584 82.5088l-12.4416 0.0768c-133.1968 0-247.7312-30.8224-313.93279999-78.08L155.2 364.288v136.7552c0 63.5136 128.6144 126.208 319.99999999 126.208 63.1808 0 119.5264-6.8352 166.656-18.2784-4.9408 23.552-6.4 43.5968-4.4032 60.2112-48.7936 10.6752-103.7056 16.6144-162.2528 16.6144-133.1968 0-247.7312-30.7968-313.93279999-78.08l-6.0672-4.5056v125.824c0 63.5136 128.6144 126.2336 319.99999999 126.2336 74.3168 0 139.1616-9.4464 190.6688-24.7296l15.18080001 55.5008a631.04 631.04 0 0 1-89.6256 19.584 803.8656 803.8656 0 0 1-116.22400001 8.192c-206.7456 0-369.3312-73.984-374.3488-169.1392l-0.128-4.5568V252.7744h0.56320001C107.32799999 158.0032 269.1712 84.5824 475.19999999 84.5824z m335.18080001 637.696c12.3648 0 22.4 10.0608 22.39999999 22.4256l-0.0768 74.112a22.3744 22.3744 0 0 1 8.96-9.3184c15.4112-8.704 27.0336-24.6528 33.408-46.592a22.4 22.4 0 1 1 43.008 12.4928c-9.6 33.024-28.416 58.4704-54.39999999 73.1136a22.4 22.4 0 0 1-30.92480001-9.216v40.7296a22.4 22.4 0 0 1-44.79999999 0V744.704c0-12.3648 10.0608-22.4 22.4256-22.4z m-15.6672-184.7808a22.784 22.784 0 0 1 31.51359999 0.256c9.8816 9.8816 24.6528 26.624 40.06400001 47.36 25.3184 34.048 44.2624 68.4544 53.24799999 101.9136a22.4256 22.4256 0 0 1-43.3664 11.3408c-9.8816-36.6848-35.584-76.3392-65.8432-111.488-39.7824 46.1824-69.76 97.152-69.75999999 138.5984 0 36.992 13.056 67.4048 33.89439999 81.5616l5.632 5.3248a22.4 22.4 0 0 1-30.77119999 31.7696c-33.8432-22.9376-53.5552-67.3792-53.55520001-118.656 0-39.1424 18.1248-81.8944 48.2816-125.8752a461.312 461.312 0 0 1 50.688-62.1056zM475.19999999 143.0016c-187.7504 0.0512-314.7776 60.416-319.53919999 122.7264 4.8128 62.2336 131.7888 122.5984 319.53919999 122.5984s314.7776-60.3648 319.5392-122.6496C789.92639999 203.4176 662.95039999 143.0016 475.19999999 143.0016z" ></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M940.8 728.32c-49.493333 26.026667-307.2 131.84-361.813333 160.426667s-85.333333 28.16-128.426667 7.68-317.013333-131.413333-366.506667-154.88c-24.746667-11.946667-37.546667-21.76-37.546666-31.146667v-94.293333s356.693333-77.653333 414.293333-98.133334 77.653333-21.333333 126.72-3.413333 341.76 70.826667 390.4 88.32V695.466667c0 8.533333-11.52 19.626667-37.12 32.853333z" fill="#A42122" ></path><path d="M940.8 634.026667c-49.493333 26.026667-307.2 131.84-361.813333 160.426666s-85.333333 28.16-128.426667 7.68-317.013333-131.413333-366.506667-154.88-50.346667-39.68-1.706666-58.88 320.853333-125.866667 378.453333-146.346666 77.653333-21.333333 126.72-3.413334 304.64 119.893333 353.28 137.386667 49.92 32.426667 0 58.026667z" fill="#D82F27" ></path><path d="M940.8 574.72c-49.493333 26.026667-307.2 131.84-361.813333 160.426667s-85.333333 28.16-128.426667 7.68-317.013333-131.413333-366.506667-154.88c-24.746667-11.946667-37.546667-21.76-37.546666-31.146667v-94.293333s356.693333-77.653333 414.293333-98.133334 77.653333-21.333333 126.72-3.413333 341.76 70.826667 390.4 88.32V541.866667c0 8.533333-11.52 19.626667-37.12 32.853333z" fill="#A42122" ></path><path d="M940.8 480.853333c-49.493333 26.026667-307.2 131.84-361.813333 160.426667s-85.333333 28.16-128.426667 7.68-317.013333-131.413333-366.506667-154.88-50.346667-39.68-1.706666-58.88S403.2 308.906667 460.8 288.426667s77.653333-21.333333 126.72-3.413334 304.64 119.893333 352.853333 137.386667 50.346667 32.426667 0.426667 58.453333z" fill="#D82F27" ></path><path d="M940.8 415.573333c-49.493333 26.026667-307.2 131.84-361.813333 160.426667s-85.333333 28.16-128.426667 7.68-317.013333-131.413333-366.506667-154.88c-24.746667-11.946667-37.546667-21.76-37.546666-31.146667V303.36s356.693333-77.653333 414.293333-98.133333 77.653333-21.333333 126.72-3.413334 341.333333 70.826667 389.973333 88.32v92.586667c0 8.533333-11.093333 19.626667-36.693333 32.853333z" fill="#A42122" ></path><path d="M940.8 321.706667c-49.493333 26.026667-307.2 131.84-361.813333 160.426666s-85.333333 28.16-128.426667 7.68-317.013333-131.84-366.506667-155.306666-50.346667-39.68-1.706666-58.88S403.2 149.76 460.8 129.28s77.653333-21.333333 126.72-3.413333 304.64 119.893333 353.28 137.386666 49.92 32.426667 0 58.453334z" fill="#D82F27" ></path><path d="M634.026667 230.826667l-80.64 8.533333-17.92 43.52-29.44-48.64L413.013333 226.133333l69.546667-25.173333-20.906667-38.4 64.853334 25.173333 61.44-20.053333-16.64 39.68 62.72 23.466667zM530.346667 441.6L379.733333 379.306667l215.893334-33.28-65.28 95.573333z" fill="#FFFFFF" ></path><path d="M206.506667 299.946667a115.2 44.8 0 1 0 230.4 0 115.2 44.8 0 1 0-230.4 0Z" fill="#FFFFFF" ></path><path d="M729.173333 242.773333l128 50.346667L729.6 343.893333l-0.426667-101.12z" fill="#791514" ></path><path d="M587.946667 298.666667l141.226666-55.893334 0.426667 101.12-14.08 5.12L587.946667 298.666667z" fill="#AD2524" ></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M897.8125003 599.75c-0.37500029 8.58750029-11.73750029 18.18749971-35.06250058 30.375-47.99999971 25.01250029-296.84999971 127.35-349.79999942 154.95000029-52.9875 27.60000029-82.38750029 27.3375-124.23750029 7.3125-41.85-19.98749971-306.60000029-126.97499971-354.30000029-149.7375-23.81249971-11.40000029-35.96249971-20.99999971-36.37499942-30.07500029v90.97499971c0 9.07499971 12.52500029 18.71250029 36.37499942 30.11250058 47.7 22.79999971 312.48749971 129.75000029 354.30000029 149.7375 41.85 20.025 71.25000029 20.28750029 124.23750029-7.35000029 52.94999971-27.60000029 301.76250029-129.89999971 349.79999942-154.95000029 24.4125-12.7125 35.25000029-22.6125 35.25000029-31.57499971v-89.70000029l-0.18749971-0.07499971z" fill="" ></path><path d="M897.77500001 451.43749971c-0.37500029 8.58750029-11.73750029 18.15000029-35.02500029 30.33750058-47.99999971 25.01250029-296.84999971 127.35-349.79999942 154.94999942-52.9875 27.60000029-82.38750029 27.3375-124.23750029 7.35000029-41.85-19.98749971-306.60000029-126.97499971-354.30000029-149.77500029-23.81249971-11.3625-35.96249971-20.99999971-36.37499942-30.0375v90.97500058c0 9.07499971 12.52500029 18.675 36.37499942 30.07499942 47.7 22.79999971 312.45000029 129.75000029 354.30000029 149.7375 41.85 20.025 71.25000029 20.28750029 124.23750029-7.3125 52.94999971-27.60000029 301.76250029-129.9375 349.79999942-154.94999942 24.4125-12.75000029 35.25000029-22.65000029 35.25000029-31.6125v-89.70000029l-0.225-0.03750029z" fill="" ></path><path d="M897.77500001 297.61250029c0.45-9.15000029-11.51250029-17.17499971-35.58750029-26.02500029-46.8-17.13750029-294.11250029-115.57500029-341.47499942-132.93749971-47.3625-17.325-66.63750029-16.61249971-122.25000058 3.375C342.7375003 161.93750029 79.41249972 265.24999971 32.5750003 283.55000029c-23.43750029 9.225-34.875 17.73749971-34.50000058 26.81249942V401.37499971c0 9.07499971 12.52500029 18.675 36.37500029 30.07500029 47.7 22.79999971 312.45000029 129.78749971 354.30000029 149.77500029 41.85 19.98749971 71.25000029 20.25 124.23749942-7.35000029 52.94999971-27.60000029 301.76250029-129.9375 349.80000029-154.95000029 24.4125-12.75000029 35.25000029-22.65000029 35.25000029-31.6125V297.61250029h-0.30000058zM320.31250001 383.75l208.53749971-32.02499971-63 92.3625-145.49999942-60.33750029z m461.25-83.17500029l-123.33750029 48.75000029-13.3875 5.24999971-123.26249971-48.74999942 136.575-54 123.37499971 48.74999942z m-362.09999971-89.36249942l-20.17500029-37.20000058 62.92500029 24.60000058 59.32499942-19.42500058-16.04999971 38.43750058 60.45000029 22.64999942-77.9625 8.1-17.47500029 42.00000029-28.19999971-46.83750029-90-8.1 67.1625-24.22499942z m-155.3625 52.49999971c61.57500029 0 111.44999971 19.31249971 111.44999971 43.16249971s-49.87500029 43.2-111.44999971 43.2-111.4875-19.38750029-111.4875-43.2c0-23.85 49.91249971-43.2 111.4875-43.2z" fill="" ></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,121 +0,0 @@
{
"id": "3953964",
"name": "mayfly-go",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "2967035",
"name": "符号-英文",
"font_class": "fuhao-yingwen",
"unicode": "e712",
"unicode_decimal": 59154
},
{
"icon_id": "26283783",
"name": "符号-中文",
"font_class": "fuhao-zhongwen",
"unicode": "e603",
"unicode_decimal": 58883
},
{
"icon_id": "23957582",
"name": "MongoDB",
"font_class": "mongo",
"unicode": "e646",
"unicode_decimal": 58950
},
{
"icon_id": "4969649",
"name": "Redis",
"font_class": "op-redis",
"unicode": "e728",
"unicode_decimal": 59176
},
{
"icon_id": "22442993",
"name": "PostgreSQL",
"font_class": "op-postgres",
"unicode": "e8b7",
"unicode_decimal": 59575
},
{
"icon_id": "12295203",
"name": "达梦数据库",
"font_class": "db-dm",
"unicode": "e6f0",
"unicode_decimal": 59120
},
{
"icon_id": "10055634",
"name": "云数据库MongoDB",
"font_class": "op-mongo",
"unicode": "e7d7",
"unicode_decimal": 59351
},
{
"icon_id": "10055642",
"name": "云数据库 RDS MySQL",
"font_class": "op-mysql",
"unicode": "e7d8",
"unicode_decimal": 59352
},
{
"icon_id": "3876165",
"name": "redis",
"font_class": "redis",
"unicode": "e619",
"unicode_decimal": 58905
},
{
"icon_id": "25271976",
"name": "oracle",
"font_class": "oracle",
"unicode": "e507",
"unicode_decimal": 58631
},
{
"icon_id": "8105644",
"name": "mariadb",
"font_class": "mariadb",
"unicode": "e513",
"unicode_decimal": 58643
},
{
"icon_id": "13601813",
"name": "sqlite",
"font_class": "sqlite",
"unicode": "e546",
"unicode_decimal": 58694
},
{
"icon_id": "29340317",
"name": "temp-mssql",
"font_class": "MSSQLNATIVE",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "7699332",
"name": "gaussdb",
"font_class": "gauss",
"unicode": "e683",
"unicode_decimal": 59011
},
{
"icon_id": "34836637",
"name": "kingbase",
"font_class": "kingbase",
"unicode": "e882",
"unicode_decimal": 59522
},
{
"icon_id": "33047500",
"name": "vastbase",
"font_class": "vastbase",
"unicode": "e62b",
"unicode_decimal": 58923
}
]
}

View File

@@ -1,5 +1,5 @@
import request from './request';
import { useApiFetch } from '@/hooks/useRequest';
import { RequestOptions, useApiFetch } from '@/hooks/useRequest';
/**
* 可用于各模块定义各自api请求
@@ -49,7 +49,7 @@ class Api {
* @param reqOptions 其他可选值
* @returns
*/
useApi<T>(params: any = null, reqOptions: RequestInit = {}) {
useApi<T>(params: any = null, reqOptions?: RequestOptions) {
return useApiFetch<T>(this, params, reqOptions);
}
@@ -59,8 +59,8 @@ class Api {
*/
async request(param: any = null, options: any = {}): Promise<any> {
const { execute, data } = this.useApi(param, options);
await execute();
return data.value;
const res = await execute();
return data.value || res;
}
/**

View File

@@ -1,10 +1,12 @@
import { i18n } from '@/i18n';
import { ElMessage } from 'element-plus';
/**
* 不符合业务断言错误
*/
class AssertError extends Error {
constructor(message: string) {
ElMessage.error(message);
super(message);
// 错误类名
this.name = 'AssertError';
@@ -15,11 +17,11 @@ class AssertError extends Error {
* 断言表达式为true
*
* @param condition 条件表达式
* @param msg 错误消息
* @param msgOrI18nKey 错误消息 或者 i18n key
*/
export function isTrue(condition: boolean, msg: string) {
export function isTrue(condition: boolean, msgOrI18nKey: string) {
if (!condition) {
throw new AssertError(msg);
throw new AssertError(i18n.global.t(msgOrI18nKey));
}
}
@@ -30,7 +32,12 @@ export function isTrue(condition: boolean, msg: string) {
* @param msg 错误消息
*/
export function notBlank(obj: any, msg: string) {
isTrue(obj, msg);
if (obj == null || obj == undefined || obj == '') {
throw new AssertError(msg);
}
if (Array.isArray(obj) && obj.length == 0) {
throw new AssertError(msg);
}
}
/**

View File

@@ -5,29 +5,40 @@ import enLocale from 'element-plus/es/locale/lang/en';
// i18n
export const I18nEnum = {
ZhCn: EnumValue.of('zh-cn', '简体中文').setExtra({ icon: 'iconfont icon-fuhao-zhongwen', el: zhcnLocale }),
En: EnumValue.of('en', 'English').setExtra({ icon: 'iconfont icon-fuhao-yingwen', el: enLocale }),
ZhCn: EnumValue.of('zh-cn', '简体中文').setExtra({ icon: 'icon layout/cn', el: zhcnLocale }),
En: EnumValue.of('en', 'English').setExtra({ icon: 'icon layout/en', el: enLocale }),
};
// 资源类型
export const ResourceTypeEnum = {
Machine: EnumValue.of(1, '机器').setExtra({ icon: 'Monitor', iconColor: 'var(--el-color-primary)' }).tagTypeSuccess(),
Db: EnumValue.of(2, '数据库实例').setExtra({ icon: 'Coin', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'iconfont icon-redis', iconColor: 'var(--el-color-danger)' }).tagTypeInfo(),
Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'iconfont icon-mongo', iconColor: 'var(--el-color-success)' }).tagTypeDanger(),
Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'icon redis/redis', iconColor: 'var(--el-color-danger)' }).tagTypeInfo(),
Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'icon mongo/mongo', iconColor: 'var(--el-color-success)' }).tagTypeDanger(),
AuthCert: EnumValue.of(5, '授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
Es: EnumValue.of(6, 'ES实例').setExtra({ icon: 'icon es/es-color', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
};
// 标签关联的资源类型
export const TagResourceTypeEnum = {
AuthCert: EnumValue.of(-2, '公共凭证').setExtra({ icon: 'Ticket' }),
PublicAuthCert: EnumValue.of(-2, '公共凭证').setExtra({ icon: 'Ticket' }),
Tag: EnumValue.of(-1, '标签').setExtra({ icon: 'CollectionTag' }),
Machine: ResourceTypeEnum.Machine,
Db: ResourceTypeEnum.Db,
DbInstance: ResourceTypeEnum.Db,
EsInstance: ResourceTypeEnum.Es,
Redis: ResourceTypeEnum.Redis,
Mongo: ResourceTypeEnum.Mongo,
AuthCert: ResourceTypeEnum.AuthCert,
MachineAuthCert: EnumValue.of(11, '机器-授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
DbAuthCert: EnumValue.of(21, '数据库-授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
DbName: EnumValue.of(22, '数据库').setExtra({ icon: 'Coin' }),
Db: EnumValue.of(22, '数据库').setExtra({ icon: 'Coin' }),
};
// 标签关联的资源类型路径
export const TagResourceTypePath = {
MachineAuthCert: `${TagResourceTypeEnum.Machine.value}/${TagResourceTypeEnum.AuthCert.value}`,
DbInstanceAuthCert: `${TagResourceTypeEnum.DbInstance.value}/${TagResourceTypeEnum.AuthCert.value}`,
Db: `${TagResourceTypeEnum.DbInstance.value}/${TagResourceTypeEnum.AuthCert.value}/${TagResourceTypeEnum.Db.value}`,
Es: `${TagResourceTypeEnum.EsInstance.value}/${TagResourceTypeEnum.AuthCert.value}`,
};

View File

@@ -1,4 +1,4 @@
function getBaseApiUrl() {
export function getBaseApiUrl() {
let path = window.location.pathname;
if (path == '/') {
return window.location.host;
@@ -15,7 +15,7 @@ const config = {
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
// 系统版本
version: 'v1.9.1',
version: 'v1.10.1',
};
export default config;

View File

@@ -7,7 +7,7 @@ export default {
getPublicKey: () => request.get('/common/public-key'),
getConfigValue: (params: any) => request.get('/sys/configs/value', params),
getServerConf: () => request.get('/sys/configs/server'),
oauth2LoginConfig: () => request.get('/auth/oauth2-config'),
oauth2LoginConfig: () => request.get('/auth/oauth2/config'),
changePwd: (param: any) => request.post('/sys/accounts/change-pwd', param),
captcha: () => request.get('/sys/captcha'),
logout: () => request.post('/auth/accounts/logout'),

View File

@@ -1,11 +0,0 @@
import { i18n } from '@/i18n';
export const AccountUsernamePattern = {
pattern: /^[a-zA-Z0-9_]{5,16}$/g,
message: i18n.global.t('system.account.usernamePatternErrMsg'),
};
export const ResourceCodePattern = {
pattern: /^[a-zA-Z0-9_\-.:]{1,32}$/g,
message: i18n.global.t('system.menu.resourceCodePatternErrMsg'),
};

View File

@@ -0,0 +1,41 @@
import { useI18nPleaseInput, useI18nPleaseSelect } from '@/hooks/useI18n';
import { i18n } from '@/i18n';
/**
* 表单验证规则
* label: 支持 i18n key
*/
export const Rules = {
requiredInput: (label: string = '', trigger: string[] = ['change', 'blur']) => {
return {
required: true,
message: useI18nPleaseInput(label),
trigger: trigger,
};
},
requiredSelect: (label: string = '', trigger: string[] = ['change', 'blur']) => {
return {
required: true,
message: useI18nPleaseSelect(label),
trigger: trigger,
};
},
accountUsername: {
pattern: /^[a-zA-Z0-9_.@:-]{5,16}$/,
message: i18n.global.t('system.account.usernamePatternErrMsg'),
trigger: 'blur',
},
accountPassword: {
pattern: /^(?=.*[A-Za-z])(?=.*\d)(?=.*[`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]])[A-Za-z\d`~!@#$%^&*()_+<>?:"{},.\/\\;'[\]]{8,}$/,
message: i18n.global.t('login.passwordRuleTip'),
trigger: 'blur',
},
resourceCode: {
pattern: /^[a-zA-Z0-9_\-.:]{1,32}$/g,
message: i18n.global.t('system.menu.resourceCodePatternErrMsg'),
trigger: 'blur',
},
};

View File

@@ -0,0 +1,47 @@
import { buildProgressProps } from '@/components/progress-notify/progress-notify';
import syssocket from './syssocket';
import { h, reactive } from 'vue';
import { ElNotification } from 'element-plus';
import ProgressNotify from '@/components/progress-notify/progress-notify.vue';
export function initSysMsgs() {
registerDbSqlExecProgress();
}
const sqlExecNotifyMap: Map<string, any> = new Map();
function registerDbSqlExecProgress() {
syssocket.registerMsgHandler('execSqlFileProgress', function (message: any) {
const content = JSON.parse(message.msg);
const id = content.id;
let progress = sqlExecNotifyMap.get(id);
if (content.terminated) {
if (progress != undefined) {
progress.notification?.close();
sqlExecNotifyMap.delete(id);
progress = undefined;
}
return;
}
if (progress == undefined) {
progress = {
props: reactive(buildProgressProps()),
notification: undefined,
};
}
progress.props.progress.title = content.title;
progress.props.progress.executedStatements = content.executedStatements;
if (!sqlExecNotifyMap.has(id)) {
progress.notification = ElNotification({
duration: 0,
title: message.title,
message: h(ProgressNotify, progress.props),
type: syssocket.getMsgType(message.type),
showClose: false,
});
sqlExecNotifyMap.set(id, progress);
}
});
}

View File

@@ -1,9 +1,9 @@
import Config from './config';
import {ElNotification} from 'element-plus';
import SocketBuilder from './SocketBuilder';
import {getToken} from '@/common/utils/storage';
import { getToken } from '@/common/utils/storage';
import {joinClientParams} from './request';
import { joinClientParams } from './request';
import { ElNotification } from 'element-plus';
class SysSocket {
/**
@@ -23,7 +23,6 @@ class SysSocket {
0: 'error',
1: 'success',
2: 'info',
22: 'info',
};
/**
@@ -57,21 +56,16 @@ class SysSocket {
return;
}
// 默认通知处理
const type = this.getMsgType(message.type);
let msg = message.msg
let duration = 0
if (message.type == 22) {
let obj = JSON.parse(msg);
msg = `文件:${obj['title']} 执行成功: ${obj['executedStatements']}`
duration = 2000
}
let msg = message.msg;
let duration = 0;
ElNotification({
duration: duration,
title: message.title,
message: msg,
type: type,
});
console.log(message)
})
.open((event: any) => console.log(event))
.close(() => {

View File

@@ -42,4 +42,5 @@ export function exportFile(filename: string, content: string) {
link.setAttribute('download', `${filename}`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); // 下载完成后移除元素
}

View File

@@ -30,6 +30,18 @@ export function formatByteSize(size: number, fixed = 2) {
return parseFloat((size / Math.pow(base, exponent)).toFixed(fixed)) + units[exponent];
}
export function formatDocSize(size: number, fixed = 2) {
if (size === 0) {
return '0';
}
const units = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
const base = 1000;
const exponent = Math.floor(Math.log(size) / Math.log(base));
return parseFloat((size / Math.pow(base, exponent)).toFixed(fixed)) + units[exponent];
}
/**
* 容量转为对应的字节大小,如 1KB转为 1024
* @param sizeString 1kb 1gb等
@@ -86,8 +98,8 @@ export function formatTime(time: number, unit: string = 's') {
let result = '';
const timeUnits = Object.entries(units).map(([unit, duration]) => {
const value = Math.floor(seconds / duration);
seconds %= duration;
const value = Math.floor(seconds / (duration as any));
seconds %= duration as any;
return { value, unit };
});

View File

@@ -54,3 +54,67 @@ export function getValueByPath(obj: any, path: string) {
return result;
}
/**
* 根据字段路径设置字段值,若路径不存在,则建对应的路径对象信息
* @param obj 对象
* @param path 字段路径
* @param value 字段值
*/
export function setValueByPath(obj: any, path: string[], value: any) {
for (let i = 0; i < path.length - 1; i++) {
const key = path[i];
if (!obj[key]) {
obj[key] = {};
}
obj = obj[key];
}
obj[path[path.length - 1]] = value;
}
/**
* 使用递归函数进行深度克隆,并支持通过回调函数进行指定字段值的调整
*
* @param obj 要克隆的对象
* @param callback 回调函数,在每个字段被克隆之前调用,可以调整字段的值
* @param hash 用于处理循环引用的 WeakMap
* @returns 深度克隆后的对象
*/
export function deepClone(
obj: any,
callback: (key: string | number, value: any) => any = (key: string | number, value: any) => value,
hash = new WeakMap()
): any {
if (Object(obj) !== obj) return obj; // 基本数据类型直接返回
if (hash.has(obj)) return hash.get(obj); // 处理循环引用
let result: any;
if (obj instanceof Set) {
result = new Set();
hash.set(obj, result);
obj.forEach((val) => result.add(deepClone(val, callback, hash)));
} else if (obj instanceof Map) {
result = new Map();
hash.set(obj, result);
obj.forEach((val, key) => result.set(key, deepClone(val, callback, hash)));
} else if (obj instanceof Date) {
result = new Date(obj.getTime());
} else if (obj instanceof RegExp) {
result = new RegExp(obj);
} else if (typeof obj === 'object') {
result = Array.isArray(obj) ? [] : {};
hash.set(obj, result);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
let value = obj[key];
value = callback(key, value);
result[key] = deepClone(value, callback, hash);
}
}
} else {
result = obj;
}
return result;
}

View File

@@ -203,6 +203,15 @@ export function randomPassword(length = 10) {
return password.join('');
}
export function randomString(length = 8) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += getRandomChar(chars);
}
return result;
}
function getRandomChar(charSet: string) {
const randomIndex = Math.floor(Math.random() * charSet.length);
return charSet[randomIndex];

View File

@@ -1,7 +1,7 @@
import { nextTick } from 'vue';
import * as svg from '@element-plus/icons-vue';
import iconfontJson from '@/assets/iconfont/iconfont.json';
import SvgIcon from '@/components/svgIcon/index.vue';
import { getLocalIcons } from '@/assets/icon/icon.js';
/**
* 导出全局注册 element plus svg 图标
@@ -16,44 +16,6 @@ export function registElSvgIcon(app: any) {
app.component('SvgIcon', SvgIcon);
}
// 获取阿里字体图标
const getAlicdnIconfont = () => {
return new Promise((resolve, reject) => {
nextTick(() => {
const styles: any = document.styleSheets;
let sheetsList = [];
let sheetsIconList = [];
for (let i = 0; i < styles.length; i++) {
console.log(styles[i]);
if (styles[i].href && styles[i].href.indexOf('iconfont') > -1) {
sheetsList.push(styles[i]);
}
}
for (let i = 0; i < sheetsList.length; i++) {
for (let j = 0; j < sheetsList[i].cssRules.length; j++) {
if (sheetsList[i].cssRules[j].selectorText && sheetsList[i].cssRules[j].selectorText.indexOf('.icon-') > -1) {
sheetsIconList.push(
`${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}`
);
}
}
}
if (sheetsIconList.length > 0) resolve(sheetsIconList);
else reject('未获取到值,请刷新重试');
});
});
};
// 获取本地阿里icons
const getLocalAliIconfont = () => {
return new Promise((resolve, reject) => {
nextTick(() => {
const prefix = iconfontJson.css_prefix_text;
resolve(iconfontJson.glyphs.map((x: any) => prefix + x.font_class));
});
});
};
// 初始化获取 css 样式,获取 element plus 自带图标
const elementPlusIconfont = () => {
return new Promise((resolve, reject) => {
@@ -69,48 +31,14 @@ const elementPlusIconfont = () => {
});
};
// 初始化获取 css 样式,这里使用 fontawesome 的图标
const awesomeIconfont = () => {
return new Promise((resolve, reject) => {
nextTick(() => {
const styles: any = document.styleSheets;
let sheetsList = [];
let sheetsIconList = [];
for (let i = 0; i < styles.length; i++) {
if (styles[i].href && styles[i].href.indexOf('netdna.bootstrapcdn.com') > -1) {
sheetsList.push(styles[i]);
}
}
for (let i = 0; i < sheetsList.length; i++) {
for (let j = 0; j < sheetsList[i].cssRules.length; j++) {
if (
sheetsList[i].cssRules[j].selectorText &&
sheetsList[i].cssRules[j].selectorText.indexOf('.fa-') === 0 &&
sheetsList[i].cssRules[j].selectorText.indexOf(',') === -1
) {
sheetsIconList.push(
`${sheetsList[i].cssRules[j].selectorText.substring(1, sheetsList[i].cssRules[j].selectorText.length).replace(/\:\:before/gi, '')}`
);
}
}
}
if (sheetsIconList.length > 0) resolve(sheetsIconList);
else reject('未获取到值,请刷新重试');
});
});
};
// 定义导出方法集合
const initIconfont = {
ali: () => {
return getLocalAliIconfont();
},
ele: () => {
return elementPlusIconfont();
},
// awe: () => {
// return awesomeIconfont();
// },
other: () => {
return getLocalIcons();
},
};
// 导出方法

View File

@@ -6,7 +6,7 @@
<el-form-item>
<template #label>
<el-space :size="4">
<span>{{ `${item?.label}` }}</span>
<span>{{ `${$t(item?.label)}` }}</span>
<el-tooltip v-if="item.tooltip" :content="item?.tooltip" placement="top">
<SvgIcon name="QuestionFilled" />
</el-tooltip>
@@ -21,8 +21,8 @@
</GridItem>
<GridItem suffix>
<div class="operation">
<el-button type="primary" :icon="Search" @click="search" plain> 搜索 </el-button>
<el-button :icon="Delete" @click="reset"> 重置 </el-button>
<el-button type="primary" :icon="Search" @click="search" plain> {{ $t('common.search') }} </el-button>
<el-button :icon="Delete" @click="reset"> {{ $t('common.reset') }} </el-button>
<el-button v-if="showCollapse" type="primary" link class="search-isOpen" @click="collapsed = !collapsed">
{{ collapsed ? '展开' : '合并' }}
<el-icon class="el-icon--right">
@@ -107,7 +107,6 @@ const handleItemKeyupEnter = (item: SearchItem) => {
margin-bottom: 10px;
box-sizing: border-box;
overflow-x: hidden;
background-color: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
border-radius: 6px;

View File

@@ -8,6 +8,7 @@
:style="`top: ${state.dropdown.y + 5}px;left: ${state.dropdown.x}px;`"
:key="Math.random()"
v-show="state.isShow && !allHide"
@contextmenu="headerContextmenuClick"
>
<ul class="el-dropdown-menu">
<template v-for="(v, k) in state.dropdownList">
@@ -125,6 +126,10 @@ const onCurrentContextmenuClick = (ci: ContextmenuItem) => {
emit('currentContextmenuClick', { id: ci.clickId, item: state.item });
};
const headerContextmenuClick = (event: any, data: any) => {
event.preventDefault(); // 阻止默认的右击菜单行为
};
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
const openContextmenu = (item: any) => {
state.item = item;

View File

@@ -37,9 +37,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="7" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 7" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="7" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 7" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 31" :key="item" :value="`${item}`">{{ item }}</el-option>
</el-select>
</div>

View File

@@ -22,9 +22,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="4" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="4" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 60" :key="item" :value="`${item - 1}`">{{ item - 1 }}</el-option>
</el-select>
</div>

View File

@@ -22,9 +22,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="4" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="4" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 60" :key="item" :value="`${item - 1}`">{{ item - 1 }}</el-option>
</el-select>
</div>

View File

@@ -22,9 +22,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="4" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="4" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 12" :key="item" :value="`${item}`">{{ item }}</el-option>
</el-select>
</div>

View File

@@ -22,9 +22,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="4" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="4" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 4" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 60" :key="item" :value="`${item - 1}`">{{ item - 1 }}</el-option>
</el-select>
</div>

View File

@@ -32,9 +32,9 @@
</el-form-item> -->
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="6" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 6" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="6" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 6" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="(item, index) of weekList" :label="item" :key="index" :value="`${index + 1}`">{{ $t(item) }}</el-option>
</el-select>
</div>

View File

@@ -26,9 +26,9 @@
</el-form-item>
<el-form-item>
<div class="flex-align-center w100">
<el-radio v-model="radioValue" :label="5" class="mr5"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 5" class="w100" clearable v-model="checkboxList" multiple>
<div class="flex items-center w-full">
<el-radio v-model="radioValue" :label="5" class="mr-1"> {{ $t('components.crontab.appoint') }} </el-radio>
<el-select @click="radioValue = 5" class="!w-full" clearable v-model="checkboxList" multiple>
<el-option v-for="item in 9" :key="item" :value="`${item - 1 + fullYear}`" :label="item - 1 + fullYear" />
</el-select>
</div>

View File

@@ -1,145 +0,0 @@
<template>
<div>
<el-dialog title="更换头像" v-model="isShowDialog" width="769px">
<div class="cropper-warp">
<div class="cropper-warp-left">
<img :src="cropperImg" class="cropper-warp-left-img" />
</div>
<div class="cropper-warp-right">
<div class="cropper-warp-right-title">预览</div>
<div class="cropper-warp-right-item">
<div class="cropper-warp-right-value">
<img :src="cropperImgBase64" class="cropper-warp-right-value-img" />
</div>
<div class="cropper-warp-right-label">100 x 100</div>
</div>
<div class="cropper-warp-right-item">
<div class="cropper-warp-right-value">
<img :src="cropperImgBase64" class="cropper-warp-right-value-img cropper-size" />
</div>
<div class="cropper-warp-right-label">50 x 50</div>
</div>
</div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="onCancel" size="small"> </el-button>
<el-button type="primary" @click="onSubmit" size="small"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts">
import { reactive, toRefs, nextTick } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
export default {
name: 'cropperIndex',
setup() {
const state = reactive({
isShowDialog: false,
cropperImg: '',
cropperImgBase64: '',
});
// 打开弹窗
const openDialog = (imgs: any) => {
state.cropperImg = imgs;
state.isShowDialog = true;
nextTick(() => {
initCropper();
});
};
// 关闭弹窗
const closeDialog = () => {
state.isShowDialog = false;
};
// 取消
const onCancel = () => {
closeDialog();
};
// 新增
const onSubmit = () => {};
// 初始化cropperjs图片裁剪
const initCropper = () => {
const letImg: any = document.querySelector('.cropper-warp-left-img');
const cropper = new Cropper(letImg, {
viewMode: 1,
dragMode: 'none',
initialAspectRatio: 1,
aspectRatio: 1,
preview: '.before',
background: false,
autoCropArea: 0.6,
zoomOnWheel: false,
crop: () => {
state.cropperImgBase64 = cropper.getCroppedCanvas().toDataURL('image/jpeg');
},
});
};
return {
openDialog,
closeDialog,
onCancel,
onSubmit,
initCropper,
...toRefs(state),
};
},
};
</script>
<style scoped lang="scss">
.cropper-warp {
display: flex;
.cropper-warp-left {
position: relative;
display: inline-block;
height: 350px;
flex: 1;
border: 1px solid #ebeef5;
background: #fff;
overflow: hidden;
background-repeat: no-repeat;
cursor: move;
border-radius: 3px;
.cropper-warp-left-img {
width: 100%;
height: 100%;
}
}
.cropper-warp-right {
width: 150px;
height: 350px;
.cropper-warp-right-title {
text-align: center;
height: 20px;
line-height: 20px;
}
.cropper-warp-right-item {
margin: 15px 0;
.cropper-warp-right-value {
display: flex;
.cropper-warp-right-value-img {
width: 100px;
height: 100px;
border-radius: 100%;
margin: auto;
}
.cropper-size {
width: 50px;
height: 50px;
}
}
.cropper-warp-right-label {
text-align: center;
font-size: 12px;
color: #666666;
height: 30px;
line-height: 30px;
}
}
}
}
</style>

View File

@@ -0,0 +1,7 @@
<template>
<FormDesign ref="makingForm" upload preview generate-code generate-json clearable> </FormDesign>
<!-- <dev></dev> -->
</template>
<script lang="ts" setup>
// import { FormDesign } from 'mayfly-lc';
</script>

View File

@@ -1,10 +1,10 @@
<template>
<div class="dynamic-form-edit w100">
<el-table :data="formItems" stripe class="w100">
<div class="dynamic-form-edit !w-full">
<el-table :data="formItems" stripe class="!w-full">
<el-table-column prop="name" label="model" min-width="100px">
<template #header>
<el-button class="ml0" type="primary" circle size="small" icon="Plus" @click="addItem()"> </el-button>
<span class="ml10">model field</span>
<span class="ml-2">model field</span>
</template>
<template #default="scope">
<el-input v-model="scope.row['model']" :placeholder="$t('components.df.fieldModelPlaceholder')" clearable> </el-input>

View File

@@ -7,7 +7,7 @@
<script lang="ts" setup>
const props = defineProps({
enums: {
type: Object, // 需要为EnumValue类型
type: Object || Array, // 需要为EnumValue类型
required: true,
},
});

View File

@@ -12,8 +12,9 @@ const props = defineProps({
required: true,
},
value: {
type: [Object, String, Number],
type: [Object, String, Number, null],
required: true,
default: () => null,
},
});
@@ -40,7 +41,7 @@ onMounted(() => {
});
const convert = (value: any) => {
const enumValue = EnumValue.getEnumByValue(props.enums, value) as any;
const enumValue = EnumValue.getEnumByValue(props.enums, value);
if (!enumValue) {
state.enumLabel = '-';
state.type = 'danger';
@@ -50,8 +51,8 @@ const convert = (value: any) => {
state.enumLabel = enumValue?.label || '';
if (enumValue.tag) {
state.color = enumValue.tag.color;
state.type = enumValue.tag.type;
state.color = enumValue.tag.color || '';
state.type = enumValue.tag.type || defaultType;
} else {
state.type = defaultType;
}

View File

@@ -0,0 +1,38 @@
<template>
<el-form-item v-bind="$attrs">
<template #label>
{{ props.label }}
<el-tooltip :placement="props.placement">
<template #content>
<span v-html="props.tooltip"></span>
</template>
<SvgIcon name="QuestionFilled" />
</el-tooltip>
</template>
<!-- 遍历父组件传入的 solts 透传给子组件 -->
<template v-for="(_, key) in useSlots()" v-slot:[key]>
<slot :name="key"></slot>
</template>
</el-form-item>
</template>
<script setup lang="ts">
import { useSlots } from 'vue';
const props = defineProps({
label: {
type: String,
require: true,
},
tooltip: {
type: String,
require: true,
},
placement: {
type: String,
default: 'top',
},
});
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="icon-selector w100 h100">
<div class="icon-selector !w-full !h-full">
<el-input
v-model="state.fontIconSearch"
:placeholder="state.fontIconPlaceholder"
@@ -12,7 +12,7 @@
@blur="onIconBlur"
>
<template #prepend>
<SvgIcon :name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="font14" />
<SvgIcon :name="state.fontIconPrefix === '' ? prepend : state.fontIconPrefix" class="!text-[14px]" />
</template>
</el-input>
<el-popover
@@ -25,18 +25,15 @@
virtual-triggering
>
<template #default>
<div class="ml-1 mt-1">{{ $t(title) }}</div>
<div class="icon-selector-warp">
<div class="ml10 mt10">{{ title }}</div>
<el-tabs v-model="state.fontIconTabActive" @tab-click="onIconClick">
<el-tab-pane lazy label="ele" name="ele">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane>
<el-tab-pane lazy label="ali" name="ali">
<el-tab-pane lazy label="other" name="other">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane>
<!-- <el-tab-pane lazy label="awe" name="awe">
<IconList :list="fontIconSheetsFilterList" :empty="emptyDescription" :prefix="state.fontIconPrefix" @get-icon="onColClick" />
</el-tab-pane> -->
</el-tabs>
</div>
</template>
@@ -60,7 +57,7 @@ const props = defineProps({
// 输入框占位文本
placeholder: {
type: String,
default: () => '请输入内容搜索图标或者选择图标',
default: () => 'components.iconSelector.placeholder',
},
// 输入框占位文本
size: {
@@ -70,7 +67,7 @@ const props = defineProps({
// 弹窗标题
title: {
type: String,
default: () => '请选择图标',
default: () => 'components.iconSelector.title',
},
// 禁用
disabled: {
@@ -108,9 +105,8 @@ const state = reactive({
fontIconPlaceholder: '',
fontIconTabActive: 'ele',
fontIconList: {
ali: [],
ele: [],
awe: [],
other: [],
},
});
@@ -128,6 +124,7 @@ const onIconBlur = () => {
if (icon.length <= 0) state.fontIconSearch = '';
}, 300);
};
// 图标搜索及图标数据显示
const fontIconSheetsFilterList = computed(() => {
const list = fontIconTabNameList();
@@ -137,14 +134,15 @@ const fontIconSheetsFilterList = computed(() => {
if (item.toLowerCase().indexOf(search) !== -1) return item;
});
});
// 根据 tab name 类型设置图标
const fontIconTabNameList = () => {
let iconList: any = [];
if (state.fontIconTabActive === 'ali') iconList = state.fontIconList.ali;
else if (state.fontIconTabActive === 'ele') iconList = state.fontIconList.ele;
else if (state.fontIconTabActive === 'awe') iconList = state.fontIconList.awe;
if (state.fontIconTabActive === 'ele') iconList = state.fontIconList.ele;
else if (state.fontIconTabActive === 'other') iconList = state.fontIconList.other;
return iconList;
};
// 处理 icon 双向绑定数值回显
const initModeValueEcho = () => {
if (props.modelValue === '') return ((<string | undefined>state.fontIconPlaceholder) = props.placeholder);
@@ -154,36 +152,24 @@ const initModeValueEcho = () => {
// 处理 icon 类型用于回显时tab 高亮与初始化数据
const initFontIconName = () => {
let name = 'ele';
if (props.modelValue!.indexOf('iconfont') > -1) {
name = 'ali';
} else {
name = 'ele';
if (props.modelValue!.indexOf('icon ') > -1) {
name = 'other';
}
// else if (props.modelValue!.indexOf('ele-') > -1) name = 'ele';
// else if (props.modelValue!.indexOf('fa') > -1) name = 'awe';
// 初始化 tab 高亮回显
state.fontIconTabActive = name;
return name;
};
// 初始化数据
const initFontIconData = async (name: string) => {
if (name === 'ali') {
// 阿里字体图标使用 `iconfont xxx`
if (state.fontIconList.ali.length > 0) return;
const res: any = await initIconfont.ali();
state.fontIconList.ali = res.map((i: string) => `iconfont ${i}`);
} else if (name === 'ele') {
if (name === 'ele') {
// element plus 图标
if (state.fontIconList.ele.length > 0) return;
await initIconfont.ele().then((res: any) => {
state.fontIconList.ele = res;
});
} else if (name === 'awe') {
// fontawesome字体图标使用 `fa xxx`
// if (state.fontIconList.awe.length > 0) return;
// await initIconfont.awe().then((res: any) => {
// state.fontIconList.awe = res.map((i: string) => `fa ${i}`);
// });
} else if (name === 'other') {
// 本地导入svg图标, icon xxx
state.fontIconList.other = initIconfont.other() as any;
}
// 初始化 input 的 placeholder
// 参考单项数据流https://cn.vuejs.org/v2/guide/components-props.html?#%E5%8D%95%E5%90%91%E6%95%B0%E6%8D%AE%E6%B5%81
@@ -213,7 +199,7 @@ const onClearFontIcon = () => {
// 获取 input 的宽度
const getInputWidth = () => {
nextTick(() => {
state.fontIconWidth = inputWidthRef.value.$el.offsetWidth;
state.fontIconWidth = inputWidthRef.value?.$el.offsetWidth;
});
};
// 监听页面宽度改变

View File

@@ -1,15 +1,15 @@
<template>
<div class="monaco-editor" style="border: 1px solid var(--el-border-color-light, #ebeef5); height: 100%">
<div class="monaco-editor-content" ref="monacoTextarea" :style="{ height: height }"></div>
<div class="monaco-editor-custom relative h-full">
<div class="monaco-editor-content" ref="monacoTextareaRef" :style="{ height: height }"></div>
<el-select v-if="canChangeMode" class="code-mode-select" v-model="languageMode" @change="changeLanguage" filterable>
<el-option v-for="mode in languageArr" :key="mode.value" :label="mode.label" :value="mode.value"> </el-option>
<el-option v-for="mode in languageArr" :key="mode.value" :label="mode.label" :value="mode.value" />
</el-select>
</div>
</template>
<script lang="ts" setup>
import { ref, watch, toRefs, reactive, onMounted, onBeforeUnmount } from 'vue';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { watch, toRefs, reactive, onMounted, onBeforeUnmount, useTemplateRef, Ref } from 'vue';
import * as monaco from 'monaco-editor';
// 相关语言
import 'monaco-editor/esm/vs/basic-languages/shell/shell.contribution.js';
import 'monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution.js';
@@ -31,7 +31,6 @@ import 'monaco-editor/esm/vs/editor/contrib/format//browser/formatActions.js';
// 提示
import 'monaco-editor/esm/vs/editor/contrib/suggest/browser/suggestController.js';
import 'monaco-editor/esm/vs/editor/contrib/suggest/browser/suggestInlineCompletions.js';
import { editor, languages } from 'monaco-editor';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js?worker';
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
@@ -45,6 +44,7 @@ import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
// import Dracula from 'monaco-themes/themes/Dracula.json'
import SolarizedLight from 'monaco-themes/themes/Solarized-light.json';
import { language as shellLan } from 'monaco-editor/esm/vs/basic-languages/shell/shell.js';
import { ElOption, ElSelect } from 'element-plus';
import { storeToRefs } from 'pinia';
@@ -53,9 +53,6 @@ import { useThemeConfig } from '@/store/themeConfig';
const { themeConfig } = storeToRefs(useThemeConfig());
const props = defineProps({
modelValue: {
type: String,
},
language: {
type: String,
default: null,
@@ -74,12 +71,11 @@ const props = defineProps({
},
options: {
type: Object,
default: null,
default: () => {},
},
});
//定义事件
const emit = defineEmits(['update:modelValue']);
const modelValue = defineModel<any>('modelValue', { required: true });
const languageArr = [
{
@@ -137,6 +133,7 @@ const defaultOptions = {
theme: 'SolarizedLight',
automaticLayout: true, //自适应宽高布局
foldingStrategy: 'indentation', //代码可分小段折叠
folding: true,
roundedSelection: false, // 禁用选择文本背景的圆角
matchBrackets: 'near',
linkedEditing: true,
@@ -152,9 +149,15 @@ const defaultOptions = {
minimap: {
enabled: false, // 不要小地图
},
};
renderLineHighlight: 'all',
selectOnLineNumbers: false,
readOnly: false,
scrollBeyondLastLine: false,
lineNumbers: 'on',
lineNumbersMinChars: 3,
} as editor.IStandaloneEditorConstructionOptions;
const monacoTextarea: any = ref();
const monacoTextareaRef: Ref<any> = useTemplateRef('monacoTextareaRef');
let monacoEditorIns: editor.IStandaloneCodeEditor = null as any;
let completionItemProvider: any = null;
@@ -177,7 +180,7 @@ const { languageMode } = toRefs(state);
onMounted(() => {
state.languageMode = props.language;
initMonacoEditorIns();
setEditorValue(props.modelValue);
setEditorValue(modelValue.value);
registerCompletionItemProvider();
});
@@ -191,15 +194,15 @@ onBeforeUnmount(() => {
}
});
watch(
() => props.modelValue,
(newValue: any) => {
if (!monacoEditorIns.hasTextFocus()) {
state.languageMode = props.language;
monacoEditorIns?.setValue(newValue);
watch(modelValue, (newValue: any) => {
if (!monacoEditorIns.hasTextFocus()) {
state.languageMode = props.language;
if (newValue == null) {
newValue = '';
}
monacoEditorIns?.setValue(newValue);
}
);
});
watch(
() => props.language,
@@ -224,11 +227,12 @@ const initMonacoEditorIns = () => {
monaco.editor.defineTheme('SolarizedLight', SolarizedLight);
defaultOptions.language = state.languageMode;
defaultOptions.theme = themeConfig.value.editorTheme;
monacoEditorIns = monaco.editor.create(monacoTextarea.value, Object.assign(defaultOptions, props.options as any));
let options = Object.assign(defaultOptions, props.options as any);
monacoEditorIns = monaco.editor.create(monacoTextareaRef.value, options);
// 监听内容改变,双向绑定
monacoEditorIns.onDidChangeModelContent(() => {
emit('update:modelValue', monacoEditorIns.getModel()?.getValue());
modelValue.value = monacoEditorIns.getModel()?.getValue();
});
};
@@ -312,7 +316,7 @@ defineExpose({ getEditor, format, focus });
</script>
<style lang="scss">
.monaco-editor {
.monaco-editor-custom {
.code-mode-select {
position: absolute;
z-index: 2;
@@ -320,5 +324,8 @@ defineExpose({ getEditor, format, focus });
top: 10px;
max-width: 130px;
}
border: 1px solid var(--el-border-color-light, #ebeef5);
width: 100%;
}
</style>

View File

@@ -0,0 +1,85 @@
import { VNode, h, render } from 'vue';
import MonacoEditorDialog from './MonacoEditorDialog.vue';
import * as monaco from 'monaco-editor';
import { ElMessage } from 'element-plus';
export type MonacoEditorDialogProps = {
content: string;
title: string;
language: string;
height?: string;
width?: string;
options?: any; // 可选项,如字体大小等
canChangeLang?: boolean; // 是否可以切换语言
showConfirmButton?: boolean;
confirmFn?: Function; // 点击确认的回调函数入参editor value
closeFn?: Function; // 点击取消 或 关闭弹窗的回调函数
completionItemProvider?: monaco.languages.CompletionItemProvider; // 自定义补全项
};
const MonacoEditorBox = (props: MonacoEditorDialogProps): void => {
const boxId = 'monaco-editor-dialog-id';
let boxInstance: VNode;
const container = document.getElementById(boxId);
if (!container) {
const container = document.createElement('div');
container.id = boxId;
if (props.showConfirmButton === undefined) {
props.showConfirmButton = true;
}
if (props.canChangeLang === undefined) {
props.canChangeLang = true;
}
if (props.content === undefined) {
props.content = '';
}
// 创建 虚拟dom
boxInstance = h(MonacoEditorDialog, {
...props,
modelValue: props.content,
'onUpdate:modelValue': (value: string) => {
props.content = value;
},
// 'onUpdate:visible': (value: boolean) => {},
visible: true,
onClose: () => {
// 卸载组件
if (boxInstance) {
render(null, container);
boxInstance = null as any;
}
// 移除 container DOM 元素
document.body.removeChild(container);
props.closeFn && props.closeFn();
},
onConfirm: () => {
let value = props.content;
if (props.language === 'json') {
let val;
try {
val = JSON.parse(value);
if (typeof val !== 'object') {
ElMessage.error('Invalid json');
return;
}
} catch (e) {
ElMessage.error('Invalid json');
return;
}
// 压缩json字符串
value = JSON.stringify(val);
}
props.confirmFn && props.confirmFn(value);
},
});
// 将虚拟dom渲染到 container dom 上
render(boxInstance, container);
// 最后将 container 追加到 body 上
document.body.appendChild(container);
}
};
export default MonacoEditorBox;

View File

@@ -1,37 +0,0 @@
import { VNode, h, render } from 'vue';
import MonacoEditorDialogComp from './MonacoEditorDialogComp.vue';
export type MonacoEditorDialogProps = {
content: string;
title: string;
language: string;
height?: string;
width?: string;
confirmFn?: Function; // 点击确认的回调函数入参editor value
cancelFn?: Function; // 点击取消 或 关闭弹窗的回调函数
};
const boxId = 'monaco-editor-dialog-id';
let boxInstance: VNode;
const MonacoEditorDialog = (props: MonacoEditorDialogProps): void => {
if (!boxInstance) {
const container = document.createElement('div');
container.id = boxId;
// 创建 虚拟dom
boxInstance = h(MonacoEditorDialogComp);
// 将虚拟dom渲染到 container dom 上
render(boxInstance, container);
// 最后将 container 追加到 body 上
document.body.appendChild(container);
}
const boxVue = boxInstance.component;
if (boxVue) {
// 调用open方法显示弹框注意不能使用boxVue.ctx来调用组件函数build打包后ctx会获取不到
boxVue.exposed?.open(props);
}
};
export default MonacoEditorDialog;

View File

@@ -0,0 +1,133 @@
<template>
<div>
<el-dialog :title="props.title" v-model="dialogVisible" :width="props.width" @close="close">
<monaco-editor
ref="editorRef"
:height="props.height"
class="editor"
:language="props.language"
v-model="modelValue"
:options="props.options"
:can-change-mode="props.canChangeLang"
/>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">{{ i18n.global.t('common.cancel') }}</el-button>
<el-button v-if="props.showConfirmButton" @click="confirm" type="primary">{{ i18n.global.t('common.confirm') }}</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { ElDialog, ElButton, ElMessage } from 'element-plus';
// import base style
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { MonacoEditorDialogProps } from './MonacoEditorBox';
import { i18n } from '@/i18n';
import { registerCompletionItemProvider } from './completionItemProvider';
const editorRef: any = ref(null);
const props = defineProps<MonacoEditorDialogProps>();
const modelValue = defineModel<string>('modelValue', {
type: String,
default: '',
});
const dialogVisible = defineModel<boolean>('visible', {
type: Boolean,
default: false,
});
const emit = defineEmits(['close', 'confirm']);
watch(
() => props.language,
() => {
// 格式化输出html;
const language = props.language;
if (language === 'html' || language == 'xml') {
modelValue.value = formatXML(modelValue.value);
}
if (props.completionItemProvider) {
registerCompletionItemProvider(language, props.completionItemProvider);
}
setTimeout(() => {
editorRef.value?.focus();
editorRef.value?.format();
}, 300);
},
{ immediate: true }
);
/**
* 确认按钮
*/
const confirm = async () => {
let value = modelValue.value;
if (props.language === 'json') {
let val;
try {
val = JSON.parse(value);
if (typeof val !== 'object') {
ElMessage.error('Invalid json');
return;
}
} catch (e) {
ElMessage.error('Invalid json');
return;
}
// 压缩json字符串
value = JSON.stringify(val);
} else if (props.language === 'html') {
// 压缩html字符串
value = compressHTML(value);
}
emit('confirm', value);
close();
};
const close = () => {
dialogVisible.value = false;
emit('close');
setTimeout(() => {
modelValue.value = '';
}, 200);
};
const formatXML = function (xml: string, tab?: string) {
let formatted = '',
indent = '';
tab = tab || ' ';
xml.split(/>\s*</).forEach(function (node) {
if (node.match(/^\/\w/)) indent = indent.substring(tab!.length);
formatted += indent + '<' + node + '>\r\n';
if (node.match(/^<?\w[^>]*[^\/]$/)) indent += tab;
});
return formatted.substring(1, formatted.length - 3);
};
function compressHTML(html: string) {
return (
html
.replace(/[\r\n\t]+/g, ' ') // 移除换行符和制表符
// .replace(/<!--[\s\S]*?-->/g, '') // 移除注释
.replace(/\s{2,}/g, ' ') // 合并多个空格为一个空格
.replace(/>\s+</g, '><')
); // 移除标签之间的空格
}
</script>
<style lang="scss" scoped>
.editor {
font-size: 9pt;
font-weight: 600;
}
</style>

View File

@@ -1,136 +0,0 @@
<template>
<div>
<el-dialog :title="state.title" v-model="state.dialogVisible" :width="state.width" @close="cancel">
<monaco-editor ref="editorRef" :height="state.height" class="editor" :language="state.language" v-model="contentValue" can-change-mode />
<template #footer>
<span class="dialog-footer">
<el-button @click="cancel">取消</el-button>
<el-button @click="confirm" type="primary">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { toRefs, ref, reactive } from 'vue';
import { ElDialog, ElButton, ElMessage } from 'element-plus';
// import base style
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { MonacoEditorDialogProps } from './MonacoEditorDialog';
const editorRef: any = ref(null);
const state = reactive({
dialogVisible: false,
height: '450px',
width: '800px',
contentValue: '',
title: '',
language: '',
});
let confirmFn: any;
let cancelFn: any;
const { contentValue } = toRefs(state);
function compressHTML(html: string) {
return (
html
.replace(/[\r\n\t]+/g, ' ') // 移除换行符和制表符
// .replace(/<!--[\s\S]*?-->/g, '') // 移除注释
.replace(/\s{2,}/g, ' ') // 合并多个空格为一个空格
.replace(/>\s+</g, '><')
); // 移除标签之间的空格
}
/**
* 确认按钮
*/
const confirm = async () => {
if (confirmFn) {
if (state.language === 'json') {
let val;
try {
val = JSON.parse(contentValue.value);
if (typeof val !== 'object') {
ElMessage.error('请输入正确的json');
return;
}
} catch (e) {
ElMessage.error('请输入正确的json');
return;
}
// 压缩json字符串
confirmFn(JSON.stringify(val));
} else if (state.language === 'html') {
// 压缩html字符串
confirmFn(compressHTML(contentValue.value));
} else {
confirmFn(contentValue.value);
}
}
state.dialogVisible = false;
setTimeout(() => {
state.contentValue = '';
state.title = '';
}, 200);
};
const cancel = () => {
state.dialogVisible = false;
// 没有执行成功,并且取消回调函数存在,则执行
cancelFn && cancelFn();
setTimeout(() => {
state.contentValue = '';
state.title = '';
}, 200);
};
const formatXML = function (xml: string, tab?: string) {
let formatted = '',
indent = '';
tab = tab || ' ';
xml.split(/>\s*</).forEach(function (node) {
if (node.match(/^\/\w/)) indent = indent.substring(tab!.length);
formatted += indent + '<' + node + '>\r\n';
if (node.match(/^<?\w[^>]*[^\/]$/)) indent += tab;
});
return formatted.substring(1, formatted.length - 3);
};
const open = (optionProps: MonacoEditorDialogProps) => {
confirmFn = optionProps.confirmFn;
cancelFn = optionProps.cancelFn;
const language = optionProps.language;
state.language = language;
state.title = optionProps.title;
if (optionProps.height) {
state.height = optionProps.height;
}
state.contentValue = optionProps.content;
// 格式化输出html;
if (language === 'html' || language == 'xml') {
state.contentValue = formatXML(optionProps.content);
}
setTimeout(() => {
editorRef.value?.focus();
editorRef.value?.format();
}, 300);
state.dialogVisible = true;
};
defineExpose({ open });
</script>
<style lang="scss" scoped>
.editor {
font-size: 9pt;
font-weight: 600;
}
</style>

View File

@@ -1,9 +1,8 @@
<template>
<div>
<div class="h-full flex flex-col flex-1 overflow-hidden">
<transition name="el-zoom-in-top">
<!-- 查询表单 -->
<SearchForm v-if="isShowSearch" :items="tableSearchItems" v-model="queryForm" :search="search"
:reset="reset" :search-col="searchCol">
<SearchForm v-if="isShowSearch" :items="tableSearchItems" v-model="queryForm" :search="search" :reset="reset" :search-col="searchCol">
<!-- 遍历父组件传入的 solts 透传给子组件 -->
<template v-for="(_, key) in useSlots()" v-slot:[key]>
<slot :name="key"></slot>
@@ -11,83 +10,104 @@
</SearchForm>
</transition>
<div class="card">
<div class="table-main">
<!-- 表格头部 操作按钮 -->
<div class="table-header">
<div class="header-button-lf">
<slot name="tableHeader" />
</div>
<div v-if="toolButton" class="header-button-ri">
<slot name="toolButton">
<div class="tool-button">
<!-- 简易单个搜索项 -->
<div v-if="nowSearchItem" class="simple-search-form">
<el-dropdown v-if="searchItems?.length > 1">
<SvgIcon :size="16" name="CaretBottom" class="mr4 mt6 simple-search-form-btn" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="searchItem in searchItems"
:key="searchItem.prop" @click="changeSimpleFormItem(searchItem)">
{{ $t(searchItem.label) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div class="simple-search-form-label mt5">
<el-text truncated tag="b">{{ `${$t(nowSearchItem?.label)} : ` }}</el-text>
</div>
<el-form-item style="width: 200px" :key="nowSearchItem.prop">
<SearchFormItem @keyup.enter.native="searchFormItemKeyUpEnter"
v-if="!nowSearchItem.slot" :item="nowSearchItem"
v-model="queryForm[nowSearchItem.prop]" />
<slot @keyup.enter.native="searchFormItemKeyUpEnter" v-else
:name="nowSearchItem.slot">
</slot>
</el-form-item>
</div>
<div>
<el-button v-if="showToolButton('search') && searchItems?.length" icon="Search"
circle @click="search" />
<!-- <el-button v-if="showToolButton('refresh')" icon="Refresh" circle @click="execQuery()" /> -->
<el-button v-if="showToolButton('search') && searchItems?.length > 1"
:icon="isShowSearch ? 'ArrowDown' : 'ArrowUp'" circle
@click="isShowSearch = !isShowSearch" />
<el-popover placement="bottom" title="表格配置"
popper-style="max-height: 550px; overflow: auto; max-width: 450px" width="auto"
trigger="click">
<div v-for="(item, index) in tableColumns" :key="index">
<el-checkbox v-model="item.show" :label="item.label" :true-value="true"
:false-value="false" />
</div>
<template #reference>
<el-button icon="Operation" circle :size="props.size"></el-button>
</template>
</el-popover>
</div>
</div>
</slot>
</div>
<el-card class="h-full" body-class="h-full flex flex-col">
<!-- 表格头部 操作按钮 -->
<div class="flex justify-between">
<div>
<slot name="tableHeader" />
</div>
<el-table ref="tableRef" v-bind="$attrs" :max-height="tableMaxHeight"
@selection-change="handleSelectionChange" :data="tableData" highlight-current-row
v-loading="loading" :size="props.size as any" :border="border">
<slot v-if="toolButton" name="toolButton">
<div class="flex">
<!-- 简易单个搜索项 -->
<div v-if="nowSearchItem" class="flex">
<el-dropdown v-if="searchItems?.length > 1">
<SvgIcon :size="16" name="CaretBottom" class="!mr-1 !mt-1.5 simple-search-form-btn" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="searchItem in searchItems" :key="searchItem.prop" @click="changeSimpleFormItem(searchItem)">
{{ $t(searchItem.label) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div class="text-right mr-1.5 mt-1">
<el-text truncated tag="b">{{ `${$t(nowSearchItem?.label)} : ` }}</el-text>
</div>
<el-form-item class="w-[200px]" :key="nowSearchItem.prop">
<SearchFormItem
@keyup.enter.native="searchFormItemKeyUpEnter"
v-if="!nowSearchItem.slot"
:item="nowSearchItem"
v-model="queryForm[nowSearchItem.prop]"
/>
<slot @keyup.enter.native="searchFormItemKeyUpEnter" v-else :name="nowSearchItem.slot"> </slot>
</el-form-item>
</div>
<div class="ml-2">
<el-button v-if="showToolButton('search') && searchItems?.length" icon="Search" circle @click="search" />
<!-- <el-button v-if="showToolButton('refresh')" icon="Refresh" circle @click="execQuery()" /> -->
<el-button
v-if="showToolButton('search') && searchItems?.length > 1"
:icon="isShowSearch ? 'ArrowDown' : 'ArrowUp'"
circle
@click="isShowSearch = !isShowSearch"
/>
<el-popover
placement="bottom"
title="表格配置"
popper-style="max-height: 550px; overflow: auto; max-width: 450px"
width="auto"
trigger="click"
>
<div v-for="(item, index) in tableColumns" :key="index">
<el-checkbox v-model="item.show" :label="$t(item.label)" :true-value="1" :false-value="0" />
</div>
<template #reference>
<el-button icon="Operation" circle :size="props.size"></el-button>
</template>
</el-popover>
</div>
</div>
</slot>
</div>
<div class="flex-1 overflow-auto">
<el-table
v-show="showTable"
ref="tableRef"
v-bind="$attrs"
height="100%"
@selection-change="handleSelectionChange"
:data="tableData"
highlight-current-row
v-loading="loading"
:size="props.size as any"
:border="border"
>
<el-table-column v-if="props.showSelection" :selectable="selectable" type="selection" width="40" />
<template v-for="(item, index) in tableColumns">
<el-table-column :key="index" v-if="item.show" :prop="item.prop" :label="$t(item.label)"
:fixed="item.fixed" :align="item.align" :show-overflow-tooltip="item.showOverflowTooltip"
:min-width="item.minWidth" :sortable="item.sortable || false" :type="item.type"
:width="item.width">
<el-table-column
:key="index"
v-if="item.show"
:prop="item.prop"
:label="$t(item.label)"
:fixed="item.fixed"
:align="item.align"
:show-overflow-tooltip="item.showOverflowTooltip"
:min-width="item.minWidth"
:sortable="item.sortable || false"
:type="item.type"
:width="item.width"
>
<!-- 插槽预留功能 -->
<template #default="scope" v-if="item.slot">
<slot :name="item.slotName ? item.slotName : item.prop" :data="scope.row"></slot>
@@ -95,21 +115,29 @@
<!-- 枚举类型使用tab展示 -->
<template #default="scope" v-else-if="item.type == 'tag'">
<enum-tag :size="props.size" :enums="item.typeParam"
:value="item.getValueByData(scope.row)"></enum-tag>
<enum-tag :size="props.size" :enums="item.typeParam" :value="item.getValueByData(scope.row)"></enum-tag>
</template>
<template #default="scope" v-else>
<!-- 配置了美化文本按钮以及文本内容大于指定长度则显示美化按钮 -->
<el-popover v-if="item.isBeautify && item.getValueByData(scope.row)?.length > 35"
effect="light" trigger="click" placement="top" width="600px">
<el-popover
v-if="item.isBeautify && item.getValueByData(scope.row)?.length > 35"
effect="light"
trigger="click"
placement="top"
width="600px"
>
<template #default>
<el-input :autosize="{ minRows: 3, maxRows: 15 }" disabled v-model="formatVal"
type="textarea" />
<el-input :autosize="{ minRows: 3, maxRows: 15 }" disabled v-model="formatVal" type="textarea" />
</template>
<template #reference>
<el-link @click="formatText(item.getValueByData(scope.row))" :underline="false"
type="success" icon="MagicStick" class="mr5"></el-link>
<el-link
@click="formatText(item.getValueByData(scope.row))"
underline="never"
type="success"
icon="MagicStick"
class="mr-1"
></el-link>
</template>
</el-popover>
@@ -120,38 +148,42 @@
</el-table>
</div>
<el-row v-if="props.pageable" class="mt20" type="flex" justify="end">
<el-pagination :small="props.size == 'small'" @current-change="pageNumChange"
@size-change="pageSizeChange" style="text-align: right" layout="prev, pager, next, total, sizes"
:total="total" v-model:current-page="queryForm.pageNum" v-model:page-size="queryForm.pageSize"
:page-sizes="pageSizes" />
<el-row v-if="props.pageable" class="mt-4" type="flex" justify="end">
<el-pagination
:small="props.size == 'small'"
@current-change="pageNumChange"
@size-change="pageSizeChange"
layout="prev, pager, next, total, sizes"
:total="total"
v-model:current-page="queryForm.pageNum"
v-model:page-size="queryForm.pageSize"
:page-sizes="pageSizes"
/>
</el-row>
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { toRefs, watch, reactive, onMounted, Ref, ref, useSlots, toValue } from 'vue';
import { toRefs, watch, reactive, onMounted, Ref, ref, useSlots, toValue, h } from 'vue';
import { TableColumn } from './index';
import EnumTag from '@/components/enumtag/EnumTag.vue';
import { useThemeConfig } from '@/store/themeConfig';
import { storeToRefs } from 'pinia';
import { useEventListener } from '@vueuse/core';
import Api from '@/common/Api';
import SearchForm from '@/components/SearchForm/index.vue';
import { SearchItem } from '../SearchForm/index';
import SearchFormItem from '../SearchForm/components/SearchFormItem.vue';
import SvgIcon from '@/components/svgIcon/index.vue';
import { usePageTable } from '@/hooks/usePageTable';
import { ElTable } from 'element-plus';
import { ElInput, ElTable } from 'element-plus';
const emit = defineEmits(['update:selectionData', 'pageSizeChange', 'pageNumChange']);
export interface PageTableProps {
size?: string;
pageApi?: Api; // 请求表格数据的 api
columns: TableColumn[]; // 列配置项 ==> 必传
columns: TableColumn[] | any[]; // 列配置项 ==> 必传
showSelection?: boolean;
selectable?: (row: any) => boolean; // 是否可选
pageable?: boolean;
@@ -208,6 +240,10 @@ const showToolButton = (key: 'setting' | 'search') => {
const nowSearchItem: Ref<SearchItem> = ref(null) as any;
// 是否已经计算列宽度
const isCalculatedWidth: Ref<boolean> = ref(false);
const showTable: Ref<boolean> = ref(false);
/**
* 改变当前的搜索项
* @param searchItem 当前点击的搜索项
@@ -239,24 +275,35 @@ const state = reactive({
pageSizes: [] as any, // 可选每页显示的数据量
// 输入框宽度
formatVal: '', // 格式化后的值
tableMaxHeight: '500px',
});
const { pageSizes, formatVal, tableMaxHeight } = toRefs(state);
const { pageSizes, formatVal } = toRefs(state);
watch(tableData, (newValue: any) => {
if (newValue && newValue.length > 0) {
props.columns.forEach((item) => {
if (item.autoWidth && item.show) {
item.autoCalculateMinWidth(tableData.value);
}
});
calculateTableColumnMinWidth();
// 需要计算完才能显示表格,否则会有表格闪烁的问题
if (!showTable.value) {
showTable.value = true;
}
});
watch(isShowSearch, () => {
calcuTableHeight();
});
/**
* 计算表格列宽
*/
const calculateTableColumnMinWidth = () => {
if (isCalculatedWidth.value || !tableData.value || tableData.value.length === 0) {
return;
}
// 计算表格列宽
props.columns.forEach((item) => {
if (item.autoWidth && item.show) {
item.autoCalculateMinWidth(tableData.value);
}
});
isCalculatedWidth.value = true;
};
watch(
() => props.data,
@@ -266,9 +313,6 @@ watch(
);
onMounted(async () => {
calcuTableHeight();
useEventListener(window, 'resize', calcuTableHeight);
if (props.searchItems.length > 0) {
nowSearchItem.value = props.searchItems[0];
}
@@ -292,11 +336,6 @@ onMounted(async () => {
}
});
const calcuTableHeight = () => {
const headerHeight = isShowSearch.value ? 330 : 250;
state.tableMaxHeight = window.innerHeight - headerHeight + 'px';
};
const searchFormItemKeyUpEnter = (event: any) => {
event.preventDefault();
search();
@@ -326,114 +365,4 @@ defineExpose({
total,
});
</script>
<style scoped lang="scss">
.table-box,
.table-main {
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
height: 100%;
// 表格 header 样式
.table-header {
width: 100%;
.header-button-lf {
float: left;
}
.header-button-ri {
float: right;
.tool-button {
display: flex;
justify-content: space-between;
}
.simple-search-form {
margin-right: 10px;
display: flex;
justify-content: space-between;
::v-deep(.el-form-item__content > *) {
width: 100% !important;
}
.simple-search-form-label {
text-align: right;
margin-right: 5px;
}
.simple-search-form-btn:hover {
color: var(--el-color-primary);
}
}
}
.el-button {
margin-bottom: 10px;
}
}
// el-table 表格样式
.el-table {
flex: 1;
// 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
table {
width: 100%;
}
// .el-table__header th {
// height: 45px;
// font-size: 15px;
// font-weight: bold;
// color: var(--el-text-color-primary);
// background: var(--el-fill-color-light);
// }
// .el-table__row {
// height: 45px;
// font-size: 14px;
// .move {
// cursor: move;
// .el-icon {
// cursor: move;
// }
// }
// }
// 设置 el-table 中 header 文字不换行,并省略
.el-table__header .el-table__cell>.cell {
// white-space: nowrap;
white-space: wrap;
}
// 解决表格数据为空时样式不居中问题(仅在element-plus中)
// .el-table__empty-block {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// .table-empty {
// line-height: 30px;
// }
// }
// table 中 image 图片样式
.table-image {
width: 50px;
height: 50px;
border-radius: 50%;
}
}
::v-deep(.el-form-item__label) {
font-weight: bold;
}
}
</style>
<style scoped lang="scss"></style>

View File

@@ -71,9 +71,9 @@ export class TableColumn {
formatFunc: Function;
/**
* 是否显示该列
* 是否显示该列,1显示 0不显示
*/
show: boolean = true;
show: number = 1;
/**
* 是否展示美化按钮主要用于美化json文本等

View File

@@ -1,5 +1,5 @@
<template>
<el-descriptions border size="small" :title="`${progress.title}`">
<el-descriptions border size="small" :title="`${props.progress.title}`">
<el-descriptions-item label="时间">{{ state.elapsedTime }}</el-descriptions-item>
<el-descriptions-item label="已处理">{{ progress.executedStatements }}</el-descriptions-item>
</el-descriptions>

View File

@@ -3,8 +3,8 @@
<component :is="getIconName" :style="setIconSvgStyle" />
</i>
<svg v-else-if="isIconfont()" class="el-icon iconfont-icon icon-middle" aria-hidden="true" :style="setIconSvgStyle">
<use :xlink:href="'#' + getIconfontName()"></use>
<svg v-else-if="isLocalIcon()" class="el-icon local-icon icon-middle" aria-hidden="true" :style="setIconSvgStyle">
<use :xlink:href="'#' + getLocalIconName()"></use>
</svg>
<div v-else-if="isShowIconImg" :style="setIconImgOutStyle">
@@ -39,10 +39,13 @@ const props = defineProps({
});
// 在线链接、本地引入地址前缀
const linesString = ['https', 'http', '/src', '/assets', 'data:image', import.meta.env.VITE_PUBLIC_PATH];
const linesString = ['https', 'http', '/src', '/assets', 'icon ', 'data:image', import.meta.env.VITE_PUBLIC_PATH];
// 获取 icon 图标名称
const getIconName = computed(() => {
// if (props.name?.startsWith('icon ')) {
// return getIcon(props?.name?.split(' ')[1] as any);
// }
return props?.name as any;
});
@@ -55,12 +58,12 @@ const isShowIconSvg = computed(() => {
return ss.length == 1;
});
const isIconfont = () => {
return props?.name?.startsWith('iconfont');
const isLocalIcon = () => {
return props?.name?.startsWith('icon ');
};
const getIconfontName = () => {
// iconfont icon-xxxx 获取icon-xxx即可
const getLocalIconName = () => {
// icon icon-xxxx 获取icon-xxx即可
return props?.name?.split(' ')[1];
};
@@ -76,20 +79,24 @@ const setIconSvgStyle = computed(() => {
// 设置图片样式
const setIconImgOutStyle = computed(() => {
return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;`;
return `width: ${props.size}px;height: ${props.size}px;display: inline-block;overflow: hidden;line-height:${props.size}px;vertical-align: middle;`;
});
// 设置图片样式
const setIconSvgInsStyle = computed(() => {
const filterStyle: string[] = [];
const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];
compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} 30px 0);`));
return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;
if (props.color) {
const filterStyle: string[] = [];
const compatibles: string[] = ['-webkit', '-ms', '-o', '-moz'];
compatibles.forEach((j) => filterStyle.push(`${j}-filter: drop-shadow(${props.color} ${props.size}px 0);`));
return `width: ${props.size}px;height: ${props.size}px;position: relative;left: -${props.size}px;${filterStyle.join('')}`;
}
return `width: ${props.size}px;height: ${props.size}px;position: relative;`;
});
</script>
<style type="text/css">
.iconfont-icon {
<style type="text/css" scoped>
.local-icon {
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
@@ -101,5 +108,7 @@ const setIconSvgInsStyle = computed(() => {
align-items: center;
cursor: pointer;
vertical-align: middle;
height: 100%; /* 确保高度与父元素一致 */
line-height: 1; /* 确保行高与高度一致 */
}
</style>

View File

@@ -3,12 +3,12 @@
<div ref="viewportRef" class="viewport" :style="{ width: state.size.width + 'px', height: state.size.height + 'px' }">
<div ref="displayRef" class="display" tabindex="0" />
<div class="btn-box">
<SvgIcon name="DocumentCopy" @click="openPaste" :size="20" class="pointer-icon mr10" title="剪贴板" />
<SvgIcon name="FolderOpened" @click="openFilesystem" :size="20" class="pointer-icon mr10" title="文件管理" />
<SvgIcon name="FullScreen" @click="state.fullscreen ? closeFullScreen() : openFullScreen()" :size="20" class="pointer-icon mr10" title="全屏" />
<SvgIcon name="DocumentCopy" @click="openPaste" :size="20" class="pointer-icon mr-2" title="剪贴板" />
<SvgIcon name="FolderOpened" @click="openFilesystem" :size="20" class="pointer-icon mr-2" title="文件管理" />
<SvgIcon name="FullScreen" @click="state.fullscreen ? closeFullScreen() : openFullScreen()" :size="20" class="pointer-icon mr-2" title="全屏" />
<el-dropdown>
<SvgIcon name="Monitor" :size="20" class="pointer-icon mr10" title="发送快捷键" style="color: #fff" />
<SvgIcon name="Monitor" :size="20" class="pointer-icon mr-2" title="发送快捷键" style="color: #fff" />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openSendKeyboard(['65507', '65513', '65535'])"> Ctrl + Alt + Delete </el-dropdown-item>
@@ -21,7 +21,7 @@
</template>
</el-dropdown>
<SvgIcon name="Refresh" @click="connect(0, 0)" :size="20" class="pointer-icon mr10" title="重新连接" />
<SvgIcon name="Refresh" @click="connect(0, 0)" :size="20" class="pointer-icon mr-2" title="重新连接" />
</div>
<clipboard-dialog ref="clipboardRef" v-model:visible="state.clipboardDialog.visible" @close="closePaste" @submit="onsubmitClipboard" />
@@ -73,8 +73,7 @@ import { TerminalExpose } from '@/components/terminal-rdp/index';
import SvgIcon from '@/components/svgIcon/index.vue';
import MachineFile from '@/views/ops/machine/file/MachineFile.vue';
import { exitFullscreen, launchIntoFullscreen, unWatchFullscreenChange, watchFullscreenChange } from '@/components/terminal-rdp/guac/screen';
import { useEventListener } from '@vueuse/core';
import { debounce } from 'lodash';
import { useDebounceFn, useEventListener } from '@vueuse/core';
import { ClientState, TunnelState } from '@/components/terminal-rdp/guac/states';
import { ElMessage } from 'element-plus';
import { joinClientParams } from '@/common/request';
@@ -191,7 +190,7 @@ const installClipboard = () => {
const installResize = () => {
// 在resize事件结束后300毫秒执行
useEventListener('resize', debounce(resize, 300));
useEventListener('resize', useDebounceFn(resize, 300));
};
const installDisplay = () => {

View File

@@ -24,7 +24,7 @@
<div class="title-right-fixed">
<el-popconfirm @confirm="connect(true)" title="确认重新连接?">
<template #reference>
<div class="mr10 pointer">
<div class="mr-2 cursor-pointer">
<el-tag v-if="state.status == TerminalStatus.Connected" type="success" effect="light" round> 已连接 </el-tag>
<el-tag v-else type="danger" effect="light" round> 未连接点击重连 </el-tag>
</div>

View File

@@ -1,25 +1,24 @@
<template>
<div id="terminal-body" :style="{ height }">
<div ref="terminalRef" class="terminal" />
<div class="h-full w-full flex">
<div ref="terminalRef" class="h-full w-full" :style="{ background: getTerminalTheme().background }" />
<TerminalSearch ref="terminalSearchRef" :search-addon="state.addon.search" @close="focus" />
</div>
</template>
<script lang="ts" setup>
import 'xterm/css/xterm.css';
import { Terminal, ITheme } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { SearchAddon } from 'xterm-addon-search';
import { WebLinksAddon } from 'xterm-addon-web-links';
import '@xterm/xterm/css/xterm.css';
import { Terminal, ITheme } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { SearchAddon } from '@xterm/addon-search';
import { WebLinksAddon } from '@xterm/addon-web-links';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/store/themeConfig';
import { ref, nextTick, reactive, onMounted, onBeforeUnmount, watch } from 'vue';
import TerminalSearch from './TerminalSearch.vue';
import { debounce } from 'lodash';
import { TerminalStatus } from './common';
import { useEventListener } from '@vueuse/core';
import { useDebounceFn, useEventListener, useIntervalFn } from '@vueuse/core';
import themes from './themes';
import { TrzszFilter } from 'trzsz';
import { useI18n } from 'vue-i18n';
@@ -42,13 +41,6 @@ const props = defineProps({
socketUrl: {
type: String,
},
/**
* 高度
*/
height: {
type: [String, Number],
default: '100%',
},
});
const emit = defineEmits(['statusChange']);
@@ -61,7 +53,6 @@ const { themeConfig } = storeToRefs(useThemeConfig());
// 终端实例
let term: Terminal;
let socket: WebSocket;
let pingInterval: any;
const state = reactive({
// 插件
@@ -90,7 +81,9 @@ watch(
watch(
() => themeConfig.value.terminalTheme,
() => {
term.options.theme = getTerminalTheme();
if (term) {
term.options.theme = getTerminalTheme();
}
}
);
@@ -98,7 +91,7 @@ onBeforeUnmount(() => {
close();
});
function init() {
const init = () => {
state.status = TerminalStatus.NoConnected;
if (term) {
console.log('重新连接...');
@@ -107,9 +100,9 @@ function init() {
nextTick(() => {
initTerm();
});
}
};
async function initTerm() {
const initTerm = async () => {
term = new Terminal({
fontSize: themeConfig.value.terminalFontSize || 15,
fontWeight: themeConfig.value.terminalFontWeight || 'normal',
@@ -129,7 +122,7 @@ async function initTerm() {
term.loadAddon(fitAddon);
fitTerminal();
// 注册窗口大小监听器
useEventListener('resize', debounce(fitTerminal, 400));
useEventListener('resize', useDebounceFn(fitTerminal, 400));
initSocket();
// 注册其他插件
@@ -145,9 +138,9 @@ async function initTerm() {
return true;
});
}
};
function initSocket() {
const initSocket = () => {
if (!props.socketUrl) {
return;
}
@@ -155,7 +148,8 @@ function initSocket() {
// 监听socket连接
socket.onopen = () => {
// 注册心跳
pingInterval = setInterval(sendPing, 15000);
useIntervalFn(sendPing, 15000);
state.status = TerminalStatus.Connected;
focus();
@@ -163,7 +157,7 @@ function initSocket() {
// 如果有初始要执行的命令,则发送执行命令
if (props.cmd) {
sendCmd(props.cmd + ' \r');
sendData(props.cmd + ' \r');
}
};
@@ -178,9 +172,9 @@ function initSocket() {
console.log('terminal socket close...', e.reason);
state.status = TerminalStatus.Disconnected;
};
}
};
function loadAddon() {
const loadAddon = () => {
// 注册搜索组件
const searchAddon = new SearchAddon();
state.addon.search = searchAddon;
@@ -197,7 +191,7 @@ function loadAddon() {
// write the server output to the terminal
writeToTerminal: (data: any) => term.write(typeof data === 'string' ? data : new Uint8Array(data)),
// send the user input to the server
sendToServer: sendCmd,
sendToServer: sendData,
// the terminal columns
terminalColumns: term.cols,
// there is a windows shell
@@ -223,7 +217,7 @@ function loadAddon() {
.then(() => console.log('upload success'))
.catch((err: any) => console.log(err));
});
}
};
// 写入内容至终端
const write2Term = (data: any) => {
@@ -238,7 +232,7 @@ const getTerminalTheme = () => {
const terminalTheme = themeConfig.value.terminalTheme;
// 如果不是自定义主题,则返回内置主题
if (terminalTheme != 'custom') {
return themes[terminalTheme];
return (themes as any)[terminalTheme];
}
// 自定义主题
@@ -271,30 +265,28 @@ enum MsgType {
Ping = 3,
}
const send = (msg: any) => {
state.status == TerminalStatus.Connected && socket?.send(msg);
const send2Socket = (data: any) => {
state.status == TerminalStatus.Connected && socket?.send(data);
};
const sendResize = (cols: number, rows: number) => {
send(`${MsgType.Resize}|${rows}|${cols}`);
send2Socket(`${MsgType.Resize}|${rows}|${cols}`);
};
const sendPing = () => {
send(`${MsgType.Ping}|ping`);
send2Socket(`${MsgType.Ping}|ping`);
};
function sendCmd(key: any) {
send(`${MsgType.Data}|${key}`);
}
const sendData = (key: any) => {
send2Socket(`${MsgType.Data}|${key}`);
};
function closeSocket() {
const closeSocket = () => {
// 关闭 websocket
socket && socket.readyState === 1 && socket.close();
// 清除 ping
pingInterval && clearInterval(pingInterval);
}
};
function close() {
const close = () => {
console.log('in terminal body close');
closeSocket();
if (term) {
@@ -303,7 +295,7 @@ function close() {
state.addon.weblinks.dispose();
term.dispose();
}
}
};
const getStatus = (): TerminalStatus => {
return state.status;
@@ -311,17 +303,4 @@ const getStatus = (): TerminalStatus => {
defineExpose({ init, fitTerminal, focus, clear, close, getStatus, sendResize, write2Term, writeln2Term });
</script>
<style lang="scss">
#terminal-body {
width: 100%;
.terminal {
width: 100%;
height: 100%;
// .xterm .xterm-viewport {
// overflow-y: hidden;
// }
}
}
</style>
<style lang="scss"></style>

View File

@@ -28,7 +28,7 @@
<div class="title-right-fixed">
<el-popconfirm @confirm="reConnect(openTerminal.terminalId)" :title="$t('components.terminal.connConfirm')">
<template #reference>
<div class="mr15 pointer">
<div class="mr-4 cursor-pointer">
<el-tag v-if="openTerminal.status == TerminalStatus.Connected" type="success" effect="light" round>
{{ $t('components.terminal.connected') }}
</el-tag>
@@ -39,10 +39,10 @@
<el-popover placement="bottom" :width="200" trigger="hover">
<template #reference>
<SvgIcon name="QuestionFilled" :size="20" class="pointer-icon mr10" />
<SvgIcon name="QuestionFilled" :size="20" class="pointer-icon !mr-2" />
</template>
<div>ctrl | command + f ({{ $t('components.terminal.search') }})</div>
<div class="mt5">{{ $t('components.terminal.reConnTips') }}</div>
<div class="mt-1">{{ $t('components.terminal.reConnTips') }}</div>
</el-popover>
<SvgIcon
@@ -50,7 +50,7 @@
v-if="props.visibleMinimize"
@click="minimize(openTerminal.terminalId)"
:size="20"
class="pointer-icon mr10"
class="pointer-icon mr-2"
:title="$t('components.terminal.minimize')"
/>
@@ -58,7 +58,7 @@
name="FullScreen"
@click="handlerFullScreen(openTerminal)"
:size="20"
class="pointer-icon mr10"
class="pointer-icon mr-2"
:title="$t('components.terminal.fullScreenTitle')"
/>
@@ -88,7 +88,7 @@
<el-card
v-for="minimizeTerminal of minimizeTerminals"
:key="minimizeTerminal.terminalId"
:class="`terminal-minimize-item pointer ${minimizeTerminal.styleClass}`"
:class="`terminal-minimize-item cursor-pointer ${minimizeTerminal.styleClass}`"
size="small"
@click="maximize(minimizeTerminal.terminalId)"
>
@@ -99,7 +99,7 @@
</el-tooltip>
<!-- 关闭按钮 -->
<SvgIcon name="CloseBold" @click.stop="closeMinimizeTerminal(minimizeTerminal.terminalId)" class="ml10 pointer-icon fr" :size="20" />
<SvgIcon name="CloseBold" @click.stop="closeMinimizeTerminal(minimizeTerminal.terminalId)" class="ml-2 pointer-icon float-right" :size="20" />
</el-card>
</div>
</div>

View File

@@ -1,19 +1,19 @@
<template>
<div>
<el-drawer v-model="visible" :before-close="cancel" size="50%">
<el-drawer v-model="visible" :before-close="cancel" size="50%" body-class="flex flex-col">
<template #header>
<DrawerHeader :header="props.title" :back="cancel">
<template #extra>
<EnumTag :enums="LogTypeEnum" :value="log?.type" class="mr20" />
<EnumTag :enums="LogTypeEnum" :value="log?.type" class="mr-4.5" />
</template>
</DrawerHeader>
</template>
<el-descriptions class="mb10" :column="1" border v-if="extra">
<el-descriptions class="mb-2" :column="1" border v-if="extra">
<el-descriptions-item v-for="(value, key) in extra" :key="key" :span="1" :label="key">{{ value }}</el-descriptions-item>
</el-descriptions>
<TerminalBody class="mb10" ref="terminalRef" height="calc(100vh - 220px)" />
<TerminalBody class="mb-2 flex-1" ref="terminalRef" />
</el-drawer>
</div>
</template>

View File

@@ -31,10 +31,10 @@
<!-- 按钮 -->
<div class="search-buttons">
<el-button class="terminal-search-button search-button-prev" type="primary" size="small" @click="searchKeywords(false)">
{{ $t('components.terminal.previous') }}}}
{{ $t('components.terminal.previous') }}
</el-button>
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="searchKeywords(true)">
{{ $t('components.terminal.next') }}}}
{{ $t('components.terminal.next') }}
</el-button>
<el-button class="terminal-search-button search-button-next" type="primary" size="small" @click="closeSearch">
{{ $t('components.terminal.close') }}
@@ -46,7 +46,7 @@
<script lang="ts" setup>
import { ref, toRefs, nextTick, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { SearchAddon, ISearchOptions } from 'xterm-addon-search';
import { SearchAddon, ISearchOptions } from '@xterm/addon-search';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();

View File

@@ -27,7 +27,7 @@ export function useI18nPleaseSelect(labelI18nKey: string) {
* @returns
*/
export async function useI18nDeleteConfirm(name: string = '') {
return useI18nConfirm('common.deleteConfirm', { name });
return useI18nConfirm('common.deleteConfirm2', { name });
}
/**
@@ -79,16 +79,29 @@ export function useI18nDetailTitle(i18nKey: string) {
}
export function useI18nOperateSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.operateSuccess'));
MsgSuccess('common.operateSuccess');
}
export function useI18nSaveSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.saveSuccess'));
MsgSuccess('common.saveSuccess');
}
export function useI18nDeleteSuccessMsg() {
const t = i18n.global.t;
ElMessage.success(t('common.deleteSuccess'));
MsgSuccess('common.deleteSuccess');
}
/**
* error msg
* @param msg msg(支持i8n msgkey)
*/
export function MsgError(msg: string) {
ElMessage.error(i18n.global.t(msg));
}
/**
* success msg
* @param msg msg(支持i8n msgkey)
*/
export function MsgSuccess(msg: string) {
ElMessage.success(i18n.global.t(msg));
}

View File

@@ -22,7 +22,7 @@ export const usePageTable = (
) => {
const state = reactive({
// 表格数据
tableData: [],
tableData: [{}],
// 总数量
total: 0,
// 查询参数,包含分页参数

View File

@@ -2,11 +2,11 @@ import router from '@/router';
import { clearUser, getClientId, getRefreshToken, getToken, saveRefreshToken, saveToken } from '@/common/utils/storage';
import { templateResolve } from '@/common/utils/string';
import { ElMessage } from 'element-plus';
import { createFetch } from '@vueuse/core';
import { createFetch, UseFetchReturn } from '@vueuse/core';
import Api from '@/common/Api';
import { Result, ResultEnum } from '@/common/request';
import config from '@/common/config';
import { unref } from 'vue';
import { ref, unref } from 'vue';
import { URL_401 } from '@/router/staticRouter';
import openApi from '@/common/openApi';
import { useThemeConfig } from '@/store/themeConfig';
@@ -38,14 +38,19 @@ const useCustomFetch = createFetch({
return { options };
},
async afterFetch(ctx) {
const result: Result = await ctx.response.json();
ctx.data = result;
ctx.data = await ctx.response.json();
return ctx;
},
},
});
export function useApiFetch<T>(api: Api, params: any = null, reqOptions: RequestInit = {}) {
interface EsReq {
esProxyReq: boolean;
}
export interface RequestOptions extends RequestInit, EsReq {}
export function useApiFetch<T>(api: Api, params: any = null, reqOptions?: RequestOptions) {
const uaf = useCustomFetch<T>(api.url, {
async beforeFetch({ url, options }) {
options.method = api.method;
@@ -90,14 +95,24 @@ export function useApiFetch<T>(api: Api, params: any = null, reqOptions: Request
},
};
},
});
onFetchError: (ctx) => {
if (reqOptions?.esProxyReq) {
uaf.data = { value: JSON.parse(ctx.data) };
return Promise.resolve(uaf.data);
}
return ctx;
},
}) as any;
// 统一处理后的返回结果如果直接使用uaf.data则数据会出现由{code: x, data: {}} -> data 的变化导致某些结果绑定报错
const data = ref<T | null>(null);
return {
execute: async function () {
return execCustomFetch(uaf);
await execCustomFetch(uaf, reqOptions);
data.value = uaf.data.value;
},
isFetching: uaf.isFetching,
data: uaf.data,
data: data,
abort: uaf.abort,
};
}
@@ -105,37 +120,44 @@ export function useApiFetch<T>(api: Api, params: any = null, reqOptions: Request
let refreshingToken = false;
let queue: any[] = [];
async function execCustomFetch(uaf: any) {
async function execCustomFetch(uaf: UseFetchReturn<any>, reqOptions?: RequestOptions) {
try {
await uaf.execute(true);
} catch (e: any) {
const rejectPromise = Promise.reject(e);
if (!reqOptions?.esProxyReq) {
const rejectPromise = Promise.reject(e);
if (e?.name == 'AbortError') {
console.log('请求已取消');
if (e?.name == 'AbortError') {
console.log('请求已取消');
return rejectPromise;
}
const respStatus = uaf.response.value?.status;
if (respStatus == 404) {
ElMessage.error('url not found');
return rejectPromise;
}
if (respStatus == 500) {
ElMessage.error('server error');
return rejectPromise;
}
console.error(e);
ElMessage.error('network error');
return rejectPromise;
}
const respStatus = uaf.response.value?.status;
if (respStatus == 404) {
ElMessage.error('请求接口不存在');
return rejectPromise;
}
if (respStatus == 500) {
ElMessage.error('服务器响应异常');
return rejectPromise;
}
console.error(e);
ElMessage.error('网络请求错误');
return rejectPromise;
}
const result: Result = uaf.data.value as any;
const result: Result & { error: any; status: number } = uaf.data.value as any;
if (!result) {
ElMessage.error('网络请求失败');
ElMessage.error('network request failed');
return Promise.reject(result);
}
// es代理请求
if (reqOptions?.esProxyReq) {
uaf.data.value = result;
return Promise.resolve(result);
}
const resultCode = result.code;
@@ -151,7 +173,7 @@ async function execCustomFetch(uaf: any) {
// 请求加入队列等待, 防止并发多次请求refreshToken
return new Promise((resolve) => {
queue.push(() => {
resolve(execCustomFetch(uaf));
resolve(execCustomFetch(uaf, reqOptions));
});
});
}
@@ -175,13 +197,13 @@ async function execCustomFetch(uaf: any) {
queue = [];
}
await execCustomFetch(uaf);
await execCustomFetch(uaf, reqOptions);
return;
}
// 如果提示没有权限,则跳转至无权限页面
if (resultCode === ResultEnum.NO_PERMISSION) {
router.push({
await router.push({
path: URL_401,
});
return Promise.reject(result);

View File

@@ -7,22 +7,29 @@ export default {
detail: 'Details',
add: 'Add',
save: 'Save',
close: 'Close',
download: 'Download',
upload: 'Upload',
remove: 'Remove',
confirm: 'Confirm',
cancel: 'Cancel',
submit: 'Submit',
operation: 'Operations',
name: 'Name',
version: 'Version',
code: 'Code',
remark: 'Remark',
status: 'Status',
username: 'Username',
mobile: 'Mobile',
email: 'Email',
role: 'Role',
msg: 'Message',
type: 'Type',
time: 'Time',
account: 'Account',
password: 'Password',
captcha: 'Captcha',
createTime: 'Create Time',
creator: 'Creator',
updateTime: 'Update Time',
@@ -45,17 +52,23 @@ export default {
previousStep: 'Previous Step',
nextStep: 'Next Step',
copy: 'Copy',
copyCell: 'Copy Cell',
search: 'Search',
pleaseInput: 'Please enter {label}',
pleaseSelect: 'Please select {label}',
formValidationError: 'Please fill in the form information correctly',
pleaseSelectOne: 'Please select Only One Data',
formValidationError: 'Please check the form',
createTitle: 'Create {name}',
editTitle: 'Edit {name}',
detailTitle: '{name} Details',
deleteConfirm: 'This operation will delete [{name}]. Do you want to continue?',
deleteConfirm: 'Sure to delete?',
deleteConfirm2: 'This operation will delete [{name}]. Do you want to continue?',
saveSuccess: 'save successfully',
deleteSuccess: 'delete successfully',
operateSuccess: 'operate successfully',
fieldNotEmpty: '{field} cannot be empty',
selectAll: 'Select all',
MultiPlaceholder: 'Multiple are separated by commas',
},
layout: {
user: {
@@ -278,6 +291,17 @@ export default {
flowProcDefSave: 'Save Process Define',
flowProcDefDelete: 'Delete Process Define',
msgManage: 'Message',
channel: 'Message Channel',
msgChannelBase: 'Base Permission',
saveMsgChannel: 'Save Message Channel',
delMsgChannel: 'Delete Message Channel',
msgTmpl: 'Message Template',
msgTmplBase: 'Base Permission',
saveMsgTmpl: 'Save Message Template',
delMsgTmpl: 'Delete Message Template',
sendMsg: 'Send Message',
system: 'System',
menuPermission: 'Menu & Permission',
menuPermissionBase: 'Base Permission',
@@ -336,25 +360,19 @@ export default {
accountPasswordLogin: 'Account Password Login',
thirdPartyLogin: 'Third Party login',
ldapLogin: 'LDAP Login',
inputUsernamePlaceholder: 'Please enter your username',
inputPasswordPlaceholder: 'Please enter your password',
inputCaptchaPlaceholder: 'Please enter the verification code',
login: 'Login',
loginFailTip: 'Tip: If you fail to log in more than {loginFailCount} times, you will not be allowed to log in again for {loginFailMin} minutes',
loginSuccessTip: 'welcome back!',
changePassword: 'Change Password',
oldPassword: 'Old Password',
newPassword: 'New Password',
inputNewPasswordPlaceholder: 'Please enter a new password',
passwordRuleTip: 'Must be at least 8 characters long and contain upper/lower case + number + special symbol',
passwordChangeSuccessTip: 'The password has been changed successfully, and the new password has been filled in the login password box',
otpValidation: 'OTP validation',
qrCode: 'QR code',
enterOtpCodeTip: 'Enter the authorization code shown in the Token APP',
inputOtpCodePlaceholder: 'Please enter the OTP authorization code',
updateBasicInfo: 'Modifying basic information',
name: 'Name',
inputNamePlaceholder: 'Please enter your name',
},
components: {
df: {
@@ -442,5 +460,9 @@ export default {
last5runTimes: 'Last 5 running times',
calculationing: 'In the calculation result',
},
iconSelector: {
title: 'please select the icon',
placeholder: 'please enter content search icon or select icon',
},
},
};

View File

@@ -73,6 +73,21 @@ export default {
newTabRunSql: 'NewTab Run SQL',
formatSql: 'Format SQL',
alias: 'Alias',
tableName: 'Name',
addColumn: 'Add Column',
addDefaultColumn: 'Add Default Column',
addIndex: 'Add Index',
length: 'Length',
numScale: 'Scale',
defaultValue: 'Default Value',
notNull: 'Not Null',
primaryKey: 'Pri',
autoIncrement: 'Auto Incr',
unique: 'Unique',
uniqueIndex: 'Unique Index',
normalIndex: 'Normal Index',
execTime: 'execution time',
oneClickCopy: 'One click copy',
asc: 'Asc',
@@ -199,9 +214,16 @@ export default {
getDbNamesModeAssign: 'Specifying the db name',
ignore: 'Ignore',
replate: 'Replate',
replace: 'Replate',
running: 'Running',
waitRun: 'Wait Run',
},
es: {
keywordPlaceholder: 'host / name / code',
port: 'Port',
acName: 'Credential',
dbInst: 'Es Instance',
connSuccess: 'be connected successfully',
},
};

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