Compare commits

441 Commits

Author SHA1 Message Date
Coder慌
4836a770c4 !139 feat(es):增加ES实例中对HTTP/HTTPS协议的支持,默认使用HTTP协议,使用https时默认证书免校验
Merge pull request !139 from davidathena/dev
2025-10-28 11:25:47 +00:00
fudawei
e6c89fad1b feat(es):增加ES实例中对HTTPS协议的支持,默认证书免校验 2025-10-23 15:29:27 +08:00
meilin.huang
dba19b1e66 fix: editor提示被遮挡问题修复等 2025-10-18 11:21:33 +08:00
davidathena
4e30bdb7cc !138 fix: 后端数据连接断开后报空指针异常后程序中断问题
* fix(connection):fix the bug for nil error in connection when connection reset
* fix(sqleditor): fix the spell error in sql editor
2025-10-18 03:15:25 +00:00
meilin.huang
4ac57cd140 refactor: 标签不可移动,资源选择优化等 2025-10-07 15:41:19 +08:00
meilin.huang
c4d52ce47a feat: 资源操作新增右键菜单操作等 2025-09-17 21:23:12 +08:00
meilin.huang
54d0688571 fix: 名称调整等 2025-09-14 20:53:47 +08:00
meilin.huang
66d5fd6ca4 feat: 容器操作优化等 2025-09-06 21:32:48 +08:00
时光似水戏流年
25195b6360 !137 现在执行sql只执行当前光标所在的sql(分号分割的),如果要执行全部sql需要先全选,再执行
* 现在执行sql只执行当前sql(分号分割的),如果要执行全部sql需要先全选,再执行
2025-09-02 11:12:04 +00:00
meilin.huang
e02ecf053f feat: 资源操作统一管理&容器操作 2025-08-31 21:46:10 +08:00
meilin.huang
c86f2ad412 refactor: 样式优化 2025-08-19 19:44:14 +08:00
meilin.huang
82fd97e06a fix: file文件缺失 2025-08-08 12:55:10 +08:00
meilin.huang
614a144f60 refactor: 样式优化 2025-08-04 21:02:27 +08:00
meilin.huang
7d344c71e1 refactor: 消息模块调整 & 样式优化 2025-08-02 22:08:56 +08:00
meilin.huang
6ad6c69660 refactor: 消息模块重构,infra包路径简写等 2025-07-27 21:02:48 +08:00
meilin.huang
e96379b6c0 fix: vite配置调整 2025-07-07 12:05:55 +08:00
meilin.huang
f7480f3bac refactor: cast包替换 2025-06-27 12:17:45 +08:00
meilin.huang
54d3a5b368 fix: sql执行记录根据关键词搜索问题修复等 2025-06-22 10:52:06 +08:00
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
meilin.huang
9366a76b84 release: v1.9.1 2024-11-21 19:02:15 +08:00
meilin.huang
e03ceecd9a fix: redis set command causes ttl loss 2024-11-21 13:20:45 +08:00
meilin.huang
99a746085b feat: i18n 2024-11-20 22:43:53 +08:00
meilin.huang
74ae031853 refactor: dbm重构、调整metadata与dialect接口 2024-11-01 17:27:22 +08:00
meilin.huang
af14be9801 refactor: 前端文件夹名称调整 2024-10-31 17:24:56 +08:00
meilin.huang
df7413a9ea fix: base.app事务方法调整 2024-10-30 19:59:45 +08:00
meilin.huang
e967e02095 fix: 数据库实例删除,事务问题 2024-10-30 12:17:55 +08:00
meilin.huang
c1d09f447d fix: pgsql查询列信息解析问题修复等 2024-10-28 12:13:41 +08:00
meilin.huang
5e5afd49dc fix: sql缺少字段补充、dockefile调整等 2024-10-24 11:56:22 +08:00
meilin.huang
2118acf244 release: v1.9.0 2024-10-23 17:30:05 +08:00
meilin.huang
44a1bd626e feat: 数据库迁移至文件支持文件保存天数等 2024-10-22 20:39:44 +08:00
meilin.huang
ea3c70a8a8 feat: 新增统一文件模块,统一文件操作 2024-10-21 22:27:42 +08:00
zongyangleo
6343173cf8 !124 一些更新和bug
* fix: 代码合并
* feat:支持数据库版本兼容,目前兼容了oracle11g部分特性
* fix: 修改数据同步bug,数据sql里指定修改字段别,导致未正确记录修改字段值
* feat: 数据库迁移支持定时迁移和迁移到sql文件
2024-10-20 03:52:23 +00:00
meilin.huang
6837a9c867 fix: sql切割转义等问题处理 2024-10-18 17:15:58 +08:00
meilin.huang
a726927a28 feat: sql脚本执行调整 2024-10-18 12:32:53 +08:00
meilin.huang
e135e4ce64 feat: sql解析器替换、工单统一由‘我的流程’发起、流程定义支持自定义条件触发审批、资源隐藏编号、model支持物理删除等 2024-10-16 17:24:50 +08:00
zongyangleo
43edef412c !123 一些bug修复
* fix: 数据同步、数据迁移体验优化
* fix: des加密传输sql
* fix: 修复达梦字段注释显示问题
* fix: mysql timestamp 字段类型导出ddl错误修复
2024-08-22 00:43:39 +00:00
meilin.huang
2deb3109c2 feat: dbms表数据新增表单视图 2024-07-19 17:06:11 +08:00
meilin.huang
a80221a950 fix: 数据库实例删除等问题修复 2024-07-05 13:14:31 +08:00
meilin.huang
10630847df fix: 工单流程信息展示问题修复 2024-06-24 17:17:57 +08:00
meilin.huang
f43851698e fix: 资源关联多标签删除、数据库实例删除等问题修复与数据库等名称过滤优化 2024-06-07 12:31:40 +08:00
Coder慌
73884bb693 !122 fix: mysql导出修复
Merge pull request !122 from zongyangleo/dev_1.8.6_fix
2024-06-05 04:17:03 +00:00
zongyangleo
1b5bb1de8b fix: mysql导出修复 2024-06-01 13:35:31 +08:00
meilin.huang
4814793546 fix: 修复数据库表数据横向滚动后切换tab导致表头错位&数据取消居中显示 2024-05-31 12:12:40 +08:00
meilin.huang
d85bbff270 release v1.8.6 2024-05-23 17:18:22 +08:00
meilin.huang
bb1522f4dc refactor: 数据库管理迁移至数据库实例-库管理、机器管理-文件支持用户和组信息查看 2024-05-21 12:34:26 +08:00
zongyangleo
a7632fbf58 !121 fix: rdp ssh
* fix: rdp ssh
2024-05-21 04:06:13 +00:00
meilin.huang
c4cb4234fd fix: 问题修复 2024-05-16 17:26:32 +08:00
meilin.huang
89e12678eb refactor: 引入dayjs、新增refreshToken无感刷新、团队新增有效期、数据库等问题修复 2024-05-13 19:55:43 +08:00
meilin.huang
137ebb8e9e fix: 数据库表新增数据表单全必填问题修复等 2024-05-11 12:09:55 +08:00
meilin.huang
05625bd8c1 feat: 1.8.3 2024-05-10 19:59:49 +08:00
meilin.huang
4afeac5fdd refactor: 代码优化与数据库表列显示配置优化 2024-05-09 21:29:34 +08:00
meilin.huang
1d0e91f1af refactor: 机器计划任务与流程定义关联至标签 2024-05-08 21:04:25 +08:00
Coder慌
cf5111a325 !118 修复空数组分隔异常
Merge pull request !118 from 蒋小小/N/A
2024-05-07 11:59:12 +00:00
meilin.huang
78957a8ebd refactor: base.repo与app重构优化 2024-05-05 14:53:30 +08:00
meilin.huang
4ed892a656 feat: 文档更新与sqlite文件更新 2024-04-29 17:09:41 +08:00
meilin.huang
3486b07003 fix: 修复机器列表查询与放开vnc 2024-04-29 12:50:49 +08:00
meilin.huang
a5cd7caf19 refactor: base.repo与base.app精简优化 2024-04-29 12:29:56 +08:00
meilin.huang
f2c7ef78c0 refactor: 精简base.repo与base.app等 2024-04-28 23:45:57 +08:00
meilin.huang
653953ee76 feat: 机器新增命令过滤配置、首页功能完善(操作记录与快捷操作) 2024-04-27 01:35:21 +08:00
meilin.huang
a831614d5a fix: sql脚本问题修复等 2024-04-23 11:35:45 +08:00
meilin.huang
ebe73e2f19 feat: 标签支持拖拽移动与机器支持执行命令查看 2024-04-21 19:35:58 +08:00
蒋小小
29fd5a25d2 修复空数组分隔异常
Signed-off-by: 蒋小小 <bwcx_jzy@163.com>
2024-04-20 17:33:19 +00:00
zongyangleo
44805ce580 !116 fix: 新版本问题修复
* fix: 新版本问题修复
2024-04-19 11:27:29 +00:00
meilin.huang
2a6d620830 fix: 问题修复 2024-04-18 20:50:14 +08:00
meilin.huang
01d3e1ad28 refactor: 数据库实例与凭证关联至标签&其他问题修复重构等 2024-04-17 21:28:28 +08:00
meilin.huang
f4162c38db fix: 问题修复与redis密码迁移至凭证 2024-04-13 17:01:12 +08:00
zongyangleo
1a4626c24d !115 fix: 新版本问题修复
* fix: 新版本问题修复
2024-04-12 14:39:08 +00:00
meilin.huang
d6eb9683d1 fix: 新版本问题修复 2024-04-12 20:30:28 +08:00
meilin.huang
e2b524dadb feat: release1.8.0 2024-04-12 17:07:28 +08:00
zongyangleo
8998a21626 !114 feat:rdp优化,mssql迁移优化,term支持trzsz
* fix: 合并代码
* refactor: rdp优化,mssql迁移优化,term支持trzsz
2024-04-12 07:53:42 +00:00
meilin.huang
abc015aec0 refactor: 数据库授权凭证迁移 2024-04-12 13:24:20 +08:00
meilin.huang
4ef8d27b1e refactor: 授权凭证优化 2024-04-10 23:17:20 +08:00
meilin.huang
40b6e603fc reafctor: 团队管理与授权凭证优化 2024-04-10 13:04:31 +08:00
meilin.huang
21498584b1 refactor: 初步提交全局授权凭证-资源多账号改造 2024-04-09 12:55:51 +08:00
meilin.huang
408bac09a1 refactor: 标签资源重构 2024-04-06 18:19:17 +08:00
zongyangleo
582d879a77 !112 feat: 机器管理支持ssh+rdp连接win服务器
* feat: rdp 文件管理
* feat: 机器管理支持ssh+rdp连接win服务器
2024-04-06 04:03:38 +00:00
meilin.huang
38ff5152e0 refactor: dbms优化 2024-03-29 21:40:26 +08:00
meilin.huang
d1d372e1bf feat: 数据迁移新增实时日志&数据库游标遍历查询问题修复 2024-03-28 22:20:39 +08:00
Coder慌
5e4793433b !111 refactor:获取表索引,默认过滤主键索引
Merge pull request !111 from zongyangleo/dev_0327_fix
2024-03-27 13:06:45 +00:00
zongyangleo
54ad19f97e refactor:获取表索引,默认过滤主键索引 2024-03-27 08:26:12 +08:00
meilin.huang
fc166650b3 refactor: dbm重构等 2024-03-26 21:46:03 +08:00
zongyangleo
2acc295259 !110 feat: 支持各源数据库导出sql,数据库迁移部分bug修复
* feat: 各源数据库导出
* fix: 数据库迁移 bug修复
2024-03-26 09:05:28 +00:00
meilin.huang
4b3ed1310d refactor: dbms 2024-03-21 20:28:24 +08:00
meilin.huang
b2cfd1517c refactor: dbms与标签管理优化 2024-03-21 17:15:52 +08:00
zongyangleo
b13d27ccd6 !109 refactor:ddl生成方式重构,数据类型和长度重构,所有数据库迁移调试
* feat:同步sqlite全量sql
* refactor:ddl生成方式重构,数据类型和长度重构,所有数据库迁移调试
2024-03-21 03:35:18 +00:00
meilin.huang
68e0088016 refactor: dbms优化 2024-03-18 12:25:40 +08:00
zongyangleo
bd1e83989d !108 feat:支持不同源数据库迁移
* feat:支持不同源数据库迁移
2024-03-15 09:01:51 +00:00
meilin.huang
263dfa6be7 refactor: dbm包重构 2024-03-15 13:31:53 +08:00
meilin.huang
eb55f93864 refactor: dbm包重构 2024-03-11 20:04:20 +08:00
meilin.huang
8589105e44 feat: oracle支持服务名、数据库执行超时时间配置等 2024-03-07 17:26:11 +08:00
meilin.huang
986b187f0a feat: v1.7.4 2024-03-04 20:33:04 +08:00
zongyangleo
008d34c453 !107 feat:支持修改表名、注释,oracle bug修复
* fix:修复oracle查询数据参数超过1000错误 ORA-01795
* feat:支持右键重命名表
* feat:支持修改表名、表注释
2024-03-04 11:32:04 +00:00
meilin.huang
49d3f988c9 feat: redis支持工单流程审批 2024-03-02 19:08:19 +08:00
zongyangleo
76475e807e !106 feat:数据同步支持唯一键冲突策略
* refactor:sql同步
* fix: 表格右键导出菜单换行符修复
* feat:数据同步支持唯一键冲突策略
2024-03-01 04:03:03 +00:00
meilin.huang
f93231da61 feat: dbms新增支持工单流程审批 2024-02-29 22:12:50 +08:00
meilin.huang
bf75483a3c refactor: 简化api层相关调用 2024-02-25 12:46:18 +08:00
meilin.huang
b56b0187cf refactor: api层尽可能屏蔽gin框架相关代码 2024-02-24 16:30:29 +08:00
meilin.huang
7e7f02b502 refactor: 机器终端操作优化 2024-02-23 22:53:17 +08:00
meilin.huang
878985f7c5 refactor: 依赖版本升级等 2024-02-22 21:03:13 +08:00
meilin.huang
2133d9b737 fix: 终端操作col和row初始化问题修复 2024-02-18 18:42:25 +08:00
meilin.huang
d711a36749 feat: v1.7.3 2024-02-08 09:53:48 +08:00
meilin.huang
9dbf104ef1 refactor: 机器操作界面调整 2024-02-07 21:14:29 +08:00
zongyangleo
20eb06fb28 !101 feat: 新增机器操作菜单
* feat: 新增机器操作菜单
2024-02-07 06:37:59 +00:00
meilin.huang
9c20bdef39 Merge branch 'dev' of https://gitee.com/objs/mayfly-go into dev 2024-02-06 15:33:31 +08:00
zongyangleo
3fdd98a390 !99 feat: DBMS新增kingbaseES、vastbase,还有一些优化
* refactor: 重构机器列表展示
* fix:修复编辑表问题
* refactor: 优化下拉实例显示
* feat: DBMS新增kingbaseES(已测试postgres、oracle兼容模式) 、vastbase
2024-02-06 07:32:03 +00:00
meilin.huang
d4f456c0cf Merge branch 'dev' of https://gitee.com/objs/mayfly-go into dev 2024-02-06 15:17:39 +08:00
kanzihuang
f2b6e15cf4 !100 定时清理数据库备份数据
* feat: 优化数据库 BINLOG 同步机制
* feat: 删除数据库实例前需删除关联的数据库备份与恢复任务
* refactor: 重构数据库备份与恢复模块
* feat: 定时清理数据库备份历史和本地 Binlog 文件
* feat: 压缩数据库备份文件
2024-02-06 07:16:56 +00:00
meilin.huang
6be0ea6aed fix: dbms数据行编辑 2024-02-01 12:05:41 +08:00
meilin.huang
eee08be2cc feat: 数据库支持编辑行数据 2024-01-31 20:41:41 +08:00
meilin.huang
252fc553f2 feat: v1.7.2 2024-01-31 12:53:27 +08:00
meilin.huang
ac2ceed3f9 refactor: code review 2024-01-30 21:56:49 +08:00
kanzihuang
3f828cc5b0 !96 删除数据库备份和恢复历史
* feat: 删除数据库备份历史
* refactor dbScheduler
* feat: 从数据库备份历史中恢复数据库
* feat: 删除数据库恢复历史记录
* refactor dbScheuler
2024-01-30 13:12:43 +00:00
zongyangleo
fc1b9ef35d !97 一些优化
* refactor: 重构表格分页组件,适配大数据量分页
* fix:定时任务修复
* feat: gaussdb单独提出来
2024-01-30 13:09:26 +00:00
meilin.huang
d0b71a1c40 refactor: dialect使用方式调整 2024-01-29 16:02:28 +08:00
meilin.huang
a743a6a05a Merge branch 'master' into dev 2024-01-29 12:21:22 +08:00
zongyangleo
0e6b9713ce !93 feat: DBMS支持mssql和一些功能优化
* feat: 表格+表格元数据缓存
* feat:跳板机支持多段跳
* fix: 所有数据库区分字段主键和自增
* feat: DBMS支持mssql
* refactor: 去除无用的getter方法
2024-01-29 04:20:23 +00:00
meilin.huang
b9afbc764d refactor: 去除无用的getter方法 2024-01-29 11:34:48 +08:00
meilin.huang
923e183a67 refactor: code review 2024-01-26 17:17:26 +08:00
meilin.huang
7e9a381641 refactor: 数据库meta使用注册方式,方便可插拔 2024-01-24 17:01:17 +08:00
zongyangleo
bed95254d0 !91 fix: oracle数据同步 bug
* fix: oracle数据同步 bug
2024-01-24 08:29:16 +00:00
meilin.huang
e4d13f3377 refactor: 引入日志切割库、indexApi拆分等 2024-01-23 19:30:28 +08:00
Coder慌
d530365ef9 !90 fix: 依赖注入支持私有变量
Merge pull request !90 from kanzihuang/feat-db-bak
2024-01-23 09:02:37 +00:00
wanli
070d4ea104 fix: 依赖注入支持私有变量 2024-01-23 16:29:41 +08:00
zongyangleo
3fc86f0fae !88 feat: dbms表支持右键菜单:删除表、编辑表、新建表、复制表
* feat: 支持复制表
* feat: dbms表支持右键菜单:删除表、编辑表、新建表
2024-01-23 04:08:02 +00:00
kanzihuang
3b77ab2727 !89 feat: 给数据库备份和恢复配置操作权限
* feat: 给数据库备份和恢复配置操作权限
* refactor: 数据库备份与恢复采用最新依赖注入机制
2024-01-23 04:06:08 +00:00
meilin.huang
76cb991282 fix: 数据同步更新时间展示等问题 2024-01-23 09:27:05 +08:00
meilin.huang
9efd20f1b9 refactor: ioc与系统初始化处理方式调整 2024-01-22 11:35:28 +08:00
kanzihuang
de5b9e46d3 !87 fix: 修复数据库备份与恢复问题
* feat: 修复数据库备份与恢复问题
* feat: 启用 BINLOG 支持全量备份和增量备份,未启用 BINLOG 仅支持全量备份
* feat: 数据库恢复后自动备份,避免数据丢失
2024-01-22 03:12:16 +00:00
meilin.huang
f27d3d200f feat: 新增简易版ioc 2024-01-21 22:52:20 +08:00
meilin.huang
f4a64b96a9 feat: v1.7.1新增支持sqlite&oracle分页限制等问题修复 2024-01-19 21:33:37 +08:00
zongyangleo
9a59749763 !86 dbms支持sqlite和一些bug修复
* fix: 达梦数据库连接修复,以支持带特殊字符的密码和schema
* fix: oracle bug修复
* feat: dbms支持sqlite
* fix: dbms 修改字段名bug
2024-01-19 08:59:35 +00:00
kanzihuang
b017b902f8 !85 fix: 修复 BINLOG同步任务加载问题
* Merge branch 'dev' of gitee.com:dromara/mayfly-go into feat-db-bak
* fix: 修复 BINLOG 同步任务加载问题
2024-01-19 00:40:44 +00:00
meilin.huang
7c53353c60 fix: sqlite数据问题时间类型问题修复等 2024-01-18 17:18:17 +08:00
meilin.huang
63f0615445 feat: v1.7.0 2024-01-17 17:02:15 +08:00
kanzihuang
94da6df33e !84 fix: 修复数据库备份与恢复问题
* refactor dbScheduler
* fix: 按团队名称检索团队
* feat: 创建数据库资源时支持全选数据库
* refactor dbScheduler
* fix: 修复数据库备份与恢复问题
2024-01-17 08:37:22 +00:00
meilin.huang
cc3981d99c fix: 数据库编辑导致标签关联删除修复、cron组件调整 2024-01-17 12:13:18 +08:00
meilin.huang
8332d9b354 feat: 新增cron组件、cron支持6位秒级别 2024-01-16 20:04:04 +08:00
meilin.huang
493925064c feat: 机器定时删除终端操作记录 2024-01-15 20:51:41 +08:00
kanzihuang
c0232c4c75 fix: 修复数据库备份与恢复问题 (#85)
* fix: 修复数据库备份与恢复问题

* fix: 修复数据库备份与恢复问题
2024-01-15 20:11:28 +08:00
zongyangleo
b873855b44 !82 feat: dbms支持oracle数据库
* fix:oracle bug修复
* feat: dbms支持oracle数据库
2024-01-15 11:55:59 +00:00
meilin.huang
9c524292f0 refactor: 数组比较方法优化等 2024-01-13 13:38:53 +08:00
meilin.huang
bfd346e65a fix: 机器文件下载问题修复&dbm重构 2024-01-12 13:15:30 +08:00
meilin.huang
bc811cbd49 refactor: 数据同步编辑页优化等 2024-01-11 12:35:44 +08:00
kanzihuang
bbec3eca0d feat: 实现数据库备份和恢复并发调度 (#84) 2024-01-11 11:35:51 +08:00
meilin.huang
3857d674ba refactor: 数据同步编辑页调整、echarts组件重构 2024-01-10 23:41:55 +08:00
meilin.huang
25b0ae4d2f fix: model.FillBaseInfo遗漏调整完善等 2024-01-09 21:37:56 +08:00
meilin.huang
b7aa281611 refactor: code review 2024-01-09 17:31:21 +08:00
meilin.huang
3c89a285f5 feat: 数据库表格数据表头支持展示备注 2024-01-09 12:19:20 +08:00
Coder慌
d3d26c85c3 !81 fix: 数据同步相关bug修复
Merge pull request !81 from zongyangleo/dev_0109
2024-01-09 04:12:53 +00:00
刘宗洋
a764c4f974 fix: 数据同步相关bug修复 2024-01-09 10:35:13 +08:00
meilin.huang
af454f7d5d refactor: 数据同步优化, base.App、base.Repo新增Save方法 2024-01-07 21:46:25 +08:00
meilin.huang
eea759e10e refactor: code review 2024-01-06 22:36:50 +08:00
meilin.huang
e158422091 refactor: code review、数据库备份恢复支持ssh隧道操作 2024-01-05 22:16:38 +08:00
meilin.huang
5ada63d4a1 Merge branch 'dev' of https://gitee.com/objs/mayfly-go into dev 2024-01-05 20:51:50 +08:00
Coder慌
5ef35001cc !80 fix: 字段映射大小写等问题
Merge pull request !80 from zongyangleo/dev_0105_table_sync_fix
2024-01-05 12:51:32 +00:00
kanzihuang
0be50f0995 feat: 新增数据库类型 mariadb, 分别为 mysql 和 mariadb 设置不同的数据库备份与恢复程序路径 (#81) 2024-01-05 17:23:29 +08:00
刘宗洋
61e1b0ca70 fix: 字段映射大小写等问题 2024-01-05 14:43:51 +08:00
zongyangleo
85910bf440 !79 feat: 支持自定义数据定时同步
* fix: 达梦数据权限问题
* feat: 支持自定义数据定时同步
2024-01-05 05:31:32 +00:00
meilin.huang
7a7a7020b4 feat: 新增系统样式配置,支持改logo图标与标题 2024-01-05 12:09:12 +08:00
kanzihuang
ae3d2659aa 重构数据库备份与恢复模块 (#80)
* fix: 保存 LastResult 时截断字符串过长部分,以避免数据库报错

* refactor: 新增 entity.DbTaskBase 和 persistence.dbTaskBase, 用于实现数据库备份和恢复任务处理相关部分

* fix: aeskey变更后,解密密码出现数组越界访问错误

* fix: 时间属性为零值时,保存到 mysql 数据库报错

* refactor db.infrastructure.service.scheduler

* feat: 实现立即备份功能

* refactor db.infrastructure.service.db_instance

* refactor: 从数据库中获取数据库备份目录、mysql文件路径等配置信息

* fix: 数据库备份和恢复问题

* fix: 修改 .gitignore 文件,忽略数据库备份目录和数据库程序目录
2024-01-05 08:55:34 +08:00
meilin.huang
76fd6675b5 refactor: code review 2023-12-29 16:48:15 +08:00
may-fly
664118a709 Merge pull request #78 from kanzihuang/feat-db-bak
feat: 实现数据库备份与恢复
2023-12-29 08:57:57 +08:00
kanzihuang
e344722794 feat: 实现数据库备份与恢复 2023-12-29 08:30:10 +08:00
meilin.huang
1a7d425f60 refactor: 动态路由重构 2023-12-28 17:21:33 +08:00
meilin.huang
a0582192bf refactor: code review 2023-12-27 19:55:36 +08:00
meilin.huang
4ac9f02d6a refactor: code review 2023-12-26 22:31:51 +08:00
meilin.huang
7e0febef8f refactor: 页面小优化 2023-12-25 17:43:42 +08:00
meilin.huang
94ed4b77d6 refactor: 单元格编辑优化 2023-12-22 17:04:06 +08:00
meilin.huang
2b419bca11 refactor: 数据库表支持editor编辑调整 2023-12-22 12:29:46 +08:00
meilin.huang
54a0f0b3c7 refactor: 数据库虚拟table卡顿优化 2023-12-22 00:47:01 +08:00
Coder慌
86bccc3b3d !78 feat: 表格支持编辑json、xml数据
Merge pull request !78 from zongyangleo/dev_1221
2023-12-21 10:55:30 +00:00
刘宗洋
0e601b5033 feat: 表格支持编辑json、xml数据 2023-12-21 15:03:11 +08:00
meilin.huang
85d745fcee feat: 数据库表单元格编辑封装 2023-12-21 13:07:02 +08:00
meilin.huang
550631c03b refactor: 达梦ssh连接调整 2023-12-20 23:01:51 +08:00
Coder慌
f29a1560aa !77 fix: 达梦支持ssh
Merge pull request !77 from zongyangleo/dev_1220
2023-12-20 13:25:45 +00:00
刘宗洋
8c4c41cf0b fix: 达梦支持ssh 2023-12-20 20:37:29 +08:00
meilin.huang
f5c90277b1 feat: 新增数据库版本查看 2023-12-20 17:29:16 +08:00
meilin.huang
2ae0cd7ab4 refactor: 数据库表操作界面优化 2023-12-19 19:23:33 +08:00
meilin.huang
1f6c14ee2f refactor: 系统模块角色分配相关优化 2023-12-18 22:39:32 +08:00
meilin.huang
574d27f6da refactor: PageTable优化 2023-12-17 14:38:53 +08:00
meilin.huang
7d62841783 refactor: rsa存储方式调整等 2023-12-17 01:43:38 +08:00
Coder慌
970d74bd70 !75 refactor: 表格日期组件大小调整
Merge pull request !75 from zongyangleo/dev_1216
2023-12-16 16:46:00 +00:00
刘宗洋
0c797f8da9 refactor: 表格日期组件大小调整 2023-12-16 23:10:38 +08:00
meilin.huang
68f8603c75 refactor: PageTable优化 2023-12-16 17:41:15 +08:00
meilin.huang
06bce33c48 refactor: 样式调整 2023-12-15 17:33:22 +08:00
Coder慌
f8837f28c3 !74 fix: 数据库查询结果日期格式化
Merge pull request !74 from zongyangleo/dev_1215_fix
2023-12-15 07:27:47 +00:00
刘宗洋
61aed08dde fix: 数据库查询结果日期格式化 2023-12-15 15:21:54 +08:00
meilin.huang
a5a813f95f refactor: sql执行列返回字段类型 2023-12-14 21:27:11 +08:00
meilin.huang
18cf2e54c4 refactor: 样式调整 2023-12-14 13:05:21 +08:00
Coder慌
5c72b1de57 !73 fix: 达梦ddl相关
Merge pull request !73 from zongyangleo/dev_1214
2023-12-14 01:30:10 +00:00
刘宗洋
6e44e90d67 fix: 达梦数据库ddl 2023-12-14 08:24:14 +08:00
Coder慌
0e699ba20e !71 fix: 达梦数据库操作bug
Merge pull request !71 from zongyangleo/dev_1213_1
2023-12-13 11:39:42 +00:00
刘宗洋
cf24c2671f fix: 达梦数据库操作bug 2023-12-13 18:39:44 +08:00
meilin.huang
d3b99ec88d Merge branch 'dev' of https://gitee.com/objs/mayfly-go into dev 2023-12-13 17:36:50 +08:00
meilin.huang
0b5ab090a4 refactor: 报错代码调整 2023-12-13 17:32:17 +08:00
Coder慌
454698286c !70 fix: 达梦数据库大小写敏感问题
Merge pull request !70 from zongyangleo/dev_1213
2023-12-13 09:31:14 +00:00
刘宗洋
14e0aadbba fix: 达梦数据库操作bug 2023-12-13 17:26:53 +08:00
meilin.huang
73986a834c fix: 删除机器、数据库时关联的标签未删除 2023-12-13 14:01:13 +08:00
meilin.huang
8faf1831d9 refactor: PageTable组件重构 2023-12-12 23:31:53 +08:00
Coder慌
d86ef0a9ab !69 fix: 库名提示,兼容mysql\pgsql\dm
Merge pull request !69 from zongyangleo/dev_1212
2023-12-12 14:30:51 +00:00
刘宗洋
c2bb0c589e fix: 库名提示,兼容mysql\pgsql\dm 2023-12-12 22:06:49 +08:00
Coder慌
9994f20a2c !66 refactor: sql代码提示重构
Merge pull request !66 from zongyangleo/dev_1212
2023-12-12 09:04:48 +00:00
刘宗洋
b5014c307f refactor: sql代码提示重构 2023-12-12 16:42:45 +08:00
meilin.huang
75bd4ca3df refactor: 前端样式调整 2023-12-11 17:08:52 +08:00
meilin.huang
d00bd2ed72 fix: PageTable调整后一些页面问题修复 2023-12-11 11:00:20 +08:00
meilin.huang
e444500835 refactor: PageTable组件重构、使用useFetch封装接口请求 2023-12-11 01:00:09 +08:00
meilin.huang
6709135a0b refactor: sql取消执行逻辑调整、前端使用vueuse重构部分代码 2023-12-09 16:17:26 +08:00
meilin.huang
59a7ff9ac7 feat: 常用操作界面支持Splitpane等 2023-12-07 23:57:11 +08:00
Coder慌
172c729535 !65 feat: 达梦数据库支持编辑表结构、索引
Merge pull request !65 from zongyangleo/dev_1207_dm
2023-12-07 10:45:23 +00:00
刘宗洋
ac5198db1c feat: 达梦数据库支持编辑表结构、索引 2023-12-07 17:32:32 +08:00
刘宗洋
5c5c2c2037 Merge remote-tracking branch 'upstream/dev' into dev_1207_dm 2023-12-07 14:32:07 +08:00
meilin.huang
1db990b554 refactor: 新增达梦图标、调整前端DbDialect接口 2023-12-07 11:48:17 +08:00
刘宗洋
70c887a16a fix: 支持达梦数据库查询索引 2023-12-07 10:03:50 +08:00
Coder慌
2430c4f6aa !64 feat: 支持达梦数据库查询
Merge pull request !64 from zongyangleo/dev_1207_dm
2023-12-07 01:28:44 +00:00
刘宗洋
84fd14c129 feat: 支持达梦数据库查询 2023-12-07 09:21:40 +08:00
meilin.huang
a376a82240 feat: 数据库sql执行支持取消执行操作 2023-12-07 01:07:34 +08:00
meilin.huang
e1e03dc09a fix: 字段补充 2023-12-06 16:02:07 +08:00
meilin.huang
790d644c34 refactor: 终端记录调整 2023-12-06 13:17:50 +08:00
meilin.huang
9de8dae954 feat: 前后端传递sql编码处理 2023-12-06 09:23:23 +08:00
meilin.huang
57361d8241 feat: 支持关联多标签、计划任务立即执行、标签相关操作优化 2023-12-05 23:03:51 +08:00
meilin.huang
b347bd7ef5 feat: 数据库超时时间设置 2023-11-30 15:02:48 +08:00
meilin.huang
070c8ac0da fix: 排序导致条件丢失 2023-11-29 20:13:29 +08:00
meilin.huang
e221c2f42e feat: 新增系统全局分页size配置,可根据屏幕大小自行设置 2023-11-29 17:34:54 +08:00
Coder慌
c7bab3a71b !62 fix:gauss驱动支持ssh
Merge pull request !62 from zongyangleo/dev_1128
2023-11-29 08:40:25 +00:00
刘宗洋
82c17a51a2 fix:libpq驱动支持gaussdb sha256加密登录 2023-11-28 22:49:42 +08:00
meilin.huang
e4447e6bc2 refactor: code review 2023-11-27 17:40:47 +08:00
Coder慌
b9570d9a5f !61 fix: 1、pgsql驱动换成高斯db驱动 2、sql格式化支持传数据库类型
Merge pull request !61 from zongyangleo/dev_1127
2023-11-27 08:58:32 +00:00
刘宗洋
01e8a2c14d fix:
1、pgsql驱动换成高斯db驱动
2、sql格式化支持传数据库类型
2023-11-27 16:55:00 +08:00
meilin.huang
64bd51c3b0 refactor: code review 2023-11-26 21:21:35 +08:00
Coder慌
54ab34df3f !60 feat: 支持pgsql编辑表、索引
Merge pull request !60 from zongyangleo/dev_1126
2023-11-26 02:32:27 +00:00
刘宗洋
206490ba3e feat: 支持pgsql编辑表、索引 2023-11-26 01:47:49 +08:00
meilin.huang
16612d2c9c refactor: 多tab结果集调整 2023-11-24 17:03:08 +08:00
meilin.huang
6b65605360 feat: sql查询支持多tab结果集 2023-11-24 12:12:47 +08:00
meilin.huang
bb37ed3b95 refactor: 数据库操作界面小优化 2023-11-22 12:19:07 +08:00
meilin.huang
d102cc8c08 feat: 数据库表操作支持复制单元格数据菜单 2023-11-20 12:21:27 +08:00
meilin.huang
a6df74d63d refactor: 虚拟表格优化 2023-11-18 21:15:33 +08:00
meilin.huang
f79760943e refactor: 虚拟表格与contextmenu菜单优化 2023-11-18 15:22:25 +08:00
meilin.huang
a40ec21a05 refactor: 数据库表使用虚拟表替换,提升数据量较大时的渲染速度 2023-11-17 13:31:28 +08:00
meilin.huang
43230267b6 refactor: 界面小调整 2023-11-15 12:28:49 +08:00
meilin.huang
0ae99cdaf9 refactor: contextmenu组件优化、标签&资源替换为contextmenu操作 2023-11-14 17:36:51 +08:00
meilin.huang
f234c72514 refactor: DB-数据操作优化 2023-11-13 17:41:03 +08:00
meilin.huang
76527d95bd refactor: 机器相关配置迁移至系统配置、pgsql数据操作完善、新增context-path 2023-11-12 20:14:44 +08:00
meilin.huang
27c53385f2 refactor: 列表操作按钮调整 2023-11-09 12:11:11 +08:00
Coder慌
a1b25e9766 !59 fix: sql代码提示修复:支持跨schema提示
Merge pull request !59 from zongyangleo/dev_1109
2023-11-09 02:13:31 +00:00
刘宗洋
abad0ed481 fix: sql代码提示修复:支持跨schema提示 2023-11-09 09:48:58 +08:00
meilin.huang
eddda41291 feat: 机器列表新增运行状态 & refactor: 登录账号信息存储与context 2023-11-07 21:05:21 +08:00
meilin.huang
d9adf0fd25 fix: 表问题修复 2023-11-03 22:29:01 +08:00
meilin.huang
0ce82b41ba refactor: 标签树展示调整 2023-11-03 17:09:20 +08:00
meilin.huang
37026f3269 feat: 数据库表操作显示表size&其他小优化 2023-11-02 12:46:21 +08:00
meilin.huang
3155380f16 refactor: tooltip延迟显示等 2023-10-31 12:36:04 +08:00
meilin.huang
f2b0f294d8 refactor: machine包调整 2023-10-30 17:34:56 +08:00
meilin.huang
12f63ef3dd refactor: db/redis/mongo连接代码包独立 2023-10-27 17:41:45 +08:00
meilin.huang
a1303b52eb refactor: 新增base.Repo与base.App,重构repo与app层代码 2023-10-26 17:15:49 +08:00
meilin.huang
10f6b03fb5 refactor: code review 2023-10-20 21:31:46 +08:00
may-fly
45d2449221 Merge pull request #74 from kanzihuang/fix-showcreatetable
fix: show create table for postgres
2023-10-20 21:15:54 +08:00
wanli
9e5f146e05 fix: show create table for postgres 2023-10-20 17:37:09 +08:00
meilin.huang
2b91bbe185 refactor: websocket支持单用户多连接 2023-10-19 19:00:23 +08:00
may-fly
747ea6404d Merge pull request #73 from kanzihuang/feat-notify
feature: 每个客户端独立处理后端发送的系统消息
2023-10-18 08:36:21 -05:00
wanli
ccfc6bd1df feature: 每个客户端独立处理后端发送的系统消息 2023-10-18 20:31:27 +08:00
kanzihuang
361eafedae feature: 执行 SQL 脚本时显示执行进度 2023-10-18 15:41:57 +08:00
meilin.huang
a64b894b08 refactor: sqlite依赖替换 2023-10-17 12:32:59 +08:00
may-fly
0ad805c170 Merge pull request #72 from kanzihuang/refactor-dbtype
refactor: 实现 DbType 类型,集中处理部分差异化的数据库操作
2023-10-15 19:41:19 -05:00
kanzihuang
ba82b5b516 refactor: 实现 DbType 类型,集中处理部分差异化的数据库操作 2023-10-15 11:39:42 +08:00
may-fly
f04b82c933 Merge pull request #71 from kanzihuang/fix-exec-postgres-sql-pullrequest
fix: 执行或导入 SQL 脚本支持 PostgreSQL
2023-10-14 09:57:12 -05:00
kanzihuang
23b137ab9b fix: 执行或导入 SQL 脚本支持 PostgreSQL 2023-10-14 21:10:53 +08:00
meilin.huang
a4d3a4627a refactor: 系统水印优化等 2023-10-14 16:00:16 +08:00
meilin.huang
77ae6e3bab refactor: 系统水印重构 2023-10-14 00:38:51 +08:00
meilin.huang
e0f1f40ba0 fix: 缓存使用redis无法set问题修复&admin账号默认有所有菜单 2023-10-12 21:50:55 +08:00
meilin.huang
d300f604f1 review 2023-10-12 12:14:56 +08:00
may-fly
2c2c0ff40b Merge pull request #69 from kanzihuang/feat-progress-notify-pullrequest
feat: 显示 SQL 文件执行进度
2023-10-10 20:52:24 -05:00
kanzihuang
b4ddbbd38f fix: 使用最新版 vitess sqlparser 解析 SQL 语句
解决 xwb1989/sqlparser 不支持 current_timestamp() 的问题
2023-10-10 23:56:01 +08:00
wanli
7544288451 feat: 前端显示 SQL 文件执行进度 2023-10-10 23:28:25 +08:00
meilin.huang
41443dccc0 feat: 支持sqlite存储数据 2023-10-10 23:21:29 +08:00
meilin.huang
22e218fc5f refactor: 系统消息调整 2023-10-10 17:39:46 +08:00
meilin.huang
4da0d1abaa refactor: form表单label统一去除':' 2023-10-09 17:29:52 +08:00
meilin.huang
6563b53436 refactor: 包依赖升级等 2023-10-08 12:14:19 +08:00
meilin.huang
fac71a4794 fix: 前端代理默认端口调整&水印开关不生效 2023-09-27 17:19:58 +08:00
meilin.huang
92dff6fdc3 refactor: review 2023-09-26 17:38:52 +08:00
meilin.huang
a1eca3d691 refactor: 登录页调整 2023-09-23 22:52:05 +08:00
meilin.huang
6681dc1057 refactor: 数据库sql提示优化&机器终端支持全屏 2023-09-20 20:42:23 +08:00
meilin.huang
829a68feaa fix: 数据库多库切换关键字提示错误修复&sql编辑器组件统一 2023-09-19 23:00:32 +08:00
meilin.huang
72677e270d feat: 前端用户信息迁移至localstorage 2023-09-16 17:07:48 +08:00
meilin.huang
dd4ac390de refactor: 界面小优化 2023-09-14 17:21:01 +08:00
meilin.huang
0bd7d38c23 fix: 切换暗模式时编辑器主题同步调整 2023-09-13 23:57:28 +08:00
meilin.huang
ead3b0d0d8 feat: 界面新增暗模式 2023-09-13 19:54:43 +08:00
meilin.huang
4b973b22a4 refactor: 系统websocket消息重构 2023-09-12 20:54:07 +08:00
meilin.huang
e4e68d02bc feat: 机器文件优化&sql新增引号包裹 2023-09-11 22:59:13 +08:00
meilin.huang
ef8822d671 refactor: monaco编辑器按需加载 2023-09-11 17:34:24 +08:00
meilin.huang
8e75e1f6ef refactor: 部分日志请求入参调整为json 2023-09-09 23:34:26 +08:00
meilin.huang
08c381fa60 feat: 机器文件支持文件夹上传&数据库列表组件拆分 2023-09-08 22:24:45 +08:00
may-fly
d7a10d4032 Merge pull request #60 from kanzihuang/feature-export-databases
fix: 前端 DBMS->数据操作->新建查询,页面不显示查询结果
2023-09-08 13:53:17 +08:00
wanli
c324a030f9 fix: 前端 DBMS->数据操作->新建查询,页面不显示查询结果 2023-09-08 12:21:24 +08:00
may-fly
b618b8f93b Merge pull request #58 from kanzihuang/feature-export-databases
feat: 优化数据库批量导出功能
2023-09-07 19:55:53 +08:00
wanli
4d2e110e1e refactor: 优化数据库导出速度 2023-09-07 19:34:35 +08:00
may-fly
ecd79a2e15 Merge pull request #57 from kanzihuang/feature-export-databases
feat: 批量导出数据库时可按名称筛选数据库
2023-09-07 17:20:42 +08:00
wanli
f4f297d3f7 refactor: 优化数据库导出速度 2023-09-07 16:51:49 +08:00
kanzihuang
b5549c0fae fix: 数据库导出失败时将错误提示输出到 SQL 文件 2023-09-07 16:41:47 +08:00
kanzihuang
929bfb3200 fix: 数据库导出失败时向前端发消息 2023-09-07 16:41:47 +08:00
kanzihuang
7d3593a944 feat: 批量导出数据库时可按名称筛选数据库 2023-09-07 16:41:37 +08:00
meilin.huang
9e0db2bc99 feat: 机器文件新增批量删除、copy、mv、rename等操作 2023-09-07 16:33:53 +08:00
meilin.huang
25b0d276b3 refactor: 机器文件操作界面重构 2023-09-06 18:06:52 +08:00
may-fly
0cb7a7cf83 Merge pull request #56 from kanzihuang/feature-export-databases
feat: 批量导出数据库(仅支持 MySQL 数据库)
2023-09-05 15:28:07 +08:00
wanli
52f72400ba refactor: 获取数据库连接调整 2023-09-05 15:22:16 +08:00
wanli
0eaff33168 fix: 由于批量导出数据库不支持 PostgreSQL,非 MySQL 数据库限制使用该功能。 2023-09-05 14:50:45 +08:00
wanli
086dbf278b feature: 导出数据库时采用gzip压缩 2023-09-05 14:50:45 +08:00
wanli
57a5e237ae fix: 执行脚SQL脚本时解析SQL失败
SQL脚本中包含use mayfly-go,应为use `mayfly-go`。
2023-09-05 14:50:45 +08:00
wanli
eee6cf7b14 fix: 导出数据库时获取表结构失败
原因是表名为 group, 应在表名前后添加 `` 符号
2023-09-05 14:50:45 +08:00
wanli
b9c6ac8d6d feature: 批量导出数据库 2023-09-05 14:50:45 +08:00
meilin.huang
618d782af3 refactor: 获取数据库连接调整 2023-09-05 14:41:12 +08:00
meilin.huang
d0ac7de4cb review: 数据库实例管理调整 2023-09-05 12:49:12 +08:00
may-fly
baf8053613 Merge pull request #55 from kanzihuang/feature-instance
feature: 从数据库管理模块中拆分数据库实例管理功能
2023-09-05 08:44:58 +08:00
wanli
b973d63331 refactor: 数据库实例表 t_instance 改为 t_db_instance
同时,为避免混淆,将 application.DbInstance 改为 application.DbConnection
2023-09-05 08:13:32 +08:00
kanzihuang
85b64d7e8d feature: 拆分数据库实例的SQL脚本 2023-09-04 23:13:05 +08:00
kanzihuang
86ad183c41 feature: 将数据库实例管理集成到数据库管理模块中 2023-09-04 23:12:50 +08:00
kanzihuang
f7b685cfad feature: 实现数据库实例管理 2023-09-04 23:09:28 +08:00
meilin.huang
649116a0b8 refactor: 日志堆栈描述调整 2023-09-03 13:04:29 +08:00
meilin.huang
899a3a8243 refactor: slog替换logrus、日志操作统一、支持json、text格式等 2023-09-02 17:24:18 +08:00
meilin.huang
d51cd4b289 refactor: 终端重构、系统参数配置调整 2023-08-31 21:49:20 +08:00
meilin.huang
537b179e78 fix: 数据导出精度修复、redis数据操作优化 2023-08-29 21:31:08 +08:00
meilin.huang
1e5b1868ab refactor: redis操作界面重构 2023-08-28 17:25:59 +08:00
may-fly
245406673c Merge pull request #54 from kanzihuang/fix-ldap-login
fix: LDAP login
2023-08-26 12:37:29 +08:00
kanzihuang
51fa197af6 fix: LDAP login 2023-08-26 12:06:29 +08:00
meilin.huang
649b2bb165 refactor: ldap登录配置迁移至系统配置 2023-08-25 23:26:14 +08:00
meilin.huang
3634c902d0 feat: 系统配置新增权限控制 2023-08-25 19:41:52 +08:00
may-fly
756e580469 Merge pull request #53 from kanzihuang/feature-ldap
feat: 实现 LDAP 登录
2023-08-25 12:10:16 +08:00
kanzihuang
4e1350d1cc feat: 实现 LDAP 登录 2023-08-25 03:48:42 +00:00
meilin.huang
2e969d46fb feat: mongo优化 2023-08-25 10:20:32 +08:00
Coder慌
a5bcbe151d !58 feat:sql编写体验优化
Merge pull request !58 from zongyangleo/dev_0823
2023-08-23 05:42:22 +00:00
刘宗洋
c4abba361a feat:sql编写体验优化
1.添加自定义关键字
2.自定义函数注释和模板
3.点击按钮添加limit
2023-08-23 12:41:58 +08:00
meilin.huang
24b46b1133 refactor: 代码小优化 2023-08-16 17:37:33 +08:00
meilin.huang
3ae7e0de75 refactor: validator调整 2023-08-04 12:22:21 +08:00
meilin.huang
c2ee4f9955 refactor: 后端validator校验错误转译 2023-07-31 17:34:32 +08:00
may-fly
2479412334 Merge pull request #46 from CodFrm/dev
ci: 优化镜像构建和docker compose
2023-07-28 16:12:50 +08:00
王一之
6da8d7fd67 ci: 优化镜像构建和docker compose 2023-07-28 13:56:32 +08:00
meilin.huang
0f596a712d feat: 数据库表查询支持页数选择 2023-07-27 16:47:05 +08:00
meilin.huang
8f37b71d7f refactor: oauth2登录优化 2023-07-26 10:24:32 +08:00
meilin.huang
5083b2bdfe refactor: oauth2登录调整 2023-07-24 22:36:07 +08:00
meilin.huang
155ae65b4a refactor: oauth2登录重构 2023-07-22 20:51:46 +08:00
may-fly
ffacfc3ae8 Merge pull request #44 from CodFrm/develop/auth
OAuth2 登录和数据库升级问题优化
2023-07-22 11:53:11 +08:00
王一之
b1ab66ecf9 feat: 优化数据库迁移与添加老表迁移 2023-07-22 00:48:41 +08:00
王一之
f5bb0cad3e fix: 修复记录ip与归属地信息问题 2023-07-21 22:46:55 +08:00
王一之
a0de5afcb0 chore: 处理合并问题 2023-07-21 22:29:41 +08:00
王一之
358d33d60e fix: 修复OAuth2绑定按钮逻辑错误 2023-07-21 22:04:38 +08:00
王一之
062d28b6e6 feat: OAuth2 登录 2023-07-21 22:04:38 +08:00
王一之
513f8ea012 wip: oauth2登录和oauth2 otp登录验证 2023-07-21 22:04:37 +08:00
王一之
179b58e557 wip: 自定义oauth2登录配置 2023-07-21 22:01:53 +08:00
meilin.huang
b7450f8869 fix: 前端界面小问题修复 2023-07-21 21:01:25 +08:00
meilin.huang
7f9e972828 feat: 代码优化、机器计划任务完善 2023-07-21 17:07:04 +08:00
meilin.huang
7b51705f4e feat: 新增机器计划任务、数据物理删除调整为逻辑删除、支持记录登录ip归属地等 2023-07-20 22:41:13 +08:00
Coder慌
6bd9e5333d !55 https://gitee.com/objs/mayfly-go/issues/I7LFVH问题解决
Merge pull request !55 from amell/databases_404_fix
2023-07-16 04:04:22 +00:00
Coder慌
112d735ac0 !56 https://gitee.com/objs/mayfly-go/issues/I7LFXS的BUG修复
Merge pull request !56 from amell/dev
2023-07-16 04:04:00 +00:00
amell
52553ed53f [fix] https://gitee.com/objs/mayfly-go/issues/I7LFXS的缺陷修复 2023-07-16 11:13:52 +08:00
amell
70d84e32d1 [fix] https://gitee.com/objs/mayfly-go/issues/I7LFVH的缺陷修复 2023-07-16 09:44:55 +08:00
meilin.huang
3269dfa5d6 refactor: 后端路由定义方式&请求参数绑定重构 2023-07-08 20:05:55 +08:00
meilin.huang
183a6e4905 refactor: 团队成员分配使用pagetable组件重构 2023-07-07 14:43:51 +08:00
meilin.huang
5463ae9d7e refactor: 前端统一使用prettier格式化&枚举值统一管理 2023-07-06 20:59:22 +08:00
Coder慌
f25bdb07ce !54 fix: 修复字段粘连无法提示的问题
Merge pull request !54 from zongyangleo/dev_0706
2023-07-06 06:54:28 +00:00
刘宗洋
aa5c08d564 fix: 修复字段粘连无法提示的问题 2023-07-06 11:08:00 +08:00
meilin.huang
dc9a2985f3 refactor: 分页组件统一替换&其他优化 2023-07-05 22:06:32 +08:00
meilin.huang
f4ac6d8360 refactor: 机器文件操作优化 2023-07-05 00:26:00 +08:00
meilin.huang
3266039aaf fix: 双击修改表sql问题修复 2023-07-04 15:07:03 +08:00
meilin.huang
e3f4c298b0 feat: 系统日志支持按描述搜索 2023-07-04 14:13:47 +08:00
meilin.huang
fa58f6d2de fix: 无法添加成员 2023-07-03 21:58:37 +08:00
meilin.huang
ae5a1fd7de refactor: code review 2023-07-03 21:42:04 +08:00
meilin.huang
c240079df4 refactor: 前端代码优化 2023-07-02 17:06:00 +08:00
meilin.huang
aca4e6751e refactor: 前端风格统一 2023-07-01 21:24:07 +08:00
meilin.huang
ce32fc7f2c refactor: 代码重构、分页数据组件支持多选 2023-07-01 14:34:42 +08:00
meilin.huang
d423572e01 fix: 新增资源选择标签问题修复、项目文档转移 2023-06-29 20:20:58 +08:00
meilin.huang
d9807b1bf0 feat: 数据库表数据支持字段设置、表格宽度自适应调整 2023-06-29 11:49:14 +08:00
meilin.huang
1bc53b4c80 refactor: 表格宽度自适应宽度计算方式调整 2023-06-29 00:40:42 +08:00
meilin.huang
6bc2603a4d fix: 查询label宽度自动适配 2023-06-28 21:50:04 +08:00
meilin.huang
e2c929aae1 feat: 统一分页表格组件、修复系统配置无法配置单个属性 2023-06-28 21:35:03 +08:00
Coder慌
0d155d592b !53 feat:修改表结构:主键默认自增,自动生成索引名
Merge pull request !53 from zongyangleo/dev_0625
2023-06-26 01:26:51 +00:00
Coder慌
ae510ff1ff !52 update server/mayfly-go.sql.
Merge pull request !52 from noday/N/A
2023-06-26 01:24:48 +00:00
noday
5b0654ad2c update server/mayfly-go.sql.
sql values字段不匹配
2023-06-26 01:18:48 +00:00
刘宗洋
466f97ecbe feat:修改表结构:主键默认自增,自动生成索引名 2023-06-25 21:12:28 +08:00
meilin.huang
27a14c22d7 fix: sql遗漏调整 2023-06-25 19:10:37 +08:00
meilin.huang
4709edcd1c fix: 遗漏sql补充 2023-06-21 15:18:43 +08:00
meilin.huang
414de9f2eb fix: 数据库提示问题修复 2023-06-20 17:08:13 +08:00
Coder慌
a53e7e7dab !50 SQL字段补全的BUG修复
Merge pull request !50 from amell/sql_autocomplete
2023-06-17 11:42:39 +00:00
amell
7fa6628dc5 [bugfix] issue修复: https://gitee.com/objs/mayfly-go/issues/I7E9LF 2023-06-17 19:29:19 +08:00
Coder慌
62c25afea8 !49 对于update和delete的SQL操作,建议增加where条件检测,缺失where条件时不执行相应的SQL
Merge pull request !49 from amell/sql_where
2023-06-17 09:25:02 +00:00
amell
481b622e3b [fix] https://gitee.com/objs/mayfly-go/issues/I7E8ZF的修复 2023-06-17 16:57:06 +08:00
meilin.huang
64f8f9a200 fix: meta_sql文件中windows换行符不同问题 2023-06-17 16:04:21 +08:00
meilin.huang
0eca951465 Merge branch 'dev' 2023-06-17 15:15:56 +08:00
meilin.huang
ef4e34c584 feat: 新增双因素校验(OTP) 2023-06-17 15:15:03 +08:00
Coder慌
d91acbc7ee !45 修复同时执行多条SQL的bug
Merge pull request !45 from amell/mutil_sql
2023-06-17 04:47:48 +00:00
amell
b397d1022e [fix] issue: I7E6QQ的缺陷修复 2023-06-17 08:59:37 +08:00
meilin.huang
b42a98aff5 fix: sql脚本问题修复 2023-06-16 08:59:22 +08:00
meilin.huang
adc65439e4 feat: redis支持flushdb、菜单资源支持拖拽排序、禁用等 2023-06-15 19:18:29 +08:00
Coder慌
445cf3716b !44 feat: sql字段提示优化
Merge pull request !44 from zongyangleo/dev_20230613
2023-06-13 09:03:53 +00:00
刘宗洋
f4b59b8503 feat:单表查询支持无别名提示字段 2023-06-13 17:01:39 +08:00
刘宗洋
4f08975df2 fix:修复数据库schema提示 2023-06-13 15:57:08 +08:00
刘宗洋
570db453d7 feat:sql字段提示优化 2023-06-13 14:54:52 +08:00
meilin.huang
b93984bf6f refactor: json tag完善 2023-06-11 19:59:35 +08:00
meilin.huang
e483db1b97 fix: 哨兵节点密码调整 2023-06-06 20:51:54 +08:00
meilin.huang
17d96acceb refactor: interface{} -> any
feat: 新增外链菜单
2023-06-01 12:31:32 +08:00
meilin.huang
9900b236ef refactor: 组件升级、代码优化 2023-05-24 12:32:17 +08:00
Coder慌
4fa52412c1 !42 fix:修改表sql,如果是修改的主键,sql bug修复
Merge pull request !42 from zongyangleo/dev_20230417
2023-04-17 09:40:11 +00:00
刘宗洋
0076869deb fix:修改表:如果修改的字段是主键 2023-04-17 16:21:06 +08:00
1440 changed files with 512899 additions and 42353 deletions

6
.gitignore vendored
View File

@@ -17,4 +17,10 @@
*/node_modules/
**/vendor/
.idea
.vscode
out
server/docs/docker-compose
server/config.yml
server/ip2region.xdb
mayfly-go.log

26
Dockerfile Normal file
View File

@@ -0,0 +1,26 @@
ARG BASEIMAGES=m.daocloud.io/docker.io/alpine:3.20.2
FROM ${BASEIMAGES} AS builder
ARG TARGETARCH
ARG MAYFLY_GO_VERSION
ARG MAYFLY_GO_DIR_NAME=mayfly-go-linux-${TARGETARCH}
ARG MAYFLY_GO_URL=https://gitee.com/dromara/mayfly-go/releases/download/${MAYFLY_GO_VERSION}/${MAYFLY_GO_DIR_NAME}.zip
RUN wget -cO mayfly-go.zip ${MAYFLY_GO_URL} && \
unzip mayfly-go.zip && \
mv ${MAYFLY_GO_DIR_NAME}/* /opt
FROM ${BASEIMAGES}
ARG TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY --from=builder /opt/mayfly-go /usr/local/bin/mayfly-go
WORKDIR /mayfly-go
EXPOSE 18888
CMD ["mayfly-go"]

39
Dockerfile.sourcebuild Normal file
View File

@@ -0,0 +1,39 @@
# 构建前端资源
FROM m.daocloud.io/docker.io/node:18-bookworm-slim AS fe-builder
WORKDIR /mayfly
COPY frontend .
RUN yarn config set registry 'https://registry.npmmirror.com' && \
yarn install && \
yarn build
# 构建后端资源
FROM m.daocloud.io/docker.io/golang:1.23 AS be-builder
ENV GOPROXY https://goproxy.cn
WORKDIR /mayfly
# Copy the go source for building server
COPY server .
RUN go mod tidy && go mod download
COPY --from=fe-builder /mayfly/dist /mayfly/static/static
# Build
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux \
go build -a -ldflags=-w \
-o mayfly-go main.go
FROM m.daocloud.io/docker.io/alpine:3.20.2
ARG TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /mayfly-go
COPY --from=be-builder /mayfly/mayfly-go /usr/local/bin/mayfly-go
CMD ["mayfly-go"]

3
Makefile Normal file
View File

@@ -0,0 +1,3 @@
docker:
docker build . -t mayfly-go

120
README.md
View File

@@ -1,87 +1,113 @@
# 🌈mayfly-go
# 🌈Dromara mayfly-go
<p align="center">
<a href="https://gitee.com/objs/mayfly-go" target="_blank">
<img src="https://gitee.com/objs/mayfly-go/badge/star.svg?theme=white" alt="star"/>
<img src="https://gitee.com/objs/mayfly-go/badge/fork.svg" alt="fork"/>
<a href="./README_EN.md">English</a> |
<a href="https://www.yuque.com/may-fly/mayfly-go">项目文档</a> |
<a href="https://space.bilibili.com/484091081/channel/collectiondetail?sid=392854">操作视频</a> |
</p>
<p align="center">
<a href="https://gitee.com/dromara/mayfly-go" target="_blank">
<img src="https://gitee.com/dromara/mayfly-go/badge/star.svg?theme=white" alt="star"/>
<img src="https://gitee.com/dromara/mayfly-go/badge/fork.svg" alt="fork"/>
</a>
<a href="https://github.com/may-fly/mayfly-go" target="_blank">
<img src="https://img.shields.io/github/stars/may-fly/mayfly-go.svg?style=social" alt="github star"/>
<img src="https://img.shields.io/github/forks/may-fly/mayfly-go.svg?style=social" alt="github fork"/>
<a href="https://github.com/dromara/mayfly-go" target="_blank">
<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.18%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">
</a>
</p>
## 前言
### 介绍
web版 **linux(终端[终端回放] 文件 脚本 进程)、数据库mysql postgres、redis(单机 哨兵 集群)、mongo统一管理操作平台**
Web 版 **统一管理操作平台**,集成了对 Linux 系统的全面操作支持(包括终端管理[终端回放、命令过滤]、文件管理、脚本执行、进程监控及计划任务设置),同时提供了多种数据库(如 MySQL、PostgreSQL、Oracle、SQL Server、达梦、高斯、SQLite 等)的数据操作、数据同步与数据迁移功能。此外,还支持 Redis单机、哨兵、集群模式、 MongoDB 、Es 的操作管理,并结合工单流程审批功能,为企业提供一站式的运维与管理解决方案。
## 开发语言与主要框架
### 开发语言与主要框架
- 前端typescript、vue3、element-plus
- 后端golang、gin、gorm
## 交流及问题反馈加 QQ 群
### 交流及问题反馈加 QQ 群
<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=IdJSHW0jTMhmWFHBUS9a83wxtrxDDhFj&jump_from=webapi">119699946</a>
## 演示环境
### 系统相关资料
- 项目文档: https://objs.gitee.io/mayfly-go-docs
- 系统操作视频: https://space.bilibili.com/484091081/channel/collectiondetail?sid=392854
- 部署文档https://objs.gitee.io/mayfly-go-docs/download
http://go.mayfly.run
账号/密码test/test123.
## 系统核心功能截图
#### 首页
![首页](https://foruda.gitee.com/images/1757163736351080323/afb6b330_1240250.png "屏幕截图")
#### 资源管理
![资源树](https://foruda.gitee.com/images/1757163958991119284/83eb2171_1240250.png "屏幕截图")
#### 资源操作
![终端操作](https://foruda.gitee.com/images/1757164093410206293/1c7dda30_1240250.png)
![文件操作](https://foruda.gitee.com/images/1757164149388450531/0542398c_1240250.png)
![文件查看](https://foruda.gitee.com/images/1714378482611638688/7753faf6_1240250.png "屏幕截图")
### 系统核心功能截图
##### 记录操作记录
![记录操作记录](https://images.gitee.com/uploads/images/2021/0508/204608_83ef7c33_1240250.png "屏幕截图.png")
#### 机器操作
##### 状态查看
![状态查看](https://objs.gitee.io/mayfly-go-docs/home/machine-status.jpg "屏幕截图.png")
##### ssh终端
![ssh终端](https://objs.gitee.io/mayfly-go-docs/home/machine-ssh.jpg "屏幕截图.png")
##### 文件操作
![文件操作](https://objs.gitee.io/mayfly-go-docs/home/file-dir.jpg "屏幕截图.png")
![文件操作](https://objs.gitee.io/mayfly-go-docs/home/file-content-update.jpg "屏幕截图.png")
![sql编辑器](https://foruda.gitee.com/images/1757164386318836686/c3b17a52_1240250.png)
#### 数据库操作
##### sql编辑器
![sql编辑器](https://objs.gitee.io/mayfly-go-docs/home/dbms-sql-editor.jpg "屏幕截图.png")
##### 在线增删改查数据
![选表查数据](https://objs.gitee.io/mayfly-go-docs/home/dbms-show-table-data.jpg "屏幕截图.png")
![选表查数据](https://foruda.gitee.com/images/1757164281011401749/5109485f_1240250.png)
#### Redis操作
![数据](https://objs.gitee.io/mayfly-go-docs/home/redis-data-list.jpg "屏幕截图.png")
![redis操作](https://foruda.gitee.com/images/1757164442298752845/4af1b296_1240250.png)
#### Mongo操作
![数据](https://objs.gitee.io/mayfly-go-docs/home/mongo-op.jpg "屏幕截图.png")
![mongo操作](https://foruda.gitee.com/images/1714378916425714642/77fc0ed9_1240250.png "屏幕截图")
![es操作](https://foruda.gitee.com/images/1757164553845346963/b5b70381_1240250.png)
![容器操作](https://foruda.gitee.com/images/1757164625186816754/2b195e25_1240250.png)
#### 工单流程审批
![流程审批](https://foruda.gitee.com/images/1714379057627690037/ad136862_1240250.png "屏幕截图")
#### 系统管理
##### 系统管理
##### 账号管理
![账号管理](https://images.gitee.com/uploads/images/2021/0607/173919_a8d7dc18_1240250.png "屏幕截图.png")
![账号管理](https://foruda.gitee.com/images/1714379179491881231/c6d802ae_1240250.png "屏幕截图")
##### 角色管理
![角色管理](https://images.gitee.com/uploads/images/2021/0607/174028_3654fb28_1240250.png "屏幕截图.png")
##### 资源管理
![资源管理](https://images.gitee.com/uploads/images/2021/0607/174436_e9e1535c_1240250.png "屏幕截图.png")
![角色管理](https://foruda.gitee.com/images/1714379269408676381/6ac1e85c_1240250.png "屏幕截图")
##### 菜单资源管理
**其他更多功能&操作指南可查看在线文档**: https://objs.gitee.io/mayfly-go-docs
![菜单资源管理](https://foruda.gitee.com/images/1714379321338009940/a00d6a02_1240250.png "屏幕截图")
**其他更多功能&操作指南可查看上述项目文档**
## 💌 支持作者
如果觉得项目不错,或者已经在使用了,希望你可以去 <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可受邀进入付费交流群享受更快、更优先的技术支持与交流服务

100
README_EN.md Normal file
View File

@@ -0,0 +1,100 @@
# 🌈Dromara mayfly-go
<p align="center">
<a href="./README.md">中文介绍</a> |
<a href="https://www.yuque.com/may-fly/mayfly-go">Documentation</a> |
<a href="https://space.bilibili.com/484091081/channel/collectiondetail?sid=392854">Operate Video</a>
</p>
<p align="center">
<a href="https://gitee.com/dromara/mayfly-go" target="_blank">
<img src="https://gitee.com/dromara/mayfly-go/badge/star.svg?theme=white" alt="star"/>
<img src="https://gitee.com/dromara/mayfly-go/badge/fork.svg" alt="fork"/>
</a>
<a href="https://github.com/dromara/mayfly-go" target="_blank">
<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://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"/>
</a>
<a href="https://cn.vuejs.org" target="_blank">
<img src="https://img.shields.io/badge/Vue-3.x-green.svg" alt="vue">
</a>
</p>
## Preface
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
- frontendtypescript、vue3、element-plus
- backendgolang、gin、gorm
## Demo
http://go.mayfly.run
account/passwordtest/test123.
## Screenshots of core features
#### Home page
![首页](https://foruda.gitee.com/images/1714378104294194769/149fd257_1240250.png "屏幕截图")
#### Resource Manage
![资源树](https://foruda.gitee.com/images/1757163958991119284/83eb2171_1240250.png "屏幕截图")
#### Resource Operation
![终端操作](https://foruda.gitee.com/images/1757164093410206293/1c7dda30_1240250.png)
![文件操作](https://foruda.gitee.com/images/1757164149388450531/0542398c_1240250.png)
![文件查看](https://foruda.gitee.com/images/1714378482611638688/7753faf6_1240250.png "屏幕截图")
![sql编辑器](https://foruda.gitee.com/images/1757164386318836686/c3b17a52_1240250.png)
![选表查数据](https://foruda.gitee.com/images/1757164281011401749/5109485f_1240250.png)
![redis操作](https://foruda.gitee.com/images/1757164442298752845/4af1b296_1240250.png)
![mongo操作](https://foruda.gitee.com/images/1714378916425714642/77fc0ed9_1240250.png "屏幕截图")
![es操作](https://foruda.gitee.com/images/1757164553845346963/b5b70381_1240250.png)
![容器操作](https://foruda.gitee.com/images/1757164625186816754/2b195e25_1240250.png)
#### Work order process approval
![流程审批](https://foruda.gitee.com/images/1714379057627690037/ad136862_1240250.png "屏幕截图")
#### System Management
##### Account
![账号管理](https://foruda.gitee.com/images/1714379179491881231/c6d802ae_1240250.png "屏幕截图")
##### Role
![角色管理](https://foruda.gitee.com/images/1714379269408676381/6ac1e85c_1240250.png "屏幕截图")
##### Menu & Permission
![菜单资源管理](https://foruda.gitee.com/images/1714379321338009940/a00d6a02_1240250.png "屏幕截图")
**Additional features & instructions can be found in the project documentation above.**
## 💌 Supporting Author
If you think the project is good, or you are already using it, I hope you can go to <a target="_blank" href="https://github.com/dromara/mayfly-go">Github</a> to help me click ⭐ Star, which will be a great encouragement and support for me.

View File

@@ -8,7 +8,7 @@ project_path=`pwd`
# 构建后的二进制执行文件名
exec_file_name="mayfly-go"
# web项目目录
web_folder="${project_path}/mayfly_go_web"
web_folder="${project_path}/frontend"
# server目录
server_folder="${project_path}/server"
@@ -28,13 +28,13 @@ function buildWeb() {
cd ${web_folder}
copy2Server=$1
echo_yellow "-------------------打包前端开始-------------------"
echo_yellow "-------------------Start bundling frontends-------------------"
yarn run build
if [ "${copy2Server}" == "2" ] ; then
echo_green '将打包后的静态文件拷贝至server/static/static'
echo_green 'Copy the packaged static files to server/static/static'
rm -rf ${server_folder}/static/static && mkdir -p ${server_folder}/static/static && cp -r ${web_folder}/dist/* ${server_folder}/static/static
fi
echo_yellow ">>>>>>>>>>>>>>>>>>>打包前端结束<<<<<<<<<<<<<<<<<<<<\n"
echo_yellow ">>>>>>>>>>>>>>>>>>>End of packaging frontend<<<<<<<<<<<<<<<<<<<<\n"
}
function build() {
@@ -46,26 +46,27 @@ function build() {
arch=$3
copyDocScript=$4
echo_yellow "-------------------${os}-${arch}打包构建开始-------------------"
echo_yellow "-------------------Start a bundle build - ${os}-${arch}-------------------"
cd ${server_folder}
echo_green "打包构建可执行文件..."
echo_green "Package build executables..."
execFileName=${exec_file_name}
# 如果是windows系统,可执行文件需要添加.exe结尾
if [ "${os}" == "windows" ];then
execFileName="${execFileName}.exe"
fi
CGO_ENABLE=0 GOOS=${os} GOARCH=${arch} go build -o ${execFileName} main.go
go mod tidy
CGO_ENABLE=0 GOOS=${os} GOARCH=${arch} go build -ldflags=-w -o ${execFileName} main.go
if [ -d ${toFolder} ] ; then
echo_green "目标文件夹已存在,清空文件夹"
echo_green "The desired folder already exists. Clear the folder"
sudo rm -rf ${toFolder}
fi
echo_green "创建'${toFolder}'目录"
echo_green "Create '${toFolder}' Directory"
mkdir ${toFolder}
echo_green "移动二进制文件至'${toFolder}'"
echo_green "Move binary to '${toFolder}'"
mv ${server_folder}/${execFileName} ${toFolder}
# if [ "${copy2Server}" == "1" ] ; then
@@ -74,15 +75,16 @@ function build() {
# fi
if [ "${copyDocScript}" == "1" ] ; then
echo_green "拷贝脚本等资源文件[config.yml、mayfly-go.sql、readme.txt、startup.sh、shutdown.sh]"
cp ${server_folder}/config.yml ${toFolder}
cp ${server_folder}/mayfly-go.sql ${toFolder}
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}/startup.sh ${toFolder}
cp ${server_folder}/shutdown.sh ${toFolder}
cp ${server_folder}/readme_en.txt ${toFolder}
cp ${server_folder}/resources/script/startup.sh ${toFolder}
cp ${server_folder}/resources/script/shutdown.sh ${toFolder}
fi
echo_yellow ">>>>>>>>>>>>>>>>>>>${os}-${arch}打包构建完成<<<<<<<<<<<<<<<<<<<<\n"
echo_yellow ">>>>>>>>>>>>>>>>>>> ${os}-${arch} - Bundle build complete <<<<<<<<<<<<<<<<<<<<\n"
}
function buildLinuxAmd64() {
@@ -102,27 +104,25 @@ function buildMac() {
}
function buildDocker() {
echo_yellow "-------------------构建docker镜像开始-------------------"
echo_yellow "-------------------Start building the docker image-------------------"
imageVersion=$1
cd ${server_folder}
imageName="mayflygo/mayfly-go:${imageVersion}"
docker build -t "${imageName}" .
echo_green "docker镜像构建完成->[${imageName}]"
echo_yellow "-------------------构建docker镜像结束-------------------"
imageName="mayfly/mayfly-go:${imageVersion}"
docker build --no-cache --platform linux/amd64 --build-arg MAYFLY_GO_VERSION="${imageVersion}" -t "${imageName}" .
echo_green "The docker image is built -> [${imageName}]"
echo_yellow "-------------------Finished building the docker image-------------------"
}
function buildxDocker() {
echo_yellow "-------------------docker buildx构建镜像开始-------------------"
echo_yellow "-------------------The docker buildx build image starts-------------------"
imageVersion=$1
cd ${server_folder}
imageName="mayflygo/mayfly-go:${imageVersion}"
docker buildx build --push --platform linux/amd64,linux/arm64 -t "${imageName}" .
echo_green "docker多版本镜像构建完成->[${imageName}]"
echo_yellow "-------------------docker buildx构建镜像结束-------------------"
imageName="ccr.ccs.tencentyun.com/mayfly/mayfly-go:${imageVersion}"
docker buildx build --no-cache --push --platform linux/amd64,linux/arm64 --build-arg MAYFLY_GO_VERSION="${imageVersion}" -t "${imageName}" .
echo_green "The docker multi-architecture version image is built -> [${imageName}]"
echo_yellow "-------------------The docker buildx image is finished-------------------"
}
function runBuild() {
read -p "请选择构建版本[0|其他->除docker镜像外其他 1->linux-amd64 2->linux-arm64 3->windows 4->mac 5->docker 6->docker buildx]: " buildType
read -p "Select build version [0 | Other->Other than docker image 1->linux-amd64 2->linux-arm64 3->windows 4->mac 5->docker 6->docker buildx]: " buildType
toPath="."
imageVersion="latest"
@@ -130,16 +130,16 @@ function runBuild() {
if [[ "${buildType}" != "5" ]] && [[ "${buildType}" != "6" ]] ; then
# 构建结果的目的路径
read -p "请输入构建产物输出目录[默认当前路径]: " toPath
read -p "Please enter the build product output directory [default current path]: " toPath
if [ ! -d ${toPath} ] ; then
echo_red "构建产物输出目录不存在!"
echo_red "Build product output directory does not exist!"
exit;
fi
if [ "${toPath}" == "" ] ; then
toPath="."
fi
read -p "是否拷贝文档&脚本[0-> 1->是][默认是]: " copyDocScript
read -p "Whether to copy documents & Scripts [0-> No 1-> Yes][Default yes]: " copyDocScript
if [ "${copyDocScript}" == "" ] ; then
copyDocScript="1"
fi
@@ -147,22 +147,21 @@ function runBuild() {
# 进入目标路径,并赋值全路径
cd ${toPath}
toPath=`pwd`
# read -p "是否构建前端[0|其他->否 1->是 2->构建并拷贝至server/static/static]: " runBuildWeb
runBuildWeb="2"
# 编译web前端
buildWeb ${runBuildWeb}
fi
if [[ "${buildType}" == "5" ]] || [[ "${buildType}" == "6" ]] ; then
read -p "请输入docker镜像版本号[默认latest]: " imageVersion
read -p "Please enter the docker image version (default latest) : " imageVersion
if [ "${imageVersion}" == "" ] ; then
imageVersion="latest"
fi
fi
# read -p "是否构建前端[0|其他->否 1->是 2->构建并拷贝至server/static/static]: " runBuildWeb
runBuildWeb="2"
# 编译web前端
buildWeb ${runBuildWeb}
case ${buildType} in
"1")
buildLinuxAmd64 ${toPath} ${copyDocScript}
@@ -190,11 +189,13 @@ function runBuild() {
;;
esac
echo_green "删除['${server_folder}/static/static']下静态资源文件."
# 删除静态资源文件保留一个favicon.ico否则后端启动会报错
rm -rf ${server_folder}/static/static/assets
rm -rf ${server_folder}/static/static/config.js
rm -rf ${server_folder}/static/static/index.html
if [[ "${buildType}" != "5" ]] && [[ "${buildType}" != "6" ]] ; then
echo_green "Delete static assets under ['${server_folder}/static/static']."
# 删除静态资源文件保留一个favicon.ico否则后端启动会报错
rm -rf ${server_folder}/static/static/assets
rm -rf ${server_folder}/static/static/config.js
rm -rf ${server_folder}/static/static/index.html
fi
}
runBuild
runBuild

View File

@@ -2,32 +2,30 @@ version: "3.9"
services:
mysql:
image: "mysql:5.7"
image: "mysql:8"
container_name: mayfly-go-mysql
environment:
MYSQL_ROOT_PASSWORD: 111049
MYSQL_DATABASE: mayfly-go
TZ: Asia/Shanghai
volumes:
- ./docs/docker-compose/mysql/data/mydir:/mydir
- ./docs/docker-compose/mysql/data/datadir:/var/lib/mysql
# 在宿主机编写 /apps/mysql/conf/my.cnf
- ./docs/docker-compose/mysql/my.cnf:/etc/my.cnf
# 数据库还原目录 可将需要还原的sql文件放在这里
- ./docs/docker-compose/mysql/init:/docker-entrypoint-initdb.d
- ./server/docs/docker-compose/mysql/data/mydir:/mydir
- ./server/docs/docker-compose/mysql/data/datadir:/var/lib/mysql
restart: always
server:
image: mayfly-go:v1.3.1
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:/mayfly/config.yml
depends_on:
- mysql
restart: always

View File

@@ -5,4 +5,10 @@ VITE_PORT = 8889
VITE_OPEN = false
# public path 配置线上环境路径(打包)
VITE_PUBLIC_PATH = ''
VITE_PUBLIC_PATH = ''
VITE_EDITOR=idea
# 路由模式
# Optional: hash | history
VITE_ROUTER_MODE = hash

View File

@@ -1,5 +1,7 @@
# 本地环境
ENV = 'development'
VITE_OPEN = true
# 本地环境接口地址
VITE_API_URL = '/api'

View File

@@ -2,4 +2,4 @@
ENV = 'production'
# 线上环境接口地址
VITE_API_URL = '/api'
VITE_API_URL = '/api'

76
frontend/.eslintrc.cjs Normal file
View File

@@ -0,0 +1,76 @@
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
extends: ['plugin:vue/essential', 'eslint:recommended'],
plugins: ['vue', '@typescript-eslint'],
overrides: [
{
files: ['*.ts', '*.tsx', '*.vue'],
rules: {
'no-undef': 'off',
},
},
],
rules: {
// http://eslint.cn/docs/rules/
// https://eslint.vuejs.org/rules/
// https://typescript-eslint.io/rules/no-unused-vars/
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'vue/custom-event-name-casing': 'off',
'vue/attributes-order': 'off',
'vue/one-component-per-file': 'off',
'vue/html-closing-bracket-newline': 'off',
'vue/max-attributes-per-line': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/attribute-hyphenation': 'off',
'vue/html-self-closing': 'off',
'vue/no-multiple-template-root': 'off',
'vue/require-default-prop': 'off',
'vue/no-v-model-argument': 'off',
'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',
'vue/multi-word-component-names': 'off',
'no-useless-escape': 'off',
'no-sparse-arrays': 'off',
'no-prototype-builtins': 'off',
'no-constant-condition': 'off',
'no-use-before-define': 'off',
'no-restricted-globals': 'off',
'no-restricted-syntax': 'off',
'generator-star-spacing': 'off',
'no-unreachable': 'off',
'no-multiple-template-root': 'off',
'no-unused-vars': 'off',
'no-v-model-argument': 'off',
'no-case-declarations': 'off',
// 'no-console': 'error',
'no-redeclare': 'off',
},
};

View File

@@ -1,7 +1,8 @@
.DS_Store
node_modules
/dist
*.lock
pnpm-lock.yaml
# local env files
.env.local

39
frontend/.prettierrc.cjs Normal file
View File

@@ -0,0 +1,39 @@
module.exports = {
// 一行最多多少个字符
printWidth: 160,
// 指定每个缩进级别的空格数
tabWidth: 4,
// 使用制表符而不是空格缩进行
useTabs: false,
// 在语句末尾打印分号
semi: true,
// 使用单引号而不是双引号
singleQuote: true,
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
quoteProps: 'as-needed',
// 在JSX中使用单引号而不是双引号
jsxSingleQuote: false,
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>"默认none
trailingComma: 'es5',
// 在对象文字中的括号之间打印空格
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 在单独的箭头函数参数周围包括括号 always(x) => x \ avoidx => x
arrowParens: 'always',
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
rangeStart: 0,
rangeEnd: Infinity,
// 指定要使用的解析器,不需要写文件开头的 @prettier
requirePragma: false,
// 不需要自动在文件开头插入 @prettier
insertPragma: false,
// 使用默认的折行标准 always\never\preserve
proseWrap: 'preserve',
// 指定HTML文件的全局空格敏感度 css\strict\ignore
htmlWhitespaceSensitivity: 'css',
// Vue文件脚本和样式标签缩进
vueIndentScriptAndStyle: false,
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
endOfLine: 'lf',
};

21
frontend/index.html Normal file
View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="keywords" content="mayfly-go" />
<meta name="description" content="" />
<link type="favicon" rel="shortcut icon" href="favicon.ico" />
<title>mayfly-go</title>
</head>
<body>
<div id="app"></div>
<script type="application/javascript" src="./config.js"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

74
frontend/package.json Normal file
View File

@@ -0,0 +1,74 @@
{
"name": "mayfly-go-frontend",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"build-preview": "npm run build && npm run preview",
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.2",
"@logicflow/core": "^2.1.3",
"@logicflow/extension": "^2.1.5",
"@vueuse/core": "^13.9.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.11.1",
"axios": "^1.6.2",
"clipboard": "^2.0.11",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.18",
"echarts": "^6.0.0",
"element-plus": "^2.11.4",
"js-base64": "^3.7.8",
"jsencrypt": "^3.5.4",
"monaco-editor": "^0.54.0",
"monaco-sql-languages": "^0.15.1",
"monaco-themes": "^0.4.7",
"nprogress": "^0.2.0",
"pinia": "^3.0.3",
"qrcode.vue": "^3.6.0",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.6",
"sql-formatter": "^15.6.8",
"trzsz": "^1.1.5",
"uuid": "^13.0.0",
"vue": "^v3.5.22",
"vue-i18n": "^11.1.12",
"vue-router": "^4.6.3",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.14",
"@types/crypto-js": "^4.2.2",
"@types/node": "^22.13.14",
"@types/nprogress": "^0.2.0",
"@types/sortablejs": "^1.15.8",
"@typescript-eslint/eslint-plugin": "^8.35.0",
"@typescript-eslint/parser": "^8.35.0",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/compiler-sfc": "^3.5.18",
"autoprefixer": "^10.4.21",
"code-inspector-plugin": "^1.0.4",
"eslint": "^9.29.0",
"eslint-plugin-vue": "^10.5.0",
"postcss": "^8.5.6",
"prettier": "^3.6.1",
"sass": "^1.93.2",
"tailwindcss": "^4.1.14",
"typescript": "^5.9.2",
"vite": "npm:rolldown-vite@latest",
"vite-plugin-progress": "0.0.7",
"vue-eslint-parser": "^10.2.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

View File

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

25
frontend/public/config.js Normal file
View File

@@ -0,0 +1,25 @@
window.globalConfig = {
// 默认为空以访问根目录为api请求地址。若前后端分离部署可单独配置该后端api请求地址
BaseApiUrl: '',
BaseWsUrl: '',
};
// index.html添加百秒级时间戳防止被浏览器缓存
// !(function () {
// let t = 't=' + new Date().getTime().toString().substring(0, 8);
// let search = location.search;
// let m = search && search.match(/t=\d*/g);
// console.log(location);
// if (m[0]) {
// if (m[0] !== t) {
// location.search = search.replace(m[0], t);
// }
// } else {
// if (search.indexOf('?') > -1) {
// location.search = search + '&' + t;
// } else {
// location.search = t;
// }
// }
// })();

BIN
frontend/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

117
frontend/src/App.vue Normal file
View File

@@ -0,0 +1,117 @@
<template>
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
<el-watermark
:zIndex="100000"
:width="210"
v-if="themeConfig.isWatermark"
:font="{ color: 'rgba(180, 180, 180, 0.3)' }"
:content="themeConfig.watermarkText"
class="!h-full"
>
<router-view />
</el-watermark>
<router-view v-if="!themeConfig.isWatermark" />
<Setings />
</el-config-provider>
</template>
<script setup lang="ts" name="app">
import { onMounted, nextTick, watch, computed, defineAsyncComponent } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/store/themeConfig';
import { useIntervalFn } from '@vueuse/core';
import { useI18n } from 'vue-i18n';
import EnumValue from './common/Enum';
import { I18nEnum } from './common/commonEnum';
import { saveThemeConfig } from './common/utils/storage';
const Setings = defineAsyncComponent(() => import('@/layout/navBars/breadcrumb/setings.vue'));
const route = useRoute();
const themeConfigStores = useThemeConfig();
const { themeConfig } = storeToRefs(themeConfigStores);
// 定义变量内容
const { locale, t } = useI18n();
// 页面加载时
onMounted(() => {
nextTick(() => {
// 初始化系统主题
themeConfigStores.initThemeConfig();
});
});
// 监听 themeConfig isWartermark配置文件的变化
watch(
() => themeConfig.value.isWatermark,
(val) => {
if (val) {
setTimeout(() => {
setWatermarkContent();
refreshWatermarkTime();
resume();
}, 500);
} else {
pause();
}
}
);
watch(
() => themeConfig.value.globalI18n,
(val) => {
locale.value = val;
}
);
watch(
themeConfig,
(val) => {
saveThemeConfig(val);
},
{ deep: true }
);
// 获取全局组件大小
const getGlobalComponentSize = computed(() => {
return themeConfig.value.globalComponentSize;
});
// 获取全局 i18n
const getGlobalI18n = computed(() => {
return EnumValue.getEnumByValue(I18nEnum, locale.value)?.extra.el;
});
// 刷新水印时间
const { pause, resume } = useIntervalFn(() => {
if (!themeConfig.value.isWatermark) {
pause();
}
refreshWatermarkTime();
}, 60000);
const setWatermarkContent = () => {
themeConfigStores.setWatermarkUser();
};
/**
* 刷新水印时间
*/
const refreshWatermarkTime = () => {
themeConfigStores.setWatermarkNowTime();
};
// 监听路由的变化,设置网站标题
watch(
() => route.path,
() => {
nextTick(() => {
document.title = `${t((route.meta.title as string) || '')} - ${themeConfig.value.globalTitle}` || themeConfig.value.globalTitle;
});
}
);
</script>

View File

@@ -0,0 +1 @@
<svg t="1756305127175" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22356" width="48" height="48"><path d="M959.718832 123.963683C872.444401 50.185297 704.593576 0.299912 511.850044 0.299912S151.255687 50.185297 63.981255 123.963683C23.193205 158.453578 0 198.04198 0 240.22962v543.840672c0 132.461193 229.132871 239.929708 511.850044 239.929708s511.850044-107.468515 511.850044-239.929708v-543.840672c0-42.18764-23.193205-81.776042-63.981256-116.265937zM87.774285 189.64444c19.794201-21.893586 50.685151-43.087377 89.373816-61.182075 42.287611-19.794201 92.073025-35.489603 147.956653-46.586352C384.087474 70.17944 446.869081 64.281168 511.850044 64.281168s127.76257 5.898272 186.745289 17.594845c55.883628 11.096749 105.669042 26.792151 147.956654 46.586352 38.688665 18.094699 69.579615 39.28849 89.373816 61.182075 15.795372 17.494875 23.793029 34.489896 23.793029 50.48521 0 16.095285-7.997657 33.090306-23.793029 50.485209-19.794201 21.893586-50.685151 43.087377-89.373816 61.182075-42.287611 19.894172-92.073025 35.489603-147.956654 46.586352-58.98272 11.696573-121.864298 17.594845-186.745289 17.594845s-127.76257-5.898272-186.74529-17.594845c-55.883628-11.096749-105.669042-26.792151-147.956653-46.586352-38.688665-18.094699-69.579615-39.28849-89.373816-61.182075C71.978912 273.319926 63.981255 256.324905 63.981255 240.22962s7.997657-33.090306 23.79303-50.58518zM63.981255 356.495558c87.274431 73.778385 255.125256 123.66377 447.868789 123.66377s360.594357-49.885385 447.868788-123.66377v155.254515c0 16.095285-7.997657 33.090306-23.793029 50.48521-19.794201 21.893586-50.685151 43.087377-89.373816 61.182075-42.287611 19.794201-92.073025 35.489603-147.956654 46.586352-58.98272 11.696573-121.864298 17.594845-186.745289 17.594845s-127.76257-5.898272-186.74529-17.594845c-55.883628-11.096749-105.669042-26.792151-147.956653-46.586352-38.688665-18.094699-69.579615-39.28849-89.373816-61.182075C71.978912 544.740408 63.981255 527.745387 63.981255 511.750073V356.495558z m895.737577 427.574734c0 16.095285-7.997657 33.090306-23.793029 50.485209-19.794201 21.893586-50.685151 43.087377-89.373816 61.182076-42.287611 19.894172-92.073025 35.489603-147.956654 46.586352-58.98272 11.696573-121.864298 17.594845-186.745289 17.594845s-127.76257-5.898272-186.74529-17.594845c-55.883628-11.096749-105.669042-26.792151-147.956653-46.586352-38.688665-18.094699-69.579615-39.28849-89.373816-61.182076C71.978912 817.160597 63.981255 800.165576 63.981255 784.070292V627.91604c87.274431 73.778385 255.125256 123.66377 447.868789 123.663771s360.594357-49.885385 447.868788-123.663771v156.154252z" p-id="22357"></path><path d="M167.950796 519.847701m-39.988285 0a39.988285 39.988285 0 1 0 79.976569 0 39.988285 39.988285 0 1 0-79.976569 0Z" p-id="22358"></path><path d="M167.950796 791.768037m-39.988285 0a39.988285 39.988285 0 1 0 79.976569 0 39.988285 39.988285 0 1 0-79.976569 0Z" p-id="22359"></path></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

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 t="1756305474315" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24277" width="48" height="48"><path d="M960 0H0v1024h1024V0.146286h-64V0z m-640 960.146286h-256v-192h256v192z m0-256.146286h-256V512.146286h256v191.853714z m320 256.146286h-256v-192h256v192z m0-256.146286h-256V512.146286h256v191.853714z m320 256.146286h-256v-192h256v192z m0-256.146286h-256V512.146286h256v191.853714z m0-256h-256V256.146286H640v192h-256V256.146286h-64v192h-256V256.146286h896v191.853714z" p-id="24278"></path></svg>

After

Width:  |  Height:  |  Size: 547 B

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 t="1756107672203" class="icon" viewBox="0 0 1472 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5144" width="48" height="48"><path d="M1449.66628 358.737a233.848 233.848 0 0 0-166.348-35.445 268.717 268.717 0 0 0-108.127-152.273l-31.158-20.026-22.265 30.455a258.736 258.736 0 0 0-22.01 265.39 177.353 177.353 0 0 1-74.28 21.241h-24.953V309.536H830.08228V0H624.44928v154.768H287.27328v154.704H118.68528V468.08H8.44728L3.26528 504.42a493.032 493.032 0 0 0 95.97 353.3c90.149 110.11 234.232 165.964 428.284 165.964a749.848 749.848 0 0 0 585.42-255.025 804.871 804.871 0 0 0 139.86-226.874c187.718-3.391 213.246-134.359 214.27-139.99l4.863-27.447-22.01-15.61z m-766.291-49.84v-92.068h87.717v92.068h-87.717z m-337.176 154.64v-92.068h87.59v92.068h-87.59z m168.588 0v-92.068h87.589v92.068h-87.589z m168.588 0v-92.068h87.717v92.068h-87.717z m170.38-92.068h87.524v92.068h-87.525v-92.068zM683.37428 62.125h87.717v92.003h-87.717V62.125zM514.78728 216.829h87.589v92.068h-87.525v-92.068z m-168.588 0h87.59v92.068h-87.59v-92.068zM177.61228 371.47h87.525v92.068H177.61228v-92.068zM527.19928 938.4a609.348 609.348 0 0 1-235-40.564 399.493 399.493 0 0 0 151.058-66.092 44.018 44.018 0 0 0 7.87-57.582 39.54 39.54 0 0 0-54.575-11.9 375.18 375.18 0 0 1-215.998 62.508 262.639 262.639 0 0 1-19.194-21.433 392.455 392.455 0 0 1-79.591-249.523h943.9a250.035 250.035 0 0 0 155.216-62.06l4.99-4.671a682.157 682.157 0 0 1-658.42 451.636z m699.432-482.412l-25.144-1.215-15.163-21.178a186.566 186.566 0 0 1-21.626-161.358 145.619 145.619 0 0 1 42.483 100.769l-1.663 60.525 54.83-18.682a205.505 205.505 0 0 1 111.07-1.664 170.123 170.123 0 0 1-144.787 42.803zM544.41028 629.31a69.738 69.738 0 1 1-66.412 69.674 68.139 68.139 0 0 1 66.412-69.674z m0 85.413a15.74 15.74 0 1 0-14.971-15.675 15.291 15.291 0 0 0 14.97 15.675z m0 0" p-id="5145"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 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="1756286353957" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19008" width="48" height="48"><path d="M853.333333 554.666667a128 128 0 0 1 128 128v170.666666a128 128 0 0 1-128 128H170.666667a128 128 0 0 1-128-128v-170.666666a128 128 0 0 1 128-128h682.666666z m0 85.333333H170.666667a42.666667 42.666667 0 0 0-42.368 37.674667L128 682.666667v170.666666a42.666667 42.666667 0 0 0 37.674667 42.368L170.666667 896h682.666666a42.666667 42.666667 0 0 0 42.368-37.674667L896 853.333333v-170.666666a42.666667 42.666667 0 0 0-42.666667-42.666667zM256 725.333333a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334zM853.333333 42.666667a128 128 0 0 1 128 128v170.666666a128 128 0 0 1-128 128H170.666667a128 128 0 0 1-128-128V170.666667a128 128 0 0 1 128-128h682.666666z m0 85.333333H170.666667a42.666667 42.666667 0 0 0-42.368 37.674667L128 170.666667v170.666666a42.666667 42.666667 0 0 0 37.674667 42.368L170.666667 384h682.666666a42.666667 42.666667 0 0 0 42.368-37.674667L896 341.333333V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667zM256 213.333333a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z" p-id="19009"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

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 t="1756389060526" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29147" width="48" height="48"><path d="M465.454545 9.402182c245.697939 0 439.575273 86.171152 452.732122 198.376727l0.496485 5.523394h0.682666v281.506909H853.333333V348.470303c-76.551758 58.585212-212.805818 97.683394-372.79806 100.010667l-15.080728 0.093091c-161.450667 0-300.280242-37.360485-380.524606-94.642425L77.575758 348.470303v165.763879c0 76.986182 155.896242 152.979394 387.878787 152.979394 76.582788 0 144.880485-8.285091 202.007273-22.155637-5.988848 28.547879-7.757576 52.844606-5.337212 72.983273-59.143758 12.939636-125.703758 20.138667-196.670061 20.138667-161.450667 0-300.280242-37.329455-380.524606-94.642424l-7.354181-5.461334v152.51394c0 76.986182 155.896242 153.010424 387.878787 153.010424 90.08097 0 168.680727-11.450182 231.113697-29.975273l18.40097 67.273697a764.89697 764.89697 0 0 1-108.637091 23.738182 974.382545 974.382545 0 0 1-140.877576 9.929697c-250.600727 0-447.674182-89.677576-453.756121-205.017212l-0.155151-5.523394V213.302303h0.682666C19.549091 98.428121 215.722667 9.433212 465.454545 9.433212z m406.279758 772.964848c14.987636 0 27.151515 12.194909 27.151515 27.182546l-0.093091 89.832727a27.120485 27.120485 0 0 1 10.860606-11.29503c18.680242-10.550303 32.768-29.882182 40.494546-56.475152a27.151515 27.151515 0 1 1 52.130909 15.142788c-11.636364 40.029091-34.443636 70.873212-65.939394 88.622546a27.151515 27.151515 0 0 1-37.484606-11.17091v49.369213a27.151515 27.151515 0 0 1-54.30303 0V809.580606c0-14.987636 12.194909-27.151515 27.182545-27.151515z m-18.990545-223.976727a27.61697 27.61697 0 0 1 38.198303 0.310303c11.977697 11.977697 29.882182 32.271515 48.562424 57.406061 30.68897 41.270303 53.651394 82.97503 64.54303 123.531636a27.182545 27.182545 0 0 1-52.565333 13.746424c-11.977697-44.466424-43.132121-92.532364-79.80994-135.136969-48.221091 55.978667-84.557576 117.76-84.557575 167.99806 0 44.838788 15.825455 81.702788 41.084121 98.862546l6.826667 6.454303a27.151515 27.151515 0 0 1-37.298425 38.508606c-41.022061-27.803152-64.915394-81.671758-64.915394-143.825455 0-47.445333 21.969455-99.265939 58.523152-152.576a559.166061 559.166061 0 0 1 61.44-75.279515zM465.454545 80.244364C237.878303 80.306424 83.905939 153.475879 78.134303 229.003636 83.968 304.407273 237.878303 377.607758 465.454545 377.607758S847.003152 304.407273 852.774788 228.941576C846.941091 153.475879 693.030788 80.244364 465.454545 80.244364z" p-id="29148"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 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 t="1756388835244" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25729" width="48" height="48"><path d="M1023.786667 611.84c-0.426667 9.770667-13.354667 20.693333-39.893334 34.56-54.613333 28.458667-337.749333 144.896-397.994666 176.298667-60.288 31.402667-93.738667 31.104-141.354667 8.32-47.616-22.741333-348.842667-144.469333-403.114667-170.368-27.093333-12.970667-40.917333-23.893333-41.386666-34.218667v103.509333c0 10.325333 14.250667 21.290667 41.386666 34.261334 54.272 25.941333 355.541333 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.362667 60.245333-31.402667 343.338667-147.797333 397.994666-176.298667 27.776-14.464 40.106667-25.728 40.106667-35.925333v-102.058667l-0.213333-0.085333z m0-168.746667c-0.512 9.770667-13.397333 20.650667-39.893334 34.517334-54.613333 28.458667-337.749333 144.896-397.994666 176.298666-60.288 31.402667-93.738667 31.104-141.354667 8.362667-47.616-22.741333-348.842667-144.469333-403.114667-170.410667-27.093333-12.928-40.917333-23.893333-41.386666-34.176v103.509334c0 10.325333 14.250667 21.248 41.386666 34.218666 54.272 25.941333 355.498667 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.32 60.245333-31.402667 343.338667-147.84 397.994666-176.298666 27.776-14.506667 40.106667-25.770667 40.106667-35.968v-102.058667l-0.256-0.042667z m0-175.018666c0.469333-10.410667-13.141333-19.541333-40.533334-29.610667-53.248-19.498667-334.634667-131.498667-388.522666-151.253333-53.888-19.712-75.818667-18.901333-139.093334 3.84C392.234667 113.706667 92.629333 231.253333 39.338667 252.074667c-26.666667 10.496-39.68 20.181333-39.253334 30.506666V386.133333c0 10.325333 14.250667 21.248 41.386667 34.218667 54.272 25.941333 355.498667 147.669333 403.114667 170.410667 47.616 22.741333 81.066667 23.04 141.354666-8.362667 60.245333-31.402667 343.338667-147.84 397.994667-176.298667 27.776-14.506667 40.106667-25.770667 40.106667-35.968V268.074667h-0.341334zM366.677333 366.08l237.269334-36.437333-71.68 105.088-165.546667-68.650667z m524.8-94.634667l-140.330666 55.466667-15.232 5.973333-140.245334-55.466666 155.392-61.44 140.373334 55.466666z m-411.989333-101.674666l-22.954667-42.325334 71.594667 27.989334 67.498667-22.101334-18.261334 43.733334 68.778667 25.770666-88.704 9.216-19.882667 47.786667-32.085333-53.290667-102.4-9.216 76.416-27.562666z m-176.768 59.733333c70.058667 0 126.805333 21.973333 126.805333 49.109333s-56.746667 49.152-126.805333 49.152-126.848-22.058667-126.848-49.152c0-27.136 56.789333-49.152 126.848-49.152z" p-id="25730"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1621859009605" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="9709" xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="200">
<defs><style type="text/css"></style></defs>
<path d="M820.203922 812.172549H684.67451v-45.176471h112.439215V279.090196H633.47451l-85.333334 277.082353c-3.011765 10.039216-12.047059 16.062745-22.086274 16.062745-10.039216 0-19.07451-7.027451-21.082353-17.066667l-71.278431-280.094117h-180.705883V762.980392h120.470589v45.176471H229.898039c-12.047059 0-22.086275-10.039216-22.086274-22.086275V252.988235c0-12.047059 10.039216-22.086275 22.086274-22.086274H451.764706c10.039216 0 19.07451 7.027451 22.086274 17.066666l55.215687 218.854902L595.32549 250.980392c3.011765-9.035294 12.047059-16.062745 21.082353-16.062745h202.792157c12.047059 0 22.086275 10.039216 22.086275 22.086275v533.082353c1.003922 12.047059-9.035294 22.086275-21.082353 22.086274z m0 0" fill="#e25813" p-id="9710" stroke-width="30" stroke="#e25813"></path>
<path d="M731.858824 425.662745c4.015686-12.047059-2.007843-25.098039-14.054902-29.113725-12.047059-4.015686-25.098039 2.007843-29.113726 14.054902L563.2 766.996078h-73.286275L371.45098 410.603922c-4.015686-12.047059-17.066667-18.070588-28.109804-14.054902-12.047059 4.015686-18.070588 17.066667-14.054901 28.109804l123.482352 371.45098c3.011765 9.035294 12.047059 15.058824 21.082353 15.058823h72.282353l-53.207843 160.627451 46.180392 2.007844 192.752942-548.141177z" fill="#2c2c2c" p-id="9711" stroke-width="30" stroke="#2c2c2c"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

126
frontend/src/common/Api.ts Normal file
View File

@@ -0,0 +1,126 @@
import request from './request';
import { RequestOptions, useApiFetch } from '@/hooks/useRequest';
/**
* 可用于各模块定义各自api请求
*/
class Api {
/**
* 请求url
*/
url: string;
/**
* 请求方法
*/
method: string;
/**
* 请求前处理函数
* param1: param请求参数
*/
beforeHandler: Function;
constructor(url: string, method: string) {
this.url = url;
this.method = method;
}
/**
* 设置请求前处理回调函数
* @param func 请求前处理器
* @returns this
*/
withBeforeHandler(func: Function) {
this.beforeHandler = func;
return this;
}
/**
* 获取权限的完整url
*/
getUrl() {
return request.getApiUrl(this.url);
}
/**
* 响应式使用该api
* @param params 响应式params
* @param reqOptions 其他可选值
* @returns
*/
useApi<T>(params: any = null, reqOptions?: RequestOptions) {
return useApiFetch<T>(this, params, reqOptions);
}
/**
* fetch 请求对应的该api
* @param {Object} param 请求该api的参数
*/
async request(param: any = null, options: any = {}): Promise<any> {
const { execute, data } = this.useApi(param, options);
const res = await execute();
return data.value || res;
}
/**
* xhr 请求对应的该api
* @param {Object} param 请求该api的参数
*/
async xhrReq(param: any = null, options: any = {}): Promise<any> {
if (this.beforeHandler) {
await this.beforeHandler(param);
}
return request.xhrReq(this.method, this.url, param, options);
}
/** 静态方法 **/
/**
* 静态工厂返回Api对象并设置url与method属性
* @param url url
* @param method 请求方法(get,post,put,delete...)
*/
static create(url: string, method: string): Api {
return new Api(url, method);
}
/**
* 创建get api
* @param url url
*/
static newGet(url: string): Api {
return Api.create(url, 'get');
}
/**
* new post api
* @param url url
*/
static newPost(url: string): Api {
return Api.create(url, 'post');
}
/**
* new put api
* @param url url
*/
static newPut(url: string): Api {
return Api.create(url, 'put');
}
/**
* new delete api
* @param url url
*/
static newDelete(url: string): Api {
return Api.create(url, 'delete');
}
}
export default Api;
export class PageRes {
list: any[] = [];
total: number = 0;
}

102
frontend/src/common/Enum.ts Normal file
View File

@@ -0,0 +1,102 @@
export interface EnumValueTag {
color?: string;
type?: string;
}
/**
* 枚举值
*/
export class EnumValue {
/**
* 枚举值
*/
value: any;
/**
* 枚举描述
*/
label: string;
/**
* 展示的标签信息
*/
tag: EnumValueTag;
extra: any;
constructor(value: any, label: string) {
this.value = value;
this.label = label;
}
setTagType(type: string = 'primary'): EnumValue {
this.tag = { type };
return this;
}
tagTypeInfo(): EnumValue {
return this.setTagType('info');
}
tagTypeSuccess(): EnumValue {
return this.setTagType('success');
}
tagTypeDanger(): EnumValue {
return this.setTagType('danger');
}
tagTypeWarning(): EnumValue {
return this.setTagType('warning');
}
setTagColor(color: string): EnumValue {
this.tag = { color };
return this;
}
setExtra(extra: any): EnumValue {
this.extra = extra;
return this;
}
public static of(value: any, label: string): EnumValue {
return new EnumValue(value, label);
}
/**
* 根据枚举值获取指定枚举值对象
*
* @param enums 枚举对象
* @param value 需要匹配的枚举值
* @returns 枚举值对象
*/
static getEnumByValue(enums: any, value: any): EnumValue | null {
const enumValues = Object.values(enums) as any;
for (let enumValue of enumValues) {
if (enumValue.value == value) {
return enumValue;
}
}
return null;
}
/**
* 根据枚举值获取枚举描述
*
* @param enums 枚举对象
* @param value 枚举值
* @returns 枚举描述
*/
static getLabelByValue(enums: any, value: any) {
const enumValues = Object.values(enums) as any;
for (let enumValue of enumValues) {
if (enumValue['value'] == value) {
return enumValue['label'];
}
}
return '';
}
}
export default EnumValue;

View File

@@ -0,0 +1,96 @@
import { i18n } from '@/i18n';
import { ElMessage } from 'element-plus';
/**
* 不符合业务断言错误
*/
class AssertError extends Error {
constructor(message: string) {
ElMessage.error(message);
super(message);
// 错误类名
this.name = 'AssertError';
}
}
/**
* 断言表达式为true
*
* @param condition 条件表达式
* @param msgOrI18nKey 错误消息 或者 i18n key
*/
export function isTrue(condition: boolean, msgOrI18nKey: string) {
if (!condition) {
throw new AssertError(i18n.global.t(msgOrI18nKey));
}
}
/**
* 断言不能为空值即null,0,''等
*
* @param obj 对象1
* @param msg 错误消息
*/
export function notBlank(obj: any, msg: string) {
if (obj == null || obj == undefined || obj == '') {
throw new AssertError(msg);
}
if (Array.isArray(obj) && obj.length == 0) {
throw new AssertError(msg);
}
}
/**
* 断言不能为空值即null,0,''等
*
* @param obj 对象
* @param field 字段支持i18n msgKey
*/
export function notBlankI18n(obj: any, field: string) {
notBlank(obj, i18n.global.t('common.fieldNotEmpty', { field: i18n.global.t(field) }));
}
/**
* 断言两对象相等
*
* @param obj1 对象1
* @param obj2 对象2
* @param msg 错误消息
*/
export function isEquals(obj1: any, obj2: any, msg: string) {
isTrue(obj1 === obj2, msg);
}
/**
* 断言对象不为null或undefiend
*
* @param obj 对象
* @param msg 错误提示
*/
export function notNull(obj: any, msg: string) {
if (obj == null || obj == undefined) {
throw new AssertError(msg);
}
}
/**
* 断言字符串不能为空
*
* @param str 字符串
* @param msg 错误提示
*/
export function notEmpty(str: string, msg: string) {
if (str == null || str == undefined || str == '') {
throw new AssertError(msg);
}
}
/**
* 断言字符串不能为空
*
* @param str 字符串
* @param field 字段支持i18n msgKey
*/
export function notEmptyI18n(str: string, field: string) {
notEmpty(str, i18n.global.t('common.fieldNotEmpty', { field: i18n.global.t(field) }));
}

View File

@@ -0,0 +1,79 @@
import EnumValue from './Enum';
// element plus 自带国际化
import zhcnLocale from 'element-plus/es/locale/lang/zh-cn';
import enLocale from 'element-plus/es/locale/lang/en';
// i18n
export const I18nEnum = {
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 LinkTypeEnum = {
Iframes: EnumValue.of(1, 'ifrmaes'),
Link: EnumValue.of(2, 'link'),
};
// 资源类型
export const ResourceTypeEnum = {
Machine: EnumValue.of(1, 'tag.machine').setExtra({ icon: 'icon machine/machine', iconColor: 'var(--el-color-primary)' }).tagTypeSuccess(),
Db: EnumValue.of(2, 'tag.db').setExtra({ icon: 'icon db/db', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
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, 'ac.ac').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }),
Es: EnumValue.of(6, 'tag.es').setExtra({ icon: 'icon es/es-color', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(),
Container: EnumValue.of(7, 'tag.container').setExtra({ icon: 'icon docker/docker', iconColor: 'var(--el-color-primary)' }),
};
// 标签关联的资源类型
export const TagResourceTypeEnum = {
PublicAuthCert: EnumValue.of(-2, '公共凭证').setExtra({ icon: 'Ticket' }),
Tag: EnumValue.of(-1, '标签').setExtra({ icon: 'CollectionTag' }),
Machine: ResourceTypeEnum.Machine,
DbInstance: ResourceTypeEnum.Db,
EsInstance: ResourceTypeEnum.Es,
Redis: ResourceTypeEnum.Redis,
Mongo: ResourceTypeEnum.Mongo,
AuthCert: ResourceTypeEnum.AuthCert,
Container: ResourceTypeEnum.Container,
Db: EnumValue.of(22, '数据库').setExtra({ icon: 'icon db/db' }),
};
// 标签关联的资源类型路径
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}`,
};
// 消息子类型
export const MsgSubtypeEnum = {
UserLogin: EnumValue.of('user.login', 'login.login').setExtra({
notifyType: 'primary',
}),
MachineFileUploadSuccess: EnumValue.of('machine.file.upload.success', 'machine.fileUploadSuccess').setExtra({
notifyType: 'success',
}),
MachineFileUploadFail: EnumValue.of('machine.file.upload.fail', 'machine.fileUploadFail').setExtra({
notifyType: 'danger',
}),
DbDumpFail: EnumValue.of('db.dump.fail', 'db.dbDumpFail').setExtra({
notifyType: 'danger',
}),
SqlScriptRunSuccess: EnumValue.of('db.sqlscript.run.success', 'db.sqlScriptRunSuccess').setExtra({
notifyType: 'success',
}),
SqlScriptRunFail: EnumValue.of('db.sqlscript.run.fail', 'db.sqlScriptRunFail').setExtra({
notifyType: 'danger',
}),
FlowUserTaskTodo: EnumValue.of('flow.usertask.todo', 'flow.todoTask').setExtra({
notifyType: 'primary',
}),
};

View File

@@ -1,8 +1,12 @@
function getBaseApiUrl() {
export function getBaseApiUrl() {
let path = window.location.pathname;
if (path == '/') {
return window.location.host;
}
if (path.endsWith('/')) {
// 去除最后一个/
return window.location.host + path.replace(/\/$/, '');
}
return window.location.host + path;
}
@@ -11,7 +15,7 @@ const config = {
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
// 系统版本
version: 'v1.4.2'
}
version: 'v1.10.4',
};
export default config
export default config;

View File

@@ -0,0 +1,74 @@
import CryptoJS from 'crypto-js';
import { getToken } from '@/common/utils/storage';
import openApi from './openApi';
import JSEncrypt from 'jsencrypt';
import { notBlank } from './assert';
/**
* AES 加密数据
* @param word
* @param key
*/
export function AesEncrypt(word: string, key?: string) {
if (!key) {
key = getToken().substring(0, 24);
}
const sKey = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.AES.encrypt(word, sKey, {
iv: sKey,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
export function AesDecrypt(word: string, key?: string): string {
if (!key) {
key = getToken().substring(0, 24);
}
const sKey = CryptoJS.enc.Utf8.parse(key);
// key 和 iv 使用同一个值
const decrypted = CryptoJS.AES.decrypt(word, sKey, {
iv: sKey,
mode: CryptoJS.mode.CBC, // CBC算法
padding: CryptoJS.pad.Pkcs7, //使用pkcs7 进行padding 后端需要注意
});
return decrypted.toString(CryptoJS.enc.Base64);
}
var encryptor: any = null;
export async function getRsaPublicKey() {
let publicKey = sessionStorage.getItem('RsaPublicKey');
if (publicKey) {
return publicKey;
}
publicKey = (await openApi.getPublicKey()) as string;
sessionStorage.setItem('RsaPublicKey', publicKey);
return publicKey;
}
/**
* 公钥加密指定值
*
* @param value value
* @returns 加密后的值
*/
export async function RsaEncrypt(value: any) {
// 不存在则返回空值
if (!value) {
return '';
}
if (encryptor != null && sessionStorage.getItem('RsaPublicKey') != null) {
return encryptor.encrypt(value);
}
encryptor = new JSEncrypt();
const publicKey = (await getRsaPublicKey()) as string;
notBlank(publicKey, '获取公钥失败');
encryptor.setPublicKey(publicKey); //设置公钥
return encryptor.encrypt(value);
}

View File

@@ -0,0 +1,19 @@
import request from './request';
export default {
login: (param: any) => request.post('/auth/accounts/login', param),
refreshToken: (param: any) => request.get('/auth/accounts/refreshToken', param),
otpVerify: (param: any) => request.post('/auth/accounts/otp-verify', param),
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'),
changePwd: (param: any) => request.post('/sys/accounts/change-pwd', param),
captcha: () => request.get('/sys/captcha'),
logout: () => request.post('/auth/accounts/logout'),
getPermissions: () => request.get('/sys/accounts/permissions'),
oauth2Callback: (params: any) => request.get('/auth/oauth2/callback', params),
getLdapEnabled: () => request.get('/auth/ldap/enabled'),
ldapLogin: (param: any) => request.post('/auth/ldap/login', param),
getFileDetail: (keys: string[]) => request.get(`/sys/files/detail/${keys.join(',')}`),
};

278
frontend/src/common/request.ts Executable file
View File

@@ -0,0 +1,278 @@
import router from '../router';
import config from './config';
import { getClientId, getToken } from './utils/storage';
import { templateResolve } from './utils/string';
import { ElMessage } from 'element-plus';
import axios from 'axios';
import { useApiFetch } from '../hooks/useRequest';
import Api from './Api';
export default {
request,
xhrReq,
get,
post,
put,
del,
getApiUrl,
};
export interface Result {
/**
* 响应码
*/
code: number;
/**
* 响应消息
*/
msg: string;
/**
* 数据
*/
data?: any;
}
export enum ResultEnum {
SUCCESS = 200,
ERROR = 400,
PARAM_ERROR = 405,
SERVER_ERROR = 500,
NO_PERMISSION = 501,
ACCESS_TOKEN_INVALID = 502, // accessToken失效
}
export const baseUrl: string = config.baseApiUrl;
// const baseUrl: string = 'http://localhost:18888/api';
// const baseWsUrl: string = config.baseWsUrl;
/**
* 通知错误消息
* @param msg 错误消息
*/
function notifyErrorMsg(msg: string) {
// 危险通知
ElMessage.error(msg);
}
// create an axios instance
const axiosInst = axios.create({
baseURL: baseUrl, // url = base url + request url
timeout: 60000, // request timeout
});
// request interceptor
axiosInst.interceptors.request.use(
(config: any) => {
// do something before request is sent
const token = getToken();
if (token) {
// 设置token
config.headers['Authorization'] = token;
config.headers['ClientId'] = getClientId();
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// response interceptor
axiosInst.interceptors.response.use(
(response) => response,
(e: any) => {
const rejectPromise = Promise.reject(e);
if (axios.isCancel(e)) {
console.log('请求已取消');
return rejectPromise;
}
const statusCode = e.response?.status;
if (statusCode == 500) {
notifyErrorMsg('服务器未知异常');
return rejectPromise;
}
if (statusCode == 404) {
notifyErrorMsg('请求接口未找到');
return rejectPromise;
}
if (e.message) {
// 对响应错误做点什么
if (e.message.indexOf('timeout') != -1) {
notifyErrorMsg('网络请求超时');
return rejectPromise;
}
if (e.message == 'Network Error') {
notifyErrorMsg('网络连接错误');
return rejectPromise;
}
}
notifyErrorMsg('网络请求错误');
return rejectPromise;
}
);
/**
* xhr请求url
*
* @param method 请求方法
* @param url url
* @param params 参数
* @param options 可选
* @returns
*/
export function xhrReq(method: string, url: string, params: any = null, options: any = {}) {
if (!url) {
throw new Error('请求url不能为空');
}
// 简单判断该url是否是restful风格
if (url.indexOf('{') != -1) {
url = templateResolve(url, params);
}
const req: any = {
method,
url,
...options,
};
// post和put使用json格式传参
if (method === 'post' || method === 'put') {
req.data = params;
} else {
req.params = params;
}
return axiosInst
.request(req)
.then((response) => {
// 获取请求返回结果
const result: Result = response.data;
return parseResult(result);
})
.catch((e) => {
return Promise.reject(e);
});
}
/**
* fetch请求url
*
* 该方法已处理请求结果中code != 200的message提示,如需其他错误处理(取消加载状态,重置对象状态等等),可catch继续处理
*
* @param {Object} method 请求方法(GET,POST,PUT,DELTE等)
* @param {Object} uri uri
* @param {Object} params 参数
*/
async function request(method: string, url: string, params: any = null, options: any = {}): Promise<any> {
const { execute, data } = useApiFetch(Api.create(url, method), params, options);
await execute();
return data.value;
}
/**
* get请求uri
* 该方法已处理请求结果中code != 200的message提示,如需其他错误处理(取消加载状态,重置对象状态等等),可catch继续处理
*
* @param {Object} url uri
* @param {Object} params 参数
*/
function get(url: string, params: any = null, options: any = {}): Promise<any> {
return request('get', url, params, options);
}
function post(url: string, params: any = null, options: any = {}): Promise<any> {
return request('post', url, params, options);
}
function put(url: string, params: any = null, options: any = {}): Promise<any> {
return request('put', url, params, options);
}
function del(url: string, params: any = null, options: any = {}): Promise<any> {
return request('delete', url, params, options);
}
function getApiUrl(url: string) {
// 只是返回api地址而不做请求用在上传组件之类的
return baseUrl + url + '?' + joinClientParams();
}
/**
* 创建 websocket
*/
export const createWebSocket = (url: string): Promise<WebSocket> => {
return new Promise<WebSocket>((resolve, reject) => {
const clientParam = (url.includes('?') ? '&' : '?') + joinClientParams();
const socket = new WebSocket(`${config.baseWsUrl}${url}${clientParam}`);
socket.onopen = () => {
resolve(socket);
};
socket.onerror = (e) => {
reject(e);
};
});
};
// 组装客户端参数,包括 token 和 clientId
export function joinClientParams(): string {
return `token=${getToken()}&clientId=${getClientId()}`;
}
/**
* 获取文件url地址
* @param key 文件key
* @returns 文件url
*/
export function getFileUrl(key: string) {
return `${baseUrl}/sys/files/${key}`;
}
/**
* 获取系统文件上传url
* @param key 文件key
* @returns 文件上传url
*/
export function getUploadFileUrl(key: string = '') {
return `${baseUrl}/sys/files/upload?token=${getToken()}&fileKey=${key}`;
}
/**
* 下载文件
* @param key 文件key
*/
export function downloadFile(key: string) {
const a = document.createElement('a');
a.setAttribute('href', `${getFileUrl(key)}`);
a.setAttribute('target', '_blank');
a.click();
a.remove();
}
function parseResult(result: Result) {
if (result.code === ResultEnum.SUCCESS) {
return result.data;
}
// 如果提示没有权限则移除token使其重新登录
if (result.code === ResultEnum.NO_PERMISSION) {
router.push({
path: '/401',
});
}
// 如果返回的code不为成功则会返回对应的错误msg则直接统一通知即可。忽略登录超时或没有权限的提示直接跳转至401页面
if (result.msg && result?.code != ResultEnum.NO_PERMISSION) {
notifyErrorMsg(result.msg);
}
return Promise.reject(result);
}

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,112 @@
import openApi from './openApi';
// 登录是否使用验证码配置key
const AccountLoginSecurityKey = 'AccountLoginSecurity';
const MachineConfigKey = 'MachineConfig';
const SysStyleConfigKey = 'SysStyleConfig';
/**
* 获取账号登录安全配置
*
* @returns
*/
export async function getAccountLoginSecurity(): Promise<any> {
const value = await getConfigValue(AccountLoginSecurityKey);
if (!value) {
return null;
}
const jsonValue = JSON.parse(value);
jsonValue.useCaptcha = convertBool(jsonValue.useCaptcha, true);
jsonValue.useOtp = convertBool(jsonValue.useOtp, true);
return jsonValue;
}
/**
* 获取全局系统样式配置logo、title等
*
* @returns
*/
export async function getSysStyleConfig(): Promise<any> {
const value = await getConfigValue(SysStyleConfigKey);
const defaultValue = {
useWatermark: true,
};
if (!value) {
return defaultValue;
}
const jsonValue = JSON.parse(value);
// 将字符串转为bool
jsonValue.useWatermark = convertBool(jsonValue.useWatermark, true);
return jsonValue;
}
/**
* 获取LDAP登录配置
*
* @returns
*/
export async function getLdapEnabled(): Promise<any> {
const value = await openApi.getLdapEnabled();
return convertBool(value, false);
}
/**
* 获取机器配置
*
* @returns
*/
export async function getMachineConfig(): Promise<any> {
const value = await getConfigValue(MachineConfigKey);
const defaultValue = {
// 默认1gb
uploadMaxFileSize: '1GB',
};
if (!value) {
return defaultValue;
}
try {
const jsonValue = JSON.parse(value);
return jsonValue;
} catch (e) {
return defaultValue;
}
}
/**
* 获取系统服务启动配置
*
* @returns 配置信息
*/
export async function getServerConf(): Promise<any> {
return openApi.getServerConf();
}
/**
* 获取系统配置值
*
* @param key 配置key
* @returns 配置值
*/
export async function getConfigValue(key: string): Promise<string> {
return (await openApi.getConfigValue({ key })) as string;
}
/**
* 获取bool类型系统配置值
*
* @param key 配置key
* @param defaultValue 默认值
* @returns 是否为ture1: true其他: false
*/
export async function getBoolConfigValue(key: string, defaultValue: boolean): Promise<boolean> {
const value = await getConfigValue(key);
return convertBool(value, defaultValue);
}
function convertBool(value: string, defaultValue: boolean) {
if (!value) {
return defaultValue;
}
return value == '1' || value == 'true';
}

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 async function initSysMsgs() {
await registerDbSqlExecProgress();
}
const sqlExecNotifyMap: Map<string, any> = new Map();
async function registerDbSqlExecProgress() {
await syssocket.registerMsgHandler('sqlScriptRunProgress', function (message: any) {
const content = message.params;
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: 'info',
showClose: false,
});
sqlExecNotifyMap.set(id, progress);
}
});
}

View File

@@ -0,0 +1,107 @@
import { getToken } from '@/common/utils/storage';
import { createWebSocket } from './request';
import { ElNotification } from 'element-plus';
import { MsgSubtypeEnum } from './commonEnum';
import EnumValue from './Enum';
import { h } from 'vue';
import { MessageRenderer } from '@/components/message/message';
class SysSocket {
/**
* socket连接
*/
socket: WebSocket | null = null;
/**
* key -> 消息类别value -> 消息对应的处理器函数
*/
categoryHandlers: Map<string, any> = new Map();
/**
* 初始化全局系统消息websocket
*/
async init() {
// 存在则不需要重新建立连接
if (this.socket) {
return;
}
const token = getToken();
if (!token) {
return null;
}
console.log('init system ws');
try {
this.socket = await createWebSocket('/sysmsg');
this.socket.onmessage = async (event: { data: string }) => {
let message;
try {
message = JSON.parse(event.data);
} catch (e) {
console.error('解析ws消息失败', e);
return;
}
// 存在消息类别对应的处理器,则进行处理,否则进行默认通知处理
const handler = this.categoryHandlers.get(message.category);
if (handler) {
handler(message);
return;
}
const msgSubtype = EnumValue.getEnumByValue(MsgSubtypeEnum, message.subtype);
if (!msgSubtype) {
console.log(`not found msg subtype: ${message.subtype}`);
return;
}
// 动态导入 i18n 或延迟获取 i18n 实例
let title = '';
try {
// 方式1: 动态导入
const { i18n } = await import('@/i18n');
title = i18n.global.t(msgSubtype?.label);
} catch (e) {
console.warn('i18n not ready, using default title');
}
ElNotification({
duration: 0,
title,
message: h(MessageRenderer, { content: message.msg }),
type: msgSubtype?.extra.notifyType || 'info',
});
};
} catch (e) {
console.error('open system ws error', e);
}
}
destory() {
this.socket?.close();
this.socket = null;
this.categoryHandlers?.clear();
}
/**
* 注册消息处理函数
*
* @param category 消息类别
* @param handlerFunc 消息处理函数
*/
async registerMsgHandler(category: any, handlerFunc: any) {
if (this.categoryHandlers.has(category)) {
console.log(`${category}该类别消息处理器已存在...`);
return;
}
if (typeof handlerFunc != 'function') {
throw new Error('message handler需为函数');
}
this.categoryHandlers.set(category, handlerFunc);
}
}
// 全局系统消息websocket;
const sysSocket = new SysSocket();
export default sysSocket;

View File

@@ -6,34 +6,41 @@ export function exportCsv(filename: string, columns: string[], datas: []) {
let dataValueArr: any = [];
for (let column of columns) {
let val: any = data[column];
if (typeof val == 'string' && val) {
// csv格式如果有逗号整体用双引号括起来如果里面还有双引号就替换成两个双引号这样导出来的格式就不会有问题了
if (val == null || val == undefined) {
val = '';
} else if (val && typeof val == 'string') {
// 替换换行符
val = val.replace(/[\r\n]/g, '\\n');
// csv格式如果有逗号整体用双引号括起来如果里面还有双引号就替换成两个双引号这样导出来的格式就不会有问题了
if (val.indexOf(',') != -1) {
// 如果还有双引号,先将双引号转义,避免两边加了双引号后转义错误
if (val.indexOf('"') != -1) {
val = val.replace(/\"/g, "\"\"");
val = val.replace(/"/g, '""');
}
// 再将逗号转义
val = `"${val}"`;
}
dataValueArr.push(val);
} else {
dataValueArr.push(val);
}
dataValueArr.push(String(val));
}
cvsData.push(dataValueArr);
}
const csvString = cvsData.map((e) => e.join(',')).join('\n');
exportFile(`${filename}.csv`, csvString);
}
export function exportFile(filename: string, content: string) {
// 导出
let link = document.createElement('a');
let exportContent = '\uFEFF';
let blob = new Blob([exportContent + csvString], {
type: 'text/plain;charset=utrf-8',
let blob = new Blob([exportContent + content], {
type: 'text/plain;charset=utf-8',
});
link.id = 'download-csv';
link.id = 'download-file';
link.setAttribute('href', URL.createObjectURL(blob));
link.setAttribute('download', `${filename}.csv`);
link.setAttribute('download', `${filename}`);
document.body.appendChild(link);
link.click();
}
document.body.removeChild(link); // 下载完成后移除元素
}

View File

@@ -0,0 +1,128 @@
import dayjs from 'dayjs';
/**
* 格式化日期
* @param date 日期 字符串 Date 时间戳等
* @param format 格式化格式 默认 YYYY-MM-DD HH:mm:ss
* @returns 格式化后内容
*/
export function formatDate(date: any, format: string = 'YYYY-MM-DD HH:mm:ss') {
if (!date) {
return '';
}
return dayjs(date).format(format);
}
/**
* 格式化字节单位
* @param size byte size
* @returns
*/
export function formatByteSize(size: number, fixed = 2) {
if (size === 0) {
return '0B';
}
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const base = 1024;
const exponent = Math.floor(Math.log(size) / Math.log(base));
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等
* @returns
*/
export function convertToBytes(sizeStr: string) {
sizeStr = sizeStr.trim();
const unit = sizeStr.slice(-2);
const valueStr = sizeStr.slice(0, -2);
const value = parseInt(valueStr, 10);
let bytes = 0;
switch (unit.toUpperCase()) {
case 'KB':
bytes = value * 1024;
break;
case 'MB':
bytes = value * 1024 * 1024;
break;
case 'GB':
bytes = value * 1024 * 1024 * 1024;
break;
default:
throw new Error('Invalid size unit');
}
return bytes;
}
/**
* 格式化指定时间数为人性化可阅读的内容(默认time为秒单位)
*
* @param time 时间数
* @param unit time对应的单位
* @returns
*/
export function formatTime(time: number, unit: string = 's') {
const units: any = {
y: 31536000,
M: 2592000,
d: 86400,
h: 3600,
m: 60,
s: 1,
};
if (!units[unit]) {
return 'Invalid unit';
}
let seconds = time * units[unit];
let result = '';
const timeUnits = Object.entries(units).map(([unit, duration]) => {
const value = Math.floor(seconds / (duration as any));
seconds %= duration as any;
return { value, unit };
});
timeUnits.forEach(({ value, unit }) => {
if (value > 0) {
result += `${value}${unit} `;
}
});
return result;
}
/**
* formatAxis(new Date()) // 上午好
*/
export function formatAxis(param: any) {
let hour: number = new Date(param).getHours();
if (hour < 6) return '凌晨好';
else if (hour < 9) return '早上好';
else if (hour < 12) return '上午好';
else if (hour < 14) return '中午好';
else if (hour < 17) return '下午好';
else if (hour < 19) return '傍晚好';
else if (hour < 22) return '晚上好';
else return '夜里好';
}

View File

@@ -0,0 +1,72 @@
import { nextTick } from 'vue';
import '@/theme/loading.scss';
import { useThemeConfig } from '@/store/themeConfig';
import { storeToRefs } from 'pinia';
/**
* 页面全局 Loading
* @method start 创建 loading
* @method done 移除 loading
*/
export const NextLoading = {
// 创建 loading
start: () => {
// 如果已经存在loading元素则不重复创建
if (document.querySelector('.loading-next')) {
return;
}
const bodys: Element = document.body;
const div = <HTMLElement>document.createElement('div');
div.setAttribute('class', 'loading-next');
const { themeConfig } = storeToRefs(useThemeConfig());
if (themeConfig.value.isDark) {
div.classList.add('dark');
}
const htmls = `
<div class="loading-next-box">
<div class="loading-next-box-warp">
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
<div class="loading-next-box-item"></div>
</div>
</div>
`;
div.innerHTML = htmls;
// 插入到body的第一个子元素之前避免影响布局
if (bodys.firstChild) {
bodys.insertBefore(div, bodys.firstChild);
} else {
bodys.appendChild(div);
}
},
// 移除 loading
done: (time: number = 500) => {
nextTick(() => {
setTimeout(() => {
const el = <HTMLElement>document.querySelector('.loading-next');
if (el) {
// 添加淡出效果
el.style.transition = 'opacity 0.3s ease-out';
el.style.opacity = '0';
setTimeout(() => {
el?.parentNode?.removeChild(el);
}, 300);
}
}, time);
});
},
};
export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

View File

@@ -0,0 +1,120 @@
/**
* 根据对象访问路径,获取对应的值
*
* @param obj 对象,如 {user: {name: 'xxx'}, orderNo: 1212211, products: [{id: 12}]}
* @param path 访问路径,如 orderNo 或者 user.name 或者product[0].id
* @returns 路径对应的值
*/
export function getValueByPath(obj: any, path: string) {
const keys = path.split('.');
let result = obj;
for (let key of keys) {
if (!result) {
return undefined;
}
// 如果是字符串则尝试使用json解析
if (typeof result == 'string') {
try {
result = JSON.parse(result);
} catch (e) {
console.error(e);
return undefined;
}
}
if (typeof result !== 'object') {
return undefined;
}
if (key.includes('[') && key.includes(']')) {
// 处理包含数组索引的情况
const arrayKey = key.substring(0, key.indexOf('['));
const matchIndex = key.match(/\[(.*?)\]/);
if (!matchIndex) {
return undefined;
}
const index = parseInt(matchIndex[1]);
let arrValue = result[arrayKey];
if (typeof arrValue == 'string') {
try {
arrValue = JSON.parse(arrValue);
} catch (e) {
result = undefined;
break;
}
}
result = Array.isArray(arrValue) ? arrValue[index] : undefined;
} else {
result = result[key];
}
}
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

@@ -0,0 +1,45 @@
// 字体图标 url
const cssCdnUrlList: Array<string> = [];
// 第三方 js url
const jsCdnUrlList: Array<string> = [];
// 动态批量设置字体图标
export function setCssCdn() {
if (cssCdnUrlList.length <= 0) return false;
cssCdnUrlList.map((v) => {
let link = document.createElement('link');
link.rel = 'stylesheet';
link.href = v;
link.crossOrigin = 'anonymous';
document.getElementsByTagName('head')[0].appendChild(link);
});
}
// 动态批量设置第三方js
export function setJsCdn() {
if (jsCdnUrlList.length <= 0) return false;
jsCdnUrlList.map((v) => {
let link = document.createElement('script');
link.src = v;
document.body.appendChild(link);
});
}
/**
* 批量设置字体图标、动态js
* @method cssCdn 动态批量设置字体图标
* @method jsCdn 动态批量设置第三方js
*/
const setIntroduction = {
// 设置css
cssCdn: () => {
setCssCdn();
},
// 设置js
jsCdn: () => {
setJsCdn();
},
};
// 导出函数方法
export default setIntroduction;

View File

@@ -0,0 +1,133 @@
import { randomUuid } from './string';
const TokenKey = 'm-token';
const RefreshTokenKey = 'm-refresh-token';
const UserKey = 'm-user';
const TagViewsKey = 'm-tagViews';
const ClientIdKey = 'm-clientId';
// 获取请求token
export function getToken(): string {
return getLocal(TokenKey);
}
// 保存用户访问token
export function saveToken(token: string) {
setLocal(TokenKey, token);
}
export function getRefreshToken(): string {
return getLocal(RefreshTokenKey);
}
export function saveRefreshToken(refreshToken: string) {
return setLocal(RefreshTokenKey, refreshToken);
}
// 获取登录用户基础信息
export function getUser() {
return getLocal(UserKey);
}
// 保存用户信息
export function saveUser(userinfo: any) {
setLocal(UserKey, userinfo);
}
export function saveThemeConfig(themeConfig: any) {
setLocal('themeConfig', themeConfig);
}
export function getThemeConfig() {
return getLocal('themeConfig');
}
/**
* 清除当前登录用户相关信息
*/
export function clearUser() {
removeLocal(TokenKey);
removeLocal(UserKey);
removeLocal(RefreshTokenKey);
}
export function getTagViews() {
return getSession(TagViewsKey);
}
export function setTagViews(tagViews: Array<object>) {
setSession(TagViewsKey, tagViews);
}
export function removeTagViews() {
removeSession(TagViewsKey);
}
// 获取客户端UUID
export function getClientId(): string {
let uuid = getSession(ClientIdKey);
if (uuid == null) {
uuid = randomUuid();
setSession(ClientIdKey, uuid);
}
return uuid;
}
// 1. localStorage
// 设置永久缓存
export function setLocal(key: string, val: any) {
if (typeof val == 'object') {
val = JSON.stringify(val);
}
window.localStorage.setItem(key, val);
}
// 获取永久缓存
export function getLocal(key: string) {
let val: any = window.localStorage.getItem(key);
try {
return JSON.parse(val);
} catch (e) {
return val;
}
}
// 移除永久缓存
export function removeLocal(key: string) {
window.localStorage.removeItem(key);
}
// 移除全部永久缓存
export function clearLocal() {
window.localStorage.clear();
}
// 2. sessionStorage
// 设置临时缓存
export function setSession(key: string, val: any) {
if (typeof val == 'object') {
val = JSON.stringify(val);
}
window.sessionStorage.setItem(key, val);
}
// 获取临时缓存
export function getSession(key: string) {
let val: any = window.sessionStorage.getItem(key);
try {
return JSON.parse(val);
} catch (e) {
return val;
}
}
// 移除临时缓存
export function removeSession(key: string) {
window.sessionStorage.removeItem(key);
}
// 移除全部临时缓存
export function clearSession() {
clearUser();
window.sessionStorage.clear();
}

View File

@@ -0,0 +1,231 @@
import { v1 as uuidv1 } from 'uuid';
import Clipboard from 'clipboard';
import { ElMessage } from 'element-plus';
/**
* 模板字符串解析template = 'hahaha{name}_{id}' ,param = {name: 'hh', id: 1}
* 解析后为 hahahahh_1
* @param template 模板字符串
* @param param 参数占位符
* @returns
*/
export function templateResolve(template: string, param: any) {
return template.replace(/\{\w+\}/g, (word) => {
const key = word.substring(1, word.length - 1);
let value;
// 兼容FormData类型的参数
if (param instanceof FormData) {
value = param.get(key);
} else {
value = param[key];
}
if (value != null || value != undefined) {
return value;
}
return '';
});
}
// 首字符头像
export function letterAvatar(name: string, size = 60, color = '') {
name = name || '';
size = size || 60;
var colours = [
'#1abc9c',
'#2ecc71',
'#3498db',
'#9b59b6',
'#34495e',
'#16a085',
'#27ae60',
'#2980b9',
'#8e44ad',
'#2c3e50',
'#f1c40f',
'#e67e22',
'#e74c3c',
'#00bcd4',
'#95a5a6',
'#f39c12',
'#d35400',
'#c0392b',
'#bdc3c7',
'#7f8c8d',
],
nameSplit = String(name).split(' '),
initials,
charIndex,
colourIndex,
canvas,
context,
dataURI;
if (nameSplit.length == 1) {
initials = nameSplit[0] ? nameSplit[0].charAt(0) : '?';
} else {
initials = nameSplit[0].charAt(0) + nameSplit[1].charAt(0);
}
if (window.devicePixelRatio) {
size = size * window.devicePixelRatio;
}
initials = initials.toLocaleUpperCase();
charIndex = (initials == '?' ? 72 : initials.charCodeAt(0)) - 64;
colourIndex = charIndex % 20;
canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
context = canvas.getContext('2d') as any;
context.fillStyle = color ? color : colours[colourIndex - 1];
context.fillRect(0, 0, canvas.width, canvas.height);
context.font = Math.round(canvas.width / 2) + "px 'Microsoft Yahei'";
context.textAlign = 'center';
context.fillStyle = '#FFF';
context.fillText(initials, size / 2, size / 1.5);
dataURI = canvas.toDataURL();
canvas = null;
return dataURI;
}
/**
* 计算文本所占用的宽度px -> 该种方式较为准确
* 使用span标签包裹内容然后计算span的宽度 width px
* @param str
*/
export function getTextWidth(str: string) {
let width = 0;
let html = document.createElement('span');
html.innerText = str;
html.className = 'getTextWidth';
document?.querySelector('body')?.appendChild(html);
width = (document?.querySelector('.getTextWidth') as any).offsetWidth;
document?.querySelector('.getTextWidth')?.remove();
return width;
}
/**
*
* @returns uuid
*/
export function randomUuid() {
return uuidv1();
}
/**
* 拷贝文本至剪贴板
* @param txt 需要拷贝到剪贴板的文本
* @param selector click事件对应的元素selector默认为 #copyValue
* @returns
*/
export async function copyToClipboard(txt: string, selector: string = '#copyValue') {
// navigator clipboard 需要https等安全上下文
if (navigator.clipboard && window.isSecureContext) {
// navigator clipboard 向剪贴板写文本
try {
// 拷贝单元格数据
await navigator.clipboard.writeText(txt);
ElMessage.success('复制成功');
} catch (e: any) {
ElMessage.error('复制失败');
}
return;
}
let clipboard = new Clipboard(selector, {
text: function () {
return txt;
},
});
clipboard.on('success', () => {
ElMessage.success('复制成功');
// 释放内存
clipboard.destroy();
});
clipboard.on('error', () => {
// 不支持复制
ElMessage.error('该浏览器不支持自动复制');
// 释放内存
clipboard.destroy();
});
}
export function fuzzyMatchField(keyword: string, fields: any[], ...valueExtractFuncs: Function[]) {
keyword = keyword?.toLowerCase();
return fields.filter((field) => {
for (let valueExtractFunc of valueExtractFuncs) {
const value = valueExtractFunc(field)?.toLowerCase();
if (isPrefixSubsequence(keyword, value)) {
return true;
}
}
return false;
});
}
/**
* 匹配是否为前缀子序列 targetTemplate=username prefix=uname -> trueprefix=uname2 -> false
* @param prefix 字符串前缀(不连续也可以,但不改变字符的相对顺序)
* @param targetTemplate 目标模板
* @returns 是否匹配
*/
export function isPrefixSubsequence(prefix: string, targetTemplate: string) {
let i = 0; // 指向prefix的索引
let j = 0; // 指向targetTemplate的索引
while (i < prefix.length && j < targetTemplate.length) {
if (prefix[i] === targetTemplate[j]) {
// 字符匹配,两个指针都向前移动
i++;
}
j++; // 目标字符串指针始终向前移动
}
// 如果prefix的所有字符都被找到返回true
return i === prefix.length;
}
/**
* 生成随机密码
* @param length 密码长度
*/
export function randomPassword(length = 10) {
const lowerCase = 'abcdefghijklmnopqrstuvwxyz';
const upperCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';
const specialChars = '!@#$%^&*()-_=+[]{}|;:,.<>?';
// 确保每个类别至少包含一个字符
let password = [getRandomChar(lowerCase), getRandomChar(upperCase), getRandomChar(numbers), getRandomChar(specialChars)];
// 剩余字符从所有字符集中随机选择
const allChars = lowerCase + upperCase + numbers + specialChars;
for (let i = 4; i < length; i++) {
password.push(getRandomChar(allChars));
}
// 打乱数组顺序以增加随机性
shuffleArray(password);
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];
}
function shuffleArray(array: string[]) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

View File

@@ -0,0 +1,45 @@
import { nextTick } from 'vue';
import * as svg from '@element-plus/icons-vue';
import SvgIcon from '@/components/svgIcon/index.vue';
import { getLocalIcons } from '@/assets/icon/icon.js';
/**
* 导出全局注册 element plus svg 图标
* @param app vue 实例
* @description 使用https://element-plus.gitee.io/zh-CN/component/icon.html
*/
export function registElSvgIcon(app: any) {
const icons = svg as any;
for (const i in icons) {
app.component(`${icons[i].name}`, icons[i]);
}
app.component('SvgIcon', SvgIcon);
}
// 初始化获取 css 样式,获取 element plus 自带图标
const elementPlusIconfont = () => {
return new Promise((resolve, reject) => {
nextTick(() => {
const icons = svg as any;
const sheetsIconList = [];
for (const i in icons) {
sheetsIconList.push(`${icons[i].name}`);
}
if (sheetsIconList.length > 0) resolve(sheetsIconList);
else reject('未获取到值,请刷新重试');
});
});
};
// 定义导出方法集合
const initIconfont = {
ele: () => {
return elementPlusIconfont();
},
other: () => {
return getLocalIcons();
},
};
// 导出方法
export default initIconfont;

View File

@@ -0,0 +1,28 @@
import { useUserInfo } from '@/store/userInfo';
/**
* 判断当前用户是否拥有指定权限
* @param code 权限code
* @returns
*/
export function hasPerm(code: string): boolean {
if (!code) {
return true;
}
return useUserInfo().userInfo.permissions.some((v: any) => v === code);
}
/**
* 判断用户是否拥有权限对象里对应的code
* @returns {"xxx:save": true} key->permission code
* @param permCodes
*/
export function hasPerms(permCodes: any[]): Record<string, boolean> {
const res = {} as { [key: string]: boolean };
for (let permCode of permCodes) {
if (hasPerm(permCode)) {
res[permCode] = true;
}
}
return res;
}

View File

@@ -0,0 +1,59 @@
import Contextmenu from './index.vue';
class ContextmenuItem {
clickId: any;
txt: string;
icon: string;
affix: boolean;
permission: string;
/**
* 是否隐藏回调函数
*/
hideFunc: (data: any) => boolean;
onClickFunc: (data: any) => void;
constructor(clickId: any, txt: string) {
this.clickId = clickId;
this.txt = txt;
}
withIcon(icon: string) {
this.icon = icon;
return this;
}
withPermission(permission: string) {
this.permission = permission;
return this;
}
withHideFunc(func: (data: any) => boolean) {
this.hideFunc = func;
return this;
}
withOnClick(func: (data: any) => void) {
this.onClickFunc = func;
return this;
}
/**
* 是否隐藏
* @param data 点击数据项
* @returns
*/
isHide(data: any) {
if (this.hideFunc) {
return this.hideFunc(data);
}
return false;
}
}
export { Contextmenu, ContextmenuItem };

View File

@@ -0,0 +1,206 @@
<template>
<transition @enter="onEnter" name="el-zoom-in-center">
<div
:aria-hidden="state.isShow ? 'false' : 'true'"
class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
role="tooltip"
data-popper-placement="bottom"
: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">
<li
:id="v.clickId"
v-auth="v.permission"
class="el-dropdown-menu__item"
aria-disabled="false"
tabindex="-1"
:key="k"
v-if="!v.affix && !v.isHide(state.item)"
@click="onCurrentContextmenuClick(v)"
>
<SvgIcon :name="v.icon" />
<span>{{ $t(v.txt) }}</span>
</li>
</template>
</ul>
<div v-if="state.arrowLeft > 0" class="el-popper__arrow" :style="{ left: `${state.arrowLeft}px` }"></div>
</div>
</transition>
</template>
<script setup lang="ts" name="layoutTagsViewContextmenu">
import { computed, reactive, onMounted, onUnmounted, watch } from 'vue';
import { ContextmenuItem } from './index';
import SvgIcon from '@/components/svgIcon/index.vue';
import { useWindowSize } from '@vueuse/core';
// 定义父组件传过来的值
const props = defineProps({
dropdown: {
type: Object,
default: () => {
return {
x: 0,
y: 0,
};
},
},
items: {
type: Array<ContextmenuItem>,
default: () => [],
},
});
// 定义子组件向父组件传值/事件
const emit = defineEmits(['currentContextmenuClick']);
const { width: vw, height: vh } = useWindowSize();
// 定义变量内容
const state = reactive({
isShow: false,
dropdownList: [] as ContextmenuItem[],
item: {} as any,
arrowLeft: 10,
dropdown: {
x: 0,
y: 0,
},
});
// 下拉菜单宽高
let contextmenuWidth = 117;
let contextmenuHeight = 117;
// 下拉菜单元素
let ele = null as any;
const onEnter = (el: any) => {
if (ele || el.offsetHeight == 0) {
return;
}
ele = el;
contextmenuHeight = el.offsetHeight;
contextmenuWidth = el.offsetWidth;
setDropdowns(props.dropdown);
};
const setDropdowns = (dropdown: any) => {
let { x, y } = dropdown;
state.arrowLeft = 10;
// `Dropdown 下拉菜单` 的宽度
if (x + contextmenuWidth > vw.value) {
state.arrowLeft = contextmenuWidth - (vw.value - x);
x = vw.value - contextmenuWidth - 5;
}
if (y + contextmenuHeight > vh.value) {
y = vh.value - contextmenuHeight - 5;
state.arrowLeft = 0;
}
state.dropdown.x = x;
state.dropdown.y = y;
};
const allHide = computed(() => {
for (let item of state.dropdownList) {
if (!item.isHide(state.item)) {
return false;
}
}
return true;
});
// 当前项菜单点击
const onCurrentContextmenuClick = (ci: ContextmenuItem) => {
// 存在点击事件,则触发该事件函数
if (ci.onClickFunc) {
ci.onClickFunc(state.item);
}
emit('currentContextmenuClick', { id: ci.clickId, item: state.item });
};
const headerContextmenuClick = (event: any) => {
event.preventDefault(); // 阻止默认的右击菜单行为
};
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
const openContextmenu = (item: any) => {
state.item = item;
closeContextmenu();
setTimeout(() => {
state.isShow = true;
}, 10);
};
// 关闭右键菜单
const closeContextmenu = () => {
state.isShow = false;
};
// 监听页面监听进行右键菜单的关闭
onMounted(() => {
document.body.addEventListener('click', closeContextmenu);
state.dropdownList = props.items;
});
// 页面卸载时,移除右键菜单监听事件
onUnmounted(() => {
document.body.removeEventListener('click', closeContextmenu);
});
watch(
() => props.dropdown,
() => {
// 元素置为空重新在onEnter赋值元素否则会造成堆栈溢出
ele = null;
},
{
deep: true,
}
);
watch(
() => props.items,
(x: any) => {
state.dropdownList = x;
},
{
deep: true,
}
);
// 暴露变量
defineExpose({
openContextmenu,
closeContextmenu,
});
</script>
<style scoped lang="scss">
.custom-contextmenu {
transform-origin: center top;
z-index: 2190;
position: fixed;
.el-dropdown-menu__item {
padding: 5px 12px;
}
.el-dropdown-menu__item {
font-size: 12px !important;
white-space: nowrap;
i {
font-size: 12px !important;
}
}
}
</style>
.

View File

@@ -0,0 +1,298 @@
<template>
<div class="crontab">
<el-tabs v-model="state.activeName" @tab-change="changeTab(state.activeName)" type="border-card">
<el-tab-pane :label="$t('components.crontab.second')" name="second" v-if="shouldHide('second')">
<CrontabSecond :cron="crontabValueObj" ref="secondRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.minute')" name="min" v-if="shouldHide('min')">
<CrontabMin :cron="crontabValueObj" ref="minRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.hour')" name="hour" v-if="shouldHide('hour')">
<CrontabHour :cron="crontabValueObj" ref="hourRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.day')" name="day" v-if="shouldHide('day')">
<CrontabDay :cron="crontabValueObj" ref="dayRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.month')" name="mouth" v-if="shouldHide('mouth')">
<CrontabMouth :cron="crontabValueObj" ref="mouthRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.week')" name="week" v-if="shouldHide('week')">
<CrontabWeek :cron="crontabValueObj" ref="weekRef" />
</el-tab-pane>
<el-tab-pane :label="$t('components.crontab.year')" name="year" v-if="shouldHide('year')">
<CrontabYear :cron="crontabValueObj" ref="yearRef" />
</el-tab-pane>
</el-tabs>
<div class="popup-main">
<div class="popup-result">
<p class="title">{{ $t('components.crontab.timeExpression') }}</p>
<table>
<thead>
<tr>
<th v-for="item of tabTitles" width="40" :key="item">{{ item }}</th>
<th>{{ $t('components.crontab.crontabCompleteExpression') }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span>{{ crontabValueObj.second }}</span>
</td>
<td>
<span>{{ crontabValueObj.min }}</span>
</td>
<td>
<span>{{ crontabValueObj.hour }}</span>
</td>
<td>
<span>{{ crontabValueObj.day }}</span>
</td>
<td>
<span>{{ crontabValueObj.mouth }}</span>
</td>
<td>
<span>{{ crontabValueObj.week }}</span>
</td>
<td>
<span>{{ crontabValueObj.year }}</span>
</td>
<td>
<span>{{ crontabValueString }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<CrontabResult :ex="crontabValueString"></CrontabResult>
<div class="pop_btn">
<el-button size="small" @click="hidePopup">{{ $t('common.cancel') }}</el-button>
<el-button size="small" type="warning" @click="clearCron">{{ $t('common.reset') }}</el-button>
<el-button size="small" type="primary" @click="submitFill">{{ $t('common.confirm') }}</el-button>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, toRefs, onMounted, reactive, ref, nextTick, watch } from 'vue';
import CrontabSecond from './CrontabSecond.vue';
import CrontabMin from './CrontabMin.vue';
import CrontabHour from './CrontabHour.vue';
import CrontabDay from './CrontabDay.vue';
import CrontabMouth from './CrontabMouth.vue';
import CrontabWeek from './CrontabWeek.vue';
import CrontabYear from './CrontabYear.vue';
import CrontabResult from './CrontabResult.vue';
const secondRef: any = ref(null);
const minRef: any = ref(null);
const hourRef: any = ref(null);
const dayRef: any = ref(null);
const mouthRef: any = ref(null);
const weekRef: any = ref(null);
const yearRef: any = ref(null);
const props = defineProps({
expression: {
type: String,
required: true,
},
hideComponent: {
type: Array,
},
});
//定义事件
const emit = defineEmits(['hide', 'fill']);
const state = reactive({
tabTitles: ['秒', '分钟', '小时', '日', '月', '周', '年'],
tabActive: 0,
activeName: 'second',
myindex: 0,
crontabValueObj: {
second: '*',
min: '*',
hour: '*',
day: '*',
mouth: '*',
week: '?',
year: '',
},
});
const { tabTitles, crontabValueObj } = toRefs(state);
onMounted(() => {
resolveExp();
});
watch(
() => props.expression,
() => {
resolveExp();
}
);
function shouldHide(key: string) {
if (props.hideComponent && props.hideComponent.includes(key)) return false;
return true;
}
function resolveExp() {
//反解析 表达式
if (props.expression) {
let arr = props.expression.split(' ');
if (arr.length >= 6) {
//6 位以上是合法表达式
let obj = {
second: arr[0],
min: arr[1],
hour: arr[2],
day: arr[3],
mouth: arr[4],
week: arr[5],
year: arr[6] ? arr[6] : '',
};
state.crontabValueObj = {
...obj,
};
}
changeTab(state.activeName);
} else {
//没有传入的表达式 则还原
clearCron();
}
}
// 改变tab
const changeTab = (name: string) => {
nextTick(() => {
getRefByName(name).value?.parse();
});
};
const getRefByName = (name: string) => {
switch (name) {
case 'second':
return secondRef;
case 'min':
return minRef;
case 'hour':
return hourRef;
case 'day':
return dayRef;
case 'mouth':
return mouthRef;
case 'week':
return weekRef;
case 'year':
return yearRef;
}
};
// 隐藏弹窗
function hidePopup() {
emit('hide');
}
// 填充表达式
const submitFill = () => {
emit('fill', crontabValueString.value);
hidePopup();
};
const clearCron = () => {
// 还原选择项
state.crontabValueObj = {
second: '*',
min: '*',
hour: '*',
day: '*',
mouth: '*',
week: '?',
year: '',
};
changeTab(state.activeName);
};
const crontabValueString = computed(() => {
let obj = state.crontabValueObj;
let str = obj.second + ' ' + obj.min + ' ' + obj.hour + ' ' + obj.day + ' ' + obj.mouth + ' ' + obj.week + (obj.year == '' ? '' : ' ' + obj.year);
return str;
});
</script>
<style scoped lang="scss">
.pop_btn {
text-align: right;
}
.popup-main {
position: relative;
margin: 10px auto;
background: var(--el-bg-color-overlay);
border-radius: 5px;
font-size: 12px;
overflow: hidden;
}
.popup-title {
overflow: hidden;
line-height: 34px;
padding-top: 6px;
background: #f2f2f2;
}
.popup-result {
box-sizing: border-box;
line-height: 24px;
margin: 15px auto;
padding: 15px 20px 10px;
border: 1px solid var(--el-border-color);
position: relative;
}
.popup-result .title {
position: absolute;
top: -18px;
left: 50%;
width: 140px;
font-size: 14px;
margin-left: -70px;
text-align: center;
line-height: 30px;
background: var(--el-bg-color-overlay);
}
.popup-result table {
text-align: center;
width: 100%;
margin: 0 auto;
}
.popup-result table span {
display: block;
width: 100%;
font-family: arial;
line-height: 30px;
height: 30px;
white-space: nowrap;
overflow: hidden;
border: 1px solid var(--el-border-color);
}
.popup-result-scroll {
font-size: 12px;
line-height: 24px;
height: 10em;
overflow-y: auto;
}
.crontab {
::v-deep(.el-form-item) {
margin-bottom: 10px !important;
}
}
</style>

View File

@@ -0,0 +1,219 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> {{ $t('components.crontab.day') }}{{ $t('components.crontab.dayCrontype1') }} </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2"> {{ $t('components.crontab.crontype2') }} </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
{{ $t('components.crontab.crontype3') }}
<el-input-number v-model="cycle01" :min="0" :max="31" /> - <el-input-number v-model="cycle02" :min="0" :max="31" />
{{ $t('components.crontab.day') }}
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="4">
{{ $t('components.crontab.crontypeFrom') }}
<el-input-number v-model="average01" :min="0" :max="31" /> {{ $t('components.crontab.crontypeStartDay') }}
{{ $t('components.crontab.crontypeEvery') }} <el-input-number v-model="average02" :min="0" :max="31" />
{{ $t('components.crontab.crontypeExecDay') }}
</el-radio>
</el-form-item>
<!-- <el-form-item>
<el-radio v-model="radioValue" :label="5">
每月
<el-input-number v-model="workday" :min="0" :max="31" /> 号最近的那个工作日
</el-radio>
</el-form-item> -->
<el-form-item>
<el-radio v-model="radioValue" :label="6"> {{ $t('components.crontab.monthLastDay') }} </el-radio>
</el-form-item>
<el-form-item>
<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>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { computed, toRefs, watch, reactive } from 'vue';
import { checkNumber, CrontabValueObj } from './index';
const cron = defineModel<CrontabValueObj>('cron', { required: true });
const state = reactive({
radioValue: 1,
workday: 1,
cycle01: 1,
cycle02: 2,
average01: 1,
average02: 1,
checkboxList: [] as any,
});
const { radioValue, workday, cycle01, cycle02, average01, average02, checkboxList } = toRefs(state);
// 单选按钮值变化时
function radioChange() {
if (state.radioValue === 1) {
cron.value.day = '*';
cron.value.week = '?';
cron.value.mouth = '*';
} else {
if (cron.value.hour === '*') {
cron.value.hour = '0';
}
if (cron.value.min === '*') {
cron.value.min = '0';
}
if (cron.value.second === '*') {
cron.value.second = '0';
}
}
switch (state.radioValue) {
case 2:
cron.value.day = '?';
break;
case 3:
cron.value.day = state.cycle01 + '-' + state.cycle02;
break;
case 4:
cron.value.day = state.average01 + '/' + state.average02;
break;
case 5:
cron.value.day = state.workday + 'W';
break;
case 6:
cron.value.day = 'L';
break;
case 7:
cron.value.day = checkboxString.value;
break;
}
}
// 周期两个值变化时
function cycleChange() {
if (state.radioValue == 3) {
cron.value.day = cycleTotal.value;
}
}
// 平均两个值变化时
function averageChange() {
state.average01 = checkNumber(state.average01, 1, 31);
state.average02 = checkNumber(state.average02, 1, 31);
if (state.radioValue == 4) {
cron.value.day = averageTotal.value;
}
}
// 最近工作日值变化时
function workdayChange() {
state.workday = checkNumber(state.workday, 1, 31);
if (state.radioValue == 5) {
cron.value.day = state.workday + 'W';
}
}
// checkbox值变化时
function checkboxChange() {
if (state.radioValue == 7) {
cron.value.day = checkboxString.value;
}
}
// 父组件传递的week发生变化触发
// function weekChange() {
// //判断week值与day不能同时为“?”
// if (cron.value.week == '?' && state.radioValue == 2) {
// state.radioValue = 1;
// } else if (cron.value.week !== '?' && state.radioValue != 2) {
// state.radioValue = 2;
// }
// }
// 计算两个周期值
const cycleTotal = computed(() => {
return state.cycle01 + '-' + state.cycle02;
});
// 计算平均用到的值
const averageTotal = computed(() => {
return state.average01 + '/' + state.average02;
});
// 计算工作日格式
const workdayCheck = computed(() => {
return state.workday;
});
// 计算勾选的checkbox值合集
const checkboxString = computed(() => {
let str = state.checkboxList.join();
return str == '' ? '*' : str;
});
watch(
() => state.radioValue,
() => {
radioChange();
}
);
watch(cycleTotal, () => {
cycleChange();
});
watch(averageTotal, () => {
averageChange();
});
watch(workdayCheck, () => {
workdayChange();
});
watch(checkboxString, () => {
checkboxChange();
});
const parse = () => {
//反解析
let value = cron.value.day;
if (value === '*') {
state.radioValue = 1;
} else if (value == '?') {
state.radioValue = 2;
} else if (value.indexOf('-') > -1) {
state.radioValue = 3;
let indexArr = value.split('-') as any;
isNaN(indexArr[0]) ? (state.cycle01 = 0) : (state.cycle01 = indexArr[0]);
state.cycle02 = indexArr[1];
} else if (value.indexOf('/') > -1) {
state.radioValue = 4;
let indexArr = value.split('/') as any;
isNaN(indexArr[0]) ? (state.average01 = 0) : (state.average01 = indexArr[0]);
state.average02 = indexArr[1];
} else if (value.indexOf('W') > -1) {
state.radioValue = 5;
let indexArr = value.split('W') as any;
isNaN(indexArr[0]) ? (state.workday = 0) : (state.workday = indexArr[0]);
} else if (value === 'L') {
state.radioValue = 6;
} else {
state.checkboxList = value.split(',');
state.radioValue = 7;
}
};
defineExpose({ parse });
</script>

View File

@@ -0,0 +1,159 @@
<template>
<el-form size="small">
<el-form-item>
<el-radio v-model="radioValue" :label="1"> {{ $t('components.crontab.hour') }}{{ $t('components.crontab.hourCronType1') }} </el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="2">
{{ $t('components.crontab.crontype3') }}
<el-input-number v-model="cycle01" :min="0" :max="60" /> - <el-input-number v-model="cycle02" :min="0" :max="60" />
{{ $t('components.crontab.hour') }}
</el-radio>
</el-form-item>
<el-form-item>
<el-radio v-model="radioValue" :label="3">
{{ $t('components.crontab.crontypeFrom') }}
<el-input-number v-model="average01" :min="0" :max="60" /> {{ $t('components.crontab.crontypeStartHour') }}
{{ $t('components.crontab.crontypeEvery') }} <el-input-number v-model="average02" :min="0" :max="60" />
{{ $t('components.crontab.crontypeExecHour') }}
</el-radio>
</el-form-item>
<el-form-item>
<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>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { computed, toRefs, watch, reactive } from 'vue';
import { checkNumber, CrontabValueObj } from './index';
const cron = defineModel<CrontabValueObj>('cron', { required: true });
const state = reactive({
radioValue: 1,
cycle01: 0,
cycle02: 1,
average01: 0,
average02: 1,
checkboxList: [] as any,
});
const { radioValue, cycle01, cycle02, average01, average02, checkboxList } = toRefs(state);
// 单选按钮值变化时
function radioChange() {
if (state.radioValue === 1) {
cron.value.hour = '*';
cron.value.day = '*';
} else {
if (cron.value.min === '*') {
cron.value.min = '0';
}
if (cron.value.second === '*') {
cron.value.second = '0';
}
}
switch (state.radioValue) {
case 2:
cron.value.hour = state.cycle01 + '-' + state.cycle02;
break;
case 3:
cron.value.hour = state.average01 + '/' + state.average02;
break;
case 4:
cron.value.hour = checkboxString.value;
break;
}
}
// 周期两个值变化时
function cycleChange() {
state.cycle01 = checkNumber(state.cycle01, 0, 23);
state.cycle02 = checkNumber(state.cycle02, 0, 23);
if (state.radioValue == 2) {
cron.value.hour = cycleTotal.value;
}
}
// 平均两个值变化时
function averageChange() {
state.average01 = checkNumber(state.average01, 0, 23);
state.average02 = checkNumber(state.average02, 0, 23);
if (state.radioValue == 3) {
cron.value.hour = averageTotal.value;
}
}
// checkbox值变化时
function checkboxChange() {
if (state.radioValue == 4) {
cron.value.hour = checkboxString.value;
}
}
// 计算两个周期值
const cycleTotal = computed(() => {
return state.cycle01 + '-' + state.cycle02;
});
// 计算平均用到的值
const averageTotal = computed(() => {
return state.average01 + '/' + state.average02;
});
// 计算勾选的checkbox值合集
const checkboxString = computed(() => {
let str = state.checkboxList.join();
return str == '' ? '*' : str;
});
watch(
() => state.radioValue,
() => {
radioChange();
}
);
watch(cycleTotal, () => {
cycleChange();
});
watch(averageTotal, () => {
averageChange();
});
watch(checkboxString, () => {
checkboxChange();
});
const parse = () => {
//反解析
let ins = cron.value.hour;
if (ins === '*') {
state.radioValue = 1;
} else if (ins.indexOf('-') > -1) {
state.radioValue = 2;
let indexArr = ins.split('-') as any;
isNaN(indexArr[0]) ? (state.cycle01 = 0) : (state.cycle01 = indexArr[0]);
state.cycle02 = indexArr[1];
} else if (ins.indexOf('/') > -1) {
state.radioValue = 3;
let indexArr = ins.split('/') as any;
isNaN(indexArr[0]) ? (state.average01 = 0) : (state.average01 = indexArr[0]);
state.average02 = indexArr[1];
} else {
state.radioValue = 4;
state.checkboxList = ins.split(',');
}
};
defineExpose({ parse });
</script>

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