Compare commits

..

9 Commits

Author SHA1 Message Date
lijiahangmax
6d18b016c1 Merge pull request #17 from lijiahangmax/dev
📝 更新文档.
2024-05-24 11:26:13 +08:00
lijiahang
f54acf595b 📝 更新文档. 2024-05-24 11:24:37 +08:00
lijiahangmax
8acebd5ad7 Merge pull request #16 from lijiahangmax/dev
Dev
2024-05-24 11:23:04 +08:00
lijiahang
c28c12ee01 📝 修改文档. 2024-05-24 10:47:28 +08:00
lijiahang
532c4afeaa 🐛 修复资产页面时间展示错误. 2024-05-23 14:37:12 +08:00
lijiahang
c201eb301f 添加演示模式. 2024-05-23 13:56:03 +08:00
lijiahang
ca8e629e4c chrome PWA 支持. 2024-05-22 12:50:30 +08:00
lijiahang
35ee4faffc 添加预览模式. 2024-05-22 10:12:43 +08:00
lijiahang
aee2795285 🔖 升级版本. 2024-05-21 13:42:34 +08:00
75 changed files with 2292 additions and 149 deletions

View File

@@ -55,9 +55,20 @@
⭐ 体验后可以点一下 `star` 这对我很重要!
🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
[github](https://github.com/lijiahangmax/orion-visor) [gitee](https://gitee.com/lijiahangmax/orion-visor)
## 快速开始
```bash
# clone
git clone https://github.com/lijiahangmax/orion-visor
cd orion-visor
# 启动
docker compose up -d
```
## 项目文档
* [文档地址](https://lijiahangmax.github.io/orion-visor/#/)
* [docker安装](https://lijiahangmax.github.io/orion-visor/#/quickstart/docker-install)
* [普通安装](https://lijiahangmax.github.io/orion-visor/#/quickstart/install)

View File

@@ -1,7 +1,7 @@
version: '3.3'
services:
orion-visor-service:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.1
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.2
ports:
- 1081:80
environment:
@@ -13,13 +13,14 @@ services:
- REDIS_HOST=orion-visor-redis
- REDIS_PASSWORD=Data@123456
- SECRET_KEY=uQeacXV8b3isvKLK
- DEMO_MODE=false
volumes:
- /data/orion-visor-space/docker-volumes/orion-visor-service/root-orion:/root/orion
depends_on:
- orion-visor-mysql
- orion-visor-redis
orion-visor-mysql:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.1
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.2
privileged: true
ports:
- 3307:3306
@@ -33,7 +34,7 @@ services:
- /data/orion-visor-space/docker-volumes/orion-visor-mysql/var-lib-mysql-files:/var/lib/mysql-files
- /data/orion-visor-space/docker-volumes/orion-visor-mysql/etc-mysql:/etc/mysql
orion-visor-redis:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.1
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.2
privileged: true
ports:
- 6380:6379

View File

@@ -1,4 +1,8 @@
#/bin/bash
docker compose down
sh ./pull.sh
# demo 启动
if [ "$1" == "demo" ]; then
sed -i 's/DEMO_MODE=false/DEMO_MODE=true/g' docker-compose.yml
fi
docker compose up -d

View File

@@ -1,5 +1,5 @@
#/bin/bash
version=2.0.1
version=2.0.2
cp -r ../../sql ./sql
docker build -t orion-visor-mysql:${version} .
rm -rf ./sql

View File

@@ -1,5 +1,5 @@
#/bin/bash
version=2.0.1
version=2.0.2
docker build -t orion-visor-redis:${version} .
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}

View File

@@ -2,7 +2,7 @@ FROM nginx:alpine
USER root
RUN \
echo "" > /etc/apk/repositories && \
echo "http://mirrors.aliyun.com/alpine/v3.8/main" >> /etc/apk/repositories &&\
echo "http://mirrors.aliyun.com/alpine/v3.8/main" >> /etc/apk/repositories && \
echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories && \
apk update
RUN apk add openjdk8

View File

@@ -1,9 +1,9 @@
#/bin/bash
version=2.0.1
version=2.0.2
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
mv ../../orion-visor-ui/dist ./dist
docker build -t orion-visor-service:${version} .
rm -f ./orion-visor-launch.jar
rm -rf ./orion-visor-launch.jar
rm -rf ./dist
docker tag orion-visor-service:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:${version}
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:${version}

View File

@@ -55,9 +55,20 @@
⭐ 体验后可以点一下 `star` 这对我很重要!
🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
[github](https://github.com/lijiahangmax/orion-visor) [gitee](https://gitee.com/lijiahangmax/orion-visor)
## 快速开始
```bash
# clone
git clone https://github.com/lijiahangmax/orion-visor
cd orion-visor
# 启动
docker compose up -d
```
## 项目文档
* [文档地址](https://lijiahangmax.github.io/orion-visor/#/)
* [docker安装](/quickstart/docker-install)
* [普通安装](/quickstart/install)

View File

@@ -1,4 +1,4 @@
# orion-visor <small>2.0.1</small>
# orion-visor <small>2.0.2</small>
> 一款开箱即用的运维平台。

View File

@@ -14,6 +14,14 @@
* 执行 升级的 `bash` 脚本
* 进入 代码目录执行 `sh docker-upgrade.sh` 进行容器升级 `down` > `pull` > `up -d`
### v2.0.2
`2024-05-24` `release`
* 🐞 修复 资产授权密钥时间显示错误
* 🌈 添加 演示模式
* ⭐ 支持 Chrome PWA
### v2.0.1
`2024-05-21` `release`

View File

@@ -37,8 +37,6 @@ cd orion-visor
# MYSQL_ROOT_PASSWORD mysql root 密码
# REDIS_PASSWORD redis 密码
# SECRET_KEY 加密密钥
# 构建
docker compose build
```
### 启动

View File

@@ -1,11 +0,0 @@
## v2.0.2
> sql 脚本 - DDL
```sql
```
> sql 脚本 - DML
```sql
```

View File

@@ -1,4 +1,4 @@
## v2.0.1
## v2.0.3
> sql 脚本 - DDL

View File

@@ -14,7 +14,7 @@
<url>https://github.com/lijiahangmax/orion-visor</url>
<properties>
<revision>2.0.1</revision>
<revision>2.0.2</revision>
<spring.boot.version>2.7.17</spring.boot.version>
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>

View File

@@ -14,7 +14,7 @@ public interface AppConst extends OrionConst {
/**
* 同 ${orion.version} 迭代时候需要手动更改
*/
String VERSION = "2.0.1";
String VERSION = "2.0.2";
String ORION_VISOR = "orion-visor";

View File

@@ -0,0 +1,32 @@
package com.orion.visor.framework.common.constant;
/**
* bean 排序常量
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/6/29 16:09
*/
public interface BeanOrderConst {
/**
* 公共返回值包装处理器
*/
int RESPONSE_ADVICE_WRAPPER = Integer.MIN_VALUE + 1000;
/**
* 演示模式切面
*/
int DEMO_DISABLE_API_ASPECT = Integer.MIN_VALUE + 10;
/**
* 全局日志打印
*/
int LOG_PRINT_ASPECT = Integer.MIN_VALUE + 20;
/**
* 操作日志切面
*/
int OPERATOR_LOG_ASPECT = Integer.MIN_VALUE + 30;
}

View File

@@ -86,6 +86,8 @@ public enum ErrorCode implements CodeInfo {
UNSUPPOETED(915, "不支持此操作"),
DEMO_DISABLE_API(916, "演示模式不支持此功能"),
;
ErrorCode(int code, String message) {

View File

@@ -1,14 +0,0 @@
package com.orion.visor.framework.common.constant;
/**
* 拦截器排序常量
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/6/16 18:15
*/
public interface InterceptorOrderConst {
int LOG_FILTER = Integer.MIN_VALUE;
}

View File

@@ -1,14 +0,0 @@
package com.orion.visor.framework.common.constant;
/**
* 结果增强器 排序常量
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/6/29 16:09
*/
public interface ResponseAdviceOrderConst {
int WRAPPER = Integer.MIN_VALUE + 1000;
}

View File

@@ -72,7 +72,7 @@ public class OrionOperatorLogAutoConfiguration {
OperatorLogs.setSerializeFilters(serializeFilters);
OperatorLogFiller.setSerializeFilters(serializeFilters);
OperatorLogFiller.setOperatorLogConfig(operatorLogConfig);
return new OperatorLogAspect(operatorLogConfig, service, serializeFilters);
return new OperatorLogAspect(service);
}
}

View File

@@ -1,10 +1,8 @@
package com.orion.visor.framework.biz.operator.log.core.aspect;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.orion.lang.define.thread.ExecutorBuilder;
import com.orion.lang.utils.Arrays1;
import com.orion.lang.utils.Strings;
import com.orion.visor.framework.biz.operator.log.configuration.config.OperatorLogConfig;
import com.orion.visor.framework.biz.operator.log.core.annotation.IgnoreParameter;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.biz.operator.log.core.factory.OperatorTypeHolder;
@@ -13,6 +11,7 @@ import com.orion.visor.framework.biz.operator.log.core.model.OperatorType;
import com.orion.visor.framework.biz.operator.log.core.service.OperatorLogFrameworkService;
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogFiller;
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
import com.orion.visor.framework.common.constant.BeanOrderConst;
import com.orion.visor.framework.common.security.LoginUser;
import com.orion.visor.framework.common.security.SecurityHolder;
import lombok.extern.slf4j.Slf4j;
@@ -20,6 +19,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@@ -43,6 +43,7 @@ import java.util.concurrent.ExecutorService;
*/
@Aspect
@Slf4j
@Order(BeanOrderConst.OPERATOR_LOG_ASPECT)
public class OperatorLogAspect {
private static final ExecutorService LOG_SAVER = ExecutorBuilder.create()
@@ -53,21 +54,13 @@ public class OperatorLogAspect {
.useLinkedBlockingQueue()
.build();
private final OperatorLogConfig operatorLogConfig;
private final OperatorLogFrameworkService operatorLogFrameworkService;
private final SerializeFilter[] serializeFilters;
@Resource
private SecurityHolder securityHolder;
public OperatorLogAspect(OperatorLogConfig operatorLogConfig,
OperatorLogFrameworkService operatorLogFrameworkService,
SerializeFilter[] serializeFilters) {
this.operatorLogConfig = operatorLogConfig;
public OperatorLogAspect(OperatorLogFrameworkService operatorLogFrameworkService) {
this.operatorLogFrameworkService = operatorLogFrameworkService;
this.serializeFilters = serializeFilters;
}
@Around("@annotation(o)")

View File

@@ -1,7 +1,7 @@
package com.orion.visor.framework.log.configuration;
import com.orion.visor.framework.common.constant.AutoConfigureOrderConst;
import com.orion.visor.framework.common.constant.InterceptorOrderConst;
import com.orion.visor.framework.common.constant.BeanOrderConst;
import com.orion.visor.framework.log.configuration.config.LogPrinterConfig;
import com.orion.visor.framework.log.core.interceptor.LogPrinterInterceptor;
import com.orion.visor.framework.log.core.interceptor.PrettyLogPrinterInterceptor;
@@ -59,7 +59,7 @@ public class OrionLogPrinterConfiguration {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression(config.getExpression());
advisor.setAdvice(logPrinterInterceptor);
advisor.setOrder(InterceptorOrderConst.LOG_FILTER);
advisor.setOrder(BeanOrderConst.LOG_PRINT_ASPECT);
return advisor;
}

View File

@@ -27,6 +27,7 @@ public class ServerTemplate extends Template {
table.bizPackage = bizPackage;
table.enableUnitTest = true;
table.enableOperatorLog = true;
table.enableDemoApi = true;
}
/**
@@ -102,6 +103,16 @@ public class ServerTemplate extends Template {
return this;
}
/**
* 是否生成演示模式 api 注解
*
* @return this
*/
public ServerTemplate disableDemoApi() {
table.enableDemoApi = false;
return this;
}
/**
* 设置 cache
*

View File

@@ -58,6 +58,11 @@ public class Table {
*/
protected boolean enableOperatorLog;
/**
* 是否生成演示模式 api 注解
*/
protected boolean enableDemoApi;
/**
* 缓存的 key
*/

View File

@@ -6,6 +6,9 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
#end
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
#if($meta.enableDemoApi)
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
#end
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import ${package.Service}.*;
@@ -51,6 +54,9 @@ public class ${table.controllerName} {
@Resource
private ${type}Service ${typeLower}Service;
#if($meta.enableDemoApi)
@DemoDisableApi
#end
#if($meta.enableOperatorLog)
@OperatorLog(${type}OperatorType.CREATE)
#end
@@ -61,6 +67,9 @@ public class ${table.controllerName} {
return ${typeLower}Service.create${type}(request);
}
#if($meta.enableDemoApi)
@DemoDisableApi
#end
#if($meta.enableOperatorLog)
@OperatorLog(${type}OperatorType.UPDATE)
#end
@@ -105,6 +114,9 @@ public class ${table.controllerName} {
return ${typeLower}Service.get${type}Page(request);
}
#if($meta.enableDemoApi)
@DemoDisableApi
#end
#if($meta.enableOperatorLog)
@OperatorLog(${type}OperatorType.DELETE)
#end
@@ -116,6 +128,9 @@ public class ${table.controllerName} {
return ${typeLower}Service.delete${type}ById(id);
}
#if($meta.enableDemoApi)
@DemoDisableApi
#end
#if($meta.enableOperatorLog)
@OperatorLog(${type}OperatorType.DELETE)
#end

View File

@@ -126,9 +126,11 @@ public class OrionSecurityAutoConfiguration {
}
/**
* @return security holder 代理用于内部 framework 调用
* <p>
* - mybatis fill
* - operator log
* - log printer
*
* @return security holder 代理用于内部 framework 调用
*/
@Bean
public SecurityHolderDelegate securityHolder() {

View File

@@ -6,6 +6,7 @@ import com.orion.lang.utils.collect.Lists;
import com.orion.visor.framework.common.constant.AutoConfigureOrderConst;
import com.orion.visor.framework.common.constant.FilterOrderConst;
import com.orion.visor.framework.common.web.filter.FilterCreator;
import com.orion.visor.framework.web.core.aspect.DemoDisableApiAspect;
import com.orion.visor.framework.web.core.filter.TraceIdFilter;
import com.orion.visor.framework.web.core.handler.GlobalExceptionHandler;
import com.orion.visor.framework.web.core.handler.WrapperResultHandler;
@@ -139,4 +140,13 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer {
return FilterCreator.create(new TraceIdFilter(), FilterOrderConst.TRICE_ID_FILTER);
}
/**
* @return 演示模式禁用 api 切面
*/
@Bean
@ConditionalOnProperty(value = "orion.demo", havingValue = "true")
public DemoDisableApiAspect demoDisableApiAspect() {
return new DemoDisableApiAspect();
}
}

View File

@@ -0,0 +1,16 @@
package com.orion.visor.framework.web.core.annotation;
import java.lang.annotation.*;
/**
* 演示模式禁用 api
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/5/21 16:44
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DemoDisableApi {
}

View File

@@ -0,0 +1,36 @@
package com.orion.visor.framework.web.core.aspect;
import com.orion.visor.framework.common.constant.BeanOrderConst;
import com.orion.visor.framework.common.constant.ErrorCode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
/**
* 演示模式禁用 api 切面
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/5/21 16:52
*/
@Aspect
@Slf4j
@Order(BeanOrderConst.DEMO_DISABLE_API_ASPECT)
public class DemoDisableApiAspect {
public DemoDisableApiAspect() {
}
@Pointcut("@annotation(e)")
public void disableApi(DemoDisableApi e) {
}
@Before(value = "disableApi(e)", argNames = "e")
public void beforeDisableApi(DemoDisableApi e) {
throw ErrorCode.DEMO_DISABLE_API.exception();
}
}

View File

@@ -3,7 +3,7 @@ package com.orion.visor.framework.web.core.handler;
import com.orion.lang.constant.StandardContentType;
import com.orion.lang.define.wrapper.HttpWrapper;
import com.orion.lang.define.wrapper.RpcWrapper;
import com.orion.visor.framework.common.constant.ResponseAdviceOrderConst;
import com.orion.visor.framework.common.constant.BeanOrderConst;
import com.orion.visor.framework.web.core.annotation.IgnoreWrapper;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +23,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
* @version 1.0.0
* @since 2023/6/15 17:38
*/
@Order(ResponseAdviceOrderConst.WRAPPER)
@Order(BeanOrderConst.RESPONSE_ADVICE_WRAPPER)
@ControllerAdvice
public class WrapperResultHandler implements ResponseBodyAdvice<Object> {

View File

@@ -5,6 +5,12 @@
"type": "java.lang.String",
"description": "项目版本."
},
{
"name": "orion.demo",
"type": "java.lang.Boolean",
"description": "是否为演示模式.",
"defaultValue": false
},
{
"name": "orion.api.prefix",
"type": "java.lang.String",

View File

@@ -41,6 +41,8 @@ knife4j:
enable: false
orion:
# 是否为演示模式
demo: ${DEMO_MODE:false}
logging:
printer:
mode: ROW

View File

@@ -190,6 +190,8 @@ app:
orion:
# 版本
version: @revision@
# 是否为演示模式
demo: false
api:
# 公共 api 前缀
prefix: /orion-visor/api

View File

@@ -3,6 +3,7 @@ package com.orion.visor.module.asset.controller;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest;
@@ -59,6 +60,7 @@ public class HostConfigController {
return hostConfigService.getHostConfigList(hostId);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_CONFIG)
@PutMapping("/update")
@Operation(summary = "更新主机配置")
@@ -67,6 +69,7 @@ public class HostConfigController {
return hostConfigService.updateHostConfig(request);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_CONFIG_STATUS)
@PutMapping("/update-status")
@Operation(summary = "更新主机配置状态/动态初始化配置")

View File

@@ -6,6 +6,7 @@ import com.orion.visor.framework.common.validator.group.Id;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostConnectLogOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostConnectLogQueryRequest;
@@ -88,6 +89,7 @@ public class HostConnectLogController {
return hostConnectLogService.clearHostConnectLog(request);
}
@DemoDisableApi
@OperatorLog(HostConnectLogOperatorType.FORCE_OFFLINE)
@PutMapping("/force-offline")
@Operation(summary = "强制断开主机连接")

View File

@@ -5,6 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostCreateRequest;
@@ -42,6 +43,7 @@ public class HostController {
@Resource
private HostService hostService;
@DemoDisableApi
@OperatorLog(HostOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建主机")
@@ -50,6 +52,7 @@ public class HostController {
return hostService.createHost(request);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "通过 id 更新主机")
@@ -83,6 +86,7 @@ public class HostController {
return hostService.getHostPage(request);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 删除主机")

View File

@@ -3,6 +3,7 @@ package com.orion.visor.module.asset.controller;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostGroupOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostGroupRelUpdateRequest;
@@ -42,6 +43,7 @@ public class HostGroupController {
@Resource
private HostGroupService hostGroupService;
@DemoDisableApi
@OperatorLog(HostGroupOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建主机分组")
@@ -58,6 +60,7 @@ public class HostGroupController {
return hostGroupService.queryHostGroupTree();
}
@DemoDisableApi
@OperatorLog(HostGroupOperatorType.RENAME)
@PutMapping("/rename")
@Operation(summary = "修改名称")
@@ -66,6 +69,7 @@ public class HostGroupController {
return hostGroupService.updateHostGroupName(request);
}
@DemoDisableApi
@OperatorLog(HostGroupOperatorType.MOVE)
@PutMapping("/move")
@Operation(summary = "移动位置")
@@ -74,6 +78,7 @@ public class HostGroupController {
return hostGroupService.moveHostGroup(request);
}
@DemoDisableApi
@OperatorLog(HostGroupOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "删除主机分组")
@@ -91,6 +96,7 @@ public class HostGroupController {
return hostGroupService.queryHostGroupRel(groupId);
}
@DemoDisableApi
@OperatorLog(HostGroupOperatorType.UPDATE_REL)
@PutMapping("/update-rel")
@Operation(summary = "修改分组内主机")

View File

@@ -5,6 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostIdentityOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostIdentityCreateRequest;
@@ -42,6 +43,7 @@ public class HostIdentityController {
@Resource
private HostIdentityService hostIdentityService;
@DemoDisableApi
@OperatorLog(HostIdentityOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建主机身份")
@@ -50,6 +52,7 @@ public class HostIdentityController {
return hostIdentityService.createHostIdentity(request);
}
@DemoDisableApi
@OperatorLog(HostIdentityOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "通过 id 更新主机身份")
@@ -84,6 +87,7 @@ public class HostIdentityController {
return hostIdentityService.getHostIdentityPage(request);
}
@DemoDisableApi
@OperatorLog(HostIdentityOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 删除主机身份")

View File

@@ -5,6 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostKeyOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostKeyCreateRequest;
@@ -42,6 +43,7 @@ public class HostKeyController {
@Resource
private HostKeyService hostKeyService;
@DemoDisableApi
@OperatorLog(HostKeyOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建主机密钥")
@@ -50,6 +52,7 @@ public class HostKeyController {
return hostKeyService.createHostKey(request);
}
@DemoDisableApi
@OperatorLog(HostKeyOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "通过 id 更新主机密钥")
@@ -83,6 +86,7 @@ public class HostKeyController {
return hostKeyService.getHostKeyPage(request);
}
@DemoDisableApi
@OperatorLog(HostKeyOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 删除主机密钥")

View File

@@ -8,6 +8,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* 主机身份缓存
@@ -38,4 +39,16 @@ public class HostIdentityCacheDTO implements LongCacheIdModel, Serializable {
@Schema(description = "密钥id")
private Long keyId;
/**
* 资产页面展示
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 资产页面展示
*/
@Schema(description = "修改时间")
private Date updateTime;
}

View File

@@ -8,6 +8,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* 主机密钥缓存
@@ -29,4 +30,16 @@ public class HostKeyCacheDTO implements LongCacheIdModel, Serializable {
@Schema(description = "名称")
private String name;
/**
* 资产页面展示
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 资产页面展示
*/
@Schema(description = "修改时间")
private Date updateTime;
}

View File

@@ -4,10 +4,10 @@ Content-Type: application/json
Authorization: {{token}}
{
"key": "",
"valueType": "",
"extraSchema": "",
"description": ""
"keyName": "operatorLogType",
"valueType": "1",
"extraSchema": "{}",
"description": "1"
}
@@ -18,7 +18,7 @@ Authorization: {{token}}
{
"id": "",
"key": "",
"keyName": "",
"valueType": "",
"extraSchema": "",
"description": ""

View File

@@ -4,6 +4,7 @@ import com.orion.lang.define.wrapper.DataGrid;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.DictKeyOperatorType;
import com.orion.visor.module.infra.entity.request.dict.DictKeyCreateRequest;
@@ -41,6 +42,7 @@ public class DictKeyController {
@Resource
private DictKeyService dictKeyService;
@DemoDisableApi
@OperatorLog(DictKeyOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建字典配置项")
@@ -49,6 +51,7 @@ public class DictKeyController {
return dictKeyService.createDictKey(request);
}
@DemoDisableApi
@OperatorLog(DictKeyOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "更新字典配置项")
@@ -80,6 +83,7 @@ public class DictKeyController {
return true;
}
@DemoDisableApi
@OperatorLog(DictKeyOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "删除字典配置项")
@@ -89,6 +93,7 @@ public class DictKeyController {
return dictKeyService.deleteDictKeyById(id);
}
@DemoDisableApi
@OperatorLog(DictKeyOperatorType.DELETE)
@DeleteMapping("/batch-delete")
@Operation(summary = "批量删除字典配置项")

View File

@@ -6,6 +6,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.DictValueOperatorType;
import com.orion.visor.module.infra.entity.request.dict.DictValueCreateRequest;
@@ -45,6 +46,7 @@ public class DictValueController {
@Resource
private DictValueService dictValueService;
@DemoDisableApi
@OperatorLog(DictValueOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建字典配置值")
@@ -53,6 +55,7 @@ public class DictValueController {
return dictValueService.createDictValue(request);
}
@DemoDisableApi
@OperatorLog(DictValueOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "更新字典配置值")
@@ -61,6 +64,7 @@ public class DictValueController {
return dictValueService.updateDictValueById(request);
}
@DemoDisableApi
@OperatorLog(DictValueOperatorType.UPDATE)
@PutMapping("/rollback")
@Operation(summary = "回滚字典配置值")
@@ -84,6 +88,7 @@ public class DictValueController {
return dictValueService.getDictValuePage(request);
}
@DemoDisableApi
@OperatorLog(DictValueOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "删除字典配置值")
@@ -93,6 +98,7 @@ public class DictValueController {
return dictValueService.deleteDictValueById(id);
}
@DemoDisableApi
@OperatorLog(DictValueOperatorType.DELETE)
@DeleteMapping("/batch-delete")
@Operation(summary = "批量删除字典配置值")

View File

@@ -5,6 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.AuthenticationOperatorType;
import com.orion.visor.module.infra.entity.request.operator.OperatorLogQueryRequest;
@@ -57,6 +58,7 @@ public class MineController {
return mineService.updateCurrentUser(request);
}
@DemoDisableApi
@OperatorLog(AuthenticationOperatorType.UPDATE_PASSWORD)
@Operation(summary = "修改当前用户密码")
@PutMapping("/update-password")
@@ -79,6 +81,7 @@ public class MineController {
return mineService.getCurrentUserSessionList();
}
@DemoDisableApi
@PutMapping("/offline-session")
@Operation(summary = "下线当前用户会话")
public Boolean offlineCurrentUserSession(@Validated @RequestBody UserSessionOfflineRequest request) {

View File

@@ -3,6 +3,7 @@ package com.orion.visor.module.infra.controller;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.SystemMenuOperatorType;
import com.orion.visor.module.infra.entity.request.menu.SystemMenuCreateRequest;
@@ -41,6 +42,7 @@ public class SystemMenuController {
@Resource
private SystemMenuService systemMenuService;
@DemoDisableApi
@OperatorLog(SystemMenuOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建菜单")
@@ -49,6 +51,7 @@ public class SystemMenuController {
return systemMenuService.createSystemMenu(request);
}
@DemoDisableApi
@OperatorLog(SystemMenuOperatorType.UPDATE)
@PutMapping("/update")
@Operation(summary = "通过 id 更新菜单")
@@ -57,6 +60,7 @@ public class SystemMenuController {
return systemMenuService.updateSystemMenuById(request);
}
@DemoDisableApi
@OperatorLog(SystemMenuOperatorType.UPDATE_STATUS)
@PutMapping("/update-status")
@Operation(summary = "通过 id 级联更新菜单状态")
@@ -82,6 +86,7 @@ public class SystemMenuController {
return systemMenuService.getSystemMenuByIdList(request);
}
@DemoDisableApi
@OperatorLog(SystemMenuOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 级联删除菜单")

View File

@@ -5,6 +5,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.SystemRoleOperatorType;
import com.orion.visor.module.infra.entity.request.menu.SystemRoleGrantMenuRequest;
@@ -64,6 +65,7 @@ public class SystemRoleController {
return systemRoleService.updateSystemRoleById(request);
}
@DemoDisableApi
@OperatorLog(SystemRoleOperatorType.UPDATE_STATUS)
@PutMapping("/update-status")
@Operation(summary = "通过 id 更新角色状态")
@@ -105,6 +107,7 @@ public class SystemRoleController {
return systemRoleMenuService.getRoleMenuIdList(roleId);
}
@DemoDisableApi
@OperatorLog(SystemRoleOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 删除角色")

View File

@@ -6,6 +6,7 @@ import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.common.validator.group.Page;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.infra.define.operator.SystemUserOperatorType;
import com.orion.visor.module.infra.entity.request.user.*;
@@ -73,6 +74,7 @@ public class SystemUserController {
// TODO 修改头像 最后再说 可有可无的功能 要是有 http 文件需求就写
@DemoDisableApi
@OperatorLog(SystemUserOperatorType.UPDATE_STATUS)
@PutMapping("/update-status")
@Operation(summary = "修改用户状态")
@@ -95,6 +97,7 @@ public class SystemUserController {
}
}
@DemoDisableApi
@OperatorLog(SystemUserOperatorType.RESET_PASSWORD)
@PutMapping("/reset-password")
@Operation(summary = "重置用户密码")
@@ -137,6 +140,7 @@ public class SystemUserController {
return systemUserService.getSystemUserPage(request);
}
@DemoDisableApi
@OperatorLog(SystemUserOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "通过 id 删除用户")
@@ -154,6 +158,7 @@ public class SystemUserController {
return systemUserManagementService.getUserSessionList(id);
}
@DemoDisableApi
@OperatorLog(SystemUserOperatorType.OFFLINE)
@PutMapping("/session/offline")
@Operation(summary = "下线用户会话")

View File

@@ -1,4 +1,5 @@
VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion-visor/api'
VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion-visor/keep-alive'
VITE_APP_VERSION= '2.0.1'
VITE_APP_VERSION= '2.0.2'
VITE_SFTP_PREVIEW_MB= 2
VITE_DEMO_MODE= false

View File

@@ -1,4 +1,5 @@
VITE_API_BASE_URL= '/orion-visor/api'
VITE_WS_BASE_URL= '/orion-visor/keep-alive'
VITE_APP_VERSION= '2.0.1'
VITE_APP_VERSION= '2.0.2'
VITE_SFTP_PREVIEW_MB= 2
VITE_DEMO_MODE= false

View File

@@ -1,5 +1,6 @@
node_modules
.DS_Store
dist
dev-dist
dist-ssr
*.local

View File

@@ -0,0 +1,131 @@
import type { VitePWAOptions } from 'vite-plugin-pwa';
import { VitePWA } from 'vite-plugin-pwa';
import { isProductionMode } from '../utils';
/**
* 配置 pwa
*/
export default function configPwaPlugin() {
if (isProductionMode()) {
// 生产启用
return VitePWA(enabled());
} else {
// 本地禁用
return VitePWA(disabled());
}
}
// 禁用
const disabled = (): Partial<VitePWAOptions> => {
return {
disable: true,
manifest: false,
selfDestroying: true,
devOptions: {
enabled: false,
disableRuntimeConfig: true,
},
};
};
// 启用
const enabled = (): Partial<VitePWAOptions> => {
return {
manifest: {
name: 'Orion Visor Community',
short_name: 'Orion Visor',
description: '一款高颜值、现代化的智能运维&轻量堡垒机平台。',
theme_color: '#212529',
icons: [{
src: 'logo_150.png',
sizes: '150x150',
type: 'image/png',
}],
},
registerType: 'autoUpdate',
workbox: {
// 缓存相关静态资源
globPatterns: ['**/*.{js,css,html,ico,png,jpg,svg}'],
// 配置自定义运行时缓存
runtimeCaching: [
isProductionMode()
? {
urlPattern: ({ url }) => url.origin === 'https://app-api.id',
handler: 'NetworkFirst',
options: {
cacheName: 'wisbayar-api',
cacheableResponse: {
statuses: [200]
}
}
} : {
urlPattern: ({ url }) => url.origin === 'https://app-api-0.com',
handler: 'NetworkFirst',
options: {
cacheName: 'wisbayar-api',
cacheableResponse: {
statuses: [200]
}
}
},
{
urlPattern: /\.(?:png|jpg|jpeg|svg)$/,
handler: 'CacheFirst',
options: {
cacheName: 'wisbayar-images',
expiration: {
// 最多30个图
maxEntries: 30
}
}
},
{
urlPattern: /.*\.js.*/,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'wisbayar-js',
// 最多缓存30个, 超过的按照LRU原则删除
expiration: {
maxEntries: 30,
maxAgeSeconds: 7 * 24 * 60 * 60
},
cacheableResponse: {
statuses: [200]
}
}
},
{
urlPattern: /.*\.css.*/,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'wisbayar-css',
expiration: {
maxEntries: 20,
maxAgeSeconds: 7 * 24 * 60 * 60
},
cacheableResponse: {
statuses: [200]
}
}
},
{
urlPattern: /.*\.html.*/,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'wisbayar-html',
expiration: {
maxEntries: 20,
maxAgeSeconds: 7 * 24 * 60 * 60
},
cacheableResponse: {
statuses: [200]
}
}
}
]
},
devOptions: {
enabled: true,
},
};
};

View File

@@ -1,8 +1,15 @@
export default {};
/**
* 是否生成打包报告
*/
export default {};
export function isReportMode(): boolean {
return process.env.REPORT === 'true';
}
/**
* 是否为生产模式
*/
export function isProductionMode(): boolean {
return process.env.NODE_ENV === 'production';
}

View File

@@ -4,6 +4,7 @@ import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import svgLoader from 'vite-svg-loader';
import configArcoStyleImportPlugin from './plugin/arcoStyleImport';
import configPwaPlugin from './plugin/pwa';
export default defineConfig({
plugins: [
@@ -11,6 +12,7 @@ export default defineConfig({
vueJsx(),
svgLoader({ svgoConfig: {} }),
configArcoStyleImportPlugin(),
configPwaPlugin(),
],
resolve: {
alias: [

View File

@@ -19,5 +19,5 @@ export default mergeConfig(
}),
],
},
baseConfig
baseConfig,
);

View File

@@ -27,5 +27,5 @@ export default mergeConfig(
chunkSizeWarningLimit: 2000,
},
},
baseConfig
baseConfig,
);

View File

@@ -1,5 +0,0 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="/src/assets/images/logo.svg?url">
<link rel="shortcut icon" type="image/x-icon" href="/src/assets/logo.svg?url">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Orion Visor</title>
</head>

View File

@@ -1,7 +1,7 @@
{
"name": "orion-visor-ui",
"description": "Orion Visor UI",
"version": "2.0.1",
"version": "2.0.2",
"private": true,
"author": "Jiahang Li",
"license": "Apache 2.0",
@@ -103,6 +103,7 @@
"vite-plugin-compression": "^0.5.1",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-pwa": "^0.20.0",
"vite-svg-loader": "^3.6.0",
"vue-tsc": "^1.0.14"
},

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -1,17 +0,0 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs>
<style>.cls-1{fill:url(#未命名的渐变_4);}.cls-2{fill:url(#未命名的渐变_6);}</style>
<linearGradient id="未命名的渐变_4" x1="0.32" y1="15.03" x2="20.16" y2="15.03" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#23b6b6"/>
<stop offset="1" stop-color="#189c98"/>
</linearGradient>
<linearGradient id="未命名的渐变_6" x1="11.84" y1="16.97" x2="31.68" y2="16.97" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#08589b"/>
<stop offset="1" stop-color="#2167b2"/>
</linearGradient>
</defs>
<path class="cls-1"
d="M20,17.37a1.56,1.56,0,0,0-2.13-.65l-7.56,4.07A4.65,4.65,0,0,1,4,18.91H4a4.65,4.65,0,0,1,1.88-6.3L13.6,8.44a1.56,1.56,0,0,0,.64-2.1h0a1.56,1.56,0,0,0-2.13-.65l-8,4.3a7.24,7.24,0,0,0-2.94,9.82l.51.94a7.24,7.24,0,0,0,9.82,2.94l7.81-4.22a1.56,1.56,0,0,0,.65-2.1Z"/>
<path class="cls-2"
d="M12,14.63a1.56,1.56,0,0,0,2.13.65l7.56-4.07A4.65,4.65,0,0,1,28,13.09h0a4.65,4.65,0,0,1-1.88,6.3L18.4,23.56a1.56,1.56,0,0,0-.64,2.1h0a1.56,1.56,0,0,0,2.13.65l8-4.3a7.24,7.24,0,0,0,2.94-9.82l-.51-.94a7.24,7.24,0,0,0-9.82-2.94l-7.81,4.22a1.56,1.56,0,0,0-.65,2.1Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,12 +1,17 @@
<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.37754 16.9795L12.7498 9.43027C14.7163 7.41663 17.9428 7.37837 19.9564 9.34482C19.9852 9.37297 20.0137 9.40145 20.0418 9.43027L20.1221 9.51243C22.1049 11.5429 22.1049 14.7847 20.1221 16.8152L12.7498 24.3644C10.7834 26.378 7.55686 26.4163 5.54322 24.4498C5.5144 24.4217 5.48592 24.3932 5.45777 24.3644L5.37754 24.2822C3.39468 22.2518 3.39468 19.0099 5.37754 16.9795Z" fill="#12D2AC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.0479 9.43034L27.3399 16.8974C29.3674 18.9735 29.3674 22.2883 27.3399 24.3644C25.3735 26.3781 22.147 26.4163 20.1333 24.4499C20.1045 24.4217 20.076 24.3933 20.0479 24.3644L12.7558 16.8974C10.7284 14.8213 10.7284 11.5065 12.7558 9.43034C14.7223 7.4167 17.9488 7.37844 19.9624 9.34489C19.9912 9.37304 20.0197 9.40152 20.0479 9.43034Z" fill="#307AF2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1321 9.52163L23.6851 13.1599L16.3931 20.627L9.10103 13.1599L12.6541 9.52163C14.6707 7.45664 17.9794 7.4174 20.0444 9.434C20.074 9.46286 20.1032 9.49207 20.1321 9.52163Z" fill="#0057FE"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="26" height="19" fill="white" transform="translate(3.5 7)"/>
</clipPath>
</defs>
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs>
<style>.cls-1{fill:url(#未命名的渐变_4);}.cls-2{fill:url(#未命名的渐变_6);}</style>
<linearGradient id="未命名的渐变_4" x1="0.32" y1="15.03" x2="20.16" y2="15.03" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#23b6b6"/>
<stop offset="1" stop-color="#189c98"/>
</linearGradient>
<linearGradient id="未命名的渐变_6" x1="11.84" y1="16.97" x2="31.68" y2="16.97" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#08589b"/>
<stop offset="1" stop-color="#2167b2"/>
</linearGradient>
</defs>
<path class="cls-1"
d="M20,17.37a1.56,1.56,0,0,0-2.13-.65l-7.56,4.07A4.65,4.65,0,0,1,4,18.91H4a4.65,4.65,0,0,1,1.88-6.3L13.6,8.44a1.56,1.56,0,0,0,.64-2.1h0a1.56,1.56,0,0,0-2.13-.65l-8,4.3a7.24,7.24,0,0,0-2.94,9.82l.51.94a7.24,7.24,0,0,0,9.82,2.94l7.81-4.22a1.56,1.56,0,0,0,.65-2.1Z"/>
<path class="cls-2"
d="M12,14.63a1.56,1.56,0,0,0,2.13.65l7.56-4.07A4.65,4.65,0,0,1,28,13.09h0a4.65,4.65,0,0,1-1.88,6.3L18.4,23.56a1.56,1.56,0,0,0-.64,2.1h0a1.56,1.56,0,0,0,2.13.65l8-4.3a7.24,7.24,0,0,0,2.94-9.82l-.51-.94a7.24,7.24,0,0,0-9.82-2.94l-7.81,4.22a1.56,1.56,0,0,0-.65,2.1Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -8,7 +8,7 @@
<a-link target="_blank" href="https://gitee.com/lijiahangmax/orion-visor">gitee</a-link>
<a-link target="_blank" href="https://lijiahangmax.github.io/orion-visor">文档</a-link>
<a-link target="_blank" href="https://github.com/lijiahangmax/orion-visor/blob/main/LICENSE">License</a-link>
<a-link target="_blank" :href="`https://github.com/lijiahangmax/orion-visor/releases/tag/v${version}`">V{{ version }} 社区版</a-link>
<a-link target="_blank" :href="`https://github.com/lijiahangmax/orion-visor/releases/tag/v${version}`">v{{ version }} Community</a-link>
</a-space>
<span class="copyright">
Copyright<icon-copyright /> 2023 - {{ new Date().getFullYear() }} Li Jiahang, All rights reserved.

View File

@@ -7,7 +7,7 @@
<img class="left-side-logo"
alt="logo"
draggable="false"
src="@/assets/images/logo.svg?url" />
src="@/assets/logo.svg?url" />
<!-- 标头 -->
<a-typography-title :heading="5"
:style="{ margin: 0, fontSize: '18px', height: '1.4em', overflow: 'hidden' }">

View File

@@ -21,6 +21,14 @@
<block :options="dataOpts" title="数据设置" />
<!-- 页面视图 -->
<block :options="viewsOpts" title="页面视图" />
<!-- 保存为桌面程序 -->
<a-button v-if="visibleCreatePwaApp()"
class="mb16"
type="primary"
@click="createPwaApp"
long>
保存为桌面程序
</a-button>
</div>
</a-drawer>
</template>
@@ -30,6 +38,8 @@
import { useAppStore } from '@/store';
import useVisible from '@/hooks/visible';
import { CardPageSizeOptions, TablePageSizeOptions } from '@/types/const';
import { Message } from '@arco-design/web-vue';
import { isStandaloneMode } from '@/utils/env';
import Block from './block.vue';
const appStore = useAppStore();
@@ -39,6 +49,7 @@
const open = () => {
setVisible(true);
};
defineExpose({ open });
// 布局设置
@@ -110,7 +121,6 @@
},
]);
// 页面视图配置
const viewsOpts = computed(() => [
{
@@ -142,6 +152,26 @@
},
]);
// 是否展示创建 PWA 应用
const visibleCreatePwaApp = () => {
return !isStandaloneMode && !!(window as CustomWindow).deferredPrompt;
};
// 创建 PWA 应用
const createPwaApp = () => {
const win = window as CustomWindow;
try {
win.deferredPrompt.prompt();
win.deferredPrompt.userChoice.then((choiceResult: any) => {
if (choiceResult.outcome === 'accepted') {
win.deferredPrompt = null;
}
});
} catch (e) {
Message.error('无法安装 PWA 应用');
}
};
</script>
<style lang="less" scoped>

View File

@@ -7,11 +7,20 @@ declare module '*.vue' {
export default component;
}
// window
interface CustomWindow extends Window {
deferredPrompt?: any;
}
declare const window: CustomWindow;
// .env
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string;
readonly VITE_WS_BASE_URL: string;
readonly VITE_APP_VERSION: string;
readonly VITE_SFTP_PREVIEW_MB: number;
readonly VITE_SFTP_PREVIEW_MB: string;
readonly VITE_DEMO_MODE: string;
}
// editor

View File

@@ -7,12 +7,12 @@ import store from './store';
import i18n from './locale';
import directive from './directive';
import './mock';
import App from './App.vue';
// 样式通过 arco-plugin 插件导入 详见目录文件 config/plugin/arcoStyleImport.ts
import '@/assets/style/global.less';
import '@/assets/style/layout.less';
import '@/assets/style/arco-extends.less';
import '@/api/interceptor';
import App from './App.vue';
const app = createApp(App);
@@ -26,3 +26,9 @@ app.use(globalComponents);
app.use(directive);
app.mount('#app');
// 监听 PWA 注册事件
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
(window as CustomWindow).deferredPrompt = e;
});

View File

@@ -5,6 +5,7 @@ import { appRoutes } from './routes';
import BASE_ROUTERS from './routes/base';
import createRouteGuard from './guard';
import { openWindow } from '@/utils';
import { isStandaloneMode } from '@/utils/env';
import 'nprogress/nprogress.css';
NProgress.configure({ showSpinner: false });
@@ -27,7 +28,13 @@ createRouteGuard(router);
// 新页面打开路由
export const openNewRoute = (route: RouteLocationRaw) => {
const { href } = router.resolve(route);
openWindow(href);
if (isStandaloneMode) {
// 单应用 PWA 则跳转
window.location.href = href;
} else {
// 浏览器 则直接打开
openWindow(href);
}
};
export default router;

View File

@@ -5,6 +5,16 @@ export const isSecureEnvironment = (() => {
return window.location.protocol === 'https:' || window.location.hostname === 'localhost';
})();
// 当前是否为单应用模式 PWA
export const isStandaloneMode = (() => (
(window.matchMedia('(display-mode: standalone)').matches)
|| ((window.navigator as any).standalone)
|| document.referrer.includes('android-app://')
) === true)();
// 是否为 demo 环境
export const isDemoMode = (() => import.meta.env.VITE_DEMO_MODE === 'true')();
// http base url
export const httpBaseUrl = (() => {
const configBase = import.meta.env.VITE_API_BASE_URL;

View File

@@ -51,19 +51,17 @@
const router = useRouter();
const { t } = useI18n();
const errorMessage = ref('');
const { loading, setLoading } = useLoading();
const userStore = useUserStore();
const errorMessage = ref('');
const userInfo = reactive<LoginRequest>({
username: undefined,
password: undefined,
});
const handleSubmit = async ({
errors,
values,
}: {
const handleSubmit = async ({ errors, values }: {
errors: Record<string, ValidatedError> | undefined;
values: LoginRequest;
}) => {

View File

@@ -4,7 +4,7 @@
<div class="logo">
<img class="logo-img"
alt="logo"
src="@/assets/images/logo.svg?url" />
src="@/assets/logo.svg?url" />
<div class="logo-text">Orion Visor</div>
</div>
<!-- 左侧 banner -->

View File

@@ -5,7 +5,7 @@
<img alt="logo"
class="terminal-header-logo"
draggable="false"
src="@/assets/images/logo.svg?url" />
src="@/assets/logo.svg?url" />
<h5 class="terminal-header-logo-text">Orion Visor</h5>
</div>
<!-- 左侧 tabs -->

View File

@@ -152,7 +152,7 @@
import columns from './types/table.columns';
import { FILE_TYPE, openSftpChmodModalKey, openSftpMoveModalKey } from '../../types/terminal.const';
const previewSize = import.meta.env.VITE_SFTP_PREVIEW_MB;
const previewSize = Number.parseInt(import.meta.env.VITE_SFTP_PREVIEW_MB);
const props = defineProps<{
session?: ISftpSession;

View File

@@ -22,7 +22,7 @@
</modules>
<properties>
<revision>2.0.1</revision>
<revision>2.0.2</revision>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>