!30 今晚打老虎队半决赛代码提交

Merge pull request !30 from York_Luo/master
This commit is contained in:
opengauss-bot 2022-09-23 04:13:40 +00:00 committed by Gitee
commit 020f6d4e88
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
167 changed files with 22092 additions and 0 deletions

View File

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.szgx</groupId>
<artifactId>kunpeng</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kunpeng</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.opengauss</groupId>-->
<!-- <artifactId>opengauss-jdbc</artifactId>-->
<!-- <version>3.0.0</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
<!--JWT生成校验工具-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.huawei</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>3.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/opengauss-jdbc-3.0.0.jar</systemPath>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.huawei.shade</groupId>-->
<!-- <artifactId>postgresql</artifactId>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/postgresql.jar</systemPath>-->
<!-- <version>1.3.1</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.ganymed</groupId>
<artifactId>ganymed-ssh2-build210</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ganymed-ssh2-build210.jar</systemPath>
</dependency>
<!-- <dependency>-->
<!-- <groupId>ch.ethz.ganymed</groupId>-->
<!-- <artifactId>ganymed-ssh2</artifactId>-->
<!-- <version>262</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- mybatis-plus -->
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>mybatis-plus-boot-starter</artifactId>-->
<!-- <version>3.4.3.1</version>-->
<!-- </dependency>-->
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<!-- mybatis-spring-boot-starter的1.3.2版本号一定要和mybatis-plus的3.1.2主版本号一致 -->
<version>3.1.2</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.baomidou</groupId>-->
<!--<artifactId>mybatis-plus-boot-starter</artifactId>-->
<!--<version>3.4.1</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>
true
</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,16 @@
package com.szgx.kunpeng;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class KunpengApplication {
public static void main(String[] args) {
SpringApplication.run(KunpengApplication.class, args);
}
}

View File

@ -0,0 +1,308 @@
package com.szgx.kunpeng.basic.common;
public interface CommonConstant {
/**
* 正常状态
*/
public static final Integer STATUS_NORMAL = 0;
/**
* 禁用状态
*/
public static final Integer STATUS_DISABLE = -1;
/**
* 删除标志
*/
public static final Integer DEL_FLAG_1 = 1;
/**
* 未删除
*/
public static final Integer DEL_FLAG_0 = 0;
/**
* 系统日志类型 登录
*/
public static final int LOG_TYPE_1 = 1;
/**
* 系统日志类型 操作
*/
public static final int LOG_TYPE_2 = 2;
/**
* 操作日志类型 查询
*/
public static final int OPERATE_TYPE_1 = 1;
/**
* 操作日志类型 添加
*/
public static final int OPERATE_TYPE_2 = 2;
/**
* 操作日志类型 更新
*/
public static final int OPERATE_TYPE_3 = 3;
/**
* 操作日志类型 删除
*/
public static final int OPERATE_TYPE_4 = 4;
/**
* 操作日志类型 倒入
*/
public static final int OPERATE_TYPE_5 = 5;
/**
* 操作日志类型 导出
*/
public static final int OPERATE_TYPE_6 = 6;
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_OK_200 = 200;
/**访问权限认证未通过 510*/
public static final Integer SC_JEECG_NO_AUTHZ=510;
/** 登录用户Shiro权限缓存KEY前缀 */
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:";
/** 登录用户Token令牌缓存KEY前缀 */
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
/** Token缓存时间3600秒即一小时 */
public static final int TOKEN_EXPIRE_TIME = 3600;
/**
* 0一级菜单
*/
public static final Integer MENU_TYPE_0 = 0;
/**
* 1子菜单
*/
public static final Integer MENU_TYPE_1 = 1;
/**
* 2按钮权限
*/
public static final Integer MENU_TYPE_2 = 2;
/**通告对象类型USER:指定用户ALL:全体用户)*/
public static final String MSG_TYPE_UESR = "USER";
public static final String MSG_TYPE_ALL = "ALL";
/**发布状态0未发布1已发布2已撤销*/
public static final String NO_SEND = "0";
public static final String HAS_SEND = "1";
public static final String HAS_CANCLE = "2";
/**阅读状态0未读1已读*/
public static final String HAS_READ_FLAG = "1";
public static final String NO_READ_FLAG = "0";
/**优先级L低M中H高*/
public static final String PRIORITY_L = "L";
public static final String PRIORITY_M = "M";
public static final String PRIORITY_H = "H";
/**
* 短信模板方式 0 .登录模板1.注册模板2.忘记密码模板
*/
public static final String SMS_TPL_TYPE_0 = "0";
public static final String SMS_TPL_TYPE_1 = "1";
public static final String SMS_TPL_TYPE_2 = "2";
/**
* 状态(0无效1有效)
*/
public static final String STATUS_0 = "0";
public static final String STATUS_1 = "1";
/**
* 同步工作流引擎1同步0不同步
*/
public static final Integer ACT_SYNC_1 = 1;
public static final Integer ACT_SYNC_0 = 0;
/**
* 消息类型1:通知公告2:系统消息
*/
public static final String MSG_CATEGORY_1 = "1";
public static final String MSG_CATEGORY_2 = "2";
/**
* 是否配置菜单的数据权限 1是0否
*/
public static final Integer RULE_FLAG_0 = 0;
public static final Integer RULE_FLAG_1 = 1;
/**
* 是否用户已被冻结 1正常(解冻) 2冻结
*/
public static final Integer USER_UNFREEZE = 1;
public static final Integer USER_FREEZE = 2;
/**字典翻译文本后缀*/
public static final String DICT_TEXT_SUFFIX = "_dictText";
/**
* 表单设计器主表类型
*/
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
/**
* 表单设计器子表表类型
*/
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
/**
* 表单设计器URL授权通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
/**
* 表单设计器URL授权未通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
/**
* 表单设计器新增 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
/**
* 表单设计器修改 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
/**
* 表单设计器详情 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
/**
* 表单设计器复用数据 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
/**
* 表单设计器编辑 Flag 已弃用
*/
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
/**
* online参数值设置Y, N
*/
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
/**
* 文件上传类型本地localMiniominio阿里云alioss
*/
public static final String UPLOAD_TYPE_LOCAL = "local";
public static final String UPLOAD_TYPE_MINIO = "minio";
public static final String UPLOAD_TYPE_OSS = "alioss";
/**
* 文档上传自定义桶名称
*/
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
/**
* 文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
/**
* 文件外链接有效天数
*/
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
/**
* 员工身份 1:普通员工 2:上级
*/
public static final Integer USER_IDENTITY_1 = 1;
public static final Integer USER_IDENTITY_2 = 2;
/** sys_user 表 username 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
/** sys_user 表 work_no 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
/** sys_user 表 phone 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
/** sys_user 表 email 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
/** sys_quartz_job 表 job_class_name 唯一键索引 */
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
/** sys_position 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
/** sys_role 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
/** sys_depart 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
/**
* 在线聊天 是否为默认分组
*/
public static final String IM_DEFAULT_GROUP = "1";
/**
* 在线聊天 图片文件保存路径
*/
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
/**
* 在线聊天 用户状态
*/
public static final String IM_STATUS_ONLINE = "online";
/**
* 在线聊天 SOCKET消息类型
*/
public static final String IM_SOCKET_TYPE = "chatMessage";
/**
* 在线聊天 是否开启默认添加好友 1是 0否
*/
public static final String IM_DEFAULT_ADD_FRIEND = "1";
/**
* 在线聊天 用户好友缓存前缀
*/
public static final String IM_PREFIX_USER_FRIEND_CACHE = "im_prefix_user_friend_";
/**
* 考勤补卡业务状态 1同意 2不同意
*/
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
/**
* 公文文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
/**
* 公文文档下载自定义路径
*/
public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
/**
* WPS存储值类别(1 code文号 2 textWPS模板还是公文发文模板)
*/
public static final String WPS_TYPE_1="1";
public static final String WPS_TYPE_2="2";
public final static String X_ACCESS_TOKEN = "X-Access-Token";
/**
* 多租户 请求头
*/
public final static String TENANT_ID = "tenant_id";
/**
* 微服务读取配置文件属性 服务地址
*/
public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
/**
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
*/
public final static String THIRD_LOGIN_CODE = "third_login_code";
}

View File

@ -0,0 +1,16 @@
package com.szgx.kunpeng.basic.common;
/**
* @author York_Luo
* @create 2022-09-14-21:32
*/
public class CommonResultStatus {
public static String USERNAME_ERROR="用户名错误";
public static String PASSWORD_ERROR = "密码错误";
public static String LOGIN_SUCCESS = "登陆成功";
}

View File

@ -0,0 +1,45 @@
package com.szgx.kunpeng.basic.common;
/**
* @author zhangrb
* @date 2022/8/11 10:47
*/
public interface PrometheusApiConstant {
/**
* 系统指标
* start 开始日期
* end
* step :1小时=14
*/
//获取CPU使用率
String API_CPU_URL = "/api/v1/query_range?query=%281+-+sum%28rate%28node_cpu_seconds_total%7Bmode%3D%22idle%22%7D%5B1m%5D%29%29+by+%28instance%29+%2F+sum%28rate%28node_cpu_seconds_total%5B1m%5D%29%29+by+%28instance%29+%29+*+100";
//内存使用率
String API_RAM_URL = "/api/v1/query_range?query=%281-+%28node_memory_Buffers_bytes+%2B+node_memory_Cached_bytes+%2B+node_memory_MemFree_bytes%29+%2F+node_memory_MemTotal_bytes%29+*+100";
//磁盘使用率
String API_DISK_URL = "/api/v1/query_range?query=%28node_filesystem_size_bytes+%7Bmountpoint+%3D%22%2F%22%7D+-+node_filesystem_free_bytes+%7Bmountpoint+%3D%22%2F%22%7D%29+%2F%0Anode_filesystem_size_bytes+%7Bmountpoint+%3D%22%2F%22%7D+*+100%0A";
//磁盘读写IO
String API_DISK_R_W_IO_URL = "/api/v1/query_range?query=sum+by+%28instance%29+%28rate%28node_disk_reads_completed_total%5B1m%5D%29+%2B+rate%28node_disk_writes_completed_total%5B1m%5D%29%29";
//磁盘读IO
String API_DISK_R_URL = "/api/v1/query_range?query=sum+by+%28instance%29+%28rate%28node_disk_reads_completed_total%5B1m%5D%29%29";
//磁盘写IO
String API_DISK_W_URL = "/api/v1/query_range?query=sum+by+%28instance%29+%28rate%28node_disk_writes_completed_total%5B1m%5D%29%29";
//上行宽带
String API_DK_UP_URL = "/api/v1/query_range?query=sum+by+%28instance%29+%28rate%28node_network_receive_bytes_total%5B1m%5D%29%29";
//下行宽带
String API_DK_DOWN_URL = "/api/v1/query_range?query=sum+by+%28instance%29+%28rate%28node_network_transmit_bytes_total%5B1m%5D%29%29";
/**
* openGauss指标
*/
//数据库后端连接数
String API_GS_CONNECT_URL = "/api/v1/query_range?query=pg_stat_database_numbackends";
//数据库使用磁盘空间
String API_GS_DISK_URL = "/api/v1/query_range?query=pg_database_size_bytes";
//由于锁定超时而取消此数据库中的查询数
String API_GS_LOCK_URL = "/api/v1/query_range?query=pg_stat_database_conflicts_confl_lock";
//数据库中由于死锁而取消的查询数
String API_GS_DEADLOCK_URL = "/api/v1/query_range?query=pg_stat_database_conflicts_confl_deadlock";
}

View File

@ -0,0 +1,13 @@
package com.szgx.kunpeng.basic.common.exception;
import org.apache.shiro.authc.AuthenticationException;
/**
* @author York_Luo
* @create 2022-09-14-21:32
*/
public class BusinessException extends AuthenticationException {
public BusinessException(String message) {
super(message);
}
}

View File

@ -0,0 +1,78 @@
package com.szgx.kunpeng.basic.config;
import com.szgx.kunpeng.basic.common.CommonResultStatus;
import com.szgx.kunpeng.basic.common.exception.BusinessException;
import com.szgx.kunpeng.basic.entiry.SysUserInfo;
import com.szgx.kunpeng.basic.service.SysUserInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;
/**
* @author York_Luo
* @create 2022-09-14-20:52
*/
@Slf4j
public class CustomRealm extends AuthorizingRealm {
@Autowired
private SysUserInfoMapper userInfoMapper;
/**
* 权限认证/获取授权信息
* 该方法只有在需要权限认证时才会进入
* 比如前面配置类中配置了
* filterChainDefinitionMap.put("/admin/**", "roles[admin]"); 的管理员角色
* 这时进入 /admin 时就会进入该方法来检查权限
* @author cheetah
* @date 2020/11/21
* @param principals:
* @return: org.apache.shiro.authz.AuthorizationInfo
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("————权限认证————");
String username = (String) SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获得该用户角色
String role = userInfoMapper.getRole(username);
Set<String> set = new HashSet<>();
//需要将 role 封装到 Set 作为 info.setRoles() 的参数
set.add(role);
//设置该用户拥有的角色
info.setRoles(set);
return info;
}
/**
* 身份认证/获取身份验证信息
* Shiro中最终是通过 Realm 来获取应用程序中的用户角色及权限信息的
* 该方法则是需要身份认证时比如前面的 Subject.login() 方法才会进入
* @author cheetah
* @date 2020/11/21
* @param authenticationToken: 用户身份信息 token
* @return: org.apache.shiro.authc.AuthenticationInfo
* 返回封装了用户信息的 AuthenticationInfo 实例
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
log.info("————身份认证方法————");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 从数据库获取对应用户名密码的用户
SysUserInfo userInfo = userInfoMapper.getUserByLogin(token.getUsername());
if (null == userInfo) {
throw new BusinessException(CommonResultStatus.USERNAME_ERROR);
} else if (!userInfo.getPassword().equals(new String((char[]) token.getCredentials()))) {
throw new BusinessException(CommonResultStatus.PASSWORD_ERROR);
}
return new SimpleAuthenticationInfo(token.getPrincipal(), userInfo.getPassword(), getName());
}
}

View File

@ -0,0 +1,25 @@
package com.szgx.kunpeng.basic.config;
import org.apache.shiro.authc.AuthenticationToken;
/**
* tocken
*/
public class JwtToken implements AuthenticationToken {
private String token;
public JwtToken(String jwt){
this.token = jwt;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}

View File

@ -0,0 +1,87 @@
package com.szgx.kunpeng.basic.config;
import com.szgx.kunpeng.basic.filter.CustomRolesOrAuthorizationFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
@Slf4j
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
* @author cheetah
* @date 2020/11/21
* @return: org.apache.shiro.spring.web.ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager());
//设置shiro内置过滤器
Map<String, Filter> filters = new LinkedHashMap<>();
//增加自定义过滤器只对需要登陆的接口进行过滤
filters.put("authc", new CustomRolesOrAuthorizationFilter());
//filters.put("roles", new CustomRolesOrAuthorizationFilter());
shiroFilterFactoryBean.setFilters(filters);
// setLoginUrl 如果不设置值默认会自动寻找Web工程根目录下的"/login.jsp"页面 "/login" 映射
shiroFilterFactoryBean.setLoginUrl("/basic/login");
// 设置无权限时跳转的 url;
shiroFilterFactoryBean.setUnauthorizedUrl("/notAuth");
// 设置拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//游客开发权限
filterChainDefinitionMap.put("/guest/**", "anon");
//用户需要角色权限 user
filterChainDefinitionMap.put("/user/**", "roles[user]");
//管理员需要角色权限 admin
filterChainDefinitionMap.put("/admin/**", "roles[admin]");
//商品需要角色权限 user
//filterChainDefinitionMap.put("/productInfo/**", "roles[user]");
//开放登陆接口
filterChainDefinitionMap.put("/basic/login", "anon");
//其余接口一律拦截
//主要这行代码必须放在所有权限设置的最后不然会导致所有 url 都被拦截
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
log.info("-------Shiro拦截器工厂类注入成功-----------");
return shiroFilterFactoryBean;
}
/**
* 注入安全管理器
* @author cheetah
* @date 2020/11/21
* @return: java.lang.SecurityManager
*/
@Bean
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(customRealm());
return securityManager;
}
/**
* 注入自定义身份认证
* @author cheetah
* @date 2020/11/21
* @return: com.cheetah.shiroandjwt.config.CustomRealm
*/
@Bean
public CustomRealm customRealm(){
return new CustomRealm();
}
}

View File

@ -0,0 +1,49 @@
package com.szgx.kunpeng.basic.controller;
import com.szgx.kunpeng.basic.common.CommonResultStatus;
import com.szgx.kunpeng.basic.config.JwtToken;
import com.szgx.kunpeng.basic.entiry.SysUserInfo;
import com.szgx.kunpeng.basic.util.JwtUtils;
import com.szgx.kunpeng.basic.util.Result;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.sql.SQLException;
/**
* @author York_Luo
* @create 2022-09-14-23:21
*/
@RestController
@RequestMapping("/basic")
public class UserController {
@Autowired
JwtUtils jwtUtils;
@PostMapping(value = "/login")
@ApiOperation(value = "登录",notes = "登录")
public Result login(@Valid @RequestBody SysUserInfo userInfo) throws SQLException {
if (!"admin".equals(userInfo.getUsername())) {
return Result.OK("用户不存在");
}
if (!"123456".equals(userInfo.getPassword())) {
return Result.OK("用户密码不正确");
}
UsernamePasswordToken token = new UsernamePasswordToken(userInfo.getUsername(),userInfo.getPassword());
// JwtToken jwtToken = new JwtToken(jwtUtils.generateToken(userInfo.getUsername()));
Subject subject = SecurityUtils.getSubject();
subject.login(token);
return Result.OK(CommonResultStatus.LOGIN_SUCCESS);
}
}

View File

@ -0,0 +1,14 @@
package com.szgx.kunpeng.basic.entiry;
import lombok.Data;
/**
* @author York_Luo
* @create 2022-09-14-21:28
*/
@Data
public class SysUserInfo {
String username;
String password;
}

View File

@ -0,0 +1,55 @@
package com.szgx.kunpeng.basic.filter;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
/**
* @author York_Luo
* @create 2022-09-14-20:55
*/
public class CustomRolesOrAuthorizationFilter extends AuthorizationFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
//验证用户是否登陆若是未登陆直接返回异常信息
Subject subject = getSubject(request, response);
Object principal = subject.getPrincipal();
if (principal == null) {
return false;
}
//获取当前访问路径所需要的角色集合
String[] rolesArray = (String[]) mappedValue;
//没有角色限制可以直接访问
if (rolesArray == null || rolesArray.length == 0) {
//没有指定角色的话不需要进行验证放行
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
//当前subject是roles中的任意一个则有权限访问
for (String role : roles) {
if (subject.hasRole(role)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,33 @@
package com.szgx.kunpeng.basic.filter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class SimpleCORSFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request =(HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "content-type,token");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}

View File

@ -0,0 +1,35 @@
package com.szgx.kunpeng.basic.service;
import com.szgx.kunpeng.basic.entiry.SysUserInfo;
import org.springframework.stereotype.Service;
/**
* @author York_Luo
* @create 2022-09-14-21:26
*/
@Service
public class SysUserInfoMapper {
public String getRole(String username) {
if ("admin".equals(username)) {
return "admin";
}
return "";
}
public SysUserInfo getUserByLogin(String username) {
SysUserInfo sysUserInfo = null;
if ("admin".equals(username)) {
sysUserInfo = new SysUserInfo();
sysUserInfo.setUsername("admin");
sysUserInfo.setPassword("123456");
return sysUserInfo;
}
return sysUserInfo;
}
}

View File

@ -0,0 +1,174 @@
package com.szgx.kunpeng.basic.tool;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.szgx.kunpeng.basic.util.JdbcUtils;
import com.szgx.kunpeng.basic.util.LocalCacheUtil;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhangrb
* @date 2021/6/25
*/
public class BaseQueryTool {
protected static final Logger logger = LoggerFactory.getLogger(BaseQueryTool.class);
private DataSource datasource;
private Connection connection;
/**
* 当前数据库名
*/
private String currentSchema;
private String currentDatabase;
/**
* 构造方法
*
* @param jobDatasource
*/
public BaseQueryTool(JobDatasource jobDatasource) throws SQLException {
if (LocalCacheUtil.get(jobDatasource.getDatasourceName()) == null) {
getDataSource(jobDatasource);
} else {
this.connection = (Connection) LocalCacheUtil.get(jobDatasource.getDatasourceName());
if (!this.connection.isValid(500)) {
LocalCacheUtil.remove(jobDatasource.getDatasourceName());
getDataSource(jobDatasource);
}
}
// currentSchema = getSchema(jobDatasource.getJdbcUsername());
// currentDatabase = jobDatasource.getDatasource();
LocalCacheUtil.set(jobDatasource.getDatasourceName(), this.connection, 4 * 60 * 60 * 1000);
}
private void getDataSource(JobDatasource jobDatasource) throws SQLException {
//这里默认使用 hikari 数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setUsername(jobDatasource.getJdbcUsername());
dataSource.setPassword(jobDatasource.getJdbcPassword());
dataSource.setJdbcUrl(jobDatasource.getJdbcUrl());
dataSource.setDriverClassName(jobDatasource.getJdbcDriverClass());
dataSource.setMaximumPoolSize(5);
dataSource.setMinimumIdle(0);
dataSource.setConnectionTimeout(30000);
this.datasource = dataSource;
this.connection = this.datasource.getConnection();
}
//根据connection获取schema
private String getSchema(String jdbcUsername) {
String res = null;
try {
res = connection.getCatalog();
} catch (SQLException e) {
try {
res = connection.getSchema();
} catch (SQLException e1) {
logger.error("[SQLException getSchema Exception] --> "
+ "the exception message is:" + e1.getMessage());
}
logger.error("[getSchema Exception] --> "
+ "the exception message is:" + e.getMessage());
}
// 如果res是null则将用户名当作 schema
if (StrUtil.isBlank(res) && StringUtils.isNotEmpty(jdbcUsername)) {
res = jdbcUsername.toUpperCase();
}
return res;
}
//执行executeUpdate insert,delete,update
public ExecuteResult executeUpdateSql(String sql){
Long startTime = System.currentTimeMillis();
ExecuteResult executeResult = new ExecuteResult();
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate(sql);
Long endTime = System.currentTimeMillis();
Double time = Double.valueOf(endTime - startTime) / 1000;
executeResult.setCode(sql);
executeResult.setType("UPDATE");
executeResult.setResult("OK");
executeResult.setTime(time+"");
return executeResult;
} catch (SQLException e) {
executeResult.setCode(sql);
executeResult.setSuccess(false);
executeResult.setResult(e.getMessage());
executeResult.setType("UPDATE");
executeResult.setTime("0秒");
return executeResult;
} finally {
JdbcUtils.close(stmt);
}
}
public ExecuteResult executeSelectSql(String querySql) {
Long startTime = System.currentTimeMillis();
ExecuteResult executeResult = new ExecuteResult();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = connection.createStatement();
rs = stmt.executeQuery(querySql);
List list = new ArrayList();
ResultSetMetaData md = rs.getMetaData();//获取键名
int columnCount = md.getColumnCount();//获取行的数量
int resultDataCount = 0;
while (rs.next()) {
resultDataCount += 1;
Map<String,Object> rowData = new LinkedHashMap<>();//声明Map
for (int i = 1; i <= columnCount; i++) {
rowData.put(md.getColumnName(i), rs.getObject(i));//获取键名及值
}
list.add(rowData);
}
if (resultDataCount == 0) {
Map<String,Object> rowData = new LinkedHashMap<>();//声明Map
for (int i = 1; i <= columnCount; i++) {
rowData.put(md.getColumnName(i), "");//获取键名及值
}
list.add(rowData);
}
Long endTime = System.currentTimeMillis();
Double time = Double.valueOf(endTime - startTime) / 1000;
executeResult.setCode(querySql);
executeResult.setResult("OK");
executeResult.setType("SELECT");
executeResult.setTable(list);
executeResult.setTime(time +"");
return executeResult;
} catch (SQLException e) {
e.printStackTrace();
logger.error("[getPageDataSql Exception] --> "
+ "the exception message is:" + e.getMessage());
executeResult.setCode(querySql);
executeResult.setSuccess(false);
executeResult.setResult(e.getMessage());
executeResult.setType("SELECT");
executeResult.setTime("0秒");
return executeResult;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
}
}

View File

@ -0,0 +1,38 @@
package com.szgx.kunpeng.basic.tool;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* @author zhangrb
* @date 2021/7/8
*/
@Data
public class ExecuteResult {
@ApiModelProperty(value = "执行语句")
private String code;
@ApiModelProperty(value = "类型")
private String type;
@ApiModelProperty(value = "select类型返回集合")
private List<Map<String,Object>> table;
@ApiModelProperty(value = "成功标志")
private boolean success = true;
@ApiModelProperty(value = "执行结果")
private String result;
@ApiModelProperty("执行耗时")
private String time;
public ExecuteResult(){
}
public ExecuteResult(String code, String result){
this.type = "UNKNOWN";
this.result = result;
this.code = code;
this.time = "0秒";
}
}

View File

@ -0,0 +1,141 @@
package com.szgx.kunpeng.basic.tool;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* jdbc数据源配置实体类(job_jdbc_datasource)
*
* @author zhouhongfa@gz-yibo.com
* @version v1.0
* @since 2019-07-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel
public class JobDatasource extends Model<JobDatasource> {
/**
* 自增主键
*/
@TableId
@ApiModelProperty(value = "自增主键")
private Long id;
/**
* 数据源名称
*/
@ApiModelProperty(value = "数据源名称")
private String datasourceName;
/**
* 数据源
*/
@ApiModelProperty(value = "数据源")
private String datasource;
/**
* 数据源分组
*/
@ApiModelProperty(value = "数据源分组")
private String datasourceGroup;
/**
* 用户名
* AESEncryptHandler 加密类
* MyBatis Plus 3.0.7.1之前版本没有typeHandler属性需要升级到最低3.1.2
*/
@ApiModelProperty(value = "用户名")
private String jdbcUsername;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
private String jdbcPassword;
/**
* jdbc url
*/
@ApiModelProperty(value = "jdbc url")
private String jdbcUrl;
/**
* jdbc驱动类
*/
@ApiModelProperty(value = "jdbc驱动类")
private String jdbcDriverClass;
/**
* 状态0删除 1启用 2禁用
*/
@TableLogic
@ApiModelProperty(value = "状态0删除 1启用 2禁用")
private Integer status;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建人", hidden = true)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@JSONField(format = "yyyy/MM/dd")
@ApiModelProperty(value = "创建时间", hidden = true)
private Date createDate;
/**
* 更新人
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "更新人", hidden = true)
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@JSONField(format = "yyyy/MM/dd")
@ApiModelProperty(value = "更新时间", hidden = true)
private Date updateDate;
/**
* 备注
*/
@ApiModelProperty(value = "备注", hidden = true)
private String comments;
/**
* zookeeper地址
*/
@ApiModelProperty(value = "zookeeper地址", hidden = true)
private String zkAdress;
/**
* 数据库名
*/
@ApiModelProperty(value = "数据库名", hidden = true)
private String databaseName;
/**
* 获取主键值
*
* @return 主键值
*/
@Override
protected Serializable pkVal() {
return this.id;
}
}

View File

@ -0,0 +1,196 @@
package com.szgx.kunpeng.basic.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author zhangrb
* @date 2022/8/11 11:50
*/
@Slf4j
public class HttpClientUtil {
/**
* 发送get无参请求
* @param url 请求url
* @return
*/
public static JSONObject doGet(String url) {
return doGet(url, null);
}
/**
* 发送get有参请求
* @param url 请求url
* @param param 请求参数
* @return
*/
public static JSONObject doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = null;
JSONObject result = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
//响应实体JSON处理
HttpEntity entity = response.getEntity();
String resultString = EntityUtils.toString(entity, "UTF-8");
result = JSONObject.parseObject(resultString);
}else {
log.info("http get请求失败->code{}", response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 发送post无参请求
* @param url
* @return
*/
public static JSONObject doPost(String url) {
return doPost(url, null);
}
/**
* 发送post有参请求
* @param url
* @param param
* @return
*/
public static JSONObject doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
JSONObject result = null;
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"UTF-8");
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
//响应实体JSON处理
HttpEntity entity = response.getEntity();
String resultString = EntityUtils.toString(entity, "UTF-8");
result = JSONObject.parseObject(resultString);
}else {
log.info("http post请求失败->code{}", response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(response != null){
response.close();
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* 发送post请求
* @param url
* @param json
* @return
*/
public static JSONObject HttpPostWithJson(String url, String json) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
JSONObject result = null;
try {
//第一步创建HttpClient对象
httpClient = HttpClients.createDefault();
//第二步创建httpPost对象
HttpPost httpPost = new HttpPost(url);
//第三步给httpPost设置JSON格式的参数
StringEntity requestEntity = new StringEntity(json, "utf-8");
requestEntity.setContentEncoding("UTF-8");
httpPost.setHeader("Content-type", "application/json");
httpPost.setEntity(requestEntity);
//第四步发送HttpPost请求获取返回值
response = httpClient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
//响应实体JSON处理
HttpEntity entity = response.getEntity();
String resultString = EntityUtils.toString(entity, "UTF-8");
result = JSONObject.parseObject(resultString);
} else {
log.info("http post请求失败->code{}", response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//第五步处理返回值
return result;
}
}

View File

@ -0,0 +1,135 @@
package com.szgx.kunpeng.basic.util;
/**
* JdbcConstants
*
* @author jingwk
* @ClassName JdbcConstants
* @Version 2.1.1
* @since 2020/03/14 07:15
*/
public interface JdbcConstants {
String HBASE_ZK_QUORUM = "hbase.zookeeper.quorum";
String MONGODB ="mongodb";
String CASSANDRA ="cassandra";
String ELASTICSEARCH ="elastic_search";
String JTDS = "jtds";
String MOCK = "mock";
String HSQL = "hsql";
String DB2 = "db2";
String DB2_DRIVER = "com.ibm.db2.jcc.DB2Driver";
String POSTGRESQL = "postgresql";
String POSTGRESQL_DRIVER = "org.postgresql.Driver";
String SYBASE = "sybase";
String SQL_SERVER = "sqlserver";
String SQL_SERVER_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String SQL_SERVER_DRIVER_SQLJDBC4 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String SQL_SERVER_DRIVER_JTDS = "net.sourceforge.jtds.jdbc.Driver";
String ORACLE = "oracle";
String ORACLE_DRIVER = "oracle.jdbc.OracleDriver";
String ORACLE_DRIVER2 = "oracle.jdbc.driver.OracleDriver";
String ALI_ORACLE = "AliOracle";
String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
String MYSQL = "mysql";
String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
String MYSQL_DRIVER_6 = "com.mysql.cj.jdbc.Driver";
String MYSQL_DRIVER_REPLICATE = "com.mysql.jdbc.";
String MARIADB = "mariadb";
String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
String DERBY = "derby";
String HBASE = "hbase";
String HIVE = "hive";
String HIVE_DRIVER = "org.apache.hive.jdbc.HiveDriver";
String H2 = "h2";
String H2_DRIVER = "org.h2.Driver";
String DM = "dm";
String DM_DRIVER = "dm.jdbc.driver.DmDriver";
String KINGBASE = "kingbase";
String KINGBASE_DRIVER = "com.kingbase.Driver";
String GBASE = "gbase";
String GBASE_DRIVER = "com.gbase.jdbc.Driver";
String XUGU = "xugu";
String XUGU_DRIVER = "com.xugu.cloudjdbc.Driver";
String OCEANBASE = "oceanbase";
String OCEANBASE_DRIVER = "com.mysql.jdbc.Driver";
String INFORMIX = "informix";
/**
* 阿里云odps
*/
String ODPS = "odps";
String ODPS_DRIVER = "com.aliyun.odps.jdbc.OdpsDriver";
String TERADATA = "teradata";
String TERADATA_DRIVER = "com.teradata.jdbc.TeraDriver";
/**
* Log4JDBC
*/
String LOG4JDBC = "log4jdbc";
String LOG4JDBC_DRIVER = "net.sf.log4jdbc.DriverSpy";
String PHOENIX = "phoenix";
String PHOENIX_DRIVER = "org.apache.phoenix.jdbc.PhoenixDriver";
String ENTERPRISEDB = "edb";
String ENTERPRISEDB_DRIVER = "com.edb.Driver";
String KYLIN = "kylin";
String KYLIN_DRIVER = "org.apache.kylin.jdbc.Driver";
String SQLITE = "sqlite";
String SQLITE_DRIVER = "org.sqlite.JDBC";
String ALIYUN_ADS = "aliyun_ads";
String ALIYUN_DRDS = "aliyun_drds";
String PRESTO = "presto";
String PRESTO_DRIVER = "com.facebook.presto.jdbc.PrestoDriver";
String ELASTIC_SEARCH = "elastic_search";
String ELASTIC_SEARCH_DRIVER = "com.alibaba.xdriver.elastic.jdbc.ElasticDriver";
String CLICKHOUSE = "clickhouse";
String CLICKHOUSE_DRIVER = "ru.yandex.clickhouse.ClickHouseDriver";
// for HBase2.X and Phoenix5.X
String HBASE20XSQL = "hbase20xsql";
String HBASE20XSQL_DRIVER = "org.apache.phoenix.jdbc.PhoenixDriver";
String TXTFILE = "txtfile";
String FTP = "ftp";
String SFTP = "sftp";
String HDFS = "hdfs";
}

View File

@ -0,0 +1,711 @@
package com.szgx.kunpeng.basic.util;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.PagerUtils;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.szgx.kunpeng.basic.tool.JobDatasource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.io.Closeable;
import java.io.InputStream;
import java.net.URL;
import java.sql.*;
import java.util.*;
/**
* jdbc utils
*
* @author jingwk
* @ClassName JdbcUtils
* @Version 2.1.1
* @since 2020/03/14 07:15
*/
public final class JdbcUtils implements JdbcConstants {
private static Logger LOG = LoggerFactory.getLogger(JdbcUtils.class);
private static final Properties DRIVER_URL_MAPPING = new Properties();
private static Boolean mysql_driver_version_6 = null;
static {
try {
ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
if (ctxClassLoader != null) {
for (Enumeration<URL> e = ctxClassLoader.getResources("META-INF/druid-driver.properties"); e.hasMoreElements();) {
URL url = e.nextElement();
Properties property = new Properties();
InputStream is = null;
try {
is = url.openStream();
property.load(is);
} finally {
JdbcUtils.close(is);
}
DRIVER_URL_MAPPING.putAll(property);
}
}
} catch (Exception e) {
LOG.error("load druid-driver.properties error", e);
}
}
public static void close(Connection x) {
if (x == null) {
return;
}
try {
x.close();
} catch (Exception e) {
LOG.debug("close connection error", e);
}
}
public static void close(Statement x) {
if (x == null) {
return;
}
try {
x.close();
} catch (Exception e) {
LOG.debug("close statement error", e);
}
}
public static void close(ResultSet x) {
if (x == null) {
return;
}
try {
x.close();
} catch (Exception e) {
LOG.debug("close result set error", e);
}
}
public static void close(Closeable x) {
if (x == null) {
return;
}
try {
x.close();
} catch (Exception e) {
LOG.debug("close error", e);
}
}
public static void close(Blob x) {
if (x == null) {
return;
}
try {
x.free();
} catch (Exception e) {
LOG.debug("close error", e);
}
}
public static void close(Clob x) {
if (x == null) {
return;
}
try {
x.free();
} catch (Exception e) {
LOG.debug("close error", e);
}
}
// public static void printResultSet(ResultSet rs) throws SQLException {
// printResultSet(rs, System.out);
// }
//
// public static void printResultSet(ResultSet rs, PrintStream out) throws SQLException {
// printResultSet(rs, out, true, "\t");
// }
// public static void printResultSet(ResultSet rs, PrintStream out, boolean printHeader, String seperator) throws SQLException {
// ResultSetMetaData metadata = rs.getMetaData();
// int columnCount = metadata.getColumnCount();
// if (printHeader) {
// for (int columnIndex = 1; columnIndex <= columnCount; ++columnIndex) {
// if (columnIndex != 1) {
// out.print(seperator);
// }
// out.print(metadata.getColumnName(columnIndex));
// }
// }
//
// out.println();
//
// while (rs.next()) {
//
// for (int columnIndex = 1; columnIndex <= columnCount; ++columnIndex) {
// if (columnIndex != 1) {
// out.print(seperator);
// }
//
// int type = metadata.getColumnType(columnIndex);
//
// if (type == Types.VARCHAR || type == Types.CHAR || type == Types.NVARCHAR || type == Types.NCHAR) {
// out.print(rs.getString(columnIndex));
// } else if (type == Types.DATE) {
// Date date = rs.getDate(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(date.toString());
// }
// } else if (type == Types.BIT) {
// boolean value = rs.getBoolean(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Boolean.toString(value));
// }
// } else if (type == Types.BOOLEAN) {
// boolean value = rs.getBoolean(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Boolean.toString(value));
// }
// } else if (type == Types.TINYINT) {
// byte value = rs.getByte(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Byte.toString(value));
// }
// } else if (type == Types.SMALLINT) {
// short value = rs.getShort(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Short.toString(value));
// }
// } else if (type == Types.INTEGER) {
// int value = rs.getInt(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Integer.toString(value));
// }
// } else if (type == Types.BIGINT) {
// long value = rs.getLong(columnIndex);
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(Long.toString(value));
// }
// } else if (type == Types.TIMESTAMP) {
// out.print(String.valueOf(rs.getTimestamp(columnIndex)));
// } else if (type == Types.DECIMAL) {
// out.print(String.valueOf(rs.getBigDecimal(columnIndex)));
// } else if (type == Types.CLOB) {
// out.print(String.valueOf(rs.getString(columnIndex)));
// } else if (type == Types.JAVA_OBJECT) {
// Object object = rs.getObject(columnIndex);
//
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(String.valueOf(object));
// }
// } else if (type == Types.LONGVARCHAR) {
// Object object = rs.getString(columnIndex);
//
// if (rs.wasNull()) {
// out.print("null");
// } else {
// out.print(String.valueOf(object));
// }
// } else if (type == Types.NULL) {
// out.print("null");
// } else {
// Object object = rs.getObject(columnIndex);
//
// if (rs.wasNull()) {
// out.print("null");
// } else {
// if (object instanceof byte[]) {
// byte[] bytes = (byte[]) object;
// String text = HexBin.encode(bytes);
// out.print(text);
// } else {
// out.print(String.valueOf(object));
// }
// }
// }
// }
// out.println();
// }
// }
public static String getTypeName(int sqlType) {
switch (sqlType) {
case Types.ARRAY:
return "ARRAY";
case Types.BIGINT:
return "BIGINT";
case Types.BINARY:
return "BINARY";
case Types.BIT:
return "BIT";
case Types.BLOB:
return "BLOB";
case Types.BOOLEAN:
return "BOOLEAN";
case Types.CHAR:
return "CHAR";
case Types.CLOB:
return "CLOB";
case Types.DATALINK:
return "DATALINK";
case Types.DATE:
return "DATE";
case Types.DECIMAL:
return "DECIMAL";
case Types.DISTINCT:
return "DISTINCT";
case Types.DOUBLE:
return "DOUBLE";
case Types.FLOAT:
return "FLOAT";
case Types.INTEGER:
return "INTEGER";
case Types.JAVA_OBJECT:
return "JAVA_OBJECT";
case Types.LONGNVARCHAR:
return "LONGNVARCHAR";
case Types.LONGVARBINARY:
return "LONGVARBINARY";
case Types.NCHAR:
return "NCHAR";
case Types.NCLOB:
return "NCLOB";
case Types.NULL:
return "NULL";
case Types.NUMERIC:
return "NUMERIC";
case Types.NVARCHAR:
return "NVARCHAR";
case Types.REAL:
return "REAL";
case Types.REF:
return "REF";
case Types.ROWID:
return "ROWID";
case Types.SMALLINT:
return "SMALLINT";
case Types.SQLXML:
return "SQLXML";
case Types.STRUCT:
return "STRUCT";
case Types.TIME:
return "TIME";
case Types.TIMESTAMP:
return "TIMESTAMP";
case Types.TINYINT:
return "TINYINT";
case Types.VARBINARY:
return "VARBINARY";
case Types.VARCHAR:
return "VARCHAR";
default:
return "OTHER";
}
}
public static String getDbType(String rawUrl, String driverClassName) {
if (rawUrl == null) {
return null;
}
if (rawUrl.startsWith("jdbc:derby:") || rawUrl.startsWith("jdbc:log4jdbc:derby:")) {
return DERBY;
} else if (rawUrl.startsWith("jdbc:mysql:") || rawUrl.startsWith("jdbc:cobar:")
|| rawUrl.startsWith("jdbc:log4jdbc:mysql:")) {
return MYSQL;
} else if (rawUrl.startsWith("jdbc:mariadb:")) {
return MARIADB;
} else if (rawUrl.startsWith("jdbc:oracle:") || rawUrl.startsWith("jdbc:log4jdbc:oracle:")) {
return ORACLE;
} else if (rawUrl.startsWith("jdbc:alibaba:oracle:")) {
return ALI_ORACLE;
} else if (rawUrl.startsWith("jdbc:microsoft:") || rawUrl.startsWith("jdbc:log4jdbc:microsoft:")) {
return SQL_SERVER;
} else if (rawUrl.startsWith("jdbc:sqlserver:") || rawUrl.startsWith("jdbc:log4jdbc:sqlserver:")) {
return SQL_SERVER;
} else if (rawUrl.startsWith("jdbc:sybase:Tds:") || rawUrl.startsWith("jdbc:log4jdbc:sybase:")) {
return SYBASE;
} else if (rawUrl.startsWith("jdbc:jtds:") || rawUrl.startsWith("jdbc:log4jdbc:jtds:")) {
return JTDS;
} else if (rawUrl.startsWith("jdbc:fake:") || rawUrl.startsWith("jdbc:mock:")) {
return MOCK;
} else if (rawUrl.startsWith("jdbc:postgresql:") || rawUrl.startsWith("jdbc:log4jdbc:postgresql:")) {
return POSTGRESQL;
} else if (rawUrl.startsWith("jdbc:edb:")) {
return ENTERPRISEDB;
} else if (rawUrl.startsWith("jdbc:hsqldb:") || rawUrl.startsWith("jdbc:log4jdbc:hsqldb:")) {
return HSQL;
} else if (rawUrl.startsWith("jdbc:odps:")) {
return ODPS;
} else if (rawUrl.startsWith("jdbc:db2:")) {
return DB2;
} else if (rawUrl.startsWith("jdbc:sqlite:")) {
return SQLITE;
} else if (rawUrl.startsWith("jdbc:ingres:")) {
return "ingres";
} else if (rawUrl.startsWith("jdbc:h2:") || rawUrl.startsWith("jdbc:log4jdbc:h2:")) {
return H2;
} else if (rawUrl.startsWith("jdbc:mckoi:")) {
return "mckoi";
} else if (rawUrl.startsWith("jdbc:cloudscape:")) {
return "cloudscape";
} else if (rawUrl.startsWith("jdbc:informix-sqli:") || rawUrl.startsWith("jdbc:log4jdbc:informix-sqli:")) {
return "informix";
} else if (rawUrl.startsWith("jdbc:timesten:")) {
return "timesten";
} else if (rawUrl.startsWith("jdbc:as400:")) {
return "as400";
} else if (rawUrl.startsWith("jdbc:sapdb:")) {
return "sapdb";
} else if (rawUrl.startsWith("jdbc:JSQLConnect:")) {
return "JSQLConnect";
} else if (rawUrl.startsWith("jdbc:JTurbo:")) {
return "JTurbo";
} else if (rawUrl.startsWith("jdbc:firebirdsql:")) {
return "firebirdsql";
} else if (rawUrl.startsWith("jdbc:interbase:")) {
return "interbase";
} else if (rawUrl.startsWith("jdbc:pointbase:")) {
return "pointbase";
} else if (rawUrl.startsWith("jdbc:edbc:")) {
return "edbc";
} else if (rawUrl.startsWith("jdbc:mimer:multi1:")) {
return "mimer";
} else if (rawUrl.startsWith("jdbc:dm:")) {
return JdbcConstants.DM;
} else if (rawUrl.startsWith("jdbc:kingbase:")) {
return JdbcConstants.KINGBASE;
} else if (rawUrl.startsWith("jdbc:gbase:")) {
return JdbcConstants.GBASE;
} else if (rawUrl.startsWith("jdbc:xugu:")) {
return JdbcConstants.XUGU;
} else if (rawUrl.startsWith("jdbc:log4jdbc:")) {
return LOG4JDBC;
} else if (rawUrl.startsWith("jdbc:hive:")) {
return HIVE;
} else if (rawUrl.startsWith("jdbc:hive2:")) {
return HIVE;
} else if (rawUrl.startsWith("jdbc:phoenix:")) {
return PHOENIX;
} else if (rawUrl.startsWith("jdbc:elastic:")) {
return ELASTIC_SEARCH;
} else if (rawUrl.startsWith("jdbc:clickhouse:")) {
return CLICKHOUSE;
}else if (rawUrl.startsWith("jdbc:presto:")) {
return PRESTO;
} else {
return null;
}
}
public static Driver createDriver(String driverClassName) throws SQLException {
return createDriver(null, driverClassName);
}
public static Driver createDriver(ClassLoader classLoader, String driverClassName) throws SQLException {
Class<?> clazz = null;
if (classLoader != null) {
try {
clazz = classLoader.loadClass(driverClassName);
} catch (ClassNotFoundException e) {
// skip
}
}
if (clazz == null) {
try {
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
if (contextLoader != null) {
clazz = contextLoader.loadClass(driverClassName);
}
} catch (ClassNotFoundException e) {
// skip
}
}
if (clazz == null) {
try {
clazz = Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
throw new SQLException(e.getMessage(), e);
}
}
try {
return (Driver) clazz.newInstance();
} catch (IllegalAccessException e) {
throw new SQLException(e.getMessage(), e);
} catch (InstantiationException e) {
throw new SQLException(e.getMessage(), e);
}
}
public static int executeUpdate(DataSource dataSource, String sql, Object... parameters) throws SQLException {
return executeUpdate(dataSource, sql, Arrays.asList(parameters));
}
public static int executeUpdate(DataSource dataSource, String sql, List<Object> parameters) throws SQLException {
Connection conn = null;
try {
conn = dataSource.getConnection();
return executeUpdate(conn, sql, parameters);
} finally {
close(conn);
}
}
public static int executeUpdate(Connection conn, String sql, List<Object> parameters) throws SQLException {
PreparedStatement stmt = null;
int updateCount;
try {
stmt = conn.prepareStatement(sql);
setParameters(stmt, parameters);
updateCount = stmt.executeUpdate();
} finally {
JdbcUtils.close(stmt);
}
return updateCount;
}
public static void execute(DataSource dataSource, String sql, Object... parameters) throws SQLException {
execute(dataSource, sql, Arrays.asList(parameters));
}
public static void execute(DataSource dataSource, String sql, List<Object> parameters) throws SQLException {
Connection conn = null;
try {
conn = dataSource.getConnection();
execute(conn, sql, parameters);
} finally {
close(conn);
}
}
public static void execute(Connection conn, String sql) throws SQLException {
execute(conn, sql, Collections.emptyList());
}
public static void execute(Connection conn, String sql, List<Object> parameters) throws SQLException {
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(sql);
setParameters(stmt, parameters);
stmt.executeUpdate();
} finally {
JdbcUtils.close(stmt);
}
}
public static List<Map<String, Object>> executeQuery(DataSource dataSource, String sql, Object... parameters)
throws SQLException {
return executeQuery(dataSource, sql, Arrays.asList(parameters));
}
public static List<Map<String, Object>> executeQuery(DataSource dataSource, String sql, List<Object> parameters)
throws SQLException {
Connection conn = null;
try {
conn = dataSource.getConnection();
return executeQuery(conn, sql, parameters);
} finally {
close(conn);
}
}
public static List<Map<String, Object>> executeQuery(Connection conn, String sql, List<Object> parameters)
throws SQLException {
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement(sql);
setParameters(stmt, parameters);
rs = stmt.executeQuery();
ResultSetMetaData rsMeta = rs.getMetaData();
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<String, Object>();
for (int i = 0, size = rsMeta.getColumnCount(); i < size; ++i) {
String columName = rsMeta.getColumnLabel(i + 1);
Object value = rs.getObject(i + 1);
row.put(columName, value);
}
rows.add(row);
}
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
return rows;
}
private static void setParameters(PreparedStatement stmt, List<Object> parameters) throws SQLException {
for (int i = 0, size = parameters.size(); i < size; ++i) {
Object param = parameters.get(i);
stmt.setObject(i + 1, param);
}
}
public static void insertToTable(DataSource dataSource, String tableName, Map<String, Object> data)
throws SQLException {
Connection conn = null;
try {
conn = dataSource.getConnection();
insertToTable(conn, tableName, data);
} finally {
close(conn);
}
}
public static void insertToTable(Connection conn, String tableName, Map<String, Object> data) throws SQLException {
String sql = makeInsertToTableSql(tableName, data.keySet());
List<Object> parameters = new ArrayList<Object>(data.values());
execute(conn, sql, parameters);
}
public static String makeInsertToTableSql(String tableName, Collection<String> names) {
StringBuilder sql = new StringBuilder() //
.append("insert into ") //
.append(tableName) //
.append("("); //
int nameCount = 0;
for (String name : names) {
if (nameCount > 0) {
sql.append(",");
}
sql.append(name);
nameCount++;
}
sql.append(") values (");
for (int i = 0; i < nameCount; ++i) {
if (i != 0) {
sql.append(",");
}
sql.append("?");
}
sql.append(")");
return sql.toString();
}
public static String findPageSql(int page, int pageSize, DbType dbType, String tableName, List<String> items){
SQLSelect sqlSelect = new SQLSelect();
SQLSelectQueryBlock queryBlock = new SQLSelectQueryBlock();
//查询的字段
for (String item : items){
queryBlock.addSelectItem(new SQLIdentifierExpr(item));
}
//查询的表
queryBlock.setFrom(new SQLExprTableSource(new SQLIdentifierExpr(tableName)));
sqlSelect.setQuery(queryBlock);
//分页
String sql = PagerUtils.limit(SQLUtils.toSQLString(sqlSelect),dbType,page,pageSize);;
System.out.println(sql);
return sql;
}
public static JobDatasource getJobDataSource(){
JobDatasource jdbcDatasource = new JobDatasource();
jdbcDatasource.setDatasourceName("openGauss");
jdbcDatasource.setJdbcUsername("xxx");
jdbcDatasource.setJdbcPassword("xxx");
jdbcDatasource.setJdbcUrl("jdbc:postgresql://xxxx:15400/postgres");
jdbcDatasource.setJdbcDriverClass("org.postgresql.Driver");
return jdbcDatasource;
}
public static void main(String[] args) {
List<String> list = new ArrayList<String>(){
{
add("*");
/*add("COMPANY_TYPE");
add("COMPANY_SCALE");
add("ORGANIZATION_ID");
add("ADDRESS");*/
}
};
findPageSql(1,20,DbType.mysql,"TB_ORACLE_DATA_SOURCE_01",list);
}
}

View File

@ -0,0 +1,70 @@
package com.szgx.kunpeng.basic.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* jwt工具类
*
* @author
*/
@ConfigurationProperties(prefix = "jwt")
@Configuration
@Slf4j
@Data
public class JwtUtils {
// @Value("${jwt.secret}")
String secret;
// @Value("${jwt.expire}")
long expire;
// @Value("${jwt.header}")
String header;
/**
* 生成jwt token
*/
public String generateToken(String userId) {
Date nowDate = new Date();
//过期时间
Date expireDate = new Date(nowDate.getTime() + expire * 1000);
return Jwts.builder()
.setHeaderParam("type", "JWT")
.setSubject(userId)
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
log.debug("validate is token error ", e);
return null;
}
}
/**
* token是否过期
*
* @return true过期
*/
public boolean isTokenExpired(Date expiration) {
return expiration.before(new Date());
}
}

View File

@ -0,0 +1,133 @@
package com.szgx.kunpeng.basic.util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* local cache tool
*
* @author xuxueli 2018-01-22 21:37:34
*/
public class LocalCacheUtil {
private static ConcurrentMap<String, LocalCacheData> cacheRepository = new ConcurrentHashMap<String, LocalCacheData>(); // 类型建议用抽象父类兼容性更好
private static class LocalCacheData{
private String key;
private Object val;
private long timeoutTime;
public LocalCacheData() {
}
public LocalCacheData(String key, Object val, long timeoutTime) {
this.key = key;
this.val = val;
this.timeoutTime = timeoutTime;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getVal() {
return val;
}
public void setVal(Object val) {
this.val = val;
}
public long getTimeoutTime() {
return timeoutTime;
}
public void setTimeoutTime(long timeoutTime) {
this.timeoutTime = timeoutTime;
}
}
/**
* set cache
*
* @param key
* @param val
* @param cacheTime
* @return
*/
public static boolean set(String key, Object val, long cacheTime){
// clean timeout cache, before set new cache (avoid cache too much)
cleanTimeoutCache();
// set new cache
if (key==null || key.trim().length()==0) {
return false;
}
if (val == null) {
remove(key);
}
if (cacheTime <= 0) {
remove(key);
}
long timeoutTime = System.currentTimeMillis() + cacheTime;
LocalCacheData localCacheData = new LocalCacheData(key, val, timeoutTime);
cacheRepository.put(localCacheData.getKey(), localCacheData);
return true;
}
/**
* remove cache
*
* @param key
* @return
*/
public static boolean remove(String key){
if (key==null || key.trim().length()==0) {
return false;
}
cacheRepository.remove(key);
return true;
}
/**
* get cache
*
* @param key
* @return
*/
public static Object get(String key){
if (key==null || key.trim().length()==0) {
return null;
}
LocalCacheData localCacheData = cacheRepository.get(key);
if (localCacheData!=null && System.currentTimeMillis()<localCacheData.getTimeoutTime()) {
return localCacheData.getVal();
} else {
remove(key);
return null;
}
}
/**
* clean timeout cache
*
* @return
*/
public static boolean cleanTimeoutCache(){
if (!cacheRepository.keySet().isEmpty()) {
for (String key: cacheRepository.keySet()) {
LocalCacheData localCacheData = cacheRepository.get(key);
if (localCacheData!=null && System.currentTimeMillis()>=localCacheData.getTimeoutTime()) {
cacheRepository.remove(key);
}
}
}
return true;
}
}

View File

@ -0,0 +1,145 @@
package com.szgx.kunpeng.basic.util;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.szgx.kunpeng.basic.common.CommonConstant;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value="接口返回对象", description="接口返回对象")
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
@ApiModelProperty(value = "成功标志")
private boolean success = true;
/**
* 返回处理消息
*/
@ApiModelProperty(value = "返回处理消息")
private String message = "请求成功!";
/**
* 返回代码
*/
@ApiModelProperty(value = "返回代码")
private Integer code = 0;
/**
* 返回数据对象 data
*/
@ApiModelProperty(value = "返回数据对象")
private T result;
// /**
// * 返回登录token 和用户ID 信息
// */
// @ApiModelProperty(value = "返回用户对象")
// private T user;
/**
* 时间戳
*/
@ApiModelProperty(value = "时间戳")
private long timestamp = System.currentTimeMillis();
public Result() {
}
public Result<T> success(String message) {
this.message = message;
this.code = CommonConstant.SC_OK_200;
this.success = true;
return this;
}
@Deprecated
public static Result<Object> ok() {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage("成功");
return r;
}
@Deprecated
public static Result<Object> ok(String msg) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
return r;
}
@Deprecated
public static Result<Object> ok(Object data) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static<T> Result<T> OK() {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage("成功");
return r;
}
public static<T> Result<T> OK(T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static<T> Result<T> OK(String msg, T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
r.setResult(data);
return r;
}
public static Result<Object> error(String msg) {
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static Result<Object> error(int code, String msg) {
Result<Object> r = new Result<Object>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static Result<Object> noauth(String msg) {
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
}
@JsonIgnore
private String onlTable;
}

View File

@ -0,0 +1,95 @@
package com.szgx.kunpeng.jdbc.controller;
import com.szgx.kunpeng.jdbc.entity.vo.DownloadWRDReportReqVO;
import com.szgx.kunpeng.jdbc.entity.vo.DownloadWRDReportResVO;
import com.szgx.kunpeng.jdbc.service.SlowSqlService;
import com.szgx.kunpeng.jdbc.service.SnapshotService;
import com.szgx.kunpeng.shell.service.ShellService;
import com.szgx.kunpeng.basic.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.sql.SQLException;
/**
* @author ly
* @create 2022-07-29-11:53
*/
@RestController
@RequestMapping("/jdbc")
@Api(description = "jdbc模块")
public class JdbcController {
@Autowired
SnapshotService snapshotService;
@Autowired
ShellService shellService;
@Autowired
SlowSqlService slowSqlService;
/**
* 获取快照列表
* @return
* @throws SQLException
*/
@GetMapping(value = "/getSnapshotList")
@ApiOperation(value = "获取所有快照",notes = "获取所有快照")
public Result<String> getSnapshotList() throws SQLException {
String result = snapshotService.getSnapshotList();
return Result.OK(result);
}
/**
* 立刻生成一次快照
* @return
* @throws SQLException
*/
@GetMapping("/generateSnapshot")
@ApiOperation(value = "立即生成一次快照")
public Result generateSnapshot() throws SQLException {
snapshotService.generateSnapshot();
return Result.OK();
}
/**
* 下载报告
* @param reqVO
* @return
* @throws IOException
*/
@PostMapping("/downloadWRDReport")
@ApiOperation(value = "下载报告", notes = "下载报告")
public Result downloadWRDReport(@Valid DownloadWRDReportReqVO reqVO) throws IOException {
DownloadWRDReportResVO wrdReportResVO;
try {
snapshotService.outputSnapshot(reqVO.getBeginSnapId(),reqVO.getEndSnapId(),reqVO.getReportType(),reqVO.getReportScope(),reqVO.getNodeName(),reqVO.getReportName());
wrdReportResVO = shellService.downloadWRDReport(reqVO.getReportName());
} catch (Exception e) {
e.printStackTrace();
return Result.error(e.getMessage());
}
return Result.OK(wrdReportResVO);
}
@GetMapping("/checkSlowSql")
@ApiOperation(value = "获取慢sql",notes = "获取慢sql")
public Result checkSlowSql(@NotBlank(message = "开始时间不能为空") String beginTime,@NotBlank(message = "结束时间不能为空") String endTime) throws SQLException {
return Result.OK(slowSqlService.checkSlowSql(beginTime, endTime));
}
}

View File

@ -0,0 +1,73 @@
package com.szgx.kunpeng.jdbc.controller;
import com.szgx.kunpeng.basic.util.Result;
import com.szgx.kunpeng.jdbc.service.SessionService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLException;
/**
* Session性能模块
*
* @author ly
* @create 2022-09-16-11:06
*/
@RestController
@RequestMapping("/session")
public class SessionController {
@Autowired
SessionService sessionService;
@GetMapping(value = "/getSessionRelation")
@ApiOperation(value = "查看session之间的阻塞关系",notes = "查看session之间的阻塞关系")
public Result<String> getSessionRelation() throws SQLException {
String result = sessionService.getSessionRelation();
return Result.OK(result);
}
@GetMapping(value = "/getBlockSessionInfo")
@ApiOperation(value = "采样blocking session信息",notes = "采样blocking session信息")
public Result<String> getBlockSessionInfo(String startTime,String endTime) throws SQLException {
String result = sessionService.getBlockSessionInfo(startTime,endTime);
return Result.OK(result);
}
@GetMapping(value = "/getMostWaitEvent")
@ApiOperation(value = "最耗资源的wait event",notes = "最耗资源的wait event")
public Result<String> getMostWaitEvent(String startTime,String endTime) throws SQLException {
String result = sessionService.getMostWaitEvent(startTime,endTime);
return Result.OK(result);
}
@GetMapping(value = "/getEventOfSessionByTime")
@ApiOperation(value = "查看最近几分钟较耗资源的session把资源都花费在哪些event上",notes = "查看最近几分钟较耗资源的session把资源都花费在哪些event上")
public Result<String> getEventOfSessionByTime(String startTime,String endTime) throws SQLException {
String result = sessionService.getEventOfSessionByTime(startTime,endTime);
return Result.OK(result);
}
@GetMapping(value = "/getEventOfSqlByTime")
@ApiOperation(value = "最近几分钟比较占资源的SQL把资源都消耗在哪些event上",notes = "最近几分钟比较占资源的SQL把资源都消耗在哪些event上")
public Result<String> getEventOfSqlByTime(String startTime,String endTime) throws SQLException {
String result = sessionService.getEventOfSqlByTime(startTime,endTime);
return Result.OK(result);
}
}

View File

@ -0,0 +1,37 @@
package com.szgx.kunpeng.jdbc.entity.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author York_Luo
* @create 2022-08-02-17:27
*/
@Data
@ApiModel
public class DownloadWRDReportReqVO {
@ApiModelProperty(example = "1", value = "查询时间段开始的snapshot的id")
@NotBlank
String beginSnapId;
@ApiModelProperty(example = "2", value = "查询时间段结束snapshot的id。默认end_snap_id大于begin_snap_id")
@NotBlank
String endSnapId;
@ApiModelProperty(example = "all",value = "指定生成report的类型。例如summary汇总数据。detail明细数据。all包含summary和detail")
@NotBlank
String reportType;
@ApiModelProperty(example = "cluster", value = "指定生成report的范围。cluster数据库级别的信息。node节点级别的信息。")
@NotBlank
String reportScope;
@ApiModelProperty(example = "",value = "在report_scope指定为node时需要把该参数指定为对应节点的名称。在report_scope为cluster时该值可以省略或者指定为空或NULL")
String nodeName;
// @ApiModelProperty(example = "C:\\Users\\Desktop",value = "本地下载路径")
// @NotBlank
// String localPath;
@ApiModelProperty(example = "report",value = "报告名字")
@NotBlank
String reportName;
}

View File

@ -0,0 +1,21 @@
package com.szgx.kunpeng.jdbc.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author ly
* @create 2022-08-13-14:21
*/
@Data
public class DownloadWRDReportResVO {
@ApiModelProperty(example = "asiatrip", value = "minio标签")
String bucketId;
@ApiModelProperty(example = "", value = "文件下载地址")
String url;
@ApiModelProperty(example = "", value = "文件名")
String fileName;
}

View File

@ -0,0 +1,16 @@
package com.szgx.kunpeng.jdbc.entity.vo;
import lombok.Data;
/**
* @author York_Luo
* @create 2022-08-01-11:15
*/
@Data
public class SnapshotResVO {
String snapshotId;
String startTs;
String endTs;
}

View File

@ -0,0 +1,41 @@
package com.szgx.kunpeng.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
public class jdbcTest {
public static void main(String[] args) {
getConnect();
}
public static void getConnect() {
//驱动类
String driver = "org.opengauss.Driver";
//数据库连接描述符
String sourceURL = "jdbc:opengauss://139.159.187.78:15400/mydb";
String username = "coder";
String passwd = "qwE_23sz123";
Connection conn = null;
try {
//加载驱动
// Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
try {
//创建连接
conn = DriverManager.getConnection(sourceURL, username, passwd);
System.out.println("Connection succeed!");
} catch (Exception e) {
e.printStackTrace();
}
}
;
}

View File

@ -0,0 +1,26 @@
package com.szgx.kunpeng.jdbc.service;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
/**
* session性能模块
*
* @author ly
* @create 2022-09-15-16:41
*/
@Service
public interface SessionService {
String getSessionRelation() throws SQLException;
String getBlockSessionInfo(String beginTime,String endTime) throws SQLException;
String getMostWaitEvent(String startTime,String endTime) throws SQLException;
String getEventOfSessionByTime(String startTime,String endTime) throws SQLException;
String getEventOfSqlByTime(String startTime,String endTime) throws SQLException;
}

View File

@ -0,0 +1,115 @@
package com.szgx.kunpeng.jdbc.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.szgx.kunpeng.basic.tool.BaseQueryTool;
import com.szgx.kunpeng.basic.tool.ExecuteResult;
import com.szgx.kunpeng.basic.tool.JobDatasource;
import com.szgx.kunpeng.basic.util.JdbcUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
import java.util.Map;
/**
* @author ly
* @create 2022-09-16-10:48
*/
@Service
@Slf4j
public class SessionServiceImpl implements SessionService {
/**
* 查看session之间的阻塞关系
*
* @return
* @throws SQLException
*/
@Override
public String getSessionRelation() throws SQLException {
String sql = "select * from pg_thread_wait_status";
return getSqlExecuteResult(sql);
}
/**
* 采样blocking session信息
* @return
*/
@Override
public String getBlockSessionInfo(String startTime,String endTime) throws SQLException {
String sql=String.format("select * from DBE_PERF.local_active_session where start_time between '%s' and '%s'",startTime,endTime);
return getSqlExecuteResult(sql);
}
/**
* 最耗资源的wait event
* @return
*/
@Override
public String getMostWaitEvent(String startTime,String endTime) throws SQLException {
String sql = String.format("SELECT * " +
" FROM dbe_perf.wait_events s, (" +
" SELECT event, COUNT (*)" +
" FROM dbe_perf.local_active_session" +
" WHERE sample_time between '%s' and '%s'"+
" GROUP BY event)t WHERE s.event = t.event ORDER BY count DESC",startTime,endTime);
return getSqlExecuteResult(sql);
}
/**
* 查看最近几分钟较耗资源的session把资源都花费在哪些event上
* @return
*/
@Override
public String getEventOfSessionByTime(String startTime,String endTime) throws SQLException {
// String sql = "SELECT sessionid, start_time, event, count" +
String sql = String.format("SELECT * " +
" FROM (" +
" SELECT sessionid, start_time, event, COUNT(*)" +
" FROM dbe_perf.local_active_session" +
" WHERE sample_time between '%s' and '%s'"+
" GROUP BY sessionid, start_time, event) as t ORDER BY SUM(t.count) OVER (PARTITION BY t. sessionid, start_time)DESC, t.event",startTime,endTime);
return getSqlExecuteResult(sql);
}
/**
* 最近几分钟比较占资源的SQL把资源都消耗在哪些event上
* @return
* @throws SQLException
*/
@Override
public String getEventOfSqlByTime(String startTime,String endTime) throws SQLException {
// String sql = "SELECT query_id, event, count" +
String sql = String.format("SELECT * " +
" FROM (" +
" SELECT query_id, event, COUNT(*)" +
" FROM dbe_perf.local_active_session" +
" WHERE sample_time between '%s' and '%s'"+
" GROUP BY query_id, event) t ORDER BY SUM (t.count) OVER (PARTITION BY t.query_id ) DESC, t.event DESC",startTime,endTime);
return getSqlExecuteResult(sql);
}
String getSqlExecuteResult(String sql) throws SQLException {
JobDatasource jdbcDatasource = JdbcUtils.getJobDataSource();
BaseQueryTool baseQueryTool = new BaseQueryTool(jdbcDatasource);
ExecuteResult result = baseQueryTool.executeSelectSql(sql);
JSONArray array = new JSONArray();
if (result.getTable() != null) {
for (Map map : result.getTable()) {
JSONObject object = new JSONObject(map);
array.add(object);
}
}
return array.toString();
}
}

View File

@ -0,0 +1,17 @@
package com.szgx.kunpeng.jdbc.service;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
/**
* 慢sql
*
* @author ly
* @create 2022-08-18-11:02
*/
@Service
public interface SlowSqlService {
String checkSlowSql(String beginTime,String endTime) throws SQLException;
}

View File

@ -0,0 +1,39 @@
package com.szgx.kunpeng.jdbc.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.szgx.kunpeng.basic.tool.BaseQueryTool;
import com.szgx.kunpeng.basic.tool.ExecuteResult;
import com.szgx.kunpeng.basic.tool.JobDatasource;
import com.szgx.kunpeng.basic.util.JdbcUtils;
import org.springframework.stereotype.Service;
import java.sql.SQLException;
import java.util.Map;
/**
* 慢sql
*
* @author ly
* @create 2022-08-18-11:02
*/
@Service
public class SlowSqlServiceImpl implements SlowSqlService{
@Override
public String checkSlowSql(String beginTime, String endTime) throws SQLException {
JobDatasource jdbcDatasource = JdbcUtils.getJobDataSource();
BaseQueryTool baseQueryTool = new BaseQueryTool(jdbcDatasource);
ExecuteResult result = baseQueryTool.executeSelectSql(String.format("select * from dbe_perf.get_global_full_sql_by_timestamp('%s','%s')", beginTime, endTime));
JSONArray array = new JSONArray();
for (Map map : result.getTable()) {
JSONObject object = new JSONObject(map);
array.add(object);
}
return array.toString();
}
}

View File

@ -0,0 +1,24 @@
package com.szgx.kunpeng.jdbc.service;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.sql.SQLException;
/**
* 快照相关
*
* @author York_Luo
* @create 2022-08-01-11:33
*/
@Service
public interface SnapshotService {
String getSnapshotList() throws SQLException;
void generateSnapshot() throws SQLException;
void outputSnapshot(String beginSnapId,String endSnapId,String reportType,String reportScope,String nodeName,String reportName) throws SQLException, IOException;
}

View File

@ -0,0 +1,80 @@
package com.szgx.kunpeng.jdbc.service;
import com.alibaba.fastjson.JSONObject;
import com.szgx.kunpeng.basic.util.JdbcUtils;
import com.szgx.kunpeng.shell.service.ShellService;
import com.szgx.kunpeng.basic.tool.BaseQueryTool;
import com.szgx.kunpeng.basic.tool.ExecuteResult;
import com.szgx.kunpeng.basic.tool.JobDatasource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/**
* @author York_Luo
* @create 2022-08-01-11:37
*/
@Service
public class SnapshotServiceImpl implements SnapshotService {
String dataSourceName;
String username;
String password;
String url;
@Autowired
ShellService shellService;
/**
* 获取快照列表
* @return
* @throws SQLException
*/
@Override
public String getSnapshotList() throws SQLException {
JobDatasource jdbcDatasource = JdbcUtils.getJobDataSource();
BaseQueryTool baseQueryTool = new BaseQueryTool(jdbcDatasource);
ExecuteResult result = baseQueryTool.executeSelectSql("select * from snapshot.snapshot");
List<Map<String, Object>> list = result.getTable();
String resultJson = JSONObject.toJSONString(list);
return resultJson;
}
/**
* 生成一次快照
*/
@Override
public void generateSnapshot() throws SQLException {
JobDatasource jdbcDatasource = JdbcUtils.getJobDataSource();
BaseQueryTool baseQueryTool = new BaseQueryTool(jdbcDatasource);
baseQueryTool.executeSelectSql("select create_wdr_snapshot()");
}
/**
* 输出快照到文件
*/
@Override
public void outputSnapshot(String beginSnapId,String endSnapId,String reportType,String reportScope,String nodeName,String reportName) throws SQLException, IOException {
JobDatasource jdbcDatasource = JdbcUtils.getJobDataSource();
BaseQueryTool baseQueryTool = new BaseQueryTool(jdbcDatasource);
// baseQueryTool.executeSelectSql("select count(1) from tb_test2; ");
baseQueryTool.executeSelectSql("\\o \\a \\t /home/omm/test2.html;");
// shellService.executeShell(beginSnapId,endSnapId,reportType,reportScope,nodeName,reportName);
// baseQueryTool.executeSelectSql(String.format("select generate_wdr_report(%s,%s,'%s','%s',%s)",beginSnapId,endSnapId,reportType,reportScope,nodeName));
}
}

View File

@ -0,0 +1,43 @@
package com.szgx.kunpeng.screen.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.szgx.kunpeng.screen.service.PrometheusService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhangrb
* @date 2022/8/11 10:32
*/
@RestController
@RequestMapping("/screen")
public class PrometheusController {
@Autowired
private PrometheusService prometheusService;
/**
* 获取系统指标数据
*/
@GetMapping("/system")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取系统指标数据", notes = "")
public Object system(Integer type, String startTime, String step) {
return prometheusService.systemData(type,startTime,step);
}
/**
* 获取高斯指标数据
*/
@GetMapping("/gauss")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "获取高斯指标数据", notes = "")
public Object gauss(Integer type, String startTime, String step) {
return prometheusService.gaussData(type,startTime,step);
}
}

View File

@ -0,0 +1,5 @@
/**
* @author zhangrb
* @date 2022/8/11 10:29
*/
package com.szgx.kunpeng.screen;

View File

@ -0,0 +1,13 @@
package com.szgx.kunpeng.screen.service;
/**
* @author zhangrb
* @date 2022/8/11 15:07
*/
public interface PrometheusService {
Object systemData(Integer type, String startTime, String step);
Object gaussData(Integer type, String startTime, String step);
}

View File

@ -0,0 +1,90 @@
package com.szgx.kunpeng.screen.service.impl;
import com.szgx.kunpeng.basic.common.PrometheusApiConstant;
import com.szgx.kunpeng.screen.service.PrometheusService;
import com.szgx.kunpeng.basic.util.HttpClientUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author zhangrb
* @date 2022/8/11 15:08
*/
@Service
public class PrometheusServiceImpl implements PrometheusService {
@Value("${screen.baseurl}")
private String baseUrl;
@Override
public Object systemData(Integer type, String startTime, String step) {
return HttpClientUtil.doGet(baseUrl + getSystemUri(type,startTime,step));
}
@Override
public Object gaussData(Integer type, String startTime, String step) {
return HttpClientUtil.doGet(baseUrl + getGaussUri(type,startTime,step));
}
private String getGaussUri(Integer type, String startTime, String step) {
StringBuilder uri = new StringBuilder();
Long end = System.currentTimeMillis() / 1000;
Long start = startTime == null? (end - 3600) : Long.valueOf(startTime);
switch (type) {
case 1:
uri.append(PrometheusApiConstant.API_GS_CONNECT_URL);
break;
case 2:
uri.append(PrometheusApiConstant.API_GS_DISK_URL);
break;
case 3:
uri.append(PrometheusApiConstant.API_GS_LOCK_URL);
break;
case 4:
uri.append(PrometheusApiConstant.API_GS_DEADLOCK_URL);
break;
}
return uri.append("&start=").append(start).append("&end=").append(end).append("&step=").append(step == null? 14 : step).toString();
}
/**
* 设置开始时间结束时间
*
* @param type
* @return
*/
private String getSystemUri(Integer type, String startTime, String step) {
StringBuilder uri = new StringBuilder();
Long end = System.currentTimeMillis() / 1000;
Long start = startTime == null? (end - 3600) : Long.valueOf(startTime);
switch (type) {
case 1:
uri.append(PrometheusApiConstant.API_CPU_URL);
break;
case 2:
uri.append(PrometheusApiConstant.API_RAM_URL);
break;
case 3:
uri.append(PrometheusApiConstant.API_DISK_URL);
break;
case 4:
uri.append(PrometheusApiConstant.API_DISK_R_W_IO_URL);
break;
case 5:
uri.append(PrometheusApiConstant.API_DISK_R_URL);
break;
case 6:
uri.append(PrometheusApiConstant.API_DISK_W_URL);
break;
case 7:
uri.append(PrometheusApiConstant.API_DK_UP_URL);
break;
case 8:
uri.append(PrometheusApiConstant.API_DK_DOWN_URL);
break;
}
return uri.append("&start=").append(start).append("&end=").append(end).append("&step=").append(step == null? 14 : step).toString();
}
}

View File

@ -0,0 +1,83 @@
package com.szgx.kunpeng.shell;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ShellTest {
public static void main(String[] args) {
String hostname = "139.159.187.78";//远程机器IP
String username = "root";//登录用户名
String password = "keMd@!vD24dSf2r";//登录密码
try {
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
///是否登录成功
if (isAuthenticated == false) {
throw new IOException("登录失败!!!");
}
SCPClient scpClient = conn.createSCPClient();
scpClient.get("/home/omm/test.html","C:\\Users\\luoy\\Desktop");
// Session sess = conn.openSession();
// //执行命令
// sess.execCommand("uname -a && date && uptime && who");
// InputStream stdout = new StreamGobbler(sess.getStdout());
// BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
// while (true) {
// String line = br.readLine();
// if (line == null) {
// break;
// }
// System.out.println("linux返回结果"+line);
// }
// System.out.println("ExitCode: " + sess.getExitStatus());
// //关闭连接
// sess.close();
conn.close();
} catch (IOException e) {
e.printStackTrace(System.err);
System.exit(2);
}
}
/**
* @param pathOrCommand 脚本路径或者命令
* @return
*/
public static List<String> exceShell(String pathOrCommand) {
List<String> result = new ArrayList<>();
try {
// 执行脚本
Process ps = Runtime.getRuntime().exec(pathOrCommand);
int exitValue = ps.waitFor();
if (0 != exitValue) {
System.out.println("call shell failed. error code is :" + exitValue);
}
// 只能接收脚本echo打印的数据并且是echo打印的最后一次数据
BufferedInputStream in = new BufferedInputStream(ps.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println("脚本返回的数据如下: " + line);
result.add(line);
}
in.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -0,0 +1,19 @@
package com.szgx.kunpeng.shell.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Shell操作相关接口
*
* @author York_Luo
* @create 2022-08-02-9:42
*/
@RestController
@RequestMapping("/shell")
public class ShellController {
}

View File

@ -0,0 +1,25 @@
package com.szgx.kunpeng.shell.service;
import com.szgx.kunpeng.jdbc.entity.vo.DownloadWRDReportResVO;
import io.minio.errors.*;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.rmi.ServerException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* shell操作相关
*
* @author York_Luo
* @create 2022-08-02-10:04
*/
@Service
public interface ShellService {
DownloadWRDReportResVO downloadWRDReport(String reportName) throws IOException, InvalidPortException, InvalidEndpointException, NoSuchAlgorithmException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, InvalidBucketNameException, XmlParserException, ErrorResponseException, RegionConflictException, ServerException, InvalidExpiresRangeException;
void executeShell(String beginId,String endId,String reportType,String reportScope,String nodeName,String reportName) throws IOException;
}

View File

@ -0,0 +1,110 @@
package com.szgx.kunpeng.shell.service.impl;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import com.szgx.kunpeng.jdbc.entity.vo.DownloadWRDReportResVO;
import com.szgx.kunpeng.shell.service.ShellService;
import io.minio.MinioClient;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.rmi.ServerException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* shell操作相关
*
* @author York_Luo
* @create 2022-08-02-10:05
*/
@Service
public class ShellServiceImpl implements ShellService {
@Value("${shell.hostname}")
String hostname;
@Value("${shell.username}")
String username;
@Value("${shell.password}")
String password;
@Value("${minio.url}")
String url;
@Value("${minio.accessKey}")
String accessKey;
@Value("${minio.secretKey}")
String secretKey;
@Override
public DownloadWRDReportResVO downloadWRDReport(String reportName) throws IOException, InvalidPortException, InvalidEndpointException, NoSuchAlgorithmException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, InvalidBucketNameException, XmlParserException, ErrorResponseException, RegionConflictException, ServerException, InvalidExpiresRangeException {
Connection conn = getConnection(hostname, username, password);
SCPClient scpClient = conn.createSCPClient();
String projectPath = System.getProperty("user.dir");
String filePath = projectPath + "/WRDReport/";
scpClient.get("/home/omm/" + reportName + ".html", filePath);
MinioClient minioClient = new MinioClient(url, accessKey, secretKey, "share");
String id = "cloud-monitor";
// 检查存储桶是否已经存在
boolean isExist = minioClient.bucketExists(id);
if (isExist) {
System.out.println("Bucket already exists.");
} else {
// 创建一个名为asiatrip的存储桶
minioClient.makeBucket(id);
}
minioClient.putObject(id, reportName + ".html", filePath + reportName + ".html", null);
DownloadWRDReportResVO reportResVO = new DownloadWRDReportResVO();
String url = minioClient.presignedGetObject(id, reportName + ".html");
reportResVO.setBucketId(id);
reportResVO.setFileName(reportName + ".html");
reportResVO.setUrl(url);
return reportResVO;
}
@Override
public void executeShell(String beginId, String endId, String reportType, String reportScope, String nodeName, String reportName) throws IOException {
Connection conn = getConnection(hostname, username, password);
Session session = conn.openSession();
// session.execCommand("/home/omm/format.sh '\\t \\a \\o test2.html \nselect generate_wdr_report("+beginId+","+endId+", \'all\', \'cluster\', pgxc_node_str()::cstring);'");
// session.execCommand("/home/omm/generate.sh '\\t \\a \\o test2.html; \nselect generate_wdr_report(,214, \'all\', \'cluster\', pgxc_node_str()::cstring);'");
if ("node".equals(reportScope)) {
nodeName = "pgxc_node_str()::cstring";
}
if ("cluster".equals(reportScope)) {
nodeName = null;
}
session.execCommand("/home/omm/generate.sh '" + beginId + "' '" + endId + "' '" + reportType + "' '" + reportScope + "' '" + nodeName + "' '" + reportName + "'");
}
/**
* 通过用户名密码获取shell链接
*
* @param hostname
* @param username
* @param password
* @return
*/
private Connection getConnection(String hostname, String username, String password) throws IOException {
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
///是否登录成功
if (isAuthenticated == false) {
throw new IOException("登录失败!!!");
}
return conn;
}
}

View File

@ -0,0 +1,30 @@
spring:
datasource:
url: jdbc:postgresql://xxxx:15400/mydb
username: xxxx
password: xxx
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.postgresql.Driver
datasource-name:
#Mybatis 日志
logging:
level: info
screen:
baseurl: http://xxx:9090
jwt:
secret: xxx
expire: 1000
header: opengauss
shell:
hostname: xxxx
username: xxxx
password: xxxx
minio:
url: http://xxxx:9000
accessKey: xxxx
secretKey: xxxxx

View File

@ -0,0 +1,51 @@
package com.szgx.kunpeng;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.sql.Connection;
import java.sql.DriverManager;
@SpringBootTest
class KunpengApplicationTests {
@Test
void contextLoads() {
}
@Test
public void getConnect()
{
//驱动类
String driver = "org.openGauss.Driver";
//数据库连接描述符
String sourceURL = "jdbc:postgresql://139.159.187.78:15400/mydb";
String username="coder";
String passwd = "qwE_23sz123";
Connection conn = null;
try
{
//加载驱动
Class.forName(driver);
}
catch( Exception e )
{
e.printStackTrace();
}
try
{
//创建连接
conn = DriverManager.getConnection(sourceURL, username, passwd);
System.out.println("Connection succeed!");
}
catch(Exception e)
{
e.printStackTrace();
}
};
}

View File

@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

View File

@ -0,0 +1,5 @@
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = 'http://localhost:8080'

View File

@ -0,0 +1,6 @@
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = '/api'

View File

@ -0,0 +1,4 @@
build/*.js
src/assets
public
dist

View File

@ -0,0 +1,200 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never'],
'vue/html-self-closing': 0
}
}

View File

@ -0,0 +1,16 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
tests/**/coverage/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present PanJiaChen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,111 @@
# vue-admin-template
> 这是一个极简的 vue admin 管理后台。它只包含了 Element UI & axios & iconfont & permission control & lint这些搭建后台必要的东西。
[线上地址](http://panjiachen.github.io/vue-admin-template)
[国内访问](https://panjiachen.gitee.io/vue-admin-template)
目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0),它不依赖 `vue-cli`
<p align="center">
<b>SPONSORED BY</b>
</p>
<p align="center">
<a href="https://finclip.com?from=vue_element" title="FinClip" target="_blank">
<img height="200px" src="https://gitee.com/panjiachen/gitee-cdn/raw/master/vue%E8%B5%9E%E5%8A%A9.png" title="FinClip">
</a>
</p>
## Extra
如果你想要根据用户角色来动态生成侧边栏和 router你可以使用该分支[permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
## 相关项目
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板,专门针对本项目的文章,算作是一篇文档)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
## Build Setup
```bash
# 克隆项目
git clone https://github.com/PanJiaChen/vue-admin-template.git
# 进入项目目录
cd vue-admin-template
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org
# 启动服务
npm run dev
```
浏览器访问 [http://localhost:9528](http://localhost:9528)
## 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
```
## 其它
```bash
# 预览发布环境效果
npm run preview
# 预览发布环境效果 + 静态资源分析
npm run preview -- --report
# 代码格式检查
npm run lint
# 代码格式检查并自动修复
npm run lint -- --fix
```
更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
## 购买贴纸
你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,我们将获得 2 元的捐赠。
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen

View File

@ -0,0 +1,99 @@
# vue-admin-template
English | [简体中文](./README-zh.md)
> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
**Live demo:** http://panjiachen.github.io/vue-admin-template
**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
<p align="center">
<b>SPONSORED BY</b>
</p>
<p align="center">
<a href="https://finclip.com?from=vue_element" title="FinClip" target="_blank">
<img height="200px" src="https://gitee.com/panjiachen/gitee-cdn/raw/master/vue%E8%B5%9E%E5%8A%A9.png" title="FinClip">
</a>
</p>
## Build Setup
```bash
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git
# enter the project directory
cd vue-admin-template
# install dependency
npm install
# develop
npm run dev
```
This will automatically open http://localhost:9528
## Build
```bash
# build for test environment
npm run build:stage
# build for production environment
npm run build:prod
```
## Advanced
```bash
# preview the release environment effect
npm run preview
# preview the release environment effect + static resource analysis
npm run preview -- --report
# code format check
npm run lint
# code format check and auto fix
npm run lint -- --fix
```
Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
## Demo
![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
## Extra
If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
## Related Project
- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
## Browsers support
Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
## License
[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
Copyright (c) 2017-present PanJiaChen

View File

@ -0,0 +1,14 @@
module.exports = {
presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
'@vue/cli-plugin-babel/preset'
],
'env': {
'development': {
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
'plugins': ['dynamic-import-node']
}
}
}

View File

@ -0,0 +1,35 @@
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}

Binary file not shown.

View File

@ -0,0 +1,24 @@
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
coverageDirectory: '<rootDir>/tests/unit/coverage',
// 'collectCoverage': true,
'coverageReporters': [
'lcov',
'text-summary'
],
testURL: 'http://localhost/'
}

View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

View File

@ -0,0 +1,57 @@
const Mock = require('mockjs')
const { param2Obj } = require('./utils')
const user = require('./user')
const table = require('./table')
const mocks = [
...user,
...table
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
function mockXHR() {
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
module.exports = {
mocks,
mockXHR
}

View File

@ -0,0 +1,81 @@
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const Mock = require('mockjs')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { mocks } = require('./index.js')
const mocksForServer = mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
for (const mock of mocksForServer) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocksForServer).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
type: type || 'get',
response(req, res) {
console.log('request invoke:' + req.path)
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
module.exports = app => {
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}

View File

@ -0,0 +1,29 @@
const Mock = require('mockjs')
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
module.exports = [
{
url: '/vue-admin-template/table/list',
type: 'get',
response: config => {
const items = data.items
return {
code: 20000,
data: {
total: items.length,
items: items
}
}
}
}
]

View File

@ -0,0 +1,84 @@
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
'editor-token': {
roles: ['editor'],
introduction: 'I am an editor',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
module.exports = [
// user login
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// get user info
{
url: '/vue-admin-template/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
const info = users[token]
// mock error
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// user logout
{
url: '/vue-admin-template/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]

View File

@ -0,0 +1,25 @@
/**
* @param {string} url
* @returns {Object}
*/
function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
module.exports = {
param2Obj
}

View File

@ -0,0 +1,64 @@
{
"name": "snapshot",
"version": "4.4.0",
"description": "A Prometheus monitor project",
"author": "",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit"
},
"dependencies": {
"axios": "0.18.1",
"core-js": "^3.24.0",
"echarts": "^5.3.3",
"element-ui": "2.13.2",
"js-cookie": "2.2.0",
"minio": "^7.0.30",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"vue": "2.6.10",
"vue-router": "3.0.6",
"vuex": "3.1.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.4",
"@vue/cli-plugin-eslint": "4.4.4",
"@vue/cli-plugin-unit-jest": "4.4.4",
"@vue/cli-service": "4.4.4",
"@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "9.5.1",
"babel-eslint": "10.1.0",
"babel-jest": "23.6.0",
"babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "2.4.2",
"connect": "3.6.6",
"eslint": "6.7.2",
"eslint-plugin-vue": "6.2.2",
"html-webpack-plugin": "3.2.0",
"mockjs": "1.0.1-beta3",
"runjs": "4.3.2",
"sass": "1.26.8",
"sass-loader": "8.0.2",
"script-ext-html-webpack-plugin": "2.1.3",
"serve-static": "1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.2",
"vue-template-compiler": "2.6.10"
},
"browserslist": [
"> 1%",
"last 2 versions"
],
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"license": "MIT"
}

View File

@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
'plugins': {
// to edit target browsers: use "browserslist" field in package.json
'autoprefixer': {}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon2.ico">
<title><%= webpackConfig.name %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -0,0 +1,11 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>

View File

@ -0,0 +1,92 @@
import request from '@/utils/request'
export function login(params) {
return request({
url: '/basic/login',
method: 'post',
data: params
})
}
export function snapshotListApi() {
return request({
url: '/jdbc/getSnapshotList',
method: 'get'
})
}
export function snapshotGenerateApi() {
return request({
url: '/jdbc/generateSnapshot',
method: 'get'
})
}
export function snapshotDownloadApi(params) {
return request({
url: "/jdbc/downloadWRDReport",
method: 'post',
params
})
}
export function slowSql(params) {
return request({
url: "/jdbc/checkSlowSql",
method: 'get',
params
})
}
export function monitorApi1(params) {
return request({
url: '/screen/system',
method: 'get',
params
})
}
export function monitorApi2(params) {
return request({
url: '/screen/gauss',
method: 'get',
params
})
}
// session性能分析
export function getSessionRelationApi(params) {
return request({
url: '/session/getSessionRelation',
method: 'get',
params
})
}
export function getBlockSessionInfoApi(params) {
return request({
url: '/session/getBlockSessionInfo',
method: 'get',
params
})
}
export function getMostWaitEventApi(params) {
return request({
url: '/session/getMostWaitEvent',
method: 'get',
params
})
}
export function getEventOfSessionByTimeApi(params) {
return request({
url: '/session/getEventOfSessionByTime',
method: 'get',
params
})
}
export function getEventOfSqlByTimeApi(params) {
return request({
url: '/session/getEventOfSqlByTime',
method: 'get',
params
})
}

View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
export function getList(params) {
return request({
url: '/vue-admin-template/table/list',
method: 'get',
params
})
}

View File

@ -0,0 +1,24 @@
import request from '@/utils/request'
export function login(data) {
return request({
url: '/vue-admin-template/user/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/vue-admin-template/user/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/vue-admin-template/user/logout',
method: 'post'
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,78 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp'
export default {
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) {
// matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>

View File

@ -0,0 +1,9 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

View File

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

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -0,0 +1 @@
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

After

Width:  |  Height:  |  Size: 944 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

After

Width:  |  Height:  |  Size: 821 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

After

Width:  |  Height:  |  Size: 623 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

After

Width:  |  Height:  |  Size: 597 B

View File

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1 @@
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

After

Width:  |  Height:  |  Size: 440 B

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