Initial commit all
parent
9ba4f3027d
commit
c063b1a0ec
bocloud.sms.booter
src/main
java/com/bocloud/sms/booter
controller
bocloud.sms.service
src/main/java/com/bocloud/sms/interfaces
|
@ -0,0 +1,228 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>bocloud.sms</artifactId>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<version>6.5.0-LTS-SZ</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>bocloud.sms.booter</artifactId>
|
||||
<version>${bocloud.booter.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.platform</groupId>
|
||||
<artifactId>jakarta.jakartaee-api</artifactId>
|
||||
<version>10.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
<artifactId>jakarta.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>2.0.7</version>
|
||||
</dependency>
|
||||
<!-- Spring boot Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Bocloud相关配置 -->
|
||||
<dependency>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<artifactId>bocloud.sms.service</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<artifactId>bocloud.boot.common</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<artifactId>bocloud.cmp.core</artifactId>
|
||||
<version>${bocloud.core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.freedom</groupId>
|
||||
<artifactId>megatron.microservice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-websocket</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.websocket</groupId>
|
||||
<artifactId>jakarta.websocket-api</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.23.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<parameters>true</parameters>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.bocloud.sms.booter.Application</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
<useUniqueVersions>false</useUniqueVersions>
|
||||
<classpathPrefix>libs/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<type>jar</type>
|
||||
<includeTypes>jar</includeTypes>
|
||||
<includeScope>runtime</includeScope>
|
||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>com.gitee.starblues</groupId>-->
|
||||
<!-- <artifactId>spring-brick-maven-packager</artifactId>-->
|
||||
<!-- <version>${spring-brick.version}</version>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <mode>dev</mode>-->
|
||||
<!-- <mainConfig>-->
|
||||
<!-- <mainClass>com.bocloud.sms.booter.Application</mainClass>-->
|
||||
<!-- </mainConfig>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- <executions>-->
|
||||
<!-- <execution>-->
|
||||
<!-- <goals>-->
|
||||
<!-- <goal>repackage</goal>-->
|
||||
<!-- </goals>-->
|
||||
<!-- </execution>-->
|
||||
<!-- </executions>-->
|
||||
<!-- </plugin>-->
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>bocloud.booter.tomcat</id>
|
||||
<properties>
|
||||
<bocloud.booter.version>6.5.0-LTS-SZ</bocloud.booter.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bocloud.booter.tongweb</id>
|
||||
<properties>
|
||||
<bocloud.booter.version>6.5.0-LTS-SZ-TONGWEB</bocloud.booter.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.tongweb</groupId>
|
||||
<artifactId>tongweb-embed</artifactId>
|
||||
<version>7.0.E.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tongweb.springboot</groupId>
|
||||
<artifactId>tongweb-spring-boot-starter</artifactId>
|
||||
<version>2.x.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tongweb.springboot</groupId>
|
||||
<artifactId>tongweb-spring-boot-websocket</artifactId>
|
||||
<version>2.x.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,20 @@
|
|||
package com.bocloud.sms.booter;
|
||||
|
||||
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* @author dmw
|
||||
*/
|
||||
@EnableRabbit
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
@ComponentScan(value = {"com.bocloud", "com.megatron"})
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.bocloud.sms.entity.ApiToken;
|
||||
import com.bocloud.sms.entity.Role;
|
||||
import com.bocloud.sms.entity.Tenant;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.entity.UserGroup;
|
||||
import com.bocloud.sms.repository.ApiTokenRepository;
|
||||
import com.bocloud.sms.repository.RoleRepository;
|
||||
import com.bocloud.sms.repository.TenantRepository;
|
||||
import com.bocloud.sms.repository.UserGroupRepository;
|
||||
import com.bocloud.sms.repository.UserRepository;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @since 2020/3/25 周三 14:06
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AccountCache implements InitializingBean {
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final TenantRepository tenantRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final RoleRepository roleRepository;
|
||||
private final UserGroupRepository userGroupRepository;
|
||||
private final ApiTokenRepository apiTokenRepository;
|
||||
private final ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
public AccountCache(StringRedisTemplate redisTemplate, TenantRepository tenantRepository,
|
||||
UserRepository userRepository, RoleRepository roleRepository, UserGroupRepository userGroupRepository,
|
||||
ApiTokenRepository apiTokenRepository, ThreadPoolTaskExecutor taskExecutor) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.tenantRepository = tenantRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.roleRepository = roleRepository;
|
||||
this.userGroupRepository = userGroupRepository;
|
||||
this.apiTokenRepository = apiTokenRepository;
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
public void putAccountCache(RequestContext.Catalog catalog, Long id, String account) {
|
||||
String key = catalog.name() + "_" + id;
|
||||
this.redisTemplate.opsForValue().set(key, account);
|
||||
}
|
||||
|
||||
public void putNameCache(RequestContext.Catalog catalog, Long id, String name) {
|
||||
String key = catalog.name() + "_Name_" + id;
|
||||
this.redisTemplate.opsForValue().set(key, name);
|
||||
}
|
||||
|
||||
public void putRoleCache(Long id, String name) {
|
||||
this.redisTemplate.opsForValue().set("Role_Name_" + id, name);
|
||||
}
|
||||
|
||||
public void putUserGroupCache(Long id, String name) {
|
||||
this.redisTemplate.opsForValue().set("Group_Name_" + id, name);
|
||||
}
|
||||
|
||||
public void putApiTokenCache(String token, String apis) {
|
||||
this.redisTemplate.opsForValue().set("Api_Token_" + token, apis);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中用户账号
|
||||
*
|
||||
* @param id
|
||||
* 用户id
|
||||
* @return
|
||||
*/
|
||||
public String getUserAccount(Long id) {
|
||||
return redisTemplate.opsForValue().get(RequestContext.Catalog.User.name() + "_" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中用户名称
|
||||
*
|
||||
* @param id
|
||||
* 用户id
|
||||
* @return
|
||||
*/
|
||||
public String getUserName(Long id) {
|
||||
return redisTemplate.opsForValue().get(RequestContext.Catalog.User.name() + "_Name_" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中租户账号
|
||||
*
|
||||
* @param id
|
||||
* 租户id
|
||||
* @return
|
||||
*/
|
||||
public String getTenantAccount(Long id) {
|
||||
return redisTemplate.opsForValue().get(RequestContext.Catalog.Tenant.name() + "_" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中租户名称
|
||||
*
|
||||
* @param id
|
||||
* 租户id
|
||||
* @return
|
||||
*/
|
||||
public String getTenantName(Long id) {
|
||||
return redisTemplate.opsForValue().get(RequestContext.Catalog.Tenant.name() + "_Name_" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中角色名称
|
||||
*
|
||||
* @param id
|
||||
* 租户id
|
||||
* @return
|
||||
*/
|
||||
public String getRoleName(Long id) {
|
||||
return redisTemplate.opsForValue().get("Role_Name_" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存中用户组名称
|
||||
*
|
||||
* @param id
|
||||
* 租户id
|
||||
* @return
|
||||
*/
|
||||
public String getUserGroupName(Long id) {
|
||||
return redisTemplate.opsForValue().get("Group_Name_" + id);
|
||||
}
|
||||
|
||||
public String getApiToken(String api) {
|
||||
return redisTemplate.opsForValue().get("Api_Token_" + api);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
taskExecutor.execute(this::addTenantCache);
|
||||
taskExecutor.execute(this::addUserCache);
|
||||
taskExecutor.execute(this::addRoleCache);
|
||||
taskExecutor.execute(this::addUserGroupCache);
|
||||
taskExecutor.execute(this::addApiTokenCache);
|
||||
}
|
||||
|
||||
public void addTenantCache() {
|
||||
try {
|
||||
List<Tenant> tenants = tenantRepository.listAll();
|
||||
// 缓存租户账号和租户名
|
||||
for (Tenant tenant : tenants) {
|
||||
if (!tenant.getDeleted()) {
|
||||
putAccountCache(RequestContext.Catalog.Tenant, tenant.getId(), tenant.getAccount());
|
||||
}
|
||||
putNameCache(RequestContext.Catalog.Tenant, tenant.getId(), tenant.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("put tenant cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addUserCache() {
|
||||
try {
|
||||
List<User> users = userRepository.listAll();
|
||||
// 缓存用户账号和用户名
|
||||
for (User user : users) {
|
||||
if (!user.getDeleted()) {
|
||||
putAccountCache(RequestContext.Catalog.User, user.getId(), user.getAccount());
|
||||
}
|
||||
putNameCache(RequestContext.Catalog.User, user.getId(), user.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("put user cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addRoleCache() {
|
||||
try {
|
||||
List<Role> roles = roleRepository.list();
|
||||
// 缓存角色名
|
||||
for (Role role : roles) {
|
||||
putRoleCache(role.getId(), role.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("put role cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addUserGroupCache() {
|
||||
try {
|
||||
List<UserGroup> groups = userGroupRepository.list();
|
||||
// 缓存角色名
|
||||
for (UserGroup group : groups) {
|
||||
putUserGroupCache(group.getId(), group.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("put user group cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addApiTokenCache() {
|
||||
try {
|
||||
List<ApiToken> tokens = apiTokenRepository.listAll();
|
||||
// 缓存角色名
|
||||
for (ApiToken token : tokens) {
|
||||
if (!token.getEnabled()) {
|
||||
continue;
|
||||
}
|
||||
putApiTokenCache(token.getToken(), token.getApis());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("put api token cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.entity.Dictionary;
|
||||
import com.bocloud.sms.interfaces.DictService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @since 2020/3/25 周三 14:06
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DictCache implements InitializingBean {
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final DictService dictService;
|
||||
private final ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
public DictCache(StringRedisTemplate redisTemplate, DictService dictService, ThreadPoolTaskExecutor taskExecutor) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.dictService = dictService;
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
public void putCache(String code, String value) {
|
||||
String key = Dictionary.class.getSimpleName() + "_" + code;
|
||||
this.redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
taskExecutor.execute(this::addOsNamesCache);
|
||||
taskExecutor.execute(this::addDataCenterCache);
|
||||
}
|
||||
|
||||
public void addOsNamesCache() {
|
||||
try {
|
||||
List<String> list = dictService.getAllOsName();
|
||||
putCache("OS_CATEGORY_TASK", JSONObject.toJSONString(list));
|
||||
} catch (Exception e) {
|
||||
log.error("put os name cache error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDataCenterCache() {
|
||||
try {
|
||||
Map<String,String> map = dictService.getAllDataCenter();
|
||||
putCache("DATA_CENTER", JSONObject.toJSONString(map));
|
||||
} catch (Exception e) {
|
||||
log.error("put data center cache error,", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import com.bocloud.cmp.boot.model.BoCloudExchange;
|
||||
import com.bocloud.cmp.core.encrypt.AbstractEncryptHandler;
|
||||
import com.bocloud.sms.booter.listener.BocloudMessageListener;
|
||||
import com.megatron.common.utils.IDFactory;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* rabbitmq配置类
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 1.0
|
||||
* @since 2018年3月30日
|
||||
*/
|
||||
@Configuration
|
||||
public class RabbitMQConfiguration {
|
||||
|
||||
private final ConnectionFactory connectionFactory;
|
||||
private final Map<String, Object> arguments = MapTools.simpleMap("x-ha-policy", "all");
|
||||
|
||||
public RabbitMQConfiguration(ConnectionFactory connectionFactory) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明主题交换机
|
||||
*
|
||||
* @return 交换机
|
||||
*/
|
||||
@Bean
|
||||
public TopicExchange topicExchange() {
|
||||
return new TopicExchange(BoCloudExchange.Default.TOPIC.getExchange(), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明默认交换机
|
||||
*
|
||||
* @return 交换机
|
||||
*/
|
||||
@Bean
|
||||
public DirectExchange defaultExchange() {
|
||||
return new DirectExchange(BoCloudExchange.Default.DIRECT.getExchange(), true, true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Binding bindingMessageQueue(CurrentService service) {
|
||||
return BindingBuilder.bind(declareMessageQueue(service)).to(topicExchange()).with("bocloud.message.queue.#");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter messageConverter() {
|
||||
return new Jackson2JsonMessageConverter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Queue declareMessageQueue(CurrentService service) {
|
||||
return new Queue("bocloud.message.queue.sms." + service.getToken(), true, false, true, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明审计日志队列
|
||||
*
|
||||
* @return 队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue declareLogQueue() {
|
||||
return new Queue("bocloud.log.queue", true, false, false, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 声明通知消息队列
|
||||
*
|
||||
* @return 队列
|
||||
*/
|
||||
@Bean
|
||||
public Queue declareNoticeQueue() {
|
||||
return new Queue("event.notice.queue", true, false, false, arguments);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Binding bindingNoticeQueue() {
|
||||
return BindingBuilder.bind(declareNoticeQueue()).to(defaultExchange()).withQueueName();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Binding bindingLogQueue() {
|
||||
return BindingBuilder.bind(declareLogQueue()).to(defaultExchange()).withQueueName();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AbstractEncryptHandler.class)
|
||||
public Queue declareLicenseInstallQueue() {
|
||||
return new Queue("license.install.queue." + IDFactory.instance().uuid(), true, false, true, arguments);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AbstractEncryptHandler.class)
|
||||
public Binding bindLicenseInstallQueue() {
|
||||
return BindingBuilder.bind(declareLicenseInstallQueue()).to(defaultExchange()).with("license.install.queue");
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public RabbitTemplate amqpTemplate() {
|
||||
RabbitTemplate amqpTemplate = new RabbitTemplate(connectionFactory);
|
||||
amqpTemplate.setMessageConverter(messageConverter());
|
||||
return amqpTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RabbitAdmin rabbitAdmin() {
|
||||
return new RabbitAdmin(amqpTemplate());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleMessageListenerContainer autoMessageListener(CurrentService service, BocloudMessageListener bocloudMessageListener) {
|
||||
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
|
||||
container.setQueues(declareMessageQueue(service));
|
||||
// 设置确认模式自动确认
|
||||
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
|
||||
container.setMessageListener(bocloudMessageListener);
|
||||
container.setAmqpAdmin(rabbitAdmin());
|
||||
container.setAutoStartup(true);
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AbstractEncryptHandler.class)
|
||||
public SimpleMessageListenerContainer licenseInstallListener(AbstractEncryptHandler encryptHandler) {
|
||||
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
|
||||
// 设置确认模式自动确认
|
||||
container.setQueues(declareLicenseInstallQueue());
|
||||
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
|
||||
container.setMessageListener(encryptHandler);
|
||||
container.setAmqpAdmin(rabbitAdmin());
|
||||
container.setAutoStartup(true);
|
||||
return container;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author dmw
|
||||
*/
|
||||
@Configuration
|
||||
public class SwaggerConfiguration {
|
||||
@Bean
|
||||
public GlobalOpenApiCustomizer orderGlobalOpenApiCustomizer() {
|
||||
return openApi -> {
|
||||
if (openApi.getTags() != null) {
|
||||
openApi.getTags().forEach(tag -> {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("x-order", RandomUtil.randomInt(0, 100));
|
||||
tag.setExtensions(map);
|
||||
});
|
||||
}
|
||||
if (openApi.getPaths() != null) {
|
||||
openApi.addExtension("x-production", "BeyondCMP");
|
||||
openApi.getPaths().addExtension("x-sign", RandomUtil.randomInt(1, 100));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info().title("系统管理服务API接口文档")
|
||||
.version("6.5.0-LTS")
|
||||
.description("系统管理服务API接口文档")
|
||||
.termsOfService("https://www.bocloud.com")
|
||||
.license(new License().name("Apache 2.0").url("https://www.bocloud.com")));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import com.bocloud.cmp.boot.config.PagerArgumentResolver;
|
||||
import com.bocloud.cmp.boot.interceptor.AccessInterceptor;
|
||||
import com.bocloud.cmp.boot.interceptor.LogInterceptor;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.megatron.framework.core.InterceptorBridge;
|
||||
import com.megatron.framework.core.config.InterceptorConfiguration;
|
||||
import com.megatron.framework.core.domain.InterceptorEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.Scanner;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 拦截器配置类
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 1.0
|
||||
* @since 2018年3月30日
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WebInterceptorConfiguration implements InterceptorConfiguration {
|
||||
|
||||
private static final String[] ACCESS_EXCLUDES = new String[]{"/*/*.css",
|
||||
"/*/*.js", "/*/*.png", "/*/*.jpg", "/*/*.jpeg", "/*.html", "/*/*.html", "/swagger-resources/**",
|
||||
"/favicon.ico", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/v1/log/**", "/v1/logo", "/v1/configs", "/v1/*/login",
|
||||
"/v1/logview", "/v1/logzip", "/status/**", "/v1/tokens", "/v1/config/captcha/install", "/v1/status/sid",
|
||||
"/v1/config/license/install", "/v1/config/status/", "/v1/status/sids", "/status", "/status/db",
|
||||
"/error", "/v1/*/info", "/v1/*/status", "/v1/config/**", "/v1/status/**", "/v1/config/license",
|
||||
"/v3/api-docs/**", "/v1/autologin", "/v1/single/login"};
|
||||
private static final String[] LOG_EXCLUDES = new String[]{"/*/*.css",
|
||||
"/*/*.js", "/*/*.png", "/*/*.jpg", "/*/*.jpeg", "/*.html", "/*/*.html", "/swagger-resources/**", "/favicon.ico",
|
||||
"/webjars/**", "/v2/**", "/swagger-ui.html/**", "/error", "/v3/api-docs/**"};
|
||||
private static final String[] INCLUDES = new String[]{"/**"};
|
||||
private final LogInterceptor logInterceptor;
|
||||
private final AccessInterceptor accessInterceptor;
|
||||
|
||||
@Autowired
|
||||
public WebInterceptorConfiguration(AccessInterceptor accessInterceptor, LogInterceptor logInterceptor) {
|
||||
this.logInterceptor = logInterceptor;
|
||||
this.accessInterceptor = accessInterceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterceptorBridge buildBridge() {
|
||||
log.info("start to build interceptor bridge ...");
|
||||
InterceptorEntity accessEntity = InterceptorEntity.builder().interceptor(accessInterceptor).includes(INCLUDES).excludes(ACCESS_EXCLUDES).order(0).build();
|
||||
InterceptorEntity auditLogEntity = InterceptorEntity.builder().interceptor(logInterceptor).includes(INCLUDES).excludes(LOG_EXCLUDES).order(1).build();
|
||||
|
||||
List<InterceptorEntity> interceptors = new ArrayList<>();
|
||||
interceptors.add(accessEntity);
|
||||
interceptors.add(auditLogEntity);
|
||||
|
||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
|
||||
resolvers.add(new PagerArgumentResolver());
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
||||
converters.add(this.byteConverter());
|
||||
converters.add(this.jsonConverter());
|
||||
|
||||
InterceptorBridge bridge = new InterceptorBridge();
|
||||
bridge.setInterceptors(interceptors);
|
||||
bridge.setResolvers(resolvers);
|
||||
bridge.setMessageConverters(converters);
|
||||
|
||||
log.info("build interceptor bridge success!!!");
|
||||
return bridge;
|
||||
}
|
||||
|
||||
private HttpMessageConverter<?> byteConverter() {
|
||||
return new ByteArrayHttpMessageConverter();
|
||||
}
|
||||
|
||||
private HttpMessageConverter<?> jsonConverter() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
Reflections reflections = new Reflections("com", new Scanner[0]);
|
||||
Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(JsonTypeName.class);
|
||||
objectMapper.registerSubtypes(classSet);
|
||||
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
|
||||
jackson2HttpMessageConverter.setDefaultCharset(Charset.defaultCharset());
|
||||
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
|
||||
jackson2HttpMessageConverter.setPrettyPrint(true);
|
||||
jackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
return jackson2HttpMessageConverter;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import com.bocloud.sms.booter.websocket.logview.LogViewHandler;
|
||||
import com.bocloud.sms.booter.websocket.message.MessageHandler;
|
||||
import com.bocloud.sms.booter.websocket.message.MessageInterceptor;
|
||||
import com.bocloud.sms.booter.websocket.upload.UploadServiceHandler;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
|
||||
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
|
||||
|
||||
/**
|
||||
* 拦截器配置类
|
||||
*
|
||||
* @author tyl
|
||||
* @version 1.0
|
||||
* @since 2021年3月25日
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
@RequiredArgsConstructor
|
||||
public class WebSocketConfiguration implements WebSocketConfigurer {
|
||||
|
||||
private final MessageInterceptor messageInterceptor;
|
||||
private final MessageHandler messageHandler;
|
||||
private final LogViewHandler logViewHandler;
|
||||
private final UploadServiceHandler uploadServiceHandler;
|
||||
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter() {
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultHandshakeHandler handshakeHandler() {
|
||||
return new DefaultHandshakeHandler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletServerContainerFactoryBean createWebSocketContainer() {
|
||||
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
|
||||
container.setMaxTextMessageBufferSize(10240);
|
||||
container.setMaxBinaryMessageBufferSize(5 * 1024 * 1024);
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
// 注册普通消息服务
|
||||
registry.addHandler(messageHandler, "/messageService").addInterceptors(messageInterceptor)
|
||||
.setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*");
|
||||
registry.addHandler(messageHandler, "/sockjs/messageService").addInterceptors(messageInterceptor)
|
||||
.setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*").withSockJS();
|
||||
// 注册日志查看消息服务
|
||||
registry.addHandler(logViewHandler, "/logViewService").addInterceptors(messageInterceptor)
|
||||
.setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*");
|
||||
registry.addHandler(logViewHandler, "/sockjs/logViewService").addInterceptors(messageInterceptor)
|
||||
.setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*").withSockJS();
|
||||
// 普通文件上传消息服务
|
||||
registry.addHandler(this.uploadServiceHandler, "/uploadService").addInterceptors(messageInterceptor)
|
||||
.setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*");
|
||||
registry.addHandler(this.uploadServiceHandler, "/sockjs/uploadService")
|
||||
.addInterceptors(this.messageInterceptor).setHandshakeHandler(handshakeHandler()).setAllowedOrigins("*")
|
||||
.withSockJS();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.bocloud.sms.booter.config;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* api权限白名单设置
|
||||
*
|
||||
* @author tyl
|
||||
* @since 2021/3/9 18:10
|
||||
*/
|
||||
@Component
|
||||
public class WhiteApiCache implements InitializingBean {
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
public WhiteApiCache(StringRedisTemplate redisTemplate, ThreadPoolTaskExecutor taskExecutor) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
taskExecutor.execute(() -> {
|
||||
//设置白名单
|
||||
List<String> whiteList = Lists.newArrayList("^GET:/v1/users/permissions$",
|
||||
"^GET:/v1/login/detail$", "^GET:/v1/messages$", "^GET:/v1/token$",
|
||||
"^POST:/v1/users/logout$", "^POST:/v1/tenants/logout$", "^GET:/v1/config/license$", "^GET:/v1/roles/ids$");
|
||||
redisTemplate.opsForValue().set("permission_white", JSONObject.toJSONString(whiteList));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Admission;
|
||||
import com.bocloud.sms.interfaces.AdmissionService;
|
||||
import com.bocloud.sms.model.AdmissionModel;
|
||||
import com.bocloud.sms.service.utils.AdmissionUtil;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ip访问限制控制器
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 4.2.1-SNAPSHOT
|
||||
* @since 2019/11/12
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/admissions")
|
||||
@Tag(name = "IP限制管理")
|
||||
public class AdmissionController {
|
||||
|
||||
private final AdmissionService admissionService;
|
||||
private final AdmissionUtil admissionUtil;
|
||||
|
||||
public AdmissionController(AdmissionService admissionService, AdmissionUtil admissionUtil) {
|
||||
this.admissionService = admissionService;
|
||||
this.admissionUtil = admissionUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取IP访问限制列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 分页数据
|
||||
*/
|
||||
@Operation(summary = "查询IP访问限制列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Admission>> list(Pager pager) {
|
||||
return admissionService.list(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加IP访问限制
|
||||
*
|
||||
* @param admissionModel ip和类型
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
@Operation(summary = "创建IP访问限制")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody AdmissionModel admissionModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
Assert.notNull(admissionModel, "请求参数不能为空");
|
||||
Result result = admissionService.create(admissionModel, requestContext);
|
||||
if (result.isSuccess()) {
|
||||
admissionUtil.refresh();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除IP访问限制
|
||||
*
|
||||
* @param id 被删除的id
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Operation(summary = "删除IP访问限制")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id) {
|
||||
Result result = admissionService.remove(id);
|
||||
if (result.isSuccess()) {
|
||||
admissionUtil.refresh();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看IP访问限制详情
|
||||
*
|
||||
* @param id 被查看的数据id
|
||||
* @return id访问限制
|
||||
*/
|
||||
@Operation(summary = "查看IP访问限制")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Admission> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return admissionService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除IP访问限制
|
||||
*
|
||||
* @param ids 被删除的id列表
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "批量删除IP访问限制")
|
||||
@DeleteMapping
|
||||
public Result batchRemove(@RequestBody List<Long> ids) {
|
||||
return admissionService.batchRemove(ids);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.ApiToken;
|
||||
import com.bocloud.sms.interfaces.ApiTokenService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* api token访问限制控制器
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/api/tokens")
|
||||
@Tag(name = "API Token管理")
|
||||
public class ApiTokenController {
|
||||
|
||||
@Autowired
|
||||
private ApiTokenService apiTokenService;
|
||||
|
||||
@GetMapping("/check/{token}")
|
||||
@Operation(summary = "查看API Token")
|
||||
public GeneralResult<ApiToken> detail(@PathVariable(value = Common.TOKEN) String token) {
|
||||
return apiTokenService.get(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Token
|
||||
*
|
||||
* @param token
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@PostMapping
|
||||
@Operation(summary = "创建 ApiToken")
|
||||
public GeneralResult<ApiToken> create(@RequestBody ApiToken token, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return apiTokenService.create(token, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询Api token列表
|
||||
*
|
||||
* @param pager
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "查看API Token列表")
|
||||
public GeneralResult<GridBean<ApiToken>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return apiTokenService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改Api token
|
||||
*
|
||||
* @param token
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@PutMapping
|
||||
@Operation(summary = "修改API Token")
|
||||
public GeneralResult<Void> modify(@RequestBody ApiToken token, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return apiTokenService.modify(token, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除Api Token
|
||||
*
|
||||
* @param id
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "移除Api Token")
|
||||
public GeneralResult<Void> remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return apiTokenService.remove(id, context);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.interfaces.AutoLoginService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v1/autologin")
|
||||
@Tag(name = "自动登录")
|
||||
public class AutoLoginController {
|
||||
|
||||
@Autowired
|
||||
private AutoLoginService autoLoginService;
|
||||
|
||||
@GetMapping()
|
||||
@Operation(summary = "查看API Token")
|
||||
public RedirectView autoLogin(
|
||||
@RequestHeader(value = "x-forwarded-host", required = false) String host,
|
||||
HttpServletRequest request) {
|
||||
return autoLoginService.autoLogin(host, request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Business;
|
||||
import com.bocloud.sms.entity.Project;
|
||||
import com.bocloud.sms.interfaces.BusinessService;
|
||||
import com.bocloud.sms.model.BusinessModel;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @time 2020/6/3 周三 15:29
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/bizs")
|
||||
@Tag(name = "业务管理")
|
||||
@Slf4j
|
||||
public class BusinessController {
|
||||
|
||||
private final BusinessService businessService;
|
||||
|
||||
public BusinessController(BusinessService businessService) {
|
||||
this.businessService = businessService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看业务列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 分页查询数据
|
||||
*/
|
||||
@Operation(summary = "查看业务列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Business>> list(Pager pager,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return businessService.list(pager, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加业务
|
||||
*
|
||||
* @param businessModel 要添加的业务
|
||||
* @param requestContext 请求上下文
|
||||
* @return 是否添加成功
|
||||
*/
|
||||
@Operation(summary = "添加业务")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody BusinessModel businessModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return businessService.create(businessModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改业务
|
||||
*
|
||||
* @param id 被修改的业务id
|
||||
* @param businessModel 修改的数据
|
||||
* @param requestContext 请求上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改业务")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody BusinessModel businessModel, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return businessService.modify(id, businessModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除业务
|
||||
*
|
||||
* @param id 被删除的业务id
|
||||
* @param requestContext 请求上下文
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除业务")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return businessService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除业务
|
||||
*
|
||||
* @param ids 被删除的业务id列表
|
||||
* @param requestContext 请求上下文
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "批量删除业务")
|
||||
@DeleteMapping
|
||||
public Result batchRemove(@RequestBody List<Long> ids,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return businessService.batchRemove(ids, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看业务明细
|
||||
*
|
||||
* @param id 被查看的业务id
|
||||
* @return 业务实体类
|
||||
*/
|
||||
@Operation(summary = "查看业务明细")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Business> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return businessService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看业务下项目
|
||||
*
|
||||
* @param id 业务id
|
||||
* @return 项目列表
|
||||
*/
|
||||
@Operation(summary = "查看业务下项目")
|
||||
@GetMapping("/{id}/projects")
|
||||
public GeneralResult<List<Project>> projects(
|
||||
@PathVariable(value = Common.ID) Long id) {
|
||||
return businessService.listBusinessProject(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置业务项目
|
||||
*
|
||||
* @param id 业务id
|
||||
* @param projectIds 项目id列表
|
||||
* @return 配置结果
|
||||
*/
|
||||
@Operation(summary = "配置业务项目")
|
||||
@PatchMapping("/{id}")
|
||||
public Result businessAction(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody List<Long> projectIds) {
|
||||
return businessService.businessAction(id, projectIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出业务列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param requestContext 上下文
|
||||
*/
|
||||
@Deprecated
|
||||
@Operation(summary = "导出项目列表")
|
||||
@RequestMapping(value = "/export", method = {RequestMethod.GET})
|
||||
public void export(Pager pager,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
List<Param> paramList = pager.getParams();
|
||||
try {
|
||||
XSSFWorkbook workbook = businessService.export(paramList, requestContext);
|
||||
// 下载表格到浏览器
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("application/octet-stream");
|
||||
String fileName = "业务统计数据" + System.currentTimeMillis() + ".xlsx";
|
||||
final String userAgent = request.getHeader("user-agent").toLowerCase();
|
||||
if (userAgent.contains("trident") || userAgent.contains("edge")) {
|
||||
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||
} else {
|
||||
fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
OutputStream os = response.getOutputStream();
|
||||
workbook.write(os);
|
||||
os.flush();
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
log.error("export project error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载业务列表模板
|
||||
*
|
||||
* @param response 浏览器响应
|
||||
*/
|
||||
@Operation(summary = "下载业务列表模板")
|
||||
@RequestMapping(value = "/import/template", method = {RequestMethod.GET})
|
||||
public void importTemp(HttpServletResponse response) {
|
||||
businessService.importTemp(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入业务列表
|
||||
*
|
||||
* @param requestContext 请求上下文
|
||||
* @param request 请求参数
|
||||
* @return 导入结果
|
||||
*/
|
||||
@Operation(summary = "导入业务列表")
|
||||
@PostMapping(value = "/import")
|
||||
public Result importData(@Value(Common.REQ_CONTEXT) RequestContext requestContext, HttpServletRequest request) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<MultipartFile> fileList = multipartRequest.getFiles("file");
|
||||
if (fileList.isEmpty()) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
MultipartFile multipartFile = fileList.get(0);
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
// 判断文件名
|
||||
if (originalFilename == null || !(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
return businessService.importData(multipartFile, requestContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.cmp.boot.model.BoCloudExchange;
|
||||
import com.bocloud.sms.model.LicenseMask;
|
||||
import com.megatron.common.http.HttpClient;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.License;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import com.megatron.framework.license.LicenseDaemon;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 服务节点信息
|
||||
*
|
||||
* @author weiwei
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/v1")
|
||||
@Tag(name = "服务节点信息管理")
|
||||
public class ConfigController {
|
||||
|
||||
private static final String LICENSE_SUCCESS = "证书激活成功";
|
||||
private static final String LICENSE_FAILED = "证书激活失败";
|
||||
private final LicenseDaemon licenseDaemon;
|
||||
@Value("${service.host:127.0.0.1}")
|
||||
private String host;
|
||||
@Value("${server.port:18088}")
|
||||
private String port;
|
||||
@Autowired
|
||||
private AmqpTemplate amqpTemplate;
|
||||
|
||||
public ConfigController(CurrentService currentService) {
|
||||
this.licenseDaemon = LicenseDaemon.instance(currentService);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询云管license信息
|
||||
*
|
||||
* @return license信息
|
||||
*/
|
||||
@Operation(summary = "查询云管license信息")
|
||||
@GetMapping("/config/license")
|
||||
public GeneralResult<License> license() {
|
||||
License license = licenseDaemon.content();
|
||||
return new GeneralResult<>(true, license, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统状态信息
|
||||
*
|
||||
* @param value 系统url
|
||||
* @return 系统状态信息
|
||||
*/
|
||||
@Operation(summary = "系统状态信息")
|
||||
@GetMapping("/config/status")
|
||||
public GeneralResult status(@RequestParam(value = Common.VALUE) String value) {
|
||||
HttpClient client = new HttpClient();
|
||||
String message = client.get(value).getMessage();
|
||||
return JSONObject.parseObject(message, GeneralResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装证书
|
||||
*
|
||||
* @param file 证书文件
|
||||
* @return 安装结果
|
||||
*/
|
||||
@Operation(summary = "安装证书")
|
||||
@PostMapping("/config/license/install")
|
||||
public Result licenseInstall(@RequestParam("file") MultipartFile file) {
|
||||
if (file.isEmpty()) {
|
||||
return new Result(false, "证书为空!");
|
||||
}
|
||||
Result result;
|
||||
try {
|
||||
result = licenseDaemon.verify(file.getBytes());
|
||||
if (result.isFailed()) {
|
||||
log.error("证书校验失败");
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
result = licenseDaemon.install(file.getBytes());
|
||||
if (result.isSuccess()) {
|
||||
return new Result(true, LICENSE_SUCCESS);
|
||||
}
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
} catch (IOException e) {
|
||||
log.error("证书激活异常:", e);
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装license验证码
|
||||
*
|
||||
* @param licenseMask license验证码
|
||||
* @return 安装结果
|
||||
*/
|
||||
@Operation(summary = "安装license验证码")
|
||||
@PostMapping("/config/captcha/install")
|
||||
public Result captchaInstall(@RequestBody LicenseMask licenseMask) {
|
||||
try {
|
||||
GeneralResult<byte[]> GeneralResult = licenseDaemon.decode(licenseMask.getLicenseMask());
|
||||
if (GeneralResult.isFailed()) {
|
||||
log.error("证书激活码格式有误,激活失败!");
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
Result result = licenseDaemon.verify(GeneralResult.getData());
|
||||
if (result.isFailed()) {
|
||||
log.error("证书格式不正确!");
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
result = licenseDaemon.install(GeneralResult.getData());
|
||||
if (result.isFailed()) {
|
||||
log.error("证书安装失败");
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(),
|
||||
"license.install.queue", LICENSE_SUCCESS);
|
||||
return new Result(true, LICENSE_SUCCESS);
|
||||
} catch (Exception e) {
|
||||
log.error("证书激活异常!", e);
|
||||
return new Result(false, LICENSE_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统sid信息
|
||||
*
|
||||
* @return sid信息
|
||||
*/
|
||||
@Operation(summary = "系统状态信息")
|
||||
@GetMapping("/status/sid")
|
||||
public GeneralResult getSid() {
|
||||
HttpClient client = new HttpClient();
|
||||
String url = "http://" + host + ":" + port + "/status/sid";
|
||||
String message = client.get(url).getMessage();
|
||||
return JSONObject.parseObject(message, GeneralResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统sid信息
|
||||
*
|
||||
* @return sid信息列表
|
||||
*/
|
||||
@Operation(summary = "系统状态信息")
|
||||
@GetMapping("/status/sids")
|
||||
public GeneralResult getSids() {
|
||||
HttpClient client = new HttpClient();
|
||||
String url = "http://" + host + ":" + port + "/status/sids";
|
||||
String message = client.get(url).getMessage();
|
||||
return JSONObject.parseObject(message, GeneralResult.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Department;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.interfaces.DepartmentService;
|
||||
import com.bocloud.sms.model.DepartmentModel;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组织管理控制器
|
||||
*
|
||||
* @author tyl
|
||||
* @since 2021/03/25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/departments")
|
||||
@Tag(name = "组织管理")
|
||||
public class DepartmentController {
|
||||
|
||||
private final DepartmentService departmentService;
|
||||
|
||||
public DepartmentController(DepartmentService departmentService) {
|
||||
this.departmentService = departmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织机构
|
||||
*
|
||||
* @param parentId 父组织id
|
||||
* @param requestContext 上下文
|
||||
* @return 组织机构列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "组织机构列表显示")
|
||||
public GeneralResult<List<Department>> list(@RequestParam(value = Common.PARENTID) Long parentId, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return departmentService.list(parentId, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织机构下的管理员
|
||||
*
|
||||
* @param id 组织id
|
||||
* @param requestContext 上下文
|
||||
* @return 管理员信息
|
||||
*/
|
||||
@GetMapping("/{id}/managers")
|
||||
@Operation(summary = "查询组织机构下的管理员")
|
||||
public GeneralResult<List<User>> listDeptManager(@PathVariable(value = Common.ID) Long id, RequestContext requestContext) {
|
||||
return departmentService.listDeptManager(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建组织机构
|
||||
*
|
||||
* @param department 组织
|
||||
* @param requestContext 上下文
|
||||
* @return 创建结果
|
||||
*/
|
||||
@Operation(summary = "创建组织机构")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody DepartmentModel department,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return departmentService.create(department, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改组织机构
|
||||
*
|
||||
* @param id 组织id
|
||||
* @param department 组织
|
||||
* @param requestContext 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改组织机构")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody DepartmentModel department,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return departmentService.modify(id, department, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组织机构
|
||||
*
|
||||
* @param id 组织id
|
||||
* @param requestContext 上下文
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除组织机构")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return departmentService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组织机构详情
|
||||
*
|
||||
* @param id 组织id
|
||||
* @return 组织
|
||||
*/
|
||||
@Operation(summary = "组织机构详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Department> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return departmentService.detail(id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Dictionary;
|
||||
import com.bocloud.sms.interfaces.DictService;
|
||||
import com.bocloud.sms.model.DictionaryBean;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典信息控制器
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/dictionaries")
|
||||
@Tag(name = "字典信息管理")
|
||||
public class DictController {
|
||||
private final DictService dictService;
|
||||
|
||||
public DictController(DictService dictService) {
|
||||
this.dictService = dictService;
|
||||
}
|
||||
|
||||
@Operation(summary = "查询字典树列表")
|
||||
@GetMapping
|
||||
public GeneralResult<List<Dictionary>> list(@RequestParam(value = "pid", required = false) Long pid) {
|
||||
return dictService.list(pid);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据id查询字典")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Dictionary> detail(@PathVariable(value = "id") Long id) {
|
||||
return dictService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典值获取子节点列表
|
||||
*
|
||||
* @param value 字典值
|
||||
* @return 子节点列表
|
||||
*/
|
||||
@Operation(summary = "查询系统字典子信息")
|
||||
@GetMapping("/children")
|
||||
public GeneralResult<List<Dictionary>> children(@RequestParam(value = Common.VALUE, required = false) String value,
|
||||
@RequestParam(value = "pid", required = false) Long pid) {
|
||||
return dictService.listChild(value, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典树
|
||||
*
|
||||
* @param value 字典值
|
||||
* @return 字典树
|
||||
*/
|
||||
@Operation(summary = "查询字典树")
|
||||
@GetMapping("/children/tree")
|
||||
public GeneralResult<List<Dictionary>> childTree(@RequestParam(value = Common.VALUE, required = false) String value) {
|
||||
return dictService.childTree(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*
|
||||
* @param dictionary 字典数据
|
||||
* @return 创建结果
|
||||
*/
|
||||
@Operation(summary = "新增字典")
|
||||
@PostMapping
|
||||
public GeneralResult<Dictionary> create(@RequestBody Dictionary dictionary) {
|
||||
return dictService.create(dictionary);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字典
|
||||
*
|
||||
* @param id 字典id
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除字典")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id) {
|
||||
return dictService.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改字典
|
||||
*
|
||||
* @param id 字典id
|
||||
* @param bean 字典
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改字典")
|
||||
@PutMapping("/{id}")
|
||||
public GeneralResult<Dictionary> modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody DictionaryBean bean) {
|
||||
bean.setId(id);
|
||||
return dictService.modify(bean);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.bocloud.sms.entity.SystemConfig;
|
||||
import com.bocloud.sms.repository.SystemConfigRepository;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.Tokens;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* {@code @time} 2020/4/24 周五 20:02
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping
|
||||
@Tag(name = "跳转控制")
|
||||
public class DispatchController {
|
||||
|
||||
private final SystemConfigRepository configRepository;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
|
||||
public DispatchController(SystemConfigRepository systemConfigService, StringRedisTemplate redisTemplate) {
|
||||
this.configRepository = systemConfigService;
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单点登录跳转接口
|
||||
*
|
||||
* @param request 浏览器请求
|
||||
* @param response 浏览器响应
|
||||
* @throws Exception 出现的异常
|
||||
*/
|
||||
|
||||
@RequestMapping("/v1/redirect")
|
||||
@Operation(summary = "单点登录跳转")
|
||||
public void redirect(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
//获取登录地址
|
||||
String target = request.getParameter("target");
|
||||
String redirectParameter = request.getParameter("redirect");
|
||||
SystemConfig config;
|
||||
if (target == null || "Manager".equals(target)) {
|
||||
config = configRepository.queryByCode("ManagerAddress");
|
||||
} else {
|
||||
config = configRepository.queryByCode("TenantAddress");
|
||||
}
|
||||
String loginAddress = config.getValue();
|
||||
log.info("#######debuge########the request url is {}", request.getRequestURL() + "?" + request.getQueryString());
|
||||
log.info("#######debuge########the redirect url is {}", redirectParameter);
|
||||
String redirect = Optional.ofNullable(redirectParameter).orElse(loginAddress + "/#/");
|
||||
String token = request.getParameter("token");
|
||||
log.info("#######debuge########the redirect token is {}", token);
|
||||
Claim claim = Tokens.parse(token);
|
||||
if (!Objects.isNull(claim)) {
|
||||
String catalog = claim.asMap().get("catalog").toString();
|
||||
long uuid = Long.parseLong(claim.asMap().get(Common.UUID).toString());
|
||||
String tokenKey = Common.TOKEN + "_" + catalog + "_" + uuid;
|
||||
boolean checkResult = check(token, tokenKey);
|
||||
if (checkResult) {
|
||||
HttpSession session = request.getSession();
|
||||
session.setAttribute("redirect", redirect);
|
||||
session.setAttribute(Common.TOKEN, token);
|
||||
response.sendRedirect(loginAddress + "/#/sso");
|
||||
} else {
|
||||
String replace = redirect.replace("#", "%23");
|
||||
response.sendRedirect(loginAddress + "/#/login?redirect=" + replace);
|
||||
}
|
||||
} else {
|
||||
String replace = redirect.replace("#", "%23");
|
||||
response.sendRedirect(loginAddress + "/#/login?redirect=" + replace);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean check(String token, String tokenKey) {
|
||||
String newTokenCache = (String) this.redisTemplate.opsForHash().get(tokenKey + "_n", Common.TOKEN);
|
||||
String oldTokenCache = this.redisTemplate.opsForValue().get(tokenKey + "_o");
|
||||
if (token.equals(newTokenCache)) {
|
||||
return true;
|
||||
} else {
|
||||
return token.equals(oldTokenCache);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Environment;
|
||||
import com.bocloud.sms.interfaces.EnvironmentService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 环境实体类Controller
|
||||
*
|
||||
* @author wangshuai
|
||||
* @version 4.1.0-SNAPSHOT
|
||||
* @since 2018/12/24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/environments")
|
||||
@Tag(name = "所属环境")
|
||||
public class EnvironmentController {
|
||||
private final EnvironmentService environmentService;
|
||||
|
||||
public EnvironmentController(EnvironmentService environmentService) {
|
||||
this.environmentService = environmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看环境列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 环境列表
|
||||
*/
|
||||
@Operation(summary = "获取所属环境列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Environment>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return environmentService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加环境
|
||||
*
|
||||
* @param environment 环境
|
||||
* @param context 上下文
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Operation(summary = "添加所属环境")
|
||||
@PostMapping
|
||||
public GeneralResult<Environment> create(@RequestBody Environment environment,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return environmentService.create(environment, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改环境
|
||||
*
|
||||
* @param id 环境id
|
||||
* @param environment 环境
|
||||
* @param context 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改所属环境")
|
||||
@PutMapping("/{id}")
|
||||
public GeneralResult<Environment> modify(@PathVariable(value = Common.ID) Long id, @RequestBody Environment environment,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
environment.setId(id);
|
||||
return environmentService.modify(environment, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除环境
|
||||
*
|
||||
* @param id 环境id
|
||||
* @param context 上下文
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除所属环境")
|
||||
@DeleteMapping("/{id}")
|
||||
public GeneralResult remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return environmentService.remove(id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看环境明细
|
||||
*
|
||||
* @param id 环境id
|
||||
* @return 环境
|
||||
*/
|
||||
@Operation(summary = "查看所属环境详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Environment> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return environmentService.detail(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.GlobalManConfig;
|
||||
import com.bocloud.sms.interfaces.GlobalManConfigService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author wpj
|
||||
* @since 2022/9/8
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/global/config")
|
||||
@Slf4j
|
||||
@Tag(name = "全局运维配置")
|
||||
public class GlobalManConfigController {
|
||||
|
||||
private final GlobalManConfigService globalManConfigService;
|
||||
|
||||
public GlobalManConfigController(GlobalManConfigService globalManConfigService) {
|
||||
this.globalManConfigService = globalManConfigService;
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "查询周期时间列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<GlobalManConfig>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return globalManConfigService.list(pager, context);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "创建禁止周期时间")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody GlobalManConfig globalManConfig,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return globalManConfigService.create(globalManConfig, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改禁止周期时间")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@RequestBody GlobalManConfig globalManConfig,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return globalManConfigService.modify(globalManConfig, requestContext);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "删除禁止周期时间")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return globalManConfigService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "查询当前全局配置是否被禁止")
|
||||
@GetMapping("/isAllow")
|
||||
public Result isAllow(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return globalManConfigService.allow(requestContext);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Icon;
|
||||
import com.bocloud.sms.interfaces.IconService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 图标controller层
|
||||
*
|
||||
* @author 胡立伟
|
||||
* @Version 1.0
|
||||
* @since 2020年4月7日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/icon")
|
||||
@Tag(name = "图标管理")
|
||||
public class IconController {
|
||||
@Autowired
|
||||
private IconService iconService;
|
||||
|
||||
/**
|
||||
* 图标列表查询
|
||||
*
|
||||
* @return 图标列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "图标列表查询")
|
||||
public GeneralResult<GridBean<Icon>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return iconService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图标
|
||||
*
|
||||
* @param files 图标文件
|
||||
* @param context 上下文
|
||||
* @return 上传结果
|
||||
*/
|
||||
@PostMapping()
|
||||
@Operation(summary = "上传图标")
|
||||
public GeneralResult<Void> upload(MultipartFile[] files, String category, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return iconService.create(files, category, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除图标
|
||||
*
|
||||
* @param id 图标id
|
||||
* @return 删除结果
|
||||
*/
|
||||
@DeleteMapping(value = "/{id}")
|
||||
@Operation(summary = "删除图标")
|
||||
public GeneralResult<Void> remove(@PathVariable(value = Common.ID) Long id) {
|
||||
return iconService.remove(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Label;
|
||||
import com.bocloud.sms.interfaces.LabelService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author zhangdi
|
||||
* @since 2018/7/2
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/tags")
|
||||
@Tag(name = "标签管理")
|
||||
public class LabelController {
|
||||
|
||||
private final LabelService labelService;
|
||||
|
||||
public LabelController(LabelService labelService) {
|
||||
this.labelService = labelService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 标签列表
|
||||
*/
|
||||
@Operation(summary = "获取命名规则列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Label>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return labelService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加标签
|
||||
*
|
||||
* @param label 标签
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Operation(summary = "添加标签")
|
||||
@PostMapping
|
||||
public GeneralResult<Label> create(@RequestBody Label label, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return labelService.create(label, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改标签
|
||||
*
|
||||
* @param id 标签id
|
||||
* @param label 标签
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改标签")
|
||||
@PutMapping("/{id}")
|
||||
public GeneralResult<Label> modify(@PathVariable(value = Common.ID) Long id, @RequestBody Label label) {
|
||||
label.setId(id);
|
||||
return labelService.modify(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除标签
|
||||
*
|
||||
* @param id 标签id
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除标签")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id) {
|
||||
return labelService.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看标签详情
|
||||
*
|
||||
* @param id 标签id
|
||||
* @return 标签
|
||||
*/
|
||||
@Operation(summary = "查看标签详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Label> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return labelService.detail(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.LogArchiveRecord;
|
||||
import com.bocloud.sms.interfaces.LogArchiveRecordService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 审计日志归档记录
|
||||
*
|
||||
* @author zhangdi
|
||||
* @since Nov 6,2019
|
||||
*/
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v1/archives")
|
||||
@Tag(name = "日志归档管理")
|
||||
public class LogArchiveRecordController {
|
||||
|
||||
private final LogArchiveRecordService logArchiveRecordService;
|
||||
|
||||
public LogArchiveRecordController(LogArchiveRecordService logArchiveRecordService) {
|
||||
this.logArchiveRecordService = logArchiveRecordService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 日志列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "审计日志归档记录")
|
||||
public GeneralResult<GridBean<LogArchiveRecord>> list(Pager pager) {
|
||||
return logArchiveRecordService.list(pager);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.AccessLog;
|
||||
import com.bocloud.sms.interfaces.LogService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审计日志控制器,用来进行平台审计日志的查询操作
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/logs")
|
||||
@Tag(name = "审计日志管理")
|
||||
public class LogController {
|
||||
|
||||
private final LogService logService;
|
||||
|
||||
public LogController(LogService logService) {
|
||||
this.logService = logService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 审计日志查询
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 日志列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "获取审计日志列表")
|
||||
public GeneralResult<GridBean<AccessLog>> list(Pager pager) {
|
||||
return this.logService.list(pager);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存审计日志
|
||||
*
|
||||
* @param logs 审计日志数组
|
||||
* @return 保存结果
|
||||
*/
|
||||
@Operation(summary = "批量保存审计日志")
|
||||
@PostMapping
|
||||
public Result batchSave(@RequestBody List<AccessLog> logs) {
|
||||
return this.logService.batch(logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 审计日志归档
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @param deleted 是否删除
|
||||
* @param context 请求对象
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/archive")
|
||||
@Operation(summary = "审计日志归档")
|
||||
public GeneralResult<StringBuilder> archive(@RequestParam(value = "startTime", required = false) String startTime,
|
||||
@RequestParam(value = "endTime", required = false) String endTime,
|
||||
@RequestParam(value = "deleted", required = false) Boolean deleted,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return logService.archive(startTime, endTime, deleted, context, request, response);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.booter.websocket.model.LogViewMessage;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.megatron.common.enums.PostDataFormat;
|
||||
import com.megatron.common.http.HttpClient;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 当日日志和历史日志下载
|
||||
*
|
||||
* @author zhangdi
|
||||
* @since 2018.7.23
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/v1/logs")
|
||||
@Tag(name = "日志下载管理")
|
||||
public class LogDownloadController {
|
||||
|
||||
@Value("${logging.dir:/log/services}")
|
||||
private String loggingDir;
|
||||
|
||||
/**
|
||||
* 实时日志下载
|
||||
*
|
||||
* @param token token
|
||||
* @param server 服务
|
||||
* @param host host
|
||||
* @param request 浏览器请求
|
||||
* @param response 浏览器响应
|
||||
*/
|
||||
@Operation(summary = "当日日志下载")
|
||||
@RequestMapping(value = "/download", method = {RequestMethod.GET})
|
||||
public void download(@RequestParam(value = "token") String token,
|
||||
@RequestParam(value = "server") String server,
|
||||
@RequestParam(value = "host") String host,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
Long position = 0L;
|
||||
Long presize = Long.MAX_VALUE;
|
||||
String fileName = server + ".log";
|
||||
String filepath = loggingDir + File.separator + fileName;
|
||||
LogViewMessage logViewMessage;
|
||||
switch (server) {
|
||||
case "worker": {
|
||||
String workPath = "/var/log/bocloud/bocloud_worker.log";
|
||||
String url = "http://" + host + "/api/" + server + "/v1/logview";
|
||||
logViewMessage = getRemoteLog(url, workPath, position, presize, host.substring(0, host.indexOf(':')));
|
||||
break;
|
||||
}
|
||||
case "pontus": {
|
||||
String workPath = "/var/log/pontus/pontus.log";
|
||||
String url = "http://" + host + "/api/" + server + "/v1/logview";
|
||||
logViewMessage = getRemoteLog(url, workPath, position, presize, null);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
String url = "http://" + host + "/v1/logview";
|
||||
log.info("token:{}", token);
|
||||
logViewMessage = getRemoteLog(token, url, filepath, position, presize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
String content;
|
||||
try {
|
||||
content = JSONObject.toJSONString(logViewMessage.getContent());
|
||||
// 获取当前时间并拼成yyyy-MM-dd格式 HH:mm
|
||||
Date date = new Date();
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
String beginIndex = dateFormat.format(date).substring(0, 11) + "00:00";
|
||||
String endIndex = dateFormat.format(date);
|
||||
|
||||
// 将开始结束时间放入日历类 操作日历截取日志
|
||||
Calendar beginTime = Calendar.getInstance();
|
||||
Calendar endTime = Calendar.getInstance();
|
||||
beginTime.setTime(dateFormat.parse(beginIndex));
|
||||
// beginTime.add(Calendar.MINUTE, -1);
|
||||
endTime.setTime(dateFormat.parse(endIndex));
|
||||
|
||||
// 根据开始时间和结束时间进行索引
|
||||
int begin = content.indexOf(beginIndex);
|
||||
int end = content.indexOf(endIndex);
|
||||
// 判断开始时间是否存在,不存在则向后推一分钟
|
||||
int i = 0;
|
||||
while (begin == -1) {
|
||||
beginTime.add(Calendar.MINUTE, 1);
|
||||
SimpleDateFormat beginFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
String newBeginIndex = beginFormat.format(beginTime.getTime());
|
||||
begin = content.indexOf(newBeginIndex);
|
||||
i++;
|
||||
if (i > 1440) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断结束时间是否存在,不存在则向前推一分钟
|
||||
int j = 0;
|
||||
while (end == -1) {
|
||||
endTime.add(Calendar.MINUTE, -1);
|
||||
SimpleDateFormat endFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
String newEndIndex = endFormat.format(endTime.getTime());
|
||||
// 索引最后一次出现的结束时间
|
||||
end = content.lastIndexOf(newEndIndex);
|
||||
j++;
|
||||
if (j > 1440) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断此时间段内是否有日志
|
||||
String total;
|
||||
if (begin > end || begin == -1) {
|
||||
total = "此时间段内无日志";
|
||||
} else {
|
||||
String substring = content.substring(begin, end);
|
||||
// 补上最后时刻的一条数据
|
||||
String character = "\\n";
|
||||
// 从end的索引开始,向后拿到到“\n”为址的第一条数据
|
||||
int endAdd = content.indexOf(character, end);
|
||||
String add = content.substring(end, endAdd);
|
||||
total = substring + add;
|
||||
// 将捕获日志时拿到的“\n”、“\\”及着色符替换掉
|
||||
total = total.replace("\\\\", "").replace("\\n", "\r\n").replace("\\u001B[36m", "")
|
||||
.replace("\\u001B[34m", "").replace("\\u001B[31m", "").replace("\\u001B[1;31m", "")
|
||||
.replace("\\u001B[0;39m", "").replace("\\tat", " ").replace("\\t...", "...");
|
||||
}
|
||||
response.setContentType("text/plain");
|
||||
String filename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||
final String userAgent = request.getHeader("USER-AGENT");
|
||||
if (userAgent.contains("Mozilla")) {
|
||||
filename = new String(fileName.getBytes(), "ISO8859-1");
|
||||
}
|
||||
response.setHeader("Content-Disposition", "attachment;fileName=" + filename);
|
||||
// 定义输出流
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
byte[] decode = total.getBytes();
|
||||
outputStream.write(decode);
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
log.error("Daily log download failed!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 历史日志打包下载
|
||||
*
|
||||
* @param server 服务名称
|
||||
* @param host host
|
||||
* @param begin 开始时间
|
||||
* @param end 结束时间
|
||||
* @param request 浏览器请求
|
||||
* @param response 浏览器响应
|
||||
*/
|
||||
@Operation(summary = "历史日志下载")
|
||||
@RequestMapping(value = "/zip", method = {RequestMethod.GET})
|
||||
public void zip(@RequestParam(value = "token") String token,
|
||||
@RequestParam(value = "server") String server,
|
||||
@RequestParam(value = "host") String host,
|
||||
@RequestParam(value = "begin") String begin,
|
||||
@RequestParam(value = "end") String end,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
String filepath = loggingDir + File.separator + "history";
|
||||
// 定义导出文件名称
|
||||
String fileName = server + ".zip";
|
||||
String url = "http://" + host + "/v1/logzip";
|
||||
Map<String, byte[]> map = getRemoteZip(token, url, filepath, begin, end, server);
|
||||
|
||||
response.setContentType("application/x-zip-compressed");
|
||||
String filename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||
final String userAgent = request.getHeader("USER-AGENT");
|
||||
if (userAgent.contains("Mozilla")) {
|
||||
filename = new String(fileName.getBytes(), "ISO8859-1");
|
||||
}
|
||||
response.setHeader("Content-Disposition", "attachment;fileName=" + filename);
|
||||
// 创建一个临时文件
|
||||
File file = new File(System.getProperty("user.home") + File.separator + fileName);
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(file))) {
|
||||
byte[] buffer = new byte[1024];
|
||||
// 遍历拿到的每个文件的数据
|
||||
for (Map.Entry<String, byte[]> entry : map.entrySet()) {
|
||||
InputStream inputStream = new ByteArrayInputStream(entry.getValue());
|
||||
// 文件命名
|
||||
zipOutputStream.putNextEntry(new ZipEntry(entry.getKey()));
|
||||
int len;
|
||||
// 读入需要下载的文件的内容
|
||||
while ((len = inputStream.read(buffer)) > 0) {
|
||||
zipOutputStream.write(buffer, 0, len);
|
||||
}
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Get error message:", e);
|
||||
}
|
||||
|
||||
try (FileInputStream fileInputStream = new FileInputStream(file)) {
|
||||
IOUtils.copy(fileInputStream, outputStream);
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Get error message:", e);
|
||||
}
|
||||
// 删除临时文件
|
||||
boolean flag = file.delete();
|
||||
log.info("临时文件删除状态:{}", flag);
|
||||
} catch (Exception e) {
|
||||
log.error("Get error message:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端服务器上的日志文件内容
|
||||
*
|
||||
* @param url 服务地址
|
||||
* @param filepath 文件路径
|
||||
* @param position 起始位点
|
||||
* @param presize 前移位点
|
||||
* @return
|
||||
*/
|
||||
private LogViewMessage getRemoteLog(String token, String url, String filepath, Long position, Long presize) {
|
||||
LogViewMessage message;
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
Map<String, Object> param = MapTools.simpleMap("filepath", filepath);
|
||||
param.put("position", position);
|
||||
param.put("presize", presize);
|
||||
Result result = client.get(MapTools.simpleMap("token", token), param, url);
|
||||
if (result.isFailed()) {
|
||||
message = new LogViewMessage("", position);
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(result.getMessage());
|
||||
if (null != jsonObject) {
|
||||
jsonObject = JSONObject.parseObject(jsonObject.getString("message"));
|
||||
} else {
|
||||
jsonObject = new JSONObject();
|
||||
}
|
||||
message = new LogViewMessage(jsonObject.getString("content"), jsonObject.getLong("position"));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端worker服务器上的日志文件内容
|
||||
*
|
||||
* @param url 服务地址
|
||||
* @param filepath 文件路径
|
||||
* @param position 起始位点
|
||||
* @param presize 前移位点
|
||||
* @param target worker服务器IP地址
|
||||
* @return
|
||||
*/
|
||||
private LogViewMessage getRemoteLog(String url, String filepath, Long position, Long presize, String target) {
|
||||
LogViewMessage message;
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
Map<String, Object> param = MapTools.simpleMap("filepath", filepath);
|
||||
param.put("position", position);
|
||||
param.put("presize", presize);
|
||||
if (StringUtils.isNotEmpty(target)) {
|
||||
param.put("target", target);
|
||||
}
|
||||
Result result = client.post(null, param, url);
|
||||
if (result.isFailed()) {
|
||||
message = new LogViewMessage("", position);
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(result.getMessage());
|
||||
message = new LogViewMessage(jsonObject.getString("message"), jsonObject.getLong("filesize"));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取远程服务器历史日志
|
||||
*
|
||||
* @param url 远程地址
|
||||
* @param filepath 文件路径
|
||||
* @param begin 开始实际按
|
||||
* @param end 结束实际按
|
||||
* @param server 服务名称
|
||||
* @return 历史日志byte
|
||||
*/
|
||||
private Map<String, byte[]> getRemoteZip(String token, String url, String filepath, String begin, String end,
|
||||
String server) {
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
Map<String, Object> param = MapTools.simpleMap("filepath", filepath);
|
||||
param.put("begin", begin);
|
||||
param.put("end", end);
|
||||
param.put("server", server);
|
||||
Result result = client.get(MapTools.simpleMap("token", token), param, url);
|
||||
|
||||
Map<String, byte[]> dataMap = Maps.newHashMap();
|
||||
if (result.isSuccess() && StringUtils.isNotEmpty(result.getMessage())) {
|
||||
JSONObject object = JSONObject.parseObject(result.getMessage(), JSONObject.class);
|
||||
log.info("获取到日志结果为 {} ", JSONObject.toJSONString(object));
|
||||
for (String key : object.keySet()) {
|
||||
try {
|
||||
dataMap.put(key, object.getBytes(key));
|
||||
} catch (Exception e) {
|
||||
log.error("获取日志异常 {} , ->>>>>{}", JSONObject.toJSONString(key), object.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataMap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.AccountSecurity;
|
||||
import com.bocloud.sms.entity.SystemConfig;
|
||||
import com.bocloud.sms.entity.TenantAccount;
|
||||
import com.bocloud.sms.interfaces.TenantService;
|
||||
import com.bocloud.sms.interfaces.UserService;
|
||||
import com.bocloud.sms.model.LoginModel;
|
||||
import com.bocloud.sms.repository.SystemConfigRepository;
|
||||
import com.bocloud.sms.service.internel.CosInternelService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import com.megatron.framework.lock.LockFactory;
|
||||
import com.megatron.framework.utils.IpTool;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 登录控制器
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/v1")
|
||||
@Tag(name = "登录管理")
|
||||
public class LoginController {
|
||||
|
||||
private final UserService userService;
|
||||
private final TenantService tenantService;
|
||||
private final CosInternelService cosInternelService;
|
||||
private final SystemConfigRepository systemConfigRepository;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final LockFactory lockFactory;
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param loginModel 登录信息
|
||||
* @param request 浏览器请求
|
||||
* @return 登录结果
|
||||
*/
|
||||
@Operation(summary = "用户登录")
|
||||
@PostMapping("/users/login")
|
||||
public GeneralResult<Map<String, Object>> userLogin(@RequestBody LoginModel loginModel,
|
||||
HttpServletRequest request) {
|
||||
log.info("开始执行登录请求");
|
||||
long start;
|
||||
String account = loginModel.getAccount();
|
||||
String password = loginModel.getPassword();
|
||||
log.info("开始调用UserService");
|
||||
GeneralResult<Map<String, Object>> loginResult = userService
|
||||
.login(account, password, request.getSession().getId(), IpTool.getIP(request), loginModel.getIsManager());
|
||||
log.info("结束调用UserService");
|
||||
if (loginResult.isFailed()) {
|
||||
if (null == loginResult.getData()) {
|
||||
String path = "Login_" + account;
|
||||
try (com.megatron.framework.lock.AutoCloseLock lock = lockFactory.getACLock(path)) {
|
||||
Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
|
||||
start = System.currentTimeMillis();
|
||||
String value = redisTemplate.opsForValue().get(RequestContext.Catalog.User.name() + account);
|
||||
log.info("查询Redis耗时{}ms", System.currentTimeMillis() - start);
|
||||
SystemConfig errorNumber = systemConfigRepository.queryByCode("pwdErrorNumber");
|
||||
int error = Integer.parseInt(errorNumber.getValue());
|
||||
if (!StringUtils.hasText(value)) {
|
||||
//密码操作失败
|
||||
start = System.currentTimeMillis();
|
||||
redisTemplate.opsForValue()
|
||||
.set(RequestContext.Catalog.User.name() + account, String.valueOf(1), 60, TimeUnit.SECONDS);
|
||||
log.info("写入Redis耗时{}ms", System.currentTimeMillis() - start);
|
||||
loginResult = new GeneralResult<>(false, loginResult.getMessage() + ",已操作【1】次");
|
||||
} else if (Integer.parseInt(value) >= error) {
|
||||
Result lockResult = userService.lockByAccount(account);
|
||||
boolean success = lockResult.isSuccess();
|
||||
start = System.currentTimeMillis();
|
||||
redisTemplate.delete(RequestContext.Catalog.User.name() + account);
|
||||
log.info("删除Redis耗时{}ms", System.currentTimeMillis() - start);
|
||||
if (success) {
|
||||
loginResult = new GeneralResult<>(false, "账号或者密码错误已达【" + error + "】次,若用户存在将被冻结,请联系管理员解冻");
|
||||
} else {
|
||||
loginResult = new GeneralResult<>(false, "认证服务账号缓存存在问题");
|
||||
}
|
||||
} else {
|
||||
start = System.currentTimeMillis();
|
||||
redisTemplate.boundValueOps(RequestContext.Catalog.User.name() + account).increment(1L);
|
||||
log.info("写入Redis耗时{}ms", System.currentTimeMillis() - start);
|
||||
String num = redisTemplate.opsForValue().get(RequestContext.Catalog.User.name() + account);
|
||||
loginResult = new GeneralResult<>(false, loginResult.getMessage() + ",已操作【" + num + "】次");
|
||||
}
|
||||
log.info("登录请求处理完成");
|
||||
return loginResult;
|
||||
} catch (Exception e) {
|
||||
log.error("Get login error message:", e);
|
||||
log.info("登录请求处理完成");
|
||||
return loginResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
start = System.currentTimeMillis();
|
||||
redisTemplate.delete(RequestContext.Catalog.User.name() + account);
|
||||
log.info("删除Redis耗时{}ms", System.currentTimeMillis() - start);
|
||||
log.info("登录请求处理完成");
|
||||
return loginResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @return 登出结果
|
||||
*/
|
||||
@Operation(summary = "用户退出系统")
|
||||
@PostMapping("/users/logout")
|
||||
public Result userLogout(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.logout(requestContext.getTarget());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 租户登录
|
||||
*
|
||||
* @param loginModel 租户登录信息
|
||||
* @param request 浏览器请求
|
||||
* @return 登录结果,token
|
||||
*/
|
||||
@Operation(summary = "租户登录")
|
||||
@PostMapping("/tenants/login")
|
||||
public GeneralResult<Map<String, Object>> tenantLogin(
|
||||
@RequestBody LoginModel loginModel, HttpServletRequest request) {
|
||||
String account = loginModel.getAccount();
|
||||
String password = loginModel.getPassword();
|
||||
GeneralResult<Map<String, Object>> loginResult =
|
||||
tenantService.login(account, password, request.getSession().getId(), IpTool.getIP(request));
|
||||
if (loginResult.isFailed()) {
|
||||
if (null == loginResult.getData()) {
|
||||
String path = "Login_" + account;
|
||||
try (com.megatron.framework.lock.AutoCloseLock lock = lockFactory.getACLock(path)) {
|
||||
Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
|
||||
String value = redisTemplate.opsForValue().get(RequestContext.Catalog.Tenant.name() + account);
|
||||
SystemConfig errorNumber = systemConfigRepository.queryByCode("pwdErrorNumber");
|
||||
int error = Integer.parseInt(errorNumber.getValue());
|
||||
if (!StringUtils.hasText(value)) {
|
||||
//密码操作失败
|
||||
redisTemplate.opsForValue()
|
||||
.set(RequestContext.Catalog.Tenant.name() + account, String.valueOf(1), 60,
|
||||
TimeUnit.SECONDS);
|
||||
loginResult = new GeneralResult<>(false, loginResult.getMessage() + ",已操作【1】次");
|
||||
} else if (Integer.parseInt(value) >= error) {
|
||||
Result lockResult = tenantService.lockByAccount(account);
|
||||
boolean success = lockResult.isSuccess();
|
||||
redisTemplate.delete(RequestContext.Catalog.Tenant.name() + account);
|
||||
if (success) {
|
||||
loginResult = new GeneralResult<>(false, "账号或者密码错误已达【" + error + "】次,若租户存在将被冻结,请联系管理员解冻");
|
||||
} else {
|
||||
loginResult = new GeneralResult<>(false, "认证服务存在问题");
|
||||
}
|
||||
} else {
|
||||
redisTemplate.boundValueOps(RequestContext.Catalog.Tenant.name() + account).increment(1L);
|
||||
String num = redisTemplate.opsForValue().get(RequestContext.Catalog.Tenant.name() + account);
|
||||
loginResult = new GeneralResult<>(false, loginResult.getMessage() + ",已操作【" + num + "】次");
|
||||
}
|
||||
return loginResult;
|
||||
} catch (Exception e) {
|
||||
log.error("Get error message:", e);
|
||||
return loginResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
redisTemplate.delete(RequestContext.Catalog.Tenant.name() + account);
|
||||
return loginResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户登出
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @return 登出结果
|
||||
*/
|
||||
@Operation(summary = "租户登出")
|
||||
@PostMapping("/tenants/logout")
|
||||
public Result tenantLogout(
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.logout(requestContext.getTarget());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验用户密码
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @param password 密码
|
||||
* @return 校验结果
|
||||
*/
|
||||
@Operation(summary = "校验用户密码")
|
||||
@GetMapping("/check/password")
|
||||
public GeneralResult checkPassword(@Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
@RequestParam String password
|
||||
) {
|
||||
switch (requestContext.getCatalog()) {
|
||||
case Tenant:
|
||||
return tenantService.checkPassword(requestContext, password);
|
||||
case Manager:
|
||||
case User:
|
||||
return userService.checkPassword(requestContext, password);
|
||||
default:
|
||||
}
|
||||
return new GeneralResult(false, "校验用户密码异常");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key
|
||||
*
|
||||
* @param apiKey 安全密钥
|
||||
* @return key
|
||||
*/
|
||||
@Operation(summary = "获取key")
|
||||
@GetMapping("/key")
|
||||
public GeneralResult<AccountSecurity> key(@RequestParam(value = "apiKey") String apiKey) {
|
||||
return tenantService.apiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录账号信息详情
|
||||
*
|
||||
* @param requestContext 请求人
|
||||
* @return 账号信息详情
|
||||
*/
|
||||
@Operation(summary = "获取登录账号信息详情")
|
||||
@GetMapping("/login/detail")
|
||||
public GeneralResult<Map<String, Object>> loginDetail(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
Map<String, Object> resultMap = MapTools.simpleMap("accountCategory", requestContext.getCatalog());
|
||||
if (Objects.requireNonNull(requestContext.getCatalog()) == RequestContext.Catalog.Tenant) {
|
||||
resultMap.put(requestContext.getCatalog().name(),
|
||||
tenantService.detail(requestContext.getTarget()).getData());
|
||||
GeneralResult<TenantAccount> accountDetail =
|
||||
cosInternelService.tenantAccountDetail(requestContext.getTarget(), requestContext.getApiKey());
|
||||
resultMap.put("tenantAccount", accountDetail.isSuccess() ? accountDetail.getData() : null);
|
||||
} else {
|
||||
resultMap
|
||||
.put(requestContext.getCatalog().name(), userService.detail(requestContext.getTarget()).getData());
|
||||
}
|
||||
Long projectId = Long.parseLong(
|
||||
Optional.ofNullable(redisTemplate.opsForValue().get("current_project_" + requestContext.getApiKey()))
|
||||
.orElse("0"));
|
||||
resultMap.put("projectId", projectId);
|
||||
return new GeneralResult<>(true, resultMap, "获取登录账号信息成功");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Message;
|
||||
import com.bocloud.sms.interfaces.MessageService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/messages")
|
||||
@Tag(name = "消息管理")
|
||||
public class MessageController {
|
||||
|
||||
private final MessageService messageService;
|
||||
|
||||
public MessageController(MessageService messageService) {
|
||||
this.messageService = messageService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息列表
|
||||
*
|
||||
* @param pager 分页对象
|
||||
* @param context 请求对象
|
||||
* @return 消息列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "获取消息列表")
|
||||
public GeneralResult<GridBean<Message>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return messageService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除消息
|
||||
*
|
||||
* @param id 消息id
|
||||
* @param context 请求对象
|
||||
* @return 删除结果
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除消息")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return messageService.remove(id, context.getTarget());
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息详情
|
||||
*
|
||||
* @param id 消息id
|
||||
* @param context 请求对象
|
||||
* @return 消息详情
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取消息详情")
|
||||
public GeneralResult<Message> detail(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return messageService.detail(id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户消息状态全部更新为已读
|
||||
*
|
||||
* @param context 请求对象
|
||||
* @return 更新结果
|
||||
*/
|
||||
@PatchMapping
|
||||
@Operation(summary = "更改消息状态")
|
||||
public Result readAll(@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return messageService.messageRead(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计当前用户消息的状态数量
|
||||
*
|
||||
* @param context 请求对象
|
||||
* @return 状态数量
|
||||
*/
|
||||
@GetMapping(value = "/stats")
|
||||
@Operation(summary = "统计消息数量")
|
||||
public GeneralResult<Message> statistics(@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return messageService.statistics(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.NameRule;
|
||||
import com.bocloud.sms.interfaces.NameRuleService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 命名规则控制器
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 3.0.0-SNAPSHOT
|
||||
* @since 2018/7/2
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/namings")
|
||||
@Tag(name = "命名规则")
|
||||
public class NameRuleController {
|
||||
|
||||
private final NameRuleService nameRuleService;
|
||||
|
||||
public NameRuleController(NameRuleService nameRuleService) {
|
||||
this.nameRuleService = nameRuleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取命名规则列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 命名规则列表
|
||||
*/
|
||||
@Operation(summary = "获取命名规则列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<NameRule>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return nameRuleService.list(pager, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加命名规则
|
||||
*
|
||||
* @param nameRule 命名规则
|
||||
* @param context 上下文
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Operation(summary = "添加命名规则")
|
||||
@PostMapping
|
||||
public GeneralResult<NameRule> create(@RequestBody NameRule nameRule,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return nameRuleService.create(nameRule, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改命名规则
|
||||
*
|
||||
* @param id 命名规则id
|
||||
* @param nameRule 命名规则
|
||||
* @param context 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改命名规则")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody NameRule nameRule, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
nameRule.setId(id);
|
||||
return nameRuleService.modify(nameRule, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据命名规则生成云主机名称
|
||||
*
|
||||
* @param id 命名规则id
|
||||
* @param tenantId 租户id
|
||||
* @param userId 用户id
|
||||
* @param projectId 项目id
|
||||
* @return 云主机名称
|
||||
*/
|
||||
@Operation(summary = "根据命名规则生成云主机名称")
|
||||
@PatchMapping("/{id}")
|
||||
public GeneralResult<String> patch(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestParam(value = "tenantId") Long tenantId,
|
||||
@RequestParam(value = "userId") Long userId,
|
||||
@RequestParam(value = "projectId") Long projectId, RequestContext context) {
|
||||
return nameRuleService.generate(id, tenantId, userId, projectId, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除命名规则
|
||||
*
|
||||
* @param id 命名规则id
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除命名规则")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id) {
|
||||
return nameRuleService.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看命名规则详情
|
||||
*
|
||||
* @param id 命名规则id
|
||||
* @return 命名规则
|
||||
*/
|
||||
@Operation(summary = "查看命名规则详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<NameRule> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return nameRuleService.detail(id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.Permission;
|
||||
import com.bocloud.sms.interfaces.PermissionService;
|
||||
import com.bocloud.sms.model.*;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限控制器
|
||||
*
|
||||
* @author tyl
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "权限管理")
|
||||
@RequestMapping("/v1/permissions")
|
||||
public class PermissionController {
|
||||
|
||||
private final PermissionService permissionService;
|
||||
|
||||
public PermissionController(PermissionService permissionService) {
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询权限树
|
||||
*
|
||||
* @param parentId 父权限id
|
||||
* @param tenant 是否为租户权限
|
||||
* @return 权限树
|
||||
*/
|
||||
@Operation(summary = "查询权限列表")
|
||||
@GetMapping("/tree")
|
||||
public GeneralResult<List<PermissionBean>> list(@RequestParam(value = Common.PARENTID, required = false) Long parentId, @RequestParam(value = "category", required = false) String category, @RequestParam(value = "tenant", required = false) Boolean tenant) {
|
||||
return permissionService.list(parentId, category, tenant);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询图标
|
||||
*
|
||||
* @return 图标列表
|
||||
*/
|
||||
@Operation(summary = "查询图标")
|
||||
@GetMapping("/icons")
|
||||
public GeneralResult<List<PermissionIcon>> listIcon(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.listIcon(requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有权限父节点
|
||||
*
|
||||
* @return 权限列表
|
||||
*/
|
||||
@Operation(summary = "查询父节点")
|
||||
@GetMapping("/parents")
|
||||
public GeneralResult<List<PermissionParentsBean>> listParents(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.listParents(requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加权限
|
||||
*
|
||||
* @param permissionModel 权限
|
||||
* @param requestContext 上下文
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Operation(summary = "添加权限")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody PermissionModel permissionModel, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.create(permissionModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改权限
|
||||
*
|
||||
* @param id 权限id
|
||||
* @param permissionModel 权限
|
||||
* @param requestContext 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "权限修改")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id, @RequestBody PermissionModel permissionModel, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.modify(id, permissionModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除权限
|
||||
*
|
||||
* @param id 权限id
|
||||
* @param requestContext 上下文
|
||||
* @return 移除结果
|
||||
*/
|
||||
@Operation(summary = "删除权限")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看权限详细信息
|
||||
*
|
||||
* @param id 权限id
|
||||
* @return 权限
|
||||
*/
|
||||
@Operation(summary = "查询权限详细信息")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Permission> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return permissionService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按类型查询权限列表
|
||||
*
|
||||
* @param parentId 父权限id
|
||||
* @param tenant 是否为租户权限
|
||||
*/
|
||||
@Operation(summary = "查询权限列表")
|
||||
@GetMapping
|
||||
public GeneralResult<List<PermissionBean>> listPermissions(@RequestParam(value = Common.PARENTID, required = false) Long parentId, @RequestParam(value = "category", required = false) String category, @RequestParam(value = "tenant", required = false) Boolean tenant) {
|
||||
return permissionService.list(parentId, category, tenant);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 按字典查询权限列表
|
||||
*
|
||||
* @param condition 字典值
|
||||
*/
|
||||
@Operation(summary = "字典查询权限列表")
|
||||
@GetMapping("/condition")
|
||||
public GeneralResult<List<Permission>> listPermissionsByCondition(@RequestParam(value = Common.CONDITION, required = false) String condition) {
|
||||
return permissionService.listPermissionsByCondition(condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ServiceId获取服务菜单权限信息
|
||||
*
|
||||
* @param serviceId 服务id
|
||||
* @return 菜单权限
|
||||
*/
|
||||
@Operation(summary = "查询服务菜单权限")
|
||||
@GetMapping("/info")
|
||||
public GeneralResult<Permission> getServicePermissions(@RequestParam(value = "serviceId", required = false) Long serviceId) {
|
||||
return permissionService.getServicePermission(serviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询服务模块api权限列表
|
||||
*
|
||||
* @return 权限列表
|
||||
*/
|
||||
@Operation(summary = "查询服务模块API权限列表")
|
||||
@GetMapping("/modules")
|
||||
public GeneralResult<JSONArray> getApiList() {
|
||||
return permissionService.getApiList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据服务code查询服务模块API权限列表
|
||||
*
|
||||
* @param serviceCodes
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "根据服务code查询服务模块API权限列表")
|
||||
@GetMapping("/modules/services")
|
||||
public GeneralResult<JSONArray> getApiList(@RequestParam(value = "serviceCodes") String serviceCodes) {
|
||||
List<String> codes = JSONArray.parseArray(serviceCodes).toJavaList(String.class);
|
||||
if (!codes.isEmpty()) {
|
||||
return permissionService.getApiList(codes);
|
||||
}
|
||||
return new GeneralResult<>(false, "参数格式错误");
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件绑定权限
|
||||
*
|
||||
* @param permissionPlugins 权限插件
|
||||
* @param requestContext 上下文
|
||||
* @return 权限列表
|
||||
*/
|
||||
@Operation(summary = "插件绑定权限")
|
||||
@PutMapping("/binding/plugins")
|
||||
public Result bindingPlugins(@RequestBody PermissionPlugins permissionPlugins, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return permissionService.bindingPlugins(permissionPlugins.getPermissionIdList(), permissionPlugins.getPluginsCode(), permissionPlugins.getTenant(), requestContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,274 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Dictionary;
|
||||
import com.bocloud.sms.entity.Plugin;
|
||||
import com.bocloud.sms.interfaces.PluginService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 插件管理
|
||||
*
|
||||
* @author zhangyf
|
||||
* @since 2022-05-20
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/v2/plugins")
|
||||
@Tag(name = "插件管理")
|
||||
public class PluginController {
|
||||
|
||||
private final PluginService pluginService;
|
||||
|
||||
@Value("${spring.upload.path:/home/cmp}")
|
||||
private String path;
|
||||
@Value("${plugin.repository.path:/home/cmp/plugins/repository/}")
|
||||
private String pluginRepoPath;
|
||||
|
||||
public PluginController(PluginService pluginService) {
|
||||
this.pluginService = pluginService;
|
||||
}
|
||||
|
||||
/*-------------------------------------------- 不可见插件列表接口 --------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 新增Plugin插件
|
||||
*
|
||||
* @param name 名称
|
||||
* @param vendorType 平台
|
||||
* @param service 主服务
|
||||
* @param filepath 插件包
|
||||
* @return 新增结果
|
||||
*/
|
||||
@PostMapping
|
||||
@Operation(summary = "新增插件")
|
||||
public Result create(@RequestParam(value = "name") String name,
|
||||
@RequestParam(value = "vendorType", required = false) String vendorType,
|
||||
@RequestParam(value = "service", required = false) String service,
|
||||
@RequestParam(value = "filepath", required = false) String filepath) throws IOException {
|
||||
File tmpFile = new File(path + File.separator + filepath);
|
||||
File destFile = new File(pluginRepoPath + File.separator + service, tmpFile.getName());
|
||||
try {
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
if (!destFile.getParentFile().mkdirs()) {
|
||||
log.error("mkdir {} failed}", destFile.getParentFile());
|
||||
}
|
||||
}
|
||||
FileUtils.copyFile(tmpFile, destFile);
|
||||
FileUtils.delete(tmpFile);
|
||||
if (FileUtils.isEmptyDirectory(tmpFile.getParentFile())) {
|
||||
FileUtils.deleteDirectory(tmpFile.getParentFile());
|
||||
}
|
||||
Plugin plugin = new Plugin();
|
||||
plugin.setService(service);
|
||||
plugin.setName(name);
|
||||
plugin.setService(service);
|
||||
plugin.setVendorType(vendorType);
|
||||
plugin.setSize(FileUtils.sizeOf(destFile));
|
||||
plugin.setPath(destFile.getName());
|
||||
return pluginService.create(plugin);
|
||||
} catch (RuntimeException | IOException e) {
|
||||
if (destFile.exists() && !destFile.delete()) {
|
||||
log.warn("临时文件删除失败:{}", destFile.getPath());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改Plugin插件
|
||||
*
|
||||
* @param id ID
|
||||
* @param name 名称
|
||||
* @param vendorType 平台类型
|
||||
* @param service 主服务
|
||||
* @param filepath 插件包
|
||||
* @return 修改结果
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
@Operation(summary = "修改插件")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id, @RequestParam(value = "name") String name,
|
||||
@RequestParam(value = "vendorType", required = false) String vendorType,
|
||||
@RequestParam(value = "service", required = false) String service,
|
||||
@RequestParam(value = "filepath", required = false) String filepath) throws IOException {
|
||||
boolean hasPackage = filepath != null;
|
||||
File tmpFile = filepath != null ? new File(path + File.separator + filepath) : null;
|
||||
File destFile = null;
|
||||
if (hasPackage) {
|
||||
destFile = new File(pluginRepoPath + File.separator + service, tmpFile.getName());
|
||||
}
|
||||
try {
|
||||
if (hasPackage) {
|
||||
if (!destFile.getParentFile().exists()) {
|
||||
if (!destFile.getParentFile().mkdirs()) {
|
||||
log.error("mkdir {} failed}", destFile.getParentFile());
|
||||
}
|
||||
}
|
||||
FileUtils.copyFile(tmpFile, destFile);
|
||||
FileUtils.delete(tmpFile);
|
||||
if (FileUtils.isEmptyDirectory(tmpFile.getParentFile())) {
|
||||
FileUtils.deleteDirectory(tmpFile.getParentFile());
|
||||
}
|
||||
}
|
||||
Plugin plugin = new Plugin();
|
||||
plugin.setService(service);
|
||||
plugin.setName(name);
|
||||
plugin.setVendorType(vendorType);
|
||||
plugin.setSize(hasPackage ? FileUtils.sizeOf(destFile) : null);
|
||||
plugin.setPath(hasPackage ? destFile.getName() : null);
|
||||
return pluginService.modify(id, plugin, hasPackage);
|
||||
} catch (RuntimeException | IOException e) {
|
||||
if (hasPackage) {
|
||||
if (destFile.exists() && !destFile.delete()) {
|
||||
log.warn("临时文件删除失败:{}", destFile.getPath());
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Plugin插件
|
||||
*
|
||||
* @param id 插件id
|
||||
* @return 删除结果
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "删除插件")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id) {
|
||||
return pluginService.remove(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除Plugin插件
|
||||
*
|
||||
* @param idList 插件id列表
|
||||
* @return 成功/失败 个数
|
||||
*/
|
||||
@DeleteMapping("/batch")
|
||||
@Operation(summary = "批量删除插件")
|
||||
public Result batchRemove(@RequestBody List<Long> idList) {
|
||||
return pluginService.batchRemove(idList);
|
||||
}
|
||||
|
||||
@GetMapping("/{service}/installed")
|
||||
@Operation(summary = "已安装插件列表")
|
||||
public GeneralResult<Map<String, List<Plugin>>> listInstalled(@PathVariable(value = "service") String service) {
|
||||
Map<String, List<Plugin>> pluginList = pluginService.listInstalled(service);
|
||||
return new GeneralResult<>(true, pluginList, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 可更新插件列表
|
||||
*
|
||||
* @param service 服务name
|
||||
* @return 插件列表
|
||||
*/
|
||||
@GetMapping("/{service}/update")
|
||||
@Operation(summary = "可更新插件列表")
|
||||
public GeneralResult<Map<String, List<Plugin>>> listUpdate(@PathVariable(value = "service") String service) {
|
||||
Map<String, List<Plugin>> pluginList = pluginService.listUpdate(service);
|
||||
return new GeneralResult<>(true, pluginList, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 已安装插件列表
|
||||
*
|
||||
* @param service 服务名称
|
||||
* @return 插件列表
|
||||
*/
|
||||
@GetMapping("/{service}/install")
|
||||
@Operation(summary = "已安装插件列表")
|
||||
public GeneralResult<Map<String, List<Plugin>>> listCanInstall(@PathVariable(value = "service") String service) {
|
||||
Map<String, List<Plugin>> pluginList = pluginService.listCanInstall(service);
|
||||
return new GeneralResult<>(true, pluginList, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 插件列表
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(summary = "插件列表")
|
||||
public GeneralResult<GridBean<Plugin>> list(Pager pager) {
|
||||
return pluginService.list(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件列表
|
||||
*
|
||||
* @param code 分页参数
|
||||
* @return 插件列表
|
||||
*/
|
||||
@GetMapping("/{code}/upgrade")
|
||||
@Operation(summary = "插件列表")
|
||||
public GeneralResult<GridBean<Plugin>> upgradeList(@PathVariable(value = "code") String code, Pager pager) {
|
||||
pager.getParams().add(new Param(MapTools.simpleMap("code", code), Sign.EQ));
|
||||
return pluginService.list(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件列表
|
||||
*
|
||||
* @param code 分页参数
|
||||
* @return 插件列表
|
||||
*/
|
||||
@GetMapping("/{code}/degradation")
|
||||
@Operation(summary = "插件列表")
|
||||
public GeneralResult<GridBean<Plugin>> degradationList(@PathVariable(value = "code") String code, Pager pager) {
|
||||
pager.getParams().add(new Param(MapTools.simpleMap("code", code), Sign.EQ));
|
||||
return pluginService.list(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询插件详情
|
||||
*
|
||||
* @param id 插件id
|
||||
* @return 插件
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "插件详情")
|
||||
public GeneralResult<Plugin> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return new GeneralResult<>(true, pluginService.detail(id), "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件支持的云平台列表信息(资源接入)
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return 插件支持的云平台列表信息
|
||||
*/
|
||||
@GetMapping("/vendors")
|
||||
@Operation(summary = "插件支持的云平台列表")
|
||||
public GeneralResult<List<Dictionary>> getVendorList(Pager pager) {
|
||||
return pluginService.getVendorList(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取license中的插件列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return license中的插件列表
|
||||
*/
|
||||
@GetMapping("/license")
|
||||
@Operation(summary = "获取Plugin插件列表")
|
||||
public GeneralResult<List<Plugin>> licenseList(Pager pager) {
|
||||
List<Plugin> plugins = pluginService.listLicense(pager);
|
||||
return new GeneralResult<>(true, plugins, "查询成功");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.service.internel.PluginInsideService;
|
||||
import com.megatron.common.model.Result;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/v1/plugins")
|
||||
@Tag(name = "插件")
|
||||
@Slf4j
|
||||
public class PluginInsideController {
|
||||
|
||||
private final PluginInsideService pluginInsideService;
|
||||
private final ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
public PluginInsideController(PluginInsideService pluginInsideService, ThreadPoolTaskExecutor taskExecutor) {
|
||||
this.pluginInsideService = pluginInsideService;
|
||||
this.taskExecutor = taskExecutor;
|
||||
}
|
||||
|
||||
@PutMapping("/{pluginId}/start")
|
||||
@Operation(summary = "启动插件")
|
||||
public Result start(@PathVariable(value = "pluginId") String pluginId,
|
||||
@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance) {
|
||||
taskExecutor.execute(() -> pluginInsideService.start(service, instance, pluginId));
|
||||
return new Result(true, "启动插件任务已下发");
|
||||
}
|
||||
|
||||
@PutMapping("/{pluginId}/stop")
|
||||
@Operation(summary = "停止插件")
|
||||
public Result stop(@PathVariable(value = "pluginId") String pluginId,
|
||||
@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance) {
|
||||
taskExecutor.execute(() -> pluginInsideService.stop(service, instance, pluginId));
|
||||
return new Result(true, "停止插件任务已下发");
|
||||
}
|
||||
|
||||
@PutMapping("/install")
|
||||
@Operation(summary = "安装插件")
|
||||
public Result install(@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance,
|
||||
@RequestParam(value = "pluginPath") String pluginPath) {
|
||||
taskExecutor.execute(() -> pluginInsideService.install(service, instance, pluginPath));
|
||||
return new Result(true, "安装插件任务已下发");
|
||||
}
|
||||
|
||||
@PutMapping("/{pluginId}/uninstall")
|
||||
@Operation(summary = "卸载插件")
|
||||
public Result uninstall(@PathVariable(value = "pluginId") String pluginId,
|
||||
@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance) {
|
||||
taskExecutor.execute(() -> pluginInsideService.uninstall(service, instance, pluginId));
|
||||
return new Result(true, "卸载插件任务已下发");
|
||||
}
|
||||
|
||||
@PutMapping("/{pluginId}/upgrade")
|
||||
@Operation(summary = "升级插件")
|
||||
public Result upgrade(@PathVariable(value = "pluginId") String pluginId,
|
||||
@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance,
|
||||
@RequestParam(value = "pluginPath") String pluginPath) {
|
||||
taskExecutor.execute(() -> pluginInsideService.upgrade(service, instance, pluginId, pluginPath));
|
||||
return new Result(true, "升级插件任务已下发");
|
||||
}
|
||||
|
||||
@PutMapping("/{pluginId}/demote")
|
||||
@Operation(summary = "降级插件")
|
||||
public Result demote(@PathVariable(value = "pluginId") String pluginId,
|
||||
@RequestParam(value = "service") String service,
|
||||
@RequestParam(value = "instance") String instance,
|
||||
@RequestParam(value = "pluginPath") String pluginPath) {
|
||||
taskExecutor.execute(() -> pluginInsideService.upgrade(service, instance, pluginId, pluginPath));
|
||||
return new Result(true, "降级插件任务已下发");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.interfaces.PortalElementConfigService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 组件配置元素controller层
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/portal/elements")
|
||||
@Tag(name = "组件配置管理")
|
||||
public class PortalElementConfigController {
|
||||
@Autowired
|
||||
private PortalElementConfigService portalElementConfigService;
|
||||
|
||||
/**
|
||||
* 组件配置元素列表展示
|
||||
*
|
||||
* @param poolId 组件id
|
||||
* @return 元素列表
|
||||
*/
|
||||
@Operation(summary = "组件配置元素列表展示")
|
||||
@GetMapping
|
||||
public GeneralResult list(@RequestParam(value = "poolId") Long poolId) {
|
||||
if (null != poolId) {
|
||||
return portalElementConfigService.list(poolId);
|
||||
} else {
|
||||
return new GeneralResult(false, "参数格式不正确");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
|
||||
import com.bocloud.sms.interfaces.PortalElementPoolService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 组件池controller层
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/portal/elementpools")
|
||||
@Tag(name = "组件池管理")
|
||||
public class PortalElementPoolController {
|
||||
@Autowired
|
||||
private PortalElementPoolService portalElementPoolService;
|
||||
|
||||
/**
|
||||
* 组件池列表展示
|
||||
*
|
||||
* @param module 配置
|
||||
* @return 组件池列表
|
||||
*/
|
||||
@Operation(summary = "组件池列表展示")
|
||||
@GetMapping
|
||||
public GeneralResult list(@RequestParam(value = "module", required = false) String module) {
|
||||
return portalElementPoolService.list(module);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.entity.PortalPanel;
|
||||
import com.bocloud.sms.interfaces.PortalPanelService;
|
||||
import com.bocloud.sms.model.PortalPanelBean;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 首页配置controller
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/portal/panels")
|
||||
@Tag(name = "主页配置管理")
|
||||
public class PortalPanelController {
|
||||
|
||||
@Autowired
|
||||
private PortalPanelService portalPanelService;
|
||||
|
||||
/**
|
||||
* 查询配置列表展示
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return 配置列表
|
||||
*/
|
||||
@Operation(summary = "主页配置列表展示")
|
||||
@GetMapping
|
||||
public GeneralResult list(@RequestParam(value = "module", required = false) String module,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return portalPanelService.list(module, context);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新首页配置
|
||||
*
|
||||
* @param portalPanelBean 首页配置
|
||||
* @param context 上下文
|
||||
* @return 更新结果
|
||||
*/
|
||||
@Operation(summary = "保存主页配置")
|
||||
@PatchMapping
|
||||
public GeneralResult save(@RequestBody PortalPanelBean portalPanelBean,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
if (null != portalPanelBean) {
|
||||
if (portalPanelBean.getConfig() == null) {
|
||||
return new GeneralResult(false, "参数格式不正确");
|
||||
}
|
||||
List<PortalPanel> portalPanels = JSONObject.parseArray(portalPanelBean.getConfig(), PortalPanel.class);
|
||||
return portalPanelService.save(portalPanels, context.getTarget(), context.getTenant(), null, portalPanelBean.getModule());
|
||||
} else {
|
||||
return new GeneralResult(false, "参数格式不正确");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复默认设置
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return 恢复结果
|
||||
*/
|
||||
@Operation(summary = "恢复默认设置")
|
||||
@PutMapping("/{module}/reset")
|
||||
public GeneralResult reset(@PathVariable(value = "module") String module, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return portalPanelService.reset(module, context);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.Business;
|
||||
import com.bocloud.sms.entity.Project;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.interfaces.ProjectService;
|
||||
import com.bocloud.sms.interfaces.UserService;
|
||||
import com.bocloud.sms.model.ProjectModel;
|
||||
import com.bocloud.sms.model.ProjectUserBean;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/projects")
|
||||
@Tag(name = "项目关联")
|
||||
@Slf4j
|
||||
public class ProjectController {
|
||||
|
||||
private final ProjectService projectService;
|
||||
private final UserService userService;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
|
||||
public ProjectController(ProjectService projectService, UserService userService, StringRedisTemplate redisTemplate) {
|
||||
this.projectService = projectService;
|
||||
this.userService = userService;
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询项目列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param requestContext 请求上下文
|
||||
* @return 项目列表
|
||||
*/
|
||||
@Operation(summary = "获取项目列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Project>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
@RequestParam(value = "tenantId", required = false, defaultValue = "false") Boolean tenantId) {
|
||||
return projectService.list(pager, requestContext, tenantId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字典查询项目信息
|
||||
*
|
||||
* @param condition 字典值
|
||||
* @return 项目信息
|
||||
*/
|
||||
@Operation(summary = "字典查询项目信息")
|
||||
@GetMapping("/condition")
|
||||
public GeneralResult condition(@RequestParam(value = Common.CONDITION, required = false) String condition, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.condition(condition, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
*
|
||||
* @param projectModel 项目
|
||||
* @param requestContext 上下文
|
||||
* @return 创建结果
|
||||
*/
|
||||
@Operation(summary = "创建项目")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody ProjectModel projectModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.create(projectModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换项目
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return 项目切换结果
|
||||
*/
|
||||
@Operation(summary = "切换项目")
|
||||
@PatchMapping("/{id}")
|
||||
public Result switchProject(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
String apiKey = requestContext.getApiKey();
|
||||
Assert.isTrue(StringUtils.isNotEmpty(apiKey), "当前会话存在异常");
|
||||
try {
|
||||
redisTemplate.opsForValue().set("current_project_" + apiKey, String.valueOf(id));
|
||||
return new Result(true, "项目切换成功");
|
||||
} catch (Exception e) {
|
||||
return new Result(false, "项目切换失败");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改项目
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param projectModel 项目
|
||||
* @param requestContext 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "修改项目信息")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id, @RequestBody ProjectModel projectModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.modify(id, projectModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param requestContext 上下文
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Operation(summary = "删除项目")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除项目
|
||||
*
|
||||
* @param ids 项目id列表
|
||||
* @param requestContext 上下文
|
||||
* @return 批量删除结果
|
||||
*/
|
||||
@Operation(summary = "批量删除项目")
|
||||
@DeleteMapping
|
||||
public Result batchRemove(@RequestBody List<Long> ids, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.batchRemove(ids, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看项目详情
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return 项目
|
||||
*/
|
||||
@Operation(summary = "查看项目详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Project> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return projectService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看项目所在业务
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return 业务
|
||||
*/
|
||||
@Operation(summary = "查看项目所在业务信息")
|
||||
@GetMapping("/{id}/business")
|
||||
public GeneralResult<Business> business(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return projectService.getBusinessDetail(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目配置用户
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param projectUserBean 项目用户
|
||||
* @return 配置结果
|
||||
*/
|
||||
@Operation(summary = "项目配追用户")
|
||||
@PostMapping("/{id}/users")
|
||||
public Result configUser(@PathVariable(value = Common.ID) Long id, @RequestBody ProjectUserBean projectUserBean) {
|
||||
return projectService.configUser(id, projectUserBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目用户设置为项目经理
|
||||
*
|
||||
* @param id 项目id
|
||||
* @param userId 用户id
|
||||
* @return 设置结果
|
||||
*/
|
||||
@Operation(summary = "项目用户设置为项目经理")
|
||||
@PatchMapping("/{id}/users/{userId}")
|
||||
public Result configUser(@PathVariable(value = Common.ID) Long id, @PathVariable(value = "userId") Long userId) {
|
||||
return projectService.configProjectManager(id, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询项目下关联的的用户ID
|
||||
*
|
||||
* @param id 项目id
|
||||
* @return 用户列表
|
||||
*/
|
||||
@Operation(summary = "查询项目下关联用户")
|
||||
@GetMapping("/{id}/users")
|
||||
public GeneralResult<List<User>> listByProject(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.listProjectUser(id, requestContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询项目经理
|
||||
*
|
||||
* @param id 项目
|
||||
* @return 用户列表
|
||||
*/
|
||||
@Operation(summary = "查询项目经理")
|
||||
@GetMapping("/{id}/managers")
|
||||
public GeneralResult<List<User>> listProjectManager(@PathVariable(value = Common.ID) Long id) {
|
||||
return userService.listProjectManager(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出项目列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param requestContext 请求上下文
|
||||
* @return 项目列表
|
||||
*/
|
||||
@Deprecated
|
||||
@Operation(summary = "导出项目列表")
|
||||
@RequestMapping(value = "/export", method = {RequestMethod.GET})
|
||||
public void export(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
List<Param> paramList = pager.getParams();
|
||||
if (paramList.size() == 0) {
|
||||
paramList.add(new Param(MapTools.simpleMap("tenantId", 0), Sign.UEQ));
|
||||
}
|
||||
try {
|
||||
XSSFWorkbook workbook = projectService.export(paramList, requestContext);
|
||||
// 下载表格到浏览器
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("application/octet-stream");
|
||||
String fileName = "项目统计数据" + System.currentTimeMillis() + ".xlsx";
|
||||
final String userAgent = request.getHeader("user-agent").toLowerCase();
|
||||
if (userAgent.contains("trident") || userAgent.contains("edge")) {
|
||||
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
|
||||
} else {
|
||||
fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
|
||||
OutputStream os = response.getOutputStream();
|
||||
workbook.write(os);
|
||||
os.flush();
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
log.error("export project error,", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载项目列表模板
|
||||
*
|
||||
* @param request 浏览器请求
|
||||
* @param response 浏览器响应
|
||||
* @param requestContext 上下文
|
||||
*/
|
||||
@Operation(summary = "下载项目列表模板")
|
||||
@RequestMapping(value = "/import/template", method = {RequestMethod.GET})
|
||||
public void importTemp(HttpServletRequest request, HttpServletResponse response,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
projectService.importTemp(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入项目列表
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @param request 浏览器请求
|
||||
* @return 导入结果
|
||||
*/
|
||||
@Operation(summary = "导入项目列表")
|
||||
@PostMapping(value = "/import")
|
||||
public Result importData(@Value(Common.REQ_CONTEXT) RequestContext requestContext, HttpServletRequest request) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<MultipartFile> fileList = multipartRequest.getFiles("file");
|
||||
if (fileList.isEmpty()) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
MultipartFile multipartFile = fileList.get(0);
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
// 判断文件名
|
||||
if (originalFilename == null || !(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
return projectService.importData(multipartFile, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询某组织下所有项目
|
||||
*
|
||||
* @param requestContext 请求上下文
|
||||
* @return 项目列表
|
||||
*/
|
||||
@Operation(summary = "根据组织名称查询某组织下所有项目")
|
||||
@GetMapping("/by/depart")
|
||||
public GeneralResult<List<Project>> queryByDepart(@Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
@RequestParam(value = "departName") String departName) {
|
||||
return projectService.queryByDepart(departName);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据组织ID查询某组织下所有项目")
|
||||
@GetMapping("/by/depart/ids")
|
||||
public GeneralResult<List<Project>> queryByDepart(Pager pager, @RequestParam(value = "departIds") List<Long> departIds) {
|
||||
return projectService.queryByDepartIds(pager, departIds);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据项目名称获取项目")
|
||||
@GetMapping("/by/name")
|
||||
public GeneralResult<Project> getByProjectName(@RequestParam(value = "projectName") String projectName) {
|
||||
return projectService.getByProjectName(projectName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.Role;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.interfaces.RoleService;
|
||||
import com.bocloud.sms.model.ApiInfo;
|
||||
import com.bocloud.sms.model.CloudServiceBean;
|
||||
import com.bocloud.sms.model.RoleModel;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/roles")
|
||||
@Tag(name = "角色管理")
|
||||
public class RoleController {
|
||||
|
||||
private final RoleService roleService;
|
||||
|
||||
public RoleController(RoleService roleService) {
|
||||
this.roleService = roleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加角色
|
||||
*
|
||||
* @param roleModel 角色
|
||||
* @param requestContext 上下文
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Operation(summary = "创建角色")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody RoleModel roleModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.create(roleModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改角色
|
||||
*
|
||||
* @param roleModel 角色
|
||||
* @param requestContext 上下文
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Operation(summary = "角色修改")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody RoleModel roleModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.modify(id, roleModel, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除角色
|
||||
*
|
||||
* @param id 角色id
|
||||
* @param requestContext 上下文
|
||||
* @return 移除结果
|
||||
*/
|
||||
@Operation(summary = "角色删除")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看角色详细信息
|
||||
*
|
||||
* @param id 角色id
|
||||
* @return 角色
|
||||
*/
|
||||
@Operation(summary = "角色详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Role> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return roleService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色授权
|
||||
*
|
||||
* @param id 角色id
|
||||
* @param ids 用户id
|
||||
* @param requestContext 上下文
|
||||
* @return 授权结果
|
||||
*/
|
||||
@Operation(summary = "角色授权")
|
||||
@PatchMapping("/{id}")
|
||||
public Result accredit(@PathVariable(value = Common.ID) Long id, @RequestBody List<Long> ids,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.accredit(id, ids, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询角色的权限列表
|
||||
*
|
||||
* @param id 角色id
|
||||
* @param requestContext 上下文
|
||||
* @return 权限列表
|
||||
*/
|
||||
@Operation(summary = "获取权限列表")
|
||||
@GetMapping("/{id}/permissions")
|
||||
public GeneralResult<List<CloudServiceBean>> permissions(@PathVariable(value = Common.ID) Long id, @RequestParam(value = "menu", required = false) boolean menu,
|
||||
@RequestParam(value = "tenant", required = false) boolean tenant, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.listPermissions(id, menu, tenant, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询角色列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param requestContext 上下文
|
||||
* @return 角色列表
|
||||
*/
|
||||
@Operation(summary = "获取角色列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Role>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.list(pager, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求用户角色信息(用于boot comment 获取角色Api权限)
|
||||
*
|
||||
* @param requestContext 请求用户
|
||||
* @return 角色信息
|
||||
*/
|
||||
@GetMapping("/ids")
|
||||
public GeneralResult<List<Long>> roleIds(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return roleService.roleIds(requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* API授权
|
||||
*
|
||||
* @param id 角色id
|
||||
* @param apis apiid列表
|
||||
* @return 授权结果
|
||||
*/
|
||||
@Operation(summary = "API授权")
|
||||
@PatchMapping("/{id}/apis")
|
||||
public Result accreditRole(@PathVariable(value = Common.ID) Long id, @RequestBody List<ApiInfo> apis) {
|
||||
return roleService.accreditRole(id, apis);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询API权限列表
|
||||
*
|
||||
* @param id 角色id
|
||||
* @param tags
|
||||
* @return 权限列表
|
||||
*/
|
||||
@Operation(summary = "查询API权限列表")
|
||||
@GetMapping("/{id}/apis")
|
||||
public GeneralResult<JSONArray> getModuleList(@PathVariable(value = Common.ID) Long id, @RequestParam(value = "tags", required = false) String tags) {
|
||||
return roleService.getApiPermission(id, tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定角色下的用户
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param id 角色id
|
||||
* @return 用户列表
|
||||
*/
|
||||
@Operation(summary = "查询指定角色下的用户")
|
||||
@GetMapping("/{id}/users")
|
||||
public GeneralResult<GridBean<User>> listUsersByRoleId(Pager pager, @PathVariable(value = Common.ID) Long id) {
|
||||
return roleService.listUsersByRoleId(pager, id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.interfaces.*;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/v1/single/login")
|
||||
@Tag(name = "单点登录")
|
||||
public class SingleLoginController {
|
||||
|
||||
@Autowired
|
||||
private SingleLoginService service;
|
||||
|
||||
@GetMapping()
|
||||
@Operation(summary = "单点登录")
|
||||
public RedirectView doLoginCallback(@RequestParam String token, HttpServletRequest request) throws Exception {
|
||||
return service.singleLogin(token, request);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.interfaces.SysDateViewService;
|
||||
import com.megatron.common.model.Result;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @ClassName: SysDateViewController
|
||||
* @Description: 系统数据统计概览
|
||||
* @Author lxy
|
||||
* @Date 2021/9/29 10:09
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/system")
|
||||
@Tag(name = "系统数据统计概览")
|
||||
public class SysDateViewController {
|
||||
@Autowired
|
||||
private SysDateViewService sysDateViewService;
|
||||
|
||||
/**
|
||||
* 用户访问控制数据统计
|
||||
*
|
||||
* @return 用户访问控制数据
|
||||
*/
|
||||
@Operation(summary = "用户访问控制数据统计")
|
||||
@GetMapping("/count")
|
||||
public Result systemCount() {
|
||||
return sysDateViewService.systemCount();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.interfaces.SystemConfigService;
|
||||
import com.bocloud.sms.model.ConfigModel;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lyy
|
||||
* @Version 1.0
|
||||
* @since 2017年8月18日
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1")
|
||||
@Tag(name = "系统配置管理")
|
||||
public class SystemConfigController {
|
||||
|
||||
private final SystemConfigService systemConfigService;
|
||||
|
||||
public SystemConfigController(SystemConfigService systemConfigService) {
|
||||
this.systemConfigService = systemConfigService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统配置
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @param request 浏览器请求
|
||||
* @return 更新结果
|
||||
*/
|
||||
@Operation(summary = "更新系统配置")
|
||||
@PutMapping("/system-configs")
|
||||
public Result modify(@Value(Common.REQ_CONTEXT) RequestContext requestContext, HttpServletRequest request) {
|
||||
List<ConfigModel> configs = JSONArray.parseArray(request.getParameter("configs"), ConfigModel.class);
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
return systemConfigService.batchUpdate(configs, fileMap, requestContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步Ldap
|
||||
*
|
||||
* @return 同步结果
|
||||
*/
|
||||
@Operation(summary = "同步Ldap")
|
||||
@PostMapping("/configs/syncLdap")
|
||||
public Result syncLdap() {
|
||||
return systemConfigService.syncLdap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询系统配置
|
||||
*
|
||||
* @param category
|
||||
* @param codes
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量查询系统配置")
|
||||
@GetMapping("/configs")
|
||||
public GeneralResult<Map<String, String>> getByCodes(@RequestParam(value = "category", required = false) String category, @RequestParam(value = "codes", required = false) ArrayList<String> codes) {
|
||||
return systemConfigService.listConfigs(category, codes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询系统配置类型树
|
||||
*
|
||||
* @param category
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询系统配置类型树")
|
||||
@GetMapping("/configs/tree")
|
||||
public GeneralResult<JSONArray> listCategoryTree(@RequestParam(value = "category") String category) {
|
||||
return systemConfigService.listCategoryTree(category);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 系统配置连接测试
|
||||
*
|
||||
* @param category
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "系统配置连接测试")
|
||||
@GetMapping("/configs/test")
|
||||
public Result configTest(@RequestParam(value = "category") String category) {
|
||||
return systemConfigService.configTest(category);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,949 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.cmp.boot.model.BoCloudExchange;
|
||||
import com.bocloud.cmp.boot.model.BoCloudService;
|
||||
import com.bocloud.sms.interfaces.PrometheusService;
|
||||
import com.bocloud.sms.interfaces.QueryService;
|
||||
import com.bocloud.sms.monitor.*;
|
||||
import com.bocloud.sms.service.monitor.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.megatron.common.http.HttpClient;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.License;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.IDFactory;
|
||||
import com.megatron.common.utils.ListTool;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import com.megatron.framework.core.RegistryService;
|
||||
import com.megatron.framework.core.Service;
|
||||
import com.megatron.framework.license.LicenseDaemon;
|
||||
import com.megatron.framework.registry.ZooKeeperClient;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageProperties;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.connection.*;
|
||||
import org.springframework.data.redis.connection.jedis.JedisClusterConnection;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.jedis.JedisSentinelConnection;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceClusterConnection;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceSentinelConnection;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Tag(name = "系统监控")
|
||||
@RestController
|
||||
@RequestMapping("/v1/system/monitor")
|
||||
@Slf4j
|
||||
public class SystemController {
|
||||
private static final String NODE_EXPORTER = "node_exporter";
|
||||
private static final String TELEGRAF = "telegraf";
|
||||
private static final String BLACK_BOX = "blackbox";
|
||||
private static final String MASTER = "master";
|
||||
private static final String ERROR = "error";
|
||||
private static final String WARNING = "warning";
|
||||
private static final String RUNNING = "running";
|
||||
/**
|
||||
* 声明超时时间
|
||||
*/
|
||||
private static final Long TIME_OUT = (long) (1000 * 10);
|
||||
private final LicenseDaemon licenseDaemon;
|
||||
|
||||
@Autowired
|
||||
private RegistryService registry;
|
||||
@Autowired
|
||||
private RabbitAdmin rabbitAdmin;
|
||||
@Autowired
|
||||
private ZooKeeperClient client;
|
||||
@Autowired
|
||||
private StringRedisTemplate redisTemplate;
|
||||
@Autowired
|
||||
private Environment env;
|
||||
@Autowired
|
||||
private PrometheusMonitor prometheusMonitor;
|
||||
@Autowired
|
||||
private PrometheusConfig prometheusConfig;
|
||||
@Autowired
|
||||
private PrometheusService prometheusService;
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
@Autowired
|
||||
private RegistryService registryService;
|
||||
@Autowired
|
||||
private MySqlConfiguration mySqlConfiguration;
|
||||
@Autowired
|
||||
private QueryService queryService;
|
||||
|
||||
public SystemController(CurrentService currentService) {
|
||||
this.licenseDaemon = LicenseDaemon.instance(currentService);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询主机状态统计图
|
||||
*
|
||||
* @param start 开始时间
|
||||
* @param end 结束时间
|
||||
* @param ip 地址
|
||||
* @param step 间隔时长
|
||||
* @return 统计数据信息
|
||||
*/
|
||||
@GetMapping("/charts")
|
||||
@Operation(summary = "查询主机状态统计信息")
|
||||
public GeneralResult<?> getChars(String start, String end, String ip, String step) {
|
||||
String cpuParam = "round((1 - avg(irate(node_cpu_seconds_total{instance=\"" + ip
|
||||
+ "\",mode=\"idle\"}[5m])) by (instance))*100,0.01)";
|
||||
String memParam = "round(100 - ((node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes)/node_memory_MemTotal_bytes{instance=\"" + ip
|
||||
+ "\"}) * 100,0.01)";
|
||||
String diskParam = "round(100 - sum(node_filesystem_free_bytes{ instance=\"" + ip
|
||||
+ "\",fstype!~\"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*\"}) "
|
||||
+ "/ sum(node_filesystem_size_bytes{ instance=\"" + ip
|
||||
+ "\",fstype!~\"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*\"}) * 100,0.01)";
|
||||
String networkParam1 = "sum(round(1/1024*irate(node_network_receive_bytes_total{instance=\"" + ip
|
||||
+ "\",device=~\"en.*|em.*|eth.*|ten.*|one.*\"}[5m])))";
|
||||
String networkParam2 = "sum(round(1/1024*irate(node_network_transmit_bytes_total{instance=\"" + ip
|
||||
+ "\",device=~\"en.*|em.*|eth.*|ten.*|one.*\"}[5m])))";
|
||||
Map<String, Object> charsMap = new HashMap<>(16, 0.75F);
|
||||
charsMap.put("cpu", queryService.chart(Collections.singletonList(cpuParam), Collections.singletonList("cpu使用率"), start, end, "20", "%"));
|
||||
charsMap.put("mem", queryService.chart(Collections.singletonList(memParam), Collections.singletonList("内存使用率"), start, end, "20", "%"));
|
||||
charsMap.put("disk", queryService.chart(Collections.singletonList(diskParam), Collections.singletonList("磁盘使用率"), start, end, "20", "%"));
|
||||
charsMap.put("network", queryService.chart(Arrays.asList(networkParam1, networkParam2), Arrays.asList("网络流入速率", "网络流出速率"), start, end, "20", "kb/s"));
|
||||
return new GeneralResult<>(true, charsMap, "success");
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统状态信息
|
||||
*
|
||||
* @param host 服务host地址(带端口)
|
||||
* @return 系统主机状态信息
|
||||
*/
|
||||
@Operation(summary = "服务状态信息")
|
||||
@GetMapping("/status")
|
||||
public GeneralResult<?> status(@RequestParam(value = Common.VALUE) String host) {
|
||||
HttpClient client = new HttpClient();
|
||||
String value = "http://" + host + "/status";
|
||||
Result result = client.get(value);
|
||||
return result.isSuccess() ? JSONObject.parseObject(result.getMessage(), GeneralResult.class)
|
||||
: new GeneralResult<>(false, result.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询系统状态信息
|
||||
*
|
||||
* @return 状态
|
||||
*/
|
||||
@Operation(summary = "查询系统状态信息")
|
||||
@GetMapping("/servers")
|
||||
public GeneralResult<?> servers() {
|
||||
Set<String> instances = prometheusService.filter("up{tag='cmp'}", "instance");
|
||||
List<Map<String, Object>> servers = Lists.newArrayList();
|
||||
Optional.ofNullable(instances).orElse(new HashSet<>()).forEach(host -> {
|
||||
// 先判断主机是否启动
|
||||
Double value = prometheusService.simpleQuery("up{tag='cmp'}", Collections.singletonMap("instance", host));
|
||||
Map<String, Object> data = new HashMap<>(16, 0.75F);
|
||||
Double cpuUsed = prometheusService.simpleQuery("round((1 - avg(irate(node_cpu_seconds_total{mode='idle'}[5m])) by (instance))*100,0.01)", Collections.singletonMap("instance", host));
|
||||
Double memUsed = prometheusService.simpleQuery("round(100 - ((node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes)/node_memory_MemTotal_bytes{}) * 100,0.01)", Collections.singletonMap("instance", host));
|
||||
Double diskUsed = prometheusService.simpleQuery("round(100 - sum(node_filesystem_free_bytes{ instance='" + host
|
||||
+ "',fstype!~'rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*'})"
|
||||
+ "/ sum(node_filesystem_size_bytes{instance='" + host
|
||||
+ "',fstype!~'rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*'}) * 100,0.01)");
|
||||
data.put("host", host);
|
||||
data.put("cpuUsed", cpuUsed);
|
||||
data.put("memUsed", memUsed);
|
||||
data.put("diskUsed", diskUsed);
|
||||
data.put("status", (1D == value) ? RUNNING : ERROR);
|
||||
servers.add(data);
|
||||
});
|
||||
return new GeneralResult<>(true, servers, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询服务状态信息
|
||||
*
|
||||
* @return 返回服务状态信息
|
||||
*/
|
||||
@Operation(summary = "查询服务状态信息")
|
||||
@GetMapping("/services")
|
||||
public GeneralResult<?> service() {
|
||||
ServicesModel servicesModel = new ServicesModel();
|
||||
License catalog = licenseDaemon.content();
|
||||
List<String> services = catalog.getService();
|
||||
Integer hosts = catalog.getCatalog().getHosts();
|
||||
Integer instances = catalog.getCatalog().getInstances();
|
||||
// 从Licenses里面获取AIO/STD
|
||||
servicesModel.setHosts(hosts);
|
||||
servicesModel.setInstances(instances);
|
||||
List<ServicesModel.Service> serviceList = Lists.newArrayList();
|
||||
License content = licenseDaemon.content();
|
||||
if (services != null) {
|
||||
if (services.contains(BoCloudService.CMP.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.CMP, "纳管服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.SMS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.SMS, "系统管理服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.CMS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.CMS, "监控服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.COP.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.COP, "运维服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.TSE.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.TSE, "任务引擎服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.ROS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.ROS, "编排服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.COS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.COS, "运营服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.AMS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.AMS, "资产服务", content));
|
||||
}
|
||||
if (services.contains(BoCloudService.BMS.getName())) {
|
||||
serviceList.add(buildServiceModel(BoCloudService.BMS, "裸金属服务", content));
|
||||
}
|
||||
}
|
||||
servicesModel.setService(serviceList);
|
||||
return new GeneralResult<>(true, servicesModel, "查询成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取插件的状态信息
|
||||
*
|
||||
* @return 插件列表
|
||||
*/
|
||||
@Operation(summary = "查询插件状态信息")
|
||||
@GetMapping("/plugins")
|
||||
public GeneralResult<?> plugins() {
|
||||
List<PluginsModel> pluginsModel = Lists.newArrayList();
|
||||
License catalog = licenseDaemon.content();
|
||||
List<String> services = catalog.getService();
|
||||
if (services != null) {
|
||||
if (services.contains(BoCloudService.GAIA.getName())) {
|
||||
pluginsModel.add(buildPluginsModel(BoCloudService.GAIA, "作业代理"));
|
||||
}
|
||||
if (services.contains(BoCloudService.PONTUS.getName())) {
|
||||
pluginsModel.add(buildPluginsModel(BoCloudService.PONTUS, "存储代理"));
|
||||
}
|
||||
}
|
||||
return new GeneralResult<>(true, pluginsModel, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询组件状态信息
|
||||
*
|
||||
* @return 组件状态信息
|
||||
*/
|
||||
@Operation(summary = "查询组件状态信息")
|
||||
@GetMapping("/components")
|
||||
public GeneralResult<?> components() {
|
||||
List<ComponentModel> componentModels = Lists.newArrayList();
|
||||
String druidUrl = env.getProperty("spring.datasource.druid.url");
|
||||
assert druidUrl != null;
|
||||
if (druidUrl.contains("mysql")) {
|
||||
componentModels.add(buildComponentMysql());
|
||||
}
|
||||
componentModels.add(buildComponentPrometheus());
|
||||
componentModels.add(buildComponentZookeeper());
|
||||
componentModels.add(buildComponentRabbitmq());
|
||||
componentModels.add(buildComponentAlertManager());
|
||||
componentModels.add(buildComponentRedis());
|
||||
return new GeneralResult<>(true, componentModels, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询网关状态信息
|
||||
*
|
||||
* @return 组件状态信息
|
||||
*/
|
||||
@Operation(summary = "查询网关状态信息")
|
||||
@GetMapping("/gateway")
|
||||
public GeneralResult<?> gateWayComponents() {
|
||||
List<ComponentModel> componentModels = Lists.newArrayList();
|
||||
componentModels.add(buildComponentGateway());
|
||||
return new GeneralResult<>(true, componentModels, "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务对应实例地址
|
||||
*
|
||||
* @param service 服务
|
||||
* @return 实例地址集合
|
||||
*/
|
||||
private List<String> getServices(BoCloudService service) {
|
||||
try {
|
||||
List<String> serviceInstances = registry.getServices(Service.create(service.getName()));
|
||||
return ListTool.isEmpty(serviceInstances) ? new ArrayList<>() : serviceInstances;
|
||||
} catch (RuntimeException e) {
|
||||
log.error("get services error:" + e.getMessage());
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务数据
|
||||
*
|
||||
* @param service 服务
|
||||
* @param alias 服务名
|
||||
* @return 服务数据
|
||||
*/
|
||||
private ServicesModel.Service buildServiceModel(@NonNull BoCloudService service, @NonNull String alias, License content) {
|
||||
List<ServicesModel.Service.Instance> data = Lists.newArrayList();
|
||||
try {
|
||||
String status = RUNNING;
|
||||
// 获取license里面规定的实例个数(从mac地址中获取)
|
||||
int instances = content.getAddress().size();
|
||||
List<String> servers = getServices(service);
|
||||
log.info(service + " 获取到服务列表:" + servers);
|
||||
int errorNum = 0;
|
||||
for (String server : servers) {
|
||||
server = server.replaceAll("http://", "").replaceAll("https://", "");
|
||||
String state = this.registryService.getServiceState(service.getName(), server);
|
||||
SystemBean systemBean;
|
||||
ServicesModel.Service.Instance serviceInstance = new ServicesModel.Service.Instance();
|
||||
try {
|
||||
systemBean = JSONObject.parseObject(state).toJavaObject(SystemBean.class);
|
||||
} catch (Exception e) {
|
||||
log.error(service + "获取服务信息失败!" + e);
|
||||
errorNum++;
|
||||
serviceInstance.setHost(server);
|
||||
serviceInstance.setStatus(ERROR);
|
||||
data.add(serviceInstance);
|
||||
continue;
|
||||
}
|
||||
serviceInstance.setHost(systemBean.getServiceInstance());
|
||||
serviceInstance.setStatus(RUNNING);
|
||||
serviceInstance.setCpuUsed(this.round(BigDecimal.valueOf(systemBean.getJvmCpuUsage()).doubleValue() * 100d));
|
||||
serviceInstance.setMemUsed(this.round(BigDecimal.valueOf(txfloat(systemBean.getJvmMemoryUsed(), systemBean.getJvmMemoryMax())).doubleValue() * 100d));
|
||||
serviceInstance.setLogger(service.getName() + ".server");
|
||||
serviceInstance.setIsLeader(systemBean.getIsLeader());
|
||||
data.add(serviceInstance);
|
||||
}
|
||||
if (0 < errorNum || data.size() < instances) {
|
||||
if (data.size() <= instances) {
|
||||
int difference = instances - data.size();
|
||||
for (int i = 0; i < difference; i++) {
|
||||
ServicesModel.Service.Instance errorInstance = new ServicesModel.Service.Instance();
|
||||
errorInstance.setStatus(ERROR);
|
||||
data.add(errorInstance);
|
||||
}
|
||||
}
|
||||
status = WARNING;
|
||||
}
|
||||
if (errorNum >= data.size() || data.size() <= 0) {
|
||||
status = ERROR;
|
||||
}
|
||||
return new ServicesModel.Service(alias, status, data);
|
||||
} catch (Exception e) {
|
||||
log.error("系统监控服务查询失败!" + service);
|
||||
return new ServicesModel.Service(alias, ERROR, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重载方法,一个是参数只有 插件名,从Prometheus里获取其状态 另一个是有插件名,和oCloudService
|
||||
* service,从getServices获取IP,后确定其状态
|
||||
*
|
||||
* @param name 插件名
|
||||
* @return 插件数据
|
||||
*/
|
||||
private PluginsModel buildPluginsModel(String name) {
|
||||
String pluginsName = switch (name) {
|
||||
case "采集组件" -> TELEGRAF;
|
||||
case "通断监控" -> BLACK_BOX;
|
||||
default -> NODE_EXPORTER;
|
||||
};
|
||||
PluginsModel pluginsModel = new PluginsModel();
|
||||
try {
|
||||
List<PrometheusResult> results = prometheusService.query("up{job=\"" + pluginsName + "\"}");
|
||||
List<PluginsModel.Plugin> data = Lists.newArrayList();
|
||||
boolean status = !ListTool.isEmpty(results);
|
||||
// 活跃个数应该与服务器个数相同,介于 0 和
|
||||
int runningNums = Optional.ofNullable(results).orElse(new ArrayList<>()).size();
|
||||
// size之间为 warning,0 为 error
|
||||
for (PrometheusResult obj : results) {
|
||||
PluginsModel.Plugin plugin = new PluginsModel.Plugin();
|
||||
String host = String.valueOf(obj.getMetric().get("instance"));
|
||||
boolean active = "1".equals(obj.getValue()[1]);
|
||||
if (!active) {
|
||||
runningNums--;
|
||||
// 只要有不存活的服务器,status就是false;即不可能是running状态
|
||||
status = false;
|
||||
}
|
||||
plugin.setStatus(active ? RUNNING : ERROR);
|
||||
if (!NODE_EXPORTER.equals(pluginsName)) {
|
||||
plugin.setHost(host + "(" + name + ")");
|
||||
} else {
|
||||
plugin.setHost(host);
|
||||
}
|
||||
plugin.setLogger(pluginsName + ".server");
|
||||
data.add(plugin);
|
||||
}
|
||||
pluginsModel.setName(pluginsName + "(" + data.size() + ")");
|
||||
pluginsModel.setStatus(runningNums == 0 ? ERROR : status ? RUNNING : WARNING);
|
||||
pluginsModel.setInstance(data);
|
||||
return pluginsModel;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
pluginsModel.setName(pluginsName + "(0)");
|
||||
pluginsModel.setStatus(ERROR);
|
||||
pluginsModel.setInstance(null);
|
||||
return pluginsModel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重载方法,一个是参数只有 插件名,从Prometheus里获取其状态 另一个是有插件名,和BoCloudService
|
||||
* service,从getServices获取IP,后确定其状态
|
||||
*
|
||||
* @param service 插件服务
|
||||
* @param alias 插件服务名
|
||||
* @return 插件数据
|
||||
*/
|
||||
private PluginsModel buildPluginsModel(@NonNull BoCloudService service, @NonNull String alias) {
|
||||
List<String> servers = getServices(service);
|
||||
PluginsModel pluginsModel = new PluginsModel();
|
||||
List<PluginsModel.Plugin> data = Lists.newArrayList();
|
||||
boolean status = !servers.isEmpty();
|
||||
// 活跃个数应该与服务器个数相同,介于 0 和 size之间为 warning,0 为 error
|
||||
int runningNums = servers.size();
|
||||
for (String server : servers) {
|
||||
PluginsModel.Plugin plugin = new PluginsModel.Plugin();
|
||||
if (service == BoCloudService.MCS) {
|
||||
// fixBug:不兼容的类型: com.megatron.framework.core.Service无法转换为java.lang.String
|
||||
registry.getServices(Service.create(service.getName()));
|
||||
Map<String, String> serviceStatus = registry.getServiceStatus(service.getName());
|
||||
plugin.setStatus(serviceStatus.isEmpty() ? ERROR : RUNNING);
|
||||
} else {
|
||||
plugin.setStatus(RUNNING);
|
||||
}
|
||||
server = server.replaceAll("http://", "").replaceAll("https://", "");
|
||||
if (service == BoCloudService.MCS) {
|
||||
plugin.setHost(server + "(" + alias + ")");
|
||||
} else {
|
||||
plugin.setHost(server);
|
||||
}
|
||||
plugin.setLogger(service.getName() + ".server");
|
||||
data.add(plugin);
|
||||
}
|
||||
// 将telegraf和blackbox放入EXPORTER里面,作为一个个体
|
||||
if (service == BoCloudService.MCS) {
|
||||
// 为了函数能返回两个值,放进一个集合,index 0为Boolean,index 1为Integer类型,不能打乱顺序,已经写死,后面根据索引取出
|
||||
List<Object> list = new ArrayList<>(2);
|
||||
list.add(status);
|
||||
list.add(runningNums);
|
||||
getPluginInstance("通断监控(" + data.size() + ")", list, data);
|
||||
getPluginInstance("采集组件(" + data.size() + ")", list, data);
|
||||
status = (boolean) list.get(0);
|
||||
runningNums = (int) list.get(1);
|
||||
}
|
||||
pluginsModel.setName(alias);
|
||||
String setStatus = runningNums == 0 ? ERROR : status ? RUNNING : WARNING;
|
||||
pluginsModel.setStatus(setStatus);
|
||||
pluginsModel.setInstance(data);
|
||||
return pluginsModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* telegraf和blackbox放入了EXPORTER,该函数为在EXPORTER中单独获取telegraf和blackbox
|
||||
*
|
||||
* @param name 名字
|
||||
* @param list 列表
|
||||
* @param data 数据展示
|
||||
*/
|
||||
private void getPluginInstance(String name, List<Object> list, List<PluginsModel.Plugin> data) {
|
||||
boolean status = (boolean) list.get(0);
|
||||
int runningNums = (int) list.get(1);
|
||||
PluginsModel model = buildPluginsModel(name);
|
||||
if (model.getInstance() != null) {
|
||||
for (PluginsModel.Plugin plugin : model.getInstance()) {
|
||||
if (RUNNING.equals(model.getStatus())) {
|
||||
runningNums++;
|
||||
} else {
|
||||
status = false;
|
||||
}
|
||||
data.add(plugin);
|
||||
}
|
||||
} else {
|
||||
PluginsModel.Plugin plugin = new PluginsModel.Plugin();
|
||||
plugin.setStatus(ERROR);
|
||||
plugin.setHost(name);
|
||||
status = false;
|
||||
data.add(plugin);
|
||||
}
|
||||
list.set(0, status);
|
||||
list.set(1, runningNums);
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加mysql
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentMysql() {
|
||||
try {
|
||||
GeneralResult<?> result = mySqlConfiguration.dbStatus();
|
||||
log.info("mySqlExecuteResult: " + result);
|
||||
List<ComponentModel.Component> components = Lists.newArrayList();
|
||||
int errorNum = 0;
|
||||
if (result.isSuccess()) {
|
||||
JSONObject mysqlInfo = JSONObject.parseObject(result.getData().toString());
|
||||
if (mysqlInfo.getString("mysqlInfos") != null) {
|
||||
List<String> masterHosts = JSONArray.parseArray(mysqlInfo.getJSONArray("masterHosts").toJSONString(), String.class);
|
||||
JSONArray mysqlInfos = mysqlInfo.getJSONArray("mysqlInfos");
|
||||
// 主节点没有slaveStatus这个属性
|
||||
for (int i = 0; i < mysqlInfos.size(); i++) {
|
||||
JSONObject info = mysqlInfos.getJSONObject(i);
|
||||
String host = info.getString("host");
|
||||
String status;
|
||||
if (info.getJSONArray("ThreadsGlobalStatus") != null) {
|
||||
status = RUNNING;
|
||||
} else {
|
||||
status = ERROR;
|
||||
errorNum++;
|
||||
}
|
||||
components.add(new ComponentModel.Component(host, status, null, masterHosts.contains(host), info));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorNum == components.size()) {
|
||||
return new ComponentModel("数据库", ERROR, components);
|
||||
} else if (errorNum > 0) {
|
||||
return new ComponentModel("数据库", WARNING, components);
|
||||
}
|
||||
return new ComponentModel("数据库", RUNNING, components);
|
||||
} catch (Exception e) {
|
||||
log.error("获取数据库状态失败:" + e.getMessage(), e);
|
||||
return new ComponentModel("数据库", ERROR, Lists.newArrayList());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加Prometheus
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentPrometheus() {
|
||||
String addr = null;
|
||||
List<ComponentModel.Component> servers = Lists.newArrayList();
|
||||
try {
|
||||
String[] addresses = Optional.ofNullable(prometheusConfig.getNodeUrls()).orElse("").split(",");
|
||||
boolean status = addresses.length != 0;
|
||||
// 活跃个数应该与服务器个数相同,介于 0 和 size之间为 warning,0 为 error
|
||||
int runningNums = addresses.length;
|
||||
for (String address : addresses) {
|
||||
addr = address;
|
||||
try {
|
||||
boolean conn = prometheusMonitor.isPrometheusConn(address);
|
||||
if (!conn) {
|
||||
runningNums--;
|
||||
// 只要有不存活的服务器,status就是false;即不可能是running状态
|
||||
status = false;
|
||||
}
|
||||
servers.add(new ComponentModel.Component(address.replaceAll("https?://", ""), conn ? RUNNING : ERROR, null,
|
||||
true, null));
|
||||
} catch (Exception e) {
|
||||
log.error("获取Prometheus组件信息失败: " + address);
|
||||
servers.add(new ComponentModel.Component(address.replaceAll("https?://", ""), ERROR, null,
|
||||
false, null));
|
||||
}
|
||||
}
|
||||
ComponentModel componentModel = new ComponentModel();
|
||||
componentModel.setName("监控中心");
|
||||
componentModel.setStatus(runningNums == 0 ? ERROR : status ? RUNNING : WARNING);
|
||||
componentModel.setInstance(servers);
|
||||
return componentModel;
|
||||
} catch (Exception e) {
|
||||
log.error("获取Prometheus组件信息失败: " + addr);
|
||||
ComponentModel componentModel = new ComponentModel();
|
||||
componentModel.setName("监控中心");
|
||||
componentModel.setStatus(ERROR);
|
||||
componentModel.setInstance(servers);
|
||||
return componentModel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加zookeeper
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentZookeeper() {
|
||||
try {
|
||||
boolean connected = client.getClient().getZookeeperClient().isConnected();
|
||||
String[] serverUrls = client.getProperties().getServerUrl().split(",");
|
||||
ComponentModel componentModel = new ComponentModel();
|
||||
List<ComponentModel.Component> servers = Lists.newArrayList();
|
||||
boolean warning = false;
|
||||
componentModel.setName("注册中心");
|
||||
for (String serverUrl : serverUrls) {
|
||||
String host = serverUrl.split(":")[0];
|
||||
String port = serverUrl.split(":")[1];
|
||||
ZooKeeper zk = ZooKeeperMonitor.getZooKeeperMonitor(host, Integer.parseInt(port));
|
||||
// 获取状态
|
||||
String status = zk.getStatus();
|
||||
String state = "";
|
||||
if (zk.getMonitorInfo() != null) {
|
||||
// 获取角色leader,follow
|
||||
state = zk.getMonitorInfo().getString("zk_server_state");
|
||||
}
|
||||
// 检测单个节点是否挂掉了
|
||||
if (ERROR.equals(status)) {
|
||||
warning = true;
|
||||
}
|
||||
servers.add(new ComponentModel.Component(host + ":" + port, status, null,
|
||||
serverUrls.length == 1 || "leader".equals(state), zk));
|
||||
}
|
||||
componentModel.setInstance(servers);
|
||||
String setStatus = connected ? warning ? WARNING : RUNNING : ERROR;
|
||||
componentModel.setStatus(setStatus);
|
||||
return componentModel;
|
||||
} catch (RuntimeException e) {
|
||||
log.error("build zookeeper component error:" + e.getMessage(), e);
|
||||
return new ComponentModel("注册中心", ERROR, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加rabbitMq
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentRabbitmq() {
|
||||
try {
|
||||
String queue = IDFactory.instance().uuid();
|
||||
String address = env.getProperty("spring.rabbitmq.addresses");
|
||||
String mqHost = env.getProperty("spring.rabbitmq.host");
|
||||
String rabbitmqHost = address != null ? address : mqHost;
|
||||
int port = rabbitAdmin.getRabbitTemplate().getConnectionFactory().getPort();
|
||||
String[] hosts = Objects.requireNonNull(rabbitmqHost).split(",");
|
||||
boolean success = false;
|
||||
try {
|
||||
rabbitAdmin.declareQueue(new Queue(queue, false, false, true));
|
||||
rabbitAdmin.declareBinding(new Binding(queue, Binding.DestinationType.QUEUE,
|
||||
BoCloudExchange.Default.DIRECT.getExchange(), queue, null));
|
||||
String testContent = "This message is used for testing.";
|
||||
rabbitAdmin.getRabbitTemplate().send(queue, new Message(testContent.getBytes(), new MessageProperties()));
|
||||
//fix Bug Cast one of the operands of this multiplication operation to a "long"
|
||||
Message message = rabbitAdmin.getRabbitTemplate().receive(queue, TIME_OUT);
|
||||
if (message != null && message.getBody().length > 0) {
|
||||
String content = new String(message.getBody());
|
||||
if (testContent.equals(content)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("detect RabbitMQ connection exception:" + e.getMessage());
|
||||
} finally {
|
||||
this.rabbitAdmin.deleteQueue(queue);
|
||||
}
|
||||
List<ComponentModel.Component> servers = Lists.newArrayList();
|
||||
for (String host : hosts) {
|
||||
String username = env.getProperty("spring.rabbitmq.username");
|
||||
String password = env.getProperty("spring.rabbitmq.password");
|
||||
// RabbitMQ的Http API端口都是 15672 但是配置文件中没有 直接用固定值
|
||||
assert username != null;
|
||||
JSONObject overview = RabbitMqMonitor.getOverview(host.split(":")[0], username, password);
|
||||
if (overview == null) {
|
||||
if (address != null) {
|
||||
servers.add(new ComponentModel.Component(host, ERROR, null, false, null));
|
||||
} else {
|
||||
servers.add(new ComponentModel.Component(host + ":" + port, ERROR, null, false, null));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
String clusterName = overview.getString("cluster_name");
|
||||
String node = overview.getString("node");
|
||||
JSONObject nodeInfo = RabbitMqMonitor.getNodeMonitor(host.split(":")[0], username, password, node);
|
||||
JSONObject rabbitmq = new JSONObject();
|
||||
rabbitmq.put("overview", overview);
|
||||
rabbitmq.put("nodeInfo", nodeInfo);
|
||||
if (address != null) {
|
||||
servers.add(new ComponentModel.Component(host, success ? RUNNING : ERROR, null,
|
||||
clusterName.equals(node), rabbitmq));
|
||||
} else {
|
||||
servers.add(new ComponentModel.Component(host + ":" + port, success ? RUNNING : ERROR, null,
|
||||
clusterName.equals(node), rabbitmq));
|
||||
}
|
||||
}
|
||||
return new ComponentModel("消息队列", success ? RUNNING : ERROR, servers);
|
||||
} catch (RuntimeException e) {
|
||||
log.error("build zookeeper component error:" + e.getMessage(), e);
|
||||
return new ComponentModel("消息队列", ERROR, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加alertManager告警分发中心
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentAlertManager() {
|
||||
try {
|
||||
String[] addresses = Optional.ofNullable(prometheusConfig.getAlertmanagerUrl()).orElse("").split(",");
|
||||
boolean status = addresses.length != 0;
|
||||
// 活跃个数应该与服务器个数相同,介于 0 和 size之间为 warning,0 为 error
|
||||
int runningNums = addresses.length;
|
||||
List<ComponentModel.Component> componentList = Lists.newArrayList();
|
||||
for (String address : addresses) {
|
||||
try {
|
||||
boolean conn = prometheusMonitor.isAlertManagerConn(address);
|
||||
if (!conn) {
|
||||
runningNums--;
|
||||
// 只要有不存活的服务器,status就是false;即不可能是running状态
|
||||
status = false;
|
||||
}
|
||||
componentList.add(new ComponentModel.Component(address.replaceAll("https?://", ""), conn ? RUNNING : ERROR,
|
||||
null, true, null));
|
||||
} catch (Exception e) {
|
||||
log.error("获取AlertManager组件信息失败: " + address);
|
||||
componentList.add(new ComponentModel.Component(address.replaceAll("https?://", ""), ERROR,
|
||||
null, false, null));
|
||||
}
|
||||
}
|
||||
ComponentModel componentModel = new ComponentModel();
|
||||
componentModel.setName("告警中心");
|
||||
String setStatus = runningNums == 0 ? ERROR : status ? RUNNING : WARNING;
|
||||
componentModel.setStatus(setStatus);
|
||||
componentModel.setInstance(componentList);
|
||||
return componentModel;
|
||||
} catch (RuntimeException e) {
|
||||
log.error("build alertManager component error:" + e.getMessage(), e);
|
||||
return new ComponentModel("告警中心", ERROR, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件添加Redis
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentRedis() {
|
||||
try {
|
||||
boolean success = false;
|
||||
try (RedisConnection redisConnection = redisTemplate.getRequiredConnectionFactory().getConnection()) {
|
||||
if (!redisConnection.isClosed()) {
|
||||
String uuidKey = UUID.randomUUID().toString();
|
||||
redisTemplate.opsForValue().set(uuidKey, uuidKey, 10, TimeUnit.SECONDS);
|
||||
redisTemplate.delete(uuidKey);
|
||||
success = true;
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
log.error("detect redis connection error:" + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
List<ComponentModel.Component> servers = Lists.newArrayList();
|
||||
RedisConnectionFactory factory = this.redisTemplate.getConnectionFactory();
|
||||
if (factory instanceof JedisConnectionFactory jedisConnectionFactory) {
|
||||
if (jedisConnectionFactory.isRedisClusterAware()) {
|
||||
JedisClusterConnection jedisClusterConnection = (JedisClusterConnection) jedisConnectionFactory
|
||||
.getClusterConnection();
|
||||
Set<RedisClusterNode> clusterNodes = jedisClusterConnection.clusterGetNodes();
|
||||
for (RedisClusterNode clusterNode : clusterNodes) {
|
||||
String role = RedisMonitor.getRole(clusterNode.getHost(), Objects.requireNonNull(clusterNode.getPort()),
|
||||
jedisConnectionFactory.getPassword());
|
||||
servers.add(new ComponentModel.Component(clusterNode.getHost() + ":" + clusterNode.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
}
|
||||
} else if (jedisConnectionFactory.isRedisSentinelAware()) {
|
||||
buildSentinelInfo(servers, success, jedisConnectionFactory);
|
||||
} else {
|
||||
String role = RedisMonitor.getRole(jedisConnectionFactory.getHostName(),
|
||||
jedisConnectionFactory.getPort(), jedisConnectionFactory.getPassword());
|
||||
servers.add(new ComponentModel.Component(
|
||||
jedisConnectionFactory.getHostName() + ":" + jedisConnectionFactory.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
}
|
||||
} else if (factory instanceof LettuceConnectionFactory lettuceConnectionFactory) {
|
||||
if (lettuceConnectionFactory.isClusterAware()) {
|
||||
try {
|
||||
LettuceClusterConnection lettuceClusterConnection = (LettuceClusterConnection) lettuceConnectionFactory
|
||||
.getClusterConnection();
|
||||
List<RedisClusterNode> clusterNodes = lettuceClusterConnection.clusterGetNodes();
|
||||
for (RedisClusterNode clusterNode : clusterNodes) {
|
||||
String role = RedisMonitor.getRole(clusterNode.getHost(), Objects.requireNonNull(clusterNode.getPort()),
|
||||
lettuceConnectionFactory.getPassword());
|
||||
servers.add(new ComponentModel.Component(clusterNode.getHost() + ":" + clusterNode.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return new ComponentModel("集群缓存", ERROR, servers);
|
||||
}
|
||||
} else if (lettuceConnectionFactory.isRedisSentinelAware()) {
|
||||
buildSentinelInfo(servers, success, lettuceConnectionFactory);
|
||||
} else {
|
||||
String role = RedisMonitor.getRole(lettuceConnectionFactory.getHostName(),
|
||||
lettuceConnectionFactory.getPort(), lettuceConnectionFactory.getPassword());
|
||||
servers.add(new ComponentModel.Component(
|
||||
lettuceConnectionFactory.getHostName() + ":" + lettuceConnectionFactory.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
}
|
||||
}
|
||||
return new ComponentModel("缓存", RUNNING, servers);
|
||||
} catch (RuntimeException e) {
|
||||
log.error("build redis component error:" + e.getMessage(), e);
|
||||
return new ComponentModel("缓存", ERROR, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装redis哨兵数据(密码得在环境里面拿)
|
||||
*
|
||||
* @param servers 服务列表
|
||||
* @param success 成功/失败
|
||||
* @param redisConnectionFactory 连接配置数据
|
||||
*/
|
||||
private void buildSentinelInfo(List<ComponentModel.Component> servers, boolean success, RedisConnectionFactory redisConnectionFactory) {
|
||||
try (RedisSentinelConnection sentinelConnection = redisConnectionFactory.getSentinelConnection()) {
|
||||
// 所有master节点
|
||||
if (sentinelConnection instanceof LettuceSentinelConnection) {
|
||||
try {
|
||||
LettuceSentinelConnection lettuceSentinelConnection = (LettuceSentinelConnection) sentinelConnection;
|
||||
List<RedisServer> masters = lettuceSentinelConnection.masters();
|
||||
for (RedisServer master : masters) {
|
||||
String role = RedisMonitor.getRole(master.getHost(), Objects.requireNonNull(master.getPort()),
|
||||
env.getProperty("spring.redis.password"));
|
||||
servers.add(new ComponentModel.Component(master.getHost() + ":" + master.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
// 查找所有slave节点
|
||||
List<RedisServer> slaves = lettuceSentinelConnection.slaves(Objects.requireNonNull(master.getName()));
|
||||
for (RedisServer slave : slaves) {
|
||||
String nodeRole = RedisMonitor.getRole(slave.getHost(), Objects.requireNonNull(slave.getPort()),
|
||||
env.getProperty("spring.redis.password"));
|
||||
servers.add(new ComponentModel.Component(slave.getHost() + ":" + slave.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(nodeRole), null));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("组装redis哨兵数据失败:" + e.getMessage(), e);
|
||||
servers.add(new ComponentModel.Component(null, ERROR, null, false, null));
|
||||
}
|
||||
} else if (sentinelConnection instanceof JedisSentinelConnection) {
|
||||
try {
|
||||
JedisSentinelConnection jedisSentinelConnection = (JedisSentinelConnection) sentinelConnection;
|
||||
List<RedisServer> masters = jedisSentinelConnection.masters();
|
||||
for (RedisServer master : masters) {
|
||||
String role = RedisMonitor.getRole(master.getHost(), Objects.requireNonNull(master.getPort()),
|
||||
env.getProperty("spring.redis.password"));
|
||||
servers.add(new ComponentModel.Component(master.getHost() + ":" + master.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(role), null));
|
||||
// 查找所有slave节点
|
||||
List<RedisServer> slaves = jedisSentinelConnection.replicas(Objects.requireNonNull(master.getName()));
|
||||
for (RedisServer slave : slaves) {
|
||||
String nodeRole = RedisMonitor.getRole(slave.getHost(), Objects.requireNonNull(slave.getPort()),
|
||||
env.getProperty("spring.redis.password"));
|
||||
servers.add(new ComponentModel.Component(slave.getHost() + ":" + slave.getPort(),
|
||||
success ? RUNNING : ERROR, null, MASTER.equals(nodeRole), null));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("组装redis哨兵数据失败:" + e.getMessage(), e);
|
||||
servers.add(new ComponentModel.Component(null, ERROR, null, false, null));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 组件添加网关
|
||||
*
|
||||
* @return 成功/失败
|
||||
*/
|
||||
private ComponentModel buildComponentGateway() {
|
||||
try {
|
||||
ComponentModel componentModel = new ComponentModel();
|
||||
componentModel.setName("服务网关");
|
||||
List<ComponentModel.Component> servers = Lists.newArrayList();
|
||||
List<String> services = discoveryClient.getServices();
|
||||
List<ServiceInstance> gateways = new ArrayList<>();
|
||||
for (String service : services) {
|
||||
if ("gateway".equalsIgnoreCase(service)) {
|
||||
gateways = discoveryClient.getInstances(service);
|
||||
}
|
||||
}
|
||||
Optional.ofNullable(gateways).orElse(new ArrayList<>()).forEach(serviceInstance -> {
|
||||
boolean status = false;
|
||||
Map<String, String> metadata = serviceInstance.getMetadata();
|
||||
if (metadata.get("instance_status") != null) {
|
||||
status = "UP".equals(metadata.get("instance_status"));
|
||||
}
|
||||
servers.add(new ComponentModel.Component(serviceInstance.getHost() + ":" + serviceInstance.getPort(),
|
||||
Boolean.toString(status), null, false, serviceInstance));
|
||||
componentModel.setInstance(servers);
|
||||
componentModel.setStatus(Boolean.toString(status));
|
||||
});
|
||||
return componentModel;
|
||||
} catch (RuntimeException e) {
|
||||
log.error("build gateway component error:" + e.getMessage(), e);
|
||||
return new ComponentModel("服务网关", ERROR, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 除法运算,保留小数
|
||||
*
|
||||
* @param a 被除数
|
||||
* @param b 除数
|
||||
* @return 商
|
||||
* @author fzx
|
||||
*/
|
||||
private Double txfloat(int a, int b) {
|
||||
try {
|
||||
if (a == 0 || b == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
//设置保留位数
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
String result = df.format((double) a / b);
|
||||
return Double.parseDouble(result);
|
||||
} catch (Exception e) {
|
||||
log.error("错误除法运算!" + e);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 四舍五入函数
|
||||
*
|
||||
* @param sourceNum 原来的数字
|
||||
* @author sxp
|
||||
* @since 2018-04-26
|
||||
*/
|
||||
private double round(double sourceNum) {
|
||||
String num = Double.toString(sourceNum);
|
||||
BigDecimal sourceBd = new BigDecimal(num);
|
||||
BigDecimal one = new BigDecimal("1");
|
||||
// ROUND_HALF_UP
|
||||
// 向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则舍入远离零的方向(数轴上方向上)。
|
||||
// 注意,这是我们大多数人在小学时就学过的舍入模式,即四舍五入。
|
||||
return sourceBd.divide(one, 2, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.interfaces.SystemHomeService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
@Tag(name = "系统主页")
|
||||
@RestController
|
||||
@RequestMapping("/v1/system/home")
|
||||
@Slf4j
|
||||
public class SystemHomeController {
|
||||
|
||||
@Autowired
|
||||
private SystemHomeService systemHomeService;
|
||||
|
||||
|
||||
@Operation(summary = "获取云宏token")
|
||||
@GetMapping("/winhong/token")
|
||||
public GeneralResult<?> getToken() {
|
||||
return systemHomeService.getToken();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.SystemNotice;
|
||||
import com.bocloud.sms.interfaces.SystemNoticeService;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/system/notice")
|
||||
@Tag(name = "系统公告管理")
|
||||
public class SystemNoticeController {
|
||||
|
||||
private final SystemNoticeService service;
|
||||
|
||||
public SystemNoticeController(SystemNoticeService systemNoticeService) {
|
||||
this.service = systemNoticeService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*
|
||||
* @param entity
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody SystemNotice entity, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return service.create(entity, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "删除")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return service.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param id
|
||||
* @param entity
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id, @RequestBody SystemNotice entity,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return service.modify(entity, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "发布")
|
||||
@PostMapping("/send/{id}")
|
||||
public Result send(@PathVariable(value = Common.ID) Long id) {
|
||||
return service.sendMsg(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<SystemNotice>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return service.list(pager, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<SystemNotice> detail(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return service.detail(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,426 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.*;
|
||||
import com.bocloud.sms.interfaces.TenantService;
|
||||
import com.bocloud.sms.model.*;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author admin
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/tenants")
|
||||
@Tag(name = "租户管理")
|
||||
@Slf4j
|
||||
public class TenantController {
|
||||
|
||||
|
||||
private final TenantService tenantService;
|
||||
|
||||
public TenantController(TenantService tenantService) {
|
||||
this.tenantService = tenantService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加租户
|
||||
*
|
||||
* @param tenant
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建租户")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody TenantModel tenant,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.create(tenant, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改租户
|
||||
*
|
||||
* @param id
|
||||
* @param tenant
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改租户")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody TenantModel tenant,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.modify(id, tenant, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除租户
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "删除租户")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看租户详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询租户详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<Tenant> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return tenantService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定租户
|
||||
*
|
||||
* @param account 租户账号
|
||||
* @return 锁定结果
|
||||
*/
|
||||
@Operation(summary = "锁定租户")
|
||||
@PutMapping()
|
||||
public Result tenantLock(@RequestParam(value = Common.ACCOUNT) String account) {
|
||||
return tenantService.lockByAccount(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户根据账号获取登录需要信息
|
||||
*
|
||||
* @param account 账号
|
||||
* @return 登录信息
|
||||
*/
|
||||
@Operation(summary = "获取租户信息")
|
||||
@PostMapping("/info")
|
||||
public GeneralResult<Map<String, Object>> tenantAccountInfo(@RequestParam(value = Common.ACCOUNT) String account) {
|
||||
return tenantService.tokenLogin(account);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取某个租户下的所有项目
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取项目列表")
|
||||
@GetMapping("/{id}/projects")
|
||||
public GeneralResult<List<Project>> projects(@PathVariable(value = Common.ID) Long id) {
|
||||
return tenantService.projects(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询租户列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "分页获取租户列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<Tenant>> list(Pager pager, @Value(value = Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.list(pager, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改租户状态
|
||||
*
|
||||
* @param id
|
||||
* @param action
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "租户操作")
|
||||
@PatchMapping("/{id}")
|
||||
public Result updateStatus(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody ActionModel action,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.updateStatus(id, action.getAction(), requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改租户密码
|
||||
*
|
||||
* @param id 租户id
|
||||
* @param passwordModel 密码对象
|
||||
* @param requestContext 请求对象
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改租户密码")
|
||||
@PatchMapping("/{id}/pwd")
|
||||
public Result changePwd(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody PasswordModel passwordModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.changePwd(id, passwordModel.getOldPassword(), passwordModel.getPassword(), requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置租户密码
|
||||
*
|
||||
* @param id 租户id
|
||||
* @param passwordModel 密码对象
|
||||
* @param requestContext 请求对象
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "重置租户密码")
|
||||
@PatchMapping("/{id}/reset")
|
||||
public Result resetPwd(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody PasswordModel passwordModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.resetPwd(id, passwordModel.getPassword(), requestContext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查租户是否异地登录
|
||||
*
|
||||
* @param id
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "检查租户是否登录")
|
||||
@GetMapping("/{id}/status")
|
||||
public Result checkTenant(@PathVariable(value = Common.ID) Long id,
|
||||
HttpServletRequest request) {
|
||||
return tenantService.checkTenant(id, request.getHeader(Common.TOKEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户的角色列表
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询租户的角色列表")
|
||||
@GetMapping("/{id}/roles")
|
||||
public GeneralResult<List<Role>> roles(@PathVariable(value = Common.ID) Long id) {
|
||||
return tenantService.listRoles(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取租户安全对象
|
||||
*
|
||||
* @param apiKey
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取租户安全对象")
|
||||
@GetMapping("/security")
|
||||
public GeneralResult<AccountSecurity> security(@RequestParam(value = "apiKey") String apiKey) {
|
||||
return tenantService.getByApiKey(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作租户
|
||||
*
|
||||
* @param batchAction
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量操作租户")
|
||||
@PatchMapping
|
||||
public Result batchLock(@RequestBody BatchActionModel batchAction, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
switch (batchAction.getAction()) {
|
||||
case lock:
|
||||
return tenantService.batchLock(batchAction.getIds(), requestContext);
|
||||
case active:
|
||||
return tenantService.batchActive(batchAction.getIds(), requestContext);
|
||||
case remove:
|
||||
return tenantService.batchRemove(batchAction.getIds(), requestContext);
|
||||
default:
|
||||
return new Result(false, "不支持这种操作");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除租户资源池关系
|
||||
*
|
||||
* @param poolId
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "删除租户资源池关联")
|
||||
@DeleteMapping("/pools")
|
||||
public Result poolDelete(@RequestParam(value = "poolId") Long poolId) {
|
||||
return tenantService.deleteByPoolId(poolId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据租户查询资源池关联信息
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询租户资源池关联")
|
||||
@GetMapping("/{id}/pools")
|
||||
public GeneralResult<List<TenantPool>> businessPools(@PathVariable(value = Common.ID) Long id) {
|
||||
return tenantService.listTenantPool(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户配置资源池
|
||||
*
|
||||
* @param id
|
||||
* @param poolIds
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "租户配置资源池")
|
||||
@PostMapping("/{id}/pools")
|
||||
public Result configPool(@PathVariable(value = Common.ID) Long id, @RequestBody List<Long> poolIds, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.configPool(id, null, poolIds, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户配置业务
|
||||
*
|
||||
* @param id
|
||||
* @param businessIds
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "租户配置业务")
|
||||
@PostMapping("/{id}/businesses")
|
||||
public Result configBusiness(@PathVariable(value = Common.ID) Long id, @RequestParam(value = "businessIds") String businessIds) {
|
||||
List<Long> businesses = JSONArray.parseArray(businessIds, Long.class);
|
||||
return tenantService.configBusiness(id, businesses);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录记录查询
|
||||
*
|
||||
* @param pager
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "登录记录查询")
|
||||
@GetMapping("/track")
|
||||
public GeneralResult<GridBean<LoginRecord>> records(Pager pager) {
|
||||
return this.tenantService.list(pager);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加收藏")
|
||||
@PostMapping("/favorites/{id}")
|
||||
public Result addFavorite(@PathVariable("id") Long serviceId, @RequestParam("tenantId") Long tenantId) {
|
||||
return tenantService.addFavorite(serviceId, tenantId);
|
||||
}
|
||||
|
||||
@Operation(summary = "批量添加收藏")
|
||||
@PostMapping("/favorites")
|
||||
public Result addFavorites(@RequestBody List<Favorite> favorites) {
|
||||
return tenantService.addFavorites(favorites);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除收藏")
|
||||
@DeleteMapping("/favorites")
|
||||
public Result cancelTenantFavorite(@RequestParam(value = "serviceId", required = false) Long serviceId, @RequestParam(value = "tenantId", required = false) Long tenantId, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.cancelFavorite(serviceId, tenantId, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取收藏夹")
|
||||
@GetMapping("/favorites")
|
||||
public GeneralResult<List<CloudServiceBean>> listFavorite(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.listFavorite(requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取服务目录")
|
||||
@GetMapping("/services")
|
||||
public GeneralResult<List<ServiceMenuBean>> listServiceMenu(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.listServiceMenu(requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改收藏夹排序")
|
||||
@PostMapping("/favorites/order")
|
||||
public Result changePriority(@RequestBody List<PriorityModel> priorityModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return tenantService.changePriority(priorityModel, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询租户下用户")
|
||||
@GetMapping("/{id}/users")
|
||||
public GeneralResult<List<User>> getTenantUsers(@PathVariable(value = Common.ID) Long id) {
|
||||
return tenantService.getTenantUsers(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "租户配置用户")
|
||||
@PostMapping("/{id}/users")
|
||||
public Result configUsers(@PathVariable(value = Common.ID) Long id, @RequestBody List<Long> userIds) {
|
||||
return tenantService.configUsers(id, userIds);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询租户账号是否存在")
|
||||
@GetMapping("/{account}/exist")
|
||||
public Result exist(@PathVariable(value = Common.ACCOUNT) String account) {
|
||||
return tenantService.exist(account);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据省市编码查询租户")
|
||||
@GetMapping("/{city}/list")
|
||||
public GeneralResult<List<Tenant>> listTenantByCity(@PathVariable(value = "city") String city) {
|
||||
return tenantService.listTenantByCity(city);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出租户列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@Operation(summary = "导出租户列表")
|
||||
@RequestMapping(value = "/export", method = {RequestMethod.GET})
|
||||
public void export(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
List<Param> paramList = pager.getParams();
|
||||
Result result = tenantService.export(paramList, requestContext, response);
|
||||
Assert.isTrue(result.isSuccess(), "导出租户列表异常");
|
||||
}
|
||||
|
||||
@Operation(summary = "下载租户列表模板")
|
||||
@RequestMapping(value = "/import/template", method = {RequestMethod.GET})
|
||||
public void importTemp(HttpServletRequest request, HttpServletResponse response,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
Result result = tenantService.importTemp("租户列表模板", requestContext, response);
|
||||
Assert.isTrue(result.isSuccess(), result.getMessage());
|
||||
}
|
||||
|
||||
@Operation(summary = "导入租户列表")
|
||||
@PostMapping(value = "/import")
|
||||
public Result importData(@Value(Common.REQ_CONTEXT) RequestContext requestContext, HttpServletRequest request) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<MultipartFile> fileList = multipartRequest.getFiles("file");
|
||||
if (fileList.isEmpty()) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
MultipartFile multipartFile = fileList.get(0);
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
// 判断文件名
|
||||
if (originalFilename == null || !(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
return tenantService.importData(multipartFile, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询租户账号是否存在")
|
||||
@GetMapping("/condition")
|
||||
public GeneralResult condition(@RequestParam(value = Common.CONDITION, required = false) String condition) {
|
||||
return tenantService.condition(condition);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.bocloud.sms.interfaces.TenantService;
|
||||
import com.bocloud.sms.interfaces.UserService;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.Tokens;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @since 2020/7/24 周五 11:38
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "token管理")
|
||||
public class TokenController {
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final TenantService tenantService;
|
||||
private final UserService userService;
|
||||
|
||||
public TokenController(StringRedisTemplate redisTemplate, TenantService tenantService, UserService userService) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.tenantService = tenantService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单点登录验证token
|
||||
*
|
||||
* @param request 请求
|
||||
* @return token
|
||||
*/
|
||||
@GetMapping("/v1/token")
|
||||
@Operation(summary = "单点登录验证token")
|
||||
public GeneralResult<String> checkToken(HttpServletRequest request) {
|
||||
String token = request.getHeader(Common.TOKEN);
|
||||
if (!StringUtils.hasText(token)) {
|
||||
token = request.getParameter(Common.TOKEN);
|
||||
}
|
||||
String tokenKey = "";
|
||||
if (StringUtils.hasText(token)) {
|
||||
Claim claim = Tokens.parse(token);
|
||||
if (claim == null) {
|
||||
return new GeneralResult<>(false, "token校验失败");
|
||||
}
|
||||
String catalog = claim.asMap().get("catalog").toString();
|
||||
long uuid = Long.parseLong(claim.asMap().get(Common.UUID).toString());
|
||||
tokenKey = Common.TOKEN + "_" + catalog + "_" + uuid;
|
||||
}
|
||||
//校验token
|
||||
boolean checkResult = check(token, tokenKey);
|
||||
if (checkResult) {
|
||||
String newTokenCache = (String) this.redisTemplate.opsForHash().get(tokenKey + "_n", Common.TOKEN);
|
||||
return new GeneralResult<>(true, newTokenCache, "校验token成功");
|
||||
} else {
|
||||
return new GeneralResult<>(false, "token校验失败");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean check(String token, String tokenKey) {
|
||||
String newTokenCache = (String) this.redisTemplate.opsForHash().get(tokenKey + "_n", Common.TOKEN);
|
||||
if (token.equals(newTokenCache)) {
|
||||
return true;
|
||||
} else {
|
||||
String oldTokenCache = this.redisTemplate.opsForValue().get(tokenKey + "_o");
|
||||
return token.equals(oldTokenCache);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/v1/sso/token/info")
|
||||
@Operation(summary = "token解析获取信息")
|
||||
public GeneralResult<Map<String, Object>> getTokenInfo(HttpServletRequest request) {
|
||||
String token = request.getHeader(Common.TOKEN);
|
||||
HttpSession session = request.getSession();
|
||||
if (!StringUtils.hasText(token)) {
|
||||
return new GeneralResult<>(false, "token不存在");
|
||||
}
|
||||
Claim claim = Tokens.parse(token);
|
||||
if (claim == null) {
|
||||
return new GeneralResult<>(false, "token信息异常重新登录");
|
||||
}
|
||||
String catalog = claim.asMap().get("catalog").toString();
|
||||
String account = claim.asMap().get(Common.ACCOUNT).toString();
|
||||
GeneralResult<Map<String, Object>> result;
|
||||
if (catalog.equals(RequestContext.Catalog.Tenant.name())) {
|
||||
result = tenantService.tokenLogin(account);
|
||||
} else {
|
||||
result = userService.tokenLogin(account);
|
||||
}
|
||||
Map<String, Object> object = result.getData();
|
||||
object.put(Common.TOKEN, token);
|
||||
object.put("redirect", session.getAttribute("redirect"));
|
||||
result.setData(object);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.alibaba.druid.filter.config.ConfigTools;
|
||||
import com.bocloud.cmp.boot.config.DataSourceConfiguration;
|
||||
import com.bocloud.sms.entity.UpgradeHistory;
|
||||
import com.bocloud.sms.entity.UpgradeTask;
|
||||
import com.bocloud.sms.interfaces.UpgradeService;
|
||||
import com.megatron.common.encrypt.AESEncryptor;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统升级
|
||||
*
|
||||
* @author luyanchao
|
||||
* @date 2021-06-09
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/upgrade")
|
||||
@Tag(name = "系统升级")
|
||||
@Slf4j
|
||||
public class UpgradeController {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UpgradeService upgradeService;
|
||||
@Autowired
|
||||
private DataSourceConfiguration dataSourceConfiguration;
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前数据源信息
|
||||
*
|
||||
* @return url, user, pass
|
||||
*/
|
||||
@Operation(summary = "获取当前数据源")
|
||||
@GetMapping("/datasource")
|
||||
public GeneralResult<Map<String, String>> getDatasource() {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("url", dataSourceConfiguration.getUrl());
|
||||
result.put("user", dataSourceConfiguration.getUsername());
|
||||
PublicKey publicKey = ConfigTools.getPublicKey(dataSourceConfiguration.getPublicKey());
|
||||
try {
|
||||
String passPlainText = ConfigTools.decrypt(publicKey, dataSourceConfiguration.getPassword());
|
||||
result.put("pass", new AESEncryptor().encrypt(passPlainText, null));
|
||||
} catch (Exception e) {
|
||||
log.warn("MySQL密码解密失败:{}", e.getMessage());
|
||||
return new GeneralResult<>(true, result, "执行成功");
|
||||
}
|
||||
return new GeneralResult<>(true, result, "执行成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行数据迁移
|
||||
*
|
||||
* @param param 参数
|
||||
*/
|
||||
@Operation(summary = "执行数据迁移")
|
||||
@PostMapping("/datasource")
|
||||
public GeneralResult<Boolean> newMigration(@RequestBody Param param, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return upgradeService.newMigration(param.getUrl(), param.getUser(), param.getPass(), context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重试数据迁移
|
||||
*
|
||||
* @param id 数据迁移id
|
||||
*/
|
||||
@Operation(summary = "重试数据迁移")
|
||||
@PostMapping("/datasource/{id}")
|
||||
public GeneralResult<Boolean> retryMigration(@PathVariable(value = "id") Long id,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return upgradeService.retryMigration(id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据迁移列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
*/
|
||||
@Operation(summary = "查询数据迁移列表")
|
||||
@GetMapping("/records")
|
||||
public GeneralResult<GridBean<UpgradeHistory>> listUpgradeHistory(Pager pager) {
|
||||
return upgradeService.listUpgradeHistory(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询数据迁移详情
|
||||
*
|
||||
* @param id 数据迁移id
|
||||
*/
|
||||
@Operation(summary = "查询数据迁移详情")
|
||||
@GetMapping("/records/{id}")
|
||||
public GeneralResult<UpgradeHistory> getUpgradeHistory(@PathVariable(value = "id") Long id) {
|
||||
return upgradeService.getUpgradeHistory(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询数据迁移子任务列表
|
||||
*
|
||||
* @param id 数据迁移id
|
||||
* @param pager 分页参数
|
||||
*/
|
||||
@Operation(summary = "查询数据迁移子任务列表")
|
||||
@GetMapping("/records/{id}/tasks")
|
||||
public GeneralResult<GridBean<UpgradeTask>> listUpgradeTask(Pager pager, @PathVariable(value = "id") Long id) {
|
||||
return upgradeService.listUpgradeTask(id, pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重试数据迁移子任务
|
||||
*
|
||||
* @param recordId 数据迁移id
|
||||
* @param taskId 子任务id
|
||||
*/
|
||||
@Operation(summary = "重试数据迁移子任务")
|
||||
@PostMapping("/records/{recordId}/tasks/{taskId}")
|
||||
public GeneralResult<Boolean> retryUpgradeTask(@PathVariable(value = "recordId") Long recordId,
|
||||
@PathVariable(value = "taskId") Long taskId,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return upgradeService.retryUpgradeTask(taskId, context);
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class Param {
|
||||
private String url;
|
||||
private String user;
|
||||
private String pass;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,417 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.*;
|
||||
import com.bocloud.sms.interfaces.ManagerService;
|
||||
import com.bocloud.sms.interfaces.TenantService;
|
||||
import com.bocloud.sms.interfaces.UserPermissionService;
|
||||
import com.bocloud.sms.interfaces.UserService;
|
||||
import com.bocloud.sms.model.*;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/v1/users")
|
||||
@Tag(name = "用户管理")
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
private final UserPermissionService userPermissionService;
|
||||
private final TenantService tenantService;
|
||||
private final ManagerService managerService;
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询用户列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<User>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.list(pager, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*
|
||||
* @param userBean
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建用户")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody UserBean userBean, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.create(userBean, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*
|
||||
* @param userBean
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户修改")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@RequestBody UserBean userBean, @Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
@PathVariable(value = Common.ID) Long id) {
|
||||
return userService.modify(id, userBean, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "删除用户")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.remove(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看用户详细信息
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<User> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return userService.detail(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询用户账号是否存在
|
||||
*
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询用户账号是否存在")
|
||||
@GetMapping("/{account}/exist")
|
||||
public Result exist(@PathVariable(value = Common.ACCOUNT) String account) {
|
||||
return userService.exist(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看租户详情
|
||||
*
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户详情")
|
||||
@GetMapping("/detail")
|
||||
public GeneralResult<User> detail(@Value(value = Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.detail(requestContext.getTarget());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
*
|
||||
* @param id
|
||||
* @param action
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改用户状态")
|
||||
@PatchMapping("/{id}")
|
||||
public Result updateStatus(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody ActionModel action,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.updateStatus(id, action.getAction(), requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码
|
||||
*
|
||||
* @param id 用户id
|
||||
* @param passwordModel 旧密码
|
||||
* @param requestContext 请求对象
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改用户密码")
|
||||
@PatchMapping("/{id}/pwd")
|
||||
public Result changePwd(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody PasswordModel passwordModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.changePwd(id, passwordModel.getOldPassword(), passwordModel.getPassword(), requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param id 用户id
|
||||
* @param passwordModel 密码
|
||||
* @param requestContext 请求对象
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "重置用户密码")
|
||||
@PatchMapping("/{id}/reset")
|
||||
public Result resetPwd(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody PasswordModel passwordModel,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.resetPwd(id, passwordModel.getPassword(), requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户授权
|
||||
*
|
||||
* @param id 用户id
|
||||
* @param roleIds 角色id
|
||||
* @param requestContext 请求对象
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户授权角色")
|
||||
@PatchMapping("/{id}/accredit")
|
||||
public Result accredit(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestBody List<Long> roleIds,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.accredit(id, roleIds, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否异地登录
|
||||
*
|
||||
* @param id
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "检查用户是否登录")
|
||||
@GetMapping("/{id}/status")
|
||||
public Result checkUser(@PathVariable(value = Common.ID) Long id, HttpServletRequest request) {
|
||||
return userService.checkUser(id, request.getHeader(Common.TOKEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户的角色列表
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取角色列表")
|
||||
@GetMapping("/{id}/roles")
|
||||
public GeneralResult<List<Role>> roles(@PathVariable(value = Common.ID) Long id,
|
||||
@RequestParam(value = Common.CONDITION, required = false) String condition,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.listRoles(id, condition, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key
|
||||
*
|
||||
* @param apiKey
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取key")
|
||||
@GetMapping("/security")
|
||||
public GeneralResult<AccountSecurity> secKey(@RequestParam(value = "apiKey") String apiKey) {
|
||||
return userService.getAccountSecurity(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作用户
|
||||
*
|
||||
* @param batchAction
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "批量操作用户")
|
||||
@PatchMapping
|
||||
public Result batchLock(@RequestBody BatchActionModel batchAction, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
switch (batchAction.getAction()) {
|
||||
case lock:
|
||||
return userService.batchLock(batchAction.getIds(), requestContext);
|
||||
case active:
|
||||
return userService.batchActive(batchAction.getIds(), requestContext);
|
||||
case remove:
|
||||
return userService.batchRemove(batchAction.getIds(), requestContext);
|
||||
default:
|
||||
return new Result(false, "不支持这种操作");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户移除所属租户
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户移除所属租户")
|
||||
@PatchMapping("/{id}/tenants")
|
||||
public Result unBindTenants(@PathVariable Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.unBindTenants(id, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录记录查询
|
||||
*
|
||||
* @param pager
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "登录记录查询")
|
||||
@GetMapping("/track")
|
||||
public GeneralResult<GridBean<LoginRecord>> records(Pager pager) {
|
||||
return this.userService.list(pager);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加收藏")
|
||||
@PostMapping("/favorites/{id}")
|
||||
public Result addFavorite(@PathVariable("id") Long id, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.addFavorite(id, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除收藏")
|
||||
@DeleteMapping("/favorites/{id}")
|
||||
public Result cancelFavorite(@PathVariable("id") Long serviceId, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.cancelFavorite(serviceId, requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取收藏夹")
|
||||
@GetMapping("/favorites")
|
||||
public GeneralResult<List<CloudServiceBean>> listFavorite(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.listFavorite(requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取服务目录")
|
||||
@GetMapping("/services")
|
||||
public GeneralResult<List<ServiceMenuBean>> listServiceMenu(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.listServiceMenu(requestContext);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改收藏夹排序")
|
||||
@PostMapping("/favorites/order")
|
||||
public Result changePriority(@RequestBody List<PriorityModel> priorityModels, @Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
return userService.changePriority(priorityModels, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个用户下的所有项目
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取项目列表")
|
||||
@GetMapping("/{id}/projects")
|
||||
public GeneralResult<List<Project>> projects(@PathVariable(value = Common.ID) Long id) {
|
||||
return userService.projects(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出用户列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@Operation(summary = "导出项目列表")
|
||||
@RequestMapping(value = "/export", method = {RequestMethod.GET})
|
||||
public void export(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
List<Param> paramList = pager.getParams();
|
||||
Result export = userService.export(paramList, requestContext, response);
|
||||
Assert.isTrue(export.isSuccess(), "用户列表导出失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "下载用户列表模板")
|
||||
@RequestMapping(value = "/import/template", method = {RequestMethod.GET})
|
||||
public void importTemp(HttpServletRequest request, HttpServletResponse response,
|
||||
@RequestParam(value = "tenantId", required = false) Long tenantId,
|
||||
@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
Result result = userService.importTemp("用户列表", response);
|
||||
Assert.isTrue(result.isSuccess(), "用户模板下载失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "导入用户列表")
|
||||
@PostMapping(value = "/import")
|
||||
public Result importData(@Value(Common.REQ_CONTEXT) RequestContext requestContext,
|
||||
@RequestParam(value = "tenantId", required = false) Long tenantId, HttpServletRequest request) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
List<MultipartFile> fileList = multipartRequest.getFiles("file");
|
||||
if (fileList.isEmpty()) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
MultipartFile multipartFile = fileList.get(0);
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
// 判断文件名
|
||||
if (originalFilename == null || !(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) {
|
||||
return new Result(false, "文件错误");
|
||||
}
|
||||
return userService.importData(multipartFile, tenantId, requestContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定用户
|
||||
*
|
||||
* @param account 用户账号
|
||||
* @return 锁定结果
|
||||
*/
|
||||
@Operation(summary = "锁定用户")
|
||||
@PutMapping
|
||||
@Deprecated
|
||||
public Result userLock(@RequestParam(value = Common.ACCOUNT) String account) {
|
||||
return userService.lockByAccount(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户根据根据账号获取登录需要信息
|
||||
*
|
||||
* @param account 账号
|
||||
* @return 登录信息
|
||||
*/
|
||||
@PostMapping("/info")
|
||||
@Operation(summary = "获取用户信息")
|
||||
public GeneralResult<Map<String, Object>> userAccountInfo(@RequestParam(value = Common.ACCOUNT) String account) {
|
||||
return userService.tokenLogin(account);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录用户权限
|
||||
*
|
||||
* @param requestContext 上下文
|
||||
* @return 用户权限
|
||||
*/
|
||||
@Operation(summary = "获取登录用户权限")
|
||||
@GetMapping("/permissions")
|
||||
public GeneralResult loginPermission(@Value(Common.REQ_CONTEXT) RequestContext requestContext) {
|
||||
switch (requestContext.getCatalog()) {
|
||||
case Tenant:
|
||||
return tenantService.listPermissions(requestContext);
|
||||
case Manager:
|
||||
return managerService.listPermissions(requestContext);
|
||||
case User:
|
||||
return userPermissionService.listPermissions(requestContext);
|
||||
default:
|
||||
}
|
||||
return new GeneralResult(false, "获取用户信息异常");
|
||||
}
|
||||
|
||||
@Operation(summary = "获取登录用户按钮权限")
|
||||
@GetMapping("/button/permissions")
|
||||
public GeneralResult<List<Permission>> buttonPermissions(@Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
List<Permission> list = userPermissionService.listButtonPermissions(context);
|
||||
return new GeneralResult<>(true, list, "获取登录用户按钮权限成功");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package com.bocloud.sms.booter.controller;
|
||||
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.entity.UserGroup;
|
||||
import com.bocloud.sms.interfaces.UserGroupService;
|
||||
import com.bocloud.sms.model.UserGroupBean;
|
||||
import com.megatron.common.model.*;
|
||||
import com.megatron.common.utils.Common;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author hongqingyu
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/v1/users/groups")
|
||||
@Tag(name = "用户管理")
|
||||
public class UserGroupController {
|
||||
|
||||
@Autowired
|
||||
private UserGroupService userGroupService;
|
||||
|
||||
/**
|
||||
* 获取用户组列表
|
||||
*
|
||||
* @param pager
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "查询用户组列表")
|
||||
@GetMapping
|
||||
public GeneralResult<GridBean<User>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return userGroupService.list(pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户组
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "创建用户组")
|
||||
@PostMapping
|
||||
public Result create(@RequestBody UserGroup group, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return userGroupService.create(group, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户组
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户组修改")
|
||||
@PutMapping("/{id}")
|
||||
public Result modify(@RequestBody UserGroupBean bean, @Value(Common.REQ_CONTEXT) RequestContext context,
|
||||
@PathVariable(value = Common.ID) Long id) {
|
||||
bean.setId(id);
|
||||
return userGroupService.modify(bean, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户组
|
||||
*
|
||||
* @param id
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "删除用户组")
|
||||
@DeleteMapping("/{id}")
|
||||
public Result remove(@PathVariable(value = Common.ID) Long id, @Value(Common.REQ_CONTEXT) RequestContext context) {
|
||||
return userGroupService.remove(id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看用户组详细信息
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户组详情")
|
||||
@GetMapping("/{id}")
|
||||
public GeneralResult<UserGroup> detail(@PathVariable(value = Common.ID) Long id) {
|
||||
return userGroupService.detail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置用户与用户组的关系
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/relation")
|
||||
@Operation(summary = "关联账号")
|
||||
public Result relation(@RequestBody UserGroupBean bean) {
|
||||
return userGroupService.configUser(bean.getUserIds(), bean.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过userId查询用户组信息
|
||||
*
|
||||
* @param id 用户id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/relation/users/{id}")
|
||||
@Operation(summary = "根据用户id查询用户组")
|
||||
public Result listGroupIdByUserId(@PathVariable Long id) {
|
||||
return userGroupService.listGroupIdByUserId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看用户组详细信息
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "用户组用户详情")
|
||||
@GetMapping("/{id}/users")
|
||||
public GeneralResult<UserGroup> users(Pager pager, @PathVariable(value = Common.ID) Long id) {
|
||||
return userGroupService.listUserByGroupId(pager, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户组列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "获取全量用户组")
|
||||
@GetMapping("/all")
|
||||
public GeneralResult<GridBean<User>> listAll() {
|
||||
return userGroupService.listAll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.bocloud.sms.booter.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.booter.websocket.message.MessageHandler;
|
||||
import com.bocloud.sms.booter.websocket.model.CommonMessage;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.OperateResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.utils.JSONTools;
|
||||
import io.jsonwebtoken.lang.Assert;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.core.MessageListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 站内信通知监听
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 1.0
|
||||
* @since 2017年8月10日
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class BocloudMessageListener implements MessageListener {
|
||||
|
||||
private final MessageHandler messageHandler;
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
String content = new String(message.getBody());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("get bocloud message:{}", content);
|
||||
}
|
||||
Assert.notNull(content, "消息内容为空");
|
||||
GeneralResult<JSONObject> result = JSONTools.isJSON(content);
|
||||
Assert.isTrue(result.isSuccess(), result.getMessage());
|
||||
OperateResult operate = JSONObject.parseObject(content, OperateResult.class);
|
||||
Assert.notNull(content, "消息格式不正确");
|
||||
RequestContext context = operate.getContext();
|
||||
if (null != context && null != context.getTarget() && 0 != context.getTarget()) {
|
||||
// 发送消息给指定ID的用户前端
|
||||
messageHandler.sendMessageToUser(context.getCatalog(), context.getTarget(), new CommonMessage(content));
|
||||
} else {// 发送给所有的用户前端
|
||||
messageHandler.sendMessageToUsers(new CommonMessage(content));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("send websocket message failed: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package com.bocloud.sms.booter.listener;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.entity.Tenant;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.interfaces.MessageService;
|
||||
import com.bocloud.sms.model.NotifyMessage;
|
||||
import com.bocloud.sms.repository.TenantRepository;
|
||||
import com.bocloud.sms.repository.UserRepository;
|
||||
import com.bocloud.sms.service.utils.DingTalkSender;
|
||||
import com.bocloud.sms.service.utils.EmailSender;
|
||||
import com.bocloud.sms.service.utils.WeChatWorkSender;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 事件通知监听器
|
||||
*
|
||||
* @author weiwei
|
||||
* @since 2017年7月26日
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component("eventListener")
|
||||
@Slf4j
|
||||
public class EventListener {
|
||||
|
||||
private final MessageService messageService;
|
||||
private final EmailSender emailSender;
|
||||
private final UserRepository userRepository;
|
||||
private final TenantRepository tenantRepository;
|
||||
private final DingTalkSender dingTalkSender;
|
||||
private final WeChatWorkSender weChatWorkSender;
|
||||
|
||||
@RabbitListener(queues = "event.notice.queue", admin = "rabbitAdmin", autoStartup = "true")
|
||||
public void onMessage(NotifyMessage message) {
|
||||
log.debug("接收到时间通知消息:{}", JSONObject.toJSON(message));
|
||||
try {
|
||||
// 主题
|
||||
String subject = message.getSubject();
|
||||
// 站内信内容
|
||||
String msgContent = message.getContent();
|
||||
// 邮件内容
|
||||
String emailContent = StringUtils.hasText(message.getEmailContent()) ? message.getEmailContent() : message.getContent();
|
||||
// 企业微信内容
|
||||
String weChatContent = StringUtils.hasText(message.getWeChatContent()) ? message.getWeChatContent() : message.getContent();
|
||||
// 钉钉内容
|
||||
String dingTalkContent = StringUtils.hasText(message.getDingTalkContent()) ? message.getDingTalkContent() : message.getContent();
|
||||
RequestContext context = message.getContext();
|
||||
List<RequestContext> contexts = Optional.ofNullable(message.getContexts()).orElse(new ArrayList<>());
|
||||
if (context != null) {
|
||||
contexts.add(context);
|
||||
}
|
||||
//收件邮箱
|
||||
String[] emails = null;
|
||||
//接收者钉钉唯一标识
|
||||
String dingTalkUserId = null;
|
||||
//企业微信唯一标识
|
||||
String weChatUserId = null;
|
||||
for (RequestContext requestContext : contexts) {
|
||||
if (RequestContext.Catalog.Tenant == requestContext.getCatalog()) {
|
||||
Tenant tenant = tenantRepository.query(requestContext.getTarget());
|
||||
if (tenant != null) {
|
||||
if (StringUtils.hasText(tenant.getEmail())) {
|
||||
emails = new String[]{tenant.getEmail()};
|
||||
}
|
||||
if (StringUtils.hasText(tenant.getDingTalkNumber())) {
|
||||
dingTalkUserId = tenant.getDingTalkNumber();
|
||||
}
|
||||
if (StringUtils.hasText(tenant.getWeChatWorkNumber())) {
|
||||
weChatUserId = tenant.getWeChatWorkNumber();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
User user = userRepository.query(requestContext.getTarget());
|
||||
if (user != null) {
|
||||
if (StringUtils.hasText(user.getEmail())) {
|
||||
emails = new String[]{user.getEmail()};
|
||||
}
|
||||
if (StringUtils.hasText(user.getDingtalk())) {
|
||||
dingTalkUserId = user.getDingtalk();
|
||||
}
|
||||
if (StringUtils.hasText(user.getWechat())) {
|
||||
weChatUserId = user.getWechat();
|
||||
}
|
||||
}
|
||||
}
|
||||
// 发送站内信
|
||||
if (message.isSendMsg()) {
|
||||
messageService.create(requestContext, subject, msgContent);
|
||||
}
|
||||
// 发送邮件
|
||||
if (message.isSendEmail() && null != emails) {
|
||||
if (emailContent == null) {
|
||||
emailSender.send(subject, emails, msgContent, null);
|
||||
} else {
|
||||
emailSender.send(subject, emails, emailContent, null);
|
||||
}
|
||||
}
|
||||
if (message.isSendDingTalk() && StringUtils.hasText(dingTalkUserId)) {
|
||||
//发送钉钉消息
|
||||
dingTalkSender.sendMessage(dingTalkContent, dingTalkUserId, null, false);
|
||||
}
|
||||
if (message.isSendWeChat() && StringUtils.hasText(weChatUserId)) {
|
||||
//发送企业微信消息
|
||||
weChatWorkSender.pushMessage(weChatUserId, weChatContent);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Send message or email error:", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package com.bocloud.sms.booter.listener;
|
||||
|
||||
import com.bocloud.sms.entity.AccessLog;
|
||||
import com.bocloud.sms.interfaces.LogService;
|
||||
import com.megatron.common.utils.IDFactory;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* 审计日志监听器,用来监听从rabbitmq日志队列发出的日志消息
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
@Component("logListener")
|
||||
@Slf4j
|
||||
public class LogListener implements InitializingBean {
|
||||
|
||||
private BlockingQueue<AccessLog> accessLogQueue = new LinkedBlockingQueue<>();
|
||||
private volatile boolean runnable = true;
|
||||
@Autowired
|
||||
private LogService logService;
|
||||
|
||||
/**
|
||||
* 处理访问日志消息,用来将审计日志存储到数据库
|
||||
*
|
||||
* @param log
|
||||
*/
|
||||
@RabbitListener(queues = "bocloud.log.queue", admin = "rabbitAdmin", autoStartup = "true")
|
||||
public void processAccessLogMessage(AccessLog log) {
|
||||
log.setId(IDFactory.instance().uuid());
|
||||
if ("系统配置".equals(log.getTarget()) && "更新操作".equals(log.getAction())) {
|
||||
if (log.getDetail().length() > 65535) {
|
||||
log.setDetail(log.getDetail().substring(0, 65534).replace("/", ""));
|
||||
}
|
||||
|
||||
}
|
||||
accessLogQueue.add(log);
|
||||
}
|
||||
|
||||
class BatchSaver implements Runnable {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* 获取日志队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<AccessLog> fetchLog() {
|
||||
List<AccessLog> logList = new ArrayList<>();
|
||||
try {
|
||||
while ((System.currentTimeMillis() - start) < 1000 && logList.size() < 512) {
|
||||
logList.add(accessLogQueue.take());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Fetch log Error!", e);
|
||||
}
|
||||
return logList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (runnable) {
|
||||
List<AccessLog> logs = fetchLog();
|
||||
if (logs.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
logService.batch(logs);
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
new Thread(new BatchSaver()).start();
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destory() {
|
||||
this.runnable = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package com.bocloud.sms.booter.scheduler;
|
||||
|
||||
import com.bocloud.cmp.boot.model.BoCloudExchange;
|
||||
import com.bocloud.cmp.boot.model.BocloudStatus;
|
||||
import com.bocloud.sms.entity.Tenant;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.model.NotifyMessage;
|
||||
import com.bocloud.sms.repository.TenantRepository;
|
||||
import com.bocloud.sms.repository.UserRepository;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import io.jsonwebtoken.lang.Collections;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 账号状态(过期)监控
|
||||
*
|
||||
* @author tyl
|
||||
* @time 2020/7/22 周三 9:55
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AccountStatusMonitor implements InitializingBean {
|
||||
|
||||
|
||||
private final CurrentService service;
|
||||
private final UserRepository userRepository;
|
||||
private final TenantRepository tenantRepository;
|
||||
private final AmqpTemplate amqpTemplate;
|
||||
// 一天毫秒数
|
||||
private static final Long ONE_DAY = 24 * 60 * 60 * 1000L;
|
||||
|
||||
public AccountStatusMonitor(CurrentService service, UserRepository userRepository, TenantRepository tenantRepository, AmqpTemplate amqpTemplate) {
|
||||
this.service = service;
|
||||
this.userRepository = userRepository;
|
||||
this.tenantRepository = tenantRepository;
|
||||
this.amqpTemplate = amqpTemplate;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
private void accountStatusMonitor() throws Exception {
|
||||
log.info("用户有效期监控开启");
|
||||
log.info("当前服务是否是leader:{}", service.isLeader());
|
||||
if (!service.isLeader()) {
|
||||
return;
|
||||
}
|
||||
long threeDaysAgo = System.currentTimeMillis() - 3 * ONE_DAY;
|
||||
Date date = new Date(threeDaysAgo);
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String format = simpleDateFormat.format(date);
|
||||
//管理员
|
||||
List<User> users = userRepository.listManagerHasExpiredDate(format);
|
||||
for (User user : users) {
|
||||
// 获取管理员的有效期时间
|
||||
Date expireDate = user.getExpiredDate();
|
||||
Long useTime = expireDate.getTime() - System.currentTimeMillis();
|
||||
// 剩余时间小于3天
|
||||
if (useTime <= 3 * ONE_DAY) {
|
||||
String content = null;
|
||||
if (useTime <= 0L) {
|
||||
content = "用户账号已过期,请联系管理员进行重置!";
|
||||
user.setStatus(BocloudStatus.Basic.EXPIRED.name());
|
||||
user.setGmtModify(new Date());
|
||||
user.setMenderId(1L);
|
||||
userRepository.update(user);
|
||||
} else if (useTime % ONE_DAY == 0L) {
|
||||
content = "用户账号还有【" + useTime / ONE_DAY + "天】将过期,请尽快修改或重置!";
|
||||
} else if (useTime % ONE_DAY > 0L) {
|
||||
content = "用户账号还有【" + useTime / ONE_DAY + "天" + useTime % ONE_DAY / (60 * 60 * 1000L)
|
||||
+ "小时】将过期,请尽快修改或重置!";
|
||||
}
|
||||
|
||||
NotifyMessage message = new NotifyMessage(new RequestContext(RequestContext.Catalog.Manager, user.getId(), 0L, null, null),
|
||||
"用户账号使用时间到期预警", content, true, false);
|
||||
amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), "event.notice.queue",
|
||||
message);
|
||||
log.info("账号到期预警信息发送完毕!管理员{}", user.getName());
|
||||
}
|
||||
}
|
||||
//租户
|
||||
List<Tenant> tenants = tenantRepository.listManagerHasExpiredDate();
|
||||
for (Tenant tenant : tenants) {
|
||||
Date expireDate = tenant.getExpiredDate();
|
||||
// 账号剩余使用时间
|
||||
Long useTime = expireDate.getTime() - System.currentTimeMillis();
|
||||
if (useTime <= 3 * ONE_DAY) {
|
||||
String content = null;
|
||||
if (useTime <= 0L) {
|
||||
content = "租户账号已过期,请联系管理员进行重置!";
|
||||
tenant.setStatus(BocloudStatus.Basic.EXPIRED.name());
|
||||
tenant.setGmtModify(new Date());
|
||||
tenant.setMenderId(1L);
|
||||
tenantRepository.update(tenant);
|
||||
} else if (useTime % ONE_DAY == 0L) {
|
||||
content = "租户账号还有【" + useTime / ONE_DAY + "天】将过期,请尽快修改或重置!";
|
||||
} else if (useTime % ONE_DAY > 0L) {
|
||||
content = "租户账号还有【" + useTime / ONE_DAY + "天" + useTime % ONE_DAY / (60 * 60 * 1000L)
|
||||
+ "小时】将过期,请尽快修改或重置!";
|
||||
}
|
||||
NotifyMessage message = new NotifyMessage(new RequestContext(RequestContext.Catalog.Tenant, tenant.getId(), 0L, null, null),
|
||||
"租户账号使用时间到期预警", content, true, false);
|
||||
amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), "event.notice.queue",
|
||||
message);
|
||||
log.info("账号到期预警信息发送完毕!租户{}", tenant.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.accountStatusMonitor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.bocloud.sms.booter.scheduler;
|
||||
|
||||
import com.bocloud.sms.entity.SystemNotice;
|
||||
import com.bocloud.sms.interfaces.SystemNoticeService;
|
||||
import com.bocloud.sms.repository.SystemNoticeRepository;
|
||||
import com.bocloud.sms.service.SystemNoticeServiceImpl;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.megatron.common.model.Param;
|
||||
import com.megatron.common.model.Sign;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import com.megatron.framework.lock.AutoCloseLock;
|
||||
import com.megatron.framework.lock.LockFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class SystemNoticeScheduler implements InitializingBean {
|
||||
|
||||
private final CurrentService service;
|
||||
private final SystemNoticeService systemNoticeService;
|
||||
private final SystemNoticeRepository systemNoticeRepository;
|
||||
private final LockFactory lockFactory;
|
||||
|
||||
@Scheduled(cron = "0 */2 * * * ?")
|
||||
protected void sendNotice() {
|
||||
log.debug("[执行]定时发送系统公告");
|
||||
log.debug("当前服务是否是leader:{}", service.isLeader());
|
||||
if (!service.isLeader()) {
|
||||
return;
|
||||
}
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
String path = SystemNoticeScheduler.class.getSimpleName() + "_sendNotice";
|
||||
try (AutoCloseLock lock = lockFactory.getACLock(path)) {
|
||||
Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
|
||||
// 获取未发送且已经到发送时间的系统公告进行发送
|
||||
List<Param> params = Lists.newArrayList();
|
||||
params.add(new Param(MapTools.simpleMap("status", SystemNoticeServiceImpl.StatusEnum.NOTSEND), Sign.EQ));
|
||||
params.add(new Param(MapTools.simpleMap("sendTime", sdf.format(new Date())), Sign.LET));
|
||||
List<SystemNotice> notices = systemNoticeRepository.list(params);
|
||||
Assert.notNull(notices, "没有数据");
|
||||
for (SystemNotice notice : notices) {
|
||||
systemNoticeService.sendMsg(notice.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("SystemNoticeScheduler sendNotice error:", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
this.sendNotice();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package com.bocloud.sms.booter.scheduler;
|
||||
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import com.bocloud.cmp.boot.model.BoCloudExchange;
|
||||
import com.bocloud.sms.entity.SystemConfig;
|
||||
import com.bocloud.sms.entity.Tenant;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.model.NotifyMessage;
|
||||
import com.bocloud.sms.repository.SystemConfigRepository;
|
||||
import com.bocloud.sms.repository.TenantRepository;
|
||||
import com.bocloud.sms.repository.UserRepository;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.framework.core.CurrentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.AmqpTemplate;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户密码使用时长监控
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 4.2.1-SNAPSHOT
|
||||
* @since 2019/11/11
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UserPasswordMonitor implements InitializingBean {
|
||||
|
||||
private final CurrentService service;
|
||||
private final TenantRepository tenantRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final SystemConfigRepository systemConfigRepository;
|
||||
private final AmqpTemplate amqpTemplate;
|
||||
// 一天毫秒数
|
||||
private static final Long ONE_DAY = 24 * 60 * 60 * 1000L;
|
||||
|
||||
/**
|
||||
* 每天执行一次
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
protected void monitor() throws Exception {
|
||||
log.info("当前服务是否是leader:{}", service.isLeader());
|
||||
if (!service.isLeader()) {
|
||||
return;
|
||||
}
|
||||
// 密码最大使用时长,若用户最后一次密码至今时长超过该值,则用户被冻结
|
||||
Long pwdMaxUsage = 90 * ONE_DAY;
|
||||
SystemConfig config = systemConfigRepository.queryByCode("pwdExpireDay");
|
||||
if (null != config) {
|
||||
String value = config.getValue();
|
||||
if (!StringUtils.isEmpty(value)) {
|
||||
pwdMaxUsage = Long.parseLong(value) * ONE_DAY;
|
||||
// 需对密码最大使用时间判断,如果为-1,表示过期时间为无期限
|
||||
if ("-1".equals(value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 租户
|
||||
List<Tenant> tenants = tenantRepository.list(1, Integer.MAX_VALUE, new ArrayList<>(), null);
|
||||
for (Tenant tenant : tenants) {
|
||||
Date lastPwdModifyDate = tenant.getLastPwdModifyDate();
|
||||
if (null == lastPwdModifyDate) {
|
||||
tenant.setLastPwdModifyDate(new Date());
|
||||
tenant.setGmtModify(new Date());
|
||||
tenantRepository.update(tenant);
|
||||
continue;
|
||||
}
|
||||
// 密码已使用时间
|
||||
Long useTime = System.currentTimeMillis() - lastPwdModifyDate.getTime();
|
||||
// 密码剩余使用时间
|
||||
Long residueTime = pwdMaxUsage - useTime;
|
||||
if (residueTime <= 3 * ONE_DAY) {
|
||||
String content = null;
|
||||
if (residueTime < 0L) {
|
||||
content = "登录密码已过期,租户账号将被冻结,请联系管理员进行重置密码!";
|
||||
tenantRepository.lock(tenant.getId(), 1L);
|
||||
} else if (residueTime % ONE_DAY == 0L) {
|
||||
content = "登录密码还有【" + residueTime / ONE_DAY + "天】将过期,请尽快修改或重置密码!";
|
||||
} else if (residueTime % ONE_DAY > 0L) {
|
||||
content = "登录密码还有【" + residueTime / ONE_DAY + "天" + residueTime % ONE_DAY / (60 * 60 * 1000L)
|
||||
+ "小时】将过期,请尽快修改或重置密码!";
|
||||
}
|
||||
NotifyMessage message = new NotifyMessage(new RequestContext(RequestContext.Catalog.Tenant, tenant.getId(),
|
||||
tenant.getId(), null, null), "租户账号密码使用时间到期预警", content, true, false);
|
||||
amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), "event.notice.queue",
|
||||
message);
|
||||
log.info("密码到期预警信息发送完毕!租户{}", tenant.getName());
|
||||
}
|
||||
}
|
||||
// 用户
|
||||
List<User> users = userRepository.list(1, Integer.MAX_VALUE, new ArrayList<>(), null, null);
|
||||
for (User user : users) {
|
||||
if (1L == user.getId()) {
|
||||
// admin账户忽略,密码永不过期
|
||||
continue;
|
||||
}
|
||||
Date lastPwdModifyDate = user.getLastPwdModifyDate();
|
||||
if (null == lastPwdModifyDate) {
|
||||
user.setLastPwdModifyDate(new Date());
|
||||
user.setGmtModify(new Date());
|
||||
userRepository.update(user);
|
||||
continue;
|
||||
}
|
||||
// 密码已使用时间
|
||||
Long useTime = System.currentTimeMillis() - lastPwdModifyDate.getTime();
|
||||
// 密码剩余使用时间
|
||||
Long residueTime = pwdMaxUsage - useTime;
|
||||
if (residueTime <= 3 * ONE_DAY) {
|
||||
String content = null;
|
||||
if (residueTime < 0L) {
|
||||
content = "登录密码已过期,用户将被冻结,请联系管理员进行重置密码!";
|
||||
userRepository.lock(user.getId(), 1L);
|
||||
} else if (residueTime % ONE_DAY == 0L) {
|
||||
content = "登录密码还有【" + residueTime / ONE_DAY + "天】将过期,请尽快修改或重置密码!";
|
||||
} else if (residueTime % ONE_DAY > 0L) {
|
||||
content = "登录密码还有【" + residueTime / ONE_DAY + "天" + residueTime % ONE_DAY / (60 * 60 * 1000L)
|
||||
+ "小时】将过期,请尽快修改或重置密码!";
|
||||
}
|
||||
NotifyMessage userMessage = new NotifyMessage(new RequestContext(RequestContext.Catalog.User, user.getId(),
|
||||
user.getTenantId(), null, null), "用户密码使用时间到期预警", content, true, false);
|
||||
amqpTemplate.convertAndSend(BoCloudExchange.Default.DIRECT.getExchange(), "event.notice.queue", userMessage);
|
||||
log.info("密码到期预警信息发送完毕!用户{}", user.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.monitor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.bocloud.sms.booter.scheduler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.entity.Message;
|
||||
import com.bocloud.sms.repository.MessageRepository;
|
||||
import com.megatron.common.enums.PostDataFormat;
|
||||
import com.megatron.common.http.HttpClient;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 从运控获取工单数据到站内信
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class YunKongMessageSchedule {
|
||||
|
||||
@Value("${message.enable:false}")
|
||||
private Boolean enable;
|
||||
@Value("${message.host:http://127.0.0.1}")
|
||||
private String host;
|
||||
@Value("${message.reqUserId:0}")
|
||||
private String reqUserId;
|
||||
@Value("${message.systemId:0}")
|
||||
private String systemId;
|
||||
@Value("${message.userId:0}")
|
||||
private String userId;
|
||||
|
||||
private final MessageRepository messageRepository;
|
||||
|
||||
@Scheduled(cron = "${message.schedule:0 0/1 * * * ?}")
|
||||
protected void schedule() {
|
||||
if (!enable) return;
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("page", 1);
|
||||
params.put("limit", 1000);
|
||||
params.put("approve_status", 1);
|
||||
params.put("userId", userId);
|
||||
params.put("taskStatus", "");
|
||||
params.put("taskName", "");
|
||||
|
||||
Map<String, Object> request = new HashMap<>();
|
||||
request.put("reqUserId", reqUserId);
|
||||
request.put("systemId", systemId);
|
||||
request.put("method", "/activiti/rwMainTask/getTaskList");
|
||||
request.put("params", params);
|
||||
|
||||
String url = host + "/system/common/queryYKInterface";
|
||||
HttpClient httpClient = new HttpClient(PostDataFormat.RAW);
|
||||
log.info("curl -k -X POST -H 'Content-Type: application/json' -d '{}' '{}'", JSON.toJSONString(request), url);
|
||||
Result result = httpClient.post(new HashMap<>(), request, url);
|
||||
Assert.isTrue(result.isSuccess(), result.getMessage());
|
||||
|
||||
JSONArray array = JSON.parseObject(result.getMessage()).getJSONObject("data").getJSONArray("data");
|
||||
List<Message> oldMessages = messageRepository.list(Message.class, "select * from message where external_id is not null");
|
||||
List<Message> existsMessages = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
String externalId = item.getString("record_id");
|
||||
Message message = oldMessages.stream()
|
||||
.filter(m -> externalId.equals(m.getExternalId()))
|
||||
.findFirst().orElse(new Message());
|
||||
message.setCatalog(RequestContext.Catalog.User);
|
||||
message.setStatus("UNREAD");
|
||||
message.setGmtCreate(new Date());
|
||||
message.setCreatorId(1L);
|
||||
message.setOwnerId(1L);
|
||||
message.setSender(1L);
|
||||
message.setExternalId(externalId);
|
||||
message.setName(item.getString("task_name"));
|
||||
message.setContent(item.getString("task_content"));
|
||||
if (message.getId() == null) {
|
||||
messageRepository.save(message);
|
||||
} else {
|
||||
messageRepository.update(message);
|
||||
existsMessages.add(message);
|
||||
}
|
||||
}
|
||||
|
||||
oldMessages.removeAll(existsMessages);
|
||||
for (Message m : oldMessages) {
|
||||
messageRepository.remove(m.getId(), 1L);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.bocloud.sms.booter.syslog;
|
||||
|
||||
import ch.qos.logback.classic.net.SyslogAppender;
|
||||
import ch.qos.logback.core.net.SyslogOutputStream;
|
||||
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class SysLogAppenderTcpAndUdp extends SyslogAppender {
|
||||
|
||||
@Override
|
||||
public SyslogOutputStream createOutputStream() throws SocketException, UnknownHostException {
|
||||
return new SyslogOutputStreamTcpAndUdp(getSyslogHost(), getPort());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.bocloud.sms.booter.syslog;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.pattern.CompositeConverter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SysLogLevelConvertor extends CompositeConverter<ILoggingEvent> {
|
||||
|
||||
private static final Map<String, String> MAP = new HashMap<>() {{
|
||||
this.put("DEBUG", "7");
|
||||
this.put("INFO", "6");
|
||||
this.put("WARN", "4");
|
||||
this.put("ERROR", "3");
|
||||
}};
|
||||
|
||||
@Override
|
||||
protected String transform(ILoggingEvent iLoggingEvent, String s) {
|
||||
return MAP.getOrDefault(iLoggingEvent.getLevel().toString(), iLoggingEvent.getLevel().toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.bocloud.sms.booter.syslog;
|
||||
|
||||
import ch.qos.logback.core.net.SyslogOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class SyslogOutputStreamTcpAndUdp extends SyslogOutputStream {
|
||||
|
||||
private static final int MAX_LEN_TCP = 1024;
|
||||
|
||||
private InetAddress addressTcp;
|
||||
private Socket socketTcp;
|
||||
private ByteArrayOutputStream baosTcp = new ByteArrayOutputStream();
|
||||
final private int portTcp;
|
||||
|
||||
public SyslogOutputStreamTcpAndUdp(String syslogHost, int port) throws SocketException, UnknownHostException {
|
||||
super(syslogHost, port);
|
||||
this.addressTcp = InetAddress.getByName(syslogHost);
|
||||
this.portTcp = port;
|
||||
try {
|
||||
this.socketTcp = new Socket(addressTcp, portTcp);
|
||||
} catch (IOException e) {
|
||||
throw new SocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] byteArray, int offset, int len) throws IOException {
|
||||
super.write(byteArray, offset, len);
|
||||
baosTcp.write(byteArray, offset, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
super.flush();
|
||||
|
||||
byte[] bytes = baosTcp.toByteArray();
|
||||
|
||||
// clean up for next round
|
||||
if (baosTcp.size() > MAX_LEN_TCP) {
|
||||
baosTcp = new ByteArrayOutputStream();
|
||||
} else {
|
||||
baosTcp.reset();
|
||||
}
|
||||
|
||||
// after a failure, it can happen that bytes.length is zero
|
||||
// in that case, there is no point in sending out an empty message/
|
||||
if (bytes.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (this.socketTcp != null) {
|
||||
socketTcp.getOutputStream().write(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
addressTcp = null;
|
||||
try {
|
||||
socketTcp.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
package com.bocloud.sms.booter.websocket.logview;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.cmp.boot.model.BoCloudService;
|
||||
import com.bocloud.sms.booter.websocket.model.LogViewMessage;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.megatron.common.enums.PostDataFormat;
|
||||
import com.megatron.common.http.HttpClient;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.LogBean;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.megatron.common.utils.JSONTools;
|
||||
import com.megatron.common.utils.ListTool;
|
||||
import com.megatron.common.utils.LogCrawler;
|
||||
import com.megatron.common.utils.MapTools;
|
||||
import com.megatron.framework.core.RegistryService;
|
||||
import com.megatron.framework.core.Service;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.socket.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ Description: @ Author :丁明威 @ Date :Created in 11:21 2018/11/5 @ Modified By:
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LogViewHandler implements WebSocketHandler {
|
||||
private static final String FETCH_SERVICE = "/logview";
|
||||
private static final String[] EXCLUDE_SERVERS =
|
||||
{"tds.server", "ams.server", "cms.server", "mcs.server", "cop.server", "tse.server", "gaia.server",
|
||||
"cos.server", "sms.server", "gms.server", "ros.server", "ams.server", "bms.server", "cmp.server"};
|
||||
private final RegistryService registryService;
|
||||
@Value("${logging.dir:/log/services}")
|
||||
private String loggingDir;
|
||||
|
||||
public LogViewHandler(RegistryService registryService) {
|
||||
this.registryService = registryService;
|
||||
}
|
||||
|
||||
private String buildUrl(String host, String value) {
|
||||
return "http://" + host + (!StringUtils.hasText(value) ? "" : value) + FETCH_SERVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
|
||||
if (message instanceof TextMessage textMessage) {
|
||||
String path = new File(loggingDir).getPath() + File.separator;
|
||||
JSONObject messageJson = JSONTools.isJSONObj(textMessage.getPayload());
|
||||
if (null == messageJson) {
|
||||
return;
|
||||
}
|
||||
String log = messageJson.getString("logger");
|
||||
String host = messageJson.getString("host");
|
||||
Long position = messageJson.getLong("position");
|
||||
Long presize = messageJson.getLong("logsize");
|
||||
if (null == position || position <= 0) {
|
||||
position = 0L;
|
||||
}
|
||||
if (null == presize) {
|
||||
presize = 0L;
|
||||
}
|
||||
LogViewMessage logViewMessage = null;
|
||||
if (Arrays.asList(EXCLUDE_SERVERS).contains(log)) {
|
||||
path += log.split("\\.")[0] + ".log";
|
||||
String url = buildUrl(host, "/v1");
|
||||
logViewMessage = getRemoteLog(url, path, position, presize);
|
||||
} else if ("gaia.server".equals(log)) {
|
||||
String url = buildUrl(host, "/api/" + log.split("\\.")[0] + "/v1");
|
||||
logViewMessage = getRemoteLog(url, "", position, presize, host.split(":")[0]);
|
||||
} else if ("pontus.server".equals(log)) {
|
||||
String url = buildUrl(host, "/api/" + log.split("\\.")[0] + "/v1");
|
||||
logViewMessage = getRemoteLog(url, "", position, presize, null);
|
||||
} else if (StringUtils.hasText(log) && log.contains("service.log")) {
|
||||
String user = messageJson.getString("user");
|
||||
String password = messageJson.getString("password");
|
||||
String target = messageJson.getString("target");
|
||||
path = messageJson.getString("filepath");
|
||||
String category = messageJson.getString("category");
|
||||
Integer port = messageJson.getInteger("port");
|
||||
logViewMessage = getRemoteLog(path, position, presize, user, password, port, target, category);
|
||||
}
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(logViewMessage)));
|
||||
} else {
|
||||
log.error("Unexpected WebSocket message type: " + message);
|
||||
throw new IllegalStateException("Unexpected WebSocket message type: " + message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
if (session.isOpen()) {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端服务器上的日志文件内容
|
||||
*
|
||||
* @param url 服务地址
|
||||
* @param filepath 文件路径
|
||||
* @param position 起始位点
|
||||
* @param presize 前移位点
|
||||
* @return
|
||||
*/
|
||||
private LogViewMessage getRemoteLog(String url, String filepath, Long position, Long presize) {
|
||||
LogViewMessage message = null;
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
Map<String, Object> param = MapTools.simpleMap("filepath", filepath);
|
||||
param.put("position", position);
|
||||
param.put("presize", presize);
|
||||
Result result = client.get(null, param, url);
|
||||
if (result.isFailed()) {
|
||||
message = new LogViewMessage("", position);
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(result.getMessage());
|
||||
jsonObject = JSONObject.parseObject(jsonObject.getString("message"));
|
||||
String originalMessage = jsonObject.getString("content");
|
||||
String msg = originalMessage.replaceAll("\\[(.{2,4})[m]", "");
|
||||
message = new LogViewMessage(msg, jsonObject.getLong("position"));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端服务器上的日志文件内容
|
||||
*
|
||||
* @param filepath 文件路径
|
||||
* @param position 起始位点
|
||||
* @param presize 前移位点
|
||||
* @param user 用户账号
|
||||
* @param password 用户密码
|
||||
* @param port 目标端口
|
||||
* @return
|
||||
*/
|
||||
private LogViewMessage getRemoteLog(String filepath, Long position, Long presize, String user, String password,
|
||||
Integer port, String host, String category) {
|
||||
String address = registryService.getService(Service.create(BoCloudService.GAIA.getName()));
|
||||
if (!StringUtils.hasText(address)) {
|
||||
return new LogViewMessage("远端日志获取异常");
|
||||
}
|
||||
String url = address + "/api/gaia/v1/job/submit";
|
||||
log.info("服务地址:" + url);
|
||||
LogViewMessage viewMessage;
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
// 同步请求
|
||||
Map<String, Object> param = MapTools.simpleMap("response", "sync");
|
||||
// module设置
|
||||
Map<String, Object> module = MapTools.simpleMap("name", "logview");
|
||||
Map<String, Object> logview = MapTools.simpleMap("position", position);
|
||||
logview.put("presize", presize);
|
||||
logview.put("log_file", filepath);
|
||||
Map<String, Object> args = MapTools.simpleMap("gaia_logview", logview);
|
||||
module.put("args", args);
|
||||
param.put("module", module);
|
||||
Map<String, Object> target = MapTools.simpleMap("host", host);
|
||||
target.put("pasd", password);
|
||||
target.put("user", user);
|
||||
|
||||
if (!StringUtils.hasText(category) || !"windows".equalsIgnoreCase(category)) {
|
||||
category = "Linux";
|
||||
}
|
||||
target.put("category", category);
|
||||
if (null == port) {
|
||||
port = "windows".equalsIgnoreCase(category) ? 5985 : 22;
|
||||
}
|
||||
target.put("port", port);
|
||||
List<Object> targets = Lists.newArrayList();
|
||||
targets.add(target);
|
||||
param.put("targets", targets);
|
||||
Result result = client.post(null, param, url);
|
||||
log.info("请求结果内容:" + JSONObject.toJSONString(result));
|
||||
if (result.isFailed()) {
|
||||
viewMessage = new LogViewMessage(false, "文件可能不存在或文件为空", position);
|
||||
} else {
|
||||
JSONObject object = JSONObject.parseObject(result.getMessage());
|
||||
List<JSONObject> datas = JSONObject.parseArray(object.getString("data"), JSONObject.class);
|
||||
if (!ListTool.isEmpty(datas)) {
|
||||
JSONObject data = datas.get(0);
|
||||
JSONObject message = data.getJSONObject("message");
|
||||
if (null != object.getBoolean("success") && object.getBoolean("success")) {
|
||||
String content = null;
|
||||
if (null != message) {
|
||||
content = message.getString("content");
|
||||
}
|
||||
viewMessage = new LogViewMessage(true, content, object.getLong("curr_position"));
|
||||
} else {
|
||||
viewMessage = new LogViewMessage(false, "文件不存在或存在的文件无法打开", position);
|
||||
}
|
||||
} else {
|
||||
viewMessage = new LogViewMessage(false, "文件可能不存在或文件为空", position);
|
||||
}
|
||||
}
|
||||
return viewMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取远端worker服务器上的日志文件内容
|
||||
*
|
||||
* @param url 服务地址
|
||||
* @param filepath 文件路径
|
||||
* @param position 起始位点
|
||||
* @param presize 前移位点
|
||||
* @param target worker服务器IP地址
|
||||
* @return
|
||||
*/
|
||||
private LogViewMessage getRemoteLog(String url, String filepath, Long position, Long presize, String target) {
|
||||
LogViewMessage message;
|
||||
HttpClient client = new HttpClient();
|
||||
client.setDataFormat(PostDataFormat.RAW);
|
||||
Map<String, Object> param = MapTools.simpleMap("filepath", filepath);
|
||||
param.put("position", position);
|
||||
param.put("presize", presize);
|
||||
if (StringUtils.hasText(target)) {
|
||||
param.put("target", target);
|
||||
}
|
||||
Result result = client.post(null, param, url);
|
||||
if (result.isFailed()) {
|
||||
message = new LogViewMessage("", position);
|
||||
} else {
|
||||
JSONObject jsonObject = JSONObject.parseObject(result.getMessage());
|
||||
String originalMessage = jsonObject.getString("message");
|
||||
String msg = originalMessage.replaceAll("\\[(.{2,4})[m]", "");
|
||||
message = new LogViewMessage(msg, jsonObject.getLong("filesize"));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private LogViewMessage getLocalLog(String filepath, Long position, Long presize) {
|
||||
LogViewMessage message = null;
|
||||
GeneralResult<LogBean> crawlResult = LogCrawler.crawl(filepath, position, presize);
|
||||
if (crawlResult.isFailed()) {
|
||||
message = new LogViewMessage("", position);
|
||||
} else {
|
||||
LogBean logBean = crawlResult.getData();
|
||||
String originalMessage = logBean.getContent();
|
||||
String msg = originalMessage.replaceAll("\\[(.{2,4})[m]", "");
|
||||
message = new LogViewMessage(msg, logBean.getPosition());
|
||||
}
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
package com.bocloud.sms.booter.websocket.message;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.bocloud.sms.booter.websocket.model.CommonMessage;
|
||||
import com.megatron.common.model.OperateResult;
|
||||
import com.megatron.common.model.RequestContext.Catalog;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* 通知类WebSocket处理器
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MessageHandler implements WebSocketHandler, InitializingBean {
|
||||
|
||||
|
||||
private Vector<WebSocketSession> webSocketSessions;
|
||||
|
||||
/*
|
||||
* (non-Javadoc) WebSocket连接建立之后的操作
|
||||
*
|
||||
* @see org.springframework.web.socket.WebSocketHandler#
|
||||
* afterConnectionEstablished(org.springframework.web.socket. WebSocketSession)
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
|
||||
if (null == webSocketSession.getAttributes().get("catalog")
|
||||
|| null == webSocketSession.getAttributes().get("id")) {
|
||||
log.error("Target Information Is Null !!");
|
||||
throw new Exception("Target Information Is Null !!");
|
||||
}
|
||||
this.webSocketSessions.addElement(webSocketSession);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.
|
||||
* springframework.web.socket.WebSocketSession,
|
||||
* org.springframework.web.socket.WebSocketMessage)
|
||||
*/
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> message) throws Exception {
|
||||
if (webSocketSession.isOpen() && "HeartBeat".equals(message.getPayload().toString())) {
|
||||
OperateResult result = new OperateResult();
|
||||
result.setData("{}");
|
||||
result.setSuccess(true);
|
||||
result.setOperate(message.getPayload().toString());
|
||||
CommonMessage content = new CommonMessage(JSON.toJSONString(result));
|
||||
webSocketSession.sendMessage(new TextMessage(content.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.web.socket.WebSocketHandler#handleTransportError(org.
|
||||
* springframework.web.socket.WebSocketSession, java.lang.Throwable)
|
||||
*/
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession webSocketSession, Throwable exception) throws Exception {
|
||||
if (webSocketSession.isOpen()) {
|
||||
webSocketSession.close();
|
||||
}
|
||||
this.webSocketSessions.remove(webSocketSession);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org
|
||||
* .springframework.web.socket.WebSocketSession,
|
||||
* org.springframework.web.socket.CloseStatus)
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
|
||||
this.webSocketSessions.remove(webSocketSession);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭用户websocket的session连接
|
||||
*
|
||||
* @param targetId
|
||||
*/
|
||||
public void closeUserSession(Long targetId, String targetCatalog) {
|
||||
for (int i = this.webSocketSessions.size() - 1; i >= 0; i--) {
|
||||
WebSocketSession webSocketSession = webSocketSessions.get(i);
|
||||
String catalog = (String) webSocketSession.getAttributes().get("catalog");
|
||||
Long id = (Long) webSocketSession.getAttributes().get("id");
|
||||
if (null == catalog || null == id) {
|
||||
continue;
|
||||
}
|
||||
if (id.equals(targetId) && catalog.equalsIgnoreCase(targetCatalog)) {
|
||||
if (webSocketSession.isOpen()) {
|
||||
try {
|
||||
webSocketSession.close();
|
||||
webSocketSessions.remove(webSocketSession);
|
||||
log.info("websocket session closed");
|
||||
} catch (IOException e) {
|
||||
log.error("close websocket session exception:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessageToUsers(CommonMessage message) {
|
||||
for (WebSocketSession webSocketSession : this.webSocketSessions) {
|
||||
try {
|
||||
if (webSocketSession.isOpen()) {
|
||||
webSocketSession.sendMessage(new TextMessage(message.toString()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Send WebSocket Message To All Users Exception {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送websocket消息到指定用户ID
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public void sendMessageToUser(Catalog targetCatalog, Long userId, CommonMessage message) {
|
||||
for (WebSocketSession webSocketSession : webSocketSessions) {
|
||||
String catalog = (String) webSocketSession.getAttributes().get("catalog");
|
||||
Long id = (Long) webSocketSession.getAttributes().get("id");
|
||||
if (id.equals(userId) && (Catalog.Tenant != targetCatalog || Catalog.Tenant.name().equalsIgnoreCase(catalog))) {
|
||||
try {
|
||||
if (webSocketSession.isOpen()) {
|
||||
webSocketSession.sendMessage(new TextMessage(message.toString()));
|
||||
log.info("Send WebSocket Message to [{} {}] Success !!!", catalog, userId);
|
||||
} else {
|
||||
log.warn("Send WebSocket Message to [{} {}] Exception for session is closed !!!", catalog,
|
||||
userId);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Send WebSocket Message to [{} {}] Exception:{}", catalog, userId, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.webSocketSessions = new Vector<>();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @author hty
|
||||
* @time 上午9:39:37
|
||||
* @date 2014年12月5日
|
||||
*/
|
||||
package com.bocloud.sms.booter.websocket.message;
|
||||
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.megatron.common.utils.Common;
|
||||
import com.megatron.common.utils.Tokens;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.http.server.ServletServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageInterceptor implements HandshakeInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean beforeHandshake(@NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response, @NonNull WebSocketHandler wsHandler,
|
||||
@NonNull Map<String, Object> attributes) throws Exception {
|
||||
if (request instanceof ServletServerHttpRequest) {
|
||||
HttpServletRequest httpRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
||||
String token = httpRequest.getHeader("Sec-WebSocket-Protocol");
|
||||
if (!StringUtils.hasText(token)) {
|
||||
return false;
|
||||
}
|
||||
Claim claim = Tokens.parse(token);
|
||||
if (null == claim) {
|
||||
return false;
|
||||
}
|
||||
String catalog = claim.asMap().get("catalog").toString();
|
||||
if (!StringUtils.hasText(catalog)) {
|
||||
return false;
|
||||
}
|
||||
Long id = Long.valueOf(claim.asMap().get(Common.UUID).toString());
|
||||
attributes.put("catalog", catalog);
|
||||
attributes.put("id", id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||
Exception exception) {
|
||||
if (request instanceof ServletServerHttpRequest) {
|
||||
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
||||
HttpServletResponse servletResponse = ((ServletServerHttpResponse) response).getServletResponse();
|
||||
String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
|
||||
if (StringUtils.hasText(servletRequest.getHeader(SEC_WEBSOCKET_PROTOCOL))) {
|
||||
servletResponse.addHeader("Sec-WebSocket-Protocol", servletRequest.getHeader("Sec-WebSocket-Protocol"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* 上传文件消息
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
public class CommonMessage implements Message<Object> {
|
||||
private MessageCategory category;
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* @return the category
|
||||
*/
|
||||
public MessageCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category the category to set
|
||||
*/
|
||||
public void setCategory(MessageCategory category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CommonMessage(String content) {
|
||||
this.setCategory(MessageCategory.TEXT);
|
||||
this.setContent(content);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSONObject.toJSONString(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
public class LogViewMessage {
|
||||
|
||||
private boolean success;
|
||||
private MessageCategory category;
|
||||
private String content;
|
||||
private Long position;
|
||||
|
||||
/**
|
||||
* @return the success
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param success the success to set
|
||||
*/
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the category
|
||||
*/
|
||||
public MessageCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category the category to set
|
||||
*/
|
||||
public void setCategory(MessageCategory category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the content
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content the content to set
|
||||
*/
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the position
|
||||
*/
|
||||
public Long getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the position to set
|
||||
*/
|
||||
public void setPosition(Long position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public LogViewMessage() {
|
||||
super();
|
||||
}
|
||||
|
||||
public LogViewMessage(String content) {
|
||||
this.category = MessageCategory.VIEW_LOG;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public LogViewMessage(String content, Long position) {
|
||||
this.category = MessageCategory.VIEW_LOG;
|
||||
this.content = content;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public LogViewMessage(Boolean success, String content, Long position) {
|
||||
this.success = success;
|
||||
this.category = MessageCategory.VIEW_LOG;
|
||||
this.content = content;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
public enum MessageCategory {
|
||||
/**
|
||||
* 文本
|
||||
*/
|
||||
TEXT,
|
||||
/**
|
||||
* 上传
|
||||
*/
|
||||
UPLOAD,
|
||||
/**
|
||||
* 上传确认
|
||||
*/
|
||||
UPLOAD_ACK,
|
||||
/**
|
||||
* 上传取消
|
||||
*/
|
||||
UPLOAD_CANCEL,
|
||||
/**
|
||||
* 任务
|
||||
*/
|
||||
TASK,
|
||||
/**
|
||||
* 回滚
|
||||
*/
|
||||
CALLBACK,
|
||||
/**
|
||||
* 实时日志
|
||||
*/
|
||||
VIEW_LOG
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* 上传文件消息
|
||||
*
|
||||
* @author zero
|
||||
*
|
||||
*/
|
||||
public class UploadACK implements Message<Object> {
|
||||
private MessageCategory category;
|
||||
private String content;
|
||||
|
||||
|
||||
/**
|
||||
* @return the category
|
||||
*/
|
||||
public MessageCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category the category to set
|
||||
*/
|
||||
public void setCategory(MessageCategory category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public UploadACK(String content) {
|
||||
this.setCategory(MessageCategory.UPLOAD_ACK);
|
||||
this.setContent(content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UploadBean {
|
||||
|
||||
private Long timestamp;
|
||||
private String filename;
|
||||
private String path;
|
||||
private String source;
|
||||
private String target;
|
||||
private boolean sendover;
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* 上传文件消息
|
||||
*
|
||||
* @author zero
|
||||
*
|
||||
*/
|
||||
public class UploadCancel implements Message<Object> {
|
||||
private MessageCategory category;
|
||||
private String content;
|
||||
|
||||
|
||||
/**
|
||||
* @return the category
|
||||
*/
|
||||
public MessageCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category the category to set
|
||||
*/
|
||||
public void setCategory(MessageCategory category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public UploadCancel(String content) {
|
||||
this.setCategory(MessageCategory.UPLOAD_CANCEL);
|
||||
this.setContent(content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.bocloud.sms.booter.websocket.model;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* 上传文件消息
|
||||
*
|
||||
* @author zero
|
||||
*/
|
||||
public class UploadMessage implements Message<Object> {
|
||||
private MessageCategory category;
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* @return the category
|
||||
*/
|
||||
public MessageCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param category the category to set
|
||||
*/
|
||||
public void setCategory(MessageCategory category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public UploadMessage(String content) {
|
||||
this.setCategory(MessageCategory.UPLOAD);
|
||||
this.setContent(content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
package com.bocloud.sms.booter.websocket.upload;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.sms.booter.websocket.model.UploadACK;
|
||||
import com.bocloud.sms.booter.websocket.model.UploadBean;
|
||||
import com.bocloud.sms.booter.websocket.model.UploadCancel;
|
||||
import com.bocloud.sms.booter.websocket.model.UploadMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class UploadServiceHandler implements WebSocketHandler {
|
||||
|
||||
private static final String SAVE_SUCCESS = "SAVE_SUCCESS";
|
||||
private static final String SAVE_FAILURE = "SAVE_FAILURE";
|
||||
private static final String CANCEL_SUCCESS = "CANCEL_SUCCESS";
|
||||
private static final String CANCEL_FAILURE = "CANCEL_FAILURE";
|
||||
private static final String UPLOAD_CANCEL = "UPLOAD_CANCEL";
|
||||
private static List<WebSocketSession> currentUsers;
|
||||
|
||||
static {
|
||||
UploadServiceHandler.setCurrentUsers(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Value("${spring.upload.path:/home/cmp}")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* @return the currentUsers
|
||||
*/
|
||||
public static List<WebSocketSession> getCurrentUsers() {
|
||||
return currentUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentUsers the currentUsers to set
|
||||
*/
|
||||
public static void setCurrentUsers(List<WebSocketSession> currentUsers) {
|
||||
UploadServiceHandler.currentUsers = currentUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二进制byte[]数组写入文件中
|
||||
*
|
||||
* @param byteBuffer byte[]数组
|
||||
* @param outputFile 文件位置
|
||||
* @return 成功: true 失败: false
|
||||
*/
|
||||
private static boolean saveFile(ByteBuffer byteBuffer, String outputFile) {
|
||||
FileOutputStream fstream = null;
|
||||
File file = null;
|
||||
try {
|
||||
file = new File(outputFile);
|
||||
if (!file.exists() && !file.createNewFile()) {
|
||||
log.error("create new file error,path:{}", file.getPath());
|
||||
return false;
|
||||
}
|
||||
fstream = new FileOutputStream(file, true);
|
||||
fstream.write(byteBuffer.array());
|
||||
} catch (Exception e) {
|
||||
log.error("saveFile Exception:", e);
|
||||
return false;
|
||||
} finally {
|
||||
if (fstream != null) {
|
||||
try {
|
||||
fstream.close();
|
||||
} catch (IOException e1) {
|
||||
log.error("close fileimput Exception:", e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getPath() {
|
||||
if (this.path.endsWith(String.valueOf(File.separatorChar))) {
|
||||
return this.path.substring(0, this.path.length() - 1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
UploadServiceHandler.getCurrentUsers().add(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
|
||||
if (message instanceof TextMessage) {
|
||||
handleText(session, (TextMessage) message);
|
||||
} else if (message instanceof BinaryMessage) {
|
||||
handleBinary(session, (BinaryMessage) message);
|
||||
} else {
|
||||
log.error("Unexpected WebSocket message type: " + message);
|
||||
throw new IllegalStateException("Unexpected WebSocket message type: " + message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理字符串
|
||||
*
|
||||
* @param session
|
||||
* @param message
|
||||
*/
|
||||
private void handleText(WebSocketSession session, TextMessage message) {
|
||||
UploadBean uploadBean = null;
|
||||
try {
|
||||
if (message.getPayload().contains("upload")) {
|
||||
uploadBean = JSONObject.parseObject(message.getPayload(), UploadBean.class);
|
||||
String date = DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd");
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
String path = File.separatorChar + "tmp" + File.separatorChar + date + File.separatorChar + uuid;
|
||||
File dir = new File(this.getPath(), path);
|
||||
if (!dir.exists()) {
|
||||
boolean flag = dir.mkdirs();
|
||||
if (!flag) {
|
||||
log.error("mkdir failed, path: " + dir.getPath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
path = path + File.separatorChar + uploadBean.getFilename();
|
||||
uploadBean.setTarget(this.getPath() + path);
|
||||
session.getAttributes().put("uploadBean", uploadBean);
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadACK(path))));
|
||||
} else if (message.getPayload().contains("sendover")) {
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadMessage("TRUE"))));
|
||||
} else if (message.getPayload().contains(UPLOAD_CANCEL)) {
|
||||
log.warn("用户取消文件上传");
|
||||
uploadBean = (UploadBean) session.getAttributes().get("uploadBean");
|
||||
File file = new File(uploadBean.getTarget());
|
||||
this.deleteTmpFile(file);
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadCancel(CANCEL_SUCCESS))));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("上传文件异常:", e);
|
||||
if (null == uploadBean) {
|
||||
return;
|
||||
}
|
||||
File file = new File(uploadBean.getTarget());
|
||||
this.deleteTmpFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("static-access")
|
||||
private void handleBinary(WebSocketSession session, BinaryMessage message) throws IOException {
|
||||
UploadBean uploadBean = (UploadBean) session.getAttributes().get("uploadBean");
|
||||
if (null == uploadBean) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (saveFile(message.getPayload(), uploadBean.getTarget())) {
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadMessage(SAVE_SUCCESS))));
|
||||
} else {
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadMessage(SAVE_FAILURE))));
|
||||
this.deleteTmpFile(new File(uploadBean.getTarget()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("上传文件异常:", e);
|
||||
session.sendMessage(new TextMessage(JSONObject.toJSONString(new UploadMessage(SAVE_FAILURE))));
|
||||
this.deleteTmpFile(new File(uploadBean.getTarget()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除临时文件及文件夹
|
||||
*
|
||||
* @param file 文件
|
||||
*/
|
||||
private void deleteTmpFile(File file) {
|
||||
if (file.exists()) {
|
||||
if (!file.delete()) {
|
||||
log.error("file delete failed, path:{} " + file.getPath());
|
||||
return;
|
||||
}
|
||||
File dirFile = file.getParentFile();
|
||||
if (!dirFile.exists()) {
|
||||
return;
|
||||
}
|
||||
if (Objects.requireNonNull(dirFile.list()).length == 0) {
|
||||
if (!dirFile.delete()) {
|
||||
log.error("file delete failed, path:{} " + file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
|
||||
UploadServiceHandler.getCurrentUsers().remove(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
if (session.isOpen()) {
|
||||
session.close();
|
||||
}
|
||||
UploadServiceHandler.getCurrentUsers().remove(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
server:
|
||||
port: '18087'
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: sms
|
||||
thread:
|
||||
core:
|
||||
pool:
|
||||
size: 1000
|
||||
max:
|
||||
pool:
|
||||
size: 1000
|
||||
queue:
|
||||
capacity: 2000
|
||||
upload:
|
||||
path: /home/cmp
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: 10.20.12.65:2181
|
||||
home: /bocloud/cmp/product
|
||||
auth:
|
||||
username: bocloud
|
||||
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
|
||||
config:
|
||||
enabled: false
|
||||
discovery:
|
||||
register: true
|
||||
enable: true
|
||||
instance-host: 10.20.12.65
|
||||
instance-port: ${server.port}
|
||||
root: ${spring.cloud.zookeeper.home}/services
|
||||
conn:
|
||||
timeout: '50000'
|
||||
session:
|
||||
timeout: '50000'
|
||||
datasource:
|
||||
druid:
|
||||
dialect: mysql
|
||||
url: jdbc:mysql://10.20.12.65:3306/cmp?characterEncoding=utf8&useSSL=false
|
||||
username: cmp
|
||||
password: Gy2VghUgWHszx8gLFT4etT9ZVOukJi73KoG1q3Oz/DAz5h2mFVVunjcyaaKT9tMPsBgoWBFRmrYbhgqJqT/Q8A==
|
||||
initialSize: '2'
|
||||
maxActive: '30'
|
||||
minIdle: '2'
|
||||
maxWait: '60000'
|
||||
poolPreparedStatements: 'true'
|
||||
maxOpenPreparedStatements: '20'
|
||||
maxPoolPreparedStatementPerConnectionSize: '20'
|
||||
validationQuery: select 1
|
||||
validationQueryTimeout: '1'
|
||||
testOnBorrow: 'true'
|
||||
testOnReturn: 'true'
|
||||
testWhileIdle: 'true'
|
||||
remove-abandoned: 'true'
|
||||
remove-abandoned-timeout: '60'
|
||||
log-abandoned: 'true'
|
||||
timeBetweenEvictionRunsMillis: '10000'
|
||||
minEvictableIdleTimeMillis: '30001'
|
||||
asyncCloseConnectionEnable: 'true'
|
||||
filters: config,stat,wall,log4j
|
||||
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==
|
||||
connectionProperties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==;druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
use-global-data-source-stat: 'true'
|
||||
rabbitmq:
|
||||
host: 10.20.12.65
|
||||
port: 5672
|
||||
username: admin
|
||||
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
|
||||
virtual-host: cmp
|
||||
dynamic: 'true'
|
||||
banner:
|
||||
charset: UTF-8
|
||||
freemarker:
|
||||
checkTemplateLocation: 'false'
|
||||
data:
|
||||
redis:
|
||||
host: 10.20.12.65
|
||||
port: 6379
|
||||
password: AES@CoU6oY/zuAoBbu6cdgOKlA==
|
||||
timeout: 5000
|
||||
lettuce:
|
||||
pool:
|
||||
enabled: false
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
max-active: 5
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 5
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: 5000
|
||||
time-between-eviction-runs: 1000
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 2MB
|
||||
max-request-size: 20MB
|
||||
main:
|
||||
allow-circular-references: true
|
||||
logging:
|
||||
config: classpath:logback-spring.xml
|
||||
dir: ${user.dir}/log/services
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
bocloud: info
|
||||
file:
|
||||
max-size: 100MB
|
||||
max-history: '30'
|
||||
total-size-cap: 2GB
|
||||
syslog:
|
||||
host: mai-miao.cn
|
||||
port: 8340
|
||||
facility: LOCAL1
|
||||
level: error
|
||||
prometheus:
|
||||
timeout: 60000
|
||||
url: http://10.20.12.65:9091
|
||||
node:
|
||||
url: http://10.20.12.65:9091
|
||||
alertmanager:
|
||||
url: http://10.20.12.65:9093
|
||||
ipmi:
|
||||
exporter:
|
||||
url: http://10.20.12.65:9290
|
||||
plugin:
|
||||
mainPackage: com.bocloud
|
||||
runMode: prod
|
||||
repository:
|
||||
path: ${user.dir}/plugins/
|
||||
deploy:
|
||||
env: physical
|
||||
count: 1
|
|
@ -0,0 +1,11 @@
|
|||
/$$$$$$$ /$$ /$$$$$$ /$$ /$$ /$$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$
|
||||
| $$__ $$ | $$ /$$__ $$| $$$ /$$$| $$__ $$ /$$__ $$| $$$ /$$$ /$$__ $$
|
||||
| $$ \ $$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$$| $$ \__/| $$$$ /$$$$| $$ \ $$ | $$ \__/| $$$$ /$$$$| $$ \__/
|
||||
| $$$$$$$ /$$__ $$| $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$ | $$ $$/$$ $$| $$$$$$$/ | $$$$$$ | $$ $$/$$ $$| $$$$$$
|
||||
| $$__ $$| $$$$$$$$| $$ | $$| $$ \ $$| $$ \ $$| $$ | $$| $$ | $$ $$$| $$| $$____/ \____ $$| $$ $$$| $$ \____ $$
|
||||
| $$ \ $$| $$_____/| $$ | $$| $$ | $$| $$ | $$| $$ | $$| $$ $$| $$\ $ | $$| $$ /$$ \ $$| $$\ $ | $$ /$$ \ $$
|
||||
| $$$$$$$/| $$$$$$$| $$$$$$$| $$$$$$/| $$ | $$| $$$$$$$| $$$$$$/| $$ \/ | $$| $$ | $$$$$$/| $$ \/ | $$| $$$$$$/
|
||||
|_______/ \_______/ \____ $$ \______/ |__/ |__/ \_______/ \______/ |__/ |__/|__/ \______/ |__/ |__/ \______/
|
||||
/$$ | $$
|
||||
| $$$$$$/
|
||||
\______/
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<!-- 读取application.properties中的配置 -->
|
||||
<springProperty scope="context" name="service.name" source="spring.application.name"/>
|
||||
<springProperty scope="context" name="logging.dir" source="logging.dir"/>
|
||||
<springProperty scope="context" name="logging.file.total-size-cap" source="logging.file.total-size-cap"/>
|
||||
<springProperty scope="context" name="logging.file.max-size" source="logging.file.max-size"/>
|
||||
<springProperty scope="context" name="logging.file.max-history" source="logging.file.max-history"/>
|
||||
<springProperty scope="context" name="logging.level.com.bocloud" source="logging.level.com.bocloud"/>
|
||||
<springProperty scope="context" name="logging.level.root" source="logging.level.root"/>
|
||||
<springProperty scope="context" name="logging.syslog.host" source="logging.syslog.host"/>
|
||||
<springProperty scope="context" name="logging.syslog.port" source="logging.syslog.port"/>
|
||||
<springProperty scope="context" name="logging.syslog.facility" source="logging.syslog.facility"/>
|
||||
<springProperty scope="context" name="logging.syslog.level" source="logging.syslog.level"/>
|
||||
|
||||
<conversionRule conversionWord="ilevel" converterClass="com.bocloud.sms.booter.syslog.SysLogLevelConvertor"/>
|
||||
|
||||
<property name="local_log_pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] [%X{REQUEST_ID}] %cyan(%logger{32}):%L - %msg%n"/>
|
||||
<property name="sys_log_pattern" value="{"level":"%ilevel{%level}","log_level":"%level","time":"%d{yyyy-MM-dd HH:mm:ss.SSS}","thread":"%thread","class":"%logger{36}.%M:%line","message":"%msg"}%n"/>
|
||||
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
|
||||
<!-- 默认的控制台日志输出,一般生产环境都是后台启动,这个没太大作用 -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<pattern>${local_log_pattern}</pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- 配置文件轮转 -->
|
||||
<appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<File>${logging.dir}/${service.name}.log</File>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<FileNamePattern>${logging.dir}/history/${service.name}.%d{yyyy-MM-dd}.%i.log.gz
|
||||
</FileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>${logging.file.max-size}</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<MaxHistory>${logging.file.max-history}</MaxHistory>
|
||||
<totalSizeCap>${logging.file.total-size-cap}</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<pattern>${local_log_pattern}</pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!--syslog -->
|
||||
<appender name="SYSLOG" class="com.bocloud.sms.booter.syslog.SysLogAppenderTcpAndUdp">
|
||||
<syslogHost>${logging.syslog.host}</syslogHost> <!-- Syslog 服务器的地址 -->
|
||||
<port>${logging.syslog.port}</port> <!-- Syslog 服务器的端口号 -->
|
||||
<facility>${logging.syslog.facility}</facility> <!-- Syslog 设备标识 -->
|
||||
<suffixPattern>${sys_log_pattern}</suffixPattern>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>${logging.syslog.level}</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<root level="${logging.level.root}">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="LOG_FILE"/>
|
||||
<appender-ref ref="SYSLOG"/>
|
||||
</root>
|
||||
|
||||
<logger name="com.bocloud" level="${logging.level.com.bocloud}" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="LOG_FILE"/>
|
||||
<appender-ref ref="SYSLOG"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.alibaba.druid.pool.DruidAbstractDataSource" level="error" additivity="false">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="LOG_FILE"/>
|
||||
<appender-ref ref="SYSLOG"/>
|
||||
</logger>
|
||||
</configuration>
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<artifactId>bocloud.sms</artifactId>
|
||||
<version>6.5.0-LTS-SZ</version>
|
||||
</parent>
|
||||
<artifactId>bocloud.sms.service</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.freedom</groupId>
|
||||
<artifactId>megatron.framework</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.mail</groupId>
|
||||
<artifactId>jakarta.mail-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.bocloud</groupId>
|
||||
<artifactId>bocloud.sms.storage</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ldap</groupId>
|
||||
<artifactId>spring-ldap-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.amqp</groupId>
|
||||
<artifactId>spring-amqp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
<!--导出Excel依赖-->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.starblues</groupId>
|
||||
<artifactId>spring-brick</artifactId>
|
||||
<version>${spring-brick.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>4.4.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Admission;
|
||||
import com.bocloud.sms.model.AdmissionModel;
|
||||
import com.megatron.common.exception.InternalServerException;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ip访问控制业务接口
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 4.2.1-SNAPSHOT
|
||||
* @since 2019/11/12
|
||||
*/
|
||||
public interface AdmissionService {
|
||||
|
||||
/**
|
||||
* 查询IP访问限制列表
|
||||
*
|
||||
* @param pager
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<Admission>> list(Pager pager);
|
||||
|
||||
/**
|
||||
* 查询IP访问限制详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Admission> detail(Long id);
|
||||
|
||||
/**
|
||||
* 创建IP访问限制
|
||||
*
|
||||
* @param admission
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result create(AdmissionModel admission, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 删除IP访问限制
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result remove(Long id) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 批量删除IP访问限制
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result batchRemove(List<Long> ids) throws InternalServerException;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.ApiToken;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
|
||||
/**
|
||||
* api token访问控制业务接口
|
||||
*/
|
||||
public interface ApiTokenService {
|
||||
|
||||
GeneralResult<ApiToken> get(String token);
|
||||
|
||||
GeneralResult<ApiToken> create(ApiToken param, RequestContext context);
|
||||
|
||||
GeneralResult<GridBean<ApiToken>> list(Pager pager, RequestContext context);
|
||||
|
||||
GeneralResult<Void> modify(ApiToken param, RequestContext context);
|
||||
|
||||
GeneralResult<Void> remove(Long id, RequestContext context);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
public interface AutoLoginService {
|
||||
|
||||
RedirectView autoLogin(String host, HttpServletRequest request);
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Business;
|
||||
import com.bocloud.sms.entity.Project;
|
||||
import com.bocloud.sms.model.BusinessModel;
|
||||
import com.megatron.common.model.*;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @time 2020/6/2 周二 15:57
|
||||
*/
|
||||
public interface BusinessService {
|
||||
/**
|
||||
* 分页查询业务列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<Business>> list(Pager pager, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 创建业务
|
||||
*
|
||||
* @param params
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Result create(BusinessModel params, RequestContext user);
|
||||
|
||||
/**
|
||||
* 修改业务
|
||||
*
|
||||
* @param id
|
||||
* @param params
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Result modify(Long id, BusinessModel params, RequestContext user);
|
||||
|
||||
/**
|
||||
* 查看业务详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Business> detail(Long id);
|
||||
|
||||
/**
|
||||
* 删除业务
|
||||
*
|
||||
* @param id
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
Result remove(Long id, RequestContext user);
|
||||
|
||||
/**
|
||||
* 批量删除业务
|
||||
*
|
||||
* @param ids
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result batchRemove(List<Long> ids, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 获取业务下的项目
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Project>> listBusinessProject(Long id);
|
||||
|
||||
/**
|
||||
* 业务操作
|
||||
*
|
||||
* @param id
|
||||
* @param projectIds
|
||||
* @return
|
||||
*/
|
||||
Result businessAction(Long id, List<Long> projectIds);
|
||||
|
||||
/**
|
||||
* 业务导入模板
|
||||
*
|
||||
* @param title
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
XSSFWorkbook importTemp2(String title, RequestContext requestContext);
|
||||
|
||||
|
||||
/**
|
||||
* 业务导入模板
|
||||
*
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
Result importTemp(HttpServletResponse response);
|
||||
|
||||
|
||||
/**
|
||||
* 业务数据导入
|
||||
*
|
||||
* @param multipartFile
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result importData(MultipartFile multipartFile, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 业务数据导出
|
||||
*
|
||||
* @param paramList
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
XSSFWorkbook export(List<Param> paramList, RequestContext requestContext);
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.megatron.common.exception.InternalServerException;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import com.bocloud.sms.entity.Department;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.model.DepartmentModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组织机构抽象Service接口
|
||||
*
|
||||
* @author tyl
|
||||
*/
|
||||
public interface DepartmentService {
|
||||
|
||||
/**
|
||||
* 创建组织机构
|
||||
*
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result create(DepartmentModel params, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 修改组织机构
|
||||
*
|
||||
* @param id
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result modify(Long id, DepartmentModel params, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 删除组织机构
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result remove(Long id, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 组织机构详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Department> detail(Long id);
|
||||
|
||||
/**
|
||||
* 查询组织机构
|
||||
*
|
||||
* @param parentId
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Department>> list(Long parentId, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 是否存在
|
||||
*
|
||||
* @param name
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Department> exists(String name, Long tenantId);
|
||||
|
||||
/**
|
||||
* 查询组织机构下管理员
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<User>> listDeptManager(Long id, RequestContext requestContext);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
|
||||
import com.bocloud.sms.entity.Dictionary;
|
||||
import com.bocloud.sms.model.DictionaryBean;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.Result;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 环境信息服务接口
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
public interface DictService {
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @param dictionary
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Dictionary> create(Dictionary dictionary);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Result remove(Long id);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Dictionary> modify(DictionaryBean bean);
|
||||
|
||||
/**
|
||||
* 字典树
|
||||
*
|
||||
* @param pid
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Dictionary>> list(Long pid);
|
||||
|
||||
/**
|
||||
* 根据值获取子节点数据
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Dictionary>> listChild(String value, Long id);
|
||||
|
||||
/**
|
||||
* 查询字典树
|
||||
*
|
||||
* @param pid
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Dictionary>> childTree(String pid);
|
||||
|
||||
/**
|
||||
* 查询所有osName
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<String> getAllOsName();
|
||||
|
||||
/**
|
||||
* 获取全部数据中心及下级信息
|
||||
*
|
||||
* @return 数据中心及下级信息
|
||||
*/
|
||||
Map<String, String> getAllDataCenter();
|
||||
|
||||
/**
|
||||
* 通过id查询字典
|
||||
*
|
||||
* @param id id
|
||||
* @return {@link GeneralResult}<{@link Dictionary}>
|
||||
*/
|
||||
GeneralResult<Dictionary> detail(Long id);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Environment;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
|
||||
/**
|
||||
* 环境实体类Service
|
||||
*
|
||||
* @author wangshuai
|
||||
* @version 4.1.0-SNAPSHOT
|
||||
* @since 2018/12/24
|
||||
*/
|
||||
public interface EnvironmentService {
|
||||
|
||||
|
||||
GeneralResult<GridBean<Environment>> list(Pager pager, RequestContext context);
|
||||
|
||||
/**
|
||||
* 移除所属环境
|
||||
*
|
||||
* @param id
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult remove(Long id, RequestContext context);
|
||||
|
||||
/**
|
||||
* 查询环境详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Environment> detail(Long id);
|
||||
|
||||
/**
|
||||
* 创建环境
|
||||
*
|
||||
* @param environment
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Environment> create(Environment environment, RequestContext context);
|
||||
|
||||
/**
|
||||
* 修改环境
|
||||
*
|
||||
* @param bean
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Environment> modify(Environment bean, RequestContext context);
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.GlobalManConfig;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
/**
|
||||
* @author wpj
|
||||
* @since 2022/9/8
|
||||
*/
|
||||
public interface GlobalManConfigService {
|
||||
|
||||
GeneralResult<GridBean<GlobalManConfig>> list(Pager pager, RequestContext context);
|
||||
|
||||
Result create(GlobalManConfig globalManConfig, RequestContext context);
|
||||
|
||||
Result modify(GlobalManConfig globalManConfig, RequestContext context);
|
||||
|
||||
Result remove(Long id, RequestContext context);
|
||||
|
||||
Result allow(RequestContext context);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
|
||||
import com.bocloud.sms.entity.Icon;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 图表service层
|
||||
*
|
||||
* @author 胡立伟
|
||||
* @Version 1.0
|
||||
* @since 2020年4月7日
|
||||
*/
|
||||
public interface IconService {
|
||||
GeneralResult<GridBean<Icon>> list(Pager pager, RequestContext context);
|
||||
|
||||
GeneralResult<Void> create(MultipartFile[] files, String category, RequestContext requestContext);
|
||||
|
||||
GeneralResult<Void> remove(Long id);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Label;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
public interface LabelService {
|
||||
|
||||
/**
|
||||
* 查询标签列表
|
||||
*
|
||||
* @param pager
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<Label>> list(Pager pager, RequestContext context);
|
||||
|
||||
/**
|
||||
* 查看标签详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Label> detail(Long id);
|
||||
|
||||
/**
|
||||
* 创建标签
|
||||
*
|
||||
* @param label
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Label> create(Label label, RequestContext context);
|
||||
|
||||
/**
|
||||
* 更新标签
|
||||
*
|
||||
* @param label
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Label> modify(Label label);
|
||||
|
||||
/**
|
||||
* 删除标签
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Result remove(Long id);
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.LogArchiveRecord;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
*/
|
||||
public interface LogArchiveRecordService {
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @param pager
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<LogArchiveRecord>> list(Pager pager);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.AccessLog;
|
||||
import com.megatron.common.model.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 审计日志服务接口
|
||||
*
|
||||
* @author dmw
|
||||
*/
|
||||
public interface LogService {
|
||||
|
||||
/**
|
||||
* 审计日志列表
|
||||
*
|
||||
* @param pager
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<AccessLog>> list(Pager pager);
|
||||
|
||||
/**
|
||||
* 添加审计日志
|
||||
*
|
||||
* @param accessLog
|
||||
* @return
|
||||
*/
|
||||
Result create(AccessLog accessLog);
|
||||
|
||||
/**
|
||||
* 批量插入日志
|
||||
*
|
||||
* @param logs
|
||||
* @return
|
||||
*/
|
||||
Result batch(List<AccessLog> logs);
|
||||
|
||||
/**
|
||||
* 审计日志归档
|
||||
*
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
* @param deleted
|
||||
* @param request
|
||||
* @param response
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<StringBuilder> archive(String startTime, String endTime, boolean deleted, RequestContext context, HttpServletRequest request,
|
||||
HttpServletResponse response);
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.model.PermissionBean;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @time 2020/2/4 周二 9:38
|
||||
*/
|
||||
public interface ManagerService {
|
||||
|
||||
/**
|
||||
* 查询管理员权限树形列表
|
||||
*
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<PermissionBean>> listPermissions(RequestContext requestContext);
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Message;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 消息服务接口
|
||||
*
|
||||
* @author weiwei
|
||||
* @version 1.0
|
||||
* @since 2016.10.26
|
||||
*/
|
||||
public interface MessageService {
|
||||
|
||||
/**
|
||||
* 获取分页信息
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @param context 请求对象
|
||||
* @return 满足条件的列表
|
||||
*/
|
||||
GeneralResult<GridBean<Message>> list(Pager pager, RequestContext context);
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param context
|
||||
* @param title
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
Result create(RequestContext context, String title, String content);
|
||||
|
||||
/**
|
||||
* 移除
|
||||
*
|
||||
* @param id ID
|
||||
* @param userId 操作者ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Result remove(Long id, Long userId);
|
||||
|
||||
/**
|
||||
* 获取详细信息
|
||||
*
|
||||
* @param id ID
|
||||
* @param context 操作者ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
GeneralResult<Message> detail(Long id, RequestContext context);
|
||||
|
||||
/**
|
||||
* 当前用户消息状态全部更新为已读
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
Result messageRead(RequestContext context);
|
||||
|
||||
/**
|
||||
* 统计当前用户消息的状态数量
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Message> statistics(RequestContext context);
|
||||
|
||||
/**
|
||||
* 发送队列消息
|
||||
*
|
||||
* @param queueName
|
||||
* @param message
|
||||
*/
|
||||
void sendQueueMessage(String queueName, Map<String, Object> message);
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.NameRule;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
/**
|
||||
* 命名规则service实现
|
||||
*
|
||||
* @author wangyu
|
||||
* @version 3.0.0-SNAPSHOT
|
||||
* @since 2018/7/2
|
||||
*/
|
||||
public interface NameRuleService {
|
||||
|
||||
/**
|
||||
* 查询命名规则列表
|
||||
*
|
||||
* @param pager
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<NameRule>> list(Pager pager, RequestContext context);
|
||||
|
||||
/**
|
||||
* 查看命名规则详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<NameRule> detail(Long id);
|
||||
|
||||
/**
|
||||
* 创建命名规则
|
||||
*
|
||||
* @param nameRule
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<NameRule> create(NameRule nameRule, RequestContext context);
|
||||
|
||||
/**
|
||||
* 更新命名规则
|
||||
*
|
||||
* @param nameRule
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
Result modify(NameRule nameRule, RequestContext context);
|
||||
|
||||
/**
|
||||
* 删除命名规则
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Result remove(Long id);
|
||||
|
||||
/**
|
||||
* 生成命名
|
||||
*
|
||||
* @param id
|
||||
* @param tenantId
|
||||
* @param userId
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<String> generate(Long id, Long tenantId, Long userId, Long projectId, RequestContext context);
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.Permission;
|
||||
import com.bocloud.sms.model.PermissionBean;
|
||||
import com.bocloud.sms.model.PermissionIcon;
|
||||
import com.bocloud.sms.model.PermissionModel;
|
||||
import com.bocloud.sms.model.PermissionParentsBean;
|
||||
import com.megatron.common.exception.InternalServerException;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @time 2020/2/4 周二 9:43
|
||||
*/
|
||||
public interface PermissionService {
|
||||
/**
|
||||
* 创建权限
|
||||
*
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result create(PermissionModel params, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 修改权限
|
||||
*
|
||||
* @param id
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result modify(Long id, PermissionModel params, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 删除权限
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result remove(Long id, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 权限详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Permission> detail(Long id);
|
||||
|
||||
/**
|
||||
* 查询权限
|
||||
*
|
||||
* @param parentId
|
||||
* @param category
|
||||
* @param tenant
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<PermissionBean>> list(Long parentId, String category, Boolean tenant);
|
||||
|
||||
/**
|
||||
* 查询父节点
|
||||
*
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<PermissionParentsBean>> listParents(RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 查询图标
|
||||
*
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<PermissionIcon>> listIcon(RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 根据服务id查询服务菜单权限
|
||||
*
|
||||
* @param serviceId
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Permission> getServicePermission(Long serviceId);
|
||||
|
||||
/**
|
||||
* 根据服务id集合查询服务菜单权限
|
||||
*
|
||||
* @param services
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Permission>> getServicePermissions(List<Long> services);
|
||||
|
||||
/**
|
||||
* 获取指定API模块权限列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<JSONArray> getApiList();
|
||||
|
||||
/**
|
||||
* 根据服务code获取指定API模块权限列表
|
||||
*
|
||||
* @param codes
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<JSONArray> getApiList(List<String> codes);
|
||||
|
||||
GeneralResult<List<Permission>> listPermissionsByCondition(String condition);
|
||||
|
||||
/**
|
||||
* 插件绑定权限
|
||||
*
|
||||
* @param permissionIdList 权限id列表
|
||||
* @param pluginsCode 插件编码
|
||||
* @param tenant 是否是租户端的菜单页面
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result bindingPlugins(List<Long> permissionIdList, String pluginsCode, Boolean tenant, RequestContext requestContext);
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Dictionary;
|
||||
import com.bocloud.sms.entity.Plugin;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.GridBean;
|
||||
import com.megatron.common.model.Pager;
|
||||
import com.megatron.common.model.Result;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 插件
|
||||
*
|
||||
* @author zhangyf
|
||||
* @since 2022-05-19
|
||||
*/
|
||||
public interface PluginService {
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
* @param pager 分野
|
||||
* @return plugin列表
|
||||
*/
|
||||
GeneralResult<GridBean<Plugin>> list(Pager pager);
|
||||
|
||||
/**
|
||||
* 已安装列表
|
||||
*
|
||||
* @param service 主服务
|
||||
* @return 插件列表
|
||||
*/
|
||||
Map<String, List<Plugin>> listInstalled(String service);
|
||||
|
||||
/**
|
||||
* 可更新列表
|
||||
*
|
||||
* @param service 主服务
|
||||
* @return 插件列表
|
||||
*/
|
||||
Map<String, List<Plugin>> listUpdate(String service);
|
||||
|
||||
/**
|
||||
* 可安装列表
|
||||
*
|
||||
* @param service 主服务
|
||||
* @return 插件列表
|
||||
*/
|
||||
Map<String, List<Plugin>> listCanInstall(String service);
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param plugin 插件
|
||||
* @return 成功/失败
|
||||
*/
|
||||
Result create(Plugin plugin);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param id ID
|
||||
* @param plugin 实体类
|
||||
* @param hasPackage 是否修改插件包
|
||||
* @return 更新 成功/失败
|
||||
*/
|
||||
Result modify(Long id, Plugin plugin, boolean hasPackage);
|
||||
|
||||
/**
|
||||
* 移除
|
||||
*
|
||||
* @param id
|
||||
* @return 删除
|
||||
*/
|
||||
Result remove(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param idList
|
||||
* @return 成功/失败 个数
|
||||
*/
|
||||
Result batchRemove(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 获取详细信息
|
||||
*
|
||||
* @param id
|
||||
* @return plugin详细信息
|
||||
*/
|
||||
Plugin detail(Long id);
|
||||
|
||||
/**
|
||||
* 查询插件下的云平台列表
|
||||
*
|
||||
* @param pager
|
||||
* @return 云平台列表 to ims
|
||||
*/
|
||||
GeneralResult<List<Dictionary>> getVendorList(Pager pager);
|
||||
|
||||
/**
|
||||
* 获取license中插件列表
|
||||
*
|
||||
* @param pager 分页参数
|
||||
* @return license中插件列表
|
||||
*/
|
||||
List<Plugin> listLicense(Pager pager);
|
||||
|
||||
/**
|
||||
* 当前运行的插件集合
|
||||
*
|
||||
* @param services 主服务
|
||||
* @return 插件集合
|
||||
*/
|
||||
List<Plugin> runningPlugins(String... services);
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
|
||||
/**
|
||||
* 组件配置元素service层
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
public interface PortalElementConfigService {
|
||||
|
||||
/**
|
||||
* 组件配置元素列表查询
|
||||
*
|
||||
* @param poolId
|
||||
* @return
|
||||
*/
|
||||
GeneralResult list(Long poolId);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
|
||||
/**
|
||||
* 组件池service层
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
public interface PortalElementPoolService {
|
||||
|
||||
/**
|
||||
* 组件池列表展示
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
GeneralResult list(String module);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.PortalPanel;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 首页配置service层
|
||||
*
|
||||
* @author lyy
|
||||
* @version 2.0
|
||||
* @time 2017年12月27日
|
||||
*/
|
||||
public interface PortalPanelService {
|
||||
|
||||
/**
|
||||
* 首页配置列表展示
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult list(String module, RequestContext context);
|
||||
|
||||
/**
|
||||
* 全保存
|
||||
*
|
||||
* @param portalPanels
|
||||
* @param userId
|
||||
* @param module
|
||||
* @param tenantId
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
GeneralResult save(List<PortalPanel> portalPanels, Long userId, Long tenantId, Long projectId, String module);
|
||||
|
||||
|
||||
/**
|
||||
* 重置
|
||||
*
|
||||
* @param module
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
GeneralResult reset(String module, RequestContext context);
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.Business;
|
||||
import com.bocloud.sms.entity.Project;
|
||||
import com.bocloud.sms.model.ProjectModel;
|
||||
import com.bocloud.sms.model.ProjectUserBean;
|
||||
import com.megatron.common.model.*;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tyl
|
||||
* @time 2020/6/2 周二 15:57
|
||||
*/
|
||||
public interface ProjectService {
|
||||
|
||||
/**
|
||||
* 分页查询项目列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<Project>> list(Pager pager, RequestContext requestContext, Boolean tenantId);
|
||||
|
||||
/**
|
||||
* 字典查询项目信息
|
||||
*
|
||||
* @param condition
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult condition(String condition, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 创建项目
|
||||
*
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result create(ProjectModel params, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 修改项目
|
||||
*
|
||||
* @param id
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result modify(Long id, ProjectModel params, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result remove(Long id, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 批量删除项目
|
||||
*
|
||||
* @param ids
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result batchRemove(List<Long> ids, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 查询详细
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Project> detail(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* 项目下配置用户
|
||||
*
|
||||
* @param projectId
|
||||
* @param projectUserBean
|
||||
* @return
|
||||
*/
|
||||
Result configUser(Long projectId, ProjectUserBean projectUserBean);
|
||||
|
||||
/**
|
||||
* 根据查询条件导出项目列表
|
||||
*
|
||||
* @param params
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
XSSFWorkbook export(List<Param> params, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 查询项目所在业务详细信息
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Business> getBusinessDetail(Long id, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 设置项目成员为项目经理
|
||||
*
|
||||
* @param id
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Result configProjectManager(Long id, Long userId);
|
||||
|
||||
/**
|
||||
* 导入模板下载
|
||||
*
|
||||
* @param title
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
XSSFWorkbook importTemp2(String title, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 导入模板下载
|
||||
*
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
Result importTemp(HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 导入项目
|
||||
*
|
||||
* @param multipartFile
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result importData(MultipartFile multipartFile, RequestContext requestContext);
|
||||
|
||||
GeneralResult<List<Project>> queryByDepart(String departName);
|
||||
|
||||
GeneralResult<List<Project>> queryByDepartIds(Pager pager, List<Long> departIds);
|
||||
|
||||
GeneralResult<Project> getByProjectName(String departName);
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
|
||||
import com.bocloud.sms.monitor.LabelParam;
|
||||
import com.bocloud.sms.monitor.PrometheusResult;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* prometheus监控数据查询
|
||||
*
|
||||
* @author zhangyf
|
||||
* @since 2018-12-27
|
||||
*/
|
||||
public interface PrometheusService {
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @return 监控数据
|
||||
*/
|
||||
Double simpleQuery(String expr);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param time 当前请求时间点的时间戳
|
||||
* @return 监控数据
|
||||
*/
|
||||
Double simpleQuery(String expr, String time);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询表达式
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
Double simpleQuery(String expr, Map<String, String> params);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询表达式
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
Double simpleQuery(String expr, List<LabelParam> params);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr, Map<String, String> params);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr, List<LabelParam> params);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param time 当前请求时间点的时间戳
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr, String time);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param time 当前请求时间点的时间戳
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr, Map<String, String> params, String time);
|
||||
|
||||
/**
|
||||
* query查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param time 当前请求时间点的时间戳
|
||||
* @param params 参数
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> query(String expr, List<LabelParam> params, String time);
|
||||
|
||||
/**
|
||||
* query_range查询方式请求
|
||||
*
|
||||
* @param start 过去某个时间点的时间戳
|
||||
* @param end 当前请求时间点的时间戳
|
||||
* @param step 获取时间与时间之间数据的步长
|
||||
* @param expr 查询条件
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> queryRange(String expr, String start, String end, String step);
|
||||
|
||||
/**
|
||||
* query_range查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param params 参数
|
||||
* @param start 过去某个时间点的时间戳
|
||||
* @param end 当前请求时间点的时间戳
|
||||
* @param step 获取时间与时间之间数据的步长
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> queryRange(String expr, Map<String, String> params, String start, String end, String step);
|
||||
|
||||
/**
|
||||
* query_range查询方式请求
|
||||
*
|
||||
* @param expr 查询条件
|
||||
* @param params 参数
|
||||
* @param start 过去某个时间点的时间戳
|
||||
* @param end 当前请求时间点的时间戳
|
||||
* @param step 获取时间与时间之间数据的步长
|
||||
* @return 监控数据
|
||||
*/
|
||||
List<PrometheusResult> queryRange(String expr, List<LabelParam> params, String start, String end, String step);
|
||||
|
||||
/**
|
||||
* 过滤集合
|
||||
*
|
||||
* @param expr 表达示
|
||||
* @param filter 要过滤元素
|
||||
* @return 过滤后的Label值集合
|
||||
*/
|
||||
Set<String> filter(String expr, String filter);
|
||||
|
||||
/**
|
||||
* 重新加载prometheus配置信息
|
||||
*/
|
||||
void reload();
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.model.LineChartResult;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 监控数据查询
|
||||
*
|
||||
* @author zhangyf
|
||||
* @since 2019-01-08
|
||||
*/
|
||||
public interface QueryService {
|
||||
|
||||
/**
|
||||
* 图表
|
||||
*
|
||||
* @param exprs 表达式集合
|
||||
* @param names 图表名集合
|
||||
* @param start 开始时间戳
|
||||
* @param end 结束时间戳
|
||||
* @param step 步长
|
||||
* @param unit 单位
|
||||
* @return 监控图表
|
||||
*/
|
||||
LineChartResult chart(List<String> exprs, List<String> names, String start, String end, String step, String unit);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.Role;
|
||||
import com.bocloud.sms.entity.User;
|
||||
import com.bocloud.sms.model.ApiInfo;
|
||||
import com.bocloud.sms.model.CloudServiceBean;
|
||||
import com.bocloud.sms.model.RoleModel;
|
||||
import com.megatron.common.exception.InternalServerException;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色抽象Service接口
|
||||
*
|
||||
* @author tyl
|
||||
*/
|
||||
public interface RoleService {
|
||||
|
||||
/**
|
||||
* 创建角色
|
||||
*
|
||||
* @param roleModel
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result create(RoleModel roleModel, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 修改角色信息
|
||||
*
|
||||
* @param id
|
||||
* @param roleModel
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result modify(Long id, RoleModel roleModel, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
*
|
||||
* @param id
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result remove(Long id, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 查询角色详情
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<Role> detail(Long id);
|
||||
|
||||
/**
|
||||
* 授权角色权限
|
||||
*
|
||||
* @param id
|
||||
* @param ids
|
||||
* @param requestContext
|
||||
* @return
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
Result accredit(Long id, List<Long> ids, RequestContext requestContext) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 查询角色列表
|
||||
*
|
||||
* @param pager
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<Role>> list(Pager pager, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 查询角色权限
|
||||
*
|
||||
* @param id
|
||||
* @param menu
|
||||
* @param tenant
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<CloudServiceBean>> listPermissions(Long id, boolean menu, boolean tenant, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 查询角色是否存在
|
||||
*
|
||||
* @param name
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
Result exists(String name, Long tenantId);
|
||||
|
||||
/**
|
||||
* 获取请求用户角色信息
|
||||
*
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<List<Long>> roleIds(RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* API权限授权角色
|
||||
*
|
||||
* @param id
|
||||
* @param module
|
||||
* @param apiList
|
||||
* @return
|
||||
*/
|
||||
Result accreditRole(Long id, List<ApiInfo> apiList);
|
||||
|
||||
/**
|
||||
* 获取API权限列表
|
||||
*
|
||||
* @param id
|
||||
* @param tags
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<JSONArray> getApiPermission(Long id, String tags);
|
||||
|
||||
/**
|
||||
* 查询指定角色下的用户
|
||||
*
|
||||
* @param pager
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
GeneralResult<GridBean<User>> listUsersByRoleId(Pager pager, Long id);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
public interface SingleLoginService {
|
||||
|
||||
public RedirectView singleLogin(String token, HttpServletRequest request) throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.megatron.common.model.Result;
|
||||
|
||||
/**
|
||||
* @ClassName: SysDateViewService
|
||||
* @Description:
|
||||
* @Author lxy
|
||||
* @Date 2021/9/29 10:10
|
||||
*/
|
||||
public interface SysDateViewService {
|
||||
Result systemCount();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.bocloud.sms.entity.SystemConfig;
|
||||
import com.bocloud.sms.model.ConfigModel;
|
||||
import com.megatron.common.exception.InternalServerException;
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
import com.megatron.common.model.RequestContext;
|
||||
import com.megatron.common.model.Result;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lyy
|
||||
* @Version 1.0
|
||||
* @since 2017年8月18日
|
||||
*/
|
||||
public interface SystemConfigService {
|
||||
|
||||
/**
|
||||
* 更新系统配置
|
||||
*
|
||||
* @param systemConfig
|
||||
* @return
|
||||
*/
|
||||
Result modify(SystemConfig systemConfig) throws InternalServerException;
|
||||
|
||||
/**
|
||||
* 批量修改
|
||||
*
|
||||
* @param list
|
||||
* @param requestContext
|
||||
* @return
|
||||
*/
|
||||
Result batchUpdate(List<ConfigModel> list, Map<String, MultipartFile> fileMap, RequestContext requestContext);
|
||||
|
||||
Result syncLdap();
|
||||
|
||||
GeneralResult<Map<String, String>> listConfigs(String category, List<String> codes);
|
||||
|
||||
GeneralResult<JSONArray> listCategoryTree(String category);
|
||||
|
||||
/**
|
||||
* 系统配置测试连接
|
||||
*
|
||||
* @param category
|
||||
* @return
|
||||
*/
|
||||
Result configTest(String category);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.megatron.common.model.GeneralResult;
|
||||
|
||||
public interface SystemHomeService {
|
||||
|
||||
GeneralResult<?> getToken();
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.bocloud.sms.interfaces;
|
||||
|
||||
import com.bocloud.sms.entity.SystemNotice;
|
||||
import com.megatron.common.model.*;
|
||||
|
||||
|
||||
/**
|
||||
* 系统公告
|
||||
*/
|
||||
public interface SystemNoticeService {
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*/
|
||||
Result create(SystemNotice entity, RequestContext user);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
Result remove(Long id, RequestContext user);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
Result modify(SystemNotice params, RequestContext user);
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
GeneralResult<GridBean<SystemNotice>> list(Pager pager, RequestContext requestContext);
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
GeneralResult<SystemNotice> detail(Long id);
|
||||
|
||||
/**
|
||||
* 发布
|
||||
*/
|
||||
GeneralResult<Void> sendMsg(Long id);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue